mirror of
https://github.com/samvallad33/vestige.git
synced 2026-05-02 20:32:37 +02:00
fix(graph): default /api/graph to newest-memory center, add sort param
memory_timeline PR #37 exposed the same class of bug in the graph endpoint: the dashboard Graph page (and the /api/graph endpoint it hits) defaulted to centering on the most-connected memory, ran BFS at depth 3, and capped the subgraph at 150 nodes. On a mature corpus this clustered the visualization around a historical hotspot and hid freshly ingested memories that hadn't accumulated edges yet. User-visible symptom: TimeSlider on /graph showing "Feb 21 → Mar 1 2026" when the database actually contains memories through today (Apr 20). **Backend (`crates/vestige-mcp/src/dashboard/handlers.rs`):** - `GraphParams` gains `sort: Option<String>` (accepted: "recent" | "connected", unknown falls back to "recent"). - New internal `GraphSort` enum + case-insensitive `parse()`. - Extracted `default_center_id(storage, sort)` so handler logic and tests share the same branching. Recent path picks `get_all_nodes(1, 0)` (ORDER BY created_at DESC). Connected path picks `get_most_connected_memory`, degrading gracefully to recent if the DB has no edges yet. - Default behaviour flipped from "connected" to "recent" — matches user expectation of "show me my recent stuff". **Dashboard (`apps/dashboard`):** - `api.graph()` accepts `sort?: 'recent' | 'connected'` with JSDoc explaining the rationale. - `/graph/+page.svelte` passes `sort: 'recent'` when no query or center_id is active. Query / center_id paths unchanged — they already carry their own centering intent. **Tests:** 6 new unit tests in `handlers::tests`: - `graph_sort_parse_defaults_to_recent` (None, empty, garbage, "recent", "Recent", "RECENT") - `graph_sort_parse_accepts_connected_case_insensitive` - `default_center_id_recent_returns_newest_node` — ingest 3 nodes, assert newest is picked - `default_center_id_connected_prefers_hub_over_newest` — wire a hub node with 3 spokes, then ingest a newer "lonely" node; assert the hub wins in Connected mode even though it's older - `default_center_id_connected_falls_back_to_recent_when_no_edges` — fresh DB with no connections still returns newest, not 404 - `default_center_id_returns_not_found_on_empty_db` — both modes return 404 cleanly on empty storage Build + test: - cargo test -p vestige-mcp --lib handlers:: → 6/6 pass - cargo test --workspace --lib → 830/830 pass, 0 failed - cargo clippy -p vestige-core -p vestige-mcp --lib -- -D warnings → clean - npm run check → 0 errors, 0 warnings - npm test → 361/361 pass Binary already installed at ~/.local/bin/vestige-mcp (copied from cargo build --release -p vestige-mcp). New Claude Desktop / Code sessions will pick it up automatically when they respawn their MCP subprocess. The dashboard HTTP server on port 3927 needs a manual relaunch from a terminal with the usual pattern: nohup bash -c 'tail -f /dev/null | \ VESTIGE_DASHBOARD_ENABLED=true ~/.local/bin/vestige-mcp' \ > /tmp/vestige-mcp.log 2>&1 & disown
This commit is contained in:
parent
8fe8bb2f39
commit
7441b3cdfe
3 changed files with 206 additions and 20 deletions
|
|
@ -63,7 +63,21 @@ export const api = {
|
|||
fetcher<TimelineResponse>(`/timeline?days=${days}&limit=${limit}`),
|
||||
|
||||
// Graph
|
||||
graph: (params?: { query?: string; center_id?: string; depth?: number; max_nodes?: number }) => {
|
||||
//
|
||||
// `sort` controls the default center when no query/center_id is given:
|
||||
// - "recent" (default) — newest memory; matches user expectation of
|
||||
// "show me what I just added". Previously the backend defaulted to
|
||||
// "connected" which clustered on historical hotspots and hid
|
||||
// fresh memories that hadn't accumulated edges yet.
|
||||
// - "connected" — densest node; richer initial subgraph for a
|
||||
// well-aged corpus. Exposed for a future UI toggle.
|
||||
graph: (params?: {
|
||||
query?: string;
|
||||
center_id?: string;
|
||||
depth?: number;
|
||||
max_nodes?: number;
|
||||
sort?: 'recent' | 'connected';
|
||||
}) => {
|
||||
const qs = params ? '?' + new URLSearchParams(
|
||||
Object.entries(params)
|
||||
.filter(([, v]) => v !== undefined)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue