tenseleyflow/loader / c1b81ca

Browse files

Add runtime launcher entrypoint seam

Authored by espadonne
SHA
c1b81cafedea705c7242d1cc5949451d25e21e2b
Parents
99f36b3
Tree
21997cc

2 changed files

StatusFile+-
M src/loader/agent/loop.py 5 6
A src/loader/runtime/launcher.py 53 0
src/loader/agent/loop.pymodified
@@ -9,7 +9,6 @@ from pathlib import Path
99
 from ..context.project import ProjectContext, detect_project
1010
 from ..llm.base import LLMBackend, Message, Role
1111
 from ..runtime.capabilities import resolve_backend_capability_profile
12
-from ..runtime.conversation import ConversationRuntime
1312
 from ..runtime.deliberation import (
1413
     DECOMPOSITION_PROMPT,
1514
     parse_decomposition,
@@ -17,7 +16,7 @@ from ..runtime.deliberation import (
1716
 )
1817
 from ..runtime.dod import DefinitionOfDoneStore
1918
 from ..runtime.events import AgentEvent, TurnSummary
20
-from ..runtime.explore import ExploreRuntime
19
+from ..runtime.launcher import build_runtime_launcher
2120
 from ..runtime.permissions import (
2221
     PermissionMode,
2322
     build_permission_policy,
@@ -577,8 +576,8 @@ class Agent:
577576
     ) -> str:
578577
         """Inner execution loop without planning."""
579578
 
580
-        runtime = ConversationRuntime(self)
581
-        self.last_turn_summary = await runtime.run_turn(
579
+        launcher = build_runtime_launcher(self)
580
+        self.last_turn_summary = await launcher.run_turn(
582581
             task,
583582
             emit,
584583
             on_confirmation=on_confirmation,
@@ -651,8 +650,8 @@ class Agent:
651650
                 if inspect.iscoroutine(result):
652651
                     await result
653652
 
654
-        runtime = ExploreRuntime(self)
655
-        self.last_turn_summary = await runtime.run_query(user_message, emit)
653
+        launcher = build_runtime_launcher(self)
654
+        self.last_turn_summary = await launcher.run_explore(user_message, emit)
656655
         return self.last_turn_summary.final_response
657656
 
658657
     def clear_history(self) -> None:
src/loader/runtime/launcher.pyadded
@@ -0,0 +1,53 @@
1
+"""Public runtime launcher helpers for conversation and explore entrypoints."""
2
+
3
+from __future__ import annotations
4
+
5
+from .bootstrap import RuntimeBootstrapSource
6
+from .conversation import ConfirmationHandler, ConversationRuntime, EventSink, UserQuestionHandler
7
+from .events import TurnSummary
8
+from .explore import ExploreRuntime
9
+
10
+
11
+class RuntimeLauncher:
12
+    """Thin launcher over the shared runtime bootstrap contract."""
13
+
14
+    def __init__(self, source: RuntimeBootstrapSource) -> None:
15
+        self.source = source
16
+
17
+    async def run_turn(
18
+        self,
19
+        task: str,
20
+        emit: EventSink,
21
+        *,
22
+        on_confirmation: ConfirmationHandler = None,
23
+        on_user_question: UserQuestionHandler = None,
24
+        requested_mode: str | None = None,
25
+        original_task: str | None = None,
26
+    ) -> TurnSummary:
27
+        """Run one conversation turn through the shared launcher seam."""
28
+
29
+        runtime = ConversationRuntime(self.source)
30
+        return await runtime.run_turn(
31
+            task,
32
+            emit,
33
+            on_confirmation=on_confirmation,
34
+            on_user_question=on_user_question,
35
+            requested_mode=requested_mode,
36
+            original_task=original_task,
37
+        )
38
+
39
+    async def run_explore(
40
+        self,
41
+        prompt: str,
42
+        emit: EventSink,
43
+    ) -> TurnSummary:
44
+        """Run one read-only explore query through the shared launcher seam."""
45
+
46
+        runtime = ExploreRuntime(self.source)
47
+        return await runtime.run_query(prompt, emit)
48
+
49
+
50
+def build_runtime_launcher(source: RuntimeBootstrapSource) -> RuntimeLauncher:
51
+    """Build a public runtime launcher from the shared bootstrap source."""
52
+
53
+    return RuntimeLauncher(source)