weacpx 0.4.0-beta.0 → 0.4.0-beta.2
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/bridge/bridge-main.js +67 -17
- package/dist/cli.js +643 -378
- package/dist/weixin/agent/interface.d.ts +8 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -9477,211 +9477,6 @@ function readVersion(moduleUrl = import.meta.url) {
|
|
|
9477
9477
|
var PACKAGE_NAME = "weacpx";
|
|
9478
9478
|
var init_version = () => {};
|
|
9479
9479
|
|
|
9480
|
-
// src/formatting/render-text.ts
|
|
9481
|
-
function renderAgents(config2) {
|
|
9482
|
-
const names = Object.keys(config2.agents);
|
|
9483
|
-
if (names.length === 0) {
|
|
9484
|
-
return "还没有注册任何 Agent。";
|
|
9485
|
-
}
|
|
9486
|
-
return ["已注册的 Agent:", ...names.map((name) => `- ${name}`)].join(`
|
|
9487
|
-
`);
|
|
9488
|
-
}
|
|
9489
|
-
function renderWorkspaces(config2) {
|
|
9490
|
-
const names = Object.entries(config2.workspaces);
|
|
9491
|
-
if (names.length === 0) {
|
|
9492
|
-
return "还没有注册任何工作区。";
|
|
9493
|
-
}
|
|
9494
|
-
return ["已注册的工作区:", ...names.map(([name, workspace]) => `- ${name}: ${workspace.cwd}`)].join(`
|
|
9495
|
-
`);
|
|
9496
|
-
}
|
|
9497
|
-
function renderOrchestrationUnavailable() {
|
|
9498
|
-
return "当前未启用任务编排服务。";
|
|
9499
|
-
}
|
|
9500
|
-
function renderDelegateSuccess(taskId, workerSession) {
|
|
9501
|
-
return [`已创建委派任务「${taskId}」`, `worker 会话:${workerSession}`].join(`
|
|
9502
|
-
`);
|
|
9503
|
-
}
|
|
9504
|
-
function renderGroupCreated(group) {
|
|
9505
|
-
return [`已创建任务组「${group.groupId}」`, `- 标题:${group.title}`].join(`
|
|
9506
|
-
`);
|
|
9507
|
-
}
|
|
9508
|
-
function renderGroupList(groups) {
|
|
9509
|
-
if (groups.length === 0) {
|
|
9510
|
-
return "当前协调会话下还没有任务组。";
|
|
9511
|
-
}
|
|
9512
|
-
return ["当前协调会话的任务组:", ...groups.map((group) => renderGroupListItem(group))].join(`
|
|
9513
|
-
`);
|
|
9514
|
-
}
|
|
9515
|
-
function renderGroupSummary(summary) {
|
|
9516
|
-
const { group, tasks } = summary;
|
|
9517
|
-
const lines = [
|
|
9518
|
-
`任务组「${group.groupId}」`,
|
|
9519
|
-
`- 标题:${group.title}`,
|
|
9520
|
-
`- 协调会话:${group.coordinatorSession}`,
|
|
9521
|
-
`- 总任务数:${summary.totalTasks}`,
|
|
9522
|
-
`- 待确认:${summary.pendingApprovalTasks}`,
|
|
9523
|
-
`- 运行中:${summary.runningTasks}`,
|
|
9524
|
-
`- 已完成:${summary.completedTasks}`,
|
|
9525
|
-
`- 已失败:${summary.failedTasks}`,
|
|
9526
|
-
`- 已取消:${summary.cancelledTasks}`,
|
|
9527
|
-
`- 是否终态:${summary.terminal ? "是" : "否"}`
|
|
9528
|
-
];
|
|
9529
|
-
if (group.injectionPending !== undefined) {
|
|
9530
|
-
lines.push(`- 注入待处理:${group.injectionPending ? "是" : "否"}`);
|
|
9531
|
-
}
|
|
9532
|
-
if (group.injectionAppliedAt) {
|
|
9533
|
-
lines.push(`- 注入完成时间:${group.injectionAppliedAt}`);
|
|
9534
|
-
}
|
|
9535
|
-
if (group.lastInjectionError) {
|
|
9536
|
-
lines.push(`- 最近注入错误:${group.lastInjectionError}`);
|
|
9537
|
-
}
|
|
9538
|
-
if (tasks.length > 0) {
|
|
9539
|
-
lines.push("- 成员:");
|
|
9540
|
-
for (const task of tasks) {
|
|
9541
|
-
lines.push(` - ${task.taskId} [${task.status}] ${task.targetAgent}`);
|
|
9542
|
-
}
|
|
9543
|
-
}
|
|
9544
|
-
return lines.join(`
|
|
9545
|
-
`);
|
|
9546
|
-
}
|
|
9547
|
-
function renderGroupCancelSuccess(input) {
|
|
9548
|
-
return [
|
|
9549
|
-
`任务组「${input.summary.group.groupId}」已发起取消`,
|
|
9550
|
-
`- 已请求取消:${input.cancelledTaskIds.length}`,
|
|
9551
|
-
`- 已跳过终态任务:${input.skippedTaskIds.length}`
|
|
9552
|
-
].join(`
|
|
9553
|
-
`);
|
|
9554
|
-
}
|
|
9555
|
-
function renderTaskList(tasks) {
|
|
9556
|
-
if (tasks.length === 0) {
|
|
9557
|
-
return "当前协调会话下还没有任务。";
|
|
9558
|
-
}
|
|
9559
|
-
return ["当前协调会话的任务:", ...tasks.map((task) => renderTaskListItem(task))].join(`
|
|
9560
|
-
`);
|
|
9561
|
-
}
|
|
9562
|
-
function renderTaskSummary(task) {
|
|
9563
|
-
const header = [
|
|
9564
|
-
`任务「${task.taskId}」`,
|
|
9565
|
-
`- 状态:${task.status}`,
|
|
9566
|
-
`- 协调会话:${task.coordinatorSession}`,
|
|
9567
|
-
`- worker 会话:${task.workerSession ?? "未分配"}`,
|
|
9568
|
-
`- 目标 Agent:${task.targetAgent}`
|
|
9569
|
-
];
|
|
9570
|
-
if (task.role)
|
|
9571
|
-
header.push(`- 角色:${task.role}`);
|
|
9572
|
-
if (task.groupId)
|
|
9573
|
-
header.push(`- 任务组:${task.groupId}`);
|
|
9574
|
-
if (task.status === "needs_confirmation") {
|
|
9575
|
-
header.push(`- 来源:${task.sourceKind} / ${task.sourceHandle}${task.role ? ` / ${task.role}` : ""}`);
|
|
9576
|
-
}
|
|
9577
|
-
header.push(`- 任务:${task.task}`);
|
|
9578
|
-
if (task.summary.trim().length > 0)
|
|
9579
|
-
header.push(`- 摘要:${task.summary}`);
|
|
9580
|
-
if (task.resultText.trim().length > 0)
|
|
9581
|
-
header.push(`- 结果:${task.resultText}`);
|
|
9582
|
-
const events = [];
|
|
9583
|
-
events.push({ at: task.createdAt, event: "created" });
|
|
9584
|
-
if (task.workerSession && task.status !== "needs_confirmation") {
|
|
9585
|
-
events.push({ at: task.createdAt, event: "dispatched", detail: task.workerSession });
|
|
9586
|
-
}
|
|
9587
|
-
if (task.lastProgressAt)
|
|
9588
|
-
events.push({ at: task.lastProgressAt, event: "last_progress" });
|
|
9589
|
-
if (task.cancelRequestedAt)
|
|
9590
|
-
events.push({ at: task.cancelRequestedAt, event: "cancel_requested" });
|
|
9591
|
-
if (task.cancelCompletedAt)
|
|
9592
|
-
events.push({ at: task.cancelCompletedAt, event: "cancel_completed" });
|
|
9593
|
-
if (task.lastCancelError)
|
|
9594
|
-
events.push({ at: task.updatedAt, event: "cancel_failed", detail: task.lastCancelError });
|
|
9595
|
-
if (task.status === "completed")
|
|
9596
|
-
events.push({ at: task.updatedAt, event: "completed" });
|
|
9597
|
-
if (task.status === "failed")
|
|
9598
|
-
events.push({ at: task.updatedAt, event: "failed" });
|
|
9599
|
-
if (task.noticeSentAt)
|
|
9600
|
-
events.push({ at: task.noticeSentAt, event: "notice_sent", detail: task.deliveryAccountId });
|
|
9601
|
-
if (task.lastNoticeError)
|
|
9602
|
-
events.push({ at: task.updatedAt, event: "notice_failed", detail: task.lastNoticeError });
|
|
9603
|
-
if (task.injectionAppliedAt)
|
|
9604
|
-
events.push({ at: task.injectionAppliedAt, event: "injection_applied" });
|
|
9605
|
-
if (task.lastInjectionError)
|
|
9606
|
-
events.push({ at: task.updatedAt, event: "injection_failed", detail: task.lastInjectionError });
|
|
9607
|
-
events.sort((a, b) => a.at.localeCompare(b.at));
|
|
9608
|
-
const timeline = events.length > 0 ? ["- 时间线:", ...events.map((e) => ` - [${e.at}] ${e.event}${e.detail ? `: ${e.detail}` : ""}`)] : [];
|
|
9609
|
-
return [...header, ...timeline].join(`
|
|
9610
|
-
`);
|
|
9611
|
-
}
|
|
9612
|
-
function renderTaskCancelSuccess(task) {
|
|
9613
|
-
if (task.status === "completed" || task.status === "failed" || task.status === "cancelled") {
|
|
9614
|
-
return [`任务「${task.taskId}」已结束。`, `- 当前状态:${task.status}`].join(`
|
|
9615
|
-
`);
|
|
9616
|
-
}
|
|
9617
|
-
if (task.cancelRequestedAt) {
|
|
9618
|
-
return [`已请求取消任务「${task.taskId}」。`, `- 当前状态:${task.status}`].join(`
|
|
9619
|
-
`);
|
|
9620
|
-
}
|
|
9621
|
-
return [`任务「${task.taskId}」已取消。`, `- 当前状态:${task.status}`].join(`
|
|
9622
|
-
`);
|
|
9623
|
-
}
|
|
9624
|
-
function renderTaskApprovalSuccess(task) {
|
|
9625
|
-
return [`已批准任务「${task.taskId}」。`, `- 当前状态:${task.status}`].join(`
|
|
9626
|
-
`);
|
|
9627
|
-
}
|
|
9628
|
-
function renderTaskRejectionSuccess(task) {
|
|
9629
|
-
return [`已拒绝任务「${task.taskId}」。`, `- 当前状态:${task.status}`].join(`
|
|
9630
|
-
`);
|
|
9631
|
-
}
|
|
9632
|
-
function renderTaskConfirmationUnavailable(task) {
|
|
9633
|
-
return [`任务「${task.taskId}」当前不是待确认状态。`, `- 当前状态:${task.status}`].join(`
|
|
9634
|
-
`);
|
|
9635
|
-
}
|
|
9636
|
-
function renderTasksCleanResult(removedTasks, removedBindings) {
|
|
9637
|
-
if (removedTasks === 0 && removedBindings === 0) {
|
|
9638
|
-
return "当前协调会话下没有可清理的任务。";
|
|
9639
|
-
}
|
|
9640
|
-
const lines = [];
|
|
9641
|
-
if (removedTasks > 0) {
|
|
9642
|
-
lines.push(`已清理 ${removedTasks} 个已结束的任务。`);
|
|
9643
|
-
}
|
|
9644
|
-
if (removedBindings > 0) {
|
|
9645
|
-
lines.push(`已释放 ${removedBindings} 个无效的 worker 绑定。`);
|
|
9646
|
-
}
|
|
9647
|
-
return lines.join(`
|
|
9648
|
-
`);
|
|
9649
|
-
}
|
|
9650
|
-
function renderTaskListItem(task) {
|
|
9651
|
-
const role = task.role ? ` / ${task.role}` : "";
|
|
9652
|
-
const group = task.groupId ? `;组:${task.groupId}` : "";
|
|
9653
|
-
const summary = task.summary.trim().length > 0 ? `:${task.summary}` : "";
|
|
9654
|
-
const source = task.status === "needs_confirmation" ? `;来源:${task.sourceKind} / ${task.sourceHandle}${task.role ? ` / ${task.role}` : ""}` : "";
|
|
9655
|
-
const reliability = [
|
|
9656
|
-
task.noticePending ? "通知待重试" : "",
|
|
9657
|
-
task.injectionPending ? "注入待重试" : "",
|
|
9658
|
-
task.cancelRequestedAt && !task.cancelCompletedAt && task.status === "running" ? "取消中" : ""
|
|
9659
|
-
].filter(Boolean).map((item) => `;${item}`).join("");
|
|
9660
|
-
return `- ${task.taskId} [${task.status}] ${task.targetAgent}${role} -> ${task.workerSession ?? "未分配"}${group}${source}${summary}${reliability}`;
|
|
9661
|
-
}
|
|
9662
|
-
function renderGroupListItem(group) {
|
|
9663
|
-
const reliability = [
|
|
9664
|
-
group.group.injectionPending ? "注入待重试" : ""
|
|
9665
|
-
].filter(Boolean).map((item) => `;${item}`).join("");
|
|
9666
|
-
return [
|
|
9667
|
-
`- ${group.group.groupId}`,
|
|
9668
|
-
group.group.title,
|
|
9669
|
-
`总计 ${group.totalTasks}`,
|
|
9670
|
-
`待确认 ${group.pendingApprovalTasks}`,
|
|
9671
|
-
`运行中 ${group.runningTasks}`,
|
|
9672
|
-
`完成 ${group.completedTasks}`,
|
|
9673
|
-
`失败 ${group.failedTasks}`,
|
|
9674
|
-
`取消 ${group.cancelledTasks}${reliability}`
|
|
9675
|
-
].join(" | ");
|
|
9676
|
-
}
|
|
9677
|
-
function renderTaskProgress(task, summary) {
|
|
9678
|
-
return `⏳ 任务「${task.taskId}」(${task.targetAgent}):${summary}`;
|
|
9679
|
-
}
|
|
9680
|
-
function renderTaskHeartbeat(task, elapsedSeconds) {
|
|
9681
|
-
const minutes = Math.floor(elapsedSeconds / 60);
|
|
9682
|
-
return `⏳ 任务「${task.taskId}」已运行 ${minutes} 分钟,等待中...`;
|
|
9683
|
-
}
|
|
9684
|
-
|
|
9685
9480
|
// src/orchestration/task-wait-timeouts.ts
|
|
9686
9481
|
var DEFAULT_TASK_WAIT_TIMEOUT_MS, MAX_TASK_WAIT_TIMEOUT_MS, DEFAULT_TASK_WAIT_POLL_INTERVAL_MS = 1000, MAX_TASK_WAIT_POLL_INTERVAL_MS = 1e4, TASK_WAIT_RPC_TIMEOUT_PADDING_MS = 5000;
|
|
9687
9482
|
var init_task_wait_timeouts = __esm(() => {
|
|
@@ -16774,8 +16569,10 @@ async function handleSessionRemove(context, chatKey, alias) {
|
|
|
16774
16569
|
return { text: lines.join(`
|
|
16775
16570
|
`) };
|
|
16776
16571
|
}
|
|
16777
|
-
async function promptWithSession(context, session, chatKey, text, reply, replyContextToken, accountId, media) {
|
|
16572
|
+
async function promptWithSession(context, session, chatKey, text, reply, replyContextToken, accountId, media, abortSignal) {
|
|
16778
16573
|
const effectiveReplyMode = session.replyMode ?? context.config?.channel.replyMode ?? "verbose";
|
|
16574
|
+
if (!session.replyMode)
|
|
16575
|
+
session.replyMode = effectiveReplyMode;
|
|
16779
16576
|
const transportReply = effectiveReplyMode !== "final" ? reply : undefined;
|
|
16780
16577
|
if (context.orchestration) {
|
|
16781
16578
|
try {
|
|
@@ -16796,8 +16593,8 @@ async function promptWithSession(context, session, chatKey, text, reply, replyCo
|
|
|
16796
16593
|
}
|
|
16797
16594
|
const { promptText, taskIds, groupIds, claimHumanReply } = await preparePromptWithFallback(context, session, chatKey, text, replyContextToken, accountId);
|
|
16798
16595
|
try {
|
|
16799
|
-
const replyContext = transportReply && context.quota ? { chatKey, quota: context.quota } : undefined;
|
|
16800
|
-
const result = await context.interaction.promptTransportSession(session, promptText, transportReply, replyContext, media);
|
|
16596
|
+
const replyContext = transportReply && context.quota && getChannelIdFromChatKey(chatKey) === "weixin" ? { chatKey, quota: context.quota } : undefined;
|
|
16597
|
+
const result = await context.interaction.promptTransportSession(session, promptText, transportReply, replyContext, media, abortSignal);
|
|
16801
16598
|
if (claimHumanReply) {
|
|
16802
16599
|
try {
|
|
16803
16600
|
await context.orchestration?.claimActiveHumanReply?.(claimHumanReply);
|
|
@@ -16817,17 +16614,17 @@ async function promptWithSession(context, session, chatKey, text, reply, replyCo
|
|
|
16817
16614
|
throw error2;
|
|
16818
16615
|
}
|
|
16819
16616
|
}
|
|
16820
|
-
async function handlePrompt(context, chatKey, text, reply, replyContextToken, accountId, media) {
|
|
16617
|
+
async function handlePrompt(context, chatKey, text, reply, replyContextToken, accountId, media, abortSignal) {
|
|
16821
16618
|
const session = await context.sessions.getCurrentSession(chatKey);
|
|
16822
16619
|
if (!session) {
|
|
16823
16620
|
return { text: NO_CURRENT_SESSION_TEXT };
|
|
16824
16621
|
}
|
|
16825
16622
|
try {
|
|
16826
|
-
return await promptWithSession(context, session, chatKey, text, reply, replyContextToken, accountId, media);
|
|
16623
|
+
return await promptWithSession(context, session, chatKey, text, reply, replyContextToken, accountId, media, abortSignal);
|
|
16827
16624
|
} catch (error2) {
|
|
16828
16625
|
const recovered = await context.recovery.tryRecoverMissingSession(session, error2);
|
|
16829
16626
|
if (recovered) {
|
|
16830
|
-
return await promptWithSession(context, recovered, chatKey, text, reply, replyContextToken, accountId, media);
|
|
16627
|
+
return await promptWithSession(context, recovered, chatKey, text, reply, replyContextToken, accountId, media, abortSignal);
|
|
16831
16628
|
}
|
|
16832
16629
|
return context.recovery.renderTransportError(session, error2);
|
|
16833
16630
|
}
|
|
@@ -16855,107 +16652,312 @@ async function preparePromptWithFallback(context, session, chatKey, text, replyC
|
|
|
16855
16652
|
return { promptText: text, taskIds: [], groupIds: [] };
|
|
16856
16653
|
}
|
|
16857
16654
|
}
|
|
16858
|
-
async function markCoordinatorResultsInjected(context, taskIds, groupIds) {
|
|
16859
|
-
if (taskIds.length === 0 && groupIds.length === 0 || !context.orchestration) {
|
|
16860
|
-
return;
|
|
16861
|
-
}
|
|
16862
|
-
try {
|
|
16863
|
-
if (groupIds.length > 0) {
|
|
16864
|
-
await context.orchestration.markCoordinatorGroupsInjected?.(groupIds);
|
|
16865
|
-
}
|
|
16866
|
-
if (taskIds.length > 0) {
|
|
16867
|
-
await context.orchestration.markTaskInjectionApplied(taskIds);
|
|
16868
|
-
}
|
|
16869
|
-
} catch (error2) {
|
|
16870
|
-
await context.logger.error("orchestration.coordinator_results.mark_failed", "failed to mark coordinator results injected", {
|
|
16871
|
-
taskIds: taskIds.join(","),
|
|
16872
|
-
groupIds: groupIds.join(","),
|
|
16873
|
-
error: error2 instanceof Error ? error2.message : String(error2)
|
|
16874
|
-
});
|
|
16875
|
-
}
|
|
16655
|
+
async function markCoordinatorResultsInjected(context, taskIds, groupIds) {
|
|
16656
|
+
if (taskIds.length === 0 && groupIds.length === 0 || !context.orchestration) {
|
|
16657
|
+
return;
|
|
16658
|
+
}
|
|
16659
|
+
try {
|
|
16660
|
+
if (groupIds.length > 0) {
|
|
16661
|
+
await context.orchestration.markCoordinatorGroupsInjected?.(groupIds);
|
|
16662
|
+
}
|
|
16663
|
+
if (taskIds.length > 0) {
|
|
16664
|
+
await context.orchestration.markTaskInjectionApplied(taskIds);
|
|
16665
|
+
}
|
|
16666
|
+
} catch (error2) {
|
|
16667
|
+
await context.logger.error("orchestration.coordinator_results.mark_failed", "failed to mark coordinator results injected", {
|
|
16668
|
+
taskIds: taskIds.join(","),
|
|
16669
|
+
groupIds: groupIds.join(","),
|
|
16670
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
16671
|
+
});
|
|
16672
|
+
}
|
|
16673
|
+
}
|
|
16674
|
+
async function markCoordinatorResultsInjectionFailed(context, taskIds, groupIds, error2) {
|
|
16675
|
+
if (taskIds.length === 0 && groupIds.length === 0 || !context.orchestration) {
|
|
16676
|
+
return;
|
|
16677
|
+
}
|
|
16678
|
+
const errorMessage = error2 instanceof Error ? error2.message : String(error2);
|
|
16679
|
+
try {
|
|
16680
|
+
if (groupIds.length > 0) {
|
|
16681
|
+
await context.orchestration.markCoordinatorGroupsInjectionFailed?.(groupIds, errorMessage);
|
|
16682
|
+
}
|
|
16683
|
+
if (taskIds.length > 0) {
|
|
16684
|
+
await context.orchestration.markTaskInjectionFailed(taskIds, errorMessage);
|
|
16685
|
+
}
|
|
16686
|
+
} catch (markError) {
|
|
16687
|
+
await context.logger.error("orchestration.coordinator_results.mark_failed", "failed to mark coordinator results injection failure", {
|
|
16688
|
+
taskIds: taskIds.join(","),
|
|
16689
|
+
groupIds: groupIds.join(","),
|
|
16690
|
+
error: markError instanceof Error ? markError.message : String(markError)
|
|
16691
|
+
});
|
|
16692
|
+
}
|
|
16693
|
+
}
|
|
16694
|
+
var NO_CURRENT_SESSION_TEXT = "当前还没有选中的会话。请先执行 /session new ... 或 /use <alias>。", sessionHelp, modeHelp, replyModeHelp, statusHelp, cancelHelp;
|
|
16695
|
+
var init_session_handler = __esm(() => {
|
|
16696
|
+
init_build_coordinator_prompt();
|
|
16697
|
+
init_channel_scope();
|
|
16698
|
+
sessionHelp = {
|
|
16699
|
+
topic: "session",
|
|
16700
|
+
aliases: ["ss", "sessions"],
|
|
16701
|
+
summary: "创建、恢复、切换和重置逻辑会话。",
|
|
16702
|
+
commands: [
|
|
16703
|
+
{ usage: "/sessions", description: "查看当前会话列表" },
|
|
16704
|
+
{ usage: "/session 或 /ss", description: "查看会话列表" },
|
|
16705
|
+
{ usage: "/ss <agent> (-d <path> | --ws <name>)", description: "快速新建或复用一个会话" },
|
|
16706
|
+
{ usage: "/ss new <agent> (-d <path> | --ws <name>)", description: "强制新建会话" },
|
|
16707
|
+
{ usage: "/ss new <alias> -a <name> --ws <name>", description: "按指定配置新建会话" },
|
|
16708
|
+
{ usage: "/ss attach <alias> -a <name> --ws <name> --name <transport-session>", description: "绑定已有会话" },
|
|
16709
|
+
{ usage: "/session rm <alias>", description: "删除逻辑会话" },
|
|
16710
|
+
{ usage: "/use <alias>", description: "切换当前会话" },
|
|
16711
|
+
{ usage: "/session reset 或 /clear", description: "重置当前会话上下文" }
|
|
16712
|
+
],
|
|
16713
|
+
examples: ["/ss codex -d /absolute/path/to/repo", "/use backend-fix", "/session rm old-session", "/session reset"]
|
|
16714
|
+
};
|
|
16715
|
+
modeHelp = {
|
|
16716
|
+
topic: "mode",
|
|
16717
|
+
aliases: [],
|
|
16718
|
+
summary: "查看或设置当前会话 mode。",
|
|
16719
|
+
commands: [
|
|
16720
|
+
{ usage: "/mode", description: "查看当前会话已保存的 mode" },
|
|
16721
|
+
{ usage: "/mode <id>", description: "设置当前会话 mode" }
|
|
16722
|
+
],
|
|
16723
|
+
examples: ["/mode", "/mode plan"]
|
|
16724
|
+
};
|
|
16725
|
+
replyModeHelp = {
|
|
16726
|
+
topic: "replymode",
|
|
16727
|
+
aliases: [],
|
|
16728
|
+
summary: "查看或设置当前逻辑会话的回复输出模式。",
|
|
16729
|
+
commands: [
|
|
16730
|
+
{ usage: "/replymode", description: "查看全局默认、当前覆盖和实际生效值" },
|
|
16731
|
+
{ usage: "/replymode stream", description: "当前会话使用流式回复" },
|
|
16732
|
+
{ usage: "/replymode verbose", description: "当前会话流式回复并显示工具调用" },
|
|
16733
|
+
{ usage: "/replymode final", description: "当前会话只发送最终文本" },
|
|
16734
|
+
{ usage: "/replymode reset", description: "清除当前会话覆盖并回退到全局默认" }
|
|
16735
|
+
],
|
|
16736
|
+
examples: ["/replymode", "/replymode final", "/replymode verbose"]
|
|
16737
|
+
};
|
|
16738
|
+
statusHelp = {
|
|
16739
|
+
topic: "status",
|
|
16740
|
+
aliases: [],
|
|
16741
|
+
summary: "查看当前选中会话的状态。",
|
|
16742
|
+
commands: [{ usage: "/status", description: "查看当前会话状态" }],
|
|
16743
|
+
examples: ["/status"]
|
|
16744
|
+
};
|
|
16745
|
+
cancelHelp = {
|
|
16746
|
+
topic: "cancel",
|
|
16747
|
+
aliases: ["stop"],
|
|
16748
|
+
summary: "取消当前会话里正在执行的任务。",
|
|
16749
|
+
commands: [
|
|
16750
|
+
{ usage: "/cancel", description: "取消当前任务" },
|
|
16751
|
+
{ usage: "/stop", description: "取消当前任务(/cancel 别名)" }
|
|
16752
|
+
],
|
|
16753
|
+
examples: ["/cancel"]
|
|
16754
|
+
};
|
|
16755
|
+
});
|
|
16756
|
+
|
|
16757
|
+
// src/formatting/render-text.ts
|
|
16758
|
+
function renderAgents(config2) {
|
|
16759
|
+
const names = Object.keys(config2.agents);
|
|
16760
|
+
if (names.length === 0) {
|
|
16761
|
+
return "还没有注册任何 Agent。";
|
|
16762
|
+
}
|
|
16763
|
+
return ["已注册的 Agent:", ...names.map((name) => `- ${name}`)].join(`
|
|
16764
|
+
`);
|
|
16765
|
+
}
|
|
16766
|
+
function renderWorkspaces(config2) {
|
|
16767
|
+
const names = Object.entries(config2.workspaces);
|
|
16768
|
+
if (names.length === 0) {
|
|
16769
|
+
return "还没有注册任何工作区。";
|
|
16770
|
+
}
|
|
16771
|
+
return ["已注册的工作区:", ...names.map(([name, workspace]) => `- ${name}: ${workspace.cwd}`)].join(`
|
|
16772
|
+
`);
|
|
16773
|
+
}
|
|
16774
|
+
function renderOrchestrationUnavailable() {
|
|
16775
|
+
return "当前未启用任务编排服务。";
|
|
16776
|
+
}
|
|
16777
|
+
function renderDelegateSuccess2(taskId, workerSession) {
|
|
16778
|
+
return [`已创建委派任务「${taskId}」`, `worker 会话:${workerSession}`].join(`
|
|
16779
|
+
`);
|
|
16780
|
+
}
|
|
16781
|
+
function renderGroupCreated2(group) {
|
|
16782
|
+
return [`已创建任务组「${group.groupId}」`, `- 标题:${group.title}`].join(`
|
|
16783
|
+
`);
|
|
16784
|
+
}
|
|
16785
|
+
function renderGroupList2(groups) {
|
|
16786
|
+
if (groups.length === 0) {
|
|
16787
|
+
return "当前协调会话下还没有任务组。";
|
|
16788
|
+
}
|
|
16789
|
+
return ["当前协调会话的任务组:", ...groups.map((group) => renderGroupListItem2(group))].join(`
|
|
16790
|
+
`);
|
|
16791
|
+
}
|
|
16792
|
+
function renderGroupSummary2(summary) {
|
|
16793
|
+
const { group, tasks } = summary;
|
|
16794
|
+
const lines = [
|
|
16795
|
+
`任务组「${group.groupId}」`,
|
|
16796
|
+
`- 标题:${group.title}`,
|
|
16797
|
+
`- 协调会话:${group.coordinatorSession}`,
|
|
16798
|
+
`- 总任务数:${summary.totalTasks}`,
|
|
16799
|
+
`- 待确认:${summary.pendingApprovalTasks}`,
|
|
16800
|
+
`- 运行中:${summary.runningTasks}`,
|
|
16801
|
+
`- 已完成:${summary.completedTasks}`,
|
|
16802
|
+
`- 已失败:${summary.failedTasks}`,
|
|
16803
|
+
`- 已取消:${summary.cancelledTasks}`,
|
|
16804
|
+
`- 是否终态:${summary.terminal ? "是" : "否"}`
|
|
16805
|
+
];
|
|
16806
|
+
if (group.injectionPending !== undefined) {
|
|
16807
|
+
lines.push(`- 注入待处理:${group.injectionPending ? "是" : "否"}`);
|
|
16808
|
+
}
|
|
16809
|
+
if (group.injectionAppliedAt) {
|
|
16810
|
+
lines.push(`- 注入完成时间:${group.injectionAppliedAt}`);
|
|
16811
|
+
}
|
|
16812
|
+
if (group.lastInjectionError) {
|
|
16813
|
+
lines.push(`- 最近注入错误:${group.lastInjectionError}`);
|
|
16814
|
+
}
|
|
16815
|
+
if (tasks.length > 0) {
|
|
16816
|
+
lines.push("- 成员:");
|
|
16817
|
+
for (const task of tasks) {
|
|
16818
|
+
lines.push(` - ${task.taskId} [${task.status}] ${task.targetAgent}`);
|
|
16819
|
+
}
|
|
16820
|
+
}
|
|
16821
|
+
return lines.join(`
|
|
16822
|
+
`);
|
|
16823
|
+
}
|
|
16824
|
+
function renderGroupCancelSuccess2(input) {
|
|
16825
|
+
return [
|
|
16826
|
+
`任务组「${input.summary.group.groupId}」已发起取消`,
|
|
16827
|
+
`- 已请求取消:${input.cancelledTaskIds.length}`,
|
|
16828
|
+
`- 已跳过终态任务:${input.skippedTaskIds.length}`
|
|
16829
|
+
].join(`
|
|
16830
|
+
`);
|
|
16831
|
+
}
|
|
16832
|
+
function renderTaskList2(tasks) {
|
|
16833
|
+
if (tasks.length === 0) {
|
|
16834
|
+
return "当前协调会话下还没有任务。";
|
|
16835
|
+
}
|
|
16836
|
+
return ["当前协调会话的任务:", ...tasks.map((task) => renderTaskListItem2(task))].join(`
|
|
16837
|
+
`);
|
|
16838
|
+
}
|
|
16839
|
+
function renderTaskSummary2(task) {
|
|
16840
|
+
const header = [
|
|
16841
|
+
`任务「${task.taskId}」`,
|
|
16842
|
+
`- 状态:${task.status}`,
|
|
16843
|
+
`- 协调会话:${task.coordinatorSession}`,
|
|
16844
|
+
`- worker 会话:${task.workerSession ?? "未分配"}`,
|
|
16845
|
+
`- 目标 Agent:${task.targetAgent}`
|
|
16846
|
+
];
|
|
16847
|
+
if (task.role)
|
|
16848
|
+
header.push(`- 角色:${task.role}`);
|
|
16849
|
+
if (task.groupId)
|
|
16850
|
+
header.push(`- 任务组:${task.groupId}`);
|
|
16851
|
+
if (task.status === "needs_confirmation") {
|
|
16852
|
+
header.push(`- 来源:${task.sourceKind} / ${task.sourceHandle}${task.role ? ` / ${task.role}` : ""}`);
|
|
16853
|
+
}
|
|
16854
|
+
header.push(`- 任务:${task.task}`);
|
|
16855
|
+
if (task.summary.trim().length > 0)
|
|
16856
|
+
header.push(`- 摘要:${task.summary}`);
|
|
16857
|
+
if (task.resultText.trim().length > 0)
|
|
16858
|
+
header.push(`- 结果:${task.resultText}`);
|
|
16859
|
+
const events = [];
|
|
16860
|
+
events.push({ at: task.createdAt, event: "created" });
|
|
16861
|
+
if (task.workerSession && task.status !== "needs_confirmation") {
|
|
16862
|
+
events.push({ at: task.createdAt, event: "dispatched", detail: task.workerSession });
|
|
16863
|
+
}
|
|
16864
|
+
if (task.lastProgressAt)
|
|
16865
|
+
events.push({ at: task.lastProgressAt, event: "last_progress" });
|
|
16866
|
+
if (task.cancelRequestedAt)
|
|
16867
|
+
events.push({ at: task.cancelRequestedAt, event: "cancel_requested" });
|
|
16868
|
+
if (task.cancelCompletedAt)
|
|
16869
|
+
events.push({ at: task.cancelCompletedAt, event: "cancel_completed" });
|
|
16870
|
+
if (task.lastCancelError)
|
|
16871
|
+
events.push({ at: task.updatedAt, event: "cancel_failed", detail: task.lastCancelError });
|
|
16872
|
+
if (task.status === "completed")
|
|
16873
|
+
events.push({ at: task.updatedAt, event: "completed" });
|
|
16874
|
+
if (task.status === "failed")
|
|
16875
|
+
events.push({ at: task.updatedAt, event: "failed" });
|
|
16876
|
+
if (task.noticeSentAt)
|
|
16877
|
+
events.push({ at: task.noticeSentAt, event: "notice_sent", detail: task.deliveryAccountId });
|
|
16878
|
+
if (task.lastNoticeError)
|
|
16879
|
+
events.push({ at: task.updatedAt, event: "notice_failed", detail: task.lastNoticeError });
|
|
16880
|
+
if (task.injectionAppliedAt)
|
|
16881
|
+
events.push({ at: task.injectionAppliedAt, event: "injection_applied" });
|
|
16882
|
+
if (task.lastInjectionError)
|
|
16883
|
+
events.push({ at: task.updatedAt, event: "injection_failed", detail: task.lastInjectionError });
|
|
16884
|
+
events.sort((a, b) => a.at.localeCompare(b.at));
|
|
16885
|
+
const timeline = events.length > 0 ? ["- 时间线:", ...events.map((e) => ` - [${e.at}] ${e.event}${e.detail ? `: ${e.detail}` : ""}`)] : [];
|
|
16886
|
+
return [...header, ...timeline].join(`
|
|
16887
|
+
`);
|
|
16888
|
+
}
|
|
16889
|
+
function renderTaskCancelSuccess(task) {
|
|
16890
|
+
if (task.status === "completed" || task.status === "failed" || task.status === "cancelled") {
|
|
16891
|
+
return [`任务「${task.taskId}」已结束。`, `- 当前状态:${task.status}`].join(`
|
|
16892
|
+
`);
|
|
16893
|
+
}
|
|
16894
|
+
if (task.cancelRequestedAt) {
|
|
16895
|
+
return [`已请求取消任务「${task.taskId}」。`, `- 当前状态:${task.status}`].join(`
|
|
16896
|
+
`);
|
|
16897
|
+
}
|
|
16898
|
+
return [`任务「${task.taskId}」已取消。`, `- 当前状态:${task.status}`].join(`
|
|
16899
|
+
`);
|
|
16900
|
+
}
|
|
16901
|
+
function renderTaskApprovalSuccess2(task) {
|
|
16902
|
+
return [`已批准任务「${task.taskId}」。`, `- 当前状态:${task.status}`].join(`
|
|
16903
|
+
`);
|
|
16904
|
+
}
|
|
16905
|
+
function renderTaskRejectionSuccess2(task) {
|
|
16906
|
+
return [`已拒绝任务「${task.taskId}」。`, `- 当前状态:${task.status}`].join(`
|
|
16907
|
+
`);
|
|
16908
|
+
}
|
|
16909
|
+
function renderTaskConfirmationUnavailable(task) {
|
|
16910
|
+
return [`任务「${task.taskId}」当前不是待确认状态。`, `- 当前状态:${task.status}`].join(`
|
|
16911
|
+
`);
|
|
16912
|
+
}
|
|
16913
|
+
function renderTasksCleanResult(removedTasks, removedBindings) {
|
|
16914
|
+
if (removedTasks === 0 && removedBindings === 0) {
|
|
16915
|
+
return "当前协调会话下没有可清理的任务。";
|
|
16916
|
+
}
|
|
16917
|
+
const lines = [];
|
|
16918
|
+
if (removedTasks > 0) {
|
|
16919
|
+
lines.push(`已清理 ${removedTasks} 个已结束的任务。`);
|
|
16920
|
+
}
|
|
16921
|
+
if (removedBindings > 0) {
|
|
16922
|
+
lines.push(`已释放 ${removedBindings} 个无效的 worker 绑定。`);
|
|
16923
|
+
}
|
|
16924
|
+
return lines.join(`
|
|
16925
|
+
`);
|
|
16926
|
+
}
|
|
16927
|
+
function renderTaskListItem2(task) {
|
|
16928
|
+
const role = task.role ? ` / ${task.role}` : "";
|
|
16929
|
+
const group = task.groupId ? `;组:${task.groupId}` : "";
|
|
16930
|
+
const summary = task.summary.trim().length > 0 ? `:${task.summary}` : "";
|
|
16931
|
+
const source = task.status === "needs_confirmation" ? `;来源:${task.sourceKind} / ${task.sourceHandle}${task.role ? ` / ${task.role}` : ""}` : "";
|
|
16932
|
+
const reliability = [
|
|
16933
|
+
task.noticePending ? "通知待重试" : "",
|
|
16934
|
+
task.injectionPending ? "注入待重试" : "",
|
|
16935
|
+
task.cancelRequestedAt && !task.cancelCompletedAt && task.status === "running" ? "取消中" : ""
|
|
16936
|
+
].filter(Boolean).map((item) => `;${item}`).join("");
|
|
16937
|
+
return `- ${task.taskId} [${task.status}] ${task.targetAgent}${role} -> ${task.workerSession ?? "未分配"}${group}${source}${summary}${reliability}`;
|
|
16938
|
+
}
|
|
16939
|
+
function renderGroupListItem2(group) {
|
|
16940
|
+
const reliability = [
|
|
16941
|
+
group.group.injectionPending ? "注入待重试" : ""
|
|
16942
|
+
].filter(Boolean).map((item) => `;${item}`).join("");
|
|
16943
|
+
return [
|
|
16944
|
+
`- ${group.group.groupId}`,
|
|
16945
|
+
group.group.title,
|
|
16946
|
+
`总计 ${group.totalTasks}`,
|
|
16947
|
+
`待确认 ${group.pendingApprovalTasks}`,
|
|
16948
|
+
`运行中 ${group.runningTasks}`,
|
|
16949
|
+
`完成 ${group.completedTasks}`,
|
|
16950
|
+
`失败 ${group.failedTasks}`,
|
|
16951
|
+
`取消 ${group.cancelledTasks}${reliability}`
|
|
16952
|
+
].join(" | ");
|
|
16953
|
+
}
|
|
16954
|
+
function renderTaskProgress(task, summary) {
|
|
16955
|
+
return `⏳ 任务「${task.taskId}」(${task.targetAgent}):${summary}`;
|
|
16876
16956
|
}
|
|
16877
|
-
|
|
16878
|
-
|
|
16879
|
-
|
|
16880
|
-
}
|
|
16881
|
-
const errorMessage = error2 instanceof Error ? error2.message : String(error2);
|
|
16882
|
-
try {
|
|
16883
|
-
if (groupIds.length > 0) {
|
|
16884
|
-
await context.orchestration.markCoordinatorGroupsInjectionFailed?.(groupIds, errorMessage);
|
|
16885
|
-
}
|
|
16886
|
-
if (taskIds.length > 0) {
|
|
16887
|
-
await context.orchestration.markTaskInjectionFailed(taskIds, errorMessage);
|
|
16888
|
-
}
|
|
16889
|
-
} catch (markError) {
|
|
16890
|
-
await context.logger.error("orchestration.coordinator_results.mark_failed", "failed to mark coordinator results injection failure", {
|
|
16891
|
-
taskIds: taskIds.join(","),
|
|
16892
|
-
groupIds: groupIds.join(","),
|
|
16893
|
-
error: markError instanceof Error ? markError.message : String(markError)
|
|
16894
|
-
});
|
|
16895
|
-
}
|
|
16957
|
+
function renderTaskHeartbeat(task, elapsedSeconds) {
|
|
16958
|
+
const minutes = Math.floor(elapsedSeconds / 60);
|
|
16959
|
+
return `⏳ 任务「${task.taskId}」已运行 ${minutes} 分钟,等待中...`;
|
|
16896
16960
|
}
|
|
16897
|
-
var NO_CURRENT_SESSION_TEXT = "当前还没有选中的会话。请先执行 /session new ... 或 /use <alias>。", sessionHelp, modeHelp, replyModeHelp, statusHelp, cancelHelp;
|
|
16898
|
-
var init_session_handler = __esm(() => {
|
|
16899
|
-
init_build_coordinator_prompt();
|
|
16900
|
-
init_channel_scope();
|
|
16901
|
-
sessionHelp = {
|
|
16902
|
-
topic: "session",
|
|
16903
|
-
aliases: ["ss", "sessions"],
|
|
16904
|
-
summary: "创建、恢复、切换和重置逻辑会话。",
|
|
16905
|
-
commands: [
|
|
16906
|
-
{ usage: "/sessions", description: "查看当前会话列表" },
|
|
16907
|
-
{ usage: "/session 或 /ss", description: "查看会话列表" },
|
|
16908
|
-
{ usage: "/ss <agent> (-d <path> | --ws <name>)", description: "快速新建或复用一个会话" },
|
|
16909
|
-
{ usage: "/ss new <agent> (-d <path> | --ws <name>)", description: "强制新建会话" },
|
|
16910
|
-
{ usage: "/ss new <alias> -a <name> --ws <name>", description: "按指定配置新建会话" },
|
|
16911
|
-
{ usage: "/ss attach <alias> -a <name> --ws <name> --name <transport-session>", description: "绑定已有会话" },
|
|
16912
|
-
{ usage: "/session rm <alias>", description: "删除逻辑会话" },
|
|
16913
|
-
{ usage: "/use <alias>", description: "切换当前会话" },
|
|
16914
|
-
{ usage: "/session reset 或 /clear", description: "重置当前会话上下文" }
|
|
16915
|
-
],
|
|
16916
|
-
examples: ["/ss codex -d /absolute/path/to/repo", "/use backend-fix", "/session rm old-session", "/session reset"]
|
|
16917
|
-
};
|
|
16918
|
-
modeHelp = {
|
|
16919
|
-
topic: "mode",
|
|
16920
|
-
aliases: [],
|
|
16921
|
-
summary: "查看或设置当前会话 mode。",
|
|
16922
|
-
commands: [
|
|
16923
|
-
{ usage: "/mode", description: "查看当前会话已保存的 mode" },
|
|
16924
|
-
{ usage: "/mode <id>", description: "设置当前会话 mode" }
|
|
16925
|
-
],
|
|
16926
|
-
examples: ["/mode", "/mode plan"]
|
|
16927
|
-
};
|
|
16928
|
-
replyModeHelp = {
|
|
16929
|
-
topic: "replymode",
|
|
16930
|
-
aliases: [],
|
|
16931
|
-
summary: "查看或设置当前逻辑会话的回复输出模式。",
|
|
16932
|
-
commands: [
|
|
16933
|
-
{ usage: "/replymode", description: "查看全局默认、当前覆盖和实际生效值" },
|
|
16934
|
-
{ usage: "/replymode stream", description: "当前会话使用流式回复" },
|
|
16935
|
-
{ usage: "/replymode verbose", description: "当前会话流式回复并显示工具调用" },
|
|
16936
|
-
{ usage: "/replymode final", description: "当前会话只发送最终文本" },
|
|
16937
|
-
{ usage: "/replymode reset", description: "清除当前会话覆盖并回退到全局默认" }
|
|
16938
|
-
],
|
|
16939
|
-
examples: ["/replymode", "/replymode final", "/replymode verbose"]
|
|
16940
|
-
};
|
|
16941
|
-
statusHelp = {
|
|
16942
|
-
topic: "status",
|
|
16943
|
-
aliases: [],
|
|
16944
|
-
summary: "查看当前选中会话的状态。",
|
|
16945
|
-
commands: [{ usage: "/status", description: "查看当前会话状态" }],
|
|
16946
|
-
examples: ["/status"]
|
|
16947
|
-
};
|
|
16948
|
-
cancelHelp = {
|
|
16949
|
-
topic: "cancel",
|
|
16950
|
-
aliases: ["stop"],
|
|
16951
|
-
summary: "取消当前会话里正在执行的任务。",
|
|
16952
|
-
commands: [
|
|
16953
|
-
{ usage: "/cancel", description: "取消当前任务" },
|
|
16954
|
-
{ usage: "/stop", description: "取消当前任务(/cancel 别名)" }
|
|
16955
|
-
],
|
|
16956
|
-
examples: ["/cancel"]
|
|
16957
|
-
};
|
|
16958
|
-
});
|
|
16959
16961
|
|
|
16960
16962
|
// src/commands/handlers/orchestration-handler.ts
|
|
16961
16963
|
async function handleDelegateRequest(context, chatKey, targetAgent, task, role, groupId, replyContextToken, accountId) {
|
|
@@ -16980,7 +16982,7 @@ async function handleDelegateRequest(context, chatKey, targetAgent, task, role,
|
|
|
16980
16982
|
...replyContextToken ? { replyContextToken } : {},
|
|
16981
16983
|
...accountId ? { accountId } : {}
|
|
16982
16984
|
});
|
|
16983
|
-
return { text:
|
|
16985
|
+
return { text: renderDelegateSuccess2(result.taskId, result.workerSession) };
|
|
16984
16986
|
}
|
|
16985
16987
|
async function handleGroupCreate(context, chatKey, title) {
|
|
16986
16988
|
const session = await getCurrentSession(context, chatKey);
|
|
@@ -16995,7 +16997,7 @@ async function handleGroupCreate(context, chatKey, title) {
|
|
|
16995
16997
|
coordinatorSession: session.transportSession,
|
|
16996
16998
|
title
|
|
16997
16999
|
});
|
|
16998
|
-
return { text:
|
|
17000
|
+
return { text: renderGroupCreated2(group) };
|
|
16999
17001
|
}
|
|
17000
17002
|
async function handleGroupList(context, chatKey, filter) {
|
|
17001
17003
|
const session = await getCurrentSession(context, chatKey);
|
|
@@ -17010,7 +17012,7 @@ async function handleGroupList(context, chatKey, filter) {
|
|
|
17010
17012
|
coordinatorSession: session.transportSession,
|
|
17011
17013
|
...filter ?? {}
|
|
17012
17014
|
});
|
|
17013
|
-
return { text:
|
|
17015
|
+
return { text: renderGroupList2(groups) };
|
|
17014
17016
|
}
|
|
17015
17017
|
async function handleGroupGet(context, chatKey, groupId) {
|
|
17016
17018
|
const session = await getCurrentSession(context, chatKey);
|
|
@@ -17028,7 +17030,7 @@ async function handleGroupGet(context, chatKey, groupId) {
|
|
|
17028
17030
|
if (!group) {
|
|
17029
17031
|
return { text: GROUP_NOT_FOUND_TEXT };
|
|
17030
17032
|
}
|
|
17031
|
-
return { text:
|
|
17033
|
+
return { text: renderGroupSummary2(group) };
|
|
17032
17034
|
}
|
|
17033
17035
|
async function handleGroupCancel(context, chatKey, groupId) {
|
|
17034
17036
|
const session = await getCurrentSession(context, chatKey);
|
|
@@ -17050,7 +17052,7 @@ async function handleGroupCancel(context, chatKey, groupId) {
|
|
|
17050
17052
|
groupId,
|
|
17051
17053
|
coordinatorSession: session.transportSession
|
|
17052
17054
|
});
|
|
17053
|
-
return { text:
|
|
17055
|
+
return { text: renderGroupCancelSuccess2(cancelled) };
|
|
17054
17056
|
}
|
|
17055
17057
|
async function handleGroupDelegate(context, chatKey, groupId, targetAgent, task, role, replyContextToken, accountId) {
|
|
17056
17058
|
const session = await getCurrentSession(context, chatKey);
|
|
@@ -17083,7 +17085,7 @@ async function handleTaskList(context, chatKey, filter) {
|
|
|
17083
17085
|
coordinatorSession: session.transportSession,
|
|
17084
17086
|
...filter ?? {}
|
|
17085
17087
|
});
|
|
17086
|
-
return { text:
|
|
17088
|
+
return { text: renderTaskList2(tasks) };
|
|
17087
17089
|
}
|
|
17088
17090
|
async function handleTaskGet(context, chatKey, taskId) {
|
|
17089
17091
|
const session = await getCurrentSession(context, chatKey);
|
|
@@ -17098,7 +17100,7 @@ async function handleTaskGet(context, chatKey, taskId) {
|
|
|
17098
17100
|
if (!task || task.coordinatorSession !== session.transportSession) {
|
|
17099
17101
|
return { text: TASK_NOT_FOUND_TEXT };
|
|
17100
17102
|
}
|
|
17101
|
-
return { text:
|
|
17103
|
+
return { text: renderTaskSummary2(task) };
|
|
17102
17104
|
}
|
|
17103
17105
|
async function handleTaskApprove(context, chatKey, taskId) {
|
|
17104
17106
|
const session = await getCurrentSession(context, chatKey);
|
|
@@ -17120,7 +17122,7 @@ async function handleTaskApprove(context, chatKey, taskId) {
|
|
|
17120
17122
|
taskId,
|
|
17121
17123
|
coordinatorSession: session.transportSession
|
|
17122
17124
|
});
|
|
17123
|
-
return { text:
|
|
17125
|
+
return { text: renderTaskApprovalSuccess2(approved) };
|
|
17124
17126
|
}
|
|
17125
17127
|
async function handleTaskReject(context, chatKey, taskId) {
|
|
17126
17128
|
const session = await getCurrentSession(context, chatKey);
|
|
@@ -17142,7 +17144,7 @@ async function handleTaskReject(context, chatKey, taskId) {
|
|
|
17142
17144
|
taskId,
|
|
17143
17145
|
coordinatorSession: session.transportSession
|
|
17144
17146
|
});
|
|
17145
|
-
return { text:
|
|
17147
|
+
return { text: renderTaskRejectionSuccess2(rejected) };
|
|
17146
17148
|
}
|
|
17147
17149
|
async function handleTaskCancel(context, chatKey, taskId) {
|
|
17148
17150
|
const session = await getCurrentSession(context, chatKey);
|
|
@@ -18148,7 +18150,7 @@ class CommandRouter {
|
|
|
18148
18150
|
this.quota = quota;
|
|
18149
18151
|
this.logger = logger2 ?? createNoopAppLogger();
|
|
18150
18152
|
}
|
|
18151
|
-
async handle(chatKey, input, reply, replyContextToken, accountId, media, metadata) {
|
|
18153
|
+
async handle(chatKey, input, reply, replyContextToken, accountId, media, metadata, abortSignal) {
|
|
18152
18154
|
const startedAt = Date.now();
|
|
18153
18155
|
const command = parseCommand(input);
|
|
18154
18156
|
await this.logger.debug("command.parsed", "parsed inbound command", {
|
|
@@ -18262,7 +18264,7 @@ class CommandRouter {
|
|
|
18262
18264
|
case "task.cancel":
|
|
18263
18265
|
return await handleTaskCancel(this.createHandlerContext(), chatKey, command.taskId);
|
|
18264
18266
|
case "prompt":
|
|
18265
|
-
return await handlePrompt(this.createSessionHandlerContext(), chatKey, command.text, reply, replyContextToken, accountId, media);
|
|
18267
|
+
return await handlePrompt(this.createSessionHandlerContext(), chatKey, command.text, reply, replyContextToken, accountId, media, abortSignal);
|
|
18266
18268
|
}
|
|
18267
18269
|
});
|
|
18268
18270
|
}
|
|
@@ -18314,7 +18316,7 @@ class CommandRouter {
|
|
|
18314
18316
|
return {
|
|
18315
18317
|
setModeTransportSession: (session, modeId) => this.setModeTransportSession(session, modeId),
|
|
18316
18318
|
cancelTransportSession: (session) => this.cancelTransportSession(session),
|
|
18317
|
-
promptTransportSession: (session, text, reply, replyContext, media) => this.promptTransportSession(session, text, reply, replyContext, media)
|
|
18319
|
+
promptTransportSession: (session, text, reply, replyContext, media, abortSignal) => this.promptTransportSession(session, text, reply, replyContext, media, abortSignal)
|
|
18318
18320
|
};
|
|
18319
18321
|
}
|
|
18320
18322
|
createSessionRenderRecoveryOps() {
|
|
@@ -18477,9 +18479,50 @@ class CommandRouter {
|
|
|
18477
18479
|
async checkTransportSession(session) {
|
|
18478
18480
|
return await this.measureTransportCall("has_session", session, () => this.transport.hasSession(session));
|
|
18479
18481
|
}
|
|
18480
|
-
async promptTransportSession(session, text, reply, replyContext, media) {
|
|
18482
|
+
async promptTransportSession(session, text, reply, replyContext, media, abortSignal) {
|
|
18481
18483
|
session.mcpCoordinatorSession ??= session.transportSession;
|
|
18482
|
-
|
|
18484
|
+
let done = false;
|
|
18485
|
+
let cancelOnAbort;
|
|
18486
|
+
const fireCancel = () => {
|
|
18487
|
+
if (done)
|
|
18488
|
+
return;
|
|
18489
|
+
try {
|
|
18490
|
+
const result = this.transport.cancel(session);
|
|
18491
|
+
if (result && typeof result.catch === "function") {
|
|
18492
|
+
result.catch(async (error2) => {
|
|
18493
|
+
await this.logger.error("transport.cancel_on_abort_failed", "transport cancel triggered by abort signal failed", {
|
|
18494
|
+
agent: session.agent,
|
|
18495
|
+
workspace: session.workspace,
|
|
18496
|
+
alias: session.alias,
|
|
18497
|
+
message: error2 instanceof Error ? error2.message : String(error2)
|
|
18498
|
+
});
|
|
18499
|
+
});
|
|
18500
|
+
}
|
|
18501
|
+
} catch (error2) {
|
|
18502
|
+
this.logger.error("transport.cancel_on_abort_failed", "transport cancel triggered by abort signal threw synchronously", {
|
|
18503
|
+
agent: session.agent,
|
|
18504
|
+
workspace: session.workspace,
|
|
18505
|
+
alias: session.alias,
|
|
18506
|
+
message: error2 instanceof Error ? error2.message : String(error2)
|
|
18507
|
+
});
|
|
18508
|
+
}
|
|
18509
|
+
};
|
|
18510
|
+
if (abortSignal) {
|
|
18511
|
+
if (abortSignal.aborted) {
|
|
18512
|
+
done = true;
|
|
18513
|
+
throw new DOMException("Aborted before prompt started", "AbortError");
|
|
18514
|
+
}
|
|
18515
|
+
cancelOnAbort = fireCancel;
|
|
18516
|
+
abortSignal.addEventListener("abort", cancelOnAbort, { once: true });
|
|
18517
|
+
}
|
|
18518
|
+
try {
|
|
18519
|
+
return await this.measureTransportCall("prompt", session, () => this.transport.prompt(session, text, reply, replyContext, media ? { media } : undefined));
|
|
18520
|
+
} finally {
|
|
18521
|
+
done = true;
|
|
18522
|
+
if (cancelOnAbort && abortSignal) {
|
|
18523
|
+
abortSignal.removeEventListener("abort", cancelOnAbort);
|
|
18524
|
+
}
|
|
18525
|
+
}
|
|
18483
18526
|
}
|
|
18484
18527
|
async setModeTransportSession(session, modeId) {
|
|
18485
18528
|
return await this.measureTransportCall("set_mode", session, () => this.transport.setMode(session, modeId));
|
|
@@ -18624,7 +18667,7 @@ class ConsoleAgent {
|
|
|
18624
18667
|
mimeType: m.mimeType,
|
|
18625
18668
|
...m.fileName ? { fileName: m.fileName } : {}
|
|
18626
18669
|
})) : undefined;
|
|
18627
|
-
return await this.router.handle(request.conversationId, request.text, request.reply, request.replyContextToken, request.accountId, promptMedia, request.metadata);
|
|
18670
|
+
return await this.router.handle(request.conversationId, request.text, request.reply, request.replyContextToken, request.accountId, promptMedia, request.metadata, request.abortSignal);
|
|
18628
18671
|
}
|
|
18629
18672
|
isKnownCommand(text) {
|
|
18630
18673
|
return isKnownWeacpxCommandText(text);
|
|
@@ -23203,7 +23246,7 @@ ${result.text}` : "" };
|
|
|
23203
23246
|
name: session.transportSession,
|
|
23204
23247
|
mcpCoordinatorSession: session.mcpCoordinatorSession,
|
|
23205
23248
|
mcpSourceHandle: session.mcpSourceHandle,
|
|
23206
|
-
|
|
23249
|
+
replyMode: session.replyMode ?? "verbose"
|
|
23207
23250
|
};
|
|
23208
23251
|
}
|
|
23209
23252
|
}
|
|
@@ -23442,26 +23485,32 @@ function formatToolCallEvent(update, sessionUpdate) {
|
|
|
23442
23485
|
if (title.length === 0)
|
|
23443
23486
|
return null;
|
|
23444
23487
|
const emoji2 = KIND_EMOJI[kind] ?? "\uD83D\uDD27";
|
|
23445
|
-
const
|
|
23446
|
-
|
|
23447
|
-
|
|
23448
|
-
}
|
|
23449
|
-
if (sessionUpdate === "tool_call_update" || isGenericToolTitle(kind, title))
|
|
23488
|
+
const inputSummary = summarizeToolInput(update.rawInput);
|
|
23489
|
+
const status = readString(update, "status");
|
|
23490
|
+
if (!inputSummary && isGenericToolTitle(kind, title))
|
|
23450
23491
|
return null;
|
|
23451
|
-
|
|
23492
|
+
const summaryText = inputSummary ? `: ${truncateToolDisplay(inputSummary)}` : "";
|
|
23493
|
+
const statusText = status ? ` (${status})` : "";
|
|
23494
|
+
return `${emoji2} ${title}${statusText}${summaryText}`;
|
|
23452
23495
|
}
|
|
23453
|
-
function
|
|
23454
|
-
if (
|
|
23455
|
-
return
|
|
23456
|
-
|
|
23457
|
-
|
|
23458
|
-
|
|
23496
|
+
function summarizeToolInput(rawInput) {
|
|
23497
|
+
if (rawInput == null)
|
|
23498
|
+
return;
|
|
23499
|
+
if (typeof rawInput === "string" || typeof rawInput === "number" || typeof rawInput === "boolean") {
|
|
23500
|
+
return String(rawInput);
|
|
23501
|
+
}
|
|
23502
|
+
if (!isRecord3(rawInput))
|
|
23503
|
+
return;
|
|
23504
|
+
const command = readFirstString(rawInput, ["command", "cmd", "program"]);
|
|
23505
|
+
const args = readFirstStringArray(rawInput, ["args", "arguments"]);
|
|
23506
|
+
if (command) {
|
|
23507
|
+
return [command, ...args ?? []].join(" ");
|
|
23459
23508
|
}
|
|
23460
|
-
const parsedCmd =
|
|
23461
|
-
if (parsedCmd && parsedCmd.length > 0) {
|
|
23509
|
+
const parsedCmd = rawInput.parsed_cmd;
|
|
23510
|
+
if (Array.isArray(parsedCmd) && parsedCmd.length > 0) {
|
|
23462
23511
|
const parts = [];
|
|
23463
23512
|
for (const entry of parsedCmd) {
|
|
23464
|
-
if (entry && typeof entry.cmd === "string" && entry.cmd.length > 0) {
|
|
23513
|
+
if (isRecord3(entry) && typeof entry.cmd === "string" && entry.cmd.length > 0) {
|
|
23465
23514
|
parts.push(entry.cmd);
|
|
23466
23515
|
}
|
|
23467
23516
|
}
|
|
@@ -23469,7 +23518,51 @@ function getToolDisplayCommand(update) {
|
|
|
23469
23518
|
return parts.join(" ");
|
|
23470
23519
|
}
|
|
23471
23520
|
}
|
|
23472
|
-
return
|
|
23521
|
+
return readFirstString(rawInput, [
|
|
23522
|
+
"path",
|
|
23523
|
+
"file",
|
|
23524
|
+
"filePath",
|
|
23525
|
+
"filepath",
|
|
23526
|
+
"target",
|
|
23527
|
+
"uri",
|
|
23528
|
+
"url",
|
|
23529
|
+
"query",
|
|
23530
|
+
"pattern",
|
|
23531
|
+
"text",
|
|
23532
|
+
"search",
|
|
23533
|
+
"name",
|
|
23534
|
+
"description"
|
|
23535
|
+
]);
|
|
23536
|
+
}
|
|
23537
|
+
function readFirstString(record3, keys) {
|
|
23538
|
+
for (const key of keys) {
|
|
23539
|
+
const value = record3[key];
|
|
23540
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
23541
|
+
return value.trim();
|
|
23542
|
+
}
|
|
23543
|
+
}
|
|
23544
|
+
return;
|
|
23545
|
+
}
|
|
23546
|
+
function readFirstStringArray(record3, keys) {
|
|
23547
|
+
for (const key of keys) {
|
|
23548
|
+
const value = record3[key];
|
|
23549
|
+
if (!Array.isArray(value))
|
|
23550
|
+
continue;
|
|
23551
|
+
const entries = value.map((entry) => typeof entry === "string" && entry.trim().length > 0 ? entry.trim() : undefined).filter((entry) => entry !== undefined);
|
|
23552
|
+
if (entries.length > 0) {
|
|
23553
|
+
return entries;
|
|
23554
|
+
}
|
|
23555
|
+
}
|
|
23556
|
+
return;
|
|
23557
|
+
}
|
|
23558
|
+
function isRecord3(value) {
|
|
23559
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23560
|
+
}
|
|
23561
|
+
function readString(rawInput, key) {
|
|
23562
|
+
if (!isRecord3(rawInput))
|
|
23563
|
+
return;
|
|
23564
|
+
const value = rawInput[key];
|
|
23565
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
23473
23566
|
}
|
|
23474
23567
|
function truncateToolDisplay(text) {
|
|
23475
23568
|
return text.length > 60 ? `${text.slice(0, 57)}...` : text;
|
|
@@ -23833,7 +23926,7 @@ class AcpxCliTransport {
|
|
|
23833
23926
|
const args = this.buildPromptArgs(session, text, structuredPrompt?.filePath);
|
|
23834
23927
|
try {
|
|
23835
23928
|
if (reply || options?.onSegment) {
|
|
23836
|
-
const formatToolCalls = session.replyMode === "verbose";
|
|
23929
|
+
const formatToolCalls = (session.replyMode ?? "verbose") === "verbose";
|
|
23837
23930
|
const { result: result2, overflowCount } = await this.runStreamingPrompt(this.command, args, reply, 30000, formatToolCalls, replyContext, options?.onSegment);
|
|
23838
23931
|
const baseText = getPromptText(result2);
|
|
23839
23932
|
if (!reply) {
|
|
@@ -29571,7 +29664,7 @@ function finalize(ctx, schema) {
|
|
|
29571
29664
|
result.$schema = "http://json-schema.org/draft-07/schema#";
|
|
29572
29665
|
} else if (ctx.target === "draft-04") {
|
|
29573
29666
|
result.$schema = "http://json-schema.org/draft-04/schema#";
|
|
29574
|
-
} else if (ctx.target === "openapi-3.0") {}
|
|
29667
|
+
} else if (ctx.target === "openapi-3.0") {}
|
|
29575
29668
|
if (ctx.external?.uri) {
|
|
29576
29669
|
const id = ctx.external.registry.get(schema)?.id;
|
|
29577
29670
|
if (!id)
|
|
@@ -29793,7 +29886,7 @@ var literalProcessor = (schema, ctx, json, _params) => {
|
|
|
29793
29886
|
if (val === undefined) {
|
|
29794
29887
|
if (ctx.unrepresentable === "throw") {
|
|
29795
29888
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
29796
|
-
}
|
|
29889
|
+
}
|
|
29797
29890
|
} else if (typeof val === "bigint") {
|
|
29798
29891
|
if (ctx.unrepresentable === "throw") {
|
|
29799
29892
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -38344,7 +38437,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38344
38437
|
return [
|
|
38345
38438
|
{
|
|
38346
38439
|
name: "delegate_request",
|
|
38347
|
-
description: `Delegate a subtask to another agent under the current coordinator.${availableAgents && availableAgents.length > 0 ? ` Available agents: ${availableAgents.join(", ")}.` : ""}`,
|
|
38440
|
+
description: `Delegate a subtask to another agent under the current coordinator. Pass an absolute workingDirectory for the worker.${availableAgents && availableAgents.length > 0 ? ` Available agents: ${availableAgents.join(", ")}.` : ""}`,
|
|
38348
38441
|
inputSchema: exports_external.object({
|
|
38349
38442
|
targetAgent: exports_external.string().min(1),
|
|
38350
38443
|
task: exports_external.string().min(1),
|
|
@@ -38359,12 +38452,12 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38359
38452
|
...sourceHandle ? { sourceHandle } : {},
|
|
38360
38453
|
...input2
|
|
38361
38454
|
});
|
|
38362
|
-
return createSuccessResult(
|
|
38455
|
+
return createSuccessResult(renderDelegateSuccess(result), result);
|
|
38363
38456
|
})
|
|
38364
38457
|
},
|
|
38365
38458
|
{
|
|
38366
38459
|
name: "group_new",
|
|
38367
|
-
description: "Create a new task group
|
|
38460
|
+
description: "Create a new task group under the current coordinator.",
|
|
38368
38461
|
inputSchema: exports_external.object({
|
|
38369
38462
|
title: exports_external.string().min(1)
|
|
38370
38463
|
}).strict(),
|
|
@@ -38373,12 +38466,12 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38373
38466
|
coordinatorSession,
|
|
38374
38467
|
title: args.title
|
|
38375
38468
|
});
|
|
38376
|
-
return createSuccessResult(
|
|
38469
|
+
return createSuccessResult(renderGroupCreated(group), group);
|
|
38377
38470
|
})
|
|
38378
38471
|
},
|
|
38379
38472
|
{
|
|
38380
38473
|
name: "group_get",
|
|
38381
|
-
description: "Fetch a single task
|
|
38474
|
+
description: "Fetch a single task-group summary under the current coordinator.",
|
|
38382
38475
|
inputSchema: exports_external.object({
|
|
38383
38476
|
groupId: exports_external.string().min(1)
|
|
38384
38477
|
}).strict(),
|
|
@@ -38392,7 +38485,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38392
38485
|
},
|
|
38393
38486
|
{
|
|
38394
38487
|
name: "group_list",
|
|
38395
|
-
description: "List task groups
|
|
38488
|
+
description: "List task groups under the current coordinator.",
|
|
38396
38489
|
inputSchema: exports_external.object({
|
|
38397
38490
|
status: groupStatusSchema.optional(),
|
|
38398
38491
|
stuck: exports_external.boolean().optional(),
|
|
@@ -38413,7 +38506,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38413
38506
|
},
|
|
38414
38507
|
{
|
|
38415
38508
|
name: "group_cancel",
|
|
38416
|
-
description: "Cancel all unfinished tasks in a task group
|
|
38509
|
+
description: "Cancel all unfinished tasks in a task group under the current coordinator.",
|
|
38417
38510
|
inputSchema: exports_external.object({
|
|
38418
38511
|
groupId: exports_external.string().min(1)
|
|
38419
38512
|
}).strict(),
|
|
@@ -38427,7 +38520,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38427
38520
|
},
|
|
38428
38521
|
{
|
|
38429
38522
|
name: "task_get",
|
|
38430
|
-
description: "Fetch a single
|
|
38523
|
+
description: "Fetch a single task under the current coordinator.",
|
|
38431
38524
|
inputSchema: exports_external.object({
|
|
38432
38525
|
taskId: exports_external.string().min(1)
|
|
38433
38526
|
}).strict(),
|
|
@@ -38441,7 +38534,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38441
38534
|
},
|
|
38442
38535
|
{
|
|
38443
38536
|
name: "task_list",
|
|
38444
|
-
description: "List
|
|
38537
|
+
description: "List tasks under the current coordinator.",
|
|
38445
38538
|
inputSchema: exports_external.object({
|
|
38446
38539
|
status: taskStatusSchema.optional(),
|
|
38447
38540
|
stuck: exports_external.boolean().optional(),
|
|
@@ -38462,7 +38555,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38462
38555
|
},
|
|
38463
38556
|
{
|
|
38464
38557
|
name: "task_approve",
|
|
38465
|
-
description: "Approve a pending
|
|
38558
|
+
description: "Approve a pending task under the current coordinator.",
|
|
38466
38559
|
inputSchema: exports_external.object({
|
|
38467
38560
|
taskId: exports_external.string().min(1)
|
|
38468
38561
|
}).strict(),
|
|
@@ -38476,7 +38569,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38476
38569
|
},
|
|
38477
38570
|
{
|
|
38478
38571
|
name: "task_reject",
|
|
38479
|
-
description: "Reject a pending
|
|
38572
|
+
description: "Reject a pending task under the current coordinator.",
|
|
38480
38573
|
inputSchema: exports_external.object({
|
|
38481
38574
|
taskId: exports_external.string().min(1)
|
|
38482
38575
|
}).strict(),
|
|
@@ -38490,7 +38583,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38490
38583
|
},
|
|
38491
38584
|
{
|
|
38492
38585
|
name: "task_cancel",
|
|
38493
|
-
description: "Request cancellation for
|
|
38586
|
+
description: "Request cancellation for a task under the current coordinator.",
|
|
38494
38587
|
inputSchema: exports_external.object({
|
|
38495
38588
|
taskId: exports_external.string().min(1)
|
|
38496
38589
|
}).strict(),
|
|
@@ -38499,12 +38592,12 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38499
38592
|
coordinatorSession,
|
|
38500
38593
|
taskId: args.taskId
|
|
38501
38594
|
});
|
|
38502
|
-
return createSuccessResult(
|
|
38595
|
+
return createSuccessResult(renderTaskCancelRequest(task), task);
|
|
38503
38596
|
})
|
|
38504
38597
|
},
|
|
38505
38598
|
{
|
|
38506
38599
|
name: "task_wait",
|
|
38507
|
-
description:
|
|
38600
|
+
description: `Wait for a task to finish or require attention. Defaults: timeout ${DEFAULT_TASK_WAIT_TIMEOUT_MS} ms, poll interval ${DEFAULT_TASK_WAIT_POLL_INTERVAL_MS} ms. Maximums: timeout ${MAX_TASK_WAIT_TIMEOUT_MS} ms, poll interval ${MAX_TASK_WAIT_POLL_INTERVAL_MS} ms.`,
|
|
38508
38601
|
inputSchema: exports_external.object({
|
|
38509
38602
|
taskId: exports_external.string().min(1),
|
|
38510
38603
|
timeoutMs: exports_external.number().int().min(0).max(MAX_TASK_WAIT_TIMEOUT_MS).optional(),
|
|
@@ -38520,7 +38613,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38520
38613
|
},
|
|
38521
38614
|
{
|
|
38522
38615
|
name: "worker_raise_question",
|
|
38523
|
-
description: "Raise a blocker question for the current bound session.",
|
|
38616
|
+
description: "Raise a blocker question for the current bound worker session.",
|
|
38524
38617
|
inputSchema: exports_external.object({
|
|
38525
38618
|
taskId: exports_external.string().min(1),
|
|
38526
38619
|
question: exports_external.string().min(1),
|
|
@@ -38535,8 +38628,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38535
38628
|
sourceHandle,
|
|
38536
38629
|
...args
|
|
38537
38630
|
});
|
|
38538
|
-
return createSuccessResult(
|
|
38539
|
-
`), result);
|
|
38631
|
+
return createSuccessResult(renderWorkerRaiseQuestionSuccess(result), result);
|
|
38540
38632
|
})
|
|
38541
38633
|
},
|
|
38542
38634
|
{
|
|
@@ -38552,8 +38644,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38552
38644
|
coordinatorSession,
|
|
38553
38645
|
...args
|
|
38554
38646
|
});
|
|
38555
|
-
return createSuccessResult(
|
|
38556
|
-
`), task);
|
|
38647
|
+
return createSuccessResult(renderCoordinatorAnswerQuestionSuccess(task), task);
|
|
38557
38648
|
})
|
|
38558
38649
|
},
|
|
38559
38650
|
{
|
|
@@ -38569,10 +38660,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38569
38660
|
coordinatorSession,
|
|
38570
38661
|
...args
|
|
38571
38662
|
});
|
|
38572
|
-
|
|
38573
|
-
`) : [`问题已加入当前 human question queue。`, `- 已排队任务:${result.queuedTaskIds.length}`].join(`
|
|
38574
|
-
`);
|
|
38575
|
-
return createSuccessResult(text, result);
|
|
38663
|
+
return createSuccessResult(renderCoordinatorRequestHumanInputSuccess(result), result);
|
|
38576
38664
|
})
|
|
38577
38665
|
},
|
|
38578
38666
|
{
|
|
@@ -38589,13 +38677,12 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38589
38677
|
coordinatorSession,
|
|
38590
38678
|
...args
|
|
38591
38679
|
});
|
|
38592
|
-
return createSuccessResult(
|
|
38593
|
-
`), result);
|
|
38680
|
+
return createSuccessResult(renderCoordinatorFollowUpHumanPackageSuccess(result), result);
|
|
38594
38681
|
})
|
|
38595
38682
|
},
|
|
38596
38683
|
{
|
|
38597
38684
|
name: "coordinator_review_contested_result",
|
|
38598
|
-
description: "Review a contested
|
|
38685
|
+
description: "Review a contested result under the current coordinator.",
|
|
38599
38686
|
inputSchema: exports_external.object({
|
|
38600
38687
|
taskId: exports_external.string().min(1),
|
|
38601
38688
|
reviewId: exports_external.string().min(1),
|
|
@@ -38608,9 +38695,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
38608
38695
|
decision,
|
|
38609
38696
|
...rest
|
|
38610
38697
|
});
|
|
38611
|
-
|
|
38612
|
-
return createSuccessResult([`${actionText}任务「${task.taskId}」的 contested result。`, `- 当前状态:${task.status}`].join(`
|
|
38613
|
-
`), task);
|
|
38698
|
+
return createSuccessResult(renderCoordinatorReviewContestedResultSuccess(task, decision), task);
|
|
38614
38699
|
})
|
|
38615
38700
|
}
|
|
38616
38701
|
];
|
|
@@ -38661,10 +38746,185 @@ function createErrorResult(message) {
|
|
|
38661
38746
|
isError: true
|
|
38662
38747
|
};
|
|
38663
38748
|
}
|
|
38749
|
+
function renderDelegateSuccess(result) {
|
|
38750
|
+
return [`Delegation task "${result.taskId}" created.`, `- Status: ${result.status}`].join(`
|
|
38751
|
+
`);
|
|
38752
|
+
}
|
|
38753
|
+
function renderGroupCreated(group) {
|
|
38754
|
+
return [`Task group "${group.groupId}" created.`, `- Title: ${group.title}`].join(`
|
|
38755
|
+
`);
|
|
38756
|
+
}
|
|
38757
|
+
function renderGroupSummary(summary) {
|
|
38758
|
+
const { group, tasks } = summary;
|
|
38759
|
+
const lines = [
|
|
38760
|
+
`Task group "${group.groupId}"`,
|
|
38761
|
+
`- Title: ${group.title}`,
|
|
38762
|
+
`- Coordinator session: ${group.coordinatorSession}`,
|
|
38763
|
+
`- Total tasks: ${summary.totalTasks}`,
|
|
38764
|
+
`- Pending approval: ${summary.pendingApprovalTasks}`,
|
|
38765
|
+
`- Running: ${summary.runningTasks}`,
|
|
38766
|
+
`- Completed: ${summary.completedTasks}`,
|
|
38767
|
+
`- Failed: ${summary.failedTasks}`,
|
|
38768
|
+
`- Cancelled: ${summary.cancelledTasks}`,
|
|
38769
|
+
`- Terminal: ${summary.terminal ? "yes" : "no"}`
|
|
38770
|
+
];
|
|
38771
|
+
if (group.injectionPending !== undefined) {
|
|
38772
|
+
lines.push(`- Injection pending: ${group.injectionPending ? "yes" : "no"}`);
|
|
38773
|
+
}
|
|
38774
|
+
if (group.injectionAppliedAt) {
|
|
38775
|
+
lines.push(`- Injection completed at: ${group.injectionAppliedAt}`);
|
|
38776
|
+
}
|
|
38777
|
+
if (group.lastInjectionError) {
|
|
38778
|
+
lines.push(`- Last injection error: ${group.lastInjectionError}`);
|
|
38779
|
+
}
|
|
38780
|
+
if (tasks.length > 0) {
|
|
38781
|
+
lines.push("- Members:");
|
|
38782
|
+
for (const task of tasks) {
|
|
38783
|
+
lines.push(` - ${task.taskId} [${task.status}] ${task.targetAgent}`);
|
|
38784
|
+
}
|
|
38785
|
+
}
|
|
38786
|
+
return lines.join(`
|
|
38787
|
+
`);
|
|
38788
|
+
}
|
|
38789
|
+
function renderGroupList(groups) {
|
|
38790
|
+
if (groups.length === 0) {
|
|
38791
|
+
return "There are no task groups under the current coordinator.";
|
|
38792
|
+
}
|
|
38793
|
+
return ["Task groups for the current coordinator:", ...groups.map((group) => renderGroupListItem(group))].join(`
|
|
38794
|
+
`);
|
|
38795
|
+
}
|
|
38796
|
+
function renderGroupListItem(group) {
|
|
38797
|
+
const reliability = group.group.injectionPending ? " | injection pending" : "";
|
|
38798
|
+
return [
|
|
38799
|
+
`- ${group.group.groupId}`,
|
|
38800
|
+
group.group.title,
|
|
38801
|
+
`total ${group.totalTasks}`,
|
|
38802
|
+
`pending ${group.pendingApprovalTasks}`,
|
|
38803
|
+
`running ${group.runningTasks}`,
|
|
38804
|
+
`completed ${group.completedTasks}`,
|
|
38805
|
+
`failed ${group.failedTasks}`,
|
|
38806
|
+
`cancelled ${group.cancelledTasks}${reliability}`
|
|
38807
|
+
].join(" | ");
|
|
38808
|
+
}
|
|
38809
|
+
function renderGroupCancelSuccess(input) {
|
|
38810
|
+
return [
|
|
38811
|
+
`Task group "${input.summary.group.groupId}" cancellation requested.`,
|
|
38812
|
+
`- Cancel requested: ${input.cancelledTaskIds.length}`,
|
|
38813
|
+
`- Skipped terminal tasks: ${input.skippedTaskIds.length}`
|
|
38814
|
+
].join(`
|
|
38815
|
+
`);
|
|
38816
|
+
}
|
|
38817
|
+
function renderTaskList(tasks) {
|
|
38818
|
+
if (tasks.length === 0) {
|
|
38819
|
+
return "There are no tasks under the current coordinator.";
|
|
38820
|
+
}
|
|
38821
|
+
return ["Tasks for the current coordinator:", ...tasks.map((task) => renderTaskListItem(task))].join(`
|
|
38822
|
+
`);
|
|
38823
|
+
}
|
|
38824
|
+
function renderTaskListItem(task) {
|
|
38825
|
+
const role = task.role ? ` / ${task.role}` : "";
|
|
38826
|
+
const group = task.groupId ? `; group: ${task.groupId}` : "";
|
|
38827
|
+
const summary = task.summary.trim().length > 0 ? `: ${task.summary}` : "";
|
|
38828
|
+
const source = task.status === "needs_confirmation" ? `; source: ${task.targetAgent}${task.role ? ` / ${task.role}` : ""}` : "";
|
|
38829
|
+
const reliability = [
|
|
38830
|
+
task.noticePending ? "notice pending retry" : "",
|
|
38831
|
+
task.injectionPending ? "injection pending retry" : "",
|
|
38832
|
+
task.cancelRequestedAt && !task.cancelCompletedAt && task.status === "running" ? "cancelling" : ""
|
|
38833
|
+
].filter(Boolean).map((item) => `; ${item}`).join("");
|
|
38834
|
+
return `- ${task.taskId} [${task.status}] ${task.targetAgent}${role} -> ${task.workerSession ?? "unassigned"}${group}${source}${summary}${reliability}`;
|
|
38835
|
+
}
|
|
38836
|
+
function renderTaskSummary(task) {
|
|
38837
|
+
const header = [
|
|
38838
|
+
`Task "${task.taskId}"`,
|
|
38839
|
+
`- Status: ${task.status}`,
|
|
38840
|
+
`- Coordinator session: ${task.coordinatorSession}`,
|
|
38841
|
+
`- Worker session: ${task.workerSession ?? "unassigned"}`,
|
|
38842
|
+
`- Target agent: ${task.targetAgent}`
|
|
38843
|
+
];
|
|
38844
|
+
if (task.role)
|
|
38845
|
+
header.push(`- Role: ${task.role}`);
|
|
38846
|
+
if (task.groupId)
|
|
38847
|
+
header.push(`- Group: ${task.groupId}`);
|
|
38848
|
+
if (task.status === "needs_confirmation") {
|
|
38849
|
+
header.push(`- Source: ${task.sourceKind} / ${task.sourceHandle}${task.role ? ` / ${task.role}` : ""}`);
|
|
38850
|
+
}
|
|
38851
|
+
header.push(`- Task: ${task.task}`);
|
|
38852
|
+
if (task.summary.trim().length > 0)
|
|
38853
|
+
header.push(`- Summary: ${task.summary}`);
|
|
38854
|
+
if (task.resultText.trim().length > 0)
|
|
38855
|
+
header.push(`- Result: ${task.resultText}`);
|
|
38856
|
+
const events = [];
|
|
38857
|
+
events.push({ at: task.createdAt, event: "created" });
|
|
38858
|
+
if (task.workerSession && task.status !== "needs_confirmation") {
|
|
38859
|
+
events.push({ at: task.createdAt, event: "dispatched", detail: task.workerSession });
|
|
38860
|
+
}
|
|
38861
|
+
if (task.lastProgressAt)
|
|
38862
|
+
events.push({ at: task.lastProgressAt, event: "last progress" });
|
|
38863
|
+
if (task.cancelRequestedAt)
|
|
38864
|
+
events.push({ at: task.cancelRequestedAt, event: "cancel requested" });
|
|
38865
|
+
if (task.cancelCompletedAt)
|
|
38866
|
+
events.push({ at: task.cancelCompletedAt, event: "cancel completed" });
|
|
38867
|
+
if (task.lastCancelError)
|
|
38868
|
+
events.push({ at: task.updatedAt, event: "cancel failed", detail: task.lastCancelError });
|
|
38869
|
+
if (task.status === "completed")
|
|
38870
|
+
events.push({ at: task.updatedAt, event: "completed" });
|
|
38871
|
+
if (task.status === "failed")
|
|
38872
|
+
events.push({ at: task.updatedAt, event: "failed" });
|
|
38873
|
+
if (task.noticeSentAt)
|
|
38874
|
+
events.push({ at: task.noticeSentAt, event: "notice sent", detail: task.deliveryAccountId });
|
|
38875
|
+
if (task.lastNoticeError)
|
|
38876
|
+
events.push({ at: task.updatedAt, event: "notice failed", detail: task.lastNoticeError });
|
|
38877
|
+
if (task.injectionAppliedAt)
|
|
38878
|
+
events.push({ at: task.injectionAppliedAt, event: "injection applied" });
|
|
38879
|
+
if (task.lastInjectionError)
|
|
38880
|
+
events.push({ at: task.updatedAt, event: "injection failed", detail: task.lastInjectionError });
|
|
38881
|
+
events.sort((a, b) => a.at.localeCompare(b.at));
|
|
38882
|
+
const timeline = events.length > 0 ? ["- Timeline:", ...events.map((e) => ` - [${e.at}] ${e.event}${e.detail ? `: ${e.detail}` : ""}`)] : [];
|
|
38883
|
+
return [...header, ...timeline].join(`
|
|
38884
|
+
`);
|
|
38885
|
+
}
|
|
38886
|
+
function renderTaskCancelRequest(task) {
|
|
38887
|
+
if (task.status === "completed" || task.status === "failed" || task.status === "cancelled") {
|
|
38888
|
+
return [`Task "${task.taskId}" has already finished.`, `- Current status: ${task.status}`].join(`
|
|
38889
|
+
`);
|
|
38890
|
+
}
|
|
38891
|
+
return [`Cancellation requested for task "${task.taskId}".`, `- Current status: ${task.status}`].join(`
|
|
38892
|
+
`);
|
|
38893
|
+
}
|
|
38894
|
+
function renderTaskApprovalSuccess(task) {
|
|
38895
|
+
return [`Task "${task.taskId}" approved.`, `- Current status: ${task.status}`].join(`
|
|
38896
|
+
`);
|
|
38897
|
+
}
|
|
38898
|
+
function renderTaskRejectionSuccess(task) {
|
|
38899
|
+
return [`Task "${task.taskId}" rejected.`, `- Current status: ${task.status}`].join(`
|
|
38900
|
+
`);
|
|
38901
|
+
}
|
|
38902
|
+
function renderWorkerRaiseQuestionSuccess(task) {
|
|
38903
|
+
return [`Blocker question submitted for task "${task.taskId}".`, `- questionId: ${task.questionId}`].join(`
|
|
38904
|
+
`);
|
|
38905
|
+
}
|
|
38906
|
+
function renderCoordinatorAnswerQuestionSuccess(task) {
|
|
38907
|
+
return [`Answered the blocker question for task "${task.taskId}".`, `- Current status: ${task.status}`].join(`
|
|
38908
|
+
`);
|
|
38909
|
+
}
|
|
38910
|
+
function renderCoordinatorRequestHumanInputSuccess(result) {
|
|
38911
|
+
return result.packageId ? [`Created human question package "${result.packageId}".`, `- Queued tasks: ${result.queuedTaskIds.length}`].join(`
|
|
38912
|
+
`) : [`Queued the question in the current human question queue.`, `- Queued tasks: ${result.queuedTaskIds.length}`].join(`
|
|
38913
|
+
`);
|
|
38914
|
+
}
|
|
38915
|
+
function renderCoordinatorFollowUpHumanPackageSuccess(result) {
|
|
38916
|
+
return [`Appended follow-up to human package "${result.packageId}".`, `- messageId: ${result.messageId}`].join(`
|
|
38917
|
+
`);
|
|
38918
|
+
}
|
|
38919
|
+
function renderCoordinatorReviewContestedResultSuccess(task, decision) {
|
|
38920
|
+
const actionText = decision === "accept" ? "Accepted" : "Discarded";
|
|
38921
|
+
return [`${actionText} contested result for task "${task.taskId}".`, `- Current status: ${task.status}`].join(`
|
|
38922
|
+
`);
|
|
38923
|
+
}
|
|
38664
38924
|
function formatToolError(error2) {
|
|
38665
38925
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
38666
38926
|
if (/ECONNREFUSED|ENOENT|server closed without a response|socket hang up|connect /i.test(message)) {
|
|
38667
|
-
return
|
|
38927
|
+
return `Failed to connect to the orchestration daemon: ${message}`;
|
|
38668
38928
|
}
|
|
38669
38929
|
return message;
|
|
38670
38930
|
}
|
|
@@ -38884,6 +39144,9 @@ function createWeacpxMcpServer(options) {
|
|
|
38884
39144
|
return await toolStatePromise;
|
|
38885
39145
|
}
|
|
38886
39146
|
toolStatePromise = resolveMcpIdentity(server, options).then((identity) => {
|
|
39147
|
+
if (!options.transport) {
|
|
39148
|
+
throw new Error("weacpx MCP transport is not configured");
|
|
39149
|
+
}
|
|
38887
39150
|
toolState = buildToolState({
|
|
38888
39151
|
transport: options.transport,
|
|
38889
39152
|
coordinatorSession: identity.coordinatorSession,
|
|
@@ -38943,7 +39206,7 @@ async function resolveMcpIdentity(server, options) {
|
|
|
38943
39206
|
throw new McpError(ErrorCode.InvalidRequest, "weacpx MCP identity is not configured; run through `weacpx mcp-stdio` or provide --coordinator-session");
|
|
38944
39207
|
}
|
|
38945
39208
|
async function runWeacpxMcpServer(options) {
|
|
38946
|
-
const transport = createOrchestrationTransport(options.endpoint ?? resolveDefaultOrchestrationEndpoint(process.env, process.platform));
|
|
39209
|
+
const transport = options.transport ?? createOrchestrationTransport(options.endpoint ?? resolveDefaultOrchestrationEndpoint(process.env, process.platform));
|
|
38947
39210
|
const server = createWeacpxMcpServer({
|
|
38948
39211
|
transport,
|
|
38949
39212
|
...options.coordinatorSession ? { coordinatorSession: options.coordinatorSession } : {},
|
|
@@ -40724,6 +40987,7 @@ async function defaultMcpStdio(args, deps = {}) {
|
|
|
40724
40987
|
let coordinatorSession;
|
|
40725
40988
|
let sourceHandle;
|
|
40726
40989
|
let endpoint;
|
|
40990
|
+
let transport;
|
|
40727
40991
|
let identityResolver;
|
|
40728
40992
|
let availableAgents;
|
|
40729
40993
|
try {
|
|
@@ -40732,6 +40996,7 @@ async function defaultMcpStdio(args, deps = {}) {
|
|
|
40732
40996
|
const workspace = parseCoordinatorWorkspace(args, process.env);
|
|
40733
40997
|
endpoint = resolveDefaultOrchestrationEndpoint(process.env, process.platform);
|
|
40734
40998
|
const client = new OrchestrationClient(endpoint);
|
|
40999
|
+
transport = createOrchestrationTransport(endpoint, { client });
|
|
40735
41000
|
const runtimePaths = (await init_main().then(() => exports_main)).resolveRuntimePaths();
|
|
40736
41001
|
await ensureConfigExists(runtimePaths.configPath);
|
|
40737
41002
|
const config2 = await loadConfig(runtimePaths.configPath);
|
|
@@ -40745,7 +41010,7 @@ async function defaultMcpStdio(args, deps = {}) {
|
|
|
40745
41010
|
state,
|
|
40746
41011
|
client
|
|
40747
41012
|
});
|
|
40748
|
-
const eagerIdentity = parsedCoordinatorSession
|
|
41013
|
+
const eagerIdentity = parsedCoordinatorSession ? await resolveIdentity({ clientName: undefined, listRoots: async () => [] }) : null;
|
|
40749
41014
|
coordinatorSession = eagerIdentity?.coordinatorSession ?? "";
|
|
40750
41015
|
identityResolver = eagerIdentity ? undefined : resolveIdentity;
|
|
40751
41016
|
} catch (error2) {
|
|
@@ -40754,7 +41019,7 @@ async function defaultMcpStdio(args, deps = {}) {
|
|
|
40754
41019
|
return 2;
|
|
40755
41020
|
}
|
|
40756
41021
|
await runWeacpxMcpServer({
|
|
40757
|
-
|
|
41022
|
+
transport,
|
|
40758
41023
|
...coordinatorSession ? { coordinatorSession } : {},
|
|
40759
41024
|
...sourceHandle ? { sourceHandle } : {},
|
|
40760
41025
|
...identityResolver ? { resolveIdentity: identityResolver } : {},
|