UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

148 lines (147 loc) 6.86 kB
import "./src-vebZIeLe.js"; import { t as safeParseJson } from "./json-coercion-AulM0PZ6.js"; import { t as createSubsystemLogger } from "./subsystem-Dy2tqXOS.js"; import { a as getNodeSqliteKysely, r as executeSqliteQuerySync } from "./kysely-sync-COmh4HWh.js"; import { i as openOpenClawStateDatabase, s as runOpenClawStateWriteTransaction, vt as normalizeSqliteNumber } from "./openclaw-state-db-BRTnL-D8.js"; import { isDeepStrictEqual } from "node:util"; //#region src/sessions/session-upstream-links.ts const log = createSubsystemLogger("sessions/upstream-links"); function getSessionUpstreamKysely(db) { return getNodeSqliteKysely(db); } function parseJson(value) { if (value === null) return null; return safeParseJson(value) ?? null; } function rowToSessionUpstreamLink(row) { return { sessionKey: row.session_key, agentId: row.agent_id, catalogId: row.catalog_id, hostId: row.host_id, threadId: row.thread_id, upstreamKind: row.upstream_kind, upstreamRef: parseJson(row.upstream_ref_json), marker: parseJson(row.last_marker_json), ...row.last_scanned_at === null ? {} : { lastScannedAt: normalizeSqliteNumber(row.last_scanned_at) ?? 0 }, createdAt: normalizeSqliteNumber(row.created_at) ?? 0, updatedAt: normalizeSqliteNumber(row.updated_at) ?? 0 }; } function upsertSessionUpstreamLink(input, options = {}) { const now = options.now ?? Date.now(); try { return runOpenClawStateWriteTransaction(({ db }) => { options.assertCommitAllowed?.(); const written = executeSqliteQuerySync(db, getSessionUpstreamKysely(db).insertInto("session_upstream_links").values({ session_key: input.sessionKey, agent_id: input.agentId, catalog_id: input.catalogId, host_id: input.hostId, thread_id: input.threadId, upstream_kind: input.upstreamKind, upstream_ref_json: JSON.stringify(input.upstreamRef), last_marker_json: JSON.stringify(input.marker), last_scanned_at: null, created_at: now, updated_at: now }).onConflict((conflict) => options.ifAbsent ? conflict.columns(["session_key", "agent_id"]).doNothing() : conflict.columns(["session_key", "agent_id"]).doUpdateSet((eb) => { const sourceChanged = eb.or([ eb("session_upstream_links.thread_id", "!=", eb.ref("excluded.thread_id")), eb("session_upstream_links.host_id", "!=", eb.ref("excluded.host_id")), eb("session_upstream_links.upstream_kind", "!=", eb.ref("excluded.upstream_kind")), eb("session_upstream_links.upstream_ref_json", "!=", eb.ref("excluded.upstream_ref_json")) ]); return { agent_id: input.agentId, catalog_id: input.catalogId, host_id: input.hostId, thread_id: input.threadId, upstream_kind: input.upstreamKind, upstream_ref_json: JSON.stringify(input.upstreamRef), last_marker_json: eb.case().when(sourceChanged).then(JSON.stringify(input.marker)).else(eb.ref("session_upstream_links.last_marker_json")).end(), last_scanned_at: eb.case().when(sourceChanged).then(null).else(eb.ref("session_upstream_links.last_scanned_at")).end(), updated_at: now }; }))).numAffectedRows === 1n; options.assertCommitAllowed?.(); return written; }, options); } catch (error) { if (options.ifAbsent) throw error; log.warn(`failed to upsert session upstream link: ${String(error)}`); return false; } } function readSessionUpstreamLink(sessionKey, agentId, options = {}) { try { const { db } = openOpenClawStateDatabase(options); const row = executeSqliteQuerySync(db, getSessionUpstreamKysely(db).selectFrom("session_upstream_links").selectAll().where("session_key", "=", sessionKey).where("agent_id", "=", agentId)).rows[0]; return row ? rowToSessionUpstreamLink(row) : void 0; } catch (error) { log.warn(`failed to read session upstream link: ${String(error)}`); return; } } function updateSessionUpstreamLinkMarker(sessionKey, agentId, marker, options = {}) { const now = options.now ?? Date.now(); try { let updated = false; runOpenClawStateWriteTransaction(({ db }) => { let query = getSessionUpstreamKysely(db).updateTable("session_upstream_links").set({ last_marker_json: JSON.stringify(marker), last_scanned_at: now, updated_at: now }).where("session_key", "=", sessionKey).where("agent_id", "=", agentId); if (options.expectedUpdatedAt !== void 0) query = query.where("updated_at", "=", options.expectedUpdatedAt); updated = executeSqliteQuerySync(db, query).numAffectedRows === 1n; }, options); return updated; } catch (error) { log.warn(`failed to update session upstream marker: ${String(error)}`); return false; } } function deleteSessionUpstreamLink(sessionKey, agentId, options = {}) { try { return runOpenClawStateWriteTransaction(({ db }) => { options.assertCommitAllowed?.(); const kysely = getSessionUpstreamKysely(db); if (options.expected) { const row = executeSqliteQuerySync(db, kysely.selectFrom("session_upstream_links").selectAll().where("session_key", "=", sessionKey).where("agent_id", "=", agentId)).rows[0]; if (!row) return "absent"; if (!isDeepStrictEqual(rowToSessionUpstreamLink(row), options.expected)) return "changed"; } executeSqliteQuerySync(db, kysely.deleteFrom("session_upstream_links").where("session_key", "=", sessionKey).where("agent_id", "=", agentId)); options.assertCommitAllowed?.(); return "deleted"; }, options); } catch (error) { if (options.expected) throw error; log.warn(`failed to delete session upstream link: ${String(error)}`); return; } } function listWatchedSessionUpstreamLinks(options = {}) { const grouped = /* @__PURE__ */ new Map(); try { const { db } = openOpenClawStateDatabase(options); const links = executeSqliteQuerySync(db, getSessionUpstreamKysely(db).selectFrom("session_upstream_links as links").innerJoin("session_watch_cursors as cursors", "cursors.target_session_key", "links.session_key").selectAll("links").distinct().orderBy("links.catalog_id", "asc").orderBy("links.session_key", "asc")).rows.map(rowToSessionUpstreamLink); const keyCounts = /* @__PURE__ */ new Map(); for (const link of links) keyCounts.set(link.sessionKey, (keyCounts.get(link.sessionKey) ?? 0) + 1); for (const link of links) { if ((keyCounts.get(link.sessionKey) ?? 0) > 1) { log.warn(`skipping ambiguous upstream links for ${link.sessionKey}: multiple agents adopt the same key`); continue; } const catalogLinks = grouped.get(link.catalogId) ?? []; catalogLinks.push(link); grouped.set(link.catalogId, catalogLinks); } } catch (error) { log.warn(`failed to list watched session upstream links: ${String(error)}`); } return grouped; } //#endregion export { upsertSessionUpstreamLink as a, updateSessionUpstreamLinkMarker as i, listWatchedSessionUpstreamLinks as n, readSessionUpstreamLink as r, deleteSessionUpstreamLink as t };