mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-18 22:24:46 +00:00
test: clear acp spawn broad matchers
This commit is contained in:
@@ -327,8 +327,70 @@ function expectAcceptedSpawn(result: SpawnResult): Extract<SpawnResult, { status
|
||||
return result;
|
||||
}
|
||||
|
||||
function expectRecordFields(
|
||||
record: unknown,
|
||||
expected: Record<string, unknown>,
|
||||
): Record<string, unknown> {
|
||||
expect(record).toBeDefined();
|
||||
const actual = record as Record<string, unknown>;
|
||||
for (const [key, value] of Object.entries(expected)) {
|
||||
expect(actual[key]).toEqual(value);
|
||||
}
|
||||
return actual;
|
||||
}
|
||||
|
||||
function gatewayRequests(): Array<{ method?: string; params?: Record<string, unknown> }> {
|
||||
return hoisted.callGatewayMock.mock.calls.map(
|
||||
(call: unknown[]) => call[0] as { method?: string; params?: Record<string, unknown> },
|
||||
);
|
||||
}
|
||||
|
||||
function gatewayRequest(method: string): { method?: string; params?: Record<string, unknown> } {
|
||||
const request = gatewayRequests().find((candidate) => candidate.method === method);
|
||||
expect(request).toBeDefined();
|
||||
return request as { method?: string; params?: Record<string, unknown> };
|
||||
}
|
||||
|
||||
function expectGatewayMethodNotCalled(method: string): void {
|
||||
expect(gatewayRequests().some((request) => request.method === method)).toBe(false);
|
||||
}
|
||||
|
||||
function expectSessionPatchFields(expected: Record<string, unknown>): void {
|
||||
expectRecordFields(gatewayRequest("sessions.patch").params, expected);
|
||||
}
|
||||
|
||||
function expectInitializeSessionFields(expected: Record<string, unknown>): Record<string, unknown> {
|
||||
return expectRecordFields(hoisted.initializeSessionMock.mock.calls[0]?.[0], expected);
|
||||
}
|
||||
|
||||
function expectBindingCallFields(expected: {
|
||||
conversation?: Record<string, unknown>;
|
||||
metadata?: Record<string, unknown>;
|
||||
placement?: string;
|
||||
targetKind?: string;
|
||||
}): Record<string, unknown> {
|
||||
const input = expectRecordFields(hoisted.sessionBindingBindMock.mock.calls.at(-1)?.[0], {
|
||||
...(expected.placement ? { placement: expected.placement } : {}),
|
||||
...(expected.targetKind ? { targetKind: expected.targetKind } : {}),
|
||||
});
|
||||
if (expected.conversation) {
|
||||
expectRecordFields(input.conversation, expected.conversation);
|
||||
}
|
||||
if (expected.metadata) {
|
||||
expectRecordFields(input.metadata, expected.metadata);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
function expectRelayCallFields(expected: Record<string, unknown>, callIndex = 0): void {
|
||||
expectRecordFields(
|
||||
hoisted.startAcpSpawnParentStreamRelayMock.mock.calls[callIndex]?.[0],
|
||||
expected,
|
||||
);
|
||||
}
|
||||
|
||||
function expectAgentGatewayCall(overrides: AgentCallParams): void {
|
||||
const agentCall = findAgentGatewayCall();
|
||||
const agentCall = gatewayRequest("agent");
|
||||
expect(agentCall?.params?.deliver).toBe(overrides.deliver);
|
||||
expect(agentCall?.params?.channel).toBe(overrides.channel);
|
||||
expect(agentCall?.params?.to).toBe(overrides.to);
|
||||
@@ -689,37 +751,28 @@ describe("spawnAcpDirect", () => {
|
||||
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");
|
||||
expect(patchCall?.params).toMatchObject({
|
||||
expectSessionPatchFields({
|
||||
key: accepted.childSessionKey,
|
||||
spawnedBy: "agent:main:main",
|
||||
});
|
||||
expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
targetKind: "session",
|
||||
placement: "child",
|
||||
}),
|
||||
);
|
||||
expectBindingCallFields({
|
||||
targetKind: "session",
|
||||
placement: "child",
|
||||
});
|
||||
expectResolvedIntroTextInBindMetadata();
|
||||
|
||||
const agentCall = hoisted.callGatewayMock.mock.calls
|
||||
.map((call: unknown[]) => call[0] as { method?: string; params?: Record<string, unknown> })
|
||||
.find((request) => request.method === "agent");
|
||||
const agentCall = gatewayRequest("agent");
|
||||
expect(agentCall?.params?.sessionKey).toMatch(/^agent:codex:acp:/);
|
||||
expect(agentCall?.params?.to).toBe("channel:child-thread");
|
||||
expect(agentCall?.params?.threadId).toBe("child-thread");
|
||||
expect(agentCall?.params?.deliver).toBe(true);
|
||||
expect(agentCall?.params?.lane).toBe("subagent");
|
||||
expect(agentCall?.params?.acpTurnSource).toBe("manual_spawn");
|
||||
expect(hoisted.initializeSessionMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sessionKey: expect.stringMatching(/^agent:codex:acp:/),
|
||||
agent: "codex",
|
||||
mode: "persistent",
|
||||
}),
|
||||
);
|
||||
const initInput = expectInitializeSessionFields({
|
||||
agent: "codex",
|
||||
mode: "persistent",
|
||||
});
|
||||
expect(initInput.sessionKey).toMatch(/^agent:codex:acp:/);
|
||||
const transcriptCalls = hoisted.resolveSessionTranscriptFileMock.mock.calls.map(
|
||||
(call: unknown[]) => call[0] as { threadId?: string },
|
||||
);
|
||||
@@ -765,11 +818,7 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expectAcceptedSpawn(result);
|
||||
expect(hoisted.initializeSessionMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
resumeSessionId,
|
||||
}),
|
||||
);
|
||||
expectInitializeSessionFields({ resumeSessionId });
|
||||
});
|
||||
|
||||
it("rejects ACP resume IDs not recorded for the requester session", async () => {
|
||||
@@ -807,7 +856,7 @@ describe("spawnAcpDirect", () => {
|
||||
},
|
||||
);
|
||||
|
||||
expect(result).toMatchObject({
|
||||
expectRecordFields(result, {
|
||||
status: "forbidden",
|
||||
errorCode: "resume_forbidden",
|
||||
});
|
||||
@@ -829,16 +878,14 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expectAcceptedSpawn(result);
|
||||
expect(hoisted.initializeSessionMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sessionKey: expect.stringMatching(/^agent:codex:acp:/),
|
||||
agent: "codex",
|
||||
runtimeOptions: {
|
||||
model: "openai-codex/gpt-5.4",
|
||||
thinking: "high",
|
||||
},
|
||||
}),
|
||||
);
|
||||
const initInput = expectInitializeSessionFields({
|
||||
agent: "codex",
|
||||
runtimeOptions: {
|
||||
model: "openai-codex/gpt-5.4",
|
||||
thinking: "high",
|
||||
},
|
||||
});
|
||||
expect(initInput.sessionKey).toMatch(/^agent:codex:acp:/);
|
||||
});
|
||||
|
||||
it("applies ACP spawn run timeout to runtime options and dispatch", async () => {
|
||||
@@ -854,15 +901,13 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expectAcceptedSpawn(result);
|
||||
expect(hoisted.initializeSessionMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sessionKey: expect.stringMatching(/^agent:codex:acp:/),
|
||||
agent: "codex",
|
||||
runtimeOptions: {
|
||||
timeoutSeconds: 45,
|
||||
},
|
||||
}),
|
||||
);
|
||||
const initInput = expectInitializeSessionFields({
|
||||
agent: "codex",
|
||||
runtimeOptions: {
|
||||
timeoutSeconds: 45,
|
||||
},
|
||||
});
|
||||
expect(initInput.sessionKey).toMatch(/^agent:codex:acp:/);
|
||||
const agentCall = findAgentGatewayCall();
|
||||
expect(agentCall?.params?.lane).toBe("subagent");
|
||||
expect(agentCall?.params?.timeout).toBe(45);
|
||||
@@ -897,15 +942,13 @@ describe("spawnAcpDirect", () => {
|
||||
},
|
||||
);
|
||||
|
||||
expect(result).toMatchObject({
|
||||
expectRecordFields(result, {
|
||||
status: "error",
|
||||
errorCode: "runtime_agent_mismatch",
|
||||
});
|
||||
expect(result).toHaveProperty("error", expect.stringContaining("OpenClaw config agent"));
|
||||
expect(hoisted.initializeSessionMock).not.toHaveBeenCalled();
|
||||
expect(hoisted.callGatewayMock).not.toHaveBeenCalledWith(
|
||||
expect.objectContaining({ method: "agent" }),
|
||||
);
|
||||
expectGatewayMethodNotCalled("agent");
|
||||
});
|
||||
|
||||
it("maps OpenClaw ACP runtime agent aliases to their configured harness id", async () => {
|
||||
@@ -943,12 +986,8 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expectAcceptedSpawn(result);
|
||||
expect(hoisted.initializeSessionMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
agent: "codex",
|
||||
sessionKey: expect.stringMatching(/^agent:codex:acp:/),
|
||||
}),
|
||||
);
|
||||
const initInput = expectInitializeSessionFields({ agent: "codex" });
|
||||
expect(initInput.sessionKey).toMatch(/^agent:codex:acp:/);
|
||||
});
|
||||
|
||||
it("inherits subagent envelope fields onto ACP children", async () => {
|
||||
@@ -971,10 +1010,7 @@ describe("spawnAcpDirect", () => {
|
||||
});
|
||||
|
||||
const accepted = expectAcceptedSpawn(result);
|
||||
const patchCall = hoisted.callGatewayMock.mock.calls
|
||||
.map((call: unknown[]) => call[0] as { method?: string; params?: Record<string, unknown> })
|
||||
.find((request) => request.method === "sessions.patch");
|
||||
expect(patchCall?.params).toMatchObject({
|
||||
expectSessionPatchFields({
|
||||
key: accepted.childSessionKey,
|
||||
spawnedBy: "agent:main:subagent:parent",
|
||||
spawnDepth: 2,
|
||||
@@ -1261,16 +1297,14 @@ describe("spawnAcpDirect", () => {
|
||||
},
|
||||
);
|
||||
expect(result.status, JSON.stringify(result)).toBe("accepted");
|
||||
expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
placement: "child",
|
||||
conversation: expect.objectContaining({
|
||||
channel: "matrix",
|
||||
accountId: "default",
|
||||
conversationId: "!room:example",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expectBindingCallFields({
|
||||
placement: "child",
|
||||
conversation: {
|
||||
channel: "matrix",
|
||||
accountId: "default",
|
||||
conversationId: "!room:example",
|
||||
},
|
||||
});
|
||||
expectAgentGatewayCall({
|
||||
deliver: true,
|
||||
channel: "matrix",
|
||||
@@ -1321,16 +1355,14 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expect(result.status, JSON.stringify(result)).toBe("accepted");
|
||||
expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
placement: "child",
|
||||
conversation: expect.objectContaining({
|
||||
channel: "matrix",
|
||||
accountId: "default",
|
||||
conversationId: "!Room:Example.org",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expectBindingCallFields({
|
||||
placement: "child",
|
||||
conversation: {
|
||||
channel: "matrix",
|
||||
accountId: "default",
|
||||
conversationId: "!Room:Example.org",
|
||||
},
|
||||
});
|
||||
expectAgentGatewayCall({
|
||||
deliver: true,
|
||||
channel: "matrix",
|
||||
@@ -1382,17 +1414,15 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expect(result.status, JSON.stringify(result)).toBe("accepted");
|
||||
expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
placement: "child",
|
||||
conversation: expect.objectContaining({
|
||||
channel: "matrix",
|
||||
accountId: "default",
|
||||
conversationId: "$thread-root",
|
||||
parentConversationId: "!Room:Example.org",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expectBindingCallFields({
|
||||
placement: "child",
|
||||
conversation: {
|
||||
channel: "matrix",
|
||||
accountId: "default",
|
||||
conversationId: "$thread-root",
|
||||
parentConversationId: "!Room:Example.org",
|
||||
},
|
||||
});
|
||||
expectAgentGatewayCall({
|
||||
deliver: true,
|
||||
channel: "matrix",
|
||||
@@ -1418,13 +1448,11 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expect(result.status).toBe("accepted");
|
||||
expect(hoisted.initializeSessionMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sessionKey: expect.stringMatching(/^agent:claude-code:acp:/),
|
||||
agent: "claude-code",
|
||||
cwd: fixture.targetWorkspace,
|
||||
}),
|
||||
);
|
||||
const initInput = expectInitializeSessionFields({
|
||||
agent: "claude-code",
|
||||
cwd: fixture.targetWorkspace,
|
||||
});
|
||||
expect(initInput.sessionKey).toMatch(/^agent:claude-code:acp:/);
|
||||
} finally {
|
||||
await fs.rm(fixture.workspaceRoot, { recursive: true, force: true });
|
||||
}
|
||||
@@ -1450,13 +1478,11 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expect(result.status).toBe("accepted");
|
||||
expect(hoisted.initializeSessionMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sessionKey: expect.stringMatching(/^agent:claude-code:acp:/),
|
||||
agent: "claude-code",
|
||||
cwd: undefined,
|
||||
}),
|
||||
);
|
||||
const initInput = expectInitializeSessionFields({
|
||||
agent: "claude-code",
|
||||
cwd: undefined,
|
||||
});
|
||||
expect(initInput.sessionKey).toMatch(/^agent:claude-code:acp:/);
|
||||
} finally {
|
||||
await fs.rm(fixture.workspaceRoot, { recursive: true, force: true });
|
||||
}
|
||||
@@ -1534,16 +1560,14 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expect(result.status, JSON.stringify(result)).toBe("accepted");
|
||||
expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
placement: "current",
|
||||
conversation: expect.objectContaining({
|
||||
channel: "line",
|
||||
accountId: "default",
|
||||
conversationId: "U1234567890abcdef1234567890abcdef",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expectBindingCallFields({
|
||||
placement: "current",
|
||||
conversation: {
|
||||
channel: "line",
|
||||
accountId: "default",
|
||||
conversationId: "U1234567890abcdef1234567890abcdef",
|
||||
},
|
||||
});
|
||||
expectAgentGatewayCall({
|
||||
deliver: true,
|
||||
channel: "line",
|
||||
@@ -1629,16 +1653,14 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expect(result.status).toBe("accepted");
|
||||
expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
placement: "current",
|
||||
conversation: expect.objectContaining({
|
||||
channel: "custom",
|
||||
accountId: "work",
|
||||
conversationId: "123456",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expectBindingCallFields({
|
||||
placement: "current",
|
||||
conversation: {
|
||||
channel: "custom",
|
||||
accountId: "work",
|
||||
conversationId: "123456",
|
||||
},
|
||||
});
|
||||
expectAgentGatewayCall({
|
||||
deliver: true,
|
||||
channel: "custom",
|
||||
@@ -1740,17 +1762,15 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expect(result.status).toBe("accepted");
|
||||
expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
placement: "child",
|
||||
conversation: expect.objectContaining({
|
||||
channel: "matrix",
|
||||
accountId: "bot-alpha",
|
||||
conversationId: boundRoom,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expect(findAgentGatewayCall()?.params).toMatchObject({
|
||||
expectBindingCallFields({
|
||||
placement: "child",
|
||||
conversation: {
|
||||
channel: "matrix",
|
||||
accountId: "bot-alpha",
|
||||
conversationId: boundRoom,
|
||||
},
|
||||
});
|
||||
expectRecordFields(gatewayRequest("agent").params, {
|
||||
deliver: true,
|
||||
channel: "matrix",
|
||||
accountId: "bot-alpha",
|
||||
@@ -1820,16 +1840,14 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expect(result.status).toBe("accepted");
|
||||
expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
placement: "current",
|
||||
conversation: expect.objectContaining({
|
||||
channel: "line",
|
||||
accountId: "default",
|
||||
conversationId: expectedConversationId,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expectBindingCallFields({
|
||||
placement: "current",
|
||||
conversation: {
|
||||
channel: "line",
|
||||
accountId: "default",
|
||||
conversationId: expectedConversationId,
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1873,16 +1891,14 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expect(result.status).toBe("accepted");
|
||||
expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
placement: "current",
|
||||
conversation: expect.objectContaining({
|
||||
channel: "line",
|
||||
accountId: "default",
|
||||
conversationId: "R1234567890abcdef1234567890abcdef",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expectBindingCallFields({
|
||||
placement: "current",
|
||||
conversation: {
|
||||
channel: "line",
|
||||
accountId: "default",
|
||||
conversationId: "R1234567890abcdef1234567890abcdef",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it.each([
|
||||
@@ -1919,13 +1935,11 @@ describe("spawnAcpDirect", () => {
|
||||
expect(accepted.streamLogPath).toBeUndefined();
|
||||
expect(hoisted.startAcpSpawnParentStreamRelayMock).not.toHaveBeenCalled();
|
||||
if (expectTranscriptPersistence) {
|
||||
expect(hoisted.resolveSessionTranscriptFileMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
sessionId: "sess-123",
|
||||
storePath: "/tmp/codex-sessions.json",
|
||||
agentId: "codex",
|
||||
}),
|
||||
);
|
||||
expectRecordFields(hoisted.resolveSessionTranscriptFileMock.mock.calls[0]?.[0], {
|
||||
sessionId: "sess-123",
|
||||
storePath: "/tmp/codex-sessions.json",
|
||||
agentId: "codex",
|
||||
});
|
||||
}
|
||||
expectAgentGatewayCall(expectedAgentCall);
|
||||
});
|
||||
@@ -1974,13 +1988,10 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expect(result.status).toBe("accepted");
|
||||
expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
metadata: expect.objectContaining({
|
||||
introText: expect.stringContaining("cwd: /home/bob/clawd"),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
const bindInput = expectBindingCallFields({});
|
||||
const metadata = expectRecordFields(bindInput.metadata, {});
|
||||
expect(typeof metadata.introText).toBe("string");
|
||||
expect(metadata.introText).toContain("cwd: /home/bob/clawd");
|
||||
});
|
||||
|
||||
it("rejects disallowed ACP agents", async () => {
|
||||
@@ -2003,7 +2014,7 @@ describe("spawnAcpDirect", () => {
|
||||
},
|
||||
);
|
||||
|
||||
expect(result).toMatchObject({
|
||||
expectRecordFields(result, {
|
||||
status: "forbidden",
|
||||
});
|
||||
});
|
||||
@@ -2132,22 +2143,22 @@ describe("spawnAcpDirect", () => {
|
||||
expect(typeof relayCallOrder).toBe("number");
|
||||
expect(typeof agentCallOrder).toBe("number");
|
||||
expect(relayCallOrder < agentCallOrder).toBe(true);
|
||||
expect(hoisted.startAcpSpawnParentStreamRelayMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
parentSessionKey: "agent:main:main",
|
||||
agentId: "codex",
|
||||
logPath: "/tmp/sess-main.acp-stream.jsonl",
|
||||
emitStartNotice: false,
|
||||
}),
|
||||
);
|
||||
expectRelayCallFields({
|
||||
parentSessionKey: "agent:main:main",
|
||||
agentId: "codex",
|
||||
logPath: "/tmp/sess-main.acp-stream.jsonl",
|
||||
emitStartNotice: false,
|
||||
});
|
||||
const relayRuns = hoisted.startAcpSpawnParentStreamRelayMock.mock.calls.map(
|
||||
(call: unknown[]) => (call[0] as { runId?: string }).runId,
|
||||
);
|
||||
expect(relayRuns).toContain(agentCall?.params?.idempotencyKey);
|
||||
expect(relayRuns).toContain(accepted.runId);
|
||||
expect(hoisted.resolveAcpSpawnStreamLogPathMock).toHaveBeenCalledWith({
|
||||
childSessionKey: expect.stringMatching(/^agent:codex:acp:/),
|
||||
});
|
||||
const streamPathInput = expectRecordFields(
|
||||
hoisted.resolveAcpSpawnStreamLogPathMock.mock.calls[0]?.[0],
|
||||
{},
|
||||
);
|
||||
expect(streamPathInput.childSessionKey).toMatch(/^agent:codex:acp:/);
|
||||
expect(firstHandle.dispose).toHaveBeenCalledTimes(1);
|
||||
expect(firstHandle.notifyStarted).not.toHaveBeenCalled();
|
||||
expect(secondHandle.notifyStarted).toHaveBeenCalledTimes(1);
|
||||
@@ -2220,19 +2231,17 @@ describe("spawnAcpDirect", () => {
|
||||
expect(agentCall?.params?.channel).toBeUndefined();
|
||||
expect(agentCall?.params?.to).toBeUndefined();
|
||||
expect(agentCall?.params?.threadId).toBeUndefined();
|
||||
expect(hoisted.startAcpSpawnParentStreamRelayMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
parentSessionKey: "agent:main:subagent:parent",
|
||||
agentId: "codex",
|
||||
logPath: "/tmp/sess-main.acp-stream.jsonl",
|
||||
deliveryContext: {
|
||||
channel: "discord",
|
||||
to: "channel:parent-channel",
|
||||
accountId: "default",
|
||||
},
|
||||
emitStartNotice: false,
|
||||
}),
|
||||
);
|
||||
expectRelayCallFields({
|
||||
parentSessionKey: "agent:main:subagent:parent",
|
||||
agentId: "codex",
|
||||
logPath: "/tmp/sess-main.acp-stream.jsonl",
|
||||
deliveryContext: {
|
||||
channel: "discord",
|
||||
to: "channel:parent-channel",
|
||||
accountId: "default",
|
||||
},
|
||||
emitStartNotice: false,
|
||||
});
|
||||
expect(firstHandle.dispose).toHaveBeenCalledTimes(1);
|
||||
expect(secondHandle.notifyStarted).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
@@ -2570,17 +2579,15 @@ describe("spawnAcpDirect", () => {
|
||||
|
||||
const accepted = expectAcceptedSpawn(result);
|
||||
expect(accepted.mode).toBe("session");
|
||||
expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
placement: "current",
|
||||
conversation: expect.objectContaining({
|
||||
channel: "telegram",
|
||||
accountId: "default",
|
||||
conversationId: "2",
|
||||
parentConversationId: "-1003342490704",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expectBindingCallFields({
|
||||
placement: "current",
|
||||
conversation: {
|
||||
channel: "telegram",
|
||||
accountId: "default",
|
||||
conversationId: "2",
|
||||
parentConversationId: "-1003342490704",
|
||||
},
|
||||
});
|
||||
const agentCall = hoisted.callGatewayMock.mock.calls
|
||||
.map((call: unknown[]) => call[0] as { method?: string; params?: Record<string, unknown> })
|
||||
.find((request) => request.method === "agent");
|
||||
@@ -2608,16 +2615,14 @@ describe("spawnAcpDirect", () => {
|
||||
|
||||
const accepted = expectAcceptedSpawn(result);
|
||||
expect(accepted.mode).toBe("session");
|
||||
expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
placement: "current",
|
||||
conversation: expect.objectContaining({
|
||||
channel: "telegram",
|
||||
accountId: "default",
|
||||
conversationId: "6098642967",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expectBindingCallFields({
|
||||
placement: "current",
|
||||
conversation: {
|
||||
channel: "telegram",
|
||||
accountId: "default",
|
||||
conversationId: "6098642967",
|
||||
},
|
||||
});
|
||||
const bindCall = hoisted.sessionBindingBindMock.mock.calls.at(-1)?.[0] as
|
||||
| { conversation?: { parentConversationId?: string } }
|
||||
| undefined;
|
||||
@@ -2643,16 +2648,14 @@ describe("spawnAcpDirect", () => {
|
||||
);
|
||||
|
||||
expect(result.status).toBe("accepted");
|
||||
expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
placement: "current",
|
||||
conversation: expect.objectContaining({
|
||||
channel: "telegram",
|
||||
accountId: "default",
|
||||
conversationId: "-1003342490704:topic:2",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expectBindingCallFields({
|
||||
placement: "current",
|
||||
conversation: {
|
||||
channel: "telegram",
|
||||
accountId: "default",
|
||||
conversationId: "-1003342490704:topic:2",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("disposes pre-registered parent relay when initial ACP dispatch fails", async () => {
|
||||
|
||||
Reference in New Issue
Block a user