From 6d54df655e8efb15ba1e9bb05730094f0481ff89 Mon Sep 17 00:00:00 2001 From: shanu Date: Thu, 27 Aug 2026 16:37:37 +0530 Subject: [PATCH 1/5] feat: add MemoryScoring bus family (#5560) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the 21st memory bus capability family — Scoring — with three methods: - extract_entities(query) -> Vec - embed_text(text) -> Vec - embedder_slug() -> String Routes three direct tinymemory-core engine calls through the memory bus, eliminating the remaining raw engine deps for entity extraction and embedding. - tinymemory-api: new MemoryScoring trait + null impl + driver accessor - tinymemory-bus: Capability::Scoring (index 20), ALL grows to 21 - tinymemory-module: ExtractEntities/EmbedText/EmbedderSlug handlers - tinymemory-tinycortex: full TinycortexProvider impl for the family --- crates/tinymemory-api/src/null.rs | 17 +++++- crates/tinymemory-api/src/provider/driver.rs | 7 +++ crates/tinymemory-api/src/provider/mod.rs | 2 + crates/tinymemory-api/src/provider/scoring.rs | 61 +++++++++++++++++++ crates/tinymemory-bus/src/capabilities.rs | 8 ++- .../tinymemory-bus/src/capabilities_tests.rs | 9 +-- crates/tinymemory-module/src/lib.rs | 4 ++ crates/tinymemory-module/src/service/mod.rs | 26 ++++++++ .../tinymemory-tinycortex/src/engine/mod.rs | 46 +++++++++++++- 9 files changed, 173 insertions(+), 7 deletions(-) create mode 100644 crates/tinymemory-api/src/provider/scoring.rs diff --git a/crates/tinymemory-api/src/null.rs b/crates/tinymemory-api/src/null.rs index 9e737c4..9f12685 100644 --- a/crates/tinymemory-api/src/null.rs +++ b/crates/tinymemory-api/src/null.rs @@ -65,7 +65,7 @@ use crate::provider::{ FastRetrieveQuery, MemoryChunks, MemoryCodingSessions, MemoryCore, MemoryDiff, MemoryDocuments, MemoryEntities, MemoryGoals, MemoryGraph, MemoryIngest, MemoryMaintenance, MemoryPeople, MemoryPortability, MemoryProfile, MemoryProvider, MemoryRecall, MemoryRetrieval, - MemorySourceSink, MemorySourceSync, MemoryToolMemory, MemoryTree, PersonHandle, + MemoryScoring, MemorySourceSink, MemorySourceSync, MemoryToolMemory, MemoryTree, PersonHandle, PersonInteraction, PersonRecord, PersonScore, ProfileFacet, RankedPerson, RawArchiveCoverage, RawRebuildOutcome, ResolvedPerson, RetrievalHit, RetrievalResponse, SourceRetrievalQuery, SourceSyncState, SourceSyncStatus, SyncAuditEntry, SyncRunOutcome, UserState, @@ -785,6 +785,21 @@ impl MemoryCodingSessions for NullMemoryProvider { } } +#[async_trait] +impl MemoryScoring for NullMemoryProvider { + async fn extract_entities(&self, _query: &str) -> Result, MemoryError> { + unsupported(Capability::Scoring) + } + + async fn embed_text(&self, _text: &str) -> Result, MemoryError> { + unsupported(Capability::Scoring) + } + + async fn embedder_slug(&self) -> Result { + unsupported(Capability::Scoring) + } +} + #[cfg(test)] #[path = "null_tests.rs"] mod tests; diff --git a/crates/tinymemory-api/src/provider/driver.rs b/crates/tinymemory-api/src/provider/driver.rs index b3768ce..c25769f 100644 --- a/crates/tinymemory-api/src/provider/driver.rs +++ b/crates/tinymemory-api/src/provider/driver.rs @@ -66,6 +66,7 @@ use crate::provider::records::{ MemoryGoals, MemoryMaintenance, MemorySourceSink, MemoryToolMemory, }; use crate::provider::retrieval::MemoryRetrieval; +use crate::provider::scoring::MemoryScoring; use crate::provider::sessions::MemoryCodingSessions; use crate::provider::sync::MemorySourceSync; @@ -214,6 +215,11 @@ pub trait MemoryProvider: MemoryCore + MemoryRecall + MemoryPortability + 'stati None } + /// Scoring and NLP operations, when advertised. + fn as_scoring(&self) -> Option<&dyn MemoryScoring> { + None + } + /// Whether `capability` is actually **reachable** on this driver. /// /// This is the implementation-side truth, as opposed to @@ -246,6 +252,7 @@ pub trait MemoryProvider: MemoryCore + MemoryRecall + MemoryPortability + 'stati Capability::Episodic => self.as_episodic().is_some(), Capability::SourceSync => self.as_source_sync().is_some(), Capability::CodingSessions => self.as_coding_sessions().is_some(), + Capability::Scoring => self.as_scoring().is_some(), } } } diff --git a/crates/tinymemory-api/src/provider/mod.rs b/crates/tinymemory-api/src/provider/mod.rs index 01c1591..7b74eb7 100644 --- a/crates/tinymemory-api/src/provider/mod.rs +++ b/crates/tinymemory-api/src/provider/mod.rs @@ -76,6 +76,7 @@ pub mod people; pub mod profile; pub mod records; pub mod retrieval; +pub mod scoring; pub mod sessions; pub mod sync; // The value types every family exchanges, defined in `tinymemory-bus` and @@ -109,6 +110,7 @@ pub use retrieval::{ CoverWindowQuery, EntityMatch, FastRetrieveQuery, MemoryRetrieval, RetrievalHit, RetrievalNodeKind, RetrievalResponse, SourceRetrievalQuery, }; +pub use scoring::MemoryScoring; pub use sessions::{ CodingSessionIngestReport, CodingSessionIngestRequest, CodingSessionSource, MemoryCodingSessions, diff --git a/crates/tinymemory-api/src/provider/scoring.rs b/crates/tinymemory-api/src/provider/scoring.rs new file mode 100644 index 0000000..2d8a8d1 --- /dev/null +++ b/crates/tinymemory-api/src/provider/scoring.rs @@ -0,0 +1,61 @@ +//! [`MemoryScoring`] — scoring and NLP operations exposed over the bus. +//! +//! This family carries the three operations that currently keep +//! `tinymemory-core` in the host's build graph: entity extraction, text +//! embedding, and embedder identification. Moving them behind the bus lets +//! every call site that reached the engine directly for these purposes route +//! through the contract instead. +//! +//! ## Design note — why the host requests, not constructs +//! +//! The host previously constructed an embedder from config and called it +//! directly. That pattern cannot cross the bus: config is host-side, the +//! embedder lives in the module. The correct shape is that the host asks the +//! driver to perform the operation by intent (`embed_text`) and to identify +//! which provider is active (`embedder_slug`), delegating both the construction +//! and the execution to the driver. + +use async_trait::async_trait; + +use crate::error::MemoryError; + +/// Scoring and NLP operations exposed over the bus. +#[async_trait] +pub trait MemoryScoring: Send + Sync { + /// Extract canonical entity strings from a natural-language query. + /// + /// Returns `":"` strings in the same namespace as the indexed + /// chunk entities. An empty result means the query is ungrounded — no + /// entity anchors were found — which routes retrieval toward the global + /// (dense) branch rather than the entity-indexed branch. + /// + /// Never fails: when the NLP backend is unavailable the implementation + /// degrades to a regex extractor rather than returning an error. + /// + /// # Errors + /// + /// Only infrastructure failures (e.g. the module bus is down). The NLP + /// step itself never errors — it degrades gracefully. + async fn extract_entities(&self, query: &str) -> Result, MemoryError>; + + /// Embed a text string with the active embedder. + /// + /// Returns a float vector; the length matches the active embedding + /// dimension (currently 1024 for the default bge-m3 model). + /// + /// # Errors + /// + /// When no embedder is configured (`Unsupported`) or the embedding call + /// fails (e.g. the Ollama server is unreachable). + async fn embed_text(&self, text: &str) -> Result, MemoryError>; + + /// Stable string identifying which embedder provider is currently active. + /// + /// One of: `"ollama"`, `"none"`, `"custom"`, `"cloud"`, `"unconfigured"`. + /// Used by the host to decide how to attribute embedding costs in the UI. + /// + /// # Errors + /// + /// Only infrastructure failures. Config resolution itself never errors. + async fn embedder_slug(&self) -> Result; +} diff --git a/crates/tinymemory-bus/src/capabilities.rs b/crates/tinymemory-bus/src/capabilities.rs index 2a4600d..a90edf9 100644 --- a/crates/tinymemory-bus/src/capabilities.rs +++ b/crates/tinymemory-bus/src/capabilities.rs @@ -113,6 +113,9 @@ pub enum Capability { /// walk. Advertising them together would put a dead control in front of /// whichever half is absent. CodingSessions, + /// Scoring and NLP operations: entity extraction, text embedding, and + /// embedder identification. + Scoring, } impl Capability { @@ -121,7 +124,7 @@ impl Capability { /// Declaration order is also bit order in [`Capabilities`] and iteration /// order in its serialized form, so this slice is the single ordering /// authority for the whole module. - pub const ALL: [Capability; 20] = [ + pub const ALL: [Capability; 21] = [ Capability::Core, Capability::Recall, Capability::Ingest, @@ -145,6 +148,7 @@ impl Capability { Capability::Episodic, Capability::SourceSync, Capability::CodingSessions, + Capability::Scoring, ]; /// The families a driver must advertise to be bindable at all. @@ -190,6 +194,7 @@ impl Capability { Self::Episodic => "episodic", Self::SourceSync => "source_sync", Self::CodingSessions => "coding_sessions", + Self::Scoring => "scoring", } } @@ -239,6 +244,7 @@ impl Capability { Self::Episodic => 17, Self::SourceSync => 18, Self::CodingSessions => 19, + Self::Scoring => 20, } } diff --git a/crates/tinymemory-bus/src/capabilities_tests.rs b/crates/tinymemory-bus/src/capabilities_tests.rs index 6f0ce9e..19f9230 100644 --- a/crates/tinymemory-bus/src/capabilities_tests.rs +++ b/crates/tinymemory-bus/src/capabilities_tests.rs @@ -2,7 +2,7 @@ //! //! Three properties are load-bearing and each has its own test: //! -//! 1. the enum has exactly the twenty contract families and no more; +//! 1. the enum has exactly the twenty-one contract families and no more; //! 2. the serialized form is stable snake_case **strings**, never discriminant //! integers — a driver deployed against an older build must keep advertising //! the same set after a variant is inserted mid-enum; @@ -19,9 +19,9 @@ use super::*; use serde_json::json; #[test] -fn capability_has_exactly_the_twenty_contract_families() { - assert_eq!(Capability::ALL.len(), 20); - assert_eq!(Capability::all().len(), 20); +fn capability_has_exactly_the_twenty_one_contract_families() { + assert_eq!(Capability::ALL.len(), 21); + assert_eq!(Capability::all().len(), 21); let names: Vec<&str> = Capability::ALL.iter().map(|c| c.as_str()).collect(); assert_eq!( @@ -47,6 +47,7 @@ fn capability_has_exactly_the_twenty_contract_families() { "episodic", "source_sync", "coding_sessions", + "scoring", ] ); } diff --git a/crates/tinymemory-module/src/lib.rs b/crates/tinymemory-module/src/lib.rs index cd0ba88..70d56ed 100644 --- a/crates/tinymemory-module/src/lib.rs +++ b/crates/tinymemory-module/src/lib.rs @@ -783,6 +783,10 @@ mod exports { // Local coding-agent transcripts. "CodingSessionStatus", "IngestCodingSessions", + // Scoring: entity extraction, text embedding, embedder identification. + "ExtractEntities", + "EmbedText", + "EmbedderSlug", ], signals = [], // The host's embedder is deliberately NOT declared as `requires`. That diff --git a/crates/tinymemory-module/src/service/mod.rs b/crates/tinymemory-module/src/service/mod.rs index 29126d6..1afeb6d 100644 --- a/crates/tinymemory-module/src/service/mod.rs +++ b/crates/tinymemory-module/src/service/mod.rs @@ -77,6 +77,10 @@ //! //! CodingSessionStatus() -> [CodingSessionSource] //! IngestCodingSessions(request) -> CodingSessionIngestReport +//! +//! ExtractEntities(query) -> [String] +//! EmbedText(text) -> [f32] +//! EmbedderSlug() -> String //! ``` //! //! # Source scope crosses as an argument, never as ambient state @@ -172,6 +176,7 @@ use tinymemory_api::provider::retrieval::{ CoverWindowQuery, EntityMatch, FastRetrieveQuery, RetrievalHit, RetrievalResponse, SourceRetrievalQuery, }; +use tinymemory_api::provider::scoring::MemoryScoring; use tinymemory_api::provider::sessions::{ CodingSessionIngestReport, CodingSessionIngestRequest, CodingSessionSource, }; @@ -1896,6 +1901,27 @@ impl MemoryService { .await .map_err(|error| into_bus_error(&error)) } + + async fn extract_entities(&self, query: String) -> BusResult> { + require_family!(self, as_scoring, Capability::Scoring) + .extract_entities(&query) + .await + .map_err(|error| into_bus_error(&error)) + } + + async fn embed_text(&self, text: String) -> BusResult> { + require_family!(self, as_scoring, Capability::Scoring) + .embed_text(&text) + .await + .map_err(|error| into_bus_error(&error)) + } + + async fn embedder_slug(&self) -> BusResult { + require_family!(self, as_scoring, Capability::Scoring) + .embedder_slug() + .await + .map_err(|error| into_bus_error(&error)) + } } /// The response-size ceiling for a method that returns a list of entries. diff --git a/crates/tinymemory-tinycortex/src/engine/mod.rs b/crates/tinymemory-tinycortex/src/engine/mod.rs index 744bd45..55f112d 100644 --- a/crates/tinymemory-tinycortex/src/engine/mod.rs +++ b/crates/tinymemory-tinycortex/src/engine/mod.rs @@ -49,7 +49,7 @@ use tinymemory_api::provider::{ FacetType, FastRetrieveQuery, MemoryChunks, MemoryCodingSessions, MemoryCore, MemoryDiff, MemoryDocuments, MemoryEntities, MemoryEpisodic, MemoryGoals, MemoryGraph, MemoryIngest, MemoryMaintenance, MemoryPeople, MemoryPortability, MemoryProfile, MemoryProvider, - MemoryRecall, MemoryRetrieval, MemorySourceSink, MemorySourceSync, MemoryToolMemory, + MemoryRecall, MemoryRetrieval, MemoryScoring, MemorySourceSink, MemorySourceSync, MemoryToolMemory, MemoryTree, PersonHandle, PersonInteraction, PersonRecord, PersonScore, ProfileFacet, RankedPerson, RawArchiveCoverage, RawRebuildOutcome, ResolvedPerson, RetrievalHit, RetrievalResponse, SourceRetrievalQuery, SourceSyncState, SourceSyncStatus, SourceTotal, @@ -2343,6 +2343,9 @@ impl MemoryProvider for TinycortexProvider { fn as_coding_sessions(&self) -> Option<&dyn MemoryCodingSessions> { Some(self) } + fn as_scoring(&self) -> Option<&dyn MemoryScoring> { + Some(self) + } } // ── Source sync ────────────────────────────────────────────────────────────── @@ -2786,6 +2789,47 @@ impl MemoryCodingSessions for TinycortexProvider { } } +// ── Scoring ────────────────────────────────────────────────────────────────── + +#[async_trait] +impl MemoryScoring for TinycortexProvider { + async fn extract_entities(&self, query: &str) -> Result, MemoryError> { + let config = self.config.clone(); + let query = query.to_owned(); + let entities = + tokio::task::spawn_blocking(move || { + tokio::runtime::Handle::current().block_on( + tinymemory_core::tree::nlp::extract_query_entities(&config, &query), + ) + }) + .await + .map_err(|error| Self::other("extract entities", error))?; + Ok(entities.into_iter().map(|e| e.canonical_id).collect()) + } + + async fn embed_text(&self, text: &str) -> Result, MemoryError> { + let config = self.config.clone(); + let text = text.to_owned(); + tokio::task::spawn_blocking(move || { + let embedder = + tinymemory_core::tree::score::embed::factory::build_embedder_from_config(&config) + .map_err(|error| MemoryError::Other(anyhow::anyhow!("{error}")))?; + tokio::runtime::Handle::current() + .block_on(embedder.embed(&text)) + .map_err(|error| MemoryError::Other(anyhow::anyhow!("{error}"))) + }) + .await + .map_err(|error| Self::other("embed text", error))? + } + + async fn embedder_slug(&self) -> Result { + Ok( + tinymemory_core::tree::score::embed::factory::effective_embedder_slug(&self.config) + .to_string(), + ) + } +} + // ── People ─────────────────────────────────────────────────────────────────── // // The conversions below destructure both sides exhaustively rather than From 6d7f0fffcb49822b0260c7eb053e917454954a95 Mon Sep 17 00:00:00 2001 From: shanu Date: Thu, 27 Aug 2026 16:59:02 +0530 Subject: [PATCH 2/5] style: cargo fmt --- crates/tinymemory-api/src/null.rs | 4 +-- .../tinymemory-tinycortex/src/engine/mod.rs | 25 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/crates/tinymemory-api/src/null.rs b/crates/tinymemory-api/src/null.rs index 9f12685..dffd04f 100644 --- a/crates/tinymemory-api/src/null.rs +++ b/crates/tinymemory-api/src/null.rs @@ -64,8 +64,8 @@ use crate::provider::{ CodingSessionIngestRequest, CodingSessionSource, CoverWindowQuery, EntityMatch, FacetType, FastRetrieveQuery, MemoryChunks, MemoryCodingSessions, MemoryCore, MemoryDiff, MemoryDocuments, MemoryEntities, MemoryGoals, MemoryGraph, MemoryIngest, MemoryMaintenance, MemoryPeople, - MemoryPortability, MemoryProfile, MemoryProvider, MemoryRecall, MemoryRetrieval, - MemoryScoring, MemorySourceSink, MemorySourceSync, MemoryToolMemory, MemoryTree, PersonHandle, + MemoryPortability, MemoryProfile, MemoryProvider, MemoryRecall, MemoryRetrieval, MemoryScoring, + MemorySourceSink, MemorySourceSync, MemoryToolMemory, MemoryTree, PersonHandle, PersonInteraction, PersonRecord, PersonScore, ProfileFacet, RankedPerson, RawArchiveCoverage, RawRebuildOutcome, ResolvedPerson, RetrievalHit, RetrievalResponse, SourceRetrievalQuery, SourceSyncState, SourceSyncStatus, SyncAuditEntry, SyncRunOutcome, UserState, diff --git a/crates/tinymemory-tinycortex/src/engine/mod.rs b/crates/tinymemory-tinycortex/src/engine/mod.rs index 55f112d..a39b7b2 100644 --- a/crates/tinymemory-tinycortex/src/engine/mod.rs +++ b/crates/tinymemory-tinycortex/src/engine/mod.rs @@ -49,11 +49,11 @@ use tinymemory_api::provider::{ FacetType, FastRetrieveQuery, MemoryChunks, MemoryCodingSessions, MemoryCore, MemoryDiff, MemoryDocuments, MemoryEntities, MemoryEpisodic, MemoryGoals, MemoryGraph, MemoryIngest, MemoryMaintenance, MemoryPeople, MemoryPortability, MemoryProfile, MemoryProvider, - MemoryRecall, MemoryRetrieval, MemoryScoring, MemorySourceSink, MemorySourceSync, MemoryToolMemory, - MemoryTree, PersonHandle, PersonInteraction, PersonRecord, PersonScore, ProfileFacet, - RankedPerson, RawArchiveCoverage, RawRebuildOutcome, ResolvedPerson, RetrievalHit, - RetrievalResponse, SourceRetrievalQuery, SourceSyncState, SourceSyncStatus, SourceTotal, - SyncAuditEntry, SyncFreshness, SyncRunOutcome, UserState, + MemoryRecall, MemoryRetrieval, MemoryScoring, MemorySourceSink, MemorySourceSync, + MemoryToolMemory, MemoryTree, PersonHandle, PersonInteraction, PersonRecord, PersonScore, + ProfileFacet, RankedPerson, RawArchiveCoverage, RawRebuildOutcome, ResolvedPerson, + RetrievalHit, RetrievalResponse, SourceRetrievalQuery, SourceSyncState, SourceSyncStatus, + SourceTotal, SyncAuditEntry, SyncFreshness, SyncRunOutcome, UserState, }; use tinymemory_api::recall::OwnedRecallOpts; use tinymemory_api::tool_memory::ToolMemoryRule; @@ -2796,14 +2796,13 @@ impl MemoryScoring for TinycortexProvider { async fn extract_entities(&self, query: &str) -> Result, MemoryError> { let config = self.config.clone(); let query = query.to_owned(); - let entities = - tokio::task::spawn_blocking(move || { - tokio::runtime::Handle::current().block_on( - tinymemory_core::tree::nlp::extract_query_entities(&config, &query), - ) - }) - .await - .map_err(|error| Self::other("extract entities", error))?; + let entities = tokio::task::spawn_blocking(move || { + tokio::runtime::Handle::current().block_on( + tinymemory_core::tree::nlp::extract_query_entities(&config, &query), + ) + }) + .await + .map_err(|error| Self::other("extract entities", error))?; Ok(entities.into_iter().map(|e| e.canonical_id).collect()) } From 3c9f2cc1784a5b81bb51ef0c7e64591c2203f6c3 Mon Sep 17 00:00:00 2001 From: shanu Date: Thu, 27 Aug 2026 17:04:56 +0530 Subject: [PATCH 3/5] fix: remove unused MemoryScoring import in service/mod.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The #[tinybus::interface] macro brings family traits into scope internally when generating dispatch code — no other family trait (MemoryRetrieval, MemoryCodingSessions, etc.) is imported at the module level either. The import was added incorrectly; the pattern is consistent without it. --- crates/tinymemory-module/src/service/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/tinymemory-module/src/service/mod.rs b/crates/tinymemory-module/src/service/mod.rs index 1afeb6d..92766b9 100644 --- a/crates/tinymemory-module/src/service/mod.rs +++ b/crates/tinymemory-module/src/service/mod.rs @@ -176,7 +176,6 @@ use tinymemory_api::provider::retrieval::{ CoverWindowQuery, EntityMatch, FastRetrieveQuery, RetrievalHit, RetrievalResponse, SourceRetrievalQuery, }; -use tinymemory_api::provider::scoring::MemoryScoring; use tinymemory_api::provider::sessions::{ CodingSessionIngestReport, CodingSessionIngestRequest, CodingSessionSource, }; From b2c3eded7b4c34cbdf6dfa33c8725ad4c20236e5 Mon Sep 17 00:00:00 2001 From: shanu Date: Thu, 27 Aug 2026 17:20:23 +0530 Subject: [PATCH 4/5] fix: register ExtractEntities/EmbedText/EmbedderSlug in tinymemory-bus names The module serves these three Scoring family methods but they were absent from METHODS in tinymemory-bus, causing the served-vs-published contract test to fail. Adds the three constants to the methods module and appends them to METHODS (123 -> 126), in the same declaration order as the module. --- crates/tinymemory-bus/src/names.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/tinymemory-bus/src/names.rs b/crates/tinymemory-bus/src/names.rs index 9ebdf9e..065f588 100644 --- a/crates/tinymemory-bus/src/names.rs +++ b/crates/tinymemory-bus/src/names.rs @@ -316,6 +316,14 @@ pub mod methods { pub const CODING_SESSION_STATUS: &str = "CodingSessionStatus"; /// `IngestCodingSessions` — distil coding sessions into observations. pub const INGEST_CODING_SESSIONS: &str = "IngestCodingSessions"; + + // Scoring family — entity extraction and text embedding through the bus. + /// `ExtractEntities` — extract canonical entity ids from a query string. + pub const EXTRACT_ENTITIES: &str = "ExtractEntities"; + /// `EmbedText` — produce a dense embedding vector for an arbitrary string. + pub const EMBED_TEXT: &str = "EmbedText"; + /// `EmbedderSlug` — the stable identifier of the active embedder. + pub const EMBEDDER_SLUG: &str = "EmbedderSlug"; } /// Every member name, in the order the module declares them. @@ -323,7 +331,7 @@ pub mod methods { /// The order matters: `tinybus`'s `Interface::members()` returns declaration /// order, and the module compares the two sequences directly rather than as /// sets, so a reordering is caught alongside an addition or a removal. -pub const METHODS: [&str; 123] = [ +pub const METHODS: [&str; 126] = [ methods::DRIVER_ID, methods::CAPABILITIES, methods::HEALTH, @@ -447,6 +455,9 @@ pub const METHODS: [&str; 123] = [ methods::REBUILD_FROM_RAW_ARCHIVE, methods::CODING_SESSION_STATUS, methods::INGEST_CODING_SESSIONS, + methods::EXTRACT_ENTITIES, + methods::EMBED_TEXT, + methods::EMBEDDER_SLUG, ]; #[cfg(test)] From 708d3e79894dc0b84be984480d353427fc486b29 Mon Sep 17 00:00:00 2001 From: shanu Date: Thu, 27 Aug 2026 17:38:27 +0530 Subject: [PATCH 5/5] fix: add ExtractEntities/EmbedText/EmbedderSlug to EXPECTED_METHODS in module_e2e --- crates/tinymemory-module/tests/module_e2e.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/tinymemory-module/tests/module_e2e.rs b/crates/tinymemory-module/tests/module_e2e.rs index 315ff45..398acf7 100644 --- a/crates/tinymemory-module/tests/module_e2e.rs +++ b/crates/tinymemory-module/tests/module_e2e.rs @@ -705,6 +705,10 @@ const EXPECTED_METHODS: &[&str] = &[ "RebuildFromRawArchive", "CodingSessionStatus", "IngestCodingSessions", + // Scoring family. + "ExtractEntities", + "EmbedText", + "EmbedderSlug", ]; #[tokio::test]