summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-07 18:56:16 +0900
committerAdam Malczewski <[email protected]>2026-06-07 18:56:16 +0900
commitccfd2f4157c1cbbb3d8aeceee94d9e963a82ab03 (patch)
tree4b8a1be9ac885dd2527279bc0cb84e70b1115bba
parent80f8a219c89a963c485da0f40dc428bf688fedb7 (diff)
downloaddispatch-web-ccfd2f4157c1cbbb3d8aeceee94d9e963a82ab03.tar.gz
dispatch-web-ccfd2f4157c1cbbb3d8aeceee94d9e963a82ab03.zip
fix(core): add step-complete contract guard for [email protected]
The backend's AgentEvent union now includes TurnStepCompleteEvent (wire/transport-contract 0.3.0). Add: no-op case in foldEvent (transcript reducer ignores timing metadata), exhaustiveness case in assertAgentEventExhaustive, and a step-complete sample in the conformance test (now 12 variants).
-rw-r--r--src/core/chunks/reducer.ts4
-rw-r--r--src/core/wire/conformance.test.ts14
-rw-r--r--src/core/wire/conformance.ts2
3 files changed, 18 insertions, 2 deletions
diff --git a/src/core/chunks/reducer.ts b/src/core/chunks/reducer.ts
index 1dcfa39..54b1922 100644
--- a/src/core/chunks/reducer.ts
+++ b/src/core/chunks/reducer.ts
@@ -148,6 +148,10 @@ export function foldEvent(state: TranscriptState, event: AgentEvent): Transcript
case "usage":
return { ...state, latestUsage: event.usage };
+ case "step-complete":
+ // Timing metadata — no content chunk; handled by the telemetry reducer.
+ return state;
+
case "done": {
const provisional = flushAccumulating(state.provisional, state.accumulating);
return {
diff --git a/src/core/wire/conformance.test.ts b/src/core/wire/conformance.test.ts
index 50b7f35..690ba4e 100644
--- a/src/core/wire/conformance.test.ts
+++ b/src/core/wire/conformance.test.ts
@@ -62,6 +62,15 @@ describe("classifies every AgentEvent type", () => {
turnId: "t1",
usage: { inputTokens: 10, outputTokens: 20 },
},
+ {
+ type: "step-complete",
+ conversationId: "c1",
+ turnId: "t1",
+ stepId: "t1#0" as StepId,
+ ttftMs: 300,
+ decodeMs: 700,
+ genTotalMs: 1000,
+ },
{ type: "error", conversationId: "c1", turnId: "t1", message: "oops" },
{ type: "done", conversationId: "c1", turnId: "t1", reason: "complete" },
{ type: "turn-sealed", conversationId: "c1", turnId: "t1" },
@@ -78,14 +87,15 @@ describe("classifies every AgentEvent type", () => {
"tool-result",
"tool-output",
"usage",
+ "step-complete",
"error",
"done",
"turn-sealed",
]);
});
- it("covers all 11 AgentEvent variants", () => {
- expect(samples).toHaveLength(11);
+ it("covers all 12 AgentEvent variants", () => {
+ expect(samples).toHaveLength(12);
});
});
diff --git a/src/core/wire/conformance.ts b/src/core/wire/conformance.ts
index 5d75a60..d89772e 100644
--- a/src/core/wire/conformance.ts
+++ b/src/core/wire/conformance.ts
@@ -30,6 +30,8 @@ export function assertAgentEventExhaustive(event: AgentEvent): string {
return "done";
case "turn-sealed":
return "turn-sealed";
+ case "step-complete":
+ return "step-complete";
default:
return event satisfies never;
}