fix: update agent loop iterations and improve tool usage guidelines in chat_with_mcp_tools
Browse files
src/unpredictable_lord/chat/chat.py
CHANGED
|
@@ -20,8 +20,10 @@ from unpredictable_lord.settings import USE_MODAL
|
|
| 20 |
|
| 21 |
logger = logging.getLogger(__name__)
|
| 22 |
|
| 23 |
-
# Maximum iterations for tool
|
| 24 |
-
|
|
|
|
|
|
|
| 25 |
|
| 26 |
|
| 27 |
if USE_MODAL:
|
|
@@ -74,6 +76,10 @@ Available advice options:
|
|
| 74 |
|
| 75 |
After calling execute_turn, summarize the results to your advisor in character.
|
| 76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
IMPORTANT: After each action or when starting a conversation:
|
| 78 |
1. Explain the current situation and any recent changes
|
| 79 |
2. Ask your advisor what they suggest next
|
|
@@ -187,9 +193,16 @@ async def chat_with_mcp_tools(
|
|
| 187 |
|
| 188 |
accumulated_response = ""
|
| 189 |
|
| 190 |
-
#
|
| 191 |
-
for iteration in range(
|
| 192 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
|
| 194 |
result = StreamResult()
|
| 195 |
async for history in _stream_response(
|
|
@@ -204,16 +217,26 @@ async def chat_with_mcp_tools(
|
|
| 204 |
tool_calls = extract_tool_calls(result.parsed_messages)
|
| 205 |
|
| 206 |
if not tool_calls:
|
| 207 |
-
logger.info("No tool calls found, ending loop")
|
| 208 |
break
|
| 209 |
|
| 210 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 211 |
|
| 212 |
# Add parsed messages to conversation
|
| 213 |
messages.extend(result.parsed_messages)
|
| 214 |
|
| 215 |
-
#
|
| 216 |
-
partial_history[-1]["content"]
|
|
|
|
|
|
|
| 217 |
yield partial_history
|
| 218 |
|
| 219 |
# Execute tools via MCP
|
|
@@ -221,7 +244,7 @@ async def chat_with_mcp_tools(
|
|
| 221 |
|
| 222 |
messages.extend(tool_result_messages)
|
| 223 |
|
| 224 |
-
#
|
| 225 |
partial_history[-1]["content"] = accumulated_response
|
| 226 |
yield partial_history
|
| 227 |
|
|
|
|
| 20 |
|
| 21 |
logger = logging.getLogger(__name__)
|
| 22 |
|
| 23 |
+
# Maximum iterations for agent loop (LLM call -> tool execution -> LLM call ...)
|
| 24 |
+
# Typically completes in 2 iterations: (1) tool call, (2) text response with results
|
| 25 |
+
# Higher values allow for complex multi-step reasoning if needed
|
| 26 |
+
MAX_AGENT_ITERATIONS = 3
|
| 27 |
|
| 28 |
|
| 29 |
if USE_MODAL:
|
|
|
|
| 76 |
|
| 77 |
After calling execute_turn, summarize the results to your advisor in character.
|
| 78 |
|
| 79 |
+
TOOL USAGE GUIDELINES:
|
| 80 |
+
- After receiving tool results, ALWAYS respond with text (do not call more tools)
|
| 81 |
+
- Keep the conversation flowing naturally without excessive tool calls
|
| 82 |
+
|
| 83 |
IMPORTANT: After each action or when starting a conversation:
|
| 84 |
1. Explain the current situation and any recent changes
|
| 85 |
2. Ask your advisor what they suggest next
|
|
|
|
| 193 |
|
| 194 |
accumulated_response = ""
|
| 195 |
|
| 196 |
+
# Agent loop: LLM generates response -> extract tool calls -> execute tools -> repeat
|
| 197 |
+
for iteration in range(MAX_AGENT_ITERATIONS):
|
| 198 |
+
is_final_iteration = iteration == MAX_AGENT_ITERATIONS - 1
|
| 199 |
+
logger.info(f"Agent loop iteration {iteration + 1}/{MAX_AGENT_ITERATIONS}")
|
| 200 |
+
|
| 201 |
+
# Show thinking status
|
| 202 |
+
partial_history[-1]["content"] = accumulated_response + (
|
| 203 |
+
"\n\n*(...thinking...)*" if not accumulated_response else ""
|
| 204 |
+
)
|
| 205 |
+
yield partial_history
|
| 206 |
|
| 207 |
result = StreamResult()
|
| 208 |
async for history in _stream_response(
|
|
|
|
| 217 |
tool_calls = extract_tool_calls(result.parsed_messages)
|
| 218 |
|
| 219 |
if not tool_calls:
|
| 220 |
+
logger.info("No tool calls found, ending agent loop")
|
| 221 |
break
|
| 222 |
|
| 223 |
+
# If this is the final iteration, execute tools but don't loop again
|
| 224 |
+
# (LLM won't get another chance to respond with the results)
|
| 225 |
+
if is_final_iteration:
|
| 226 |
+
logger.warning(
|
| 227 |
+
f"Max agent iterations ({MAX_AGENT_ITERATIONS}) reached, "
|
| 228 |
+
"executing final tool calls without follow-up"
|
| 229 |
+
)
|
| 230 |
+
|
| 231 |
+
logger.info(f"Found {len(tool_calls)} tool call(s), executing...")
|
| 232 |
|
| 233 |
# Add parsed messages to conversation
|
| 234 |
messages.extend(result.parsed_messages)
|
| 235 |
|
| 236 |
+
# Show tool execution status
|
| 237 |
+
partial_history[-1]["content"] = (
|
| 238 |
+
accumulated_response + "\n\n*(executing...)*"
|
| 239 |
+
)
|
| 240 |
yield partial_history
|
| 241 |
|
| 242 |
# Execute tools via MCP
|
|
|
|
| 244 |
|
| 245 |
messages.extend(tool_result_messages)
|
| 246 |
|
| 247 |
+
# Clear status message before next iteration
|
| 248 |
partial_history[-1]["content"] = accumulated_response
|
| 249 |
yield partial_history
|
| 250 |
|