PYAE1994 commited on
Commit
9f4ee55
·
verified ·
1 Parent(s): 1bf29fe

Update app/agent/agent.py

Browse files
Files changed (1) hide show
  1. app/agent/agent.py +69 -31
app/agent/agent.py CHANGED
@@ -13,10 +13,11 @@ class Agent:
13
  self.history = []
14
  self.executor = Executor(llm=self.call_llm)
15
 
16
- # ========================
17
- # LLM CALL LAYER (SAFE)
18
- # ========================
19
  def call_llm(self, messages):
 
20
  try:
21
  res = requests.post(
22
  Config.LLM_API_URL,
@@ -32,27 +33,51 @@ class Agent:
32
  timeout=60
33
  )
34
 
 
 
 
35
  data = res.json()
36
 
37
- # safety check
 
 
 
 
 
 
38
  return data
39
 
40
  except Exception as e:
41
- return {
42
- "error": str(e),
43
- "choices": [{
 
 
 
 
 
 
 
 
44
  "message": {
45
  "content": "LLM_ERROR"
46
  }
47
- }]
48
- }
 
49
 
50
- # ========================
51
  # GOAL MODE (AUTONOMOUS)
52
- # ========================
53
  def run_goal(self, goal: str):
54
 
55
- plan = create_plan(goal)
 
 
 
 
 
 
56
 
57
  results = self.executor.run_plan(plan)
58
 
@@ -63,9 +88,9 @@ class Agent:
63
  "results": results
64
  }
65
 
66
- # ========================
67
- # TOOL MODE (DIRECT)
68
- # ========================
69
  def run(self, user_input):
70
 
71
  messages = [
@@ -76,8 +101,8 @@ class Agent:
76
  You are an autonomous coding + browser + planning agent.
77
 
78
  MODES:
79
- 1) TOOL MODE → STRICT JSON ONLY
80
- 2) NORMAL MODE → plain text
81
 
82
  TOOLS:
83
  - run_shell(cmd)
@@ -89,6 +114,10 @@ TOOLS:
89
  - browser_click(selector)
90
  - browser_type(selector, text)
91
  - browser_screenshot(path)
 
 
 
 
92
  """
93
  },
94
  {
@@ -99,20 +128,27 @@ TOOLS:
99
 
100
  response = self.call_llm(messages)
101
 
102
- # ========================
103
- # SAFE PARSING
104
- # ========================
 
 
105
  try:
106
- content = response["choices"][0]["message"]["content"]
 
 
107
  except Exception:
 
 
 
108
  return {
109
  "mode": "error",
110
- "response": "Invalid LLM response structure"
111
  }
112
 
113
- # ========================
114
  # TOOL EXECUTION PATH
115
- # ========================
116
  try:
117
  tool_call = json.loads(content)
118
 
@@ -120,11 +156,13 @@ TOOLS:
120
 
121
  result = execute_tool_call(tool_call)
122
 
123
- # NO CRASH FIX (healer optional safe guard)
124
  try:
125
  fix = self.executor.healer.heal(user_input, result)
126
- if fix:
 
127
  result = execute_tool_call(fix)
 
128
  except Exception:
129
  pass
130
 
@@ -142,18 +180,18 @@ TOOLS:
142
  except json.JSONDecodeError:
143
  pass
144
 
145
- # ========================
146
- # NORMAL RESPONSE PATH
147
- # ========================
148
  return {
149
  "mode": "normal_response",
150
  "response": content
151
  }
152
 
153
 
154
- # ========================
155
  # DEBUG
156
- # ========================
157
  if __name__ == "__main__":
158
  agent = Agent()
159
 
 
13
  self.history = []
14
  self.executor = Executor(llm=self.call_llm)
15
 
16
+ # =====================================================
17
+ # LLM CALL LAYER (ROBUST)
18
+ # =====================================================
19
  def call_llm(self, messages):
20
+
21
  try:
22
  res = requests.post(
23
  Config.LLM_API_URL,
 
33
  timeout=60
34
  )
35
 
36
+ # HTTP check
37
+ res.raise_for_status()
38
+
39
  data = res.json()
40
 
41
+ # structure validation
42
+ if not isinstance(data, dict):
43
+ return self._llm_fallback("invalid_response")
44
+
45
+ if "choices" not in data:
46
+ return self._llm_fallback("missing_choices")
47
+
48
  return data
49
 
50
  except Exception as e:
51
+ return self._llm_fallback(str(e))
52
+
53
+ # =====================================================
54
+ # SAFE FALLBACK RESPONSE
55
+ # =====================================================
56
+ def _llm_fallback(self, error_msg):
57
+
58
+ return {
59
+ "error": error_msg,
60
+ "choices": [
61
+ {
62
  "message": {
63
  "content": "LLM_ERROR"
64
  }
65
+ }
66
+ ]
67
+ }
68
 
69
+ # =====================================================
70
  # GOAL MODE (AUTONOMOUS)
71
+ # =====================================================
72
  def run_goal(self, goal: str):
73
 
74
+ try:
75
+ plan = create_plan(goal)
76
+ except Exception as e:
77
+ return {
78
+ "mode": "error",
79
+ "error": f"plan_failed: {str(e)}"
80
+ }
81
 
82
  results = self.executor.run_plan(plan)
83
 
 
88
  "results": results
89
  }
90
 
91
+ # =====================================================
92
+ # TOOL / CHAT MODE
93
+ # =====================================================
94
  def run(self, user_input):
95
 
96
  messages = [
 
101
  You are an autonomous coding + browser + planning agent.
102
 
103
  MODES:
104
+ - TOOL MODE → STRICT JSON ONLY
105
+ - NORMAL MODE → plain text
106
 
107
  TOOLS:
108
  - run_shell(cmd)
 
114
  - browser_click(selector)
115
  - browser_type(selector, text)
116
  - browser_screenshot(path)
117
+
118
+ RULE:
119
+ If action → JSON ONLY
120
+ If explanation → text only
121
  """
122
  },
123
  {
 
128
 
129
  response = self.call_llm(messages)
130
 
131
+ # =================================================
132
+ # SAFE CONTENT EXTRACTION
133
+ # =================================================
134
+ content = None
135
+
136
  try:
137
+ content = response.get("choices", [{}])[0] \
138
+ .get("message", {}) \
139
+ .get("content", None)
140
  except Exception:
141
+ content = None
142
+
143
+ if not content:
144
  return {
145
  "mode": "error",
146
+ "response": "Empty LLM response"
147
  }
148
 
149
+ # =================================================
150
  # TOOL EXECUTION PATH
151
+ # =================================================
152
  try:
153
  tool_call = json.loads(content)
154
 
 
156
 
157
  result = execute_tool_call(tool_call)
158
 
159
+ # SAFE HEALER CALL (NO CRASH)
160
  try:
161
  fix = self.executor.healer.heal(user_input, result)
162
+
163
+ if isinstance(fix, dict) and "tool" in fix:
164
  result = execute_tool_call(fix)
165
+
166
  except Exception:
167
  pass
168
 
 
180
  except json.JSONDecodeError:
181
  pass
182
 
183
+ # =================================================
184
+ # NORMAL RESPONSE
185
+ # =================================================
186
  return {
187
  "mode": "normal_response",
188
  "response": content
189
  }
190
 
191
 
192
+ # =====================================================
193
  # DEBUG
194
+ # =====================================================
195
  if __name__ == "__main__":
196
  agent = Agent()
197