docs(runtime): tighten queue goal gate
This commit is contained in:
1 parent
2a3c4abc60
commit
9f1ff51950
3 files changed
+29
-6
No files matched your search
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
### Documentation
|
||||
|
||||
- **PR #TBD** by @Michaelyklam (refs #1925) — Advance the runtime-adapter RFC after the Slice 3b approval/clarify seam shipped in v0.51.89. The RFC now marks Slice 3b as shipped and defines the next Slice 3c queue/continue + goal control gate: route those controls through `RuntimeAdapter.queue_input(...)` / `update_goal(...)` only after pinning stable response contracts, bounded unavailable-control behavior, replayable lifecycle/status evidence, ordering/idempotency expectations, and explicit non-goals for runner/sidecar ownership or a WebUI-owned queue/goal scheduler.
|
||||
- **PR #TBD** by @Michaelyklam (refs #1925) — Advance the runtime-adapter RFC after the Slice 3b approval/clarify seam shipped in v0.51.89. The RFC now marks Slice 3b as shipped and defines the next Slice 3c queue/continue + goal control gate: route those controls through `RuntimeAdapter.queue_message(...)` / `update_goal(...)` only after pinning stable response contracts, bounded unavailable-control behavior, replayable lifecycle/status evidence, ordering/idempotency expectations, and explicit non-goals for runner/sidecar ownership or a WebUI-owned queue/goal scheduler.
|
||||
|
||||
## [v0.51.89] — 2026-05-18 — Release BM (stage-382 — 6-PR full sweep batch — runtime adapter approval/clarify seam + SOUL.md memory panel + #1855 resolve_model_provider fast-path + PWA sidebar spinner fix + /model active-provider preference + contributor contract docs index)
|
||||
|
||||
|
||||
@@ -342,10 +342,20 @@ class RuntimeAdapter:
|
||||
def cancel_run(self, run_id: str) -> ControlResult: ...
|
||||
def respond_approval(self, run_id: str, approval_id: str, choice: str) -> ControlResult: ...
|
||||
def respond_clarify(self, run_id: str, clarify_id: str, response: str) -> ControlResult: ...
|
||||
def queue_input(self, run_id: str, message: str, *, mode: str = "queue") -> ControlResult: ...
|
||||
def update_goal(self, session_id: str, action: str, text: str | None = None) -> ControlResult: ...
|
||||
def queue_message(self, run_id: str, message: str, *, mode: str = "queue") -> ControlResult: ...
|
||||
def update_goal(
|
||||
self,
|
||||
session_id: str,
|
||||
action: Literal["set", "pause", "resume", "clear", "status", "edit"],
|
||||
text: str | None = None,
|
||||
) -> ControlResult: ...
|
||||
```
|
||||
|
||||
`queue_message` is named for the legacy `/api/session/queue` payload: it
|
||||
accepts follow-up chat text rather than arbitrary runtime input. The method name
|
||||
does not require the HTTP route to change; it documents the adapter-level control
|
||||
semantics that a later Slice 3c implementation should preserve.
|
||||
|
||||
Required data classes / payload fields:
|
||||
|
||||
| Type | Required fields | Notes |
|
||||
@@ -394,7 +404,7 @@ way the new entry point is selected.
|
||||
| `cancel_run` | delegate to existing cancel handler/control path | do not redesign cancellation semantics yet |
|
||||
| `respond_approval` | delegate to existing approval response path | do not persist approval callbacks in the main server as a new adapter-owned queue |
|
||||
| `respond_clarify` | delegate to existing clarify response path | do not persist clarify callbacks in the main server as a new adapter-owned queue |
|
||||
| `queue_input` | delegate to existing queue/continue path when that slice is accepted | do not invent a parallel continuation buffer or run scheduler |
|
||||
| `queue_message` | delegate to existing queue/continue path when that slice is accepted | do not invent a parallel continuation buffer or run scheduler |
|
||||
| `update_goal` | delegate to existing goal command/control path when that slice is accepted | do not move goal evaluation or continuation ownership into the adapter |
|
||||
|
||||
Any implementation that needs a new long-lived queue, agent cache, cancellation
|
||||
@@ -572,12 +582,17 @@ or resumable work; goal controls set, pause, resume, clear, or inspect a
|
||||
standing cross-turn objective. Both can accidentally create a second continuation
|
||||
model if WebUI buffers or evaluates them independently.
|
||||
|
||||
During Slice 3c, `RuntimeAdapter.queue_input(...)` and
|
||||
During Slice 3c, `RuntimeAdapter.queue_message(...)` and
|
||||
`RuntimeAdapter.update_goal(...)` should remain protocol translators over the
|
||||
existing legacy queue/goal paths. They must not create a WebUI-owned run queue,
|
||||
goal evaluator, continuation scheduler, agent loop, or sidecar substitute inside
|
||||
the main WebUI process.
|
||||
|
||||
`RuntimeAdapter.update_goal(...)` controls goal state mutations only. Post-turn
|
||||
goal evaluation and the decision to continue remain in the existing agent
|
||||
conversation loop until the later runner/sidecar slice moves execution
|
||||
ownership; Slice 3c must not move that evaluator into WebUI or the adapter.
|
||||
|
||||
Acceptance properties:
|
||||
|
||||
1. **Same visible result as legacy queue/continue and goal.** Existing `/queue`
|
||||
@@ -613,7 +628,7 @@ Suggested regression coverage:
|
||||
|
||||
- route/source tests proving flagged queue/continue and goal paths call the
|
||||
adapter seam while the default path remains the existing legacy handler;
|
||||
- adapter unit tests proving `queue_input` and `update_goal` delegate exactly
|
||||
- adapter unit tests proving `queue_message` and `update_goal` delegate exactly
|
||||
once, return accepted/not-active/unsupported/conflict `ControlResult` values,
|
||||
and do not expose unsafe internal strings to browser responses;
|
||||
- ordering/idempotency tests for repeated queue/continue and repeated goal
|
||||
|
||||
@@ -24,6 +24,14 @@ def test_runtime_adapter_interface_and_legacy_journal_methods_exist():
|
||||
assert runtime.runtime_adapter_mode({"HERMES_WEBUI_RUNTIME_ADAPTER": "sidecar"}) == "legacy-direct"
|
||||
|
||||
|
||||
def test_queue_goal_adapter_methods_remain_docs_only_until_slice3c_implementation():
|
||||
runtime = importlib.import_module("api.runtime_adapter")
|
||||
|
||||
for name in ("queue_message", "queue_input", "update_goal"):
|
||||
assert not hasattr(runtime.RuntimeAdapter, name)
|
||||
assert not hasattr(runtime.LegacyJournalRuntimeAdapter, name)
|
||||
|
||||
|
||||
def test_legacy_journal_adapter_start_run_delegates_without_owning_runtime_state():
|
||||
runtime = importlib.import_module("api.runtime_adapter")
|
||||
calls = []
|
||||
|
||||
Reference in new issue
Block a user