diff --git a/docs/api-reference/memory/add-memories.mdx b/docs/api-reference/memory/add-memories.mdx index 6a4d987b2..672bb8747 100644 --- a/docs/api-reference/memory/add-memories.mdx +++ b/docs/api-reference/memory/add-memories.mdx @@ -49,10 +49,6 @@ Provide conversation messages for Mem0 to extract memories from. At least one en | `run_id` | string | No* | Associates the memory with a run. | | `app_id` | string | No* | Associates the memory with an app. | | `metadata` | object | Optional | Custom key/value metadata (e.g., `{"topic": "preferences"}`). | -| `timestamp` | integer | Optional | Unix timestamp used to anchor imported or historical memories. | -| `observation_date` | string | Optional | Original conversation date (`YYYY-MM-DD`) for temporal grounding. | -| `observation_datetime` | string | Optional | Original conversation datetime for more precise temporal grounding. | -| `timezone` | string | Optional | IANA timezone used when resolving relative dates. | | `infer` | boolean (default `true`) | Optional | Set to `false` to skip inference and store the provided text as-is. | > \* At least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`) is required. @@ -87,7 +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. - - - Some deployments run temporal enrichment in a follow-up async step. In that mode, the add event can complete successfully before temporal search fields are fully available on later searches. - diff --git a/docs/api-reference/memory/get-memories.mdx b/docs/api-reference/memory/get-memories.mdx index 3b2f4b011..d197150d0 100644 --- a/docs/api-reference/memory/get-memories.mdx +++ b/docs/api-reference/memory/get-memories.mdx @@ -19,31 +19,6 @@ The `filters` object supports complex logical operations (AND, OR, NOT) and comp Pass `page` and `page_size` as query parameters to paginate through results. -## Temporal fields on `get_all` - -`get_all` returns the **stored** memory record. For temporally enriched memories, that can include top-level fields such as: - -- `event_date` -- `event_start` -- `event_end` -- `time_precision` -- `timezone` -- `polarity` -- `temporal_relation` -- `state_key` -- `plan_status` - -These are stored memory attributes, not search-time interpretation fields. - -`get_all` does **not** add search-only fields such as: - -- `effective_plan_status` -- `temporal_surface` -- `reference_date_used` -- `score_breakdown` - -Those fields belong to `search`, where Mem0 interprets a query in context. - ```python Code memories = client.get_all( @@ -75,16 +50,7 @@ memories = client.get_all( "metadata": {}, "categories": [], "created_at": "2024-07-01T12:00:00Z", - "updated_at": "2024-07-01T12:00:00Z", - "event_date": "2024-07-01", - "event_start": "2024-07-01", - "event_end": "2024-07-10", - "time_precision": "interval", - "timezone": "UTC", - "polarity": "positive", - "temporal_relation": "during", - "state_key": null, - "plan_status": "pending" + "updated_at": "2024-07-01T12:00:00Z" }, { "id": "a2b8c3d4-5e6f-7g8h-9i0j-1k2l3m4n5o6p", @@ -93,16 +59,7 @@ memories = client.get_all( "metadata": {}, "categories": [], "created_at": "2024-07-05T15:30:00Z", - "updated_at": "2024-07-05T15:30:00Z", - "event_date": null, - "event_start": null, - "event_end": null, - "time_precision": null, - "timezone": null, - "polarity": null, - "temporal_relation": null, - "state_key": null, - "plan_status": null + "updated_at": "2024-07-05T15:30:00Z" } ] } diff --git a/docs/api-reference/memory/search-memories.mdx b/docs/api-reference/memory/search-memories.mdx index 3bbe2a52e..811b8aba2 100644 --- a/docs/api-reference/memory/search-memories.mdx +++ b/docs/api-reference/memory/search-memories.mdx @@ -18,20 +18,9 @@ The `filters` object supports complex logical operations (AND, OR, NOT) and comp - `icontains`: Case-insensitive containment check - `*`: Wildcard character that matches everything -## Temporal fields in V3 responses +## Temporal reasoning in V3 responses -When Temporal Reasoning is enabled for a query, search results can include additional **top-level** fields such as: - -- `memory_type` -- `event_date` -- `event_start` -- `event_end` -- `plan_status` -- `effective_plan_status` -- `time_precision` -- `temporal_surface` -- `reference_date_used` -- `score_breakdown.temporal_boost` +Temporal Reasoning is applied internally during retrieval. Search responses keep the normal result shape. ### Search parameter defaults @@ -78,7 +67,7 @@ related_memories = client.search( ``` -### Temporal example +### Temporal query example ```python Platform API Example @@ -97,15 +86,6 @@ results = client.search( "memory": "Finished the Q1 product review on March 10, 2025.", "user_id": "alice", "score": 0.91, - "memory_type": "event", - "event_date": "2025-03-10", - "event_start": "2025-03-10", - "event_end": "2025-03-10", - "plan_status": null, - "effective_plan_status": null, - "time_precision": "day", - "temporal_surface": "Mar 10, 2025", - "reference_date_used": "2025-03-21", "metadata": {}, "categories": [], "created_at": "2025-03-10T00:00:00Z", @@ -116,10 +96,6 @@ results = client.search( ``` - - Temporal fields are most useful on `search`. The paginated `get_all` endpoint remains a broader retrieval surface and does not mirror the full time-aware search result shape. - - ```python Wildcard Example # Using wildcard to match all run_ids for a specific user diff --git a/docs/cookbooks/essentials/temporal-memory-assistant.mdx b/docs/cookbooks/essentials/temporal-memory-assistant.mdx deleted file mode 100644 index ef0bc6ff7..000000000 --- a/docs/cookbooks/essentials/temporal-memory-assistant.mdx +++ /dev/null @@ -1,316 +0,0 @@ ---- -title: Time-Aware Retrieval -description: Use Mem0 Platform v3 Temporal Reasoning to make one memory store answer past, upcoming, and current questions correctly. ---- - -An assistant often stores all of these in the same user profile: - -- "I finished the Q1 product review on March 10, 2025." -- "I have a dentist appointment on April 18, 2025 at 2 PM." -- "I am the product lead at Acme Corp." - -Those memories are all relevant to the same person, but they should not rank the same way for every question. A query like `what did I do last week?` should favor the finished review. A query like `what do I have coming up?` should favor the appointment. A query like `where do I work right now?` should favor the ongoing role. - -This cookbook shows how to get that behavior with Mem0 Platform v3 using the normal `add()` and `search()` flow. - - -**Time to complete:** ~15 minutes · **Languages:** Python, JavaScript - - -## Setup - - -```python Python -from mem0 import MemoryClient - -client = MemoryClient(api_key="your-api-key") -USER_ID = "jordan" -REFERENCE_DATE = "2025-03-21T00:00:00Z" -``` - -```javascript JavaScript -import MemoryClient from "mem0ai"; - -const client = new MemoryClient({ apiKey: process.env.MEM0_API_KEY }); -const USER_ID = "jordan"; -const REFERENCE_DATE = "2025-03-21T00:00:00Z"; -``` - - - - These examples target **Mem0 Platform v3**. Writes are asynchronous, so allow a short delay before validating search behavior. - - -## Seed Memories - -Start with one past event, one future plan, and one ongoing state: - - -```python Python -client.add( - [{"role": "user", "content": "I finished the Q1 product review on March 10, 2025."}], - user_id=USER_ID, -) - -client.add( - [{"role": "user", "content": "I have a dentist appointment on April 18, 2025 at 2 PM."}], - user_id=USER_ID, -) - -client.add( - [{"role": "user", "content": "I am the product lead at Acme Corp."}], - user_id=USER_ID, -) -``` - -```javascript JavaScript -await client.add( - [{ role: "user", content: "I finished the Q1 product review on March 10, 2025." }], - { userId: USER_ID } -); - -await client.add( - [{ role: "user", content: "I have a dentist appointment on April 18, 2025 at 2 PM." }], - { userId: USER_ID } -); - -await client.add( - [{ role: "user", content: "I am the product lead at Acme Corp." }], - { userId: USER_ID } -); -``` - - -## Run a Temporal Search - -Temporal Reasoning is always on for v3 searches — no flag required. The pipeline detects time language in the query and uses stored temporal fields to rank results appropriately. - - -```python Python -results = client.search( - "what did I do last week?", - filters={"user_id": USER_ID}, - reference_date=REFERENCE_DATE, -) - -for item in results["results"]: - print(item["memory"], item["score"]) -``` - -```javascript JavaScript -const results = await client.search("what did I do last week?", { - filters: { user_id: USER_ID }, - referenceDate: REFERENCE_DATE, -}); - -results.results.forEach((item) => { - console.log(item.memory, item.score); -}); -``` - - -**Illustrative output:** -```text -I finished the Q1 product review on March 10, 2025. -``` - -Mem0 uses the query’s time intent and the stored temporal metadata to rank the memory that fits `last week` higher. The April 18 appointment and the ongoing job title score lower because their temporal classification and date don’t match a historical range query. - - -Expected behavior: the March 10 event leads for `last week`. The April 18 appointment and the ongoing Acme role score lower because their temporal type and date don’t match a historical range query. - - -## See the Three Query Shapes - -The same memory store can now support three different retrieval patterns. - -### 1. Past-oriented retrieval - -Use this for questions about completed activity. - -```python -client.search( - "what did I do last week?", - filters={"user_id": USER_ID}, - reference_date=REFERENCE_DATE, -) -``` - -Expected outcome: the completed review ranks above future plans and ongoing profile facts. - -### 2. Upcoming retrieval - -Use this for scheduled commitments and future-facing assistant flows. - - -```python Python -upcoming = client.search( - "what do I have coming up?", - filters={"user_id": USER_ID}, - reference_date=REFERENCE_DATE, -) - -for item in upcoming["results"]: - print(item["memory"], item["score"]) -``` - -```javascript JavaScript -const upcoming = await client.search("what do I have coming up?", { - filters: { user_id: USER_ID }, - referenceDate: REFERENCE_DATE, -}); - -upcoming.results.forEach((item) => { - console.log(item.memory, item.score); -}); -``` - - -**Illustrative output:** -```text -I have a dentist appointment on April 18, 2025 at 2 PM. -``` - - - Upcoming queries work best when the source memory includes a real date or date range. Vague text like "we should schedule something soon" is less reliable for future-oriented retrieval. - - -### 3. Current-state retrieval - -Use this for durable facts that are still true now. - - -```python Python -current = client.search( - "where do I work right now?", - filters={"user_id": USER_ID}, - reference_date=REFERENCE_DATE, -) - -for item in current["results"]: - print(item["memory"], item["score"]) -``` - -```javascript JavaScript -const current = await client.search("where do I work right now?", { - filters: { user_id: USER_ID }, - referenceDate: REFERENCE_DATE, -}); - -current.results.forEach((item) => { - console.log(item.memory, item.score); -}); -``` - - -**Illustrative output:** -```text -I am the product lead at Acme Corp. -``` - -## Use the Right Controls - -The main control for temporal retrieval is `reference_date`, which anchors relative phrases like `last week`, `tomorrow`, and `right now` to a known point in time. Without it, the server uses the current date. - -### Deterministic tests and demos - -Use `reference_date` whenever the wording is relative. - - -```python Python -client.search( - "what did I do last week?", - filters={"user_id": USER_ID}, - reference_date="2025-03-21T00:00:00Z", -) -``` - -```javascript JavaScript -await client.search("what did I do last week?", { - filters: { user_id: USER_ID }, - referenceDate: "2025-03-21T00:00:00Z", -}); -``` - - -### Historical imports - -If you are backfilling old data, send the original event time instead of relying only on ingestion time. - - -```python Python -from datetime import datetime, timezone - -client.add( - [{"role": "user", "content": "I attended the partner summit on November 15, 2024."}], - user_id=USER_ID, - timestamp=int(datetime(2024, 11, 15, tzinfo=timezone.utc).timestamp()), -) -``` - -```javascript JavaScript -await client.add( - [{ role: "user", content: "I attended the partner summit on November 15, 2024." }], - { - userId: USER_ID, - timestamp: Math.floor(new Date("2024-11-15T00:00:00Z").getTime() / 1000), - } -); -``` - - -### Combine with normal Platform filters - -Temporal retrieval still respects the normal entity filters. - - -```python Python -client.search( - "what did we discuss last week?", - filters={ - "AND": [ - {"user_id": USER_ID}, - {"agent_id": "task-planner"}, - ] - }, - reference_date=REFERENCE_DATE, -) -``` - -```javascript JavaScript -await client.search("what did we discuss last week?", { - filters: { - AND: [ - { user_id: USER_ID }, - { agent_id: "task-planner" }, - ], - }, - referenceDate: REFERENCE_DATE, -}); -``` - - -## What You Built - -- Past questions can favor completed events instead of just semantically related memories. -- Upcoming questions can surface scheduled plans instead of historical notes. -- Current-state questions can keep stable facts available without letting them take over every search. - -## Next Steps - -If your application depends on relative time language, keep `reference_date` in your tests and evals, and pass `timestamp` when you backfill older conversations. That keeps time-aware retrieval predictable without adding a separate timeline system to your stack. - - - - - diff --git a/docs/core-concepts/memory-operations/search.mdx b/docs/core-concepts/memory-operations/search.mdx index fa3583bd7..d964066ff 100644 --- a/docs/core-concepts/memory-operations/search.mdx +++ b/docs/core-concepts/memory-operations/search.mdx @@ -157,7 +157,7 @@ const memories = memory.search("food preferences", { - On Mem0 Platform v3, time-aware queries can also return top-level temporal fields such as `memory_type`, `event_date`, `event_start`, `event_end`, `effective_plan_status`, `temporal_surface`, and `score_breakdown.temporal_boost`. See Temporal Reasoning. + On Mem0 Platform v3, time-aware queries use Temporal Reasoning internally while preserving the normal search response shape. See Temporal Reasoning. ## Filter patterns diff --git a/docs/docs.json b/docs/docs.json index 7e9a209e4..4bbf062cb 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -330,7 +330,6 @@ "cookbooks/essentials/building-ai-companion", "cookbooks/essentials/entity-partitioning-playbook", "cookbooks/essentials/controlling-memory-ingestion", - "cookbooks/essentials/temporal-memory-assistant", "cookbooks/essentials/tagging-and-organizing-memories", "cookbooks/essentials/exporting-memories" ] diff --git a/docs/migration/platform-v2-to-v3.mdx b/docs/migration/platform-v2-to-v3.mdx index 73b13754f..dd3b93fa6 100644 --- a/docs/migration/platform-v2-to-v3.mdx +++ b/docs/migration/platform-v2-to-v3.mdx @@ -63,7 +63,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. Temporal signals are used internally for ranking and are not exposed as client-facing temporal metadata. +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 used internally for ranking and are not returned as extra client-facing data. ## API Changes @@ -299,7 +299,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 rather than returned as temporal fields in the client response. +- **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 f08c2d5b6..435482d57 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -1866,55 +1866,7 @@ "updated_at": { "type": "string", "format": "date-time" - }, - "plan_status": { - "type": "string", - "nullable": true, - "description": "Stored plan status if this memory is a plan." - }, - "event_date": { - "type": "string", - "format": "date", - "nullable": true, - "description": "Primary event date when available." - }, - "event_start": { - "type": "string", - "format": "date", - "nullable": true, - "description": "Start date for an event or interval when available." - }, - "event_end": { - "type": "string", - "format": "date", - "nullable": true, - "description": "End date for an event or interval when available." - }, - "time_precision": { - "type": "string", - "nullable": true, - "description": "Temporal precision for the resolved date information." - }, - "timezone": { - "type": "string", - "nullable": true, - "description": "Stored timezone associated with the temporal record, when available." - }, - "polarity": { - "type": "string", - "nullable": true, - "description": "Stored temporal polarity, when available." - }, - "temporal_relation": { - "type": "string", - "nullable": true, - "description": "Stored temporal relation, when available." - }, - "state_key": { - "type": "string", - "nullable": true, - "description": "Stored state key for state-like memories, when available." - } + } }, "required": [ "id", @@ -1945,16 +1897,7 @@ "location" ], "created_at": "2026-01-15T10:30:00Z", - "updated_at": "2026-01-15T10:30:00Z", - "event_date": "2026-01-15", - "event_start": "2026-01-15", - "event_end": null, - "time_precision": "day", - "timezone": "UTC", - "polarity": "positive", - "temporal_relation": "on", - "state_key": null, - "plan_status": null + "updated_at": "2026-01-15T10:30:00Z" } ] } @@ -2056,33 +1999,11 @@ "type": "string", "description": "Project-level instructions that guide extraction for this call." }, - "observation_date": { - "type": "string", - "format": "date", - "nullable": true, - "description": "Original conversation date used for temporal grounding." - }, - "observation_datetime": { - "type": "string", - "format": "date-time", - "nullable": true, - "description": "Original conversation datetime used for temporal grounding." - }, - "timezone": { - "type": "string", - "nullable": true, - "description": "IANA timezone used to resolve observation dates and relative dates." - }, "multilingual": { "type": "boolean", "nullable": true, "description": "Extract memories in the same language as the input." }, - "timestamp": { - "type": "integer", - "nullable": true, - "description": "Unix epoch timestamp for when the conversation happened." - }, "expiration_date": { "type": "string", "format": "date", diff --git a/docs/platform/features/temporal-reasoning.mdx b/docs/platform/features/temporal-reasoning.mdx index f654b2beb..8133c0825 100644 --- a/docs/platform/features/temporal-reasoning.mdx +++ b/docs/platform/features/temporal-reasoning.mdx @@ -32,12 +32,12 @@ client = MemoryClient(api_key="your-api-key") Temporal Reasoning has two public-facing parts: -- **Write-time enrichment**: when Mem0 stores a memory, it can attach temporal structure such as memory type and date bounds when that information is present in the text. -- **Search-time interpretation**: when a query includes time language like `last week`, `upcoming`, or `right now`, Mem0 uses the stored temporal fields to return more appropriate results. +- **Write-time enrichment**: when Mem0 stores a memory, it can infer internal temporal structure when that information is present in the text. +- **Search-time interpretation**: when a query includes time language like `last week`, `upcoming`, or `right now`, Mem0 uses internal temporal signals to return more appropriate results. ### Memory types -Mem0 normalizes temporal memories into a small set of developer-facing types: +Mem0 normalizes temporal memories into a small set of internal classes: | Type | What it represents | Example | | --- | --- | --- | @@ -47,7 +47,7 @@ Mem0 normalizes temporal memories into a small set of developer-facing types: | `relationship` | A durable connection between people or entities | "Priya manages Jordan." | | `preference` | A stable preference or habit | "I prefer morning meetings." | -At search time, Temporal Reasoning influences how results are ranked — memories that match the temporal intent of the query receive a boost — but no temporal metadata is added to the API response. The ranking effect is transparent: results come back in the normal shape. +At search time, Temporal Reasoning influences how results are ranked. The ranking effect is transparent: results come back in the normal shape. ## Configure it @@ -210,9 +210,6 @@ results.results.forEach((item) => { Anchor imported memories to when they actually happened. - - Follow the cookbook for an end-to-end temporal retrieval workflow. -