fix(subagents): preserve non-internal announce origin channels (#23030) (thanks @mcinteerj)

This commit is contained in:
Peter Steinberger
2026-02-24 04:13:29 +00:00
parent 325d835d82
commit cb1de71138
2 changed files with 30 additions and 0 deletions

View File

@@ -38,6 +38,7 @@ Docs: https://docs.openclaw.ai
- Infra/Windows TOCTOU: handle Windows `dev=0` edge cases in same-file identity checks. (#24939)
- Exec/Bash tools: clamp poll sleep duration to non-negative values in process polling loops. (#24889)
- Subagents/Announce queue: add exponential backoff when queue-drain delivery fails to reduce retry storms. (#24783)
- Subagents/Announce routing: preserve non-internal requester channels when resolving announce origin so stale session channel hints do not override spawn-time routing context. (#23030) Thanks @mcinteerj.
- Config/Kilo Gateway: Kilo provider flow now surfaces an updated list of models. (#24921) thanks @gumadeiras.
- Agents/Tool warnings: suppress `sessions_send` relay errors from chat-facing warning payloads to avoid leaking transient inter-session transport failures. (#24740) Thanks @Glucksberg.
- WhatsApp/Logging: redact outbound recipient identifiers in WhatsApp outbound + heartbeat logs and remove message/poll preview text from those log lines. (#24980) Thanks @coygeek.

View File

@@ -1628,6 +1628,35 @@ describe("subagent announce formatting", () => {
expect(call?.params?.to).toBe("telegram:123");
});
it("preserves non-internal requesterOrigin channel over stale session lastChannel", async () => {
embeddedRunMock.isEmbeddedPiRunActive.mockReturnValue(true);
embeddedRunMock.isEmbeddedPiRunStreaming.mockReturnValue(false);
sessionStore = {
"agent:main:main": {
sessionId: "session-stale-custom",
lastChannel: "whatsapp",
queueMode: "collect",
queueDebounceMs: 0,
},
};
const didAnnounce = await runSubagentAnnounceFlow({
childSessionKey: "agent:main:subagent:test",
childRunId: "run-stale-custom-channel",
requesterSessionKey: "main",
requesterOrigin: { channel: "custombridge", to: "room:42" },
requesterDisplayKey: "main",
...defaultOutcomeAnnounce,
});
expect(didAnnounce).toBe(true);
expect(agentSpy).toHaveBeenCalledTimes(1);
const call = agentSpy.mock.calls[0]?.[0] as { params?: Record<string, unknown> };
expect(call?.params?.channel).toBe("custombridge");
expect(call?.params?.to).toBe("room:42");
});
it("routes or falls back for ended parent subagent sessions (#18037)", async () => {
const cases = [
{