fix: 校正实时探针可选工具事件合同
This commit is contained in:
@@ -36,6 +36,7 @@ test("realtime fanout keeps the YAML terminal timeout when durationMs is absent"
|
||||
},
|
||||
forbiddenRequestPaths: [],
|
||||
requiredEventTypes: { agentrun: ["terminal_status"], hwlab: ["terminal"] },
|
||||
conditionalEventTypePairs: { "tool-call": { agentrun: "tool_call", hwlab: "tool" } },
|
||||
expectedKafka: {
|
||||
topics: { stdio: "codex-stdio.raw.v1", agentrun: "agentrun.event.v1", hwlab: "hwlab.event.v1" },
|
||||
groups: { directPublish: "direct", transactionalProjector: "projector", liveSse: "live" },
|
||||
@@ -46,6 +47,91 @@ test("realtime fanout keeps the YAML terminal timeout when durationMs is absent"
|
||||
assert.equal(effectiveProfile(profile, null).terminalTimeoutMs, 480_000);
|
||||
assert.equal(effectiveProfile(profile, undefined).terminalTimeoutMs, 480_000);
|
||||
assert.equal(effectiveProfile(profile, 5_000).terminalTimeoutMs, 5_000);
|
||||
assert.deepEqual(effectiveProfile(profile, null).conditionalEventTypePairs, profile.conditionalEventTypePairs);
|
||||
});
|
||||
|
||||
test("realtime fanout terminal completion does not require absent optional tool families", () => {
|
||||
const source = nodeWebObserveRunnerRealtimeSource();
|
||||
const build = new Function(`${source}\nreturn realtimeDebugTurnCompletion;`) as () => (
|
||||
snapshot: Record<string, any>, traceId: string, profile: Record<string, any>,
|
||||
) => Record<string, any>;
|
||||
const completion = build();
|
||||
const traceId = "trc_direct_answer";
|
||||
const profile = {
|
||||
debugStreams: ["stdio", "agentrun", "hwlab"],
|
||||
requiredEventTypes: {
|
||||
agentrun: ["user_message", "assistant_message", "terminal_status"],
|
||||
hwlab: ["user", "assistant", "terminal"],
|
||||
},
|
||||
conditionalEventTypePairs: {
|
||||
"tool-call": { agentrun: "tool_call", hwlab: "tool" },
|
||||
"command-output": { agentrun: "command_output", hwlab: "status" },
|
||||
},
|
||||
};
|
||||
const snapshot = {
|
||||
records: {
|
||||
stdio: [{ traceId, eventType: "codex.stdio.stdout" }],
|
||||
agentrun: ["user_message", "backend_status", "assistant_message", "terminal_status"].map((eventType) => ({ traceId, eventType })),
|
||||
hwlab: ["user", "backend", "assistant", "terminal"].map((eventType) => ({ traceId, eventType })),
|
||||
},
|
||||
};
|
||||
|
||||
const directAnswer = completion(snapshot, traceId, profile);
|
||||
assert.equal(directAnswer.complete, true);
|
||||
assert.deepEqual(directAnswer.missingEventTypes, { agentrun: [], hwlab: [] });
|
||||
|
||||
const missingTerminal = completion({
|
||||
records: {
|
||||
...snapshot.records,
|
||||
agentrun: snapshot.records.agentrun.filter((row: Record<string, string>) => row.eventType !== "terminal_status"),
|
||||
hwlab: snapshot.records.hwlab.filter((row: Record<string, string>) => row.eventType !== "terminal"),
|
||||
},
|
||||
}, traceId, profile);
|
||||
assert.equal(missingTerminal.complete, false);
|
||||
assert.deepEqual(missingTerminal.missingEventTypes, { agentrun: ["terminal_status"], hwlab: ["terminal"] });
|
||||
assert.ok(missingTerminal.observedEventTypes.agentrun.includes("assistant_message"));
|
||||
});
|
||||
|
||||
test("realtime fanout validates optional tool events only when they occur", () => {
|
||||
const source = nodeWebObserveRunnerRealtimeSource();
|
||||
const build = new Function(`${source}\nreturn realtimeValidateConditionalEventTypePairs;`) as () => (
|
||||
input: Record<string, any>,
|
||||
) => void;
|
||||
const validate = build();
|
||||
const traceId = "trc_optional_tool";
|
||||
const base = {
|
||||
turn: 1,
|
||||
traceId,
|
||||
profile: {
|
||||
conditionalEventTypePairs: {
|
||||
"tool-call": { agentrun: "tool_call", hwlab: "tool" },
|
||||
"command-output": { agentrun: "command_output", hwlab: "status" },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
assert.doesNotThrow(() => validate({ ...base, debug: { records: { agentrun: [], hwlab: [] } } }));
|
||||
assert.doesNotThrow(() => validate({
|
||||
...base,
|
||||
debug: {
|
||||
records: {
|
||||
agentrun: [{ traceId, eventType: "tool_call", eventId: "evt_tool" }],
|
||||
hwlab: [{ traceId, eventType: "tool", sourceEventId: "evt_tool" }],
|
||||
},
|
||||
},
|
||||
}));
|
||||
assert.throws(
|
||||
() => validate({
|
||||
...base,
|
||||
debug: {
|
||||
records: {
|
||||
agentrun: [{ traceId, eventType: "command_output", eventId: "evt_output" }],
|
||||
hwlab: [],
|
||||
},
|
||||
},
|
||||
}),
|
||||
/conditional event pair command-output count differs/u,
|
||||
);
|
||||
});
|
||||
|
||||
test("realtime fanout retries a YAML-bounded transient health navigation", async () => {
|
||||
|
||||
Reference in New Issue
Block a user