UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

573 lines (572 loc) • 25.8 kB
import { c as withSqliteReaderOwner } from "../../sqlite-reader-lifecycle-CF8Y2ajA.mjs"; import { r as decodeAgentDatabaseReaderRequest } from "../../agent-database-readers-m64TtGjG.mjs"; import { r as cloneEnvWithPlatformSemantics } from "../../config-env-vars-BzUE_dOh.mjs"; import { i as runWithSessionTranscriptReadFence } from "../../session-transcript-read-fence-DqVaDIch.mjs"; import { a as sessionHistoryCleanupError, i as encodeSessionTranscriptWorkerError, r as encodeSessionTranscriptRequestError } from "../../session-history-worker-errors-DRVUiJbS.mjs"; import { t as serveOwnedWorkerTasks } from "../../worker-task-server-sbLPhqBg.mjs"; import { n as prepareSessionHistoryReadOperation, t as isSessionHistoryReadOperation } from "../../session-history-read-operation.worker-CvWK7Qpj.mjs"; import { threadId } from "node:worker_threads"; //#region src/config/sessions/session-transcript-worker-scopes.ts const MAX_RETAINED_HISTORY_DATABASES = 64; const historyDatabaseScopes = /* @__PURE__ */ new Map(); async function withHistoryDatabase(database, operationLabel, operation, validation) { const key = JSON.stringify(database); let retained = historyDatabaseScopes.get(key); if (!retained) { const { OpenClawAgentDatabaseReadOnlyScope } = await import("../../openclaw-agent-db-readonly-scope-DrX9jNcf.mjs"); retained = { database, scope: new OpenClawAgentDatabaseReadOnlyScope() }; } const { scope } = retained; try { const value = await withSqliteReaderOwner({ operation: `sessions.${operationLabel}`, ownerKind: "worker" }, () => scope.run({ ...database, validation }, operation)); historyDatabaseScopes.delete(key); if (!scope.hasRetainedConnection) return { ok: true, value, closedHistoryDatabase: database }; historyDatabaseScopes.set(key, retained); if (historyDatabaseScopes.size > MAX_RETAINED_HISTORY_DATABASES) { const oldest = historyDatabaseScopes.entries().next().value; oldest[1].scope.close(); historyDatabaseScopes.delete(oldest[0]); return { ok: true, value, closedHistoryDatabase: oldest[1].database }; } return { ok: true, value }; } catch (error) { try { scope.close(); } catch (cleanupError) { throw sessionHistoryCleanupError(error, cleanupError, "database close"); } throw error; } } function pruneClosedHistoryDatabaseScopes() { for (const [identity, retained] of historyDatabaseScopes) if (!retained.scope.hasRetainedConnection) historyDatabaseScopes.delete(identity); } //#endregion //#region src/config/sessions/session-transcript.worker.ts let releaseReadValidation; serveOwnedWorkerTasks(async (input, channel, control) => { releaseReadValidation ??= (await import("../../openclaw-agent-db-validation-cache-10fYsiQU.mjs")).releaseOpenClawAgentDatabaseReadValidation; const request = input; if (request.kind === "cli-process-history") { if (!channel) throw new Error("Process-held history requires its host reader channel"); const { readProcessHeldCliHistoryInWorker } = await import("../../cli-session-history.process-held-ByiZkY_w.mjs"); return { ok: true, value: await readProcessHeldCliHistoryInWorker(request.request, channel) }; } if (request.kind === "sqlite-target") { const { resolveSqliteTargetFromSessionStorePath } = await import("../../session-sqlite-target-k12BsIK1.mjs"); return { ok: true, value: { target: resolveSqliteTargetFromSessionStorePath(request.storePath, request) } }; } if (request.kind === "usage-cost") { const { executeUsageCostWorker, usageCostWorkerFailure } = await import("../../session-cost-usage-worker-DIaFRMii.mjs"); try { if (!channel) throw new Error("Usage cost worker requires its host channel"); const closed = /* @__PURE__ */ new Map(); return { ok: true, value: await executeUsageCostWorker(request, channel, control, async (database, read) => { closed.delete(JSON.stringify(database)); const result = await withHistoryDatabase(database, request.kind, read); if (result.closedHistoryDatabase) closed.set(JSON.stringify(result.closedHistoryDatabase), result.closedHistoryDatabase); return result.value; }), closedDatabases: [...closed.values()] }; } catch (error) { return usageCostWorkerFailure(error); } } const readRequest = async () => { if (request.kind === "transcript-search") { if (!channel) throw new Error("Transcript search requires its host status channel"); const { searchSessionTranscriptsReadOnlySync, isSessionTranscriptSearchCurrentSync } = await import("../../session-transcript-search-HE_nAsPw.mjs"); const options = { ...request.database, env: cloneEnvWithPlatformSemantics(request.params.env ?? process.env) }; const { found, revision, ...result } = searchSessionTranscriptsReadOnlySync(request.params, options); let indexing = false; if (found) { const status = await channel.request("transcript-index-status"); try { if (typeof status.input !== "boolean") throw new Error("Invalid transcript search index status"); indexing = status.input || revision === void 0 || !isSessionTranscriptSearchCurrentSync(revision, options); } finally { status.consumed(); } } return { kind: request.kind, result: { ...result, indexing } }; } if (isSessionHistoryReadOperation(request)) return (await prepareSessionHistoryReadOperation(request))(); if (request.kind === "session-cleanup") { const { readSessionCleanupSnapshot } = await import("../../cleanup-service-read.worker-CLIPh10R.mjs"); return readSessionCleanupSnapshot(request); } if (request.kind === "lifecycle-artifact-plan") { const { readSessionLifecycleArtifactCleanup } = await import("../../session-accessor.sqlite-lifecycle-artifacts-Dnt42bUY.mjs"); const { withOpenClawAgentDatabaseReadOnly } = await import("../../openclaw-agent-db-readonly-BPrk2NDl.mjs"); const result = withOpenClawAgentDatabaseReadOnly((database) => readSessionLifecycleArtifactCleanup(database, request.input, request.expectedSource), { ...request.database, env: request.env }); return { kind: request.kind, plan: result.found ? result.value : { entries: [], deletePlans: [] }, diagnostics: request.input.diagnostics }; } if (request.kind === "prewarm") { await Promise.all([ import("../../session-history-worker-reader-BjCyV9Wj.mjs"), import("../../chat-history-page-kernel-DuGoW0-t.mjs"), import("../../chat-history-response-page-CgLWJ4M3.mjs"), import("../../session-history-snapshot-Bmlndhic.mjs") ]); const { withOpenClawAgentDatabaseReadOnly } = await import("../../openclaw-agent-db-readonly-BPrk2NDl.mjs"); const opened = withOpenClawAgentDatabaseReadOnly(() => void 0, { ...request.database, env: cloneEnvWithPlatformSemantics(request.env) }); if (!opened.found && opened.reason !== "database-missing") throw new Error(`Session history prewarm admission unavailable: ${opened.reason}`); return { kind: "prewarm" }; } if (request.kind === "historical-eviction-candidates") { const { withOpenClawAgentDatabaseReadOnly } = await import("../../openclaw-agent-db-readonly-BPrk2NDl.mjs"); const { runSqliteDeferredTransactionSync } = await import("../../sqlite-transaction-x-XSqHJX.mjs"); const { readHistoricalSessionIdsInDatabase, readDiskEvictableArchivedSessionBatchInDatabase } = await import("../../session-history-eviction-candidates-o-iXNR8G.mjs"); const result = withOpenClawAgentDatabaseReadOnly((database) => runSqliteDeferredTransactionSync(database.db, () => "archived" in request ? { batch: readDiskEvictableArchivedSessionBatchInDatabase(database, request.archived) } : { sessionIds: readHistoricalSessionIdsInDatabase({ ...request, database }) }), { ...request.database, env: request.env }); if (!result.found) { if ("archived" in request && result.reason === "database-missing") return { kind: "historical-eviction-candidates", batch: { candidates: [], exhausted: true } }; throw new Error(`SQLite history eviction cannot read its database: ${result.reason}`); } return { kind: "historical-eviction-candidates", ...result.value }; } if (request.kind === "session-pending-archives") { const { withOpenClawAgentDatabaseReadOnly } = await import("../../openclaw-agent-db-readonly-BPrk2NDl.mjs"); const { hasPendingSessionTranscriptArchives } = await import("../../session-accessor.sqlite-archive-store-kernel-BLACa31R.mjs"); const result = withOpenClawAgentDatabaseReadOnly(hasPendingSessionTranscriptArchives, { ...request.database, env: cloneEnvWithPlatformSemantics(request.env) }); return { kind: "session-pending-archives", pending: result.found && result.value }; } if (request.kind === "memory-session-targets") { const { readMemorySessionTargets } = await import("../../session-memory-targets-BfVZbLhI.mjs"); return { kind: request.kind, targets: readMemorySessionTargets({ ...request.params, env: cloneEnvWithPlatformSemantics(request.params.env) }, request.continuation) }; } if (request.kind === "session-archive-inventory") { const { listSessionTranscriptArchivesReadOnly } = await import("../../session-accessor.sqlite-history-TPw6vAF1.mjs"); return { kind: request.kind, archives: listSessionTranscriptArchivesReadOnly({ ...request, env: cloneEnvWithPlatformSemantics(request.env ?? process.env) }) }; } if (request.kind === "session-corpus-inventory") { const { readSessionTranscriptCorpusInventory } = await import("../../session-transcript-corpus-DyR5DQlv.mjs"); return { kind: request.kind, entries: readSessionTranscriptCorpusInventory({ ...request.scope, env: cloneEnvWithPlatformSemantics(request.scope.env) }, request.options, request.artifacts, request.database.path, request.continuation) }; } if (request.kind === "session-archive-presence") { const { readTranscriptArchivePresenceInWorker } = await import("../../session-accessor.sqlite-archive-read-Dssnm1dU.mjs"); return { kind: "session-archive-presence", registered: readTranscriptArchivePresenceInWorker({ ...request, env: cloneEnvWithPlatformSemantics(request.env) }) }; } if (request.kind === "session-archive-pruning") { const { readSessionArchivePruningInWorker } = await import("../../session-history-archive-pruning.worker-_B7KFb7c.mjs"); return { kind: "session-archive-pruning", result: readSessionArchivePruningInWorker(request) }; } if (request.kind === "cold-metadata" || request.kind === "cold-storage-inventory") { const cold = await import("../../session-cold-storage-worker-CLdi8Iwe.mjs"); const options = { ...request.database, env: cloneEnvWithPlatformSemantics(request.env) }; return request.kind === "cold-metadata" ? { kind: request.kind, archive: cold.readSessionColdMetadataInWorker(options, request.sessionId) } : { kind: request.kind, ...cold.readSessionColdStorageInventoryInWorker(options) }; } if (request.kind === "session-store-target") { const { readSessionStoreTargetResult } = await import("../../session-store-target-inventory-C8PUuvYl.mjs"); request.request.env = cloneEnvWithPlatformSemantics(request.request.env); const read = readSessionStoreTargetResult(request.request); if (!read.ok) { const readError = encodeSessionTranscriptWorkerError(read.error); if (!readError) throw read.error; return { kind: "session-store-target", readError }; } return read.value; } if (request.kind === "session-retirement-read") { const { readSessionRetirementInWorker } = await import("../../session-retirement-read.worker-CAGv8n6t.mjs"); return { kind: request.kind, result: readSessionRetirementInWorker(request) }; } if (request.kind === "session-exact-entries") { const { readExactSessionEntriesWithLifecycle } = await import("../../session-entry-read.worker-Bk0PyRMc.mjs"); request.env = cloneEnvWithPlatformSemantics(request.env); return readExactSessionEntriesWithLifecycle(request); } if (request.kind === "session-row-facts") { const { readSessionRowDatabaseFacts } = await import("../../session-entry-read.worker-Bk0PyRMc.mjs"); return readSessionRowDatabaseFacts(request); } if (request.kind === "session-maintenance-read") { const { readSessionMaintenanceInWorker } = await import("../../session-accessor.sqlite-maintenance-transaction-wDLc5AtK.mjs"); return { kind: "session-maintenance-read", result: readSessionMaintenanceInWorker({ ...request.plan, databaseOptions: { ...request.database, env: cloneEnvWithPlatformSemantics(request.env) } }), workerThreadId: threadId }; } if (request.kind === "session-entry-current") { const { readSessionEntryCurrentFacts } = await import("../../session-entry-read.worker-Bk0PyRMc.mjs"); return readSessionEntryCurrentFacts(request); } if (request.kind === "session-row-backfill") { const { readSessionRowTranscriptFields } = await import("../../session-row-transcript-backfill.kernel-CVxyEZiM.mjs"); return { kind: "session-row-backfill", fields: readSessionRowTranscriptFields(request.params) }; } if (request.kind === "session-target-inventory") { const { readSessionStoreTargetInventory } = await import("../../session-store-target-inventory-C8PUuvYl.mjs"); return readSessionStoreTargetInventory(request.request); } if (request.kind === "session-identity-evidence") { const { withOpenClawAgentDatabaseReadOnly } = await import("../../openclaw-agent-db-readonly-BPrk2NDl.mjs"); const { readSessionIdentityEvidenceInDatabase } = await import("../../session-accessor.sqlite-entry-availability--ufK-s3p.mjs"); const { readWithCanonicalSessionReaderContinuation } = await import("../../session-canonical-key-GVDAgytN.mjs"); const result = withOpenClawAgentDatabaseReadOnly((database) => readWithCanonicalSessionReaderContinuation(database, request.continuation, () => readSessionIdentityEvidenceInDatabase(database, request.identities)), { ...request.database, env: cloneEnvWithPlatformSemantics(request.env) }); return { kind: "session-identity-evidence", evidence: result.found ? result.value : request.identities.map(() => result.reason === "database-missing" ? { status: "absent" } : { status: "unknown", reason: result.reason }) }; } if (request.kind === "session-diagnostic-text") { const { readSessionDiagnosticText } = await import("../../session-entry-read.worker-Bk0PyRMc.mjs"); return readSessionDiagnosticText(request); } if (request.kind === "session-entry-read" || request.kind === "session-runtime-target") { const { readSessionEntryWorkerRequest } = await import("../../session-entry-read.worker-Bk0PyRMc.mjs"); return readSessionEntryWorkerRequest(request); } if (request.kind === "session-entry-list") { const { readSessionEntryList } = await import("../../session-entry-list.worker-ByuJF9WD.mjs"); return { kind: "session-entry-list", ...readSessionEntryList(request) }; } if (request.kind === "session-store-projection") { const { readSessionStoreProjection } = await import("../../session-entry-read.worker-Bk0PyRMc.mjs"); return readSessionStoreProjection(request); } if (request.kind === "session-store-summary") { const { readSessionStoreSummaryReadOnly } = await import("../../session-accessor.sqlite-summary-CVbBNO_8.mjs"); return { kind: "session-store-summary", summary: readSessionStoreSummaryReadOnly({ agentId: request.database.agentId, storePath: request.database.path, env: cloneEnvWithPlatformSemantics(request.env) }, request) }; } if (request.kind === "voice-sessions") { const { readOpenVoiceSessions } = await import("../../client-voice-session-lookup.worker-AuA_FxyB.mjs"); return readOpenVoiceSessions({ ...request.database, env: request.env }, request.request); } if (request.kind === "usage-cache") { const { readSessionCostUsageCache } = await import("../../session-cost-usage-cache-read-Diektlil.mjs"); return readSessionCostUsageCache({ ...request.database, env: request.env }, request.request); } if (request.kind === "session-membership-facts") { const { withOpenClawAgentDatabaseReadOnly } = await import("../../openclaw-agent-db-readonly-BPrk2NDl.mjs"); const { readSessionMembershipFactsInDatabase } = await import("../../session-membership-facts-Dm05rmhE.mjs"); const { readWithCanonicalSessionReaderContinuation } = await import("../../session-canonical-key-GVDAgytN.mjs"); const result = withOpenClawAgentDatabaseReadOnly((database) => readWithCanonicalSessionReaderContinuation(database, request.continuation, () => readSessionMembershipFactsInDatabase(database, request.sessionKeys)), { ...request.database, env: cloneEnvWithPlatformSemantics(request.env) }); if (!result.found && result.reason !== "database-missing") throw new Error(`Session membership read unavailable: ${result.reason}`); return result.found ? result.value : { kind: "session-membership-facts", facts: [] }; } if (request.kind === "projection-status") { const { withOpenClawAgentDatabaseReadOnly } = await import("../../openclaw-agent-db-readonly-BPrk2NDl.mjs"); const { runSqliteDeferredTransactionSync } = await import("../../sqlite-transaction-x-XSqHJX.mjs"); const { sessionTranscriptIndexNeedsReconcile } = await import("../../session-transcript-index-BiC3FRBe.mjs"); const result = withOpenClawAgentDatabaseReadOnly(({ db }) => runSqliteDeferredTransactionSync(db, () => sessionTranscriptIndexNeedsReconcile(db, request.sessionId)), { ...request.database, env: request.env }); return result.found && result.value; } if (request.kind === "session-members") { const { withOpenClawAgentDatabaseReadOnly } = await import("../../openclaw-agent-db-readonly-BPrk2NDl.mjs"); const { readSessionMembersInDatabase } = await import("../../session-sharing-store.kernel-Bq3JS1TS.mjs"); const { readWithCanonicalSessionReaderContinuation } = await import("../../session-canonical-key-GVDAgytN.mjs"); const result = withOpenClawAgentDatabaseReadOnly((database) => readWithCanonicalSessionReaderContinuation(database, request.continuation, () => readSessionMembersInDatabase(database, request.sessionKey)), { ...request.database, env: request.env }); return { kind: "session-members", ...result.found ? result.value : { entry: void 0, members: [] } }; } if (request.kind === "session-suggestions") { const { withOpenClawAgentDatabaseReadOnly } = await import("../../openclaw-agent-db-readonly-BPrk2NDl.mjs"); const { listSessionSuggestionsInDatabase } = await import("../../session-suggestion-store.kernel-C06OeZ_S.mjs"); const result = withOpenClawAgentDatabaseReadOnly((database) => listSessionSuggestionsInDatabase(database, request.sessionKey, request.params), { ...request.database, env: request.env }); return { kind: "session-suggestions", suggestions: result.found ? result.value : [] }; } if (request.kind === "session-pending-input-history") { const { readPendingInputHistoryInWorker } = await import("../../session-pending-input-history-read.worker-DR9Ul02p.mjs"); return { kind: "session-pending-input-history", snapshot: readPendingInputHistoryInWorker(request) }; } if (request.kind === "conversation-rows") { const { withOpenClawAgentDatabaseReadOnly } = await import("../../openclaw-agent-db-readonly-BPrk2NDl.mjs"); const { selectConversationRowsFromDatabase } = await import("../../session-accessor.sqlite-conversation-read-D1f01LJj.mjs"); const read = withOpenClawAgentDatabaseReadOnly((database) => selectConversationRowsFromDatabase(database, request.query), { ...request.database, env: cloneEnvWithPlatformSemantics(request.env) }); return { kind: "conversation-rows", rows: read.found ? read.value : [] }; } if (request.kind === "conversation-delivery") { const { withOpenClawAgentDatabaseReadOnly } = await import("../../openclaw-agent-db-readonly-BPrk2NDl.mjs"); const { readConversationDeliveryInDatabase } = await import("../../conversation-delivery-store.kernel-CuDWhKBD.mjs"); const result = withOpenClawAgentDatabaseReadOnly((database) => readConversationDeliveryInDatabase(database, request.lookup), { ...request.database, env: cloneEnvWithPlatformSemantics(request.env) }); return { kind: "conversation-delivery", record: result.found ? result.value : void 0 }; } if (request.kind === "goal-operation-receipt") { const { withOpenClawAgentDatabaseReadOnly } = await import("../../openclaw-agent-db-readonly-BPrk2NDl.mjs"); const { assertSessionGoalOperationTime, readSessionGoalOperationInDatabase, SessionGoalOperationError } = await import("../../goals-operations-D-PH2Flj.mjs"); try { assertSessionGoalOperationTime(request.operation, Date.now()); const result = withOpenClawAgentDatabaseReadOnly((database) => readSessionGoalOperationInDatabase(database, request), { ...request.database, env: cloneEnvWithPlatformSemantics(request.env) }); return { kind: "goal-operation-receipt", result: { receipt: result.found ? result.value : void 0 } }; } catch (error) { if (!(error instanceof SessionGoalOperationError)) throw error; return { kind: "goal-operation-receipt", result: { error: { code: error.code, message: error.message } } }; } } if (request.kind === "session-progress-card") { const { withOpenClawAgentDatabaseReadOnly } = await import("../../openclaw-agent-db-readonly-BPrk2NDl.mjs"); const { readSessionProgressCard } = await import("../../progress-card-store-Ce1AKI5o.mjs"); const result = withOpenClawAgentDatabaseReadOnly((database) => readSessionProgressCard(database.db, request.sessionKey), { ...request.database, env: request.env }); return { kind: "session-progress-card", card: result.found ? result.value : null }; } if (request.kind === "session-row-presence") { const { loadSessionEntryReadOnlyInScope } = await import("../../session-accessor.sqlite-exact-read-BFce1gmG.mjs"); return loadSessionEntryReadOnlyInScope({ ...request.scope, projection: "list" }) !== void 0; } return await runWithSessionTranscriptReadFence(request.admission, async () => { if (request.kind === "session-activity-summary-source") { const { readActivitySummaryBatch } = await import("../../session-activity-summary-source-CNgv1bzD.mjs"); return { kind: "session-activity-summary-source", source: readActivitySummaryBatch(request) }; } if (request.kind === "transcript-hydration" || request.kind === "transcript-maintenance" || request.kind === "current-turn-entry" || request.kind === "recent-active-events" || request.kind === "latest-active-message") { const { readSessionTranscriptHydrationRequest } = await import("../../session-transcript-hydration-read.worker-CyiURMbZ.mjs"); return readSessionTranscriptHydrationRequest(request, channel, control); } if (request.kind === "history-page") { const { readSessionHistoryRequest } = await import("../../session-history-worker-reader-BjCyV9Wj.mjs"); return readSessionHistoryRequest(request.request, { ...request.target, database: request.database }); } if (request.kind === "session-reset-recall") { const { readSessionResetRecallCutoffInProcess } = await import("../../session-reset-recall-read-DnjvsKmG.mjs"); return { cutoff: readSessionResetRecallCutoffInProcess(request.scope) }; } const { buildSessionEntryInProcess, readSessionEntryResetRecallCutoff } = await import("../../session-files-Bt1vfylo.mjs"); const { createSensitiveTextRedactor } = await import("../../redact-DVwqubI_.mjs"); const entry = await buildSessionEntryInProcess(request.absPath, request.options, createSensitiveTextRedactor(request.redaction)); return { entry, resetRecallCutoff: entry ? readSessionEntryResetRecallCutoff(entry) : { state: "absent" } }; }); }; try { return "database" in request ? await withHistoryDatabase(request.database, request.kind === "history-page" ? request.request.kind === "summary" ? `history.${request.request.params.query.kind}` : `history.${request.request.kind}` : request.kind, readRequest, request.validation) : { ok: true, value: await readRequest() }; } catch (error) { const encoded = encodeSessionTranscriptRequestError(error, request); if (encoded) return { ok: false, error: encoded }; throw error; } }, { transferList(reply) { if (!reply.ok) return []; const value = reply.value; if (typeof value !== "object" || value === null || !("kind" in value)) return []; const body = value.kind === "rpc" ? value.page.encodedResponse?.messages : value.kind === "artifacts" && value.result.kind === "download-response" ? value.result.response?.body : void 0; return body ? [body.buffer] : []; }, closeResource: (key) => { const request = decodeAgentDatabaseReaderRequest(key); if (request?.kind !== "close") throw new Error("Session reader cleanup requires captured physical paths"); releaseReadValidation?.(request.candidates, request.deleted ? void 0 : request.retainedPaths); pruneClosedHistoryDatabaseScopes(); } }); //#endregion export {};