|
33 | 33 | ToolResultMessageEvent, |
34 | 34 | TypedEvent, |
35 | 35 | ) |
36 | | -from ..types.content import Message |
| 36 | +from ..types.content import Message, Messages |
37 | 37 | from ..types.exceptions import ( |
38 | 38 | ContextWindowOverflowException, |
39 | 39 | EventLoopException, |
|
56 | 56 | MAX_DELAY = 240 # 4 minutes |
57 | 57 |
|
58 | 58 |
|
| 59 | +def _has_tool_use_in_latest_message(messages: "Messages") -> bool: |
| 60 | + """Check if the latest message contains any ToolUse content blocks. |
| 61 | +
|
| 62 | + Args: |
| 63 | + messages: List of messages in the conversation. |
| 64 | +
|
| 65 | + Returns: |
| 66 | + True if the latest message contains at least one ToolUse content block, False otherwise. |
| 67 | + """ |
| 68 | + if len(messages) > 0: |
| 69 | + latest_message = messages[-1] |
| 70 | + content_blocks = latest_message.get("content", []) |
| 71 | + |
| 72 | + for content_block in content_blocks: |
| 73 | + if "toolUse" in content_block: |
| 74 | + return True |
| 75 | + |
| 76 | + return False |
| 77 | + |
| 78 | + |
59 | 79 | async def event_loop_cycle( |
60 | 80 | agent: "Agent", |
61 | 81 | invocation_state: dict[str, Any], |
@@ -121,7 +141,10 @@ async def event_loop_cycle( |
121 | 141 | if agent._interrupt_state.activated: |
122 | 142 | stop_reason: StopReason = "tool_use" |
123 | 143 | message = agent._interrupt_state.context["tool_use_message"] |
124 | | - |
| 144 | + # Skip model invocation if the latest message contains ToolUse |
| 145 | + elif _has_tool_use_in_latest_message(agent.messages): |
| 146 | + stop_reason = "tool_use" |
| 147 | + message = agent.messages[-1] |
125 | 148 | else: |
126 | 149 | model_events = _handle_model_execution( |
127 | 150 | agent, cycle_span, cycle_trace, invocation_state, tracer, structured_output_context |
|
0 commit comments