refactor: 全栈架构重构与质量硬化——API 错误统一、工具域重组、安全加固、前端组件化
后端核心变更: - API 层: 新增 AppError 枚举统一错误类型,替代散落的 (StatusCode, String) - Agent 工具域: 重组为 astro/system/ 和 astro/research/ 两级域,新增 ProcessPaperTool 流水线工具 - 安全: 新增 SSRF 双层防护 (同步字符串级 + 异步 DNS 解析级),覆盖 IPv4/IPv6 私网段 - 弱密码检测: 扩展弱密码列表并增加最小长度检查 - LLM 客户端: 新增 ChatCompleter/Embedder trait,支持依赖注入与批量向量化 embed_batch - 批量处理: AssetBatch 从串行改为 Semaphore 并发池 (BATCH_CONCURRENCY=3) - 分块器: 重写为三阶段结构化管线 (章节解析→短节合并→带标题路径子块) - RAG: embedding 计算移出事务,RetrievalResult 新增 headings/section_index 字段 - 检索: ADS/arXiv 并行检索 (tokio::join!),去重改用 HashSet,本地库回填批量 IN 查询 - 天体查询: Sesame API 升级到 v4,新增视差误差/自行/视向速度/多波段测光字段 - 迁移: 14 个增量文件合并为单一 init.sql,支持 sqlx::migrate! 内存库集成测试 - 测试: circuit_breaker/hooks/task_board/session/memory/streaming_executor 新增修正 15+ 测试 前端架构重构: - 目录重组: features/ → pages/ + components/ + hooks/ 三层分离 - App.tsx 从 1181 行压缩至 ~174 行 (逻辑抽入 9 个自定义 Hook) - Agent 面板拆分为 AgentSessionSidebar/AgentMessageList/AgentInputArea 子组件 - 新增 GlobalDialog/PaperDetailModal/UncachedPaperModal 通用对话框组件 - 工具函数抽取: celestial.ts (天体坐标格式), paper.tsx (文献信息渲染)
This commit is contained in:
@@ -0,0 +1,356 @@
|
||||
-- AstroResearch 完整数据库初始化迁移
|
||||
-- 合并自 18 个开发期增量迁移文件,版本: 2026-06-25
|
||||
--
|
||||
-- 领域划分:
|
||||
-- 1. 文献与引用
|
||||
-- 2. 笔记与高亮
|
||||
-- 3. 批量同步
|
||||
-- 4. RAG 切片与天体目标
|
||||
-- 5. Agent 会话与消息
|
||||
-- 6. Agent 任务看板
|
||||
-- 7. Agent 审计日志
|
||||
-- 8. Agent 团队协作
|
||||
-- 9. 全文搜索 (FTS5)
|
||||
|
||||
-- ============================================================
|
||||
-- 1. 文献与引用
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS papers (
|
||||
bibcode TEXT PRIMARY KEY,
|
||||
title TEXT NOT NULL,
|
||||
authors TEXT, -- JSON array of author names
|
||||
year TEXT,
|
||||
pub TEXT, -- journal / publisher
|
||||
keywords TEXT, -- JSON array of keywords
|
||||
abstract TEXT,
|
||||
doi TEXT,
|
||||
arxiv_id TEXT,
|
||||
citation_count INTEGER DEFAULT 0,
|
||||
reference_count INTEGER DEFAULT 0,
|
||||
pdf_path TEXT,
|
||||
html_path TEXT,
|
||||
markdown_path TEXT,
|
||||
translation_path TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
doctype TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_papers_doi ON papers(doi);
|
||||
CREATE INDEX IF NOT EXISTS idx_papers_arxiv_id ON papers(arxiv_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS citations_references (
|
||||
source_bibcode TEXT NOT NULL,
|
||||
target_bibcode TEXT NOT NULL,
|
||||
PRIMARY KEY (source_bibcode, target_bibcode)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_citations_ref_source ON citations_references(source_bibcode);
|
||||
CREATE INDEX IF NOT EXISTS idx_citations_ref_target ON citations_references(target_bibcode);
|
||||
|
||||
-- ============================================================
|
||||
-- 2. 笔记与高亮
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS notes (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
bibcode TEXT NOT NULL,
|
||||
paragraph_index INTEGER NOT NULL,
|
||||
note_text TEXT NOT NULL DEFAULT '',
|
||||
highlight_color TEXT NOT NULL DEFAULT 'yellow',
|
||||
selected_text TEXT NOT NULL DEFAULT '',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (bibcode) REFERENCES papers(bibcode) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_notes_bibcode ON notes(bibcode);
|
||||
|
||||
-- ============================================================
|
||||
-- 3. 批量同步
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sync_queries (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
query TEXT NOT NULL,
|
||||
source TEXT NOT NULL,
|
||||
limit_count INTEGER NOT NULL,
|
||||
last_run DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(query, source, limit_count)
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- 4. RAG 切片与天体目标
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS paper_chunks_content (
|
||||
rowid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
bibcode TEXT,
|
||||
paragraph_index INTEGER,
|
||||
content TEXT,
|
||||
headings TEXT DEFAULT 'Document',
|
||||
section_index INTEGER DEFAULT 0,
|
||||
FOREIGN KEY(bibcode) REFERENCES papers(bibcode) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS paper_targets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
bibcode TEXT,
|
||||
target_name TEXT,
|
||||
ra TEXT,
|
||||
dec TEXT,
|
||||
parallax REAL,
|
||||
spectral_type TEXT,
|
||||
v_magnitude REAL,
|
||||
aliases TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
otype TEXT,
|
||||
oname TEXT,
|
||||
pm_ra REAL,
|
||||
pm_de REAL,
|
||||
radial_velocity REAL,
|
||||
parallax_err REAL,
|
||||
photometry TEXT,
|
||||
FOREIGN KEY(bibcode) REFERENCES papers(bibcode) ON DELETE CASCADE,
|
||||
UNIQUE(bibcode, target_name)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_paper_targets_name ON paper_targets(target_name);
|
||||
|
||||
-- ============================================================
|
||||
-- 5. Agent 会话与消息
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_sessions (
|
||||
session_id TEXT PRIMARY KEY,
|
||||
title TEXT NOT NULL DEFAULT '',
|
||||
model TEXT NOT NULL DEFAULT '',
|
||||
turn_count INTEGER NOT NULL DEFAULT 0,
|
||||
last_error TEXT,
|
||||
summary TEXT,
|
||||
metadata TEXT,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at DATETIME,
|
||||
rewind_count INTEGER NOT NULL DEFAULT 0,
|
||||
parent_session_id TEXT REFERENCES agent_sessions(session_id),
|
||||
branch_metadata TEXT,
|
||||
mode TEXT NOT NULL DEFAULT 'default'
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_sessions_updated
|
||||
ON agent_sessions(updated_at) WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_messages (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
session_id TEXT NOT NULL,
|
||||
turn_index INTEGER NOT NULL DEFAULT 0,
|
||||
step_index INTEGER NOT NULL DEFAULT 0,
|
||||
role TEXT NOT NULL CHECK(role IN ('system', 'user', 'assistant', 'tool')),
|
||||
content TEXT NOT NULL DEFAULT '',
|
||||
thought TEXT,
|
||||
tool_calls TEXT,
|
||||
tool_call_id TEXT,
|
||||
token_count INTEGER NOT NULL DEFAULT 0,
|
||||
metadata TEXT,
|
||||
raw_json TEXT,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
agent_name TEXT NOT NULL DEFAULT 'lead',
|
||||
active INTEGER NOT NULL DEFAULT 1,
|
||||
FOREIGN KEY (session_id) REFERENCES agent_sessions(session_id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_messages_session ON agent_messages(session_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_messages_turn ON agent_messages(session_id, turn_index);
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_messages_agent ON agent_messages(session_id, agent_name);
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_messages_active ON agent_messages(session_id, active);
|
||||
|
||||
-- ============================================================
|
||||
-- 6. Agent 任务看板
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_tasks (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
session_id TEXT NOT NULL,
|
||||
task_id TEXT NOT NULL,
|
||||
content TEXT NOT NULL DEFAULT '',
|
||||
status TEXT NOT NULL DEFAULT 'pending'
|
||||
CHECK(status IN ('pending', 'in_progress', 'completed')),
|
||||
blocked_by TEXT NOT NULL DEFAULT '[]',
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
owner TEXT NOT NULL DEFAULT '',
|
||||
FOREIGN KEY (session_id) REFERENCES agent_sessions(session_id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_tasks_session ON agent_tasks(session_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_tasks_status ON agent_tasks(session_id, status);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_tasks_session_task ON agent_tasks(session_id, task_id);
|
||||
|
||||
-- ============================================================
|
||||
-- 7. Agent 审计日志
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_audit_log (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
session_id TEXT NOT NULL,
|
||||
step INTEGER NOT NULL DEFAULT 0,
|
||||
tool_name TEXT,
|
||||
status TEXT NOT NULL CHECK(status IN ('OK', 'FAIL', 'SESSION_STOP')),
|
||||
elapsed_ms INTEGER NOT NULL DEFAULT 0,
|
||||
output_preview TEXT,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
agent_name TEXT NOT NULL DEFAULT 'lead',
|
||||
FOREIGN KEY (session_id) REFERENCES agent_sessions(session_id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_log_session ON agent_audit_log(session_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_log_created ON agent_audit_log(created_at);
|
||||
|
||||
-- ============================================================
|
||||
-- 8. Agent 团队协作
|
||||
-- ============================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_team_members (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
session_id TEXT NOT NULL,
|
||||
agent_name TEXT NOT NULL,
|
||||
agent_role TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active'
|
||||
CHECK(status IN ('spawning', 'active', 'idle', 'shutdown')),
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (session_id) REFERENCES agent_sessions(session_id) ON DELETE CASCADE,
|
||||
UNIQUE(session_id, agent_name)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_team_members_session ON agent_team_members(session_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_team_members_status ON agent_team_members(session_id, status);
|
||||
|
||||
-- ============================================================
|
||||
-- 9. 全文搜索 (FTS5)
|
||||
-- ============================================================
|
||||
|
||||
-- 文献全文搜索
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS papers_fts USING fts5(
|
||||
title,
|
||||
authors,
|
||||
keywords,
|
||||
abstract,
|
||||
pub,
|
||||
content='papers',
|
||||
content_rowid='rowid'
|
||||
);
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS papers_fts_insert AFTER INSERT ON papers
|
||||
BEGIN
|
||||
INSERT INTO papers_fts(rowid, title, authors, keywords, abstract, pub)
|
||||
VALUES (NEW.rowid, NEW.title, NEW.authors, NEW.keywords, NEW.abstract, NEW.pub);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS papers_fts_update AFTER UPDATE ON papers
|
||||
BEGIN
|
||||
UPDATE papers_fts SET
|
||||
title = NEW.title,
|
||||
authors = NEW.authors,
|
||||
keywords = NEW.keywords,
|
||||
abstract = NEW.abstract,
|
||||
pub = NEW.pub
|
||||
WHERE rowid = OLD.rowid;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS papers_fts_delete AFTER DELETE ON papers
|
||||
BEGIN
|
||||
DELETE FROM papers_fts WHERE rowid = OLD.rowid;
|
||||
END;
|
||||
|
||||
-- Agent 会话全文搜索
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS agent_sessions_fts USING fts5(
|
||||
session_id,
|
||||
title,
|
||||
summary,
|
||||
metadata,
|
||||
content='agent_sessions',
|
||||
content_rowid='rowid'
|
||||
);
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS sessions_fts_insert AFTER INSERT ON agent_sessions
|
||||
BEGIN
|
||||
INSERT INTO agent_sessions_fts(rowid, session_id, title, summary, metadata)
|
||||
VALUES (NEW.rowid, NEW.session_id, NEW.title, NEW.summary, NEW.metadata);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS sessions_fts_update AFTER UPDATE ON agent_sessions
|
||||
BEGIN
|
||||
UPDATE agent_sessions_fts SET
|
||||
session_id = NEW.session_id,
|
||||
title = NEW.title,
|
||||
summary = NEW.summary,
|
||||
metadata = NEW.metadata
|
||||
WHERE rowid = OLD.rowid;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS sessions_fts_delete AFTER DELETE ON agent_sessions
|
||||
BEGIN
|
||||
DELETE FROM agent_sessions_fts WHERE rowid = OLD.rowid;
|
||||
END;
|
||||
|
||||
-- Agent 消息全文搜索
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS agent_messages_fts USING fts5(
|
||||
session_id,
|
||||
role,
|
||||
content,
|
||||
thought,
|
||||
tool_calls,
|
||||
content='agent_messages',
|
||||
content_rowid='rowid'
|
||||
);
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS messages_fts_insert AFTER INSERT ON agent_messages
|
||||
BEGIN
|
||||
INSERT INTO agent_messages_fts(rowid, session_id, role, content, thought, tool_calls)
|
||||
VALUES (NEW.rowid, NEW.session_id, NEW.role, NEW.content, NEW.thought, NEW.tool_calls);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS messages_fts_update AFTER UPDATE ON agent_messages
|
||||
BEGIN
|
||||
UPDATE agent_messages_fts SET
|
||||
session_id = NEW.session_id,
|
||||
role = NEW.role,
|
||||
content = NEW.content,
|
||||
thought = NEW.thought,
|
||||
tool_calls = NEW.tool_calls
|
||||
WHERE rowid = OLD.rowid;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS messages_fts_delete AFTER DELETE ON agent_messages
|
||||
BEGIN
|
||||
DELETE FROM agent_messages_fts WHERE rowid = OLD.rowid;
|
||||
END;
|
||||
|
||||
-- 段落切片全文搜索(配合 vec_paper_chunks 向量检索做混合搜索)
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS paper_chunks_fts USING fts5(
|
||||
content,
|
||||
content='paper_chunks_content',
|
||||
content_rowid='rowid'
|
||||
);
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS chunks_fts_insert AFTER INSERT ON paper_chunks_content
|
||||
BEGIN
|
||||
INSERT INTO paper_chunks_fts(rowid, content) VALUES (NEW.rowid, NEW.content);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS chunks_fts_update AFTER UPDATE ON paper_chunks_content
|
||||
BEGIN
|
||||
UPDATE paper_chunks_fts SET content = NEW.content WHERE rowid = OLD.rowid;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS chunks_fts_delete AFTER DELETE ON paper_chunks_content
|
||||
BEGIN
|
||||
DELETE FROM paper_chunks_fts WHERE rowid = OLD.rowid;
|
||||
END;
|
||||
|
||||
-- ============================================================
|
||||
-- 注意: vec_paper_chunks 向量虚拟表由 main.rs 在运行时动态创建,
|
||||
-- 维度由 EMBEDDING_DIM 环境变量控制 (默认 1536)。
|
||||
-- ============================================================
|
||||
@@ -1,32 +0,0 @@
|
||||
-- migrations/20260608000000_init.sql
|
||||
|
||||
CREATE TABLE IF NOT EXISTS papers (
|
||||
bibcode TEXT PRIMARY KEY,
|
||||
title TEXT NOT NULL,
|
||||
authors TEXT, -- JSON array of author names
|
||||
year TEXT,
|
||||
pub TEXT, -- journal / publisher
|
||||
keywords TEXT, -- JSON array of keywords
|
||||
abstract TEXT,
|
||||
doi TEXT,
|
||||
arxiv_id TEXT,
|
||||
citation_count INTEGER DEFAULT 0,
|
||||
reference_count INTEGER DEFAULT 0,
|
||||
pdf_path TEXT,
|
||||
html_path TEXT,
|
||||
markdown_path TEXT,
|
||||
translation_path TEXT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS citations_references (
|
||||
source_bibcode TEXT NOT NULL,
|
||||
target_bibcode TEXT NOT NULL,
|
||||
PRIMARY KEY (source_bibcode, target_bibcode)
|
||||
);
|
||||
|
||||
-- Indexes for performance
|
||||
CREATE INDEX IF NOT EXISTS idx_papers_doi ON papers(doi);
|
||||
CREATE INDEX IF NOT EXISTS idx_papers_arxiv_id ON papers(arxiv_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_citations_ref_source ON citations_references(source_bibcode);
|
||||
CREATE INDEX IF NOT EXISTS idx_citations_ref_target ON citations_references(target_bibcode);
|
||||
@@ -1,15 +0,0 @@
|
||||
-- migrations/20260608000001_notes.sql
|
||||
-- 笔记/高亮表:每条记录对应一篇文献中某个段落的标注笔记
|
||||
|
||||
CREATE TABLE IF NOT EXISTS notes (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
bibcode TEXT NOT NULL,
|
||||
paragraph_index INTEGER NOT NULL, -- 在文章 Markdown 段落中的序号(从 0 开始)
|
||||
note_text TEXT NOT NULL DEFAULT '',
|
||||
highlight_color TEXT NOT NULL DEFAULT 'yellow', -- 'yellow' | 'green' | 'blue' | 'pink'
|
||||
selected_text TEXT NOT NULL DEFAULT '', -- 被高亮选中的原始文本片段
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (bibcode) REFERENCES papers(bibcode) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_notes_bibcode ON notes(bibcode);
|
||||
@@ -1,3 +0,0 @@
|
||||
-- migrations/20260608000002_add_doctype.sql
|
||||
|
||||
ALTER TABLE papers ADD COLUMN doctype TEXT;
|
||||
@@ -1,12 +0,0 @@
|
||||
-- migrations/20260608000003_sync_features.sql
|
||||
|
||||
-- 批量同步检索配置表 (支持唯一去重机制)
|
||||
CREATE TABLE IF NOT EXISTS sync_queries (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
query TEXT NOT NULL,
|
||||
source TEXT NOT NULL,
|
||||
limit_count INTEGER NOT NULL,
|
||||
last_run DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(query, source, limit_count) -- 去重约束
|
||||
);
|
||||
@@ -1,29 +0,0 @@
|
||||
-- migrations/20260613000000_paper_chunks_metadata.sql
|
||||
-- RAG 文本切片内容表与天体目标缓存表
|
||||
|
||||
-- 存储文献 Markdown 段落切片的元数据与文本内容
|
||||
-- rowid 与 vec_paper_chunks 虚拟表的 rowid 保持 1:1 对齐
|
||||
CREATE TABLE IF NOT EXISTS paper_chunks_content (
|
||||
rowid INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
bibcode TEXT,
|
||||
paragraph_index INTEGER,
|
||||
content TEXT,
|
||||
FOREIGN KEY(bibcode) REFERENCES papers(bibcode) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- 天体目标信息缓存表,从 SIMBAD/Sesame 解析后本地持久化
|
||||
CREATE TABLE IF NOT EXISTS paper_targets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
bibcode TEXT,
|
||||
target_name TEXT, -- 标准化天体名称 (如 GD 358)
|
||||
ra TEXT, -- 赤道坐标:赤经 (Right Ascension)
|
||||
dec TEXT, -- 赤道坐标:赤纬 (Declination)
|
||||
parallax REAL, -- 视差 (mas,毫角秒)
|
||||
spectral_type TEXT, -- 光谱分类 (如 DA1)
|
||||
v_magnitude REAL, -- 视星等
|
||||
aliases TEXT, -- 天体别名 (JSON 数组文本)
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY(bibcode) REFERENCES papers(bibcode) ON DELETE CASCADE,
|
||||
UNIQUE(bibcode, target_name)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_paper_targets_name ON paper_targets(target_name);
|
||||
@@ -1,36 +0,0 @@
|
||||
-- 科研智能体会话与消息持久化表
|
||||
-- 支持 ReAct 框架的多轮对话、工具调用与思考链存储
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_sessions (
|
||||
session_id TEXT PRIMARY KEY,
|
||||
title TEXT NOT NULL DEFAULT '',
|
||||
model TEXT NOT NULL DEFAULT '',
|
||||
turn_count INTEGER NOT NULL DEFAULT 0,
|
||||
last_error TEXT,
|
||||
summary TEXT,
|
||||
metadata TEXT,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at DATETIME
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_messages (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
session_id TEXT NOT NULL,
|
||||
turn_index INTEGER NOT NULL DEFAULT 0,
|
||||
step_index INTEGER NOT NULL DEFAULT 0,
|
||||
role TEXT NOT NULL CHECK(role IN ('system', 'user', 'assistant', 'tool')),
|
||||
content TEXT NOT NULL DEFAULT '',
|
||||
thought TEXT,
|
||||
tool_calls TEXT,
|
||||
tool_call_id TEXT,
|
||||
token_count INTEGER NOT NULL DEFAULT 0,
|
||||
metadata TEXT,
|
||||
raw_json TEXT,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (session_id) REFERENCES agent_sessions(session_id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_messages_session ON agent_messages(session_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_messages_turn ON agent_messages(session_id, turn_index);
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_sessions_updated ON agent_sessions(updated_at) WHERE deleted_at IS NULL;
|
||||
@@ -1,31 +0,0 @@
|
||||
-- 智能体任务持久化表
|
||||
-- 支持 DAG 依赖模式 (blocked_by) 和任务状态生命周期
|
||||
--
|
||||
-- Status lifecycle:
|
||||
-- pending -> in_progress -> completed
|
||||
-- (可回退: in_progress -> pending)
|
||||
--
|
||||
-- blocked_by 存储 JSON 数组格式: ["task_id_1", "task_id_2"]
|
||||
-- 应用层负责验证 DAG 有效性(无自引用、无循环依赖)
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_tasks (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
session_id TEXT NOT NULL,
|
||||
task_id TEXT NOT NULL,
|
||||
content TEXT NOT NULL DEFAULT '',
|
||||
status TEXT NOT NULL DEFAULT 'pending'
|
||||
CHECK(status IN ('pending', 'in_progress', 'completed')),
|
||||
blocked_by TEXT NOT NULL DEFAULT '[]',
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (session_id) REFERENCES agent_sessions(session_id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- 按会话查询任务(最常用)
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_tasks_session ON agent_tasks(session_id);
|
||||
|
||||
-- 按状态过滤(用于恢复/展示)
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_tasks_status ON agent_tasks(session_id, status);
|
||||
|
||||
-- 保证同一会话内 task_id 唯一
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_agent_tasks_session_task ON agent_tasks(session_id, task_id);
|
||||
@@ -1,19 +0,0 @@
|
||||
-- 智能体审计日志表
|
||||
-- 记录所有工具调用的详细信息:工具名称、执行状态、耗时、输出预览
|
||||
--
|
||||
-- status: OK (成功) / FAIL (失败) / SESSION_STOP (会话终止)
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_audit_log (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
session_id TEXT NOT NULL,
|
||||
step INTEGER NOT NULL DEFAULT 0,
|
||||
tool_name TEXT,
|
||||
status TEXT NOT NULL CHECK(status IN ('OK', 'FAIL', 'SESSION_STOP')),
|
||||
elapsed_ms INTEGER NOT NULL DEFAULT 0,
|
||||
output_preview TEXT,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (session_id) REFERENCES agent_sessions(session_id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_log_session ON agent_audit_log(session_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_log_created ON agent_audit_log(created_at);
|
||||
@@ -1,36 +0,0 @@
|
||||
-- 智能体身份隔离与团队协作支持
|
||||
--
|
||||
-- 为子代理(delegate_research)和多智能体团队(spawn_teammate)
|
||||
-- 提供 agent 粒度的消息隔离、审计追踪和任务归属。
|
||||
--
|
||||
-- 所有 ALTER TABLE 使用 DEFAULT 值,保证向后兼容:
|
||||
-- 现有数据自动标记为 'lead',旧代码无需修改。
|
||||
|
||||
-- 1. agent_messages: 消息归属
|
||||
ALTER TABLE agent_messages ADD COLUMN agent_name TEXT NOT NULL DEFAULT 'lead';
|
||||
|
||||
-- 2. agent_audit_log: 审计归属
|
||||
ALTER TABLE agent_audit_log ADD COLUMN agent_name TEXT NOT NULL DEFAULT 'lead';
|
||||
|
||||
-- 3. agent_tasks: 任务分配目标(支持角色路由)
|
||||
ALTER TABLE agent_tasks ADD COLUMN owner TEXT NOT NULL DEFAULT '';
|
||||
|
||||
-- 4. 新建: 团队成员注册表
|
||||
CREATE TABLE IF NOT EXISTS agent_team_members (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
session_id TEXT NOT NULL,
|
||||
agent_name TEXT NOT NULL,
|
||||
agent_role TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active'
|
||||
CHECK(status IN ('spawning', 'active', 'idle', 'shutdown')),
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (session_id) REFERENCES agent_sessions(session_id) ON DELETE CASCADE,
|
||||
UNIQUE(session_id, agent_name)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_team_members_session ON agent_team_members(session_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_team_members_status ON agent_team_members(session_id, status);
|
||||
|
||||
-- 重建 agent_messages 索引(包含 agent_name 过滤加速)
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_messages_agent ON agent_messages(session_id, agent_name);
|
||||
@@ -1,20 +0,0 @@
|
||||
-- Migration: Session Rewind Support
|
||||
--
|
||||
-- 添加会话回退 (undo) 所需的软删除基础设施。
|
||||
-- 参考 Hermes-Agent hermes_state.py active=0 模型。
|
||||
--
|
||||
-- active 列:
|
||||
-- 1 = 活跃消息(对 LLM 可见,默认值)
|
||||
-- 0 = 软删除(rewind 操作移除,LLM 不可见,保留用于审计)
|
||||
--
|
||||
-- rewind_count:
|
||||
-- 单调递增计数器,记录会话被回退的次数
|
||||
|
||||
-- 1. agent_messages: 添加 active 列
|
||||
ALTER TABLE agent_messages ADD COLUMN active INTEGER NOT NULL DEFAULT 1;
|
||||
|
||||
-- 2. agent_sessions: 添加 rewind_count
|
||||
ALTER TABLE agent_sessions ADD COLUMN rewind_count INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
-- 3. 加速 active=1 过滤的索引(覆盖最常用的查询模式)
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_messages_active ON agent_messages(session_id, active);
|
||||
@@ -1,13 +0,0 @@
|
||||
-- Migration: Session Branch Support
|
||||
--
|
||||
-- 添加会话分叉所需的基础设施。
|
||||
-- 参考 Hermes-Agent parent_session_id 模型。
|
||||
--
|
||||
-- parent_session_id: 分叉的源会话 ID(NULL = 根会话)
|
||||
-- branched_from: 分叉的消息 ID(在源会话中的分叉点)
|
||||
|
||||
-- 1. agent_sessions: 添加 parent_session_id
|
||||
ALTER TABLE agent_sessions ADD COLUMN parent_session_id TEXT REFERENCES agent_sessions(session_id);
|
||||
|
||||
-- 2. agent_sessions: 添加分支元数据 JSON(存储 {branched_from, branch_reason} 等)
|
||||
ALTER TABLE agent_sessions ADD COLUMN branch_metadata TEXT;
|
||||
@@ -1,73 +0,0 @@
|
||||
-- FTS5 跨会话全文搜索
|
||||
-- 在 agent_sessions 和 agent_messages 上创建虚拟表,支持 BM25 排序搜索。
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS agent_sessions_fts USING fts5(
|
||||
session_id,
|
||||
title,
|
||||
summary,
|
||||
metadata,
|
||||
content='agent_sessions',
|
||||
content_rowid='rowid'
|
||||
);
|
||||
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS agent_messages_fts USING fts5(
|
||||
session_id,
|
||||
role,
|
||||
content,
|
||||
thought,
|
||||
tool_calls,
|
||||
content='agent_messages',
|
||||
content_rowid='rowid'
|
||||
);
|
||||
|
||||
-- Triggers: sessions
|
||||
CREATE TRIGGER IF NOT EXISTS sessions_fts_insert AFTER INSERT ON agent_sessions
|
||||
BEGIN
|
||||
INSERT INTO agent_sessions_fts(session_id, title, summary, metadata)
|
||||
VALUES (NEW.session_id, NEW.title, NEW.summary, NEW.metadata);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS sessions_fts_update AFTER UPDATE ON agent_sessions
|
||||
BEGIN
|
||||
UPDATE agent_sessions_fts SET
|
||||
session_id = NEW.session_id,
|
||||
title = NEW.title,
|
||||
summary = NEW.summary,
|
||||
metadata = NEW.metadata
|
||||
WHERE rowid = OLD.rowid;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS sessions_fts_delete AFTER DELETE ON agent_sessions
|
||||
BEGIN
|
||||
DELETE FROM agent_sessions_fts WHERE rowid = OLD.rowid;
|
||||
END;
|
||||
|
||||
-- Triggers: messages
|
||||
CREATE TRIGGER IF NOT EXISTS messages_fts_insert AFTER INSERT ON agent_messages
|
||||
BEGIN
|
||||
INSERT INTO agent_messages_fts(session_id, role, content, thought, tool_calls)
|
||||
VALUES (NEW.session_id, NEW.role, NEW.content, NEW.thought, NEW.tool_calls);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS messages_fts_update AFTER UPDATE ON agent_messages
|
||||
BEGIN
|
||||
UPDATE agent_messages_fts SET
|
||||
session_id = NEW.session_id,
|
||||
role = NEW.role,
|
||||
content = NEW.content,
|
||||
thought = NEW.thought,
|
||||
tool_calls = NEW.tool_calls
|
||||
WHERE rowid = OLD.rowid;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS messages_fts_delete AFTER DELETE ON agent_messages
|
||||
BEGIN
|
||||
DELETE FROM agent_messages_fts WHERE rowid = OLD.rowid;
|
||||
END;
|
||||
|
||||
-- 回填已有数据
|
||||
INSERT OR IGNORE INTO agent_sessions_fts(session_id, title, summary, metadata)
|
||||
SELECT session_id, title, summary, metadata FROM agent_sessions;
|
||||
|
||||
INSERT OR IGNORE INTO agent_messages_fts(session_id, role, content, thought, tool_calls)
|
||||
SELECT session_id, role, content, thought, tool_calls FROM agent_messages;
|
||||
@@ -1,30 +0,0 @@
|
||||
-- 修复 FTS5 全文搜索中虚拟表与原始物理表的 rowid 不一致问题
|
||||
-- 增量迁移:删除旧触发器,以正确映射 rowid 的触发器替代,并重建现有 FTS5 数据
|
||||
|
||||
-- 1. 删除旧的不安全触发器
|
||||
DROP TRIGGER IF EXISTS sessions_fts_insert;
|
||||
DROP TRIGGER IF EXISTS messages_fts_insert;
|
||||
|
||||
-- 2. 重新创建指定 rowid 列的插入触发器,确保 FTS 行 ID 与原始物理表行 ID 完全一致
|
||||
CREATE TRIGGER IF NOT EXISTS sessions_fts_insert AFTER INSERT ON agent_sessions
|
||||
BEGIN
|
||||
INSERT INTO agent_sessions_fts(rowid, session_id, title, summary, metadata)
|
||||
VALUES (NEW.rowid, NEW.session_id, NEW.title, NEW.summary, NEW.metadata);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER IF NOT EXISTS messages_fts_insert AFTER INSERT ON agent_messages
|
||||
BEGIN
|
||||
INSERT INTO agent_messages_fts(rowid, session_id, role, content, thought, tool_calls)
|
||||
VALUES (NEW.rowid, NEW.session_id, NEW.role, NEW.content, NEW.thought, NEW.tool_calls);
|
||||
END;
|
||||
|
||||
-- 3. 清理之前因不一致导致的错乱 FTS 数据
|
||||
DELETE FROM agent_sessions_fts;
|
||||
DELETE FROM agent_messages_fts;
|
||||
|
||||
-- 4. 使用正确的 rowid 重新索引现有数据
|
||||
INSERT OR IGNORE INTO agent_sessions_fts(rowid, session_id, title, summary, metadata)
|
||||
SELECT rowid, session_id, title, summary, metadata FROM agent_sessions;
|
||||
|
||||
INSERT OR IGNORE INTO agent_messages_fts(rowid, session_id, role, content, thought, tool_calls)
|
||||
SELECT rowid, session_id, role, content, thought, tool_calls FROM agent_messages;
|
||||
@@ -1,11 +0,0 @@
|
||||
-- Migration: Add Agent Session Mode Support
|
||||
--
|
||||
-- 为代理会话增加运行模式 (mode) 字段,支持多模式 Agent 架构。
|
||||
-- 现有会话自动获得 mode='default'(保持当前行为不变)。
|
||||
--
|
||||
-- mode 取值:
|
||||
-- 'default' — 通用科研助手
|
||||
-- 'deep-research' — 深度研究模式
|
||||
-- 'literature-reader' — 文献阅读助手模式
|
||||
|
||||
ALTER TABLE agent_sessions ADD COLUMN mode TEXT NOT NULL DEFAULT 'default';
|
||||
Reference in New Issue
Block a user