feat: add reasoning toggle in agents routes (#3705)

This commit is contained in:
cthomas
2025-08-06 11:47:06 -07:00
committed by GitHub
parent bd56635ba9
commit 4e52969b57
3 changed files with 37 additions and 0 deletions

View File

@@ -212,6 +212,7 @@ class CreateAgent(BaseModel, validate_assignment=True): #
None, description="The maximum number of tokens to generate for reasoning step. If not set, the model will use its default value."
)
enable_reasoner: Optional[bool] = Field(False, description="Whether to enable internal extended thinking step for a reasoner model.")
reasoning: Optional[bool] = Field(None, description="Whether to enable reasoning for this agent.")
from_template: Optional[str] = Field(None, description="The template id used to configure the agent")
template: bool = Field(False, description="Whether the agent is a template")
project: Optional[str] = Field(
@@ -335,6 +336,7 @@ class UpdateAgent(BaseModel):
embedding: Optional[str] = Field(
None, description="The embedding configuration handle used by the agent, specified in the format provider/model-name."
)
reasoning: Optional[bool] = Field(None, description="Whether to enable reasoning for this agent.")
enable_sleeptime: Optional[bool] = Field(None, description="If set to True, memory management will move to a background agent thread.")
response_format: Optional[ResponseFormatUnion] = Field(None, description="The response format for the agent.")
last_run_completion: Optional[datetime] = Field(None, description="The timestamp when the agent last completed a run.")

View File

@@ -183,3 +183,30 @@ class LLMConfig(BaseModel):
+ (f" [type={self.model_endpoint_type}]" if self.model_endpoint_type else "")
+ (f" [ip={self.model_endpoint}]" if self.model_endpoint else "")
)
@classmethod
def apply_reasoning_setting_to_config(cls, config: "LLMConfig", reasoning: bool):
if reasoning:
if (
config.model_endpoint_type == "anthropic"
and ("claude-opus-4" in config.model or "claude-sonnet-4" in config.model or "claude-3-7-sonnet" in config.model)
) or (
config.model_endpoint_type == "google_vertex" and ("gemini-2.5-flash" in config.model or "gemini-2.0-pro" in config.model)
):
config.put_inner_thoughts_in_kwargs = False
config.enable_reasoner = True
if config.max_reasoning_tokens == 0:
config.max_reasoning_tokens = 1024
elif config.model_endpoint_type == "openai" and (
config.model.startswith("o1") or config.model.startswith("o3") or config.model.startswith("o4")
):
config.put_inner_thoughts_in_kwargs = True
config.enable_reasoner = True
if config.reasoning_effort is None:
config.reasoning_effort = "medium"
else:
config.put_inner_thoughts_in_kwargs = True
config.enable_reasoner = False
else:
config.put_inner_thoughts_in_kwargs = False
config.enable_reasoner = False

View File

@@ -51,6 +51,7 @@ from letta.schemas.enums import ProviderType, ToolType
from letta.schemas.file import FileMetadata as PydanticFileMetadata
from letta.schemas.group import Group as PydanticGroup
from letta.schemas.group import ManagerType
from letta.schemas.llm_config import LLMConfig
from letta.schemas.memory import ContextWindowOverview, Memory
from letta.schemas.message import Message
from letta.schemas.message import Message as PydanticMessage
@@ -452,6 +453,9 @@ 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)
# blocks
block_ids = list(agent_create.block_ids or [])
if agent_create.memory_blocks:
@@ -877,6 +881,10 @@ class AgentManager:
agent.updated_at = datetime.now(timezone.utc)
agent.last_updated_by_id = actor.id
if agent_update.reasoning is not None:
llm_config = agent_update.llm_config or agent.llm_config
agent_update.llm_config = LLMConfig.apply_reasoning_setting_to_config(llm_config, agent_update.reasoning)
scalar_updates = {
"name": agent_update.name,
"system": agent_update.system,