Expand description
B5a — the RuntimeActionHost impl over the harness, lived in rpi-cli
(NOT rpi-harness) so rpi-extensions stays a leaf in the crate DAG. The
trait is defined in rpi-extensions (JSON + primitives only); this is the
host side that bridges the 16 [RuntimeActionId] actions to the harness.
10 ops delegate to harness.lane("main") (the AgentLane surface backs
prompt_message/prompt_text/get_active_tools/set_active_tools/
set_model/get_thinking_level/set_thinking_level/compact/
navigate_tree). Run-ops serialize via acquire_run’s active_run guard —
a concurrent plugin invocation surfaces lane_busy as the harness error
string, the right behavior (a plugin can’t re-enter an active run).
6 non-lane ops:
append_entry/set_session_name→harness.session().append_message/set_name.get_system_prompt→AgentHarness::get_system_prompt(B5a accessor).new_session/fork/switch_session→ reusecrate::session’s create/fork/open helpers +harness.set_session.reload→ handled byActionBridge.reload(B5d); the host impl is the “not configured” fallback for bridges without a callback.
§Construction ordering (the load-bearing wrinkle)
Extensions load before the harness is created (extensions provide the
tools the harness is built with), but the plugin stores the
ActionBridge’s user_data pointer during register and that pointer
must remain valid for the whole session. So the host cannot hold the
AgentHarness directly — it holds an Arc<OnceLock<Arc<AgentHarness>>>
that is empty at register time and filled once by
HarnessActionHost::set_harness immediately after AgentHarness::create
succeeds. No plugin can call a runtime action before the harness runs, so
the cell is always set before the first get(). The Arc<dyn RuntimeActionHost> (and thus the ActionBridge pointer) is stable from
construction, satisfying the FFI lifetime requirement.
The impl needs the model catalog for set_model(id) (the lane wants a
Model, not an id) and the cwd for session create/fork/switch. Both are
held by rpi-cli at build time and moved into the host.
Structs§
- Harness
Action Host - The
RuntimeActionHostimpl over anAgentHarness. Built once per session incrate::session::build— constructed empty before extension load (the harness doesn’t exist yet), then filled viaset_harnessonceAgentHarness::createsucceeds. Carried inside the [ActionBridge] asArc<dyn RuntimeActionHost>.