Run the agent loop with MCP tools.
(
client: Anthropic,
model: str,
question: str,
tools: list[dict[str, Any]],
connection: Any,
)
| 84 | |
| 85 | |
| 86 | async def agent_loop( |
| 87 | client: Anthropic, |
| 88 | model: str, |
| 89 | question: str, |
| 90 | tools: list[dict[str, Any]], |
| 91 | connection: Any, |
| 92 | ) -> tuple[str, dict[str, Any]]: |
| 93 | """Run the agent loop with MCP tools.""" |
| 94 | messages = [{"role": "user", "content": question}] |
| 95 | |
| 96 | response = await asyncio.to_thread( |
| 97 | client.messages.create, |
| 98 | model=model, |
| 99 | max_tokens=4096, |
| 100 | system=EVALUATION_PROMPT, |
| 101 | messages=messages, |
| 102 | tools=tools, |
| 103 | ) |
| 104 | |
| 105 | messages.append({"role": "assistant", "content": response.content}) |
| 106 | |
| 107 | tool_metrics = {} |
| 108 | |
| 109 | while response.stop_reason == "tool_use": |
| 110 | tool_use = next(block for block in response.content if block.type == "tool_use") |
| 111 | tool_name = tool_use.name |
| 112 | tool_input = tool_use.input |
| 113 | |
| 114 | tool_start_ts = time.time() |
| 115 | try: |
| 116 | tool_result = await connection.call_tool(tool_name, tool_input) |
| 117 | tool_response = json.dumps(tool_result) if isinstance(tool_result, (dict, list)) else str(tool_result) |
| 118 | except Exception as e: |
| 119 | tool_response = f"Error executing tool {tool_name}: {str(e)}\n" |
| 120 | tool_response += traceback.format_exc() |
| 121 | tool_duration = time.time() - tool_start_ts |
| 122 | |
| 123 | if tool_name not in tool_metrics: |
| 124 | tool_metrics[tool_name] = {"count": 0, "durations": []} |
| 125 | tool_metrics[tool_name]["count"] += 1 |
| 126 | tool_metrics[tool_name]["durations"].append(tool_duration) |
| 127 | |
| 128 | messages.append({ |
| 129 | "role": "user", |
| 130 | "content": [{ |
| 131 | "type": "tool_result", |
| 132 | "tool_use_id": tool_use.id, |
| 133 | "content": tool_response, |
| 134 | }] |
| 135 | }) |
| 136 | |
| 137 | response = await asyncio.to_thread( |
| 138 | client.messages.create, |
| 139 | model=model, |
| 140 | max_tokens=4096, |
| 141 | system=EVALUATION_PROMPT, |
| 142 | messages=messages, |
| 143 | tools=tools, |
no test coverage detected