| trae-agent | minor |
|---|
AgentTypeenum: New memberOrchestratorAgent = "orchestrator_agent". Consumers that match exhaustively onAgentTypemust add a case.AgentStepStateenum: 5 new values —PLANNING,CODING,REVIEWING,WAITING,RETRYING(10 total). Consumers that match exhaustively must add cases.BaseAgent:- New
allow_mcp_servers: list[str] | Noneattribute (defaultNone). - New
initialise_mcp()async method (no-op base, overridden byTraeAgent). - New abstract method pattern:
cleanup_mcp_clients()already existed;initialise_mcp()added alongside it for symmetry.
- New
-
OrchestratorAgent(trae_agent/agent/orchestrator_agent.py):- 3-phase execution flow:
PLANNING → CODING → REVIEWING - Each phase runs an isolated ReAct loop with:
- Fresh message context (no cross-phase message bleed)
- Per-phase system prompt (
PLANNER_SYSTEM_PROMPT,CODER_SYSTEM_PROMPT,REVIEWER_SYSTEM_PROMPT) - Per-phase tool permission isolation via
PHASE_TOOL_NAMESdict - Structured text handoff between phases (no raw message sharing)
- Phase completion signals:
- PLANNING: "plan completed" in LLM response content
- CODING:
task_donetool call detected - REVIEWING:
**Pass**,**Fail**, or## Review Verdictin content
MAX_STEPS_PER_PHASE = 30inner-loop bound- Error handling: LLM exceptions caught per-phase, returned as error string (execution continues to remaining phases)
- 3-phase execution flow:
-
Agentfacade (trae_agent/agent/agent.py):- Routes
AgentType.OrchestratorAgenttoOrchestratorAgentvia match/case self.agenttype widened fromTraeAgenttoBaseAgent
- Routes
-
Context compression (
BaseAgent._compress_messages):- Deterministic summarization triggered at
step_number % 10 == 0ANDlen(messages) > 30 - Preserves: system prompt + last 15 messages verbatim
- Compresses middle section: extracts tool result outcomes (success/failure) and assistant "plan"/"approach" content
- Injects
Context Summarymessage at position 1
- Deterministic summarization triggered at
-
LLM client history reset (
BaseAgent._reset_llm_client_history):- Resets
self._llm_client.client.message_history = []after compression - Wrapped in
contextlib.suppress(AttributeError)for client variants withoutmessage_history
- Resets
TraeAgent.reflect_on_result: Replaced barereturn Nonewith error-specific reflection guidance strings (timeout, not found, permission denied, default)BaseAgent._tool_call_handler: Fixed handling ofNoneand emptytool_calls:None(no tool_call field): if substantive content (>20 chars), treat as thinking; else nudge LLM- Empty list: if content exists, pass through; else push "not completed" message
BaseAgent._run_llm_step: Fixedtool_calls = getattr(llm_response, 'tool_calls', [])— was returningNonefrom Anthropic responses, now correctly defaults to empty list
PHASE_TOOL_NAMESper phase:- PLANNING:
str_replace_based_edit_tool,sequentialthinking(read-only, no bash) - CODING: All
TraeAgentToolNames(full tool access includingbash,task_done) - REVIEWING:
str_replace_based_edit_tool,bash,sequentialthinking(notask_done)
- PLANNING:
tests/agent/test_agent_basics.py— 8 tests forAgentStepStatenew valuestests/agent/test_context_compression.py— 11 tests covering threshold, preservation, failure summaries, client history resettests/agent/test_orchestrator_agent.py— 23 tests covering phase constants, completion detection, tool isolation, context handoff, full 3-phase execution, error handling, AgentType registrationtests/agent/test_trae_agent.py— 7 existing tests (no regressions)