|
31 | 31 | ToolResultMessageEvent, |
32 | 32 | TypedEvent, |
33 | 33 | ) |
34 | | -from ..types.content import Message |
| 34 | +from ..types.content import Message, Messages |
35 | 35 | from ..types.exceptions import ( |
36 | 36 | ContextWindowOverflowException, |
37 | 37 | EventLoopException, |
|
53 | 53 | MAX_DELAY = 240 # 4 minutes |
54 | 54 |
|
55 | 55 |
|
| 56 | +def _has_tool_use_in_latest_message(messages: "Messages") -> bool: |
| 57 | + """Check if the latest message contains any ToolUse content blocks. |
| 58 | +
|
| 59 | + Args: |
| 60 | + messages: List of messages in the conversation. |
| 61 | +
|
| 62 | + Returns: |
| 63 | + True if the latest message contains at least one ToolUse content block, False otherwise. |
| 64 | + """ |
| 65 | + latest_message = messages[-1] |
| 66 | + content_blocks = latest_message.get("content", []) |
| 67 | + |
| 68 | + for content_block in content_blocks: |
| 69 | + if "toolUse" in content_block: |
| 70 | + return True |
| 71 | + |
| 72 | + return False |
| 73 | + |
| 74 | + |
56 | 75 | async def event_loop_cycle(agent: "Agent", invocation_state: dict[str, Any]) -> AsyncGenerator[TypedEvent, None]: |
57 | 76 | """Execute a single cycle of the event loop. |
58 | 77 |
|
@@ -111,7 +130,10 @@ async def event_loop_cycle(agent: "Agent", invocation_state: dict[str, Any]) -> |
111 | 130 | if agent._interrupt_state.activated: |
112 | 131 | stop_reason: StopReason = "tool_use" |
113 | 132 | message = agent._interrupt_state.context["tool_use_message"] |
114 | | - |
| 133 | + # Skip model invocation if the latest message contains ToolUse |
| 134 | + elif _has_tool_use_in_latest_message(agent.messages): |
| 135 | + stop_reason = "tool_use" |
| 136 | + message = agent.messages[-1] |
115 | 137 | else: |
116 | 138 | model_events = _handle_model_execution(agent, cycle_span, cycle_trace, invocation_state, tracer) |
117 | 139 | async for model_event in model_events: |
|
0 commit comments