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:
co-authored by
Claude Sonnet 4.6
parent
b2d2c8a8ef
commit
f864e9b871
@@ -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. |
|
||||
| `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. |
|
||||
| `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.
|
||||
|
||||
|
||||
@@ -81,53 +81,9 @@ await client.add(
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Compare Retrieval Modes
|
||||
## Run a Temporal Search
|
||||
|
||||
The easiest way to understand Temporal Reasoning is to compare the same query in two modes:
|
||||
|
||||
- **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.
|
||||
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.
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
@@ -138,12 +94,7 @@ results = client.search(
|
||||
)
|
||||
|
||||
for item in results["results"]:
|
||||
print(
|
||||
item["memory"],
|
||||
item.get("memory_type"),
|
||||
item.get("event_date"),
|
||||
item.get("temporal_surface"),
|
||||
)
|
||||
print(item["memory"], item["score"])
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
@@ -153,20 +104,20 @@ const results = await client.search("what did I do last week?", {
|
||||
});
|
||||
|
||||
results.results.forEach((item) => {
|
||||
console.log(item.memory, item.memoryType, item.eventDate, item.temporalSurface);
|
||||
console.log(item.memory, item.score);
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
**Illustrative output:**
|
||||
```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">
|
||||
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>
|
||||
|
||||
## See the Three Query Shapes
|
||||
@@ -200,7 +151,7 @@ upcoming = client.search(
|
||||
)
|
||||
|
||||
for item in upcoming["results"]:
|
||||
print(item["memory"], item.get("memory_type"), item.get("effective_plan_status"))
|
||||
print(item["memory"], item["score"])
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
@@ -210,14 +161,14 @@ const upcoming = await client.search("what do I have coming up?", {
|
||||
});
|
||||
|
||||
upcoming.results.forEach((item) => {
|
||||
console.log(item.memory, item.memoryType, item.effectivePlanStatus);
|
||||
console.log(item.memory, item.score);
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
**Illustrative output:**
|
||||
```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>
|
||||
@@ -237,7 +188,7 @@ current = client.search(
|
||||
)
|
||||
|
||||
for item in current["results"]:
|
||||
print(item["memory"], item.get("memory_type"), item.get("temporal_surface"))
|
||||
print(item["memory"], item["score"])
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
@@ -247,22 +198,19 @@ const current = await client.search("where do I work right now?", {
|
||||
});
|
||||
|
||||
current.results.forEach((item) => {
|
||||
console.log(item.memory, item.memoryType, item.temporalSurface);
|
||||
console.log(item.memory, item.score);
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
**Illustrative output:**
|
||||
```text
|
||||
I am the product lead at Acme Corp. state ongoing
|
||||
I am the product lead at Acme Corp.
|
||||
```
|
||||
|
||||
## Use the Right Controls
|
||||
|
||||
There are two public controls that matter most in production:
|
||||
|
||||
- `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
|
||||
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
|
||||
|
||||
@@ -285,27 +233,6 @@ await client.search("what did I do last week?", {
|
||||
```
|
||||
</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
|
||||
|
||||
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.
|
||||
- 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.
|
||||
- You can switch between standard retrieval and temporal retrieval per request with `temporal_reasoning`.
|
||||
|
||||
## Next Steps
|
||||
|
||||
|
||||
+1
-21
@@ -2093,11 +2093,6 @@
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"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,
|
||||
"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": {
|
||||
"semantic": 0.78,
|
||||
"bm25": 0.0,
|
||||
"entity": 0.0,
|
||||
"temporal_boost": 0.04
|
||||
"entity": 0.0
|
||||
},
|
||||
"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": {},
|
||||
"categories": [
|
||||
"location"
|
||||
|
||||
@@ -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." |
|
||||
| `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:
|
||||
|
||||
- `memory_type`
|
||||
- `event_date`
|
||||
- `event_start`
|
||||
- `event_end`
|
||||
- `plan_status`
|
||||
- `effective_plan_status`
|
||||
- `time_precision`
|
||||
- `temporal_surface`
|
||||
- `reference_date_used`
|
||||
- `score_breakdown.temporal_boost`
|
||||
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.
|
||||
|
||||
## Configure it
|
||||
|
||||
### Default behavior
|
||||
|
||||
Temporal Reasoning is enabled by default for supported v3 searches and writes.
|
||||
|
||||
### 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>
|
||||
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.
|
||||
|
||||
### Anchor imports and tests
|
||||
|
||||
@@ -208,7 +154,7 @@ results = client.search(
|
||||
)
|
||||
|
||||
for item in results["results"]:
|
||||
print(item["memory"], item.get("memory_type"), item.get("event_date"))
|
||||
print(item["memory"], item["score"])
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
@@ -218,7 +164,7 @@ const results = await client.search("what did I do last week?", {
|
||||
});
|
||||
|
||||
results.results.forEach((item) => {
|
||||
console.log(item.memory, item.memoryType, item.eventDate);
|
||||
console.log(item.memory, item.score);
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -249,8 +195,7 @@ results.results.forEach((item) => {
|
||||
|
||||
## 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`.
|
||||
- Repeat the same query with `temporal_reasoning=False` and confirm ranking changes for time-sensitive prompts.
|
||||
- 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.
|
||||
- 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`.
|
||||
|
||||
@@ -260,7 +205,6 @@ results.results.forEach((item) => {
|
||||
- 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.
|
||||
- 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}>
|
||||
<Card title="Memory Timestamps" icon="calendar" href="/platform/features/timestamp">
|
||||
|
||||
Reference in New Issue
Block a user