fix: Fix parsing bug where Anthropic returns nested JSON (#3096)
This commit is contained in:
@@ -210,17 +210,21 @@ def generate_step_id():
|
||||
return f"step-{uuid.uuid4()}"
|
||||
|
||||
|
||||
def _safe_load_dict(raw: str) -> dict:
|
||||
def _safe_load_tool_call_str(tool_call_args_str: str) -> dict:
|
||||
"""Lenient JSON → dict with fallback to eval on assertion failure."""
|
||||
if "}{" in raw: # strip accidental parallel calls
|
||||
raw = raw.split("}{", 1)[0] + "}"
|
||||
# Temp hack to gracefully handle parallel tool calling attempt, only take first one
|
||||
if "}{" in tool_call_args_str:
|
||||
tool_call_args_str = tool_call_args_str.split("}{", 1)[0] + "}"
|
||||
|
||||
try:
|
||||
data = json.loads(raw)
|
||||
if not isinstance(data, dict):
|
||||
raise AssertionError
|
||||
return data
|
||||
except (json.JSONDecodeError, AssertionError):
|
||||
return json.loads(raw) if raw else {}
|
||||
tool_args = json.loads(tool_call_args_str)
|
||||
if not isinstance(tool_args, dict):
|
||||
# Load it again - this is due to sometimes Anthropic returning weird json @caren
|
||||
tool_args = json.loads(tool_args)
|
||||
except json.JSONDecodeError:
|
||||
tool_args = {}
|
||||
|
||||
return tool_args
|
||||
|
||||
|
||||
def _pop_heartbeat(tool_args: dict) -> bool:
|
||||
|
||||
@@ -15,7 +15,7 @@ from letta.agents.helpers import (
|
||||
_create_letta_response,
|
||||
_pop_heartbeat,
|
||||
_prepare_in_context_messages_no_persist_async,
|
||||
_safe_load_dict,
|
||||
_safe_load_tool_call_str,
|
||||
generate_step_id,
|
||||
)
|
||||
from letta.constants import DEFAULT_MAX_STEPS, NON_USER_MSG_PREFIX
|
||||
@@ -944,7 +944,7 @@ class LettaAgent(BaseAgent):
|
||||
# 1. Parse and validate the tool-call envelope
|
||||
tool_call_name: str = tool_call.function.name
|
||||
tool_call_id: str = tool_call.id or f"call_{uuid.uuid4().hex[:8]}"
|
||||
tool_args = _safe_load_dict(tool_call.function.arguments)
|
||||
tool_args = _safe_load_tool_call_str(tool_call.function.arguments)
|
||||
request_heartbeat: bool = _pop_heartbeat(tool_args)
|
||||
tool_args.pop(INNER_THOUGHTS_KWARG, None)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user