diff --git a/application/agents/base.py b/application/agents/base.py
index dff191a3..068b2a3c 100644
--- a/application/agents/base.py
+++ b/application/agents/base.py
@@ -142,28 +142,28 @@ class BaseAgent(ABC):
tool_id, action_name, call_args = parser.parse_args(call)
call_id = getattr(call, "id", None) or str(uuid.uuid4())
-
+
# Check if parsing failed
if tool_id is None or action_name is None:
error_message = f"Error: Failed to parse LLM tool call. Tool name: {getattr(call, 'name', 'unknown')}"
logger.error(error_message)
-
+
tool_call_data = {
"tool_name": "unknown",
"call_id": call_id,
- "action_name": getattr(call, 'name', 'unknown'),
+ "action_name": getattr(call, "name", "unknown"),
"arguments": call_args or {},
"result": f"Failed to parse tool call. Invalid tool name format: {getattr(call, 'name', 'unknown')}",
}
yield {"type": "tool_call", "data": {**tool_call_data, "status": "error"}}
self.tool_calls.append(tool_call_data)
return f"Failed to parse tool call.", call_id
-
+
# Check if tool_id exists in available tools
if tool_id not in tools_dict:
error_message = f"Error: Tool ID '{tool_id}' extracted from LLM call not found in available tools_dict. Available IDs: {list(tools_dict.keys())}"
logger.error(error_message)
-
+
# Return error result
tool_call_data = {
"tool_name": "unknown",
@@ -175,7 +175,7 @@ class BaseAgent(ABC):
yield {"type": "tool_call", "data": {**tool_call_data, "status": "error"}}
self.tool_calls.append(tool_call_data)
return f"Tool with ID {tool_id} not found.", call_id
-
+
tool_call_data = {
"tool_name": tools_dict[tool_id]["name"],
"call_id": call_id,
diff --git a/application/agents/tools/mcp_tool.py b/application/agents/tools/mcp_tool.py
index 72a26482..dc689367 100644
--- a/application/agents/tools/mcp_tool.py
+++ b/application/agents/tools/mcp_tool.py
@@ -283,7 +283,14 @@ class MCPTool(Tool):
"""
self._ensure_valid_session()
- call_params = {"name": action_name, "arguments": kwargs}
+ # Skipping empty/None values - letting the server use defaults
+
+ cleaned_kwargs = {}
+ for key, value in kwargs.items():
+ if value == "" or value is None:
+ continue
+ cleaned_kwargs[key] = value
+ call_params = {"name": action_name, "arguments": cleaned_kwargs}
try:
result = self._make_mcp_request("tools/call", call_params)
return result
diff --git a/application/core/settings.py b/application/core/settings.py
index a8c6bfa3..f1563569 100644
--- a/application/core/settings.py
+++ b/application/core/settings.py
@@ -26,7 +26,7 @@ class Settings(BaseSettings):
"gpt-4o-mini": 128000,
"gpt-3.5-turbo": 4096,
"claude-2": 1e5,
- "gemini-2.0-flash-exp": 1e6,
+ "gemini-2.5-flash": 1e6,
}
UPLOAD_FOLDER: str = "inputs"
PARSE_PDF_AS_IMAGE: bool = False
diff --git a/application/llm/google_ai.py b/application/llm/google_ai.py
index 54567f6f..b88e1d9f 100644
--- a/application/llm/google_ai.py
+++ b/application/llm/google_ai.py
@@ -151,15 +151,8 @@ class GoogleLLM(BaseLLM):
if role == "assistant":
role = "model"
- elif role == "system":
- continue
elif role == "tool":
- continue
- elif role not in ["user", "model"]:
- logging.warning(
- f"GoogleLLM: Converting unsupported role '{role}' to 'user'"
- )
- role = "user"
+ role = "model"
parts = []
if role and content is not None:
diff --git a/application/llm/handlers/base.py b/application/llm/handlers/base.py
index 43205472..96ed4c00 100644
--- a/application/llm/handlers/base.py
+++ b/application/llm/handlers/base.py
@@ -205,7 +205,6 @@ class LLMHandler(ABC):
except StopIteration as e:
tool_response, call_id = e.value
break
-
updated_messages.append(
{
"role": "assistant",
@@ -222,17 +221,36 @@ class LLMHandler(ABC):
)
updated_messages.append(self.create_tool_message(call, tool_response))
-
except Exception as e:
logger.error(f"Error executing tool: {str(e)}", exc_info=True)
- updated_messages.append(
- {
- "role": "tool",
- "content": f"Error executing tool: {str(e)}",
- "tool_call_id": call.id,
- }
+ error_call = ToolCall(
+ id=call.id, name=call.name, arguments=call.arguments
)
+ error_response = f"Error executing tool: {str(e)}"
+ error_message = self.create_tool_message(error_call, error_response)
+ updated_messages.append(error_message)
+ call_parts = call.name.split("_")
+ if len(call_parts) >= 2:
+ tool_id = call_parts[-1] # Last part is tool ID (e.g., "1")
+ action_name = "_".join(call_parts[:-1])
+ tool_name = tools_dict.get(tool_id, {}).get("name", "unknown_tool")
+ full_action_name = f"{action_name}_{tool_id}"
+ else:
+ tool_name = "unknown_tool"
+ action_name = call.name
+ full_action_name = call.name
+ yield {
+ "type": "tool_call",
+ "data": {
+ "tool_name": tool_name,
+ "call_id": call.id,
+ "action_name": full_action_name,
+ "arguments": call.arguments,
+ "error": error_response,
+ "status": "error",
+ },
+ }
return updated_messages
def handle_non_streaming(
@@ -263,13 +281,11 @@ class LLMHandler(ABC):
except StopIteration as e:
messages = e.value
break
-
response = agent.llm.gen(
model=agent.gpt_model, messages=messages, tools=agent.tools
)
parsed = self.parse_response(response)
self.llm_calls.append(build_stack_data(agent.llm))
-
return parsed.content
def handle_streaming(
diff --git a/application/llm/handlers/google.py b/application/llm/handlers/google.py
index b43f2a16..7fa44cb6 100644
--- a/application/llm/handlers/google.py
+++ b/application/llm/handlers/google.py
@@ -17,7 +17,6 @@ class GoogleLLMHandler(LLMHandler):
finish_reason="stop",
raw_response=response,
)
-
if hasattr(response, "candidates"):
parts = response.candidates[0].content.parts if response.candidates else []
tool_calls = [
@@ -41,7 +40,6 @@ class GoogleLLMHandler(LLMHandler):
finish_reason="tool_calls" if tool_calls else "stop",
raw_response=response,
)
-
else:
tool_calls = []
if hasattr(response, "function_call"):
@@ -61,14 +59,16 @@ class GoogleLLMHandler(LLMHandler):
def create_tool_message(self, tool_call: ToolCall, result: Any) -> Dict:
"""Create Google-style tool message."""
- from google.genai import types
return {
- "role": "tool",
+ "role": "model",
"content": [
- types.Part.from_function_response(
- name=tool_call.name, response={"result": result}
- ).to_json_dict()
+ {
+ "function_response": {
+ "name": tool_call.name,
+ "response": {"result": result},
+ }
+ }
],
}
diff --git a/frontend/src/conversation/ConversationBubble.tsx b/frontend/src/conversation/ConversationBubble.tsx
index 3be40df7..bbdf5e00 100644
--- a/frontend/src/conversation/ConversationBubble.tsx
+++ b/frontend/src/conversation/ConversationBubble.tsx
@@ -1,6 +1,6 @@
import 'katex/dist/katex.min.css';
-import { forwardRef, Fragment, useRef, useState, useEffect } from 'react';
+import { forwardRef, Fragment, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import ReactMarkdown from 'react-markdown';
import { useSelector } from 'react-redux';
@@ -12,12 +12,13 @@ import {
import rehypeKatex from 'rehype-katex';
import remarkGfm from 'remark-gfm';
import remarkMath from 'remark-math';
-import DocumentationDark from '../assets/documentation-dark.svg';
+
import ChevronDown from '../assets/chevron-down.svg';
import Cloud from '../assets/cloud.svg';
import DocsGPT3 from '../assets/cute_docsgpt3.svg';
import Dislike from '../assets/dislike.svg?react';
import Document from '../assets/document.svg';
+import DocumentationDark from '../assets/documentation-dark.svg';
import Edit from '../assets/edit.svg';
import Like from '../assets/like.svg?react';
import Link from '../assets/link.svg';
@@ -761,7 +762,11 @@ function ToolCalls({ toolCalls }: { toolCalls: ToolCallsType[] }) {
Response
{' '}
+ + {toolCall.error} + +
+ )} diff --git a/frontend/src/conversation/types/index.ts b/frontend/src/conversation/types/index.ts index 4ccb04a1..d962e4bc 100644 --- a/frontend/src/conversation/types/index.ts +++ b/frontend/src/conversation/types/index.ts @@ -4,5 +4,6 @@ export type ToolCallsType = { call_id: string; arguments: Record