test: isolate Codex terminal diagnostic fallback

This commit is contained in:
Peter Steinberger
2026-05-23 22:34:27 +01:00
parent f603fa58fe
commit fa5c8345f3
2 changed files with 76 additions and 92 deletions

View File

@@ -9,7 +9,6 @@ import {
onAgentEvent,
queueAgentHarnessMessage,
resetAgentEventsForTest,
wrapToolWithBeforeToolCallHook,
type AgentEventPayload,
type EmbeddedRunAttemptParams,
} from "openclaw/plugin-sdk/agent-harness-runtime";
@@ -3366,25 +3365,26 @@ describe("runCodexAppServerAttempt", () => {
});
it("emits request-boundary terminal diagnostics when a wrapped dynamic tool does not", async () => {
const harness = createStartedThreadHarness();
const diagnosticEvents: DiagnosticEventPayload[] = [];
const unsubscribeDiagnostics = onInternalDiagnosticEvent((event) =>
diagnosticEvents.push(event),
);
const rawTool = {
name: "echo",
description: "echo test tool",
parameters: {
type: "object",
properties: {},
additionalProperties: false,
},
execute: vi.fn(async () => ({
content: [{ type: "text" as const, text: "echo done" }],
details: {},
})),
};
rawTool.execute.mockImplementationOnce(async () => {
try {
const call = {
threadId: "thread-1",
turnId: "turn-1",
callId: "call-echo-unobserved-terminal",
namespace: null,
tool: "echo",
arguments: {},
} satisfies CodexDynamicToolCallParams;
emitDynamicToolStartedDiagnostic({
call,
runId: "run-1",
sessionId: "session-1",
sessionKey: "agent:main:session-1",
});
emitTrustedDiagnosticEvent({
type: "tool.execution.completed",
runId: "other-run",
@@ -3394,84 +3394,67 @@ describe("runCodexAppServerAttempt", () => {
toolCallId: "call-echo-unobserved-terminal",
durationMs: 1,
});
return {
content: [{ type: "text" as const, text: "echo done" }],
details: {},
};
});
const markedWrappedTool = {
...wrapToolWithBeforeToolCallHook(rawTool as never),
execute: rawTool.execute,
};
testing.setOpenClawCodingToolsFactoryForTests(() => [markedWrappedTool as never]);
expect(
testing.hasPendingDynamicToolTerminalDiagnostic({
call,
runId: "run-1",
sessionId: "session-1",
sessionKey: "agent:main:session-1",
}),
).toBe(false);
const params = createParams(
path.join(tempDir, "session.jsonl"),
path.join(tempDir, "workspace"),
);
params.disableTools = false;
params.runtimePlan = createCodexRuntimePlanFixture();
const run = runCodexAppServerAttempt(params);
await harness.waitForMethod("thread/start");
const toolResult = (await harness.handleServerRequest({
id: "request-echo-unobserved-terminal-tool",
method: "item/tool/call",
params: {
threadId: "thread-1",
turnId: "turn-1",
callId: "call-echo-unobserved-terminal",
namespace: null,
tool: "echo",
arguments: {},
},
})) as {
contentItems?: Array<{ text?: string; type?: string }>;
success?: boolean;
};
expect(toolResult.success).toBe(true);
await harness.completeTurn({ threadId: "thread-1", turnId: "turn-1" });
await run;
await flushDiagnosticEvents();
unsubscribeDiagnostics();
const toolDiagnosticEvents = diagnosticEvents.filter(
(
event,
): event is Extract<
DiagnosticEventPayload,
{ type: "tool.execution.started" | "tool.execution.completed" | "tool.execution.error" }
> => event.type.startsWith("tool.execution."),
);
expect(
toolDiagnosticEvents.map((event) => ({
runId: event.runId,
type: event.type,
toolName: event.toolName,
toolCallId: event.toolCallId,
})),
).toEqual([
{
emitDynamicToolTerminalDiagnostic({
call,
runId: "run-1",
type: "tool.execution.started",
toolName: "echo",
toolCallId: "call-echo-unobserved-terminal",
},
{
runId: "other-run",
type: "tool.execution.completed",
toolName: "echo",
toolCallId: "call-echo-unobserved-terminal",
},
{
runId: "run-1",
type: "tool.execution.completed",
toolName: "echo",
toolCallId: "call-echo-unobserved-terminal",
},
]);
sessionId: "session-1",
sessionKey: "agent:main:session-1",
durationMs: 1,
response: {
success: true,
contentItems: [{ type: "inputText", text: "echo done" }],
},
});
await flushDiagnosticEvents();
const toolDiagnosticEvents = diagnosticEvents.filter(
(
event,
): event is Extract<
DiagnosticEventPayload,
{ type: "tool.execution.started" | "tool.execution.completed" | "tool.execution.error" }
> => event.type.startsWith("tool.execution."),
);
expect(
toolDiagnosticEvents.map((event) => ({
runId: event.runId,
type: event.type,
toolName: event.toolName,
toolCallId: event.toolCallId,
})),
).toEqual([
{
runId: "run-1",
type: "tool.execution.started",
toolName: "echo",
toolCallId: "call-echo-unobserved-terminal",
},
{
runId: "other-run",
type: "tool.execution.completed",
toolName: "echo",
toolCallId: "call-echo-unobserved-terminal",
},
{
runId: "run-1",
type: "tool.execution.completed",
toolName: "echo",
toolCallId: "call-echo-unobserved-terminal",
},
]);
} finally {
unsubscribeDiagnostics();
}
});
it("does not duplicate terminal diagnostics for wrapped dynamic tool blocks", async () => {

View File

@@ -5644,6 +5644,7 @@ export const testing = {
shouldForceMessageTool,
shouldReleaseTurnAfterTerminalDynamicTool,
resolveTerminalDynamicToolBatchAction,
hasPendingDynamicToolTerminalDiagnostic,
buildCodexPluginThreadConfigEligibilityLogData,
withCodexStartupTimeout,
setOpenClawCodingToolsFactoryForTests(factory: OpenClawCodingToolsFactory): void {