@@ -22,6 +22,11 @@ import {
2222 readTranscriptFileState ,
2323 type TranscriptFileState ,
2424} from "./transcript-file-state.js" ;
25+ import {
26+ persistRuntimeTranscriptStateMutation ,
27+ resolveRuntimeTranscriptReadTarget ,
28+ type RuntimeTranscriptScope ,
29+ } from "./transcript-runtime-state.js" ;
2530
2631type SessionManagerLike = ReturnType < typeof SessionManager . open > ;
2732type SessionBranchEntry = ReturnType < SessionManagerLike [ "getBranch" ] > [ number ] ;
@@ -372,8 +377,65 @@ export function rewriteTranscriptEntriesInState(params: {
372377}
373378
374379/**
375- * Open a transcript file, rewrite message entries on the active branch, and
376- * emit a transcript update when the active branch changed.
380+ * Rewrites message entries for a runtime transcript without using the
381+ * file-backed path as caller identity.
382+ */
383+ export async function rewriteTranscriptEntriesInRuntimeTranscript ( params : {
384+ scope : RuntimeTranscriptScope ;
385+ request : TranscriptRewriteRequest ;
386+ config ?: SessionWriteLockAcquireTimeoutConfig ;
387+ } ) : Promise < TranscriptRewriteResult > {
388+ let sessionLock : Awaited < ReturnType < typeof acquireSessionWriteLock > > | undefined ;
389+ try {
390+ const target = await resolveRuntimeTranscriptReadTarget ( params . scope ) ;
391+ sessionLock = await acquireSessionWriteLock ( {
392+ sessionFile : target . sessionFile ,
393+ ...resolveSessionWriteLockOptions ( params . config ) ,
394+ } ) ;
395+ const state = await readTranscriptFileState ( target . sessionFile ) ;
396+ const result = rewriteTranscriptEntriesInState ( {
397+ state,
398+ replacements : params . request . replacements ,
399+ ...( params . request . allowedRewriteSuffixEntryIds
400+ ? { allowedRewriteSuffixEntryIds : params . request . allowedRewriteSuffixEntryIds }
401+ : { } ) ,
402+ } ) ;
403+ if ( result . changed ) {
404+ await persistRuntimeTranscriptStateMutation ( {
405+ target,
406+ state,
407+ appendedEntries : result . appendedEntries ,
408+ } ) ;
409+ emitSessionTranscriptUpdate ( {
410+ sessionFile : target . sessionFile ,
411+ sessionKey : target . sessionKey ,
412+ agentId : target . agentId ,
413+ } ) ;
414+ log . info (
415+ `[transcript-rewrite] rewrote ${ result . rewrittenEntries } entr` +
416+ `${ result . rewrittenEntries === 1 ? "y" : "ies" } ` +
417+ `bytesFreed=${ result . bytesFreed } ` +
418+ `sessionKey=${ target . sessionKey } ` ,
419+ ) ;
420+ }
421+ return result ;
422+ } catch ( err ) {
423+ const reason = formatErrorMessage ( err ) ;
424+ log . warn ( `[transcript-rewrite] failed: ${ reason } ` ) ;
425+ return {
426+ changed : false ,
427+ bytesFreed : 0 ,
428+ rewrittenEntries : 0 ,
429+ reason,
430+ } ;
431+ } finally {
432+ await sessionLock ?. release ( ) ;
433+ }
434+ }
435+
436+ /**
437+ * Rewrites a named transcript file artifact. Runtime callers should prefer
438+ * rewriteTranscriptEntriesInRuntimeTranscript with agent/session scope.
377439 */
378440export async function rewriteTranscriptEntriesInSessionFile ( params : {
379441 sessionFile : string ;
0 commit comments