Python · 2883 bytes Raw Blame History
1 """Tests for typed runtime context construction."""
2
3 from __future__ import annotations
4
5 from pathlib import Path
6
7 from loader.agent.loop import Agent, AgentConfig
8 from loader.runtime.bootstrap import build_runtime_bootstrap_source, build_runtime_context
9 from loader.runtime.context import RuntimeContext
10 from loader.runtime.recovery import RecoveryContext
11 from loader.runtime.steering import SteeringDirective
12 from tests.helpers.runtime_harness import ScriptedBackend
13
14
15 def test_agent_builds_typed_runtime_context(temp_dir: Path) -> None:
16 backend = ScriptedBackend()
17 agent = Agent(
18 backend=backend,
19 config=AgentConfig(auto_context=False),
20 project_root=temp_dir,
21 )
22 source = build_runtime_bootstrap_source(agent)
23
24 context = build_runtime_context(source)
25
26 assert isinstance(context, RuntimeContext)
27 assert context.project_root == temp_dir.resolve()
28 assert context.backend is backend
29 assert context.registry is agent.registry
30 assert context.session is agent.session
31 assert context.config is agent.config
32 assert context.capability_profile == agent.capability_profile
33 assert context.project_context is None
34 assert context.permission_policy is agent.permission_policy
35 assert context.permission_config_status is agent.permission_config_status
36 assert context.workflow_mode == agent.workflow_mode
37 assert context.safeguards is agent.safeguards
38 assert context.messages is agent.session.messages
39 assert context.use_react == agent.use_react
40 assert context.active_permission_mode == agent.active_permission_mode
41 assert context.active_permission_rule_counts == agent.active_permission_rule_counts
42 assert context.reasoning is not None
43 assert context.messages is agent.session.messages
44
45
46 def test_runtime_context_control_callbacks_stay_in_sync(temp_dir: Path) -> None:
47 agent = Agent(
48 backend=ScriptedBackend(),
49 config=AgentConfig(auto_context=False),
50 project_root=temp_dir,
51 )
52 source = build_runtime_bootstrap_source(agent)
53
54 context = build_runtime_context(source)
55 context.queue_steering_message("Re-check the current task.")
56
57 assert context.drain_steering_messages() == [
58 SteeringDirective(content="Re-check the current task.")
59 ]
60
61 context.set_workflow_mode("clarify")
62 assert agent.workflow_mode == "clarify"
63 assert context.workflow_mode == "clarify"
64
65 recovery = RecoveryContext(original_tool="read", original_args={"file_path": "README.md"})
66 context.recovery_context = recovery
67 assert context.recovery_context is recovery
68
69 backend = agent.backend
70 backend._supports_native_tools = False # type: ignore[attr-defined]
71 context.refresh_capability_profile()
72 assert context.capability_profile == agent.capability_profile
73 assert context.capability_profile.supports_native_tools is False