Files
zclaw_openfang/crates/zclaw-memory/src/schema.rs
iven 4b15ead8e7 feat(hermes): implement intelligence pipeline — 4 chunks, 684 tests passing
Hermes Intelligence Pipeline closes breakpoints in ZCLAW's existing
intelligence components with 4 self-contained modules:

Chunk 1 — Self-improvement Loop:
- ExperienceStore (zclaw-growth): FTS5+TF-IDF wrapper with scope prefix
- ExperienceExtractor (desktop/intelligence): template-based extraction
  from successful proposals with implicit keyword detection

Chunk 2 — User Modeling:
- UserProfileStore (zclaw-memory): SQLite-backed structured profiles
  with industry/role/expertise/comm_style/recent_topics/pain_points
- UserProfiler (desktop/intelligence): fact classification by category
  (Preference/Knowledge/Behavior) with profile summary formatting

Chunk 3 — NL Cron Chinese Time Parser:
- NlScheduleParser (zclaw-runtime): 6 pattern matchers for Chinese time
  expressions (每天/每周/工作日/间隔/每月/一次性) producing cron expressions
- Period-aware hour adjustment (下午3点→15, 晚上8点→20)
- Schedule intent detection + task description extraction

Chunk 4 — Trajectory Compression:
- TrajectoryStore (zclaw-memory): trajectory_events + compressed_trajectories
- TrajectoryRecorderMiddleware (zclaw-runtime/middleware): priority 650,
  async non-blocking event recording via tokio::spawn
- TrajectoryCompressor (desktop/intelligence): dedup, request classification,
  satisfaction detection, execution chain JSON

Schema migrations: v2→v3 (user_profiles), v3→v4 (trajectory tables)
2026-04-09 17:47:43 +08:00

140 lines
4.6 KiB
Rust

//! Database schema definitions
/// Current schema version
pub const SCHEMA_VERSION: i32 = 2;
/// Schema creation SQL
pub const CREATE_SCHEMA: &str = r#"
-- Agents table
CREATE TABLE IF NOT EXISTS agents (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
config TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
-- Sessions table
CREATE TABLE IF NOT EXISTS sessions (
id TEXT PRIMARY KEY,
agent_id TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE
);
-- Messages table
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL,
seq INTEGER NOT NULL,
content TEXT NOT NULL,
created_at TEXT NOT NULL,
FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE,
UNIQUE(session_id, seq)
);
-- KV Store table
CREATE TABLE IF NOT EXISTS kv_store (
agent_id TEXT NOT NULL,
key TEXT NOT NULL,
value TEXT NOT NULL,
updated_at TEXT NOT NULL,
PRIMARY KEY (agent_id, key),
FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE
);
-- Schema version table
CREATE TABLE IF NOT EXISTS schema_version (
version INTEGER PRIMARY KEY
);
-- Hand execution runs table
CREATE TABLE IF NOT EXISTS hand_runs (
id TEXT PRIMARY KEY,
hand_name TEXT NOT NULL,
trigger_source TEXT NOT NULL,
params TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
result TEXT,
error TEXT,
duration_ms INTEGER,
created_at TEXT NOT NULL,
started_at TEXT,
completed_at TEXT
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_sessions_agent ON sessions(agent_id);
CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);
CREATE INDEX IF NOT EXISTS idx_kv_agent ON kv_store(agent_id);
CREATE INDEX IF NOT EXISTS idx_hand_runs_hand ON hand_runs(hand_name);
CREATE INDEX IF NOT EXISTS idx_hand_runs_status ON hand_runs(status);
CREATE INDEX IF NOT EXISTS idx_hand_runs_created ON hand_runs(created_at);
-- Structured facts table (extracted from conversations)
CREATE TABLE IF NOT EXISTS facts (
id TEXT PRIMARY KEY,
agent_id TEXT NOT NULL,
content TEXT NOT NULL,
category TEXT NOT NULL,
confidence REAL NOT NULL,
source_session TEXT,
created_at INTEGER NOT NULL,
FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_facts_agent ON facts(agent_id);
CREATE INDEX IF NOT EXISTS idx_facts_category ON facts(agent_id, category);
CREATE INDEX IF NOT EXISTS idx_facts_confidence ON facts(agent_id, confidence DESC);
"#;
/// Incremental migrations (safe to run repeatedly via ALTER … ADD COLUMN + IF NOT EXISTS pattern)
pub const MIGRATIONS: &[&str] = &[
// v1→v2: persist runtime state and message count
"ALTER TABLE agents ADD COLUMN state TEXT NOT NULL DEFAULT 'running'",
"ALTER TABLE agents ADD COLUMN message_count INTEGER NOT NULL DEFAULT 0",
// v2→v3: user profiles for structured user modeling
"CREATE TABLE IF NOT EXISTS user_profiles (
user_id TEXT PRIMARY KEY,
industry TEXT,
role TEXT,
expertise_level TEXT,
communication_style TEXT,
preferred_language TEXT DEFAULT 'zh-CN',
recent_topics TEXT DEFAULT '[]',
active_pain_points TEXT DEFAULT '[]',
preferred_tools TEXT DEFAULT '[]',
confidence REAL DEFAULT 0.0,
updated_at TEXT NOT NULL
)",
// v3→v4: trajectory recording for tool-call chain analysis
"CREATE TABLE IF NOT EXISTS trajectory_events (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL,
agent_id TEXT NOT NULL,
step_index INTEGER NOT NULL,
step_type TEXT NOT NULL,
input_summary TEXT,
output_summary TEXT,
duration_ms INTEGER DEFAULT 0,
timestamp TEXT NOT NULL
)",
"CREATE INDEX IF NOT EXISTS idx_trajectory_session ON trajectory_events(session_id)",
"CREATE TABLE IF NOT EXISTS compressed_trajectories (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL,
agent_id TEXT NOT NULL,
request_type TEXT NOT NULL,
tools_used TEXT,
outcome TEXT NOT NULL,
total_steps INTEGER DEFAULT 0,
total_duration_ms INTEGER DEFAULT 0,
total_tokens INTEGER DEFAULT 0,
execution_chain TEXT NOT NULL,
satisfaction_signal TEXT,
created_at TEXT NOT NULL
)",
"CREATE INDEX IF NOT EXISTS idx_ct_request_type ON compressed_trajectories(request_type)",
"CREATE INDEX IF NOT EXISTS idx_ct_outcome ON compressed_trajectories(outcome)",
];