|
|
@@ -0,0 +1,169 @@
|
|
|
+from __future__ import annotations
|
|
|
+
|
|
|
+from dataclasses import asdict
|
|
|
+
|
|
|
+import pytest
|
|
|
+
|
|
|
+from agent.core.runner import AgentRunner, RunConfig
|
|
|
+from agent.orchestration.models import CompletionPolicy, TaskRecord
|
|
|
+from agent.tools.builtin.context import get_current_context
|
|
|
+from agent.tools.builtin.knowledge import KnowledgeConfig
|
|
|
+from agent.trace.goal_models import GoalTree
|
|
|
+from agent.trace.models import Trace
|
|
|
+from agent.trace.store import FileSystemTraceStore
|
|
|
+
|
|
|
+
|
|
|
+def _explicit_config(**overrides):
|
|
|
+ values = {
|
|
|
+ "agent_type": "planner",
|
|
|
+ "completion_policy": CompletionPolicy.EXPLICIT_VALIDATION,
|
|
|
+ "name": "explicit mission",
|
|
|
+ }
|
|
|
+ values.update(overrides)
|
|
|
+ return RunConfig(**values)
|
|
|
+
|
|
|
+
|
|
|
+def test_legacy_task_goal_id_is_ignored_when_loading_ledger_record():
|
|
|
+ record = TaskRecord.from_dict(
|
|
|
+ {
|
|
|
+ "task_id": "task",
|
|
|
+ "goal_id": "obsolete-projection",
|
|
|
+ "parent_task_id": None,
|
|
|
+ "display_path": "0",
|
|
|
+ "specs": [
|
|
|
+ {
|
|
|
+ "version": 1,
|
|
|
+ "objective": "mission",
|
|
|
+ "acceptance_criteria": [
|
|
|
+ {"criterion_id": "done", "description": "complete"}
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+ assert "goal_id" not in record.__dict__
|
|
|
+ assert "goal_id" not in asdict(record)
|
|
|
+
|
|
|
+
|
|
|
+@pytest.mark.asyncio
|
|
|
+async def test_new_traces_persist_only_the_selected_plan_model(tmp_path):
|
|
|
+ store = FileSystemTraceStore(str(tmp_path))
|
|
|
+ runner = AgentRunner(trace_store=store)
|
|
|
+
|
|
|
+ explicit, explicit_tree, _ = await runner._prepare_new_trace(
|
|
|
+ [],
|
|
|
+ _explicit_config(new_trace_id="explicit"),
|
|
|
+ )
|
|
|
+ legacy, legacy_tree, _ = await runner._prepare_new_trace(
|
|
|
+ [],
|
|
|
+ RunConfig(new_trace_id="legacy", name="legacy mission"),
|
|
|
+ )
|
|
|
+
|
|
|
+ assert explicit.agent_role == "planner"
|
|
|
+ assert explicit.parent_goal_id is None
|
|
|
+ assert explicit_tree is None
|
|
|
+ assert await store.get_goal_tree("explicit") is None
|
|
|
+ assert legacy.agent_role == "legacy"
|
|
|
+ assert legacy_tree is not None
|
|
|
+ assert await store.get_goal_tree("legacy") is not None
|
|
|
+
|
|
|
+
|
|
|
+@pytest.mark.asyncio
|
|
|
+async def test_explicit_resume_ignores_historical_goal_file(tmp_path):
|
|
|
+ store = FileSystemTraceStore(str(tmp_path))
|
|
|
+ await store.create_trace(
|
|
|
+ Trace(
|
|
|
+ trace_id="explicit",
|
|
|
+ mode="agent",
|
|
|
+ task="mission",
|
|
|
+ agent_type="planner",
|
|
|
+ agent_role="planner",
|
|
|
+ )
|
|
|
+ )
|
|
|
+ await store.update_goal_tree("explicit", GoalTree(mission="obsolete projection"))
|
|
|
+ runner = AgentRunner(trace_store=store)
|
|
|
+
|
|
|
+ _, loaded_tree, _ = await runner._prepare_existing_trace(
|
|
|
+ _explicit_config(trace_id="explicit")
|
|
|
+ )
|
|
|
+
|
|
|
+ assert loaded_tree is None
|
|
|
+ assert (await store.get_goal_tree("explicit")).mission == "obsolete projection"
|
|
|
+
|
|
|
+
|
|
|
+@pytest.mark.asyncio
|
|
|
+async def test_explicit_current_context_uses_task_ledger_read_model(tmp_path):
|
|
|
+ class Coordinator:
|
|
|
+ async def task_context(self, root_trace_id):
|
|
|
+ assert root_trace_id == "root"
|
|
|
+ return "## Current Task Plan\n\n- 0 [running] deliver result"
|
|
|
+
|
|
|
+ store = FileSystemTraceStore(str(tmp_path))
|
|
|
+ await store.create_trace(
|
|
|
+ Trace(
|
|
|
+ trace_id="planner",
|
|
|
+ mode="agent",
|
|
|
+ agent_role="planner",
|
|
|
+ context={"root_trace_id": "root"},
|
|
|
+ )
|
|
|
+ )
|
|
|
+ runner = AgentRunner(trace_store=store, task_coordinator=Coordinator())
|
|
|
+
|
|
|
+ result = await get_current_context(
|
|
|
+ {
|
|
|
+ "runner": runner,
|
|
|
+ "trace_id": "planner",
|
|
|
+ "root_trace_id": "root",
|
|
|
+ "completion_policy": CompletionPolicy.EXPLICIT_VALIDATION.value,
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+ assert "Current Task Plan" in result.output
|
|
|
+ assert "deliver result" in result.output
|
|
|
+ assert "GoalTree" not in result.output
|
|
|
+ compression_context = await runner._current_execution_context(
|
|
|
+ "planner",
|
|
|
+ None,
|
|
|
+ _explicit_config(),
|
|
|
+ )
|
|
|
+ assert compression_context == "## Current Task Plan\n\n- 0 [running] deliver result"
|
|
|
+
|
|
|
+
|
|
|
+@pytest.mark.asyncio
|
|
|
+async def test_explicit_overflow_skips_goal_level_one(monkeypatch, tmp_path):
|
|
|
+ store = FileSystemTraceStore(str(tmp_path))
|
|
|
+ await store.create_trace(
|
|
|
+ Trace(trace_id="root", mode="agent", agent_role="planner")
|
|
|
+ )
|
|
|
+ runner = AgentRunner(trace_store=store)
|
|
|
+ history = [{"role": "user", "content": "large context " * 20}]
|
|
|
+
|
|
|
+ monkeypatch.setattr(
|
|
|
+ "agent.core.runner.CompressionConfig.get_max_tokens",
|
|
|
+ lambda _self, _model: 1,
|
|
|
+ )
|
|
|
+ monkeypatch.setattr(
|
|
|
+ "agent.core.runner.compress_completed_goals",
|
|
|
+ lambda *_args, **_kwargs: (_ for _ in ()).throw(
|
|
|
+ AssertionError("explicit mode must not run Goal Level 1")
|
|
|
+ ),
|
|
|
+ )
|
|
|
+
|
|
|
+ updated, _, _, needs_level_two = await runner._manage_context_usage(
|
|
|
+ "root",
|
|
|
+ history,
|
|
|
+ GoalTree(mission="must be ignored"),
|
|
|
+ _explicit_config(
|
|
|
+ knowledge=KnowledgeConfig(
|
|
|
+ enable_extraction=False,
|
|
|
+ enable_completion_extraction=False,
|
|
|
+ enable_injection=False,
|
|
|
+ )
|
|
|
+ ),
|
|
|
+ sequence=1,
|
|
|
+ head_seq=0,
|
|
|
+ )
|
|
|
+
|
|
|
+ assert updated == history
|
|
|
+ assert needs_level_two is True
|