Traits Reference

All public traits in synwire-core and synwire-agent. Every trait is Send + Sync unless noted otherwise. Methods returning async results use BoxFuture<'_, Result<T, E>> from synwire_core::BoxFuture.


Core Agent Traits — synwire_core::agents


AgentNode

#![allow(unused)]
fn main() {
pub trait AgentNode: Send + Sync {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn run(&self, input: Value) -> BoxFuture<'_, Result<AgentEventStream, AgentError>>;
    fn sub_agents(&self) -> Vec<String> { vec![] }  // default: empty
}
}

A runnable agent that produces a stream of AgentEvent values.

MethodDescription
nameStable identifier used for routing, logging, and sub-agent references.
descriptionHuman-readable string; surfaced in introspection and UI.
runStart a turn. Returns an event stream that terminates with TurnComplete or Error.
sub_agentsNames of agents this node may spawn. Used by the runner for capability declaration.

The Agent<O> builder implements AgentNode. Provider crates replace the stub model invocation with a real LLM call.


ExecutionStrategy

#![allow(unused)]
fn main() {
pub trait ExecutionStrategy: Send + Sync {
    fn execute<'a>(&'a self, action: &'a str, input: Value)
        -> BoxFuture<'a, Result<Value, StrategyError>>;
    fn tick(&self)
        -> BoxFuture<'_, Result<Option<Value>, StrategyError>>;
    fn snapshot(&self)
        -> Result<Box<dyn StrategySnapshot>, StrategyError>;
    fn signal_routes(&self) -> Vec<SignalRoute> { vec![] } // default: empty
}
}

Controls how an agent orchestrates actions.

MethodDescription
executeAttempt an action from the current state. Returns the (possibly modified) input on success. FsmStrategy validates the action against the current FSM state. DirectStrategy passes input through unconditionally.
tickProcess pending deferred work. Returns Some(value) if there is a result to route back; None otherwise.
snapshotCapture serialisable strategy state for checkpointing.
signal_routesSignal routes contributed by this strategy to the composed router.

GuardCondition

#![allow(unused)]
fn main() {
pub trait GuardCondition: Send + Sync {
    fn evaluate(&self, input: &Value) -> bool;
    fn name(&self) -> &str;
}
}

Predicate evaluated before an FSM transition is accepted.

MethodDescription
evaluateReturn true to allow the transition.
nameHuman-readable name used in error messages and logging.

ClosureGuard is a convenience adapter that wraps Fn(&Value) -> bool.


StrategySnapshot

#![allow(unused)]
fn main() {
pub trait StrategySnapshot: Send + Sync {
    fn to_value(&self) -> Result<Value, StrategyError>;
}
}

Serialises strategy state to JSON for checkpointing. The value is opaque from the runtime's perspective; each strategy defines its own schema.


DirectiveFilter

#![allow(unused)]
fn main() {
pub trait DirectiveFilter: Send + Sync {
    fn filter(&self, directive: Directive) -> Option<Directive>;
    fn decision(&self, directive: &Directive) -> FilterDecision { /* default */ }
}
}

Filters directives before they reach the executor.

MethodDescription
filterReturn Some(directive) to pass through (possibly modified) or None to suppress.
decisionInspect a directive without consuming it. Default implementation calls filter on a clone.

FilterChain applies a sequence of filters in registration order; the first None result short-circuits the chain.


DirectiveExecutor

#![allow(unused)]
fn main() {
pub trait DirectiveExecutor: Send + Sync {
    fn execute_directive(
        &self,
        directive: &Directive,
    ) -> BoxFuture<'_, Result<Option<Value>, DirectiveError>>;
}
}

Executes a Directive and optionally routes a result value back to the agent.

ReturnsMeaning
Ok(None)Directive executed; no result to route back.
Ok(Some(v))Result value to inject into the next agent turn (used by RunInstruction).
Err(e)Execution failed.

NoOpExecutor always returns Ok(None). Useful for pure directive-testing without side effects.


DirectivePayload

#![allow(unused)]
fn main() {
#[typetag::serde(tag = "custom_type")]
pub trait DirectivePayload: Debug + Send + Sync + DynClone {}
}

