fix(diagnostics): include talk events in stability snapshots

This commit is contained in:
Vincent Koc
2026-05-06 01:42:19 -07:00
parent 8d9e7c8178
commit 827e602d3a
2 changed files with 46 additions and 2 deletions

View File

@@ -22,7 +22,7 @@ describe("diagnostic stability recorder", () => {
resetDiagnosticEventsForTest();
});
it("records a bounded payload-free projection of diagnostic events", () => {
it("records a bounded payload-free projection of diagnostic events", async () => {
startDiagnosticStabilityRecorder();
emitDiagnosticEvent({
@@ -41,13 +41,29 @@ describe("diagnostic stability recorder", () => {
count: 3,
message: "message that should not be stored",
});
emitDiagnosticEvent({
type: "talk.event",
sessionId: "talk-session-secret",
turnId: "talk-turn-secret",
captureId: "talk-capture-secret",
talkEventType: "latency.metrics",
mode: "realtime",
transport: "gateway-relay",
brain: "agent-consult",
provider: "openai",
final: true,
durationMs: 12,
byteLength: 345,
});
await new Promise<void>((resolve) => setImmediate(resolve));
const snapshot = getDiagnosticStabilitySnapshot({ limit: 10 });
expect(snapshot.count).toBe(2);
expect(snapshot.count).toBe(3);
expect(snapshot.summary.byType).toMatchObject({
"webhook.error": 1,
"tool.loop": 1,
"talk.event": 1,
});
expect(snapshot.events[0]).toMatchObject({
type: "webhook.error",
@@ -66,6 +82,20 @@ describe("diagnostic stability recorder", () => {
expect(snapshot.events[1]).not.toHaveProperty("message");
expect(snapshot.events[1]).not.toHaveProperty("sessionId");
expect(snapshot.events[1]).not.toHaveProperty("sessionKey");
expect(snapshot.events[2]).toMatchObject({
type: "talk.event",
talkEventType: "latency.metrics",
mode: "realtime",
transport: "gateway-relay",
brain: "agent-consult",
provider: "openai",
final: true,
durationMs: 12,
bytes: 345,
});
expect(snapshot.events[2]).not.toHaveProperty("sessionId");
expect(snapshot.events[2]).not.toHaveProperty("turnId");
expect(snapshot.events[2]).not.toHaveProperty("captureId");
});
it("keeps stable reason codes but drops free-form reason text", () => {

View File

@@ -27,6 +27,9 @@ export type DiagnosticStabilityEventRecord = {
phase?: string;
detector?: string;
deliveryKind?: string;
talkEventType?: string;
transport?: string;
brain?: string;
toolName?: string;
activeWorkKind?: string;
pairedToolName?: string;
@@ -40,6 +43,7 @@ export type DiagnosticStabilityEventRecord = {
commandLength?: number;
exitCode?: number;
timedOut?: boolean;
final?: boolean;
costUsd?: number;
count?: number;
bytes?: number;
@@ -228,6 +232,16 @@ function sanitizeDiagnosticEvent(event: DiagnosticEventPayload): DiagnosticStabi
record.outcome = "error";
assignReasonCode(record, event.errorCategory);
break;
case "talk.event":
record.talkEventType = event.talkEventType;
record.mode = event.mode;
record.transport = event.transport;
record.brain = event.brain;
record.provider = event.provider;
record.final = event.final;
record.durationMs = event.durationMs;
record.bytes = event.byteLength;
break;
case "session.state":
record.outcome = event.state;
assignReasonCode(record, event.reason);