openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
122 lines (121 loc) • 6.43 kB
JavaScript
import { a as getNodeSqliteKysely, i as executeSqliteQueryTakeFirstSync, r as executeSqliteQuerySync } from "./kysely-sync-COmh4HWh.js";
import { i as openOpenClawStateDatabase, s as runOpenClawStateWriteTransaction } from "./openclaw-state-db-BRTnL-D8.js";
//#region src/gateway/managed-image-record-store.ts
const MANAGED_OUTGOING_ORIGINALS_SUBDIR = "outgoing/originals";
function stateDatabaseOptions(stateDir) {
return stateDir ? { env: {
...process.env,
OPENCLAW_STATE_DIR: stateDir
} } : { env: process.env };
}
function managedImageRecordToRow(record) {
return {
attachment_id: record.attachmentId,
session_key: record.sessionKey,
agent_id: record.agentId ?? null,
message_id: record.messageId,
created_at: record.createdAt,
updated_at: record.updatedAt ?? null,
retention_class: record.retentionClass ?? null,
alt: record.alt,
original_media_root: record.original.mediaRoot,
original_media_id: record.original.mediaId,
original_media_subdir: record.original.mediaSubdir,
original_content_type: record.original.contentType,
original_width: record.original.width,
original_height: record.original.height,
original_size_bytes: record.original.sizeBytes,
original_filename: record.original.filename,
record_json: JSON.stringify(record)
};
}
function managedImageRecordFromRow(row) {
return {
attachmentId: row.attachment_id,
sessionKey: row.session_key,
...row.agent_id ? { agentId: row.agent_id } : {},
messageId: row.message_id,
createdAt: row.created_at,
...row.updated_at ? { updatedAt: row.updated_at } : {},
...row.retention_class === "history" || row.retention_class === "transient" ? { retentionClass: row.retention_class } : {},
alt: row.alt,
original: {
mediaRoot: row.original_media_root,
mediaId: row.original_media_id,
mediaSubdir: row.original_media_subdir,
contentType: row.original_content_type,
width: row.original_width,
height: row.original_height,
sizeBytes: row.original_size_bytes,
filename: row.original_filename
}
};
}
function managedImageRecordsEqual(left, right) {
return JSON.stringify(left) === JSON.stringify(right);
}
function readManagedImageRecord(attachmentId, stateDir) {
const database = openOpenClawStateDatabase(stateDatabaseOptions(stateDir));
const row = executeSqliteQueryTakeFirstSync(database.db, getNodeSqliteKysely(database.db).selectFrom("managed_outgoing_image_records").selectAll().where("attachment_id", "=", attachmentId).where("cleanup_pending", "=", 0));
return row ? managedImageRecordFromRow(row) : null;
}
function listManagedImageRecordEntries(params) {
const database = openOpenClawStateDatabase(stateDatabaseOptions(params.stateDir));
let query = getNodeSqliteKysely(database.db).selectFrom("managed_outgoing_image_records").selectAll();
if (params.sessionKey) query = query.where("session_key", "=", params.sessionKey);
return executeSqliteQuerySync(database.db, query.orderBy("created_at", "desc").orderBy("attachment_id", "asc")).rows.map((row) => ({
record: managedImageRecordFromRow(row),
cleanupPending: row.cleanup_pending === 1
}));
}
function insertManagedImageRecord(record, stateDir) {
runOpenClawStateWriteTransaction(({ db }) => {
executeSqliteQuerySync(db, getNodeSqliteKysely(db).insertInto("managed_outgoing_image_records").values(managedImageRecordToRow(record)));
}, stateDatabaseOptions(stateDir));
}
/** Promote a transient record atomically so concurrent message commits cannot lose state. */
function attachManagedImageRecordToMessage(params) {
return runOpenClawStateWriteTransaction(({ db }) => {
const stateDb = getNodeSqliteKysely(db);
const row = executeSqliteQueryTakeFirstSync(db, stateDb.selectFrom("managed_outgoing_image_records").selectAll().where("attachment_id", "=", params.attachmentId).where("session_key", "=", params.sessionKey));
if (!row) return false;
if (row.cleanup_pending === 1) return false;
const current = managedImageRecordFromRow(row);
if (current.messageId === params.messageId && current.retentionClass === "history") return true;
const nextRow = managedImageRecordToRow({
...current,
messageId: params.messageId,
retentionClass: "history",
updatedAt: params.updatedAt
});
executeSqliteQuerySync(db, stateDb.updateTable("managed_outgoing_image_records").set({
message_id: nextRow.message_id,
retention_class: nextRow.retention_class,
updated_at: nextRow.updated_at,
record_json: nextRow.record_json
}).where("attachment_id", "=", params.attachmentId));
return true;
}, stateDatabaseOptions(params.stateDir));
}
/** Claim only the exact row cleanup planned against; concurrent updates win. */
function claimManagedImageRecordCleanupIfCurrent(planned, stateDir) {
return runOpenClawStateWriteTransaction(({ db }) => {
const stateDb = getNodeSqliteKysely(db);
const row = executeSqliteQueryTakeFirstSync(db, stateDb.selectFrom("managed_outgoing_image_records").selectAll().where("attachment_id", "=", planned.attachmentId));
if (!row || row.cleanup_pending === 1 || !managedImageRecordsEqual(managedImageRecordFromRow(row), planned)) return false;
executeSqliteQuerySync(db, stateDb.updateTable("managed_outgoing_image_records").set({ cleanup_pending: 1 }).where("attachment_id", "=", planned.attachmentId));
return true;
}, stateDatabaseOptions(stateDir));
}
/** Delete a durably claimed row only after its attachment file is gone. */
function deleteClaimedManagedImageRecord(planned, stateDir) {
return runOpenClawStateWriteTransaction(({ db }) => {
const stateDb = getNodeSqliteKysely(db);
const row = executeSqliteQueryTakeFirstSync(db, stateDb.selectFrom("managed_outgoing_image_records").selectAll().where("attachment_id", "=", planned.attachmentId));
if (!row || row.cleanup_pending !== 1 || !managedImageRecordsEqual(managedImageRecordFromRow(row), planned)) return false;
executeSqliteQuerySync(db, stateDb.deleteFrom("managed_outgoing_image_records").where("attachment_id", "=", planned.attachmentId));
return true;
}, stateDatabaseOptions(stateDir));
}
//#endregion
export { insertManagedImageRecord as a, managedImageRecordToRow as c, deleteClaimedManagedImageRecord as i, managedImageRecordsEqual as l, attachManagedImageRecordToMessage as n, listManagedImageRecordEntries as o, claimManagedImageRecordCleanupIfCurrent as r, managedImageRecordFromRow as s, MANAGED_OUTGOING_ORIGINALS_SUBDIR as t, readManagedImageRecord as u };