Skip to main content

Suggestor

Trait Suggestor 

Source
pub trait Suggestor: Send + Sync {
    // Required methods
    fn name(&self) -> &str;
    fn dependencies(&self) -> &[ContextKey];
    fn accepts(&self, ctx: &dyn Context) -> bool;
    fn execute<'life0, 'life1, 'async_trait>(
        &'life0 self,
        ctx: &'life1 dyn Context,
    ) -> Pin<Box<dyn Future<Output = AgentEffect> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait;

    // Provided methods
    fn provenance(&self) -> Provenance { ... }
    fn complexity_hint(&self) -> Option<&'static str> { ... }
}
Expand description

The core suggestor contract.

Every suggestor in the Converge ecosystem implements this trait — whether it wraps an LLM, a policy engine, an optimizer, analytics, knowledge retrieval, or a simple rule.

The engine calls accepts() to determine eligibility, then execute() to collect effects. Effects are merged by the engine in deterministic registration order via [crate::types::SuggestorId].

§Async

execute() is async, allowing suggestors to call LLM providers, search backends, and other I/O without blocking. The engine awaits each suggestor and controls concurrency — suggestors don’t need to manage their own parallelism.

§Thread Safety

Suggestors must be Send + Sync because the engine may execute eligible suggestors concurrently in the future.

Required Methods§

Source

fn name(&self) -> &str

Human-readable name, used for logging and provenance.

Must be unique within a convergence run. Deterministic execution order is derived from registration order, not lexical name sorting.

Source

fn dependencies(&self) -> &[ContextKey]

Context keys this suggestor reads from.

The engine uses this to determine when a suggestor becomes eligible: a suggestor is a candidate when at least one of its dependency keys has been modified since the last cycle.

Source

fn accepts(&self, ctx: &dyn Context) -> bool

Pure predicate: should this suggestor execute given the current context?

§Contract
  • Must be pure: no side effects, no I/O, no state mutation.
  • Must be deterministic: same context → same answer.
  • Must check idempotency via context: look for your own contributions in context (both Proposals and target key), not internal flags.
Source

fn execute<'life0, 'life1, 'async_trait>( &'life0 self, ctx: &'life1 dyn Context, ) -> Pin<Box<dyn Future<Output = AgentEffect> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Produce effects given the current context.

§Contract
  • Read-only: do not mutate context. Return effects instead.
  • Effects are collected by the engine and merged after all eligible suggestors have executed.
  • For LLM suggestors: emit ProposedFact to ContextKey::Proposals, not directly to the target key.

Provided Methods§

Source

fn provenance(&self) -> Provenance

Typed provenance for this suggestor’s emitted facts and execution span.

Used by both the engine’s tracing layer and by ProposedFact::new callers that want to cite the suggestor as the proposal’s origin. The emitted proposal still remains the authoritative audit boundary: every ProposedFact must carry a non-empty Provenance.

The default impl derives the provenance from name, which is sufficient for span labels and for proposal provenance when the suggestor’s identity is exhausted by its name. Fact-emitting suggestors that carry richer identity claims (versioned model, capability scope, source URI) should override this with their crate-canonical typed provenance constructor:

fn provenance(&self) -> Provenance { ARBITER_PROVENANCE.clone() }

Empty provenance on an emitted proposal is a kernel error; the default impl above never produces empty provenance as long as name() is non-empty.

Source

fn complexity_hint(&self) -> Option<&'static str>

Algorithmic complexity of this suggestor’s core computation.

Returns a short string describing time complexity and practical scale guidance. None means negligible / not applicable (e.g. pure LLM calls where latency is network-bound, not algorithmic).

Examples: "O(n³) — n = agents/tasks, practical for n ≤ 500"

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl Suggestor for AssignmentSuggestor

Source§

fn name(&self) -> &str

Source§

fn dependencies(&self) -> &[ContextKey]

Source§

fn complexity_hint(&self) -> Option<&'static str>

Source§

fn accepts(&self, ctx: &dyn Context) -> bool

Source§

fn execute<'life0, 'life1, 'async_trait>( &'life0 self, ctx: &'life1 dyn Context, ) -> Pin<Box<dyn Future<Output = AgentEffect> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, AssignmentSuggestor: 'async_trait,

Source§

fn provenance(&self) -> Provenance

Source§

impl Suggestor for FlowOptimizationSuggestor

Source§

fn name(&self) -> &str

Source§

fn dependencies(&self) -> &[ContextKey]

Source§

