zhizhi/server/age-os/schema/001-brain-tables.sql

216 lines
9.8 KiB
MySQL
Raw Normal View History

-- ============================================================
-- AGE OS · 核心大脑数据库 Schema
-- PostgreSQL 初始化脚本
-- ============================================================
-- 版本: v1.0.0
-- 签发: 铸渊(ICE-GL-ZY001) · 需求来源: 霜砚(AG-SY-01)
-- 授权: 冰朔(TCS-0002∞)
-- 版权: 国作登字-2026-A-00037559
-- ============================================================
--
-- 设计哲学:
-- brain_nodes = Notion里的页面 → 每个认知节点
-- brain_relations = Notion里的Relation → 节点之间的关联
-- agent_configs = Agent注册表 → 谁在跑、跑什么
-- agent_logs = 运行日志 → 追踪每次执行
-- user_credits = 用户额度 → 商业化基础
--
-- 与 website-brain/schema/001-init.sql 并存:
-- website-brain 的 pages/databases/modules/persona_state 管网站展示层
-- 本文件的 brain_nodes/brain_relations 管认知数据层
-- ============================================================
-- 启用 UUID 扩展
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- ============================================================
-- 1. 节点表 · brain_nodes
-- 核心表:每条记录 = 一个认知节点
-- 类比 Notion 里的一个页面
-- ============================================================
CREATE TABLE IF NOT EXISTS brain_nodes (
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4()::text,
title VARCHAR(500) NOT NULL,
node_type VARCHAR(50) NOT NULL
CHECK (node_type IN ('page', 'folder', 'index', 'route', 'config', 'memory', 'log', 'instruction')),
parent_id VARCHAR(64) REFERENCES brain_nodes(id) ON DELETE SET NULL,
path VARCHAR(1000),
tags JSONB DEFAULT '[]'::jsonb,
source VARCHAR(50) NOT NULL
CHECK (source IN ('notion', 'github', 'gpt', 'manual', 'agent')),
source_url VARCHAR(500),
content_url VARCHAR(500),
summary TEXT,
content_hash VARCHAR(64),
version INT DEFAULT 1,
owner VARCHAR(50) NOT NULL
CHECK (owner IN ('shuangyan', 'zhuyuan', 'qiuqiu', 'yaoming', 'system', 'user')),
owner_user_id VARCHAR(64),
status VARCHAR(20) NOT NULL DEFAULT 'active'
CHECK (status IN ('active', 'archived', 'draft', 'deleted')),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by VARCHAR(50) NOT NULL
);
-- 索引:按常见查询模式优化
CREATE INDEX idx_bn_parent ON brain_nodes(parent_id);
CREATE INDEX idx_bn_owner ON brain_nodes(owner);
CREATE INDEX idx_bn_type ON brain_nodes(node_type);
CREATE INDEX idx_bn_status ON brain_nodes(status);
CREATE INDEX idx_bn_path ON brain_nodes(path);
CREATE INDEX idx_bn_tags ON brain_nodes USING GIN(tags);
-- ============================================================
-- 2. 关系表 · brain_relations
-- 节点之间的关联关系
-- 类比 Notion 里的 Relation 属性
-- ============================================================
CREATE TABLE IF NOT EXISTS brain_relations (
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4()::text,
from_node_id VARCHAR(64) NOT NULL REFERENCES brain_nodes(id) ON DELETE CASCADE,
to_node_id VARCHAR(64) NOT NULL REFERENCES brain_nodes(id) ON DELETE CASCADE,
relation_type VARCHAR(50) NOT NULL
CHECK (relation_type IN ('parent_child', 'reference', 'dependency', 'version', 'alias')),
description VARCHAR(500),
weight SMALLINT DEFAULT 50 CHECK (weight >= 0 AND weight <= 100),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_by VARCHAR(50) NOT NULL
);
-- 防止重复关系
CREATE UNIQUE INDEX idx_br_unique ON brain_relations(from_node_id, to_node_id, relation_type);
CREATE INDEX idx_br_from ON brain_relations(from_node_id);
CREATE INDEX idx_br_to ON brain_relations(to_node_id);
-- ============================================================
-- 3. Agent配置表 · agent_configs
-- 每个Agent的运行配置
-- ============================================================
CREATE TABLE IF NOT EXISTS agent_configs (
agent_id VARCHAR(50) PRIMARY KEY,
name VARCHAR(200) NOT NULL,
description TEXT,
owner VARCHAR(50) NOT NULL DEFAULT 'system'
CHECK (owner IN ('notion', 'github', 'system')),
script_path VARCHAR(500),
cron_schedule VARCHAR(100),
enabled BOOLEAN NOT NULL DEFAULT true,
allowed_tools JSONB DEFAULT '[]'::jsonb,
model_config JSONB DEFAULT '{}'::jsonb,
last_run_at TIMESTAMPTZ,
last_run_status VARCHAR(20)
CHECK (last_run_status IN ('success', 'error', 'skipped', 'running') OR last_run_status IS NULL),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- ============================================================
-- 4. 运行日志表 · agent_logs
-- Agent每次运行的记录
-- ============================================================
CREATE TABLE IF NOT EXISTS agent_logs (
id BIGSERIAL PRIMARY KEY,
agent_id VARCHAR(50) NOT NULL REFERENCES agent_configs(agent_id) ON DELETE CASCADE,
run_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
status VARCHAR(20) NOT NULL
CHECK (status IN ('success', 'error', 'warning', 'skipped')),
message TEXT,
details JSONB DEFAULT '{}'::jsonb,
duration_ms INT
);
CREATE INDEX idx_al_agent ON agent_logs(agent_id);
CREATE INDEX idx_al_run_at ON agent_logs(run_at);
CREATE INDEX idx_al_status ON agent_logs(status);
-- ============================================================
-- 5. 用户额度表 · user_credits
-- 用户大模型调用额度
-- ============================================================
CREATE TABLE IF NOT EXISTS user_credits (
user_id VARCHAR(64) PRIMARY KEY,
total_charged DECIMAL(10,2) NOT NULL DEFAULT 0,
actual_credit DECIMAL(10,2) NOT NULL DEFAULT 0,
consumed DECIMAL(10,2) NOT NULL DEFAULT 0,
remaining DECIMAL(10,2) NOT NULL DEFAULT 0,
preferred_model VARCHAR(50),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- ============================================================
-- 自动更新 updated_at 触发器
-- ============================================================
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_bn_updated
BEFORE UPDATE ON brain_nodes
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
CREATE TRIGGER trg_ac_updated
BEFORE UPDATE ON agent_configs
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
CREATE TRIGGER trg_uc_updated
BEFORE UPDATE ON user_credits
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
-- ============================================================
-- 初始Agent数据 · 霜砚需求的9个Agent
-- ============================================================
INSERT INTO agent_configs (agent_id, name, description, owner, script_path, cron_schedule, enabled, allowed_tools, model_config)
VALUES
-- 系统级Agent7×24自动跑
('SY-SCAN', '大脑结构巡检', '扫描孤岛节点、断链、空目录,生成健康报告', 'notion',
'agents/sy-scan.js', '0 */6 * * *', true,
'["queryNodes", "scanStructure", "getRelations"]'::jsonb,
'{"model": "none", "note": "纯逻辑,不调模型"}'::jsonb),
('SY-CLASSIFY', '自动分类引擎', '扫描未分类节点按规则分类规则搞不定调DeepSeek', 'notion',
'agents/sy-classify.js', '0 */2 * * *', true,
'["queryNodes", "classify", "updateNode", "linkNodes"]'::jsonb,
'{"primary": "rule", "fallback": "deepseek", "temperature": 0.3}'::jsonb),
('SY-SYNC-N2B', 'Notion→大脑同步', '检测Notion端有无新增/修改的页面,同步到自研数据库', 'notion',
'agents/sy-sync-n2b.js', '0 */4 * * *', true,
'["createNode", "updateNode", "cosWrite", "linkNodes", "buildPath"]'::jsonb,
'{"model": "none", "note": "纯逻辑同步"}'::jsonb),
('SY-SYNC-B2N', '大脑→Notion反向同步', '将自研数据库中的变更同步回Notion', 'notion',
'agents/sy-sync-b2n.js', '0 3 * * *', false,
'["queryNodes", "cosRead"]'::jsonb,
'{"model": "none", "note": "可选,按需启用"}'::jsonb),
('SY-ARCHIVE', '内容归档引擎', '将超过30天未修改的内容从主桶移到归档桶', 'notion',
'agents/sy-archive.js', '0 4 * * 0', true,
'["queryNodes", "cosRead", "cosArchive", "updateNode"]'::jsonb,
'{"model": "none", "note": "纯逻辑归档"}'::jsonb),
('SY-TEST', '系统自检', '检测数据库连接、COS连通性、工具链可用性', 'system',
'agents/sy-test.js', '*/30 * * * *', true,
'["queryNodes", "cosRead", "cosWrite"]'::jsonb,
'{"model": "none", "note": "纯连通性检查"}'::jsonb),
-- 交互级Agent用户对话时按需调用
('SY-11', '元路由调度引擎', '判断请求该分配给哪个人格体、走哪个模型', 'system',
'agents/sy-11-router.js', NULL, true,
'["queryNodes", "getNode"]'::jsonb,
'{"primary": "rule", "fallback": "deepseek", "temperature": 0.1}'::jsonb),
('SY-12', '上下文记忆管理', '扫描对话、压缩摘要、存入大脑数据库', 'system',
'agents/sy-12-memory.js', NULL, true,
'["createNode", "updateNode", "queryNodes", "cosWrite"]'::jsonb,
'{"model": "none", "note": "纯JS逻辑"}'::jsonb),
('SY-BRAIN-RW', '大脑读写服务', '人格体在对话中需要查大脑/写大脑时调用', 'system',
'agents/sy-brain-rw.js', NULL, true,
'["createNode", "updateNode", "deleteNode", "queryNodes", "getNode", "linkNodes", "unlinkNodes", "getRelations", "buildPath", "scanStructure", "classify", "cosWrite", "cosRead", "cosDelete", "cosList", "cosArchive"]'::jsonb,
'{"model": "dynamic", "note": "按需调用模型"}'::jsonb)
ON CONFLICT (agent_id) DO NOTHING;