docs(temporal): remove temporal metadata from v3 search response docs

Temporal fields (event_date, memory_type, effective_plan_status, etc.)
are backend-only ranking signals and must not be documented as part of
the public search API response.

- temporal-reasoning.mdx: replace response-field table with a note that
  temporal reasoning affects ranking only; no metadata added to responses
- temporal-memory-assistant.mdx: remove temporal field reads from all
  three retrieval examples; update illustrative output blocks
- openapi.json: remove temporal fields from /v3/memories/search/ example
  response; remove temporal_boost from score_breakdown example
- add-memories.mdx: remove temporal_reasoning toggle from request params

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
agumpandey
2026-05-09 10:43:56 +05:30
co-authored by Claude Sonnet 4.6
parent b2d2c8a8ef
commit f864e9b871
4 changed files with 20 additions and 171 deletions
@@ -54,7 +54,6 @@ Provide conversation messages for Mem0 to extract memories from. At least one en
| `observation_datetime` | string | Optional | Original conversation datetime for more precise temporal grounding. | | `observation_datetime` | string | Optional | Original conversation datetime for more precise temporal grounding. |
| `timezone` | string | Optional | IANA timezone used when resolving relative dates. | | `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. | | `infer` | boolean (default `true`) | Optional | Set to `false` to skip inference and store the provided text as-is. |
| `temporal_reasoning` | boolean | Optional | Overrides the deployment default for temporal enrichment on this write. |
> \* At least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`) is required. > \* At least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`) is required.
@@ -81,53 +81,9 @@ await client.add(
``` ```
</CodeGroup> </CodeGroup>
## Compare Retrieval Modes ## Run a Temporal Search
The easiest way to understand Temporal Reasoning is to compare the same query in two modes: 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.
- **Standard retrieval** with `temporal_reasoning=False`
- **Temporal retrieval** with the default time-aware mode enabled
### Mode 1: Standard Retrieval
This is useful for broad semantic lookups, but it does not try to interpret `last week` against a timeline.
<CodeGroup>
```python Python
results = client.search(
"what did I do last week?",
filters={"user_id": USER_ID},
reference_date=REFERENCE_DATE,
temporal_reasoning=False,
)
for item in results["results"]:
print(item["memory"])
```
```javascript JavaScript
const results = await client.search("what did I do last week?", {
filters: { user_id: USER_ID },
referenceDate: REFERENCE_DATE,
temporalReasoning: false,
});
results.results.forEach((item) => console.log(item.memory));
```
</CodeGroup>
**Illustrative output:**
```text
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.
```
That result set is semantically reasonable, but it is not yet behaving like a time-aware assistant.
### Mode 2: Temporal Retrieval
Now run the same query with temporal mode enabled. This is the default, so you can omit the flag.
<CodeGroup> <CodeGroup>
```python Python ```python Python
@@ -138,12 +94,7 @@ results = client.search(
) )
for item in results["results"]: for item in results["results"]:
print( print(item["memory"], item["score"])
item["memory"],
item.get("memory_type"),
item.get("event_date"),
item.get("temporal_surface"),
)
``` ```
```javascript JavaScript ```javascript JavaScript
@@ -153,20 +104,20 @@ const results = await client.search("what did I do last week?", {
}); });
results.results.forEach((item) => { results.results.forEach((item) => {
console.log(item.memory, item.memoryType, item.eventDate, item.temporalSurface); console.log(item.memory, item.score);
}); });
``` ```
</CodeGroup> </CodeGroup>
**Illustrative output:** **Illustrative output:**
```text ```text
I finished the Q1 product review on March 10, 2025. event 2025-03-10 Mar 10, 2025 I finished the Q1 product review on March 10, 2025.
``` ```
The impact is not just better ranking. Mem0 is now using the query’s time intent plus the stored temporal fields to prefer the memory that fits `last week`. 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.
<Info icon="check"> <Info icon="check">
Expected behavior: with temporal mode on, the March 10 event should lead for `last week`, while the April 18 appointment and the ongoing job title should not dominate the answer. 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.
</Info> </Info>
## See the Three Query Shapes ## See the Three Query Shapes
@@ -200,7 +151,7 @@ upcoming = client.search(
) )
for item in upcoming["results"]: for item in upcoming["results"]:
print(item["memory"], item.get("memory_type"), item.get("effective_plan_status")) print(item["memory"], item["score"])
``` ```
```javascript JavaScript ```javascript JavaScript
@@ -210,14 +161,14 @@ const upcoming = await client.search("what do I have coming up?", {
}); });
upcoming.results.forEach((item) => { upcoming.results.forEach((item) => {
console.log(item.memory, item.memoryType, item.effectivePlanStatus); console.log(item.memory, item.score);
}); });
``` ```
</CodeGroup> </CodeGroup>
**Illustrative output:** **Illustrative output:**
```text ```text
I have a dentist appointment on April 18, 2025 at 2 PM. plan upcoming I have a dentist appointment on April 18, 2025 at 2 PM.
``` ```
<Warning> <Warning>
@@ -237,7 +188,7 @@ current = client.search(
) )
for item in current["results"]: for item in current["results"]:
print(item["memory"], item.get("memory_type"), item.get("temporal_surface")) print(item["memory"], item["score"])
``` ```
```javascript JavaScript ```javascript JavaScript
@@ -247,22 +198,19 @@ const current = await client.search("where do I work right now?", {
}); });
current.results.forEach((item) => { current.results.forEach((item) => {
console.log(item.memory, item.memoryType, item.temporalSurface); console.log(item.memory, item.score);
}); });
``` ```
</CodeGroup> </CodeGroup>
**Illustrative output:** **Illustrative output:**
```text ```text
I am the product lead at Acme Corp. state ongoing I am the product lead at Acme Corp.
``` ```
## Use the Right Controls ## Use the Right Controls
There are two public controls that matter most in production: 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.
- `reference_date` anchors relative phrases like `last week`, `tomorrow`, and `right now`
- `temporal_reasoning` lets you switch between standard retrieval and temporal retrieval for a specific request
### Deterministic tests and demos ### Deterministic tests and demos
@@ -285,27 +233,6 @@ await client.search("what did I do last week?", {
``` ```
</CodeGroup> </CodeGroup>
### Standard retrieval for timeless queries
Turn temporal mode off when a question is not time-sensitive.
<CodeGroup>
```python Python
client.search(
"what is my job title?",
filters={"user_id": USER_ID},
temporal_reasoning=False,
)
```
```javascript JavaScript
await client.search("what is my job title?", {
filters: { user_id: USER_ID },
temporalReasoning: false,
});
```
</CodeGroup>
### Historical imports ### Historical imports
If you are backfilling old data, send the original event time instead of relying only on ingestion time. If you are backfilling old data, send the original event time instead of relying only on ingestion time.
@@ -368,7 +295,6 @@ await client.search("what did we discuss last week?", {
- Past questions can favor completed events instead of just semantically related memories. - Past questions can favor completed events instead of just semantically related memories.
- Upcoming questions can surface scheduled plans instead of historical notes. - 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. - Current-state questions can keep stable facts available without letting them take over every search.
- You can switch between standard retrieval and temporal retrieval per request with `temporal_reasoning`.
## Next Steps ## Next Steps
+1 -21
View File
@@ -2093,11 +2093,6 @@
"type": "boolean", "type": "boolean",
"default": true, "default": true,
"description": "When `false`, stores each message verbatim without running the extraction LLM." "description": "When `false`, stores each message verbatim without running the extraction LLM."
},
"temporal_reasoning": {
"type": "boolean",
"nullable": true,
"description": "Enable V3 temporal reasoning write-path metadata. Defaults to the deployment setting."
} }
} }
}, },
@@ -2240,11 +2235,6 @@
], ],
"nullable": true, "nullable": true,
"description": "Optional query anchor time for relative temporal interpretation. Accepts Unix epoch, YYYY-MM-DD, or ISO datetime." "description": "Optional query anchor time for relative temporal interpretation. Accepts Unix epoch, YYYY-MM-DD, or ISO datetime."
},
"temporal_reasoning": {
"type": "boolean",
"nullable": true,
"description": "Enable V3 temporal intent and temporal scoring. Defaults to the deployment setting."
} }
} }
}, },
@@ -2329,18 +2319,8 @@
"score_breakdown": { "score_breakdown": {
"semantic": 0.78, "semantic": 0.78,
"bm25": 0.0, "bm25": 0.0,
"entity": 0.0, "entity": 0.0
"temporal_boost": 0.04
}, },
"memory_type": "event",
"event_date": "2026-01-15",
"event_start": "2026-01-15",
"event_end": "2026-01-15",
"plan_status": null,
"effective_plan_status": null,
"time_precision": "day",
"temporal_surface": "Jan 15, 2026",
"reference_date_used": "2026-01-20",
"metadata": {}, "metadata": {},
"categories": [ "categories": [
"location" "location"
+5 -61
View File
@@ -47,67 +47,13 @@ Mem0 normalizes temporal memories into a small set of developer-facing types:
| `relationship` | A durable connection between people or entities | "Priya manages Jordan." | | `relationship` | A durable connection between people or entities | "Priya manages Jordan." |
| `preference` | A stable preference or habit | "I prefer morning meetings." | | `preference` | A stable preference or habit | "I prefer morning meetings." |
On search responses, temporal fields are returned as top-level result attributes when Temporal Reasoning is active. The most useful ones are: 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.
- `memory_type`
- `event_date`
- `event_start`
- `event_end`
- `plan_status`
- `effective_plan_status`
- `time_precision`
- `temporal_surface`
- `reference_date_used`
- `score_breakdown.temporal_boost`
## Configure it ## Configure it
### Default behavior ### Default behavior
Temporal Reasoning is enabled by default for supported v3 searches and writes. Temporal Reasoning is enabled by default for all v3 searches and writes. There is no per-request toggle — the pipeline runs automatically when temporal structure is detectable in the memory text or query.
### Per-request override
Use `temporal_reasoning=False` when you want a specific call to behave like a normal semantic add or search.
<CodeGroup>
```python Python
client.add(
[{"role": "user", "content": "Preferred language is English."}],
user_id="jordan",
temporal_reasoning=False,
)
results = client.search(
"preferred language",
filters={"user_id": "jordan"},
temporal_reasoning=False,
)
```
```javascript JavaScript
await client.add(
[{ role: "user", content: "Preferred language is English." }],
{ userId: "jordan", temporalReasoning: false }
);
const results = await client.search("preferred language", {
filters: { user_id: "jordan" },
temporalReasoning: false,
});
```
```bash cURL
curl -X POST "https://api.mem0.ai/v3/memories/search/" \
-H "Authorization: Token your-api-key" \
-H "Content-Type: application/json" \
-d '{
"query": "preferred language",
"filters": { "user_id": "jordan" },
"temporal_reasoning": false
}'
```
</CodeGroup>
### Anchor imports and tests ### Anchor imports and tests
@@ -208,7 +154,7 @@ results = client.search(
) )
for item in results["results"]: for item in results["results"]:
print(item["memory"], item.get("memory_type"), item.get("event_date")) print(item["memory"], item["score"])
``` ```
```javascript JavaScript ```javascript JavaScript
@@ -218,7 +164,7 @@ const results = await client.search("what did I do last week?", {
}); });
results.results.forEach((item) => { results.results.forEach((item) => {
console.log(item.memory, item.memoryType, item.eventDate); console.log(item.memory, item.score);
}); });
``` ```
</CodeGroup> </CodeGroup>
@@ -249,8 +195,7 @@ results.results.forEach((item) => {
## Verify the feature is working ## Verify the feature is working
- Run a temporal search and confirm results include top-level fields like `memory_type`, `event_date`, or `effective_plan_status`. - Run a temporal search with a time-aware query ("what did I do last week?") and confirm the result ordering matches temporal intent — the memory that fits the time window should rank first.
- Repeat the same query with `temporal_reasoning=False` and confirm ranking changes for time-sensitive prompts.
- Use `reference_date` in test queries so relative phrases resolve consistently. - Use `reference_date` in test queries so relative phrases resolve consistently.
- For backfilled data, confirm imported memories use the expected chronology after you set `timestamp`. - For backfilled data, confirm imported memories use the expected chronology after you set `timestamp`.
@@ -260,7 +205,6 @@ results.results.forEach((item) => {
- Pass `timestamp` during historical imports so ingestion time does not become the only time anchor. - Pass `timestamp` during historical imports so ingestion time does not become the only time anchor.
- Keep search scoped with `filters` so time-aware ranking runs inside the right entity boundary. - Keep search scoped with `filters` so time-aware ranking runs inside the right entity boundary.
- Use `reference_date` in automated tests and reproducible demos. - Use `reference_date` in automated tests and reproducible demos.
- Disable Temporal Reasoning only for clearly timeless lookups such as static profile fields.
<CardGroup cols={2}> <CardGroup cols={2}>
<Card title="Memory Timestamps" icon="calendar" href="/platform/features/timestamp"> <Card title="Memory Timestamps" icon="calendar" href="/platform/features/timestamp">