auto-sync: 2026-05-17 00:42:06
This commit is contained in:
+160
-189
@@ -12,7 +12,8 @@ def init_db(db_path: Path) -> None:
|
|||||||
db_path.parent.mkdir(parents=True, exist_ok=True)
|
db_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
conn = _connect(db_path)
|
conn = _connect(db_path)
|
||||||
try:
|
try:
|
||||||
conn.executescript(SCHEMA_SQL)
|
for stmt in _SCHEMA_STATEMENTS:
|
||||||
|
conn.execute(stmt)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
finally:
|
finally:
|
||||||
conn.close()
|
conn.close()
|
||||||
@@ -90,203 +91,173 @@ ATTEMPT_OUTCOMES = frozenset({
|
|||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Schema SQL
|
# Schema - split into individual statements to avoid SQLite 3.51 CHECK bug
|
||||||
|
# (table-level CHECK as non-last column definition causes parse error)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
SCHEMA_SQL = """
|
_SCHEMA_STATEMENTS = [
|
||||||
-- ===== 任务表 =====
|
# tasks
|
||||||
CREATE TABLE IF NOT EXISTS tasks (
|
"""CREATE TABLE IF NOT EXISTS tasks (
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
description TEXT,
|
description TEXT,
|
||||||
status TEXT NOT NULL DEFAULT 'pending',
|
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','claimed','working','review','done','failed','blocked','cancelled')),
|
||||||
CHECK (status IN ('pending','claimed','working','review','done','failed','blocked','cancelled')),
|
assignee TEXT,
|
||||||
|
assigned_by TEXT,
|
||||||
|
depends_on TEXT,
|
||||||
|
parent_task TEXT,
|
||||||
|
priority INTEGER NOT NULL DEFAULT 5,
|
||||||
|
task_type TEXT,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
claimed_at TEXT,
|
||||||
|
started_at TEXT,
|
||||||
|
completed_at TEXT,
|
||||||
|
deadline TEXT,
|
||||||
|
retry_count INTEGER NOT NULL DEFAULT 0,
|
||||||
|
max_retries INTEGER NOT NULL DEFAULT 2,
|
||||||
|
must_haves TEXT,
|
||||||
|
risk_level TEXT DEFAULT 'standard',
|
||||||
|
estimated_duration_minutes INTEGER,
|
||||||
|
escalated INTEGER DEFAULT 0
|
||||||
|
)""",
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_tasks_assignee ON tasks(assignee)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_tasks_parent ON tasks(parent_task)",
|
||||||
|
|
||||||
assignee TEXT,
|
# comments
|
||||||
assigned_by TEXT,
|
"""CREATE TABLE IF NOT EXISTS comments (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
task_id TEXT NOT NULL REFERENCES tasks(id),
|
||||||
|
author TEXT NOT NULL,
|
||||||
|
comment_type TEXT NOT NULL DEFAULT 'general' CHECK (comment_type IN ('general','handoff','observation','rebuttal','rebuttal_response','debate_argument','debate_rebuttal','debate_judgment')),
|
||||||
|
body TEXT NOT NULL,
|
||||||
|
mentions TEXT,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
)""",
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_comments_task ON comments(task_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_comments_type ON comments(task_id, comment_type)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_comments_author ON comments(author)",
|
||||||
|
|
||||||
depends_on TEXT,
|
# outputs
|
||||||
parent_task TEXT,
|
"""CREATE TABLE IF NOT EXISTS outputs (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
task_id TEXT NOT NULL REFERENCES tasks(id),
|
||||||
|
agent TEXT NOT NULL,
|
||||||
|
output_type TEXT NOT NULL CHECK (output_type IN ('code','document','data','config','other')),
|
||||||
|
title TEXT NOT NULL,
|
||||||
|
content_path TEXT,
|
||||||
|
summary TEXT,
|
||||||
|
metadata TEXT,
|
||||||
|
attempt_number INTEGER DEFAULT 1,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
)""",
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_outputs_task ON outputs(task_id)",
|
||||||
|
|
||||||
priority INTEGER NOT NULL DEFAULT 5,
|
# decisions
|
||||||
task_type TEXT,
|
"""CREATE TABLE IF NOT EXISTS decisions (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
task_id TEXT NOT NULL REFERENCES tasks(id),
|
||||||
|
decider TEXT NOT NULL,
|
||||||
|
decision TEXT NOT NULL,
|
||||||
|
rationale TEXT NOT NULL,
|
||||||
|
alternatives TEXT,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
)""",
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_decisions_task ON decisions(task_id)",
|
||||||
|
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
# observations
|
||||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
"""CREATE TABLE IF NOT EXISTS observations (
|
||||||
claimed_at TEXT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
started_at TEXT,
|
task_id TEXT NOT NULL REFERENCES tasks(id),
|
||||||
completed_at TEXT,
|
observer TEXT NOT NULL,
|
||||||
deadline TEXT,
|
severity TEXT NOT NULL DEFAULT 'info' CHECK (severity IN ('blocking','warning','info','audit')),
|
||||||
|
body TEXT NOT NULL,
|
||||||
|
resolved_by TEXT,
|
||||||
|
resolved_at TEXT,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
)""",
|
||||||
|
|
||||||
retry_count INTEGER NOT NULL DEFAULT 0,
|
# events
|
||||||
max_retries INTEGER NOT NULL DEFAULT 2,
|
"""CREATE TABLE IF NOT EXISTS events (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
task_id TEXT,
|
||||||
|
agent TEXT,
|
||||||
|
event_type TEXT NOT NULL,
|
||||||
|
detail TEXT,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
)""",
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_events_task ON events(task_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_events_time ON events(created_at)",
|
||||||
|
|
||||||
must_haves TEXT,
|
# agents
|
||||||
risk_level TEXT DEFAULT 'standard',
|
"""CREATE TABLE IF NOT EXISTS agents (
|
||||||
estimated_duration_minutes INTEGER,
|
agent_id TEXT PRIMARY KEY,
|
||||||
|
role TEXT,
|
||||||
|
current_status TEXT DEFAULT 'idle',
|
||||||
|
current_task TEXT,
|
||||||
|
last_active TEXT,
|
||||||
|
capabilities TEXT
|
||||||
|
)""",
|
||||||
|
|
||||||
escalated INTEGER DEFAULT 0
|
# task_attempts
|
||||||
);
|
"""CREATE TABLE IF NOT EXISTS task_attempts (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
task_id TEXT NOT NULL REFERENCES tasks(id),
|
||||||
|
attempt_number INTEGER NOT NULL,
|
||||||
|
agent TEXT NOT NULL,
|
||||||
|
outcome TEXT NOT NULL CHECK (outcome IN ('completed','blocked','crashed','timed_out','spawn_failed','reclaimed')),
|
||||||
|
exit_code INTEGER,
|
||||||
|
log_path TEXT,
|
||||||
|
summary TEXT,
|
||||||
|
metadata TEXT,
|
||||||
|
started_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
completed_at TEXT
|
||||||
|
)""",
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_attempts_task ON task_attempts(task_id)",
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
|
# reviews
|
||||||
CREATE INDEX IF NOT EXISTS idx_tasks_assignee ON tasks(assignee);
|
"""CREATE TABLE IF NOT EXISTS reviews (
|
||||||
CREATE INDEX IF NOT EXISTS idx_tasks_parent ON tasks(parent_task);
|
id TEXT PRIMARY KEY,
|
||||||
|
task_id TEXT NOT NULL REFERENCES tasks(id),
|
||||||
|
output_id TEXT,
|
||||||
|
reviewer TEXT NOT NULL,
|
||||||
|
review_type TEXT NOT NULL CHECK (review_type IN ('plan_review','output_review','guardrail','final_review')),
|
||||||
|
verdict TEXT NOT NULL CHECK (verdict IN ('approved','rejected','needs_revision')),
|
||||||
|
confidence REAL,
|
||||||
|
round INTEGER NOT NULL DEFAULT 1,
|
||||||
|
max_rounds INTEGER NOT NULL DEFAULT 3,
|
||||||
|
consensus_reached INTEGER DEFAULT 0,
|
||||||
|
summary TEXT NOT NULL,
|
||||||
|
detail_path TEXT,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
)""",
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_reviews_task ON reviews(task_id)",
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_reviews_output ON reviews(output_id)",
|
||||||
|
|
||||||
-- ===== 评论线程表 =====
|
# experiences
|
||||||
CREATE TABLE IF NOT EXISTS comments (
|
"""CREATE TABLE IF NOT EXISTS experiences (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
experience_id TEXT PRIMARY KEY,
|
||||||
task_id TEXT NOT NULL,
|
source TEXT NOT NULL CHECK (source IN ('task_completion','error_correction','review_finding','manual')),
|
||||||
author TEXT NOT NULL,
|
task_id TEXT,
|
||||||
comment_type TEXT NOT NULL DEFAULT 'general',
|
summary TEXT NOT NULL,
|
||||||
body TEXT NOT NULL,
|
category TEXT NOT NULL CHECK (category IN ('pitfall','best_practice','pattern','anti_pattern')),
|
||||||
mentions TEXT,
|
confidence REAL DEFAULT 0.8,
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
status TEXT DEFAULT 'active' CHECK (status IN ('draft','active','deprecated')),
|
||||||
FOREIGN KEY (task_id) REFERENCES tasks(id),
|
skill_id TEXT,
|
||||||
CHECK (comment_type IN ('general','handoff','observation','rebuttal','rebuttal_response','debate_argument','debate_rebuttal','debate_judgment'))
|
usage_count INTEGER DEFAULT 0,
|
||||||
);
|
last_used_at TEXT,
|
||||||
|
created_at TEXT NOT NULL,
|
||||||
|
created_by TEXT NOT NULL,
|
||||||
|
updated_at TEXT,
|
||||||
|
deprecated_reason TEXT
|
||||||
|
)""",
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_comments_task ON comments(task_id);
|
# experience_tags
|
||||||
CREATE INDEX IF NOT EXISTS idx_comments_type ON comments(task_id, comment_type);
|
"""CREATE TABLE IF NOT EXISTS experience_tags (
|
||||||
CREATE INDEX IF NOT EXISTS idx_comments_author ON comments(author);
|
experience_id TEXT NOT NULL REFERENCES experiences(experience_id),
|
||||||
|
tag TEXT NOT NULL,
|
||||||
-- ===== 产出表 =====
|
PRIMARY KEY (experience_id, tag)
|
||||||
CREATE TABLE IF NOT EXISTS outputs (
|
)""",
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
"CREATE INDEX IF NOT EXISTS idx_exptags_tag ON experience_tags(tag)",
|
||||||
task_id TEXT NOT NULL,
|
]
|
||||||
agent TEXT NOT NULL,
|
|
||||||
output_type TEXT NOT NULL,
|
|
||||||
title TEXT NOT NULL,
|
|
||||||
content_path TEXT,
|
|
||||||
summary TEXT,
|
|
||||||
metadata TEXT,
|
|
||||||
attempt_number INTEGER DEFAULT 1,
|
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
||||||
FOREIGN KEY (task_id) REFERENCES tasks(id),
|
|
||||||
CHECK (output_type IN ('code','document','data','config','other'))
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_outputs_task ON outputs(task_id);
|
|
||||||
|
|
||||||
-- ===== 决策记录表 =====
|
|
||||||
CREATE TABLE IF NOT EXISTS decisions (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
task_id TEXT NOT NULL,
|
|
||||||
decider TEXT NOT NULL,
|
|
||||||
decision TEXT NOT NULL,
|
|
||||||
rationale TEXT NOT NULL,
|
|
||||||
alternatives TEXT,
|
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
||||||
FOREIGN KEY (task_id) REFERENCES tasks(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_decisions_task ON decisions(task_id);
|
|
||||||
|
|
||||||
-- ===== 观察表 =====
|
|
||||||
CREATE TABLE IF NOT EXISTS observations (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
task_id TEXT NOT NULL,
|
|
||||||
observer TEXT NOT NULL,
|
|
||||||
severity TEXT NOT NULL DEFAULT 'info',
|
|
||||||
CHECK (severity IN ('blocking','warning','info','audit')),
|
|
||||||
body TEXT NOT NULL,
|
|
||||||
resolved_by TEXT,
|
|
||||||
resolved_at TEXT,
|
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
||||||
FOREIGN KEY (task_id) REFERENCES tasks(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- ===== 事件日志 =====
|
|
||||||
CREATE TABLE IF NOT EXISTS events (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
task_id TEXT,
|
|
||||||
agent TEXT,
|
|
||||||
event_type TEXT NOT NULL,
|
|
||||||
detail TEXT,
|
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_events_task ON events(task_id);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_events_time ON events(created_at);
|
|
||||||
|
|
||||||
-- ===== Agent 注册表 =====
|
|
||||||
CREATE TABLE IF NOT EXISTS agents (
|
|
||||||
agent_id TEXT PRIMARY KEY,
|
|
||||||
role TEXT,
|
|
||||||
current_status TEXT DEFAULT 'idle',
|
|
||||||
current_task TEXT,
|
|
||||||
last_active TEXT,
|
|
||||||
capabilities TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
-- ===== 任务尝试记录 =====
|
|
||||||
CREATE TABLE IF NOT EXISTS task_attempts (
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
task_id TEXT NOT NULL,
|
|
||||||
attempt_number INTEGER NOT NULL,
|
|
||||||
agent TEXT NOT NULL,
|
|
||||||
outcome TEXT NOT NULL,
|
|
||||||
CHECK (outcome IN ('completed','blocked','crashed','timed_out','spawn_failed','reclaimed')),
|
|
||||||
exit_code INTEGER,
|
|
||||||
log_path TEXT,
|
|
||||||
summary TEXT,
|
|
||||||
metadata TEXT,
|
|
||||||
started_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
||||||
completed_at TEXT,
|
|
||||||
FOREIGN KEY (task_id) REFERENCES tasks(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_attempts_task ON task_attempts(task_id);
|
|
||||||
|
|
||||||
-- ===== 评审表 =====
|
|
||||||
CREATE TABLE IF NOT EXISTS reviews (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
task_id TEXT NOT NULL,
|
|
||||||
output_id TEXT,
|
|
||||||
reviewer TEXT NOT NULL,
|
|
||||||
review_type TEXT NOT NULL,
|
|
||||||
CHECK (review_type IN ('plan_review','output_review','guardrail','final_review')),
|
|
||||||
verdict TEXT NOT NULL,
|
|
||||||
CHECK (verdict IN ('approved','rejected','needs_revision')),
|
|
||||||
confidence REAL,
|
|
||||||
round INTEGER NOT NULL DEFAULT 1,
|
|
||||||
max_rounds INTEGER NOT NULL DEFAULT 3,
|
|
||||||
consensus_reached INTEGER DEFAULT 0,
|
|
||||||
summary TEXT NOT NULL,
|
|
||||||
detail_path TEXT,
|
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
||||||
FOREIGN KEY (task_id) REFERENCES tasks(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_reviews_task ON reviews(task_id);
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_reviews_output ON reviews(output_id);
|
|
||||||
|
|
||||||
-- ===== 经验表 =====
|
|
||||||
CREATE TABLE IF NOT EXISTS experiences (
|
|
||||||
experience_id TEXT PRIMARY KEY,
|
|
||||||
source TEXT NOT NULL,
|
|
||||||
CHECK (source IN ('task_completion','error_correction','review_finding','manual')),
|
|
||||||
task_id TEXT,
|
|
||||||
summary TEXT NOT NULL,
|
|
||||||
category TEXT NOT NULL,
|
|
||||||
CHECK (category IN ('pitfall','best_practice','pattern','anti_pattern')),
|
|
||||||
confidence REAL DEFAULT 0.8,
|
|
||||||
status TEXT DEFAULT 'active',
|
|
||||||
CHECK (status IN ('draft','active','deprecated')),
|
|
||||||
skill_id TEXT,
|
|
||||||
usage_count INTEGER DEFAULT 0,
|
|
||||||
last_used_at TEXT,
|
|
||||||
created_at TEXT NOT NULL,
|
|
||||||
created_by TEXT NOT NULL,
|
|
||||||
updated_at TEXT,
|
|
||||||
deprecated_reason TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
-- ===== 经验标签关联表 =====
|
|
||||||
CREATE TABLE IF NOT EXISTS experience_tags (
|
|
||||||
experience_id TEXT NOT NULL REFERENCES experiences(experience_id),
|
|
||||||
tag TEXT NOT NULL,
|
|
||||||
PRIMARY KEY (experience_id, tag)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_exptags_tag ON experience_tags(tag);
|
|
||||||
"""
|
|
||||||
|
|||||||
Reference in New Issue
Block a user