Marker trait for user-defined directive data carried by Directive::Custom. Requires #[typetag::serde] on the implementation for serialisation support.


Middleware

#![allow(unused)]
fn main() {
pub trait Middleware: Send + Sync {
    fn name(&self) -> &str;
    fn process(&self, input: MiddlewareInput)
        -> BoxFuture<'_, Result<MiddlewareResult, AgentError>>;  // default: pass-through
    fn tools(&self) -> Vec<Box<dyn Tool>> { vec![] }
    fn system_prompt_additions(&self) -> Vec<String> { vec![] }
}
}

Cross-cutting concern injected into the agent loop via MiddlewareStack.

MethodDescription
nameIdentifier for logging and ordering diagnostics.
processTransform MiddlewareInput. Return Continue(modified) to chain or Terminate(reason) to halt. The default implementation is a no-op pass-through.
toolsAdditional tools injected into the agent context by this middleware.
system_prompt_additionsPrompt fragments appended in stack order by MiddlewareStack::system_prompt_additions.

Plugin

#![allow(unused)]
fn main() {
pub trait Plugin: Send + Sync {
    fn name(&self) -> &str;
    fn on_user_message<'a>(&'a self, input: &'a PluginInput, state: &'a PluginStateMap)
        -> BoxFuture<'a, Vec<Directive>> { /* default: empty */ }
    fn on_event<'a>(&'a self, event: &'a AgentEvent, state: &'a PluginStateMap)
        -> BoxFuture<'a, Vec<Directive>> { /* default: empty */ }
    fn before_run<'a>(&'a self, state: &'a PluginStateMap)
        -> BoxFuture<'a, Vec<Directive>> { /* default: empty */ }
    fn after_run<'a>(&'a self, state: &'a PluginStateMap)
        -> BoxFuture<'a, Vec<Directive>> { /* default: empty */ }
    fn signal_routes(&self) -> Vec<SignalRoute> { vec![] }
}
}

Lifecycle extension point for the agent loop. All methods have default no-op implementations; plugins only override hooks they require.

MethodTriggered when
on_user_messageA user message arrives.
on_eventAny AgentEvent is emitted.
before_runBefore each run loop iteration.
after_runAfter each run loop iteration.
signal_routesCalled at startup to register signal routes in the composed router.

Plugins return Vec<Directive> to request effects without direct mutation.


PluginStateKey

#![allow(unused)]
fn main() {
pub trait PluginStateKey: Send + Sync + 'static {
    type State: Send + Sync + 'static;
    const KEY: &'static str;
}
}

Typed key for isolated plugin state stored in PluginStateMap.

Associated itemDescription
type StateThe concrete state type stored for this plugin. Must be Send + Sync + 'static.
const KEYUnique string key used for serialisation. Must be globally unique across all registered plugins.

Plugins cannot access other plugins' state — the TypeId of P enforces isolation at runtime.


SignalRouter

#![allow(unused)]
fn main() {
pub trait SignalRouter: Send + Sync {
    fn route(&self, signal: &Signal) -> Option<Action>;
    fn routes(&self) -> Vec<SignalRoute>;
}
}

Routes Signal values to Action decisions.

MethodDescription
routeReturn the best-matching action, or None if no route matches.
routesAll routes contributed by this router.

ComposedRouter merges strategy, agent, and plugin route tiers: strategy routes always win regardless of priority value. Within a tier, the highest priority field wins.


SessionManager

#![allow(unused)]
fn main() {
pub trait SessionManager: Send + Sync {
    fn list(&self)
        -> BoxFuture<'_, Result<Vec<SessionMetadata>, AgentError>>;
    fn resume(&self, session_id: &str)
        -> BoxFuture<'_, Result<Session, AgentError>>;
    fn save(&self, session: &Session)
        -> BoxFuture<'_, Result<(), AgentError>>;
    fn delete(&self, session_id: &str)
        -> BoxFuture<'_, Result<(), AgentError>>;
    fn fork(&self, session_id: &str, new_name: Option<String>)
        -> BoxFuture<'_, Result<SessionMetadata, AgentError>>;
    fn rewind(&self, session_id: &str, turn_index: u32)
        -> BoxFuture<'_, Result<Session, AgentError>>;
    fn tag(&self, session_id: &str, tags: Vec<String>)
        -> BoxFuture<'_, Result<(), AgentError>>;
    fn rename(&self, session_id: &str, new_name: String)
        -> BoxFuture<'_, Result<(), AgentError>>;
}
}

