MCPcopy Create free account
hub / github.com/cortexkit/magic-context / createPiTranscript

Function createPiTranscript

packages/pi-plugin/src/transcript-pi.ts:148–230  ·  view source on GitHub ↗
(
	source: unknown[],
	sessionId: string | undefined,
	entryIds?: readonly (string | undefined)[],
)

Source from the content-addressed store, hash-verified

146 * structural typing.
147 */
148export function createPiTranscript(
149 source: unknown[],
150 sessionId: string | undefined,
151 entryIds?: readonly (string | undefined)[],
152): Transcript & {
153 /**
154 * Pi-only escape hatch: returns the rebuilt message array suitable
155 * for `{ messages }` in the `pi.on("context", ...)` result. Returns
156 * the original array if no mutations occurred — preserves identity
157 * so Pi can short-circuit downstream cache invalidation.
158 */
159 getOutputMessages(): unknown[];
160 /**
161 * Pi-only escape hatch: the mutable `working` array that part proxies
162 * (tagging, drops, caveman) write to and `commit()` flushes back to source.
163 *
164 * Phases that mutate messages OUTSIDE the transcript part API — reasoning
165 * clearing/replay, which set `part.thinking = "[cleared]"` in place — MUST
166 * target this array, not the original `source`. Tagging/drops/caveman
167 * REASSIGN `working[idx]` to fresh spread-copied objects; if reasoning mutated
168 * `source[idx]` (a now-divergent object) instead, the later `commit()` would
169 * overwrite `source[idx] = working[idx]` and silently discard the reasoning
170 * mutation while the cleared-reasoning watermark still advanced — a defer-pass
171 * replay divergence (wire keeps original reasoning, state says cleared) that
172 * busts the prompt cache. Routing reasoning through `working` keeps every
173 * mutation in the single channel `commit()` flushes.
174 */
175 getWorkingMessages(): PiAgentMessage[];
176} {
177 const working = source.slice() as unknown as PiAgentMessage[];
178 const dirtyMessages = new Set<number>();
179
180 // Normalize: fold consecutive toolResult runs into the immediately
181 // following user message as tool_result transcript parts. Track
182 // source-array locations so commit() can write mutations back.
183 const transcriptMessages: TranscriptMessage[] = buildTranscriptView(
184 working,
185 sessionId,
186 (messageIndex) => {
187 dirtyMessages.add(messageIndex);
188 },
189 entryIds,
190 );
191
192 let committed = false;
193
194 return {
195 messages: transcriptMessages,
196 harness: "pi",
197 commit(): void {
198 if (committed) return;
199 committed = true;
200 // Sync mutations from `working` back into `source` so that
201 // any structural changes the caller applies to `source`
202 // directly (e.g. `<session-history>` injection's splice +
203 // message[0] prepend) compose correctly with our part-level
204 // mutations.
205 //

Calls 1

buildTranscriptViewFunction · 0.85

Tested by 2

makeTranscriptIdFunction · 0.72
tagMessagesFunction · 0.72