From b8e00d403cf0be4bca886b28b58f9bd6bed7df10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E6=BD=AE?= Date: Tue, 23 Dec 2025 19:11:27 +0800 Subject: [PATCH] =?UTF-8?q?=20=20=E4=BF=AE=E5=A4=8D=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E3=80=82=E4=B8=BB=E8=A6=81=E6=94=B9=E5=8A=A8=EF=BC=9A=20=201.?= =?UTF-8?q?=20=E6=96=B0=E5=A2=9E=20=5Fclean=5Fcontent=5Fblocks=20=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=9A=E4=B8=93=E9=97=A8=E5=A4=84=E7=90=86=20conten?= =?UTF-8?q?t=20=E5=AD=97=E6=AE=B5=E7=9A=84=E6=B8=85=E7=90=86=20=20=20=20-?= =?UTF-8?q?=20=E5=BD=93=20content=20=E6=98=AF=E5=88=97=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E6=97=B6=EF=BC=8C=E8=BF=87=E6=BB=A4=E6=8E=89=20type:?= =?UTF-8?q?=20'tool=5Fuse'=20=E7=9A=84=E5=9D=97=EF=BC=88=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=20id=20=E4=B8=8D=E5=9C=A8=20valid=5Ftool=5Fcall=5Fids=20?= =?UTF-8?q?=E4=B8=AD=EF=BC=89=20=20=20=20-=20=E8=BF=94=E5=9B=9E=E6=B8=85?= =?UTF-8?q?=E7=90=86=E5=90=8E=E7=9A=84=20content=20=E5=92=8C=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E6=9C=89=E6=96=87=E6=9C=AC=E5=86=85=E5=AE=B9=E7=9A=84?= =?UTF-8?q?=E6=A0=87=E5=BF=97=20=202.=20=E6=9B=B4=E6=96=B0=20=5Fcleanup=5F?= =?UTF-8?q?tool=5Fuse=5Fmessages=20=E6=96=B9=E6=B3=95=EF=BC=9A=20=20=20=20?= =?UTF-8?q?-=20=E8=B0=83=E7=94=A8=20=5Fclean=5Fcontent=5Fblocks=20?= =?UTF-8?q?=E6=9D=A5=E6=B8=85=E7=90=86=20content=20=20=20=20-=20=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=B8=85=E7=90=86=E5=90=8E=E7=9A=84=20cleaned=5Fconte?= =?UTF-8?q?nt=20=E5=88=9B=E5=BB=BA=E6=96=B0=E7=9A=84=20AIMessage=20=20?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E6=A0=B9=E6=BA=90=EF=BC=9A=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E7=9A=84=E4=BB=A3=E7=A0=81=E5=8F=AA=E6=B8=85=E7=A9=BA=E4=BA=86?= =?UTF-8?q?=20tool=5Fcalls=3D[]=EF=BC=8C=E4=BD=86=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E4=BB=8E=20content=20=E5=88=97=E8=A1=A8=E4=B8=AD=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=20type:=20'tool=5Fuse'=20=E7=9A=84=E5=9D=97=E3=80=82A?= =?UTF-8?q?nthropic=20API=20=E4=BC=9A=E6=A3=80=E6=9F=A5=E8=BF=99=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E5=9C=B0=E6=96=B9=EF=BC=8C=E5=AF=BC=E8=87=B4=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent/tool_use_cleanup_middleware.py | 57 ++++++++++++++++++++++++---- mcp/mcp_settings_deep_agent.json | 14 +++++++ 2 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 mcp/mcp_settings_deep_agent.json diff --git a/agent/tool_use_cleanup_middleware.py b/agent/tool_use_cleanup_middleware.py index 83fb733..5758f52 100644 --- a/agent/tool_use_cleanup_middleware.py +++ b/agent/tool_use_cleanup_middleware.py @@ -66,6 +66,45 @@ class ToolUseCleanupMiddleware(AgentMiddleware): # Other types, treat as having content if it's truthy return bool(content) + def _clean_content_blocks(self, content: Any, valid_tool_call_ids: set[str]) -> tuple[Any, bool]: + """ + Clean up content blocks by removing orphaned tool_use blocks. + + Args: + content: The content to clean (can be str, list, or other) + valid_tool_call_ids: Set of valid tool_call_ids to keep + + Returns: + Tuple of (cleaned_content, has_meaningful_content) + """ + if isinstance(content, str): + return content, bool(content.strip()) + elif isinstance(content, list): + # Filter out tool_use blocks that don't have valid ids + cleaned_blocks = [] + has_text_content = False + + for block in content: + if isinstance(block, dict): + block_type = block.get('type') + if block_type == 'tool_use': + # Only keep tool_use blocks with valid ids + tool_id = block.get('id') + if tool_id in valid_tool_call_ids: + cleaned_blocks.append(block) + elif block_type == 'text' and block.get('text', '').strip(): + cleaned_blocks.append(block) + has_text_content = True + else: + # Keep other block types (images, etc.) + cleaned_blocks.append(block) + else: + cleaned_blocks.append(block) + + return cleaned_blocks, has_text_content + else: + return content, bool(content) + def _cleanup_tool_use_messages(self, messages: list[AnyMessage]) -> list[AnyMessage]: """ Clean up messages by removing tool_use blocks that don't have corresponding tool_results. @@ -98,21 +137,25 @@ class ToolUseCleanupMiddleware(AgentMiddleware): ] removed_count = len(current_msg.tool_calls) - len(filtered_tool_calls) + removed_ids = [tc.get('id') for tc in current_msg.tool_calls if tc.get('id') not in valid_tool_call_ids] if removed_count > 0: self.stats['removed_tool_calls'] += removed_count logger.warning( f"Removed {removed_count} orphaned tool_use(s) from AIMessage. " - f"tool_call_ids: {[tc.get('id') for tc in current_msg.tool_calls]}, " + f"tool_call_ids: {removed_ids}, " f"valid_ids: {valid_tool_call_ids}" ) - has_content = self._has_meaningful_content(current_msg) + # Clean content blocks to remove orphaned tool_use blocks + cleaned_content, has_meaningful_content = self._clean_content_blocks( + current_msg.content, valid_tool_call_ids + ) if filtered_tool_calls: # Has valid tool_calls, keep the message cleaned_msg = AIMessage( - content=current_msg.content, + content=cleaned_content, tool_calls=filtered_tool_calls, additional_kwargs=current_msg.additional_kwargs, response_metadata=current_msg.response_metadata, @@ -120,10 +163,10 @@ class ToolUseCleanupMiddleware(AgentMiddleware): name=current_msg.name, ) cleaned_messages.append(cleaned_msg) - elif has_content: + elif has_meaningful_content: # No valid tool_calls but has meaningful content, keep without tool_calls cleaned_msg = AIMessage( - content=current_msg.content, + content=cleaned_content, tool_calls=[], additional_kwargs=current_msg.additional_kwargs, response_metadata=current_msg.response_metadata, @@ -134,14 +177,14 @@ class ToolUseCleanupMiddleware(AgentMiddleware): self.stats['cleaned_ai_messages'] += 1 logger.info( f"Removed all tool_calls from AIMessage but kept content. " - f"Content preview: {current_msg.content[:50]}..." + f"Content preview: {str(cleaned_content)[:200]}..." ) else: # No valid tool_calls and no meaningful content, completely remove this message self.stats['removed_ai_messages'] += 1 logger.info( f"Removed entire AIMessage with orphaned tool_calls (no meaningful content). " - f"Removed tool_call_ids: {[tc.get('id') for tc in current_msg.tool_calls]}" + f"Removed tool_call_ids: {removed_ids}" ) # Don't add to cleaned_messages - skip this message entirely else: diff --git a/mcp/mcp_settings_deep_agent.json b/mcp/mcp_settings_deep_agent.json new file mode 100644 index 0000000..ddf9962 --- /dev/null +++ b/mcp/mcp_settings_deep_agent.json @@ -0,0 +1,14 @@ +[ + { + "mcpServers": { + "rag_retrieve": { + "transport": "stdio", + "command": "python", + "args": [ + "./mcp/rag_retrieve_server.py", + "{bot_id}" + ] + } + } + } +]