Manages session persistence and lifecycle.

MethodDescription
listReturn all session metadata, ordered by updated_at descending.
resumeLoad the full Session by ID.
saveCreate or update a session, refreshing updated_at.
deleteRemove a session and all associated data.
forkDuplicate a session with a new ID. The copy shares history up to the fork point. new_name overrides the name or appends " (fork)".
rewindTruncate messages to turn_index (zero-based). Returns the modified session.
tagAdd tags. Duplicate tags are silently ignored.
renameUpdate the human-readable session name.

InMemorySessionManager (in synwire_agent) is an ephemeral implementation suitable for testing. A persistent SQLite implementation is in synwire-checkpoint.


ModelProvider

#![allow(unused)]
fn main() {
pub trait ModelProvider: Send + Sync {
    fn list_models(&self)
        -> BoxFuture<'_, Result<Vec<ModelInfo>, AgentError>>;
}
}

Implemented by LLM provider crates (synwire-llm-openai, synwire-llm-ollama). Returns the set of models offered by the provider along with their capabilities and context window sizes.


Backend Traits — synwire_core::vfs


Vfs

#![allow(unused)]
fn main() {
pub trait Vfs: Send + Sync {
    fn ls(&self, path: &str)
        -> BoxFuture<'_, Result<Vec<DirEntry>, VfsError>>;
    fn read(&self, path: &str)
        -> BoxFuture<'_, Result<FileContent, VfsError>>;
    fn write(&self, path: &str, content: &[u8])
        -> BoxFuture<'_, Result<WriteResult, VfsError>>;
    fn edit(&self, path: &str, old: &str, new: &str)
        -> BoxFuture<'_, Result<EditResult, VfsError>>;
    fn grep(&self, pattern: &str, opts: GrepOptions)
        -> BoxFuture<'_, Result<Vec<GrepMatch>, VfsError>>;
    fn glob(&self, pattern: &str)
        -> BoxFuture<'_, Result<Vec<GlobEntry>, VfsError>>;
    fn upload(&self, from: &str, to: &str)
        -> BoxFuture<'_, Result<TransferResult, VfsError>>;
    fn download(&self, from: &str, to: &str)
        -> BoxFuture<'_, Result<TransferResult, VfsError>>;
    fn pwd(&self)
        -> BoxFuture<'_, Result<String, VfsError>>;
    fn cd(&self, path: &str)
        -> BoxFuture<'_, Result<(), VfsError>>;
    fn rm(&self, path: &str)
        -> BoxFuture<'_, Result<(), VfsError>>;
    fn cp(&self, from: &str, to: &str)
        -> BoxFuture<'_, Result<TransferResult, VfsError>>;
    fn mv_file(&self, from: &str, to: &str)
        -> BoxFuture<'_, Result<TransferResult, VfsError>>;
    fn capabilities(&self) -> VfsCapabilities;
}
}

Unified protocol for agent filesystem and storage operations. Backends that do not support an operation return VfsError::Unsupported.

MethodDescription
lsList directory contents.
readRead file bytes and optional MIME type.
writeWrite bytes; creates or overwrites.
editReplace the first occurrence of old with new (text files only).
grepRipgrep-style content search with GrepOptions.
globFind paths matching a glob pattern.
uploadCopy a local file (from) to the backend (to).
downloadCopy a backend file (from) to a local path (to).
pwdReturn the current working directory.
cdChange the current working directory.
rmRemove a file or directory.
cpCopy within the backend.
mv_fileMove or rename within the backend.
capabilitiesReturn the VfsCapabilities bitflags supported.

Implementations in synwire_agent: LocalProvider, GitBackend, HttpBackend, ProcessManager, ArchiveManager, StoreProvider, MemoryProvider, Shell, CompositeProvider.


SandboxVfs

