feat(core/agent): 添加 Step 和 LoopResult 数据类

保真 TRM4 算法 #11,Step 新增 call_id 字段。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-06 22:32:59 -04:00
parent 6b7c28ea1e
commit 9340c5e0f8
2 changed files with 81 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
"""AgentLoop 数据类型。"""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any
@dataclass
class Step:
"""Agent 单步决策记录。"""
thought: str
reflect: dict[str, Any]
plan: dict[str, Any]
tool_call: dict[str, Any]
tool_output: str
raw_content: str
call_id: str
@dataclass
class LoopResult:
"""AgentLoop 完整运行结果。"""
result: dict[str, Any] | None = None
steps: list[Step] = field(default_factory=list)
steps_used: int = 0
token_usage: dict[str, int] = field(
default_factory=lambda: {"prompt_tokens": 0, "completion_tokens": 0}
)
stop_reason: str = "finished"
+50
View File
@@ -0,0 +1,50 @@
"""core/agent/types.py 单元测试。"""
from __future__ import annotations
from core.agent.types import LoopResult, Step
class TestStep:
def test_creation(self) -> None:
step = Step(
thought="thinking...",
reflect={"key": "value"},
plan={"next": "do something"},
tool_call={"tool": "search", "args": {"query": "test"}},
tool_output="result text",
raw_content='{"reflect": {}, "plan": {}, "action": {}}',
call_id="uuid-1",
)
assert step.thought == "thinking..."
assert step.tool_call["tool"] == "search"
assert step.call_id == "uuid-1"
class TestLoopResult:
def test_defaults(self) -> None:
lr = LoopResult()
assert lr.result is None
assert lr.steps == []
assert lr.steps_used == 0
assert lr.token_usage == {"prompt_tokens": 0, "completion_tokens": 0}
assert lr.stop_reason == "finished"
def test_with_steps(self) -> None:
step = Step(
thought="t", reflect={}, plan={},
tool_call={"tool": "t", "args": {}},
tool_output="o", raw_content="r", call_id="c",
)
lr = LoopResult(
result={"answer": "42"}, steps=[step], steps_used=1,
token_usage={"prompt_tokens": 100, "completion_tokens": 50},
stop_reason="finished",
)
assert lr.result == {"answer": "42"}
assert len(lr.steps) == 1
def test_separate_instances_have_independent_lists(self) -> None:
lr1 = LoopResult()
lr2 = LoopResult()
lr1.steps.append(Step("t", {}, {}, {"tool": "x", "args": {}}, "o", "r", "c"))
assert len(lr2.steps) == 0