初步完成channel->queueu->[tool]->[queue]->[assistant]->channel的流程

【待处理】上下文管理和错误处理。
This commit is contained in:
2026-06-29 09:15:30 +08:00
parent 79ec21bfd4
commit 46544e9c42
46 changed files with 1215 additions and 755 deletions
@@ -1,29 +0,0 @@
-- iAs 初始数据库迁移
-- 认证信息和聊天记录存储
-- 应用状态表(key-value 存储,用于认证信息等)
CREATE TABLE IF NOT EXISTS app_state (
key TEXT PRIMARY KEY,
value JSONB NOT NULL,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- 聊天记录表
CREATE TABLE IF NOT EXISTS chat_records (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
direction TEXT NOT NULL, -- 'inbound' | 'outbound'
user_id TEXT NOT NULL, -- 微信用户 ID
account_id TEXT NOT NULL, -- 机器人账号 ID
text TEXT NOT NULL, -- 消息内容
source TEXT NOT NULL DEFAULT '', -- 消息来源
context_token TEXT NOT NULL DEFAULT '', -- 上下文令牌
message_id TEXT NOT NULL DEFAULT '',
meta JSONB NOT NULL DEFAULT '{}'::JSONB
);
CREATE INDEX IF NOT EXISTS idx_chat_records_user_created
ON chat_records (user_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_chat_records_account_created
ON chat_records (account_id, created_at DESC);
@@ -1,17 +0,0 @@
-- 待审批的工具调用
CREATE TABLE IF NOT EXISTS pending_approvals (
id UUID PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
expires_at TIMESTAMPTZ NOT NULL,
user_id TEXT NOT NULL,
skill_name TEXT NOT NULL,
params JSONB NOT NULL,
code_hash TEXT NOT NULL,
attempts_left INTEGER NOT NULL DEFAULT 3,
status TEXT NOT NULL DEFAULT 'pending',
result JSONB,
consumed_at TIMESTAMPTZ
);
CREATE INDEX IF NOT EXISTS idx_pending_approvals_user_status
ON pending_approvals (user_id, status);
@@ -1,20 +0,0 @@
-- 定时任务表(Phase 6
CREATE TABLE IF NOT EXISTS scheduled_tasks (
id UUID PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
description TEXT NOT NULL DEFAULT '',
user_id TEXT NOT NULL,
command TEXT NOT NULL,
shell TEXT NOT NULL DEFAULT '/bin/bash',
cwd TEXT NOT NULL DEFAULT '',
interval_seconds INTEGER NOT NULL,
enabled BOOLEAN NOT NULL DEFAULT true,
next_run_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
last_run_at TIMESTAMPTZ,
last_status TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_due
ON scheduled_tasks (enabled, next_run_at);
@@ -1,15 +0,0 @@
-- LLM Token 用量统计
CREATE TABLE IF NOT EXISTS llm_usage (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
user_id TEXT NOT NULL DEFAULT '',
model TEXT NOT NULL DEFAULT '',
provider TEXT NOT NULL DEFAULT 'deepseek',
prompt_tokens INTEGER NOT NULL DEFAULT 0,
completion_tokens INTEGER NOT NULL DEFAULT 0,
total_tokens INTEGER NOT NULL DEFAULT 0,
cache_hit_tokens INTEGER NOT NULL DEFAULT 0,
cache_miss_tokens INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX IF NOT EXISTS idx_llm_usage_created ON llm_usage (created_at DESC);
@@ -1,9 +0,0 @@
-- 长期记忆表
CREATE TABLE IF NOT EXISTS user_memories (
id SERIAL PRIMARY KEY,
user_id TEXT NOT NULL DEFAULT 'default',
content TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_user_memories_user ON user_memories (user_id);
@@ -1,12 +0,0 @@
-- 会话摘要持久化
CREATE TABLE IF NOT EXISTS session_summaries (
id SERIAL PRIMARY KEY,
user_id TEXT NOT NULL DEFAULT 'default',
summary_text TEXT NOT NULL,
reason TEXT NOT NULL DEFAULT 'overflow',
message_count INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_session_summaries_created
ON session_summaries (created_at DESC);
@@ -1,11 +0,0 @@
-- 修复 llm_usage 表:从 iPet 旧格式迁移到 iAs 新格式
-- 旧表有 kind/entry 字段,新表需要 prompt_tokens/completion_tokens 等
ALTER TABLE llm_usage ADD COLUMN IF NOT EXISTS prompt_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE llm_usage ADD COLUMN IF NOT EXISTS completion_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE llm_usage ADD COLUMN IF NOT EXISTS total_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE llm_usage ADD COLUMN IF NOT EXISTS cache_hit_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE llm_usage ADD COLUMN IF NOT EXISTS cache_miss_tokens INTEGER NOT NULL DEFAULT 0;
ALTER TABLE llm_usage ADD COLUMN IF NOT EXISTS user_id TEXT NOT NULL DEFAULT '';
ALTER TABLE llm_usage ADD COLUMN IF NOT EXISTS model TEXT NOT NULL DEFAULT '';
ALTER TABLE llm_usage ADD COLUMN IF NOT EXISTS provider TEXT NOT NULL DEFAULT 'deepseek';
@@ -1,3 +0,0 @@
-- scheduled_tasks.user_id 默认值修复
ALTER TABLE scheduled_tasks ALTER COLUMN user_id SET DEFAULT '';
ALTER TABLE scheduled_tasks ALTER COLUMN user_id DROP NOT NULL;
@@ -1,3 +0,0 @@
-- 聊天记录去重索引(普通索引,不用 UNIQUE 避免存量重复数据冲突)
CREATE INDEX IF NOT EXISTS idx_chat_records_message_id
ON chat_records (message_id) WHERE message_id != '';
@@ -1,4 +0,0 @@
-- 移除 llm_usage 表中旧 iPet 遗留列的 NOT NULL 约束
-- kind/entry 是旧格式字段,新代码不使用它们
ALTER TABLE llm_usage ALTER COLUMN kind DROP NOT NULL;
ALTER TABLE llm_usage ALTER COLUMN entry DROP NOT NULL;
@@ -1,26 +0,0 @@
-- 修复 chat_records 表中 iPet 遗留的 context_token_present (boolean) → context_token (text)
-- 迁移 0001 创建的是 context_token TEXT,但旧库中列名是 context_token_present BOOLEAN
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'chat_records' AND column_name = 'context_token_present') THEN
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'chat_records' AND column_name = 'context_token') THEN
-- 两列都存在(混合/半迁移库):回填数据后删除旧列
UPDATE chat_records
SET context_token = CASE WHEN context_token_present::boolean THEN '1' ELSE '' END
WHERE context_token = '';
ALTER TABLE chat_records DROP COLUMN context_token_present;
ELSE
-- 只有旧列:类型转换 boolean → text (true → '1', false → ''),再重命名
ALTER TABLE chat_records
ALTER COLUMN context_token_present TYPE TEXT
USING CASE WHEN context_token_present::boolean THEN '1' ELSE '' END;
ALTER TABLE chat_records RENAME COLUMN context_token_present TO context_token;
ALTER TABLE chat_records ALTER COLUMN context_token SET DEFAULT '';
END IF;
END IF;
END;
$$;
@@ -1,12 +0,0 @@
-- 聊天记录去重:清理存量重复 → 建 partial UNIQUE 索引支持 ON CONFLICT
-- 1) 删除重复记录(保留每个 message_id 最早的那条)
DELETE FROM chat_records a
USING chat_records b
WHERE a.message_id = b.message_id
AND a.message_id NOT IN ('', '0')
AND a.id > b.id;
-- 2) 替换旧普通索引为 UNIQUE partial index(排除空和占位值)
DROP INDEX IF EXISTS idx_chat_records_message_id;
CREATE UNIQUE INDEX idx_chat_records_message_id
ON chat_records (message_id) WHERE message_id NOT IN ('', '0');
@@ -1,3 +0,0 @@
-- 确保 llm_usage 表在全新数据库上也有 kind/entry 列(迁移 0010 仅解除了旧库的 NOT NULL
ALTER TABLE llm_usage ADD COLUMN IF NOT EXISTS kind TEXT;
ALTER TABLE llm_usage ADD COLUMN IF NOT EXISTS entry JSONB;
@@ -1,6 +0,0 @@
-- 定时任务增加 task_type 字段:system(系统任务)或 model(模型任务)
-- 模型只能管理 model 类型的任务,不能修改 system 任务
ALTER TABLE scheduled_tasks ADD COLUMN IF NOT EXISTS task_type TEXT NOT NULL DEFAULT 'model';
CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_type
ON scheduled_tasks (task_type, enabled, next_run_at);
@@ -1,4 +0,0 @@
-- 空迁移:用于对齐 _sqlx_migrations 表中已记录但文件丢失的迁移
-- 该迁移已被之前的某次运行应用过,但对应文件被删除/重命名
-- 此文件仅用于让 sqlx 迁移校验通过,不执行任何 DDL
SELECT 1;
@@ -1,4 +0,0 @@
-- 为"按用户查询最近的会话边界(clear/timeout 摘要)"添加索引。
-- list_recent_chat_records_for_context 会据此过滤掉已过期会话的消息。
CREATE INDEX IF NOT EXISTS idx_session_summaries_user_created
ON session_summaries (user_id, created_at DESC);
@@ -1,10 +1,12 @@
-- Add migration script here
CREATE TABLE ias_wechat_users (
CREATE TABLE ias_wechat_accounts (
id BIGSERIAL PRIMARY KEY,
user_name VARCHAR(100) NOT NULL,
token VARCHAR(255),
account_id VARCHAR(255),
base_url VARCHAR(255),
user_id VARCHAR(255),
updates_buf VARCHAR(255),
user_status INTEGER,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
@@ -1,2 +0,0 @@
-- Add migration script here
ALTER TABLE ias_wechat_users ADD COLUMN user_id VARCHAR(255);