Python · 4801 bytes Raw Blame History
1 """Tests for shared runtime bootstrap and context synchronization."""
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 (
9 RuntimeBootstrapView,
10 build_runtime_bootstrap_source,
11 build_runtime_context,
12 sync_runtime_context,
13 )
14 from loader.runtime.conversation import ConversationRuntime
15 from loader.runtime.explore import ExploreRuntime
16 from loader.runtime.launcher import RuntimeLauncher, build_runtime_launcher
17 from tests.helpers.runtime_harness import ScriptedBackend
18
19
20 def test_build_runtime_context_uses_shared_bootstrap_contract(
21 temp_dir: Path,
22 ) -> None:
23 backend = ScriptedBackend()
24 agent = Agent(
25 backend=backend,
26 config=AgentConfig(auto_context=False),
27 project_root=temp_dir,
28 )
29 source = build_runtime_bootstrap_source(agent)
30
31 context = build_runtime_context(source)
32
33 assert context.project_root == temp_dir.resolve()
34 assert context.backend is agent.backend
35 assert context.registry is agent.registry
36 assert context.session is agent.session
37 assert context.config is agent.config
38 assert context.capability_profile == agent.capability_profile
39 assert context.permission_policy is agent.permission_policy
40 assert context.permission_config_status is agent.permission_config_status
41 assert context.workflow_mode == agent.workflow_mode
42 assert context.prompt_format == agent.prompt_format
43 assert context.prompt_sections == agent.prompt_sections
44 assert source.metadata == {
45 "owner_type": "Agent",
46 "owner_path": "public-agent",
47 }
48
49
50 def test_sync_runtime_context_refreshes_prompt_and_capability_state(
51 temp_dir: Path,
52 ) -> None:
53 backend = ScriptedBackend(supports_native_tools=True)
54 agent = Agent(
55 backend=backend,
56 config=AgentConfig(auto_context=False),
57 project_root=temp_dir,
58 )
59 source = build_runtime_bootstrap_source(agent)
60 context = build_runtime_context(source)
61
62 agent.prompt_format = "native"
63 agent.prompt_sections = ["Workflow Context", "Runtime Config"]
64 agent.set_workflow_mode("clarify")
65 backend._supports_native_tools = False # type: ignore[attr-defined]
66 agent.refresh_capability_profile()
67
68 sync_runtime_context(context, source)
69
70 assert context.workflow_mode == "clarify"
71 assert context.prompt_format == "native"
72 assert context.prompt_sections == ["Workflow Context", "Runtime Config"]
73 assert context.capability_profile.supports_native_tools is False
74
75
76 def test_conversation_runtime_uses_shared_bootstrap_factory(
77 temp_dir: Path,
78 monkeypatch,
79 ) -> None:
80 agent = Agent(
81 backend=ScriptedBackend(),
82 config=AgentConfig(auto_context=False, stream=False),
83 project_root=temp_dir,
84 )
85 calls: list[str] = []
86 real_build_runtime_context = build_runtime_context
87
88 def fake_build_runtime_context(source) -> object:
89 calls.append("conversation")
90 return real_build_runtime_context(source)
91
92 monkeypatch.setattr(
93 "loader.runtime.conversation.build_runtime_context",
94 fake_build_runtime_context,
95 )
96
97 source = build_runtime_bootstrap_source(agent)
98 runtime = ConversationRuntime(source)
99
100 assert calls == ["conversation"]
101 assert runtime.context.project_root == temp_dir.resolve()
102 assert runtime.source is source
103
104
105 def test_explore_runtime_uses_shared_bootstrap_factory(
106 temp_dir: Path,
107 monkeypatch,
108 ) -> None:
109 agent = Agent(
110 backend=ScriptedBackend(),
111 config=AgentConfig(auto_context=False, stream=False),
112 project_root=temp_dir,
113 )
114 calls: list[str] = []
115 real_build_runtime_context = build_runtime_context
116
117 def fake_build_runtime_context(source) -> object:
118 calls.append("explore")
119 return real_build_runtime_context(source)
120
121 monkeypatch.setattr(
122 "loader.runtime.explore.build_runtime_context",
123 fake_build_runtime_context,
124 )
125
126 source = build_runtime_bootstrap_source(agent)
127 runtime = ExploreRuntime(source)
128
129 assert calls == ["explore"]
130 assert runtime.context.project_root == temp_dir.resolve()
131 assert runtime.source is source
132
133
134 def test_build_runtime_launcher_wraps_shared_bootstrap_source(
135 temp_dir: Path,
136 ) -> None:
137 agent = Agent(
138 backend=ScriptedBackend(),
139 config=AgentConfig(auto_context=False, stream=False),
140 project_root=temp_dir,
141 )
142
143 launcher = build_runtime_launcher(agent)
144
145 assert isinstance(launcher, RuntimeLauncher)
146 assert isinstance(launcher.source, RuntimeBootstrapView)
147 assert launcher.source is not agent
148 assert launcher.source.metadata == {
149 "owner_type": "Agent",
150 "owner_path": "public-agent",
151 }