pub trait ExtensionHandler: Send + Sync {
Show 15 methods
// Required methods
fn id(&self) -> &str;
fn handle<'life0, 'life1, 'async_trait>(
&'life0 self,
event: &'life1 HookEvent,
) -> Pin<Box<dyn Future<Output = HookResult> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn shutdown<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
// Provided methods
fn call_tool<'life0, 'life1, 'async_trait>(
&'life0 self,
_name: &'life1 str,
_input: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn provider_complete<'life0, 'async_trait>(
&'life0 self,
_params: ProviderCompleteParams,
) -> Pin<Box<dyn Future<Output = Result<ProviderCompleteResult, String>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn provider_stream<'life0, 'async_trait>(
&'life0 self,
_params: ProviderCompleteParams,
_sink: Sender<ProviderStreamEvent>,
) -> Pin<Box<dyn Future<Output = Result<ProviderCompleteResult, String>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn invoke_command<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_command: &'life1 str,
_args: Vec<String>,
_request_id: &'life2 str,
_sink: InvokeEventSink,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn get_info<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<PluginInfo, String>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn sidecar_spawn_args<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<SidecarSpawnArgs, String>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn settings_editor_open<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_category: &'life1 str,
_field: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn settings_editor_key<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
_category: &'life1 str,
_field: &'life2 str,
_key: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait { ... }
fn settings_editor_commit<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_category: &'life1 str,
_field: &'life2 str,
_value: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn subscribe_notifications<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = (usize, Receiver<NotificationFrame>)> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn health<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = ExtensionHealth> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn restart_count<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = usize> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
}Expand description
Trait for extension runtimes that can handle hook events.
Required Methods§
Provided Methods§
Sourcefn call_tool<'life0, 'life1, 'async_trait>(
&'life0 self,
_name: &'life1 str,
_input: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn call_tool<'life0, 'life1, 'async_trait>(
&'life0 self,
_name: &'life1 str,
_input: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Call an extension-provided tool.
Sourcefn provider_complete<'life0, 'async_trait>(
&'life0 self,
_params: ProviderCompleteParams,
) -> Pin<Box<dyn Future<Output = Result<ProviderCompleteResult, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn provider_complete<'life0, 'async_trait>(
&'life0 self,
_params: ProviderCompleteParams,
) -> Pin<Box<dyn Future<Output = Result<ProviderCompleteResult, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Complete a chat request through an extension-provided model provider.
Sourcefn provider_stream<'life0, 'async_trait>(
&'life0 self,
_params: ProviderCompleteParams,
_sink: Sender<ProviderStreamEvent>,
) -> Pin<Box<dyn Future<Output = Result<ProviderCompleteResult, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn provider_stream<'life0, 'async_trait>(
&'life0 self,
_params: ProviderCompleteParams,
_sink: Sender<ProviderStreamEvent>,
) -> Pin<Box<dyn Future<Output = Result<ProviderCompleteResult, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Stream a chat request through an extension-provided model provider.
The handler must forward provider.stream.event notifications to sink
in order. The returned ProviderCompleteResult is the final aggregated
response (so callers that don’t need streaming can use it as the final
state). Implementations that don’t support streaming should return
Err("provider.stream is not supported by this extension").
Sourcefn invoke_command<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_command: &'life1 str,
_args: Vec<String>,
_request_id: &'life2 str,
_sink: InvokeEventSink,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn invoke_command<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_command: &'life1 str,
_args: Vec<String>,
_request_id: &'life2 str,
_sink: InvokeEventSink,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Invoke a plugin-registered interactive slash command. The handler must
forward command.output notifications matching request_id and any
task.* notifications to sink. Returns the final response value.
CP-11 fix-3: the sink is BOUNDED and metered
(crate::extensions::invoke_output::InvokeEventSink). It must be
paired with an EAGERLY CONCURRENT consumer — normally the collector
half of crate::extensions::invoke_output::invoke_event_channel,
joined with this call by
ExtensionManager::invoke_command_collected — which enforces
invocation-local byte/event budgets at production time. A hostile
command.output flood is therefore paced by awaited sends and
bounded retention instead of parking aggregate bytes in an
unbounded post-hoc queue (the pre-fix behavior). Handlers must
treat a closed sink like the old closed-unbounded-sink case: stop
forwarding, still complete the call.
Sourcefn get_info<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<PluginInfo, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_info<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<PluginInfo, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Fetch optional plugin capability/build/model information.
Sourcefn sidecar_spawn_args<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<SidecarSpawnArgs, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn sidecar_spawn_args<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<SidecarSpawnArgs, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Ask the plugin to supply sidecar spawn arguments. Used by the
modality-neutral sidecar bootstrap path (see
crate::sidecar::spawn); plugins that don’t host a sidecar
should leave the default Err in place. Core treats the
returned [SidecarSpawnArgs::args] as opaque.
Sourcefn settings_editor_open<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_category: &'life1 str,
_field: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn settings_editor_open<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_category: &'life1 str,
_field: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Open a plugin-owned custom settings editor and return its initial render payload.
Sourcefn settings_editor_key<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
_category: &'life1 str,
_field: &'life2 str,
_key: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn settings_editor_key<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
_category: &'life1 str,
_field: &'life2 str,
_key: &'life3 str,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Forward a keypress to the active plugin-owned custom settings editor.
Sourcefn settings_editor_commit<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_category: &'life1 str,
_field: &'life2 str,
_value: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn settings_editor_commit<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_category: &'life1 str,
_field: &'life2 str,
_value: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Ask the plugin to commit a custom editor value selected by the UI.
Sourcefn subscribe_notifications<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = (usize, Receiver<NotificationFrame>)> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn subscribe_notifications<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = (usize, Receiver<NotificationFrame>)> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Subscribe to raw JSON-RPC notifications from this extension.
Returns a monotonic subscription id (for unsubscribing) and a
receiver that yields every notification frame. The default
implementation returns a channel whose sender is immediately
dropped, so the receiver yields None right away — effectively
a no-op for handler impls that don’t support notifications.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".