/** * Golden test: 9 real-world DSML leak shapes captured from a long-context * DeepSeek session (wrapped edit/shell calls, seqs 5177–5695), preserved as * synthetic byte-faithful fixtures (`test/golden/db-messages.json`, generated by * `test/golden/build-fixtures.ts`). No private content: paths, code, and prose * are generic. Each message is run through the parser AND the streaming * middleware. * * Expectations per message (verified against the DB by hand): * - 5177, 5425, 5443, 5624, 5647, 5663, 5679, 5695: finish=stop, orphan/degraded * markup. The parser must recover the intended call where one is unambiguous * (edit/shell with parseable params) or strip the noise otherwise; the stream * must emit identical text plus the recovered call and flip finish to tool-calls. * - 5608: finish=tool-calls with leaked markup alongside — parser recovers the call, * leaked text is stripped, finish stays tool-calls. */ import { describe, expect, test } from "bun:test" import type { LanguageModelV3StreamPart } from "@ai-sdk/provider" import { parseDsml, stripRanges } from "../src/parse.ts" import { createDsmlStreamMiddleware } from "../src/middleware.ts" import raw from "./golden/db-messages.json" with { type: "json" } interface GoldenMessage { seq: number finish: string text: string } const messages = raw as GoldenMessage[] function splitDeltas(text: string, size: number): string[] { const parts: string[] = [] for (let i = 0; i < text.length; i += size) parts.push(text.slice(i, i + size)) return parts } async function runStream(text: string) { const chunks = splitDeltas(text, 7) // awkward split: cuts through markers const parts: LanguageModelV3StreamPart[] = [ { type: "stream-start", warnings: [] }, { type: "text-start", id: "t1" }, ...chunks.map((delta): LanguageModelV3StreamPart => ({ type: "text-delta", id: "t1", delta })), { type: "text-end", id: "t1" }, { type: "finish", finishReason: { unified: "stop", raw: "stop" }, usage: {} as never }, ] const stream = new ReadableStream({ start(c) { for (const p of parts) c.enqueue(p) c.close() }, }) const middleware = createDsmlStreamMiddleware() const wrapped = await middleware.wrapStream!({ doStream: async () => ({ stream }), doGenerate: (async () => ({})) as never, params: {} as never, model: {} as never, }) const events: LanguageModelV3StreamPart[] = [] const reader = wrapped.stream.getReader() for (;;) { const { done, value } = await reader.read() if (done) break events.push(value) } return events } describe("golden: DB session leaks", () => { test("all 9 fixtures load with DSML content", () => { expect(messages).toHaveLength(9) for (const m of messages) expect(m.text).toMatch(/DSML/) }) for (const m of messages) { test(`seq ${m.seq}: stream preserves text, recovers call, flips finish`, async () => { const parsed = parseDsml(m.text) const events = await runStream(m.text) const textOut = events .filter((e): e is Extract => e.type === "text-delta") .map((e) => e.delta) .join("") const calls = events.filter((e) => e.type === "tool-call") const finish = events.find((e) => e.type === "finish") as Extract< LanguageModelV3StreamPart, { type: "finish" } > // No text is ever lost: emitted text + stripped ranges === input minus calls. // Concretely: every non-markup word of the input must appear in the output. // (Comparison ignores quote chars: call args travel JSON-escaped in parts.) const inputWords = m.text.replace(/<[^>]*>/g, " ").split(/\s+/).filter(Boolean) const haystacks = [textOut, JSON.stringify(calls)].map((h) => h.replace(/["\\]/g, "")) for (const word of inputWords) { if (word.length > 20) continue // long values may be inside recovered args const bare = word.replace(/["\\]/g, "") expect(haystacks.some((h) => h.includes(bare))).toBe(true) } // Parser and stream agree on the call count. expect(calls.length).toBe(parsed.calls.length) if (parsed.calls.length > 0) { expect(finish.finishReason.unified).toBe("tool-calls") } else { expect(finish.finishReason.unified).toBe("stop") } // Stripped output contains no marker. expect(stripRanges(m.text, parsed.ranges)).not.toMatch(/DSML/) }) } test("seq 5608 (native tool-calls): wrapped edit call recovered", async () => { const m = messages.find((x) => x.seq === 5608)! const parsed = parseDsml(m.text) expect(parsed.calls.length).toBeGreaterThan(0) expect(parsed.calls[0]!.name).toBe("edit") expect(parsed.calls[0]!.arguments).toHaveProperty("newString") }) })