1import type { ProviderDriverKind, ProviderReplayTranscript } from "@t3tools/contracts";
2
3import { buildRuntimeInstructions } from "@t3tools/provider-core/server/runtimeInstructions";
4
5/** Adds current runtime context to legacy prompt expectations, keeping outbound matching exact. */
6export function materializeReplayTranscriptRuntimeInstructions(
7 transcript: ProviderReplayTranscript,
8 runtime: { readonly driver: ProviderDriverKind; readonly model: string },
9): ProviderReplayTranscript {
10 const harness =
11 runtime.driver === "cursor"
12 ? "Cursor"
13 : runtime.driver === "grok"
14 ? "Grok"
15 : runtime.driver === "acpRegistry"
16 ? "acpRegistry"
17 : undefined;
18 if (harness === undefined) return transcript;
19 const instructions = buildRuntimeInstructions({ harness, model: runtime.model });
20
21 return {
22 ...transcript,
23 entries: transcript.entries.map((entry) => {
24 if (entry.type !== "expect_outbound") return entry;
25 const frame = entry.frame;
26 if (typeof frame !== "object" || frame === null) return entry;
27 if (
28 runtime.driver === "cursor" &&
29 "type" in frame &&
30 frame.type === "run.start" &&
31 "message" in frame &&
32 typeof frame.message === "string"
33 ) {
34 return frame.message.endsWith(instructions)
35 ? entry
36 : { ...entry, frame: { ...frame, message: `${frame.message}\n\n${instructions}` } };
37 }
38 if (
39 "method" in frame &&
40 frame.method === "session/prompt" &&
41 "params" in frame &&
42 typeof frame.params === "object" &&
43 frame.params !== null &&
44 "prompt" in frame.params &&
45 Array.isArray(frame.params.prompt)
46 ) {
47 const prompt: ReadonlyArray<unknown> = frame.params.prompt;
48 const lastPart = prompt.at(-1);
49 if (
50 typeof lastPart === "object" &&
51 lastPart !== null &&
52 "type" in lastPart &&
53 lastPart.type === "text" &&
54 "text" in lastPart &&
55 lastPart.text === instructions
56 ) {
57 return entry;
58 }
59 return {
60 ...entry,
61 frame: {
62 ...frame,
63 params: { ...frame.params, prompt: [...prompt, { type: "text", text: instructions }] },
64 },
65 };
66 }
67 return entry;
68 }),
69 };
70}