From 0107fd53b8e629310ba948700fbcc405a53fbb7e Mon Sep 17 00:00:00 2001 From: Agam Pandey Date: Wed, 13 May 2026 01:59:38 +0530 Subject: [PATCH] feat: add temporal reasoning cookbook and docs (#5061) --- docs/api-reference/events/get-event.mdx | 2 + docs/api-reference/memory/add-memories.mdx | 1 - docs/api-reference/memory/get-memories.mdx | 1 - docs/api-reference/memory/search-memories.mdx | 1 + docs/changelog/highlights.mdx | 17 +- docs/changelog/platform.mdx | 12 +- docs/changelog/sdk.mdx | 2 +- .../memory-operations/search.mdx | 6 +- docs/docs.json | 5 +- docs/llms.txt | 1 + docs/migration/platform-v2-to-v3.mdx | 5 +- docs/openapi.json | 19 ++- docs/platform/features/temporal-reasoning.mdx | 145 ++++++++++++++++++ 13 files changed, 205 insertions(+), 12 deletions(-) create mode 100644 docs/platform/features/temporal-reasoning.mdx diff --git a/docs/api-reference/events/get-event.mdx b/docs/api-reference/events/get-event.mdx index 7acdb5b33..c93614fc4 100644 --- a/docs/api-reference/events/get-event.mdx +++ b/docs/api-reference/events/get-event.mdx @@ -5,3 +5,5 @@ openapi: get /v1/event/{event_id}/ --- Retrieve details about a specific event by passing its `event_id`. This endpoint is particularly helpful for tracking the status, payload, and completion details of asynchronous memory operations. + +For `POST /v3/memories/add/`, the event confirms that the write pipeline completed. Temporal reasoning enrichment runs asynchronously by default, so the event may be `SUCCEEDED` slightly before temporal ranking signals are available to subsequent `search` calls. diff --git a/docs/api-reference/memory/add-memories.mdx b/docs/api-reference/memory/add-memories.mdx index 338fa1b1a..672bb8747 100644 --- a/docs/api-reference/memory/add-memories.mdx +++ b/docs/api-reference/memory/add-memories.mdx @@ -83,4 +83,3 @@ The request is queued for background processing. The response contains an `event Poll the event status via `GET /v1/event/{event_id}/`. Status will be `SUCCEEDED` or `FAILED` once processing completes. - diff --git a/docs/api-reference/memory/get-memories.mdx b/docs/api-reference/memory/get-memories.mdx index 08c61f16d..d89d82fc3 100644 --- a/docs/api-reference/memory/get-memories.mdx +++ b/docs/api-reference/memory/get-memories.mdx @@ -64,4 +64,3 @@ memories = client.get_all( The response is a paginated envelope with `count`, `next`, `previous`, and `results`. Use `page` and `page_size` query params to step through results. - diff --git a/docs/api-reference/memory/search-memories.mdx b/docs/api-reference/memory/search-memories.mdx index b4d237cb1..c91c1a0f4 100644 --- a/docs/api-reference/memory/search-memories.mdx +++ b/docs/api-reference/memory/search-memories.mdx @@ -49,6 +49,7 @@ related_memories = client.search( { "id": "ea925981-272f-40dd-b576-be64e4871429", "memory": "Likes to play cricket and plays cricket on weekends.", + "user_id": "alice", "metadata": { "category": "hobbies" }, diff --git a/docs/changelog/highlights.mdx b/docs/changelog/highlights.mdx index 71530a1b2..7739e1c09 100644 --- a/docs/changelog/highlights.mdx +++ b/docs/changelog/highlights.mdx @@ -4,6 +4,21 @@ description: "Major product launches, headline features, and milestones for Mem0 mode: "wide" --- + + +**Temporal Reasoning — Time-Aware Retrieval for Platform v3** + +Mem0 Platform v3 can now interpret time-aware memories and queries so assistants retrieve the right information for questions about the past, upcoming plans, and current state. + +- **Time-aware search intent** — Queries like `last week`, `upcoming`, `right now`, and `as of March 2025` return contextually appropriate results automatically +- **Enabled by default** — No per-request toggle required for v3 writes or searches +- **Anchored relative queries** — `reference_date` anchors relative search phrases for tests, backfills, and reproducible demos +- **Normal response shape** — Temporal reasoning affects ranking while preserving existing client response patterns + +See [Temporal Reasoning](/platform/features/temporal-reasoning) for usage details. + + + **Memory Decay — Recently-Used Memories Surface Higher, Automatically** @@ -112,4 +127,4 @@ Major expansion of the provider ecosystem: First skill launch — a dedicated Mem0 skill providing platform API reference, quickstart patterns, and integration examples directly inside agent sessions. Available on [skills.sh](https://skills.sh) for any compatible AI coding agent. - \ No newline at end of file + diff --git a/docs/changelog/platform.mdx b/docs/changelog/platform.mdx index 996aa20c4..6547f3124 100644 --- a/docs/changelog/platform.mdx +++ b/docs/changelog/platform.mdx @@ -4,6 +4,17 @@ description: "Release notes for the Mem0 hosted platform — backend, dashboard, mode: "wide" --- + + +**New Features:** +- **Memory:** Added Temporal Reasoning for Platform v3 to improve ranking for time-aware queries such as `last week`, `upcoming`, `right now`, and `as of ...` +- **Search:** Added `reference_date` support to anchor relative temporal queries for tests, backfills, and reproducible demos + +**Improvements:** +- **API:** Temporal reasoning preserves the normal client response shape for search and get-all results + + + **New Features:** @@ -301,4 +312,3 @@ mode: "wide" - **Core:** Fixed unicode error in user_id, agent_id, run_id and app_id - diff --git a/docs/changelog/sdk.mdx b/docs/changelog/sdk.mdx index 9025b5e42..c9db329fe 100644 --- a/docs/changelog/sdk.mdx +++ b/docs/changelog/sdk.mdx @@ -55,7 +55,7 @@ mode: "wide" **Breaking Changes:** - **`add()` returns ADD-only events** — No more `"UPDATE"` or `"DELETE"` events. Memories accumulate; nothing is overwritten ([#4805](https://github.com/mem0ai/mem0/pull/4805)) - **`search()` default `threshold` is now `0.1`** — Pass `threshold=0.0` for previous behavior ([#4805](https://github.com/mem0ai/mem0/pull/4805)) -- **`search()` `score` is now a combined multi-signal score** — The top-level `score` fuses semantic similarity, BM25 keyword match, and entity boost into one value. Absolute numbers shift versus the old raw cosine score; retune any hard thresholds against representative queries. Per-signal scores are not exposed on the response ([#4805](https://github.com/mem0ai/mem0/pull/4805), [#4836](https://github.com/mem0ai/mem0/pull/4836)) +- **`search()` `score` is now a combined multi-signal score** — The top-level `score` fuses semantic similarity, BM25 keyword match, entity signals, and temporal boosts into one value. Absolute numbers shift versus the old raw cosine score; retune any hard thresholds against representative queries ([#4805](https://github.com/mem0ai/mem0/pull/4805), [#4836](https://github.com/mem0ai/mem0/pull/4836)) - **`search()` default `rerank` is now `False`** — Pass `rerank=True` for previous behavior ([#4805](https://github.com/mem0ai/mem0/pull/4805)) - **`top_k` default changed 100 → 20** in `Memory.get_all()` and `Memory.search()` (sync + async). Pass `top_k=100` explicitly to restore the old behavior ([#4843](https://github.com/mem0ai/mem0/pull/4843)) - **Entity ID validation:** `user_id` / `agent_id` / `run_id` are trimmed; empty-string and whitespace-only values now raise `ValueError` ([#4843](https://github.com/mem0ai/mem0/pull/4843)) diff --git a/docs/core-concepts/memory-operations/search.mdx b/docs/core-concepts/memory-operations/search.mdx index 62019d96e..57f3f14e4 100644 --- a/docs/core-concepts/memory-operations/search.mdx +++ b/docs/core-concepts/memory-operations/search.mdx @@ -156,6 +156,10 @@ const memories = memory.search("food preferences", { Expect an array of memory documents. Platform responses include vectors, metadata, and timestamps; OSS returns your stored schema. + + On Mem0 Platform v3, time-aware queries use Temporal Reasoning internally while preserving the normal search response shape. See Temporal Reasoning. + + ## Filter patterns Filters help narrow down search results. Common use cases: @@ -251,4 +255,4 @@ For the full list of filter logic, comparison operators, and optional search par icon="rocket" href="/cookbooks/operations/support-inbox" /> - \ No newline at end of file + diff --git a/docs/docs.json b/docs/docs.json index 8e0bf8056..e3644a7ae 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -72,7 +72,8 @@ "platform/features/entity-scoped-memory", "platform/features/async-client", "platform/features/multimodal-support", - "platform/features/custom-categories" + "platform/features/custom-categories", + "platform/features/temporal-reasoning" ] }, { @@ -1144,4 +1145,4 @@ "destination": "/introduction" } ] -} \ No newline at end of file +} diff --git a/docs/llms.txt b/docs/llms.txt index 2b1d7e0b8..7ef58b201 100644 --- a/docs/llms.txt +++ b/docs/llms.txt @@ -185,6 +185,7 @@ If the user is on a pre-current major (Python < 2, TS < 3, or Platform `output_f ### Features - Advanced Retrieval - [Advanced Retrieval](https://docs.mem0.ai/platform/features/advanced-retrieval) [Platform]: Use when the user needs keyword search, reranking, or hybrid retrieval. - [Criteria-Based Retrieval](https://docs.mem0.ai/platform/features/criteria-retrieval) [Platform]: Use when targeting memories by custom criteria, not just semantic similarity. +- [Temporal Reasoning](https://docs.mem0.ai/platform/features/temporal-reasoning) [Platform]: Use when time-aware searches like last week, upcoming, or right now need better result ordering. - [Contextual Add](https://docs.mem0.ai/platform/features/contextual-add) [Platform]: Use when `add()` should consider the surrounding conversation, not just the latest turn. - [Custom Instructions](https://docs.mem0.ai/platform/features/custom-instructions) [Platform]: Use when tailoring what Mem0 extracts and stores on Platform. - [Memory Decay](https://docs.mem0.ai/platform/features/memory-decay) [Platform]: Use when search results should boost recently-reinforced memories and dampen stale ones — opt-in per project, search-time only, never filters candidates out. diff --git a/docs/migration/platform-v2-to-v3.mdx b/docs/migration/platform-v2-to-v3.mdx index 8ad0c06af..fa021aac2 100644 --- a/docs/migration/platform-v2-to-v3.mdx +++ b/docs/migration/platform-v2-to-v3.mdx @@ -42,7 +42,7 @@ Previously, when an agent said something like "I've booked your flight for March ### Retrieval is hybrid now -Search now uses hybrid retrieval, which improves ranking quality — especially for queries involving exact keywords, proper nouns, or entities that appear across multiple memories. The response shape is unchanged: +Search now uses hybrid retrieval, which improves ranking quality — especially for queries involving exact keywords, proper nouns, entities that appear across multiple memories, and time-aware queries (via Temporal Reasoning). The response shape is unchanged: ```json { @@ -58,7 +58,7 @@ Search now uses hybrid retrieval, which improves ranking quality — especially } ``` -The top-level `score` remains a `[0, 1]` value. Relative ranking between results stays comparable to v2, but absolute numbers shift since the scoring method changed — retune any hard thresholds in your app against representative queries. +The top-level `score` remains a `[0, 1]` value. Relative ranking between results stays comparable to v2, but absolute numbers shift since the scoring method changed — retune any hard thresholds in your app against representative queries. Temporal signals are applied internally during ranking and are not returned as extra client-facing fields. ## API Changes @@ -289,6 +289,7 @@ If your application previously read graph relations from the API response (`rela - **V1 and V2 endpoints continue to work.** There is no requirement to migrate to V3 endpoints immediately. - **Existing memories are preserved.** The new algorithm does not modify or re-process previously stored memories. - **Search response shape is unchanged.** The top-level `score` and `results[]` array are the same; existing code that reads `score` continues to work. What changed is the scoring method behind the number (multi-signal fusion instead of pure cosine), so the absolute values shift even when ranking stays comparable. +- **Search remains backward-compatible at the top level.** Existing code that reads `results[]` and `score` continues to work. Temporal signals are applied internally during retrieval and do not change the client response shape. - **List response shape changed.** `get_all` now returns a paginated envelope (`{count, next, previous, results}`) instead of a bare `{results: [...]}`. Update code that reads `response["results"]` to continue working, or switch to the client SDKs which handle both shapes. ## Performance Improvements diff --git a/docs/openapi.json b/docs/openapi.json index ae7c80c48..8609e2d58 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -419,7 +419,7 @@ }, "results": { "type": "array", - "description": "Array of results produced by the event." + "description": "Array of results produced by the event. For add events, this confirms the write completed; temporal reasoning enrichment runs asynchronously by default." }, "created_at": { "type": "string", @@ -2071,7 +2071,7 @@ "memories" ], "summary": "Search memories (V3)", - "description": "Relevance-ranked search across stored memories. V3 uses hybrid retrieval — the returned `score` is a combined `[0, 1]` value; per-signal component scores are not exposed on the response. Entity IDs **must** be passed inside the `filters` object — top-level `user_id` / `agent_id` / `run_id` are rejected with 400. At least one entity ID is required.", + "description": "Relevance-ranked search across stored memories. V3 uses hybrid retrieval and can also apply temporal reasoning for time-aware queries. Entity IDs **must** be passed inside the `filters` object — top-level `user_id` / `agent_id` / `run_id` are rejected with 400. At least one entity ID is required.", "operationId": "memories_search_v3", "requestBody": { "required": true, @@ -2112,6 +2112,21 @@ "type": "boolean", "default": false, "description": "Apply the managed reranker for better ordering (adds latency)." + }, + "reference_date": { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "string" + } + ], + "nullable": true, + "description": "Optional query anchor time for relative temporal interpretation. Accepts Unix epoch, YYYY-MM-DD, or ISO datetime." } } }, diff --git a/docs/platform/features/temporal-reasoning.mdx b/docs/platform/features/temporal-reasoning.mdx new file mode 100644 index 000000000..7ea1de697 --- /dev/null +++ b/docs/platform/features/temporal-reasoning.mdx @@ -0,0 +1,145 @@ +--- +title: Temporal Reasoning +description: "Time-aware memory retrieval for Mem0 Platform v3 so queries like 'last week', 'upcoming', and 'right now' return the right memories." +icon: "clock" +badge: "v3" +--- + +Some memories matter because of **when** they happened, not just because they sound similar. Temporal Reasoning lets Mem0 Platform v3 understand time-aware queries and return the most contextually appropriate results. + + + **Use Temporal Reasoning when…** + - Users ask questions like "what happened last week?" or "what do I have coming up?" + - Your app stores both past events and future plans for the same person + - You want time-aware retrieval without building your own date-parsing layer + + + + Temporal Reasoning is a **Mem0 Platform v3** feature. It is not available on OSS memory stores or older Platform endpoints. + + +## Configure access + +Confirm your `MEM0_API_KEY` is set and that you are using the v3 Platform client: + +```python +from mem0 import MemoryClient + +client = MemoryClient(api_key="your-api-key") +``` + +## How it works + +When a memory describes an event, a future plan, or an ongoing state, Temporal Reasoning recognizes the time context so the right results surface at search time. + +A query like `what did I do last week?` should return a completed past event — not an upcoming appointment and not a stable fact that hasn't changed. Temporal Reasoning handles that distinction automatically. + +### Memory types Temporal Reasoning handles + +| Type | What it represents | Example | +| --- | --- | --- | +| Dated occurrence | Something that happened at a known time | "I finished the Q1 review on March 10, 2025." | +| Future plan | A future commitment or scheduled item | "I have a dentist appointment on March 18, 2025." | +| Ongoing state | A fact that remains true over time | "I am the product lead at Acme Corp." | +| Relationship | A durable connection between people or entities | "Priya manages Jordan." | +| Preference | A stable preference or habit | "I prefer morning meetings." | + +Results come back in the normal search response shape — Temporal Reasoning affects ranking, not the response format. + +## Configure it + +Temporal Reasoning is enabled by default for all v3 searches and writes. There is no per-request toggle. + +Two parameters give you precise control when you need it: + +- `timestamp` on `add()` — anchors an imported memory to the time it actually happened, rather than the time it was added to Mem0 +- `reference_date` on `search()` — resolves relative phrases like `last week` against a fixed point in time + + +```python Python +from datetime import datetime, timezone +from mem0 import MemoryClient + +client = MemoryClient(api_key="your-api-key") + +# Import a historical memory anchored to when it happened +client.add( + [{"role": "user", "content": "I finished the Q1 review on March 10, 2025."}], + user_id="jordan", + timestamp=int(datetime(2025, 3, 10, tzinfo=timezone.utc).timestamp()), +) + +# Search with a relative query anchored to a known date +results = client.search( + "what did I do last week?", + filters={"user_id": "jordan"}, + reference_date="2025-03-21T00:00:00Z", +) +``` + +```javascript JavaScript +import { MemoryClient } from "mem0ai"; + +const client = new MemoryClient({ apiKey: "your-api-key" }); + +// Import a historical memory anchored to when it happened +await client.add( + [{ role: "user", content: "I finished the Q1 review on March 10, 2025." }], + { + userId: "jordan", + timestamp: Math.floor(new Date("2025-03-10T00:00:00Z").getTime() / 1000), + } +); + +// Search with a relative query anchored to a known date +const results = await client.search("what did I do last week?", { + filters: { user_id: "jordan" }, + referenceDate: "2025-03-21T00:00:00Z", +}); +``` + + + + `reference_date` is especially useful in automated tests and demos because it makes relative phrases like `last week` resolve consistently every time. + + +## Supported query patterns + + + + Examples: `last week`, `last month`, `in March 2025`, `on 2025-03-10` + + + Examples: `upcoming`, `next week`, `tomorrow`, `what do I have coming up?` + + + Examples: `right now`, `currently`, `where do I work now?` + + + Examples: `as of March 2025`, `where was I living as of 2024?` + + + Examples: `how long have I lived here?`, `since when have I worked there?` + + + +## Verify the feature is working + +- Run a temporal search with a time-aware query (e.g., "what did I do last week?") and confirm the memory that fits the time window ranks first. +- Use `reference_date` in test queries so relative phrases resolve consistently across runs. +- For backfilled data, pass `timestamp` on `add()` to confirm the memory reflects the right point in time. + +## Best practices + +- Use explicit dates in source conversations when events or plans matter temporally. +- Pass `timestamp` during historical imports so the ingestion time does not become the only time anchor. +- Scope searches with `filters` so time-aware ranking operates inside the right user boundary. +- Use `reference_date` in automated tests and reproducible demos. + + + + Anchor imported memories to when they actually happened. + + + +