pub struct HarnessActionHost { /* private fields */ }Expand description
The RuntimeActionHost impl over an AgentHarness. Built once per session
in crate::session::build — constructed empty before extension load
(the harness doesn’t exist yet), then filled via set_harness
once AgentHarness::create succeeds. Carried inside the [ActionBridge] as
Arc<dyn RuntimeActionHost>.
runtime is captured at build time so the bridge can spawn dispatch from
any thread; the impl’s async methods run ON that runtime (they are spawned
by the trampoline), so they may freely await.
Implementations§
Source§impl HarnessActionHost
impl HarnessActionHost
Sourcepub fn new_empty(
catalog: Vec<Model>,
cwd: PathBuf,
runtime: Handle,
cli_flags: BTreeMap<String, Value>,
tool_context: ToolCallContext,
) -> (Self, Arc<OnceLock<WeakAgentHarness>>)
pub fn new_empty( catalog: Vec<Model>, cwd: PathBuf, runtime: Handle, cli_flags: BTreeMap<String, Value>, tool_context: ToolCallContext, ) -> (Self, Arc<OnceLock<WeakAgentHarness>>)
Build an empty host (no harness yet). The runtime is the handle
the bridge captured (kept only so the impl can name it for future
direct-spawn needs; the trampoline already spawns on the bridge’s
runtime). Call set_harness once the harness is
created. Returns (host, harness_cell) where harness_cell is the
shared OnceLock the caller fills.
pub fn set_catalog(&self, catalog: Vec<Model>)
Sourcepub fn set_harness(
cell: &Arc<OnceLock<WeakAgentHarness>>,
harness: Arc<AgentHarness>,
)
pub fn set_harness( cell: &Arc<OnceLock<WeakAgentHarness>>, harness: Arc<AgentHarness>, )
Fill the harness cell. Call exactly once, immediately after
AgentHarness::create succeeds. Returns the host (for fluent chaining)
— the caller already holds the Arc<dyn RuntimeActionHost> from
construction; this just populates the cell that host reads.
Trait Implementations§
Source§impl RuntimeActionHost for HarnessActionHost
impl RuntimeActionHost for HarnessActionHost
Source§fn reload_models<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn reload_models<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
ReloadModels — re-read the model/provider catalog from disk without
touching the extension registry.
The work happens on the TUI’s main loop (it owns the harness), so the
request goes through the ReloadModelsMailbox and the answer comes
back over the same request’s reply channel.
Source§fn tool_program<'life0, 'async_trait>(
&'life0 self,
capability: Arc<ToolProgram>,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn tool_program<'life0, 'async_trait>(
&'life0 self,
capability: Arc<ToolProgram>,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn cancel_side_questions(&self, owner: u64)
fn cancel_side_questions(&self, owner: u64)
Source§fn side_question_revision(&self) -> u64
fn side_question_revision(&self) -> u64
fn side_question_views(&self) -> Vec<Value>
fn side_question_ui<'life0, 'async_trait>(
&'life0 self,
owner: u64,
thread_id: String,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn side_question<'life0, 'async_trait>(
&'life0 self,
owner: u64,
args: Value,
sink: SideQuestionSink,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn side_question<'life0, 'async_trait>(
&'life0 self,
owner: u64,
args: Value,
sink: SideQuestionSink,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn cancel_child_agents(&self, owner: u64)
fn cancel_child_agents(&self, owner: u64)
Source§fn replace_model_catalog(&self, models: Vec<Model>)
fn replace_model_catalog(&self, models: Vec<Model>)
Source§fn list_commands<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_commands<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn publish_registry(&self, snapshot: Arc<RegistrySnapshot>)
fn publish_registry(&self, snapshot: Arc<RegistrySnapshot>)
Source§fn publish_registry_opt(&self, snapshot: Option<Arc<RegistrySnapshot>>)
fn publish_registry_opt(&self, snapshot: Option<Arc<RegistrySnapshot>>)
None when a reload found no plugins at all. Read moreSource§fn abort<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn abort<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn stop_round(&self, _args: Value) -> Result<Value, String>
fn stop_round(&self, _args: Value) -> Result<Value, String>
Self::abort. Read moreSource§fn get_execution_context<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_execution_context<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn child_agent<'life0, 'async_trait>(
&'life0 self,
owner: u64,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn child_agent<'life0, 'async_trait>(
&'life0 self,
owner: u64,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
owner is supplied by the bridge, NOT JSON.Source§fn get_cli_flag<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_cli_flag<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
GetCliFlag — read a parsed extension CLI flag. Args are
{"name":"flag"} and the result is {"value": <bool|string|null>}.Source§fn send_message<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn send_message<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
SendMessage — Pi-compatible triggerTurn and deliverAs scheduling.
Defaults append while idle and steer while running; explicit true
starts an idle run, false only updates context, and nextTurn waits
for a new explicit prompt. Results distinguish appended/queued/run.Source§fn send_user_message<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn send_user_message<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
SendUserMessage — drive a run from a user-text message.Source§fn append_entry<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn append_entry<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
AppendEntry — append without starting a run. customType/data
persists extension data only. A message is durably queued during an
operation and committed after its current turn; the returned entryId
is reserved and may not yet resolve to a transcript entry. Optional
expected: {sessionId, leafId, customType, entryId} performs a conditional
write against that exact branch snapshot; a successful reply must confirm
scoped: true. Scoped messages additionally require outboxKey and must
be custom messages: acceptance is idempotent on the current branch and
pending context stays with its source state entry.Source§fn get_session_branch<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_session_branch<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
GetSessionBranch — query custom entries on the current main branch.
Required: non-empty customTypes string array. Optional: afterSeq
(exclusive), limit (positive), order (oldestFirst default or
newestFirst). Unknown/legacy keys and unfiltered {} are rejected.
Sorting/limit apply globally across the requested types; identifiers
match exactly. Consumers must require filtered == true in the reply
rather than accepting an older host’s unfiltered successful response.
This host also returns pinned sessionId, leafId, and scopedAppend: true for callers performing conditional state writes or outbox delivery.Source§fn set_session_name<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn set_session_name<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
SetSessionName — set the session’s display name.Source§fn get_active_tools<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_active_tools<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
GetActiveTools — the active tool-name list.Source§fn set_active_tools<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn set_active_tools<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
SetActiveTools — replace the active tool-name list.Source§fn set_model<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn set_model<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
SetModel — switch the active model (by id; host resolves to a Model).Source§fn get_thinking_level<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_thinking_level<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
GetThinkingLevel — the current thinking level.Source§fn set_thinking_level<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn set_thinking_level<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
SetThinkingLevel — set the thinking level.Source§fn compact<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn compact<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Compact — compact the session transcript.Source§fn get_system_prompt<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_system_prompt<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
GetSystemPrompt — the live composed system prompt.Source§fn new_session<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn new_session<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
NewSession — start a fresh session and switch to it.Source§fn fork<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn fork<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Fork — fork the current session and switch to the fork.NavigateTree — navigate/rewind the session tree.Source§fn switch_session<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn switch_session<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
SwitchSession — hot-switch to an existing session by id.Source§fn reload<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn reload<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Reload — re-run extension discovery + Part-A resource loaders (a CLI
concern; the host impl wires it to the ActionBridge.reload callback in
B5d — until then this returns an “unsupported” error string).Source§fn ui_dialog<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn ui_dialog<'life0, 'async_trait>(
&'life0 self,
_args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
UiDialog fallback for hosts that do not install an interactive
mailbox. The default is deliberately an error so headless runs cannot
accidentally report a fabricated user answer.