From f42fc5d34b54ed74d0bb28bbb2abcd28951b60de Mon Sep 17 00:00:00 2001 From: marko-kraemer Date: Sun, 13 Apr 2025 01:33:23 +0100 Subject: [PATCH] wip --- backend/agent/run.py | 4 ++- backend/agent/tools/web_search_tool.py | 2 ++ backend/agentpress/response_processor.py | 38 ++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/backend/agent/run.py b/backend/agent/run.py index 76736d9c..45c614e2 100644 --- a/backend/agent/run.py +++ b/backend/agent/run.py @@ -46,6 +46,7 @@ async def run_agent(thread_id: str, project_id: str, stream: bool = True, thread system_message = { "role": "system", "content": get_system_prompt() } model_name = "anthropic/claude-3-7-sonnet-latest" + # model_name = "groq/llama-3.3-70b-versatile" # model_name = "openrouter/qwen/qwen2.5-vl-72b-instruct" # model_name = "bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0" # model_name = "anthropic/claude-3-5-sonnet-latest" @@ -97,7 +98,8 @@ async def run_agent(thread_id: str, project_id: str, stream: bool = True, thread # temporary_message=state_message, llm_model=model_name, llm_temperature=0, - llm_max_tokens=64000, + # llm_max_tokens=64000, + llm_max_tokens=32768, tool_choice="auto", max_xml_tool_calls=1, processor_config=ProcessorConfig( diff --git a/backend/agent/tools/web_search_tool.py b/backend/agent/tools/web_search_tool.py index 25563b6b..2964ee14 100644 --- a/backend/agent/tools/web_search_tool.py +++ b/backend/agent/tools/web_search_tool.py @@ -5,6 +5,8 @@ import os from dotenv import load_dotenv from agentpress.tool import Tool, ToolResult, openapi_schema, xml_schema +# TODO: add subpages, etc... in filters as sometimes its necessary + class WebSearchTool(Tool): """Tool for performing web searches using the Exa API.""" diff --git a/backend/agentpress/response_processor.py b/backend/agentpress/response_processor.py index 5d7bbfb8..f3b85433 100644 --- a/backend/agentpress/response_processor.py +++ b/backend/agentpress/response_processor.py @@ -156,8 +156,13 @@ class ResponseProcessor: accumulated_content += chunk_content current_xml_content += chunk_content - # Always yield the content chunk first - yield {"type": "content", "content": chunk_content} + # Check if we've reached the XML tool call limit before yielding content + if config.max_xml_tool_calls > 0 and xml_tool_call_count >= config.max_xml_tool_calls: + # We've reached the limit, don't yield any more content + logger.info("XML tool call limit reached - not yielding more content") + else: + # Always yield the content chunk if we haven't reached the limit + yield {"type": "content", "content": chunk_content} # Parse XML tool calls if enabled if config.xml_tool_calling: @@ -394,6 +399,18 @@ class ResponseProcessor: # After streaming completes, process any remaining content and tool calls # IMPORTANT: Always process accumulated content even when XML tool limit is reached if accumulated_content: + # If we've reached the XML tool call limit, we need to truncate accumulated_content + # to end right after the last XML tool call that was processed + if config.max_xml_tool_calls > 0 and xml_tool_call_count >= config.max_xml_tool_calls and xml_chunks_buffer: + # Find the last processed XML chunk + last_xml_chunk = xml_chunks_buffer[-1] + # Find its position in the accumulated content + last_chunk_end_pos = accumulated_content.find(last_xml_chunk) + len(last_xml_chunk) + if last_chunk_end_pos > 0: + # Truncate the accumulated content to end right after the last XML chunk + logger.info(f"Truncating accumulated content after XML tool call limit reached") + accumulated_content = accumulated_content[:last_chunk_end_pos] + # Extract final complete tool calls for native format complete_native_tool_calls = [] if config.native_tool_calling: @@ -559,13 +576,28 @@ class ResponseProcessor: if hasattr(response_message, 'content') and response_message.content: content = response_message.content - # Parse XML tool calls if enabled + # Process XML tool calls if config.xml_tool_calling: xml_tool_calls = self._parse_xml_tool_calls(content) # Apply XML tool call limit if configured if config.max_xml_tool_calls > 0 and len(xml_tool_calls) > config.max_xml_tool_calls: logger.info(f"Limiting XML tool calls from {len(xml_tool_calls)} to {config.max_xml_tool_calls}") + + # Truncate the content after the last XML tool call that will be processed + if xml_tool_calls and config.max_xml_tool_calls > 0: + # Get XML chunks that will be processed + xml_chunks = self._extract_xml_chunks(content)[:config.max_xml_tool_calls] + if xml_chunks: + # Find position of the last XML chunk that will be processed + last_chunk = xml_chunks[-1] + last_chunk_pos = content.find(last_chunk) + if last_chunk_pos >= 0: + # Truncate content to end after the last processed XML chunk + content = content[:last_chunk_pos + len(last_chunk)] + logger.info(f"Truncated content after XML tool call limit") + + # Limit the tool calls to process xml_tool_calls = xml_tool_calls[:config.max_xml_tool_calls] # Set a custom finish reason finish_reason = "xml_tool_limit_reached"