#![allow(unused)]
fn main() {
pub trait SandboxVfs: Send + Sync {
    fn execute(&self, cmd: &str, args: &[String])
        -> BoxFuture<'_, Result<ExecuteResponse, VfsError>>;
    fn execute_pipeline(&self, stages: &[PipelineStage])
        -> BoxFuture<'_, Result<Vec<ExecuteResponse>, VfsError>>;
    fn id(&self) -> &str;
}
}

Separate from Vfs to make command-execution capability explicit.

MethodDescription
executeRun a single command with arguments.
execute_pipelineRun a sequence of stages; each stage's stdout is piped into the next.
idSandbox identifier used for logging and audit.

BaseSandbox is a type alias for dyn SandboxVfs + Send + Sync.


ApprovalCallback

#![allow(unused)]
fn main() {
pub trait ApprovalCallback: Send + Sync {
    fn request(&self, req: ApprovalRequest)
        -> BoxFuture<'_, ApprovalDecision>;
}
}

Gate for risky operations. Called before any operation whose RiskLevel requires approval under the active PermissionMode.

AutoApproveCallback always returns ApprovalDecision::Allow. AutoDenyCallback always returns ApprovalDecision::Deny. ThresholdGate auto-approves operations at or below a configured RiskLevel and delegates higher-risk operations to an inner callback.


MCP Traits — synwire_core::mcp


McpTransport

#![allow(unused)]
fn main() {
pub trait McpTransport: Send + Sync {
    fn connect(&self)
        -> BoxFuture<'_, Result<(), AgentError>>;
    fn reconnect(&self)
        -> BoxFuture<'_, Result<(), AgentError>>;
    fn disconnect(&self)
        -> BoxFuture<'_, Result<(), AgentError>>;
    fn status(&self)
        -> BoxFuture<'_, McpServerStatus>;
    fn list_tools(&self)
        -> BoxFuture<'_, Result<Vec<McpToolDescriptor>, AgentError>>;
    fn call_tool(&self, tool_name: &str, arguments: Value)
        -> BoxFuture<'_, Result<Value, AgentError>>;
}
}

Low-level transport for communicating with an MCP server.

MethodDescription
connectEstablish connection. For StdioMcpTransport, this spawns the subprocess.
reconnectRe-establish after a drop without changing configuration.
disconnectClean shutdown.
statusReturn a McpServerStatus snapshot including call counters and connection state.
list_toolsReturn all tools advertised by the server.
call_toolInvoke a tool by name with JSON arguments; returns the tool's JSON response.

Implementations in synwire_agent: StdioMcpTransport, HttpMcpTransport, InProcessMcpTransport. These are managed by McpLifecycleManager.


OnElicitation

#![allow(unused)]
fn main() {
pub trait OnElicitation: Send + Sync {
    fn elicit(&self, request: ElicitationRequest)
        -> BoxFuture<'_, Result<ElicitationResult, AgentError>>;
}
}

Receives mid-call requests for additional user input from an MCP server (credentials, confirmations, etc.) and returns a ElicitationResult.

CancelAllElicitations is the default implementation — it cancels every request without prompting.


Store Trait — synwire_agent


BaseStore

#![allow(unused)]
fn main() {
pub trait BaseStore: Send + Sync {
    fn get(&self, namespace: &str, key: &str)
        -> Result<Option<Vec<u8>>, VfsError>;
    fn set(&self, namespace: &str, key: &str, value: Vec<u8>)
        -> Result<(), VfsError>;
    fn delete(&self, namespace: &str, key: &str)
        -> Result<(), VfsError>;
    fn list(&self, namespace: &str)
        -> Result<Vec<String>, VfsError>;
}
}

Synchronous namespaced key-value store. Note: unlike most Synwire traits, BaseStore methods are synchronous (Result, not BoxFuture).

MethodDescription
getReturn the value for namespace/key, or None if absent.
setWrite value to namespace/key. Creates or overwrites.
deleteRemove namespace/key. Returns VfsError::NotFound if absent.
listReturn all keys in namespace (without the namespace prefix).

InMemoryStore wraps a BTreeMap behind a RwLock. StoreProvider wraps a BaseStore and exposes it as Vfs with paths of the form /<namespace>/<key>.