From bd8d3ed15a925c3fb7cc4140fc4c6bea9890d9d0 Mon Sep 17 00:00:00 2001 From: sanil-23 Date: Fri, 3 Apr 2026 17:23:02 +0530 Subject: [PATCH] fix(memory): clean up unused JWT token parameter in memory init (#204) (#300) * fix: patch whisper-rs-sys for Windows MSVC static CRT (/MT) The upstream whisper-rs-sys builds whisper.cpp via CMake which defaults to /MD (dynamic CRT), but Rust and all other C deps use /MT (static CRT). This causes LNK2038/LNK1169 linker errors on Windows. Patch whisper-rs-sys from tinyhumansai/whisper-rs-sys fork which adds config.static_crt(true) and overrides all per-config CMake flags (Debug/Release/MinSizeRel/RelWithDebInfo) from /MD to /MT. Closes #273 * fix: clean up unused JWT token parameter in memory init Memory is local-only (SQLite). The from_token() method accepted a JWT but ignored it, always falling back to new_local(). Remove the dead method, make jwt_token optional in MemoryInitRequest for backward compat, and document the local-only design. Closes #204 Co-Authored-By: Claude Opus 4.6 (1M context) --------- Co-authored-by: sanil jain Co-authored-by: Claude Opus 4.6 (1M context) --- app/src/utils/tauriCommands.ts | 18 ++++++++++++------ docs/tinyhumansai-sdk.md | 19 +++++++++---------- src/core/jsonrpc.rs | 16 +++++++++++----- src/openhuman/memory/ops.rs | 8 +++++--- src/openhuman/memory/rpc_models.rs | 7 ++++++- src/openhuman/memory/schemas.rs | 8 ++++---- src/openhuman/memory/store/client.rs | 9 +++++---- 7 files changed, 52 insertions(+), 33 deletions(-) diff --git a/app/src/utils/tauriCommands.ts b/app/src/utils/tauriCommands.ts index 10b47cdf2..97d550e24 100644 --- a/app/src/utils/tauriCommands.ts +++ b/app/src/utils/tauriCommands.ts @@ -203,9 +203,14 @@ export async function restartCoreProcess(): Promise { // --- Memory Commands --- /** - * Initialise the TinyHumans memory client in Rust with the user's JWT token - * (sourced from `authSlice.token` in Redux). Call this after login and after - * Redux Persist rehydration. + * Initialise the local-only (SQLite) memory subsystem in the Rust core. + * + * The `token` parameter is accepted for backward compatibility with callers + * that pass the user's JWT, but the core **ignores** it — all memory storage + * and retrieval is local. Remote/cloud memory sync is a future consideration. + * + * Call this after login and after Redux Persist rehydration so the core + * process has a ready memory client for the current workspace. */ export async function syncMemoryClientToken(token: string): Promise { console.debug( @@ -213,12 +218,13 @@ export async function syncMemoryClientToken(token: string): Promise { !!token, isTauri() ); - if (!isTauri() || !token) { - console.debug('[memory] syncMemoryClientToken: exit — skipped (not Tauri or empty token)'); + if (!isTauri()) { + console.debug('[memory] syncMemoryClientToken: exit — skipped (not Tauri)'); return; } try { - console.debug('[memory] syncMemoryClientToken: payload → memory.init'); + console.debug('[memory] syncMemoryClientToken: payload → memory.init (local-only)'); + // jwt_token is passed for backward compatibility but ignored by the core. await callCoreRpc({ method: 'openhuman.memory_init', params: { jwt_token: token } }); console.info('[memory] syncMemoryClientToken: exit — ok'); } catch (err) { diff --git a/docs/tinyhumansai-sdk.md b/docs/tinyhumansai-sdk.md index 81c215628..3d8b0577f 100644 --- a/docs/tinyhumansai-sdk.md +++ b/docs/tinyhumansai-sdk.md @@ -375,20 +375,19 @@ Both `document_id` and `namespace` are required (validated before the request is **File:** `src-tauri/src/memory/mod.rs` -The project wraps `TinyHumansMemoryClient` in a `MemoryClient` struct. Construction happens at runtime via the `init_memory_client` Tauri command, using the user's JWT from Redux `authSlice.token` — not a hardcoded API key. +The project wraps memory operations in a `MemoryClient` struct backed by local SQLite +(via `UnifiedMemory`). Construction happens at runtime via the `openhuman.memory_init` +RPC method. Memory is **local-only** — the `jwt_token` parameter in the init request +is accepted for backward compatibility but ignored. Remote/cloud memory sync is a +future consideration. ```rust -pub fn from_token(jwt_token: String) -> Option { - // Base URL resolved in order: - // 1. OPENHUMAN_BASE_URL env var - // 2. TINYHUMANS_BASE_URL env var - // 3. get_backend_url() — app's configured backend - let config = TinyHumanConfig::new(jwt_token).with_base_url(resolved_url); - TinyHumansMemoryClient::new(config).ok().map(|inner| Self { inner }) -} +// Local-only — no remote sync. +pub fn new_local() -> Result { /* ... */ } +pub fn from_workspace_dir(workspace_dir: PathBuf) -> Result { /* ... */ } ``` -The client is stored as `Arc` inside a `Mutex>` (`MemoryState`), shared across Tauri commands. +The client is stored as `Arc` inside a `Mutex>` (`MemoryState`), shared across RPC handlers. --- diff --git a/src/core/jsonrpc.rs b/src/core/jsonrpc.rs index 0933300bc..25e33ec58 100644 --- a/src/core/jsonrpc.rs +++ b/src/core/jsonrpc.rs @@ -697,11 +697,17 @@ mod tests { } #[tokio::test] - async fn invoke_memory_init_missing_required_param_fails() { - let err = invoke_method(default_state(), "openhuman.memory_init", json!({})) - .await - .expect_err("missing jwt_token should fail"); - assert!(err.contains("jwt_token")); + async fn invoke_memory_init_accepts_empty_params() { + // jwt_token is optional (accepted for backward compat but ignored). + // The call may still fail for workspace reasons in test, but must NOT + // fail with a missing-param error for jwt_token. + let result = invoke_method(default_state(), "openhuman.memory_init", json!({})).await; + if let Err(ref e) = result { + assert!( + !e.contains("missing required param") || !e.contains("jwt_token"), + "jwt_token should be optional, got: {e}" + ); + } } #[tokio::test] diff --git a/src/openhuman/memory/ops.rs b/src/openhuman/memory/ops.rs index 85f94c4b4..d8735c9d4 100644 --- a/src/openhuman/memory/ops.rs +++ b/src/openhuman/memory/ops.rs @@ -736,12 +736,14 @@ pub async fn graph_query( Ok(RpcOutcome::single_log(rows, "memory graph queried")) } +/// Initialise the local-only (SQLite) memory subsystem for the current workspace. +/// +/// `request.jwt_token` is accepted for backward compatibility but ignored — all +/// memory operations are local. Remote/cloud sync is a future consideration. pub async fn memory_init( request: MemoryInitRequest, ) -> Result>, String> { - if request.jwt_token.trim().is_empty() { - return Err("jwt_token must not be empty".to_string()); - } + let _ = request.jwt_token; // accepted but unused — memory is local-only let workspace_dir = current_workspace_dir().await?; let client = Arc::new(MemoryClient::from_workspace_dir(workspace_dir.clone())?); *lock_memory_client_state()? = Some(client); diff --git a/src/openhuman/memory/rpc_models.rs b/src/openhuman/memory/rpc_models.rs index c58f4d8d0..e54c74cb9 100644 --- a/src/openhuman/memory/rpc_models.rs +++ b/src/openhuman/memory/rpc_models.rs @@ -43,10 +43,15 @@ pub struct ApiEnvelope { #[serde(deny_unknown_fields)] pub struct EmptyRequest {} +/// Request payload for `openhuman.memory_init`. +/// +/// `jwt_token` is accepted for backward compatibility but **not used** — memory +/// is local-only (SQLite). Remote/cloud memory sync is a future consideration. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct MemoryInitRequest { - pub jwt_token: String, + #[serde(default)] + pub jwt_token: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/src/openhuman/memory/schemas.rs b/src/openhuman/memory/schemas.rs index d47f0c800..77dc7475b 100644 --- a/src/openhuman/memory/schemas.rs +++ b/src/openhuman/memory/schemas.rs @@ -153,12 +153,12 @@ pub fn schemas(function: &str) -> ControllerSchema { "init" => ControllerSchema { namespace: "memory", function: "init", - description: "Initialise the memory subsystem for the current workspace.", + description: "Initialise the local-only (SQLite) memory subsystem for the current workspace. The jwt_token parameter is accepted for backward compatibility but ignored — memory is entirely local.", inputs: vec![FieldSchema { name: "jwt_token", - ty: TypeSchema::String, - comment: "JWT token for authenticating the memory session.", - required: true, + ty: TypeSchema::Option(Box::new(TypeSchema::String)), + comment: "Accepted for backward compatibility but ignored — memory is local-only. Remote sync is a future consideration.", + required: false, }], outputs: vec![FieldSchema { name: "result", diff --git a/src/openhuman/memory/store/client.rs b/src/openhuman/memory/store/client.rs index cd1d39863..b1ca4c5a2 100644 --- a/src/openhuman/memory/store/client.rs +++ b/src/openhuman/memory/store/client.rs @@ -12,16 +12,17 @@ pub type MemoryClientRef = Arc; pub struct MemoryState(pub std::sync::Mutex>); +/// Local-only memory client backed by SQLite in the user's workspace directory. +/// +/// All memory storage and retrieval happens on-device; there is no remote sync. +/// Remote/cloud memory sync is a future consideration — until then the memory +/// subsystem operates entirely locally via [`UnifiedMemory`]. #[derive(Clone)] pub struct MemoryClient { inner: Arc, } impl MemoryClient { - pub fn from_token(_jwt_token: String) -> Option { - Self::new_local().ok() - } - pub fn new_local() -> Result { let workspace_dir = dirs::home_dir() .ok_or_else(|| "Failed to resolve home directory".to_string())?