PYAE1994 commited on
Commit
9ef3a3e
·
verified ·
1 Parent(s): b89676e

Update app/agent/executor.py

Browse files
Files changed (1) hide show
  1. app/agent/executor.py +41 -31
app/agent/executor.py CHANGED
@@ -9,52 +9,51 @@ class Executor:
9
  self.healer = SelfHealer(llm=llm)
10
 
11
  # =====================================================
12
- # MAIN PLAN EXECUTION PIPELINE
13
  # =====================================================
14
  def run_plan(self, plan):
15
 
16
- results = []
17
-
18
  if not isinstance(plan, dict):
19
  return {"error": "Plan must be dict"}
20
 
21
  steps = plan.get("steps", [])
22
-
23
  if not isinstance(steps, list):
24
  return {"error": "Invalid steps format"}
25
 
 
 
26
  for step in steps:
27
 
28
  print(f"🚀 Executing step: {step}")
29
 
30
- # ==============================
31
- # 1. TOOL EXECUTION
32
- # ==============================
33
  tool_result = self._execute_as_tool(step)
34
 
35
- # ==============================
36
- # 2. SELF HEAL LAYER (SAFE)
37
- # ==============================
38
  try:
39
  fix = self.healer.heal(step, tool_result)
40
 
41
  if isinstance(fix, dict) and "tool" in fix:
42
  print("🛠️ Self-healing triggered")
43
 
44
- healed_result = execute_tool_call(fix)
45
 
46
- # only replace if fix is successful
47
- if healed_result:
48
- tool_result = healed_result
49
 
50
  except Exception as e:
51
  tool_result = {
52
- "error": f"healer crashed: {str(e)}"
53
  }
54
 
55
- # ==============================
56
- # 3. LLM ANALYSIS (SAFE NON-EXEC MODE)
57
- # ==============================
58
  llm_result = None
59
 
60
  if self.llm:
@@ -63,8 +62,8 @@ class Executor:
63
  {
64
  "role": "system",
65
  "content": (
66
- "You are a strict analysis engine. "
67
- "Only analyze results. Never call tools."
68
  )
69
  },
70
  {
@@ -73,20 +72,21 @@ class Executor:
73
  }
74
  ])
75
 
76
- # SAFE extraction
77
  if isinstance(response, dict):
78
- llm_result = response.get("choices", [{}])[0] \
79
- .get("message", {}) \
80
- .get("content", response)
 
 
81
  else:
82
- llm_result = response
83
 
84
  except Exception as e:
85
- llm_result = {"error": str(e)}
86
 
87
- # ==============================
88
  # 4. STORE RESULT
89
- # ==============================
90
  results.append({
91
  "step": step,
92
  "tool_result": tool_result,
@@ -104,16 +104,26 @@ class Executor:
104
  def _execute_as_tool(self, step):
105
 
106
  try:
107
- # string step → shell execution
108
  if isinstance(step, str):
 
 
 
 
 
 
 
 
 
 
109
  return execute_tool_call({
110
  "tool": "run_shell",
111
  "args": {
112
- "cmd": step.strip()
113
  }
114
  })
115
 
116
- # dict tool call
117
  if isinstance(step, dict):
118
 
119
  if "tool" not in step or "args" not in step:
 
9
  self.healer = SelfHealer(llm=llm)
10
 
11
  # =====================================================
12
+ # MAIN EXECUTION PIPELINE
13
  # =====================================================
14
  def run_plan(self, plan):
15
 
 
 
16
  if not isinstance(plan, dict):
17
  return {"error": "Plan must be dict"}
18
 
19
  steps = plan.get("steps", [])
 
20
  if not isinstance(steps, list):
21
  return {"error": "Invalid steps format"}
22
 
23
+ results = []
24
+
25
  for step in steps:
26
 
27
  print(f"🚀 Executing step: {step}")
28
 
29
+ # =========================
30
+ # 1. TOOL EXECUTION LAYER
31
+ # =========================
32
  tool_result = self._execute_as_tool(step)
33
 
34
+ # =========================
35
+ # 2. SELF HEAL (SAFE)
36
+ # =========================
37
  try:
38
  fix = self.healer.heal(step, tool_result)
39
 
40
  if isinstance(fix, dict) and "tool" in fix:
41
  print("🛠️ Self-healing triggered")
42
 
43
+ healed = execute_tool_call(fix)
44
 
45
+ # replace only if valid result
46
+ if healed:
47
+ tool_result = healed
48
 
49
  except Exception as e:
50
  tool_result = {
51
+ "error": f"healer_error: {str(e)}"
52
  }
53
 
54
+ # =========================
55
+ # 3. LLM ANALYSIS (NO EXECUTION)
56
+ # =========================
57
  llm_result = None
58
 
59
  if self.llm:
 
62
  {
63
  "role": "system",
64
  "content": (
65
+ "You are an analysis engine. "
66
+ "NEVER execute tools. Only explain results."
67
  )
68
  },
69
  {
 
72
  }
73
  ])
74
 
 
75
  if isinstance(response, dict):
76
+ llm_result = (
77
+ response.get("choices", [{}])[0]
78
+ .get("message", {})
79
+ .get("content", "LLM_EMPTY")
80
+ )
81
  else:
82
+ llm_result = str(response)
83
 
84
  except Exception as e:
85
+ llm_result = f"llm_error: {str(e)}"
86
 
87
+ # =========================
88
  # 4. STORE RESULT
89
+ # =========================
90
  results.append({
91
  "step": step,
92
  "tool_result": tool_result,
 
104
  def _execute_as_tool(self, step):
105
 
106
  try:
107
+ # CASE 1: string → shell command
108
  if isinstance(step, str):
109
+ cmd = step.strip()
110
+
111
+ # block fake natural language commands
112
+ blocked_words = ["create", "install", "open", "navigate", "save", "run"]
113
+ if any(w in cmd.lower().split()[0] for w in blocked_words):
114
+ return {
115
+ "error": "Unsafe natural-language step rejected",
116
+ "step": cmd
117
+ }
118
+
119
  return execute_tool_call({
120
  "tool": "run_shell",
121
  "args": {
122
+ "cmd": cmd
123
  }
124
  })
125
 
126
+ # CASE 2: tool dict
127
  if isinstance(step, dict):
128
 
129
  if "tool" not in step or "args" not in step: