tenseleyflow/loader / d67b8f9

Browse files

Cover runtime bootstrap source contract

Authored by espadonne
SHA
d67b8f99f005b49de6752069d8a61f84284f2dc0
Parents
3c26874
Tree
ebfca5e

6 changed files

StatusFile+-
M tests/test_response_route_handlers.py 1 1
M tests/test_response_routing.py 1 1
M tests/test_runtime_bootstrap.py 21 7
M tests/test_runtime_context.py 5 3
M tests/test_runtime_launcher.py 4 1
M tests/test_turn_iteration.py 1 1
tests/test_response_route_handlers.pymodified
@@ -51,7 +51,7 @@ async def _prepare_context(
51
         task=prepared.task,
51
         task=prepared.task,
52
         effective_task=prepared.effective_task,
52
         effective_task=prepared.effective_task,
53
         iterations=1,
53
         iterations=1,
54
-        max_iterations=runtime.agent.config.max_iterations,
54
+        max_iterations=runtime.context.config.max_iterations,
55
         actions_taken=[],
55
         actions_taken=[],
56
         continuation_count=continuation_count,
56
         continuation_count=continuation_count,
57
         consecutive_errors=consecutive_errors,
57
         consecutive_errors=consecutive_errors,
tests/test_response_routing.pymodified
@@ -53,7 +53,7 @@ async def _prepare_context(
53
         task=prepared.task,
53
         task=prepared.task,
54
         effective_task=prepared.effective_task,
54
         effective_task=prepared.effective_task,
55
         iterations=1,
55
         iterations=1,
56
-        max_iterations=runtime.agent.config.max_iterations,
56
+        max_iterations=runtime.context.config.max_iterations,
57
         actions_taken=[],
57
         actions_taken=[],
58
         continuation_count=continuation_count,
58
         continuation_count=continuation_count,
59
         consecutive_errors=consecutive_errors,
59
         consecutive_errors=consecutive_errors,
tests/test_runtime_bootstrap.pymodified
@@ -5,7 +5,12 @@ from __future__ import annotations
5
 from pathlib import Path
5
 from pathlib import Path
6
 
6
 
7
 from loader.agent.loop import Agent, AgentConfig
7
 from loader.agent.loop import Agent, AgentConfig
8
-from loader.runtime.bootstrap import build_runtime_context, sync_runtime_context
8
+from loader.runtime.bootstrap import (
9
+    RuntimeBootstrapView,
10
+    build_runtime_bootstrap_source,
11
+    build_runtime_context,
12
+    sync_runtime_context,
13
+)
9
 from loader.runtime.conversation import ConversationRuntime
14
 from loader.runtime.conversation import ConversationRuntime
10
 from loader.runtime.explore import ExploreRuntime
15
 from loader.runtime.explore import ExploreRuntime
11
 from loader.runtime.launcher import RuntimeLauncher, build_runtime_launcher
16
 from loader.runtime.launcher import RuntimeLauncher, build_runtime_launcher
@@ -21,8 +26,9 @@ def test_build_runtime_context_uses_shared_bootstrap_contract(
21
         config=AgentConfig(auto_context=False),
26
         config=AgentConfig(auto_context=False),
22
         project_root=temp_dir,
27
         project_root=temp_dir,
23
     )
28
     )
29
+    source = build_runtime_bootstrap_source(agent)
24
 
30
 
25
-    context = build_runtime_context(agent)
31
+    context = build_runtime_context(source)
26
 
32
 
27
     assert context.project_root == temp_dir.resolve()
33
     assert context.project_root == temp_dir.resolve()
28
     assert context.backend is agent.backend
34
     assert context.backend is agent.backend
@@ -35,6 +41,7 @@ def test_build_runtime_context_uses_shared_bootstrap_contract(
35
     assert context.workflow_mode == agent.workflow_mode
41
     assert context.workflow_mode == agent.workflow_mode
36
     assert context.prompt_format == agent.prompt_format
42
     assert context.prompt_format == agent.prompt_format
37
     assert context.prompt_sections == agent.prompt_sections
43
     assert context.prompt_sections == agent.prompt_sections
44
+    assert source.metadata == {"owner_type": "Agent"}
38
 
45
 
39
 
46
 
40
 def test_sync_runtime_context_refreshes_prompt_and_capability_state(
47
 def test_sync_runtime_context_refreshes_prompt_and_capability_state(
@@ -46,7 +53,8 @@ def test_sync_runtime_context_refreshes_prompt_and_capability_state(
46
         config=AgentConfig(auto_context=False),
53
         config=AgentConfig(auto_context=False),
47
         project_root=temp_dir,
54
         project_root=temp_dir,
48
     )
55
     )
49
-    context = build_runtime_context(agent)
56
+    source = build_runtime_bootstrap_source(agent)
57
+    context = build_runtime_context(source)
50
 
58
 
51
     agent.prompt_format = "native"
59
     agent.prompt_format = "native"
52
     agent.prompt_sections = ["Workflow Context", "Runtime Config"]
60
     agent.prompt_sections = ["Workflow Context", "Runtime Config"]
@@ -54,7 +62,7 @@ def test_sync_runtime_context_refreshes_prompt_and_capability_state(
54
     backend._supports_native_tools = False  # type: ignore[attr-defined]
62
     backend._supports_native_tools = False  # type: ignore[attr-defined]
55
     agent.refresh_capability_profile()
63
     agent.refresh_capability_profile()
56
 
64
 
57
-    sync_runtime_context(context, agent)
65
+    sync_runtime_context(context, source)
58
 
66
 
59
     assert context.workflow_mode == "clarify"
67
     assert context.workflow_mode == "clarify"
60
     assert context.prompt_format == "native"
68
     assert context.prompt_format == "native"
@@ -83,10 +91,12 @@ def test_conversation_runtime_uses_shared_bootstrap_factory(
83
         fake_build_runtime_context,
91
         fake_build_runtime_context,
84
     )
92
     )
85
 
93
 
86
-    runtime = ConversationRuntime(agent)
94
+    source = build_runtime_bootstrap_source(agent)
95
+    runtime = ConversationRuntime(source)
87
 
96
 
88
     assert calls == ["conversation"]
97
     assert calls == ["conversation"]
89
     assert runtime.context.project_root == temp_dir.resolve()
98
     assert runtime.context.project_root == temp_dir.resolve()
99
+    assert runtime.source is source
90
 
100
 
91
 
101
 
92
 def test_explore_runtime_uses_shared_bootstrap_factory(
102
 def test_explore_runtime_uses_shared_bootstrap_factory(
@@ -110,10 +120,12 @@ def test_explore_runtime_uses_shared_bootstrap_factory(
110
         fake_build_runtime_context,
120
         fake_build_runtime_context,
111
     )
121
     )
112
 
122
 
113
-    runtime = ExploreRuntime(agent)
123
+    source = build_runtime_bootstrap_source(agent)
124
+    runtime = ExploreRuntime(source)
114
 
125
 
115
     assert calls == ["explore"]
126
     assert calls == ["explore"]
116
     assert runtime.context.project_root == temp_dir.resolve()
127
     assert runtime.context.project_root == temp_dir.resolve()
128
+    assert runtime.source is source
117
 
129
 
118
 
130
 
119
 def test_build_runtime_launcher_wraps_shared_bootstrap_source(
131
 def test_build_runtime_launcher_wraps_shared_bootstrap_source(
@@ -128,4 +140,6 @@ def test_build_runtime_launcher_wraps_shared_bootstrap_source(
128
     launcher = build_runtime_launcher(agent)
140
     launcher = build_runtime_launcher(agent)
129
 
141
 
130
     assert isinstance(launcher, RuntimeLauncher)
142
     assert isinstance(launcher, RuntimeLauncher)
131
-    assert launcher.source is agent
143
+    assert isinstance(launcher.source, RuntimeBootstrapView)
144
+    assert launcher.source is not agent
145
+    assert launcher.source.metadata == {"owner_type": "Agent"}
tests/test_runtime_context.pymodified
@@ -5,7 +5,7 @@ from __future__ import annotations
5
 from pathlib import Path
5
 from pathlib import Path
6
 
6
 
7
 from loader.agent.loop import Agent, AgentConfig
7
 from loader.agent.loop import Agent, AgentConfig
8
-from loader.runtime.bootstrap import build_runtime_context
8
+from loader.runtime.bootstrap import build_runtime_bootstrap_source, build_runtime_context
9
 from loader.runtime.context import RuntimeContext
9
 from loader.runtime.context import RuntimeContext
10
 from loader.runtime.recovery import RecoveryContext
10
 from loader.runtime.recovery import RecoveryContext
11
 from tests.helpers.runtime_harness import ScriptedBackend
11
 from tests.helpers.runtime_harness import ScriptedBackend
@@ -18,8 +18,9 @@ def test_agent_builds_typed_runtime_context(temp_dir: Path) -> None:
18
         config=AgentConfig(auto_context=False),
18
         config=AgentConfig(auto_context=False),
19
         project_root=temp_dir,
19
         project_root=temp_dir,
20
     )
20
     )
21
+    source = build_runtime_bootstrap_source(agent)
21
 
22
 
22
-    context = build_runtime_context(agent)
23
+    context = build_runtime_context(source)
23
 
24
 
24
     assert isinstance(context, RuntimeContext)
25
     assert isinstance(context, RuntimeContext)
25
     assert context.project_root == temp_dir.resolve()
26
     assert context.project_root == temp_dir.resolve()
@@ -47,8 +48,9 @@ def test_runtime_context_control_callbacks_stay_in_sync(temp_dir: Path) -> None:
47
         config=AgentConfig(auto_context=False),
48
         config=AgentConfig(auto_context=False),
48
         project_root=temp_dir,
49
         project_root=temp_dir,
49
     )
50
     )
51
+    source = build_runtime_bootstrap_source(agent)
50
 
52
 
51
-    context = build_runtime_context(agent)
53
+    context = build_runtime_context(source)
52
     context.queue_steering_message("Re-check the current task.")
54
     context.queue_steering_message("Re-check the current task.")
53
 
55
 
54
     assert context.drain_steering_messages() == ["Re-check the current task."]
56
     assert context.drain_steering_messages() == ["Re-check the current task."]
tests/test_runtime_launcher.pymodified
@@ -8,6 +8,7 @@ import pytest
8
 
8
 
9
 from loader.agent.loop import Agent, AgentConfig, ReasoningConfig
9
 from loader.agent.loop import Agent, AgentConfig, ReasoningConfig
10
 from loader.llm.base import CompletionResponse, StreamChunk
10
 from loader.llm.base import CompletionResponse, StreamChunk
11
+from loader.runtime.bootstrap import RuntimeBootstrapView
11
 from loader.runtime.launcher import RuntimeLauncher, build_runtime_launcher
12
 from loader.runtime.launcher import RuntimeLauncher, build_runtime_launcher
12
 from tests.helpers.runtime_harness import ScriptedBackend
13
 from tests.helpers.runtime_harness import ScriptedBackend
13
 
14
 
@@ -24,7 +25,9 @@ def test_build_runtime_launcher_returns_launcher_for_agent_source(
24
     launcher = build_runtime_launcher(agent)
25
     launcher = build_runtime_launcher(agent)
25
 
26
 
26
     assert isinstance(launcher, RuntimeLauncher)
27
     assert isinstance(launcher, RuntimeLauncher)
27
-    assert launcher.source is agent
28
+    assert isinstance(launcher.source, RuntimeBootstrapView)
29
+    assert launcher.source is not agent
30
+    assert launcher.source.metadata == {"owner_type": "Agent"}
28
 
31
 
29
 
32
 
30
 @pytest.mark.asyncio
33
 @pytest.mark.asyncio
tests/test_turn_iteration.pymodified
@@ -44,7 +44,7 @@ async def _run_iteration(
44
         original_task=original_task,
44
         original_task=original_task,
45
         effective_max_tokens=prepared.effective_max_tokens,
45
         effective_max_tokens=prepared.effective_max_tokens,
46
         iterations=1,
46
         iterations=1,
47
-        max_iterations=runtime.agent.config.max_iterations,
47
+        max_iterations=runtime.context.config.max_iterations,
48
         actions_taken=[],
48
         actions_taken=[],
49
         continuation_count=0,
49
         continuation_count=0,
50
         empty_retry_count=0,
50
         empty_retry_count=0,