fn complexity_hint(&self) -> Option<&'static str>

Source§

fn accepts(&self, ctx: &dyn Context) -> bool

Source§

fn execute<'life0, 'life1, 'async_trait>( &'life0 self, ctx: &'life1 dyn Context, ) -> Pin<Box<dyn Future<Output = AgentEffect> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, FlowOptimizationSuggestor: 'async_trait,

Source§

fn provenance(&self) -> Provenance

Source§

impl Suggestor for GreedySchedulerSuggestor

Source§

fn name(&self) -> &str

Source§

fn dependencies(&self) -> &[ContextKey]

Source§

fn complexity_hint(&self) -> Option<&'static str>

Source§

fn accepts(&self, ctx: &dyn Context) -> bool

Source§

fn execute<'life0, 'life1, 'async_trait>( &'life0 self, ctx: &'life1 dyn Context, ) -> Pin<Box<dyn Future<Output = AgentEffect> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, GreedySchedulerSuggestor: 'async_trait,

Source§

fn provenance(&self) -> Provenance

Source§

impl Suggestor for NearestNeighborTimeWindowRoutingSuggestor

Source§

fn name(&self) -> &str

Source§

fn dependencies(&self) -> &[ContextKey]

Source§

fn complexity_hint(&self) -> Option<&'static str>

Source§

fn accepts(&self, ctx: &dyn Context) -> bool

Source§

fn execute<'life0, 'life1, 'async_trait>( &'life0 self, ctx: &'life1 dyn Context, ) -> Pin<Box<dyn Future<Output = AgentEffect> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, NearestNeighborTimeWindowRoutingSuggestor: 'async_trait,

Source§

fn provenance(&self) -> Provenance

Source§

impl Suggestor for PortfolioSuggestor

Source§

fn name(&self) -> &str

Source§

fn dependencies(&self) -> &[ContextKey]

Source§

fn complexity_hint(&self) -> Option<&'static str>

Source§

fn accepts(&self, ctx: &dyn Context) -> bool

Source§

fn execute<'life0, 'life1, 'async_trait>( &'life0 self, ctx: &'life1 dyn Context, ) -> Pin<Box<dyn Future<Output = AgentEffect> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, PortfolioSuggestor: 'async_trait,

Source§

fn provenance(&self) -> Provenance

Source§

impl Suggestor for ReactOnceSuggestor

Source§

fn name(&self) -> &str

Source§

fn dependencies(&self) -> &[ContextKey]

Source§

fn accepts(&self, ctx: &dyn Context) -> bool

Source§

fn provenance(&self) -> Provenance

Source§

fn execute<'life0, 'life1, 'async_trait>( &'life0 self, _ctx: &'life1 dyn Context, ) -> Pin<Box<dyn Future<Output = AgentEffect> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, ReactOnceSuggestor: 'async_trait,

Source§

impl Suggestor for SeedSuggestor

Source§

fn name(&self) -> &str

Source§

fn dependencies(&self) -> &[ContextKey]

Source§

fn accepts(&self, ctx: &dyn Context) -> bool

Source§

fn execute<'life0, 'life1, 'async_trait>( &'life0 self, _ctx: &'life1 dyn Context, ) -> Pin<Box<dyn Future<Output = AgentEffect> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, SeedSuggestor: 'async_trait,

Source§

fn provenance(&self) -> Provenance

Source§

impl Suggestor for ValidationAgent

Source§

fn name(&self) -> &str

Source§

fn dependencies(&self) -> &[ContextKey]

Source§

fn accepts(&self, ctx: &dyn Context) -> bool

Source§

fn provenance(&self) -> Provenance

Source§

fn execute<'life0, 'life1, 'async_trait>( &'life0 self, ctx: &'life1 dyn Context, ) -> Pin<Box<dyn Future<Output = AgentEffect> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, ValidationAgent: 'async_trait,

Source§

impl Suggestor for WorkScheduleSuggestor

Source§

fn name(&self) -> &str

Source§

fn dependencies(&self) -> &[ContextKey]

Source§

fn complexity_hint(&self) -> Option<&'static str>

Source§

fn accepts(&self, ctx: &dyn Context) -> bool

Source§

fn execute<'life0, 'life1, 'async_trait>( &'life0 self, ctx: &'life1 dyn Context, ) -> Pin<Box<dyn Future<Output = AgentEffect> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, WorkScheduleSuggestor: 'async_trait,

Source§

fn provenance(&self) -> Provenance

Implementors§