1212# Plugin identifier
1313SLUG = "coc"
1414
15+ # Maximum attempts to fix code
16+ MAX_FIX_ATTEMPTS = 3
17+
1518# List of allowed modules for execution
1619ALLOWED_MODULES = {
1720 'math' : math ,
1821}
1922
20- # Prompts
23+ # Initial code generation prompt
2124CHAIN_OF_CODE_PROMPT = '''
22- You are an AI assistant that uses Chain of Code (CoC) approach to solve problems. Follow these steps:
23-
24- 1. Write Python code that breaks down the problem into clear steps
25- 2. Each step should either be:
26- - Executable Python code that performs computations
27- - Pseudocode that you will simulate with natural language understanding
28- 3. Track final result in an 'answer' variable
29- 4. Return the final answer within the <output> tags
25+ Write Python code to solve this problem. The code should:
26+ 1. Break down the problem into clear computational steps
27+ 2. Use standard Python features and math operations
28+ 3. Store the final result in a variable named 'answer'
29+ 4. Include error handling where appropriate
30+ 5. Be complete and executable
3031
3132Format your response using:
3233```python
3334[Your complete Python program here]
3435```
36+ '''
37+
38+ # Code fix prompt
39+ CODE_FIX_PROMPT = '''
40+ The following Python code failed to execute. Fix the code to make it work.
41+ Original code:
42+ ```python
43+ {code}
44+ ```
3545
36- Finally provide output as:
37- <output>
38- [Your final answer]
39- </output>
46+ Error encountered:
47+ {error}
48+
49+ Please provide a complete, fixed version of the code that:
50+ 1. Addresses the error message
51+ 2. Maintains the same logic and approach
52+ 3. Stores the final result in 'answer'
53+ 4. Is complete and executable
54+
55+ Return only the fixed code in a code block:
56+ ```python
57+ [Your fixed code here]
58+ ```
4059'''
4160
42- STATE_SIMULATION_PROMPT = '''You are simulating the execution of a Python program.
43- Given the code below, simulate its execution and return the final value that would be in the 'answer' variable.
44- Return ONLY the final value, no explanations or additional text.
61+ # Simulation prompt
62+ SIMULATION_PROMPT = '''
63+ The following Python code could not be executed after several attempts.
64+ Please simulate its execution and determine the final value that would be in the 'answer' variable.
4565
4666Code to simulate:
67+ ```python
4768{code}
69+ ```
70+
71+ Last error encountered:
72+ {error}
73+
74+ Important:
75+ 1. Follow the logic of the code exactly
76+ 2. Perform all calculations carefully
77+ 3. Return ONLY the final numeric or string value, no explanations
78+ 4. If the code contains semantic functions (like text analysis), use your judgment to simulate them
4879'''
4980
5081def extract_code_blocks (text : str ) -> List [str ]:
@@ -57,100 +88,168 @@ def extract_code_blocks(text: str) -> List[str]:
5788 logger .info (f"Code block { i + 1 } :\n { block } " )
5889 return blocks
5990
60- def extract_output (text : str ) -> str :
61- """Extract content from output tags."""
62- pattern = r'<output>(.*?)</output>'
63- match = re .search (pattern , text , re .DOTALL )
64- result = match .group (1 ).strip () if match else text .strip ()
65- logger .info (f"Extracted output: { result } " )
66- return result
67-
68- def execute_code (code : str , client , model : str ) -> Tuple [Any , int ]:
69- """Execute full code block either with Python or LM simulation."""
70- logger .info ("Attempting to execute complete code block" )
91+ def sanitize_code (code : str ) -> str :
92+ """Prepare code for execution by adding necessary imports and safety checks."""
93+ # Add standard imports
94+ imports = "\n " .join (f"import { mod } " for mod in ALLOWED_MODULES )
95+
96+ # Add safety wrapper
97+ wrapper = f"""
98+ { imports }
99+
100+ def safe_execute():
101+ { code .replace ('\n ' , '\n ' )}
102+ return answer if 'answer' in locals() else None
103+
104+ result = safe_execute()
105+ answer = result
106+ """
107+ return wrapper
108+
109+ def execute_code (code : str ) -> Tuple [Any , str ]:
110+ """Attempt to execute the code and return result or error."""
111+ logger .info ("Attempting to execute code" )
71112 logger .info (f"Code:\n { code } " )
72113
73- # Add imports
74114 execution_env = {}
75- for mod_name , mod in ALLOWED_MODULES .items ():
76- execution_env [mod_name ] = mod
77-
78115 try :
79- # Try executing the complete code block with Python
80- logger .info ("Attempting Python execution" )
81- exec (code , execution_env )
116+ sanitized_code = sanitize_code (code )
117+ exec (sanitized_code , execution_env )
82118 answer = execution_env .get ('answer' )
83- logger .info (f"Python execution successful. Answer: { answer } " )
84- return answer , 0
85119
120+ if answer is not None :
121+ logger .info (f"Execution successful. Answer: { answer } " )
122+ return answer , None
123+ else :
124+ error = "Code executed but did not produce an answer"
125+ logger .warning (error )
126+ return None , error
127+
86128 except Exception as e :
87- logger .info (f"Python execution failed: { str (e )} " )
88- logger .info ("Falling back to LM simulation" )
89-
90- # If Python execution fails, simulate with LM
91- response = client .chat .completions .create (
92- model = model ,
93- messages = [
94- {"role" : "system" , "content" : STATE_SIMULATION_PROMPT .format (code = code )},
95- {"role" : "user" , "content" : "Simulate this code and return the final value of 'answer'." }
96- ],
97- temperature = 0.2
98- )
99-
129+ error = f"{ type (e ).__name__ } : { str (e )} \n { traceback .format_exc ()} "
130+ logger .error (f"Execution failed: { error } " )
131+ return None , error
132+
133+ def generate_fixed_code (original_code : str , error : str , client , model : str ) -> Tuple [str , int ]:
134+ """Ask LLM to fix the broken code."""
135+ logger .info ("Requesting code fix from LLM" )
136+ logger .info (f"Original error: { error } " )
137+
138+ response = client .chat .completions .create (
139+ model = model ,
140+ messages = [
141+ {"role" : "system" , "content" : CODE_FIX_PROMPT .format (
142+ code = original_code , error = error )},
143+ {"role" : "user" , "content" : "Fix the code to make it work." }
144+ ],
145+ temperature = 0.2
146+ )
147+
148+ fixed_code = response .choices [0 ].message .content
149+ code_blocks = extract_code_blocks (fixed_code )
150+
151+ if code_blocks :
152+ logger .info ("Received fixed code from LLM" )
153+ return code_blocks [0 ], response .usage .completion_tokens
154+ else :
155+ logger .warning ("No code block found in LLM response" )
156+ return None , response .usage .completion_tokens
157+
158+ def simulate_execution (code : str , error : str , client , model : str ) -> Tuple [Any , int ]:
159+ """Ask LLM to simulate code execution."""
160+ logger .info ("Attempting code simulation with LLM" )
161+
162+ response = client .chat .completions .create (
163+ model = model ,
164+ messages = [
165+ {"role" : "system" , "content" : SIMULATION_PROMPT .format (
166+ code = code , error = error )},
167+ {"role" : "user" , "content" : "Simulate this code and return the final answer value." }
168+ ],
169+ temperature = 0.2
170+ )
171+
172+ try :
173+ result = response .choices [0 ].message .content .strip ()
174+ # Try to convert to appropriate type
100175 try :
101- answer = response .choices [0 ].message .content .strip ()
102- logger .info (f"LM simulation successful. Answer: { answer } " )
103-
104- # Try to convert to number if possible
105- try :
106- answer = ast .literal_eval (answer )
107- except :
108- pass
109-
110- return answer , response .usage .completion_tokens
111-
112- except Exception as e :
113- logger .error (f"Could not parse LM simulation response: { str (e )} " )
114- return None , response .usage .completion_tokens
176+ answer = ast .literal_eval (result )
177+ except :
178+ answer = result
179+ logger .info (f"Simulation successful. Result: { answer } " )
180+ return answer , response .usage .completion_tokens
181+ except Exception as e :
182+ logger .error (f"Failed to parse simulation result: { str (e )} " )
183+ return None , response .usage .completion_tokens
115184
116185def run (system_prompt : str , initial_query : str , client , model : str ) -> Tuple [str , int ]:
117186 """Main Chain of Code execution function."""
118187 logger .info ("Starting Chain of Code execution" )
119188 logger .info (f"Query: { initial_query } " )
120189
190+ # Initial code generation
121191 messages = [
122192 {"role" : "system" , "content" : system_prompt + "\n " + CHAIN_OF_CODE_PROMPT },
123193 {"role" : "user" , "content" : initial_query }
124194 ]
125195
126- logger .info ("Generating code solution" )
127196 response = client .chat .completions .create (
128197 model = model ,
129198 messages = messages ,
130199 temperature = 0.7
131200 )
132- initial_response = response .choices [0 ].message .content
133201 total_tokens = response .usage .completion_tokens
134202
135- logger .info ("Initial response from LM:" )
136- logger .info (initial_response )
137-
138- code_blocks = extract_code_blocks (initial_response )
203+ # Extract initial code
204+ code_blocks = extract_code_blocks (response .choices [0 ].message .content )
139205 if not code_blocks :
140206 logger .warning ("No code blocks found in response" )
141- return initial_response , total_tokens
142-
143- # Execute the complete code block
144- code = code_blocks [0 ]
145- answer , execution_tokens = execute_code (code , client , model )
146- total_tokens += execution_tokens
207+ return response .choices [0 ].message .content , total_tokens
147208
148- # If we got an answer from code execution, use it
149- if answer is not None :
150- final_answer = str (answer )
151- else :
152- # Fall back to output tags if code execution failed
153- final_answer = extract_output (initial_response )
209+ current_code = code_blocks [0 ]
210+ fix_attempts = 0
211+ last_error = None
212+
213+ # Strategy 1: Direct execution and fix attempts
214+ while fix_attempts < MAX_FIX_ATTEMPTS :
215+ fix_attempts += 1
216+ logger .info (f"Execution attempt { fix_attempts } /{ MAX_FIX_ATTEMPTS } " )
217+
218+ # Try to execute current code
219+ answer , error = execute_code (current_code )
220+
221+ # If successful, return the answer
222+ if error is None :
223+ logger .info (f"Successful execution on attempt { fix_attempts } " )
224+ return str (answer ), total_tokens
154225
155- logger .info (f"Chain of Code execution completed. Final answer: { final_answer } " )
156- return final_answer , total_tokens
226+ last_error = error
227+
228+ # If we hit max attempts, break to try simulation
229+ if fix_attempts >= MAX_FIX_ATTEMPTS :
230+ logger .warning (f"Failed after { fix_attempts } fix attempts" )
231+ break
232+
233+ # Otherwise, try to get fixed code from LLM
234+ logger .info (f"Requesting code fix, attempt { fix_attempts } " )
235+ fixed_code , fix_tokens = generate_fixed_code (current_code , error , client , model )
236+ total_tokens += fix_tokens
237+
238+ if fixed_code :
239+ current_code = fixed_code
240+ else :
241+ logger .error ("Failed to get fixed code from LLM" )
242+ break
243+
244+ # Strategy 2: If all execution attempts failed, try simulation
245+ logger .info ("All execution attempts failed, trying simulation" )
246+ simulated_answer , sim_tokens = simulate_execution (current_code , last_error , client , model )
247+ total_tokens += sim_tokens
248+
249+ if simulated_answer is not None :
250+ logger .info ("Successfully got answer from simulation" )
251+ return str (simulated_answer ), total_tokens
252+
253+ # If we get here, everything failed
254+ logger .warning ("All strategies failed" )
255+ return f"Error: Could not solve problem after all attempts. Last error: { last_error } " , total_tokens
0 commit comments