diff --git a/core/bindings/node/src/engine.rs b/core/bindings/node/src/engine.rs index 359def6b..83adbe9b 100644 --- a/core/bindings/node/src/engine.rs +++ b/core/bindings/node/src/engine.rs @@ -3,7 +3,7 @@ use crate::types::*; use dashmap::DashMap; use engine_orchestrator::EngineOrchestrator; use engine_orchestrator::search::FactId; -use engine_orchestrator::storage::{CandidateFactRow, EmbeddingRow, WriteAck}; +use engine_orchestrator::storage::{CandidateFactRow, EmbeddingRow, RankedFact, WriteAck}; use napi::bindgen_prelude::*; use napi::threadsafe_function::ThreadsafeFunction; use napi_derive::napi; @@ -138,12 +138,44 @@ impl MemoriEngine { tokio::task::spawn_blocking(move || { let req = serde_json::from_value(serde_json::to_value(&request).unwrap()) .map_err(|e| Error::from_reason(format!("Invalid retrieval request: {}", e)))?; - let results = inner + let results: Vec = inner .retrieve(req) .map_err(|e| Error::from_reason(e.to_string()))?; - let napi_results: Vec = - serde_json::from_value(serde_json::to_value(&results).unwrap()) - .map_err(|e| Error::from_reason(e.to_string()))?; + let napi_results = results + .into_iter() + .map(|r| { + let id = match r.id { + FactId::Int(n) => Either::A(n), + FactId::String(s) => Either::B(s), + }; + let summaries = if r.summaries.is_empty() { + None + } else { + Some( + r.summaries + .into_iter() + .map(|s| NapiRecallSummary { + content: s["content"].as_str().unwrap_or("").to_string(), + date_created: s["date_created"] + .as_str() + .unwrap_or("") + .to_string(), + entity_fact_id: fact_id_from_json(&s["entity_fact_id"]), + fact_id: fact_id_from_json(&s["fact_id"]), + }) + .collect(), + ) + }; + NapiRecallObject { + id, + content: r.content, + rank_score: Some(r.rank_score as f64), + similarity: Some(r.similarity as f64), + date_created: Some(r.date_created), + summaries, + } + }) + .collect(); Ok(napi_results) }) .await @@ -200,3 +232,11 @@ impl MemoriEngine { self.inner.shutdown(); } } + +fn fact_id_from_json(v: &serde_json::Value) -> Option> { + match v { + serde_json::Value::Number(n) => n.as_i64().map(Either::A), + serde_json::Value::String(s) => Some(Either::B(s.clone())), + _ => None, + } +} diff --git a/core/bindings/node/src/types.rs b/core/bindings/node/src/types.rs index 7c8c5db5..dcbfbc17 100644 --- a/core/bindings/node/src/types.rs +++ b/core/bindings/node/src/types.rs @@ -15,18 +15,16 @@ pub struct NapiRetrievalRequest { } #[napi(object)] -#[derive(Serialize, Deserialize)] pub struct NapiRecallSummary { pub content: String, pub date_created: String, - pub entity_fact_id: Option, - pub fact_id: Option, + pub entity_fact_id: Option>, + pub fact_id: Option>, } #[napi(object)] -#[derive(Serialize, Deserialize)] pub struct NapiRecallObject { - pub id: i64, + pub id: Either, pub content: String, pub rank_score: Option, pub similarity: Option, diff --git a/memori-ts/package-lock.json b/memori-ts/package-lock.json index 1416442b..7497d764 100644 --- a/memori-ts/package-lock.json +++ b/memori-ts/package-lock.json @@ -1,12 +1,12 @@ { "name": "@memorilabs/memori", - "version": "0.1.16-beta", + "version": "0.1.17-beta", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@memorilabs/memori", - "version": "0.1.16-beta", + "version": "0.1.17-beta", "license": "Apache-2.0", "dependencies": { "@memorilabs/axon": "^0.1.5" diff --git a/memori-ts/package.json b/memori-ts/package.json index 445c2668..c83f521f 100644 --- a/memori-ts/package.json +++ b/memori-ts/package.json @@ -1,6 +1,6 @@ { "name": "@memorilabs/memori", - "version": "0.1.16-beta", + "version": "0.1.17-beta", "description": "The official TypeScript SDK for Memori", "type": "module", "main": "./dist/index.js", diff --git a/memori-ts/src/core/engine.ts b/memori-ts/src/core/engine.ts index b5618055..2f5c9f69 100644 --- a/memori-ts/src/core/engine.ts +++ b/memori-ts/src/core/engine.ts @@ -184,8 +184,8 @@ export class NativeEngine { summaries: r.summaries?.map((s) => ({ content: s.content, date_created: s.dateCreated, - entity_fact_id: s.entityFactId as number, - fact_id: s.factId as number, + entity_fact_id: s.entityFactId as number | string, + fact_id: s.factId as number | string, })), })); } diff --git a/memori-ts/src/native/index.d.ts b/memori-ts/src/native/index.d.ts index c466efc0..ebb1b4c6 100644 --- a/memori-ts/src/native/index.d.ts +++ b/memori-ts/src/native/index.d.ts @@ -61,7 +61,7 @@ export interface NapiMessage { } export interface NapiRecallObject { - id: number; + id: number | string; content: string; rankScore?: number; similarity?: number; @@ -72,8 +72,8 @@ export interface NapiRecallObject { export interface NapiRecallSummary { content: string; dateCreated: string; - entityFactId?: number; - factId?: number; + entityFactId?: number | string; + factId?: number | string; } export interface NapiRetrievalRequest { diff --git a/memori-ts/src/types/api.ts b/memori-ts/src/types/api.ts index 4e63c8e1..d81a94c6 100644 --- a/memori-ts/src/types/api.ts +++ b/memori-ts/src/types/api.ts @@ -14,7 +14,7 @@ export interface RetrievalRequest { * @internal */ export interface RecallObject { - id: number; + id: number | string; content: string; rank_score?: number; similarity?: number; @@ -26,7 +26,7 @@ export interface RecallObject { * Single row from the native N-API `retrieve` response (camelCase before mapping to `RecallObject`). */ export interface NapiRecallRow { - id: number; + id: number | string; content: string; rankScore?: number; similarity?: number; @@ -34,8 +34,8 @@ export interface NapiRecallRow { summaries?: Array<{ content: string; dateCreated: string; - entityFactId?: number; - factId?: number; + entityFactId?: number | string; + factId?: number | string; }>; } @@ -51,8 +51,8 @@ export type RecallItem = string | RecallObject; export interface RecallSummary { content: string; date_created: string; - entity_fact_id: number; - fact_id: number; + entity_fact_id: number | string; + fact_id: number | string; } /** diff --git a/memori-ts/src/utils/utils.ts b/memori-ts/src/utils/utils.ts index 4bb0eb5b..c5e55743 100644 --- a/memori-ts/src/utils/utils.ts +++ b/memori-ts/src/utils/utils.ts @@ -51,7 +51,7 @@ export function formatSummariesFromFacts(facts: ParsedFact[]): string[] { function attachRawSummariesToFacts(facts: RecallItem[], summaries: RecallSummary[]): RecallItem[] { if (summaries.length === 0) return facts; - const summariesByFactId = new Map(); + const summariesByFactId = new Map(); for (const summary of summaries) { const summaryFactId = summary.entity_fact_id;