@ai-zen/agents-host 0.0.0-stage → 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/LICENSE +21 -0
- package/README.md +759 -2
- package/dist/app.d.ts +384 -0
- package/dist/app.js +1148 -0
- package/dist/cli.d.ts +21 -0
- package/dist/cli.js +353 -0
- package/dist/config.d.ts +97 -0
- package/dist/config.js +171 -0
- package/dist/handlers/agentHandlers.d.ts +18 -0
- package/dist/handlers/agentHandlers.js +20 -0
- package/dist/handlers/assetHandlers.d.ts +29 -0
- package/dist/handlers/assetHandlers.js +35 -0
- package/dist/handlers/capabilities.d.ts +26 -0
- package/dist/handlers/capabilities.js +138 -0
- package/dist/handlers/completionHandlers.d.ts +18 -0
- package/dist/handlers/completionHandlers.js +13 -0
- package/dist/handlers/configHandlers.d.ts +31 -0
- package/dist/handlers/configHandlers.js +59 -0
- package/dist/handlers/conversationHandlers.d.ts +118 -0
- package/dist/handlers/conversationHandlers.js +314 -0
- package/dist/handlers/handoffHandlers.d.ts +17 -0
- package/dist/handlers/handoffHandlers.js +14 -0
- package/dist/handlers/hostHandlers.d.ts +39 -0
- package/dist/handlers/hostHandlers.js +56 -0
- package/dist/handlers/index.d.ts +128 -0
- package/dist/handlers/index.js +92 -0
- package/dist/handlers/messageHandlers.d.ts +11 -0
- package/dist/handlers/messageHandlers.js +10 -0
- package/dist/handlers/modelHandlers.d.ts +17 -0
- package/dist/handlers/modelHandlers.js +19 -0
- package/dist/handlers/noticeHandlers.d.ts +24 -0
- package/dist/handlers/noticeHandlers.js +24 -0
- package/dist/handlers/questionHandlers.d.ts +16 -0
- package/dist/handlers/questionHandlers.js +16 -0
- package/dist/handlers/searchHandlers.d.ts +12 -0
- package/dist/handlers/searchHandlers.js +12 -0
- package/dist/handlers/workspaceHandlers.d.ts +29 -0
- package/dist/handlers/workspaceHandlers.js +47 -0
- package/dist/i18n/en.d.ts +243 -0
- package/dist/i18n/en.js +270 -0
- package/dist/i18n/index.d.ts +43 -0
- package/dist/i18n/index.js +72 -0
- package/dist/i18n/zh.d.ts +240 -0
- package/dist/i18n/zh.js +257 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +15 -0
- package/dist/net/UploadReceiver.d.ts +186 -0
- package/dist/net/UploadReceiver.js +494 -0
- package/dist/net/WsHub.d.ts +231 -0
- package/dist/net/WsHub.js +689 -0
- package/dist/net/auth.d.ts +73 -0
- package/dist/net/auth.js +74 -0
- package/dist/net/discovery.d.ts +72 -0
- package/dist/net/discovery.js +171 -0
- package/dist/net/index.d.ts +14 -0
- package/dist/net/index.js +10 -0
- package/dist/runtime/ChatRunner.d.ts +374 -0
- package/dist/runtime/ChatRunner.js +1204 -0
- package/dist/runtime/ConversationDrafts.d.ts +43 -0
- package/dist/runtime/ConversationDrafts.js +47 -0
- package/dist/runtime/RunRegistry.d.ts +79 -0
- package/dist/runtime/RunRegistry.js +108 -0
- package/dist/runtime/ScopeRegistry.d.ts +153 -0
- package/dist/runtime/ScopeRegistry.js +259 -0
- package/dist/runtime/TransientRunner.d.ts +90 -0
- package/dist/runtime/TransientRunner.js +179 -0
- package/dist/runtime/index.d.ts +14 -0
- package/dist/runtime/index.js +10 -0
- package/dist/services/AgentService.d.ts +150 -0
- package/dist/services/AgentService.js +718 -0
- package/dist/services/AssetService.d.ts +338 -0
- package/dist/services/AssetService.js +739 -0
- package/dist/services/AutoNaming.d.ts +92 -0
- package/dist/services/AutoNaming.js +235 -0
- package/dist/services/CompletionService.d.ts +122 -0
- package/dist/services/CompletionService.js +442 -0
- package/dist/services/ConfigService.d.ts +171 -0
- package/dist/services/ConfigService.js +695 -0
- package/dist/services/ConversationService.d.ts +274 -0
- package/dist/services/ConversationService.js +902 -0
- package/dist/services/CredentialService.d.ts +33 -0
- package/dist/services/CredentialService.js +86 -0
- package/dist/services/DiscoveryService.d.ts +182 -0
- package/dist/services/DiscoveryService.js +998 -0
- package/dist/services/HandoffService.d.ts +189 -0
- package/dist/services/HandoffService.js +414 -0
- package/dist/services/Logger.d.ts +130 -0
- package/dist/services/Logger.js +256 -0
- package/dist/services/MessageService.d.ts +88 -0
- package/dist/services/MessageService.js +280 -0
- package/dist/services/ModelService.d.ts +89 -0
- package/dist/services/ModelService.js +489 -0
- package/dist/services/NoticeService.d.ts +93 -0
- package/dist/services/NoticeService.js +217 -0
- package/dist/services/QuestionService.d.ts +184 -0
- package/dist/services/QuestionService.js +457 -0
- package/dist/services/SearchService.d.ts +54 -0
- package/dist/services/SearchService.js +117 -0
- package/dist/services/WorkspaceService.d.ts +96 -0
- package/dist/services/WorkspaceService.js +213 -0
- package/dist/services/imageSize.d.ts +41 -0
- package/dist/services/imageSize.js +146 -0
- package/dist/services/index.d.ts +20 -0
- package/dist/services/index.js +15 -0
- package/dist/services/secretMask.d.ts +24 -0
- package/dist/services/secretMask.js +34 -0
- package/dist/storage/AssetRepository.d.ts +87 -0
- package/dist/storage/AssetRepository.js +180 -0
- package/dist/storage/ConversationRepository.d.ts +55 -0
- package/dist/storage/ConversationRepository.js +128 -0
- package/dist/storage/CredentialRepository.d.ts +28 -0
- package/dist/storage/CredentialRepository.js +47 -0
- package/dist/storage/Database.d.ts +95 -0
- package/dist/storage/Database.js +180 -0
- package/dist/storage/MessageRepository.d.ts +104 -0
- package/dist/storage/MessageRepository.js +323 -0
- package/dist/storage/MetaRepository.d.ts +21 -0
- package/dist/storage/MetaRepository.js +33 -0
- package/dist/storage/NoticeRepository.d.ts +31 -0
- package/dist/storage/NoticeRepository.js +89 -0
- package/dist/storage/QuestionRepository.d.ts +34 -0
- package/dist/storage/QuestionRepository.js +96 -0
- package/dist/storage/WorkspaceRepository.d.ts +25 -0
- package/dist/storage/WorkspaceRepository.js +44 -0
- package/dist/storage/dbWorker.d.ts +10 -0
- package/dist/storage/dbWorker.js +132 -0
- package/dist/storage/index.d.ts +20 -0
- package/dist/storage/index.js +16 -0
- package/dist/storage/migrations.d.ts +26 -0
- package/dist/storage/migrations.js +207 -0
- package/dist/storage/types.d.ts +298 -0
- package/dist/storage/types.js +14 -0
- package/dist/wire/errors.d.ts +105 -0
- package/dist/wire/errors.js +143 -0
- package/dist/wire/events.d.ts +102 -0
- package/dist/wire/events.js +13 -0
- package/dist/wire/frames.d.ts +106 -0
- package/dist/wire/frames.js +156 -0
- package/dist/wire/index.d.ts +31 -0
- package/dist/wire/index.js +31 -0
- package/dist/wire/methods.d.ts +1896 -0
- package/dist/wire/methods.js +99 -0
- package/dist/wire/states.d.ts +487 -0
- package/dist/wire/states.js +61 -0
- package/package.json +63 -3
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 建表与迁移。
|
|
3
|
+
*
|
|
4
|
+
* `meta.schemaVersion` 是唯一的版本真相:`migrate` 从当前版本往上逐级执行,
|
|
5
|
+
* 每一级的所有语句 + 版本号推进都在**同一个事务**里 —— 结构改了一半而版本号没动,
|
|
6
|
+
* 或者版本号动了而结构没改,都会让下次启动跑在错误的假设上。
|
|
7
|
+
*
|
|
8
|
+
* 不识别任何旧数据、不做数据搬迁(PRD L1:新库从空开始)。
|
|
9
|
+
*/
|
|
10
|
+
import { MetaRepository } from "./MetaRepository.js";
|
|
11
|
+
/**
|
|
12
|
+
* 迁移列表。眼下只有 v1:这套表结构还没随版本发出去,PM 在 W1 之后的裁定(cwd 唯一、
|
|
13
|
+
* 身份列非空)直接落进了 v1 的建表语句。再往后改结构时追加新条目 —— 已经装上升过级的库
|
|
14
|
+
* 不会重跑旧条目,改旧条目会让两台机器的表结构悄悄分叉。
|
|
15
|
+
*/
|
|
16
|
+
export const MIGRATIONS = [
|
|
17
|
+
{
|
|
18
|
+
version: 1,
|
|
19
|
+
statements: [
|
|
20
|
+
// meta:单行表(id 固定为 1),存 schemaVersion 与建库时间
|
|
21
|
+
`CREATE TABLE IF NOT EXISTS meta (
|
|
22
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
23
|
+
schemaVersion INTEGER NOT NULL,
|
|
24
|
+
createdAt INTEGER NOT NULL
|
|
25
|
+
)`,
|
|
26
|
+
// workspaces:一个工作目录登记一次。cwd 不可变(PRD D9),所以没有更新的入口。
|
|
27
|
+
// cwd 唯一:同一个目录登记两次会出现两个 Scope 抢同一目录;唯一约束自带的索引
|
|
28
|
+
// 就是「这个 cwd 登记过没有」(PRD D10 的问一次)的查询路径,不再另建普通索引
|
|
29
|
+
`CREATE TABLE IF NOT EXISTS workspaces (
|
|
30
|
+
id TEXT PRIMARY KEY,
|
|
31
|
+
name TEXT NOT NULL,
|
|
32
|
+
cwd TEXT NOT NULL UNIQUE,
|
|
33
|
+
createdAt INTEGER NOT NULL
|
|
34
|
+
)`,
|
|
35
|
+
// conversations:项目 / 助手创建时定死,模型与思考档位是这段会话自己的(可以改)。
|
|
36
|
+
// agentId / modelId 不允许为空 —— 解析不出助手或模型时在创建处就失败,不落半成品行。
|
|
37
|
+
// nameIsAuto 记住「这个名字是不是自动起的」(R35):创建时的原名算自动,用户改名置 0,
|
|
38
|
+
// 自动命名写入新名并置 1。
|
|
39
|
+
// thinkingLevel 存档位名(可空):空 = 跟随助手定义上的那份参数;非空 = 这一段会话选的档位,
|
|
40
|
+
// 装配 agent 时按该模型的思考策略表展开成参数补丁。
|
|
41
|
+
`CREATE TABLE IF NOT EXISTS conversations (
|
|
42
|
+
id TEXT PRIMARY KEY,
|
|
43
|
+
workspaceId TEXT NOT NULL REFERENCES workspaces (id) ON DELETE CASCADE,
|
|
44
|
+
name TEXT NOT NULL,
|
|
45
|
+
nameIsAuto INTEGER NOT NULL DEFAULT 1,
|
|
46
|
+
pinned INTEGER NOT NULL DEFAULT 0,
|
|
47
|
+
agentId TEXT NOT NULL,
|
|
48
|
+
modelId TEXT NOT NULL,
|
|
49
|
+
thinkingLevel TEXT,
|
|
50
|
+
createdAt INTEGER NOT NULL,
|
|
51
|
+
updatedAt INTEGER NOT NULL
|
|
52
|
+
)`,
|
|
53
|
+
// 侧栏排序 = 置顶优先、再按创建时间倒序(PRD D13);活动/改名不影响顺序
|
|
54
|
+
`CREATE INDEX IF NOT EXISTS idx_conversations_workspace
|
|
55
|
+
ON conversations (workspaceId, pinned DESC, createdAt DESC)`,
|
|
56
|
+
// messages:边流边写,同一条消息按 id 反复覆盖(PRD D15)。
|
|
57
|
+
// parentToolCallId 记录子 Agent 消息挂在哪次工具调用上(R37),顶层消息为空。
|
|
58
|
+
`CREATE TABLE IF NOT EXISTS messages (
|
|
59
|
+
id TEXT PRIMARY KEY,
|
|
60
|
+
conversationId TEXT NOT NULL REFERENCES conversations (id) ON DELETE CASCADE,
|
|
61
|
+
seq INTEGER NOT NULL,
|
|
62
|
+
role TEXT NOT NULL,
|
|
63
|
+
status TEXT NOT NULL,
|
|
64
|
+
omit INTEGER NOT NULL DEFAULT 0,
|
|
65
|
+
content TEXT NOT NULL DEFAULT '',
|
|
66
|
+
data TEXT,
|
|
67
|
+
searchText TEXT NOT NULL DEFAULT '',
|
|
68
|
+
parentToolCallId TEXT,
|
|
69
|
+
createdAt INTEGER NOT NULL,
|
|
70
|
+
updatedAt INTEGER NOT NULL,
|
|
71
|
+
UNIQUE (conversationId, seq)
|
|
72
|
+
)`,
|
|
73
|
+
// 按对话顺序读取,以及 `after=<消息 id>` 定位
|
|
74
|
+
`CREATE INDEX IF NOT EXISTS idx_messages_conversation_seq
|
|
75
|
+
ON messages (conversationId, seq)`,
|
|
76
|
+
// 按父工具调用取子 Agent 的消息(R37 的读取路径);NULL 行不进索引,顶层消息不受影响
|
|
77
|
+
`CREATE INDEX IF NOT EXISTS idx_messages_parent_tool_call
|
|
78
|
+
ON messages (parentToolCallId)`,
|
|
79
|
+
// assets:二进制素材的唯一真相(PRD L2 / F-H8)—— 文件在 assets/ 下,这一行记的是引用、
|
|
80
|
+
// 大小、类型、内容摘要与像素尺寸。
|
|
81
|
+
// 去重是**全局**的:sha256 唯一,同一份字节在整台机器上只有一行、一份磁盘。所以这张表
|
|
82
|
+
// 不再记「属于哪段对话 / 哪条消息」:归属在 conversation_assets 里,一张图贴到两个项目
|
|
83
|
+
// 就是一行素材 + 两行关系。
|
|
84
|
+
// width / height 可空:落定时按文件头解(PNG / JPEG),解不出来就是 NULL。
|
|
85
|
+
`CREATE TABLE IF NOT EXISTS assets (
|
|
86
|
+
id TEXT PRIMARY KEY,
|
|
87
|
+
name TEXT,
|
|
88
|
+
path TEXT NOT NULL,
|
|
89
|
+
mime TEXT NOT NULL,
|
|
90
|
+
bytes INTEGER NOT NULL,
|
|
91
|
+
sha256 TEXT NOT NULL UNIQUE,
|
|
92
|
+
width INTEGER,
|
|
93
|
+
height INTEGER,
|
|
94
|
+
createdAt INTEGER NOT NULL
|
|
95
|
+
)`,
|
|
96
|
+
// conversation_assets:谁引用了哪份素材(消息 × 素材的关系行)。
|
|
97
|
+
// 写入时机是消息落库那一刻(扫 content 里的 `__asset_id`,同一 message+asset 一行);
|
|
98
|
+
// 撤回 / 删对话 / 删消息都由外键级联删掉关系行,不需要谁去减计数。
|
|
99
|
+
// assetId 用 RESTRICT:还有人引用时物理删不掉素材行(护栏),真正的删除条件由
|
|
100
|
+
// 「COUNT(*) = 0」判定(见 AssetRepository.deleteIfUnreferenced)。
|
|
101
|
+
// 「几张会话引用了它」= COUNT(DISTINCT conversationId),走 idx_conversation_assets_asset。
|
|
102
|
+
`CREATE TABLE IF NOT EXISTS conversation_assets (
|
|
103
|
+
conversationId TEXT NOT NULL REFERENCES conversations (id) ON DELETE CASCADE,
|
|
104
|
+
messageId TEXT NOT NULL REFERENCES messages (id) ON DELETE CASCADE,
|
|
105
|
+
assetId TEXT NOT NULL REFERENCES assets (id) ON DELETE RESTRICT,
|
|
106
|
+
createdAt INTEGER NOT NULL,
|
|
107
|
+
UNIQUE (messageId, assetId)
|
|
108
|
+
)`,
|
|
109
|
+
`CREATE INDEX IF NOT EXISTS idx_conversation_assets_asset ON conversation_assets (assetId)`,
|
|
110
|
+
`CREATE INDEX IF NOT EXISTS idx_conversation_assets_conversation
|
|
111
|
+
ON conversation_assets (conversationId)`,
|
|
112
|
+
// asset_vendor_files:厂商侧文件 id 的缓存(端点维度)。
|
|
113
|
+
// 它**不是**真相:删光之后从 assets 重建即可(下次发送时重新上传一遍),所以这里只记
|
|
114
|
+
// 「哪个素材在哪个端点上对应哪个 file_id」;素材没了就跟着走。
|
|
115
|
+
`CREATE TABLE IF NOT EXISTS asset_vendor_files (
|
|
116
|
+
assetId TEXT NOT NULL REFERENCES assets (id) ON DELETE CASCADE,
|
|
117
|
+
endpointId TEXT NOT NULL,
|
|
118
|
+
vendorFileId TEXT NOT NULL,
|
|
119
|
+
createdAt INTEGER NOT NULL,
|
|
120
|
+
UNIQUE (assetId, endpointId)
|
|
121
|
+
)`,
|
|
122
|
+
// 缓存行的两种查法靠 UNIQUE (assetId, endpointId):
|
|
123
|
+
// 「这个端点上有没有」与「别的端点上有没有」都走这条(都是 assetId 前缀查询)
|
|
124
|
+
// notices:持久化,durationMs 为 null 表示永久(PRD L3)。
|
|
125
|
+
// conversationId 是「这条通知与哪段对话有关」的真值(可空 = 全局通知):按对话过滤、
|
|
126
|
+
// 按对话清都走这一列;对话没了它也就没有意义,所以跟着级联删除。
|
|
127
|
+
`CREATE TABLE IF NOT EXISTS notices (
|
|
128
|
+
id TEXT PRIMARY KEY,
|
|
129
|
+
level TEXT NOT NULL,
|
|
130
|
+
code TEXT NOT NULL,
|
|
131
|
+
params TEXT,
|
|
132
|
+
durationMs INTEGER,
|
|
133
|
+
conversationId TEXT REFERENCES conversations (id) ON DELETE CASCADE,
|
|
134
|
+
createdAt INTEGER NOT NULL
|
|
135
|
+
)`,
|
|
136
|
+
`CREATE INDEX IF NOT EXISTS idx_notices_createdAt ON notices (createdAt)`,
|
|
137
|
+
`CREATE INDEX IF NOT EXISTS idx_notices_conversation ON notices (conversationId)`,
|
|
138
|
+
// questions:有状态、可持久化、多端共享(PRD D22 / F-I9)
|
|
139
|
+
`CREATE TABLE IF NOT EXISTS questions (
|
|
140
|
+
id TEXT PRIMARY KEY,
|
|
141
|
+
conversationId TEXT NOT NULL REFERENCES conversations (id) ON DELETE CASCADE,
|
|
142
|
+
kind TEXT NOT NULL,
|
|
143
|
+
payload TEXT NOT NULL,
|
|
144
|
+
state TEXT NOT NULL,
|
|
145
|
+
answer TEXT,
|
|
146
|
+
createdAt INTEGER NOT NULL,
|
|
147
|
+
updatedAt INTEGER NOT NULL,
|
|
148
|
+
answeredAt INTEGER
|
|
149
|
+
)`,
|
|
150
|
+
`CREATE INDEX IF NOT EXISTS idx_questions_conversation
|
|
151
|
+
ON questions (conversationId, createdAt)`,
|
|
152
|
+
// credentials:只存 sha256 摘要,明文不在库里(PRD L11:多串、带备注、可单独吊销)
|
|
153
|
+
`CREATE TABLE IF NOT EXISTS credentials (
|
|
154
|
+
id TEXT PRIMARY KEY,
|
|
155
|
+
note TEXT NOT NULL DEFAULT '',
|
|
156
|
+
hash TEXT NOT NULL,
|
|
157
|
+
createdAt INTEGER NOT NULL,
|
|
158
|
+
revokedAt INTEGER
|
|
159
|
+
)`,
|
|
160
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS idx_credentials_hash ON credentials (hash)`,
|
|
161
|
+
// 全文检索:外部内容表挂在 messages 上,只索引 searchText(正文纯文本,不含 JSON 键名)。
|
|
162
|
+
// tokenize='trigram':默认的 unicode61 会把整段中文当成一个 token,那样中文搜索永远
|
|
163
|
+
// 命中不了;trigram 按三字符切分,中文子串才搜得到(代价是查询词至少 3 个字符,
|
|
164
|
+
// 少于 3 个字符的查询在仓储里退化到 LIKE,见 MessageRepository.search)
|
|
165
|
+
`CREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5 (
|
|
166
|
+
searchText,
|
|
167
|
+
content='messages',
|
|
168
|
+
content_rowid='rowid',
|
|
169
|
+
tokenize='trigram'
|
|
170
|
+
)`,
|
|
171
|
+
// 用触发器同步索引:写路径只有一条(都走 messages 表),不存在「仓储忘了同步」的情况
|
|
172
|
+
`CREATE TRIGGER IF NOT EXISTS messages_fts_after_insert AFTER INSERT ON messages BEGIN
|
|
173
|
+
INSERT INTO messages_fts (rowid, searchText) VALUES (new.rowid, new.searchText);
|
|
174
|
+
END`,
|
|
175
|
+
`CREATE TRIGGER IF NOT EXISTS messages_fts_after_delete AFTER DELETE ON messages BEGIN
|
|
176
|
+
INSERT INTO messages_fts (messages_fts, rowid, searchText)
|
|
177
|
+
VALUES ('delete', old.rowid, old.searchText);
|
|
178
|
+
END`,
|
|
179
|
+
`CREATE TRIGGER IF NOT EXISTS messages_fts_after_update AFTER UPDATE OF searchText ON messages BEGIN
|
|
180
|
+
INSERT INTO messages_fts (messages_fts, rowid, searchText)
|
|
181
|
+
VALUES ('delete', old.rowid, old.searchText);
|
|
182
|
+
INSERT INTO messages_fts (rowid, searchText) VALUES (new.rowid, new.searchText);
|
|
183
|
+
END`,
|
|
184
|
+
],
|
|
185
|
+
},
|
|
186
|
+
];
|
|
187
|
+
/**
|
|
188
|
+
* 把库升到最新版本。重复调用是幂等的:已经跑过的版本会跳过,不会再执行一遍语句。
|
|
189
|
+
*/
|
|
190
|
+
export async function migrate(db) {
|
|
191
|
+
const meta = new MetaRepository(db);
|
|
192
|
+
let current = await meta.getSchemaVersion();
|
|
193
|
+
const now = Date.now();
|
|
194
|
+
for (const migration of MIGRATIONS) {
|
|
195
|
+
if (migration.version <= current)
|
|
196
|
+
continue;
|
|
197
|
+
const target = migration.version;
|
|
198
|
+
await db.tx((tx) => {
|
|
199
|
+
for (const statement of migration.statements)
|
|
200
|
+
tx.run(statement);
|
|
201
|
+
// 版本号与结构改动同一次事务提交,两者不会分叉
|
|
202
|
+
tx.run(`INSERT INTO meta (id, schemaVersion, createdAt) VALUES (1, ?, ?)
|
|
203
|
+
ON CONFLICT (id) DO UPDATE SET schemaVersion = excluded.schemaVersion`, [target, now]);
|
|
204
|
+
});
|
|
205
|
+
current = target;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 存储层的行类型与入参类型。
|
|
3
|
+
*
|
|
4
|
+
* 约定:
|
|
5
|
+
* - 列名与字段名都是 camelCase(SQLite 的列名并不强制风格,这里让「行类型 = 列名」,
|
|
6
|
+
* 读写两侧不用再维护一张映射表)。
|
|
7
|
+
* - 所有时间戳都是 `Date.now()` 的毫秒数,列类型 INTEGER(见各表注释)。
|
|
8
|
+
* - 带 `Row` 后缀的是**数据库原样行**(JSON 列还是字符串),不带后缀的是仓储解好的对象。
|
|
9
|
+
* - 消息正文直接用 core 的 `AgentNS.MessageContent`(R21 / R30):列里存的就是它的 JSON,
|
|
10
|
+
* 仓储反序列化后就是同一个形状,服务层与运行时不必在两种形状之间翻译。
|
|
11
|
+
* - `role` / `status` 仍以字符串存取(取值与 `AgentNS.Role` / `AgentNS.MessageStatus` 一致),
|
|
12
|
+
* 收敛成 core 的枚举发生在服务层。
|
|
13
|
+
*/
|
|
14
|
+
import type { AgentNS } from "@ai-zen/agents-core";
|
|
15
|
+
/** 消息角色,取值与 core 的 `AgentNS.Role` 对齐 */
|
|
16
|
+
export type MessageRole = "system" | "user" | "assistant" | "tool" | "function" | "unknown";
|
|
17
|
+
/** 消息状态,取值与 core 的 `AgentNS.MessageStatus` 对齐 */
|
|
18
|
+
export type MessageStatus = "pending" | "writing" | "completed" | "error" | "aborted" | "unknown";
|
|
19
|
+
export interface WorkspaceRow {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
/** 工作目录:创建后不可变(PRD D9),因此这里没有更新方法 */
|
|
23
|
+
cwd: string;
|
|
24
|
+
createdAt: number;
|
|
25
|
+
}
|
|
26
|
+
export interface WorkspaceCreateInput {
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
cwd: string;
|
|
30
|
+
createdAt: number;
|
|
31
|
+
}
|
|
32
|
+
export interface ConversationRow {
|
|
33
|
+
id: string;
|
|
34
|
+
workspaceId: string;
|
|
35
|
+
name: string;
|
|
36
|
+
/** 0 / 1:这个名字是不是自动起的(R35)。创建时的原名算自动,用户改名置 0,自动命名置 1 */
|
|
37
|
+
nameIsAuto: number;
|
|
38
|
+
/** 0 / 1:侧栏置顶(PRD D13) */
|
|
39
|
+
pinned: number;
|
|
40
|
+
/** 创建时定死的助手(PRD L7),此处只存 id;定义本身在配置层 */
|
|
41
|
+
agentId: string;
|
|
42
|
+
/** 这段会话现在用的模型:创建时取助手定义上那个,之后可以由 `conversation.setModel` 改 */
|
|
43
|
+
modelId: string;
|
|
44
|
+
/**
|
|
45
|
+
* 这段会话选的思考档位名;`null` = 跟随助手定义上的那份参数。
|
|
46
|
+
*
|
|
47
|
+
* 存的是档位名而不是展开后的参数:档位属于模型(同一个档位名在不同模型的策略表里
|
|
48
|
+
* 对应不同参数),换模型时这一列被清空,展开只在装配 agent 那一刻做。
|
|
49
|
+
*/
|
|
50
|
+
thinkingLevel: string | null;
|
|
51
|
+
createdAt: number;
|
|
52
|
+
/** 最后一次结构性变化的时间;排序只看 pinned + createdAt,不看它(D13) */
|
|
53
|
+
updatedAt: number;
|
|
54
|
+
}
|
|
55
|
+
export interface Conversation extends Omit<ConversationRow, "pinned" | "nameIsAuto"> {
|
|
56
|
+
pinned: boolean;
|
|
57
|
+
/** 名字仍是自动起的那个(真值来自 `conversations.nameIsAuto` 列,不由名字反推) */
|
|
58
|
+
nameIsAuto: boolean;
|
|
59
|
+
}
|
|
60
|
+
export interface ConversationCreateInput {
|
|
61
|
+
id: string;
|
|
62
|
+
workspaceId: string;
|
|
63
|
+
name: string;
|
|
64
|
+
/** 助手是对话身份的一部分,创建时必须已知(解析不出来就先解析、不建行) */
|
|
65
|
+
agentId: string;
|
|
66
|
+
/** 模型创建时也必须有值(取助手定义上那个,或创建时点名的那一个) */
|
|
67
|
+
modelId: string;
|
|
68
|
+
/** 创建时就能定的思考档位(草稿期间用户先调过档、首次发消息才落库);缺省 `null` = 跟随助手 */
|
|
69
|
+
thinkingLevel?: string | null;
|
|
70
|
+
createdAt: number;
|
|
71
|
+
updatedAt?: number;
|
|
72
|
+
}
|
|
73
|
+
export interface MessageRow {
|
|
74
|
+
id: string;
|
|
75
|
+
conversationId: string;
|
|
76
|
+
/** 同一对话内单调递增的序号,用于稳定排序与 `after` 游标 */
|
|
77
|
+
seq: number;
|
|
78
|
+
role: string;
|
|
79
|
+
status: string;
|
|
80
|
+
/** 0 / 1:是否已被移出上下文(PRD D15 要求 status / omit 必须落盘) */
|
|
81
|
+
omit: number;
|
|
82
|
+
/** JSON:消息正文(core 内容形状的 JSON 文本) */
|
|
83
|
+
content: string;
|
|
84
|
+
/** JSON:其余字段(tool_calls / reasoning_content / usage / name / finish_reason …) */
|
|
85
|
+
data: string | null;
|
|
86
|
+
/** 供全文检索的纯文本(从 content 抽出来的正文,不含 JSON 键名) */
|
|
87
|
+
searchText: string;
|
|
88
|
+
/** 子 Agent 消息挂在哪次工具调用上;顶层消息为 NULL(R37) */
|
|
89
|
+
parentToolCallId: string | null;
|
|
90
|
+
createdAt: number;
|
|
91
|
+
updatedAt: number;
|
|
92
|
+
}
|
|
93
|
+
export interface StoredMessage {
|
|
94
|
+
id: string;
|
|
95
|
+
conversationId: string;
|
|
96
|
+
/** 子 Agent 消息所属的父工具调用 id;顶层消息为 `null`(R37) */
|
|
97
|
+
parentToolCallId: string | null;
|
|
98
|
+
seq: number;
|
|
99
|
+
role: string;
|
|
100
|
+
status: string;
|
|
101
|
+
omit: boolean;
|
|
102
|
+
/** 已反序列化的正文:core 的内容形状;`null` 表示这条消息没有正文 */
|
|
103
|
+
content: AgentNS.MessageContent | null;
|
|
104
|
+
data: Record<string, unknown> | null;
|
|
105
|
+
createdAt: number;
|
|
106
|
+
updatedAt: number;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* 边流边写的入参:同一条消息按 id 反复 upsert,每次覆盖正文 / 状态 / omit,
|
|
110
|
+
* 但 `seq` 与 `createdAt` 保持第一次写入时的值。
|
|
111
|
+
*/
|
|
112
|
+
export interface MessageUpsertInput {
|
|
113
|
+
id: string;
|
|
114
|
+
conversationId: string;
|
|
115
|
+
role: string;
|
|
116
|
+
status: string;
|
|
117
|
+
/** core 的内容形状;不给表示这条消息没有正文 */
|
|
118
|
+
content?: AgentNS.MessageContent | null;
|
|
119
|
+
data?: Record<string, unknown> | null;
|
|
120
|
+
omit?: boolean;
|
|
121
|
+
/** 子 Agent 消息要挂的父工具调用 id;不给表示顶层消息(R37) */
|
|
122
|
+
parentToolCallId?: string | null;
|
|
123
|
+
createdAt: number;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* 全文搜索的范围:一段对话内,或一个 Workspace 下的全部对话。
|
|
127
|
+
*
|
|
128
|
+
* 之所以做成二选一的联合类型而不是两个可选字段,是因为「两个都没给」在语义上等于
|
|
129
|
+
* 全库搜索,而 PRD D16 只要求「按 Workspace 过滤」,不给就不该搜全库。
|
|
130
|
+
*/
|
|
131
|
+
export type MessageSearchScope = {
|
|
132
|
+
conversationId: string;
|
|
133
|
+
} | {
|
|
134
|
+
workspaceId: string;
|
|
135
|
+
} | undefined;
|
|
136
|
+
/** 全文搜索命中项:带上对话名与命中附近的片段,前端不用再查一遍 */
|
|
137
|
+
export interface MessageSearchHit {
|
|
138
|
+
id: string;
|
|
139
|
+
conversationId: string;
|
|
140
|
+
conversationName: string;
|
|
141
|
+
workspaceId: string;
|
|
142
|
+
role: string;
|
|
143
|
+
/** 命中位置前后截取的正文片段 */
|
|
144
|
+
snippet: string;
|
|
145
|
+
createdAt: number;
|
|
146
|
+
}
|
|
147
|
+
export interface AssetRow {
|
|
148
|
+
id: string;
|
|
149
|
+
/** 原始文件名(可空:粘贴的图片未必有名字) */
|
|
150
|
+
name: string | null;
|
|
151
|
+
/** 数据根下 `assets/` 的相对路径,库里只存引用(PRD L2) */
|
|
152
|
+
path: string;
|
|
153
|
+
mime: string;
|
|
154
|
+
bytes: number;
|
|
155
|
+
/** 内容摘要(上传时宿主自己算的那一份):全库唯一,即全局去重的键 */
|
|
156
|
+
sha256: string;
|
|
157
|
+
/** 像素宽度:落定时按文件头解出(PNG / JPEG),解不出来是 null */
|
|
158
|
+
width: number | null;
|
|
159
|
+
/** 像素高度;口径同 `width` */
|
|
160
|
+
height: number | null;
|
|
161
|
+
createdAt: number;
|
|
162
|
+
}
|
|
163
|
+
export interface AssetCreateInput {
|
|
164
|
+
id: string;
|
|
165
|
+
name?: string | null;
|
|
166
|
+
path: string;
|
|
167
|
+
mime: string;
|
|
168
|
+
bytes: number;
|
|
169
|
+
sha256: string;
|
|
170
|
+
width?: number | null;
|
|
171
|
+
height?: number | null;
|
|
172
|
+
createdAt: number;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* 关系行:某条消息引用了某份素材。
|
|
176
|
+
*
|
|
177
|
+
* 一行就是一次「引用」;同一对 `(messageId, assetId)` 只有一行(唯一约束)。
|
|
178
|
+
* 素材的归属、以及「几张会话引用了它」都从这张表算,`assets` 行上不再记对话 / 消息。
|
|
179
|
+
*/
|
|
180
|
+
export interface ConversationAssetRow {
|
|
181
|
+
conversationId: string;
|
|
182
|
+
messageId: string;
|
|
183
|
+
assetId: string;
|
|
184
|
+
createdAt: number;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* 厂商侧文件 id 的缓存行。
|
|
188
|
+
*
|
|
189
|
+
* `vendorFileId` 是**端点维度**的资源:同一个素材在 A 端点上传得到的 id 拿到 B 端点用会 not found。
|
|
190
|
+
* 所以这张表是缓存:这个端点上有就直接用,没有就按素材服务那三条规则走。
|
|
191
|
+
*/
|
|
192
|
+
export interface AssetVendorFileRow {
|
|
193
|
+
assetId: string;
|
|
194
|
+
endpointId: string;
|
|
195
|
+
vendorFileId: string;
|
|
196
|
+
createdAt: number;
|
|
197
|
+
}
|
|
198
|
+
export interface AssetVendorFileUpsertInput {
|
|
199
|
+
assetId: string;
|
|
200
|
+
endpointId: string;
|
|
201
|
+
vendorFileId: string;
|
|
202
|
+
createdAt: number;
|
|
203
|
+
}
|
|
204
|
+
export interface NoticeRow {
|
|
205
|
+
id: string;
|
|
206
|
+
/** 语气档位(PRD L3 的三档),取值由上层定义,存储层不判断 */
|
|
207
|
+
level: string;
|
|
208
|
+
/** 文案码:库里存码 + 参数,读出时按连接语言渲染(architecture.md §6) */
|
|
209
|
+
code: string;
|
|
210
|
+
/** JSON:文案参数 */
|
|
211
|
+
params: string | null;
|
|
212
|
+
/** 毫秒数;null 表示永久存在,只能手动清(PRD L3) */
|
|
213
|
+
durationMs: number | null;
|
|
214
|
+
/** 这条通知与哪段对话有关;null 表示全局通知(对话删掉时随之级联删除) */
|
|
215
|
+
conversationId: string | null;
|
|
216
|
+
createdAt: number;
|
|
217
|
+
}
|
|
218
|
+
export interface Notice {
|
|
219
|
+
id: string;
|
|
220
|
+
level: string;
|
|
221
|
+
code: string;
|
|
222
|
+
params: Record<string, unknown> | null;
|
|
223
|
+
durationMs: number | null;
|
|
224
|
+
/** 这条通知与哪段对话有关;null 表示全局通知 */
|
|
225
|
+
conversationId: string | null;
|
|
226
|
+
createdAt: number;
|
|
227
|
+
}
|
|
228
|
+
export interface NoticeCreateInput {
|
|
229
|
+
id: string;
|
|
230
|
+
level: string;
|
|
231
|
+
code: string;
|
|
232
|
+
params?: Record<string, unknown> | null;
|
|
233
|
+
durationMs?: number | null;
|
|
234
|
+
/** 挂在哪段对话上;不给表示全局通知 */
|
|
235
|
+
conversationId?: string | null;
|
|
236
|
+
createdAt: number;
|
|
237
|
+
}
|
|
238
|
+
export interface QuestionRow {
|
|
239
|
+
id: string;
|
|
240
|
+
conversationId: string;
|
|
241
|
+
/** 问题种类,取值由上层定义(交接确认、二次确认) */
|
|
242
|
+
kind: string;
|
|
243
|
+
/** JSON:候选项、正文等载荷 */
|
|
244
|
+
payload: string;
|
|
245
|
+
/** 状态机取值由上层定义,存储层原样存取(PRD D22:有状态、可持久化) */
|
|
246
|
+
state: string;
|
|
247
|
+
/** JSON:用户的回答 */
|
|
248
|
+
answer: string | null;
|
|
249
|
+
createdAt: number;
|
|
250
|
+
updatedAt: number;
|
|
251
|
+
answeredAt: number | null;
|
|
252
|
+
}
|
|
253
|
+
export interface Question {
|
|
254
|
+
id: string;
|
|
255
|
+
conversationId: string;
|
|
256
|
+
kind: string;
|
|
257
|
+
payload: unknown;
|
|
258
|
+
state: string;
|
|
259
|
+
answer: unknown;
|
|
260
|
+
createdAt: number;
|
|
261
|
+
updatedAt: number;
|
|
262
|
+
answeredAt: number | null;
|
|
263
|
+
}
|
|
264
|
+
export interface QuestionCreateInput {
|
|
265
|
+
id: string;
|
|
266
|
+
conversationId: string;
|
|
267
|
+
kind: string;
|
|
268
|
+
payload: unknown;
|
|
269
|
+
state: string;
|
|
270
|
+
createdAt: number;
|
|
271
|
+
}
|
|
272
|
+
export interface CredentialRow {
|
|
273
|
+
id: string;
|
|
274
|
+
note: string;
|
|
275
|
+
/** 凭证的 sha256 摘要;明文不进库(PRD L11) */
|
|
276
|
+
hash: string;
|
|
277
|
+
createdAt: number;
|
|
278
|
+
/** 吊销时间;null 表示仍然有效 */
|
|
279
|
+
revokedAt: number | null;
|
|
280
|
+
}
|
|
281
|
+
/** 对外展示用:不含 hash */
|
|
282
|
+
export interface CredentialInfo {
|
|
283
|
+
id: string;
|
|
284
|
+
note: string;
|
|
285
|
+
createdAt: number;
|
|
286
|
+
revokedAt: number | null;
|
|
287
|
+
}
|
|
288
|
+
export interface CredentialCreateInput {
|
|
289
|
+
id: string;
|
|
290
|
+
note: string;
|
|
291
|
+
hash: string;
|
|
292
|
+
createdAt: number;
|
|
293
|
+
}
|
|
294
|
+
export interface MetaRow {
|
|
295
|
+
id: number;
|
|
296
|
+
schemaVersion: number;
|
|
297
|
+
createdAt: number;
|
|
298
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 存储层的行类型与入参类型。
|
|
3
|
+
*
|
|
4
|
+
* 约定:
|
|
5
|
+
* - 列名与字段名都是 camelCase(SQLite 的列名并不强制风格,这里让「行类型 = 列名」,
|
|
6
|
+
* 读写两侧不用再维护一张映射表)。
|
|
7
|
+
* - 所有时间戳都是 `Date.now()` 的毫秒数,列类型 INTEGER(见各表注释)。
|
|
8
|
+
* - 带 `Row` 后缀的是**数据库原样行**(JSON 列还是字符串),不带后缀的是仓储解好的对象。
|
|
9
|
+
* - 消息正文直接用 core 的 `AgentNS.MessageContent`(R21 / R30):列里存的就是它的 JSON,
|
|
10
|
+
* 仓储反序列化后就是同一个形状,服务层与运行时不必在两种形状之间翻译。
|
|
11
|
+
* - `role` / `status` 仍以字符串存取(取值与 `AgentNS.Role` / `AgentNS.MessageStatus` 一致),
|
|
12
|
+
* 收敛成 core 的枚举发生在服务层。
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { type Language, type MessageKey } from "../i18n/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* 业务码与错误类。
|
|
4
|
+
*
|
|
5
|
+
* 分工(architecture §6):JSON-RPC 的 `error.code` 是数字(协议层),`error.data` 里才是
|
|
6
|
+
* 产品要用的三样东西 ——
|
|
7
|
+
* - `data.code`:**稳定业务码**,小写下划线,客户端据此分支(换文案不该改它);
|
|
8
|
+
* - `data.message`:已按连接语言渲染好的人话(PRD D8:宿主自己做多语言);
|
|
9
|
+
* - `data.detail` / `data.params`:结构化事实与渲染参数,让客户端不必解析句子去猜原因。
|
|
10
|
+
*
|
|
11
|
+
* 业务码本身只增不改语义:一个码的含义一旦发出去,客户端就可能已经按它写了分支。
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* 稳定业务码。命名小写下划线,客户端按它分支。
|
|
15
|
+
*
|
|
16
|
+
* 逐条对应的用户可见处境(文案见 `i18n/en.ts` 的 `error.*`):
|
|
17
|
+
*/
|
|
18
|
+
export type BizCode =
|
|
19
|
+
/** 凭证没被接受(含未 `hello` 就发别的请求) */
|
|
20
|
+
"unauthorized"
|
|
21
|
+
/** 参数形状 / 取值不对(含帧解析失败的字段级原因) */
|
|
22
|
+
| "invalid_params"
|
|
23
|
+
/** 目标对象不存在(对话、消息、问题、附件……) */
|
|
24
|
+
| "not_found"
|
|
25
|
+
/** 这段对话正在跑上一轮(PRD D14:忙就拒,不排队) */
|
|
26
|
+
| "busy"
|
|
27
|
+
/** 上传或请求体超限(PRD D5:图片 20MB/张) */
|
|
28
|
+
| "payload_too_large"
|
|
29
|
+
/** 协议里我们不用的那部分,或某个能力在本宿主不提供(PRD A4) */
|
|
30
|
+
| "unsupported"
|
|
31
|
+
/** 宿主内部错误,细节只在日志里 */
|
|
32
|
+
| "internal"
|
|
33
|
+
/** 配置读得出来但用不了(PRD F-A8:结构化原因,能当场修) */
|
|
34
|
+
| "config_invalid"
|
|
35
|
+
/** MCP 服务器连不上或没响应(PRD F-G1) */
|
|
36
|
+
| "mcp_unavailable"
|
|
37
|
+
/** 目标模型不具备所需能力,例如读不了历史里的图片(PRD D20 / F-B8) */
|
|
38
|
+
| "model_unsupported"
|
|
39
|
+
/** 用户选择了不交接(PRD F-D2 的三个选项之一 / F-D7 取消不等于失败) */
|
|
40
|
+
| "handoff_declined"
|
|
41
|
+
/** 还有问题挂着没答,且它在挡着这段对话(PRD D22 / D23 / F-D10) */
|
|
42
|
+
| "question_pending"
|
|
43
|
+
/** 上下文到了硬线,本轮不再发出请求(PRD F-D1 / D23) */
|
|
44
|
+
| "context_guard";
|
|
45
|
+
/** 全部业务码;用于校验与测试遍历 */
|
|
46
|
+
export declare const BIZ_CODES: readonly BizCode[];
|
|
47
|
+
/** 业务码对应的 JSON-RPC 数字码 */
|
|
48
|
+
export declare function jsonRpcCode(code: BizCode): number;
|
|
49
|
+
/** 业务码对应的默认文案键 */
|
|
50
|
+
export declare function defaultMessageKey(code: BizCode): MessageKey;
|
|
51
|
+
/** 运行时判断一个值是不是已知业务码 */
|
|
52
|
+
export declare function isBizCode(value: unknown): value is BizCode;
|
|
53
|
+
/**
|
|
54
|
+
* 错误帧里 `error.data` 的形状。
|
|
55
|
+
*
|
|
56
|
+
* 客户端读 `code` 分支、显示 `message`、按 `detail` 做「该往哪个输入框填什么」这类动作。
|
|
57
|
+
*/
|
|
58
|
+
export interface ErrorData {
|
|
59
|
+
/** 稳定业务码 */
|
|
60
|
+
code: BizCode;
|
|
61
|
+
/** 已按连接语言渲染的人话 */
|
|
62
|
+
message: string;
|
|
63
|
+
/** 结构化事实:哪个字段不对、还差什么(形状由各码约定,客户端不解析句子) */
|
|
64
|
+
detail?: unknown;
|
|
65
|
+
/** 渲染 `message` 用到的参数,客户端如需自己重排文案可直接用 */
|
|
66
|
+
params: Record<string, unknown>;
|
|
67
|
+
}
|
|
68
|
+
/** 构造 `HostError` 的可选项 */
|
|
69
|
+
export interface HostErrorOptions {
|
|
70
|
+
/** 文案键;缺省按 `code` 取(见 `defaultMessageKey`) */
|
|
71
|
+
messageKey?: MessageKey;
|
|
72
|
+
/** 渲染参数(`{name}` 形式占位) */
|
|
73
|
+
params?: Record<string, unknown>;
|
|
74
|
+
/** 结构化事实 */
|
|
75
|
+
detail?: unknown;
|
|
76
|
+
/** 原始错误,留给日志 */
|
|
77
|
+
cause?: unknown;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* 宿主抛给接线的错误:带业务码、文案键与渲染参数,出网时按连接语言渲染。
|
|
81
|
+
*
|
|
82
|
+
* 业务层只管用码与参数描述「哪里不对」,不拼句子、不碰语言 —— 语言是连接的事。
|
|
83
|
+
*/
|
|
84
|
+
export declare class HostError extends Error {
|
|
85
|
+
readonly code: BizCode;
|
|
86
|
+
readonly messageKey: MessageKey;
|
|
87
|
+
readonly params?: Record<string, unknown>;
|
|
88
|
+
readonly detail?: unknown;
|
|
89
|
+
constructor(code: BizCode, options?: HostErrorOptions);
|
|
90
|
+
/** 渲染成错误帧里的 `data`(PRD D8:按连接语言出人话) */
|
|
91
|
+
toErrorData(language?: Language): ErrorData;
|
|
92
|
+
/** 换一条更适合当前上下文的文案键(例如带上具体实体名),返回新实例 */
|
|
93
|
+
withMessage(messageKey: MessageKey, params?: Record<string, unknown>): HostError;
|
|
94
|
+
/** 追加结构化事实后返回新实例 */
|
|
95
|
+
withDetail(detail: unknown): HostError;
|
|
96
|
+
/** 判断任意值是不是 `HostError`(跨模块实例判断用不到 `instanceof` 的场合) */
|
|
97
|
+
static is(value: unknown): value is HostError;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 把任意抛出物收敛成 `ErrorData`。
|
|
101
|
+
*
|
|
102
|
+
* 接线层只会写一次 `catch`,其它错误(`TypeError`、SDK 抛的、字符串)都在这里被兜成
|
|
103
|
+
* `internal`,原始信息进 `detail.reason` 供排查 —— 于是界面上是一句人话,而不是一堆堆栈。
|
|
104
|
+
*/
|
|
105
|
+
export declare function toErrorData(error: unknown, language?: Language): ErrorData;
|