212ff3ff80
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>
188 lines
8.1 KiB
SQL
188 lines
8.1 KiB
SQL
-- 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;
|