davidleocadio94
feat: data analyzer agent with gradio interface
c8a4550
"""Coding agent implementation with iterative LLM loop.
Main agent loop that orchestrates LLM calls, tool execution,
and conversation memory management.
"""
import json
from openai import OpenAI
from e2b_code_interpreter import Sandbox
from .tools import execute_tool
def coding_agent(
client: OpenAI,
query: str,
system: str,
tools: dict,
tools_schemas: list,
sbx: Sandbox,
messages: list = None,
max_steps: int = 5
):
"""Run coding agent with iterative tool calling loop.
Args:
client: OpenAI client instance
query: User query/prompt
system: System prompt defining agent behavior
tools: Dict mapping tool names to functions
tools_schemas: List of OpenAI function schemas
sbx: E2B Sandbox instance for code execution
messages: Optional existing message history
max_steps: Maximum iteration steps (default 5)
Returns:
Tuple of (messages list, metadata dict)
- messages: Full conversation history
- metadata: Accumulated metadata (especially images)
"""
if messages is None:
messages = []
messages.append({"role": "user", "content": query})
metadata = {}
steps = 0
while steps < max_steps:
# Call LLM with current conversation state
response = client.responses.create(
model="gpt-4.1-mini",
input=[
{"role": "developer", "content": system},
*messages
],
tools=tools_schemas
)
has_function_call = False
# Process all parts of the response
for part in response.output:
messages.append(part.to_dict())
if part.type == "message":
print(part.content)
elif part.type == "function_call":
has_function_call = True
name = part.name
args = part.arguments
# Execute the tool and get results
result, tool_metadata = execute_tool(name, args, tools, sbx=sbx)
# Accumulate metadata (especially images)
if "images" in tool_metadata:
metadata.setdefault("images", []).extend(tool_metadata["images"])
if "error" in tool_metadata:
metadata["error"] = tool_metadata["error"]
# Append function result to conversation
messages.append({
"type": "function_call_output",
"call_id": part.call_id,
"output": json.dumps(result)
})
# Stop if no more function calls
if not has_function_call:
break
steps += 1
return messages, metadata