openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
127 lines (126 loc) • 7.19 kB
JavaScript
import { i as executeSqliteQueryTakeFirstSync, o as iterateSqliteQuerySync } from "./kysely-sync-COmh4HWh.js";
import { k as resolveOpenClawAgentSqlitePath } from "./openclaw-agent-db-lease-Djvd6LWN.js";
import { g as runOpenClawAgentWriteTransaction } from "./openclaw-agent-db-CWtDoRbC.js";
import { n as appendTranscriptEventsInTransaction, r as createTranscriptEventInserter } from "./session-accessor.sqlite-transcript-store-B0zw3fAU.js";
import { g as writeSessionEntry } from "./session-accessor.sqlite-entry-store-BxYl0nro.js";
import { c as resolveSqliteScope, i as getSessionKysely, m as toDatabaseOptions, p as runExclusiveSqliteSessionWrite, r as formatSqliteSessionReferenceForScope } from "./session-accessor.sqlite-scope-2KfMzb44.js";
import { i as ensureTranscriptSessionRoot, l as touchTranscriptMutationInTransaction, r as ensureTranscriptGenerationInTransaction, t as advanceTranscriptMutationAtInTransaction, v as publishSessionEntryCacheInvalidation } from "./session-accessor.sqlite-transcript-state-DwF2owZS.js";
import { c as reconcileSessionTranscriptIndexInTransaction } from "./session-transcript-index-DmCW_GtW.js";
import { i as readExactSessionEntryRowForCanonicalRepair } from "./session-accessor.sqlite-canonical-repair-ChKhq4_W.js";
import { n as replaceSessionOwnerInTransaction } from "./session-accessor.sqlite-owner-DysLwyNh.js";
import { t as withSqliteSessionImportStage } from "./session-accessor.sqlite-import-stage-BRYc0bpF.js";
//#region src/config/sessions/session-accessor.sqlite-import.ts
function resolveSqliteSessionImport(params) {
if (params.readExactTranscriptRows && params.readTranscriptEvents) throw new Error("SQLite session import accepts only one transcript row source");
const resolvedScope = resolveSqliteScope(params);
return {
params,
resolved: params.preserveExactStoredKey ? {
...resolvedScope,
sessionKey: params.sessionKey
} : resolvedScope
};
}
function importSqliteSessionRowsInTransaction(database, prepared, stage, source, repair) {
const { params, resolved } = prepared;
let transcriptEvents = 0;
const currentEntry = readExactSessionEntryRowForCanonicalRepair(database, resolved.sessionKey, { allowMalformedRowRepair: params.allowMalformedRowRepair === true })?.entry;
if (params.skipIfExists === true && currentEntry) return {
sessionId: params.entry.sessionId,
sessionKey: resolved.sessionKey,
skippedExisting: true,
transcriptEvents
};
const preservedHarnessId = params.entry.agentHarnessId === void 0 && currentEntry?.sessionId === params.entry.sessionId && currentEntry.lifecycleRevision === params.entry.lifecycleRevision ? currentEntry.agentHarnessId?.trim() : void 0;
const importedEntry = {
...params.entry,
...preservedHarnessId ? { agentHarnessId: preservedHarnessId } : {},
sessionFile: formatSqliteSessionReferenceForScope({
...resolved,
sessionId: params.entry.sessionId
})
};
writeSessionEntry(database, resolved.sessionKey, importedEntry, {
allowStoredAliases: true,
previousEntry: currentEntry ?? null
});
if (params.readExactTranscriptRows) {
replaceSessionOwnerInTransaction(database, resolved.sessionKey, params.entry.owner);
const transcriptScope = {
...resolved,
sessionId: params.entry.sessionId
};
const db = getSessionKysely(database.db);
if (!executeSqliteQueryTakeFirstSync(database.db, db.selectFrom("transcript_events").select("seq").where("session_id", "=", params.entry.sessionId).limit(1))) {
const insertEvent = createTranscriptEventInserter(database, params.entry.sessionId);
for (const row of stage.rows(source)) {
if (row.seq === 0) {
ensureTranscriptSessionRoot(database, transcriptScope, row.createdAt, { allowStoredAlias: true });
ensureTranscriptGenerationInTransaction(database, params.entry.sessionId);
}
insertEvent({
seq: row.seq,
eventJson: row.eventJson,
createdAt: row.createdAt
});
transcriptEvents += 1;
}
reconcileSessionTranscriptIndexInTransaction(database.db, params.entry.sessionId);
publishSessionEntryCacheInvalidation(database);
}
} else if (params.readTranscriptEvents) {
const transcriptScope = {
...resolved,
sessionId: params.entry.sessionId
};
stage.resetSeen();
for (const row of iterateSqliteQuerySync(database.db, getSessionKysely(database.db).selectFrom("transcript_events").select("event_json").where("session_id", "=", params.entry.sessionId))) stage.addSeen(row.event_json);
transcriptEvents = appendTranscriptEventsInTransaction(database, transcriptScope, stage.iterateUnseenEvents(source), {
allowStoredAlias: true,
scheduleProjectionReconcile: false,
touchMutation: false
});
reconcileSessionTranscriptIndexInTransaction(database.db, params.entry.sessionId);
publishSessionEntryCacheInvalidation(database);
}
if (params.transcriptMtimeMs !== void 0) advanceTranscriptMutationAtInTransaction(database, params.entry.sessionId, params.transcriptMtimeMs);
else if (transcriptEvents > 0) touchTranscriptMutationInTransaction(database, params.entry.sessionId);
return {
sessionId: params.entry.sessionId,
sessionKey: resolved.sessionKey,
transcriptEvents,
...repair ? { recovery: {
complete: repair.recognized && stage.complete,
repaired: repair.repaired,
events: repair.events
} } : {}
};
}
/** Imports legacy session rows that share one SQLite store in one durable transaction. */
async function importSqliteSessionRowsBatch(params) {
if (params.length === 0) return [];
const prepared = params.map(resolveSqliteSessionImport);
const resolved = prepared[0].resolved;
const databasePath = resolveOpenClawAgentSqlitePath(toDatabaseOptions(resolved));
if (prepared.some((row) => resolveOpenClawAgentSqlitePath(toDatabaseOptions(row.resolved)) !== databasePath)) throw new Error("SQLite session import batch spans multiple stores");
return await runExclusiveSqliteSessionWrite(resolved, async () => withSqliteSessionImportStage((stage) => {
const validators = [];
const repairs = /* @__PURE__ */ new Map();
for (const [source, { params: importParams }] of prepared.entries()) {
let seq = 0;
importParams.readExactTranscriptRows?.((row) => stage.append(source, seq++, row.eventJson, row.createdAt));
const validate = importParams.readTranscriptEvents?.((event) => stage.append(source, seq++, JSON.stringify(event), null));
if (validate) validators.push(validate);
if (importParams.repairLegacyTranscript && importParams.readTranscriptEvents) repairs.set(source, stage.repairLegacyTranscript(source));
}
for (const validate of validators) validate();
for (const { params: importParams } of prepared) importParams.beforePersistentApply?.();
return runOpenClawAgentWriteTransaction((database) => prepared.map((row, source) => importSqliteSessionRowsInTransaction(database, row, stage, source, repairs.get(source))), toDatabaseOptions(resolved));
}));
}
/** Imports one legacy session entry and its transcript rows for doctor migration. */
async function importSqliteSessionRows(params) {
return (await importSqliteSessionRowsBatch([params]))[0];
}
//#endregion
export { importSqliteSessionRowsBatch as n, importSqliteSessionRows as t };