ryomo commited on
Commit
700b662
·
1 Parent(s): 056e98d

fix: update agent loop iterations and improve tool usage guidelines in chat_with_mcp_tools

Browse files
Files changed (1) hide show
  1. src/unpredictable_lord/chat/chat.py +33 -10
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 calling loop
24
- MAX_TOOL_CALL_ITERATIONS = 5
 
 
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
- # Tool calling loop
191
- for iteration in range(MAX_TOOL_CALL_ITERATIONS):
192
- logger.info(f"Tool calling iteration {iteration + 1}")
 
 
 
 
 
 
 
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
- logger.info(f"Found {len(tool_calls)} tool call(s)")
 
 
 
 
 
 
 
 
211
 
212
  # Add parsed messages to conversation
213
  messages.extend(result.parsed_messages)
214
 
215
- # Indicate tool execution in UI
216
- partial_history[-1]["content"] += "\n\n*(Executing orders...)*"
 
 
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
- # Remove status message
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