paseo-plugin-zcode-provider 0.2.0 → 0.4.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/NOTICE.md +3 -3
- package/README.md +15 -15
- package/client/runtime.tsx +1 -1
- package/package.json +7 -6
- package/server/account.ts +10 -0
- package/server/build-info.ts +1 -1
- package/server/discovery/manifest.ts +2 -2
- package/server/host/bridge.ts +2 -0
- package/server/mapping.ts +31 -0
- package/server/provider.ts +5 -18
- package/server/runtime/pins.ts +7 -5
- package/server/session.ts +9 -10
- package/server/unsupported-capabilities.ts +21 -0
- package/server/vendor/zcode/NOTICE.md +4 -1
- package/server/vendor/zcode/packages/rpc/src/channelClient.ts +1 -0
- package/server/vendor/zcode/packages/rpc/src/channelServer.ts +2 -0
- package/server/vendor/zcode/packages/rpc/src/channels.shared.ts +1 -0
- package/server/vendor/zcode/packages/rpc/src/protocol.ts +3 -2
- package/server/vendor/zcode/packages/shared/src/app-runtime-preferences.ts +18 -0
- package/server/vendor/zcode/packages/shared/src/attachment-source.ts +5 -0
- package/server/vendor/zcode/packages/shared/src/bots.ts +385 -2
- package/server/vendor/zcode/packages/shared/src/browser-use/commands.ts +3 -1
- package/server/vendor/zcode/packages/shared/src/channel-mention.ts +131 -0
- package/server/vendor/zcode/packages/shared/src/conversationSelection.ts +37 -0
- package/server/vendor/zcode/packages/shared/src/dynamic-workflow-feature.ts +137 -0
- package/server/vendor/zcode/packages/shared/src/env.ts +15 -11
- package/server/vendor/zcode/packages/shared/src/highspeed.ts +232 -0
- package/server/vendor/zcode/packages/shared/src/mcp-apps/appTools.ts +148 -0
- package/server/vendor/zcode/packages/shared/src/mcp-apps/contract.ts +262 -0
- package/server/vendor/zcode/packages/shared/src/mcp-apps/instance.ts +12 -0
- package/server/vendor/zcode/packages/shared/src/mcp-apps/resourceMime.ts +73 -0
- package/server/vendor/zcode/packages/shared/src/mcp-apps/sampling.ts +117 -0
- package/server/vendor/zcode/packages/shared/src/mcp-apps/schemas.ts +90 -0
- package/server/vendor/zcode/packages/shared/src/model-execution.ts +58 -1
- package/server/vendor/zcode/packages/shared/src/oauth.ts +3 -0
- package/server/vendor/zcode/packages/shared/src/off-peak-execution.ts +73 -0
- package/server/vendor/zcode/packages/shared/src/protocol.ts +78 -4
- package/server/vendor/zcode/packages/shared/src/remoteTarget.ts +65 -0
- package/server/vendor/zcode/packages/shared/src/request-security-edition/verification-policy.ts +46 -0
- package/server/vendor/zcode/packages/shared/src/server-remote.ts +93 -0
- package/server/vendor/zcode/packages/shared/src/source-server/compatibility.ts +115 -0
- package/server/vendor/zcode/packages/shared/src/source-server/contracts.ts +426 -0
- package/server/vendor/zcode/packages/shared/src/source-server/errorCodes.ts +74 -0
- package/server/vendor/zcode/packages/shared/src/sqlite-migrations/contract.ts +83 -0
- package/server/vendor/zcode/packages/shared/src/subagent-profile.ts +62 -0
- package/server/vendor/zcode/packages/shared/src/subagent-runtime-config.ts +51 -0
- package/server/vendor/zcode/packages/shared/src/subagents-types.ts +164 -0
- package/server/vendor/zcode/packages/shared/src/usage-stats.ts +14 -0
- package/server/vendor/zcode/packages/shared/src/validationAppSettings.ts +136 -3
- package/server/vendor/zcode/packages/shared/src/version.ts +13 -0
- package/server/vendor/zcode/packages/shared/src/zcode-agent-policy.ts +24 -1
- package/server/vendor/zcode/packages/shared/src/zcode-protocol/index.ts +697 -36
- package/server/vendor/zcode/packages/shared/src/zcode-protocol/trace.ts +11 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-legacy-types.ts +14 -2
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/apply.ts +28 -9
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/attachment-ref.ts +3 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/command.ts +73 -53
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/create-session-config.ts +15 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/create-workflow-display.ts +47 -1
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/delta.ts +58 -2
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/input-intent.ts +31 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/rows.ts +28 -13
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/sessions-index-workflow-activity.ts +37 -3
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/sessions-index.ts +36 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/snapshot.ts +21 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/submission.ts +1 -1
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/toolDisplay.ts +32 -4
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/transport.ts +31 -6
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-assembler.ts +4 -1
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/wire-fault.ts +4 -1
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-artifacts.ts +62 -4
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-command-rejections.ts +30 -0
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-row-meta.ts +40 -3
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-run-settings-command.ts +2 -2
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-runs-delta.ts +6 -5
- package/server/vendor/zcode/packages/shared/src/zcode-protocol-v4/workflow-runs.ts +103 -26
- package/server/vendor/zcode/packages/shared/src/zcode-task-mode-schema.ts +13 -1
- package/server/vendor/zcode/packages/shared/src/zcode-task-types-core.ts +31 -2
- package/server/vendor/zcode/packages/shared/src/zcodeEndpoint.ts +188 -73
- package/server/vendor/zcode/provenance.json +189 -80
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { zcodeProtocolTraceSchema, type ZCodeProtocolTrace } from "./zcode-protocol/trace.js";
|
|
2
|
+
import { channelContentPartsSchema, type ChannelContentPart } from "./channel-mention.js";
|
|
1
3
|
/* oxlint-disable eslint(max-lines) -- Bot 共享合约集中维护 provider、状态和 schema,保持类型与校验就近。 */
|
|
2
4
|
import { z } from "zod";
|
|
3
5
|
import { modelSelectionSchema, type ModelSelection } from "./model-selection.js";
|
|
6
|
+
import { conversationQuotesSchema } from "./conversationSelection.js";
|
|
4
7
|
import { ZCODE_AGENT_PROVIDER, ZCODE_AGENT_PROVIDER_LABEL } from "./zcode-agent-policy.js";
|
|
5
8
|
import type {
|
|
6
9
|
ZCodeConfigOption,
|
|
@@ -44,6 +47,8 @@ export const zcodeAutomationBotDeliveryTargetSchema = z
|
|
|
44
47
|
botId: z.string().trim().min(1),
|
|
45
48
|
providerUserId: z.string().trim().min(1),
|
|
46
49
|
chatType: z.enum(["private", "group"]),
|
|
50
|
+
threadId: z.string().min(1).optional(),
|
|
51
|
+
rootMessageId: z.string().min(1).optional(),
|
|
47
52
|
})
|
|
48
53
|
.strict();
|
|
49
54
|
|
|
@@ -76,6 +81,10 @@ export interface BotWorkspaceRef {
|
|
|
76
81
|
label: string;
|
|
77
82
|
workspacePath: string;
|
|
78
83
|
workspaceIdentity?: string;
|
|
84
|
+
/** 新版选择虚拟项目;旧协议字段名保留。空 roots 在提交时才分配 cwd。 */
|
|
85
|
+
projectId?: string;
|
|
86
|
+
hostId?: string;
|
|
87
|
+
rootPaths?: string[];
|
|
79
88
|
}
|
|
80
89
|
|
|
81
90
|
export interface BotAllowedCommands {
|
|
@@ -176,9 +185,14 @@ export interface BotsConfigFile {
|
|
|
176
185
|
|
|
177
186
|
export interface BotState {
|
|
178
187
|
botId: string;
|
|
188
|
+
group?: BotGroupSession;
|
|
179
189
|
workspacePath: string;
|
|
180
190
|
workspaceIdentity?: string;
|
|
181
191
|
workspaceId?: string;
|
|
192
|
+
/** hostId 缺席表示旧状态待交接;明确 NULL 项目不会再次按目录归入。 */
|
|
193
|
+
projectId?: string | null;
|
|
194
|
+
hostId?: string;
|
|
195
|
+
additionalDirectories?: string[];
|
|
182
196
|
mode: BotContextMode;
|
|
183
197
|
activeTaskId: string | null;
|
|
184
198
|
draftOptions?: BotDraftOptions;
|
|
@@ -187,11 +201,263 @@ export interface BotState {
|
|
|
187
201
|
telegramOffset?: number;
|
|
188
202
|
weixinGetUpdatesBuf?: string;
|
|
189
203
|
weixinActivatedAt?: number;
|
|
204
|
+
/** 单聊绑定代际,阻止换绑后迟到事件恢复旧关联。 */
|
|
205
|
+
privateBindingId?: string;
|
|
206
|
+
/** iLink 登录返回机器人身份,单聊接收人来自已授权入站消息。 */
|
|
207
|
+
privateRecipientId?: string;
|
|
190
208
|
updatedAt: number;
|
|
191
209
|
}
|
|
192
210
|
|
|
193
211
|
export type BotContextState = BotState;
|
|
194
212
|
|
|
213
|
+
export const botGroupDeliverySchema = z
|
|
214
|
+
.object({
|
|
215
|
+
/** 名字解析前的请求指纹;重复调用只读原回执,不因目录变化改发给其他人。 */
|
|
216
|
+
channelReplyRequestHash: z
|
|
217
|
+
.string()
|
|
218
|
+
.regex(/^[a-f0-9]{64}$/u)
|
|
219
|
+
.optional(),
|
|
220
|
+
appId: z.string().optional(),
|
|
221
|
+
trace: zcodeProtocolTraceSchema.optional(),
|
|
222
|
+
authorizationId: z.string().optional(),
|
|
223
|
+
id: z.string().min(1),
|
|
224
|
+
taskId: z.string().min(1),
|
|
225
|
+
sourceCommandId: z.string().min(1).optional(),
|
|
226
|
+
text: z.string(),
|
|
227
|
+
replyToMessageId: z.string().optional(),
|
|
228
|
+
mentionedUserIds: z.array(z.string().min(1)).max(200).optional(),
|
|
229
|
+
contentParts: channelContentPartsSchema.optional(),
|
|
230
|
+
providerMessageId: z.string().optional(),
|
|
231
|
+
threadId: z.string().min(1).optional(),
|
|
232
|
+
rootMessageId: z.string().optional(),
|
|
233
|
+
status: z.enum(["pending", "sent", "failed", "unknown", "invalidated"]),
|
|
234
|
+
lastError: z.string().optional(),
|
|
235
|
+
updatedAt: z.number(),
|
|
236
|
+
})
|
|
237
|
+
.strict();
|
|
238
|
+
export type BotGroupDelivery = z.infer<typeof botGroupDeliverySchema>;
|
|
239
|
+
|
|
240
|
+
export const botGroupCardSchema = z
|
|
241
|
+
.object({
|
|
242
|
+
chatId: z.string().min(1),
|
|
243
|
+
threadId: z.string().min(1).optional(),
|
|
244
|
+
conversationThreadId: z.string().min(1).nullable().optional(),
|
|
245
|
+
taskId: z.string().nullable(),
|
|
246
|
+
authorizationId: z.string().min(1),
|
|
247
|
+
})
|
|
248
|
+
.strict();
|
|
249
|
+
export type BotGroupCard = z.infer<typeof botGroupCardSchema>;
|
|
250
|
+
|
|
251
|
+
export const botTopicMessageSchema = z
|
|
252
|
+
.object({
|
|
253
|
+
id: z.string().min(1),
|
|
254
|
+
chatId: z.string().min(1),
|
|
255
|
+
threadId: z.string().min(1),
|
|
256
|
+
senderId: z.string(),
|
|
257
|
+
senderName: z.string().optional(),
|
|
258
|
+
parentId: z.string().optional(),
|
|
259
|
+
attachments: z.array(z.object({ name: z.string(), kind: z.string() }).strict()).optional(),
|
|
260
|
+
senderType: z.enum(["user", "app"]),
|
|
261
|
+
text: z.string(),
|
|
262
|
+
createdAt: z.number(),
|
|
263
|
+
kind: z.string(),
|
|
264
|
+
controlCard: z.boolean().optional(),
|
|
265
|
+
deleted: z.boolean().optional(),
|
|
266
|
+
})
|
|
267
|
+
.strict();
|
|
268
|
+
export type BotTopicMessage = z.infer<typeof botTopicMessageSchema>;
|
|
269
|
+
|
|
270
|
+
export interface BotTopicHistoryRequest {
|
|
271
|
+
chatId: string;
|
|
272
|
+
threadId: string;
|
|
273
|
+
rootMessageId: string;
|
|
274
|
+
messageId: string;
|
|
275
|
+
checkpoint?: string;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export const botTopicContextSchema = z
|
|
279
|
+
.object({
|
|
280
|
+
messages: z.array(botTopicMessageSchema).max(201),
|
|
281
|
+
checkpoint: z.string().min(1),
|
|
282
|
+
hasGap: z.boolean(),
|
|
283
|
+
})
|
|
284
|
+
.strict();
|
|
285
|
+
export type BotTopicHistoryBatch = z.infer<typeof botTopicContextSchema>;
|
|
286
|
+
|
|
287
|
+
export const botIdentitySchema = z
|
|
288
|
+
.object({ name: z.string().min(1), openId: z.string().min(1).optional() })
|
|
289
|
+
.strict();
|
|
290
|
+
export const botBackgroundHistorySchema = z
|
|
291
|
+
.object({ revision: z.string().min(1), checkpoint: z.string().min(1).optional() })
|
|
292
|
+
.strict();
|
|
293
|
+
|
|
294
|
+
export const botAutoReplyGuardSchema = z
|
|
295
|
+
.object({
|
|
296
|
+
consecutive: z.number().int().min(0).max(5),
|
|
297
|
+
messageIds: z.array(z.string().min(1)),
|
|
298
|
+
})
|
|
299
|
+
.strict();
|
|
300
|
+
|
|
301
|
+
export interface BotGroupSession {
|
|
302
|
+
preparation?: BotTopicPreparation[];
|
|
303
|
+
chatId: string;
|
|
304
|
+
chatMode?: "group" | "topic";
|
|
305
|
+
threadId?: string;
|
|
306
|
+
rootMessageId?: string;
|
|
307
|
+
topicTitle?: string;
|
|
308
|
+
topicUrl?: string;
|
|
309
|
+
/** 仅群默认记录拥有此配置;话题按群授权检查读取。 */
|
|
310
|
+
historyEnabled?: boolean;
|
|
311
|
+
/** 仅成功接收首次输入后接入;leave 后保留任务但停止普通消息触发。 */
|
|
312
|
+
topicActive?: boolean;
|
|
313
|
+
topicAliases?: Record<string, { taskId: string; rootMessageId: string }>;
|
|
314
|
+
name: string;
|
|
315
|
+
ownerId: string;
|
|
316
|
+
enabled: boolean;
|
|
317
|
+
taskIds: string[];
|
|
318
|
+
taskWorkspaces?: Record<string, { workspacePath: string; workspaceIdentity?: string }>;
|
|
319
|
+
currentOptions: BotCurrentOptions;
|
|
320
|
+
initiatorId?: string;
|
|
321
|
+
authorizationId?: string;
|
|
322
|
+
deliveries?: Record<string, BotGroupDelivery>;
|
|
323
|
+
autoReplyGuard?: z.infer<typeof botAutoReplyGuardSchema>;
|
|
324
|
+
backgroundHistory?: z.infer<typeof botBackgroundHistorySchema>;
|
|
325
|
+
inputs?: Record<
|
|
326
|
+
string,
|
|
327
|
+
{
|
|
328
|
+
taskId: string;
|
|
329
|
+
source: BotGroupInputSource;
|
|
330
|
+
admission?: "pending" | "accepted" | "rejected";
|
|
331
|
+
progress?: BotGroupInputProgress;
|
|
332
|
+
}
|
|
333
|
+
>;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export const botGroupInputStatusSchema = z.enum([
|
|
337
|
+
"waiting",
|
|
338
|
+
"working",
|
|
339
|
+
"done",
|
|
340
|
+
"failed",
|
|
341
|
+
"stopped",
|
|
342
|
+
"cancelled",
|
|
343
|
+
"discarded",
|
|
344
|
+
]);
|
|
345
|
+
export type BotGroupInputStatus = z.infer<typeof botGroupInputStatusSchema>;
|
|
346
|
+
export const botTopicPreparationSchema = z
|
|
347
|
+
.object({
|
|
348
|
+
contentParts: channelContentPartsSchema.optional(),
|
|
349
|
+
messageId: z.string().min(1),
|
|
350
|
+
senderName: z.string(),
|
|
351
|
+
text: z.string(),
|
|
352
|
+
status: z.enum(["preparing", "waitingStop", "failed"]),
|
|
353
|
+
error: z.string().optional(),
|
|
354
|
+
})
|
|
355
|
+
.strict();
|
|
356
|
+
export type BotTopicPreparation = z.infer<typeof botTopicPreparationSchema>;
|
|
357
|
+
export const botGroupInputProgressSchema = z
|
|
358
|
+
.object({
|
|
359
|
+
status: botGroupInputStatusSchema,
|
|
360
|
+
interruptionReason: z.literal("newMessage").optional(),
|
|
361
|
+
cardMessageId: z.string().min(1).optional(),
|
|
362
|
+
cardStatus: botGroupInputStatusSchema.optional(),
|
|
363
|
+
})
|
|
364
|
+
.strict();
|
|
365
|
+
export type BotGroupInputProgress = z.infer<typeof botGroupInputProgressSchema>;
|
|
366
|
+
|
|
367
|
+
/** CLI 只接收轻量材料索引;原文留在 Host 归档及文本附件。 */
|
|
368
|
+
export const botTopicHistorySourceSchema = z
|
|
369
|
+
.object({
|
|
370
|
+
checkpoint: z.string().min(1).max(256),
|
|
371
|
+
hasGap: z.boolean(),
|
|
372
|
+
messageCount: z.number().int().min(0).max(201),
|
|
373
|
+
resourceMessages: z
|
|
374
|
+
.array(
|
|
375
|
+
z
|
|
376
|
+
.object({
|
|
377
|
+
messageId: z.string().min(1).max(256),
|
|
378
|
+
count: z.number().int().min(1).max(1000),
|
|
379
|
+
})
|
|
380
|
+
.strict(),
|
|
381
|
+
)
|
|
382
|
+
.max(201),
|
|
383
|
+
})
|
|
384
|
+
.strict();
|
|
385
|
+
|
|
386
|
+
export const botTopicInputMessageSchema = z
|
|
387
|
+
.object({
|
|
388
|
+
contentParts: channelContentPartsSchema.optional(),
|
|
389
|
+
messageId: z.string().min(1),
|
|
390
|
+
senderId: z.string().min(1),
|
|
391
|
+
senderName: z.string(),
|
|
392
|
+
mentionedBot: z.boolean().optional(),
|
|
393
|
+
text: z.string(),
|
|
394
|
+
conversationQuotes: conversationQuotesSchema.optional(),
|
|
395
|
+
attachmentIndexes: z.array(z.number().int().nonnegative()),
|
|
396
|
+
})
|
|
397
|
+
.strict();
|
|
398
|
+
|
|
399
|
+
/** 可信 Host 注入的输入来源;身份展示不能反向授予执行权限。 */
|
|
400
|
+
export const botGroupInputSourceSchema = z
|
|
401
|
+
.object({
|
|
402
|
+
botIdentity: botIdentitySchema.optional(),
|
|
403
|
+
appId: z.string().min(1).optional(),
|
|
404
|
+
contentParts: channelContentPartsSchema.optional(),
|
|
405
|
+
authorizationId: z.string().min(1).optional(),
|
|
406
|
+
botId: z.string().min(1),
|
|
407
|
+
provider: z.enum(["feishu", "lark"]),
|
|
408
|
+
chatId: z.string().min(1),
|
|
409
|
+
threadId: z.string().min(1).optional(),
|
|
410
|
+
rootMessageId: z.string().optional(),
|
|
411
|
+
senderId: z.string().min(1),
|
|
412
|
+
senderName: z.string(),
|
|
413
|
+
mentionedBot: z.boolean().optional(),
|
|
414
|
+
messageId: z.string().min(1),
|
|
415
|
+
messages: z.array(botTopicInputMessageSchema).min(1).max(200).optional(),
|
|
416
|
+
topicContext: botTopicContextSchema.optional(),
|
|
417
|
+
topicHistory: botTopicHistorySourceSchema.optional(),
|
|
418
|
+
})
|
|
419
|
+
.strict()
|
|
420
|
+
.superRefine((source, ctx) => {
|
|
421
|
+
if (
|
|
422
|
+
source.messages &&
|
|
423
|
+
(!source.threadId ||
|
|
424
|
+
source.messages.at(-1)?.messageId !== source.messageId ||
|
|
425
|
+
new Set(source.messages.map((message) => message.messageId)).size !==
|
|
426
|
+
source.messages.length)
|
|
427
|
+
) {
|
|
428
|
+
ctx.addIssue({
|
|
429
|
+
code: "custom",
|
|
430
|
+
path: ["messages"],
|
|
431
|
+
message: "Topic batch boundary mismatch",
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
if (
|
|
436
|
+
source.topicHistory &&
|
|
437
|
+
(!source.threadId || source.topicHistory.checkpoint !== source.messageId)
|
|
438
|
+
) {
|
|
439
|
+
ctx.addIssue({
|
|
440
|
+
code: "custom",
|
|
441
|
+
path: ["topicHistory"],
|
|
442
|
+
message: "Topic history scope mismatch",
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
if (
|
|
446
|
+
source.topicContext &&
|
|
447
|
+
(!source.threadId ||
|
|
448
|
+
source.topicContext.checkpoint !== source.messageId ||
|
|
449
|
+
source.topicContext.messages.some(
|
|
450
|
+
(m) => m.chatId !== source.chatId || m.threadId !== source.threadId,
|
|
451
|
+
))
|
|
452
|
+
)
|
|
453
|
+
ctx.addIssue({
|
|
454
|
+
code: "custom",
|
|
455
|
+
path: ["topicContext"],
|
|
456
|
+
message: "Topic context scope mismatch",
|
|
457
|
+
});
|
|
458
|
+
});
|
|
459
|
+
export type BotGroupInputSource = z.infer<typeof botGroupInputSourceSchema>;
|
|
460
|
+
|
|
195
461
|
export interface BotsStateFile {
|
|
196
462
|
version: 3;
|
|
197
463
|
bots: Record<string, BotState>;
|
|
@@ -200,6 +466,8 @@ export interface BotsStateFile {
|
|
|
200
466
|
export interface BotRuntimeInfo {
|
|
201
467
|
/** 最近一次消息投递错误;独立于长连接状态,成功投递后清除。 */
|
|
202
468
|
deliveryError?: string;
|
|
469
|
+
/** 当前进程保留的失败单聊回复;显式重试可能重复此前已收到的内容。 */
|
|
470
|
+
deliveryRetryId?: string;
|
|
203
471
|
botId: string;
|
|
204
472
|
provider: BotProvider;
|
|
205
473
|
status: "disabled" | "idle" | "polling" | "connected" | "error";
|
|
@@ -210,12 +478,20 @@ export interface BotRuntimeInfo {
|
|
|
210
478
|
}
|
|
211
479
|
|
|
212
480
|
export interface BotActor {
|
|
481
|
+
/** 本次可信输入是否明确提及机器人;用于话题回复提醒。 */
|
|
482
|
+
mentionedBot?: boolean;
|
|
213
483
|
provider: BotProvider;
|
|
214
484
|
botId: string;
|
|
215
485
|
providerUserId: string;
|
|
216
486
|
displayName?: string;
|
|
217
487
|
chatType: "private" | "group";
|
|
218
488
|
chatId?: string;
|
|
489
|
+
threadId?: string;
|
|
490
|
+
/** 仅服务根据已保存的结果关联设置;null 表示原群默认任务。 */
|
|
491
|
+
conversationThreadId?: string | null;
|
|
492
|
+
rootMessageId?: string;
|
|
493
|
+
topicTitle?: string;
|
|
494
|
+
topicUrl?: string;
|
|
219
495
|
providerMessageId?: string;
|
|
220
496
|
providerContextToken?: string;
|
|
221
497
|
}
|
|
@@ -236,6 +512,10 @@ export interface BotInboundAttachment {
|
|
|
236
512
|
}
|
|
237
513
|
|
|
238
514
|
export type BotCommand =
|
|
515
|
+
| { type: "group.history"; enabled?: boolean }
|
|
516
|
+
| { type: "queue.cancel"; commandId: string }
|
|
517
|
+
| { type: "group.enable" }
|
|
518
|
+
| { type: "group.disable" }
|
|
239
519
|
| { type: "bind"; code: string }
|
|
240
520
|
| { type: "help" }
|
|
241
521
|
| { type: "status" }
|
|
@@ -255,6 +535,7 @@ export type BotCommand =
|
|
|
255
535
|
| { type: "reply.list" }
|
|
256
536
|
| { type: "reply.set"; value: string }
|
|
257
537
|
| { type: "stop" }
|
|
538
|
+
| { type: "topic.leave" }
|
|
258
539
|
| { type: "permission.respond"; value: string }
|
|
259
540
|
| { type: "elicitation.respond"; value: string }
|
|
260
541
|
| { type: "elicitation.submit" }
|
|
@@ -272,6 +553,7 @@ export interface SelectionPrompt {
|
|
|
272
553
|
cancelLabel?: string;
|
|
273
554
|
showCancel?: boolean;
|
|
274
555
|
action:
|
|
556
|
+
| "queue.cancel"
|
|
275
557
|
| "workspace.set"
|
|
276
558
|
| "model.provider.set"
|
|
277
559
|
| "model.set"
|
|
@@ -289,6 +571,23 @@ export interface SelectionPrompt {
|
|
|
289
571
|
}
|
|
290
572
|
|
|
291
573
|
export interface BotInboundMessage {
|
|
574
|
+
/** 仅供命令/纯唤醒识别;原文 text 和 contentParts 保持完整。 */
|
|
575
|
+
commandText?: string;
|
|
576
|
+
/** Provider 核验的当前机器人身份,不从正文推断。 */
|
|
577
|
+
botOpenId?: string;
|
|
578
|
+
/** Provider 校验的发送者类型;机器人正文不具有控制命令权限。 */
|
|
579
|
+
senderType?: "user" | "app";
|
|
580
|
+
contentParts?: ChannelContentPart[];
|
|
581
|
+
/** 由 Provider 根据真实 mention 身份设置;不是正文解析结果。 */
|
|
582
|
+
mentionedBot?: boolean;
|
|
583
|
+
/** 原生根消息经 Provider 核验确为当前机器人发送。 */
|
|
584
|
+
topicRootIsCurrentBot?: boolean;
|
|
585
|
+
/** 可信 Provider 校验后的明确引用,不参与控制命令解析。 */
|
|
586
|
+
referencedMessage?: import("./conversationSelection.js").ConversationSelectionText & {
|
|
587
|
+
messageId: string;
|
|
588
|
+
};
|
|
589
|
+
groupCard?: BotGroupCard;
|
|
590
|
+
groupCardAction?: boolean;
|
|
292
591
|
botId: string;
|
|
293
592
|
actor: BotActor;
|
|
294
593
|
text: string;
|
|
@@ -298,6 +597,12 @@ export interface BotInboundMessage {
|
|
|
298
597
|
}
|
|
299
598
|
|
|
300
599
|
export interface BotOutboundMessage {
|
|
600
|
+
trace?: ZCodeProtocolTrace;
|
|
601
|
+
contentParts?: ChannelContentPart[];
|
|
602
|
+
groupCard?: BotGroupCard;
|
|
603
|
+
threadId?: string;
|
|
604
|
+
conversationThreadId?: string | null;
|
|
605
|
+
rootMessageId?: string;
|
|
301
606
|
botId: string;
|
|
302
607
|
provider: BotProvider;
|
|
303
608
|
providerUserId: string;
|
|
@@ -306,6 +611,18 @@ export interface BotOutboundMessage {
|
|
|
306
611
|
selection?: SelectionPrompt;
|
|
307
612
|
elicitation?: BotOutboundElicitationRequest;
|
|
308
613
|
providerContextToken?: string;
|
|
614
|
+
/** 无权限/过期回调只能提示操作者,不能覆盖群共享卡片。 */
|
|
615
|
+
callbackToastOnly?: boolean;
|
|
616
|
+
/** 管理员待办独立通知,不允许用拒绝提示覆盖共享卡片。 */
|
|
617
|
+
administratorAttention?: boolean;
|
|
618
|
+
replyToMessageId?: string;
|
|
619
|
+
/** 可信输入决定的提醒对象;只作展示,不授予群操作权限。 */
|
|
620
|
+
mentionedUserIds?: string[];
|
|
621
|
+
deliveryId?: string;
|
|
622
|
+
/** 任务回推需在实际发送前重新验证群当前关联。控制命令回复不携带。 */
|
|
623
|
+
groupTaskId?: string;
|
|
624
|
+
/** 可信任务事件中的输入命令,用于将投递状态定位到对应回复。 */
|
|
625
|
+
groupSourceCommandId?: string;
|
|
309
626
|
}
|
|
310
627
|
|
|
311
628
|
export interface BotTaskSummary {
|
|
@@ -395,6 +712,13 @@ export const botAllowedCommandsSchema = z
|
|
|
395
712
|
|
|
396
713
|
export const botCommandPolicySchema = botAllowedCommandsSchema;
|
|
397
714
|
|
|
715
|
+
// 修复原因:第三方 CLI provider 已移除,ZCodeProvider 只剩 glm,但旧 bot 配置与状态文件里可能仍存有
|
|
716
|
+
// 已移除 provider 的历史值。改成严格 literal 会让整份文件 parse 失败、Bot 全部不可用;
|
|
717
|
+
// 因此解析时继续接受这些历史值,并统一归一到当前唯一的 agent provider。
|
|
718
|
+
const legacyBotAgentProviderSchema = z
|
|
719
|
+
.enum(["codex", "claude", "opencode", "gemini", "glm"])
|
|
720
|
+
.transform((): typeof ZCODE_AGENT_PROVIDER => ZCODE_AGENT_PROVIDER);
|
|
721
|
+
|
|
398
722
|
export const botCurrentOptionsSchema = z
|
|
399
723
|
.object({
|
|
400
724
|
modelSelection: modelSelectionSchema.optional(),
|
|
@@ -402,13 +726,13 @@ export const botCurrentOptionsSchema = z
|
|
|
402
726
|
sandboxMode: z.string().min(1).optional(),
|
|
403
727
|
approvalPolicy: z.string().min(1).optional(),
|
|
404
728
|
// 兼容旧 bot-config.json;CLI provider 现在统一由 ZCode Protocol 侧配置决定。
|
|
405
|
-
cli:
|
|
729
|
+
cli: legacyBotAgentProviderSchema.optional(),
|
|
406
730
|
})
|
|
407
731
|
.strict();
|
|
408
732
|
|
|
409
733
|
export const botDraftOptionsSchema = z
|
|
410
734
|
.object({
|
|
411
|
-
provider:
|
|
735
|
+
provider: legacyBotAgentProviderSchema,
|
|
412
736
|
modelSelection: modelSelectionSchema.optional(),
|
|
413
737
|
mode: z.string().min(1).optional(),
|
|
414
738
|
})
|
|
@@ -492,9 +816,66 @@ export const botsStateFileSchema = z
|
|
|
492
816
|
z.string(),
|
|
493
817
|
z.object({
|
|
494
818
|
botId: z.string().min(1),
|
|
819
|
+
group: z
|
|
820
|
+
.object({
|
|
821
|
+
chatId: z.string().trim().min(1),
|
|
822
|
+
chatMode: z.enum(["group", "topic"]).optional(),
|
|
823
|
+
threadId: z.string().trim().min(1).optional(),
|
|
824
|
+
rootMessageId: z.string().min(1).optional(),
|
|
825
|
+
topicTitle: z.string().optional(),
|
|
826
|
+
topicUrl: z.string().url().optional(),
|
|
827
|
+
historyEnabled: z.boolean().optional(),
|
|
828
|
+
topicActive: z.boolean().optional(),
|
|
829
|
+
preparation: z.array(botTopicPreparationSchema).optional(),
|
|
830
|
+
topicAliases: z
|
|
831
|
+
.record(
|
|
832
|
+
z.string(),
|
|
833
|
+
z.object({ taskId: z.string().min(1), rootMessageId: z.string().min(1) }).strict(),
|
|
834
|
+
)
|
|
835
|
+
.optional(),
|
|
836
|
+
name: z.string(),
|
|
837
|
+
ownerId: z.string().min(1),
|
|
838
|
+
enabled: z.boolean(),
|
|
839
|
+
taskIds: z.array(z.string().min(1)),
|
|
840
|
+
taskWorkspaces: z
|
|
841
|
+
.record(
|
|
842
|
+
z.string(),
|
|
843
|
+
z
|
|
844
|
+
.object({
|
|
845
|
+
workspacePath: z.string().min(1),
|
|
846
|
+
workspaceIdentity: z.string().optional(),
|
|
847
|
+
})
|
|
848
|
+
.strict(),
|
|
849
|
+
)
|
|
850
|
+
.optional(),
|
|
851
|
+
currentOptions: botCurrentOptionsSchema,
|
|
852
|
+
initiatorId: z.string().optional(),
|
|
853
|
+
authorizationId: z.string().optional(),
|
|
854
|
+
deliveries: z.record(z.string(), botGroupDeliverySchema).optional(),
|
|
855
|
+
autoReplyGuard: botAutoReplyGuardSchema.optional(),
|
|
856
|
+
backgroundHistory: botBackgroundHistorySchema.optional(),
|
|
857
|
+
inputs: z
|
|
858
|
+
.record(
|
|
859
|
+
z.string(),
|
|
860
|
+
z
|
|
861
|
+
.object({
|
|
862
|
+
taskId: z.string().min(1),
|
|
863
|
+
source: botGroupInputSourceSchema,
|
|
864
|
+
admission: z.enum(["pending", "accepted", "rejected"]).optional(),
|
|
865
|
+
progress: botGroupInputProgressSchema.optional(),
|
|
866
|
+
})
|
|
867
|
+
.strict(),
|
|
868
|
+
)
|
|
869
|
+
.optional(),
|
|
870
|
+
})
|
|
871
|
+
.strict()
|
|
872
|
+
.optional(),
|
|
495
873
|
workspacePath: z.string().min(1),
|
|
496
874
|
workspaceIdentity: z.string().min(1).optional(),
|
|
497
875
|
workspaceId: z.string().min(1).optional(),
|
|
876
|
+
projectId: z.string().min(1).nullable().optional(),
|
|
877
|
+
hostId: z.string().min(1).optional(),
|
|
878
|
+
additionalDirectories: z.array(z.string().min(1)).max(256).optional(),
|
|
498
879
|
mode: z.enum(["draft", "task"]),
|
|
499
880
|
activeTaskId: z.string().min(1).nullable(),
|
|
500
881
|
draftOptions: botDraftOptionsSchema.optional(),
|
|
@@ -514,6 +895,8 @@ export const botsStateFileSchema = z
|
|
|
514
895
|
telegramOffset: z.number().optional(),
|
|
515
896
|
weixinGetUpdatesBuf: z.string().optional(),
|
|
516
897
|
weixinActivatedAt: z.number().optional(),
|
|
898
|
+
privateBindingId: z.string().min(1).optional(),
|
|
899
|
+
privateRecipientId: z.string().min(1).optional(),
|
|
517
900
|
updatedAt: z.number(),
|
|
518
901
|
}),
|
|
519
902
|
),
|
|
@@ -578,7 +578,9 @@ export const browserCommandSchema = z.discriminatedUnion("method", [
|
|
|
578
578
|
})
|
|
579
579
|
.strict(),
|
|
580
580
|
z.object({ method: z.literal("turnEnded"), turnId: z.string().min(1).optional() }).strict(),
|
|
581
|
-
|
|
581
|
+
// closeTabs:连同该 session 名下的 tab 一起关(含已释放回该 session 的)。只给永不回来认领的
|
|
582
|
+
// session 用——dwf 子代理(docs/browser-use/2026-07-14-browser-tab-conversation-isolation-spec.md §2.3)。
|
|
583
|
+
z.object({ method: z.literal("closeSession"), closeTabs: z.boolean().optional() }).strict(),
|
|
582
584
|
z.object({ method: z.literal("cancelRequest"), requestId: z.string().min(1) }).strict(),
|
|
583
585
|
// close:关闭指定受控 tab(tabId 缺省=当前 tab)。manager 层处理:detach + 通知 renderer 卸载 webview。
|
|
584
586
|
z.object({ method: z.literal("close"), tabId: z.string().optional() }).strict(),
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { zcodeProtocolTraceSchema } from "./zcode-protocol/trace.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export const channelMentionSchema = z
|
|
5
|
+
.object({
|
|
6
|
+
type: z.literal("channelMention"),
|
|
7
|
+
refId: z.string().min(1).max(200),
|
|
8
|
+
name: z.string().min(1).max(200),
|
|
9
|
+
channel: z.enum(["feishu", "lark"]),
|
|
10
|
+
targetId: z
|
|
11
|
+
.string()
|
|
12
|
+
.max(128)
|
|
13
|
+
.regex(/^ou_[a-zA-Z0-9_-]+$/u),
|
|
14
|
+
idType: z.literal("open_id"),
|
|
15
|
+
entityType: z.enum(["user", "bot", "unknown"]),
|
|
16
|
+
})
|
|
17
|
+
.strict();
|
|
18
|
+
export const channelContentPartSchema = z.union([
|
|
19
|
+
z.object({ type: z.literal("text"), text: z.string().max(100_000) }).strict(),
|
|
20
|
+
channelMentionSchema,
|
|
21
|
+
]);
|
|
22
|
+
export const channelContentPartsSchema = z.array(channelContentPartSchema).max(200);
|
|
23
|
+
export type ChannelContentPart = z.infer<typeof channelContentPartSchema>;
|
|
24
|
+
export const channelReplyPartsSchema = z
|
|
25
|
+
.array(
|
|
26
|
+
z.union([
|
|
27
|
+
z.object({ type: z.literal("text"), text: z.string().max(2000) }).strict(),
|
|
28
|
+
z.object({ type: z.literal("mention"), refId: z.string().min(1).max(200) }).strict(),
|
|
29
|
+
z
|
|
30
|
+
.object({
|
|
31
|
+
type: z.literal("mentionName"),
|
|
32
|
+
name: z.string().trim().min(1).max(200),
|
|
33
|
+
candidateRef: z.string().min(1).max(200).optional(),
|
|
34
|
+
})
|
|
35
|
+
.strict(),
|
|
36
|
+
]),
|
|
37
|
+
)
|
|
38
|
+
.min(1)
|
|
39
|
+
.max(50);
|
|
40
|
+
export const channelReplyRequestSchema = z
|
|
41
|
+
.object({
|
|
42
|
+
taskId: z.string().min(1),
|
|
43
|
+
inputId: z.string().min(1),
|
|
44
|
+
authorizationId: z.string().min(1).optional(),
|
|
45
|
+
toolCallId: z.string().min(1),
|
|
46
|
+
parts: channelReplyPartsSchema,
|
|
47
|
+
})
|
|
48
|
+
.strict();
|
|
49
|
+
const channelDeliveryResultSchema = z
|
|
50
|
+
.object({
|
|
51
|
+
status: z.enum(["sent", "failed", "unknown", "invalidated"]),
|
|
52
|
+
deliveryId: z.string(),
|
|
53
|
+
providerMessageId: z.string().optional(),
|
|
54
|
+
error: z.string().optional(),
|
|
55
|
+
})
|
|
56
|
+
.strict();
|
|
57
|
+
export const channelMentionClarificationSchema = z
|
|
58
|
+
.object({
|
|
59
|
+
status: z.literal("needs_clarification"),
|
|
60
|
+
unresolved: z
|
|
61
|
+
.array(
|
|
62
|
+
z
|
|
63
|
+
.object({
|
|
64
|
+
name: z.string().max(200),
|
|
65
|
+
reason: z.enum(["ambiguous", "not_found", "unavailable", "selection_expired"]),
|
|
66
|
+
candidates: z
|
|
67
|
+
.array(
|
|
68
|
+
z
|
|
69
|
+
.object({
|
|
70
|
+
ref: z.string().max(200),
|
|
71
|
+
name: z.string().max(200),
|
|
72
|
+
label: z.string().max(250),
|
|
73
|
+
kind: z.enum(["user", "bot", "unknown"]),
|
|
74
|
+
})
|
|
75
|
+
.strict(),
|
|
76
|
+
)
|
|
77
|
+
.max(10),
|
|
78
|
+
truncated: z.boolean(),
|
|
79
|
+
})
|
|
80
|
+
.strict(),
|
|
81
|
+
)
|
|
82
|
+
.min(1)
|
|
83
|
+
.max(50),
|
|
84
|
+
})
|
|
85
|
+
.strict();
|
|
86
|
+
export const channelReplyResultSchema = z.union([
|
|
87
|
+
channelDeliveryResultSchema,
|
|
88
|
+
channelMentionClarificationSchema,
|
|
89
|
+
]);
|
|
90
|
+
export type ChannelReplyRequest = z.infer<typeof channelReplyRequestSchema>;
|
|
91
|
+
export type ChannelReplyResult = z.infer<typeof channelReplyResultSchema>;
|
|
92
|
+
export function channelContentText(parts: readonly ChannelContentPart[]): string {
|
|
93
|
+
return parts.map((part) => (part.type === "text" ? part.text : `@${part.name}`)).join("");
|
|
94
|
+
}
|
|
95
|
+
/** 只从 Host 已验证的会话输入解析 ref;模型不得直接提供平台 ID。 */
|
|
96
|
+
export function resolveChannelReplyParts(
|
|
97
|
+
parts: z.infer<typeof channelReplyPartsSchema>,
|
|
98
|
+
source: readonly ChannelContentPart[],
|
|
99
|
+
): ChannelContentPart[] {
|
|
100
|
+
const targets = new Map<string, z.infer<typeof channelMentionSchema>>();
|
|
101
|
+
for (const part of source) {
|
|
102
|
+
if (part.type !== "channelMention") continue;
|
|
103
|
+
const target = channelMentionSchema.parse(part);
|
|
104
|
+
const previous = targets.get(target.refId);
|
|
105
|
+
if (previous && JSON.stringify(previous) !== JSON.stringify(target))
|
|
106
|
+
throw new Error("Conflicting channel mention reference");
|
|
107
|
+
targets.set(target.refId, target);
|
|
108
|
+
}
|
|
109
|
+
channelReplyPartsSchema.parse(parts);
|
|
110
|
+
const resolved = parts.map((part) => {
|
|
111
|
+
if (part.type === "text") return part;
|
|
112
|
+
if (part.type === "mentionName")
|
|
113
|
+
throw new Error("Channel mention name must be resolved by Host");
|
|
114
|
+
const target = targets.get(part.refId);
|
|
115
|
+
if (!target) throw new Error("Unknown channel mention reference");
|
|
116
|
+
return target;
|
|
117
|
+
});
|
|
118
|
+
if (!channelContentText(resolved).trim() || channelContentText(resolved).length > 2000)
|
|
119
|
+
throw new Error("Channel reply must contain 1–2000 characters");
|
|
120
|
+
return resolved;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export const channelReplyHostRequestSchema = channelReplyRequestSchema
|
|
124
|
+
.extend({
|
|
125
|
+
trace: zcodeProtocolTraceSchema.optional(),
|
|
126
|
+
workspacePath: z.string().min(1),
|
|
127
|
+
workspaceIdentity: z.string().optional(),
|
|
128
|
+
remoteSessionId: z.string().optional(),
|
|
129
|
+
})
|
|
130
|
+
.strict();
|
|
131
|
+
export type ChannelReplyHostRequest = z.infer<typeof channelReplyHostRequestSchema>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const CONVERSATION_SELECTION_MAX_TEXT_LENGTH = 8_000;
|
|
3
|
+
export const CONVERSATION_SELECTION_MAX_COUNT = 8;
|
|
4
|
+
export const CONVERSATION_SELECTION_MAX_TOTAL_LENGTH = 16_000;
|
|
5
|
+
|
|
6
|
+
export const conversationQuoteSchema = z.object({
|
|
7
|
+
text: z.string().max(CONVERSATION_SELECTION_MAX_TEXT_LENGTH),
|
|
8
|
+
path: z.string().optional(),
|
|
9
|
+
senderName: z.string().optional(),
|
|
10
|
+
senderId: z.string().optional(),
|
|
11
|
+
messageId: z.string().optional(),
|
|
12
|
+
sentAt: z.string().datetime({ offset: true }).optional(),
|
|
13
|
+
});
|
|
14
|
+
export const conversationQuotesSchema = z
|
|
15
|
+
.array(conversationQuoteSchema)
|
|
16
|
+
.max(CONVERSATION_SELECTION_MAX_COUNT)
|
|
17
|
+
.refine(
|
|
18
|
+
(quotes) =>
|
|
19
|
+
quotes.reduce((sum, quote) => sum + quote.text.length, 0) <=
|
|
20
|
+
CONVERSATION_SELECTION_MAX_TOTAL_LENGTH,
|
|
21
|
+
);
|
|
22
|
+
export type ConversationSelectionText = z.infer<typeof conversationQuoteSchema>;
|
|
23
|
+
|
|
24
|
+
export function buildPromptWithConversationSelections(
|
|
25
|
+
visibleContent: string,
|
|
26
|
+
references: readonly ConversationSelectionText[],
|
|
27
|
+
): string {
|
|
28
|
+
if (references.length === 0) return visibleContent;
|
|
29
|
+
// 文件选段曾只发正文,导致模型与历史丢失文件来源;只保留路径,不发送内部身份字段。
|
|
30
|
+
const block = [
|
|
31
|
+
"# userselect:",
|
|
32
|
+
"```userselect",
|
|
33
|
+
JSON.stringify(references.map(({ text, path }) => (path?.trim() ? { path, text } : { text }))),
|
|
34
|
+
"```",
|
|
35
|
+
].join("\n");
|
|
36
|
+
return visibleContent ? `${visibleContent}\n\n${block}` : block;
|
|
37
|
+
}
|