pub struct EmbeddingRouter { /* private fields */ }Expand description
The embedding-based NLU router.
Pre-computes tool embeddings at initialization, then routes queries by embedding the query and computing cosine similarity against all tool embeddings. OATS refinement adjusts tool embeddings based on observed outcomes.
Implementations§
Source§impl EmbeddingRouter
impl EmbeddingRouter
Sourcepub fn new(embedder: Box<dyn Embedder>) -> Option<Self>
pub fn new(embedder: Box<dyn Embedder>) -> Option<Self>
Create a new embedding router, pre-computing tool embeddings.
Returns None if:
- The embedder is a stub (hash-based embeddings have no semantic meaning)
- Batch embedding fails
This allows the caller to gracefully fall back to the TF-IDF router.
Sourcepub fn with_descriptions(
embedder: Box<dyn Embedder>,
descriptions: Vec<(String, String)>,
) -> Option<Self>
pub fn with_descriptions( embedder: Box<dyn Embedder>, descriptions: Vec<(String, String)>, ) -> Option<Self>
Create a new embedding router from explicit (tool, description) pairs.
Unlike Self::new — which uses the static keyword profiles from
nlu.rs (169 tools, keyword-mashup descriptions) — this accepts
descriptions from the live tool registry (all 229 tools, prose
descriptions). Sentence-style descriptions embed far better than
bare keyword lists; the 2026-08-11 shadow run (42.6% disagreement)
showed keyword-mashup top-1 selection collapsing onto arbitrary
high-similarity tools.
Sourcepub fn route(&self, query: &str) -> (String, f64)
pub fn route(&self, query: &str) -> (String, f64)
Route a natural language query to a tool name and confidence score.
Returns ("gnosis", 0.0) for empty input or when no tool scores above
the minimum threshold.
Sourcepub fn route_with_margin(&self, query: &str) -> Option<(String, f64, f64)>
pub fn route_with_margin(&self, query: &str) -> Option<(String, f64, f64)>
Route a query, returning (tool, confidence, margin).
margin is the score gap between the top-1 and top-2 tools. Small
margins indicate the descriptions cannot separate intent — callers
should defer to the TF-IDF router when margin < MIN_MARGIN.
Sourcepub fn route_with_margin_and_embedding(
&self,
query: &str,
) -> Option<(String, f64, f64, Vec<f32>)>
pub fn route_with_margin_and_embedding( &self, query: &str, ) -> Option<(String, f64, f64, Vec<f32>)>
Route a query, also returning the query embedding.
The embedding is what record_outcome_with_embedding
needs — returning it here lets callers embed each query once instead of
twice (embedder HTTP round-trips dominate NLU latency).
Sourcepub fn record_outcome(&self, tool_name: &str, query: &str, success: bool)
pub fn record_outcome(&self, tool_name: &str, query: &str, success: bool)
Record a routing outcome for OATS refinement.
Call this after each tool dispatch to track whether the routing was
correct. success = true means the tool was the right choice and
executed successfully; false means it was wrong or failed.
Sourcepub fn record_outcome_with_embedding(
&self,
tool_name: &str,
query: &str,
success: bool,
query_emb: &[f32],
)
pub fn record_outcome_with_embedding( &self, tool_name: &str, query: &str, success: bool, query_emb: &[f32], )
Record a routing outcome reusing a query embedding already computed by the router.
Callers that routed through route_with_margin
should pass the embedding back here so the query is embedded only once
instead of twice (HTTP embedder round-trips dominate NLU latency).
Sourcepub fn tool_count(&self) -> usize
pub fn tool_count(&self) -> usize
Number of tool embeddings in the router.
Sourcepub fn backend_name(&self) -> &str
pub fn backend_name(&self) -> &str
Embedder backend name.
Sourcepub fn outcome_counts(&self) -> Vec<(String, usize, usize)>
pub fn outcome_counts(&self) -> Vec<(String, usize, usize)>
Get a snapshot of outcome stats counts for observability.
Auto Trait Implementations§
impl !Freeze for EmbeddingRouter
impl !RefUnwindSafe for EmbeddingRouter
impl !UnwindSafe for EmbeddingRouter
impl Send for EmbeddingRouter
impl Sync for EmbeddingRouter
impl Unpin for EmbeddingRouter
impl UnsafeUnpin for EmbeddingRouter
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<T> Fruit for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more