From 9fd901c3a5c12c01fd257f5175f66c0705069efc Mon Sep 17 00:00:00 2001 From: Charles Packer Date: Thu, 25 Sep 2025 21:57:35 -0700 Subject: [PATCH] fix(core): patch default reasoning for letta-free on letta v1 (#4953) * fix(core): patch default reasoning for letta-free on letta v1 * fix: patch (unrelated?) bug w/ missing required for empty tools like reset_research --- letta/llm_api/anthropic_client.py | 3 ++- letta/services/agent_manager.py | 23 +++++++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/letta/llm_api/anthropic_client.py b/letta/llm_api/anthropic_client.py index 696fe9b2..4a029748 100644 --- a/letta/llm_api/anthropic_client.py +++ b/letta/llm_api/anthropic_client.py @@ -294,7 +294,8 @@ class AnthropicClient(LLMClientBase): if "tools" in data: for tool in data["tools"]: tool["input_schema"]["properties"].pop(REQUEST_HEARTBEAT_PARAM, None) - if REQUEST_HEARTBEAT_PARAM in tool["input_schema"]["required"]: + if "required" in tool["input_schema"] and REQUEST_HEARTBEAT_PARAM in tool["input_schema"]["required"]: + # NOTE: required is not always present tool["input_schema"]["required"].remove(REQUEST_HEARTBEAT_PARAM) else: diff --git a/letta/services/agent_manager.py b/letta/services/agent_manager.py index f2ebf0a8..2c9d40ef 100644 --- a/letta/services/agent_manager.py +++ b/letta/services/agent_manager.py @@ -314,21 +314,24 @@ class AgentManager: if not agent_create.llm_config or not agent_create.embedding_config: raise ValueError("llm_config and embedding_config are required") - if agent_create.reasoning is not None: - agent_create.llm_config = LLMConfig.apply_reasoning_setting_to_config( - agent_create.llm_config, - agent_create.reasoning, - agent_create.agent_type, - ) # For v1 agents, enforce sane defaults even when reasoning is omitted - elif agent_create.agent_type == AgentType.letta_v1_agent: - # Default togglable models (Anthropic 3.7/4) to enabled; others disabled - default_reasoning = LLMConfig.is_anthropic_reasoning_model(agent_create.llm_config) + if agent_create.agent_type == AgentType.letta_v1_agent: + # Claude 3.7/4 or OpenAI o1/o3/o4/gpt-5 + default_reasoning = LLMConfig.is_anthropic_reasoning_model(agent_create.llm_config) or LLMConfig.is_openai_reasoning_model( + agent_create.llm_config + ) agent_create.llm_config = LLMConfig.apply_reasoning_setting_to_config( agent_create.llm_config, - default_reasoning, + agent_create.reasoning if agent_create.reasoning is not None else default_reasoning, agent_create.agent_type, ) + else: + if agent_create.reasoning is not None: + agent_create.llm_config = LLMConfig.apply_reasoning_setting_to_config( + agent_create.llm_config, + agent_create.reasoning, + agent_create.agent_type, + ) # blocks block_ids = list(agent_create.block_ids or [])