fix(gateway): stabilize imsg alias test coverage

This commit is contained in:
Vincent Koc
2026-04-15 11:24:09 +01:00
parent 804bb0f2c3
commit becd14424d
3 changed files with 21 additions and 11 deletions

View File

@@ -38,6 +38,7 @@ Docs: https://docs.openclaw.ai
- Agents/Anthropic: ignore non-positive Anthropic Messages token overrides and fail locally when no positive token budget remains, so invalid `max_tokens` values no longer reach the provider API. (#66664) thanks @jalehman
- Agents/context engines: preserve prompt-only token counts, not full request totals, when deferred maintenance reuses after-turn runtime context so background compaction bookkeeping matches the active prompt window. (#66820) thanks @jalehman.
- BlueBubbles/inbound: add a persistent file-backed GUID dedupe so MessagePoller webhook replays after BB Server restart or reconnect no longer cause the agent to re-reply to already-handled messages. (#19176, #12053, #66816) Thanks @omarshahine.
- Gateway/tests: keep the built-in `imsg` agent alias regression on the stubbed iMessage path and harden shared gateway WS request helpers against reply-listener races so the alias contract no longer flakes in CI. Thanks @vincentkoc.
- Secrets/plugins/status: align SecretRef inspect-vs-strict handling across plugin preload, read-only status/agents surfaces, and runtime auth paths so unresolved refs no longer crash read-only CLI flows while runtime-required non-env refs stay strict. (#66818) Thanks @joshavant.
- Memory/dreaming: stop ordinary transcripts that merely quote the dream-diary prompt from being classified as internal dreaming runs and silently dropped from session recall ingestion. (#66852) Thanks @gumadeiras.
- Telegram/documents: sanitize binary reply context and ZIP-like archive extraction so `.epub` and `.mobi` uploads can no longer leak raw binary into prompt context through reply metadata or archive-to-`text/plain` coercion. (#66877) Thanks @martinfrancois.

View File

@@ -225,6 +225,11 @@ describe("gateway server agent", () => {
test("agent accepts built-in channel alias (imsg)", async () => {
const registry = createRegistry([
{
pluginId: "imessage",
source: "test",
plugin: createStubChannelPlugin({ id: "imessage", label: "iMessage" }),
},
{
pluginId: "msteams",
source: "test",
@@ -245,7 +250,9 @@ describe("gateway server agent", () => {
idempotencyKey: "idem-agent-imsg",
});
expect(resIMessage.ok).toBe(true);
await vi.waitFor(() => {
expect(vi.mocked(agentCommand)).toHaveBeenCalled();
});
expectAgentRoutingCall({ channel: "imessage", deliver: true, fromEnd: 1 });
});

View File

@@ -944,6 +944,14 @@ export async function connectReq(
nonce: connectChallengeNonce,
};
})();
const isResponseForId = (o: unknown): boolean => {
if (!o || typeof o !== "object" || Array.isArray(o)) {
return false;
}
const rec = o as Record<string, unknown>;
return rec.type === "res" && rec.id === id;
};
const responsePromise = onceMessage<ConnectResponse>(ws, isResponseForId, opts?.timeoutMs);
ws.send(
JSON.stringify({
type: "req",
@@ -971,14 +979,7 @@ export async function connectReq(
},
}),
);
const isResponseForId = (o: unknown): boolean => {
if (!o || typeof o !== "object" || Array.isArray(o)) {
return false;
}
const rec = o as Record<string, unknown>;
return rec.type === "res" && rec.id === id;
};
return await onceMessage<ConnectResponse>(ws, isResponseForId, opts?.timeoutMs);
return await responsePromise;
}
export async function connectOk(ws: WebSocket, opts?: Parameters<typeof connectReq>[1]) {
@@ -1042,8 +1043,7 @@ export async function rpcReq<T extends Record<string, unknown>>(
clearSessionStoreCacheForTest();
const { randomUUID } = await import("node:crypto");
const id = randomUUID();
ws.send(JSON.stringify({ type: "req", id, method, params }));
return await onceMessage<{
const responsePromise = onceMessage<{
type: "res";
id: string;
ok: boolean;
@@ -1060,6 +1060,8 @@ export async function rpcReq<T extends Record<string, unknown>>(
},
timeoutMs,
);
ws.send(JSON.stringify({ type: "req", id, method, params }));
return await responsePromise;
}
export async function waitForSystemEvent(timeoutMs = 2000) {