mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
* 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) <noreply@anthropic.com> --------- Co-authored-by: sanil jain <jainsanil18@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
sanil jain
Claude Opus 4.6
parent
898fe13477
commit
bd8d3ed15a
@@ -203,9 +203,14 @@ export async function restartCoreProcess(): Promise<void> {
|
||||
// --- 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<void> {
|
||||
console.debug(
|
||||
@@ -213,12 +218,13 @@ export async function syncMemoryClientToken(token: string): Promise<void> {
|
||||
!!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<boolean>({ method: 'openhuman.memory_init', params: { jwt_token: token } });
|
||||
console.info('[memory] syncMemoryClientToken: exit — ok');
|
||||
} catch (err) {
|
||||
|
||||
@@ -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<Self> {
|
||||
// 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<Self, String> { /* ... */ }
|
||||
pub fn from_workspace_dir(workspace_dir: PathBuf) -> Result<Self, String> { /* ... */ }
|
||||
```
|
||||
|
||||
The client is stored as `Arc<MemoryClient>` inside a `Mutex<Option<MemoryClientRef>>` (`MemoryState`), shared across Tauri commands.
|
||||
The client is stored as `Arc<MemoryClient>` inside a `Mutex<Option<MemoryClientRef>>` (`MemoryState`), shared across RPC handlers.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+11
-5
@@ -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]
|
||||
|
||||
@@ -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<RpcOutcome<ApiEnvelope<MemoryInitResponse>>, 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);
|
||||
|
||||
@@ -43,10 +43,15 @@ pub struct ApiEnvelope<T> {
|
||||
#[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<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -12,16 +12,17 @@ pub type MemoryClientRef = Arc<MemoryClient>;
|
||||
|
||||
pub struct MemoryState(pub std::sync::Mutex<Option<MemoryClientRef>>);
|
||||
|
||||
/// 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<UnifiedMemory>,
|
||||
}
|
||||
|
||||
impl MemoryClient {
|
||||
pub fn from_token(_jwt_token: String) -> Option<Self> {
|
||||
Self::new_local().ok()
|
||||
}
|
||||
|
||||
pub fn new_local() -> Result<Self, String> {
|
||||
let workspace_dir = dirs::home_dir()
|
||||
.ok_or_else(|| "Failed to resolve home directory".to_string())?
|
||||
|
||||
Reference in New Issue
Block a user