Add User Model Service and Temporal Recall for MeMind V0.1.
Introduce UMS ingest/snapshot pipeline, Context Planner with multi-source recall, runtime context injection, canonical user mapping, and session snapshot loading on auth/me. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://memind.local/schemas/context-plan.v1.schema.json",
|
||||
"title": "ContextPlan",
|
||||
"description": "Context Planner 输出 — 决定需要哪些上下文及多源检索计划",
|
||||
"type": "object",
|
||||
"required": ["query_type", "time", "temporal_mode", "targets", "sources", "retrievals", "context_needs"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"query_type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"personal_temporal_recall",
|
||||
"memory_lookup",
|
||||
"profile_only",
|
||||
"general_chat",
|
||||
"task_execution"
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"type": "object",
|
||||
"required": ["mention_range"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"mention_range": {
|
||||
"$ref": "#/$defs/timeRange",
|
||||
"description": "按 observed_time / 提及时间过滤"
|
||||
},
|
||||
"event_range": {
|
||||
"oneOf": [{ "$ref": "#/$defs/timeRange" }, { "type": "null" }],
|
||||
"description": "按 event_time / 计划发生时间过滤"
|
||||
},
|
||||
"relative_label": {
|
||||
"type": ["string", "null"],
|
||||
"enum": [
|
||||
"today",
|
||||
"yesterday",
|
||||
"day_before_yesterday",
|
||||
"this_week",
|
||||
"last_week",
|
||||
"this_month",
|
||||
"last_month",
|
||||
"recent_days",
|
||||
null
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"temporal_mode": {
|
||||
"type": "string",
|
||||
"enum": ["OCCURRED_IN", "MENTIONED_IN", "PLANNED_IN", "CREATED_IN", "DUE_IN", "AMBIGUOUS"]
|
||||
},
|
||||
"targets": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["type", "weight"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"calendar_event",
|
||||
"event",
|
||||
"schedule",
|
||||
"todo",
|
||||
"commitment",
|
||||
"decision",
|
||||
"mention",
|
||||
"important_event"
|
||||
]
|
||||
},
|
||||
"weight": { "type": "number", "minimum": 0, "maximum": 1 }
|
||||
}
|
||||
}
|
||||
},
|
||||
"sources": {
|
||||
"type": "object",
|
||||
"additionalProperties": { "type": "number", "minimum": 0, "maximum": 1 },
|
||||
"propertyNames": {
|
||||
"enum": ["calendar", "chat", "meinput", "memory_v2", "email", "browser", "tasks", "git"]
|
||||
}
|
||||
},
|
||||
"retrievals": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["source", "query_type", "weight"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"source": {
|
||||
"type": "string",
|
||||
"enum": ["calendar", "chat", "meinput", "memory_v2"]
|
||||
},
|
||||
"query_type": {
|
||||
"type": "string",
|
||||
"description": "源内检索策略,如 important_mentions | commitments_and_decisions | events"
|
||||
},
|
||||
"expanded_queries": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "maxLength": 128 }
|
||||
},
|
||||
"weight": { "type": "number", "minimum": 0, "maximum": 1 },
|
||||
"skip_below": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1,
|
||||
"default": 0.3,
|
||||
"description": "低于此权重的 source 跳过检索"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"filters": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"importance_min": { "type": "number", "minimum": 0, "maximum": 1 },
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["any", "unresolved", "planned", "completed"]
|
||||
},
|
||||
"participants": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"group_by": {
|
||||
"type": "string",
|
||||
"enum": ["importance", "time", "source", "type"]
|
||||
},
|
||||
"dedupe": { "type": "boolean", "default": true },
|
||||
"timeline": { "type": "boolean", "default": true },
|
||||
"wide_recall": { "type": "boolean", "default": true },
|
||||
"max_items": { "type": "integer", "minimum": 1, "maximum": 200, "default": 50 }
|
||||
}
|
||||
},
|
||||
"context_needs": {
|
||||
"type": "object",
|
||||
"required": ["user_snapshot", "temporal_recall", "memory_retrieval"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"user_snapshot": { "type": "string", "enum": ["REQUIRED", "OPTIONAL", "SKIP"] },
|
||||
"temporal_recall": { "type": "string", "enum": ["REQUIRED", "OPTIONAL", "SKIP"] },
|
||||
"memory_retrieval": { "type": "string", "enum": ["REQUIRED", "OPTIONAL", "SKIP"] }
|
||||
}
|
||||
},
|
||||
"planner_meta": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"level": { "type": "string", "enum": ["cheap_router", "semantic_planner"] },
|
||||
"rule_hits": { "type": "array", "items": { "type": "string" } },
|
||||
"confidence": { "type": "number", "minimum": 0, "maximum": 1 }
|
||||
}
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"timeRange": {
|
||||
"type": "object",
|
||||
"required": ["start", "end"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"start": { "type": "string", "format": "date-time" },
|
||||
"end": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://memind.local/schemas/evidence-envelope.v1.schema.json",
|
||||
"title": "EvidenceEnvelope",
|
||||
"description": "通用 Evidence Contract v1。所有 Source(MeInput、Chat、Calendar、Browser、Git…)统一产出此结构;UMS 只消费 Envelope,不依赖各 Source 内部表结构。",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"evidence_id",
|
||||
"user_id",
|
||||
"source_type",
|
||||
"source_ref",
|
||||
"occurred_at",
|
||||
"evidence_type",
|
||||
"payload",
|
||||
"content_hash",
|
||||
"schema_version"
|
||||
],
|
||||
"properties": {
|
||||
"evidence_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Evidence 全局唯一 ID(由 Source 或 Export 层生成)"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "MeMind h5_users.id"
|
||||
},
|
||||
"source_type": {
|
||||
"type": "string",
|
||||
"enum": ["meinput", "chat", "calendar", "browser", "git", "mail", "filesystem", "voice", "location"],
|
||||
"description": "Evidence Source 类型,与 MeMind Source 体系对齐"
|
||||
},
|
||||
"source_ref": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"maxLength": 512,
|
||||
"description": "Source 内稳定引用,如 segment_id / message_id / commit_sha"
|
||||
},
|
||||
"occurred_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Evidence 发生时间(用户行为时间,非入库时间)"
|
||||
},
|
||||
"received_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Source 侧接收/导出时间,可选"
|
||||
},
|
||||
"evidence_type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"expression_segment",
|
||||
"expression_commit",
|
||||
"expression_session",
|
||||
"chat_message",
|
||||
"calendar_event",
|
||||
"browser_visit",
|
||||
"git_commit",
|
||||
"aggregate_daily",
|
||||
"timeline_report"
|
||||
],
|
||||
"description": "Evidence 语义类型,决定 payload 子 schema"
|
||||
},
|
||||
"payload": {
|
||||
"type": "object",
|
||||
"description": "类型化载荷,见 $defs"
|
||||
},
|
||||
"content_hash": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-f0-9]{64}$",
|
||||
"description": "SHA-256(canonical_json(payload)+evidence_type+source_ref),用于幂等与去重"
|
||||
},
|
||||
"schema_version": {
|
||||
"type": "integer",
|
||||
"const": 1
|
||||
},
|
||||
"privacy_level": {
|
||||
"type": "string",
|
||||
"enum": ["normal", "restricted", "secure_skip"],
|
||||
"default": "normal",
|
||||
"description": "secure_skip 的 Evidence 不应离开 Source;Export 层必须过滤"
|
||||
},
|
||||
"locale": {
|
||||
"type": "string",
|
||||
"description": "如 zh-CN,可选"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"$defs": {
|
||||
"ExpressionSegmentPayload": {
|
||||
"type": "object",
|
||||
"required": ["text", "start_at", "end_at", "event_ids"],
|
||||
"properties": {
|
||||
"text": { "type": "string", "minLength": 1 },
|
||||
"start_at": { "type": "string", "format": "date-time" },
|
||||
"end_at": { "type": "string", "format": "date-time" },
|
||||
"event_ids": { "type": "array", "items": { "type": "string", "format": "uuid" }, "minItems": 1 },
|
||||
"event_count": { "type": "integer", "minimum": 1 },
|
||||
"context": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"app": { "type": ["string", "null"] },
|
||||
"app_bundle_id": { "type": ["string", "null"] },
|
||||
"device_id": { "type": "string" },
|
||||
"scene": { "type": "string" },
|
||||
"input_method": { "type": ["string", "null"] },
|
||||
"language": { "type": ["string", "null"] }
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"AggregateDailyPayload": {
|
||||
"type": "object",
|
||||
"required": ["day", "stats"],
|
||||
"properties": {
|
||||
"day": { "type": "string", "format": "date" },
|
||||
"stats": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"events": { "type": "integer", "minimum": 0 },
|
||||
"segments": { "type": "integer", "minimum": 0 },
|
||||
"chars": { "type": "integer", "minimum": 0 },
|
||||
"peak_hour": { "type": "integer", "minimum": 0, "maximum": 23 },
|
||||
"top_apps": { "type": "array", "items": { "type": "string" } },
|
||||
"top_terms": { "type": "array", "items": { "type": "string" } }
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"TimelineReportPayload": {
|
||||
"type": "object",
|
||||
"required": ["report_type", "period_key", "edition", "status", "content"],
|
||||
"properties": {
|
||||
"report_type": { "type": "string", "enum": ["daily_close", "weekly_review"] },
|
||||
"period_key": { "type": "string" },
|
||||
"edition": { "type": "integer", "minimum": 1 },
|
||||
"status": { "type": "string", "enum": ["published", "revoked"] },
|
||||
"content": { "type": "object" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
-- memind_user_model v0 — User Model Service (UMS)
|
||||
-- 库:memind_user_model(与 meinput、goose 并列,独立 RDS 库或 schema)
|
||||
-- UMS 只 ingest Evidence Envelope v1,不读 meinput.mi_* 表。
|
||||
|
||||
-- ── L0: 原始 Evidence(immutable append)────────────────────────────────────
|
||||
|
||||
CREATE TABLE IF NOT EXISTS um_evidence (
|
||||
evidence_id CHAR(36) PRIMARY KEY,
|
||||
user_id CHAR(36) NOT NULL,
|
||||
source_type VARCHAR(32) NOT NULL,
|
||||
source_ref VARCHAR(512) NOT NULL,
|
||||
evidence_type VARCHAR(64) NOT NULL,
|
||||
occurred_at DATETIME(3) NOT NULL,
|
||||
received_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
content_hash CHAR(64) NOT NULL,
|
||||
schema_version INT NOT NULL DEFAULT 1,
|
||||
privacy_level VARCHAR(32) NOT NULL DEFAULT 'normal',
|
||||
payload_json JSON NOT NULL,
|
||||
UNIQUE KEY uq_um_evidence_content (user_id, content_hash),
|
||||
KEY idx_um_evidence_user_time (user_id, occurred_at DESC),
|
||||
KEY idx_um_evidence_source (user_id, source_type, occurred_at DESC)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── L1: Signal(观察到了什么 — 确定性,可复算)────────────────────────────
|
||||
|
||||
CREATE TABLE IF NOT EXISTS um_signals (
|
||||
signal_id CHAR(36) PRIMARY KEY,
|
||||
user_id CHAR(36) NOT NULL,
|
||||
signal_type VARCHAR(64) NOT NULL,
|
||||
-- 例:term_frequency | app_usage | entity_mention | rhythm_hour | segment_count
|
||||
dimension_key VARCHAR(128) NOT NULL,
|
||||
-- 例:term:MeInput | app:com.tencent.xin | hour:15
|
||||
window_start DATETIME(3) NOT NULL,
|
||||
window_end DATETIME(3) NOT NULL,
|
||||
value_json JSON NOT NULL,
|
||||
-- 例:{"count":126,"chars":8400,"distinct_days":7}
|
||||
evidence_ids JSON NOT NULL,
|
||||
-- 指向 um_evidence.evidence_id 数组
|
||||
computed_at BIGINT NOT NULL,
|
||||
content_hash CHAR(64) NOT NULL,
|
||||
UNIQUE KEY uq_um_signal (user_id, signal_type, dimension_key, window_start, window_end, content_hash),
|
||||
KEY idx_um_signals_user_window (user_id, window_end DESC)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── L2: Candidate(系统推断了什么 — hypothesis)────────────────────────────
|
||||
|
||||
CREATE TABLE IF NOT EXISTS um_candidates (
|
||||
candidate_id CHAR(36) PRIMARY KEY,
|
||||
user_id CHAR(36) NOT NULL,
|
||||
candidate_type VARCHAR(64) NOT NULL,
|
||||
-- project | interest | preference | relation | routine | focus
|
||||
hypothesis_json JSON NOT NULL,
|
||||
-- 例:{"type":"project","name":"MeInput","role":"active"}
|
||||
status ENUM(
|
||||
'observed',
|
||||
'open',
|
||||
'accepted',
|
||||
'rejected',
|
||||
'conflicted',
|
||||
'revoked',
|
||||
'memory_eligible',
|
||||
'memory_promoted'
|
||||
) NOT NULL DEFAULT 'observed',
|
||||
promotion_score DECIMAL(6,4) NOT NULL DEFAULT 0,
|
||||
confidence DECIMAL(6,4) NOT NULL DEFAULT 0,
|
||||
signal_ids JSON NOT NULL,
|
||||
evidence_ids JSON NOT NULL,
|
||||
first_seen_at DATETIME(3) NOT NULL,
|
||||
last_seen_at DATETIME(3) NOT NULL,
|
||||
version INT NOT NULL DEFAULT 1,
|
||||
parent_candidate_id CHAR(36) NULL,
|
||||
conflict_with_id CHAR(36) NULL,
|
||||
created_at BIGINT NOT NULL,
|
||||
updated_at BIGINT NOT NULL,
|
||||
KEY idx_um_candidates_user_status (user_id, status, last_seen_at DESC),
|
||||
KEY idx_um_candidates_user_type (user_id, candidate_type, promotion_score DESC)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── L3: User Model Graph ───────────────────────────────────────────────────
|
||||
|
||||
CREATE TABLE IF NOT EXISTS um_entities (
|
||||
entity_id CHAR(36) PRIMARY KEY,
|
||||
user_id CHAR(36) NOT NULL,
|
||||
entity_type VARCHAR(32) NOT NULL,
|
||||
-- person | project | topic | tool | preference_dim | role
|
||||
canonical_name VARCHAR(256) NOT NULL,
|
||||
aliases_json JSON NULL,
|
||||
status ENUM('active', 'archived', 'revoked') NOT NULL DEFAULT 'active',
|
||||
created_at BIGINT NOT NULL,
|
||||
updated_at BIGINT NOT NULL,
|
||||
UNIQUE KEY uq_um_entity (user_id, entity_type, canonical_name(128))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS um_attributes (
|
||||
attribute_id CHAR(36) PRIMARY KEY,
|
||||
user_id CHAR(36) NOT NULL,
|
||||
entity_id CHAR(36) NULL,
|
||||
attr_key VARCHAR(128) NOT NULL,
|
||||
value_json JSON NOT NULL,
|
||||
confidence DECIMAL(6,4) NOT NULL,
|
||||
decay_halflife_days INT NOT NULL DEFAULT 90,
|
||||
effective_weight DECIMAL(6,4) NOT NULL DEFAULT 1,
|
||||
evidence_ids JSON NOT NULL,
|
||||
candidate_id CHAR(36) NULL,
|
||||
first_seen_at DATETIME(3) NOT NULL,
|
||||
last_seen_at DATETIME(3) NOT NULL,
|
||||
status ENUM('active', 'superseded', 'revoked') NOT NULL DEFAULT 'active',
|
||||
version INT NOT NULL DEFAULT 1,
|
||||
content_hash CHAR(64) NOT NULL,
|
||||
KEY idx_um_attr_user_key (user_id, attr_key, status, effective_weight DESC),
|
||||
CONSTRAINT fk_um_attr_entity FOREIGN KEY (entity_id) REFERENCES um_entities(entity_id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS um_relations (
|
||||
relation_id CHAR(36) PRIMARY KEY,
|
||||
user_id CHAR(36) NOT NULL,
|
||||
from_entity_id CHAR(36) NOT NULL,
|
||||
rel_type VARCHAR(64) NOT NULL,
|
||||
to_entity_id CHAR(36) NOT NULL,
|
||||
confidence DECIMAL(6,4) NOT NULL,
|
||||
evidence_ids JSON NOT NULL,
|
||||
candidate_id CHAR(36) NULL,
|
||||
first_seen_at DATETIME(3) NOT NULL,
|
||||
last_seen_at DATETIME(3) NOT NULL,
|
||||
status ENUM('active', 'superseded', 'revoked') NOT NULL DEFAULT 'active',
|
||||
KEY idx_um_rel_user (user_id, from_entity_id, rel_type),
|
||||
CONSTRAINT fk_um_rel_from FOREIGN KEY (from_entity_id) REFERENCES um_entities(entity_id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_um_rel_to FOREIGN KEY (to_entity_id) REFERENCES um_entities(entity_id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── L4: Profile Projection(Graph 的结构化投影,非 narrative)──────────────
|
||||
|
||||
CREATE TABLE IF NOT EXISTS um_profile_versions (
|
||||
profile_version INT NOT NULL,
|
||||
user_id CHAR(36) NOT NULL,
|
||||
structured_json JSON NOT NULL,
|
||||
content_hash CHAR(64) NOT NULL,
|
||||
parent_version INT NULL,
|
||||
materialize_reason VARCHAR(64) NOT NULL,
|
||||
-- daily_consolidation | candidate_accepted | threshold | manual
|
||||
created_at BIGINT NOT NULL,
|
||||
status ENUM('active', 'superseded', 'revoked') NOT NULL DEFAULT 'active',
|
||||
PRIMARY KEY (user_id, profile_version)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── L5: Agent Snapshot(Profile Projection 的渲染视图,Session 加载)────────
|
||||
|
||||
CREATE TABLE IF NOT EXISTS um_profile_snapshots (
|
||||
snapshot_id CHAR(36) PRIMARY KEY,
|
||||
user_id CHAR(36) NOT NULL,
|
||||
projection VARCHAR(32) NOT NULL DEFAULT 'default',
|
||||
-- default | coding | schedule
|
||||
profile_version INT NOT NULL,
|
||||
fast_revision INT NOT NULL DEFAULT 0,
|
||||
snapshot_json JSON NOT NULL,
|
||||
byte_size INT NOT NULL,
|
||||
content_hash CHAR(64) NOT NULL,
|
||||
created_at BIGINT NOT NULL,
|
||||
expires_at BIGINT NULL,
|
||||
status ENUM('active', 'superseded', 'revoked') NOT NULL DEFAULT 'active',
|
||||
KEY idx_um_snapshot_user_proj (user_id, projection, status, created_at DESC)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── 辅助:ingest 游标(按 user + source_type)────────────────────────────────
|
||||
|
||||
CREATE TABLE IF NOT EXISTS um_ingest_cursors (
|
||||
user_id CHAR(36) NOT NULL,
|
||||
source_type VARCHAR(32) NOT NULL,
|
||||
cursor_value VARCHAR(256) NOT NULL,
|
||||
updated_at BIGINT NOT NULL,
|
||||
PRIMARY KEY (user_id, source_type)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- ── v0.1 预留:Memory lineage(暂不写入,schema 先冻结)────────────────────
|
||||
|
||||
CREATE TABLE IF NOT EXISTS um_memory_promotions (
|
||||
promotion_id CHAR(36) PRIMARY KEY,
|
||||
user_id CHAR(36) NOT NULL,
|
||||
candidate_id CHAR(36) NOT NULL,
|
||||
attribute_id CHAR(36) NULL,
|
||||
memind_candidate_id VARCHAR(64) NULL,
|
||||
content_hash CHAR(64) NOT NULL,
|
||||
promoted_at BIGINT NOT NULL,
|
||||
revoked_at BIGINT NULL,
|
||||
status ENUM('promoted', 'revoked') NOT NULL DEFAULT 'promoted',
|
||||
KEY idx_um_promo_user (user_id, status)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://memind.local/schemas/timeline-item.v1.schema.json",
|
||||
"title": "TimelineItem",
|
||||
"description": "Temporal Recall 统一时间线条目 — 跨 Source 归一化模型",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"timeline_item_id",
|
||||
"user_id",
|
||||
"source",
|
||||
"type",
|
||||
"observed_time",
|
||||
"title",
|
||||
"content",
|
||||
"importance",
|
||||
"confidence",
|
||||
"source_ref",
|
||||
"status"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"timeline_item_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "归一化后的 timeline 条目 ID"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"source": {
|
||||
"type": "string",
|
||||
"enum": ["calendar", "chat", "meinput", "memory_v2", "email", "browser", "tasks", "git", "location", "notes"]
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["event", "todo", "decision", "mention", "commitment"]
|
||||
},
|
||||
"event_time": {
|
||||
"type": ["string", "null"],
|
||||
"format": "date-time",
|
||||
"description": "事件计划/实际发生时间;未知时为 null"
|
||||
},
|
||||
"observed_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "首次被记录/输入/提到的时间"
|
||||
},
|
||||
"title": {
|
||||
"type": "string",
|
||||
"maxLength": 512
|
||||
},
|
||||
"content": {
|
||||
"type": "string",
|
||||
"maxLength": 8192
|
||||
},
|
||||
"importance": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
},
|
||||
"confidence": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1,
|
||||
"description": "抽取/归一化置信度"
|
||||
},
|
||||
"recall_score": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1,
|
||||
"description": "最终召回排序分"
|
||||
},
|
||||
"source_ref": {
|
||||
"type": "string",
|
||||
"maxLength": 512,
|
||||
"description": "源系统引用,如 meinput:segment:<id>"
|
||||
},
|
||||
"participants": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "maxLength": 128 },
|
||||
"default": []
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["planned", "completed", "mentioned", "unknown"]
|
||||
},
|
||||
"merged_from": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "maxLength": 512 },
|
||||
"description": "Dedupe 合并前的 source_ref 列表"
|
||||
},
|
||||
"app_bundle_id": {
|
||||
"type": ["string", "null"],
|
||||
"description": "MeInput 来源 App"
|
||||
},
|
||||
"app_name": {
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user