fix: mirror dispatch replies back to thread chats

This commit is contained in:
kris
2026-04-04 00:57:40 +08:00
parent 1a64fd9f29
commit 05b9bee9e8
2 changed files with 28 additions and 1 deletions

View File

@@ -5743,9 +5743,10 @@ function appendDispatchExecutionResultInState(
}
const device = state.devices.find((item) => item.id === payload.completedByDeviceId);
const targetProject = state.projects.find((item) => item.id === payload.targetProjectId);
const threadTitle =
payload.targetThreadDisplayName?.trim() ||
state.projects.find((item) => item.id === payload.targetProjectId)?.threadMeta.threadDisplayName ||
targetProject?.threadMeta.threadDisplayName ||
payload.targetThreadId;
if (execution.status === "completed" || execution.status === "failed") {
@@ -5771,6 +5772,7 @@ function appendDispatchExecutionResultInState(
}
let mirroredResult: Message | null = null;
let mirroredThreadResult: Message | null = null;
let masterSummary: Message | null = null;
if (payload.status === "completed") {
@@ -5783,6 +5785,12 @@ function appendDispatchExecutionResultInState(
body: payload.rawThreadReply.trim(),
kind: "text",
});
mirroredThreadResult = pushProjectLedgerMessage(state, payload.targetProjectId, {
sender: "device",
senderLabel: `${threadTitle} · ${device?.name ?? payload.completedByDeviceId}`,
body: payload.rawThreadReply.trim(),
kind: "text",
});
masterSummary = pushProjectLedgerMessage(state, payload.groupProjectId, {
sender: "master",
senderLabel: "主 Agent",
@@ -5808,6 +5816,7 @@ function appendDispatchExecutionResultInState(
return {
execution: { ...execution },
mirroredResult,
mirroredThreadResult,
masterSummary,
};
}
@@ -5828,6 +5837,8 @@ export async function appendDispatchExecutionResult(payload: {
);
publishBossEvent("project.messages.updated", { projectId: payload.groupProjectId });
publishBossEvent("conversation.updated", { projectId: payload.groupProjectId });
publishBossEvent("project.messages.updated", { projectId: payload.targetProjectId });
publishBossEvent("conversation.updated", { projectId: payload.targetProjectId });
return result;
}
@@ -6134,6 +6145,10 @@ export async function completeMasterAgentTask(payload: {
});
publishBossEvent("project.messages.updated", { projectId: result.projectId });
publishBossEvent("conversation.updated", { projectId: result.projectId });
if (result.dispatchExecution?.targetProjectId) {
publishBossEvent("project.messages.updated", { projectId: result.dispatchExecution.targetProjectId });
publishBossEvent("conversation.updated", { projectId: result.dispatchExecution.targetProjectId });
}
return result;
}

View File

@@ -221,6 +221,18 @@ test("POST /api/v1/master-agent/tasks/[taskId]/complete mirrors raw thread repli
message.body.includes("主 Agent 汇总线程A已返回阻塞点整理"),
);
assert.ok(masterSummary, "expected master-agent summary to be appended after the raw thread reply");
const targetThreadMessages =
nextState.projects.find((project) => project.id === execution.targetProjectId)?.messages ?? [];
const mirroredThreadReply = targetThreadMessages.find(
(message) =>
message.sender === "device" &&
message.body.includes("线程A已经完成阻塞点整理"),
);
assert.ok(
mirroredThreadReply,
"expected raw thread reply to also be mirrored back to the target single-thread conversation",
);
});
test("POST /api/v1/master-agent/tasks/[taskId]/complete is idempotent for repeated dispatch execution completions", async () => {