feat(stats): add time_field toggle to memories-timeseries chart#1246
Open
aliu-ronin wants to merge 2 commits intovectorize-io:mainfrom
Open
feat(stats): add time_field toggle to memories-timeseries chart#1246aliu-ronin wants to merge 2 commits intovectorize-io:mainfrom
aliu-ronin wants to merge 2 commits intovectorize-io:mainfrom
Conversation
`/stats/memories-timeseries` always bucketed by `created_at` (ingest time). For a bank built up in real time, ingest time ≈ event time and that's the right default. But when a corpus is backfilled in a single session — for example migrating from another memory system — every record's `created_at` collapses to the import moment, so the chart shows "all knowledge is new" and hides the underlying timeline. Adds a `time_field` query parameter that lets the caller choose which timestamp column drives the bucket assignment: - `created_at` (default, unchanged) — ingest time - `mentioned_at` — event time (when the fact was mentioned) - `occurred_start` — event time (when the underlying event started) For the event-time columns we `COALESCE(<col>, created_at)` per row so records lacking an event timestamp still show up somewhere instead of silently disappearing. The field is whitelisted (never interpolated from untrusted input), unknown values fall back to `created_at`, and the chosen column is echoed in the response for UI affordance. Depends on the tz-aware bucket fix in vectorize-io#1245 (kept as a separate commit).
Surfaces the new `time_field` backend option as a three-way toggle next to the period selector on the "Memories ingested" card: - **Ingested** — bucketed by `created_at` (default, matches old behavior) - **Mentioned** — bucketed by `mentioned_at` (event time) - **Occurred** — bucketed by `occurred_start` (event time) The card title also updates to reflect which dimension is in view so the chart reads unambiguously. Propagates `time_field` through the control-plane proxy (`/api/stats/[agentId]/memories-timeseries`) and the typed SDK (`client.getMemoriesTimeseries`). Defaults stay `created_at` everywhere so behavior is backward-compatible.
Collaborator
|
@aliu-ronin can you resolve conflicts? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Memories ingested chart on the bank dashboard always buckets by
memory_units.created_at(ingest time). For a bank built up in real time, ingest time ≈ event time and that's the right default. But when a corpus is backfilled in a single session — for example migrating from another memory system — every record'screated_atcollapses to the import moment, so the chart shows "all knowledge is new" and the underlying timeline disappears.Adds a
time_fieldquery parameter (and a three-way UI toggle) that lets the viewer pick which timestamp column drives the bucket assignment:created_at(default)mentioned_atoccurred_startFor the event-time columns we
COALESCE(<col>, created_at)per row so records lacking an event timestamp still show up in the chart instead of silently disappearing. The field is whitelisted (never interpolated from untrusted input), unknown values fall back tocreated_at, and the chosen column is echoed back in the response for UI affordance.Changes
Backend (
hindsight-api-slim)memory_engine.get_memories_timeseriesgains atime_fieldkeyword arg, validates it against an allowlist, and composesbucket_exprwithCOALESCEfor the event-time columns.MemoriesTimeseriesResponseadds atime_fieldfield.time_fieldas a query param with a clear description.Control Plane (
hindsight-control-plane)getMemoriesTimeseriesSDK helper accepts atimeFieldargument, defaulting tocreated_at./api/stats/[agentId]/memories-timeseriesproxy forwards the param.bank-stats-view.tsxrenders an Ingested / Mentioned / Occurred segmented control below the period selector; the card title updates so the chart reads unambiguously (e.g. "Memories by mentioned time").Screenshots
On a bank migrated from another memory system, toggling to Mentioned spreads the chart across the actual event timeline instead of a single ingest-day spike:
created_at→ two-day spike (04-23, 04-24)mentioned_at→ spread across 03-26 through 03-29 (real history)Test plan
curl .../memories-timeseries?period=30d&time_field=mentioned_atreturns non-zero buckets spanning the corpus's actual timelinetime_field=nonsensefalls back tocreated_at(parity with the invalid-period behavior)time_fieldso the UI can display the active dimensionNotes
created_ateverywhere; existing integrations see no behavioral change.time_fieldis selected.