@clawos-dev/clawd 0.2.739 → 0.2.741
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/dist/{dispatch → a2a}/mcp-server.cjs +328 -1033
- package/dist/app-builder-plugin/mcp-server.cjs +176 -108
- package/dist/cli.cjs +2200 -2128
- package/dist/cloud-persona-conversations.html +74 -74
- package/dist/cloud-persona-metrics.html +1 -1
- package/dist/cloud-persona-schedules.html +1 -1
- package/dist/owner-ui/assets/{owner-DqXBCm9I.js → owner-B7g_TtlC.js} +220 -220
- package/dist/owner-ui/assets/owner-DkZN0eik.css +32 -0
- package/dist/owner-ui/owner.html +2 -2
- package/dist/persona-defaults/persona-app-builder/CLAUDE.md +2 -2
- package/dist/persona-defaults/persona-app-builder/mcp/clawd-app-builder/mcp-server.cjs +176 -108
- package/dist/persona-defaults/persona-clawd-butler/.claude/skills/clawd-orchestration/SKILL.md +3 -3
- package/dist/persona-defaults/persona-clawd-butler/.claude/skills/clawd-product/SKILL.md +48 -5
- package/dist/persona-defaults/persona-dataclaw-builder/mcp/clawd-app-builder/mcp-server.cjs +176 -108
- package/dist/persona-defaults/persona-master/CLAUDE.md +16 -17
- package/dist/pi-mcp-bridge/extension.cjs +6 -1
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/{guest-Cbaz1yVH.js → guest-DZypnAPv.js} +143 -143
- package/dist/share-ui/assets/guest-DagqEvdb.css +32 -0
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
- package/dist/owner-ui/assets/owner-z9zJkPHQ.css +0 -32
- package/dist/share-ui/assets/guest-DAdPVo1T.css +0 -32
|
@@ -32182,98 +32182,110 @@ var ContactPinnedFrameSchema = external_exports.object({
|
|
|
32182
32182
|
pinnedAt: external_exports.number().int().nullable()
|
|
32183
32183
|
}).strict();
|
|
32184
32184
|
|
|
32185
|
-
// ../protocol/src/
|
|
32186
|
-
var
|
|
32187
|
-
|
|
32188
|
-
|
|
32189
|
-
|
|
32190
|
-
|
|
32191
|
-
|
|
32185
|
+
// ../protocol/src/a2a.ts
|
|
32186
|
+
var A2A_MAX_CALLS = 8;
|
|
32187
|
+
var A2A_WAIT_MAX_MS = 2 * 60 * 6e4;
|
|
32188
|
+
var A2A_WAIT_DEFAULT_MS = 30 * 6e4;
|
|
32189
|
+
var A2A_STATES = ["submitted", "working", "input_required", "completed", "failed", "canceled", "rejected"];
|
|
32190
|
+
var A2aStateSchema = external_exports.enum(A2A_STATES);
|
|
32191
|
+
var A2A_TERMINAL_STATES = ["completed", "failed", "canceled", "rejected"];
|
|
32192
|
+
var A2A_DELIVERABLE_STATES = ["input_required", ...A2A_TERMINAL_STATES];
|
|
32193
|
+
var TENANT_DEVICE = /^[A-Za-z0-9_.-]{1,128}$/;
|
|
32194
|
+
var TENANT_PERSONA = /^[a-z0-9-]{1,128}$/;
|
|
32195
|
+
function parseA2aTarget(target) {
|
|
32196
|
+
if (target.startsWith("cloud:")) {
|
|
32197
|
+
const id = target.slice("cloud:".length);
|
|
32198
|
+
return TENANT_PERSONA.test(id) ? { kind: "cloud", personaId: id } : null;
|
|
32199
|
+
}
|
|
32200
|
+
const at = target.indexOf("@");
|
|
32201
|
+
if (at < 0) return TENANT_PERSONA.test(target) ? { kind: "here", personaId: target } : null;
|
|
32202
|
+
const personaId2 = target.slice(0, at);
|
|
32203
|
+
const deviceId = target.slice(at + 1);
|
|
32204
|
+
return TENANT_PERSONA.test(personaId2) && TENANT_DEVICE.test(deviceId) ? { kind: "device", personaId: personaId2, deviceId } : null;
|
|
32205
|
+
}
|
|
32206
|
+
var A2aCallSchema = external_exports.object({
|
|
32207
|
+
target: external_exports.string().refine((v) => parseA2aTarget(v) !== null, {
|
|
32208
|
+
message: "target must be <personaId>, <personaId>@<deviceId> or cloud:<personaId>"
|
|
32192
32209
|
}),
|
|
32193
|
-
external_exports.
|
|
32194
|
-
kind: external_exports.literal("failure"),
|
|
32195
|
-
reason: external_exports.string(),
|
|
32196
|
-
brief: external_exports.string().optional()
|
|
32197
|
-
})
|
|
32198
|
-
]);
|
|
32199
|
-
var DispatchRunArgsSchema = external_exports.object({
|
|
32200
|
-
targetPersona: external_exports.string().min(1).optional(),
|
|
32201
|
-
// 续派(spec 2026-07-21,单 dispatchId 语义:一件事一行一 id):非空 = 把 prompt
|
|
32202
|
-
// 作为新 turn 打进该 dispatch 的原 worker session 接着干(台账行复位 running)。
|
|
32203
|
-
// 省略 = 新开一件事,daemon 铸新 id。
|
|
32204
|
-
dispatchId: external_exports.string().min(1).optional(),
|
|
32205
|
-
prompt: external_exports.string(),
|
|
32210
|
+
text: external_exports.string().min(1),
|
|
32206
32211
|
brief: external_exports.string().optional(),
|
|
32207
|
-
|
|
32208
|
-
|
|
32209
|
-
|
|
32210
|
-
// Model values depend on the selected engine and are validated against its runtime catalog. Overrides apply only to new dispatches.
|
|
32212
|
+
contextId: external_exports.string().min(1).optional(),
|
|
32213
|
+
taskId: external_exports.string().min(1).optional(),
|
|
32214
|
+
sessionLabel: external_exports.string().min(1).max(60).optional(),
|
|
32211
32215
|
model: external_exports.string().min(1).optional(),
|
|
32212
|
-
|
|
32216
|
+
/** 一次性换 worker 的引擎;只对本人设备上的本机目标有效,执行方领活时校验 */
|
|
32213
32217
|
tool: external_exports.string().min(1).optional(),
|
|
32214
|
-
|
|
32215
|
-
sessionLabel: external_exports.string().min(1).max(60).optional(),
|
|
32216
|
-
// 上层消费者(Master)挂载话题/线语义:topicId / lineId / 验收标准 / rejectCount 等。
|
|
32217
|
-
// daemon **不解释**内容,只透传进台账行 DispatchRecord.meta(新开)或与既有 meta
|
|
32218
|
-
// merge(续派,见 handlers/persona-dispatch.ts)。与台账行 meta 同款自由 JSON 契约。
|
|
32218
|
+
/** 线的自由字段(topicId / lineId / acceptance …),中心与 daemon 都不解释,原样进台账 */
|
|
32219
32219
|
meta: external_exports.record(external_exports.unknown()).optional()
|
|
32220
|
-
}).refine((v) => v.
|
|
32221
|
-
message: "
|
|
32222
|
-
}).refine((v) => !(v.dispatchId !== void 0 && v.targetDeviceId !== void 0), {
|
|
32223
|
-
message: "follow-ups take only dispatchId; the target device comes from the ledger row (dispatchId + targetDeviceId are mutually exclusive)"
|
|
32224
|
-
}).refine((v) => !(v.tool !== void 0 && v.targetDeviceId !== void 0), {
|
|
32225
|
-
message: "engine override is not supported for cross-device dispatch (tool + targetDeviceId are mutually exclusive)"
|
|
32226
|
-
}).refine((v) => !(v.dispatchId !== void 0 && (v.tool !== void 0 || v.model !== void 0)), {
|
|
32227
|
-
message: "a follow-up dispatch cannot change engine or model (dispatchId excludes tool / model); start a new dispatch instead"
|
|
32228
|
-
});
|
|
32229
|
-
var DispatchCompleteArgsSchema = external_exports.object({
|
|
32230
|
-
dispatchId: external_exports.string().min(1),
|
|
32231
|
-
outcome: DispatchOutcomeSchema
|
|
32232
|
-
});
|
|
32233
|
-
var DISPATCH_STATUSES = ["running", "completed", "failed"];
|
|
32234
|
-
var DispatchStatusSchema = external_exports.enum(DISPATCH_STATUSES);
|
|
32235
|
-
var DispatchRecordSchema = external_exports.object({
|
|
32236
|
-
dispatchId: external_exports.string().min(1),
|
|
32237
|
-
sourceSessionId: external_exports.string().min(1),
|
|
32238
|
-
sourcePersonaId: external_exports.string().min(1).optional(),
|
|
32239
|
-
targetPersonaId: external_exports.string().min(1),
|
|
32240
|
-
/** A-side target device attribution; absence means local for existing records. Forwarding strips it from the B-side local ledger. */
|
|
32241
|
-
targetDeviceId: external_exports.string().min(1).optional(),
|
|
32242
|
-
/** A-side cross-device rows: the B-side ledger id, used for follow-ups and for resuming polls after an A restart. */
|
|
32243
|
-
remoteDispatchId: external_exports.string().min(1).optional(),
|
|
32244
|
-
/** The A-side round B last accepted; a follow-up reopened but not yet accepted has remoteRound < round, so a restart must not resume polling it. */
|
|
32245
|
-
remoteRound: external_exports.number().int().positive().optional(),
|
|
32246
|
-
/** B 的 sessionId;registerBSession 后回填 */
|
|
32247
|
-
workerSessionId: external_exports.string().min(1).optional(),
|
|
32248
|
-
taskText: external_exports.string(),
|
|
32249
|
-
/** Explicit task summary for list/cards instead of truncated taskText; outcome owns the result summary. */
|
|
32250
|
-
taskBrief: external_exports.string().optional(),
|
|
32251
|
-
/** One ledger row across follow-up rounds. Missing on old rows is consumed as round one. */
|
|
32252
|
-
round: external_exports.number().int().positive().optional(),
|
|
32253
|
-
status: DispatchStatusSchema,
|
|
32254
|
-
outcome: DispatchOutcomeSchema.optional(),
|
|
32255
|
-
meta: external_exports.record(external_exports.unknown()).optional(),
|
|
32256
|
-
createdAt: external_exports.string().min(1),
|
|
32257
|
-
completedAt: external_exports.string().min(1).optional(),
|
|
32258
|
-
/** 结果注入 source session 成功时戳,兼当投递 dedup 标记 */
|
|
32259
|
-
deliveredAt: external_exports.string().min(1).optional()
|
|
32260
|
-
});
|
|
32261
|
-
var DispatchListArgsSchema = external_exports.object({
|
|
32262
|
-
sourceSessionId: external_exports.string().min(1).optional(),
|
|
32263
|
-
/** Include rows where this session is either source or worker. If sourceSessionId is also provided, both filters must match. */
|
|
32264
|
-
relatedSessionId: external_exports.string().min(1).optional()
|
|
32220
|
+
}).refine((v) => !(v.contextId && v.taskId), { message: "contextId (new round) and taskId (answer) are mutually exclusive" }).refine((v) => !((v.contextId || v.taskId) && (v.model || v.tool)), {
|
|
32221
|
+
message: "a follow-up cannot change engine or model (contextId / taskId exclude model / tool); start a new line instead"
|
|
32265
32222
|
});
|
|
32266
|
-
var
|
|
32267
|
-
|
|
32223
|
+
var A2aSendArgsSchema = external_exports.object({
|
|
32224
|
+
calls: external_exports.array(A2aCallSchema).min(1).max(A2A_MAX_CALLS),
|
|
32225
|
+
sessionId: external_exports.string().min(1).optional()
|
|
32268
32226
|
});
|
|
32269
|
-
var
|
|
32270
|
-
|
|
32227
|
+
var A2A_AWAIT_SLICE_MAX_MS = 6e4;
|
|
32228
|
+
var A2aAwaitArgsSchema = external_exports.object({
|
|
32229
|
+
taskIds: external_exports.array(external_exports.string().min(1)).min(1).max(A2A_MAX_CALLS),
|
|
32230
|
+
timeoutMs: external_exports.number().int().min(0).max(A2A_AWAIT_SLICE_MAX_MS)
|
|
32231
|
+
});
|
|
32232
|
+
var A2aAnswerArgsSchema = external_exports.object({ taskId: external_exports.string().min(1), text: external_exports.string().trim().min(1) });
|
|
32233
|
+
var A2aTaskIdArgsSchema = external_exports.object({ taskId: external_exports.string().min(1) });
|
|
32234
|
+
var A2aListArgsSchema = external_exports.object({
|
|
32235
|
+
contextId: external_exports.string().min(1).optional(),
|
|
32236
|
+
state: A2aStateSchema.optional(),
|
|
32237
|
+
/** 发起会话(Master 按自己的会话列线);agent 调用时 MCP 用调用者会话填 */
|
|
32238
|
+
sessionId: external_exports.string().min(1).optional(),
|
|
32239
|
+
/** UI:这个会话是发起方或 worker 的任务 */
|
|
32240
|
+
relatedSessionId: external_exports.string().min(1).optional()
|
|
32271
32241
|
});
|
|
32272
|
-
var
|
|
32273
|
-
|
|
32274
|
-
|
|
32275
|
-
|
|
32242
|
+
var A2aReportArgsSchema = external_exports.object({
|
|
32243
|
+
contextId: external_exports.string().min(1),
|
|
32244
|
+
state: external_exports.enum(["completed", "failed", "input_required"]),
|
|
32245
|
+
text: external_exports.string(),
|
|
32246
|
+
brief: external_exports.string().optional(),
|
|
32247
|
+
filePaths: external_exports.array(external_exports.string().min(1)).optional()
|
|
32248
|
+
});
|
|
32249
|
+
var A2aTaskViewSchema = external_exports.object({
|
|
32250
|
+
taskId: external_exports.string().min(1),
|
|
32251
|
+
contextId: external_exports.string().min(1),
|
|
32252
|
+
round: external_exports.number().int().positive(),
|
|
32253
|
+
state: A2aStateSchema,
|
|
32254
|
+
/** 本机执行方失联(租约过期但不判失败) */
|
|
32255
|
+
stale: external_exports.boolean(),
|
|
32256
|
+
/** 系统原因:no_executor / executor_lost / executor_restarted / not_authorized … */
|
|
32257
|
+
reason: external_exports.string().nullable(),
|
|
32258
|
+
depth: external_exports.number().int().min(0),
|
|
32259
|
+
tenant: external_exports.string(),
|
|
32260
|
+
targetPersonaId: external_exports.string(),
|
|
32261
|
+
targetDeviceId: external_exports.string().nullable(),
|
|
32262
|
+
initiator: external_exports.object({ host: external_exports.string(), personaId: external_exports.string(), sessionRef: external_exports.string().nullable() }),
|
|
32263
|
+
executorSessionRef: external_exports.string().nullable(),
|
|
32264
|
+
executorThreadId: external_exports.string().nullable(),
|
|
32265
|
+
/** 这条线在本机的 worker 会话:本机执行的,或发起方 daemon 挂出的云 worker 会话;本机没有就缺省 */
|
|
32266
|
+
workerSessionId: external_exports.string().optional(),
|
|
32267
|
+
/** 派活方给 worker 会话起的名字(首条 user 消息的 sessionLabel) */
|
|
32268
|
+
sessionLabel: external_exports.string().optional(),
|
|
32269
|
+
/** 任务正文(首条 user 消息) */
|
|
32270
|
+
taskText: external_exports.string(),
|
|
32271
|
+
/** worker 的一句话摘要(statusMessage.brief) */
|
|
32272
|
+
brief: external_exports.string().nullable(),
|
|
32273
|
+
/** worker 最后一条回报正文 */
|
|
32274
|
+
resultText: external_exports.string().nullable(),
|
|
32275
|
+
filePaths: external_exports.array(external_exports.string()),
|
|
32276
|
+
line: external_exports.record(external_exports.unknown()),
|
|
32277
|
+
deliveredAt: external_exports.string().nullable(),
|
|
32278
|
+
createdAt: external_exports.string(),
|
|
32279
|
+
updatedAt: external_exports.string(),
|
|
32280
|
+
finishedAt: external_exports.string().nullable()
|
|
32276
32281
|
});
|
|
32282
|
+
var A2aCallResultSchema = external_exports.discriminatedUnion("ok", [
|
|
32283
|
+
external_exports.object({ ok: external_exports.literal(true), task: A2aTaskViewSchema }),
|
|
32284
|
+
external_exports.object({ ok: external_exports.literal(false), error: external_exports.object({ code: external_exports.string(), message: external_exports.string() }) })
|
|
32285
|
+
]);
|
|
32286
|
+
var A2aSendResultSchema = external_exports.object({ results: external_exports.array(A2aCallResultSchema) });
|
|
32287
|
+
var A2aListResultSchema = external_exports.object({ tasks: external_exports.array(A2aTaskViewSchema) });
|
|
32288
|
+
var A2aAwaitResultSchema = external_exports.object({ tasks: external_exports.array(A2aTaskViewSchema), done: external_exports.boolean() });
|
|
32277
32289
|
|
|
32278
32290
|
// ../protocol/src/extension.ts
|
|
32279
32291
|
var EXT_ID_REGEX = /^[a-z0-9][a-z0-9-]*$/;
|
|
@@ -32652,11 +32664,14 @@ var TopicSchema = external_exports.object({
|
|
|
32652
32664
|
});
|
|
32653
32665
|
var TopicLineViewSchema = external_exports.object({
|
|
32654
32666
|
lineId: external_exports.string().min(1),
|
|
32655
|
-
|
|
32667
|
+
/** 这条线(A2A context);打回在同一 context 下开新任务 */
|
|
32668
|
+
contextId: external_exports.string().min(1),
|
|
32669
|
+
/** 最新一轮的任务 */
|
|
32670
|
+
taskId: external_exports.string().min(1),
|
|
32656
32671
|
workerSessionId: external_exports.string().optional(),
|
|
32657
32672
|
assignee: external_exports.string().min(1),
|
|
32658
32673
|
focus: external_exports.string(),
|
|
32659
|
-
status:
|
|
32674
|
+
status: A2aStateSchema,
|
|
32660
32675
|
acceptance: external_exports.array(external_exports.string()),
|
|
32661
32676
|
rejectCount: external_exports.number().int().min(0),
|
|
32662
32677
|
accepted: external_exports.boolean(),
|
|
@@ -32887,6 +32902,37 @@ var OnboardingIosInterestResultSchema = external_exports.object({
|
|
|
32887
32902
|
registered: external_exports.boolean()
|
|
32888
32903
|
});
|
|
32889
32904
|
|
|
32905
|
+
// ../protocol/src/faq-schemas.ts
|
|
32906
|
+
var FaqEvidenceSchema = external_exports.object({
|
|
32907
|
+
kind: external_exports.enum(["rpc", "file"]),
|
|
32908
|
+
/** RPC 方法名,或 `path:line` */
|
|
32909
|
+
ref: external_exports.string().min(1).max(300)
|
|
32910
|
+
});
|
|
32911
|
+
var FaqReportArgs = external_exports.object({
|
|
32912
|
+
/** 管家归纳成一句话的问题,不贴用户原话 */
|
|
32913
|
+
question: external_exports.string().min(1).max(500),
|
|
32914
|
+
status: external_exports.enum(["unanswered", "answered_unverified"]),
|
|
32915
|
+
/** answered_unverified 必填:给用户的答案 */
|
|
32916
|
+
answer: external_exports.string().max(4e3).optional(),
|
|
32917
|
+
/** answered_unverified 必填 */
|
|
32918
|
+
resolvedBy: external_exports.enum(["rpc", "source"]).optional(),
|
|
32919
|
+
/** answered_unverified 至少一项 */
|
|
32920
|
+
evidence: external_exports.array(FaqEvidenceSchema).max(20).optional(),
|
|
32921
|
+
/** 管家先看过的托管文档路径 */
|
|
32922
|
+
docsChecked: external_exports.array(external_exports.string().max(200)).max(20).optional(),
|
|
32923
|
+
/** unanswered 必填 */
|
|
32924
|
+
unansweredReason: external_exports.enum(["no_source_access", "user_declined", "not_found"]).optional()
|
|
32925
|
+
}).superRefine((v, ctx) => {
|
|
32926
|
+
if (v.status === "answered_unverified") {
|
|
32927
|
+
if (!v.answer) ctx.addIssue({ code: "custom", path: ["answer"], message: "answered_unverified \u9700\u8981 answer" });
|
|
32928
|
+
if (!v.resolvedBy) ctx.addIssue({ code: "custom", path: ["resolvedBy"], message: "answered_unverified \u9700\u8981 resolvedBy" });
|
|
32929
|
+
if (!v.evidence?.length) ctx.addIssue({ code: "custom", path: ["evidence"], message: "answered_unverified \u9700\u8981\u81F3\u5C11\u4E00\u9879 evidence" });
|
|
32930
|
+
} else if (!v.unansweredReason) {
|
|
32931
|
+
ctx.addIssue({ code: "custom", path: ["unansweredReason"], message: "unanswered \u9700\u8981 unansweredReason" });
|
|
32932
|
+
}
|
|
32933
|
+
});
|
|
32934
|
+
var FaqReportResultSchema = external_exports.object({ id: external_exports.string() });
|
|
32935
|
+
|
|
32890
32936
|
// ../protocol/src/engine-schemas.ts
|
|
32891
32937
|
var EngineStatusArgs = external_exports.object({
|
|
32892
32938
|
tool: external_exports.enum(PROBE_TOOL_IDS)
|
|
@@ -32987,11 +33033,14 @@ var HISTORY_USER_META_VALUES = [
|
|
|
32987
33033
|
"meta-text",
|
|
32988
33034
|
"attachment-skills",
|
|
32989
33035
|
"attachment-deferred-tools",
|
|
32990
|
-
// persona
|
|
32991
|
-
//
|
|
32992
|
-
//
|
|
32993
|
-
//
|
|
32994
|
-
//
|
|
33036
|
+
// persona 间调用来源分型(信封契约见 a2a-format.ts):
|
|
33037
|
+
// a2a-task 派给 worker 的任务包(首发 + 打回,打回靠信封 round 属性区分,不单开分型)
|
|
33038
|
+
// a2a-result 结果投回发起方 session 的结果包
|
|
33039
|
+
// dispatch-* 旧版信封,只在旧历史里出现,照同样语义展示
|
|
33040
|
+
// 这几类跟其它 meta 的关键差别:**它们是一轮真实交互**,参与 turn 切分与分页计数
|
|
33041
|
+
// (见 isA2aUserMeta 的消费点),不是 CC 内部注入的辅助消息。
|
|
33042
|
+
"a2a-task",
|
|
33043
|
+
"a2a-result",
|
|
32995
33044
|
"dispatch-task",
|
|
32996
33045
|
"dispatch-result"
|
|
32997
33046
|
];
|
|
@@ -33168,6 +33217,8 @@ var SessionFileSchema = external_exports.object({
|
|
|
33168
33217
|
originOwnerPersonaId: external_exports.string().min(1).optional(),
|
|
33169
33218
|
/** Dispatch source session for local tree grouping. Strip on mirrors because remote session ids cannot link into the local tree. */
|
|
33170
33219
|
dispatchedFromSessionId: external_exports.string().min(1).optional(),
|
|
33220
|
+
/** A2A line (contextId) this worker session serves; the spawn env carries it as CLAWD_A2A_CONTEXT_ID so a2aReport finds the current round. Strip on mirrors. */
|
|
33221
|
+
a2aContextId: external_exports.string().min(1).optional(),
|
|
33171
33222
|
/** Scheduler source session, distinct from dispatch/fork ancestry. Strip on mirrors because this linkage is local-only. */
|
|
33172
33223
|
shiftFiredFromSessionId: external_exports.string().min(1).optional(),
|
|
33173
33224
|
/** Bot session key, potentially virtual topic/speaker or document key, not necessarily a real IM chat id. UI hides these sessions from ordinary recent-session lists. */
|
|
@@ -34248,6 +34299,15 @@ var METHOD_DOCS = {
|
|
|
34248
34299
|
summary: "\u767B\u8BB0 owner \u60F3\u8981 iOS TestFlight\uFF1Adaemon \u8F6C\u53D1\u4E2D\u5FC3 API\uFF08\u643A\u5E26 unionId/\u98DE\u4E66\u540D\uFF09\uFF0Cserver \u843D\u8868\u53BB\u91CD\u5E76\u7528\u5B98\u65B9 bot \u901A\u77E5 David \u8D70\u98DE\u4E66\u8054\u7CFB\uFF1B\u9700\u98DE\u4E66\u5DF2\u767B\u5F55\uFF08FEISHU_GATED\uFF09",
|
|
34249
34300
|
args: OnboardingIosInterestArgs
|
|
34250
34301
|
},
|
|
34302
|
+
"faq:report": {
|
|
34303
|
+
summary: "\u7BA1\u5BB6\u4E0A\u62A5\u7B54\u4E0D\u4E0A\u6765 / \u6CA1\u7ECF\u6587\u6863\u6838\u5BF9\u7684\u95EE\u9898\uFF1Adaemon \u5148\u8131\u654F\uFF08\u4E3B\u76EE\u5F55\u8DEF\u5F84\u3001token \u5F62\u72B6\u7684\u4E32\uFF09\uFF0C\u518D\u5E26\u767B\u5F55\u7968\u8F6C\u53D1\u4E2D\u5FC3 faq_inbox\uFF1B\u5931\u8D25\u7531\u8C03\u7528\u65B9\u9759\u9ED8\u5FFD\u7565\uFF1B\u9700\u98DE\u4E66\u5DF2\u767B\u5F55\uFF08FEISHU_GATED\uFF09",
|
|
34304
|
+
args: FaqReportArgs,
|
|
34305
|
+
argsConstraints: {
|
|
34306
|
+
if: { properties: { status: { const: "answered_unverified" } } },
|
|
34307
|
+
then: { required: ["answer", "resolvedBy", "evidence"], properties: { evidence: { minItems: 1 } } },
|
|
34308
|
+
else: { required: ["unansweredReason"] }
|
|
34309
|
+
}
|
|
34310
|
+
},
|
|
34251
34311
|
"skills:list": {
|
|
34252
34312
|
summary: "\u626B\u63CF\u5E76\u5217\u51FA\u8BE5\u76EE\u5F55\u53EF\u7528\u7684 skill",
|
|
34253
34313
|
args: SkillsListArgs
|
|
@@ -34321,25 +34381,33 @@ var METHOD_DOCS = {
|
|
|
34321
34381
|
summary: "\u5220 persona\u3002owner-only",
|
|
34322
34382
|
args: PersonaIdArgsSchema
|
|
34323
34383
|
},
|
|
34324
|
-
"
|
|
34325
|
-
summary: "\
|
|
34326
|
-
args:
|
|
34327
|
-
|
|
34328
|
-
|
|
34329
|
-
|
|
34330
|
-
|
|
34384
|
+
"a2a:send": {
|
|
34385
|
+
summary: "\u6D3E\u6D3B\u7ED9\u53E6\u4E00\u4E2A persona\uFF08\u672C\u673A / \u8054\u7CFB\u4EBA\u8BBE\u5907 / \u4E91\u4E0A\uFF09\uFF0C\u4E00\u6B21 1 \u5230 8 \u4E2A call\uFF0C\u6BCF\u4E2A call \u5355\u72EC\u6210\u8D25\uFF0C\u53D1\u51FA\u5373\u8FD4\u56DE\u4EFB\u52A1\u89C6\u56FE\u3002target \u5199\u6CD5\u540C @ token\uFF1A<personaId> / <personaId>@<deviceId> / cloud:<personaId>\uFF1B\u5E26 contextId = \u540C\u4E00\u6761\u7EBF\u65B0\u4E00\u8F6E\uFF08\u6253\u56DE\uFF09\uFF0C\u5E26 taskId = \u56DE\u7B54 input_required",
|
|
34386
|
+
args: A2aSendArgsSchema
|
|
34387
|
+
},
|
|
34388
|
+
"a2a:await": {
|
|
34389
|
+
summary: "\u7B49\u8FD9\u4E9B\u4EFB\u52A1\u5168\u90E8\u8FDB\u5165\u7EC8\u6001\u6216 input_required\uFF08\u5355\u6B21\u6700\u591A 60 \u79D2\uFF09\u3002done=true \u65F6 daemon \u5F53\u573A\u786E\u8BA4\u6295\u9012\uFF0C\u7ED3\u679C\u4E0D\u518D\u6CE8\u5165\u56DE\u4F1A\u8BDD\uFF1Bdone=false \u4EC0\u4E48\u90FD\u4E0D\u786E\u8BA4",
|
|
34390
|
+
args: A2aAwaitArgsSchema
|
|
34391
|
+
},
|
|
34392
|
+
"a2a:answer": {
|
|
34393
|
+
summary: "\u56DE\u7B54\u4E00\u4E2A\u505C\u5728 input_required \u7684\u4EFB\u52A1\uFF08\u53D1\u8D77\u65B9\u672C\u4EBA\uFF09\uFF1A\u56DE\u7B54\u8FDB worker \u4F1A\u8BDD\uFF0Cworker \u63A5\u7740\u5E72\u3002\u4EFB\u52A1\u5DF2\u4E0D\u5728\u7B49\u56DE\u7B54\u65F6\u62A5\u9519",
|
|
34394
|
+
args: A2aAnswerArgsSchema
|
|
34395
|
+
},
|
|
34396
|
+
"a2a:get": {
|
|
34397
|
+
summary: "\u67E5\u4E00\u4E2A A2A \u4EFB\u52A1\u7684\u72B6\u6001\u4E0E\u7ED3\u679C\uFF08\u53D1\u8D77\u65B9\u672C\u4EBA\uFF0C\u6216\u672C\u673A\u76EE\u6807\u8BBE\u5907\uFF09",
|
|
34398
|
+
args: A2aTaskIdArgsSchema
|
|
34331
34399
|
},
|
|
34332
|
-
"
|
|
34333
|
-
summary:
|
|
34334
|
-
args:
|
|
34400
|
+
"a2a:list": {
|
|
34401
|
+
summary: "\u5217 A2A \u4EFB\u52A1\uFF1A\u6309 contextId / state \u8FC7\u6EE4\uFF1BsessionId = \u8FD9\u4E2A\u4F1A\u8BDD\u53D1\u51FA\u7684\uFF1BrelatedSessionId = \u8FD9\u4E2A\u4F1A\u8BDD\u662F\u53D1\u8D77\u65B9\u6216 worker \u7684\uFF08UI \u7528\uFF09",
|
|
34402
|
+
args: A2aListArgsSchema
|
|
34335
34403
|
},
|
|
34336
|
-
"
|
|
34337
|
-
summary: "\
|
|
34338
|
-
args:
|
|
34404
|
+
"a2a:cancel": {
|
|
34405
|
+
summary: "\u53D6\u6D88\u4E00\u4E2A\u8FD8\u6CA1\u7ED3\u675F\u7684 A2A \u4EFB\u52A1\uFF1Bworker \u4F1A\u88AB\u4E2D\u65AD",
|
|
34406
|
+
args: A2aTaskIdArgsSchema
|
|
34339
34407
|
},
|
|
34340
|
-
"
|
|
34341
|
-
summary: "\
|
|
34342
|
-
args:
|
|
34408
|
+
"a2a:report": {
|
|
34409
|
+
summary: "worker \u56DE\u62A5\u8FD9\u4E00\u8F6E\u7684\u7ED3\u679C\uFF1Acompleted / failed / input_required\uFF08\u505C\u4E0B\u6765\u8981\u53D1\u8D77\u65B9\u56DE\u7B54\uFF09\u3002contextId \u7531\u5BBF\u4E3B\u6CE8\u5165\uFF0Cdaemon \u636E\u5B83\u627E\u5F53\u524D\u8FD9\u4E00\u8F6E",
|
|
34410
|
+
args: A2aReportArgsSchema
|
|
34343
34411
|
},
|
|
34344
34412
|
"peerExec:run": {
|
|
34345
34413
|
summary: "\u5728\u8054\u7CFB\u4EBA\u8BBE\u5907\u4E0A\u8DD1\u4E00\u6761 bash \u547D\u4EE4\uFF08\u4E00\u53D1\u4E00\u6536\uFF0C\u65E0\u8DE8\u547D\u4EE4\u4F1A\u8BDD\u72B6\u6001\uFF09\u3002**\u672C\u673A\u53D1\u8D77\u5FC5\u586B peerDeviceId**\u2014\u2014\u7701\u7565\u4EC5\u7528\u4E8E\u5BF9\u7AEF guest \u53CD\u5411\u5165\u53E3\uFF0Cowner ctx \u7701\u7565\u4F1A\u88AB\u62D2\uFF1B\u9700\u5BF9\u65B9\u5F00\u4E86 remoteAccess",
|
|
@@ -34645,8 +34713,8 @@ var WebSessionExchangeResultSchema = external_exports.object({
|
|
|
34645
34713
|
expiresAt: external_exports.number()
|
|
34646
34714
|
});
|
|
34647
34715
|
|
|
34648
|
-
// ../protocol/src/
|
|
34649
|
-
var INNER_TAG_NAMES = "clawd-dispatch-task|clawd-dispatch-result|brief|detail|files";
|
|
34716
|
+
// ../protocol/src/a2a-format.ts
|
|
34717
|
+
var INNER_TAG_NAMES = "clawd-a2a-task|clawd-a2a-result|clawd-dispatch-task|clawd-dispatch-result|brief|detail|files";
|
|
34650
34718
|
var INNER_TAG_ESCAPE_RE = new RegExp(`<(\\\\*)(/?)(${INNER_TAG_NAMES})\\b`, "g");
|
|
34651
34719
|
var INNER_TAG_UNESCAPE_RE = new RegExp(`<\\\\(\\\\*)(/?)(${INNER_TAG_NAMES})\\b`, "g");
|
|
34652
34720
|
|
|
@@ -51,9 +51,9 @@ watcher 的工具、文件权限与引擎历史能力以当前会话为准;给
|
|
|
51
51
|
|
|
52
52
|
线间尽量无依赖;有依赖的串行编排,**不做假并行**。按 3-5 条线设计,不追求更多。
|
|
53
53
|
|
|
54
|
-
### 3. 派活:走
|
|
54
|
+
### 3. 派活:走 a2aAsync,把话题语义挂在线上
|
|
55
55
|
|
|
56
|
-
调 `
|
|
56
|
+
调 `clawd-a2a` 的 `a2aAsync` 时,每个 call **必须**带 `meta`:
|
|
57
57
|
|
|
58
58
|
meta: { topicId, lineId, acceptance: [该线的验收标准] }
|
|
59
59
|
|
|
@@ -66,7 +66,7 @@ watcher 的工具、文件权限与引擎历史能力以当前会话为准;给
|
|
|
66
66
|
|
|
67
67
|
- `memberPersonas` —— 可派活的 persona **全集**。每项形如 `{ personaId, deviceId? }`:没有
|
|
68
68
|
`deviceId` 就是本机 persona,有 `deviceId` 就是那台联系人设备上公开给老板的 persona。
|
|
69
|
-
|
|
69
|
+
派它时 `target` 写 `<personaId>`(本机)或 `<personaId>@<deviceId>`(联系人设备),值原样照抄
|
|
70
70
|
- `memberContactDeviceIds` —— **人类**成员,只表示「可以给这个人发 DM」
|
|
71
71
|
|
|
72
72
|
**联系人在名单里不等于他家的 persona 能派。** 要派某台设备上的 persona,那个 persona 必须
|
|
@@ -75,8 +75,8 @@ watcher 的工具、文件权限与引擎历史能力以当前会话为准;给
|
|
|
75
75
|
缺人手就**停下问老板**要不要把某个 persona 加进频道,不要绕道派给名单外的 persona。
|
|
76
76
|
|
|
77
77
|
打回次数**不要**自己往 `meta` 里记 —— daemon 在 `topic:reject` / `topic:accept` 里数,
|
|
78
|
-
你手记一份只会跟它漂。拿到 `
|
|
79
|
-
**一件事全程一个
|
|
78
|
+
你手记一份只会跟它漂。拿到 `contextId` 后立刻落账(见「落账纪律」)。
|
|
79
|
+
**一件事全程一个 contextId**,打回时复用它。
|
|
80
80
|
|
|
81
81
|
### 4. 验收:不信自述,自己核一遍
|
|
82
82
|
|
|
@@ -127,11 +127,11 @@ daemon 会单独落一条「推翻 watcher」的流水并计数。**`needsOwnerA
|
|
|
127
127
|
用 `grep -n "^import" <文件>` 展示依赖、用 `node --test ... | grep '^ok'` 贴全部用例名、
|
|
128
128
|
工具调用记录是否保留、是否能读取与引擎和权限有关;不能承诺某种写法必定留下可见痕迹。最终提供产物、测试输出与必要的过程证据,让 watcher 可复查。
|
|
129
129
|
|
|
130
|
-
### 5. 打回:同一个
|
|
130
|
+
### 5. 打回:同一个 contextId 续派
|
|
131
131
|
|
|
132
|
-
不合格 → 再调 `
|
|
132
|
+
不合格 → 再调 `a2aAsync`,**带原 contextId**(同一条线的下一轮,worker 会话接着干,上下文不丢):
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
a2aAsync({ calls: [{ target: <原 target>, contextId: <原 id>, text: "第 N 条没达标:<具体>,补一下" }] })
|
|
135
135
|
|
|
136
136
|
打回前先跑:
|
|
137
137
|
|
|
@@ -143,13 +143,12 @@ daemon 数打回次数、同时把理由写进流水(一次调用两件事,
|
|
|
143
143
|
返回 `{ rejectCount, needsOwnerAttention }`。**`needsOwnerAttention` 为 true
|
|
144
144
|
(同一条线累计两次打回)→ 停下上报老板,不要再自行打回。**
|
|
145
145
|
|
|
146
|
-
>
|
|
147
|
-
> `targetDeviceId`(协议层禁止两者同传,设备从台账取)。
|
|
146
|
+
> 跨设备派出去的线续派 / 打回与本机线一样:`target` 照旧、带上 `contextId`。
|
|
148
147
|
|
|
149
148
|
### 6. 线中途上报问题
|
|
150
149
|
|
|
151
|
-
worker
|
|
152
|
-
|
|
150
|
+
worker 干到一半上报「答不了的问题」(回报状态是 `input_required`,问题在结果正文里)时:
|
|
151
|
+
先自己判断——你是任务源头,多数问题你能答,答了就带那一轮的 `taskId` 把回答发回去(`a2aAsync` 的 call 带 `taskId`)。答不了 → 停下上报老板拍板。
|
|
153
152
|
**不许用未经确认的假设擅自解锁一条挂起的线**——除非该假设来自设定里的预授权或老板临场拍板。
|
|
154
153
|
|
|
155
154
|
### 6.1 决策留痕:代老板确认与向老板升级(硬性)
|
|
@@ -186,7 +185,7 @@ worker 的问题不能只在对话里一闪而过。你每次替老板作出判
|
|
|
186
185
|
}})
|
|
187
186
|
|
|
188
187
|
`session:interrupt` 只结束当前 worker turn,不杀会话、不丢上下文;恢复时仍复用原
|
|
189
|
-
`
|
|
188
|
+
`contextId`。如果该调用失败,不能假定 worker 已停下;仍要追加下面的 `owner-needed`
|
|
190
189
|
记录,并在 `reason` 里写明中断失败,继续保持不续派。
|
|
191
190
|
|
|
192
191
|
mcp__clawd-rpc__call({ method: 'topic:append', args: {
|
|
@@ -200,8 +199,8 @@ worker 的问题不能只在对话里一闪而过。你每次替老板作出判
|
|
|
200
199
|
}})
|
|
201
200
|
|
|
202
201
|
然后向老板报告这条待决策项,并等待明确答复;不要用普通 `topic:append` 假装已经解决。
|
|
203
|
-
如果 worker 已经 idle,则不需要额外 RPC;只是不再给该 `
|
|
204
|
-
老板答复后,先把答复原样记录成同一 `target` 的已解决决策,再用**同一个 `
|
|
202
|
+
如果 worker 已经 idle,则不需要额外 RPC;只是不再给该 `contextId` 续派,等老板答复。
|
|
203
|
+
老板答复后,先把答复原样记录成同一 `target` 的已解决决策,再用**同一个 `contextId`**
|
|
205
204
|
续派可执行指令;不要新建第二条线。`session:interrupt` 失败时不能当作已经停住。
|
|
206
205
|
记录已解决决策的调用仍走 `topic:append`:
|
|
207
206
|
|
|
@@ -214,7 +213,7 @@ worker 的问题不能只在对话里一闪而过。你每次替老板作出判
|
|
|
214
213
|
},
|
|
215
214
|
}})
|
|
216
215
|
|
|
217
|
-
随后才用原 `
|
|
216
|
+
随后才用原 `contextId` 续派。决策记录落账失败就不要继续派活,先上报失败原因。
|
|
218
217
|
决策 tab 会据此保留完整的「提出问题 → 得到结论」轨迹。
|
|
219
218
|
|
|
220
219
|
这两类记录是老板在话题「决策」tab 里唯一关注的内容:没有 `decision` 的旧流水不会出现在
|
|
@@ -247,7 +246,7 @@ worker 的问题不能只在对话里一闪而过。你每次替老板作出判
|
|
|
247
246
|
老板事后要看的不是"你做了什么",而是"你凭什么这么判断"——后者才能拿来纠正你。
|
|
248
247
|
|
|
249
248
|
**话题记录是你的外部大脑,不是事后日志**:做决策时当场写。你的上下文随时可能被清空,
|
|
250
|
-
清空后你要能只靠 `topic:get`(三要素 + 流水 + 线)+ `
|
|
249
|
+
清空后你要能只靠 `topic:get`(三要素 + 流水 + 线)+ `a2aListTasks` 接着干。
|
|
251
250
|
|
|
252
251
|
## 授权纪律(硬性)
|
|
253
252
|
|
|
@@ -16383,6 +16383,10 @@ function loadMcpServerDefs(args) {
|
|
|
16383
16383
|
return out;
|
|
16384
16384
|
}
|
|
16385
16385
|
|
|
16386
|
+
// src/a2a/limits.ts
|
|
16387
|
+
var A2A_MCP_SERVER_NAME = "clawd-a2a";
|
|
16388
|
+
var A2A_MCP_CALL_TIMEOUT_MS = 2 * 60 * 6e4 + 6e4;
|
|
16389
|
+
|
|
16386
16390
|
// src/pi-mcp-bridge/bridge.ts
|
|
16387
16391
|
var PI_MCP_CONFIGS_ENV = "CLAWD_PI_MCP_CONFIGS";
|
|
16388
16392
|
function piToolName(server, tool) {
|
|
@@ -16540,7 +16544,8 @@ var ServerLink = class {
|
|
|
16540
16544
|
const argsObj = args && typeof args === "object" && !Array.isArray(args) ? args : {};
|
|
16541
16545
|
const result = await client.callTool({ name, arguments: argsObj }, void 0, {
|
|
16542
16546
|
signal,
|
|
16543
|
-
|
|
16547
|
+
// a2aWait 一次调用可以等到 2 小时(a2a/limits.ts)
|
|
16548
|
+
timeout: this.def.name === A2A_MCP_SERVER_NAME ? Math.max(this.opts.callTimeoutMs, A2A_MCP_CALL_TIMEOUT_MS) : this.opts.callTimeoutMs,
|
|
16544
16549
|
resetTimeoutOnProgress: true
|
|
16545
16550
|
});
|
|
16546
16551
|
return result;
|