落地并存测服全端:智能体 Graph/路由、后台切 8180、主账与部署脚本齐备,便于线上重发与验收。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
-- 001_runtime_core_v1.sql
|
||||
-- 新系统运行账核心表(inquiry_robot_runtime)
|
||||
-- 禁止对现网 ytd_runtime 执行。
|
||||
-- Graph checkpoint 表由 LangGraph PostgresSaver.setup() 另建,不在此脚本。
|
||||
|
||||
CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
version TEXT PRIMARY KEY,
|
||||
applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
description TEXT NOT NULL DEFAULT ''
|
||||
);
|
||||
|
||||
-- 企微入站 inbox:回调只写入;Worker/通道线程认领
|
||||
CREATE TABLE IF NOT EXISTS agent_inbox (
|
||||
id UUID PRIMARY KEY,
|
||||
message_id TEXT NOT NULL,
|
||||
sender_id TEXT NOT NULL,
|
||||
chat_id TEXT NOT NULL DEFAULT '',
|
||||
chat_type TEXT NOT NULL DEFAULT '',
|
||||
payload JSONB NOT NULL,
|
||||
state TEXT NOT NULL DEFAULT 'pending',
|
||||
claimed_at TIMESTAMPTZ,
|
||||
claimed_by TEXT NOT NULL DEFAULT '',
|
||||
attempts INT NOT NULL DEFAULT 0,
|
||||
last_error TEXT NOT NULL DEFAULT '',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT agent_inbox_message_id_uq UNIQUE (message_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_inbox_state_created
|
||||
ON agent_inbox (state, created_at);
|
||||
|
||||
-- 企微出站 outbox:发送成功 ≠ 业务成功;过期可丢弃
|
||||
CREATE TABLE IF NOT EXISTS agent_outbox (
|
||||
id UUID PRIMARY KEY,
|
||||
dedupe_key TEXT NOT NULL DEFAULT '',
|
||||
touser TEXT NOT NULL,
|
||||
content TEXT NOT NULL DEFAULT '',
|
||||
msg_type TEXT NOT NULL DEFAULT 'text',
|
||||
payload JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
state TEXT NOT NULL DEFAULT 'pending',
|
||||
claimed_at TIMESTAMPTZ,
|
||||
claimed_by TEXT NOT NULL DEFAULT '',
|
||||
attempts INT NOT NULL DEFAULT 0,
|
||||
last_error TEXT NOT NULL DEFAULT '',
|
||||
max_age_seconds INT NOT NULL DEFAULT 86400,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_agent_outbox_dedupe
|
||||
ON agent_outbox (dedupe_key)
|
||||
WHERE dedupe_key <> '';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_outbox_state_created
|
||||
ON agent_outbox (state, created_at);
|
||||
|
||||
-- 会话:活动工单与打断栈(非六态真相)
|
||||
CREATE TABLE IF NOT EXISTS conversation_session (
|
||||
thread_id TEXT PRIMARY KEY,
|
||||
sender_id TEXT NOT NULL,
|
||||
active_inquiry_no TEXT NOT NULL DEFAULT '',
|
||||
interrupt_stack JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
meta JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_conversation_session_sender
|
||||
ON conversation_session (sender_id);
|
||||
|
||||
-- 停等账:waitVersion(与卡片/H5 绑定)
|
||||
CREATE TABLE IF NOT EXISTS suspend_wait (
|
||||
thread_id TEXT NOT NULL,
|
||||
wait_version INT NOT NULL,
|
||||
pause_name TEXT NOT NULL DEFAULT '',
|
||||
inquiry_no TEXT NOT NULL DEFAULT '',
|
||||
status TEXT NOT NULL DEFAULT 'open',
|
||||
payload JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
closed_at TIMESTAMPTZ,
|
||||
PRIMARY KEY (thread_id, wait_version)
|
||||
);
|
||||
|
||||
-- 补问 / 卡片 token(H5 TTL 约 30 分钟由应用写入 expires_at)
|
||||
CREATE TABLE IF NOT EXISTS clarification_binding (
|
||||
token TEXT PRIMARY KEY,
|
||||
thread_id TEXT NOT NULL,
|
||||
wait_version INT NOT NULL,
|
||||
sender_id TEXT NOT NULL DEFAULT '',
|
||||
allowed_actions JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
expires_at TIMESTAMPTZ NOT NULL,
|
||||
consumed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_clarification_thread_wait
|
||||
ON clarification_binding (thread_id, wait_version);
|
||||
|
||||
-- 可选:PG 任务认领表(与 Redis Stream 二选一做真相;骨架两套都建好,业务接入时只留一条)
|
||||
CREATE TABLE IF NOT EXISTS agent_job (
|
||||
id UUID PRIMARY KEY,
|
||||
job_type TEXT NOT NULL,
|
||||
idempotency_key TEXT NOT NULL DEFAULT '',
|
||||
payload JSONB NOT NULL,
|
||||
state TEXT NOT NULL DEFAULT 'pending',
|
||||
claimed_at TIMESTAMPTZ,
|
||||
claimed_by TEXT NOT NULL DEFAULT '',
|
||||
attempts INT NOT NULL DEFAULT 0,
|
||||
last_error TEXT NOT NULL DEFAULT '',
|
||||
result JSONB,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_agent_job_idem
|
||||
ON agent_job (job_type, idempotency_key)
|
||||
WHERE idempotency_key <> '';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_job_state_created
|
||||
ON agent_job (state, created_at);
|
||||
|
||||
INSERT INTO schema_migrations (version, description)
|
||||
VALUES ('001_runtime_core_v1', 'inbox/outbox/session/suspend/clarification/job 核心表')
|
||||
ON CONFLICT (version) DO NOTHING;
|
||||
@@ -0,0 +1,25 @@
|
||||
-- 002_dead_letter_v1.sql
|
||||
-- 死信表:失败任务落点(框架壳,不含业务重放逻辑)
|
||||
-- 禁止对现网 ytd_runtime 执行。
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_dead_letter (
|
||||
id UUID PRIMARY KEY,
|
||||
source TEXT NOT NULL DEFAULT '',
|
||||
source_id TEXT NOT NULL DEFAULT '',
|
||||
job_type TEXT NOT NULL DEFAULT '',
|
||||
payload JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
error TEXT NOT NULL DEFAULT '',
|
||||
attempts INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
replayed_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_dead_letter_created
|
||||
ON agent_dead_letter (created_at DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_dead_letter_job_type
|
||||
ON agent_dead_letter (job_type, created_at DESC);
|
||||
|
||||
INSERT INTO schema_migrations (version, description)
|
||||
VALUES ('002_dead_letter_v1', 'agent_dead_letter 死信表壳')
|
||||
ON CONFLICT (version) DO NOTHING;
|
||||
@@ -1,7 +1,24 @@
|
||||
# PostgreSQL 运行账迁移
|
||||
|
||||
后续在此目录添加版本化 SQL(inbox / outbox / checkpoint / 任务认领等)。
|
||||
- 只对当前环境变量 `PG_DATABASE` / `PG_DSN` 执行(新系统 **`inquiry_robot_runtime`**)。
|
||||
- **禁止**对现网 `ytd_runtime` 执行迁移(代码会拒绝)。
|
||||
|
||||
- 只对当前环境变量 `PG_DATABASE` 执行(新系统 `inquiry_robot_runtime`)。
|
||||
- **禁止**对现网 `ytd_runtime` 执行迁移。
|
||||
- 骨架阶段不建业务表。
|
||||
## 文件
|
||||
|
||||
| 文件 | 内容 |
|
||||
|---|---|
|
||||
| `001_runtime_core_v1.sql` | inbox / outbox / conversation_session / suspend_wait / clarification_binding / agent_job |
|
||||
|
||||
## Graph checkpoint
|
||||
|
||||
LangGraph `PostgresSaver.setup()` 会在连接库内另建 checkpoint 表,与上表分开。
|
||||
|
||||
## 怎么跑
|
||||
|
||||
```text
|
||||
cd inquiry-agent
|
||||
python -m agent.runtime_db.migrate --list
|
||||
python -m agent.runtime_db.migrate
|
||||
```
|
||||
|
||||
需已配置 `PG_DSN` 或 `PG_HOST`+`PG_DATABASE`+`PG_USER`(及密码)。
|
||||
|
||||
Reference in New Issue
Block a user