22import type { DatabaseSync } from "node:sqlite" ;
33import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime" ;
44import { createSubsystemLogger } from "openclaw/plugin-sdk/memory-core-host-engine-foundation" ;
5- import type { MemorySyncProgressUpdate } from "openclaw/plugin-sdk/memory-core-host-engine-storage" ;
5+ import type {
6+ MemorySessionSyncTarget ,
7+ MemorySyncParams ,
8+ MemorySyncProgressUpdate ,
9+ } from "openclaw/plugin-sdk/memory-core-host-engine-storage" ;
610
711const log = createSubsystemLogger ( "memory" ) ;
812
@@ -19,6 +23,7 @@ export type MemoryReadonlyRecoveryState = {
1923 runSync : ( params ?: {
2024 reason ?: string ;
2125 force ?: boolean ;
26+ sessions ?: MemorySessionSyncTarget [ ] ;
2227 sessionFiles ?: string [ ] ;
2328 progress ?: ( update : MemorySyncProgressUpdate ) => void ;
2429 } ) => Promise < void > ;
@@ -80,12 +85,7 @@ export function extractMemoryErrorReason(err: unknown): string {
8085
8186export async function runMemorySyncWithReadonlyRecovery (
8287 state : MemoryReadonlyRecoveryState ,
83- params ?: {
84- reason ?: string ;
85- force ?: boolean ;
86- sessionFiles ?: string [ ] ;
87- progress ?: ( update : MemorySyncProgressUpdate ) => void ;
88- } ,
88+ params ?: MemorySyncParams ,
8989) : Promise < void > {
9090 try {
9191 await state . runSync ( params ) ;
@@ -121,37 +121,46 @@ export function enqueueMemoryTargetedSessionSync(
121121 isClosed : ( ) => boolean ;
122122 getSyncing : ( ) => Promise < void > | null ;
123123 getQueuedSessionFiles : ( ) => Set < string > ;
124+ getQueuedSessions : ( ) => Map < string , MemorySessionSyncTarget > ;
124125 getQueuedSessionSync : ( ) => Promise < void > | null ;
125126 setQueuedSessionSync : ( value : Promise < void > | null ) => void ;
126- sync : ( params ?: {
127- reason ?: string ;
128- force ?: boolean ;
129- sessionFiles ?: string [ ] ;
130- progress ?: ( update : MemorySyncProgressUpdate ) => void ;
131- } ) => Promise < void > ;
127+ sync : ( params ?: MemorySyncParams ) => Promise < void > ;
132128 } ,
133- sessionFiles ?: string [ ] ,
129+ targets ?: Pick < MemorySyncParams , "sessions" | "sessionFiles" > ,
134130) : Promise < void > {
135131 const queuedSessionFiles = state . getQueuedSessionFiles ( ) ;
136- for ( const sessionFile of sessionFiles ?? [ ] ) {
132+ for ( const sessionFile of targets ?. sessionFiles ?? [ ] ) {
137133 const trimmed = sessionFile . trim ( ) ;
138134 if ( trimmed ) {
139135 queuedSessionFiles . add ( trimmed ) ;
140136 }
141137 }
142- if ( queuedSessionFiles . size === 0 ) {
138+ const queuedSessions = state . getQueuedSessions ( ) ;
139+ for ( const session of targets ?. sessions ?? [ ] ) {
140+ const normalized = normalizeQueuedMemorySessionSyncTarget ( session ) ;
141+ if ( normalized ) {
142+ queuedSessions . set ( memorySessionSyncTargetKey ( normalized ) , normalized ) ;
143+ }
144+ }
145+ if ( queuedSessionFiles . size === 0 && queuedSessions . size === 0 ) {
143146 return state . getSyncing ( ) ?? Promise . resolve ( ) ;
144147 }
145148 if ( ! state . getQueuedSessionSync ( ) ) {
146149 state . setQueuedSessionSync (
147150 ( async ( ) => {
148151 try {
149152 await state . getSyncing ( ) ?. catch ( ( ) => undefined ) ;
150- while ( ! state . isClosed ( ) && state . getQueuedSessionFiles ( ) . size > 0 ) {
153+ while (
154+ ! state . isClosed ( ) &&
155+ ( state . getQueuedSessionFiles ( ) . size > 0 || state . getQueuedSessions ( ) . size > 0 )
156+ ) {
151157 const pendingSessionFiles = Array . from ( state . getQueuedSessionFiles ( ) ) ;
158+ const pendingSessions = Array . from ( state . getQueuedSessions ( ) . values ( ) ) ;
152159 state . getQueuedSessionFiles ( ) . clear ( ) ;
160+ state . getQueuedSessions ( ) . clear ( ) ;
153161 await state . sync ( {
154- reason : "queued-session-files" ,
162+ reason : "queued-sessions" ,
163+ sessions : pendingSessions ,
155164 sessionFiles : pendingSessionFiles ,
156165 } ) ;
157166 }
@@ -163,3 +172,23 @@ export function enqueueMemoryTargetedSessionSync(
163172 }
164173 return state . getQueuedSessionSync ( ) ?? Promise . resolve ( ) ;
165174}
175+
176+ function normalizeQueuedMemorySessionSyncTarget (
177+ target : MemorySessionSyncTarget ,
178+ ) : MemorySessionSyncTarget | null {
179+ const sessionId = target . sessionId . trim ( ) ;
180+ if ( ! sessionId ) {
181+ return null ;
182+ }
183+ const agentId = target . agentId ?. trim ( ) ;
184+ const sessionKey = target . sessionKey ?. trim ( ) ;
185+ return {
186+ ...( agentId ? { agentId } : { } ) ,
187+ sessionId,
188+ ...( sessionKey ? { sessionKey } : { } ) ,
189+ } ;
190+ }
191+
192+ function memorySessionSyncTargetKey ( target : MemorySessionSyncTarget ) : string {
193+ return [ target . agentId ?? "" , target . sessionId , target . sessionKey ?? "" ] . join ( "\0" ) ;
194+ }
0 commit comments