| 1 | import type { ProviderDriverKind, ProviderReplayTranscript } from "@t3tools/contracts"; |
| 2 | |
| 3 | import { buildRuntimeInstructions } from "@t3tools/provider-core/server/runtimeInstructions"; |
| 4 | |
| 5 | /** Adds current runtime context to legacy prompt expectations, keeping outbound matching exact. */ |
| 6 | export 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 | } |