From d6961d1bc34ddc3d44825d776da9d4f16d45dd8e Mon Sep 17 00:00:00 2001 From: DeadlySilent Date: Wed, 20 May 2026 21:48:44 +0000 Subject: [PATCH] fix(memory): accept time_window_days global alias MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Allows `QueryGlobalRequest` to deserialize `time_window_days` as an alias for `window_days`. - Updates the consolidated `memory_tree` tool schema to expose the canonical `window_days` field for `query_global` while preserving the existing `time_window_days` compatibility path. - Adds regression tests for the alias and consolidated schema exposure. ## Problem The consolidated `memory_tree` tool advertised `time_window_days` for `query_global`, but the backend deserialized `query_global` arguments into: ```rust QueryGlobalRequest { window_days: u32 } ``` So calls shaped like this failed with `missing field 'window_days'`: ```json { "mode": "query_global", "time_window_days": 7 } ``` ## Solution Accept `time_window_days` as a serde alias for `window_days`: ```rust #[serde(alias = "time_window_days")] pub window_days: u32, ``` and make the consolidated schema explicit about `window_days` for `query_global`. ## Submission Checklist - [x] Tests added or updated (happy path + failure / edge case): alias deserialization test and consolidated schema exposure test added. - [x] N/A: Diff coverage >= 80% — local coverage tooling could not be run in this environment; changed behavior is covered by focused unit tests in source. - [x] N/A: Coverage matrix updated — bug fix to existing tool schema/deserialization behavior; no feature row added/removed/renamed. - [x] N/A: All affected feature IDs from the matrix are listed — no matrix feature row changed. - [x] No new external network dependencies introduced. - [x] N/A: Manual smoke checklist updated — internal memory tool schema/deserialization fix. - [x] Linked issue closed via `Closes #2252`. ## Impact - Runtime/platform impact: Rust core memory tree request deserialization and tool schema only. - Compatibility impact: back-compatible; existing callers using `window_days` continue to work, and consolidated tool callers using `time_window_days` now work too. - Security impact: none; no new capability or external access. ## Related Closes #2252 --- ## AI Authored PR Metadata ### Linear Issue - Key: N/A - URL: N/A ### Commit & Branch - Branch: `fix/memory-tree-window-alias` - Commit SHA: `c3350ae` ### Validation Run - [x] `pnpm --filter openhuman-app format:check` — N/A: Rust-only change. - [x] `pnpm typecheck` — N/A: Rust-only change. - [x] Focused tests: attempted `cargo test --manifest-path Cargo.toml memory_tree --lib`; blocked locally, see below. - [x] Rust fmt/check: attempted `cargo fmt --check`; blocked locally, see below. - [x] Tauri fmt/check: N/A: no `app/src-tauri` changes. ### Validation Blocked - `command:` `cargo fmt --check` - `error:` `error: no such command: fmt` - `impact:` Local environment has Rust 1.75 without rustfmt installed; formatting should be verified by CI. - `command:` `cargo test --manifest-path Cargo.toml memory_tree --lib` - `error:` `failed to parse lock file ... Cargo.lock; lock file version 4 requires -Znext-lockfile-bump` - `impact:` Local cargo is 1.75 and cannot read the repository's lockfile format; CI/newer cargo should run the focused tests. ### Behavior Changes - Intended behavior change: `memory_tree` global queries accept both `window_days` and the consolidated-schema alias `time_window_days`. - User-visible effect: LLM/tool calls using the advertised consolidated field no longer fail with missing `window_days`. ### Parity Contract - Legacy behavior preserved: existing `window_days` callers continue to deserialize identically. - Guard/fallback/dispatch parity checks: only request deserialization/schema metadata changed; query execution remains unchanged. ### Duplicate / Superseded PR Handling - Duplicate PR(s): none known. - Canonical PR: this PR. - Resolution: N/A. ## Summary by CodeRabbit * **Improvements** * Memory query endpoints now accept an alternate parameter name ("time_window_days") in requests for compatibility with existing clients. * The memory tool’s parameter schema now exposes both "window_days" and "time_window_days" so interfaces can supply either field. [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2255?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) Co-authored-by: ClawHub Builder Co-authored-by: Steven Enamakel --- src/openhuman/memory/tree/retrieval/rpc.rs | 11 +++++++++++ src/openhuman/tools/impl/memory/tree/mod.rs | 17 ++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/openhuman/memory/tree/retrieval/rpc.rs b/src/openhuman/memory/tree/retrieval/rpc.rs index 31b4dd587..8731d908c 100644 --- a/src/openhuman/memory/tree/retrieval/rpc.rs +++ b/src/openhuman/memory/tree/retrieval/rpc.rs @@ -84,6 +84,7 @@ pub async fn query_source_rpc( /// Request body for `memory_tree_query_global`. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct QueryGlobalRequest { + #[serde(alias = "time_window_days")] pub window_days: u32, } @@ -421,6 +422,16 @@ mod tests { ); } + #[test] + fn query_global_request_accepts_consolidated_time_window_alias() { + let req: QueryGlobalRequest = serde_json::from_value(serde_json::json!({ + "time_window_days": 7 + })) + .expect("time_window_days alias should deserialize"); + + assert_eq!(req.window_days, 7); + } + // ── query_topic_rpc ─────────────────────────────────────────────── #[tokio::test] diff --git a/src/openhuman/tools/impl/memory/tree/mod.rs b/src/openhuman/tools/impl/memory/tree/mod.rs index 2030ae10c..623311a46 100644 --- a/src/openhuman/tools/impl/memory/tree/mod.rs +++ b/src/openhuman/tools/impl/memory/tree/mod.rs @@ -83,7 +83,11 @@ impl Tool for MemoryTreeTool { }, "time_window_days": { "type": "integer", - "description": "query_source/query_global: look-back window in days." + "description": "query_source/query_topic: look-back window in days. query_global also accepts this as a compatibility alias." + }, + "window_days": { + "type": "integer", + "description": "query_global: look-back window in days." }, // drill_down params "node_id": { @@ -197,6 +201,17 @@ mod memory_tree_dispatcher_tests { assert!(modes.contains(&"ingest_document")); } + #[test] + fn memory_tree_schema_exposes_global_window_days() { + let schema = MemoryTreeTool.parameters_schema(); + let properties = schema + .get("properties") + .and_then(|p| p.as_object()) + .unwrap(); + assert!(properties.contains_key("window_days")); + assert!(properties.contains_key("time_window_days")); + } + #[tokio::test] async fn memory_tree_unknown_mode_returns_error() { let result = MemoryTreeTool