mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:40:44 +00:00
fix(acp): avoid duplicate Discord thread announces
This commit is contained in:
@@ -24,6 +24,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
- Subagents: honor `sessions_spawn` with `expectsCompletionMessage: false` by skipping parent completion handoff delivery while still running child cleanup. Fixes #75848. Thanks @alfredjbclaw.
|
||||
- Gateway/logging: keep deferred channel startup logs on the subsystem logger, so Slack, Discord, Telegram, and voice-call startup messages keep timestamped prefixes. Thanks @vincentkoc.
|
||||
- ACP/Discord: suppress completion announce delivery for inline thread-bound ACP session runs, so Discord thread-bound ACP replies are not delivered twice. Fixes #60780. Thanks @solavrc.
|
||||
- Discord/threads: ignore webhook-authored copies in already-bound Discord session threads even when the webhook id differs, preventing PluralKit proxy copies from creating duplicate turn pressure. Fixes #52005. Thanks @acgh213.
|
||||
- Discord/threads: return the created thread as partial success when the follow-up initial message fails, so agents do not retry thread creation and create empty duplicate threads. Fixes #48450. Thanks @dahifi.
|
||||
- Discord/components: consume every button or select in a non-reusable component message after the first authorized click, so single-use panels cannot fire sibling callbacks. Fixes #54227. Thanks @fujiwarakasei.
|
||||
|
||||
@@ -688,6 +688,7 @@ describe("spawnAcpDirect", () => {
|
||||
expect(accepted.childSessionKey).toMatch(/^agent:codex:acp:/);
|
||||
expect(accepted.runId).toBe("run-1");
|
||||
expect(accepted.mode).toBe("session");
|
||||
expect(accepted.inlineDelivery).toBe(true);
|
||||
const patchCall = hoisted.callGatewayMock.mock.calls
|
||||
.map((call: unknown[]) => call[0] as { method?: string; params?: Record<string, unknown> })
|
||||
.find((request) => request.method === "sessions.patch");
|
||||
|
||||
@@ -145,6 +145,7 @@ type SpawnAcpResultFields = {
|
||||
childSessionKey?: string;
|
||||
runId?: string;
|
||||
mode?: SpawnAcpMode;
|
||||
inlineDelivery?: boolean;
|
||||
streamLogPath?: string;
|
||||
note?: string;
|
||||
};
|
||||
@@ -1494,6 +1495,7 @@ export async function spawnAcpDirect(
|
||||
childSessionKey: sessionKey,
|
||||
runId: childRunId,
|
||||
mode: spawnMode,
|
||||
...(deliveryPlan.useInlineDelivery ? { inlineDelivery: true } : {}),
|
||||
note: spawnMode === "session" ? ACP_SPAWN_SESSION_ACCEPTED_NOTE : ACP_SPAWN_ACCEPTED_NOTE,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -471,6 +471,44 @@ describe("sessions_spawn tool", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("suppresses completion announces for inline ACP session delivery", async () => {
|
||||
registerAcpBackendForTest();
|
||||
hoisted.spawnAcpDirectMock.mockResolvedValueOnce({
|
||||
status: "accepted",
|
||||
childSessionKey: "agent:codex:acp:1",
|
||||
runId: "run-acp",
|
||||
mode: "session",
|
||||
inlineDelivery: true,
|
||||
});
|
||||
const tool = createSessionsSpawnTool({
|
||||
agentSessionKey: "agent:main:main",
|
||||
agentChannel: "discord",
|
||||
agentAccountId: "default",
|
||||
agentTo: "channel:parent-channel",
|
||||
agentThreadId: "child-thread",
|
||||
});
|
||||
|
||||
await tool.execute("call-inline-acp", {
|
||||
runtime: "acp",
|
||||
task: "investigate",
|
||||
agentId: "codex",
|
||||
thread: true,
|
||||
mode: "session",
|
||||
});
|
||||
|
||||
expect(hoisted.registerSubagentRunMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
runId: "run-acp",
|
||||
childSessionKey: "agent:codex:acp:1",
|
||||
requesterSessionKey: "agent:main:main",
|
||||
task: "investigate",
|
||||
cleanup: "keep",
|
||||
spawnMode: "session",
|
||||
expectsCompletionMessage: false,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects ACP runtime calls from sandboxed requester sessions", async () => {
|
||||
registerAcpBackendForTest();
|
||||
const tool = createSessionsSpawnTool({
|
||||
|
||||
@@ -334,6 +334,9 @@ export function createSessionsSpawnTool(
|
||||
to: opts?.agentTo,
|
||||
threadId: opts?.agentThreadId,
|
||||
});
|
||||
const shouldExpectCompletionMessage = result.inlineDelivery
|
||||
? false
|
||||
: expectsCompletionMessage;
|
||||
try {
|
||||
registerSubagentRun({
|
||||
runId: childRunId,
|
||||
@@ -345,7 +348,7 @@ export function createSessionsSpawnTool(
|
||||
cleanup: trackedCleanup,
|
||||
label: label || undefined,
|
||||
runTimeoutSeconds,
|
||||
expectsCompletionMessage,
|
||||
expectsCompletionMessage: shouldExpectCompletionMessage,
|
||||
spawnMode: trackedSpawnMode,
|
||||
});
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user