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§
Sourcefn name(&self) -> &str
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.
Sourcefn 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,
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§
Sourcefn process_signals<'async_trait>(
self: Arc<Self>,
signals: Signals,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
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.
Sourcefn run_stream(
self: Arc<Self>,
ctx: Context,
request: Request,
observer: Option<RunObserver>,
) -> StepStream
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.
Sourcefn 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<'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,
Sourcefn 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,
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.