@@ -15,16 +15,13 @@ import {
1515 appendTranscriptMessage ,
1616 cleanupSessionLifecycleArtifacts ,
1717 listSessionEntries ,
18- loadExactSessionEntry ,
1918 loadSessionEntry ,
20- loadTranscriptEvents ,
2119 patchSessionEntry ,
2220 publishTranscriptUpdate ,
2321 readSessionUpdatedAt ,
2422 replaceSessionEntry ,
2523 updateSessionEntry ,
2624 upsertSessionEntry ,
27- type ExactSessionEntry ,
2825 type SessionAccessScope ,
2926 type SessionEntrySummary ,
3027 type SessionTranscriptAccessScope ,
@@ -57,6 +54,8 @@ import {
5754 updateSqliteSessionEntry ,
5855 upsertSqliteSessionEntry ,
5956} from "./session-accessor.sqlite.js" ;
57+ import { loadSessionStore } from "./store.js" ;
58+ import { streamSessionTranscriptLines } from "./transcript-stream.js" ;
6059import type { SessionCompactionCheckpoint , SessionEntry } from "./types.js" ;
6160
6261// Keep accessor conformance independent of any real openclaw.json on the machine.
@@ -113,6 +112,11 @@ type AccessorAdapter = {
113112 ) : Promise < void > ;
114113} ;
115114
115+ type ExactSessionEntry = {
116+ entry : SessionEntry ;
117+ sessionKey : string ;
118+ } ;
119+
116120type TestPaths = {
117121 sqlitePath : string ;
118122 stateDir : string ;
@@ -140,20 +144,44 @@ const fileBackedAdapter: AccessorAdapter = {
140144 storePath : paths . storePath ,
141145 } ) ,
142146 loadSessionEntry,
143- loadExactSessionEntry,
147+ loadExactSessionEntry : loadExactFileSessionEntry ,
144148 listSessionEntries,
145149 readSessionUpdatedAt,
146150 upsertSessionEntry,
147151 replaceSessionEntry,
148152 patchSessionEntry,
149153 updateSessionEntry,
150154 cleanupSessionLifecycleArtifacts,
151- loadTranscriptEvents,
155+ loadTranscriptEvents : loadFileTranscriptEvents ,
152156 appendTranscriptEvent,
153157 appendTranscriptMessage,
154158 publishTranscriptUpdate,
155159} ;
156160
161+ function loadExactFileSessionEntry ( scope : SessionAccessScope ) : ExactSessionEntry | undefined {
162+ const sessionKey = scope . sessionKey . trim ( ) ;
163+ const storePath = scope . storePath ?. trim ( ) ;
164+ if ( ! sessionKey || ! storePath ) {
165+ return undefined ;
166+ }
167+ const entry = loadSessionStore ( storePath ) [ sessionKey ] ;
168+ return entry ? { sessionKey, entry : structuredClone ( entry ) } : undefined ;
169+ }
170+
171+ async function loadFileTranscriptEvents (
172+ scope : SessionTranscriptReadScope ,
173+ ) : Promise < TranscriptEvent [ ] > {
174+ const sessionFile = scope . sessionFile ?. trim ( ) ;
175+ if ( ! sessionFile ) {
176+ throw new Error ( "file-backed conformance reads require an explicit session file" ) ;
177+ }
178+ const events : TranscriptEvent [ ] = [ ] ;
179+ for await ( const line of streamSessionTranscriptLines ( sessionFile ) ) {
180+ events . push ( JSON . parse ( line ) as TranscriptEvent ) ;
181+ }
182+ return events ;
183+ }
184+
157185const sqliteAdapter : AccessorAdapter = {
158186 name : "sqlite" ,
159187 publishesTranscriptUpdates : false ,
0 commit comments