# Temporal Recall API v1 | 字段 | 值 | |------|-----| | 状态 | **Frozen(V0.1)** | | 建议 Base URL | MeMind Portal 同域 `/api/v1/temporal-recall/*` | | 输入 | `ContextPlan` 或简化 query | | 输出 | `TimelineItem[]` + 分组元数据 | --- ## 1. 职责 按 Context Plan **并行检索**多源,归一化、Dedupe、Rank,返回 Personal Timeline Recall Bundle。 **回答:** 「某个时间范围内发生了什么?」 --- ## 2. `POST /v1/temporal-recall/query` ### 方式 A — 传入完整 Plan(推荐) ```json { "plan": { "...ContextPlan..." }, "limit": 50 } ``` ### 方式 B — 快捷 query(内部先调 Planner) ```json { "query": "我这周有什么重要的事?", "user_id": "a70ff537-8908-486e-9b6c-042e07cc25db", "now": "2026-09-03T22:00:00+08:00", "limit": 50 } ``` ### 响应 ```json { "query_type": "personal_temporal_recall", "temporal_mode": "AMBIGUOUS", "time_range": { "start": "2026-09-01T00:00:00+08:00", "end": "2026-09-08T00:00:00+08:00" }, "groups": [ { "label": "occurred_in_range", "items": [ { "timeline_item_id": "...", "source": "meinput", "type": "mention", "event_time": null, "observed_time": "2026-09-02T14:30:00+08:00", "title": "MeInput 验证上屏", "content": "MeInput验证上屏", "importance": 0.71, "confidence": 0.95, "recall_score": 0.78, "source_ref": "meinput:segment:...", "status": "mentioned" } ] }, { "label": "mentioned_or_planned", "items": [] } ], "items": [], "stats": { "sources_queried": ["meinput", "chat"], "raw_count": 42, "deduped_count": 38, "returned_count": 25, "elapsed_ms": 320 }, "plan": { "...echo ContextPlan..." } } ``` `groups` 在 `temporal_mode=AMBIGUOUS` 时区分「实际发生」与「提到/安排」;否则 `items` 为 flat ranked list。 --- ## 3. `GET /v1/temporal-recall/info` ```json { "schema_version": 1, "supported_sources": ["meinput", "chat"], "planned_sources": ["calendar", "memory_v2", "email", "browser", "tasks"], "temporal_modes": ["OCCURRED_IN", "MENTIONED_IN", "PLANNED_IN", "CREATED_IN", "DUE_IN", "AMBIGUOUS"], "default_limit": 50, "max_limit": 200 } ``` --- ## 4. Source Adapter 契约 每个 adapter 实现: ```typescript interface TemporalSourceAdapter { source: 'meinput' | 'chat' | 'calendar' | 'memory_v2'; search(ctx: { userId: string; retrieval: ContextPlan['retrievals'][0]; time: ContextPlan['time']; temporalMode: ContextPlan['temporal_mode']; }): Promise; } ``` ### MeInput Adapter(V0.1) - 调用 `GET /v1/evidence/export`(MeInput Cloud) - 过滤 `expression_segment`,按 `occurred_at` 映射 `observed_time` - 规则抽取 `event_time`(「明天下午三点」→ 解析为绝对时间) - `source_ref = meinput:segment:{evidence_id}` ### Chat Adapter(V0.1) - 查 `h5_agent_runs` + session messages(用户可见范围) - `observed_time = message.created_at` - commitment/todo 规则抽取 --- ## 5. Rank 公式 ``` recall_score = source_quality(source) × temporal_match(item, plan.time, plan.temporal_mode) × semantic_match(item, expanded_queries) × importance(item) × confidence(item) ``` | 阈值 | 展示 | |------|------| | ≥ 0.75 | 主答案 | | 0.50 ~ 0.75 | 次要 | | < 0.50 | 丢弃 | --- ## 6. Dedupe - 时间:`|event_time_a - event_time_b| < 15min` 或同日 + 同类 - 语义:title/content keyword overlap > 0.7 或 embedding cosine > 0.85(v0.2) - Merge → 保留最高 `source_quality`,填充 `merged_from` --- ## 7. 认证 | 调用方 | 认证 | |--------|------| | Agent Runtime | 用户 sessionToken | | 内部 Worker | `TEMPORAL_RECALL_TOKEN`(可选) | --- ## 8. V0.1 不做 - Calendar / Email / Browser adapter - 持久化 timeline 索引表 - LLM 答案生成(只返回 structured timeline;Answer 层在 Agent) --- ## 9. 错误码 | HTTP | code | 说明 | |------|------|------| | 400 | `invalid_plan` | Plan schema 校验失败 | | 401 | `unauthenticated` | 未登录 | | 503 | `source_unavailable` | MeInput export 不可用 | | 504 | `recall_timeout` | 并行检索超时(默认 5s) |