Skip to main content

Algorithm

Trait Algorithm 

Source
pub trait Algorithm:
    Send
    + Sync
    + 'static {
    // Required methods
    fn name(&self) -> &str;
    fn create_run_task<'async_trait>(
        self: Arc<Self>,
        ctx: Context,
        driver: Driver,
        request: Request,
    ) -> Pin<Box<dyn Future<Output = Result<Response>> + Send + 'async_trait>>
       where Self: 'async_trait;

    // Provided methods
    fn process_signals<'async_trait>(
        self: Arc<Self>,
        signals: Signals,
    ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
       where Self: 'async_trait { ... }
    fn run_stream(
        self: Arc<Self>,
        ctx: Context,
        request: Request,
        observer: Option<RunObserver>,
    ) -> StepStream { ... }
    fn run<'async_trait>(
        self: Arc<Self>,
        ctx: Context,
        request: Request,
    ) -> Pin<Box<dyn Future<Output = Result<(Vec<Arc<dyn Decision>>, Response)>> + Send + 'async_trait>>
       where Self: 'async_trait { ... }
    fn run_observed<'async_trait>(
        self: Arc<Self>,
        ctx: Context,
        request: Request,
        observer: Option<RunObserver>,
    ) -> Pin<Box<dyn Future<Output = Result<(Vec<Arc<dyn Decision>>, Response)>> + Send + 'async_trait>>
       where Self: 'async_trait { ... }
}
Expand description

An optimization strategy. Implement create_run_task; callers drive it with the provided run (serve calls, get the answer) or run_stream (drive the Step stream yourself).

Methods take self: Arc<Self>: one algorithm (Arc<dyn Algorithm>) is shared across requests and run concurrently, so it owns its thread-safety and any shared state.

§Concurrency

A host may run the same algorithm concurrently for many requests. Implementations must synchronize their own mutable shared state. Each call to run_stream creates an independent Driver, so model-call promises and emitted Steps cannot cross between runs.

§Observability

run_stream creates a libsy.run span, and each offloaded model call creates a libsy.llm_call span. run additionally wraps calls it serves through a target’s default client in libsy.client_call. Decisions and failures are emitted through tracing; metrics use the global OpenTelemetry meter provider.

Required Methods§

Source

fn name(&self) -> &str

Stable, low-cardinality name identifying this algorithm — the algorithm attribute on every span, metric, and log line the crate emits for its runs.

Source

fn create_run_task<'async_trait>( self: Arc<Self>, ctx: Context, driver: Driver, request: Request, ) -> Pin<Box<dyn Future<Output = Result<Response>> + Send + 'async_trait>>
where Self: 'async_trait,

Run one request to completion: make model calls with Driver::call_llm_target, publish Decisions with Driver::info, and return the final Response. The method an algorithm implements; run / run_stream drive it. ctx carries the request’s cross-cutting values (today: the algorithm’s telemetry label in Context::values).

Provided Methods§

Source

fn process_signals<'async_trait>( self: Arc<Self>, signals: Signals, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,

Feed the algorithm agentic-stack events (tool results, budgets, etc.). The reference algorithms ignore signals; a stateful algorithm updates its own (interior-mutable) state. Takes self: Arc<Self> like the other run methods.

Source

fn run_stream( self: Arc<Self>, ctx: Context, request: Request, observer: Option<RunObserver>, ) -> StepStream

Process a request to completion, returning a stream of Steps.

The consumer must fulfill every Step::CallLlm before the algorithm can continue. The bounded step channel applies backpressure when the consumer is not polling. A successful run ends with Step::ReturnToAgent; a failure is emitted as an Err item. Dropping the stream aborts the spawned algorithm task.

Every invocation owns a separate Driver. observer, when present, receives each completed model call and, after a successful routed run, its routing overhead.

Source

fn run<'async_trait>( self: Arc<Self>, ctx: Context, request: Request, ) -> Pin<Box<dyn Future<Output = Result<(Vec<Arc<dyn Decision>>, Response)>> + Send + 'async_trait>>
where Self: 'async_trait,

Process a request to completion, returning the final Response and the trace of Decisions the algorithm made along the way.

Source

fn run_observed<'async_trait>( self: Arc<Self>, ctx: Context, request: Request, observer: Option<RunObserver>, ) -> Pin<Box<dyn Future<Output = Result<(Vec<Arc<dyn Decision>>, Response)>> + Send + 'async_trait>>
where Self: 'async_trait,

Process a request to completion while reporting each model call to observer.

Implementors§