From 992126e382af8449ceb61eceaca5413da6d3b3fd Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 11 Aug 2026 04:13:29 -0700 Subject: [PATCH] refactor(sessions): drop the Sqlite infix from session-accessor exports (#121536) * refactor(sessions): drop the Sqlite infix from session-accessor exports The storage-neutral seam completed its file->SQLite swap on 2026-07-27; the Sqlite-infixed export names and their X-as-Y rename blocks were the fossil of that migration, giving every accessor operation two greppable names. Rename ~148 exports to their canonical names at the definition sites, delete the message-cut facade (its conflict->failed mask had one consumer, which already handles conflict), collapse the remaining pure delegates, and keep honest SQLite-mechanics names (scope resolution, canonical repair, in-transaction primitives, storage-row types). The main barrel's exported surface is byte-identical. Net -203 production LOC. Part 2 of the session-accessor dual-layer collapse (part 1: #121316). * fix: repair main-breaking lint/type/test failures blocking PR CI Three breakages landed on main that push CI's changed-scope never runs: a caught-error cause missing in the release-validation script and two type errors in the package-acceptance test (direct commit 1f591bba562), and a memory-host regression where fs-safe 0.5.4 (#121508) started throwing FsSafeError("not-file") for extra-path reads whose parent chain hits a regular file, breaking the missing-file empty-text contract that rejection unchanged. Item 4 repairs managed-image action E2E narrowing from bad30d5a741 (#77017). Item 5's chat-message mock repair was superseded upstream by 750d0dcd9e7, whose broader fetch typing and explicit download capture preserve the same contract. Item 6 restores #121258's cursor token contract after #77017 hard-coded pointer. Item 7's managed-image thumbnail-path repair was superseded upstream by 750d0dcd9e7, which preserves the same contract in main's reorganized URL structure. Item 8 records #121600's explicit command-bearing lifecycle classification. Item 9's cron assertion repair was superseded upstream by 3cd034f7a8d, whose exact diagnostic rewrite includes the same redacted alert contract. Item 10 forwards fs-safe 0.5.4 bigint lstat options through the snapshot mock. Item 11 refreshes release-matrix test ownership after 1f591bba562. Item 12 awaits f3e1efead48's setup-admission settlement in direct session tests. Item 13's media FileStore-key repair was superseded upstream by cf432ec8717, which fixes the same Windows root cause at the owner boundary. Item 14 regenerates Swift approval reviewer fields added by 9935ca3b30d. --- docs/.generated/plugin-sdk-api-baseline.jsonl | 140 ++++---- .../lib/export-name-collision-baseline.json | 32 ++ .../lib/session-accessor-debt-baseline.json | 5 +- ...lite-session-entry-cache-lifetime-proof.ts | 8 +- .../run/attempt-dispatch-preparation.ts | 4 +- .../run/attempt-transcript-helpers.ts | 4 +- .../transcript-runtime-state.ts | 4 +- .../reply/agent-runner-memory.test.ts | 20 +- src/auto-reply/reply/session-fork.test.ts | 12 +- src/commands/agent.worktree-race.test.ts | 4 +- src/commands/doctor-session-canonical-keys.ts | 8 +- src/commands/doctor-session-entry-rewrite.ts | 8 +- .../doctor-session-incognito-key-repair.ts | 4 +- src/commands/doctor-session-sqlite.test.ts | 56 ++-- .../doctor-session-transcript-headers.test.ts | 28 +- .../doctor-session-transcript-headers.ts | 6 +- .../doctor-session-transcript-labels.test.ts | 48 +-- .../doctor-session-transcript-labels.ts | 4 +- src/config/sessions/conversation-registry.ts | 4 +- .../incognito-session-transcript.test.ts | 4 +- .../session-accessor.conformance.test.ts | 316 ++++++++---------- .../session-accessor.entry-mutation.ts | 58 ++-- src/config/sessions/session-accessor.entry.ts | 60 ++-- .../sessions/session-accessor.lifecycle.ts | 20 +- .../sessions/session-accessor.message-cut.ts | 37 -- ...on-accessor.reply-init-concurrency.test.ts | 6 +- .../session-accessor.sqlite-archive.ts | 48 +-- ...ion-accessor.sqlite-archive.worker.test.ts | 84 ++--- .../session-accessor.sqlite-archive.worker.ts | 34 +- ...ession-accessor.sqlite-batch-projection.ts | 6 +- ...ession-accessor.sqlite-canonical-repair.ts | 24 +- .../session-accessor.sqlite-checkpoint.ts | 14 +- ...ssion-accessor.sqlite-cleanup-race.test.ts | 45 ++- ...ssion-accessor.sqlite-data-version.test.ts | 16 +- ...session-accessor.sqlite-delete-snapshot.ts | 6 +- .../sessions/session-accessor.sqlite-delta.ts | 2 +- .../session-accessor.sqlite-entry-cache.ts | 22 +- .../session-accessor.sqlite-entry-store.ts | 83 +++-- .../sessions/session-accessor.sqlite-entry.ts | 139 ++++---- .../session-accessor.sqlite-events.ts | 4 +- .../session-accessor.sqlite-history.ts | 2 +- .../session-accessor.sqlite-import.ts | 4 +- ...session-accessor.sqlite-lifecycle-state.ts | 126 +++---- ...session-accessor.sqlite-lifecycle-types.ts | 20 +- .../session-accessor.sqlite-lifecycle.ts | 108 +++--- .../session-accessor.sqlite-maintenance.ts | 58 ++-- ...ession-accessor.sqlite-message-cut.test.ts | 25 +- .../session-accessor.sqlite-message-cut.ts | 22 +- .../session-accessor.sqlite-normalize.ts | 4 +- .../session-accessor.sqlite-parent-fork.ts | 14 +- .../session-accessor.sqlite-parent-session.ts | 98 +++--- .../session-accessor.sqlite-projection.ts | 127 ++++--- .../sessions/session-accessor.sqlite-read.ts | 46 ++- .../session-accessor.sqlite-references.ts | 2 +- ...-accessor.sqlite-replacement-projection.ts | 24 +- .../session-accessor.sqlite-session-row.ts | 70 ++-- .../session-accessor.sqlite-status.ts | 12 +- ...cessor.sqlite-transcript-message-append.ts | 2 +- ...ssion-accessor.sqlite-transcript-mirror.ts | 4 +- ...on-accessor.sqlite-transcript-sequences.ts | 8 +- ...ession-accessor.sqlite-transcript-state.ts | 10 +- ...ession-accessor.sqlite-transcript-store.ts | 14 +- ...ession-accessor.sqlite-transcript-write.ts | 94 +++--- src/config/sessions/session-accessor.test.ts | 115 +++---- .../session-accessor.transcript-target.ts | 2 - .../session-accessor.transcript-turn.ts | 12 +- .../sessions/session-accessor.transcript.ts | 71 ++-- src/config/sessions/session-accessor.ts | 4 +- src/config/sessions/session-entry-json.ts | 4 +- .../sessions/session-history-eviction.ts | 31 +- src/config/sessions/session-history.ts | 29 +- .../session-transcript-search.test.ts | 22 +- .../sessions/targets-read-availability.ts | 4 +- src/config/sessions/targets.ts | 6 +- src/gateway/managed-image-actions.e2e.test.ts | 8 +- src/gateway/managed-image-attachments.ts | 4 +- src/gateway/minimal-gateway.test-helpers.ts | 2 +- .../server-methods.authorization.test.ts | 6 +- .../server-methods/sessions-patch-engine.ts | 4 +- src/gateway/server-methods/sessions-rewind.ts | 6 +- .../server.chat.gateway-server-chat.test.ts | 6 +- .../server.sessions.delete-lifecycle.test.ts | 4 +- src/gateway/session-compaction-checkpoints.ts | 8 +- src/gateway/session-utils-search.ts | 15 +- src/gateway/session-utils-store.ts | 7 +- src/gateway/session-utils.ts | 4 +- src/plugin-sdk/session-transcript-runtime.ts | 7 +- ...anscripts-flip-proof.built-cli.e2e.test.ts | 8 +- 88 files changed, 1272 insertions(+), 1438 deletions(-) delete mode 100644 src/config/sessions/session-accessor.message-cut.ts diff --git a/docs/.generated/plugin-sdk-api-baseline.jsonl b/docs/.generated/plugin-sdk-api-baseline.jsonl index 69a7282af61c..e99d5a37fa80 100644 --- a/docs/.generated/plugin-sdk-api-baseline.jsonl +++ b/docs/.generated/plugin-sdk-api-baseline.jsonl @@ -53,17 +53,17 @@ {"closureHash":"ff3c4616cd6212a6d698831a8b287ad87e3968c8663f4090d095bb30ec40fc1c","declaration":"export function abortAndDrainAgentHarnessRun(params: { sessionId: string; sessionKey?: string; settleMs?: number; forceClear?: boolean; reason?: string; }): Promise;","entrypoint":"agent-harness","exportName":"abortAndDrainAgentHarnessRun","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"} {"closureHash":"58989e3fa91eecf2e05202e36548e6e64a3b9219e83154bd99866c851604e34e","declaration":"export function createAgentToolResultMiddlewareRunner(ctx: AgentToolResultMiddlewareContext, handlers?: AgentToolResultMiddleware[]): { applyToolResultMiddleware(event: AgentToolResultMiddlewareEvent): Promise; };","entrypoint":"agent-harness","exportName":"createAgentToolResultMiddlewareRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"} {"closureHash":"b8f6355d7ad1700aceecddaa6e9ccf43091a792d5b481a1ee3f55294a881a67d","declaration":"export function createCodexAppServerToolResultExtensionRunner(ctx: CodexAppServerExtensionContext, factories?: CodexAppServerExtensionFactory[]): { applyToolResultExtensions(event: CodexAppServerToolResultEvent): Promise>; };","entrypoint":"agent-harness","exportName":"createCodexAppServerToolResultExtensionRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"} -{"closureHash":"5fe058c49c83457e431a3fc7311fec79c53591db797b9d21662c202bf3fb6e9a","declaration":"export function createOpenClawCodingTools(options?: OpenClawCodingToolsOptions): AnyAgentTool[];","entrypoint":"agent-harness","exportName":"createOpenClawCodingTools","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"} +{"closureHash":"a0f0f98da819da90c965464d4de4e0c9d7fd9e7b0ec030e993708ccfd6542713","declaration":"export function createOpenClawCodingTools(options?: OpenClawCodingToolsOptions): AnyAgentTool[];","entrypoint":"agent-harness","exportName":"createOpenClawCodingTools","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"} {"closureHash":"13649ee853485319e7449fda25c106b3f3f53d3090e53cdbb28e220a8529eb80","declaration":"export function disposeRegisteredAgentHarnesses(): Promise;","entrypoint":"agent-harness","exportName":"disposeRegisteredAgentHarnesses","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"} {"closureHash":"f255a91162ece4c239bb8fa745efa14a1054bc024a291e9954f75f239b2b87c3","declaration":"export function resolveActiveEmbeddedRunSessionId(sessionKey: string): string | undefined;","entrypoint":"agent-harness","exportName":"resolveActiveEmbeddedRunSessionId","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"} {"closureHash":"27d9f61df9ccf68615cb2002a6da891e36ab0c07623bc37c4d07aa980b446881","declaration":"export function resolveWebSearchToolPolicy(params: WebSearchToolPolicyParams): WebSearchToolPolicyResolution;","entrypoint":"agent-harness","exportName":"resolveWebSearchToolPolicy","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"function","recordType":"export"} -{"closureHash":"dad048707e7e780a56529d7567a4d10fe081bd472786db796cd423e7c204ce6d","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"} -{"closureHash":"a0cb9cfd5f486fba8b684f5724417c3ded806072d0a9d09b95b6fb44f10d169f","declaration":"export type AgentHarnessV2 = AgentHarnessV2;","entrypoint":"agent-harness","exportName":"AgentHarnessV2","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"} +{"closureHash":"b467021581907cc4f2f8266283b147425febfe5d96c596dd00bc42ad5b9c6cac","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"} +{"closureHash":"ab44fb6980e5f0715662f663ee705ee609e0dc13d7bb57e56e89e14610cc7cd5","declaration":"export type AgentHarnessV2 = AgentHarnessV2;","entrypoint":"agent-harness","exportName":"AgentHarnessV2","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"} {"closureHash":"4ad0f830bf11a2db48faefb1439b7fbb08d9f22d22083f5e301327e1696f2310","declaration":"export type AgentToolResultMiddleware = AgentToolResultMiddleware;","entrypoint":"agent-harness","exportName":"AgentToolResultMiddleware","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"} {"closureHash":"008b6c78d5e44a9d1df1d7e32e6015382ee9ba1cb9b10bd4c2b467619d1c89d4","declaration":"export type AgentToolResultMiddlewareEvent = AgentToolResultMiddlewareEvent;","entrypoint":"agent-harness","exportName":"AgentToolResultMiddlewareEvent","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"} {"closureHash":"7414a2a79c2d78c1d52538250c827305bba1a2bb25010448837c8524a9f95b3c","declaration":"export type AnyAgentTool = AnyAgentTool;","entrypoint":"agent-harness","exportName":"AnyAgentTool","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"} -{"closureHash":"f1fdf2a77b0374b4a030f9ea4f070fee1ffc6e1b0302950ebfafc0d2686565dd","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"} -{"closureHash":"f6b266b995d12169f22f438feec586e7e8fc9723eb9b0bf730864366ccc63229","declaration":"export type EmbeddedRunAttemptParamsV2 = EmbeddedRunAttemptParamsV2;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"} +{"closureHash":"aefdbc51192417d04c2d734f27129dedc25a46521cc324e66e26827a17aaed68","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"} +{"closureHash":"10d9c3d733e1b03bbf485c7590401a5b4382e600f9bf56667352d6ed0efe2b66","declaration":"export type EmbeddedRunAttemptParamsV2 = EmbeddedRunAttemptParamsV2;","entrypoint":"agent-harness","exportName":"EmbeddedRunAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"} {"closureHash":"25c6985c3bef2c6efc6a96e70af6d66fe073be0b0d311681cfc0dfc186528d9a","declaration":"export type OpenClawAgentToolResult = OpenClawAgentToolResult;","entrypoint":"agent-harness","exportName":"OpenClawAgentToolResult","importSpecifier":"openclaw/plugin-sdk/agent-harness","kind":"type","recordType":"export"} {"category":"runtime","entrypoint":"agent-harness-runtime","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","recordType":"module"} {"closureHash":"fab99dfcb01d475a1bfdbe7a8fac9be10a93dac5f12ac78c2dea673c8ab86abf","declaration":"export function abortAgentHarnessRun(sessionId: string): boolean;\nexport function abortAgentHarnessRun(sessionId: undefined, opts: { mode: \"all\" | \"compacting\"; reason?: \"restart\"; }): boolean;","entrypoint":"agent-harness-runtime","exportName":"abortAgentHarnessRun","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} @@ -82,8 +82,8 @@ {"closureHash":"f8ad3d762c9753fdc36b2b9af0980167fdc54090c7bcca2f3dbe7c8951e86821","declaration":"export function buildAgentRuntimePlan(params: BuildAgentRuntimePlanParams): AgentRuntimePlan;","entrypoint":"agent-harness-runtime","exportName":"buildAgentRuntimePlan","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"528d11abf061b0b303722737de5a6406e7e55bffa38c45144c77d896ae1b3b0a","declaration":"export function buildBootstrapContextForFiles(bootstrapFiles: WorkspaceBootstrapFile[], params: { config?: OpenClawConfig; agentId?: string | null; warn?: (message: string) => void; }): EmbeddedContextFile[];","entrypoint":"agent-harness-runtime","exportName":"buildBootstrapContextForFiles","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"44d5a4667d2f3dc3a28e5c9d7b46765b1fb3c62820288e40251f5174911c8a6a","declaration":"export function buildEmbeddedAttemptToolRunContext(params: { trigger?: EmbeddedRunTrigger; jobId?: string; memoryFlushWritePath?: string; toolsAllow?: string[]; conversationToolPolicy?: GroupToolPolicyConfig; trace?: DiagnosticTraceContext; }): { trigger?: EmbeddedRunTrigger; jobId?: string; memoryFlushWritePath?: string; runtimeToolAllowlist?: string[]; conversationToolPolicy?: GroupToolPolicyConfig; trace?: DiagnosticTraceContext; };","entrypoint":"agent-harness-runtime","exportName":"buildEmbeddedAttemptToolRunContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} -{"closureHash":"09e81724481ffeb8e57b068f09b119ef338628fb81b60488ae89922464e04954","declaration":"export function buildHarnessContextEngineRuntimeContext(params: Parameters[0]): ContextEngineRuntimeContext;","entrypoint":"agent-harness-runtime","exportName":"buildHarnessContextEngineRuntimeContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} -{"closureHash":"a62440b3ef647775747bace0b202389f1d958f0e93fd05140b9deb8b923723d9","declaration":"export function buildHarnessContextEngineRuntimeContextFromUsage(params: Parameters[0]): ContextEngineRuntimeContext;","entrypoint":"agent-harness-runtime","exportName":"buildHarnessContextEngineRuntimeContextFromUsage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} +{"closureHash":"fe63a9c3f1864e09a969a71747f0704f02c365c1a3ce06a9f1f467bbbfe576fb","declaration":"export function buildHarnessContextEngineRuntimeContext(params: Parameters[0]): ContextEngineRuntimeContext;","entrypoint":"agent-harness-runtime","exportName":"buildHarnessContextEngineRuntimeContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} +{"closureHash":"583fa7c38b29c2ddd4ac7c93689d19335fc93132367351f2ce6838be28cadaaf","declaration":"export function buildHarnessContextEngineRuntimeContextFromUsage(params: Parameters[0]): ContextEngineRuntimeContext;","entrypoint":"agent-harness-runtime","exportName":"buildHarnessContextEngineRuntimeContextFromUsage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"33a7cd8d63d4ef045ee3a42f806026a8b621e7dd32d8d6fbf4e7b44452d5e0ce","declaration":"export function buildNativeHookRelayCommand(params: { provider: NativeHookRelayProvider; relayId: string; generation?: string; event: NativeHookRelayEvent; preToolUseUnavailable?: \"noop\"; timeoutMs?: number; executable?: string; nice?: number | false; nodeExecutable?: string; }): string;","entrypoint":"agent-harness-runtime","exportName":"buildNativeHookRelayCommand","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"3846647c3c2fb0242f70591cf95c2e02f2a5a3c44447efb4cf7a31b2dc2122fd","declaration":"export function buildSkillWorkshopPromptSection(): string[];","entrypoint":"agent-harness-runtime","exportName":"buildSkillWorkshopPromptSection","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"32e977ece65144a83ae1b0a3c8d1b9b00a2a2506ad9ef1db3b2b9770ce762dbe","declaration":"export function buildWatchedSessionsHarnessContext(params: { config?: OpenClawConfig; sessionKey?: string; sandboxed?: boolean; toolNames: Iterable; capabilityToolNames?: Iterable; }): string | undefined;","entrypoint":"agent-harness-runtime","exportName":"buildWatchedSessionsHarnessContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} @@ -100,7 +100,7 @@ {"closureHash":"51f76e9e37b65b358f0313e10152d950b003bc3e50f4bb26fe29a988237772e2","declaration":"export function consumePreExecutionBlockedToolCall(toolCallId: string, runId?: string): boolean;","entrypoint":"agent-harness-runtime","exportName":"consumePreExecutionBlockedToolCall","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"58989e3fa91eecf2e05202e36548e6e64a3b9219e83154bd99866c851604e34e","declaration":"export function createAgentToolResultMiddlewareRunner(ctx: AgentToolResultMiddlewareContext, handlers?: AgentToolResultMiddleware[]): { applyToolResultMiddleware(event: AgentToolResultMiddlewareEvent): Promise; };","entrypoint":"agent-harness-runtime","exportName":"createAgentToolResultMiddlewareRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"b8f6355d7ad1700aceecddaa6e9ccf43091a792d5b481a1ee3f55294a881a67d","declaration":"export function createCodexAppServerToolResultExtensionRunner(ctx: CodexAppServerExtensionContext, factories?: CodexAppServerExtensionFactory[]): { applyToolResultExtensions(event: CodexAppServerToolResultEvent): Promise>; };","entrypoint":"agent-harness-runtime","exportName":"createCodexAppServerToolResultExtensionRunner","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} -{"closureHash":"b6bf4c61a2352005ed91dbb938e763f227f915cfedc2be36b6efd2f48707090d","declaration":"export function deliverAgentHarnessUserInputPrompt(params: PromptDeliveryParams, questions: readonly AgentHarnessUserInputQuestion[], options?: AgentHarnessUserInputPromptOptions): Promise;","entrypoint":"agent-harness-runtime","exportName":"deliverAgentHarnessUserInputPrompt","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} +{"closureHash":"694259ef47d10912af67cdacfec68beba4b6c5f91d4d5b89dee1a0ddc0c4a371","declaration":"export function deliverAgentHarnessUserInputPrompt(params: PromptDeliveryParams, questions: readonly AgentHarnessUserInputQuestion[], options?: AgentHarnessUserInputPromptOptions): Promise;","entrypoint":"agent-harness-runtime","exportName":"deliverAgentHarnessUserInputPrompt","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"6f436485257f69fa07a18203b91d4341690522f12aff4f25805c7a1e21326ee3","declaration":"export function detectAndLoadAgentHarnessPromptImages(params: { prompt: string; workspaceDir: string; model: { input?: string[]; }; existingImages?: ImageContent[]; imageOrder?: PromptImageOrderEntry[]; media?: MediaFact[]; config?: OpenClawConfig; workspaceOnly?: boolean; localRoots?: readonly string[]; sandbox?: { root: string; bridge: SandboxFsBridge; }; }): Promise<{ images: ImageContent[]; detectedRefs: Array<{ raw: string; resolved: string; type: \"path\" | \"media-uri\"; }>; loadedCount: number; skippedCount: number; }>;","entrypoint":"agent-harness-runtime","exportName":"detectAndLoadAgentHarnessPromptImages","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"13649ee853485319e7449fda25c106b3f3f53d3090e53cdbb28e220a8529eb80","declaration":"export function disposeRegisteredAgentHarnesses(): Promise;","entrypoint":"agent-harness-runtime","exportName":"disposeRegisteredAgentHarnesses","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"c38cd390190bb07ddcd247420d6e0b489a0229bd402ddca0440417217a57251a","declaration":"export function emitAgentEvent(event: Omit): void;","entrypoint":"agent-harness-runtime","exportName":"emitAgentEvent","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} @@ -162,7 +162,7 @@ {"closureHash":"40154c3b7b2a7179df33f4a3fbef5e56078be2759d5aab29f39eb0f3c92fc631","declaration":"export function projectRuntimeToolInputSchema(schema: unknown, path?: string): RuntimeToolInputSchemaProjection;","entrypoint":"agent-harness-runtime","exportName":"projectRuntimeToolInputSchema","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"e42e3dc63e8545bb9a6056336fbd6c1dc8f356dce4f0f1c6d9765254c974390e","declaration":"export function projectSettledTurnFinalizationAttemptResult(result: AgentHarnessAttemptResult): AgentHarnessSettledTurnFinalizationResult;","entrypoint":"agent-harness-runtime","exportName":"projectSettledTurnFinalizationAttemptResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"32ab53f0ce98f72c43eb20bbcd3261b504ed4039c48533234c89331c9bcde7f1","declaration":"export function queueAgentHarnessMessage(sessionId: string, text: string, options?: EmbeddedAgentQueueMessageOptions): boolean;","entrypoint":"agent-harness-runtime","exportName":"queueAgentHarnessMessage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} -{"closureHash":"10d3b5209b22d96774a5abac94da0960837dad22ae185f2d396f5553ff415108","declaration":"export function registerNativeHookRelay(params: RegisterNativeHookRelayParams): ActiveNativeHookRelayRegistrationHandle;","entrypoint":"agent-harness-runtime","exportName":"registerNativeHookRelay","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} +{"closureHash":"503c33a47629d5afd350fa43b9f94c17709ef0307d6fceca383585950512c79a","declaration":"export function registerNativeHookRelay(params: RegisterNativeHookRelayParams): ActiveNativeHookRelayRegistrationHandle;","entrypoint":"agent-harness-runtime","exportName":"registerNativeHookRelay","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"b7cc6c35506dc6955e0359aa5c53c15a4d0db23639da8c1717f8fefda953c119","declaration":"export function requestDeferredPluginToolApproval(params: { deferredApproval: DeferredPluginToolApproval; signal?: AbortSignal; }): Promise;","entrypoint":"agent-harness-runtime","exportName":"requestDeferredPluginToolApproval","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"a2306cba08cb05ff8430c8362c0cc3c821706da5a4e65a06849ad0d0fb007ae3","declaration":"export function resetAgentEventsForTest(options?: { preserveListeners?: boolean; }): void;","entrypoint":"agent-harness-runtime","exportName":"resetAgentEventsForTest","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"f255a91162ece4c239bb8fa745efa14a1054bc024a291e9954f75f239b2b87c3","declaration":"export function resolveActiveEmbeddedRunSessionId(sessionKey: string): string | undefined;","entrypoint":"agent-harness-runtime","exportName":"resolveActiveEmbeddedRunSessionId","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} @@ -197,7 +197,7 @@ {"closureHash":"da8b724c5858691b8a1c71c63294a397631c031270db92fdff9ef4493efa2492","declaration":"export function runAgentHarnessBeforeAgentFinalizeHook(params: { event: PluginHookBeforeAgentFinalizeEvent; ctx: AgentHarnessHookContext; hookRunner?: AgentHarnessHookRunner; }): Promise;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessBeforeAgentFinalizeHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"8fec73ee8c7c9be3335bd6dc1bac9278f0be5beef22a5975eb06e56f504f4bd6","declaration":"export function runAgentHarnessBeforeCompactionHook(params: { sessionFile: string; messages?: AgentMessage[]; ctx: AgentHarnessHookContext; }): Promise;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessBeforeCompactionHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"021b81820bef2e8d54c50a5fc159d6665b23b50a1f5c40dae76a4833839d89c9","declaration":"export function runAgentHarnessBeforeMessageWriteHook(params: { message: AgentMessage; agentId?: string; sessionKey?: string; }): AgentMessage | null;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessBeforeMessageWriteHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} -{"closureHash":"ff9330bc49a836f3f5352bed2fc22674f86b01c9549129afc83d2512f9bc0a6f","declaration":"export function runAgentHarnessGatewayQuestion(params: RunAgentHarnessGatewayQuestionParams): Promise;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessGatewayQuestion","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} +{"closureHash":"bcfb1bce24242c23fb782fa69d48b2e28848e5ec4b5919970c35ee73c4a16f79","declaration":"export function runAgentHarnessGatewayQuestion(params: RunAgentHarnessGatewayQuestionParams): Promise;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessGatewayQuestion","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"89aa32c12a44b446777bc4cfbb106a048dd9cbc668260525798a895a433256f4","declaration":"export function runAgentHarnessLlmInputHook(params: { event: PluginHookLlmInputEvent; ctx: AgentHarnessHookContext; hookRunner?: AgentHarnessHookRunner; }): void;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessLlmInputHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"ba63f9cdd34249fba984af87a039494b75b3f93c0c70b925e884f3f98935b984","declaration":"export function runAgentHarnessLlmOutputHook(params: { event: PluginHookLlmOutputEvent; ctx: AgentHarnessHookContext; hookRunner?: AgentHarnessHookRunner; }): void;","entrypoint":"agent-harness-runtime","exportName":"runAgentHarnessLlmOutputHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} {"closureHash":"c4c5131ab7065decd8d8e935ac3779e3baa2c52fbbbd95a6ccb624377db09ca1","declaration":"export function runBeforeToolCallHook(args: { toolName: string; params: unknown; toolKind?: PluginHookToolKind; toolInputKind?: PluginHookToolInputKind; toolCallId?: string; ctx?: HookContext; signal?: AbortSignal; approvalMode?: \"request\" | \"report\" | \"deny\" | \"defer\"; }): Promise;","entrypoint":"agent-harness-runtime","exportName":"runBeforeToolCallHook","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"function","recordType":"export"} @@ -219,13 +219,13 @@ {"closureHash":"0701a22057edc3b733da7e05948db94aa98b337b224a5718efdd85212a8602bf","declaration":"export const TRANSCRIPT_CREDENTIAL_SAFETY_PROMPT: string;","entrypoint":"agent-harness-runtime","exportName":"TRANSCRIPT_CREDENTIAL_SAFETY_PROMPT","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"} {"closureHash":"b5845c99df6c2a834a16678c320e0111bad96a3a7ac245d379aa5e6d2555d29b","declaration":"export const agentHarnessAttemptTerminal: { merge: (current: AgentRunAttemptTerminal, incoming: AgentRunAttemptTerminal) => AgentRunAttemptTerminal; normalize: (input: { aborted?: boolean; externalAbort?: boolean; idleTimedOut?: boolean; promptError?: unknown; promptErrorSource?: AgentRunAttemptFailureSource | null; timedOut?: boolean; timedOutByRunBudget?: boolean; timedOutDuringCompaction?: boolean; timedOutDuringToolExecution?: boolean; }) => AgentRunAttemptTerminal; project: (terminal: AgentRunAttemptTerminal) => { aborted: boolean; cleanupYieldAborted: boolean; externalAbort: boolean; failed: boolean; idleTimedOut: boolean; interrupted: boolean; promptError: unknown; promptErrorSource: AgentRunAttemptFailureSource | null; timedOut: boolean; timedOutByRunBudget: boolean; timedOutDuringCompaction: boolean; timedOutDuringToolExecution: boolean; }; setFailure: (terminal: AgentRunAttemptTerminal, failure: { source: AgentRunAttemptFailureSource; error: unknown; } | null) => AgentRunAttemptTerminal;};","entrypoint":"agent-harness-runtime","exportName":"agentHarnessAttemptTerminal","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"} {"closureHash":"22bcf962aa76c76074c4ed4ad7d6558edbc3588e239263e09af74c1000bbe012","declaration":"export const embeddedAgentLog: SubsystemLogger;","entrypoint":"agent-harness-runtime","exportName":"embeddedAgentLog","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"} -{"closureHash":"1c921ea213065b01824edf3fe2a177ef5b511e25fb28f93c024405a39645f112","declaration":"export const nativeHookRelayTesting: { readonly clearNativeHookRelaysForTests: () => void; readonly getNativeHookRelayInvocationsForTests: () => NativeHookRelayInvocation[]; readonly getNativeHookRelayRegistrationForTests: (relayId: string) => NativeHookRelayRegistration | undefined; readonly getNativeHookRelayBridgeDirForTests: () => string; readonly getNativeHookRelayBridgeRegistryPathForTests: (relayId: string) => string; readonly getNativeHookRelayBridgeRecordForTests: (relayId: string) => Record | undefined; readonly isNativeHookRelayBridgeLookupRetryableForTests: (error: unknown, elapsedMs?: number) => boolean; readonly formatPermissionApprovalDescriptionForTests: (request: NativeHookRelayPermissionApprovalRequest) => string; readonly permissionRequestContentFingerprintForTests: (request: NativeHookRelayPermissionApprovalRequest) => string; readonly permissionRequestToolInputKeyFingerprintForTests: (toolInput: Record) => string; readonly setNativeHookRelayPermissionApprovalRequesterForTests: (requester: NativeHookRelayPermissionApprovalRequester) => void; readonly setNativeHookRelayDeferredToolApprovalRequesterForTests: (requester: NativeHookRelayDeferredToolApprovalRequester) => void;};","entrypoint":"agent-harness-runtime","exportName":"nativeHookRelayTesting","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"} +{"closureHash":"f43a42fbb491ae9478132011d83adb11bce65902af30cde90b195ee3e0219803","declaration":"export const nativeHookRelayTesting: { readonly clearNativeHookRelaysForTests: () => void; readonly getNativeHookRelayInvocationsForTests: () => NativeHookRelayInvocation[]; readonly getNativeHookRelayRegistrationForTests: (relayId: string) => NativeHookRelayRegistration | undefined; readonly getNativeHookRelayBridgeDirForTests: () => string; readonly getNativeHookRelayBridgeRegistryPathForTests: (relayId: string) => string; readonly getNativeHookRelayBridgeRecordForTests: (relayId: string) => Record | undefined; readonly isNativeHookRelayBridgeLookupRetryableForTests: (error: unknown, elapsedMs?: number) => boolean; readonly formatPermissionApprovalDescriptionForTests: (request: NativeHookRelayPermissionApprovalRequest) => string; readonly permissionRequestContentFingerprintForTests: (request: NativeHookRelayPermissionApprovalRequest) => string; readonly permissionRequestToolInputKeyFingerprintForTests: (toolInput: Record) => string; readonly setNativeHookRelayPermissionApprovalRequesterForTests: (requester: NativeHookRelayPermissionApprovalRequester) => void; readonly setNativeHookRelayDeferredToolApprovalRequesterForTests: (requester: NativeHookRelayDeferredToolApprovalRequester) => void;};","entrypoint":"agent-harness-runtime","exportName":"nativeHookRelayTesting","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"const","recordType":"export"} {"closureHash":"f237bbc11e1d389679cd4e2ad7aa9055951b3029348e3374b81f769786a51d55","declaration":"export type AbortAndDrainAgentHarnessRunResult = AbortAndDrainEmbeddedAgentRunResult;","entrypoint":"agent-harness-runtime","exportName":"AbortAndDrainAgentHarnessRunResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"6f802f46717d28d260bbcb2cf4790dfed4e9ab28c4fe822d259228189cca4665","declaration":"export type AgentApprovalEventData = AgentApprovalEventData;","entrypoint":"agent-harness-runtime","exportName":"AgentApprovalEventData","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"12aac3a57ce200b0f082002be237625729f84ed7c337f1bac90bcd0688a53319","declaration":"export type AgentEventPayload = AgentEventPayload;","entrypoint":"agent-harness-runtime","exportName":"AgentEventPayload","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} -{"closureHash":"dad048707e7e780a56529d7567a4d10fe081bd472786db796cd423e7c204ce6d","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness-runtime","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} -{"closureHash":"dad048707e7e780a56529d7567a4d10fe081bd472786db796cd423e7c204ce6d","declaration":"export type AgentHarnessAttemptParams = AgentHarnessAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} -{"closureHash":"f76b92687d446d08a94613e1f3554417e759cf343b0eaba22ce439036e42e735","declaration":"export type AgentHarnessAttemptParamsV2 = AgentHarnessAttemptParamsV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} +{"closureHash":"b467021581907cc4f2f8266283b147425febfe5d96c596dd00bc42ad5b9c6cac","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"agent-harness-runtime","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} +{"closureHash":"b467021581907cc4f2f8266283b147425febfe5d96c596dd00bc42ad5b9c6cac","declaration":"export type AgentHarnessAttemptParams = AgentHarnessAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} +{"closureHash":"b1ff8347a4cfae13af0e7bd3be92efb11a7dde83d42154db9f7b34004b8e8346","declaration":"export type AgentHarnessAttemptParamsV2 = AgentHarnessAttemptParamsV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"2dc2a62deea63b316142cc28d40afb88fb0d1e5ce3e048f141420726cda38248","declaration":"export type AgentHarnessAttemptResult = AgentHarnessAttemptResult;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAttemptResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"c7e642234081160830fd9e18a301900f8ee1ea8c88382e5a286f0102de65b714","declaration":"export type AgentHarnessAuthBindingFingerprintParams = AgentHarnessAuthBindingFingerprintParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessAuthBindingFingerprintParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"06b71bd1e13e23c83573c7c50a0ea47e2634060ae895d66171d80b466d64b315","declaration":"export type AgentHarnessCompactParams = CompactEmbeddedAgentSessionParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessCompactParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} @@ -239,8 +239,8 @@ {"closureHash":"95741b872a194687696eba4a96d6e887ec6e81922695fa0282cb2f0a46ff9f97","declaration":"export type AgentHarnessSessionForkParams = AgentHarnessSessionForkParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSessionForkParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"f3c46fef2a6c3393b0b6ad09915abcd6f57bb58ddddde1d60ebd113c7a1c5fa6","declaration":"export type AgentHarnessSessionForkResult = AgentHarnessSessionForkResult;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSessionForkResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"4b5a59730309e446f59a8ec1c554c3193aca1959916594cc657347098bd67a35","declaration":"export type AgentHarnessSettledTurnFinalizationResult = AgentHarnessSettledTurnFinalizationResult;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSettledTurnFinalizationResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} -{"closureHash":"8184161eb6328910c68b03bdb5ef6f2bd212269a8d64c267e73038da473b313b","declaration":"export type AgentHarnessSideQuestionParams = AgentHarnessSideQuestionParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} -{"closureHash":"8786d4d3d5c0758d6a6b6142947a46736e1b7405a9d368dfd2f56d0217143879","declaration":"export type AgentHarnessSideQuestionParamsV2 = AgentHarnessSideQuestionParamsV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} +{"closureHash":"c6cd22e63ce00e0fb45726980797f751cd464da35afe6404991c92443c855d35","declaration":"export type AgentHarnessSideQuestionParams = AgentHarnessSideQuestionParams;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} +{"closureHash":"4f5433cd58d35185fddd5cba3967f0d20257fffc27fbeb15deda02dfb9274d16","declaration":"export type AgentHarnessSideQuestionParamsV2 = AgentHarnessSideQuestionParamsV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"e84173055503c40dd0ef1cb67c6d333e9257fcf995252b27c1d58f5c904e8de9","declaration":"export type AgentHarnessSideQuestionResult = AgentHarnessSideQuestionResult;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSideQuestionResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"50214d08dac98e3c1031ac7bc733b85cb2247d2eef3b6b2045758ae403af7647","declaration":"export type AgentHarnessSupport = AgentHarnessSupport;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSupport","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"50ce26ea22bc225e6064d2e5f37356b6f4ce4a57f8b9fa42baa4c421da48aad5","declaration":"export type AgentHarnessSupportContext = AgentHarnessSupportContext;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessSupportContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} @@ -250,7 +250,7 @@ {"closureHash":"20a8a7c9d5ebf425c30d04eea3856c6c889a210f1fa53c99299df24882afbf92","declaration":"export type AgentHarnessUserInputOption = AgentHarnessUserInputOption;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessUserInputOption","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"6224f51b4189f10a642ad7a8f50a902ec9c6a6a4f8dac0c0de5f7bc0271a27e5","declaration":"export type AgentHarnessUserInputPromptOptions = AgentHarnessUserInputPromptOptions;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessUserInputPromptOptions","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"d8f1d0d118e1536d1f442d11aeae5334a1ed7949a6c61824f547e12931278e1d","declaration":"export type AgentHarnessUserInputQuestion = AgentHarnessUserInputQuestion;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessUserInputQuestion","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} -{"closureHash":"a0cb9cfd5f486fba8b684f5724417c3ded806072d0a9d09b95b6fb44f10d169f","declaration":"export type AgentHarnessV2 = AgentHarnessV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} +{"closureHash":"ab44fb6980e5f0715662f663ee705ee609e0dc13d7bb57e56e89e14610cc7cd5","declaration":"export type AgentHarnessV2 = AgentHarnessV2;","entrypoint":"agent-harness-runtime","exportName":"AgentHarnessV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"6f2af683e6a31cde5a473c77e4f03b8f0ec0351a43ea6c0af979d5b394a33f95","declaration":"export type AgentMessage = AgentMessage;","entrypoint":"agent-harness-runtime","exportName":"AgentMessage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"4ad0f830bf11a2db48faefb1439b7fbb08d9f22d22083f5e301327e1696f2310","declaration":"export type AgentToolResultMiddleware = AgentToolResultMiddleware;","entrypoint":"agent-harness-runtime","exportName":"AgentToolResultMiddleware","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"185abd2870d4df65e9f94623061a30167d17ef1279a395201fe429398bf23500","declaration":"export type AgentToolResultMiddlewareContext = AgentToolResultMiddlewareContext;","entrypoint":"agent-harness-runtime","exportName":"AgentToolResultMiddlewareContext","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} @@ -276,8 +276,8 @@ {"closureHash":"f30b66fd82f4cd61c60880c42a3b8f152ca64a2216036c99ab4129648ed329e7","declaration":"export type EmbeddedAgentCompactResult = EmbeddedAgentCompactResult;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedAgentCompactResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"1bbefad0193436f7340f9d0dec50be5d482973325c3c65170b1053dd05566f0a","declaration":"export type EmbeddedContextFile = EmbeddedContextFile;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedContextFile","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"f30b66fd82f4cd61c60880c42a3b8f152ca64a2216036c99ab4129648ed329e7","declaration":"export type EmbeddedPiCompactResult = EmbeddedAgentCompactResult;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedPiCompactResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} -{"closureHash":"f1fdf2a77b0374b4a030f9ea4f070fee1ffc6e1b0302950ebfafc0d2686565dd","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} -{"closureHash":"f6b266b995d12169f22f438feec586e7e8fc9723eb9b0bf730864366ccc63229","declaration":"export type EmbeddedRunAttemptParamsV2 = EmbeddedRunAttemptParamsV2;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} +{"closureHash":"aefdbc51192417d04c2d734f27129dedc25a46521cc324e66e26827a17aaed68","declaration":"export type EmbeddedRunAttemptParams = EmbeddedRunAttemptParams;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParams","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} +{"closureHash":"10d9c3d733e1b03bbf485c7590401a5b4382e600f9bf56667352d6ed0efe2b66","declaration":"export type EmbeddedRunAttemptParamsV2 = EmbeddedRunAttemptParamsV2;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptParamsV2","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"a6cd2eebe0d06e6578ec8438a207c5acda10ddf01041102d84e4c576a0b6a42f","declaration":"export type EmbeddedRunAttemptResult = EmbeddedRunAttemptResult;","entrypoint":"agent-harness-runtime","exportName":"EmbeddedRunAttemptResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"f6cb2d6411db22cb04220777720d97bcca977351de1cb344ce2ff6ab126a3a08","declaration":"export type ExecApprovalDecision = ExecApprovalDecision;","entrypoint":"agent-harness-runtime","exportName":"ExecApprovalDecision","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"7acb0dffc7bcda6c727e4afc49c955fa8e14f4f8b7b45d197ed794dfa0d73b8e","declaration":"export type ExecAutoReviewDecision = ExecAutoReviewDecision;","entrypoint":"agent-harness-runtime","exportName":"ExecAutoReviewDecision","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} @@ -293,7 +293,7 @@ {"closureHash":"d8a720bf250da8daf4dc6a52087aa8728ec33b650b3ad3906fcb40e184de66a0","declaration":"export type NativeHookRelayEvent = \"pre_tool_use\" | \"post_tool_use\" | \"permission_request\" | \"before_agent_finalize\";","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayEvent","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"cb72ca18e056e52e779d0bf5b67606e1dc160f225225b55937304541105027f4","declaration":"export type NativeHookRelayProcessResponse = NativeHookRelayProcessResponse;","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayProcessResponse","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"6ee390ae4784b987e22255c16884fb4171033bbfaefaef655e3dd2a2513814a5","declaration":"export type NativeHookRelayProvider = \"codex\";","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayProvider","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} -{"closureHash":"b0ce2610db663c1af26f251a5e92271d8e8b22b59871640e2b8c1fbe4b0a2ed4","declaration":"export type NativeHookRelayRegistrationHandle = NativeHookRelayRegistrationHandle;","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayRegistrationHandle","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} +{"closureHash":"8c459592602a04783b19409aef9ef8df4ac3586a4a872770025b2f396468046f","declaration":"export type NativeHookRelayRegistrationHandle = NativeHookRelayRegistrationHandle;","entrypoint":"agent-harness-runtime","exportName":"NativeHookRelayRegistrationHandle","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"90fea3155b5d32c22da90460fdaea94e4fd6895d1ca18613d5036ba9835153f9","declaration":"export type NodeListNode = NodeListNode;","entrypoint":"agent-harness-runtime","exportName":"NodeListNode","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"cefe1325c866f0cf7edbec5dcca2fe420237eedc0da172e54094e365894d205d","declaration":"export type NormalizedUsage = NormalizedUsage;","entrypoint":"agent-harness-runtime","exportName":"NormalizedUsage","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} {"closureHash":"25c6985c3bef2c6efc6a96e70af6d66fe073be0b0d311681cfc0dfc186528d9a","declaration":"export type OpenClawAgentToolResult = OpenClawAgentToolResult;","entrypoint":"agent-harness-runtime","exportName":"OpenClawAgentToolResult","importSpecifier":"openclaw/plugin-sdk/agent-harness-runtime","kind":"type","recordType":"export"} @@ -762,7 +762,7 @@ {"closureHash":"9fc7e45343d7bfbc6ed56d05c9f824e2f9cf6dafc3ca4b25437d1f65c2200727","declaration":"export function clearAccountEntryFields(params: { accounts?: Record; accountId: string; fields: string[]; isValueSet?: (value: unknown) => boolean; markClearedOnFieldPresence?: boolean; }): { nextAccounts?: Record; changed: boolean; cleared: boolean; };","entrypoint":"channel-core","exportName":"clearAccountEntryFields","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"} {"closureHash":"f4e084b64b5376268885a73fe507aa5d72bee17a88ec2d7ae1d19b36ea5f1ccb","declaration":"export function createChannelConfigUiHints(params: { channelLabel: string; dmPolicy?: { channelKey: string; includeLegacyNestedPolicy?: boolean; legacyNestedPolicyOrder?: \"before\" | \"after\"; }; configWrites?: boolean; mentionPatterns?: { targetDescription: string; policyTargetDescription?: string; policyNote?: string; denyNote?: string; }; nativeCommands?: boolean; implicitMentions?: boolean; progress?: { includeCommentary?: boolean; commentaryOrder?: \"before-command\" | \"after-command\"; labels?: \"openclaw\"; titleWording?: boolean; }; streaming?: Partial>; retry?: boolean; }): HintMap;","entrypoint":"channel-core","exportName":"createChannelConfigUiHints","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"} {"closureHash":"1010c88a3eaa05d4c2fceaa97b5d58b437cc426a13a8a175da9e2d1dc1335ac0","declaration":"export function createChatChannelPlugin(params: { base: ChatChannelPluginBase; security?: ChannelSecurityAdapter | ChatChannelSecurityOptions; pairing?: ChannelPairingAdapter | ChatChannelPairingOptions; threading?: ChannelThreadingAdapter | ChatChannelThreadingOptions; outbound?: ChannelOutboundAdapter | ChatChannelAttachedOutboundOptions; }): ChannelPlugin;","entrypoint":"channel-core","exportName":"createChatChannelPlugin","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"} -{"closureHash":"036c8a7268d64e4861bec206709236d906d1b0708870d98139f3948e7500f069","declaration":"export function defineChannelPluginEntry({ id, name, description, plugin, configSchema, setRuntime, registerCliMetadata, registerFull, registerCapabilities, }: DefineChannelPluginEntryOptions): DefinedChannelPluginEntry;","entrypoint":"channel-core","exportName":"defineChannelPluginEntry","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"} +{"closureHash":"9a492cc57372852a29d2c1edbb3c269d6fd02bae2ba0879cddb90b4fd5fe3398","declaration":"export function defineChannelPluginEntry({ id, name, description, plugin, configSchema, setRuntime, registerCliMetadata, registerFull, registerCapabilities, }: DefineChannelPluginEntryOptions): DefinedChannelPluginEntry;","entrypoint":"channel-core","exportName":"defineChannelPluginEntry","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"} {"closureHash":"0e0a9f6b22c433bdb1165e7707b1f9a1ddac1a544a8add00b503048cf157921f","declaration":"export function defineSetupPluginEntry(plugin: TPlugin): { plugin: TPlugin; };","entrypoint":"channel-core","exportName":"defineSetupPluginEntry","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"} {"closureHash":"8895f7af11b994dcd383ebc45d8cfb3c3b1e6d88a64a001b04f604a83f77e517","declaration":"export function parseOptionalDelimitedEntries(value?: string): string[] | undefined;","entrypoint":"channel-core","exportName":"parseOptionalDelimitedEntries","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"} {"closureHash":"3f97534b10d08eda6a556044eaba623b3744b200a2033877e48d2f2ca924d298","declaration":"export function recoverCurrentThreadSessionId(params: { route: ChannelOutboundSessionRoute; currentSessionKey?: string | null; canRecover?: (context: ThreadAwareOutboundSessionRouteRecoveryContext) => boolean; }): string | undefined;","entrypoint":"channel-core","exportName":"recoverCurrentThreadSessionId","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"function","recordType":"export"} @@ -774,24 +774,24 @@ {"closureHash":"8126b651a679d5435eaa5d346916792c3600e5f0f75d8492b077dd361854f7dd","declaration":"export type ChannelOutboundSessionRouteParams = { cfg: OpenClawConfig; agentId: string; accountId?: string | null; target: string; currentSessionKey?: string; resolvedTarget?: { to: string; kind: ChannelDirectoryEntryKind | \"channel\"; display?: string; source: \"normalized\" | \"directory\"; }; replyToId?: string | null; threadId?: string | number | null;};","entrypoint":"channel-core","exportName":"ChannelOutboundSessionRouteParams","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"} {"closureHash":"c896b30eefde9cf194ca8e3ef307206d2ff53922957dbbbd5572b8f211eef58d","declaration":"export type ChannelPlugin = ChannelPlugin;","entrypoint":"channel-core","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"} {"closureHash":"8054ffbe71b91afced900ef8a06f5e368ac10c4f99ffc1c6f538a802856f61c6","declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"channel-core","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"} -{"closureHash":"b8cfd4298333de90ef689017e70615b435c9076ad466ceae6f46ebc70a67f867","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"} +{"closureHash":"0860813ffb138d3dd703ab9b607c758cd9b365512a67483d1f6b8b010775cd41","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"} {"closureHash":"aac070e9a0df4c3621b12f27426c2caccf3a83458ac98261726005c8ffb311ac","declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"channel-core","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"} {"closureHash":"5d22b1a044dc147e7eef60f1c06347cab8f4e88383adfa92fec5e1a1076ab145","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"channel-core","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/channel-core","kind":"type","recordType":"export"} {"category":"channel","entrypoint":"channel-dm-policy","importSpecifier":"openclaw/plugin-sdk/channel-dm-policy","recordType":"module"} {"closureHash":"821fe6ccd0d9323322bf70c4d1ca5697071a0e32032f44c1e14157162c2c729d","declaration":"export function createChannelDmPolicy(params: CreateChannelDmPolicyParams): ChannelSetupDmPolicy & { promptAllowFrom: NonNullable; };","entrypoint":"channel-dm-policy","exportName":"createChannelDmPolicy","importSpecifier":"openclaw/plugin-sdk/channel-dm-policy","kind":"function","recordType":"export"} {"category":null,"entrypoint":"channel-entry-contract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","recordType":"module"} -{"closureHash":"0ad2b0bf194c8736c60089d876c967bebd0b2cfd8b66cabc35ec74fb3bcd7fe6","declaration":"export function defineBundledChannelEntry({ id, name, description, importMetaUrl, plugin, outbound, secrets, configSchema, runtime, accountInspect, features, registerCliMetadata, registerFull, registerCapabilities, }: DefineBundledChannelEntryOptions): BundledChannelEntryContract;","entrypoint":"channel-entry-contract","exportName":"defineBundledChannelEntry","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"} -{"closureHash":"2f00e19dbafd8e8484b1f59595620fa5bcbc698201b0ac27defd4e5cb3be8884","declaration":"export function defineBundledChannelSetupEntry({ importMetaUrl, plugin, secrets, runtime, legacyStateMigrations, legacySessionSurface, registerSetupRuntime, features, }: DefineBundledChannelSetupEntryOptions): BundledChannelSetupEntryContract;","entrypoint":"channel-entry-contract","exportName":"defineBundledChannelSetupEntry","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"} +{"closureHash":"8cda1ffcca2600619e8dbeefbb0cfd4ebd983054fdd85de807b197021aeb2005","declaration":"export function defineBundledChannelEntry({ id, name, description, importMetaUrl, plugin, outbound, secrets, configSchema, runtime, accountInspect, features, registerCliMetadata, registerFull, registerCapabilities, }: DefineBundledChannelEntryOptions): BundledChannelEntryContract;","entrypoint":"channel-entry-contract","exportName":"defineBundledChannelEntry","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"} +{"closureHash":"556bb31da6f76620954ccc8c610def33476707df07b3f42af9f0ea089b46adf2","declaration":"export function defineBundledChannelSetupEntry({ importMetaUrl, plugin, secrets, runtime, legacyStateMigrations, legacySessionSurface, registerSetupRuntime, features, }: DefineBundledChannelSetupEntryOptions): BundledChannelSetupEntryContract;","entrypoint":"channel-entry-contract","exportName":"defineBundledChannelSetupEntry","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"} {"closureHash":"cd150287d7e286e7a0d7d6caeb05d0a1efa63b5f351f75f69ba932510a108afd","declaration":"export function loadBundledEntryExportSync(importMetaUrl: string, reference: BundledEntryModuleRef, options?: BundledEntryModuleLoadOptions): T;","entrypoint":"channel-entry-contract","exportName":"loadBundledEntryExportSync","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"function","recordType":"export"} {"closureHash":"7781a3d570d08929af5b3b6cffbb9ef4b9c8e8f1bed55234e0015a681868c812","declaration":"export type AnyAgentTool = AnyAgentTool;","entrypoint":"channel-entry-contract","exportName":"AnyAgentTool","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} -{"closureHash":"a934ffcac1867430c0e0a4779b1e204cd9f4931c7c84f8e5060434c11cbbf087","declaration":"export type BundledChannelEntryContract = BundledChannelEntryContract;","entrypoint":"channel-entry-contract","exportName":"BundledChannelEntryContract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} +{"closureHash":"43db19df80cdcad45b233f44fea817a082ad4bfeb55df17dcc2fa190f5b6385d","declaration":"export type BundledChannelEntryContract = BundledChannelEntryContract;","entrypoint":"channel-entry-contract","exportName":"BundledChannelEntryContract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} {"closureHash":"f4b82dfd995bd6f08b232984743389d1c854866cb845a8dbb3605acb28818688","declaration":"export type BundledChannelEntryFeatures = BundledChannelEntryFeatures;","entrypoint":"channel-entry-contract","exportName":"BundledChannelEntryFeatures","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} {"closureHash":"960693591b9bdc974bf3f0097076d90490078db3dceb35349a4f851736cde4fc","declaration":"export type BundledChannelLegacySessionSurface = BundledChannelLegacySessionSurface;","entrypoint":"channel-entry-contract","exportName":"BundledChannelLegacySessionSurface","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} {"closureHash":"edf79e6a736e5c4977e3b86ef21e7fdf0c0b2bc7deacd8edbee2ca76cb8cef43","declaration":"export type BundledChannelLegacyStateMigrationDetector = BundledChannelLegacyStateMigrationDetector;","entrypoint":"channel-entry-contract","exportName":"BundledChannelLegacyStateMigrationDetector","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} -{"closureHash":"4519b793842bf95441c36ef0e63c7982a2faa568245bac4c35948c6d66d95240","declaration":"export type BundledChannelSetupEntryContract = BundledChannelSetupEntryContract;","entrypoint":"channel-entry-contract","exportName":"BundledChannelSetupEntryContract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} +{"closureHash":"7c807f1a5efb66fa93a46e252c30592233d41915b06a0494da8e5cedab518110","declaration":"export type BundledChannelSetupEntryContract = BundledChannelSetupEntryContract;","entrypoint":"channel-entry-contract","exportName":"BundledChannelSetupEntryContract","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} {"closureHash":"24679ecdf2ff34157b6345a37b58ec1363ec8cb1969b522599d0d92bb7a113b7","declaration":"export type BundledChannelSetupEntryFeatures = BundledChannelSetupEntryFeatures;","entrypoint":"channel-entry-contract","exportName":"BundledChannelSetupEntryFeatures","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} {"closureHash":"367219c821915e5be4d1ba3a86754475a5f8a4194512f0401de3be11cc649c60","declaration":"export type BundledEntryModuleLoadOptions = BundledEntryModuleLoadOptions;","entrypoint":"channel-entry-contract","exportName":"BundledEntryModuleLoadOptions","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} -{"closureHash":"6d0dfdda00d8250b2586ea66d428dfeddb13256d9e8650d7ef63ff1e2b3ae8cf","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-entry-contract","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} +{"closureHash":"bafb23ff5dc51ed148171694eb8b2a47738386c12ee3efc6badde00cf6201aaf","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-entry-contract","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} {"closureHash":"42c4d242826c5c12b543ddb1a312de11ebfa0208fe77bc01ac36af6d2bf36f14","declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"channel-entry-contract","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} {"closureHash":"6f006c41d66e65636985a8ecf94d378e8f8778cf5200a6bda440265b52f6db2a","declaration":"export type PluginCommandContext = PluginCommandContext;","entrypoint":"channel-entry-contract","exportName":"PluginCommandContext","importSpecifier":"openclaw/plugin-sdk/channel-entry-contract","kind":"type","recordType":"export"} {"category":null,"entrypoint":"channel-feedback","importSpecifier":"openclaw/plugin-sdk/channel-feedback","recordType":"module"} @@ -862,7 +862,7 @@ {"closureHash":"6b537112d5d84ed07c0b9fd24787eabc2f893f7bfdce1ed5915f88574a7e101c","declaration":"export function normalizeMentionText(text: string): string;","entrypoint":"channel-inbound","exportName":"normalizeMentionText","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"} {"closureHash":"92900098c3cc5b73fba7622a3aa5a1a8c48462ff7ec0cfae8ee0a3aa6f8277f0","declaration":"export function normalizeOutboundLocation(value: unknown, label?: string): OutboundLocation | undefined;","entrypoint":"channel-inbound","exportName":"normalizeOutboundLocation","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"} {"closureHash":"65f5f2725c1124096e437bcf5894983eee1023f7033be886f1a506044b77c58e","declaration":"export function recordChannelBotPairLoopAndCheckSuppression(params: ChannelBotLoopProtectionFacts): PairLoopGuardResult;","entrypoint":"channel-inbound","exportName":"recordChannelBotPairLoopAndCheckSuppression","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"} -{"closureHash":"7fe36693b2f7be000dd738335a3ac887e58d9904623985193f0e9d95380010d0","declaration":"export function recordChannelFeedbackEvent(params: { cfg: OpenClawConfig; agentId: string; sessionKey: string; event: Parameters[1]; }): Promise;","entrypoint":"channel-inbound","exportName":"recordChannelFeedbackEvent","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"} +{"closureHash":"8e414b58a0c2883599ffba7825ba68691288024b6fd3da59bb53204c93de878a","declaration":"export function recordChannelFeedbackEvent(params: { cfg: OpenClawConfig; agentId: string; sessionKey: string; event: Parameters[1]; }): Promise;","entrypoint":"channel-inbound","exportName":"recordChannelFeedbackEvent","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"} {"closureHash":"33b4280a69de6a4a87acf915c6d694b9ee41fc4f0262a1bb9836c46d53fe337c","declaration":"export function recordDroppedChannelInboundHistory(params: { input: NormalizedTurnInput; preflight: PreflightFacts; admission?: ChannelTurnAdmission; }): Promise;","entrypoint":"channel-inbound","exportName":"recordDroppedChannelInboundHistory","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"} {"closureHash":"33b4280a69de6a4a87acf915c6d694b9ee41fc4f0262a1bb9836c46d53fe337c","declaration":"export function recordDroppedChannelTurnHistory(params: { input: NormalizedTurnInput; preflight: PreflightFacts; admission?: ChannelTurnAdmission; }): Promise;","entrypoint":"channel-inbound","exportName":"recordDroppedChannelTurnHistory","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"} {"closureHash":"54b920fd80ac659a03000356b64e34d4a44ec22ae39a77accdd2ac97dc5a094e","declaration":"export function resolveChannelInboundRouteEnvelope(params: ResolveAgentRouteInput): { route: ResolvedAgentRoute; buildEnvelope: (input: ChannelInboundEnvelopeInput) => string; };","entrypoint":"channel-inbound","exportName":"resolveChannelInboundRouteEnvelope","importSpecifier":"openclaw/plugin-sdk/channel-inbound","kind":"function","recordType":"export"} @@ -1103,7 +1103,7 @@ {"closureHash":"9555a73ba2717bba0bf94888017be4cecef2c51cc3887ed34f8d8ef3c79d6abf","declaration":"export const DEFAULT_INGRESS_RETRY_DEAD_LETTER_MIN_AGE_MS: number;","entrypoint":"channel-message","exportName":"DEFAULT_INGRESS_RETRY_DEAD_LETTER_MIN_AGE_MS","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"} {"closureHash":"3a2df3ab656149630c004d2d9f71b8ceda99aa81eb6b72b0cc7b3982ed0ce044","declaration":"export const DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS: 8;","entrypoint":"channel-message","exportName":"DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"} {"closureHash":"38c735a14c65067aa7825390d1c5c8876c651d0603e84980dfaf947f5235747a","declaration":"export const INGRESS_CLAIM_PROCESS_ID: string;","entrypoint":"channel-message","exportName":"INGRESS_CLAIM_PROCESS_ID","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"} -{"closureHash":"5ff0f125fd0b55bfbef9991b21c1d34355eace44d5c49377e49643696fa0e636","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"channel-message","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"} +{"closureHash":"42768704540ab252d894266885fa71ac4c3b20e3dcfeb2f32942e7953be11d2c","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"channel-message","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"const","recordType":"export"} {"closureHash":"2c52eff200a5b9bd2d93ee72209c2626bbe165f59b538591db661b94773023b0","declaration":"export type AgentPlanStep = AgentPlanStep;","entrypoint":"channel-message","exportName":"AgentPlanStep","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"type","recordType":"export"} {"closureHash":"1e8bcb2c8d8f5327f5b81b8c217f722f090dccba21ba3943324010f4f80a5a50","declaration":"export type AgentPlanStepStatus = AgentPlanStepStatus;","entrypoint":"channel-message","exportName":"AgentPlanStepStatus","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"type","recordType":"export"} {"closureHash":"b036fc26e5330dfd7da1af8839bb3c23e85283b9e16e252a659dd4bb0c35cd5e","declaration":"export type ChannelDeliveryStreamingConfig = ChannelDeliveryStreamingConfig;","entrypoint":"channel-message","exportName":"ChannelDeliveryStreamingConfig","importSpecifier":"openclaw/plugin-sdk/channel-message","kind":"type","recordType":"export"} @@ -1232,7 +1232,7 @@ {"closureHash":"9555a73ba2717bba0bf94888017be4cecef2c51cc3887ed34f8d8ef3c79d6abf","declaration":"export const DEFAULT_INGRESS_RETRY_DEAD_LETTER_MIN_AGE_MS: number;","entrypoint":"channel-outbound","exportName":"DEFAULT_INGRESS_RETRY_DEAD_LETTER_MIN_AGE_MS","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"} {"closureHash":"3a2df3ab656149630c004d2d9f71b8ceda99aa81eb6b72b0cc7b3982ed0ce044","declaration":"export const DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS: 8;","entrypoint":"channel-outbound","exportName":"DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"} {"closureHash":"38c735a14c65067aa7825390d1c5c8876c651d0603e84980dfaf947f5235747a","declaration":"export const INGRESS_CLAIM_PROCESS_ID: string;","entrypoint":"channel-outbound","exportName":"INGRESS_CLAIM_PROCESS_ID","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"} -{"closureHash":"5ff0f125fd0b55bfbef9991b21c1d34355eace44d5c49377e49643696fa0e636","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"channel-outbound","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"} +{"closureHash":"42768704540ab252d894266885fa71ac4c3b20e3dcfeb2f32942e7953be11d2c","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"channel-outbound","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"const","recordType":"export"} {"closureHash":"2c52eff200a5b9bd2d93ee72209c2626bbe165f59b538591db661b94773023b0","declaration":"export type AgentPlanStep = AgentPlanStep;","entrypoint":"channel-outbound","exportName":"AgentPlanStep","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"type","recordType":"export"} {"closureHash":"1e8bcb2c8d8f5327f5b81b8c217f722f090dccba21ba3943324010f4f80a5a50","declaration":"export type AgentPlanStepStatus = AgentPlanStepStatus;","entrypoint":"channel-outbound","exportName":"AgentPlanStepStatus","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"type","recordType":"export"} {"closureHash":"b036fc26e5330dfd7da1af8839bb3c23e85283b9e16e252a659dd4bb0c35cd5e","declaration":"export type ChannelDeliveryStreamingConfig = ChannelDeliveryStreamingConfig;","entrypoint":"channel-outbound","exportName":"ChannelDeliveryStreamingConfig","importSpecifier":"openclaw/plugin-sdk/channel-outbound","kind":"type","recordType":"export"} @@ -1298,7 +1298,7 @@ {"closureHash":"cd6b0d3f962c8cb40d405e92bb06bb8e9285b386200897f550d21036022262c1","declaration":"export const PAIRING_APPROVED_MESSAGE: \"✅ OpenClaw access approved. Send a message to start chatting.\";","entrypoint":"channel-plugin-common","exportName":"PAIRING_APPROVED_MESSAGE","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"const","recordType":"export"} {"closureHash":"712435252d2fe5135542ca6b5a4375a6edea24e83829338011dc6ae7e9802fbb","declaration":"export type ChannelMessageActionContext = ChannelMessageActionContext;","entrypoint":"channel-plugin-common","exportName":"ChannelMessageActionContext","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"} {"closureHash":"c896b30eefde9cf194ca8e3ef307206d2ff53922957dbbbd5572b8f211eef58d","declaration":"export type ChannelPlugin = ChannelPlugin;","entrypoint":"channel-plugin-common","exportName":"ChannelPlugin","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"} -{"closureHash":"b8cfd4298333de90ef689017e70615b435c9076ad466ceae6f46ebc70a67f867","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-plugin-common","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"} +{"closureHash":"0860813ffb138d3dd703ab9b607c758cd9b365512a67483d1f6b8b010775cd41","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"channel-plugin-common","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"} {"closureHash":"5d22b1a044dc147e7eef60f1c06347cab8f4e88383adfa92fec5e1a1076ab145","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"channel-plugin-common","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/channel-plugin-common","kind":"type","recordType":"export"} {"category":null,"entrypoint":"channel-policy","importSpecifier":"openclaw/plugin-sdk/channel-policy","recordType":"module"} {"closureHash":"017ab29d16d0f3d02d60f3513e65a373868d26496bc93d020d8fc8c17fd875f4","declaration":"export function buildAccountScopedDmSecurityPolicy(params: { cfg: OpenClawConfig; channelKey: string; accountId?: string | null; fallbackAccountId?: string | null; policy?: string | null; allowFrom?: Array | null; defaultPolicy?: string; allowFromPathSuffix?: string; policyPathSuffix?: string; approveChannelId?: string; approveHint?: string; normalizeEntry?: (raw: string) => string; inheritSharedDefaultsFromDefaultAccount?: boolean; }): ChannelSecurityDmPolicy;","entrypoint":"channel-policy","exportName":"buildAccountScopedDmSecurityPolicy","importSpecifier":"openclaw/plugin-sdk/channel-policy","kind":"function","recordType":"export"} @@ -1743,7 +1743,7 @@ {"closureHash":"06f2f30510e0041a44db4478425d8b9043defcfca3a6dacfbc575c917ce248c8","declaration":"export function patchSessionEntry(params: PatchSessionEntryParams): Promise;","entrypoint":"config-runtime","exportName":"patchSessionEntry","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} {"closureHash":"1e5fba9e0733c3ca747cac6ce19e1ae81e0dd800b07e26ac58f94b19297542d9","declaration":"export function readConfigFileSnapshotForWrite(options?: { skipPluginValidation?: boolean; }): Promise;","entrypoint":"config-runtime","exportName":"readConfigFileSnapshotForWrite","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} {"closureHash":"e539adb8aaa544d4874dca14a0d0e49b3e4a671a2b14bac0519814c5d6c4489d","declaration":"export function readSessionUpdatedAt(params: SessionStoreReadParams): number | undefined;","entrypoint":"config-runtime","exportName":"readSessionUpdatedAt","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} -{"closureHash":"a7713d94404861eeaa0d82141d2d673d2ea2647bec14abdc4ea91f32f3339ab4","declaration":"export function recordSessionMetaFromInbound(params: RecordInboundSessionMetaParams): Promise;","entrypoint":"config-runtime","exportName":"recordSessionMetaFromInbound","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} +{"closureHash":"f26fb809f44cce21e85ea12d094973176ce4d8533cbd4ba2f5cf3680a9d58b0b","declaration":"export function recordSessionMetaFromInbound(params: { storePath: string; sessionKey: string; ctx: MsgContext; groupResolution?: GroupKeyResolution | null; createIfMissing?: boolean; }): Promise;","entrypoint":"config-runtime","exportName":"recordSessionMetaFromInbound","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} {"closureHash":"c914aa2ef9e46cf7b6c31f205bb3ad74b11566dc4beab04faeb15edd35214128","declaration":"export function replaceConfigFile(params: { nextConfig: OpenClawConfig; baseHash?: string; snapshot?: ConfigFileSnapshot; afterWrite?: ConfigWriteOptions[\"afterWrite\"]; writeOptions?: ConfigWriteOptions; io?: ConfigMutationIO; }): Promise;","entrypoint":"config-runtime","exportName":"replaceConfigFile","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} {"closureHash":"605ebf4cd3d4d4028a5355b3b3520b99543cf4572b64afcf346b228c1f5cfab3","declaration":"export function requireRuntimeConfig(config: OpenClawConfig, context: string): OpenClawConfig;","entrypoint":"config-runtime","exportName":"requireRuntimeConfig","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} {"closureHash":"a4a07423aa8f00011e9662691b71bfea469626b14879c6098bce5ef70ea97a5a","declaration":"export function resolveActiveTalkProviderConfig(talk: TalkConfig | undefined): ResolvedTalkConfig | undefined;","entrypoint":"config-runtime","exportName":"resolveActiveTalkProviderConfig","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} @@ -1778,7 +1778,7 @@ {"closureHash":"1c5e95dc026b11e02180af873f67623fe9327244f1705b1c1482150f798c24fd","declaration":"export function saveCronStore(storePath: string, store: CronStoreFile, opts?: SaveCronStoreOptions): Promise;","entrypoint":"config-runtime","exportName":"saveCronStore","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} {"closureHash":"21c997f58863c4eb65c8e9e7e85aa74c9ebd7caaae5508a48ee3dcf62043afc9","declaration":"export function setRuntimeConfigSnapshot(config: OpenClawConfig, sourceConfig?: OpenClawConfig): void;","entrypoint":"config-runtime","exportName":"setRuntimeConfigSnapshot","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} {"closureHash":"5de548c1897871e89cf3cd211ecca69c4b1137834670b237eef8694fa142dcfc","declaration":"export function updateConfig(mutator: (cfg: OpenClawConfig, context: UpdateConfigContext) => OpenClawConfig): Promise;","entrypoint":"config-runtime","exportName":"updateConfig","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} -{"closureHash":"3380b888ad7d38c0d95ffe0ed93b2ab8ae1fccb556adf07a65b2a5e86a2f120e","declaration":"export function updateLastRoute(params: UpdateSessionLastRouteParams): Promise;","entrypoint":"config-runtime","exportName":"updateLastRoute","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} +{"closureHash":"f39a7bb06f19d8893de109118a6338ce36bbcd34b3e136e34549454f0e54ab19","declaration":"export function updateLastRoute(params: { storePath: string; sessionKey: string; channel?: string; to?: string; accountId?: string; threadId?: string | number; route?: ChannelRouteRef; deliveryContext?: DeliveryContext; ctx?: MsgContext; groupResolution?: GroupKeyResolution | null; createIfMissing?: boolean; }): Promise;","entrypoint":"config-runtime","exportName":"updateLastRoute","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} {"closureHash":"82eceb44e1f75a0b338616e966c132d0cd88247d00dafcd6f95b19702c30339e","declaration":"export function updateSessionStoreEntry(params: UpdateSessionStoreEntryParams): Promise;","entrypoint":"config-runtime","exportName":"updateSessionStoreEntry","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} {"closureHash":"c6d8f158279844ef7b6821bd866398d0827688b68e1a514009653c88a40f8ed6","declaration":"export function upsertSessionEntry(params: UpsertSessionEntryParams): Promise;","entrypoint":"config-runtime","exportName":"upsertSessionEntry","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} {"closureHash":"ebd5c05c8e63bae51150f3b831f4c01792625cd3ca49096fa830ca6442f07287","declaration":"export function warnMissingProviderGroupPolicyFallbackOnce(params: { providerMissingFallbackApplied: boolean; providerKey: string; accountId?: string; blockedLabel?: string; log: (message: string) => void; }): boolean;","entrypoint":"config-runtime","exportName":"warnMissingProviderGroupPolicyFallbackOnce","importSpecifier":"openclaw/plugin-sdk/config-runtime","kind":"function","recordType":"export"} @@ -1897,8 +1897,8 @@ {"closureHash":"1010c88a3eaa05d4c2fceaa97b5d58b437cc426a13a8a175da9e2d1dc1335ac0","declaration":"export function createChatChannelPlugin(params: { base: ChatChannelPluginBase; security?: ChannelSecurityAdapter | ChatChannelSecurityOptions; pairing?: ChannelPairingAdapter | ChatChannelPairingOptions; threading?: ChannelThreadingAdapter | ChatChannelThreadingOptions; outbound?: ChannelOutboundAdapter | ChatChannelAttachedOutboundOptions; }): ChannelPlugin;","entrypoint":"core","exportName":"createChatChannelPlugin","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"} {"closureHash":"785b0f750c5bd20f9f3ca081886a5af79ee0e4d2c38f78f769bf994b234f5076","declaration":"export function createDedupeCache(options: DedupeCacheOptions): DedupeCache;","entrypoint":"core","exportName":"createDedupeCache","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"} {"closureHash":"e2df8d235401aebf58eb71652fbeaedb42ca00aaa5042a76909ff2c48ba6fd54","declaration":"export function createSubsystemLogger(subsystem: string): SubsystemLogger;","entrypoint":"core","exportName":"createSubsystemLogger","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"} -{"closureHash":"036c8a7268d64e4861bec206709236d906d1b0708870d98139f3948e7500f069","declaration":"export function defineChannelPluginEntry({ id, name, description, plugin, configSchema, setRuntime, registerCliMetadata, registerFull, registerCapabilities, }: DefineChannelPluginEntryOptions): DefinedChannelPluginEntry;","entrypoint":"core","exportName":"defineChannelPluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"} -{"closureHash":"6b70810fb849411789df30dc3881f93c5dbc326960fcbc38b64f10bf3b182ff2","declaration":"export function definePluginEntry({ id, name, description, kind, configSchema, reload, nodeHostCommands, securityAuditCollectors, register, }: DefinePluginEntryOptions): DefinedPluginEntry;","entrypoint":"core","exportName":"definePluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"} +{"closureHash":"9a492cc57372852a29d2c1edbb3c269d6fd02bae2ba0879cddb90b4fd5fe3398","declaration":"export function defineChannelPluginEntry({ id, name, description, plugin, configSchema, setRuntime, registerCliMetadata, registerFull, registerCapabilities, }: DefineChannelPluginEntryOptions): DefinedChannelPluginEntry;","entrypoint":"core","exportName":"defineChannelPluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"} +{"closureHash":"f934f227fd088b6c760d107b8ea16f1d69c169b63931eeccab83c380996431d2","declaration":"export function definePluginEntry({ id, name, description, kind, configSchema, reload, nodeHostCommands, securityAuditCollectors, register, }: DefinePluginEntryOptions): DefinedPluginEntry;","entrypoint":"core","exportName":"definePluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"} {"closureHash":"0e0a9f6b22c433bdb1165e7707b1f9a1ddac1a544a8add00b503048cf157921f","declaration":"export function defineSetupPluginEntry(plugin: TPlugin): { plugin: TPlugin; };","entrypoint":"core","exportName":"defineSetupPluginEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"} {"closureHash":"fed1ccba51158f3c9e0a46ec9a9d747944d984842b90bfe9f3616486fc5e42f4","declaration":"export function delegateCompactionToRuntime(params: Parameters[0]): Promise;","entrypoint":"core","exportName":"delegateCompactionToRuntime","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"} {"closureHash":"2c282e0e308f9442bca7cdeb8e89a097531b1d54a692c9d86e5f39a8db1c2537","declaration":"export function deleteAccountFromConfigSection(params: { cfg: OpenClawConfig; sectionKey: string; accountId: string; clearBaseFields?: string[]; }): OpenClawConfig;","entrypoint":"core","exportName":"deleteAccountFromConfigSection","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"} @@ -1945,7 +1945,7 @@ {"closureHash":"2e6ce1f4c1692270a00dc0cf08e2752a26739c3143f8091cb270063c6034605d","declaration":"export function tryReadSecretFileSync(filePath: string | undefined, label: string, options: CredentialFileReadOptions): string | undefined;\nexport function tryReadSecretFileSync(filePath: string | undefined, label: string, options?: FsSafeSecretFileReadOptions): string | undefined;\nexport function tryReadSecretFileSync(filePath: string, label: string, options: FsSafeSecretFileReadOptions | undefined, diagnostic: { configPath: string; }): ConfiguredCredentialResult;\nexport function tryReadSecretFileSync(filePath: string | undefined, label: string, options: FsSafeSecretFileReadOptions | undefined, diagnostic: { configPath: string; }): CredentialResult;","entrypoint":"core","exportName":"tryReadSecretFileSync","importSpecifier":"openclaw/plugin-sdk/core","kind":"function","recordType":"export"} {"closureHash":"b40933a11984425d14a7a479bda0d2cd14cbfa9371164774f39bebbf12861df7","declaration":"export const DEFAULT_ACCOUNT_ID: \"default\";","entrypoint":"core","exportName":"DEFAULT_ACCOUNT_ID","importSpecifier":"openclaw/plugin-sdk/core","kind":"const","recordType":"export"} {"closureHash":null,"declaration":"export const DEFAULT_SECRET_FILE_MAX_BYTES: number;","entrypoint":"core","exportName":"DEFAULT_SECRET_FILE_MAX_BYTES","importSpecifier":"openclaw/plugin-sdk/core","kind":"const","recordType":"export"} -{"closureHash":"dad048707e7e780a56529d7567a4d10fe081bd472786db796cd423e7c204ce6d","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"core","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} +{"closureHash":"b467021581907cc4f2f8266283b147425febfe5d96c596dd00bc42ad5b9c6cac","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"core","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} {"closureHash":"d2ff4de9ee3fd111c2cc64a3ee7e557d9f161af1b6b437ee7886bcb16e426317","declaration":"export type AgentPromptGuidance = AgentPromptGuidance;","entrypoint":"core","exportName":"AgentPromptGuidance","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} {"closureHash":"2841127a90e04467adfea8126cbf03655f44ddb089ad9e0d48833c2beea39cbd","declaration":"export type AgentPromptGuidanceEntry = AgentPromptGuidanceEntry;","entrypoint":"core","exportName":"AgentPromptGuidanceEntry","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} {"closureHash":"aa0412acefe62caff12e5271ead0545504874e824380dc21cfc0566388a05f33","declaration":"export type AgentPromptSurfaceKind = \"openclaw_main\" | \"pi_main\" | \"codex_app_server\" | \"cli_backend\" | \"acp_backend\" | \"subagent\";","entrypoint":"core","exportName":"AgentPromptSurfaceKind","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} @@ -1977,10 +1977,10 @@ {"closureHash":"54ea426dde51859b572b4c1079d2b70b412096f73da2b8c265f2749d9f01cbb5","declaration":"export type NormalizedLocation = NormalizedLocation;","entrypoint":"core","exportName":"NormalizedLocation","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} {"closureHash":"8054ffbe71b91afced900ef8a06f5e368ac10c4f99ffc1c6f538a802856f61c6","declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"core","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} {"closureHash":"5189698d102b8b064eefe1442b008312973c3994fd6b203d2205725d7ee9d118","declaration":"export type OpenClawPluginActiveModelContext = OpenClawPluginActiveModelContext;","entrypoint":"core","exportName":"OpenClawPluginActiveModelContext","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} -{"closureHash":"b8cfd4298333de90ef689017e70615b435c9076ad466ceae6f46ebc70a67f867","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} +{"closureHash":"0860813ffb138d3dd703ab9b607c758cd9b365512a67483d1f6b8b010775cd41","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"core","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} {"closureHash":"e89ab2a5316dba762220c00ee423b352ce66153297aaa1abd4299fe59d0eb9b4","declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"core","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} {"closureHash":"365beb5cee974639c2f35fc7a39088721ca8e9c618442830298b98033e9c768c","declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"core","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} -{"closureHash":"393e70c001cfe7cfdac0909d7e37e9b238f6a7a018ab6a2ea270fafc3b956492","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"core","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} +{"closureHash":"f66b177c88c8088e0922f8928f3add224549e1b07d6058247971bbfb59329a49","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"core","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} {"closureHash":"a7ed83f0924f818b23cecb5a1f3591ff28b9499ccac9667a2b8505c2bc608ea9","declaration":"export type OpenClawPluginGatewayEventScope = OpenClawPluginGatewayEventScope;","entrypoint":"core","exportName":"OpenClawPluginGatewayEventScope","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} {"closureHash":"f81f224d9b837e6353b7a546c5a76b124bcf568fd1f1fd0c6881fda30c53120a","declaration":"export type OpenClawPluginGatewayEvents = OpenClawPluginGatewayEvents;","entrypoint":"core","exportName":"OpenClawPluginGatewayEvents","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} {"closureHash":"ddc2738dd0ece94ddde9a7c655f92c15ec6416645ecf932d4aa404c7b7761159","declaration":"export type OpenClawPluginService = OpenClawPluginService;","entrypoint":"core","exportName":"OpenClawPluginService","importSpecifier":"openclaw/plugin-sdk/core","kind":"type","recordType":"export"} @@ -2215,7 +2215,7 @@ {"closureHash":"0db968dad99d84ecef5202167daadd092e3b4f456270283d3fd61585ac2bbd5a","declaration":"export type DiscordComponentSendResult = DiscordComponentSendResult;","entrypoint":"discord","exportName":"DiscordComponentSendResult","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"} {"closureHash":"084b46d7dd510eb182a4705559251e824220b57dbfa6dc54392507b72ba1815e","declaration":"export type DiscordOutboundTargetResolution = DiscordOutboundTargetResolution;","entrypoint":"discord","exportName":"DiscordOutboundTargetResolution","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"} {"closureHash":"8054ffbe71b91afced900ef8a06f5e368ac10c4f99ffc1c6f538a802856f61c6","declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"discord","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"} -{"closureHash":"b8cfd4298333de90ef689017e70615b435c9076ad466ceae6f46ebc70a67f867","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"discord","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"} +{"closureHash":"0860813ffb138d3dd703ab9b607c758cd9b365512a67483d1f6b8b010775cd41","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"discord","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"} {"closureHash":"5d22b1a044dc147e7eef60f1c06347cab8f4e88383adfa92fec5e1a1076ab145","declaration":"export type PluginRuntime = PluginRuntime;","entrypoint":"discord","exportName":"PluginRuntime","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"} {"closureHash":"6b9967e919c1cd420c8356b4f9d40dbc81932b4b15a733eecdcfb2ad84f8e5d8","declaration":"export type ResolvedDiscordAccount = ResolvedDiscordAccount;","entrypoint":"discord","exportName":"ResolvedDiscordAccount","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"} {"closureHash":"6bed5ca896b7034117e4757e2c6b4111dd5293dbad9416e3828dd6afa4e858ce","declaration":"export type ThreadBindingRecord = ThreadBindingRecord;","entrypoint":"discord","exportName":"ThreadBindingRecord","importSpecifier":"openclaw/plugin-sdk/discord","kind":"type","recordType":"export"} @@ -2360,7 +2360,7 @@ {"closureHash":"98e0cc16352b7dfcceb4957f8cd2acfe3c2b3acb223c42a5cfb885e088fcb04c","declaration":"export function resolveInboundReplyDispatchCounts(result: ChannelTurnDispatchResultLike): Record;","entrypoint":"inbound-reply-dispatch","exportName":"resolveInboundReplyDispatchCounts","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"function","recordType":"export"} {"closureHash":"906285cbb342f769c9af45c6f0c0956db3ede3ebdc882322bcae94fb34f7470b","declaration":"export function runChannelInboundEvent(params: RunChannelTurnParams): Promise>;\nexport function runChannelInboundEvent(params: ChannelInboundEventRunnerParams): Promise>;","entrypoint":"inbound-reply-dispatch","exportName":"runChannelInboundEvent","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"function","recordType":"export"} {"closureHash":"2c68496a174872b31aaf1ac8fad2789deb79d490c5ffbcb157325f1c95d1b51f","declaration":"export function runPreparedInboundReply(params: PreparedChannelTurn): Promise>;","entrypoint":"inbound-reply-dispatch","exportName":"runPreparedInboundReply","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"function","recordType":"export"} -{"closureHash":"5ff0f125fd0b55bfbef9991b21c1d34355eace44d5c49377e49643696fa0e636","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"inbound-reply-dispatch","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"const","recordType":"export"} +{"closureHash":"42768704540ab252d894266885fa71ac4c3b20e3dcfeb2f32942e7953be11d2c","declaration":"export const deliverInboundReplyWithMessageSendContext: (params: DurableInboundReplyDeliveryParams) => Promise<{ status: \"not_applicable\"; reason: \"non_final\";} | { status: \"unsupported\"; reason: \"missing_channel\" | \"missing_target\" | \"missing_outbound_handler\" | \"capability_mismatch\"; capability?: DurableFinalDeliveryRequirement;} | { status: \"handled_visible\"; delivery: ChannelDeliveryResult;} | { status: \"handled_no_send\"; reason: \"no_visible_result\"; delivery: ChannelDeliveryResult;} | { status: \"failed\"; error: unknown; sentBeforeError?: true;}>;","entrypoint":"inbound-reply-dispatch","exportName":"deliverInboundReplyWithMessageSendContext","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"const","recordType":"export"} {"closureHash":"add3eb2782f44af1661863d7f50fa714fd56e0f66aa3ef7b12c78680c690904a","declaration":"export type AssembledInboundReply = AssembledChannelTurn;","entrypoint":"inbound-reply-dispatch","exportName":"AssembledInboundReply","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"type","recordType":"export"} {"closureHash":"3de0d6d1bb8f9a83bd1c6e57aa8618e3fea71054236cd530c555e348bd0b7702","declaration":"export type ChannelBotLoopProtectionFacts = ChannelBotLoopProtectionFacts;","entrypoint":"inbound-reply-dispatch","exportName":"ChannelBotLoopProtectionFacts","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"type","recordType":"export"} {"closureHash":"f0da845bbdf49b30f6718a4b7ff012a0536deb98f65418583555dc90825797ca","declaration":"export type ChannelInboundDroppedHistoryOptions = ChannelTurnDroppedHistoryOptions;","entrypoint":"inbound-reply-dispatch","exportName":"ChannelInboundDroppedHistoryOptions","importSpecifier":"openclaw/plugin-sdk/inbound-reply-dispatch","kind":"type","recordType":"export"} @@ -3195,19 +3195,19 @@ {"closureHash":"f6027fe63e68f5a521e87cde46487f4902500668e3dc11e393f36a2796780f4d","declaration":"export function callMeetingBrowserProxyOnNode(params: { runtime: PluginRuntime; adapter: NodeAdapter; nodeId: string; } & MeetingBrowserRequestParams): Promise;","entrypoint":"meeting-runtime","exportName":"callMeetingBrowserProxyOnNode","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"c5fcd1d157edcb4773235adfaf8051e3ec7ca428cb7916b6d55f2511affab56c","declaration":"export function convertMeetingBridgeAudioForStt(audio: Buffer, audioFormat: MeetingRealtimeAudioFormat): Buffer;","entrypoint":"meeting-runtime","exportName":"convertMeetingBridgeAudioForStt","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"aa9063c27c5ff714d3653571c4a2a71e9d2eea5609b161f03e4738e15411358b","declaration":"export function convertMeetingTtsAudioForBridge(audio: Buffer, sampleRate: number, audioFormat: MeetingRealtimeAudioFormat, outputFormat?: string, platformName?: string): Buffer;","entrypoint":"meeting-runtime","exportName":"convertMeetingTtsAudioForBridge","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} -{"closureHash":"80b01caec697467156e6070e414500938453b6b2ecc761ebf6cde8954ab85c0e","declaration":"export function createLocalMeetingRealtimeAudioTransport(params: { inputCommand: string[]; outputCommand: string[]; bargeInInputCommand?: string[]; bargeInRmsThreshold: number; bargeInPeakThreshold: number; bargeInCooldownMs: number; logger: RuntimeLogger; logScope: string; audioFormat?: MeetingRealtimeAudioFormat; spawn?: MeetingRealtimeAudioSpawn; }): MeetingRealtimeAudioTransport;","entrypoint":"meeting-runtime","exportName":"createLocalMeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} +{"closureHash":"89af42fd07558b18f68995e55fa038ae54336f6befeda2c054a70ad71a31bf59","declaration":"export function createLocalMeetingRealtimeAudioTransport(params: { inputCommand: string[]; outputCommand: string[]; bargeInInputCommand?: string[]; bargeInRmsThreshold: number; bargeInPeakThreshold: number; bargeInCooldownMs: number; logger: RuntimeLogger; logScope: string; audioFormat?: MeetingRealtimeAudioFormat; spawn?: MeetingRealtimeAudioSpawn; }): MeetingRealtimeAudioTransport;","entrypoint":"meeting-runtime","exportName":"createLocalMeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"0b785f078f2c1b955c99888f6f6f20fdc4b24b8ffda47dd3c9d7b1b276a2c7ce","declaration":"export function createMeetingBrowserNodeCaller(params: { runtime: PluginRuntime; adapter: NodeAdapter; nodeId: string; }): MeetingBrowserRequestCaller;","entrypoint":"meeting-runtime","exportName":"createMeetingBrowserNodeCaller","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"f244ca8c47f556c9f388953cf9a7581c7d4d413af93e0dfa1462779e6a687a7c","declaration":"export function createMeetingBrowserNodeInvokePolicy(options: MeetingBrowserNodePolicyOptions): OpenClawPluginNodeInvokePolicy;","entrypoint":"meeting-runtime","exportName":"createMeetingBrowserNodeInvokePolicy","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"1aa4e3ff39a2cbe162421c62b1fa4a362973381d4d9ff15c671249b1ebd566bc","declaration":"export function createMeetingNodeHost(options: MeetingNodeHostOptions): { handleCommand(paramsJSON?: string | null): Promise; };","entrypoint":"meeting-runtime","exportName":"createMeetingNodeHost","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} -{"closureHash":"e39cb76f77eb918b4efe4149d7f61bc3947f6824f012ca7601a3a23a88b3ae85","declaration":"export function createMeetingRealtimeEngineBindings(params: { platform: MeetingPlatformRuntimeMetadata; config: { realtime: { agentId?: string; toolPolicy: RealtimeVoiceAgentConsultToolPolicy; }; }; fullConfig: OpenClawConfig; runtime: PluginRuntime; logger: RuntimeLogger; }): { platform: MeetingRuntimePlatform; consultAgent: (consult: MeetingAgentConsultParams) => Promise<{ text: string; }>; tools: RealtimeVoiceTool[]; handleToolCall: (call: MeetingRealtimeToolCallParams) => Promise; };","entrypoint":"meeting-runtime","exportName":"createMeetingRealtimeEngineBindings","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} +{"closureHash":"d642282aafde4a12c8e8659ecfe08d4cfa5d4a2d1b2d73442a07c761a2645c24","declaration":"export function createMeetingRealtimeEngineBindings(params: { platform: MeetingPlatformRuntimeMetadata; config: { realtime: { agentId?: string; toolPolicy: RealtimeVoiceAgentConsultToolPolicy; }; }; fullConfig: OpenClawConfig; runtime: PluginRuntime; logger: RuntimeLogger; }): { platform: MeetingRuntimePlatform; consultAgent: (consult: MeetingAgentConsultParams) => Promise<{ text: string; }>; tools: RealtimeVoiceTool[]; handleToolCall: (call: MeetingRealtimeToolCallParams) => Promise; };","entrypoint":"meeting-runtime","exportName":"createMeetingRealtimeEngineBindings","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"9124db05923060c467edb149bd8abdc8be1d00d00f867cf84600972923a58489","declaration":"export function createMeetingSession(params: { platform: MeetingPlatformRuntimeMetadata; config: { realtime: { provider?: string; voiceProvider?: string; transcriptionProvider?: string; model?: string; toolPolicy: TToolPolicy; }; }; resolved: MeetingResolvedJoin; createdAt: string; }): MeetingSessionRecord;","entrypoint":"meeting-runtime","exportName":"createMeetingSession","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"fb276e07e395ab19177b3d7967fd0a8fcda79130883f15092a4a306b826481b9","declaration":"export function createMeetingSetupStatus(checks: MeetingSetupCheck[]): MeetingSetupStatus;","entrypoint":"meeting-runtime","exportName":"createMeetingSetupStatus","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"3485569f6861fa17d2f0576a7f24909da88d8e32b25cbe31cf1672a309e26b94","declaration":"export function createMeetingVoiceCallGateway(params: { config: MeetingVoiceCallConfig; runtime: PluginRuntime; surface: MeetingVoiceCallSurface; connectClient: (params: { config: MeetingVoiceCallConfig; surface: MeetingVoiceCallSurface; }) => Promise; }): MeetingVoiceCallGateway;","entrypoint":"meeting-runtime","exportName":"createMeetingVoiceCallGateway","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} -{"closureHash":"ee75c7becb36ae63ed11f3a92484a5694b0383535c279d95f6caf5ffc44c373d","declaration":"export function createNodeMeetingRealtimeAudioTransport(params: { runtime: PluginRuntime; nodeId: string; bridgeId: string; logger: RuntimeLogger; commandName: string; logScope: string; logPrefix: string; audioFormat?: MeetingRealtimeAudioFormat; }): MeetingRealtimeAudioTransport;","entrypoint":"meeting-runtime","exportName":"createNodeMeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} +{"closureHash":"38bb7be8f3b9b577ff9dbff07bb355c4b18669344c07c221c1cb78e131d4ea54","declaration":"export function createNodeMeetingRealtimeAudioTransport(params: { runtime: PluginRuntime; nodeId: string; bridgeId: string; logger: RuntimeLogger; commandName: string; logScope: string; logPrefix: string; audioFormat?: MeetingRealtimeAudioFormat; }): MeetingRealtimeAudioTransport;","entrypoint":"meeting-runtime","exportName":"createNodeMeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"c0987b15a391a92d53d3e4e12b61eb122f9547fcf4f45478cdd3c5a8973a3e52","declaration":"export function endMeetingVoiceCallGatewayCall(params: { gateway: MeetingVoiceCallGateway; callId: string; }): Promise;","entrypoint":"meeting-runtime","exportName":"endMeetingVoiceCallGatewayCall","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"b3ebc10fe7ab372e1317eaa8f78621cf277bba1e33fda57acf2254f6759d1e9d","declaration":"export function getMeetingVoiceCallGatewayCall(params: { gateway: MeetingVoiceCallGateway; callId: string; }): Promise;","entrypoint":"meeting-runtime","exportName":"getMeetingVoiceCallGatewayCall","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"aac088df8e80d9ce89c45feccdb04ace3ae4417b3fcdd0f058410ddf25c96b46","declaration":"export function isMeetingVoiceCallMissingError(error: unknown): boolean;","entrypoint":"meeting-runtime","exportName":"isMeetingVoiceCallMissingError","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} -{"closureHash":"6173c44c085e125be5f152aa6d61a5d30ac0a424e498788ab88eb183dd122c46","declaration":"export function joinMeetingViaVoiceCallGateway(params: { config: MeetingVoiceCallConfig; gateway: MeetingVoiceCallGateway; surface: MeetingVoiceCallSurface; dialInNumber: string; dtmfSequence?: string; logger?: RuntimeLogger; message?: string; requesterSessionKey?: string; agentId?: string; sessionKey?: string; }): Promise;","entrypoint":"meeting-runtime","exportName":"joinMeetingViaVoiceCallGateway","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} +{"closureHash":"18b64a237b04dff75d9400d919eceae55cd8424454c317fc8c82c3d24ed4f5b6","declaration":"export function joinMeetingViaVoiceCallGateway(params: { config: MeetingVoiceCallConfig; gateway: MeetingVoiceCallGateway; surface: MeetingVoiceCallSurface; dialInNumber: string; dtmfSequence?: string; logger?: RuntimeLogger; message?: string; requesterSessionKey?: string; agentId?: string; sessionKey?: string; }): Promise;","entrypoint":"meeting-runtime","exportName":"joinMeetingViaVoiceCallGateway","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"bac9621cd025754fbcd4c21409b06eb0503405db81f35cac993aaf0b881ab3e1","declaration":"export function leaveMeetingWithBrowser(params: { adapter: BrowserAdapter; callBrowser: MeetingBrowserRequestCaller; launch: boolean; meetingSessionId?: string; meetingUrl: string; tab: MeetingBrowserTab; timeoutMs: number; }): Promise<{ left: boolean; note: string; }>;","entrypoint":"meeting-runtime","exportName":"leaveMeetingWithBrowser","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"c7b1aeac134b2070d053adf33026d876998b852ccd65cd2c9667119b1a1abee2","declaration":"export function openMeetingWithBrowser, Mode extends string, Health extends MeetingBrowserHealth & { browserTitle?: string; browserUrl?: string; notes?: string[]; }, Transcript extends MeetingTranscriptSnapshot>(params: { adapter: BrowserAdapter; callBrowser: MeetingBrowserRequestCaller; config: MeetingBrowserControllerConfig; session: Session; }): Promise<{ launched: boolean; browser?: Health; tab?: MeetingBrowserTab; }>;","entrypoint":"meeting-runtime","exportName":"openMeetingWithBrowser","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"34858979bd248799c2215d9c7bdd5d4a6b27660c9173bfca2e50dd4373ac27db","declaration":"export function readMeetingBrowserTab(result: unknown): MeetingBrowserCandidateTab | undefined;","entrypoint":"meeting-runtime","exportName":"readMeetingBrowserTab","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} @@ -3218,8 +3218,8 @@ {"closureHash":"a127b8c69494c8d6c4a09e81c8dcc44c6153b8799be96708c4168037db544f5d","declaration":"export function resolveMeetingBrowserNodeInfo(params: { runtime: PluginRuntime; adapter: NodeAdapter; requestedNode?: string; }): Promise;","entrypoint":"meeting-runtime","exportName":"resolveMeetingBrowserNodeInfo","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"f21196c9ea8ab90248ffdcdef3e942f1247ee2b9064ddb9757fffe352362c779","declaration":"export function resolveMeetingRealtimeAudioFormat(audioFormat: MeetingRealtimeAudioFormat): RealtimeVoiceAudioFormat;","entrypoint":"meeting-runtime","exportName":"resolveMeetingRealtimeAudioFormat","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"521dc5c262524a709cdd27cdc88e95004073da8223537bcbc73d5d423172dc2b","declaration":"export function speakMeetingViaVoiceCallGateway(params: { gateway: MeetingVoiceCallGateway; callId: string; message: string; }): Promise;","entrypoint":"meeting-runtime","exportName":"speakMeetingViaVoiceCallGateway","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} -{"closureHash":"50ac626ebaa6a23f223ab86adc4da998b8b25905ed1773bfd5e31865640548b1","declaration":"export function startMeetingAgentRealtimeEngine(params: { config: MeetingRealtimeEngineConfig; fullConfig: OpenClawConfig; runtime: PluginRuntime; platform: MeetingRuntimePlatform; meetingSessionId: string; requesterSessionKey?: string; logPrefix?: \"node\"; transport: MeetingRealtimeAudioTransport; logger: RuntimeLogger; providers?: RealtimeTranscriptionProviderPlugin[]; consultAgent: (params: MeetingAgentConsultParams) => Promise<{ text: string; }>; }): Promise;","entrypoint":"meeting-runtime","exportName":"startMeetingAgentRealtimeEngine","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} -{"closureHash":"24827d45d6a3139550ac425cc9cd953c3a3a07aa8692503020caf31972b9ee31","declaration":"export function startMeetingRealtimeEngine(params: { config: MeetingRealtimeEngineConfig; fullConfig: OpenClawConfig; runtime: PluginRuntime; platform: MeetingRuntimePlatform; meetingSessionId: string; requesterSessionKey?: string; logPrefix?: \"node\"; talkSessionId?: string; talkContext?: { nodeId: string; bridgeId: string; }; transport: MeetingRealtimeAudioTransport; logger: RuntimeLogger; providers?: RealtimeVoiceProviderPlugin[]; consultAgent: (params: MeetingAgentConsultParams) => Promise<{ text: string; }>; tools: RealtimeVoiceTool[]; handleToolCall: (params: MeetingRealtimeToolCallParams) => Promise; }): Promise;","entrypoint":"meeting-runtime","exportName":"startMeetingRealtimeEngine","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} +{"closureHash":"4bcafc3b3ce338e61fbd5a07854e4b847a2e5ad07b223f3695a02100be3fdb09","declaration":"export function startMeetingAgentRealtimeEngine(params: { config: MeetingRealtimeEngineConfig; fullConfig: OpenClawConfig; runtime: PluginRuntime; platform: MeetingRuntimePlatform; meetingSessionId: string; requesterSessionKey?: string; logPrefix?: \"node\"; transport: MeetingRealtimeAudioTransport; logger: RuntimeLogger; providers?: RealtimeTranscriptionProviderPlugin[]; consultAgent: (params: MeetingAgentConsultParams) => Promise<{ text: string; }>; }): Promise;","entrypoint":"meeting-runtime","exportName":"startMeetingAgentRealtimeEngine","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} +{"closureHash":"2924a12fcd208c4c0714f88f3fbee2bc8fe1172cd0e76fb4b9c0b9cfaa9745de","declaration":"export function startMeetingRealtimeEngine(params: { config: MeetingRealtimeEngineConfig; fullConfig: OpenClawConfig; runtime: PluginRuntime; platform: MeetingRuntimePlatform; meetingSessionId: string; requesterSessionKey?: string; logPrefix?: \"node\"; talkSessionId?: string; talkContext?: { nodeId: string; bridgeId: string; }; transport: MeetingRealtimeAudioTransport; logger: RuntimeLogger; providers?: RealtimeVoiceProviderPlugin[]; consultAgent: (params: MeetingAgentConsultParams) => Promise<{ text: string; }>; tools: RealtimeVoiceTool[]; handleToolCall: (params: MeetingRealtimeToolCallParams) => Promise; }): Promise;","entrypoint":"meeting-runtime","exportName":"startMeetingRealtimeEngine","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"function","recordType":"export"} {"closureHash":"663b9c77231b21af697efd5042e22d1c33e9ee972adeb312ad86d81a2b2e36f7","declaration":"export type MeetingAgentConsultParams = MeetingAgentConsultParams;","entrypoint":"meeting-runtime","exportName":"MeetingAgentConsultParams","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} {"closureHash":"adf0745c611bf737fc28978d766fc2a25b7104e71b6b2fed4e9b95e519c7b115","declaration":"export type MeetingBrowserCandidateTab = MeetingBrowserCandidateTab;","entrypoint":"meeting-runtime","exportName":"MeetingBrowserCandidateTab","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} {"closureHash":"59b1526172b7491b85f14f13c1ee26d8d6726f33093770748580c767b1689a17","declaration":"export type MeetingBrowserControllerConfig = MeetingBrowserControllerConfig;","entrypoint":"meeting-runtime","exportName":"MeetingBrowserControllerConfig","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} @@ -3251,7 +3251,7 @@ {"closureHash":"8244b408803f57cf2004157e96f2ce11bb036cdf864123b15ba2fac7f03b5d43","declaration":"export type MeetingSessionRuntimeHandles = MeetingSessionRuntimeHandles;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeHandles","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} {"closureHash":"aa8054fc2c442891197e89bdad61e79999ea15d813c4b127fb6150607b9e67e7","declaration":"export type MeetingSessionRuntimeJoinContext, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth, TTab extends MeetingBrowserTab> = MeetingSessionRuntimeJoinContext;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeJoinContext","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} {"closureHash":"325241724edd38da439c5df03d225e2a7cb8e56d817e98ed7c37850656d3744b","declaration":"export type MeetingSessionRuntimeMessages = MeetingSessionRuntimeMessages;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeMessages","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} -{"closureHash":"75cd899f80de13123f34f0f99db4d0de45fb3dcacd08a3f9d83b78eb863e2111","declaration":"export type MeetingSessionRuntimeOptions, TRequest, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth, TTab extends MeetingBrowserTab, TManualReason extends string, TSpeechBlockedReason extends string> = MeetingSessionRuntimeOptions;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeOptions","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} +{"closureHash":"7c44210738c733a85a5a3859dc25bb5eebd54ffbe1b3e104c4a636d62274b465","declaration":"export type MeetingSessionRuntimeOptions, TRequest, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth, TTab extends MeetingBrowserTab, TManualReason extends string, TSpeechBlockedReason extends string> = MeetingSessionRuntimeOptions;","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntimeOptions","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} {"closureHash":"d3c730cba02d30512c4cdae6e2367c662982e2c25671833ecd8701283924c642","declaration":"export type MeetingSessionState = MeetingSessionState;","entrypoint":"meeting-runtime","exportName":"MeetingSessionState","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} {"closureHash":"2496931157bf64fdb16013172ab9c023e60c5f85b98f46a3ee9532ce58d636d6","declaration":"export type MeetingSetupCheck = MeetingSetupCheck;","entrypoint":"meeting-runtime","exportName":"MeetingSetupCheck","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} {"closureHash":"f0aed6f7955a43fc387d8bbc072cb6276b0f2d18e7f829441a2ad45974bb3831","declaration":"export type MeetingSetupStatus = MeetingSetupStatus;","entrypoint":"meeting-runtime","exportName":"MeetingSetupStatus","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} @@ -3265,9 +3265,9 @@ {"closureHash":"20c70a94483aeddda4d1500cfcc5e71fab844b474ba4061c55d6c8693d40821b","declaration":"export type MeetingVoiceCallJoinResult = MeetingVoiceCallJoinResult;","entrypoint":"meeting-runtime","exportName":"MeetingVoiceCallJoinResult","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} {"closureHash":"4fb2c5928aa6f809dd4c604d71c5c99cdfe3e98b6e9c1662601c9b4ad9738162","declaration":"export type MeetingVoiceCallStatusResult = MeetingVoiceCallStatusResult;","entrypoint":"meeting-runtime","exportName":"MeetingVoiceCallStatusResult","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} {"closureHash":"5ef812397b6409a4ca228943dd1080661365959477b42e705a9aaa219757d14f","declaration":"export type MeetingVoiceCallSurface = MeetingVoiceCallSurface;","entrypoint":"meeting-runtime","exportName":"MeetingVoiceCallSurface","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"type","recordType":"export"} -{"closureHash":"2a578d48211a36fa48f18710bad4567c1059781158751128ba7355513aeb5a27","declaration":"export interface MeetingPlatformAdapter extends MeetingPlatformAdapterContract {\n}","entrypoint":"meeting-runtime","exportName":"MeetingPlatformAdapter","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"interface","recordType":"export"} +{"closureHash":"c23b89afd21f9a7a992d99f676808f6e9dfcaec46eaed15b7ea96781ec943ef3","declaration":"export interface MeetingPlatformAdapter extends MeetingPlatformAdapterContract {\n}","entrypoint":"meeting-runtime","exportName":"MeetingPlatformAdapter","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"interface","recordType":"export"} {"closureHash":"79884bd1df1ea0d07d5ceb4c62d93c1ee744b75d31c94c988845869c0f3cbd2d","declaration":"export interface MeetingRealtimeAudioTransport {\n onFatal(handler: () => void): void;\n startInput(onAudio: (audio: Buffer) => void): void;\n beginOutput?(): void;\n stop(): Promise;\n writeOutput(audio: Buffer): Promise;\n clearOutput(): Promise;\n dispose(): Promise;\n getHealth?(): MeetingRealtimeAudioTransportHealth;\n startBargeInMonitor?(onBargeIn: (audio: Buffer) => boolean): void;\n}","entrypoint":"meeting-runtime","exportName":"MeetingRealtimeAudioTransport","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"interface","recordType":"export"} -{"closureHash":"b42b3afe775d63b4b00ae1bb858b7481fdc6be99ab7e1fed8fbc05199f603ae0","declaration":"export class MeetingSessionRuntime, TRequest, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth, TTab extends MeetingBrowserTab, TManualReason extends string, TSpeechBlockedReason extends string> {\n readonly #sessions: Map;\n readonly #sessionLeaves: Map>>;\n readonly #sessionCleanup: MeetingSessionCleanupTracker;\n readonly #meetingLock: MeetingSessionJoinLock;\n readonly #sessionStops: Map Promise>;\n readonly #sessionSpeakers: Map void>;\n readonly #sessionHealth: Map Partial>;\n readonly #durableTranscripts: MeetingSessionDurableTranscripts;\n readonly #transcriptStore: MeetingSessionTranscriptStore;\n constructor(private readonly options: MeetingSessionRuntimeOptions);\n list(): TSession[];\n getSession(sessionId: string): TSession | undefined;\n async status(sessionId?: string): Promise<{\n found: boolean;\n session?: TSession;\n sessions?: TSession[];\n }>;\n async transcript(sessionId: string, options: {\n sinceIndex?: number;\n }): Promise<{ found: boolean; sessionId?: string; startIndex?: number; nextIndex?: number; droppedLines?: number; evicted?: boolean; lines?: MeetingTranscriptLine[]; }>;\n async startTranscriptSource(request: TranscriptStartRequest): Promise;\n async stopTranscriptSource(request: TranscriptStopRequest): Promise;\n isReusableSession(session: TSession, resolved: MeetingResolvedJoin): boolean;\n async join(request: TRequest): Promise<{\n session: TSession;\n spoken?: boolean;\n }>;\n async leave(sessionId: string, options?: {\n keepBrowserTab?: boolean;\n }): Promise>;\n async speak(sessionId: string, instructions?: string): Promise<{\n found: boolean;\n spoken: boolean;\n session?: TSession;\n }>;\n async speakWhenReady(session: TSession, instructions: string): Promise;\n hasHealthHandle(sessionId: string): boolean;\n refreshHealth(sessionId?: string): void;\n async refreshBrowserHealth(session: TSession, options: {\n force?: boolean;\n readOnly?: boolean;\n }): Promise;\n async refreshCaptionHealth(session: TSession): Promise;\n refreshSpeechReadiness(session: TSession): {\n ready: boolean;\n reason?: TSpeechBlockedReason;\n message?: string;\n };\n markSessionEnded(session: TSession, reason: string): void;\n async #joinUnlocked(request: TRequest, resolved: MeetingResolvedJoin): Promise<{\n session: TSession;\n spoken?: boolean;\n }>;\n async #leaveUnlocked(sessionId: string, options?: {\n keepBrowserTab?: boolean;\n }): Promise>;\n async #leaveSession(session: TSession, options?: {\n keepBrowserTab?: boolean;\n }): Promise>;\n #meetingKey(transport: TTransport, url: string): string;\n #inheritBrowserTabOwnership(params: {\n session: TSession;\n transport: TTransport;\n nodeId?: string;\n meetingUrl: string;\n tab?: TTab;\n }): TTab | undefined;\n async #settleRetainedBrowserTabs(retained: Array<{\n session: TSession;\n tab: TTab;\n }>, adopted?: {\n transport: TTransport;\n nodeId?: string;\n tab: TTab;\n }): Promise;\n async #rollbackFailedJoinSession(session: TSession): Promise;\n async #settleRetainedBrowserTabsAfterFailure(retained: Array<{\n session: TSession;\n tab: TTab;\n }>): Promise;\n #attachRuntimeHandles(session: TSession, handles: MeetingSessionRuntimeHandles): void;\n #dropRuntimeHandles(sessionId: string): void;\n #isManagedBrowserSession(session: TSession): boolean;\n #evaluateSpeechReadiness(session: TSession): {\n ready: boolean;\n reason?: TSpeechBlockedReason;\n message?: string;\n };\n #noteSession(session: TSession, note: string): void;\n}","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntime","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"class","recordType":"export"} +{"closureHash":"5d6d26130693b59b05fff933eb75cbe0d2750111ce49e2483b1347e06914c7c0","declaration":"export class MeetingSessionRuntime, TRequest, TTransport extends string, TMode extends string, THealth extends MeetingBrowserHealth, TTab extends MeetingBrowserTab, TManualReason extends string, TSpeechBlockedReason extends string> {\n readonly #sessions: Map;\n readonly #sessionLeaves: Map>>;\n readonly #sessionCleanup: MeetingSessionCleanupTracker;\n readonly #meetingLock: MeetingSessionJoinLock;\n readonly #sessionStops: Map Promise>;\n readonly #sessionSpeakers: Map void>;\n readonly #sessionHealth: Map Partial>;\n readonly #durableTranscripts: MeetingSessionDurableTranscripts;\n readonly #transcriptStore: MeetingSessionTranscriptStore;\n constructor(private readonly options: MeetingSessionRuntimeOptions);\n list(): TSession[];\n getSession(sessionId: string): TSession | undefined;\n async status(sessionId?: string): Promise<{\n found: boolean;\n session?: TSession;\n sessions?: TSession[];\n }>;\n async transcript(sessionId: string, options: {\n sinceIndex?: number;\n }): Promise<{ found: boolean; sessionId?: string; startIndex?: number; nextIndex?: number; droppedLines?: number; evicted?: boolean; lines?: MeetingTranscriptLine[]; }>;\n async startTranscriptSource(request: TranscriptStartRequest): Promise;\n async stopTranscriptSource(request: TranscriptStopRequest): Promise;\n isReusableSession(session: TSession, resolved: MeetingResolvedJoin): boolean;\n async join(request: TRequest): Promise<{\n session: TSession;\n spoken?: boolean;\n }>;\n async leave(sessionId: string, options?: {\n keepBrowserTab?: boolean;\n }): Promise>;\n async speak(sessionId: string, instructions?: string): Promise<{\n found: boolean;\n spoken: boolean;\n session?: TSession;\n }>;\n async speakWhenReady(session: TSession, instructions: string): Promise;\n hasHealthHandle(sessionId: string): boolean;\n refreshHealth(sessionId?: string): void;\n async refreshBrowserHealth(session: TSession, options: {\n force?: boolean;\n readOnly?: boolean;\n }): Promise;\n async refreshCaptionHealth(session: TSession): Promise;\n refreshSpeechReadiness(session: TSession): {\n ready: boolean;\n reason?: TSpeechBlockedReason;\n message?: string;\n };\n markSessionEnded(session: TSession, reason: string): void;\n async #joinUnlocked(request: TRequest, resolved: MeetingResolvedJoin): Promise<{\n session: TSession;\n spoken?: boolean;\n }>;\n async #leaveUnlocked(sessionId: string, options?: {\n keepBrowserTab?: boolean;\n }): Promise>;\n async #leaveSession(session: TSession, options?: {\n keepBrowserTab?: boolean;\n }): Promise>;\n #meetingKey(transport: TTransport, url: string): string;\n #inheritBrowserTabOwnership(params: {\n session: TSession;\n transport: TTransport;\n nodeId?: string;\n meetingUrl: string;\n tab?: TTab;\n }): TTab | undefined;\n async #settleRetainedBrowserTabs(retained: Array<{\n session: TSession;\n tab: TTab;\n }>, adopted?: {\n transport: TTransport;\n nodeId?: string;\n tab: TTab;\n }): Promise;\n async #rollbackFailedJoinSession(session: TSession): Promise;\n async #settleRetainedBrowserTabsAfterFailure(retained: Array<{\n session: TSession;\n tab: TTab;\n }>): Promise;\n #attachRuntimeHandles(session: TSession, handles: MeetingSessionRuntimeHandles): void;\n #dropRuntimeHandles(sessionId: string): void;\n #isManagedBrowserSession(session: TSession): boolean;\n #evaluateSpeechReadiness(session: TSession): {\n ready: boolean;\n reason?: TSpeechBlockedReason;\n message?: string;\n };\n #noteSession(session: TSession, note: string): void;\n}","entrypoint":"meeting-runtime","exportName":"MeetingSessionRuntime","importSpecifier":"openclaw/plugin-sdk/meeting-runtime","kind":"class","recordType":"export"} {"category":null,"entrypoint":"memory-core-host-engine-foundation","importSpecifier":"openclaw/plugin-sdk/memory-core-host-engine-foundation","recordType":"module"} {"closureHash":"e2df8d235401aebf58eb71652fbeaedb42ca00aaa5042a76909ff2c48ba6fd54","declaration":"export function createSubsystemLogger(subsystem: string): SubsystemLogger;","entrypoint":"memory-core-host-engine-foundation","exportName":"createSubsystemLogger","importSpecifier":"openclaw/plugin-sdk/memory-core-host-engine-foundation","kind":"function","recordType":"export"} {"closureHash":null,"declaration":"export function isPathInside(root: string, target: string): boolean;","entrypoint":"memory-core-host-engine-foundation","exportName":"isPathInside","importSpecifier":"openclaw/plugin-sdk/memory-core-host-engine-foundation","kind":"function","recordType":"export"} @@ -3403,9 +3403,9 @@ {"category":"core","entrypoint":"plugin-entry","importSpecifier":"openclaw/plugin-sdk/plugin-entry","recordType":"module"} {"closureHash":"3d27406644141af2733cfca6e8c1240fc62327910109f585ce9073cafd7fd89c","declaration":"export function buildJsonPluginConfigSchema(schema: JsonSchemaObject, options?: BuildJsonPluginConfigSchemaOptions): OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"buildJsonPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"} {"closureHash":"aff66c792d532642afb9c6e5a03c8d220f219250c3a8b49733f32058f22f98ca","declaration":"export function buildPluginConfigSchema(schema: ZodTypeAny, options?: BuildPluginConfigSchemaOptions): OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"buildPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"} -{"closureHash":"6b70810fb849411789df30dc3881f93c5dbc326960fcbc38b64f10bf3b182ff2","declaration":"export function definePluginEntry({ id, name, description, kind, configSchema, reload, nodeHostCommands, securityAuditCollectors, register, }: DefinePluginEntryOptions): DefinedPluginEntry;","entrypoint":"plugin-entry","exportName":"definePluginEntry","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"} +{"closureHash":"f934f227fd088b6c760d107b8ea16f1d69c169b63931eeccab83c380996431d2","declaration":"export function definePluginEntry({ id, name, description, kind, configSchema, reload, nodeHostCommands, securityAuditCollectors, register, }: DefinePluginEntryOptions): DefinedPluginEntry;","entrypoint":"plugin-entry","exportName":"definePluginEntry","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"} {"closureHash":"0ef1dfa3b5deeb456480e292c0e835c3cd6d13e7bb7059fc735546507da51594","declaration":"export function emptyPluginConfigSchema(): OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"emptyPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"function","recordType":"export"} -{"closureHash":"dad048707e7e780a56529d7567a4d10fe081bd472786db796cd423e7c204ce6d","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"plugin-entry","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} +{"closureHash":"b467021581907cc4f2f8266283b147425febfe5d96c596dd00bc42ad5b9c6cac","declaration":"export type AgentHarness = AgentHarness;","entrypoint":"plugin-entry","exportName":"AgentHarness","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} {"closureHash":"d2ff4de9ee3fd111c2cc64a3ee7e557d9f161af1b6b437ee7886bcb16e426317","declaration":"export type AgentPromptGuidance = AgentPromptGuidance;","entrypoint":"plugin-entry","exportName":"AgentPromptGuidance","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} {"closureHash":"2841127a90e04467adfea8126cbf03655f44ddb089ad9e0d48833c2beea39cbd","declaration":"export type AgentPromptGuidanceEntry = AgentPromptGuidanceEntry;","entrypoint":"plugin-entry","exportName":"AgentPromptGuidanceEntry","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} {"closureHash":"aa0412acefe62caff12e5271ead0545504874e824380dc21cfc0566388a05f33","declaration":"export type AgentPromptSurfaceKind = \"openclaw_main\" | \"pi_main\" | \"codex_app_server\" | \"cli_backend\" | \"acp_backend\" | \"subagent\";","entrypoint":"plugin-entry","exportName":"AgentPromptSurfaceKind","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} @@ -3421,10 +3421,10 @@ {"closureHash":"8054ffbe71b91afced900ef8a06f5e368ac10c4f99ffc1c6f538a802856f61c6","declaration":"export type OpenClawConfig = OpenClawConfig;","entrypoint":"plugin-entry","exportName":"OpenClawConfig","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} {"closureHash":"2f6e368fff73e942044cdf95c7c751b46c741e22ac0d2d4d97f45a3158f758ae","declaration":"export type OpenClawGatewayDiscoveryAdvertiseContext = OpenClawGatewayDiscoveryAdvertiseContext;","entrypoint":"plugin-entry","exportName":"OpenClawGatewayDiscoveryAdvertiseContext","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} {"closureHash":"b198058e0065e5c60b729a5bdf568f7e2436a006d8c4a7c63de764c7283f96ba","declaration":"export type OpenClawGatewayDiscoveryService = OpenClawGatewayDiscoveryService;","entrypoint":"plugin-entry","exportName":"OpenClawGatewayDiscoveryService","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} -{"closureHash":"b8cfd4298333de90ef689017e70615b435c9076ad466ceae6f46ebc70a67f867","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-entry","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} +{"closureHash":"0860813ffb138d3dd703ab9b607c758cd9b365512a67483d1f6b8b010775cd41","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-entry","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} {"closureHash":"e89ab2a5316dba762220c00ee423b352ce66153297aaa1abd4299fe59d0eb9b4","declaration":"export type OpenClawPluginCommandDefinition = OpenClawPluginCommandDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginCommandDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} {"closureHash":"365beb5cee974639c2f35fc7a39088721ca8e9c618442830298b98033e9c768c","declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"plugin-entry","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} -{"closureHash":"393e70c001cfe7cfdac0909d7e37e9b238f6a7a018ab6a2ea270fafc3b956492","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} +{"closureHash":"f66b177c88c8088e0922f8928f3add224549e1b07d6058247971bbfb59329a49","declaration":"export type OpenClawPluginDefinition = OpenClawPluginDefinition;","entrypoint":"plugin-entry","exportName":"OpenClawPluginDefinition","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} {"closureHash":"a7ed83f0924f818b23cecb5a1f3591ff28b9499ccac9667a2b8505c2bc608ea9","declaration":"export type OpenClawPluginGatewayEventScope = OpenClawPluginGatewayEventScope;","entrypoint":"plugin-entry","exportName":"OpenClawPluginGatewayEventScope","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} {"closureHash":"f81f224d9b837e6353b7a546c5a76b124bcf568fd1f1fd0c6881fda30c53120a","declaration":"export type OpenClawPluginGatewayEvents = OpenClawPluginGatewayEvents;","entrypoint":"plugin-entry","exportName":"OpenClawPluginGatewayEvents","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} {"closureHash":"7470b211ac4d3449cd0fc353ee2eb48e9fbc2dbc9259d21c680d0203577aa94f","declaration":"export type OpenClawPluginHttpRouteHandler = OpenClawPluginHttpRouteHandler;","entrypoint":"plugin-entry","exportName":"OpenClawPluginHttpRouteHandler","importSpecifier":"openclaw/plugin-sdk/plugin-entry","kind":"type","recordType":"export"} @@ -3574,14 +3574,14 @@ {"closureHash":"7906fbdeb04e9b99f512e4bab7230d701be7eee8d92fdc6529b2627c44f45f94","declaration":"export function executePluginCommand(params: { command: RegisteredPluginCommand; args?: string; senderId?: string; channel: string; channelId?: PluginCommandContext[\"channelId\"]; isAuthorizedSender: boolean; senderIsOwner?: boolean; gatewayClientScopes?: PluginCommandContext[\"gatewayClientScopes\"]; agentId?: string; sessionKey?: PluginCommandContext[\"sessionKey\"]; sessionId?: PluginCommandContext[\"sessionId\"]; sessionTarget?: PluginCommandContext[\"sessionTarget\"]; sessionFile?: PluginCommandContext[\"sessionFile\"]; authProfileId?: string; commandBody: string; config: OpenClawConfig; from?: PluginCommandContext[\"from\"]; to?: PluginCommandContext[\"to\"]; originatingTo?: string; accountId?: PluginCommandContext[\"accountId\"]; messageThreadId?: PluginCommandContext[\"messageThreadId\"]; threadParentId?: PluginCommandContext[\"threadParentId\"]; diagnosticsSessions?: PluginCommandContext[\"diagnosticsSessions\"]; diagnosticsUploadApproved?: PluginCommandContext[\"diagnosticsUploadApproved\"]; diagnosticsPreviewOnly?: PluginCommandContext[\"diagnosticsPreviewOnly\"]; diagnosticsPrivateRouted?: PluginCommandContext[\"diagnosticsPrivateRouted\"]; }): Promise;","entrypoint":"plugin-runtime","exportName":"executePluginCommand","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"} {"closureHash":"dfc8fc733f281bfbe0cc270964f0f657f17c2b97f21bc1b316aee6e9de8ff6ba","declaration":"export function getGlobalHookRunner(): HookRunner | null;","entrypoint":"plugin-runtime","exportName":"getGlobalHookRunner","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"} {"closureHash":"db6583607237e4081814e2c5d4f8fb6f216ad3bbfe623bf16fc1a9c09c15f64b","declaration":"export function getPluginCommandSpecs(provider?: string, options?: PluginCommandSpecOptions): Array<{ name: string; description: string; descriptionLocalizations?: Record; acceptsArgs: boolean; }>;","entrypoint":"plugin-runtime","exportName":"getPluginCommandSpecs","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"} -{"closureHash":"36e830c2b33f2caea933353bd13746dcb22f575e5297da625ce23608a9cf9d39","declaration":"export function getPluginRuntimeGatewayRequestScope(): PluginRuntimeGatewayRequestScope | undefined;","entrypoint":"plugin-runtime","exportName":"getPluginRuntimeGatewayRequestScope","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"} +{"closureHash":"1a1a0eb64eca57a0de656d9fc45b3bb54fe7fd2cdcae632c7f736268ef3d3e13","declaration":"export function getPluginRuntimeGatewayRequestScope(): PluginRuntimeGatewayRequestScope | undefined;","entrypoint":"plugin-runtime","exportName":"getPluginRuntimeGatewayRequestScope","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"} {"closureHash":"cfe277ce6de0c6ed50f1f54b66c889f6c95e91b058e8bcdc27aa37317a93a447","declaration":"export function listRegisteredPluginAgentPromptGuidance(params?: { surface?: AgentPromptSurfaceKind; includeLegacyGlobalGuidance?: boolean; }): string[];","entrypoint":"plugin-runtime","exportName":"listRegisteredPluginAgentPromptGuidance","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"} {"closureHash":"757a4525d8813e5cbb5308d7314751680f5f5ff0902ce994246393e8d771b7fb","declaration":"export function matchPluginCommand(commandBody: string, options?: { channel?: string; }): { command: RegisteredPluginCommand; args?: string; } | null;","entrypoint":"plugin-runtime","exportName":"matchPluginCommand","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"} {"closureHash":"9f62be89b0b32cf405337215301e81177eddf12db5c13748331b616993116495","declaration":"export function registerPluginCommand(pluginId: string, command: OpenClawPluginCommandDefinition, opts?: { pluginName?: string; pluginRoot?: string; allowReservedCommandNames?: boolean; allowOwnerStatusExposure?: boolean; }): CommandRegistrationResult;","entrypoint":"plugin-runtime","exportName":"registerPluginCommand","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"} {"closureHash":"16986e5d431f584c2d5053289eca3d2225bbe47a92cdfbbc2af91b264a165846","declaration":"export function registerPluginInteractiveHandler(pluginId: string, registration: PluginInteractiveHandlerRegistration, opts?: { pluginName?: string; pluginRoot?: string; }): InteractiveRegistrationResult;","entrypoint":"plugin-runtime","exportName":"registerPluginInteractiveHandler","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"} {"closureHash":"f20c07a48e2c949fbc889e7a32760f4e52339d9f6d3eab49e00ff249266e2396","declaration":"export function startLazyPluginServiceModule(params: { skipEnvVar?: string; overrideEnvVar?: string; validateOverrideSpecifier?: (specifier: string) => string; loadDefaultModule: () => Promise; loadOverrideModule?: (specifier: string) => Promise; startExportNames: string[]; stopExportNames?: string[]; }): Promise;","entrypoint":"plugin-runtime","exportName":"startLazyPluginServiceModule","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"function","recordType":"export"} {"closureHash":"bad43ffe69d1d9d6c92c79df4c388b3dda685013a92392daef456f1622ade659","declaration":"export type LazyPluginServiceHandle = LazyPluginServiceHandle;","entrypoint":"plugin-runtime","exportName":"LazyPluginServiceHandle","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"} -{"closureHash":"b8cfd4298333de90ef689017e70615b435c9076ad466ceae6f46ebc70a67f867","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-runtime","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"} +{"closureHash":"0860813ffb138d3dd703ab9b607c758cd9b365512a67483d1f6b8b010775cd41","declaration":"export type OpenClawPluginApi = OpenClawPluginApi;","entrypoint":"plugin-runtime","exportName":"OpenClawPluginApi","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"} {"closureHash":"365beb5cee974639c2f35fc7a39088721ca8e9c618442830298b98033e9c768c","declaration":"export type OpenClawPluginConfigSchema = OpenClawPluginConfigSchema;","entrypoint":"plugin-runtime","exportName":"OpenClawPluginConfigSchema","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"} {"closureHash":"f06379ada10ce0eca4e66bdf978db2c0035e054a135dc044c6d831ac7797c08f","declaration":"export type PluginConversationBinding = PluginConversationBinding;","entrypoint":"plugin-runtime","exportName":"PluginConversationBinding","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"} {"closureHash":"a1223d674b2b66918a576ae05b04318d7b8cbe9b1d3bc6dd7a08d1a4fa79b291","declaration":"export type PluginConversationBindingRequestParams = PluginConversationBindingRequestParams;","entrypoint":"plugin-runtime","exportName":"PluginConversationBindingRequestParams","importSpecifier":"openclaw/plugin-sdk/plugin-runtime","kind":"type","recordType":"export"} @@ -3671,10 +3671,10 @@ {"closureHash":"e66adcb55dec79be73a52bc76594b7e9210fd93c69a85b56098fbb58cecbb354","declaration":"export type WriteOAuthCredentialsOptions = WriteOAuthCredentialsOptions;","entrypoint":"provider-auth","exportName":"WriteOAuthCredentialsOptions","importSpecifier":"openclaw/plugin-sdk/provider-auth","kind":"type","recordType":"export"} {"category":null,"entrypoint":"provider-catalog-runtime","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","recordType":"module"} {"closureHash":"4f764aa4d0f8d3ffd97330520c637263a51a4d34e7dab6f6f37004b1d4b1e013","declaration":"export function augmentModelCatalogWithProviderPlugins(params: { config?: OpenClawConfig; workspaceDir?: string; env?: NodeJS.ProcessEnv; metadataSnapshot?: PluginMetadataSnapshot; context: ProviderAugmentModelCatalogContext; }): Promise;","entrypoint":"provider-catalog-runtime","exportName":"augmentModelCatalogWithProviderPlugins","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"} -{"closureHash":"dd9827ae1268928d6b92b21992af11884a6f519b35424e1c7fc747989e52c2ae","declaration":"export function isPluginProvidersLoadInFlight(params: Parameters[0]): boolean;","entrypoint":"provider-catalog-runtime","exportName":"isPluginProvidersLoadInFlight","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"} -{"closureHash":"5354b01a61adf1dec05dd3df10640ddfc20284c17fa67cb36c049babcf105b8f","declaration":"export function resolveCatalogHookProviderPluginIds(params: { config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; metadataSnapshot?: ProviderManifestLoadParams[\"metadataSnapshot\"]; }): string[];","entrypoint":"provider-catalog-runtime","exportName":"resolveCatalogHookProviderPluginIds","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"} -{"closureHash":"22c421c5fe2cc9331c4290ae6646627c840a527e4548964d6d22164fb3da9bd8","declaration":"export function resolveOwningPluginIdsForProvider(params: { provider: string; config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; manifestRegistry?: PluginManifestRegistry; metadataSnapshot?: Pick; }): string[] | undefined;","entrypoint":"provider-catalog-runtime","exportName":"resolveOwningPluginIdsForProvider","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"} -{"closureHash":"706775510bfbfb1e9067a3b2d57c58110674cad4ebf25d86858b2b1714c70e79","declaration":"export function resolvePluginProviders(params: { config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; bundledProviderVitestCompat?: boolean; onlyPluginIds?: string[]; providerRefs?: readonly string[]; modelRefs?: readonly string[]; activate?: boolean; cache?: boolean; applyAutoEnable?: boolean; pluginSdkResolution?: PluginLoadOptions[\"pluginSdkResolution\"]; mode?: \"runtime\" | \"setup\"; includeUntrustedWorkspacePlugins?: boolean; pluginMetadataSnapshot?: PluginMetadataRegistryView; skipIfLoadInFlight?: boolean; }): ProviderPlugin[];","entrypoint":"provider-catalog-runtime","exportName":"resolvePluginProviders","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"} +{"closureHash":"c83fcd9f36a82ed8ed6fe5d8806c384ee8d80e46519e3a958ab417170bb816cf","declaration":"export function isPluginProvidersLoadInFlight(params: Parameters[0]): boolean;","entrypoint":"provider-catalog-runtime","exportName":"isPluginProvidersLoadInFlight","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"} +{"closureHash":"108832e432b156ae64f432edad2aca467d3e85be72a99a60b26a2803a93ea20a","declaration":"export function resolveCatalogHookProviderPluginIds(params: { config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; metadataSnapshot?: ProviderManifestLoadParams[\"metadataSnapshot\"]; }): string[];","entrypoint":"provider-catalog-runtime","exportName":"resolveCatalogHookProviderPluginIds","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"} +{"closureHash":"ac2102abc51ab51cfe3d053dbc68e0a2ca3671b32de72de152bc8a0f958a650d","declaration":"export function resolveOwningPluginIdsForProvider(params: { provider: string; config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; manifestRegistry?: PluginManifestRegistry; metadataSnapshot?: Pick; }): string[] | undefined;","entrypoint":"provider-catalog-runtime","exportName":"resolveOwningPluginIdsForProvider","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"} +{"closureHash":"7e800655ebd84cafc2fb355c19a8c0de6f416058e6a4d0054901d50af7a6b086","declaration":"export function resolvePluginProviders(params: { config?: PluginLoadOptions[\"config\"]; workspaceDir?: string; env?: PluginLoadOptions[\"env\"]; bundledProviderVitestCompat?: boolean; onlyPluginIds?: string[]; providerRefs?: readonly string[]; modelRefs?: readonly string[]; activate?: boolean; cache?: boolean; applyAutoEnable?: boolean; pluginSdkResolution?: PluginLoadOptions[\"pluginSdkResolution\"]; mode?: \"runtime\" | \"setup\"; includeUntrustedWorkspacePlugins?: boolean; pluginMetadataSnapshot?: PluginMetadataRegistryView; skipIfLoadInFlight?: boolean; }): ProviderPlugin[];","entrypoint":"provider-catalog-runtime","exportName":"resolvePluginProviders","importSpecifier":"openclaw/plugin-sdk/provider-catalog-runtime","kind":"function","recordType":"export"} {"category":null,"entrypoint":"proxy-capture","importSpecifier":"openclaw/plugin-sdk/proxy-capture","recordType":"module"} {"closureHash":"d0e4e026d736bc00b1758d1089c44c3c5f3a09c7254291584de8cb297365804c","declaration":"export function acquireDebugProxyCaptureStore(dbPath: string, blobDir: string): { store: LegacyDebugProxyCaptureStore; release: () => void; };\nexport function acquireDebugProxyCaptureStore(options?: DebugProxyCaptureStoreOptions): { store: SharedDebugProxyCaptureStore; release: () => void; };","entrypoint":"proxy-capture","exportName":"acquireDebugProxyCaptureStore","importSpecifier":"openclaw/plugin-sdk/proxy-capture","kind":"function","recordType":"export"} {"closureHash":"d41cbb9de51b7aee1c6cf8c713b0bc44f27ac926fbb6422c05726f196d11964e","declaration":"export function captureHttpExchange(params: { url: string; method: string; requestHeaders?: Headers | Record | undefined; requestBody?: BodyInit | Buffer | string | null; response: Response; transport?: \"http\" | \"sse\"; flowId?: string; meta?: Record; }, resolved?: DebugProxySettings, deps?: DebugProxyCaptureRuntimeDeps): void;","entrypoint":"proxy-capture","exportName":"captureHttpExchange","importSpecifier":"openclaw/plugin-sdk/proxy-capture","kind":"function","recordType":"export"} @@ -4100,7 +4100,7 @@ {"closureHash":"72c82d479f20e3675cc502ab5184b47145bb1b65c7ac6714f1a3738fac843966","declaration":"export function readRecentUserAssistantTextForSession(params: ReadRecentSessionConversationTextParams): Promise;","entrypoint":"session-store-runtime","exportName":"readRecentUserAssistantTextForSession","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} {"closureHash":"e539adb8aaa544d4874dca14a0d0e49b3e4a671a2b14bac0519814c5d6c4489d","declaration":"export function readSessionUpdatedAt(params: SessionStoreReadParams): number | undefined;","entrypoint":"session-store-runtime","exportName":"readSessionUpdatedAt","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} {"closureHash":"8ff3f99fe45776fe7fed91609a35cc76c3aa92244731da8753aa17d737cc9d61","declaration":"export function readTranscriptStatsSync(params: { agentId?: string; env?: NodeJS.ProcessEnv; sessionId: string; sessionKey?: string; storePath?: string; }): { eventCount: number; maxSeq: number; sizeBytes: number; };","entrypoint":"session-store-runtime","exportName":"readTranscriptStatsSync","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} -{"closureHash":"a7713d94404861eeaa0d82141d2d673d2ea2647bec14abdc4ea91f32f3339ab4","declaration":"export function recordSessionMetaFromInbound(params: RecordInboundSessionMetaParams): Promise;","entrypoint":"session-store-runtime","exportName":"recordSessionMetaFromInbound","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} +{"closureHash":"f26fb809f44cce21e85ea12d094973176ce4d8533cbd4ba2f5cf3680a9d58b0b","declaration":"export function recordSessionMetaFromInbound(params: { storePath: string; sessionKey: string; ctx: MsgContext; groupResolution?: GroupKeyResolution | null; createIfMissing?: boolean; }): Promise;","entrypoint":"session-store-runtime","exportName":"recordSessionMetaFromInbound","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} {"closureHash":"ceeab98f1e47e10da267860232dab4334f0cfdbe50b69a7a4b38d8b9d02efd4e","declaration":"export function resolveAmbientTranscriptWatermarkKey(scope: AmbientTranscriptWatermarkScope): string;","entrypoint":"session-store-runtime","exportName":"resolveAmbientTranscriptWatermarkKey","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} {"closureHash":"f2cd1c017d99f55b339ebc95594747cad3472431fc6fba1eca77855eef3b0052","declaration":"export function resolveChannelResetConfig(params: { sessionCfg?: SessionConfig; channel?: string | null; }): SessionResetConfig | undefined;","entrypoint":"session-store-runtime","exportName":"resolveChannelResetConfig","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} {"closureHash":"6333eab946eff0194867385a4660e8ca90a5444a3b211b9bc4dfbf11eda54939","declaration":"export function resolveGroupSessionKey(ctx: MsgContext): GroupKeyResolution | null;","entrypoint":"session-store-runtime","exportName":"resolveGroupSessionKey","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} @@ -4119,7 +4119,7 @@ {"closureHash":"a4fe393f251cdc0a209513e93991198d0621344ad8518de479f7d0176a20fbf0","declaration":"export function sessionDeliveryRoute(entry?: Pick): ChannelRouteRef | undefined;","entrypoint":"session-store-runtime","exportName":"sessionDeliveryRoute","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} {"closureHash":"6b168f3f8084779c1404122dacc8f0829005fe895d1d643a49314cb6d94cdb23","declaration":"export function sqliteSessionFileMarkerMatchesSession(sessionFile: string | undefined, sessionId: string): boolean;","entrypoint":"session-store-runtime","exportName":"sqliteSessionFileMarkerMatchesSession","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} {"closureHash":"76ceaeb3bdc3d0026b03b16b905ca477173ac8b86822f60fd8278e047404a82e","declaration":"export function updateAmbientTranscriptWatermark(params: { storePath: string; sessionKey: string; key: string; messageId: string; timestampMs?: number; expectedSessionId?: string; }): Promise;","entrypoint":"session-store-runtime","exportName":"updateAmbientTranscriptWatermark","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} -{"closureHash":"3380b888ad7d38c0d95ffe0ed93b2ab8ae1fccb556adf07a65b2a5e86a2f120e","declaration":"export function updateLastRoute(params: UpdateSessionLastRouteParams): Promise;","entrypoint":"session-store-runtime","exportName":"updateLastRoute","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} +{"closureHash":"f39a7bb06f19d8893de109118a6338ce36bbcd34b3e136e34549454f0e54ab19","declaration":"export function updateLastRoute(params: { storePath: string; sessionKey: string; channel?: string; to?: string; accountId?: string; threadId?: string | number; route?: ChannelRouteRef; deliveryContext?: DeliveryContext; ctx?: MsgContext; groupResolution?: GroupKeyResolution | null; createIfMissing?: boolean; }): Promise;","entrypoint":"session-store-runtime","exportName":"updateLastRoute","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} {"closureHash":"23af15e2aedc5f222b1565b7c1c6d521ad6624a242ddd849f4d9878ccc7ca187","declaration":"export function updateSessionStore(storePath: string, mutator: (store: Record) => Promise | T, options?: UpdateSessionStoreOptions): Promise;","entrypoint":"session-store-runtime","exportName":"updateSessionStore","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} {"closureHash":"82eceb44e1f75a0b338616e966c132d0cd88247d00dafcd6f95b19702c30339e","declaration":"export function updateSessionStoreEntry(params: UpdateSessionStoreEntryParams): Promise;","entrypoint":"session-store-runtime","exportName":"updateSessionStoreEntry","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} {"closureHash":"c6d8f158279844ef7b6821bd866398d0827688b68e1a514009653c88a40f8ed6","declaration":"export function upsertSessionEntry(params: UpsertSessionEntryParams): Promise;","entrypoint":"session-store-runtime","exportName":"upsertSessionEntry","importSpecifier":"openclaw/plugin-sdk/session-store-runtime","kind":"function","recordType":"export"} @@ -4639,16 +4639,16 @@ {"closureHash":"e365d7ad911453b5139ba700931b061e560cff80b50d4cbe5e9615b5d7e13a52","declaration":"export type ScopedExpiringIdCache = ScopedExpiringIdCache;","entrypoint":"text-runtime","exportName":"ScopedExpiringIdCache","importSpecifier":"openclaw/plugin-sdk/text-runtime","kind":"type","recordType":"export"} {"closureHash":"af5502c92594c2e9049a4b4994e17c00d3adee3f6d1e68edd818a539c74c8787","declaration":"export interface CodeRegion {\n start: number;\n end: number;\n}","entrypoint":"text-runtime","exportName":"CodeRegion","importSpecifier":"openclaw/plugin-sdk/text-runtime","kind":"interface","recordType":"export"} {"category":null,"entrypoint":"tool-plugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin","recordType":"module"} -{"closureHash":"698f706462383975260d672f2c82ef7020b71c130e15c751edca586d44eb0046","declaration":"export function defineToolPlugin(definition: DefineToolPluginOptions): DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"defineToolPlugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"function","recordType":"export"} +{"closureHash":"ede2e36531418db19013ad26687b18697730f31bb762d2dda009ea3bf9d2b36a","declaration":"export function defineToolPlugin(definition: DefineToolPluginOptions): DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"defineToolPlugin","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"function","recordType":"export"} {"closureHash":"36ef907ce20f885b5f3068cbf0475dc442a68da9652579bb5bf8fb83ad34c38b","declaration":"export function getToolPluginMetadata(entry: unknown): ToolPluginMetadata | undefined;","entrypoint":"tool-plugin","exportName":"getToolPluginMetadata","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"function","recordType":"export"} {"closureHash":"bdc58154e36b2625fb3daccca3eab248d981077d04d747f0ad507cb2ff565198","declaration":"export const toolPluginMetadataSymbol: typeof toolPluginMetadataSymbol;","entrypoint":"tool-plugin","exportName":"toolPluginMetadataSymbol","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"const","recordType":"export"} -{"closureHash":"ce4db1a19af8d9cb3bf2bd5289d77487db60c535005ec50b48349911781ee277","declaration":"export type DefineToolPluginOptions = DefineToolPluginOptions;","entrypoint":"tool-plugin","exportName":"DefineToolPluginOptions","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"} -{"closureHash":"8c277e310581b59560eb3d0a898027de53e143785ad5848f332d2470e1f8f925","declaration":"export type DefinedToolPluginEntry = DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"DefinedToolPluginEntry","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"} -{"closureHash":"936fb8babce46076cd09dc5b38bade118373fc634c79f4a7669d1ef7293dea20","declaration":"export type ToolPluginExecutionContext = ToolPluginExecutionContext;","entrypoint":"tool-plugin","exportName":"ToolPluginExecutionContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"} -{"closureHash":"acc8264688da16158a628a1a9290e8960c8a586647225a74aba28a100cfb60eb","declaration":"export type ToolPluginFactoryContext = ToolPluginFactoryContext;","entrypoint":"tool-plugin","exportName":"ToolPluginFactoryContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"} +{"closureHash":"0df22e7ff0cae5c4001c05b9e4460dcf7564913bc148316a1c517a724e3b3dd5","declaration":"export type DefineToolPluginOptions = DefineToolPluginOptions;","entrypoint":"tool-plugin","exportName":"DefineToolPluginOptions","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"} +{"closureHash":"d12800a71f22b7743d96ab36619e28fcc598b98de6c1265a5ce11f398368e9a1","declaration":"export type DefinedToolPluginEntry = DefinedToolPluginEntry;","entrypoint":"tool-plugin","exportName":"DefinedToolPluginEntry","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"} +{"closureHash":"0d1d4fc199adaafddf4f62b788c5de4b97ac43d5b22ad92aa1cbfc8447334049","declaration":"export type ToolPluginExecutionContext = ToolPluginExecutionContext;","entrypoint":"tool-plugin","exportName":"ToolPluginExecutionContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"} +{"closureHash":"c37808520af266a262d52048782d6b0f659ca711c235b2a09b2a71e30c05bc7f","declaration":"export type ToolPluginFactoryContext = ToolPluginFactoryContext;","entrypoint":"tool-plugin","exportName":"ToolPluginFactoryContext","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"} {"closureHash":"f774bd092f51a31fbb34847213f9583234f585f66918d0af55e81bbbae40463b","declaration":"export type ToolPluginMetadata = ToolPluginMetadata;","entrypoint":"tool-plugin","exportName":"ToolPluginMetadata","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"} {"closureHash":"414a89d0c80eaaf682dc25d306e7223c981c6fd25366adb973a106f4268a6a54","declaration":"export type ToolPluginStaticToolMetadata = ToolPluginStaticToolMetadata;","entrypoint":"tool-plugin","exportName":"ToolPluginStaticToolMetadata","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"} -{"closureHash":"1751f45ab5485f55756a4d6ab3f9412fde03f0be7e595a0f16d327f4234c6400","declaration":"export type ToolPluginToolDefinition = ToolPluginToolDefinition;","entrypoint":"tool-plugin","exportName":"ToolPluginToolDefinition","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"} +{"closureHash":"3a4be9c5d7b137884c1bea068a9c7920512196677d01a63b9f0ea5c1d1904a57","declaration":"export type ToolPluginToolDefinition = ToolPluginToolDefinition;","entrypoint":"tool-plugin","exportName":"ToolPluginToolDefinition","importSpecifier":"openclaw/plugin-sdk/tool-plugin","kind":"type","recordType":"export"} {"category":null,"entrypoint":"tool-results","importSpecifier":"openclaw/plugin-sdk/tool-results","recordType":"module"} {"closureHash":"c5b0951c3629834dff78f92317cf1421a6bbc0faf9307be1cabb915055665280","declaration":"export function jsonResult(payload: TDetails): AgentToolResult;","entrypoint":"tool-results","exportName":"jsonResult","importSpecifier":"openclaw/plugin-sdk/tool-results","kind":"function","recordType":"export"} {"closureHash":"b9aefc637a694c74e028e92006004bef18185ed569af48ac43d36b646b0af2f3","declaration":"export function textResult(text: string, details: TDetails): AgentToolResult;","entrypoint":"tool-results","exportName":"textResult","importSpecifier":"openclaw/plugin-sdk/tool-results","kind":"function","recordType":"export"} @@ -4682,9 +4682,9 @@ {"closureHash":"9f9174f1023a8a451232f5d97d1e922b7faa88b76b58cffbfbe246a1488e0ddd","declaration":"export function readJsonWebhookBodyOrReject(params: { req: IncomingMessage; res: ServerResponse; maxBytes?: number; timeoutMs?: number; profile?: WebhookBodyReadProfile; emptyObjectOnEmpty?: boolean; invalidJsonMessage?: string; }): Promise<{ ok: true; value: unknown; } | { ok: false; }>;","entrypoint":"webhook-ingress","exportName":"readJsonWebhookBodyOrReject","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"} {"closureHash":"1bbddd5d1c8297e315275db4d5e1c8748ff09c0be7c37b0cf456db4fc69f8909","declaration":"export function readRequestBodyWithLimit(req: IncomingMessage, options: ReadRequestBodyOptions): Promise;","entrypoint":"webhook-ingress","exportName":"readRequestBodyWithLimit","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"} {"closureHash":"e8a1174cac83ce346a231fd25e82bb5f7618ffb57cdd9af6eaa208411f70646d","declaration":"export function readWebhookBodyOrReject(params: { req: IncomingMessage; res: ServerResponse; maxBytes?: number; timeoutMs?: number; profile?: WebhookBodyReadProfile; invalidBodyMessage?: string; }): Promise<{ ok: true; value: string; } | { ok: false; }>;","entrypoint":"webhook-ingress","exportName":"readWebhookBodyOrReject","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"} -{"closureHash":"457deb4e1f2cdb60d3ab6917e1f1089748b556f9d74f9737e95a181530125aa7","declaration":"export function registerPluginHttpRoute(params: { path?: string | null; fallbackPath?: string | null; handler: PluginHttpRouteHandler; auth: PluginHttpRouteRegistration[\"auth\"]; match?: PluginHttpRouteRegistration[\"match\"]; gatewayRuntimeScopeSurface?: PluginHttpRouteRegistration[\"gatewayRuntimeScopeSurface\"]; replaceExisting?: boolean; reuseExistingSameOwner?: boolean; throwOnFailure?: boolean; pluginId?: string; source?: string; accountId?: string; log?: (message: string) => void; registry?: PluginRegistry; }): () => void;","entrypoint":"webhook-ingress","exportName":"registerPluginHttpRoute","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"} +{"closureHash":"09bce222b522f6ca172d446ca59af8f9ea73eead0253eaec6c830e320993e39e","declaration":"export function registerPluginHttpRoute(params: { path?: string | null; fallbackPath?: string | null; handler: PluginHttpRouteHandler; auth: PluginHttpRouteRegistration[\"auth\"]; match?: PluginHttpRouteRegistration[\"match\"]; gatewayRuntimeScopeSurface?: PluginHttpRouteRegistration[\"gatewayRuntimeScopeSurface\"]; replaceExisting?: boolean; reuseExistingSameOwner?: boolean; throwOnFailure?: boolean; pluginId?: string; source?: string; accountId?: string; log?: (message: string) => void; registry?: PluginRegistry; }): () => void;","entrypoint":"webhook-ingress","exportName":"registerPluginHttpRoute","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"} {"closureHash":"05835f2f66f906f736b82b332a84a9714bc3a6b211890a62d8fc4dbf9258a7d4","declaration":"export function registerWebhookTarget(targetsByPath: Map, target: T, opts?: RegisterWebhookTargetOptions): RegisteredWebhookTarget;","entrypoint":"webhook-ingress","exportName":"registerWebhookTarget","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"} -{"closureHash":"7c0ef1b03d5c3965b7d7ab000ef74e3cf01cae3d2bcb926d0c2f54ffc5559090","declaration":"export function registerWebhookTargetWithPluginRoute(params: { targetsByPath: Map; target: T; route: RegisterWebhookPluginRouteOptions; onLastPathTargetRemoved?: RegisterWebhookTargetOptions[\"onLastPathTargetRemoved\"]; }): RegisteredWebhookTarget;","entrypoint":"webhook-ingress","exportName":"registerWebhookTargetWithPluginRoute","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"} +{"closureHash":"be22786e1216207a094c5af50bf78e4dccfe823360ad5174d618a3a483dbdb92","declaration":"export function registerWebhookTargetWithPluginRoute(params: { targetsByPath: Map; target: T; route: RegisterWebhookPluginRouteOptions; onLastPathTargetRemoved?: RegisterWebhookTargetOptions[\"onLastPathTargetRemoved\"]; }): RegisteredWebhookTarget;","entrypoint":"webhook-ingress","exportName":"registerWebhookTargetWithPluginRoute","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"} {"closureHash":"ec2f47e9bd7a075a3dd4302ac9e4c0bfe20630445db6735cf803f2d354275841","declaration":"export function requestBodyErrorToText(code: RequestBodyLimitErrorCode): string;","entrypoint":"webhook-ingress","exportName":"requestBodyErrorToText","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"} {"closureHash":"5e1f3b468d56eb0f82104184077fdf4b6bd0c1444aa10b71a65fcaa2ec0298a2","declaration":"export function resolveRequestClientIp(req?: IncomingMessage, trustedProxies?: string[], allowRealIpFallback?: boolean): string | undefined;","entrypoint":"webhook-ingress","exportName":"resolveRequestClientIp","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"} {"closureHash":"56c3e9868dfa6ee2a7a128eb02039a16b52696759adadbd3fe0a3bd7a6a07eeb","declaration":"export function resolveSingleWebhookTarget(targets: readonly T[], isMatch: (target: T) => boolean): WebhookTargetMatchResult;","entrypoint":"webhook-ingress","exportName":"resolveSingleWebhookTarget","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"function","recordType":"export"} @@ -4702,7 +4702,7 @@ {"closureHash":"efb74e84339c15d6f607b38d1d477b0504d47d04ae78e77083a1893c756a0b54","declaration":"export const WEBHOOK_RATE_LIMIT_DEFAULTS: Readonly<{ windowMs: 60000; maxRequests: 120; maxTrackedKeys: 4096;}>;","entrypoint":"webhook-ingress","exportName":"WEBHOOK_RATE_LIMIT_DEFAULTS","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"const","recordType":"export"} {"closureHash":"13b28ec9acae43c3bdcd683b9831154f88118dee8142e42b7eebfd59f08c602c","declaration":"export type BoundedCounter = BoundedCounter;","entrypoint":"webhook-ingress","exportName":"BoundedCounter","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"} {"closureHash":"9e737ae8c17038ef7becbd2bf1b756cfeaed571e2ded368c0fe3a446ebd1f666","declaration":"export type FixedWindowRateLimiter = FixedWindowRateLimiter;","entrypoint":"webhook-ingress","exportName":"FixedWindowRateLimiter","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"} -{"closureHash":"893d5497c2ac3593833ae7b0fdb3dc95c9c1080ce31f16a5f46454b163933559","declaration":"export type RegisterWebhookPluginRouteOptions = RegisterWebhookPluginRouteOptions;","entrypoint":"webhook-ingress","exportName":"RegisterWebhookPluginRouteOptions","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"} +{"closureHash":"3c27ecc04b6b3a0fbd65e2803d5cc67af4aa4eefbb8b2071bdd046d4feeb78d5","declaration":"export type RegisterWebhookPluginRouteOptions = RegisterWebhookPluginRouteOptions;","entrypoint":"webhook-ingress","exportName":"RegisterWebhookPluginRouteOptions","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"} {"closureHash":"b3e98619854462acfac6538ac9a2d0cefb88704a0eac712563f0996b07364152","declaration":"export type RegisterWebhookTargetOptions = RegisterWebhookTargetOptions;","entrypoint":"webhook-ingress","exportName":"RegisterWebhookTargetOptions","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"} {"closureHash":"964c2bfd8f268c411ee7b982c9de02c207f4bec402dd62c9f998a59752bb9d1f","declaration":"export type RegisteredWebhookTarget = RegisteredWebhookTarget;","entrypoint":"webhook-ingress","exportName":"RegisteredWebhookTarget","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"} {"closureHash":"aa552e5bdaefc9eb94d3b5a5cdf8c413fad555d9f452c6a2a6af5a3ce695c9d1","declaration":"export type WebhookAnomalyTracker = WebhookAnomalyTracker;","entrypoint":"webhook-ingress","exportName":"WebhookAnomalyTracker","importSpecifier":"openclaw/plugin-sdk/webhook-ingress","kind":"type","recordType":"export"} diff --git a/scripts/lib/export-name-collision-baseline.json b/scripts/lib/export-name-collision-baseline.json index 8164a987396e..308601c9fb7d 100644 --- a/scripts/lib/export-name-collision-baseline.json +++ b/scripts/lib/export-name-collision-baseline.json @@ -115,6 +115,14 @@ "src/sessions/classify-session-kind.ts" ] }, + { + "name": "cleanupSessionLifecycleArtifacts", + "files": [ + "src/config/sessions/session-accessor.sqlite-lifecycle.ts", + "src/plugin-sdk/session-store-runtime.ts" + ], + "sdk": true + }, { "name": "clearPluginRegistryLoadCache", "files": [ @@ -748,6 +756,14 @@ "src/commands/gateway-status/helpers.ts" ] }, + { + "name": "patchSessionEntry", + "files": [ + "src/config/sessions/session-accessor.sqlite-entry.ts", + "src/plugin-sdk/session-store-runtime.ts" + ], + "sdk": true + }, { "name": "pathExists", "files": [ @@ -830,6 +846,14 @@ ], "sdk": true }, + { + "name": "readSessionUpdatedAt", + "files": [ + "src/config/sessions/session-accessor.sqlite-entry.ts", + "src/plugin-sdk/session-store-runtime.ts" + ], + "sdk": true + }, { "name": "recordHookInstall", "files": [ @@ -1200,6 +1224,14 @@ "src/plugins/update-installed.ts" ] }, + { + "name": "upsertSessionEntry", + "files": [ + "src/config/sessions/session-accessor.sqlite-entry.ts", + "src/plugin-sdk/session-store-runtime.ts" + ], + "sdk": true + }, { "name": "VERSION", "files": [ diff --git a/scripts/lib/session-accessor-debt-baseline.json b/scripts/lib/session-accessor-debt-baseline.json index 7cb71a72b998..61c67dab4ee8 100644 --- a/scripts/lib/session-accessor-debt-baseline.json +++ b/scripts/lib/session-accessor-debt-baseline.json @@ -6,7 +6,7 @@ "src/agents/subagents/announce/subagent-announce.test-support.ts": 2, "src/agents/tools/transcripts-tool.ts": 2, "src/auto-reply/reply/commands-session-store.ts": 2, - "src/config/sessions/session-accessor.entry.ts": 2 + "src/config/sessions/session-accessor.entry.ts": 1 }, "sessionAccessorWrite": { "src/agents/subagents/spawn/subagent-spawn.test-helpers.ts": 1, @@ -22,7 +22,6 @@ "src/agents/embedded-agent-runner/compaction-hooks.ts": 2, "src/agents/embedded-agent-runner/thinking-replay-repair.ts": 2, "src/agents/embedded-agent-runner/tool-result-truncation.ts": 2, - "src/config/sessions/session-accessor.sqlite-events.ts": 3, - "src/config/sessions/session-accessor.transcript.ts": 2 + "src/config/sessions/session-accessor.sqlite-events.ts": 3 } } diff --git a/scripts/sqlite-session-entry-cache-lifetime-proof.ts b/scripts/sqlite-session-entry-cache-lifetime-proof.ts index 8f3df2c20b54..20b758aa6b4b 100644 --- a/scripts/sqlite-session-entry-cache-lifetime-proof.ts +++ b/scripts/sqlite-session-entry-cache-lifetime-proof.ts @@ -27,7 +27,7 @@ const importSource = async (relativePath: string) => const { upsertSessionEntry } = (await importSource( "src/config/sessions/session-accessor.js", )) as SessionAccessorModule; -const { readSqliteSessionEntryCache } = (await importSource( +const { readSessionEntryCache } = (await importSource( "src/config/sessions/session-accessor.sqlite-entry-cache.js", )) as EntryCacheModule; const { @@ -87,7 +87,7 @@ try { for (const scope of readOnlyScopes) { const result = withOpenClawAgentDatabaseReadOnly((database) => { - const snapshot = readSqliteSessionEntryCache(database, { cache: true }); + const snapshot = readSessionEntryCache(database, { cache: true }); assert.deepEqual(snapshot.keys, [scope.sessionKey]); readOnlyConnectionRefs.push(new WeakRef(database.db)); return snapshot.keys.length; @@ -112,7 +112,7 @@ try { updatedAt: index + 1, }); const database = openOpenClawAgentDatabase(scope); - const snapshot = readSqliteSessionEntryCache(database, { cache: true }); + const snapshot = readSessionEntryCache(database, { cache: true }); assert.deepEqual(snapshot.keys, [scope.sessionKey]); lruConnectionRefs.push(new WeakRef(database.db)); lruPaths.push(database.path); @@ -149,7 +149,7 @@ try { database: "real-node-sqlite", read_only_lifecycle: "withOpenClawAgentDatabaseReadOnly", writable_lifecycle: "openOpenClawAgentDatabase LRU", - cache: "readSqliteSessionEntryCache", + cache: "readSessionEntryCache", }, read_only_entry_count: readOnlyEntryCount, read_only_payload_bytes_per_entry: readOnlyPayloadBytes, diff --git a/src/agents/embedded-agent-runner/run/attempt-dispatch-preparation.ts b/src/agents/embedded-agent-runner/run/attempt-dispatch-preparation.ts index 53e46aedbffa..df11c3d79490 100644 --- a/src/agents/embedded-agent-runner/run/attempt-dispatch-preparation.ts +++ b/src/agents/embedded-agent-runner/run/attempt-dispatch-preparation.ts @@ -1,6 +1,6 @@ import fs from "node:fs/promises"; import { resolveStorePath } from "../../../config/sessions.js"; -import { resolveSessionTranscriptRuntimeReadTarget } from "../../../config/sessions/session-accessor.js"; +import { resolveSessionTranscriptRuntimeTarget } from "../../../config/sessions/session-accessor.js"; import type { resolveContextEngine } from "../../../context-engine/registry.js"; import { attachModelProviderRuntimePluginHandle } from "../../../plugins/provider-hook-runtime.js"; import { createTrajectoryRuntimeRecorder } from "../../../trajectory/runtime.js"; @@ -120,7 +120,7 @@ export async function prepareAndDispatchEmbeddedRunAttempt(input: { const resolvedTranscriptTarget = reusableSessionTarget ?? (resolvedSessionKey - ? await resolveSessionTranscriptRuntimeReadTarget({ + ? await resolveSessionTranscriptRuntimeTarget({ agentId: workspaceResolution.agentId, sessionId: sessionPromptState.sessionId, sessionKey: resolvedSessionKey, diff --git a/src/agents/embedded-agent-runner/run/attempt-transcript-helpers.ts b/src/agents/embedded-agent-runner/run/attempt-transcript-helpers.ts index bd1c59d202db..f8fa71e45ab5 100644 --- a/src/agents/embedded-agent-runner/run/attempt-transcript-helpers.ts +++ b/src/agents/embedded-agent-runner/run/attempt-transcript-helpers.ts @@ -3,7 +3,7 @@ import { resolveStorePath } from "../../../config/sessions/paths.js"; import { loadSessionEntry, loadTranscriptEvents, - resolveSessionTranscriptRuntimeReadTarget, + resolveSessionTranscriptRuntimeTarget, updateSessionEntry, } from "../../../config/sessions/session-accessor.js"; import { resolveQuotaSuspensionEntryMaintenance } from "../../../config/sessions/store-maintenance.js"; @@ -148,7 +148,7 @@ export async function resolveAttemptTrajectorySessionFile(params: { return params.sessionFile; } return ( - await resolveSessionTranscriptRuntimeReadTarget({ + await resolveSessionTranscriptRuntimeTarget({ agentId: params.agentId, sessionId: params.sessionId, sessionKey: params.sessionKey, diff --git a/src/agents/embedded-agent-runner/transcript-runtime-state.ts b/src/agents/embedded-agent-runner/transcript-runtime-state.ts index e26cccf7c47f..dc37dcd9957d 100644 --- a/src/agents/embedded-agent-runner/transcript-runtime-state.ts +++ b/src/agents/embedded-agent-runner/transcript-runtime-state.ts @@ -2,7 +2,7 @@ import type { SessionTranscriptRuntimeScope, SessionTranscriptRuntimeTarget, } from "../../config/sessions/session-accessor.js"; -import { resolveSessionTranscriptRuntimeReadTarget } from "../../config/sessions/session-accessor.js"; +import { resolveSessionTranscriptRuntimeTarget } from "../../config/sessions/session-accessor.js"; export type RuntimeTranscriptScope = SessionTranscriptRuntimeScope; type RuntimeTranscriptTarget = SessionTranscriptRuntimeTarget; @@ -14,5 +14,5 @@ type RuntimeTranscriptTarget = SessionTranscriptRuntimeTarget; export async function resolveRuntimeTranscriptReadTarget( scope: RuntimeTranscriptScope, ): Promise { - return await resolveSessionTranscriptRuntimeReadTarget(scope); + return await resolveSessionTranscriptRuntimeTarget(scope); } diff --git a/src/auto-reply/reply/agent-runner-memory.test.ts b/src/auto-reply/reply/agent-runner-memory.test.ts index b5263c325674..929b4659f90f 100644 --- a/src/auto-reply/reply/agent-runner-memory.test.ts +++ b/src/auto-reply/reply/agent-runner-memory.test.ts @@ -13,7 +13,7 @@ import { readTranscriptStatsSync, upsertSessionEntry, } from "../../config/sessions/session-accessor.js"; -import { replaceSqliteTranscriptEvents } from "../../config/sessions/session-accessor.sqlite-transcript-write.js"; +import { replaceTranscriptEvents } from "../../config/sessions/session-accessor.sqlite-transcript-write.js"; import { resolveSessionStorePathForScope } from "../../config/sessions/session-store-path.js"; import { clearMemoryPluginState, @@ -126,7 +126,7 @@ function loadMainSessionEntry(storePath: string): SessionEntry { async function writeTestSessionTranscript(params: { rootDir: string; - events: Parameters[1]; + events: Parameters[1]; sessionKey?: string; sessionId?: string; }): Promise { @@ -139,7 +139,7 @@ async function writeTestSessionTranscript(params: { storePath: path.join(params.rootDir, "sessions.json"), }; await upsertSessionEntry(scope, { sessionId, updatedAt: 10 }); - await replaceSqliteTranscriptEvents(scope, params.events); + await replaceTranscriptEvents(scope, params.events); } type RefreshQueuedFollowupSessionParams = { @@ -560,7 +560,7 @@ describe("runMemoryFlushIfNeeded", () => { const sessionKey = "agent:main:main"; const scope = { agentId: "main", sessionId: "session", sessionKey, storePath }; await upsertSessionEntry(scope, { sessionId: "session", updatedAt: 10 }); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { type: "message", message: { role: "user", content: "Research this", __openclaw: { senderIsOwner: true } }, @@ -3209,7 +3209,7 @@ describe("runMemoryFlushIfNeeded", () => { const sessionKey = "agent:main:main"; const scope = { agentId: "main", sessionId: "session", sessionKey, storePath }; await upsertSessionEntry(scope, { sessionId: "session", updatedAt: 10 }); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { message: { role: "user", content: "x".repeat(256) }, type: "message" }, ]); expect(readTranscriptStatsSync(scope).sizeBytes).toBeGreaterThan(10); @@ -3269,7 +3269,7 @@ describe("runMemoryFlushIfNeeded", () => { const sessionKey = "agent:main:main"; const scope = { agentId: "main", sessionId: "session", sessionKey, storePath }; await upsertSessionEntry(scope, { sessionId: "session", updatedAt: 10 }); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { message: { role: "user", content: "small" }, type: "message" }, ]); expect(readTranscriptStatsSync(scope).sizeBytes).toBeLessThan(10 * 1024); @@ -3330,7 +3330,7 @@ describe("runMemoryFlushIfNeeded", () => { const sessionKey = "agent:main:main"; const scope = { agentId: "main", sessionId: "session", sessionKey, storePath }; await upsertSessionEntry(scope, { sessionId: "session", updatedAt: 10 }); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { message: { role: "user", content: "x".repeat(256) }, type: "message" }, ]); expect(readTranscriptStatsSync(scope).sizeBytes).toBeGreaterThan(10); @@ -3402,7 +3402,7 @@ describe("runMemoryFlushIfNeeded", () => { const sessionKey = "agent:main:main"; const scope = { agentId: "main", sessionId: "session", sessionKey, storePath }; await upsertSessionEntry(scope, { sessionId: "session", updatedAt: 10 }); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { message: { role: "user", content: "x".repeat(256) }, type: "message" }, ]); expect(readTranscriptStatsSync(scope).sizeBytes).toBeGreaterThan(10); @@ -3577,7 +3577,7 @@ describe("runMemoryFlushIfNeeded", () => { parentId = id; return event; }); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ activeRoot, ...abandonedBranch, { @@ -3624,7 +3624,7 @@ describe("runMemoryFlushIfNeeded", () => { const sessionKey = "agent:main:main"; const scope = { agentId: "main", sessionId: "session", sessionKey, storePath }; await upsertSessionEntry(scope, { sessionId: "session", updatedAt: 10 }); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { message: { role: "user", content: "x".repeat(256) }, type: "message" }, ]); const sessionEntry: SessionEntry = { diff --git a/src/auto-reply/reply/session-fork.test.ts b/src/auto-reply/reply/session-fork.test.ts index eff33d6fc8fa..ba725f232341 100644 --- a/src/auto-reply/reply/session-fork.test.ts +++ b/src/auto-reply/reply/session-fork.test.ts @@ -8,7 +8,7 @@ import { loadTranscriptEvents, replaceSessionEntry, } from "../../config/sessions/session-accessor.js"; -import { replaceSqliteTranscriptEvents } from "../../config/sessions/session-accessor.sqlite-transcript-write.js"; +import { replaceTranscriptEvents } from "../../config/sessions/session-accessor.sqlite-transcript-write.js"; import type { InternalSessionEntry } from "../../config/sessions/types.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { @@ -120,7 +120,7 @@ describe("forkSessionEntryFromParent", () => { updatedAt: 10, }, ); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { agentId: "main", sessionId: "parent-session", @@ -290,7 +290,7 @@ describe("forkSessionEntryFromParent", () => { totalTokensFresh: false, updatedAt: 1, }; - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { agentId: "main", sessionId: parentEntry.sessionId, @@ -334,7 +334,7 @@ describe("forkSessionEntryFromParent", () => { totalTokensFresh: false, updatedAt: 1, }; - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { agentId: "main", sessionId: parentEntry.sessionId, @@ -387,7 +387,7 @@ describe("forkSessionEntryFromParent", () => { totalTokensFresh: false, updatedAt: 1, }; - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { agentId: "main", sessionId: parentEntry.sessionId, @@ -469,7 +469,7 @@ describe("forkSessionEntryFromParent", () => { totalTokensFresh: false, updatedAt: 1, }; - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { agentId: "main", sessionId: parentEntry.sessionId, diff --git a/src/commands/agent.worktree-race.test.ts b/src/commands/agent.worktree-race.test.ts index 4f81ce937e32..83005604a35d 100644 --- a/src/commands/agent.worktree-race.test.ts +++ b/src/commands/agent.worktree-race.test.ts @@ -10,7 +10,7 @@ import { prepareAgentCommandExecution } from "../agents/command/prepare.js"; import { ensureAgentWorkspace } from "../agents/workspace.js"; import { getRegistryWorktree } from "../agents/worktrees/registry.js"; import { managedWorktrees } from "../agents/worktrees/service.js"; -import { upsertSqliteSessionEntry } from "../config/sessions/session-accessor.sqlite-entry.js"; +import { upsertSessionEntry } from "../config/sessions/session-accessor.sqlite-entry.js"; import { clearSessionStoreCacheForTest } from "../config/sessions/store-writer-state.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { closeOpenClawStateDatabaseForTest } from "../state/openclaw-state-db.js"; @@ -74,7 +74,7 @@ async function seedSession( spawnedCwd: string, worktree?: { id: string; branch: string; repoRoot: string }, ): Promise { - await upsertSqliteSessionEntry( + await upsertSessionEntry( { agentId: "main", sessionKey, storePath }, { sessionId: "session-worktree-race", diff --git a/src/commands/doctor-session-canonical-keys.ts b/src/commands/doctor-session-canonical-keys.ts index cb6ea0e614c8..c6897addafd5 100644 --- a/src/commands/doctor-session-canonical-keys.ts +++ b/src/commands/doctor-session-canonical-keys.ts @@ -11,12 +11,12 @@ import { rehomeSessionDeliveryReferencesForCanonicalRepairBatch, } from "../config/sessions/session-accessor.js"; import type { SessionEntryLifecycleRemoval } from "../config/sessions/session-accessor.lifecycle-types.js"; -import { writeSqliteTranscriptArchive } from "../config/sessions/session-accessor.sqlite-archive.js"; +import { writeTranscriptArchive } from "../config/sessions/session-accessor.sqlite-archive.js"; import { copySessionNodeArtifactsForRepair, deleteSessionMembersForRepair, } from "../config/sessions/session-accessor.sqlite-node-artifacts.js"; -import { collectSqliteSessionStateIdsForEntry } from "../config/sessions/session-accessor.sqlite-references.js"; +import { collectSessionStateIdsForEntry } from "../config/sessions/session-accessor.sqlite-references.js"; import { resolveSqliteTranscriptArchiveDirectory } from "../config/sessions/session-accessor.sqlite-scope.js"; import { setCanonicalSqliteSessionMainKey } from "../config/sessions/session-canonical-key.js"; import { resolveDeliveryProvenCanonicalSessionKey } from "../config/sessions/store-entry.js"; @@ -521,7 +521,7 @@ async function repairCanonicalSessionGroup( sourceKeys: [winner.sessionKey], storePath: winner.storePath, }), - ...collectSqliteSessionStateIdsForEntry(winner.entry), + ...collectSessionStateIdsForEntry(winner.entry), ]); for (const sessionId of generationIds) { if (!sessionId) { @@ -556,7 +556,7 @@ async function repairCanonicalSessionGroup( env: params.env, path: destination.sqlitePath, }); - writeSqliteTranscriptArchive({ + writeTranscriptArchive({ archiveDirectory, content: destinationContent, reason: "deleted", diff --git a/src/commands/doctor-session-entry-rewrite.ts b/src/commands/doctor-session-entry-rewrite.ts index 8104478fffba..8bfd4fd96189 100644 --- a/src/commands/doctor-session-entry-rewrite.ts +++ b/src/commands/doctor-session-entry-rewrite.ts @@ -1,6 +1,6 @@ import { - publishSqliteSessionEntryCacheInvalidation, - trackSqliteSessionEntryCacheWrite, + publishSessionEntryCacheInvalidation, + trackSessionEntryCacheWrite, } from "../config/sessions/session-accessor.sqlite-entry-cache.js"; import { parseSqliteSessionEntryRecord } from "../config/sessions/session-entry-json.js"; import { executeSqliteQuerySync, getNodeSqliteKysely } from "../infra/kysely-sync.js"; @@ -24,7 +24,7 @@ export function writeValidatedDoctorSessionEntryJson( throw new Error(`Refusing invalid SQLite session entry rewrite for ${row.session_key}`); } const db = getNodeSqliteKysely(database.db); - const writeGeneration = trackSqliteSessionEntryCacheWrite(database, () => { + const writeGeneration = trackSessionEntryCacheWrite(database, () => { executeSqliteQuerySync( database.db, db @@ -44,7 +44,7 @@ export function writeValidatedDoctorSessionEntryJson( }); // The transaction owner defers this row publication until commit; rollback must never // expose repaired JSON through a warm connection-local session cache. - publishSqliteSessionEntryCacheInvalidation( + publishSessionEntryCacheInvalidation( database, { ...row, entry_json: entryJson }, writeGeneration, diff --git a/src/commands/doctor-session-incognito-key-repair.ts b/src/commands/doctor-session-incognito-key-repair.ts index 8e4e1eb30cce..c06cc05a4ca3 100644 --- a/src/commands/doctor-session-incognito-key-repair.ts +++ b/src/commands/doctor-session-incognito-key-repair.ts @@ -1,6 +1,6 @@ import fs from "node:fs"; import type { DatabaseSync } from "node:sqlite"; -import { publishSqliteSessionEntryCacheInvalidation } from "../config/sessions/session-accessor.sqlite-entry-cache.js"; +import { publishSessionEntryCacheInvalidation } from "../config/sessions/session-accessor.sqlite-entry-cache.js"; import { resolveAllAgentSessionStoreCandidateTargetsSync } from "../config/sessions/targets.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { executeSqliteQuerySync, getNodeSqliteKysely } from "../infra/kysely-sync.js"; @@ -178,7 +178,7 @@ function applyReservedIncognitoKeyRenames( } rewriteSessionEntryJsonReferences(database, new Map(renames.map((item) => [item.from, item.to]))); // Key and lineage columns reshape the cached map even when no entry JSON needs rewriting. - publishSqliteSessionEntryCacheInvalidation(database); + publishSessionEntryCacheInvalidation(database); } function legacyIncognitoSessionKey(sessionKey: string): string { diff --git a/src/commands/doctor-session-sqlite.test.ts b/src/commands/doctor-session-sqlite.test.ts index 352e9f70ad2b..75a32e339dd2 100644 --- a/src/commands/doctor-session-sqlite.test.ts +++ b/src/commands/doctor-session-sqlite.test.ts @@ -8,12 +8,12 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { useAutoCleanupTempDirTracker } from "../../test/helpers/temp-dir.js"; import { CURRENT_SESSION_VERSION, SessionManager } from "../agents/sessions/session-manager.js"; import { - loadExactSqliteSessionEntry, - upsertSqliteSessionEntry, + loadExactSessionEntry, + upsertSessionEntry, } from "../config/sessions/session-accessor.sqlite-entry.js"; import { - loadSqliteTranscriptEventsSync, - readSqliteTranscriptStatsSync, + loadTranscriptEventsSync, + readTranscriptStatsSync, } from "../config/sessions/session-accessor.sqlite-read.js"; import * as nodeSqlite from "../infra/node-sqlite.js"; import * as replaceFile from "../infra/replace-file.js"; @@ -259,7 +259,7 @@ describe("runDoctorSessionSqlite", () => { const stateDir = path.join(tempDir, "state"); const storePath = path.join(stateDir, "agents", "main", "sessions", "sessions.json"); const env = { ...process.env, OPENCLAW_STATE_DIR: stateDir }; - await upsertSqliteSessionEntry( + await upsertSessionEntry( { agentId: "main", env, sessionKey: "agent:main:main", storePath }, { sessionId: "sqlite-session", updatedAt: Date.now() }, ); @@ -440,14 +440,14 @@ describe("runDoctorSessionSqlite", () => { }); expect(report.totals).toMatchObject({ importedEntries: 1, issues: 0 }); - const imported = loadExactSqliteSessionEntry({ + const imported = loadExactSessionEntry({ agentId: "main", sessionKey: "agent:main:main", storePath: store.storePath, }); // The SQLite runtime does no read repair, so import must store canonical shapes. expect(typeof sessionDeliveryRoute(imported?.entry)).not.toBe("string"); - const events = loadSqliteTranscriptEventsSync({ + const events = loadTranscriptEventsSync({ agentId: "main", sessionId: "session-1", sessionKey: "agent:main:main", @@ -562,7 +562,7 @@ describe("runDoctorSessionSqlite", () => { expect(report.totals).toMatchObject({ importedEntries: 1, issues: 0 }); expect( - readSqliteTranscriptStatsSync({ + readTranscriptStatsSync({ agentId: "main", sessionId: "session-1", sessionKey: "agent:main:main", @@ -575,7 +575,7 @@ describe("runDoctorSessionSqlite", () => { const store = createLegacyStore({ entryOverrides: { lifecycleRevision: "rev-1" }, }); - await upsertSqliteSessionEntry( + await upsertSessionEntry( { agentId: "main", env: store.env, @@ -598,7 +598,7 @@ describe("runDoctorSessionSqlite", () => { expect(report.totals).toMatchObject({ importedEntries: 1, issues: 0 }); expect( - loadExactSqliteSessionEntry({ + loadExactSessionEntry({ agentId: "main", sessionKey: "agent:main:main", storePath: store.storePath, @@ -684,14 +684,14 @@ describe("runDoctorSessionSqlite", () => { expect(inspect.totals.sqliteEntries).toBe(1); expect(inspect.totals.unreferencedJsonlFiles).toBe(0); expect( - loadExactSqliteSessionEntry({ + loadExactSessionEntry({ agentId: "main", sessionKey: "agent:main:main", storePath: store.storePath, })?.entry, ).not.toHaveProperty("sessionFile"); expect( - loadSqliteTranscriptEventsSync({ + loadTranscriptEventsSync({ agentId: "main", sessionId: "session-1", sessionKey: "agent:main:main", @@ -1085,7 +1085,7 @@ describe("runDoctorSessionSqlite", () => { validatedTranscriptEvents: 0, }); expect( - loadExactSqliteSessionEntry({ + loadExactSessionEntry({ agentId: "main", sessionKey: "agent:main:main", storePath: store.storePath, @@ -2466,14 +2466,14 @@ describe("runDoctorSessionSqlite", () => { }); expect(fs.existsSync(store.transcriptPath)).toBe(false); expect( - loadExactSqliteSessionEntry({ + loadExactSessionEntry({ agentId: "main", sessionKey: "agent:main:main", storePath: store.storePath, })?.entry.sessionId, ).toBe("session-1"); expect( - loadExactSqliteSessionEntry({ + loadExactSessionEntry({ agentId: "main", sessionKey: "agent:main:alias", storePath: store.storePath, @@ -2522,7 +2522,7 @@ describe("runDoctorSessionSqlite", () => { sqliteEntries: 1, }); expect( - loadSqliteTranscriptEventsSync({ + loadTranscriptEventsSync({ agentId: "codex-proof", sessionId: "session-1", sessionKey: "agent:main:main", @@ -2552,14 +2552,14 @@ describe("runDoctorSessionSqlite", () => { sessionKey: "agent:main:main", }); expect( - loadExactSqliteSessionEntry({ + loadExactSessionEntry({ agentId: "main", sessionKey: "agent:main:main", storePath: store.storePath, })?.entry.sessionId, ).toBe("session-1"); expect( - loadSqliteTranscriptEventsSync({ + loadTranscriptEventsSync({ agentId: "main", sessionId: "session-1", sessionKey: "agent:main:main", @@ -2620,14 +2620,14 @@ describe("runDoctorSessionSqlite", () => { expect(fs.existsSync(mainTranscriptPath)).toBe(true); expect(fs.existsSync(workTranscriptPath)).toBe(true); expect( - loadExactSqliteSessionEntry({ + loadExactSessionEntry({ agentId: "main", sessionKey: "agent:main:main", storePath, })?.entry.sessionId, ).toBe("main-session"); expect( - loadExactSqliteSessionEntry({ + loadExactSessionEntry({ agentId: "work", sessionKey: "agent:work:main", storePath, @@ -2703,14 +2703,14 @@ describe("runDoctorSessionSqlite", () => { expect(target.completedMoves.some((move) => move.kind === "legacy-store")).toBe(true); } expect( - loadExactSqliteSessionEntry({ + loadExactSessionEntry({ agentId: "main", sessionKey: "agent:main:main", storePath, })?.entry.sessionId, ).toBe("main-session"); expect( - loadExactSqliteSessionEntry({ + loadExactSessionEntry({ agentId: "work", sessionKey: "agent:work:main", storePath, @@ -2735,7 +2735,7 @@ describe("runDoctorSessionSqlite", () => { fs.writeFileSync(store.transcriptPath, '{"type":"event","id":"heartbeat"}\n', { mode: 0o600, }); - await upsertSqliteSessionEntry( + await upsertSessionEntry( { agentId: "main", env: store.env, @@ -3028,7 +3028,7 @@ describe("runDoctorSessionSqlite", () => { issues: 0, }); expect( - loadSqliteTranscriptEventsSync({ + loadTranscriptEventsSync({ agentId: "main", sessionId: "session-1", sessionKey: "agent:main:main", @@ -3058,7 +3058,7 @@ describe("runDoctorSessionSqlite", () => { ), ).toBe(true); expect( - loadSqliteTranscriptEventsSync({ + loadTranscriptEventsSync({ agentId: "main", sessionId: "session-1", sessionKey: "agent:main:main", @@ -3088,7 +3088,7 @@ describe("runDoctorSessionSqlite", () => { sqliteEntries: 1, }); expect( - loadSqliteTranscriptEventsSync({ + loadTranscriptEventsSync({ agentId: "main", sessionId: "session-1", sessionKey: "agent:main:main", @@ -3129,7 +3129,7 @@ describe("runDoctorSessionSqlite", () => { expect(fs.existsSync(store.unreferencedJsonlPath)).toBe(false); expect(inspect.totals.sqliteEntries).toBe(1); expect( - loadSqliteTranscriptEventsSync({ + loadTranscriptEventsSync({ agentId: "token-supersecret", sessionId: "session-1", sessionKey: "agent:main:main", @@ -3150,7 +3150,7 @@ describe("runDoctorSessionSqlite", () => { it("reports malformed selected legacy transcripts during validation", async () => { const store = createLegacyStore({ transcriptLines: ['{"type":"session"}', "{bad"] }); - await upsertSqliteSessionEntry( + await upsertSessionEntry( { agentId: "main", env: store.env, diff --git a/src/commands/doctor-session-transcript-headers.test.ts b/src/commands/doctor-session-transcript-headers.test.ts index bf9b25b12ec3..cf79d676b8e1 100644 --- a/src/commands/doctor-session-transcript-headers.test.ts +++ b/src/commands/doctor-session-transcript-headers.test.ts @@ -6,7 +6,7 @@ import { replaceTranscriptEventsSync, upsertSessionEntry, } from "../config/sessions/session-accessor.js"; -import { readSqliteTranscriptStorageRows } from "../config/sessions/session-accessor.sqlite-read.js"; +import { readTranscriptStorageRows } from "../config/sessions/session-accessor.sqlite-read.js"; import { CURRENT_SESSION_VERSION } from "../config/sessions/version.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { @@ -105,7 +105,7 @@ describe("doctor SQLite session transcript header repair", () => { ]); const databaseOptions = { agentId: AGENT_ID, env: state.env }; const database = openOpenClawAgentDatabase(databaseOptions); - const beforeRows = readSqliteTranscriptStorageRows(database, SESSION_ID); + const beforeRows = readTranscriptStorageRows(database, SESSION_ID); runOpenClawAgentWriteTransaction((transactionDatabase) => { transactionDatabase.db .prepare( @@ -121,7 +121,7 @@ describe("doctor SQLite session transcript header repair", () => { await expect( noteSessionTranscriptHeaderHealth({ cfg, env: state.env, shouldRepair: false }), ).resolves.toEqual({ found: 1, repaired: 0 }); - expect(readSqliteTranscriptStorageRows(database, SESSION_ID)).toEqual(beforeRows); + expect(readTranscriptStorageRows(database, SESSION_ID)).toEqual(beforeRows); expect(note).toHaveBeenCalledWith( '- Found 1 canonical session transcript without a header.\n- Run "openclaw doctor --fix" to repair it before resuming the session.', "Session transcript headers", @@ -132,7 +132,7 @@ describe("doctor SQLite session transcript header repair", () => { noteSessionTranscriptHeaderHealth({ cfg, env: state.env, shouldRepair: true }), ).resolves.toEqual({ found: 1, repaired: 1 }); - const repairedRows = readSqliteTranscriptStorageRows(database, SESSION_ID); + const repairedRows = readTranscriptStorageRows(database, SESSION_ID); const repairedEvents = repairedRows.map((row) => JSON.parse(row.eventJson)); expect(repairedEvents[0]).toMatchObject({ type: "session", @@ -191,11 +191,11 @@ describe("doctor SQLite session transcript header repair", () => { ); note.mockClear(); - const afterFirstRepair = readSqliteTranscriptStorageRows(database, SESSION_ID); + const afterFirstRepair = readTranscriptStorageRows(database, SESSION_ID); await expect( noteSessionTranscriptHeaderHealth({ cfg, env: state.env, shouldRepair: true }), ).resolves.toEqual({ found: 0, repaired: 0 }); - expect(readSqliteTranscriptStorageRows(database, SESSION_ID)).toEqual(afterFirstRepair); + expect(readTranscriptStorageRows(database, SESSION_ID)).toEqual(afterFirstRepair); expect(note).not.toHaveBeenCalled(); }); @@ -205,13 +205,13 @@ describe("doctor SQLite session transcript header repair", () => { { type: "message", message: { role: "hookMessage", content: "legacy hook" } }, ]); const database = openOpenClawAgentDatabase({ agentId: AGENT_ID, env: state.env }); - const before = readSqliteTranscriptStorageRows(database, SESSION_ID); + const before = readTranscriptStorageRows(database, SESSION_ID); await expect( noteSessionTranscriptHeaderHealth({ cfg, env: state.env, shouldRepair: true }), ).resolves.toEqual({ found: 0, repaired: 0 }); - expect(readSqliteTranscriptStorageRows(database, SESSION_ID)).toEqual(before); + expect(readTranscriptStorageRows(database, SESSION_ID)).toEqual(before); expect(() => SessionManager.open(scope, state.workspaceDir)).toThrow( "require doctor/import migration before runtime use", ); @@ -252,13 +252,13 @@ describe("doctor SQLite session transcript header repair", () => { ])("does not repair $name", async ({ events }) => { await seedHeaderlessTranscript(events); const database = openOpenClawAgentDatabase({ agentId: AGENT_ID, env: state.env }); - const before = readSqliteTranscriptStorageRows(database, SESSION_ID); + const before = readTranscriptStorageRows(database, SESSION_ID); await expect( noteSessionTranscriptHeaderHealth({ cfg, env: state.env, shouldRepair: true }), ).resolves.toEqual({ found: 0, repaired: 0 }); - expect(readSqliteTranscriptStorageRows(database, SESSION_ID)).toEqual(before); + expect(readTranscriptStorageRows(database, SESSION_ID)).toEqual(before); expect(() => SessionManager.open(scope, state.workspaceDir)).toThrow( "require doctor/import migration before runtime use", ); @@ -296,13 +296,13 @@ describe("doctor SQLite session transcript header repair", () => { .prepare("UPDATE transcript_events SET event_json = ? WHERE session_id = ? AND seq = 1") .run(JSON.stringify(duplicate), SESSION_ID); }, databaseOptions); - const before = readSqliteTranscriptStorageRows(database, SESSION_ID); + const before = readTranscriptStorageRows(database, SESSION_ID); await expect( noteSessionTranscriptHeaderHealth({ cfg, env: state.env, shouldRepair: true }), ).resolves.toEqual({ found: 0, repaired: 0 }); - expect(readSqliteTranscriptStorageRows(database, SESSION_ID)).toEqual(before); + expect(readTranscriptStorageRows(database, SESSION_ID)).toEqual(before); expect(note).not.toHaveBeenCalled(); }); @@ -325,7 +325,7 @@ describe("doctor SQLite session transcript header repair", () => { ).resolves.toEqual({ found: 1, repaired: 1 }); const database = openOpenClawAgentDatabase({ agentId: AGENT_ID, env: state.env }); - const header = JSON.parse(readSqliteTranscriptStorageRows(database, SESSION_ID)[0]!.eventJson); + const header = JSON.parse(readTranscriptStorageRows(database, SESSION_ID)[0]!.eventJson); expect(header).toMatchObject({ type: "session", cwd: state.workspaceDir }); }); @@ -357,7 +357,7 @@ describe("doctor SQLite session transcript header repair", () => { ).resolves.toEqual({ found: 1, repaired: 1 }); const database = openOpenClawAgentDatabase(databaseOptions); - const header = JSON.parse(readSqliteTranscriptStorageRows(database, SESSION_ID)[0]!.eventJson); + const header = JSON.parse(readTranscriptStorageRows(database, SESSION_ID)[0]!.eventJson); expect(header).toMatchObject({ type: "session", cwd: state.workspaceDir }); }); }); diff --git a/src/commands/doctor-session-transcript-headers.ts b/src/commands/doctor-session-transcript-headers.ts index 23166cbb6226..975d80b31b89 100644 --- a/src/commands/doctor-session-transcript-headers.ts +++ b/src/commands/doctor-session-transcript-headers.ts @@ -4,7 +4,7 @@ import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js"; import { isIndexedSessionEntry } from "../agents/sessions/session-manager-codec.js"; import type { TranscriptEvent } from "../config/sessions/session-accessor.js"; import { - readSqliteTranscriptStorageRows, + readTranscriptStorageRows, type SqliteTranscriptStorageRow, } from "../config/sessions/session-accessor.sqlite-read.js"; import { getSessionKysely } from "../config/sessions/session-accessor.sqlite-scope.js"; @@ -165,7 +165,7 @@ function assertRepairPreservedEvents(params: { database: OpenClawAgentDatabase; sessionId: string; }): void { - const after = readSqliteTranscriptStorageRows(params.database, params.sessionId); + const after = readTranscriptStorageRows(params.database, params.sessionId); if (after.length !== params.before.length + 1) { throw new Error(`header repair changed the event count for ${params.sessionId}`); } @@ -246,7 +246,7 @@ export async function noteSessionTranscriptHeaderHealth(params: { try { runOpenClawAgentWriteTransaction( (database) => { - const currentRows = readSqliteTranscriptStorageRows(database, sessionId); + const currentRows = readTranscriptStorageRows(database, sessionId); if (!snapshotsMatch(snapshot.rows, currentRows)) { throw new Error( `transcript changed while preparing header repair for ${sessionId}`, diff --git a/src/commands/doctor-session-transcript-labels.test.ts b/src/commands/doctor-session-transcript-labels.test.ts index cc7be845bb5f..1ba9d4af7a31 100644 --- a/src/commands/doctor-session-transcript-labels.test.ts +++ b/src/commands/doctor-session-transcript-labels.test.ts @@ -6,8 +6,8 @@ import { } from "../auto-reply/reply/strip-inbound-meta.js"; import type { TranscriptEvent } from "../config/sessions/session-accessor.js"; import { - readSqliteTranscriptEventRows, - readSqliteTranscriptSnapshot, + readTranscriptEventRows, + readTranscriptSnapshot, type SqliteTranscriptSnapshotRow, } from "../config/sessions/session-accessor.sqlite-read.js"; import { appendTranscriptEventsInTransaction } from "../config/sessions/session-accessor.sqlite-transcript-store.js"; @@ -219,13 +219,13 @@ describe("doctor SQLite session transcript label migration", () => { it("detects and idempotently rewrites legacy labels in user events", async () => { const databaseOptions = { agentId: AGENT_ID, env: state.env }; const database = seedLegacyLabelTranscript(databaseOptions); - const before = readSqliteTranscriptSnapshot(database, SESSION_ID); + const before = readTranscriptSnapshot(database, SESSION_ID); const assistantJson = findEventJson(before.events, before.rows, "assistant"); const midLineJson = findEventJson(before.events, before.rows, "mid-line-user"); await runTranscriptLabelHealth(state, false); - expect(readSqliteTranscriptSnapshot(database, SESSION_ID).rows).toEqual(before.rows); + expect(readTranscriptSnapshot(database, SESSION_ID).rows).toEqual(before.rows); expect(note).toHaveBeenCalledWith( '- Found 1 session with legacy inbound-context labels.\n- Run "openclaw doctor --fix" to rewrite them.', "Session transcript labels", @@ -234,7 +234,7 @@ describe("doctor SQLite session transcript label migration", () => { note.mockClear(); await runTranscriptLabelHealth(state, true); - const repaired = readSqliteTranscriptSnapshot(database, SESSION_ID); + const repaired = readTranscriptSnapshot(database, SESSION_ID); const repairedContent = findMessageContent(repaired.events, "legacy-user"); expect(typeof repairedContent).toBe("string"); expect(repairedContent).toContain("Conversation info:"); @@ -280,7 +280,7 @@ describe("doctor SQLite session transcript label migration", () => { const afterFirstRepair = repaired.rows; await runTranscriptLabelHealth(state, true); - expect(readSqliteTranscriptSnapshot(database, SESSION_ID).rows).toEqual(afterFirstRepair); + expect(readTranscriptSnapshot(database, SESSION_ID).rows).toEqual(afterFirstRepair); expect(note).not.toHaveBeenCalled(); }); @@ -299,7 +299,7 @@ describe("doctor SQLite session transcript label migration", () => { ]); await runTranscriptLabelHealth(state, true); - const repaired = readSqliteTranscriptSnapshot(database, SESSION_ID); + const repaired = readTranscriptSnapshot(database, SESSION_ID); const repairedContent = findMessageContent(repaired.events, "active-memory-user"); expect(typeof repairedContent).toBe("string"); expect(repairedContent).toContain("Context:\n"); @@ -324,7 +324,7 @@ describe("doctor SQLite session transcript label migration", () => { ]); await runTranscriptLabelHealth(state, true); - const repaired = readSqliteTranscriptSnapshot(database, SESSION_ID); + const repaired = readTranscriptSnapshot(database, SESSION_ID); const repairedContent = findMessageContent(repaired.events, "crlf-active-memory-user"); expect(typeof repairedContent).toBe("string"); expect(repairedContent).toContain("Context:\r\n"); @@ -358,7 +358,7 @@ describe("doctor SQLite session transcript label migration", () => { note.mockClear(); await runTranscriptLabelHealth(state, true, cfg); - const repaired = readSqliteTranscriptSnapshot(database, SESSION_ID); + const repaired = readTranscriptSnapshot(database, SESSION_ID); const repairedContent = findMessageContent(repaired.events, "legacy-user"); expect(repairedContent).toContain("Conversation info:"); expect(repairedContent).not.toContain("Conversation info (untrusted metadata):"); @@ -391,18 +391,18 @@ describe("doctor SQLite session transcript label migration", () => { const database = seedMessageTranscript(databaseOptions, [ { id: "user-prose", content: antiCorruptionContent }, ]); - const before = readSqliteTranscriptSnapshot(database, SESSION_ID); + const before = readTranscriptSnapshot(database, SESSION_ID); await runTranscriptLabelHealth(state, false); expect(note).not.toHaveBeenCalled(); - const after = readSqliteTranscriptSnapshot(database, SESSION_ID); + const after = readTranscriptSnapshot(database, SESSION_ID); expect(after.rows).toEqual(before.rows); await runTranscriptLabelHealth(state, true); - const final = readSqliteTranscriptSnapshot(database, SESSION_ID); + const final = readTranscriptSnapshot(database, SESSION_ID); const userContent = findMessageContent(final.events, "user-prose"); expect(userContent).toContain("Foo (untrusted metadata): this is not a fence"); @@ -432,7 +432,7 @@ describe("doctor SQLite session transcript label migration", () => { ]); await runTranscriptLabelHealth(state, true); - const repaired = readSqliteTranscriptSnapshot(database, SESSION_ID); + const repaired = readTranscriptSnapshot(database, SESSION_ID); const content = findMessageContent(repaired.events, "assistant-echo"); expect(typeof content).toBe("string"); // Migrated to the marked form so the marker-only strippers recognize and remove it. @@ -465,7 +465,7 @@ describe("doctor SQLite session transcript label migration", () => { "SELECT seq, created_at FROM transcript_events WHERE session_id = ? ORDER BY seq ASC", ) .all(SESSION_ID) as Array<{ created_at: number; seq: number }>; - const before = readSqliteTranscriptSnapshot(database, SESSION_ID); + const before = readTranscriptSnapshot(database, SESSION_ID); const beforeSeqs = before.rows.map((row) => row.seq); const beforeMetadata = readRowMetadata(); @@ -488,7 +488,7 @@ describe("doctor SQLite session transcript label migration", () => { await runTranscriptLabelHealth(state, true); - const after = readSqliteTranscriptSnapshot(database, SESSION_ID); + const after = readTranscriptSnapshot(database, SESSION_ID); const afterSeqs = after.rows.map((row) => row.seq); expect(afterSeqs).toEqual(beforeSeqs); @@ -554,13 +554,13 @@ describe("doctor SQLite session transcript label migration", () => { const database = seedMessageTranscript(databaseOptions, [ { id: "unfenced-test", content: unfencedContent }, ]); - const before = readSqliteTranscriptSnapshot(database, SESSION_ID); + const before = readTranscriptSnapshot(database, SESSION_ID); await runTranscriptLabelHealth(state, false); expect(note).not.toHaveBeenCalled(); - const after = readSqliteTranscriptSnapshot(database, SESSION_ID); + const after = readTranscriptSnapshot(database, SESSION_ID); expect(after.rows).toEqual(before.rows); }); @@ -587,7 +587,7 @@ describe("doctor SQLite session transcript label migration", () => { ]); await runTranscriptLabelHealth(state, true); - const repaired = readSqliteTranscriptSnapshot(database, SESSION_ID); + const repaired = readTranscriptSnapshot(database, SESSION_ID); const content = findMessageContent(repaired.events, "fenced-test"); expect(content).toContain(`Thread starter: ${INBOUND_CONTEXT_MARKER}`); @@ -623,7 +623,7 @@ describe("doctor SQLite session transcript label migration", () => { expect.anything(), ); - const after = readSqliteTranscriptSnapshot(database, SESSION_ID); + const after = readTranscriptSnapshot(database, SESSION_ID); const content = findMessageContent(after.events, "replied-test"); // The oldest `Replied message` label is rewritten to the lineage-canonical target, NOT to a bare @@ -644,13 +644,13 @@ describe("doctor SQLite session transcript label migration", () => { const database = seedMessageTranscript(databaseOptions, [ { id: "unfenced-replied", content: unfencedContent }, ]); - const before = readSqliteTranscriptSnapshot(database, SESSION_ID); + const before = readTranscriptSnapshot(database, SESSION_ID); await runTranscriptLabelHealth(state, false); expect(note).not.toHaveBeenCalled(); - const after = readSqliteTranscriptSnapshot(database, SESSION_ID); + const after = readTranscriptSnapshot(database, SESSION_ID); expect(after.rows).toEqual(before.rows); }); @@ -697,7 +697,7 @@ describe("doctor SQLite session transcript label migration", () => { await runTranscriptLabelHealth(state, true); // The clean session was repaired. - const cleanRepaired = readSqliteTranscriptSnapshot(database, SESSION_ID); + const cleanRepaired = readTranscriptSnapshot(database, SESSION_ID); const cleanContent = findMessageContent(cleanRepaired.events, "legacy-user"); expect(cleanContent).toContain("Conversation info:"); expect(cleanContent).not.toContain("Conversation info (untrusted metadata):"); @@ -714,8 +714,8 @@ describe("doctor SQLite session transcript label migration", () => { ); // The corrupt session was rolled back: legacy label survives, malformed row untouched. - // Read raw rows without parsing: readSqliteTranscriptSnapshot would throw on the malformed row. - const corruptRows = readSqliteTranscriptEventRows(database, CORRUPT_SESSION_ID); + // Read raw rows without parsing: readTranscriptSnapshot would throw on the malformed row. + const corruptRows = readTranscriptEventRows(database, CORRUPT_SESSION_ID); const corruptLegacyJson = corruptRows.find((row) => row.eventJson.includes("corrupt-legacy-user"), ); diff --git a/src/commands/doctor-session-transcript-labels.ts b/src/commands/doctor-session-transcript-labels.ts index cb41e1156115..ccf37d78057b 100644 --- a/src/commands/doctor-session-transcript-labels.ts +++ b/src/commands/doctor-session-transcript-labels.ts @@ -3,7 +3,7 @@ import { note } from "../../packages/terminal-core/src/note.js"; import { INBOUND_CONTEXT_MARKER } from "../auto-reply/reply/inbound-context-marker.js"; import type { TranscriptEvent } from "../config/sessions/session-accessor.js"; import { - readSqliteTranscriptEventRows, + readTranscriptEventRows, type SqliteTranscriptSnapshotRow, } from "../config/sessions/session-accessor.sqlite-read.js"; import { updateSqliteTranscriptEventJsonInTransaction } from "../config/sessions/session-accessor.sqlite-transcript-store.js"; @@ -252,7 +252,7 @@ export async function noteSessionTranscriptLabelHealth(params: { runOpenClawAgentWriteTransaction( (writeDatabase) => { // Use rows-only guard (tolerant of malformed JSON in sibling rows). - const currentRows = readSqliteTranscriptEventRows(writeDatabase, sessionId); + const currentRows = readTranscriptEventRows(writeDatabase, sessionId); if (!snapshotsMatch(readResult.rows, currentRows)) { throw new Error(`transcript changed while preparing rewrite for ${sessionId}`); } diff --git a/src/config/sessions/conversation-registry.ts b/src/config/sessions/conversation-registry.ts index 429e00a32b47..5318c82145b2 100644 --- a/src/config/sessions/conversation-registry.ts +++ b/src/config/sessions/conversation-registry.ts @@ -10,7 +10,7 @@ import { resolveSqliteReadScope, toDatabaseOptions, } from "./session-accessor.sqlite-scope.js"; -import { parseSqliteSessionEntryJson } from "./session-accessor.sqlite-status.js"; +import { parseSessionEntryJson } from "./session-accessor.sqlite-status.js"; const CONVERSATION_REF_PATTERN = /^conv_[a-f0-9]{32}$/u; @@ -88,7 +88,7 @@ function mapConversationRow(row: { ? row.role : undefined; const currentEntry = row.current_entry_json - ? parseSqliteSessionEntryJson({ entry_json: row.current_entry_json }) + ? parseSessionEntryJson({ entry_json: row.current_entry_json }) : null; const hasCurrentBinding = currentEntry?.sessionId === row.current_session_id; return { diff --git a/src/config/sessions/incognito-session-transcript.test.ts b/src/config/sessions/incognito-session-transcript.test.ts index 8c8f7dd28756..09e76370bf7e 100644 --- a/src/config/sessions/incognito-session-transcript.test.ts +++ b/src/config/sessions/incognito-session-transcript.test.ts @@ -15,7 +15,7 @@ import { loadTranscriptEvents, patchSessionEntry, } from "./session-accessor.js"; -import { replaceSqliteTranscriptEvents } from "./session-accessor.sqlite-transcript-write.js"; +import { replaceTranscriptEvents } from "./session-accessor.sqlite-transcript-write.js"; const sessionKey = "agent:main:dashboard:incognito-round-trip"; @@ -123,7 +123,7 @@ describe("incognito transcript access", () => { skipMaintenance: true, }, ); - await replaceSqliteTranscriptEvents({ ...staleScope, sessionId: "incognito-stale-session" }, [ + await replaceTranscriptEvents({ ...staleScope, sessionId: "incognito-stale-session" }, [ { id: "incognito-stale-event", timestamp: new Date(now).toISOString(), diff --git a/src/config/sessions/session-accessor.conformance.test.ts b/src/config/sessions/session-accessor.conformance.test.ts index 57245fae2c84..884ed33644f7 100644 --- a/src/config/sessions/session-accessor.conformance.test.ts +++ b/src/config/sessions/session-accessor.conformance.test.ts @@ -46,31 +46,13 @@ import { type TranscriptUpdatePayload, } from "./session-accessor.js"; import { - branchSqliteCompactionCheckpointSession, - restoreSqliteCompactionCheckpointSession, + branchCompactionCheckpointSession, + restoreCompactionCheckpointSession, } from "./session-accessor.sqlite-checkpoint.js"; -import { - listSqliteSessionEntries, - loadExactSqliteSessionEntry, - loadSqliteSessionEntry, - patchSqliteSessionEntry, - readSqliteSessionUpdatedAt, - replaceSqliteSessionEntry, - replaceSqliteSessionEntrySync, - upsertSqliteSessionEntry, -} from "./session-accessor.sqlite-entry.js"; -import { publishSqliteTranscriptUpdate } from "./session-accessor.sqlite-events.js"; -import { cleanupSqliteSessionLifecycleArtifacts } from "./session-accessor.sqlite-lifecycle.js"; -import { forkSqliteSessionEntryFromParentTarget } from "./session-accessor.sqlite-parent-session.js"; -import { - loadSqliteTranscriptEvents, - loadSqliteTranscriptEventsSync, -} from "./session-accessor.sqlite-read.js"; -import { - appendSqliteTranscriptEvent, - appendSqliteTranscriptMessage, - replaceSqliteTranscriptEvents, -} from "./session-accessor.sqlite-transcript-write.js"; +import { listSessionEntryRows, replaceSessionEntrySync } from "./session-accessor.sqlite-entry.js"; +import { forkSessionEntryFromParentTarget } from "./session-accessor.sqlite-parent-session.js"; +import { loadTranscriptEventsSync } from "./session-accessor.sqlite-read.js"; +import { replaceTranscriptEvents } from "./session-accessor.sqlite-transcript-write.js"; import { setCanonicalSqliteSessionMainKey } from "./session-canonical-key.js"; import type { InternalSessionEntry, SessionCompactionCheckpoint, SessionEntry } from "./types.js"; @@ -198,19 +180,19 @@ const sqliteAdapter: AccessorAdapter = { sessionId: id, storePath: paths.sqlitePath, }), - loadSessionEntry: loadSqliteSessionEntry, - loadExactSessionEntry: loadExactSqliteSessionEntry, - listSessionEntries: listSqliteSessionEntries, - readSessionUpdatedAt: readSqliteSessionUpdatedAt, - upsertSessionEntry: upsertSqliteSessionEntry, - replaceSessionEntry: replaceSqliteSessionEntry, - patchSessionEntry: patchSqliteSessionEntry, - updateSessionEntry: patchSqliteSessionEntry, - cleanupSessionLifecycleArtifacts: cleanupSqliteSessionLifecycleArtifacts, - loadTranscriptEvents: loadSqliteTranscriptEvents, - appendTranscriptEvent: appendSqliteTranscriptEvent, - appendTranscriptMessage: appendSqliteTranscriptMessage, - publishTranscriptUpdate: publishSqliteTranscriptUpdate, + loadSessionEntry, + loadExactSessionEntry, + listSessionEntries: listSessionEntryRows, + readSessionUpdatedAt, + upsertSessionEntry, + replaceSessionEntry, + patchSessionEntry, + updateSessionEntry: patchSessionEntry, + cleanupSessionLifecycleArtifacts, + loadTranscriptEvents, + appendTranscriptEvent, + appendTranscriptMessage, + publishTranscriptUpdate, }; beforeEach(() => { @@ -587,7 +569,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( await sqliteAdapter.appendTranscriptEvent(scope, event); - expect(loadSqliteTranscriptEventsSync(readScope)).toEqual([event]); + expect(loadTranscriptEventsSync(readScope)).toEqual([event]); }); it("maps canonical sessions.json store paths to the agent SQLite database", async () => { @@ -611,22 +593,22 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( storePath: legacyStorePath, }; - await upsertSqliteSessionEntry(scope, { + await upsertSessionEntry(scope, { model: "gpt-5.5", sessionId: "session-1", updatedAt: 10, }); - expect( - loadSqliteSessionEntry({ ...scope, agentId: "voice", storePath: sqlitePath }), - ).toMatchObject({ - model: "gpt-5.5", - sessionId: "session-1", - }); + expect(loadSessionEntry({ ...scope, agentId: "voice", storePath: sqlitePath })).toMatchObject( + { + model: "gpt-5.5", + sessionId: "session-1", + }, + ); expect(fs.existsSync(sqlitePath)).toBe(true); expect(fs.existsSync(legacyStorePath)).toBe(false); expect( - listSqliteSessionEntries({ + listSessionEntryRows({ env: scope.env, storePath: sqlitePath, }), @@ -636,9 +618,9 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( sessionKey: "agent:voice:voice:123", }), ]); - expect(() => - loadSqliteSessionEntry({ ...scope, agentId: "main", storePath: sqlitePath }), - ).toThrow("belongs to agent voice; requested agent main"); + expect(() => loadSessionEntry({ ...scope, agentId: "main", storePath: sqlitePath })).toThrow( + "belongs to agent voice; requested agent main", + ); }); it("keeps custom JSON store paths beside their SQLite database", async () => { @@ -650,18 +632,18 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( storePath: customStorePath, }; - await upsertSqliteSessionEntry(scope, { + await upsertSessionEntry(scope, { model: "gpt-5.5", sessionId: "session-1", updatedAt: 10, }); - expect( - loadSqliteSessionEntry({ ...scope, agentId: "voice", storePath: sqlitePath }), - ).toMatchObject({ - model: "gpt-5.5", - sessionId: "session-1", - }); + expect(loadSessionEntry({ ...scope, agentId: "voice", storePath: sqlitePath })).toMatchObject( + { + model: "gpt-5.5", + sessionId: "session-1", + }, + ); expect(fs.existsSync(sqlitePath)).toBe(true); expect(fs.existsSync(customStorePath)).toBe(false); }); @@ -679,7 +661,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( storePath: customStorePath, }; - await upsertSqliteSessionEntry(scope, { + await upsertSessionEntry(scope, { model: "gpt-5.5", sessionId: "support-session", updatedAt: 10, @@ -689,7 +671,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( sessionId: "support-session", }); - expect(loadSqliteSessionEntry({ ...scope, storePath: customSqlitePath })).toMatchObject({ + expect(loadSessionEntry({ ...scope, storePath: customSqlitePath })).toMatchObject({ model: "gpt-5.5", sessionId: "support-session", }); @@ -705,7 +687,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( it("parses only the selected SQLite entry across keyed loads", async () => { const scope = sqliteAdapter.entryScope(paths); for (let index = 0; index < 20; index += 1) { - await upsertSqliteSessionEntry( + await upsertSessionEntry( { ...scope, sessionKey: `agent:main:unrelated-${index}`, @@ -717,7 +699,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( }, ); } - await upsertSqliteSessionEntry(scope, { + await upsertSessionEntry(scope, { model: "target", sessionId: "target-session", updatedAt: 100, @@ -732,7 +714,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( ).length; try { - expect(loadSqliteSessionEntry(scope)).toMatchObject({ + expect(loadSessionEntry(scope)).toMatchObject({ model: "target", sessionId: "target-session", }); @@ -743,7 +725,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( typeof json === "string" && json.includes('"sessionId":"unrelated-session-'), ), ).toBe(false); - expect(loadSqliteSessionEntry(scope)).toMatchObject({ + expect(loadSessionEntry(scope)).toMatchObject({ model: "target", sessionId: "target-session", }); @@ -759,20 +741,20 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( ...scope, sessionKey: "agent:main:stale-under-cap", }; - await replaceSqliteSessionEntry(staleScope, { + await replaceSessionEntry(staleScope, { model: "stale", sessionId: "stale-under-cap", updatedAt: Date.now() - 31 * 24 * 60 * 60 * 1000, }); - await upsertSqliteSessionEntry(scope, { + await upsertSessionEntry(scope, { model: "fresh", sessionId: "fresh-session", updatedAt: Date.now(), }); - expect(loadSqliteSessionEntry(staleScope)).toBeUndefined(); - expect(loadSqliteSessionEntry(scope)).toMatchObject({ + expect(loadSessionEntry(staleScope)).toBeUndefined(); + expect(loadSessionEntry(scope)).toMatchObject({ model: "fresh", sessionId: "fresh-session", }); @@ -781,7 +763,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( it("serializes concurrent SQLite entry patches", async () => { const scope = sqliteAdapter.entryScope(paths); - await upsertSqliteSessionEntry(scope, { + await upsertSessionEntry(scope, { model: "base", sessionId: "patch-session", updatedAt: 10, @@ -793,20 +775,20 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( const blockedPatch = new Promise((release) => { releasePatch = release; }); - firstPatch = patchSqliteSessionEntry(scope, async () => { + firstPatch = patchSessionEntry(scope, async () => { resolve(); await blockedPatch; return { model: "first" }; }); }); await patchStarted; - const secondPatch = patchSqliteSessionEntry(scope, () => ({ + const secondPatch = patchSessionEntry(scope, () => ({ providerOverride: "openai", })); releasePatch(); await Promise.all([firstPatch, secondPatch]); - expect(loadSqliteSessionEntry(scope)).toMatchObject({ + expect(loadSessionEntry(scope)).toMatchObject({ model: "first", providerOverride: "openai", }); @@ -817,7 +799,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( return; } const scope = sqliteAdapter.entryScope(paths); - await replaceSqliteSessionEntry(scope, { + await replaceSessionEntry(scope, { model: "base", sessionId: "transaction-gap", updatedAt: 10, @@ -831,7 +813,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( const updaterGate = new Promise((resolve) => { releaseUpdater = resolve; }); - const pendingPatch = patchSqliteSessionEntry(scope, async () => { + const pendingPatch = patchSessionEntry(scope, async () => { markUpdaterStarted(); await updaterGate; return { model: "patched" }; @@ -882,7 +864,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( sessionKey: "agent:main:shared-writers", storePath: conventionalStorePath, }; - await replaceSqliteSessionEntry(scope, { + await replaceSessionEntry(scope, { model: "base", sessionId: "shared-writers", updatedAt: 10, @@ -896,7 +878,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( const updaterGate = new Promise((resolve) => { releaseUpdater = resolve; }); - const pendingPatch = patchSqliteSessionEntry(scope, async () => { + const pendingPatch = patchSessionEntry(scope, async () => { markUpdaterStarted(); await updaterGate; return { model: "patched" }; @@ -930,7 +912,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( return; } const scope = sqliteAdapter.entryScope(paths); - await replaceSqliteSessionEntry(scope, { + await replaceSessionEntry(scope, { model: "base", sessionId: "stale-prepare", updatedAt: 10, @@ -944,7 +926,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( const updaterGate = new Promise((resolve) => { releaseUpdater = resolve; }); - const pendingPatch = patchSqliteSessionEntry(scope, async () => { + const pendingPatch = patchSessionEntry(scope, async () => { markUpdaterStarted(); await updaterGate; return { model: "stale-patch" }; @@ -953,7 +935,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( await updaterStarted; let replacementError: unknown; try { - replaceSqliteSessionEntrySync(scope, { + replaceSessionEntrySync(scope, { model: "newer", sessionId: "stale-prepare", updatedAt: 20, @@ -970,7 +952,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( expect(replacementError).toBeUndefined(); expect(mutationError).toMatchObject({ name: "SqliteSessionMutationConflictError" }); - expect(loadSqliteSessionEntry(scope)).toMatchObject({ model: "newer", updatedAt: 20 }); + expect(loadSessionEntry(scope)).toMatchObject({ model: "newer", updatedAt: 20 }); }); it("dedupes SQLite transcript identities inside the writer path", async () => { @@ -981,14 +963,14 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( type: "metadata", }; - await appendSqliteTranscriptEvent(scope, event); - await appendSqliteTranscriptEvent(scope, { + await appendTranscriptEvent(scope, event); + await appendTranscriptEvent(scope, { ...event, message: { role: "assistant", content: "duplicate" }, }); const results = await Promise.all( Array.from({ length: 8 }, () => - appendSqliteTranscriptMessage(scope, { + appendTranscriptMessage(scope, { idempotencyLookup: "scan", message: { role: "assistant", @@ -1001,7 +983,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( expect(new Set(results.map((result) => result?.messageId)).size).toBe(1); expect(results.filter((result) => result?.appended)).toHaveLength(1); - await expect(loadSqliteTranscriptEvents(scope)).resolves.toEqual([ + await expect(loadTranscriptEvents(scope)).resolves.toEqual([ event, expect.objectContaining({ message: expect.objectContaining({ idempotencyKey: "keyed-once" }), @@ -1031,10 +1013,10 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( idempotencyKey: "unchecked-once", }; - const appended = await appendSqliteTranscriptMessage(scope, { message }); - const replayed = await appendSqliteTranscriptMessage(scope, { message }); + const appended = await appendTranscriptMessage(scope, { message }); + const replayed = await appendTranscriptMessage(scope, { message }); await expect( - appendSqliteTranscriptMessage(scope, { + appendTranscriptMessage(scope, { message: { ...message, content: "unchecked replay", @@ -1042,7 +1024,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( }), ).rejects.toThrow(/conflicts with the admitted message/u); - const events = await loadSqliteTranscriptEvents(scope); + const events = await loadTranscriptEvents(scope); const keyedEvents = events.filter((event): event is { message: typeof message } => { return ( Boolean(event) && @@ -1065,14 +1047,14 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( const scope = sqliteAdapter.transcriptScope(paths, "session-event-id-dedupe"); const eventId = "message-retry-event-id"; - const appended = await appendSqliteTranscriptMessage(scope, { + const appended = await appendTranscriptMessage(scope, { eventId, message: { role: "assistant", content: "first attempt", }, }); - const replayed = await appendSqliteTranscriptMessage(scope, { + const replayed = await appendTranscriptMessage(scope, { eventId, message: { role: "assistant", @@ -1080,7 +1062,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( }, }); await expect( - appendSqliteTranscriptMessage(scope, { + appendTranscriptMessage(scope, { eventId, message: { role: "assistant", @@ -1098,7 +1080,7 @@ describe.each([publicAccessorAdapter, sqliteAdapter])( message: expect.objectContaining({ content: "first attempt" }), messageId: eventId, }); - await expect(loadSqliteTranscriptEvents(scope)).resolves.toEqual([ + await expect(loadTranscriptEvents(scope)).resolves.toEqual([ expect.objectContaining({ type: "session" }), expect.objectContaining({ id: eventId, @@ -1226,7 +1208,7 @@ describe("sqlite session normalization", () => { it("maintains normalized session node and window rows", async () => { const env = { ...process.env, OPENCLAW_STATE_DIR: paths.stateDir }; - await upsertSqliteSessionEntry( + await upsertSessionEntry( { agentId: "main", env, @@ -1323,7 +1305,7 @@ describe("sqlite session normalization", () => { it("marks identity-only row updates pending validation", async () => { const env = { ...process.env, OPENCLAW_STATE_DIR: paths.stateDir }; const sessionKey = "agent:main:identity-update"; - await replaceSqliteSessionEntry( + await replaceSessionEntry( { agentId: "main", env, sessionKey, storePath: paths.sqlitePath }, { sessionId: "identity-session", updatedAt: 10 }, ); @@ -1351,7 +1333,7 @@ describe("sqlite session normalization", () => { storePath: paths.sqlitePath, }; - await upsertSqliteSessionEntry(scope, { + await upsertSessionEntry(scope, { delivery: normalizeSessionDeliveryState({ context: { channel: "telegram" } }), chatType: "group", createdVia: "channel", @@ -1363,7 +1345,7 @@ describe("sqlite session normalization", () => { status: "killed", updatedAt: 1_782_973_392_492, }); - await appendSqliteTranscriptEvent( + await appendTranscriptEvent( { ...scope, sessionId: oldSessionId }, { id: "old-frontier", @@ -1372,7 +1354,7 @@ describe("sqlite session normalization", () => { }, ); - await upsertSqliteSessionEntry(scope, { + await upsertSessionEntry(scope, { delivery: normalizeSessionDeliveryState({ context: { channel: "telegram" } }), chatType: "group", displayName: "telegram:g-bucephalus-+-topics", @@ -1380,7 +1362,7 @@ describe("sqlite session normalization", () => { status: "running", updatedAt: 1_782_997_881_018, }); - await appendSqliteTranscriptEvent( + await appendTranscriptEvent( { ...scope, sessionId: newSessionId }, { id: "new-turn", @@ -1389,13 +1371,13 @@ describe("sqlite session normalization", () => { }, ); - await expect( - loadSqliteTranscriptEvents({ ...scope, sessionId: oldSessionId }), - ).resolves.toEqual([expect.objectContaining({ id: "old-frontier", type: "metadata" })]); - await expect( - loadSqliteTranscriptEvents({ ...scope, sessionId: newSessionId }), - ).resolves.toEqual([expect.objectContaining({ id: "new-turn", type: "metadata" })]); - expect(loadSqliteSessionEntry(scope)).toEqual( + await expect(loadTranscriptEvents({ ...scope, sessionId: oldSessionId })).resolves.toEqual([ + expect.objectContaining({ id: "old-frontier", type: "metadata" }), + ]); + await expect(loadTranscriptEvents({ ...scope, sessionId: newSessionId })).resolves.toEqual([ + expect.objectContaining({ id: "new-turn", type: "metadata" }), + ]); + expect(loadSessionEntry(scope)).toEqual( expect.objectContaining({ sessionId: newSessionId, createdVia: "channel", @@ -1418,16 +1400,16 @@ describe("sqlite session normalization", () => { storePath: paths.sqlitePath, }; - await upsertSqliteSessionEntry(scope, { + await upsertSessionEntry(scope, { sessionId: "temporary-session", updatedAt: 10, }); - await replaceSqliteSessionEntry(scope, { + await replaceSessionEntry(scope, { sessionId: "restored-session", updatedAt: 20, }); - expect(loadSqliteSessionEntry(scope)).toEqual({ + expect(loadSessionEntry(scope)).toEqual({ sessionId: "restored-session", updatedAt: 20, delivery: { kind: "none" }, @@ -1438,7 +1420,7 @@ describe("sqlite session normalization", () => { const env = { ...process.env, OPENCLAW_STATE_DIR: paths.stateDir }; const parentKey = "agent:main:parent"; const childKey = "agent:main:subagent:child"; - await upsertSqliteSessionEntry( + await upsertSessionEntry( { agentId: "main", env, @@ -1452,7 +1434,7 @@ describe("sqlite session normalization", () => { updatedAt: 10, }, ); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { agentId: "main", env, @@ -1471,7 +1453,7 @@ describe("sqlite session normalization", () => { ], ); - const result = await forkSqliteSessionEntryFromParentTarget({ + const result = await forkSessionEntryFromParentTarget({ fallbackEntry: { sessionId: "", updatedAt: 1 }, parentTarget: { canonicalKey: parentKey, storeKeys: [parentKey] }, sessionTarget: { canonicalKey: childKey, storeKeys: [childKey] }, @@ -1506,11 +1488,11 @@ describe("sqlite session normalization", () => { sessionKey: "agent:main:main", storePath: paths.sqlitePath, }; - await upsertSqliteSessionEntry(scope, { + await upsertSessionEntry(scope, { sessionId: "current-session", updatedAt: 20, }); - await appendSqliteTranscriptEvent( + await appendTranscriptEvent( { ...scope, sessionId: "stale-session", @@ -1557,7 +1539,7 @@ describe("sqlite session normalization", () => { }); const oldUpdatedAt = Date.now() - 2 * 24 * 60 * 60 * 1000; - await patchSqliteSessionEntry( + await patchSessionEntry( scopeFor("agent:main:stale"), () => ({ sessionId: "stale-session", updatedAt: oldUpdatedAt }), { @@ -1566,7 +1548,7 @@ describe("sqlite session normalization", () => { skipMaintenance: true, }, ); - await patchSqliteSessionEntry( + await patchSessionEntry( scopeFor("agent:main:older"), () => ({ sessionId: "older-session", updatedAt: oldUpdatedAt + 1 }), { @@ -1575,7 +1557,7 @@ describe("sqlite session normalization", () => { skipMaintenance: true, }, ); - await patchSqliteSessionEntry( + await patchSessionEntry( scopeFor("agent:main:active"), () => ({ sessionId: "active-session", updatedAt: Date.now() }), { @@ -1589,16 +1571,16 @@ describe("sqlite session normalization", () => { timestamp: new Date(oldUpdatedAt).toISOString(), type: "metadata", }; - await appendSqliteTranscriptEvent( + await appendTranscriptEvent( { ...scopeFor("agent:main:stale"), sessionId: "stale-session" }, staleTranscriptEvent, ); - await patchSqliteSessionEntry(scopeFor("agent:main:active"), () => ({ model: "gpt-5.5" }), { + await patchSessionEntry(scopeFor("agent:main:active"), () => ({ model: "gpt-5.5" }), { skipMaintenance: true, }); await expect( - loadSqliteTranscriptEvents({ + loadTranscriptEvents({ agentId: "main", env, sessionId: "stale-session", @@ -1606,7 +1588,7 @@ describe("sqlite session normalization", () => { }), ).resolves.toEqual([staleTranscriptEvent]); expect( - listSqliteSessionEntries({ + listSessionEntryRows({ agentId: "main", env, storePath: paths.sqlitePath, @@ -1615,7 +1597,7 @@ describe("sqlite session normalization", () => { const notify = vi.fn(); const unsubscribe = onSessionIdentityMutation(notify); - await patchSqliteSessionEntry(scopeFor("agent:main:active"), () => ({ + await patchSessionEntry(scopeFor("agent:main:active"), () => ({ providerOverride: "openai", })); unsubscribe(); @@ -1624,14 +1606,14 @@ describe("sqlite session normalization", () => { new Set(["older-session", "stale-session"]), ); expect( - listSqliteSessionEntries({ + listSessionEntryRows({ agentId: "main", env, storePath: paths.sqlitePath, }).map((summary) => summary.sessionKey), ).toEqual(["agent:main:active"]); await expect( - loadSqliteTranscriptEvents({ + loadTranscriptEvents({ agentId: "main", env, sessionId: "stale-session", @@ -1649,7 +1631,7 @@ describe("sqlite session normalization", () => { .map((line) => JSON.parse(line)), ).toEqual([staleTranscriptEvent]); - await patchSqliteSessionEntry( + await patchSessionEntry( scopeFor("agent:main:newer"), () => ({ sessionId: "newer-session", updatedAt: Date.now() + 1 }), { @@ -1658,7 +1640,7 @@ describe("sqlite session normalization", () => { skipMaintenance: true, }, ); - await patchSqliteSessionEntry( + await patchSessionEntry( scopeFor("agent:main:newest"), () => ({ sessionId: "newest-session", updatedAt: Date.now() + 2 }), { @@ -1668,7 +1650,7 @@ describe("sqlite session normalization", () => { ); expect( - listSqliteSessionEntries({ + listSessionEntryRows({ agentId: "main", env, storePath: paths.sqlitePath, @@ -1704,7 +1686,7 @@ describe("sqlite session normalization", () => { ["agent:main:slack:channel:c1", "channel-session-1"], ["agent:main:slack:channel:c2", "channel-session-2"], ] as const) { - await patchSqliteSessionEntry( + await patchSessionEntry( scopeFor(sessionKey), () => ({ sessionId, updatedAt: Date.now() - 1 }), { @@ -1715,7 +1697,7 @@ describe("sqlite session normalization", () => { ); } - await patchSqliteSessionEntry(scopeFor(cronKey), () => cronEntry, { + await patchSessionEntry(scopeFor(cronKey), () => cronEntry, { fallbackEntry: cronEntry, replaceEntry: true, skipMaintenance: true, @@ -1727,7 +1709,7 @@ describe("sqlite session normalization", () => { }); try { const triggerKey = "agent:main:maintenance-trigger"; - await patchSqliteSessionEntry( + await patchSessionEntry( scopeFor(triggerKey), () => ({ sessionId: "trigger-session", updatedAt: Date.now() + 1 }), { @@ -1736,7 +1718,7 @@ describe("sqlite session normalization", () => { }, ); - expect(loadSqliteSessionEntry(scopeFor(cronKey))).toMatchObject(cronEntry); + expect(loadSessionEntry(scopeFor(cronKey))).toMatchObject(cronEntry); } finally { admission.release(); } @@ -1764,7 +1746,7 @@ describe("sqlite session normalization", () => { const oldUpdatedAt = Date.now() - 2 * 24 * 60 * 60 * 1000; const unsharedUpdatedAt = oldUpdatedAt - 1_000; - await patchSqliteSessionEntry( + await patchSessionEntry( scopeFor("agent:main:unshared-budget"), () => ({ sessionId: "unshared-budget-session", updatedAt: unsharedUpdatedAt }), { @@ -1773,7 +1755,7 @@ describe("sqlite session normalization", () => { skipMaintenance: true, }, ); - await appendSqliteTranscriptEvent( + await appendTranscriptEvent( { ...scopeFor("agent:main:unshared-budget"), sessionId: "unshared-budget-session" }, { id: "unshared-budget-event", @@ -1783,7 +1765,7 @@ describe("sqlite session normalization", () => { }, ); - await patchSqliteSessionEntry( + await patchSessionEntry( scopeFor("agent:main:old-budget"), () => ({ sessionId: "old-budget-session", updatedAt: oldUpdatedAt }), { @@ -1792,7 +1774,7 @@ describe("sqlite session normalization", () => { skipMaintenance: true, }, ); - await appendSqliteTranscriptEvent( + await appendTranscriptEvent( { ...scopeFor("agent:main:old-budget"), sessionId: "old-budget-session" }, { id: "old-budget-event", @@ -1801,7 +1783,7 @@ describe("sqlite session normalization", () => { type: "metadata", }, ); - await patchSqliteSessionEntry( + await patchSessionEntry( scopeFor("agent:main:active-budget"), () => ({ sessionId: "active-budget-session", @@ -1819,7 +1801,7 @@ describe("sqlite session normalization", () => { }, ); - await patchSqliteSessionEntry(scopeFor("agent:main:active-budget"), () => ({ + await patchSessionEntry(scopeFor("agent:main:active-budget"), () => ({ modelOverride: "gpt-5.5", })); @@ -1827,7 +1809,7 @@ describe("sqlite session normalization", () => { // handled by the async physical-budget pass, which only reclaims // historical generations no entry, route, or admission references. expect( - listSqliteSessionEntries({ + listSessionEntryRows({ agentId: "main", env, storePath: paths.sqlitePath, @@ -1836,7 +1818,7 @@ describe("sqlite session normalization", () => { .toSorted(), ).toEqual(["agent:main:active-budget", "agent:main:old-budget", "agent:main:unshared-budget"]); await expect( - loadSqliteTranscriptEvents({ + loadTranscriptEvents({ agentId: "main", env, sessionId: "old-budget-session", @@ -1848,7 +1830,7 @@ describe("sqlite session normalization", () => { }), ]); await expect( - loadSqliteTranscriptEvents({ + loadTranscriptEvents({ agentId: "main", env, sessionId: "unshared-budget-session", @@ -1887,7 +1869,7 @@ describe("sqlite session normalization", () => { .run(legacyKey, entry.sessionId, JSON.stringify(entry), entry.updatedAt); expect(() => - loadSqliteSessionEntry({ + loadSessionEntry({ agentId: "main", env, sessionKey: canonicalKey, @@ -1895,10 +1877,10 @@ describe("sqlite session normalization", () => { }), ).toThrow("openclaw doctor --fix"); expect(() => - listSqliteSessionEntries({ agentId: "main", env, storePath: paths.sqlitePath }), + listSessionEntryRows({ agentId: "main", env, storePath: paths.sqlitePath }), ).toThrow("openclaw doctor --fix"); await expect( - appendSqliteTranscriptEvent( + appendTranscriptEvent( { agentId: "main", env, @@ -1910,7 +1892,7 @@ describe("sqlite session normalization", () => { ), ).rejects.toThrow("openclaw doctor --fix"); expect(() => - replaceSqliteSessionEntrySync( + replaceSessionEntrySync( { agentId: "main", env, sessionKey: canonicalKey, storePath: paths.sqlitePath }, { sessionId: "replacement", updatedAt: 20 }, ), @@ -1924,7 +1906,7 @@ describe("sqlite session normalization", () => { .prepare("UPDATE session_nodes SET entry_json = ?, entry_valid = -1 WHERE session_key = ?") .run("{ malformed", legacyKey); await expect( - appendSqliteTranscriptEvent( + appendTranscriptEvent( { agentId: "main", env, @@ -1954,23 +1936,23 @@ describe("sqlite session normalization", () => { .run(sessionId, sessionKey); expect(() => - listSqliteSessionEntries({ agentId: "main", env, storePath: paths.sqlitePath }), + listSessionEntryRows({ agentId: "main", env, storePath: paths.sqlitePath }), ).toThrow("openclaw doctor --fix"); }); it("revalidates an open database after its canonical main key changes", () => { const env = { ...process.env, OPENCLAW_STATE_DIR: paths.stateDir }; const storePath = paths.sqlitePath; - replaceSqliteSessionEntrySync( + replaceSessionEntrySync( { agentId: "main", env, sessionKey: "agent:main:main", storePath }, { sessionId: "main-session", updatedAt: 10 }, ); - expect(listSqliteSessionEntries({ agentId: "main", env, storePath })).toHaveLength(1); + expect(listSessionEntryRows({ agentId: "main", env, storePath })).toHaveLength(1); const database = openOpenClawAgentDatabase({ agentId: "main", env, path: paths.sqlitePath }); setCanonicalSqliteSessionMainKey(database, "work"); - expect(() => listSqliteSessionEntries({ agentId: "main", env, storePath })).toThrow( + expect(() => listSessionEntryRows({ agentId: "main", env, storePath })).toThrow( "openclaw doctor --fix", ); }); @@ -1995,13 +1977,13 @@ describe("sqlite session normalization", () => { .run(sessionKey); expect(() => - listSqliteSessionEntries({ agentId: "main", env, storePath: paths.sqlitePath }), + listSessionEntryRows({ agentId: "main", env, storePath: paths.sqlitePath }), ).toThrow("openclaw doctor --fix"); }); it("normalizes missing entry updatedAt before writing root and entry rows", async () => { const env = { ...process.env, OPENCLAW_STATE_DIR: paths.stateDir }; - await replaceSqliteSessionEntry( + await replaceSessionEntry( { agentId: "main", env, @@ -2014,7 +1996,7 @@ describe("sqlite session normalization", () => { } as SessionEntry, ); - const loaded = loadSqliteSessionEntry({ + const loaded = loadSessionEntry({ agentId: "main", env, sessionKey: "agent:main:minimal", @@ -2057,7 +2039,7 @@ describe("sqlite session normalization", () => { window_updated_at: 123, }); - await upsertSqliteSessionEntry( + await upsertSessionEntry( { agentId: "main", env, @@ -2122,11 +2104,11 @@ describe("sqlite session normalization", () => { }, }; - await replaceSqliteTranscriptEvents(preCompactionScope, [ + await replaceTranscriptEvents(preCompactionScope, [ { type: "session", id: "pre-compaction-session", cwd: paths.tempDir }, { type: "message", id: "pre-msg", parentId: null, message: { content: "pre" } }, ]); - await replaceSqliteTranscriptEvents(sourceScope, [ + await replaceTranscriptEvents(sourceScope, [ { type: "session", id: "source-session", cwd: paths.tempDir }, { type: "message", id: "post-msg-1", parentId: null, message: { content: "post-one" } }, { @@ -2143,11 +2125,11 @@ describe("sqlite session normalization", () => { updatedAt: 10, compactionCheckpoints: [checkpoint], }; - await upsertSqliteSessionEntry(sourceEntryScope, sourceEntry); + await upsertSessionEntry(sourceEntryScope, sourceEntry); const notify = vi.fn(); const unsubscribe = onSessionIdentityMutation(notify); - const result = await branchSqliteCompactionCheckpointSession({ + const result = await branchCompactionCheckpointSession({ agentId: "main", env, expectedState: sourceEntry, @@ -2166,9 +2148,7 @@ describe("sqlite session normalization", () => { sessionId: result.entry.sessionId, sessionKey: branchKey, }; - expect(loadSqliteSessionEntry({ ...sourceEntryScope, sessionKey: branchKey })).toEqual( - result.entry, - ); + expect(loadSessionEntry({ ...sourceEntryScope, sessionKey: branchKey })).toEqual(result.entry); expect(notify).toHaveBeenCalledWith({ kind: "create", previous: { sessionKeys: [] }, @@ -2184,7 +2164,7 @@ describe("sqlite session normalization", () => { }), ); expect((result.entry as InternalSessionEntry).lifecycleRunId).toBeUndefined(); - await expect(loadSqliteTranscriptEvents(branchScope)).resolves.toEqual([ + await expect(loadTranscriptEvents(branchScope)).resolves.toEqual([ expect.objectContaining({ type: "session", id: result.entry.sessionId }), expect.objectContaining({ id: "pre-msg", type: "message" }), ]); @@ -2225,18 +2205,18 @@ describe("sqlite session normalization", () => { }, }; - await replaceSqliteTranscriptEvents(sourceScope, [ + await replaceTranscriptEvents(sourceScope, [ { type: "session", id: "source-session", cwd: paths.tempDir }, { type: "message", id: "post-msg", parentId: null, message: { content: "post" } }, { type: "message", id: "skipped-msg", parentId: "post-msg", message: { content: "skip" } }, ]); - await upsertSqliteSessionEntry(sourceEntryScope, { + await upsertSessionEntry(sourceEntryScope, { sessionId: "source-session", updatedAt: 10, compactionCheckpoints: [checkpoint], }); - const result = await branchSqliteCompactionCheckpointSession({ + const result = await branchCompactionCheckpointSession({ agentId: "main", env, expectedState: { sessionId: "source-session", lifecycleRevision: undefined }, @@ -2250,7 +2230,7 @@ describe("sqlite session normalization", () => { } await expect( - loadSqliteTranscriptEvents({ + loadTranscriptEvents({ ...sourceScope, sessionId: result.entry.sessionId, sessionKey: "agent:main:checkpoint-post-fallback", @@ -2301,23 +2281,23 @@ describe("sqlite session normalization", () => { }, }; - await replaceSqliteTranscriptEvents(preCompactionScope, [ + await replaceTranscriptEvents(preCompactionScope, [ { type: "session", id: "pre-compaction-session", cwd: paths.tempDir }, { type: "message", id: "pre-msg", parentId: null, message: { content: "restore" } }, ]); - await replaceSqliteTranscriptEvents(sourceScope, [ + await replaceTranscriptEvents(sourceScope, [ { type: "session", id: "source-session", cwd: paths.tempDir }, { type: "message", id: "post-msg-1", parentId: null, message: { content: "skip" } }, { type: "message", id: "post-msg-2", parentId: "post-msg-1", message: { content: "skip" } }, ]); - await upsertSqliteSessionEntry(sourceEntryScope, { + await upsertSessionEntry(sourceEntryScope, { label: "Current", sessionId: "current-session", updatedAt: 10, compactionCheckpoints: [checkpoint], }); - const result = await restoreSqliteCompactionCheckpointSession({ + const result = await restoreCompactionCheckpointSession({ agentId: "main", env, expectedState: { sessionId: "current-session", lifecycleRevision: undefined }, @@ -2333,7 +2313,7 @@ describe("sqlite session normalization", () => { ...sourceScope, sessionId: result.entry.sessionId, }; - expect(loadSqliteSessionEntry(sourceEntryScope)).toEqual(result.entry); + expect(loadSessionEntry(sourceEntryScope)).toEqual(result.entry); expect(result.entry).toEqual( expect.objectContaining({ label: "Current", @@ -2343,7 +2323,7 @@ describe("sqlite session normalization", () => { totalTokensVersion: 1, }), ); - await expect(loadSqliteTranscriptEvents(restoredScope)).resolves.toEqual([ + await expect(loadTranscriptEvents(restoredScope)).resolves.toEqual([ expect.objectContaining({ type: "session", id: result.entry.sessionId }), expect.objectContaining({ id: "pre-msg", type: "message" }), ]); diff --git a/src/config/sessions/session-accessor.entry-mutation.ts b/src/config/sessions/session-accessor.entry-mutation.ts index 37ad5a83ce5e..113483c939ca 100644 --- a/src/config/sessions/session-accessor.entry-mutation.ts +++ b/src/config/sessions/session-accessor.entry-mutation.ts @@ -13,11 +13,15 @@ import { } from "./session-accessor.entry.js"; import { applySessionEntryLifecycleMutation } from "./session-accessor.lifecycle.js"; import { - patchSqliteSessionEntry, - recordSqliteInboundSessionMeta, - updateSqliteSessionLastRoute, + recordInboundSessionMeta, + updateSessionLastRoute, } from "./session-accessor.sqlite-entry.js"; -import { appendSqliteTranscriptEvent } from "./session-accessor.sqlite-transcript-write.js"; +import { + forkSessionEntryFromParentTarget, + forkSessionTranscriptFromParent, + resolveSessionParentForkDecision, +} from "./session-accessor.sqlite-parent-session.js"; +import { appendTranscriptEvent } from "./session-accessor.sqlite-transcript-write.js"; import type { SessionAccessScope, SessionEntryUpdateOptions, @@ -25,6 +29,8 @@ import type { SessionAbortTargetContext, SessionAbortTargetIdentity, SessionAbortTargetResult, + ForkSessionFromParentTranscriptResult, + ForkSessionFromParentTranscriptParams, SessionEntryCreateWithTranscriptContext, SessionEntryCreateWithTranscriptResult, SessionEntryCreateWithTranscriptPrepareResult, @@ -54,11 +60,18 @@ function projectSessionEntryForPersistenceRevision(params: { return projected.store.entry ?? stripped; } +export async function forkSessionFromParentTranscript( + params: ForkSessionFromParentTranscriptParams, +): Promise { + return await forkSessionTranscriptFromParent(params); +} + export { - forkSqliteSessionEntryFromParentTarget as forkSessionEntryFromParentTarget, - forkSqliteSessionTranscriptFromParent as forkSessionFromParentTranscript, - resolveSqliteSessionParentForkDecision as resolveSessionParentForkDecision, -} from "./session-accessor.sqlite-parent-session.js"; + forkSessionEntryFromParentTarget, + recordInboundSessionMeta, + resolveSessionParentForkDecision, + updateSessionLastRoute, +}; /** * Creates or updates one session entry and initializes its transcript header as @@ -90,7 +103,7 @@ export async function createSessionEntryWithTranscript( try { options.commitGuard?.(); - await appendSqliteTranscriptEvent( + await appendTranscriptEvent( { agentId, sessionId: created.entry.sessionId, @@ -247,7 +260,7 @@ export async function updateSessionEntry( ) => Promise | null> | Partial | null, options: SessionEntryUpdateOptions = {}, ): Promise { - return await patchSqliteSessionEntry(scope, update, options); + return await patchSessionEntry(scope, update, options); } export type RecordInboundSessionMetaParams = { @@ -288,31 +301,6 @@ export type UpdateSessionLastRouteParams = { to?: string; }; -/** - * Records stable conversation metadata derived from one inbound message as a - * single storage-sized upsert (createIfMissing by default). Inbound metadata - * must not refresh activity timestamps — idle reset relies on updatedAt from - * real session turns — so existing rows merge with preserve-activity - * semantics while legacy alias keys collapse onto the canonical row. - */ -export async function recordInboundSessionMeta( - params: RecordInboundSessionMetaParams, -): Promise { - return await recordSqliteInboundSessionMeta(params); -} - -/** - * Persists the last known delivery route for one session as a single - * storage-sized patch. Route updates preserve activity timestamps (#49515) - * and merge explicit route/delivery input over the persisted session - * fallback before normalizing the derived last* fields. - */ -export async function updateSessionLastRoute( - params: UpdateSessionLastRouteParams, -): Promise { - return await updateSqliteSessionLastRoute(params); -} - /** Resolves one abort target identity without exposing the mutable store. */ export function resolveSessionAbortTarget( scope: SessionAccessScope, diff --git a/src/config/sessions/session-accessor.entry.ts b/src/config/sessions/session-accessor.entry.ts index ef9d4b63c8fb..790785a4fbe5 100644 --- a/src/config/sessions/session-accessor.entry.ts +++ b/src/config/sessions/session-accessor.entry.ts @@ -17,24 +17,24 @@ import { rehomeSqliteSessionDeliveryReferencesForCanonicalRepairBatch as rehomeSessionDeliveryReferencesForCanonicalRepairBatch, } from "./session-accessor.sqlite-canonical-repair.js"; import { - countSqliteSessionEntryRowsReadOnly as countSessionEntryRowsReadOnly, - ensureSqliteSessionEntrySync as ensureSessionEntrySync, - hasSqliteSessionEntriesByStatusReadOnly as hasSessionEntriesByStatusReadOnly, - listSqliteSessionChildEntriesReadOnly as listSessionChildEntriesReadOnly, - listSqliteSessionEntries, - listSqliteSessionEntriesReadOnly as listSessionEntriesReadOnly, - listSqliteSessionEntryKeysReadOnly as listSessionEntryKeysReadOnly, - loadExactSqliteSessionEntry as loadExactSessionEntry, - loadExactSqliteSessionEntryReadOnly as loadExactSessionEntryReadOnly, - loadSqliteSessionEntry as loadSessionEntry, - loadSqliteSessionEntryReadOnly as loadSessionEntryReadOnly, - patchSqliteSessionEntry as patchSessionEntry, - patchSqliteSessionEntryTarget as patchSessionEntryTarget, - readSqliteSessionUpdatedAt as readSessionUpdatedAt, - replaceSqliteSessionEntry as replaceSessionEntry, - replaceSqliteSessionEntrySync as replaceSessionEntrySync, - resolveSqliteSessionEntry, - upsertSqliteSessionEntry as upsertSessionEntry, + countSessionEntryRowsReadOnly, + ensureSessionEntrySync, + hasSessionEntriesByStatusReadOnly, + listSessionChildEntriesReadOnly, + listSessionEntryRows, + listSessionEntriesReadOnly, + listSessionEntryKeysReadOnly, + loadExactSessionEntry, + loadExactSessionEntryReadOnly, + loadSessionEntry, + loadSessionEntryReadOnly, + patchSessionEntry, + patchSessionEntryTarget, + readSessionUpdatedAt, + replaceSessionEntry, + replaceSessionEntrySync, + resolveSessionEntry, + upsertSessionEntry, } from "./session-accessor.sqlite-entry.js"; import type { SessionAccessScope, @@ -54,7 +54,10 @@ import type { } from "./session-accessor.types.js"; import { canonicalSessionKeyMigrationRequiredError } from "./session-canonical-key.js"; import { resolveSessionStorePathForScope } from "./session-store-path.js"; -import { normalizeStoreSessionKey, resolveSessionStoreEntry } from "./store-entry.js"; +import { + normalizeStoreSessionKey, + resolveSessionStoreEntry as resolveSessionEntryFromStore, +} from "./store-entry.js"; import { resolveAllAgentSessionStoreTargetsSync, type SessionStoreTarget } from "./targets.js"; import type { SessionEntry } from "./types.js"; @@ -81,24 +84,19 @@ export { patchSessionEntryTarget, readSessionUpdatedAt, replaceSessionEntry, + // Intentionally unfenced: branching owns session-identity freshness; worker transcript commit + // fresh-reads and checks sessionId inside its locked commit, and void/entry has no rebound signal. replaceSessionEntrySync, + resolveSessionEntryFromStore, upsertSessionEntry, }; -/** Keeps legacy store-key alias resolution behind the entry owner boundary. */ -export function resolveSessionEntryFromStore(params: { - store: Record; - sessionKey: string; -}): ReturnType { - return resolveSessionStoreEntry(params); -} - /** Resolves a session directly through canonical SQLite row and alias ownership. */ export function resolveSessionEntrySelection( scope: SessionAccessScope, options: { readOnly?: boolean } = {}, -): ReturnType { - return resolveSqliteSessionEntry(scope, options); +): ReturnType { + return resolveSessionEntry(scope, options); } export function resolveAccessStorePath(scope: SessionAccessScope): string { @@ -382,7 +380,7 @@ export function listSessionEntries(scope: SessionEntryListScope = {}): SessionEn if (scope.clone === false) { return openSessionEntryReadView(scope).entries(); } - return listSqliteSessionEntries(scope); + return listSessionEntryRows(scope); } /** @@ -402,7 +400,7 @@ export function openSessionEntryReadView( clone: false, sessionKey, })?.entry, - entries: () => listSqliteSessionEntries({ ...scope, clone: false }), + entries: () => listSessionEntryRows({ ...scope, clone: false }), }; } diff --git a/src/config/sessions/session-accessor.lifecycle.ts b/src/config/sessions/session-accessor.lifecycle.ts index 0f8480be575c..143d1c8fc37c 100644 --- a/src/config/sessions/session-accessor.lifecycle.ts +++ b/src/config/sessions/session-accessor.lifecycle.ts @@ -16,19 +16,19 @@ import { replaceSessionEntry, patchSessionEntry, } from "./session-accessor.entry.js"; -import { applySqliteSessionEntryBatchProjection as applySessionEntryBatchProjection } from "./session-accessor.sqlite-batch-projection.js"; +import { applySessionEntryBatchProjection } from "./session-accessor.sqlite-batch-projection.js"; import { - cleanupSqliteSessionLifecycleArtifacts as cleanupSessionLifecycleArtifacts, - deleteSqliteSessionEntryLifecycle as deleteSessionEntryLifecycle, - rollbackSqliteAgentHarnessSessionEntryLifecycle as rollbackAgentHarnessSessionEntryLifecycle, - rollbackSqlitePluginOwnedSessionEntryLifecycle as rollbackPluginOwnedSessionEntryLifecycle, - resetSqliteSessionEntryLifecycle as resetSessionEntryLifecycle, + cleanupSessionLifecycleArtifacts, + deleteSessionEntryLifecycle, + rollbackAgentHarnessSessionEntryLifecycle, + rollbackPluginOwnedSessionEntryLifecycle, + resetSessionEntryLifecycle, } from "./session-accessor.sqlite-lifecycle.js"; import { - applySqliteSessionEntryLifecycleMutation as applySessionEntryLifecycleMutation, - applySqliteSessionEntryReplacements as applySessionEntryReplacements, - applySqliteSessionStoreProjection as applySessionStoreProjection, - purgeSqliteDeletedAgentSessionEntries as purgeDeletedAgentSessionEntries, + applySessionEntryLifecycleMutation, + applySessionEntryReplacements, + applySessionStoreProjection, + purgeDeletedAgentSessionEntries, } from "./session-accessor.sqlite-projection.js"; import type { SessionAccessScope, diff --git a/src/config/sessions/session-accessor.message-cut.ts b/src/config/sessions/session-accessor.message-cut.ts deleted file mode 100644 index 4e8f62204a01..000000000000 --- a/src/config/sessions/session-accessor.message-cut.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - forkSqliteSessionAtMessage, - rewindSqliteSessionToMessage, - switchSqliteSessionBranch, -} from "./session-accessor.sqlite-message-cut.js"; -import type { - SessionBranchSwitchMutationParams, - SessionBranchSwitchMutationResult, - SessionMessageCutMutationParams, - SessionMessageCutMutationResult, -} from "./session-accessor.types.js"; - -export { - listSqliteSessionBranches as listSessionBranches, - resolveSessionTranscriptActiveLeafEntryId, -} from "./session-accessor.sqlite-message-cut.js"; - -export async function rewindSessionToMessage( - params: SessionMessageCutMutationParams, -): Promise { - const result = await rewindSqliteSessionToMessage(params); - return result.status === "conflict" ? { status: "failed" } : result; -} - -export async function forkSessionAtMessage( - params: SessionMessageCutMutationParams & { targetKey: string }, -): Promise { - const result = await forkSqliteSessionAtMessage(params); - return result.status === "conflict" ? { status: "failed" } : result; -} - -export async function switchSessionBranch( - params: SessionBranchSwitchMutationParams, -): Promise { - const result = await switchSqliteSessionBranch(params); - return result.status === "conflict" ? { status: "failed" } : result; -} diff --git a/src/config/sessions/session-accessor.reply-init-concurrency.test.ts b/src/config/sessions/session-accessor.reply-init-concurrency.test.ts index 1771c7e25fd1..2fa7d1914a59 100644 --- a/src/config/sessions/session-accessor.reply-init-concurrency.test.ts +++ b/src/config/sessions/session-accessor.reply-init-concurrency.test.ts @@ -14,7 +14,7 @@ import { upsertSessionEntry, withTranscriptWriteLock, } from "./session-accessor.js"; -import { replaceSqliteTranscriptEvents } from "./session-accessor.sqlite-transcript-write.js"; +import { replaceTranscriptEvents } from "./session-accessor.sqlite-transcript-write.js"; vi.mock("../config.js", async () => ({ ...(await vi.importActual("../config.js")), @@ -528,7 +528,7 @@ describe("session accessor cross-process concurrency", () => { sessionId, updatedAt: Date.now(), }); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { type: "session", version: 3, id: sessionId }, { type: "message", @@ -688,7 +688,7 @@ describe("session accessor cross-process concurrency", () => { try { await upsertSessionEntry(scope, { sessionId, updatedAt: Date.now() }); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { type: "session", version: 3, id: sessionId }, { type: "message", diff --git a/src/config/sessions/session-accessor.sqlite-archive.ts b/src/config/sessions/session-accessor.sqlite-archive.ts index 4079dd7b1ddb..eaa300fab69a 100644 --- a/src/config/sessions/session-accessor.sqlite-archive.ts +++ b/src/config/sessions/session-accessor.sqlite-archive.ts @@ -13,7 +13,7 @@ import { import { formatSessionArchiveTimestamp, type SessionArchiveReason } from "./artifacts.js"; import type { SessionLifecycleArchivedTranscript } from "./session-accessor.sqlite-contract.js"; -export type SqliteSessionStateDeleteSnapshot = { +export type SessionStateDeleteSnapshot = { acpParentStreamEventCount: number; generation: string | null; lastSeq: number | null; @@ -22,38 +22,38 @@ export type SqliteSessionStateDeleteSnapshot = { transcriptUpdatedAt: number | null; }; -export type SqliteSessionStateDeletePlan = { +export type SessionStateDeletePlan = { agentId: string; archiveDirectory: string; archiveTranscript: boolean; databasePath: string; reason: "deleted" | "reset"; sessionId: string; - snapshot: SqliteSessionStateDeleteSnapshot; + snapshot: SessionStateDeleteSnapshot; }; -export type MaterializedSqliteSessionStateDeletePlan = SqliteSessionStateDeletePlan & { +export type MaterializedSessionStateDeletePlan = SessionStateDeletePlan & { archivedTranscript: SessionLifecycleArchivedTranscript | null; }; -export type SqliteTranscriptArchiveWorkerPlan = Pick< - SqliteSessionStateDeletePlan, +export type TranscriptArchiveWorkerPlan = Pick< + SessionStateDeletePlan, "agentId" | "archiveDirectory" | "databasePath" | "reason" | "sessionId" | "snapshot" >; -export type SqliteTranscriptArchiveWorkerResult = { +export type TranscriptArchiveWorkerResult = { archivedPath: string | null; sessionId: string; }; -export type SqliteTranscriptArchiveWorkerMessage = { +export type TranscriptArchiveWorkerMessage = { type: "done"; - results: SqliteTranscriptArchiveWorkerResult[]; + results: TranscriptArchiveWorkerResult[]; }; export function sqliteSessionStateDeleteSnapshotsEqual( - left: SqliteSessionStateDeleteSnapshot, - right: SqliteSessionStateDeleteSnapshot, + left: SessionStateDeleteSnapshot, + right: SessionStateDeleteSnapshot, ): boolean { return ( left.acpParentStreamEventCount === right.acpParentStreamEventCount && @@ -120,7 +120,7 @@ function findMatchingSqliteTranscriptArchive(params: { } /** Writes or reuses a transcript archive and returns its durable path. */ -export function writeSqliteTranscriptArchive(params: { +export function writeTranscriptArchive(params: { archiveDirectory: string; content: string; reason: SessionArchiveReason; @@ -210,8 +210,8 @@ function normalizeArchiveWorkerError(error: unknown): Error { } function spawnSqliteTranscriptArchiveWorker( - plans: readonly SqliteTranscriptArchiveWorkerPlan[], -): Promise { + plans: readonly TranscriptArchiveWorkerPlan[], +): Promise { const workerUrl = resolveSqliteTranscriptArchiveWorkerUrl(); let worker: Worker; try { @@ -227,9 +227,9 @@ function spawnSqliteTranscriptArchiveWorker( } return new Promise((resolve, reject) => { - let results: SqliteTranscriptArchiveWorkerResult[] | undefined; + let results: TranscriptArchiveWorkerResult[] | undefined; let workerError: Error | undefined; - worker.once("message", (message: SqliteTranscriptArchiveWorkerMessage) => { + worker.once("message", (message: TranscriptArchiveWorkerMessage) => { results = message.results; }); worker.once("error", (error) => { @@ -262,8 +262,8 @@ const sqliteTranscriptArchiveWorkerQueue = new KeyedAsyncQueue(); const SQLITE_TRANSCRIPT_ARCHIVE_WORKER_QUEUE_KEY = "lifecycle-archive"; function runSqliteTranscriptArchiveWorker( - plans: readonly SqliteTranscriptArchiveWorkerPlan[], -): Promise { + plans: readonly TranscriptArchiveWorkerPlan[], +): Promise { return sqliteTranscriptArchiveWorkerQueue.enqueue( SQLITE_TRANSCRIPT_ARCHIVE_WORKER_QUEUE_KEY, () => spawnSqliteTranscriptArchiveWorker(plans), @@ -274,9 +274,9 @@ function runSqliteTranscriptArchiveWorker( // SQLite write transactions and off the gateway event loop. The lifecycle // Worker queue and per-call dedupe prevent concurrent whole-buffer spikes // within this path. -export async function materializeSqliteSessionStateDeletePlans( - plans: readonly SqliteSessionStateDeletePlan[], -): Promise { +export async function materializeSessionStateDeletePlans( + plans: readonly SessionStateDeletePlan[], +): Promise { const deduped = dedupeSqliteSessionStateDeletePlans(plans); const archivePlans = deduped.filter((plan) => plan.archiveTranscript); const workerResults = @@ -304,9 +304,9 @@ export async function materializeSqliteSessionStateDeletePlans( // Multiple removed entries can point at one transcript session. If any owner // asked to keep an archive, the shared row gets exported once. function dedupeSqliteSessionStateDeletePlans( - plans: readonly SqliteSessionStateDeletePlan[], -): SqliteSessionStateDeletePlan[] { - const deduped = new Map(); + plans: readonly SessionStateDeletePlan[], +): SessionStateDeletePlan[] { + const deduped = new Map(); for (const plan of plans) { const existing = deduped.get(plan.sessionId); if (!existing) { diff --git a/src/config/sessions/session-accessor.sqlite-archive.worker.test.ts b/src/config/sessions/session-accessor.sqlite-archive.worker.test.ts index 8e9f10cc0f53..3d449729dd94 100644 --- a/src/config/sessions/session-accessor.sqlite-archive.worker.test.ts +++ b/src/config/sessions/session-accessor.sqlite-archive.worker.test.ts @@ -22,14 +22,14 @@ import { loadTranscriptEvents, replaceSessionEntry, } from "./session-accessor.js"; -import { materializeSqliteSessionStateDeletePlans } from "./session-accessor.sqlite-archive.js"; -import { materializeSqliteTranscriptArchiveInWorker } from "./session-accessor.sqlite-archive.worker.js"; +import { materializeSessionStateDeletePlans } from "./session-accessor.sqlite-archive.js"; +import { materializeTranscriptArchiveInWorker } from "./session-accessor.sqlite-archive.worker.js"; import { - deleteMaterializedSqliteSessionStatePlans, - planSqliteSessionStateDeleteIfUnreferenced, + deleteMaterializedSessionStatePlans, + planSessionStateDeleteIfUnreferenced, } from "./session-accessor.sqlite-lifecycle-state.js"; import { touchTranscriptMutationInTransaction } from "./session-accessor.sqlite-transcript-state.js"; -import { replaceSqliteTranscriptEvents } from "./session-accessor.sqlite-transcript-write.js"; +import { replaceTranscriptEvents } from "./session-accessor.sqlite-transcript-write.js"; import { resolveSqliteTargetFromSessionStorePath } from "./session-sqlite-target.js"; type TestTranscriptEvent = { @@ -65,17 +65,17 @@ describe("SQLite transcript archive worker", () => { : `${index}:${randomBytes(576 * 1024).toString("base64")}`, ), ); - await replaceSqliteTranscriptEvents({ sessionKey, sessionId, storePath }, events); + await replaceTranscriptEvents({ sessionKey, sessionId, storePath }, events); const heartbeatTimes = [performance.now()]; const heartbeat = setInterval(() => { heartbeatTimes.push(performance.now()); }, 5); - let materialized: Awaited>; + let materialized: Awaited>; try { const database = openLifecycleTestDatabase(storePath); const plan = planArchiveWorker(database, path.dirname(storePath), sessionId); - materialized = await materializeSqliteSessionStateDeletePlans([plan]); + materialized = await materializeSessionStateDeletePlans([plan]); } finally { heartbeatTimes.push(performance.now()); clearInterval(heartbeat); @@ -115,7 +115,7 @@ describe("SQLite transcript archive worker", () => { updatedAt: Date.now(), }, ); - await replaceSqliteTranscriptEvents({ sessionKey, sessionId, storePath }, [ + await replaceTranscriptEvents({ sessionKey, sessionId, storePath }, [ createTranscriptEvent(sessionId, "durable archive first"), ]); @@ -143,7 +143,7 @@ describe("SQLite transcript archive worker", () => { let archivedPath: string | null = null; try { const database = openLifecycleTestDatabase(storePath); - const workerResult = materializeSqliteTranscriptArchiveInWorker( + const workerResult = materializeTranscriptArchiveInWorker( planArchiveWorker(database, path.dirname(storePath), sessionId), ); archivedPath = workerResult.archivedPath; @@ -200,9 +200,9 @@ describe("SQLite transcript archive worker", () => { const opsEvent = createTranscriptEvent(opsSessionId, "archive logical-owner transcript"); await replaceSessionEntry(mainScope, { sessionId: mainSessionId, updatedAt: Date.now() }); - await replaceSqliteTranscriptEvents(mainScope, [mainEvent]); + await replaceTranscriptEvents(mainScope, [mainEvent]); await replaceSessionEntry(opsScope, { sessionId: opsSessionId, updatedAt: Date.now() }); - await replaceSqliteTranscriptEvents(opsScope, [opsEvent]); + await replaceTranscriptEvents(opsScope, [opsEvent]); const opsTarget = resolveSqliteTargetFromSessionStorePath(sharedDatabasePath, { agentId: opsScope.agentId, @@ -223,7 +223,7 @@ describe("SQLite transcript archive worker", () => { databasePath: database.path, sessionId: opsSessionId, }); - const materialized = await materializeSqliteSessionStateDeletePlans([plan]); + const materialized = await materializeSessionStateDeletePlans([plan]); const archivedPath = materialized[0]?.archivedTranscript?.archivedPath; expect(readArchiveLines(archivedPath ?? undefined)).toEqual([JSON.stringify(opsEvent)]); @@ -242,16 +242,16 @@ describe("SQLite transcript archive worker", () => { storePath, }; const original = createTranscriptEvent(sessionId, "original transcript"); - await replaceSqliteTranscriptEvents(scope, [original]); + await replaceTranscriptEvents(scope, [original]); const database = openLifecycleTestDatabase(storePath); const plan = planArchiveWorker(database, path.dirname(storePath), sessionId); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ original, createTranscriptEvent("concurrent-event", "concurrent append"), ]); - await expect(materializeSqliteSessionStateDeletePlans([plan])).rejects.toThrow( + await expect(materializeSessionStateDeletePlans([plan])).rejects.toThrow( `SQLite session state changed before archive materialization for ${sessionId}`, ); await expect(loadTranscriptEvents(scope)).resolves.toHaveLength(2); @@ -264,7 +264,7 @@ describe("SQLite transcript archive worker", () => { it("rejects deduped plans with different transcript snapshots", async () => { const sessionId = "conflicting-plan-snapshots"; - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { sessionKey: "agent:main:conflicting-plan-snapshots", sessionId, storePath }, [createTranscriptEvent(sessionId, "original transcript")], ); @@ -278,7 +278,7 @@ describe("SQLite transcript archive worker", () => { }, }; - await expect(materializeSqliteSessionStateDeletePlans([plan, conflictingPlan])).rejects.toThrow( + await expect(materializeSessionStateDeletePlans([plan, conflictingPlan])).rejects.toThrow( `Conflicting SQLite transcript archive plans for ${sessionId}`, ); }); @@ -295,11 +295,11 @@ describe("SQLite transcript archive worker", () => { const plan = planArchiveWorker(database, path.dirname(storePath), sessionId); expect(plan.snapshot.lastSeq).toBeNull(); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ createTranscriptEvent(sessionId, "first concurrent append"), ]); - await expect(materializeSqliteSessionStateDeletePlans([plan])).rejects.toThrow( + await expect(materializeSessionStateDeletePlans([plan])).rejects.toThrow( `SQLite session state changed before archive materialization for ${sessionId}`, ); await expect(loadTranscriptEvents(scope)).resolves.toHaveLength(1); @@ -312,7 +312,7 @@ describe("SQLite transcript archive worker", () => { sessionId, storePath, }; - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ createTranscriptEvent(sessionId, "preserve after file failure"), ]); const blockedArchiveDirectory = path.join(tempDir, "archive-path-is-a-file"); @@ -325,13 +325,13 @@ describe("SQLite transcript archive worker", () => { sessionId: recoverySessionId, storePath, }; - await replaceSqliteTranscriptEvents(recoveryScope, [ + await replaceTranscriptEvents(recoveryScope, [ createTranscriptEvent(recoverySessionId, "archive after queued failure"), ]); const recoveryPlan = planArchiveWorker(database, path.dirname(storePath), recoverySessionId); - const failedArchive = materializeSqliteSessionStateDeletePlans([plan]); - const recoveredArchive = materializeSqliteSessionStateDeletePlans([recoveryPlan]); + const failedArchive = materializeSessionStateDeletePlans([plan]); + const recoveredArchive = materializeSessionStateDeletePlans([recoveryPlan]); await expect(failedArchive).rejects.toThrow(); await expect(recoveredArchive).resolves.toMatchObject([ @@ -351,7 +351,7 @@ describe("SQLite transcript archive worker", () => { const sessionKey = "agent:main:archive-worker-lifecycle-failure"; const scope = { sessionKey, sessionId, storePath }; await replaceSessionEntry(scope, { sessionId, updatedAt: Date.now() }); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { type: "message", id: "archive-worker-lifecycle-failure-message", @@ -452,12 +452,12 @@ describe("SQLite transcript archive worker", () => { it("keeps rows when a transcript changes after its archive snapshot", async () => { const sessionId = "stale-archive-snapshot-session"; const sessionKey = "agent:main:stale-archive-snapshot"; - await replaceSqliteTranscriptEvents({ sessionKey, sessionId, storePath }, [ + await replaceTranscriptEvents({ sessionKey, sessionId, storePath }, [ createTranscriptEvent(sessionId, "archived snapshot"), ]); const database = openLifecycleTestDatabase(storePath); const db = getNodeSqliteKysely(database.db); - const plan = planSqliteSessionStateDeleteIfUnreferenced({ + const plan = planSessionStateDeleteIfUnreferenced({ archiveDirectory: path.dirname(storePath), database, referencedSessionIds: new Set(), @@ -466,7 +466,7 @@ describe("SQLite transcript archive worker", () => { if (!plan) { throw new Error("expected an unreferenced SQLite transcript delete plan"); } - const materialized = await materializeSqliteSessionStateDeletePlans([plan]); + const materialized = await materializeSessionStateDeletePlans([plan]); appendTranscriptEvent(database, sessionId); @@ -492,7 +492,7 @@ describe("SQLite transcript archive worker", () => { : "window" }-snapshot`; const sessionKey = `agent:main:${sessionId}`; - await replaceSqliteTranscriptEvents({ sessionKey, sessionId, storePath }, [ + await replaceTranscriptEvents({ sessionKey, sessionId, storePath }, [ createTranscriptEvent(sessionId, "archived transcript"), ]); const database = openLifecycleTestDatabase(storePath); @@ -501,7 +501,7 @@ describe("SQLite transcript archive worker", () => { expect(plan.snapshot.generation).not.toBeNull(); expect(plan.snapshot.sessionUpdatedAt).not.toBeNull(); expect(plan.snapshot.transcriptUpdatedAt).not.toBeNull(); - const materialized = await materializeSqliteSessionStateDeletePlans([plan]); + const materialized = await materializeSessionStateDeletePlans([plan]); if (kind === "rewrite generation") { executeSqliteQuerySync( @@ -551,12 +551,12 @@ describe("SQLite transcript archive worker", () => { it("keeps rows when a non-archive delete plan becomes stale", async () => { const sessionId = "stale-non-archive-snapshot-session"; const sessionKey = "agent:main:stale-non-archive-snapshot"; - await replaceSqliteTranscriptEvents({ sessionKey, sessionId, storePath }, [ + await replaceTranscriptEvents({ sessionKey, sessionId, storePath }, [ createTranscriptEvent(sessionId, "planned transcript"), ]); const database = openLifecycleTestDatabase(storePath); const db = getNodeSqliteKysely(database.db); - const plan = planSqliteSessionStateDeleteIfUnreferenced({ + const plan = planSessionStateDeleteIfUnreferenced({ archiveDirectory: path.dirname(storePath), archiveTranscript: false, database, @@ -566,7 +566,7 @@ describe("SQLite transcript archive worker", () => { if (!plan) { throw new Error("expected an unreferenced SQLite transcript delete plan"); } - const materialized = await materializeSqliteSessionStateDeletePlans([plan]); + const materialized = await materializeSessionStateDeletePlans([plan]); appendTranscriptEvent(database, sessionId); @@ -586,13 +586,13 @@ describe("SQLite transcript archive worker", () => { async (kind) => { const sessionId = `stale-${kind === "trajectory" ? "trajectory" : "acp"}-snapshot-session`; const sessionKey = `agent:main:${sessionId}`; - await replaceSqliteTranscriptEvents({ sessionKey, sessionId, storePath }, [ + await replaceTranscriptEvents({ sessionKey, sessionId, storePath }, [ createTranscriptEvent(sessionId, "archived transcript"), ]); const database = openLifecycleTestDatabase(storePath); const db = getNodeSqliteKysely(database.db); const plan = planArchiveWorker(database, path.dirname(storePath), sessionId); - const materialized = await materializeSqliteSessionStateDeletePlans([plan]); + const materialized = await materializeSessionStateDeletePlans([plan]); if (kind === "trajectory") { appendSqliteTrajectoryRuntimeEvents({ sessionId, storePath }, [ @@ -634,7 +634,7 @@ describe("SQLite transcript archive worker", () => { it("does not reuse a matching in-flight temp file as an archive", async () => { const sessionId = "in-flight-temp-archive-session"; const line = createTranscriptEventLine(sessionId, "in-flight temp archive"); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { sessionKey: "agent:main:in-flight-temp-archive", sessionId, storePath }, [JSON.parse(line) as TestTranscriptEvent], ); @@ -647,7 +647,7 @@ describe("SQLite transcript archive worker", () => { fs.writeFileSync(tempPath, `${line}\n`, "utf8"); const database = openLifecycleTestDatabase(storePath); - const result = materializeSqliteTranscriptArchiveInWorker( + const result = materializeTranscriptArchiveInWorker( planArchiveWorker(database, archiveDirectory, sessionId), ); @@ -660,7 +660,7 @@ describe("SQLite transcript archive worker", () => { const sessionId = "duplicate-archive-session"; const sessionKey = "agent:main:duplicate-archive"; await replaceSessionEntry({ sessionKey, storePath }, { sessionId, updatedAt: Date.now() }); - await replaceSqliteTranscriptEvents({ sessionKey, sessionId, storePath }, [ + await replaceTranscriptEvents({ sessionKey, sessionId, storePath }, [ createTranscriptEvent(sessionId, "reuse archive"), ]); const archivePath = path.join( @@ -687,7 +687,7 @@ describe("SQLite transcript archive worker", () => { try { const database = openLifecycleTestDatabase(storePath); - const workerResult = materializeSqliteTranscriptArchiveInWorker( + const workerResult = materializeTranscriptArchiveInWorker( planArchiveWorker(database, path.dirname(storePath), sessionId), ); expect(workerResult.archivedPath).toBe(archivePath); @@ -759,7 +759,7 @@ function planArchiveWorker( archiveDirectory: string, sessionId: string, ) { - const plan = planSqliteSessionStateDeleteIfUnreferenced({ + const plan = planSessionStateDeleteIfUnreferenced({ archiveDirectory, database, referencedSessionIds: new Set(), @@ -795,12 +795,12 @@ function appendTranscriptEvent( function deleteMaterializedPlans( database: ReturnType, - plans: Parameters[1], + plans: Parameters[1], excludedSessionKey: string, ): void { runOpenClawAgentWriteTransaction( (transactionDb) => - deleteMaterializedSqliteSessionStatePlans( + deleteMaterializedSessionStatePlans( transactionDb, plans, undefined, diff --git a/src/config/sessions/session-accessor.sqlite-archive.worker.ts b/src/config/sessions/session-accessor.sqlite-archive.worker.ts index cf61990fe6e1..604fb8a22a12 100644 --- a/src/config/sessions/session-accessor.sqlite-archive.worker.ts +++ b/src/config/sessions/session-accessor.sqlite-archive.worker.ts @@ -5,13 +5,13 @@ import { withOpenClawAgentDatabaseReadOnly } from "../../state/openclaw-agent-db import type { DB as OpenClawAgentKyselyDatabase } from "../../state/openclaw-agent-db.generated.js"; import { sqliteSessionStateDeleteSnapshotsEqual, - type SqliteSessionStateDeleteSnapshot, - type SqliteTranscriptArchiveWorkerMessage, - type SqliteTranscriptArchiveWorkerPlan, - type SqliteTranscriptArchiveWorkerResult, - writeSqliteTranscriptArchive, + type SessionStateDeleteSnapshot, + type TranscriptArchiveWorkerMessage, + type TranscriptArchiveWorkerPlan, + type TranscriptArchiveWorkerResult, + writeTranscriptArchive, } from "./session-accessor.sqlite-archive.js"; -import { readSqliteSessionStateDeleteSnapshot } from "./session-accessor.sqlite-delete-snapshot.js"; +import { readSessionStateDeleteSnapshot } from "./session-accessor.sqlite-delete-snapshot.js"; import { serializeJsonlLines } from "./transcript-jsonl.js"; type TranscriptArchiveDatabase = Pick; @@ -25,7 +25,7 @@ function isSqliteTranscriptArchiveWorkerData(value: unknown): boolean { ); } -function parseSessionStateDeleteSnapshot(value: unknown): SqliteSessionStateDeleteSnapshot | null { +function parseSessionStateDeleteSnapshot(value: unknown): SessionStateDeleteSnapshot | null { if (!value || typeof value !== "object" || Array.isArray(value)) { return null; } @@ -50,7 +50,7 @@ function parseSessionStateDeleteSnapshot(value: unknown): SqliteSessionStateDele }; } -function parseWorkerPlans(value: unknown): SqliteTranscriptArchiveWorkerPlan[] | undefined { +function parseWorkerPlans(value: unknown): TranscriptArchiveWorkerPlan[] | undefined { if (!value || typeof value !== "object" || Array.isArray(value)) { return undefined; } @@ -58,7 +58,7 @@ function parseWorkerPlans(value: unknown): SqliteTranscriptArchiveWorkerPlan[] | if (!Array.isArray(plans)) { return undefined; } - const parsed: SqliteTranscriptArchiveWorkerPlan[] = []; + const parsed: TranscriptArchiveWorkerPlan[] = []; for (const planValue of plans) { if (!planValue || typeof planValue !== "object" || Array.isArray(planValue)) { return undefined; @@ -103,9 +103,9 @@ function readTranscriptArchiveContent( return serializeJsonlLines(lines); } -export function materializeSqliteTranscriptArchiveInWorker( - plan: SqliteTranscriptArchiveWorkerPlan, -): SqliteTranscriptArchiveWorkerResult { +export function materializeTranscriptArchiveInWorker( + plan: TranscriptArchiveWorkerPlan, +): TranscriptArchiveWorkerResult { const opened = withOpenClawAgentDatabaseReadOnly( (database) => { let transactionOpen = false; @@ -113,7 +113,7 @@ export function materializeSqliteTranscriptArchiveInWorker( // sqlite-allow-raw: metadata and transcript rows must come from one read snapshot. database.db.exec("BEGIN"); transactionOpen = true; - const snapshot = readSqliteSessionStateDeleteSnapshot(database.db, plan.sessionId); + const snapshot = readSessionStateDeleteSnapshot(database.db, plan.sessionId); if (!sqliteSessionStateDeleteSnapshotsEqual(snapshot, plan.snapshot)) { throw new Error( `SQLite session state changed before archive materialization for ${plan.sessionId}`, @@ -140,7 +140,7 @@ export function materializeSqliteTranscriptArchiveInWorker( const { content } = opened.value; const archivedPath = content.length > 0 - ? writeSqliteTranscriptArchive({ + ? writeTranscriptArchive({ archiveDirectory: plan.archiveDirectory, content, reason: plan.reason, @@ -152,10 +152,10 @@ export function materializeSqliteTranscriptArchiveInWorker( function runWorkerPort( port: NonNullable, - plans: readonly SqliteTranscriptArchiveWorkerPlan[], + plans: readonly TranscriptArchiveWorkerPlan[], ): void { - const results = plans.map((plan) => materializeSqliteTranscriptArchiveInWorker(plan)); - port.postMessage({ type: "done", results } satisfies SqliteTranscriptArchiveWorkerMessage); + const results = plans.map((plan) => materializeTranscriptArchiveInWorker(plan)); + port.postMessage({ type: "done", results } satisfies TranscriptArchiveWorkerMessage); port.close(); } diff --git a/src/config/sessions/session-accessor.sqlite-batch-projection.ts b/src/config/sessions/session-accessor.sqlite-batch-projection.ts index 34a008d107df..b382136596ae 100644 --- a/src/config/sessions/session-accessor.sqlite-batch-projection.ts +++ b/src/config/sessions/session-accessor.sqlite-batch-projection.ts @@ -1,10 +1,10 @@ import { isInternalSessionEffectsKey } from "./internal-session-key.js"; import type { SessionEntryBatchProjectionUpdate } from "./session-accessor.sqlite-contract.js"; -import { applySqliteSessionEntryCanonicalReplacements } from "./session-accessor.sqlite-replacement-projection.js"; +import { applySessionEntryCanonicalReplacements } from "./session-accessor.sqlite-replacement-projection.js"; import type { SessionEntry } from "./types.js"; /** Compatibility adapter for the shipped detached-store projection. */ -export async function applySqliteSessionEntryBatchProjection(params: { +export async function applySessionEntryBatchProjection(params: { activeSessionKey?: string; agentId?: string; sessionKeys?: readonly string[]; @@ -14,7 +14,7 @@ export async function applySqliteSessionEntryBatchProjection(params: { store: Record, ) => Promise> | SessionEntryBatchProjectionUpdate; }): Promise { - return await applySqliteSessionEntryCanonicalReplacements({ + return await applySessionEntryCanonicalReplacements({ ...params, update: async (entries) => { const store = Object.fromEntries( diff --git a/src/config/sessions/session-accessor.sqlite-canonical-repair.ts b/src/config/sessions/session-accessor.sqlite-canonical-repair.ts index ba13b8a06d4b..c6e29bcd21cf 100644 --- a/src/config/sessions/session-accessor.sqlite-canonical-repair.ts +++ b/src/config/sessions/session-accessor.sqlite-canonical-repair.ts @@ -12,21 +12,21 @@ import { } from "../../state/openclaw-agent-db.js"; import { normalizeSessionDeliveryState } from "../../utils/delivery-context.shared.js"; import type { SessionEntrySummary } from "./session-accessor.sqlite-contract.js"; -import { publishSqliteSessionEntryCacheInvalidation } from "./session-accessor.sqlite-entry-cache.js"; -import { readSqliteSessionGenerationIdsForKeys } from "./session-accessor.sqlite-lifecycle-state.js"; +import { publishSessionEntryCacheInvalidation } from "./session-accessor.sqlite-entry-cache.js"; +import { readSessionGenerationIdsForKeys } from "./session-accessor.sqlite-lifecycle-state.js"; import { copySessionNodeArtifactsForRepair, deleteSessionMembersForRepair, } from "./session-accessor.sqlite-node-artifacts.js"; -import { collectSqliteSessionStateIdsForEntry } from "./session-accessor.sqlite-references.js"; +import { collectSessionStateIdsForEntry } from "./session-accessor.sqlite-references.js"; import { getSessionKysely, resolveSqliteScope, resolveSqliteStoreScope, toDatabaseOptions, } from "./session-accessor.sqlite-scope.js"; -import { bindSqliteSessionWindowEntryProjection } from "./session-accessor.sqlite-session-row.js"; -import { parseSqliteSessionEntryJson } from "./session-accessor.sqlite-status.js"; +import { bindSessionWindowEntryProjection } from "./session-accessor.sqlite-session-row.js"; +import { parseSessionEntryJson } from "./session-accessor.sqlite-status.js"; import type { SessionEntryListScope } from "./session-accessor.types.js"; import { canonicalSessionKeyMigrationRequiredError } from "./session-canonical-key.js"; import { @@ -80,7 +80,7 @@ export function readExactSessionEntryRowForCanonicalRepair( return undefined; } } - const parsedEntry = parseSqliteSessionEntryJson(row); + const parsedEntry = parseSessionEntryJson(row); if (!parsedEntry && !options.allowMalformedRowRepair) { throw canonicalSessionKeyMigrationRequiredError( `invalid persisted session row requires repair for ${sessionKey}`, @@ -129,7 +129,7 @@ export function listSqliteSessionGenerationIdsForCanonicalRepair(params: { }): string[] { const source = resolveSqliteStoreScope(params.storePath, { agentId: params.agentId }); const database = openOpenClawAgentDatabase(toDatabaseOptions(source)); - return readSqliteSessionGenerationIdsForKeys(database, uniqueStrings(params.sourceKeys), { + return readSessionGenerationIdsForKeys(database, uniqueStrings(params.sourceKeys), { exactStoredKeys: true, }); } @@ -328,7 +328,7 @@ export function listSqliteSessionEntriesForCanonicalRepair( if (row.entry_json === "{}" && row.current_window_id === row.current_session_id) { return []; } - const persistedEntry = parseSqliteSessionEntryJson(row); + const persistedEntry = parseSessionEntryJson(row); const entry = persistedEntry ?? hydrateCanonicalRepairEntry(row); const lineageProjectionMismatch = Boolean( persistedEntry && @@ -369,7 +369,7 @@ function copySqliteSessionOwnedStateForRepair(params: { const sourceDb = getSessionKysely(params.source.db); const destinationDb = getSessionKysely(params.destination.db); const entrySessionIds = uniqueStrings( - params.sourceEntries.flatMap((entry) => [...collectSqliteSessionStateIdsForEntry(entry)]), + params.sourceEntries.flatMap((entry) => [...collectSessionStateIdsForEntry(entry)]), ); const windows = executeSqliteQuerySync( params.source.db, @@ -471,7 +471,7 @@ function copySqliteSessionOwnedStateForRepair(params: { } } const preferredWindowProjection = params.preferredEntry - ? bindSqliteSessionWindowEntryProjection({ + ? bindSessionWindowEntryProjection({ entry: params.preferredEntry, sessionKey: params.canonicalKey, }) @@ -528,7 +528,7 @@ function copySqliteSessionOwnedStateForRepair(params: { (params.preferredEntry?.sessionId === sessionId ? params.preferredEntry : undefined) ?? params.sourceEntries.find((candidate) => candidate.sessionId === sessionId) ?? params.sourceEntries.find((candidate) => - new Set(collectSqliteSessionStateIdsForEntry(candidate)).has(sessionId), + new Set(collectSessionStateIdsForEntry(candidate)).has(sessionId), ); const updatedAt = entry?.updatedAt ?? Date.now(); const recoveryWindow = { @@ -580,7 +580,7 @@ function copySqliteSessionOwnedStateForRepair(params: { // Search and active-event tables are derived from transcript_events; force their canonical rebuild. deleteSessionTranscriptIndexInTransaction(params.destination.db, sessionId); reconcileSessionTranscriptIndexInTransaction(params.destination.db, sessionId); - publishSqliteSessionEntryCacheInvalidation(params.destination); + publishSessionEntryCacheInvalidation(params.destination); } // Membership is authorization state and follows the selected winner. Boards, // suggestions, and heartbeat state merge by their own revision/id contracts. diff --git a/src/config/sessions/session-accessor.sqlite-checkpoint.ts b/src/config/sessions/session-accessor.sqlite-checkpoint.ts index c3ca0f404632..decaa60e228b 100644 --- a/src/config/sessions/session-accessor.sqlite-checkpoint.ts +++ b/src/config/sessions/session-accessor.sqlite-checkpoint.ts @@ -9,7 +9,7 @@ import type { TranscriptEvent } from "./session-accessor.sqlite-contract.js"; import { collectSessionEntryLookupKeys, readSessionEntryRow, - readSqliteSessionIdentitySnapshot, + readSessionIdentitySnapshot, writeSessionEntry, } from "./session-accessor.sqlite-entry-store.js"; import { emitCommittedSessionIdentityDiff } from "./session-accessor.sqlite-identity.js"; @@ -91,7 +91,7 @@ type SqliteRestoreCheckpointSessionParams = { legacySource?: SqliteCompactionCheckpointLegacySource; }; -export async function branchSqliteCompactionCheckpointSession( +export async function branchCompactionCheckpointSession( params: SqliteBranchCheckpointSessionParams, ): Promise { const sourceKey = normalizeSqliteSessionKey(params.sourceStoreKey ?? params.sourceKey); @@ -112,7 +112,7 @@ export async function branchSqliteCompactionCheckpointSession( ...collectSessionEntryLookupKeys(database, sourceKey), ...collectSessionEntryLookupKeys(database, targetKey), ]); - previousIdentity = readSqliteSessionIdentitySnapshot(database, identityKeys); + previousIdentity = readSessionIdentitySnapshot(database, identityKeys); result = branchSqliteCompactionCheckpointSessionInTransaction(database, { checkpointId: params.checkpointId, expectedState: params.expectedState, @@ -122,7 +122,7 @@ export async function branchSqliteCompactionCheckpointSession( sourceKey, targetKey, }); - currentIdentity = readSqliteSessionIdentitySnapshot(database, identityKeys); + currentIdentity = readSessionIdentitySnapshot(database, identityKeys); }, toDatabaseOptions(resolved)); emitCommittedSessionIdentityDiff(previousIdentity, currentIdentity); return result ?? { status: "failed" }; @@ -130,7 +130,7 @@ export async function branchSqliteCompactionCheckpointSession( } /** Restores a SQLite session from a compaction checkpoint in one queued transaction. */ -export async function restoreSqliteCompactionCheckpointSession( +export async function restoreCompactionCheckpointSession( params: SqliteRestoreCheckpointSessionParams, ): Promise { const sessionKey = normalizeSqliteSessionKey(params.sessionStoreKey ?? params.sessionKey); @@ -150,7 +150,7 @@ export async function restoreSqliteCompactionCheckpointSession( ...collectSessionEntryLookupKeys(database, sessionKey), ...collectSessionEntryLookupKeys(database, targetKey), ]); - previousIdentity = readSqliteSessionIdentitySnapshot(database, identityKeys); + previousIdentity = readSessionIdentitySnapshot(database, identityKeys); result = restoreSqliteCompactionCheckpointSessionInTransaction(database, { checkpointId: params.checkpointId, expectedState: params.expectedState, @@ -159,7 +159,7 @@ export async function restoreSqliteCompactionCheckpointSession( sourceKey: sessionKey, targetKey, }); - currentIdentity = readSqliteSessionIdentitySnapshot(database, identityKeys); + currentIdentity = readSessionIdentitySnapshot(database, identityKeys); }, toDatabaseOptions(resolved)); emitCommittedSessionIdentityDiff(previousIdentity, currentIdentity); return result ?? { status: "failed" }; diff --git a/src/config/sessions/session-accessor.sqlite-cleanup-race.test.ts b/src/config/sessions/session-accessor.sqlite-cleanup-race.test.ts index 664a5141247f..6e7877963684 100644 --- a/src/config/sessions/session-accessor.sqlite-cleanup-race.test.ts +++ b/src/config/sessions/session-accessor.sqlite-cleanup-race.test.ts @@ -13,8 +13,8 @@ import { loadTranscriptEvents, replaceSessionEntry, } from "./session-accessor.js"; -import { planSqliteSessionLifecycleArtifactCleanup } from "./session-accessor.sqlite-lifecycle-state.js"; -import { replaceSqliteTranscriptEvents } from "./session-accessor.sqlite-transcript-write.js"; +import { planSessionLifecycleArtifactCleanup } from "./session-accessor.sqlite-lifecycle-state.js"; +import { replaceTranscriptEvents } from "./session-accessor.sqlite-transcript-write.js"; import { resolveSqliteTargetFromSessionStorePath } from "./session-sqlite-target.js"; import type { SessionEntry } from "./types.js"; @@ -29,11 +29,11 @@ vi.mock("./session-accessor.sqlite-archive.js", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, - materializeSqliteSessionStateDeletePlans: async ( - ...args: Parameters + materializeSessionStateDeletePlans: async ( + ...args: Parameters ) => { await archiveMaterializationHook.beforeMaterialize?.(); - const result = await actual.materializeSqliteSessionStateDeletePlans(...args); + const result = await actual.materializeSessionStateDeletePlans(...args); archiveMaterializationHook.afterMaterialize?.(); return result; }, @@ -91,7 +91,7 @@ describe("SQLite lifecycle cleanup races", () => { const sessionKey = "agent:main:cleanup-race-reused"; const sessionId = "reused-active-session"; await replaceSessionEntry({ sessionKey, storePath }, { sessionId, updatedAt: now }); - await replaceSqliteTranscriptEvents({ sessionKey, sessionId, storePath }, [ + await replaceTranscriptEvents({ sessionKey, sessionId, storePath }, [ { runId: "cleanup-race-marker-reused", timestamp: new Date(now - 600_000).toISOString(), @@ -175,7 +175,7 @@ describe("SQLite lifecycle cleanup races", () => { timestamp: new Date(staleUpdatedAt).toISOString(), type: "metadata", }; - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { agentId: "researcher", sessionKey: researcherHistoryKey, @@ -235,7 +235,7 @@ describe("SQLite lifecycle cleanup races", () => { timestamp: new Date(staleUpdatedAt).toISOString(), runId: "cleanup-race-marker-foreign", }; - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { sessionKey: foreignKey, sessionId: foreignHistoryId, storePath }, [foreignEvent], ); @@ -273,7 +273,7 @@ describe("SQLite lifecycle cleanup races", () => { timestamp: new Date(now - 600_000).toISOString(), type: "metadata", }; - await replaceSqliteTranscriptEvents({ sessionKey, sessionId, storePath }, [event]); + await replaceTranscriptEvents({ sessionKey, sessionId, storePath }, [event]); const databasePath = resolveSqliteTargetFromSessionStorePath(storePath, { agentId: "main", }).path; @@ -315,7 +315,7 @@ describe("SQLite lifecycle cleanup races", () => { pluginOwnerId: "other-plugin", }, ); - await replaceSqliteTranscriptEvents({ sessionKey, sessionId: foreignSessionId, storePath }, [ + await replaceTranscriptEvents({ sessionKey, sessionId: foreignSessionId, storePath }, [ { runId: "cleanup-race-marker-mixed-foreign", timestamp: new Date(now - 600_000).toISOString(), @@ -359,7 +359,7 @@ describe("SQLite lifecycle cleanup races", () => { content: "cleanup-race-marker transcript", } as const; await replaceSessionEntry({ sessionKey, storePath }, { sessionId, updatedAt: now }); - await replaceSqliteTranscriptEvents({ sessionKey, sessionId, storePath }, [event]); + await replaceTranscriptEvents({ sessionKey, sessionId, storePath }, [event]); const databasePath = resolveSqliteTargetFromSessionStorePath(storePath, { agentId: "main", }).path; @@ -368,7 +368,7 @@ describe("SQLite lifecycle cleanup races", () => { } const database = openOpenClawAgentDatabase({ agentId: "main", path: databasePath }); const cleanupNow = Date.now() + 60_000; - const planned = planSqliteSessionLifecycleArtifactCleanup(database, { + const planned = planSessionLifecycleArtifactCleanup(database, { archiveRemovedEntryTranscripts: true, archiveDirectory: path.dirname(storePath), sessionKeySegmentPrefix: "cleanup-race", @@ -417,7 +417,7 @@ describe("SQLite lifecycle cleanup races", () => { { sessionKey: deletedKey, storePath }, { sessionId: deletedSessionId, updatedAt: Date.now() }, ); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { sessionKey: deletedKey, sessionId: deletedSessionId, storePath }, [ { @@ -477,11 +477,11 @@ describe("SQLite lifecycle cleanup races", () => { { sessionKey: deletedKey, storePath }, { sessionId: currentSessionId, updatedAt: Date.now() }, ); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { sessionKey: deletedKey, sessionId: currentSessionId, storePath }, [{ type: "session", id: currentSessionId, content: "current transcript" }], ); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { sessionKey: deletedKey, sessionId: historicalSessionId, storePath }, [{ type: "session", id: historicalSessionId, content: "historical transcript" }], ); @@ -539,7 +539,7 @@ describe("SQLite lifecycle cleanup races", () => { { sessionKey: deletedKey, storePath }, { sessionId: deletedSessionId, updatedAt: now - 600_000 }, ); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { sessionKey: deletedKey, sessionId: deletedSessionId, storePath }, [ { @@ -611,7 +611,7 @@ describe("SQLite lifecycle cleanup races", () => { if (!persistedRemovedEntry) { throw new Error("expected persisted lifecycle removal entry"); } - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { sessionKey: removedKey, sessionId: removedEntry.sessionId, storePath }, [ { @@ -693,11 +693,10 @@ describe("SQLite lifecycle cleanup races", () => { content: "retained historical transcript", } as const; await replaceSessionEntry({ sessionKey, storePath }, currentEntry); - await replaceSqliteTranscriptEvents( - { sessionKey, sessionId: "current-planned-session", storePath }, - [currentEvent], - ); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents({ sessionKey, sessionId: "current-planned-session", storePath }, [ + currentEvent, + ]); + await replaceTranscriptEvents( { sessionKey, sessionId: "unplanned-historical-session", storePath }, [historicalEvent], ); @@ -754,7 +753,7 @@ describe("SQLite lifecycle cleanup races", () => { { sessionKey: "agent:main:window-owner", storePath }, { sessionId: retainedSessionId, updatedAt: now }, ); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { sessionKey: "agent:main:window-owner", sessionId: retainedSessionId, storePath }, [retainedEvent], ); diff --git a/src/config/sessions/session-accessor.sqlite-data-version.test.ts b/src/config/sessions/session-accessor.sqlite-data-version.test.ts index a7772d99e712..4c25c8fecb81 100644 --- a/src/config/sessions/session-accessor.sqlite-data-version.test.ts +++ b/src/config/sessions/session-accessor.sqlite-data-version.test.ts @@ -18,7 +18,7 @@ import { openSessionEntryReadView, upsertSessionEntry, } from "./session-accessor.js"; -import { readSqliteSessionEntryCache } from "./session-accessor.sqlite-entry-cache.js"; +import { readSessionEntryCache } from "./session-accessor.sqlite-entry-cache.js"; import { ensureTranscriptSessionRoot } from "./session-accessor.sqlite-transcript-state.js"; const parseSessionEntryCalls = vi.hoisted(() => vi.fn()); @@ -53,11 +53,9 @@ vi.mock("./session-accessor.sqlite-status.js", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, - parseSqliteSessionEntryJson: ( - row: Parameters[0], - ) => { + parseSessionEntryJson: (row: Parameters[0]) => { parseSessionEntryCalls(); - const entry = actual.parseSqliteSessionEntryJson(row); + const entry = actual.parseSessionEntryJson(row); if (entry?.label?.startsWith("projection-probe")) { Object.defineProperty(entry, "__projectionProbe", { configurable: true, @@ -232,7 +230,7 @@ describe("SQLite session entry cache", () => { try { parseSessionEntryCalls.mockClear(); - const alternateSnapshot = readSqliteSessionEntryCache( + const alternateSnapshot = readSessionEntryCache( { agentId: primary.agentId, db: alternate }, { cache: true }, ); @@ -247,7 +245,7 @@ describe("SQLite session entry cache", () => { expect(parseSessionEntryCalls).not.toHaveBeenCalled(); parseSessionEntryCalls.mockClear(); - const alternateAgain = readSqliteSessionEntryCache( + const alternateAgain = readSessionEntryCache( { agentId: primary.agentId, db: alternate }, { cache: true }, ); @@ -632,7 +630,7 @@ describe("SQLite session entry cache", () => { const scope = createSessionScope("placeholder-key"); await upsertSessionEntry(scope, { sessionId: "entry", updatedAt: 1 }); const database = openOpenClawAgentDatabase(scope); - const before = readSqliteSessionEntryCache(database, { cache: true }); + const before = readSessionEntryCache(database, { cache: true }); expect(before.keys).toEqual([scope.sessionKey]); const placeholderKey = "agent:main:placeholder-only"; @@ -649,7 +647,7 @@ describe("SQLite session entry cache", () => { ); }, scope); - const after = readSqliteSessionEntryCache(database, { cache: true }); + const after = readSessionEntryCache(database, { cache: true }); expect(after.keys).toEqual([scope.sessionKey, placeholderKey]); expect(after.entries.get(scope.sessionKey)).not.toBe(before.entries.get(scope.sessionKey)); }); diff --git a/src/config/sessions/session-accessor.sqlite-delete-snapshot.ts b/src/config/sessions/session-accessor.sqlite-delete-snapshot.ts index 692c6110d14e..0b098c7f5d2e 100644 --- a/src/config/sessions/session-accessor.sqlite-delete-snapshot.ts +++ b/src/config/sessions/session-accessor.sqlite-delete-snapshot.ts @@ -1,6 +1,6 @@ import { executeSqliteQueryTakeFirstSync, getNodeSqliteKysely } from "../../infra/kysely-sync.js"; import type { DB as OpenClawAgentKyselyDatabase } from "../../state/openclaw-agent-db.generated.js"; -import type { SqliteSessionStateDeleteSnapshot } from "./session-accessor.sqlite-archive.js"; +import type { SessionStateDeleteSnapshot } from "./session-accessor.sqlite-archive.js"; type SessionStateDeleteSnapshotDatabase = Pick< OpenClawAgentKyselyDatabase, @@ -16,10 +16,10 @@ function normalizeOptionalSqliteNumber(value: number | bigint | null | undefined } /** Captures the owner window and canonical child state writable outside the lifecycle queue. */ -export function readSqliteSessionStateDeleteSnapshot( +export function readSessionStateDeleteSnapshot( database: import("node:sqlite").DatabaseSync, sessionId: string, -): SqliteSessionStateDeleteSnapshot { +): SessionStateDeleteSnapshot { const db = getNodeSqliteKysely(database); const window = executeSqliteQueryTakeFirstSync( database, diff --git a/src/config/sessions/session-accessor.sqlite-delta.ts b/src/config/sessions/session-accessor.sqlite-delta.ts index d5f2b70547a4..b8965314e0b7 100644 --- a/src/config/sessions/session-accessor.sqlite-delta.ts +++ b/src/config/sessions/session-accessor.sqlite-delta.ts @@ -93,7 +93,7 @@ function bootstrapCursor( } /** Read one generation-consistent raw transcript page without parsing excluded payload rows. */ -export function readSqliteTranscriptRawDelta( +export function readTranscriptRawDelta( scope: SessionTranscriptReadScope, limits: SessionTranscriptRawDeltaLimits = {}, ): SessionTranscriptRawDeltaResult { diff --git a/src/config/sessions/session-accessor.sqlite-entry-cache.ts b/src/config/sessions/session-accessor.sqlite-entry-cache.ts index 5b9c8ef05b37..1e7359b7789d 100644 --- a/src/config/sessions/session-accessor.sqlite-entry-cache.ts +++ b/src/config/sessions/session-accessor.sqlite-entry-cache.ts @@ -5,24 +5,24 @@ import { type OpenClawAgentDatabase, } from "../../state/openclaw-agent-db.js"; import { getSessionKysely } from "./session-accessor.sqlite-scope.js"; -import { parseSqliteSessionEntryJson } from "./session-accessor.sqlite-status.js"; +import { parseSessionEntryJson } from "./session-accessor.sqlite-status.js"; import type { SessionEntry } from "./types.js"; type SessionEntryCacheDatabase = Pick; -export type SqliteSessionEntryCacheSnapshot = { +export type SessionEntryCacheSnapshot = { entries: Map; keys: string[]; listEntries: Pick, "get">; }; -type SqliteSessionEntryCache = SqliteSessionEntryCacheSnapshot & { +type SqliteSessionEntryCache = SessionEntryCacheSnapshot & { listProjections: Map; updatedAtByKey: Map; validityToken: SqliteSessionEntryCacheValidityToken; }; -type LoadedSessionEntrySnapshot = SqliteSessionEntryCacheSnapshot & { +type LoadedSessionEntrySnapshot = SessionEntryCacheSnapshot & { listProjections: Map; updatedAtByKey: Map; }; @@ -116,7 +116,7 @@ function cacheValidityTokensEqual( } /** Bracket one accessor-owned row write so its publication cannot hide earlier raw DML. */ -export function trackSqliteSessionEntryCacheWrite( +export function trackSessionEntryCacheWrite( database: OpenClawAgentDatabase, write: () => void, ): SqliteSessionEntryCacheWriteGeneration | undefined { @@ -172,7 +172,7 @@ function loadSessionEntrySnapshot(database: SessionEntryCacheDatabase): LoadedSe ).rows; const entries = new Map(); for (const row of rows) { - const entry = parseSqliteSessionEntryJson(row); + const entry = parseSessionEntryJson(row); if (!entry) { continue; } @@ -231,7 +231,7 @@ function incrementallyRevalidateSessionEntrySnapshot( .where("session_key", "in", changedKeys), ).rows; for (const row of changedRows) { - const entry = parseSqliteSessionEntryJson(row); + const entry = parseSessionEntryJson(row); if (entry) { entries.set(row.session_key, entry); } @@ -247,10 +247,10 @@ function incrementallyRevalidateSessionEntrySnapshot( }; } -export function readSqliteSessionEntryCache( +export function readSessionEntryCache( database: SessionEntryCacheDatabase, options: { cache: boolean; latest?: boolean }, -): SqliteSessionEntryCacheSnapshot { +): SessionEntryCacheSnapshot { if (!options.cache || options.latest || database.db.isTransaction) { return loadSessionEntrySnapshot(database); } @@ -324,7 +324,7 @@ function publishSqliteSessionEntryCacheUpsert( }, writeGeneration?: SqliteSessionEntryCacheWriteGeneration, ): void { - const entry = parseSqliteSessionEntryJson({ + const entry = parseSessionEntryJson({ current_session_id: row.current_session_id, entry_json: row.entry_json, updated_at: row.updated_at, @@ -369,7 +369,7 @@ function publishSqliteSessionEntryCacheUpsert( }); } -export function publishSqliteSessionEntryCacheInvalidation( +export function publishSessionEntryCacheInvalidation( database: OpenClawAgentDatabase, row?: { current_session_id: string; diff --git a/src/config/sessions/session-accessor.sqlite-entry-store.ts b/src/config/sessions/session-accessor.sqlite-entry-store.ts index 331ba6a5d927..5d2b62da610e 100644 --- a/src/config/sessions/session-accessor.sqlite-entry-store.ts +++ b/src/config/sessions/session-accessor.sqlite-entry-store.ts @@ -12,8 +12,8 @@ import { upsertConversationIdentity, } from "./session-accessor.sqlite-conversation.js"; import { - publishSqliteSessionEntryCacheInvalidation, - trackSqliteSessionEntryCacheWrite, + publishSessionEntryCacheInvalidation, + trackSessionEntryCacheWrite, } from "./session-accessor.sqlite-entry-cache.js"; import { clearSessionCollaborationForKey, @@ -22,20 +22,20 @@ import { rehomeLegacySessionNodeArtifacts, } from "./session-accessor.sqlite-node-artifacts.js"; import { resolveSessionEntryProvenanceRow } from "./session-accessor.sqlite-provenance.js"; -import { collectSqliteSessionStateIdsForEntry } from "./session-accessor.sqlite-references.js"; +import { collectSessionStateIdsForEntry } from "./session-accessor.sqlite-references.js"; import { cloneSessionEntry, getSessionKysely, normalizeSqliteSessionKey, } from "./session-accessor.sqlite-scope.js"; import { - bindSqliteSessionNode, - bindSqliteSessionRoot, - normalizeSqliteSessionEntryTimestamp, + bindSessionNode, + bindSessionRoot, + normalizeSessionEntryTimestamp, } from "./session-accessor.sqlite-session-row.js"; import { - hasValidSqliteSessionEntryIdentity, - parseSqliteSessionEntryJson as parseSessionEntryRow, + hasValidSessionEntryIdentity, + parseSessionEntryJson as parseSessionEntryRow, } from "./session-accessor.sqlite-status.js"; import { readTranscriptMutationStateInTransaction } from "./session-accessor.sqlite-transcript-state.js"; import { @@ -109,7 +109,7 @@ class SqliteSessionMutationConflictError extends Error { } } -export function readSqliteSessionIdentitySnapshot( +export function readSessionIdentitySnapshot( database: OpenClawAgentDatabase, sessionKeys: Iterable, ): Map { @@ -123,7 +123,7 @@ export function readSqliteSessionIdentitySnapshot( return snapshot; } -export function createSqliteSessionIdentitySnapshot( +export function createSessionIdentitySnapshot( rows: readonly { entry: SessionEntry; sessionKey: string }[], ): Map { return new Map(rows.map((row) => [row.sessionKey, cloneSessionEntry(row.entry)])); @@ -167,7 +167,7 @@ function readSessionEntryRowUnchecked( // Async updaters prepare against this complete selection. Capturing alias rows // prevents the commit phase from deleting a concurrently changed legacy key. -export function readSqliteSessionEntrySelectionSnapshot( +export function readSessionEntrySelectionSnapshot( database: OpenClawAgentDatabase, sessionKey: string, exact: boolean, @@ -185,7 +185,7 @@ export function readSqliteSessionEntrySelectionSnapshot( }; } -export function assertSqliteSessionEntrySelectionUnchanged( +export function assertSessionEntrySelectionUnchanged( expected: SqliteSessionEntrySelectionSnapshot, current: SqliteSessionEntrySelectionSnapshot, operationLabel: string, @@ -236,7 +236,7 @@ export function readExactSessionEntryRowValidated( return readExactSessionEntryRow(database, sessionKey); } -export function readSqliteSessionEntryStore( +export function readSessionEntryStore( database: OpenClawAgentDatabase, options: { allowCanonicalRepair?: boolean } = {}, ): Record { @@ -263,7 +263,7 @@ export function readSqliteSessionEntryStore( return store; } -export function readSqliteSessionEntryCount(database: OpenClawAgentDatabase): number { +export function readSessionEntryCount(database: OpenClawAgentDatabase): number { const db = getSessionKysely(database.db); const rows = executeSqliteQuerySync( database.db, @@ -272,7 +272,7 @@ export function readSqliteSessionEntryCount(database: OpenClawAgentDatabase): nu return rows.reduce((count, row) => count + (parseSessionEntryRow(row) ? 1 : 0), 0); } -export function readSqliteSessionEntryKeys(database: OpenClawAgentDatabaseReader): string[] { +export function readSessionEntryKeys(database: OpenClawAgentDatabaseReader): string[] { const db = getSessionKysely(database.db); return executeSqliteQuerySync( database.db, @@ -283,7 +283,7 @@ export function readSqliteSessionEntryKeys(database: OpenClawAgentDatabaseReader ).rows.flatMap((row) => (parseSessionEntryRow(row) ? [row.session_key] : [])); } -export function resolveSqliteLifecyclePrimaryEntry( +export function resolveLifecyclePrimaryEntry( database: OpenClawAgentDatabase, target: { canonicalKey: string; storeKeys: string[] }, options: { allowCanonicalMove?: boolean } = {}, @@ -307,15 +307,15 @@ export function resolveSqliteLifecyclePrimaryEntry( return row; } -export function readSqliteLifecycleTargetSnapshot( +export function readLifecycleTargetSnapshot( database: OpenClawAgentDatabase, target: { canonicalKey: string; storeKeys: string[] }, options: { allowCanonicalMove?: boolean } = {}, ): SqliteLifecycleTargetSnapshot { assertCanonicalSqliteSessionKeysCurrent(database); - const normalized = normalizeSqliteLifecycleTarget(target); + const normalized = normalizeLifecycleTarget(target); return { - primary: resolveSqliteLifecyclePrimaryEntry(database, normalized, options), + primary: resolveLifecyclePrimaryEntry(database, normalized, options), rows: normalized.storeKeys.flatMap((sessionKey) => { const row = readExactSessionEntryRow(database, sessionKey); return row ? [{ entry: cloneSessionEntry(row.entry), sessionKey }] : []; @@ -323,7 +323,7 @@ export function readSqliteLifecycleTargetSnapshot( }; } -export function assertSqliteLifecycleTargetSnapshotUnchanged( +export function assertLifecycleTargetSnapshotUnchanged( expected: SqliteLifecycleTargetSnapshot, current: SqliteLifecycleTargetSnapshot, operationLabel: string, @@ -336,10 +336,7 @@ export function assertSqliteLifecycleTargetSnapshotUnchanged( } } -export function normalizeSqliteLifecycleTarget(target: { - canonicalKey: string; - storeKeys: string[]; -}): { +export function normalizeLifecycleTarget(target: { canonicalKey: string; storeKeys: string[] }): { canonicalKey: string; storeKeys: string[]; } { @@ -350,7 +347,7 @@ export function normalizeSqliteLifecycleTarget(target: { }; } -export function deleteSqliteSessionEntryRows( +export function deleteSessionEntryRows( database: OpenClawAgentDatabase, sessionKey: string, options: { deleteOwnedWindows?: boolean; deliveryCleanupKeys?: readonly string[] } = {}, @@ -374,9 +371,7 @@ export function deleteSqliteSessionEntryRows( return true; } const entry = parseSessionEntryRow(node); - return entry - ? collectSqliteSessionStateIdsForEntry(entry).includes(window.session_id) - : false; + return entry ? collectSessionStateIdsForEntry(entry).includes(window.session_id) : false; }); if (survivingNode) { executeSqliteQuerySync( @@ -395,7 +390,7 @@ export function deleteSqliteSessionEntryRows( database.db, db.deleteFrom("session_nodes").where("session_key", "=", sessionKey), ); - publishSqliteSessionEntryCacheInvalidation(database); + publishSessionEntryCacheInvalidation(database); return; } const remainingWindow = executeSqliteQueryTakeFirstSync( @@ -415,14 +410,14 @@ export function deleteSqliteSessionEntryRows( sessionKey, updatedAt: remainingWindow.updated_at, }); - publishSqliteSessionEntryCacheInvalidation(database); + publishSessionEntryCacheInvalidation(database); return; } executeSqliteQuerySync( database.db, db.deleteFrom("session_nodes").where("session_key", "=", sessionKey), ); - publishSqliteSessionEntryCacheInvalidation(database); + publishSessionEntryCacheInvalidation(database); } /** Remove the logical entry while retaining its node-owned transcript windows. */ @@ -472,14 +467,14 @@ function clearSqliteSessionEntryPreservingWindows( ); } -export function deleteSqliteLifecycleTargetRows( +export function deleteLifecycleTargetRows( database: OpenClawAgentDatabase, target: { canonicalKey: string; storeKeys: string[] }, ): void { for (const sessionKey of uniqueStrings([target.canonicalKey, ...target.storeKeys])) { const trimmed = sessionKey.trim(); if (trimmed) { - deleteSqliteSessionEntryRows(database, trimmed); + deleteSessionEntryRows(database, trimmed); } } } @@ -513,14 +508,14 @@ function sqliteLifecycleTargetMatchesExpectedEntry( target: { canonicalKey: string; storeKeys: string[] }, expectedEntry: SessionEntry | undefined, ): boolean { - const current = resolveSqliteLifecyclePrimaryEntry(database, target)?.entry; + const current = resolveLifecyclePrimaryEntry(database, target)?.entry; if (!current || !expectedEntry) { return current === expectedEntry; } return sqliteSessionEntriesEqual(current, expectedEntry); } -export function assertSqliteLifecycleTargetUnchanged( +export function assertLifecycleTargetUnchanged( database: OpenClawAgentDatabase, target: { canonicalKey: string; storeKeys: string[] }, expectedEntry: SessionEntry | undefined, @@ -546,18 +541,18 @@ export function deleteLegacySessionEntryRows( if (legacyKey === sessionKey) { continue; } - rehomeSqliteSessionWindows(database, sessionKey, [legacyKey]); + rehomeSessionWindows(database, sessionKey, [legacyKey]); rehomeLegacySessionNodeArtifacts(database, legacyKey, sessionKey, options); executeSqliteQuerySync( database.db, db.deleteFrom("session_nodes").where("session_key", "=", legacyKey), ); - publishSqliteSessionEntryCacheInvalidation(database); + publishSessionEntryCacheInvalidation(database); } } /** Move retained generations to the canonical node before removing key aliases. */ -export function rehomeSqliteSessionWindows( +export function rehomeSessionWindows( database: OpenClawAgentDatabase, canonicalKey: string, previousKeys: Iterable, @@ -598,8 +593,8 @@ export function writeSessionEntry( ); } } - const normalizedEntry = normalizeSqliteSessionEntryTimestamp(entry); - if (!hasValidSqliteSessionEntryIdentity(normalizedEntry)) { + const normalizedEntry = normalizeSessionEntryTimestamp(entry); + if (!hasValidSessionEntryIdentity(normalizedEntry)) { throw new Error("Refusing invalid SQLite session entry identity"); } const updatedAt = normalizedEntry.updatedAt; @@ -636,7 +631,7 @@ export function writeSessionEntry( const transcriptObservedAt = readTranscriptMutationStateInTransaction(database, normalizedEntry.sessionId).updatedAt ?? updatedAt; - const boundSessionRoot = bindSqliteSessionRoot({ entry: normalizedEntry, sessionKey, updatedAt }); + const boundSessionRoot = bindSessionRoot({ entry: normalizedEntry, sessionKey, updatedAt }); const conversation = prepareSessionConversation({ entry: normalizedEntry, sessionScope: boundSessionRoot.session_scope, @@ -656,8 +651,8 @@ export function writeSessionEntry( entry: normalizedEntry, previousEntry, }); - const sessionNode = bindSqliteSessionNode({ entry: normalizedEntry, sessionKey, updatedAt }); - const writeGeneration = trackSqliteSessionEntryCacheWrite(database, () => { + const sessionNode = bindSessionNode({ entry: normalizedEntry, sessionKey, updatedAt }); + const writeGeneration = trackSessionEntryCacheWrite(database, () => { executeSqliteQuerySync( database.db, db @@ -738,7 +733,7 @@ export function writeSessionEntry( updatedAt, }); } - publishSqliteSessionEntryCacheInvalidation(database, sessionNode, writeGeneration); + publishSessionEntryCacheInvalidation(database, sessionNode, writeGeneration); } /** Resolves the parent fork decision using SQLite transcript rows when totals are stale. */ diff --git a/src/config/sessions/session-accessor.sqlite-entry.ts b/src/config/sessions/session-accessor.sqlite-entry.ts index 26d476396356..659f98f2b5c6 100644 --- a/src/config/sessions/session-accessor.sqlite-entry.ts +++ b/src/config/sessions/session-accessor.sqlite-entry.ts @@ -25,29 +25,29 @@ import type { SessionTranscriptWriteScope, } from "./session-accessor.sqlite-contract.js"; import { - readSqliteSessionEntryCache, - type SqliteSessionEntryCacheSnapshot, + readSessionEntryCache, + type SessionEntryCacheSnapshot, } from "./session-accessor.sqlite-entry-cache.js"; import { - assertSqliteLifecycleTargetSnapshotUnchanged, - assertSqliteSessionEntrySelectionUnchanged, + assertLifecycleTargetSnapshotUnchanged, + assertSessionEntrySelectionUnchanged, collectSessionEntryLookupKeys, - createSqliteSessionIdentitySnapshot, + createSessionIdentitySnapshot, deleteLegacySessionEntryRows, readExactSessionEntryRowValidated, readSessionEntryRow, - readSqliteLifecycleTargetSnapshot, - readSqliteSessionEntrySelectionSnapshot, - readSqliteSessionIdentitySnapshot, - rehomeSqliteSessionWindows, + readLifecycleTargetSnapshot, + readSessionEntrySelectionSnapshot, + readSessionIdentitySnapshot, + rehomeSessionWindows, writeSessionEntry, } from "./session-accessor.sqlite-entry-store.js"; -import { listSqliteTranscriptInstancesFromDatabase } from "./session-accessor.sqlite-history.js"; +import { listTranscriptInstancesFromDatabase } from "./session-accessor.sqlite-history.js"; import { emitCommittedSessionIdentityDiff } from "./session-accessor.sqlite-identity.js"; -import type { SqliteSessionEntryMaintenancePlan } from "./session-accessor.sqlite-lifecycle-types.js"; +import type { SessionEntryMaintenancePlan } from "./session-accessor.sqlite-lifecycle-types.js"; import { - applySqliteSessionEntryMaintenance, - finalizeSqliteSessionEntryMaintenancePlansAfterWriterReleaseBestEffort, + applySessionEntryMaintenance, + finalizeSessionEntryMaintenancePlansAfterWriterReleaseBestEffort, } from "./session-accessor.sqlite-maintenance.js"; import { createFallbackSessionEntry, @@ -64,7 +64,7 @@ import { toDatabaseOptions, type ResolvedSqliteScope, } from "./session-accessor.sqlite-scope.js"; -import { readSqliteSessionEntriesByStatus } from "./session-accessor.sqlite-status.js"; +import { readSessionEntriesByStatus } from "./session-accessor.sqlite-status.js"; import type { SessionEntryListScope } from "./session-accessor.types.js"; import { assertCanonicalSessionKeyWrite, @@ -133,7 +133,7 @@ function getChildSessionKeysByParent(entries: Map): Map> = {}, ): string[] { const resolved = resolveSqliteScope({ ...scope, sessionKey: "" }); @@ -202,7 +198,7 @@ export function listSqliteSessionEntryKeysReadOnly( } /** Exact persisted-key probe on the read-only handle, for per-row hot paths. */ -export function loadExactSqliteSessionEntryReadOnly( +export function loadExactSessionEntryReadOnly( scope: SessionAccessScope, ): ExactSessionEntry | undefined { const sessionKey = scope.sessionKey.trim(); @@ -223,9 +219,7 @@ export function loadExactSqliteSessionEntryReadOnly( } /** Lists direct child rows without cloning or rebuilding the complete session store. */ -export function listSqliteSessionChildEntriesReadOnly( - scope: SessionAccessScope, -): SessionEntrySummary[] { +export function listSessionChildEntriesReadOnly(scope: SessionAccessScope): SessionEntrySummary[] { const resolved = resolveSqliteScope(scope); const result = withOpenClawAgentDatabaseReadOnly((database) => { const snapshot = readSessionEntrySnapshot(database, resolved, scope.readConsistency); @@ -244,7 +238,7 @@ export function listSqliteSessionChildEntriesReadOnly( } /** Resolves the persisted session key for a SQLite transcript session id. */ -export function resolveSqliteSessionKeyBySessionId( +export function resolveSessionKeyBySessionId( scope: Pick, ): string | undefined { const resolved = resolveSqliteTranscriptReadScope(scope); @@ -264,7 +258,7 @@ export function resolveSqliteSessionKeyBySessionId( } /** Lists session entries from the additive SQLite session store. */ -export function listSqliteSessionEntries(scope: SessionEntryListScope = {}): SessionEntrySummary[] { +export function listSessionEntryRows(scope: SessionEntryListScope = {}): SessionEntrySummary[] { const resolved = resolveSqliteScope({ ...scope, sessionKey: "" }); const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); return listSqliteSessionEntriesFromDatabase(database, resolved, scope); @@ -275,7 +269,7 @@ export function listSqliteSessionEntries(scope: SessionEntryListScope = {}): Ses * Transient lock errors propagate: only the caller knows whether "empty" is an * acceptable degradation (health snapshots) or hides real state (migration detection). */ -export function listSqliteSessionEntriesReadOnly( +export function listSessionEntriesReadOnly( scope: SessionEntryListScope = {}, ): SessionEntrySummary[] { const resolved = resolveSqliteScope({ ...scope, sessionKey: "" }); @@ -287,7 +281,7 @@ export function listSqliteSessionEntriesReadOnly( } /** Counts durable session rows without materializing entry JSON or warming the entry cache. */ -export function countSqliteSessionEntryRowsReadOnly(scope: SessionEntryListScope = {}): number { +export function countSessionEntryRowsReadOnly(scope: SessionEntryListScope = {}): number { const resolved = resolveSqliteScope({ ...scope, sessionKey: "" }); const result = withOpenClawAgentDatabaseReadOnly((database) => { const db = getSessionKysely(database.db); @@ -306,7 +300,7 @@ export function countSqliteSessionEntryRowsReadOnly(scope: SessionEntryListScope * Proves whether a durable store has a row in one of the requested lifecycle states. * Unknown existing schemas stay eligible so the writable owner can surface or repair them. */ -export function hasSqliteSessionEntriesByStatusReadOnly( +export function hasSessionEntriesByStatusReadOnly( scope: Partial>, statuses: readonly SessionEntryStatus[], ): boolean { @@ -366,39 +360,39 @@ function readSessionEntrySnapshot( database: Pick, resolved: ResolvedSqliteScope, readConsistency: SessionAccessScope["readConsistency"], -): SqliteSessionEntryCacheSnapshot { +): SessionEntryCacheSnapshot { const cache = !isIncognitoOpenClawAgentSqlitePath(database.path, { agentId: database.agentId, env: resolved.env, }); - return readSqliteSessionEntryCache(database, { + return readSessionEntryCache(database, { cache, latest: readConsistency === "latest", }); } /** Lists only entries whose normalized session row has one of the requested statuses. */ -export function listSqliteSessionEntriesByStatus( +export function listSessionEntriesByStatus( scope: Partial>, statuses: readonly SessionEntryStatus[], ): SessionEntrySummary[] { const resolved = resolveSqliteScope({ ...scope, sessionKey: "" }); const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); - return readSqliteSessionEntriesByStatus(database, statuses).filter( + return readSessionEntriesByStatus(database, statuses).filter( ({ sessionKey }) => !isInternalSessionEffectsKey(sessionKey), ); } /** Lists transcript-bearing SQLite sessions, including retained rows from session-id rotation. */ -export function listSqliteSessionTranscriptInstances( +export function listSessionTranscriptInstances( scope: Partial> = {}, ): SessionTranscriptInstance[] { const resolved = resolveSqliteScope({ ...scope, sessionKey: "" }); const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); const currentEntries = new Map( - listSqliteSessionEntries(scope).map((summary) => [summary.sessionKey, summary.entry]), + listSessionEntryRows(scope).map((summary) => [summary.sessionKey, summary.entry]), ); - return listSqliteTranscriptInstancesFromDatabase({ + return listTranscriptInstancesFromDatabase({ agentId: resolved.agentId, currentEntries, database, @@ -407,7 +401,7 @@ export function listSqliteSessionTranscriptInstances( } /** Reads a session activity timestamp from the additive SQLite session store. */ -export function readSqliteSessionUpdatedAt(scope: SessionAccessScope): number | undefined { +export function readSessionUpdatedAt(scope: SessionAccessScope): number | undefined { const resolved = resolveSqliteScope(scope); const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); const row = readSessionEntryRow(database, resolved.sessionKey)?.row; @@ -415,46 +409,43 @@ export function readSqliteSessionUpdatedAt(scope: SessionAccessScope): number | } /** Applies a partial entry update to the additive SQLite session store. */ -export async function upsertSqliteSessionEntry( +export async function upsertSessionEntry( scope: SessionAccessScope, patch: Partial, ): Promise { - return await patchSqliteSessionEntry(scope, () => patch, { + return await patchSessionEntry(scope, () => patch, { fallbackEntry: createFallbackSessionEntry(patch), }); } /** Replaces one entry in the additive SQLite session store. */ -export async function replaceSqliteSessionEntry( +export async function replaceSessionEntry( scope: SessionAccessScope, entry: SessionEntry, ): Promise { - return await patchSqliteSessionEntry(scope, () => entry, { + return await patchSessionEntry(scope, () => entry, { fallbackEntry: entry, replaceEntry: true, }); } /** Replaces one entry synchronously for sync session runtimes. */ -export function replaceSqliteSessionEntrySync( - scope: SessionAccessScope, - entry: SessionEntry, -): void { +export function replaceSessionEntrySync(scope: SessionAccessScope, entry: SessionEntry): void { const resolved = resolveSqliteScope(scope); assertCanonicalSessionWriteScope(resolved); let previous = new Map(); let current = new Map(); runOpenClawAgentWriteTransaction((database) => { const identityKeys = collectSessionEntryLookupKeys(database, resolved.sessionKey); - previous = readSqliteSessionIdentitySnapshot(database, identityKeys); + previous = readSessionIdentitySnapshot(database, identityKeys); writeSessionEntry(database, resolved.sessionKey, entry); - current = readSqliteSessionIdentitySnapshot(database, identityKeys); + current = readSessionIdentitySnapshot(database, identityKeys); }, toDatabaseOptions(resolved)); emitCommittedSessionIdentityDiff(previous, current); } /** Creates a missing session identity without replacing a concurrently owned row. */ -export function ensureSqliteSessionEntrySync( +export function ensureSessionEntrySync( scope: SessionAccessScope & Pick, entry: SessionEntry, @@ -468,7 +459,7 @@ export function ensureSqliteSessionEntrySync( let current = new Map(); runOpenClawAgentWriteTransaction((database) => { const identityKeys = collectSessionEntryLookupKeys(database, resolved.sessionKey); - previous = readSqliteSessionIdentitySnapshot(database, identityKeys); + previous = readSessionIdentitySnapshot(database, identityKeys); const existing = readSessionEntryRow(database, resolved.sessionKey)?.entry; if (existing) { // This branch is a read-only ownership probe. The immediately following @@ -483,7 +474,7 @@ export function ensureSqliteSessionEntrySync( return; } writeSessionEntry(database, resolved.sessionKey, entry); - current = readSqliteSessionIdentitySnapshot(database, identityKeys); + current = readSessionIdentitySnapshot(database, identityKeys); owned = current.get(resolved.sessionKey)?.sessionId === entry.sessionId; }, toDatabaseOptions(resolved)); if (current.size !== previous.size || owned) { @@ -496,7 +487,7 @@ export function ensureSqliteSessionEntrySync( } /** Patches one entry in the additive SQLite session store. */ -export async function patchSqliteSessionEntry( +export async function patchSessionEntry( scope: SessionAccessScope, update: ( entry: SessionEntry, @@ -507,15 +498,15 @@ export async function patchSqliteSessionEntry( const resolved = resolveSqliteScope(scope); assertCanonicalSessionWriteScope(resolved); return await patchSqliteSessionEntrySnapshot< - ReturnType + ReturnType >({ assertSnapshotUnchanged: (prepared, fresh) => - assertSqliteSessionEntrySelectionUnchanged(prepared, fresh, "session-entry.patch"), + assertSessionEntrySelectionUnchanged(prepared, fresh, "session-entry.patch"), existingEntry: (snapshot) => snapshot.selected?.entry, legacyKeys: (snapshot) => snapshot.selected?.legacyKeys ?? [], options, readSnapshot: (database) => - readSqliteSessionEntrySelectionSnapshot( + readSessionEntrySelectionSnapshot( database, resolved.sessionKey, options.replaceEntry === true, @@ -529,7 +520,7 @@ export async function patchSqliteSessionEntry( } /** Patches one logical entry selected from a canonical key and alias set. */ -export async function patchSqliteSessionEntryTarget( +export async function patchSessionEntryTarget( scope: SessionEntryTargetPatchScope, update: ( entry: SessionEntry, @@ -538,15 +529,13 @@ export async function patchSqliteSessionEntryTarget( options: SqliteSessionEntryPatchOptions = {}, ): Promise { const resolved = resolveSqliteStoreScope(scope.storePath, { agentId: scope.agentId }); - return await patchSqliteSessionEntrySnapshot< - ReturnType - >({ + return await patchSqliteSessionEntrySnapshot>({ assertSnapshotUnchanged: (prepared, fresh) => - assertSqliteLifecycleTargetSnapshotUnchanged(prepared, fresh, "session-entry-target.patch"), + assertLifecycleTargetSnapshotUnchanged(prepared, fresh, "session-entry-target.patch"), existingEntry: (snapshot) => snapshot.primary?.entry, legacyKeys: () => scope.target.storeKeys, options, - readSnapshot: (database) => readSqliteLifecycleTargetSnapshot(database, scope.target), + readSnapshot: (database) => readLifecycleTargetSnapshot(database, scope.target), rehomeWindows: true, resolved, sessionKey: scope.target.canonicalKey, @@ -593,7 +582,7 @@ async function patchSqliteSessionEntrySnapshot( const patch = await params.update(cloneSessionEntry(writeBase), { existingEntry: existing ? cloneSessionEntry(existing) : undefined, }); - const maintenancePlans: SqliteSessionEntryMaintenancePlan[] = []; + const maintenancePlans: SessionEntryMaintenancePlan[] = []; let result: SessionEntry | null = null; let previousIdentity = new Map(); let currentIdentity = new Map(); @@ -612,7 +601,7 @@ async function patchSqliteSessionEntrySnapshot( ...legacyKeys, ...snapshotRows.map((row) => row.sessionKey), ]; - previousIdentity = createSqliteSessionIdentitySnapshot(snapshotRows); + previousIdentity = createSessionIdentitySnapshot(snapshotRows); const merged = options.replaceEntry ? cloneSessionEntry(patch as SessionEntry) : options.preserveActivity @@ -630,13 +619,13 @@ async function patchSqliteSessionEntrySnapshot( previousEntry: selectedPreviousEntry, }); if (params.rehomeWindows) { - rehomeSqliteSessionWindows(writeDatabase, sessionKey, legacyKeys); + rehomeSessionWindows(writeDatabase, sessionKey, legacyKeys); } deleteLegacySessionEntryRows(writeDatabase, legacyKeys, sessionKey, { rehomeMembers: selectedPreviousEntry.sessionId === next.sessionId, }); maintenancePlans.push( - applySqliteSessionEntryMaintenance(writeDatabase, { + applySessionEntryMaintenance(writeDatabase, { activeSessionKey: sessionKey, archiveDirectory: resolveSqliteTranscriptArchiveDirectory(resolved), maintenanceConfig: options.maintenanceConfig, @@ -644,7 +633,7 @@ async function patchSqliteSessionEntrySnapshot( storePath: params.storePath, }), ); - currentIdentity = readSqliteSessionIdentitySnapshot(writeDatabase, identityKeys); + currentIdentity = readSessionIdentitySnapshot(writeDatabase, identityKeys); result = cloneSessionEntry(next); }, toDatabaseOptions(resolved)); emitCommittedSessionIdentityDiff(previousIdentity, currentIdentity); @@ -652,7 +641,7 @@ async function patchSqliteSessionEntrySnapshot( }); // Worker materialization runs after the initial write releases the lane; // final deletion reacquires it and revalidates every planned row. - await finalizeSqliteSessionEntryMaintenancePlansAfterWriterReleaseBestEffort( + await finalizeSessionEntryMaintenancePlansAfterWriterReleaseBestEffort( resolved, committed.maintenancePlans, ); @@ -666,7 +655,7 @@ async function patchSqliteSessionEntrySnapshot( /** Forks one parent SQLite transcript into a new child transcript. */ -export async function recordSqliteInboundSessionMeta(params: { +export async function recordInboundSessionMeta(params: { storePath: string; sessionKey: string; ctx: MsgContext; @@ -674,7 +663,7 @@ export async function recordSqliteInboundSessionMeta(params: { createIfMissing?: boolean; }): Promise { const createIfMissing = params.createIfMissing ?? true; - return await patchSqliteSessionEntry( + return await patchSessionEntry( { sessionKey: params.sessionKey, storePath: params.storePath }, (_entry, context) => { const metadataPatch = deriveSessionMetaPatch({ @@ -707,7 +696,7 @@ export async function recordSqliteInboundSessionMeta(params: { } /** Updates last-route/delivery metadata without refreshing activity timestamps. */ -export async function updateSqliteSessionLastRoute(params: { +export async function updateSessionLastRoute(params: { storePath: string; sessionKey: string; channel?: string; @@ -721,7 +710,7 @@ export async function updateSqliteSessionLastRoute(params: { createIfMissing?: boolean; }): Promise { const createIfMissing = params.createIfMissing ?? true; - return await patchSqliteSessionEntry( + return await patchSessionEntry( { sessionKey: params.sessionKey, storePath: params.storePath }, (_entry, context) => { const routePatch = deriveLastRoutePatch({ diff --git a/src/config/sessions/session-accessor.sqlite-events.ts b/src/config/sessions/session-accessor.sqlite-events.ts index c9d280d887f4..3ffc37074a9a 100644 --- a/src/config/sessions/session-accessor.sqlite-events.ts +++ b/src/config/sessions/session-accessor.sqlite-events.ts @@ -8,7 +8,7 @@ import { resolveSqliteTranscriptScope } from "./session-accessor.sqlite-scope.js // Outward notifications happen only after the owning SQLite mutation commits. -export function emitArchivedSqliteTranscriptUpdates( +export function emitArchivedTranscriptUpdates( archivedTranscripts: readonly SessionLifecycleArchivedTranscript[], ): void { for (const archived of archivedTranscripts) { @@ -16,7 +16,7 @@ export function emitArchivedSqliteTranscriptUpdates( } } -export async function publishSqliteTranscriptUpdate( +export async function publishTranscriptUpdate( scope: SessionTranscriptWriteScope, update: TranscriptUpdatePayload = {}, ): Promise { diff --git a/src/config/sessions/session-accessor.sqlite-history.ts b/src/config/sessions/session-accessor.sqlite-history.ts index a1895cafcb02..f1efec390583 100644 --- a/src/config/sessions/session-accessor.sqlite-history.ts +++ b/src/config/sessions/session-accessor.sqlite-history.ts @@ -5,7 +5,7 @@ import { isInternalSessionEffectsKey } from "./internal-session-key.js"; import type { SessionTranscriptInstance } from "./session-accessor.sqlite-contract.js"; import type { SessionEntry } from "./types.js"; -export function listSqliteTranscriptInstancesFromDatabase(params: { +export function listTranscriptInstancesFromDatabase(params: { agentId: string; currentEntries: ReadonlyMap; database: OpenClawAgentDatabase; diff --git a/src/config/sessions/session-accessor.sqlite-import.ts b/src/config/sessions/session-accessor.sqlite-import.ts index e60d4d72a607..8aa48c6df36f 100644 --- a/src/config/sessions/session-accessor.sqlite-import.ts +++ b/src/config/sessions/session-accessor.sqlite-import.ts @@ -1,7 +1,7 @@ import { runOpenClawAgentWriteTransaction } from "../../state/openclaw-agent-db.js"; import { readExactSessionEntryRowForCanonicalRepair } from "./session-accessor.sqlite-canonical-repair.js"; import type { TranscriptEvent } from "./session-accessor.sqlite-contract.js"; -import { publishSqliteSessionEntryCacheInvalidation } from "./session-accessor.sqlite-entry-cache.js"; +import { publishSessionEntryCacheInvalidation } from "./session-accessor.sqlite-entry-cache.js"; import { writeSessionEntry } from "./session-accessor.sqlite-entry-store.js"; import { readTranscriptEventJsonSetInTransaction } from "./session-accessor.sqlite-read.js"; import { @@ -111,7 +111,7 @@ export async function importSqliteSessionRows( } }); reconcileSessionTranscriptIndexInTransaction(database.db, params.entry.sessionId); - publishSqliteSessionEntryCacheInvalidation(database); + publishSessionEntryCacheInvalidation(database); } if (params.transcriptMtimeMs !== undefined) { advanceTranscriptMutationAtInTransaction( diff --git a/src/config/sessions/session-accessor.sqlite-lifecycle-state.ts b/src/config/sessions/session-accessor.sqlite-lifecycle-state.ts index 2eec63bf03f8..4bbe0e92f2b7 100644 --- a/src/config/sessions/session-accessor.sqlite-lifecycle-state.ts +++ b/src/config/sessions/session-accessor.sqlite-lifecycle-state.ts @@ -10,39 +10,39 @@ import { } from "../../state/openclaw-agent-db.js"; import { sqliteSessionStateDeleteSnapshotsEqual, - type MaterializedSqliteSessionStateDeletePlan, - type SqliteSessionStateDeletePlan, + type MaterializedSessionStateDeletePlan, + type SessionStateDeletePlan, } from "./session-accessor.sqlite-archive.js"; import type { SessionEntryLifecycleRemoval, SessionEntryLifecycleUpsert, SessionLifecycleArchivedTranscript, } from "./session-accessor.sqlite-contract.js"; -import { readSqliteSessionStateDeleteSnapshot } from "./session-accessor.sqlite-delete-snapshot.js"; +import { readSessionStateDeleteSnapshot } from "./session-accessor.sqlite-delete-snapshot.js"; import { - deleteSqliteSessionEntryRows, + deleteSessionEntryRows, readExactSessionEntryJsonForCanonicalRepair, readExactSessionEntryRow, - readSqliteSessionEntryStore, + readSessionEntryStore, sqliteSessionEntriesEqual, } from "./session-accessor.sqlite-entry-store.js"; import type { - SqliteLifecycleArtifactCleanupPlan, - SqliteProjectedLifecycleMutation, - SqliteSessionEntryRemovalPlan, + LifecycleArtifactCleanupPlan, + ProjectedLifecycleMutation, + SessionEntryRemovalPlan, } from "./session-accessor.sqlite-lifecycle-types.js"; import { coerceSqliteNumber } from "./session-accessor.sqlite-normalize.js"; -import { loadSqliteTranscriptEventsFromDatabase } from "./session-accessor.sqlite-read.js"; -import { collectSqliteSessionStateIdsForEntry } from "./session-accessor.sqlite-references.js"; +import { loadTranscriptEventsFromDatabase } from "./session-accessor.sqlite-read.js"; +import { collectSessionStateIdsForEntry } from "./session-accessor.sqlite-references.js"; import { cloneSessionEntry, getSessionKysely } from "./session-accessor.sqlite-scope.js"; -import { parseSqliteSessionEntryJson as parseSessionEntryRow } from "./session-accessor.sqlite-status.js"; +import { parseSessionEntryJson as parseSessionEntryRow } from "./session-accessor.sqlite-status.js"; import { buildSessionResetBoundaryPlan } from "./session-reset-boundary-event.js"; import { deleteSessionTranscriptIndexInTransaction } from "./session-transcript-index.js"; import type { SessionEntry } from "./types.js"; // Transcript-state reclamation owner. Planning stays async-free; transactions revalidate before delete. -export function shouldRemoveSqliteSessionEntry( +export function shouldRemoveSessionEntry( entry: SessionEntry | undefined, removal: SessionEntryLifecycleRemoval, ): entry is SessionEntry { @@ -139,7 +139,7 @@ function sqliteTranscriptStateHasMarker(params: { } /** Session ids protected by live node state. */ -export function readReferencedSqliteSessionIds( +export function readReferencedSessionIds( database: OpenClawAgentDatabase, excludedSessionKeys: ReadonlySet = new Set(), ): Set { @@ -158,7 +158,7 @@ export function readReferencedSqliteSessionIds( if (!entry) { continue; } - for (const sessionId of collectSqliteSessionStateIdsForEntry(entry)) { + for (const sessionId of collectSessionStateIdsForEntry(entry)) { sessionIds.add(sessionId); } } @@ -167,7 +167,7 @@ export function readReferencedSqliteSessionIds( // Projects references after a lifecycle mutation so reset/delete can archive // before removing entry rows while still preserving shared session ids. -export function readReferencedSqliteSessionIdsAfterTargetMutation( +export function readReferencedSessionIdsAfterTargetMutation( database: OpenClawAgentDatabase, target: { canonicalKey: string; storeKeys: string[] }, nextEntry?: SessionEntry, @@ -190,26 +190,26 @@ export function readReferencedSqliteSessionIdsAfterTargetMutation( if (!entry) { continue; } - for (const sessionId of collectSqliteSessionStateIdsForEntry(entry)) { + for (const sessionId of collectSessionStateIdsForEntry(entry)) { sessionIds.add(sessionId); } } if (nextEntry) { - for (const sessionId of collectSqliteSessionStateIdsForEntry(nextEntry)) { + for (const sessionId of collectSessionStateIdsForEntry(nextEntry)) { sessionIds.add(sessionId); } } return sessionIds; } -export function planSqliteSessionStateDeleteIfUnreferenced(params: { +export function planSessionStateDeleteIfUnreferenced(params: { archiveTranscript?: boolean; archiveDirectory: string; database: OpenClawAgentDatabase; reason?: "deleted" | "reset"; referencedSessionIds: ReadonlySet; sessionId: string; -}): SqliteSessionStateDeletePlan | null { +}): SessionStateDeletePlan | null { if (params.referencedSessionIds.has(params.sessionId)) { return null; } @@ -221,18 +221,18 @@ export function planSqliteSessionStateDeleteIfUnreferenced(params: { databasePath: params.database.path, reason: params.reason ?? "deleted", sessionId: params.sessionId, - snapshot: readSqliteSessionStateDeleteSnapshot(params.database.db, params.sessionId), + snapshot: readSessionStateDeleteSnapshot(params.database.db, params.sessionId), }; } -export function deleteMaterializedSqliteSessionStatePlans( +export function deleteMaterializedSessionStatePlans( database: OpenClawAgentDatabase, - plans: readonly MaterializedSqliteSessionStateDeletePlan[], + plans: readonly MaterializedSessionStateDeletePlan[], protectedSessionIds?: ReadonlySet, excludedSessionKeys?: ReadonlySet, ): SessionLifecycleArchivedTranscript[] { const archivedTranscripts: SessionLifecycleArchivedTranscript[] = []; - const referencedSessionIds = readReferencedSqliteSessionIds(database, excludedSessionKeys); + const referencedSessionIds = readReferencedSessionIds(database, excludedSessionKeys); for (const sessionId of protectedSessionIds ?? []) { referencedSessionIds.add(sessionId); } @@ -240,7 +240,7 @@ export function deleteMaterializedSqliteSessionStatePlans( if (referencedSessionIds.has(plan.sessionId)) { continue; } - const currentSnapshot = readSqliteSessionStateDeleteSnapshot(database.db, plan.sessionId); + const currentSnapshot = readSessionStateDeleteSnapshot(database.db, plan.sessionId); if (!sqliteSessionStateDeleteSnapshotsEqual(currentSnapshot, plan.snapshot)) { throw new Error(`SQLite session state changed before deletion for ${plan.sessionId}`); } @@ -254,19 +254,19 @@ export function deleteMaterializedSqliteSessionStatePlans( // Builds delete plans from the session ids owned by an entry after callers // have projected which ids remain referenced. -export function planSqliteSessionStateAfterEntryRemoval(params: { +export function planSessionStateAfterEntryRemoval(params: { archiveDirectory: string; archiveTranscript?: boolean; database: OpenClawAgentDatabase; entry: SessionEntry; reason: "deleted" | "reset"; referencedSessionIds?: ReadonlySet; -}): SqliteSessionStateDeletePlan[] { +}): SessionStateDeletePlan[] { const referencedSessionIds = - params.referencedSessionIds ?? readReferencedSqliteSessionIds(params.database); - const plans: SqliteSessionStateDeletePlan[] = []; - for (const sessionId of collectSqliteSessionStateIdsForEntry(params.entry)) { - const plan = planSqliteSessionStateDeleteIfUnreferenced({ + params.referencedSessionIds ?? readReferencedSessionIds(params.database); + const plans: SessionStateDeletePlan[] = []; + for (const sessionId of collectSessionStateIdsForEntry(params.entry)) { + const plan = planSessionStateDeleteIfUnreferenced({ archiveTranscript: params.archiveTranscript, archiveDirectory: params.archiveDirectory, database: params.database, @@ -282,7 +282,7 @@ export function planSqliteSessionStateAfterEntryRemoval(params: { } /** Ids of every persisted generation owned by the given logical session keys. */ -export function readSqliteSessionGenerationIdsForKeys( +export function readSessionGenerationIdsForKeys( database: OpenClawAgentDatabase, keys: Iterable, options: { exactStoredKeys?: boolean } = {}, @@ -302,7 +302,7 @@ export function readSqliteSessionGenerationIdsForKeys( // Projects removals and upserts before archive materialization so same-call // upserts can keep a transcript live without producing a spurious archive. -export async function projectSqliteSessionEntryLifecycleMutation( +export async function projectSessionEntryLifecycleMutation( database: OpenClawAgentDatabase, params: { allowCanonicalRepair?: boolean; @@ -310,14 +310,14 @@ export async function projectSqliteSessionEntryLifecycleMutation( removals: readonly SessionEntryLifecycleRemoval[]; upserts: readonly SessionEntryLifecycleUpsert[]; }, -): Promise { - const store = readSqliteSessionEntryStore(database, { +): Promise { + const store = readSessionEntryStore(database, { allowCanonicalRepair: params.allowCanonicalRepair === true, }); const removedEntries: Array<{ archiveTranscript: boolean; entry: SessionEntry }> = []; const removedKeysToArchive = new Set(); const changedSessionKeys = new Set(); - const projectedRemovals: SqliteProjectedLifecycleMutation["removals"] = []; + const projectedRemovals: ProjectedLifecycleMutation["removals"] = []; for (const removal of params.removals) { const sessionKey = removal.exactStoredKey ? removal.sessionKey : removal.sessionKey.trim(); let entry = removal.exactStoredKey || sessionKey ? store[sessionKey] : undefined; @@ -330,7 +330,7 @@ export async function projectSqliteSessionEntryLifecycleMutation( } entry = removal.expectedEntry ? cloneSessionEntry(removal.expectedEntry) : undefined; } - if (!shouldRemoveSqliteSessionEntry(entry, removal)) { + if (!shouldRemoveSessionEntry(entry, removal)) { continue; } projectedRemovals.push({ @@ -348,7 +348,7 @@ export async function projectSqliteSessionEntryLifecycleMutation( changedSessionKeys.add(sessionKey); delete store[sessionKey]; } - const upsertedEntries: SqliteProjectedLifecycleMutation["upsertedEntries"] = []; + const upsertedEntries: ProjectedLifecycleMutation["upsertedEntries"] = []; for (const upsert of params.upserts) { const sessionKey = upsert.sessionKey.trim(); if (!sessionKey) { @@ -377,7 +377,7 @@ export async function projectSqliteSessionEntryLifecycleMutation( const resetBoundaryPlan = upsert.resetBoundaryReason && expectedEntry?.sessionId ? await buildSessionResetBoundaryPlan({ - events: loadSqliteTranscriptEventsFromDatabase(database, expectedEntry.sessionId), + events: loadTranscriptEventsFromDatabase(database, expectedEntry.sessionId), reason: upsert.resetBoundaryReason, }) : undefined; @@ -388,13 +388,13 @@ export async function projectSqliteSessionEntryLifecycleMutation( ...(resetBoundaryPlan ? { resetBoundaryPlan } : {}), }); } - const referencedSessionIds = collectProjectedReferencedSqliteSessionIds({ + const referencedSessionIds = collectProjectedReferencedSessionIds({ database, excludedSessionKeys: changedSessionKeys, projectedStore: store, }); const deletePlans = removedEntries.flatMap(({ archiveTranscript, entry }) => - planSqliteSessionStateAfterEntryRemoval({ + planSessionStateAfterEntryRemoval({ archiveDirectory: params.archiveDirectory, archiveTranscript, database, @@ -404,11 +404,11 @@ export async function projectSqliteSessionEntryLifecycleMutation( }), ); const plannedIds = new Set(deletePlans.map((plan) => plan.sessionId)); - for (const sessionId of readSqliteSessionGenerationIdsForKeys(database, removedKeysToArchive)) { + for (const sessionId of readSessionGenerationIdsForKeys(database, removedKeysToArchive)) { if (plannedIds.has(sessionId)) { continue; } - const plan = planSqliteSessionStateDeleteIfUnreferenced({ + const plan = planSessionStateDeleteIfUnreferenced({ archiveDirectory: params.archiveDirectory, archiveTranscript: true, database, @@ -430,7 +430,7 @@ function collectReferencedSqliteSessionIdsFromStore( ): Set { const sessionIds = new Set(); for (const entry of Object.values(store)) { - for (const sessionId of collectSqliteSessionStateIdsForEntry(entry)) { + for (const sessionId of collectSessionStateIdsForEntry(entry)) { sessionIds.add(sessionId); } } @@ -439,7 +439,7 @@ function collectReferencedSqliteSessionIdsFromStore( // Projected deletes must preserve raw session_nodes.current_session_id references for // remaining rows whose entry_json cannot be parsed into a SessionEntry. -export function collectProjectedReferencedSqliteSessionIds(params: { +export function collectProjectedReferencedSessionIds(params: { database: OpenClawAgentDatabase; excludedSessionKeys: Iterable; projectedStore: Record; @@ -460,7 +460,7 @@ export function collectProjectedReferencedSqliteSessionIds(params: { if (!entry) { continue; } - for (const sessionId of collectSqliteSessionStateIdsForEntry(entry)) { + for (const sessionId of collectSessionStateIdsForEntry(entry)) { sessionIds.add(sessionId); } } @@ -470,7 +470,7 @@ export function collectProjectedReferencedSqliteSessionIds(params: { return sessionIds; } -export { collectSqliteSessionStateIdsForEntry }; +export { collectSessionStateIdsForEntry }; function deleteSqliteSessionStateRows(database: OpenClawAgentDatabase, sessionId: string): void { const db = getSessionKysely(database.db); @@ -496,7 +496,7 @@ function planSqliteOrphanLifecycleTranscriptStateDeletes(params: { transcriptContentMarker: string; orphanTranscriptMinAgeMs: number; nowMs: number; -}): SqliteSessionStateDeletePlan[] { +}): SessionStateDeletePlan[] { const db = getSessionKysely(params.database.db); const rows = executeSqliteQuerySync( params.database.db, @@ -506,7 +506,7 @@ function planSqliteOrphanLifecycleTranscriptStateDeletes(params: { .orderBy("session_id", "asc"), ).rows; - const deletePlans: SqliteSessionStateDeletePlan[] = []; + const deletePlans: SessionStateDeletePlan[] = []; // Orphan transcript state is represented by a historical window that is no // longer the node's current id. The marker scopes cleanup to this lifecycle. for (const row of rows) { @@ -533,7 +533,7 @@ function planSqliteOrphanLifecycleTranscriptStateDeletes(params: { ) { continue; } - const plan = planSqliteSessionStateDeleteIfUnreferenced({ + const plan = planSessionStateDeleteIfUnreferenced({ archiveTranscript: params.archiveRemovedEntryTranscripts, archiveDirectory: params.archiveDirectory, database: params.database, @@ -548,7 +548,7 @@ function planSqliteOrphanLifecycleTranscriptStateDeletes(params: { return deletePlans; } -export function planSqliteSessionLifecycleArtifactCleanup( +export function planSessionLifecycleArtifactCleanup( database: OpenClawAgentDatabase, params: { agentId?: string; @@ -560,7 +560,7 @@ export function planSqliteSessionLifecycleArtifactCleanup( orphanTranscriptMinAgeMs: number; nowMs: number; }, -): SqliteLifecycleArtifactCleanupPlan { +): LifecycleArtifactCleanupPlan { const db = getSessionKysely(database.db); const rows = executeSqliteQuerySync( database.db, @@ -571,8 +571,8 @@ export function planSqliteSessionLifecycleArtifactCleanup( ).rows; const removedSessionIds = new Set(); - const entries: SqliteLifecycleArtifactCleanupPlan["entries"] = []; - const projectedStore = readSqliteSessionEntryStore(database); + const entries: LifecycleArtifactCleanupPlan["entries"] = []; + const projectedStore = readSessionEntryStore(database); const foreignOwnedSessionIds = params.pluginOwnerId ? new Set( executeSqliteQuerySync( @@ -595,7 +595,7 @@ export function planSqliteSessionLifecycleArtifactCleanup( const entry = parseSessionEntryRow(row); const sessionIds = uniqueStrings([ row.current_session_id, - ...(entry ? collectSqliteSessionStateIdsForEntry(entry) : []), + ...(entry ? collectSessionStateIdsForEntry(entry) : []), ]); // Window ownership survives placeholder nodes and ownerless row projections; preserve // the entire node when any referenced generation belongs to another plugin. @@ -629,14 +629,14 @@ export function planSqliteSessionLifecycleArtifactCleanup( delete projectedStore[row.session_key]; } - const referencedSessionIds = collectProjectedReferencedSqliteSessionIds({ + const referencedSessionIds = collectProjectedReferencedSessionIds({ database, excludedSessionKeys: entries.map((entry) => entry.sessionKey), projectedStore, }); - const deletePlans: SqliteSessionStateDeletePlan[] = []; + const deletePlans: SessionStateDeletePlan[] = []; for (const sessionId of removedSessionIds) { - const plan = planSqliteSessionStateDeleteIfUnreferenced({ + const plan = planSessionStateDeleteIfUnreferenced({ archiveTranscript: params.archiveRemovedEntryTranscripts, archiveDirectory: params.archiveDirectory, database, @@ -664,22 +664,22 @@ export function planSqliteSessionLifecycleArtifactCleanup( return { deletePlans, entries }; } -export function deletePlannedSqliteLifecycleArtifactEntries( +export function deletePlannedLifecycleArtifactEntries( database: OpenClawAgentDatabase, - entries: readonly SqliteSessionEntryRemovalPlan[], + entries: readonly SessionEntryRemovalPlan[], ): number { - assertPlannedSqliteLifecycleArtifactEntriesUnchanged(database, entries); + assertPlannedLifecycleArtifactEntriesUnchanged(database, entries); let removedEntries = 0; for (const planned of entries) { - deleteSqliteSessionEntryRows(database, planned.sessionKey); + deleteSessionEntryRows(database, planned.sessionKey); removedEntries += 1; } return removedEntries; } -export function assertPlannedSqliteLifecycleArtifactEntriesUnchanged( +export function assertPlannedLifecycleArtifactEntriesUnchanged( database: OpenClawAgentDatabase, - entries: readonly SqliteSessionEntryRemovalPlan[], + entries: readonly SessionEntryRemovalPlan[], ): void { for (const planned of entries) { const current = readExactSessionEntryRow(database, planned.sessionKey)?.entry; diff --git a/src/config/sessions/session-accessor.sqlite-lifecycle-types.ts b/src/config/sessions/session-accessor.sqlite-lifecycle-types.ts index 2317a957b298..2b43c57c269d 100644 --- a/src/config/sessions/session-accessor.sqlite-lifecycle-types.ts +++ b/src/config/sessions/session-accessor.sqlite-lifecycle-types.ts @@ -1,24 +1,24 @@ -import type { SqliteSessionStateDeletePlan } from "./session-accessor.sqlite-archive.js"; +import type { SessionStateDeletePlan } from "./session-accessor.sqlite-archive.js"; import type { SessionEntryLifecycleRemoval } from "./session-accessor.sqlite-contract.js"; import type { SessionResetBoundaryPlan } from "./session-reset-boundary-event.js"; import type { SessionEntry } from "./types.js"; // Shared plan shapes only. Runtime ownership stays in maintenance and lifecycle-state. -export type SqliteSessionEntryRemovalPlan = { +export type SessionEntryRemovalPlan = { expectedEntry: SessionEntry | undefined; sessionKey: string; }; -export type SqliteSessionEntryMaintenancePlan = { - entryRemovals: SqliteSessionEntryRemovalPlan[]; - stateDeletePlans: SqliteSessionStateDeletePlan[]; +export type SessionEntryMaintenancePlan = { + entryRemovals: SessionEntryRemovalPlan[]; + stateDeletePlans: SessionStateDeletePlan[]; }; -export type SqliteLifecycleArtifactCleanupPlan = { - deletePlans: SqliteSessionStateDeletePlan[]; - entries: SqliteSessionEntryRemovalPlan[]; +export type LifecycleArtifactCleanupPlan = { + deletePlans: SessionStateDeletePlan[]; + entries: SessionEntryRemovalPlan[]; }; -export type SqliteProjectedLifecycleMutation = { - deletePlans: SqliteSessionStateDeletePlan[]; +export type ProjectedLifecycleMutation = { + deletePlans: SessionStateDeletePlan[]; removals: Array<{ expectedEntry: SessionEntry; removal: SessionEntryLifecycleRemoval; diff --git a/src/config/sessions/session-accessor.sqlite-lifecycle.ts b/src/config/sessions/session-accessor.sqlite-lifecycle.ts index 39435d789d11..805e2ac90998 100644 --- a/src/config/sessions/session-accessor.sqlite-lifecycle.ts +++ b/src/config/sessions/session-accessor.sqlite-lifecycle.ts @@ -16,7 +16,7 @@ import { type OpenClawAgentDatabase, } from "../../state/openclaw-agent-db.js"; import type { ResetSessionEntryLifecycleMutation } from "./session-accessor.lifecycle-types.js"; -import { materializeSqliteSessionStateDeletePlans } from "./session-accessor.sqlite-archive.js"; +import { materializeSessionStateDeletePlans } from "./session-accessor.sqlite-archive.js"; import type { SessionLifecycleArchivedTranscript, DeleteSessionEntryLifecycleParams, @@ -27,28 +27,28 @@ import type { SessionLifecycleArtifactCleanupResult, } from "./session-accessor.sqlite-contract.js"; import { - assertSqliteLifecycleTargetSnapshotUnchanged, - assertSqliteLifecycleTargetUnchanged, - deleteSqliteLifecycleTargetRows, + assertLifecycleTargetSnapshotUnchanged, + assertLifecycleTargetUnchanged, + deleteLifecycleTargetRows, deleteLegacySessionEntryRows, - readSqliteLifecycleTargetSnapshot, - rehomeSqliteSessionWindows, + readLifecycleTargetSnapshot, + rehomeSessionWindows, sqliteSessionEntriesEqual, writeSessionEntry, } from "./session-accessor.sqlite-entry-store.js"; -import { emitArchivedSqliteTranscriptUpdates } from "./session-accessor.sqlite-events.js"; +import { emitArchivedTranscriptUpdates } from "./session-accessor.sqlite-events.js"; import { emitCommittedSessionEntryRemovals } from "./session-accessor.sqlite-identity.js"; import { - assertPlannedSqliteLifecycleArtifactEntriesUnchanged, - deleteMaterializedSqliteSessionStatePlans, - deletePlannedSqliteLifecycleArtifactEntries, - planSqliteSessionLifecycleArtifactCleanup, - planSqliteSessionStateDeleteIfUnreferenced, - readSqliteSessionGenerationIdsForKeys, - planSqliteSessionStateAfterEntryRemoval, - readReferencedSqliteSessionIdsAfterTargetMutation, + assertPlannedLifecycleArtifactEntriesUnchanged, + deleteMaterializedSessionStatePlans, + deletePlannedLifecycleArtifactEntries, + planSessionLifecycleArtifactCleanup, + planSessionStateDeleteIfUnreferenced, + readSessionGenerationIdsForKeys, + planSessionStateAfterEntryRemoval, + readReferencedSessionIdsAfterTargetMutation, } from "./session-accessor.sqlite-lifecycle-state.js"; -import { loadSqliteTranscriptEventsFromDatabase } from "./session-accessor.sqlite-read.js"; +import { loadTranscriptEventsFromDatabase } from "./session-accessor.sqlite-read.js"; import { cloneSessionEntry, resolveSqliteReadScope, @@ -105,7 +105,7 @@ function deleteSessionBoardRows( executeSqliteQuerySync(database.db, db.deleteFrom("board_tabs").where("session_key", "in", keys)); } -export async function cleanupSqliteSessionLifecycleArtifacts( +export async function cleanupSessionLifecycleArtifacts( params: SessionLifecycleArtifactCleanupParams, ): Promise { const sessionKeySegmentPrefix = params.sessionKeySegmentPrefix.trim(); @@ -126,7 +126,7 @@ export async function cleanupSqliteSessionLifecycleArtifacts( } const cleanupPlan = await runExclusiveSqliteSessionWrite(resolved, async () => { const database = openOpenClawAgentDatabase(databaseOptions); - return planSqliteSessionLifecycleArtifactCleanup(database, { + return planSessionLifecycleArtifactCleanup(database, { ...(params.agentId !== undefined ? { agentId: resolved.agentId } : {}), archiveRemovedEntryTranscripts: params.archiveRemovedEntryTranscripts !== false, archiveDirectory: resolveSqliteTranscriptArchiveDirectory(resolved), @@ -137,22 +137,19 @@ export async function cleanupSqliteSessionLifecycleArtifacts( nowMs: params.nowMs ?? Date.now(), }); }); - const materializedPlans = await materializeSqliteSessionStateDeletePlans(cleanupPlan.deletePlans); + const materializedPlans = await materializeSessionStateDeletePlans(cleanupPlan.deletePlans); return await runExclusiveSqliteSessionWrite(resolved, async () => { let removedEntries = 0; let archivedTranscripts: SessionLifecycleArchivedTranscript[] = []; runOpenClawAgentWriteTransaction((transactionDb) => { - assertPlannedSqliteLifecycleArtifactEntriesUnchanged(transactionDb, cleanupPlan.entries); - archivedTranscripts = deleteMaterializedSqliteSessionStatePlans( + assertPlannedLifecycleArtifactEntriesUnchanged(transactionDb, cleanupPlan.entries); + archivedTranscripts = deleteMaterializedSessionStatePlans( transactionDb, materializedPlans, undefined, new Set(cleanupPlan.entries.map((entry) => entry.sessionKey)), ); - removedEntries = deletePlannedSqliteLifecycleArtifactEntries( - transactionDb, - cleanupPlan.entries, - ); + removedEntries = deletePlannedLifecycleArtifactEntries(transactionDb, cleanupPlan.entries); }, databaseOptions); emitCommittedSessionEntryRemovals(cleanupPlan.entries); return { @@ -163,7 +160,7 @@ export async function cleanupSqliteSessionLifecycleArtifacts( } /** Resets one persisted session entry using SQLite session rows. */ -export async function resetSqliteSessionEntryLifecycle( +export async function resetSessionEntryLifecycle( params: ResetSessionEntryLifecycleParams, ): Promise { const agentId = params.agentId ?? parseAgentSessionKey(params.target.canonicalKey)?.agentId; @@ -173,7 +170,7 @@ export async function resetSqliteSessionEntryLifecycle( try { return await runExclusiveSqliteSessionWrite(resolved, async () => { const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); - const targetSnapshot = readSqliteLifecycleTargetSnapshot(database, params.target); + const targetSnapshot = readLifecycleTargetSnapshot(database, params.target); const current = targetSnapshot.primary; const nextEntry = await params.buildNextEntry({ currentEntry: current ? cloneSessionEntry(current.entry) : undefined, @@ -184,7 +181,7 @@ export async function resetSqliteSessionEntryLifecycle( current?.entry.sessionId && !sqliteSessionEntriesEqual(current.entry, nextEntry) ? await buildSessionResetBoundaryPlan({ - events: loadSqliteTranscriptEventsFromDatabase(database, current.entry.sessionId), + events: loadTranscriptEventsFromDatabase(database, current.entry.sessionId), reason: params.resetBoundaryReason, }) : undefined; @@ -194,7 +191,7 @@ export async function resetSqliteSessionEntryLifecycle( ...(current?.entry.sessionId ? { previousSessionId: current.entry.sessionId } : {}), }; runOpenClawAgentWriteTransaction((transactionDb) => { - assertSqliteLifecycleTargetUnchanged(transactionDb, params.target, current?.entry, "reset"); + assertLifecycleTargetUnchanged(transactionDb, params.target, current?.entry, "reset"); if (resetBoundaryPlan && current?.entry.sessionId) { const events = [...resetBoundaryPlan.seedEvents, resetBoundaryPlan.event]; const appended = appendTranscriptEventsInTransaction( @@ -213,11 +210,7 @@ export async function resetSqliteSessionEntryLifecycle( writeSessionEntry(transactionDb, params.target.canonicalKey, nextEntry, { previousEntry: current?.entry ?? null, }); - rehomeSqliteSessionWindows( - transactionDb, - params.target.canonicalKey, - params.target.storeKeys, - ); + rehomeSessionWindows(transactionDb, params.target.canonicalKey, params.target.storeKeys); deleteLegacySessionEntryRows( transactionDb, params.target.storeKeys, @@ -301,7 +294,7 @@ async function deleteSqliteSessionEntryLifecycleLocked( ): Promise { const prepared = await runExclusiveSqliteSessionWrite(resolved, async () => { const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); - const targetSnapshot = readSqliteLifecycleTargetSnapshot(database, params.target); + const targetSnapshot = readLifecycleTargetSnapshot(database, params.target); const current = targetSnapshot.primary; if (!current) { return null; @@ -321,7 +314,7 @@ async function deleteSqliteSessionEntryLifecycleLocked( ) { throw new Error(MODEL_SELECTION_LOCK_REMOVAL_MESSAGE); } - const referencedAfterDelete = readReferencedSqliteSessionIdsAfterTargetMutation( + const referencedAfterDelete = readReferencedSessionIdsAfterTargetMutation( database, params.target, ); @@ -332,7 +325,7 @@ async function deleteSqliteSessionEntryLifecycleLocked( const archiveDirectory = resolveSqliteTranscriptArchiveDirectory(resolved); const entryPlans = deleteTranscriptState ? targetSnapshot.rows.flatMap(({ entry }) => - planSqliteSessionStateAfterEntryRemoval({ + planSessionStateAfterEntryRemoval({ archiveDirectory, archiveTranscript: params.archiveTranscript, database, @@ -346,7 +339,7 @@ async function deleteSqliteSessionEntryLifecycleLocked( // Ids only — archive extraction happens lazily one generation at a time // outside the SQLite write transaction. const historicalGenerationIds = deleteTranscriptState - ? readSqliteSessionGenerationIdsForKeys(database, [ + ? readSessionGenerationIdsForKeys(database, [ params.target.canonicalKey, ...params.target.storeKeys, ...targetSnapshot.rows.map((row) => row.sessionKey), @@ -381,12 +374,12 @@ async function deleteSqliteSessionEntryLifecycleLocked( for (const sessionId of prepared.historicalGenerationIds) { const plan = await runExclusiveSqliteSessionWrite(resolved, async () => { const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); - assertSqliteLifecycleTargetSnapshotUnchanged( + assertLifecycleTargetSnapshotUnchanged( prepared.targetSnapshot, - readSqliteLifecycleTargetSnapshot(database, params.target), + readLifecycleTargetSnapshot(database, params.target), "delete session entry", ); - const referencedAfterDelete = readReferencedSqliteSessionIdsAfterTargetMutation( + const referencedAfterDelete = readReferencedSessionIdsAfterTargetMutation( database, params.target, ); @@ -402,7 +395,7 @@ async function deleteSqliteSessionEntryLifecycleLocked( `cannot delete session history while work is in flight for ${sessionId}; retry after the run completes`, ); } - return planSqliteSessionStateDeleteIfUnreferenced({ + return planSessionStateDeleteIfUnreferenced({ archiveDirectory: prepared.archiveDirectory, archiveTranscript: params.archiveTranscript, database, @@ -414,13 +407,13 @@ async function deleteSqliteSessionEntryLifecycleLocked( if (!plan) { continue; } - const materializedGeneration = await materializeSqliteSessionStateDeletePlans([plan]); + const materializedGeneration = await materializeSessionStateDeletePlans([plan]); const archivedGeneration = await runExclusiveSqliteSessionWrite(resolved, async () => { let committed: SessionLifecycleArchivedTranscript[] = []; runOpenClawAgentWriteTransaction((transactionDb) => { - assertSqliteLifecycleTargetSnapshotUnchanged( + assertLifecycleTargetSnapshotUnchanged( prepared.targetSnapshot, - readSqliteLifecycleTargetSnapshot(transactionDb, params.target), + readLifecycleTargetSnapshot(transactionDb, params.target), "delete session entry", ); const fenceAtDelete = collectAdmissionProtectedSessionIds({ @@ -432,31 +425,28 @@ async function deleteSqliteSessionEntryLifecycleLocked( `cannot delete session history while work is in flight for ${sessionId}; retry after the run completes`, ); } - committed = deleteMaterializedSqliteSessionStatePlans( - transactionDb, - materializedGeneration, - ); + committed = deleteMaterializedSessionStatePlans(transactionDb, materializedGeneration); }, toDatabaseOptions(resolved)); return committed; }); // Publish each committed generation immediately: a later archive or // transaction failure aborts the deletion, and observers must still see // the removals that already happened (retry completes the remainder). - emitArchivedSqliteTranscriptUpdates(archivedGeneration); + emitArchivedTranscriptUpdates(archivedGeneration); historicalArchivedTranscripts.push(...archivedGeneration); } // Archive materialization is the expensive phase. It must run between short // writer-lane sections so unrelated writes to this store can keep progressing. - const materializedPlans = await materializeSqliteSessionStateDeletePlans(prepared.entryPlans); + const materializedPlans = await materializeSessionStateDeletePlans(prepared.entryPlans); const result = await runExclusiveSqliteSessionWrite(resolved, async () => { let committed: DeleteSessionEntryLifecycleResult = { archivedTranscripts: [], deleted: false, }; runOpenClawAgentWriteTransaction((transactionDb) => { - const transactionSnapshot = readSqliteLifecycleTargetSnapshot(transactionDb, params.target); - assertSqliteLifecycleTargetSnapshotUnchanged( + const transactionSnapshot = readLifecycleTargetSnapshot(transactionDb, params.target); + assertLifecycleTargetSnapshotUnchanged( prepared.targetSnapshot, transactionSnapshot, "delete session entry", @@ -465,7 +455,7 @@ async function deleteSqliteSessionEntryLifecycleLocked( if (!shouldDeleteSqliteSessionEntryLifecycle(transactionEntry, params)) { return; } - const archivedTranscripts = deleteMaterializedSqliteSessionStatePlans( + const archivedTranscripts = deleteMaterializedSessionStatePlans( transactionDb, materializedPlans, undefined, @@ -475,7 +465,7 @@ async function deleteSqliteSessionEntryLifecycleLocked( ...transactionSnapshot.rows.map((row) => row.sessionKey), ]), ); - deleteSqliteLifecycleTargetRows(transactionDb, params.target); + deleteLifecycleTargetRows(transactionDb, params.target); deleteSessionBoardRows(transactionDb, [ params.target.canonicalKey, ...params.target.storeKeys, @@ -503,7 +493,7 @@ async function deleteSqliteSessionEntryLifecycleLocked( }, }); } - emitArchivedSqliteTranscriptUpdates(result.archivedTranscripts); + emitArchivedTranscriptUpdates(result.archivedTranscripts); // Historical generations were emitted per commit above; merge them into // the result after the final emit so callers still see every archive. result.archivedTranscripts.push(...historicalArchivedTranscripts); @@ -511,14 +501,14 @@ async function deleteSqliteSessionEntryLifecycleLocked( } /** Deletes one persisted session entry using SQLite session rows. */ -export async function deleteSqliteSessionEntryLifecycle( +export async function deleteSessionEntryLifecycle( params: DeleteSessionEntryLifecycleParams, ): Promise { return await deleteSqliteSessionEntryLifecycleInternal(params, false); } /** Rolls back one exact locked row created by failed trusted harness initialization. */ -export async function rollbackSqliteAgentHarnessSessionEntryLifecycle( +export async function rollbackAgentHarnessSessionEntryLifecycle( params: DeleteSessionEntryLifecycleParams & { expectedEntry: SessionEntry }, ): Promise { const hasExactTarget = @@ -539,7 +529,7 @@ export async function rollbackSqliteAgentHarnessSessionEntryLifecycle( } /** Rolls back one exact locked CLI row created by a failed plugin initializer. */ -export async function rollbackSqlitePluginOwnedSessionEntryLifecycle( +export async function rollbackPluginOwnedSessionEntryLifecycle( params: DeleteSessionEntryLifecycleParams & { expectedEntry: SessionEntry; expectedPluginOwnerId: string; diff --git a/src/config/sessions/session-accessor.sqlite-maintenance.ts b/src/config/sessions/session-accessor.sqlite-maintenance.ts index 5d8ea6308fa2..da84e16d321d 100644 --- a/src/config/sessions/session-accessor.sqlite-maintenance.ts +++ b/src/config/sessions/session-accessor.sqlite-maintenance.ts @@ -7,22 +7,22 @@ import { type OpenClawAgentDatabase, } from "../../state/openclaw-agent-db.js"; import { - materializeSqliteSessionStateDeletePlans, - type SqliteSessionStateDeletePlan, + materializeSessionStateDeletePlans, + type SessionStateDeletePlan, } from "./session-accessor.sqlite-archive.js"; import type { SessionLifecycleArchivedTranscript } from "./session-accessor.sqlite-contract.js"; -import { readSqliteSessionEntryCount } from "./session-accessor.sqlite-entry-store.js"; +import { readSessionEntryCount } from "./session-accessor.sqlite-entry-store.js"; import { emitCommittedSessionEntryRemovals } from "./session-accessor.sqlite-identity.js"; import { - assertPlannedSqliteLifecycleArtifactEntriesUnchanged, - collectProjectedReferencedSqliteSessionIds, - collectSqliteSessionStateIdsForEntry, - deleteMaterializedSqliteSessionStatePlans, - deletePlannedSqliteLifecycleArtifactEntries, - planSqliteSessionStateDeleteIfUnreferenced, - readSqliteSessionGenerationIdsForKeys, + assertPlannedLifecycleArtifactEntriesUnchanged, + collectProjectedReferencedSessionIds, + collectSessionStateIdsForEntry, + deleteMaterializedSessionStatePlans, + deletePlannedLifecycleArtifactEntries, + planSessionStateDeleteIfUnreferenced, + readSessionGenerationIdsForKeys, } from "./session-accessor.sqlite-lifecycle-state.js"; -import type { SqliteSessionEntryMaintenancePlan } from "./session-accessor.sqlite-lifecycle-types.js"; +import type { SessionEntryMaintenancePlan } from "./session-accessor.sqlite-lifecycle-types.js"; import { cloneSessionEntry, getSessionKysely, @@ -30,7 +30,7 @@ import { toDatabaseOptions, type ResolvedSqliteReadScope, } from "./session-accessor.sqlite-scope.js"; -import { parseSqliteSessionEntryJson as parseSessionEntryRow } from "./session-accessor.sqlite-status.js"; +import { parseSessionEntryJson as parseSessionEntryRow } from "./session-accessor.sqlite-status.js"; import { normalizeStoreSessionKey } from "./store-entry.js"; import { collectSessionMaintenancePreserveKeys, @@ -97,7 +97,7 @@ function hasStaleSqliteSessionEntryCandidate( }); } -export function applySqliteSessionEntryMaintenance( +export function applySessionEntryMaintenance( database: OpenClawAgentDatabase, params: { activeSessionKey: string; @@ -107,7 +107,7 @@ export function applySqliteSessionEntryMaintenance( skipMaintenance?: boolean; storePath: string; }, -): SqliteSessionEntryMaintenancePlan { +): SessionEntryMaintenancePlan { if (params.skipMaintenance) { return { entryRemovals: [], stateDeletePlans: [] }; } @@ -116,7 +116,7 @@ export function applySqliteSessionEntryMaintenance( return { entryRemovals: [], stateDeletePlans: [] }; } - const entryCount = readSqliteSessionEntryCount(database); + const entryCount = readSessionEntryCount(database); const preserveCandidateKeys = collectSessionMaintenancePreserveKeys([params.activeSessionKey]); const hasStaleCandidate = hasStaleSqliteSessionEntryCandidate( database, @@ -160,7 +160,7 @@ export function applySqliteSessionEntryMaintenance( const rememberRemovedEntry = (removed: { key: string; entry: SessionEntry }) => { removedKeys.add(removed.key); removedEntriesByKey.set(removed.key, cloneSessionEntry(removed.entry)); - for (const sessionId of collectSqliteSessionStateIdsForEntry(removed.entry)) { + for (const sessionId of collectSessionStateIdsForEntry(removed.entry)) { removedSessionIds.add(sessionId); } }; @@ -207,17 +207,17 @@ export function applySqliteSessionEntryMaintenance( preserveKeys, }); } - for (const sessionId of readSqliteSessionGenerationIdsForKeys(database, removedKeys)) { + for (const sessionId of readSessionGenerationIdsForKeys(database, removedKeys)) { removedSessionIds.add(sessionId); } - const referencedSessionIds = collectProjectedReferencedSqliteSessionIds({ + const referencedSessionIds = collectProjectedReferencedSessionIds({ database, excludedSessionKeys: removedKeys, projectedStore: store, }); - const deletePlans: SqliteSessionStateDeletePlan[] = []; + const deletePlans: SessionStateDeletePlan[] = []; for (const sessionId of removedSessionIds) { - const plan = planSqliteSessionStateDeleteIfUnreferenced({ + const plan = planSessionStateDeleteIfUnreferenced({ archiveTranscript: true, archiveDirectory: params.archiveDirectory, database, @@ -237,9 +237,9 @@ export function applySqliteSessionEntryMaintenance( }; } -export async function finalizeSqliteSessionEntryMaintenancePlansBestEffort( +export async function finalizeSessionEntryMaintenancePlansBestEffort( scope: Pick, - plans: readonly SqliteSessionEntryMaintenancePlan[], + plans: readonly SessionEntryMaintenancePlan[], ): Promise { return await finalizeSqliteSessionEntryMaintenancePlansWithCommit(scope, plans, async (commit) => commit(), @@ -247,9 +247,9 @@ export async function finalizeSqliteSessionEntryMaintenancePlansBestEffort( } /** Finalizes maintenance after its caller releases the per-store writer lane. */ -export async function finalizeSqliteSessionEntryMaintenancePlansAfterWriterReleaseBestEffort( +export async function finalizeSessionEntryMaintenancePlansAfterWriterReleaseBestEffort( scope: Pick, - plans: readonly SqliteSessionEntryMaintenancePlan[], + plans: readonly SessionEntryMaintenancePlan[], ): Promise { return await finalizeSqliteSessionEntryMaintenancePlansWithCommit( scope, @@ -260,7 +260,7 @@ export async function finalizeSqliteSessionEntryMaintenancePlansAfterWriterRelea async function finalizeSqliteSessionEntryMaintenancePlansWithCommit( scope: Pick, - plans: readonly SqliteSessionEntryMaintenancePlan[], + plans: readonly SessionEntryMaintenancePlan[], commit: ( fn: () => SessionLifecycleArchivedTranscript[], ) => Promise, @@ -271,18 +271,18 @@ async function finalizeSqliteSessionEntryMaintenancePlansWithCommit( return []; } try { - const materializedPlans = await materializeSqliteSessionStateDeletePlans(stateDeletePlans); + const materializedPlans = await materializeSessionStateDeletePlans(stateDeletePlans); const archivedTranscripts = await commit(() => { let committed: SessionLifecycleArchivedTranscript[] = []; runOpenClawAgentWriteTransaction((database) => { - assertPlannedSqliteLifecycleArtifactEntriesUnchanged(database, entryRemovals); - committed = deleteMaterializedSqliteSessionStatePlans( + assertPlannedLifecycleArtifactEntriesUnchanged(database, entryRemovals); + committed = deleteMaterializedSessionStatePlans( database, materializedPlans, undefined, new Set(entryRemovals.map((removal) => removal.sessionKey)), ); - deletePlannedSqliteLifecycleArtifactEntries(database, entryRemovals); + deletePlannedLifecycleArtifactEntries(database, entryRemovals); }, toDatabaseOptions(scope)); return committed; }); diff --git a/src/config/sessions/session-accessor.sqlite-message-cut.test.ts b/src/config/sessions/session-accessor.sqlite-message-cut.test.ts index 2aee1d566926..7716987b7daa 100644 --- a/src/config/sessions/session-accessor.sqlite-message-cut.test.ts +++ b/src/config/sessions/session-accessor.sqlite-message-cut.test.ts @@ -24,7 +24,6 @@ import { updateSessionEntry, upsertSessionEntry, } from "./session-accessor.js"; -import { listSqliteSessionBranches } from "./session-accessor.sqlite-message-cut.js"; import type { InternalSessionEntry } from "./types.js"; const tempDirs = useAutoCleanupTempDirTracker(afterEach); @@ -179,10 +178,10 @@ describe("SQLite session message cuts", () => { const { env } = await createSession(); const fullTranscriptLoads = trackFullTranscriptLoads(env); - const first = await listSqliteSessionBranches({ agentId, env, sessionKey }); + const first = await listSessionBranches({ agentId, env, sessionKey }); expect(fullTranscriptLoads()).toBe(1); - const second = await listSqliteSessionBranches({ agentId, env, sessionKey }); + const second = await listSessionBranches({ agentId, env, sessionKey }); expect(second).toEqual(first); expect(fullTranscriptLoads()).toBe(1); if (second.status !== "ok" || !second.branches[0]) { @@ -190,7 +189,7 @@ describe("SQLite session message cuts", () => { } second.branches[0].headline = "caller mutation"; - await expect(listSqliteSessionBranches({ agentId, env, sessionKey })).resolves.toEqual(first); + await expect(listSessionBranches({ agentId, env, sessionKey })).resolves.toEqual(first); expect(fullTranscriptLoads()).toBe(1); }); @@ -198,7 +197,7 @@ describe("SQLite session message cuts", () => { const { env, scope } = await createSession(); const fullTranscriptLoads = trackFullTranscriptLoads(env); - const before = await listSqliteSessionBranches({ agentId, env, sessionKey }); + const before = await listSessionBranches({ agentId, env, sessionKey }); expect(fullTranscriptLoads()).toBe(1); await appendTranscriptMessage(scope, { eventId: "assistant-3", @@ -207,7 +206,7 @@ describe("SQLite session message cuts", () => { parentId: "assistant-2", }); - const after = await listSqliteSessionBranches({ agentId, env, sessionKey }); + const after = await listSessionBranches({ agentId, env, sessionKey }); expect(fullTranscriptLoads()).toBe(2); expect(after).not.toEqual(before); expect(after.status).toBe("ok"); @@ -232,7 +231,7 @@ describe("SQLite session message cuts", () => { } await upsertSessionEntry({ agentId, env, sessionKey: aliasKey }, sourceEntry); const fullTranscriptLoads = trackFullTranscriptLoads(env); - await listSqliteSessionBranches({ agentId, env, sessionKey }); + await listSessionBranches({ agentId, env, sessionKey }); const result = mode === "rewind" @@ -259,10 +258,10 @@ describe("SQLite session message cuts", () => { expect(result.status).toBe("created"); const loadsBeforeAliasRead = fullTranscriptLoads(); - await listSqliteSessionBranches({ agentId, env, sessionKey: aliasKey }); + await listSessionBranches({ agentId, env, sessionKey: aliasKey }); expect(fullTranscriptLoads()).toBe(loadsBeforeAliasRead + 1); - const listed = await listSqliteSessionBranches({ + const listed = await listSessionBranches({ agentId, env, sessionKey: mode === "fork" ? targetKey : sessionKey, @@ -325,7 +324,7 @@ describe("SQLite session message cuts", () => { releaseOwnerChange(); await ownerChange; - await expect(mutation).resolves.toEqual({ status: "failed" }); + await expect(mutation).resolves.toEqual({ status: "conflict" }); expect(loadSessionEntry(scope)).toMatchObject({ lifecycleRevision: "replacement-lifecycle-revision", sessionId: sourceExpectedState.sessionId, @@ -350,8 +349,8 @@ describe("SQLite session message cuts", () => { }); const fullTranscriptLoads = trackFullTranscriptLoads(env); - const source = await listSqliteSessionBranches({ agentId, env, sessionKey }); - const other = await listSqliteSessionBranches(sibling); + const source = await listSessionBranches({ agentId, env, sessionKey }); + const other = await listSessionBranches(sibling); expect(fullTranscriptLoads()).toBe(2); expect(source.status).toBe("ok"); if (source.status !== "ok") { @@ -373,7 +372,7 @@ describe("SQLite session message cuts", () => { }, ], }); - await expect(listSqliteSessionBranches({ agentId, env, sessionKey })).resolves.toEqual(source); + await expect(listSessionBranches({ agentId, env, sessionKey })).resolves.toEqual(source); expect(fullTranscriptLoads()).toBe(2); }); diff --git a/src/config/sessions/session-accessor.sqlite-message-cut.ts b/src/config/sessions/session-accessor.sqlite-message-cut.ts index ebdcf816eb0e..f89d03963584 100644 --- a/src/config/sessions/session-accessor.sqlite-message-cut.ts +++ b/src/config/sessions/session-accessor.sqlite-message-cut.ts @@ -13,11 +13,11 @@ import type { TranscriptEvent } from "./session-accessor.sqlite-contract.js"; import { collectSessionEntryLookupKeys, readSessionEntryRow, - readSqliteSessionIdentitySnapshot, + readSessionIdentitySnapshot, writeSessionEntry, } from "./session-accessor.sqlite-entry-store.js"; import { emitCommittedSessionIdentityDiff } from "./session-accessor.sqlite-identity.js"; -import { loadSqliteTranscriptEventsFromDatabase } from "./session-accessor.sqlite-read.js"; +import { loadTranscriptEventsFromDatabase } from "./session-accessor.sqlite-read.js"; import { getSessionKysely, normalizeSqliteSessionKey, @@ -120,9 +120,7 @@ function loadSessionBranchSummaries( return cloneSessionBranchSummaries(cached.branches); } - const branches = summarizeSessionBranches( - loadSqliteTranscriptEventsFromDatabase(database, sessionId), - ); + const branches = summarizeSessionBranches(loadTranscriptEventsFromDatabase(database, sessionId)); sessionBranchCache.delete(cacheKey); sessionBranchCache.set(cacheKey, { ...watermark, branches }); pruneMapToMaxSize(sessionBranchCache, SESSION_BRANCH_CACHE_MAX_ENTRIES); @@ -135,7 +133,7 @@ function invalidateSessionBranchCache(databasePath: string, sessionIds: readonly } } -export async function listSqliteSessionBranches( +export async function listSessionBranches( params: SessionBranchListParams, ): Promise { const sourceKey = normalizeSqliteSessionKey(params.sessionStoreKey ?? params.sessionKey); @@ -167,21 +165,21 @@ export function resolveSessionTranscriptActiveLeafEntryId( return scanSessionTranscriptTree(events).leafId ?? undefined; } -export async function rewindSqliteSessionToMessage( +export async function rewindSessionToMessage( params: SessionMessageCutMutationParams, expectedState?: SessionEntryExpectedState, ): Promise { return await mutateSqliteSessionAtMessage(params, "rewind", expectedState); } -export async function forkSqliteSessionAtMessage( +export async function forkSessionAtMessage( params: SessionMessageCutMutationParams & { targetKey: string }, expectedState?: SessionEntryExpectedState, ): Promise { return await mutateSqliteSessionAtMessage(params, "fork", expectedState); } -export async function switchSqliteSessionBranch( +export async function switchSessionBranch( params: SessionBranchSwitchMutationParams, expectedState?: SessionEntryExpectedState, ): Promise { @@ -240,7 +238,7 @@ async function mutateSqliteSessionAtMessage( ...collectSessionEntryLookupKeys(database, sourceKey), ...collectSessionEntryLookupKeys(database, targetKey), ]); - previousIdentity = readSqliteSessionIdentitySnapshot(database, identityKeys); + previousIdentity = readSessionIdentitySnapshot(database, identityKeys); const mutationResult = mutateSqliteSessionAtMessageInTransaction(database, resolved, { entryId: params.entryId, canonicalSourceKey, @@ -250,7 +248,7 @@ async function mutateSqliteSessionAtMessage( sourceKey, targetKey, }); - currentIdentity = readSqliteSessionIdentitySnapshot(database, identityKeys); + currentIdentity = readSessionIdentitySnapshot(database, identityKeys); return mutationResult; }, toDatabaseOptions(resolved)); if (result.status === "created" && databasePath) { @@ -290,7 +288,7 @@ function mutateSqliteSessionAtMessageInTransaction( ) { return { status: "conflict" }; } - const events = loadSqliteTranscriptEventsFromDatabase(database, currentEntry.sessionId); + const events = loadTranscriptEventsFromDatabase(database, currentEntry.sessionId); const cut = params.mode === "switch" ? undefined : resolveMessageCut(events, params.entryId); if (cut && "status" in cut) { return cut; diff --git a/src/config/sessions/session-accessor.sqlite-normalize.ts b/src/config/sessions/session-accessor.sqlite-normalize.ts index e047edf62819..234abd373579 100644 --- a/src/config/sessions/session-accessor.sqlite-normalize.ts +++ b/src/config/sessions/session-accessor.sqlite-normalize.ts @@ -10,11 +10,11 @@ export function createFallbackSessionEntry(patch: Partial): Sessio }; } -export function normalizeSqliteText(value: unknown): string | null { +export function normalizeText(value: unknown): string | null { return typeof value === "string" && value.trim() ? value.trim() : null; } -export function normalizeSqliteChatType(value: unknown): "direct" | "group" | "channel" | null { +export function normalizeSessionRowChatType(value: unknown): "direct" | "group" | "channel" | null { if (value === "direct" || value === "group" || value === "channel") { return value; } diff --git a/src/config/sessions/session-accessor.sqlite-parent-fork.ts b/src/config/sessions/session-accessor.sqlite-parent-fork.ts index 221cf1e5e9a7..0fcac45c0baf 100644 --- a/src/config/sessions/session-accessor.sqlite-parent-fork.ts +++ b/src/config/sessions/session-accessor.sqlite-parent-fork.ts @@ -15,7 +15,7 @@ import { import type { SessionEntry } from "./types.js"; import { resolveFreshSessionTotalTokens } from "./types.js"; -export type SqliteParentForkSourceTranscript = { +export type ParentForkSourceTranscript = { appendMode?: "side"; appendParentId: string | null; branchEntries: TranscriptEvent[]; @@ -42,7 +42,7 @@ function formatParentForkTooLargeMessage(params: { ); } -export function resolveSqliteParentForkDecision( +export function planParentForkDecision( parentEntry: SessionEntry, transcriptEstimate?: SqliteTranscriptParentTokenEstimate, ): SessionParentForkDecision { @@ -64,7 +64,7 @@ export function resolveSqliteParentForkDecision( }; } -export function estimateSqliteTranscriptPromptTokens( +export function estimateTranscriptPromptTokens( events: readonly TranscriptEvent[], ): SqliteTranscriptParentTokenEstimate | undefined { let byteEstimate = 0; @@ -180,9 +180,9 @@ function readTranscriptContextUsage( return totalTokens === undefined ? undefined : { state: "available", totalTokens }; } -export function resolveSqliteParentForkSourceTranscript( +export function resolveParentForkSourceTranscript( fileEntries: readonly TranscriptEvent[], -): SqliteParentForkSourceTranscript | null { +): ParentForkSourceTranscript | null { if (fileEntries.length === 0) { return null; } @@ -283,9 +283,9 @@ function hasAssistantEntry(entries: readonly TranscriptEvent[]): boolean { ); } -export function buildSqliteForkedChildTranscriptEvents(params: { +export function buildForkedChildTranscriptEvents(params: { parentSessionFile: string; - source: SqliteParentForkSourceTranscript; + source: ParentForkSourceTranscript; targetSessionId: string; }): TranscriptEvent[] { const header = { diff --git a/src/config/sessions/session-accessor.sqlite-parent-session.ts b/src/config/sessions/session-accessor.sqlite-parent-session.ts index bee7df4ac146..df7020fd6b08 100644 --- a/src/config/sessions/session-accessor.sqlite-parent-session.ts +++ b/src/config/sessions/session-accessor.sqlite-parent-session.ts @@ -13,26 +13,26 @@ import type { } from "./session-accessor.sqlite-contract.js"; import { deleteLegacySessionEntryRows, - normalizeSqliteLifecycleTarget, - readSqliteSessionIdentitySnapshot, - rehomeSqliteSessionWindows, - resolveSqliteLifecyclePrimaryEntry, + normalizeLifecycleTarget, + readSessionIdentitySnapshot, + rehomeSessionWindows, + resolveLifecyclePrimaryEntry, writeSessionEntry, } from "./session-accessor.sqlite-entry-store.js"; import { emitCommittedSessionIdentityDiff } from "./session-accessor.sqlite-identity.js"; -import type { SqliteSessionEntryMaintenancePlan } from "./session-accessor.sqlite-lifecycle-types.js"; +import type { SessionEntryMaintenancePlan } from "./session-accessor.sqlite-lifecycle-types.js"; import { - applySqliteSessionEntryMaintenance, - finalizeSqliteSessionEntryMaintenancePlansBestEffort, + applySessionEntryMaintenance, + finalizeSessionEntryMaintenancePlansBestEffort, } from "./session-accessor.sqlite-maintenance.js"; import { - buildSqliteForkedChildTranscriptEvents, - estimateSqliteTranscriptPromptTokens, - resolveSqliteParentForkDecision, - resolveSqliteParentForkSourceTranscript, - type SqliteParentForkSourceTranscript, + buildForkedChildTranscriptEvents, + estimateTranscriptPromptTokens, + planParentForkDecision, + resolveParentForkSourceTranscript, + type ParentForkSourceTranscript, } from "./session-accessor.sqlite-parent-fork.js"; -import { loadSqliteTranscriptEventsFromDatabase } from "./session-accessor.sqlite-read.js"; +import { loadTranscriptEventsFromDatabase } from "./session-accessor.sqlite-read.js"; import { cloneSessionEntry, formatLegacySqliteSessionMarkerForScope, @@ -53,7 +53,7 @@ import { mergeSessionEntry, resolveFreshSessionTotalTokens } from "./types.js"; // Parent-session fork owner: decision, transcript copy, and child entry commit. -export async function forkSqliteSessionTranscriptFromParent( +export async function forkSessionTranscriptFromParent( params: ForkSessionFromParentTranscriptParams, ): Promise { const resolved = resolveSqliteScope({ @@ -89,8 +89,8 @@ export async function forkSqliteSessionTranscriptFromParent( return { status: "missing-parent" }; } const sourceDatabase = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); - const source = resolveSqliteParentForkSourceTranscript( - loadSqliteTranscriptEventsFromDatabase(sourceDatabase, params.parentEntry.sessionId), + const source = resolveParentForkSourceTranscript( + loadTranscriptEventsFromDatabase(sourceDatabase, params.parentEntry.sessionId), ); if (!source) { return { status: "failed" }; @@ -119,20 +119,20 @@ export async function forkSqliteSessionTranscriptFromParent( } /** Forks parent context into a child session entry using SQLite rows only. */ -export async function forkSqliteSessionEntryFromParentTarget( +export async function forkSessionEntryFromParentTarget( params: ForkSessionEntryFromParentTargetParams, ): Promise { const resolved = resolveSqliteStoreScope(params.storePath, { agentId: params.agentId }); - const parentTarget = normalizeSqliteLifecycleTarget(params.parentTarget); - const sessionTarget = normalizeSqliteLifecycleTarget(params.sessionTarget); + const parentTarget = normalizeLifecycleTarget(params.parentTarget); + const sessionTarget = normalizeLifecycleTarget(params.sessionTarget); return await runExclusiveSqliteSessionWrite(resolved, async () => { const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); - const parent = resolveSqliteLifecyclePrimaryEntry(database, parentTarget); + const parent = resolveLifecyclePrimaryEntry(database, parentTarget); if (!parent?.entry.sessionId) { return { status: "missing-parent" }; } - const existing = resolveSqliteLifecyclePrimaryEntry(database, sessionTarget); + const existing = resolveLifecyclePrimaryEntry(database, sessionTarget); const base = existing?.entry ?? params.fallbackEntry; if (!base) { return { status: "missing-entry" }; @@ -159,11 +159,11 @@ export async function forkSqliteSessionEntryFromParentTarget( typeof parent.entry.sessionId === "string" && parent.entry.sessionId.length > 0; const transcriptParentTokens = needsTranscriptTokenEstimate - ? estimateSqliteTranscriptPromptTokens( - loadSqliteTranscriptEventsFromDatabase(database, parent.entry.sessionId), + ? estimateTranscriptPromptTokens( + loadTranscriptEventsFromDatabase(database, parent.entry.sessionId), ) : undefined; - const decision = resolveSqliteParentForkDecision(parent.entry, transcriptParentTokens); + const decision = planParentForkDecision(parent.entry, transcriptParentTokens); if (decision.status === "skip") { const patch = params.decisionSkipPatch?.({ decision, @@ -187,16 +187,16 @@ export async function forkSqliteSessionEntryFromParentTarget( } let result: ForkSessionEntryFromParentTargetResult = { status: "failed" }; - const maintenancePlans: SqliteSessionEntryMaintenancePlan[] = []; + const maintenancePlans: SessionEntryMaintenancePlan[] = []; let previousIdentity = new Map(); let currentIdentity = new Map(); runOpenClawAgentWriteTransaction((writeDatabase) => { - const freshParent = resolveSqliteLifecyclePrimaryEntry(writeDatabase, parentTarget)?.entry; + const freshParent = resolveLifecyclePrimaryEntry(writeDatabase, parentTarget)?.entry; if (!freshParent?.sessionId) { result = { status: "missing-parent" }; return; } - const freshExisting = resolveSqliteLifecyclePrimaryEntry(writeDatabase, sessionTarget); + const freshExisting = resolveLifecyclePrimaryEntry(writeDatabase, sessionTarget); const freshBase = freshExisting?.entry ?? params.fallbackEntry; if (!freshBase) { result = { status: "missing-entry" }; @@ -232,15 +232,11 @@ export async function forkSqliteSessionEntryFromParentTarget( totalTokensVersion: undefined, }; const next = mergeSessionEntry(freshBase, forkIdentityPatch); - previousIdentity = readSqliteSessionIdentitySnapshot(writeDatabase, sessionTarget.storeKeys); + previousIdentity = readSessionIdentitySnapshot(writeDatabase, sessionTarget.storeKeys); writeSessionEntry(writeDatabase, sessionTarget.canonicalKey, next, { previousEntry: freshBase, }); - rehomeSqliteSessionWindows( - writeDatabase, - sessionTarget.canonicalKey, - sessionTarget.storeKeys, - ); + rehomeSessionWindows(writeDatabase, sessionTarget.canonicalKey, sessionTarget.storeKeys); deleteLegacySessionEntryRows( writeDatabase, sessionTarget.storeKeys, @@ -248,14 +244,14 @@ export async function forkSqliteSessionEntryFromParentTarget( { rehomeMembers: freshBase.sessionId === next.sessionId }, ); maintenancePlans.push( - applySqliteSessionEntryMaintenance(writeDatabase, { + applySessionEntryMaintenance(writeDatabase, { activeSessionKey: sessionTarget.canonicalKey, archiveDirectory: resolveSqliteTranscriptArchiveDirectory(resolved), skipMaintenance: true, storePath: params.storePath, }), ); - currentIdentity = readSqliteSessionIdentitySnapshot(writeDatabase, sessionTarget.storeKeys); + currentIdentity = readSessionIdentitySnapshot(writeDatabase, sessionTarget.storeKeys); result = { status: "forked", decision, @@ -265,7 +261,7 @@ export async function forkSqliteSessionEntryFromParentTarget( }; }, toDatabaseOptions(resolved)); emitCommittedSessionIdentityDiff(previousIdentity, currentIdentity); - await finalizeSqliteSessionEntryMaintenancePlansBestEffort(resolved, maintenancePlans); + await finalizeSessionEntryMaintenancePlansBestEffort(resolved, maintenancePlans); return result; }); } @@ -286,15 +282,15 @@ async function persistSqliteParentForkSkipPatch(params: { previous: params.entry, sessionKey: params.sessionTarget.canonicalKey, }); - const maintenancePlans: SqliteSessionEntryMaintenancePlan[] = []; + const maintenancePlans: SessionEntryMaintenancePlan[] = []; let previousIdentity = new Map(); let currentIdentity = new Map(); runOpenClawAgentWriteTransaction((database) => { - previousIdentity = readSqliteSessionIdentitySnapshot(database, params.sessionTarget.storeKeys); + previousIdentity = readSessionIdentitySnapshot(database, params.sessionTarget.storeKeys); writeSessionEntry(database, params.sessionTarget.canonicalKey, next, { previousEntry: params.entry, }); - rehomeSqliteSessionWindows( + rehomeSessionWindows( database, params.sessionTarget.canonicalKey, params.sessionTarget.storeKeys, @@ -306,23 +302,23 @@ async function persistSqliteParentForkSkipPatch(params: { { rehomeMembers: params.entry.sessionId === next.sessionId }, ); maintenancePlans.push( - applySqliteSessionEntryMaintenance(database, { + applySessionEntryMaintenance(database, { activeSessionKey: params.sessionTarget.canonicalKey, archiveDirectory: resolveSqliteTranscriptArchiveDirectory(params.resolved), skipMaintenance: true, storePath: params.params.storePath, }), ); - currentIdentity = readSqliteSessionIdentitySnapshot(database, params.sessionTarget.storeKeys); + currentIdentity = readSessionIdentitySnapshot(database, params.sessionTarget.storeKeys); }, toDatabaseOptions(params.resolved)); emitCommittedSessionIdentityDiff(previousIdentity, currentIdentity); - await finalizeSqliteSessionEntryMaintenancePlansBestEffort(params.resolved, maintenancePlans); + await finalizeSessionEntryMaintenancePlansBestEffort(params.resolved, maintenancePlans); return cloneSessionEntry(next); } /** Cleans scoped session lifecycle rows and associated SQLite transcript state. */ -export async function resolveSqliteSessionParentForkDecision(params: { +export async function resolveSessionParentForkDecision(params: { parentEntry: SessionEntry; storePath: string; }): Promise { @@ -332,15 +328,13 @@ export async function resolveSqliteSessionParentForkDecision(params: { typeof resolveFreshSessionTotalTokens(params.parentEntry) !== "number" && parentSessionId.length > 0; if (!needsTranscriptTokenEstimate) { - return resolveSqliteParentForkDecision(params.parentEntry); + return planParentForkDecision(params.parentEntry); } const resolved = resolveSqliteStoreScope(params.storePath); const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); - return resolveSqliteParentForkDecision( + return planParentForkDecision( params.parentEntry, - estimateSqliteTranscriptPromptTokens( - loadSqliteTranscriptEventsFromDatabase(database, parentSessionId), - ), + estimateTranscriptPromptTokens(loadTranscriptEventsFromDatabase(database, parentSessionId)), ); } @@ -357,8 +351,8 @@ function forkSqliteParentTranscriptInTransaction( if (!params.parentEntry.sessionId) { return { status: "missing-parent" }; } - const source = resolveSqliteParentForkSourceTranscript( - loadSqliteTranscriptEventsFromDatabase(database, params.parentEntry.sessionId), + const source = resolveParentForkSourceTranscript( + loadTranscriptEventsFromDatabase(database, params.parentEntry.sessionId), ); if (!source) { return { status: "failed" }; @@ -393,13 +387,13 @@ function writeSqliteForkedChildTranscriptInTransaction( targetScope: ResolvedTranscriptScope, params: { parentSessionFile: string; - source: SqliteParentForkSourceTranscript; + source: ParentForkSourceTranscript; }, ): void { appendTranscriptEventsInTransaction( database, targetScope, - buildSqliteForkedChildTranscriptEvents({ + buildForkedChildTranscriptEvents({ parentSessionFile: params.parentSessionFile, source: params.source, targetSessionId: targetScope.sessionId, diff --git a/src/config/sessions/session-accessor.sqlite-projection.ts b/src/config/sessions/session-accessor.sqlite-projection.ts index be19744b7dee..9f2dc216e8f1 100644 --- a/src/config/sessions/session-accessor.sqlite-projection.ts +++ b/src/config/sessions/session-accessor.sqlite-projection.ts @@ -12,8 +12,8 @@ import { } from "../../state/openclaw-agent-db.js"; import type { SessionArchivedTranscriptCleanupRule } from "./session-accessor.lifecycle-types.js"; import { - materializeSqliteSessionStateDeletePlans, - type MaterializedSqliteSessionStateDeletePlan, + materializeSessionStateDeletePlans, + type MaterializedSessionStateDeletePlan, } from "./session-accessor.sqlite-archive.js"; import { readExactSessionEntryRowForCanonicalRepair } from "./session-accessor.sqlite-canonical-repair.js"; import type { @@ -28,39 +28,39 @@ import type { } from "./session-accessor.sqlite-contract.js"; import { deleteLegacySessionEntryRows, - deleteSqliteSessionEntryRows, + deleteSessionEntryRows, readExactSessionEntryJsonForCanonicalRepair, readExactSessionEntryRow, - readSqliteSessionEntryCount, - readSqliteSessionEntryStore, - rehomeSqliteSessionWindows, + readSessionEntryCount, + readSessionEntryStore, + rehomeSessionWindows, sqliteSessionEntriesEqual, writeSessionEntry, } from "./session-accessor.sqlite-entry-store.js"; -import { emitArchivedSqliteTranscriptUpdates } from "./session-accessor.sqlite-events.js"; +import { emitArchivedTranscriptUpdates } from "./session-accessor.sqlite-events.js"; import { emitCommittedLifecycleIdentityMutations, emitCommittedSessionEntryRemovals, } from "./session-accessor.sqlite-identity.js"; import { - assertPlannedSqliteLifecycleArtifactEntriesUnchanged, - collectProjectedReferencedSqliteSessionIds, - deleteMaterializedSqliteSessionStatePlans, - deletePlannedSqliteLifecycleArtifactEntries, - planSqliteSessionStateAfterEntryRemoval, - projectSqliteSessionEntryLifecycleMutation, - shouldRemoveSqliteSessionEntry, + assertPlannedLifecycleArtifactEntriesUnchanged, + collectProjectedReferencedSessionIds, + deleteMaterializedSessionStatePlans, + deletePlannedLifecycleArtifactEntries, + planSessionStateAfterEntryRemoval, + projectSessionEntryLifecycleMutation, + shouldRemoveSessionEntry, } from "./session-accessor.sqlite-lifecycle-state.js"; import type { - SqliteProjectedLifecycleMutation, - SqliteSessionEntryMaintenancePlan, - SqliteSessionEntryRemovalPlan, + ProjectedLifecycleMutation, + SessionEntryMaintenancePlan, + SessionEntryRemovalPlan, } from "./session-accessor.sqlite-lifecycle-types.js"; import { - applySqliteSessionEntryMaintenance, - finalizeSqliteSessionEntryMaintenancePlansAfterWriterReleaseBestEffort, + applySessionEntryMaintenance, + finalizeSessionEntryMaintenancePlansAfterWriterReleaseBestEffort, } from "./session-accessor.sqlite-maintenance.js"; -import { applySqliteSessionEntryExactReplacements } from "./session-accessor.sqlite-replacement-projection.js"; +import { applySessionEntryExactReplacements } from "./session-accessor.sqlite-replacement-projection.js"; import { cloneSessionEntry, resolveSqliteScope, @@ -82,7 +82,7 @@ function loadSessionArchiveRuntime() { return sessionArchiveRuntimePromise; } -export async function applySqliteSessionEntryReplacements(params: { +export async function applySessionEntryReplacements(params: { activeSessionKey?: string; agentId?: string; requireWriteSuccess?: boolean; @@ -94,7 +94,7 @@ export async function applySqliteSessionEntryReplacements(params: { entries: SessionEntryReplacementSnapshot[], ) => Promise> | SessionEntryReplacementUpdate; }): Promise { - return await applySqliteSessionEntryExactReplacements(params); + return await applySessionEntryExactReplacements(params); } /** @@ -102,7 +102,7 @@ export async function applySqliteSessionEntryReplacements(params: { * This exists only for bounded compatibility adapters that must preserve a * legacy serialized callback without exposing mutable storage internals. */ -export async function applySqliteSessionStoreProjection(params: { +export async function applySessionStoreProjection(params: { activeSessionKey?: string; agentId?: string; skipMaintenance?: boolean; @@ -121,7 +121,7 @@ export async function applySqliteSessionStoreProjection(params: { }); const committed = await runExclusiveSqliteSessionWrite(resolved, async () => { const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); - const before = readSqliteSessionEntryStore(database); + const before = readSessionEntryStore(database); const projected = structuredClone(before); const operation = await params.update(projected); if (!operation.persist) { @@ -146,7 +146,7 @@ export async function applySqliteSessionStoreProjection(params: { return { maintenancePlans: [], result: operation.result }; } - const maintenancePlans: SqliteSessionEntryMaintenancePlan[] = []; + const maintenancePlans: SessionEntryMaintenancePlan[] = []; runOpenClawAgentWriteTransaction( (transactionDb) => { for (const sessionKey of changedKeys) { @@ -164,11 +164,11 @@ export async function applySqliteSessionStoreProjection(params: { previousEntry: before[sessionKey] ?? null, }); } else { - deleteSqliteSessionEntryRows(transactionDb, sessionKey); + deleteSessionEntryRows(transactionDb, sessionKey); } } maintenancePlans.push( - applySqliteSessionEntryMaintenance(transactionDb, { + applySessionEntryMaintenance(transactionDb, { activeSessionKey: params.activeSessionKey ?? "", archiveDirectory: resolveSqliteTranscriptArchiveDirectory(resolved), skipMaintenance: params.skipMaintenance, @@ -181,7 +181,7 @@ export async function applySqliteSessionStoreProjection(params: { ); return { maintenancePlans, result: operation.result }; }); - await finalizeSqliteSessionEntryMaintenancePlansAfterWriterReleaseBestEffort( + await finalizeSessionEntryMaintenancePlansAfterWriterReleaseBestEffort( resolved, committed.maintenancePlans, ); @@ -190,7 +190,7 @@ export async function applySqliteSessionStoreProjection(params: { function readProjectedRemovalEntry( database: OpenClawAgentDatabase, - projected: SqliteProjectedLifecycleMutation["removals"][number], + projected: ProjectedLifecycleMutation["removals"][number], allowCanonicalRepair = false, ): SessionEntry | undefined { const expectedRawEntryJson = projected.removal.expectedRawEntryJson; @@ -215,7 +215,7 @@ function readProjectedRemovalEntry( } /** Applies exact lifecycle removals/upserts using SQLite session rows. */ -export async function applySqliteSessionEntryLifecycleMutation(params: { +export async function applySessionEntryLifecycleMutation(params: { agentId?: string; storePath: string; removals?: Iterable; @@ -252,25 +252,23 @@ export async function applySqliteSessionEntryLifecycleMutation(params: { }; const projected = await runExclusiveSqliteSessionWrite(resolved, async () => { const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); - return await projectSqliteSessionEntryLifecycleMutation(database, { + return await projectSessionEntryLifecycleMutation(database, { ...(params.allowCanonicalRepair ? { allowCanonicalRepair: true } : {}), archiveDirectory: resolveSqliteTranscriptArchiveDirectory(resolved), removals, upserts, }); }); - let materializedRemovalPlans: MaterializedSqliteSessionStateDeletePlan[] = []; + let materializedRemovalPlans: MaterializedSessionStateDeletePlan[] = []; try { - materializedRemovalPlans = await materializeSqliteSessionStateDeletePlans( - projected.deletePlans, - ); + materializedRemovalPlans = await materializeSessionStateDeletePlans(projected.deletePlans); } catch (error) { captureArtifactCleanupError(error); } const committed = await runExclusiveSqliteSessionWrite(resolved, async () => { const removedSessionKeys: string[] = []; let archivedTranscripts: SessionLifecycleArchivedTranscript[] = []; - const maintenancePlans: SqliteSessionEntryMaintenancePlan[] = []; + const maintenancePlans: SessionEntryMaintenancePlan[] = []; runOpenClawAgentWriteTransaction((transactionDb) => { params.beforeCommitInTransaction?.(); const validatedRemovals = projected.removals.filter((removal) => { @@ -289,7 +287,7 @@ export async function applySqliteSessionEntryLifecycleMutation(params: { : `SQLite session entry changed before lifecycle removal for ${removal.sessionKey}`, ); } - const shouldRemove = shouldRemoveSqliteSessionEntry(entry, removal.removal); + const shouldRemove = shouldRemoveSessionEntry(entry, removal.removal); if ( !shouldRemove && projected.upsertedEntries.some((upsert) => upsert.sessionKey === removal.sessionKey) @@ -300,7 +298,7 @@ export async function applySqliteSessionEntryLifecycleMutation(params: { } return shouldRemove; }); - archivedTranscripts = deleteMaterializedSqliteSessionStatePlans( + archivedTranscripts = deleteMaterializedSessionStatePlans( transactionDb, materializedRemovalPlans, undefined, @@ -334,10 +332,7 @@ export async function applySqliteSessionEntryLifecycleMutation(params: { } throw new Error(`SQLite session entry changed before lifecycle upsert for ${sessionKey}`); } - if ( - sameKeyRemoval && - !shouldRemoveSqliteSessionEntry(currentEntry, sameKeyRemoval.removal) - ) { + if (sameKeyRemoval && !shouldRemoveSessionEntry(currentEntry, sameKeyRemoval.removal)) { throw new Error(`SQLite session entry has stale lifecycle state for ${sessionKey}`); } if (resetBoundaryPlan && expectedEntry?.sessionId) { @@ -363,7 +358,7 @@ export async function applySqliteSessionEntryLifecycleMutation(params: { ? [removal.sessionKey] : []; }); - rehomeSqliteSessionWindows(transactionDb, sessionKey, relatedRemovalKeys); + rehomeSessionWindows(transactionDb, sessionKey, relatedRemovalKeys); for (const legacyKey of relatedRemovalKeys) { const removedEntry = validatedRemovals.find( (removal) => removal.sessionKey === legacyKey, @@ -390,7 +385,7 @@ export async function applySqliteSessionEntryLifecycleMutation(params: { `SQLite session entry changed before lifecycle removal for ${removal.sessionKey}`, ); } - if (!shouldRemoveSqliteSessionEntry(entry, removal.removal)) { + if (!shouldRemoveSessionEntry(entry, removal.removal)) { continue; } const replacement = legacyReplacementTargets.get(removal.sessionKey); @@ -402,7 +397,7 @@ export async function applySqliteSessionEntryLifecycleMutation(params: { { rehomeMembers: replacement.rehomeMembers }, ); } else { - deleteSqliteSessionEntryRows(transactionDb, removal.sessionKey, { + deleteSessionEntryRows(transactionDb, removal.sessionKey, { deleteOwnedWindows: removal.removal.deleteOwnedWindows === true, deliveryCleanupKeys: removal.removal.deliveryCleanupKeys, }); @@ -410,7 +405,7 @@ export async function applySqliteSessionEntryLifecycleMutation(params: { removedSessionKeys.push(removal.sessionKey); } maintenancePlans.push( - applySqliteSessionEntryMaintenance(transactionDb, { + applySessionEntryMaintenance(transactionDb, { activeSessionKey: params.activeSessionKey ?? "", archiveDirectory: resolveSqliteTranscriptArchiveDirectory(resolved), forceMaintenance: params.maintenanceOverride !== undefined, @@ -426,15 +421,13 @@ export async function applySqliteSessionEntryLifecycleMutation(params: { return { archivedTranscripts, maintenancePlans, removedSessionKeys }; }); const maintenanceArchivedTranscripts = - await finalizeSqliteSessionEntryMaintenancePlansAfterWriterReleaseBestEffort( + await finalizeSessionEntryMaintenancePlansAfterWriterReleaseBestEffort( resolved, committed.maintenancePlans, ); const archivedTranscripts = [...committed.archivedTranscripts, ...maintenanceArchivedTranscripts]; - const afterCount = readSqliteSessionEntryCount( - openOpenClawAgentDatabase(toDatabaseOptions(resolved)), - ); - emitArchivedSqliteTranscriptUpdates(archivedTranscripts); + const afterCount = readSessionEntryCount(openOpenClawAgentDatabase(toDatabaseOptions(resolved))); + emitArchivedTranscriptUpdates(archivedTranscripts); const archivedTranscriptDirectories = uniqueStrings( archivedTranscripts.map((transcript) => path.dirname(transcript.archivedPath)), ).toSorted(); @@ -462,15 +455,15 @@ export async function applySqliteSessionEntryLifecycleMutation(params: { } /** Purges entries owned by a deleted agent from SQLite session rows. */ -export async function purgeSqliteDeletedAgentSessionEntries( +export async function purgeDeletedAgentSessionEntries( params: DeletedAgentSessionEntryPurgeParams, ): Promise { const resolved = resolveSqliteStoreScope(params.storePath, { agentId: params.storeAgentId }); const prepared = await runExclusiveSqliteSessionWrite(resolved, async () => { const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); - const store = readSqliteSessionEntryStore(database); + const store = readSessionEntryStore(database); const remainingStore = { ...store }; - const entryRemovals: SqliteSessionEntryRemovalPlan[] = []; + const entryRemovals: SessionEntryRemovalPlan[] = []; const removedEntriesToArchive: SessionEntry[] = []; for (const sessionKey of Object.keys(store)) { const ownerAgentId = resolveStoredSessionOwnerAgentId({ @@ -489,13 +482,13 @@ export async function purgeSqliteDeletedAgentSessionEntries( removedEntriesToArchive.push(entry); delete remainingStore[sessionKey]; } - const referencedSessionIds = collectProjectedReferencedSqliteSessionIds({ + const referencedSessionIds = collectProjectedReferencedSessionIds({ database, excludedSessionKeys: entryRemovals.map((removal) => removal.sessionKey), projectedStore: remainingStore, }); const deletePlans = removedEntriesToArchive.flatMap((entry) => - planSqliteSessionStateAfterEntryRemoval({ + planSessionStateAfterEntryRemoval({ archiveDirectory: resolveSqliteTranscriptArchiveDirectory(resolved), database, entry, @@ -505,13 +498,13 @@ export async function purgeSqliteDeletedAgentSessionEntries( ); return { deletePlans, entryRemovals }; }); - const materializedPlans = await materializeSqliteSessionStateDeletePlans(prepared.deletePlans); + const materializedPlans = await materializeSessionStateDeletePlans(prepared.deletePlans); const committed = await runExclusiveSqliteSessionWrite(resolved, async () => { const removedSessionKeys = prepared.entryRemovals.map((removal) => removal.sessionKey); let archivedTranscripts: SessionLifecycleArchivedTranscript[] = []; - const maintenancePlans: SqliteSessionEntryMaintenancePlan[] = []; + const maintenancePlans: SessionEntryMaintenancePlan[] = []; runOpenClawAgentWriteTransaction((transactionDb) => { - const currentOwnedSessionKeys = Object.keys(readSqliteSessionEntryStore(transactionDb)) + const currentOwnedSessionKeys = Object.keys(readSessionEntryStore(transactionDb)) .filter( (sessionKey) => resolveStoredSessionOwnerAgentId({ @@ -527,16 +520,16 @@ export async function purgeSqliteDeletedAgentSessionEntries( if (JSON.stringify(currentOwnedSessionKeys) !== JSON.stringify(plannedSessionKeys)) { throw new Error("SQLite deleted-agent session entries changed before purge"); } - assertPlannedSqliteLifecycleArtifactEntriesUnchanged(transactionDb, prepared.entryRemovals); - archivedTranscripts = deleteMaterializedSqliteSessionStatePlans( + assertPlannedLifecycleArtifactEntriesUnchanged(transactionDb, prepared.entryRemovals); + archivedTranscripts = deleteMaterializedSessionStatePlans( transactionDb, materializedPlans, undefined, new Set(prepared.entryRemovals.map((removal) => removal.sessionKey)), ); - deletePlannedSqliteLifecycleArtifactEntries(transactionDb, prepared.entryRemovals); + deletePlannedLifecycleArtifactEntries(transactionDb, prepared.entryRemovals); maintenancePlans.push( - applySqliteSessionEntryMaintenance(transactionDb, { + applySessionEntryMaintenance(transactionDb, { activeSessionKey: "", archiveDirectory: resolveSqliteTranscriptArchiveDirectory(resolved), storePath: params.storePath, @@ -548,15 +541,13 @@ export async function purgeSqliteDeletedAgentSessionEntries( }); const archivedTranscripts = [ ...committed.archivedTranscripts, - ...(await finalizeSqliteSessionEntryMaintenancePlansAfterWriterReleaseBestEffort( + ...(await finalizeSessionEntryMaintenancePlansAfterWriterReleaseBestEffort( resolved, committed.maintenancePlans, )), ]; - const afterCount = readSqliteSessionEntryCount( - openOpenClawAgentDatabase(toDatabaseOptions(resolved)), - ); - emitArchivedSqliteTranscriptUpdates(archivedTranscripts); + const afterCount = readSessionEntryCount(openOpenClawAgentDatabase(toDatabaseOptions(resolved))); + emitArchivedTranscriptUpdates(archivedTranscripts); return { removedEntries: committed.removedSessionKeys.length, removedSessionKeys: committed.removedSessionKeys, diff --git a/src/config/sessions/session-accessor.sqlite-read.ts b/src/config/sessions/session-accessor.sqlite-read.ts index e7e0513d15a8..d8e2f868055f 100644 --- a/src/config/sessions/session-accessor.sqlite-read.ts +++ b/src/config/sessions/session-accessor.sqlite-read.ts @@ -37,27 +37,21 @@ export type SqliteTranscriptStorageRow = SqliteTranscriptSnapshotRow & { }; /** Loads raw transcript events from the additive SQLite transcript store. */ -export async function loadSqliteTranscriptEvents( +export async function loadTranscriptEvents( scope: SessionTranscriptReadScope, ): Promise { - return loadSqliteTranscriptEventsSync(scope); + return loadTranscriptEventsSync(scope); } /** Loads raw transcript events synchronously from the additive SQLite transcript store. */ -export function loadSqliteTranscriptEventsSync( - scope: SessionTranscriptReadScope, -): TranscriptEvent[] { +export function loadTranscriptEventsSync(scope: SessionTranscriptReadScope): TranscriptEvent[] { const resolved = resolveSqliteTranscriptReadScope(scope); const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); return runSqliteDeferredTransactionSync( database.db, () => { const fence = resolveSqliteSessionTranscriptReadFence({ database, ...resolved }); - return loadSqliteTranscriptEventsFromDatabase( - database, - resolved.sessionId, - fence?.beforeRawSeq, - ); + return loadTranscriptEventsFromDatabase(database, resolved.sessionId, fence?.beforeRawSeq); }, { databaseLabel: database.path, @@ -67,7 +61,7 @@ export function loadSqliteTranscriptEventsSync( } /** Loads only the first transcript row for header metadata hot paths. */ -export function loadSqliteTranscriptHeaderSync(scope: SessionTranscriptReadScope): unknown { +export function loadTranscriptHeaderSync(scope: SessionTranscriptReadScope): unknown { const resolved = resolveSqliteTranscriptReadScope(scope); const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); const db = getSessionKysely(database.db); @@ -84,7 +78,7 @@ export function loadSqliteTranscriptHeaderSync(scope: SessionTranscriptReadScope } /** Loads a bounded newest tail in storage order for hot-path accounting. */ -export function loadSqliteTranscriptTailEventsSync( +export function loadTranscriptTailEventsSync( scope: SessionTranscriptReadScope, maxEvents: number, ): TranscriptEvent[] { @@ -109,7 +103,7 @@ export function loadSqliteTranscriptTailEventsSync( } /** Loads additive transcript rows after one durable sequence checkpoint. */ -export function loadSqliteTranscriptEventRowsAfterSeqSync( +export function loadTranscriptEventRowsAfterSeqSync( scope: SessionTranscriptReadScope, afterSeq: number, throughSeq?: number, @@ -132,7 +126,7 @@ export function loadSqliteTranscriptEventRowsAfterSeqSync( } /** Reads one checkpoint row so incremental consumers can reject transcript rewrites. */ -export function readSqliteTranscriptEventAtSeqSync( +export function readTranscriptEventAtSeqSync( scope: SessionTranscriptReadScope, seq: number, ): SessionTranscriptEventRow | undefined { @@ -155,7 +149,7 @@ export function readSqliteTranscriptEventAtSeqSync( : undefined; } -export function loadSqliteTranscriptEventsFromDatabase( +export function loadTranscriptEventsFromDatabase( database: OpenClawAgentDatabase, sessionId: string, beforeEventSeq?: number, @@ -173,11 +167,11 @@ export function loadSqliteTranscriptEventsFromDatabase( return rows.map((row) => JSON.parse(row.event_json) as TranscriptEvent); } -export function readSqliteTranscriptSnapshot( +export function readTranscriptSnapshot( database: OpenClawAgentDatabase, sessionId: string, ): { events: TranscriptEvent[]; rows: SqliteTranscriptSnapshotRow[] } { - const rows = readSqliteTranscriptEventRows(database, sessionId); + const rows = readTranscriptEventRows(database, sessionId); return { events: rows.map((row) => JSON.parse(row.eventJson) as TranscriptEvent), rows, @@ -185,7 +179,7 @@ export function readSqliteTranscriptSnapshot( } /** Reads transcript rows without decoding payloads for snapshot comparison. */ -export function readSqliteTranscriptEventRows( +export function readTranscriptEventRows( database: OpenClawAgentDatabase, sessionId: string, ): SqliteTranscriptSnapshotRow[] { @@ -205,7 +199,7 @@ export function readSqliteTranscriptEventRows( } /** Reads exact transcript storage rows for guarded doctor rewrites. */ -export function readSqliteTranscriptStorageRows( +export function readTranscriptStorageRows( database: OpenClawAgentDatabase, sessionId: string, ): SqliteTranscriptStorageRow[] { @@ -231,9 +225,7 @@ function sqliteTranscriptJsonlByteSize() { } /** Reads transcript freshness and byte size without materializing event rows. */ -export function readSqliteTranscriptStatsSync( - scope: SessionTranscriptReadScope, -): SessionTranscriptStats { +export function readTranscriptStatsSync(scope: SessionTranscriptReadScope): SessionTranscriptStats { const resolved = resolveSqliteTranscriptReadScope(scope); const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); const db = getSessionKysely(database.db); @@ -281,7 +273,7 @@ export function readTranscriptEventJsonSetInTransaction( } /** Reads the latest visible assistant text from SQLite transcript rows in reverse order. */ -export function loadLatestSqliteAssistantText( +export function loadLatestAssistantText( scope: SessionTranscriptReadScope, options: { includeTranscriptOnlyOpenClawAssistant?: boolean } = {}, ): LatestTranscriptAssistantText | undefined { @@ -374,16 +366,16 @@ function parseLatestAssistantMessageEvent( } /** Finds the newest transcript record accepted by the matcher without parsing older rows. */ -export function findSqliteTranscriptEvent( +export async function findTranscriptEvent( scope: SessionTranscriptReadScope, match: (event: TranscriptEvent) => boolean, -): { event: TranscriptEvent } | undefined { +): Promise<{ event: TranscriptEvent } | undefined> { const resolved = resolveSqliteTranscriptReadScope(scope); const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); - return findSqliteTranscriptEventInDatabase(database, resolved.sessionId, match); + return findTranscriptEventInDatabase(database, resolved.sessionId, match); } -export function findSqliteTranscriptEventInDatabase( +export function findTranscriptEventInDatabase( database: OpenClawAgentDatabase, sessionId: string, match: (event: TranscriptEvent) => boolean, diff --git a/src/config/sessions/session-accessor.sqlite-references.ts b/src/config/sessions/session-accessor.sqlite-references.ts index 4bf4404be395..1d67c2675679 100644 --- a/src/config/sessions/session-accessor.sqlite-references.ts +++ b/src/config/sessions/session-accessor.sqlite-references.ts @@ -2,7 +2,7 @@ import { uniqueStrings } from "@openclaw/normalization-core/string-normalization import type { SessionEntry } from "./types.js"; /** Every transcript generation retained by one canonical logical-session record. */ -export function collectSqliteSessionStateIdsForEntry(entry: SessionEntry): string[] { +export function collectSessionStateIdsForEntry(entry: SessionEntry): string[] { const sessionIds: string[] = []; const add = (sessionId: string | undefined) => { const normalized = sessionId?.trim(); diff --git a/src/config/sessions/session-accessor.sqlite-replacement-projection.ts b/src/config/sessions/session-accessor.sqlite-replacement-projection.ts index 6188590406d5..eaa27f0a0a56 100644 --- a/src/config/sessions/session-accessor.sqlite-replacement-projection.ts +++ b/src/config/sessions/session-accessor.sqlite-replacement-projection.ts @@ -12,14 +12,14 @@ import type { import { deleteLegacySessionEntryRows, readExactSessionEntryRow, - readSqliteSessionEntryStore, + readSessionEntryStore, writeSessionEntry, } from "./session-accessor.sqlite-entry-store.js"; import { emitCommittedSessionIdentityDiff } from "./session-accessor.sqlite-identity.js"; -import type { SqliteSessionEntryMaintenancePlan } from "./session-accessor.sqlite-lifecycle-types.js"; +import type { SessionEntryMaintenancePlan } from "./session-accessor.sqlite-lifecycle-types.js"; import { - applySqliteSessionEntryMaintenance, - finalizeSqliteSessionEntryMaintenancePlansAfterWriterReleaseBestEffort, + applySessionEntryMaintenance, + finalizeSessionEntryMaintenancePlansAfterWriterReleaseBestEffort, } from "./session-accessor.sqlite-maintenance.js"; import { cloneSessionEntry, @@ -28,7 +28,7 @@ import { runExclusiveSqliteSessionWrite, toDatabaseOptions, } from "./session-accessor.sqlite-scope.js"; -import { readSqliteSessionEntriesByStatus } from "./session-accessor.sqlite-status.js"; +import { readSessionEntriesByStatus } from "./session-accessor.sqlite-status.js"; import type { SessionEntryReplacement } from "./session-accessor.types.js"; import type { SessionEntry } from "./types.js"; @@ -72,13 +72,13 @@ async function applySqliteSessionEntryReplacementProjection( const selectedKeys = params.sessionKeys ? new Set(params.sessionKeys) : undefined; const selectedStatuses = params.statuses ? new Set(params.statuses) : undefined; const entries = selectedStatuses - ? readSqliteSessionEntriesByStatus(database, [...selectedStatuses], params.sessionKeys) + ? readSessionEntriesByStatus(database, [...selectedStatuses], params.sessionKeys) : selectedKeys ? [...selectedKeys].flatMap((sessionKey) => { const entry = readExactSessionEntryRow(database, sessionKey)?.entry; return entry ? [{ entry: cloneSessionEntry(entry), sessionKey }] : []; }) - : Object.entries(readSqliteSessionEntryStore(database)).map(([sessionKey, entry]) => ({ + : Object.entries(readSessionEntryStore(database)).map(([sessionKey, entry]) => ({ entry: cloneSessionEntry(entry), sessionKey, })); @@ -145,7 +145,7 @@ async function applySqliteSessionEntryReplacementProjection( ]), ); - const maintenancePlans: SqliteSessionEntryMaintenancePlan[] = []; + const maintenancePlans: SessionEntryMaintenancePlan[] = []; const previous = new Map(); const current = new Map(); runOpenClawAgentWriteTransaction( @@ -189,7 +189,7 @@ async function applySqliteSessionEntryReplacementProjection( current.set(replacement.sessionKey, replacement.entry); } maintenancePlans.push( - applySqliteSessionEntryMaintenance(transactionDb, { + applySessionEntryMaintenance(transactionDb, { activeSessionKey: params.activeSessionKey ?? "", archiveDirectory: resolveSqliteTranscriptArchiveDirectory(resolved), skipMaintenance: params.skipMaintenance ?? true, @@ -203,14 +203,14 @@ async function applySqliteSessionEntryReplacementProjection( emitCommittedSessionIdentityDiff(previous, current); return { maintenancePlans, result: operation.result }; }); - await finalizeSqliteSessionEntryMaintenancePlansAfterWriterReleaseBestEffort( + await finalizeSessionEntryMaintenancePlansAfterWriterReleaseBestEffort( resolved, committed.maintenancePlans, ); return committed.result; } -export async function applySqliteSessionEntryExactReplacements(params: { +export async function applySessionEntryExactReplacements(params: { activeSessionKey?: string; agentId?: string; requireWriteSuccess?: boolean; @@ -231,7 +231,7 @@ export async function applySqliteSessionEntryExactReplacements(params: { } /** Internal alias-aware owner; public SDK replacements remain exact-key only. */ -export async function applySqliteSessionEntryCanonicalReplacements( +export async function applySessionEntryCanonicalReplacements( params: ReplacementProjectionParams, ): Promise { return await applySqliteSessionEntryReplacementProjection( diff --git a/src/config/sessions/session-accessor.sqlite-session-row.ts b/src/config/sessions/session-accessor.sqlite-session-row.ts index a5de425d5582..617507fdce25 100644 --- a/src/config/sessions/session-accessor.sqlite-session-row.ts +++ b/src/config/sessions/session-accessor.sqlite-session-row.ts @@ -2,16 +2,13 @@ import { deliveryContextFromSession, sessionDeliveryChannel, } from "../../utils/delivery-context.shared.js"; -import { - normalizeSqliteChatType, - normalizeSqliteText, -} from "./session-accessor.sqlite-normalize.js"; +import { normalizeSessionRowChatType, normalizeText } from "./session-accessor.sqlite-normalize.js"; import { bindSessionEntryProvenance } from "./session-accessor.sqlite-provenance.js"; -import { normalizeSqliteStatus } from "./session-accessor.sqlite-status.js"; +import { normalizeStatus } from "./session-accessor.sqlite-status.js"; import { projectCanonicalSessionEntryShape } from "./store-entry-shape.js"; import type { SessionEntry } from "./types.js"; -export function normalizeSqliteSessionEntryTimestamp(entry: SessionEntry): SessionEntry { +export function normalizeSessionEntryTimestamp(entry: SessionEntry): SessionEntry { const raw = entry as unknown as Record; const hasLegacyDeliveryFields = [ "route", @@ -38,7 +35,7 @@ export function normalizeSqliteSessionEntryTimestamp(entry: SessionEntry): Sessi return delivery ? { ...entry, delivery, updatedAt } : { ...entry, updatedAt }; } -export function bindSqliteSessionRoot(params: { +export function bindSessionRoot(params: { entry: SessionEntry; sessionKey: string; updatedAt: number; @@ -53,35 +50,35 @@ export function bindSqliteSessionRoot(params: { created_at: resolveSqliteSessionCreatedAt(params.entry, updatedAt), updated_at: updatedAt, ...bindSessionEntryProvenance(params.entry), - ...bindSqliteSessionWindowEntryProjection(params), + ...bindSessionWindowEntryProjection(params), primary_conversation_id: null, }; } -export function bindSqliteSessionWindowEntryProjection(params: { +export function bindSessionWindowEntryProjection(params: { entry: SessionEntry; sessionKey: string; }) { return { - previous_session_id: normalizeSqliteText(params.entry.previousSessionId), + previous_session_id: normalizeText(params.entry.previousSessionId), session_scope: resolveSqliteSessionScope(params.entry, params.sessionKey), started_at: finiteSqliteNumber(params.entry.startedAt), ended_at: finiteSqliteNumber(params.entry.endedAt), - status: normalizeSqliteStatus(params.entry.status), - chat_type: normalizeSqliteChatType(params.entry.chatType), + status: normalizeStatus(params.entry.status), + chat_type: normalizeSessionRowChatType(params.entry.chatType), channel: resolveSqliteSessionChannel(params.entry), account_id: resolveSqliteSessionAccountId(params.entry), - model_provider: normalizeSqliteText(params.entry.modelProvider), - model: normalizeSqliteText(params.entry.model), - agent_harness_id: normalizeSqliteText(params.entry.agentHarnessId), - parent_session_key: normalizeSqliteText(params.entry.parentSessionKey), - spawned_by: normalizeSqliteText(params.entry.spawnedBy), + model_provider: normalizeText(params.entry.modelProvider), + model: normalizeText(params.entry.model), + agent_harness_id: normalizeText(params.entry.agentHarnessId), + parent_session_key: normalizeText(params.entry.parentSessionKey), + spawned_by: normalizeText(params.entry.spawnedBy), display_name: resolveSqliteSessionDisplayName(params.entry), }; } /** Project the canonical entry blob into the logical-node query columns. */ -export function bindSqliteSessionNode(params: { +export function bindSessionNode(params: { entry: SessionEntry; sessionKey: string; updatedAt: number; @@ -90,7 +87,7 @@ export function bindSqliteSessionNode(params: { params.entry as unknown as Record, ); const actor = params.entry.createdActor; - const legacyActorId = normalizeSqliteText( + const legacyActorId = normalizeText( (params.entry as SessionEntry & { createdBy?: { id?: unknown } }).createdBy?.id, ); return { @@ -99,22 +96,21 @@ export function bindSqliteSessionNode(params: { entry_json: JSON.stringify(canonicalEntry), entry_valid: 1, updated_at: params.updatedAt, - status: normalizeSqliteStatus(params.entry.status), + status: normalizeStatus(params.entry.status), created_at: finiteSqliteNumber(params.entry.createdAt), created_via: normalizeSqliteCreatedVia(params.entry.createdVia), created_actor_type: normalizeSqliteCreatedActorType(actor?.type) ?? (legacyActorId ? "human" : null), - created_actor_id: normalizeSqliteText(actor?.id) ?? legacyActorId, + created_actor_id: normalizeText(actor?.id) ?? legacyActorId, parent_session_key: - normalizeSqliteText(params.entry.parentSessionKey) ?? - normalizeSqliteText(params.entry.spawnedBy), - spawned_by: normalizeSqliteText(params.entry.spawnedBy), - fork_source_session_key: normalizeSqliteText(params.entry.forkSource?.sessionKey), - fork_source_session_id: normalizeSqliteText(params.entry.forkSource?.sessionId), - fork_source_entry_id: normalizeSqliteText(params.entry.forkSource?.entryId), - label: normalizeSqliteText(params.entry.label), - display_name: normalizeSqliteText(params.entry.displayName), - category: normalizeSqliteText(params.entry.category), + normalizeText(params.entry.parentSessionKey) ?? normalizeText(params.entry.spawnedBy), + spawned_by: normalizeText(params.entry.spawnedBy), + fork_source_session_key: normalizeText(params.entry.forkSource?.sessionKey), + fork_source_session_id: normalizeText(params.entry.forkSource?.sessionId), + fork_source_entry_id: normalizeText(params.entry.forkSource?.entryId), + label: normalizeText(params.entry.label), + display_name: normalizeText(params.entry.displayName), + category: normalizeText(params.entry.category), // The retired custom-icon column remains nullable until a future schema-version migration. icon: null, pinned_at: finiteSqliteNumber(params.entry.pinnedAt), @@ -146,7 +142,7 @@ function resolveSqliteSessionScope( entry: Pick, sessionKey: string, ): "conversation" | "shared-main" | "group" | "channel" { - const chatType = normalizeSqliteChatType(entry.chatType); + const chatType = normalizeSessionRowChatType(entry.chatType); const normalizedKey = sessionKey.trim().toLowerCase(); if (chatType === "direct" && (normalizedKey === "main" || normalizedKey.endsWith(":main"))) { return "shared-main"; @@ -171,18 +167,18 @@ function finiteSqliteNumber(value: unknown): number | null { } function resolveSqliteSessionChannel(entry: SessionEntry): string | null { - return normalizeSqliteText(sessionDeliveryChannel(entry)); + return normalizeText(sessionDeliveryChannel(entry)); } function resolveSqliteSessionAccountId(entry: SessionEntry): string | null { - return normalizeSqliteText(deliveryContextFromSession(entry)?.accountId); + return normalizeText(deliveryContextFromSession(entry)?.accountId); } function resolveSqliteSessionDisplayName(entry: SessionEntry): string | null { return ( - normalizeSqliteText(entry.displayName) ?? - normalizeSqliteText(entry.label) ?? - normalizeSqliteText(entry.subject) ?? - normalizeSqliteText(entry.groupId) + normalizeText(entry.displayName) ?? + normalizeText(entry.label) ?? + normalizeText(entry.subject) ?? + normalizeText(entry.groupId) ); } diff --git a/src/config/sessions/session-accessor.sqlite-status.ts b/src/config/sessions/session-accessor.sqlite-status.ts index 8845bd2da393..99463bb6de23 100644 --- a/src/config/sessions/session-accessor.sqlite-status.ts +++ b/src/config/sessions/session-accessor.sqlite-status.ts @@ -6,7 +6,7 @@ import type { SessionEntrySummary, } from "./session-accessor.sqlite-contract.js"; import { - hasValidSqliteSessionEntryIdentity, + hasValidSessionEntryIdentity, parseSqliteSessionEntryRecord, } from "./session-entry-json.js"; import { projectCanonicalSessionEntryShape } from "./store-entry-shape.js"; @@ -14,7 +14,7 @@ import type { SessionEntry } from "./types.js"; type SessionStatusDatabase = Pick; -export function normalizeSqliteStatus(value: unknown): SessionEntryStatus | null { +export function normalizeStatus(value: unknown): SessionEntryStatus | null { return value === "running" || value === "done" || value === "failed" || @@ -24,9 +24,9 @@ export function normalizeSqliteStatus(value: unknown): SessionEntryStatus | null : null; } -export { hasValidSqliteSessionEntryIdentity }; +export { hasValidSessionEntryIdentity }; -export function parseSqliteSessionEntryJson(row: { +export function parseSessionEntryJson(row: { current_session_id?: string; entry_json: string; updated_at?: number; @@ -35,7 +35,7 @@ export function parseSqliteSessionEntryJson(row: { return record ? projectCanonicalSessionEntryShape(record) : null; } -export function readSqliteSessionEntriesByStatus( +export function readSessionEntriesByStatus( database: OpenClawAgentDatabase, statuses: readonly SessionEntryStatus[], sessionKeys?: readonly string[], @@ -55,7 +55,7 @@ export function readSqliteSessionEntriesByStatus( } return executeSqliteQuerySync(database.db, query) .rows.flatMap((row) => { - const entry = parseSqliteSessionEntryJson(row); + const entry = parseSessionEntryJson(row); return entry ? [{ entry, sessionKey: row.session_key }] : []; }) .toSorted((a, b) => a.sessionKey.localeCompare(b.sessionKey)); diff --git a/src/config/sessions/session-accessor.sqlite-transcript-message-append.ts b/src/config/sessions/session-accessor.sqlite-transcript-message-append.ts index 22976100a711..169c5926604a 100644 --- a/src/config/sessions/session-accessor.sqlite-transcript-message-append.ts +++ b/src/config/sessions/session-accessor.sqlite-transcript-message-append.ts @@ -39,7 +39,7 @@ function messagesMatchForIdempotentReplay(stored: unknown, candidate: unknown): return isDeepStrictEqual(serializedShape(stored), serializedShape(candidate)); } -export function appendSqliteTranscriptMessageInTransaction( +export function appendTranscriptMessageInTransaction( database: OpenClawAgentDatabase, resolved: ResolvedTranscriptScope, options: TranscriptMessageAppendOptions & { messageAlreadyRedacted?: boolean }, diff --git a/src/config/sessions/session-accessor.sqlite-transcript-mirror.ts b/src/config/sessions/session-accessor.sqlite-transcript-mirror.ts index a8c2960bc60a..50c2f60e2ef9 100644 --- a/src/config/sessions/session-accessor.sqlite-transcript-mirror.ts +++ b/src/config/sessions/session-accessor.sqlite-transcript-mirror.ts @@ -6,7 +6,7 @@ import { runSqliteDeferredTransactionSync } from "../../infra/sqlite-transaction import type { OpenClawAgentDatabase } from "../../state/openclaw-agent-db.js"; import type { TranscriptEvent } from "./session-accessor.sqlite-contract.js"; import { - loadSqliteTranscriptEventsFromDatabase, + loadTranscriptEventsFromDatabase, readTranscriptEventMessage, } from "./session-accessor.sqlite-read.js"; import { getSessionKysely, type ResolvedTranscriptScope } from "./session-accessor.sqlite-scope.js"; @@ -52,7 +52,7 @@ function loadTranscriptEventsForMirrorFallback( return undefined; } // Raw rows stay authoritative if projection maintenance has not caught up. - return loadSqliteTranscriptEventsFromDatabase(database, sessionId); + return loadTranscriptEventsFromDatabase(database, sessionId); } /** Reads the bounded identity facts needed by transcript mirrors. */ diff --git a/src/config/sessions/session-accessor.sqlite-transcript-sequences.ts b/src/config/sessions/session-accessor.sqlite-transcript-sequences.ts index 8033c1803d49..7d02d32db1c4 100644 --- a/src/config/sessions/session-accessor.sqlite-transcript-sequences.ts +++ b/src/config/sessions/session-accessor.sqlite-transcript-sequences.ts @@ -19,14 +19,14 @@ import { readTranscriptIdentityByEventId } from "./session-accessor.sqlite-trans const committedTranscriptMessageSequences = new WeakMap(); /** Reads the visible-message sequence captured from the final active branch. */ -export function readCommittedSqliteTranscriptMessageSequence( +export function readCommittedTranscriptMessageSequence( message: TranscriptMessageAppendResult, ): number | undefined { return committedTranscriptMessageSequences.get(message); } /** Captures atomic turn cursors from the final projection before SQLite commits. */ -export function rememberCommittedSqliteTranscriptMessageSequencesInTransaction( +export function rememberCommittedTranscriptMessageSequencesInTransaction( database: OpenClawAgentDatabase, sessionId: string, messages: readonly TranscriptMessageAppendResult[], @@ -76,7 +76,7 @@ export function rememberCommittedSqliteTranscriptMessageSequencesInTransaction( } /** Resolves final cursors while an ordinary turn still owns its writer transaction. */ -export function rememberCommittedSqliteTranscriptMessageSequences( +export function rememberCommittedTranscriptMessageSequences( scope: SessionTranscriptTurnWriteContext, messages: readonly TranscriptMessageAppendResult[], ): void { @@ -89,7 +89,7 @@ export function rememberCommittedSqliteTranscriptMessageSequences( sessionKey: scope.sessionKey, ...(scope.storePath ? { storePath: scope.storePath } : {}), }); - rememberCommittedSqliteTranscriptMessageSequencesInTransaction( + rememberCommittedTranscriptMessageSequencesInTransaction( openOpenClawAgentDatabase(toDatabaseOptions(resolved)), resolved.sessionId, messages, diff --git a/src/config/sessions/session-accessor.sqlite-transcript-state.ts b/src/config/sessions/session-accessor.sqlite-transcript-state.ts index b9e7aea90e62..10e2e4e67ad8 100644 --- a/src/config/sessions/session-accessor.sqlite-transcript-state.ts +++ b/src/config/sessions/session-accessor.sqlite-transcript-state.ts @@ -5,10 +5,10 @@ import { executeSqliteQueryTakeFirstSync, } from "../../infra/kysely-sync.js"; import type { OpenClawAgentDatabase } from "../../state/openclaw-agent-db.js"; -import { publishSqliteSessionEntryCacheInvalidation } from "./session-accessor.sqlite-entry-cache.js"; +import { publishSessionEntryCacheInvalidation } from "./session-accessor.sqlite-entry-cache.js"; import { coerceSqliteNumber } from "./session-accessor.sqlite-normalize.js"; import { getSessionKysely, type ResolvedTranscriptScope } from "./session-accessor.sqlite-scope.js"; -import { parseSqliteSessionEntryJson } from "./session-accessor.sqlite-status.js"; +import { parseSessionEntryJson } from "./session-accessor.sqlite-status.js"; import { assertCanonicalSqliteSessionKeysCurrent, assertCanonicalSessionKeyWriteMatchesDatabase, @@ -98,7 +98,7 @@ export function ensureTranscriptSessionRoot( .where("session_key", "in", lookupKeys), ).rows; for (const candidate of candidates) { - const entry = parseSqliteSessionEntryJson(candidate); + const entry = parseSessionEntryJson(candidate); if (!entry) { const retainedWindow = candidate.entry_json === "{}" @@ -169,7 +169,7 @@ export function ensureTranscriptSessionRoot( .set({ entry_valid: -1 }) .where("session_key", "=", scope.sessionKey), ); - publishSqliteSessionEntryCacheInvalidation(database); + publishSessionEntryCacheInvalidation(database); } executeSqliteQuerySync( database.db, @@ -267,7 +267,7 @@ export function touchTranscriptMutationInTransaction( } } -export function deleteSqliteTranscriptEventsInTransaction( +export function deleteTranscriptEventsInTransaction( database: OpenClawAgentDatabase, sessionId: string, ): boolean { diff --git a/src/config/sessions/session-accessor.sqlite-transcript-store.ts b/src/config/sessions/session-accessor.sqlite-transcript-store.ts index 5d5bd0dc6c5d..aa1dadf3b5dc 100644 --- a/src/config/sessions/session-accessor.sqlite-transcript-store.ts +++ b/src/config/sessions/session-accessor.sqlite-transcript-store.ts @@ -12,15 +12,15 @@ import type { TranscriptMessageAppendOptions, } from "./session-accessor.sqlite-contract.js"; import { - findSqliteTranscriptEventInDatabase, - loadSqliteTranscriptEventsFromDatabase, + findTranscriptEventInDatabase, + loadTranscriptEventsFromDatabase, readTranscriptEventId, readTranscriptEventMessage, } from "./session-accessor.sqlite-read.js"; import { getSessionKysely, type ResolvedTranscriptScope } from "./session-accessor.sqlite-scope.js"; import { advanceTranscriptMutationAtInTransaction, - deleteSqliteTranscriptEventsInTransaction, + deleteTranscriptEventsInTransaction, ensureTranscriptGenerationInTransaction, ensureTranscriptSessionRoot, readTranscriptGenerationInTransaction, @@ -288,7 +288,7 @@ export function readActiveTranscriptAppendParentId( const treeEntry = parseSessionTranscriptTreeEntry(event); if (!treeEntry) { return resolveVisibleTranscriptAppendParentId( - loadSqliteTranscriptEventsFromDatabase(database, sessionId), + loadTranscriptEventsFromDatabase(database, sessionId), ); } if (latest.event_type !== "leaf") { @@ -305,7 +305,7 @@ export function readActiveTranscriptAppendParentId( // Fall through to the tolerant full-tree resolver. } return resolveVisibleTranscriptAppendParentId( - loadSqliteTranscriptEventsFromDatabase(database, sessionId), + loadTranscriptEventsFromDatabase(database, sessionId), ); } @@ -334,7 +334,7 @@ export function replaceSqliteTranscriptEventsInTransaction( ? readTranscriptMutationStateInTransaction(database, resolved.sessionId).updatedAt : undefined; const previousGeneration = readTranscriptGenerationInTransaction(database, resolved.sessionId); - const deleted = deleteSqliteTranscriptEventsInTransaction(database, resolved.sessionId); + const deleted = deleteTranscriptEventsInTransaction(database, resolved.sessionId); if (events.length === 0) { if (deleted || previousGeneration) { rotateTranscriptGenerationInTransaction(database, resolved.sessionId); @@ -532,7 +532,7 @@ export function readTranscriptMessageByScopedIdempotencyKey( if (lookup !== "scan-assistant") { return readTranscriptMessageByIdempotencyKey(database, scope, idempotencyKey); } - const found = findSqliteTranscriptEventInDatabase(database, scope.sessionId, (event) => { + const found = findTranscriptEventInDatabase(database, scope.sessionId, (event) => { const message = readTranscriptEventMessage(event); return message?.role === "assistant" && message.idempotencyKey === idempotencyKey; }); diff --git a/src/config/sessions/session-accessor.sqlite-transcript-write.ts b/src/config/sessions/session-accessor.sqlite-transcript-write.ts index b87f71cf2dba..37fc8e4818ac 100644 --- a/src/config/sessions/session-accessor.sqlite-transcript-write.ts +++ b/src/config/sessions/session-accessor.sqlite-transcript-write.ts @@ -5,7 +5,7 @@ import { runOpenClawAgentWriteTransaction, type OpenClawAgentDatabase, } from "../../state/openclaw-agent-db.js"; -import { writeSqliteTranscriptArchive } from "./session-accessor.sqlite-archive.js"; +import { writeTranscriptArchive } from "./session-accessor.sqlite-archive.js"; import type { SessionTranscriptAccessScope, SessionTranscriptTurnMessageAppend, @@ -19,18 +19,18 @@ import type { } from "./session-accessor.sqlite-contract.js"; import type { ResolvedSessionEntryRow } from "./session-accessor.sqlite-entry-store.js"; import { - assertSqliteSessionEntrySelectionUnchanged, + assertSessionEntrySelectionUnchanged, collectSessionEntryLookupKeys, deleteLegacySessionEntryRows, readSessionEntryRow, - readSqliteSessionEntrySelectionSnapshot, - readSqliteSessionIdentitySnapshot, + readSessionEntrySelectionSnapshot, + readSessionIdentitySnapshot, writeSessionEntry, } from "./session-accessor.sqlite-entry-store.js"; import { emitCommittedSessionIdentityDiff } from "./session-accessor.sqlite-identity.js"; import { - readSqliteTranscriptEventRows, - readSqliteTranscriptSnapshot, + readTranscriptEventRows, + readTranscriptSnapshot, type SqliteTranscriptSnapshotRow, } from "./session-accessor.sqlite-read.js"; import { @@ -40,12 +40,12 @@ import { runExclusiveSqliteSessionWrite, toDatabaseOptions, } from "./session-accessor.sqlite-scope.js"; -import { appendSqliteTranscriptMessageInTransaction } from "./session-accessor.sqlite-transcript-message-append.js"; +import { appendTranscriptMessageInTransaction } from "./session-accessor.sqlite-transcript-message-append.js"; import { readTranscriptMirrorFacts } from "./session-accessor.sqlite-transcript-mirror.js"; import { resolveTranscriptMessageAppendParent } from "./session-accessor.sqlite-transcript-parent.js"; import { - readCommittedSqliteTranscriptMessageSequence, - rememberCommittedSqliteTranscriptMessageSequencesInTransaction, + readCommittedTranscriptMessageSequence, + rememberCommittedTranscriptMessageSequencesInTransaction, } from "./session-accessor.sqlite-transcript-sequences.js"; import { readTranscriptGenerationInTransaction } from "./session-accessor.sqlite-transcript-state.js"; import { @@ -110,7 +110,7 @@ type SqliteTranscriptSnapshotState = | { kind: "current"; rows: SqliteTranscriptSnapshotRow[] } | { kind: "stale" }; -export async function replaceSqliteTranscriptEvents( +export async function replaceTranscriptEvents( scope: SessionTranscriptAccessScope, events: TranscriptEvent[], ): Promise { @@ -123,7 +123,7 @@ export async function replaceSqliteTranscriptEvents( } /** Rewrites exact transcript rows after atomically validating their generation and bytes. */ -export async function rewriteSqliteTranscriptEventRowsExact( +export async function rewriteTranscriptEventRowsExact( scope: SessionTranscriptAccessScope, params: { allowInitialGenerationMaterialization?: boolean; @@ -156,7 +156,7 @@ export async function rewriteSqliteTranscriptEventRowsExact( } /** Fully replaces rows for one transcript synchronously for sync session runtimes. */ -export function replaceSqliteTranscriptEventsSync( +export function replaceTranscriptEventsSync( scope: SessionTranscriptWriteScope, events: TranscriptEvent[], ): boolean { @@ -185,7 +185,7 @@ export function replaceSqliteTranscriptEventsSync( return replaced; } -export async function trimSqliteTranscriptForManualCompact( +export async function trimTranscriptForManualCompact( scope: SessionTranscriptAccessScope, selectRetainedLines: (lines: readonly string[]) => readonly string[] | null, options: { nowMs?: number } = {}, @@ -193,12 +193,8 @@ export async function trimSqliteTranscriptForManualCompact( const resolved = resolveSqliteTranscriptScope(scope); return await runExclusiveSqliteSessionWrite(resolved, async () => { const database = openOpenClawAgentDatabase(toDatabaseOptions(resolved)); - const snapshotRows = readSqliteTranscriptEventRows(database, resolved.sessionId); - const sessionSnapshot = readSqliteSessionEntrySelectionSnapshot( - database, - resolved.sessionKey, - true, - ); + const snapshotRows = readTranscriptEventRows(database, resolved.sessionId); + const sessionSnapshot = readSessionEntrySelectionSnapshot(database, resolved.sessionKey, true); const lines = snapshotRows.map((row) => row.eventJson); const retainedLines = selectRetainedLines(lines); if (!retainedLines) { @@ -210,7 +206,7 @@ export async function trimSqliteTranscriptForManualCompact( ); } const retainedEvents = retainedLines.map((line) => JSON.parse(line) as TranscriptEvent); - const archivedPath = writeSqliteTranscriptArchive({ + const archivedPath = writeTranscriptArchive({ archiveDirectory: resolveSqliteTranscriptArchiveDirectory(resolved), content: serializeJsonlLines(lines), reason: "bak", @@ -222,12 +218,12 @@ export async function trimSqliteTranscriptForManualCompact( let currentIdentity = new Map(); runOpenClawAgentWriteTransaction((writeDatabase) => { assertSqliteTranscriptSnapshotUnchanged(writeDatabase, resolved.sessionId, snapshotRows); - const freshSessionSnapshot = readSqliteSessionEntrySelectionSnapshot( + const freshSessionSnapshot = readSessionEntrySelectionSnapshot( writeDatabase, resolved.sessionKey, true, ); - assertSqliteSessionEntrySelectionUnchanged( + assertSessionEntrySelectionUnchanged( sessionSnapshot, freshSessionSnapshot, "session.transcript.manual-compact", @@ -237,7 +233,7 @@ export async function trimSqliteTranscriptForManualCompact( throw new Error(`SQLite session changed before compacting ${resolved.sessionId}`); } const identityKeys = collectSessionEntryLookupKeys(writeDatabase, resolved.sessionKey); - previousIdentity = readSqliteSessionIdentitySnapshot(writeDatabase, identityKeys); + previousIdentity = readSessionIdentitySnapshot(writeDatabase, identityKeys); replaceSqliteTranscriptEventsInTransaction(writeDatabase, resolved, retainedEvents); const nextEntry = cloneSessionEntry(freshEntry); delete nextEntry.contextBudgetStatus; @@ -252,7 +248,7 @@ export async function trimSqliteTranscriptForManualCompact( writeSessionEntry(writeDatabase, resolved.sessionKey, nextEntry, { previousEntry: freshEntry, }); - currentIdentity = readSqliteSessionIdentitySnapshot(writeDatabase, identityKeys); + currentIdentity = readSessionIdentitySnapshot(writeDatabase, identityKeys); }, toDatabaseOptions(resolved)); emitCommittedSessionIdentityDiff(previousIdentity, currentIdentity); return { archivedPath, kept: retainedLines.length, trimmed: true }; @@ -260,7 +256,7 @@ export async function trimSqliteTranscriptForManualCompact( } /** Appends one raw transcript event to the additive SQLite transcript store. */ -export async function appendSqliteTranscriptEvent( +export async function appendTranscriptEvent( scope: SessionTranscriptAccessScope, event: TranscriptEvent, options: TranscriptEventAppendOptions = {}, @@ -279,7 +275,7 @@ export async function appendSqliteTranscriptEvent( } /** Appends one raw non-message transcript event synchronously for sync session runtimes. */ -export function appendSqliteTranscriptEventSync( +export function appendTranscriptEventSync( scope: SessionTranscriptWriteScope, event: TranscriptEvent, options: TranscriptEventAppendOptions = {}, @@ -363,7 +359,7 @@ function resolveTranscriptEventAppendParent( } /** Appends a guarded transcript turn and touches its session row in one queued write. */ -export async function appendSqliteExpectedSessionTranscriptTurn( +export async function appendExpectedSessionTranscriptTurn( scope: SessionTranscriptWriteScope, options: { atomicGroup?: boolean; @@ -413,7 +409,7 @@ export async function appendSqliteExpectedSessionTranscriptTurn( const appendedMessages: TranscriptMessageAppendResult[] = []; for (const append of messages) { const { shouldAppend: _shouldAppend, ...appendOptions } = append; - const appended = appendSqliteTranscriptMessageInTransaction(transactionDb, resolved, { + const appended = appendTranscriptMessageInTransaction(transactionDb, resolved, { ...appendOptions, messageAlreadyRedacted: options.atomicGroup === true, ...((append.cwd ?? options.cwd) ? { cwd: append.cwd ?? options.cwd } : {}), @@ -434,7 +430,7 @@ export async function appendSqliteExpectedSessionTranscriptTurn( // Later explicit parents can abandon earlier rows. Capture every cursor // from the final active projection before this atomic transaction commits. - rememberCommittedSqliteTranscriptMessageSequencesInTransaction( + rememberCommittedTranscriptMessageSequencesInTransaction( transactionDb, resolved.sessionId, appendedMessages, @@ -454,10 +450,10 @@ export async function appendSqliteExpectedSessionTranscriptTurn( : fresh.entry; if (next !== fresh.entry) { const identityKeys = collectSessionEntryLookupKeys(transactionDb, resolved.sessionKey); - previousIdentity = readSqliteSessionIdentitySnapshot(transactionDb, identityKeys); + previousIdentity = readSessionIdentitySnapshot(transactionDb, identityKeys); writeSessionEntry(transactionDb, resolved.sessionKey, next); deleteLegacySessionEntryRows(transactionDb, fresh.legacyKeys, resolved.sessionKey); - currentIdentity = readSqliteSessionIdentitySnapshot(transactionDb, identityKeys); + currentIdentity = readSessionIdentitySnapshot(transactionDb, identityKeys); } result = { appendedMessages, @@ -497,17 +493,17 @@ async function selectAppendableSqliteTranscriptTurnMessages( } /** Appends one transcript message to the additive SQLite transcript store. */ -export async function appendSqliteTranscriptMessage( +export async function appendTranscriptMessage( scope: SessionTranscriptWriteScope, options: TranscriptMessageAppendOptions & { prepareMessageAfterIdempotencyCheck: (message: TMessage) => TMessage | undefined; }, ): Promise | undefined>; -export async function appendSqliteTranscriptMessage( +export async function appendTranscriptMessage( scope: SessionTranscriptWriteScope, options: TranscriptMessageAppendOptions, ): Promise>; -export async function appendSqliteTranscriptMessage( +export async function appendTranscriptMessage( scope: SessionTranscriptWriteScope, options: TranscriptMessageAppendOptions, ): Promise | undefined> { @@ -515,14 +511,14 @@ export async function appendSqliteTranscriptMessage( return await runExclusiveSqliteSessionWrite(resolved, async () => { let result: TranscriptMessageAppendResult | undefined; runOpenClawAgentWriteTransaction((database) => { - result = appendSqliteTranscriptMessageInTransaction(database, resolved, options); + result = appendTranscriptMessageInTransaction(database, resolved, options); }, toDatabaseOptions(resolved)); return result; }); } /** Appends one transcript message synchronously for sync session runtimes. */ -export function appendSqliteTranscriptMessageSync( +export function appendTranscriptMessageSync( scope: SessionTranscriptWriteScope, options: TranscriptMessageAppendOptions, ): TranscriptMessageAppendResult | undefined { @@ -542,7 +538,7 @@ export function appendSqliteTranscriptMessageSync( ) { return; } - result = appendSqliteTranscriptMessageInTransaction(database, resolved, options); + result = appendTranscriptMessageInTransaction(database, resolved, options); }, toDatabaseOptions(resolved)); if (fencedScope.expectedWriterRunId !== undefined && result === undefined) { throw new SessionTranscriptWriterClaimReboundError(scope.sessionKey); @@ -551,7 +547,7 @@ export function appendSqliteTranscriptMessageSync( } /** Runs read/append transcript work under one SQLite writer-queue critical section. */ -export async function withSqliteTranscriptWriteLock( +export async function withTranscriptWriteLock( scope: SessionTranscriptWriteScope, run: (context: SqliteTranscriptWriteLockContext) => Promise | T, ): Promise { @@ -561,7 +557,7 @@ export async function withSqliteTranscriptWriteLock( let transcriptSnapshot: SqliteTranscriptSnapshotState | undefined; return await run({ readEvents: async () => { - const snapshot = readSqliteTranscriptSnapshot(database, resolved.sessionId); + const snapshot = readTranscriptSnapshot(database, resolved.sessionId); transcriptSnapshot = { kind: "current", rows: snapshot.rows }; return snapshot.events; }, @@ -582,7 +578,7 @@ export async function withSqliteTranscriptWriteLock( ); } replaceSqliteTranscriptEventsInTransaction(writeDatabase, resolved, events); - return readSqliteTranscriptEventRows(writeDatabase, resolved.sessionId); + return readTranscriptEventRows(writeDatabase, resolved.sessionId); }, toDatabaseOptions(resolved)); transcriptSnapshot = { kind: "current", rows: nextSnapshot }; }, @@ -599,12 +595,12 @@ export async function withSqliteTranscriptWriteLock( snapshotState.rows, ) : false; - result = appendSqliteTranscriptMessageInTransaction(writeDatabase, resolved, options); + result = appendTranscriptMessageInTransaction(writeDatabase, resolved, options); if (snapshotState?.kind === "current") { nextSnapshotState = snapshotStillCurrent ? { kind: "current", - rows: readSqliteTranscriptEventRows(writeDatabase, resolved.sessionId), + rows: readTranscriptEventRows(writeDatabase, resolved.sessionId), } : { kind: "stale" }; } @@ -616,14 +612,14 @@ export async function withSqliteTranscriptWriteLock( let result: TranscriptMessageAppendResult | undefined; let messageSeq: number | undefined; runOpenClawAgentWriteTransaction((writeDatabase) => { - result = appendSqliteTranscriptMessageInTransaction(writeDatabase, resolved, options); + result = appendTranscriptMessageInTransaction(writeDatabase, resolved, options); if (result) { - rememberCommittedSqliteTranscriptMessageSequencesInTransaction( + rememberCommittedTranscriptMessageSequencesInTransaction( writeDatabase, resolved.sessionId, [result], ); - messageSeq = readCommittedSqliteTranscriptMessageSequence(result); + messageSeq = readCommittedTranscriptMessageSequence(result); } }, toDatabaseOptions(resolved)); return { @@ -636,7 +632,7 @@ export async function withSqliteTranscriptWriteLock( } /** Runs synchronous transcript work under one writer queue and SQLite transaction. */ -export async function withSqliteTranscriptWriteTransaction( +export async function withTranscriptWriteTransaction( scope: SessionTranscriptWriteScope, run: (context: SessionTranscriptWriteTransactionContext) => T, ): Promise { @@ -664,7 +660,7 @@ function isSqliteTranscriptSnapshotUnchanged( sessionId: string, expected: readonly SqliteTranscriptSnapshotRow[], ): boolean { - const current = readSqliteTranscriptEventRows(database, sessionId); + const current = readTranscriptEventRows(database, sessionId); return ( current.length === expected.length && current.every( @@ -689,10 +685,10 @@ function assertNonMessageTranscriptEvent(event: TranscriptEvent): void { return; } // Message records require parent-link, idempotency, and redaction handling - // from appendSqliteTranscriptMessage; raw event writes would bypass those invariants. + // from appendTranscriptMessage; raw event writes would bypass those invariants. if ((event as { type?: unknown }).type === "message") { throw new Error( - "appendSqliteTranscriptEvent cannot write message transcript records; use appendSqliteTranscriptMessage instead.", + "appendTranscriptEvent cannot write message transcript records; use appendTranscriptMessage instead.", ); } } diff --git a/src/config/sessions/session-accessor.test.ts b/src/config/sessions/session-accessor.test.ts index 7f254637e1b8..fb3225e88077 100644 --- a/src/config/sessions/session-accessor.test.ts +++ b/src/config/sessions/session-accessor.test.ts @@ -65,7 +65,6 @@ import { resolveSessionEntryCandidateTarget, resolveSessionEntrySelection, resolveSessionTranscriptReadTarget, - resolveSessionTranscriptRuntimeReadTarget, resolveSessionTranscriptRuntimeTarget, trimSessionTranscriptForManualCompact, updateSessionEntry, @@ -73,21 +72,16 @@ import { upsertSessionEntry, } from "./session-accessor.js"; import { - readSqliteSessionEntryCount, - readSqliteSessionEntryKeys, + readSessionEntryCount, + readSessionEntryKeys, } from "./session-accessor.sqlite-entry-store.js"; -import { - loadExactSqliteSessionEntry, - replaceSqliteSessionEntrySync, -} from "./session-accessor.sqlite-entry.js"; +import { loadExactSessionEntry, replaceSessionEntrySync } from "./session-accessor.sqlite-entry.js"; import { importSqliteSessionRows } from "./session-accessor.sqlite-import.js"; -import { deleteSqliteSessionEntryLifecycle } from "./session-accessor.sqlite-lifecycle.js"; -import { applySqliteSessionEntryLifecycleMutation } from "./session-accessor.sqlite-projection.js"; -import { applySqliteSessionEntryCanonicalReplacements } from "./session-accessor.sqlite-replacement-projection.js"; +import { applySessionEntryCanonicalReplacements } from "./session-accessor.sqlite-replacement-projection.js"; import { - appendSqliteTranscriptEventSync, - replaceSqliteTranscriptEvents, - trimSqliteTranscriptForManualCompact, + appendTranscriptEventSync, + replaceTranscriptEvents, + trimTranscriptForManualCompact, } from "./session-accessor.sqlite-transcript-write.js"; import { resolveSqliteTargetFromSessionStorePath } from "./session-sqlite-target.js"; import { @@ -180,11 +174,6 @@ describe("session accessor seam", () => { }); }); - it("exposes the canonical SQLite session lifecycle owners", () => { - expect(applySessionEntryLifecycleMutation).toBe(applySqliteSessionEntryLifecycleMutation); - expect(deleteSessionEntryLifecycle).toBe(deleteSqliteSessionEntryLifecycle); - }); - it("returns typed sync event append outcomes for missing, rebound, and duplicate rows", async () => { const scope = { agentId: "main", @@ -194,7 +183,7 @@ describe("session accessor seam", () => { }; const event = { type: "custom", id: "typed-event", timestamp: 1 }; - expect(appendSqliteTranscriptEventSync(scope, event)).toEqual({ + expect(appendTranscriptEventSync(scope, event)).toEqual({ ok: false, error: { code: "session-entry-missing", @@ -204,7 +193,7 @@ describe("session accessor seam", () => { }); await upsertSessionEntry(scope, { sessionId: "replacement-session", updatedAt: 1 }); - expect(appendSqliteTranscriptEventSync(scope, event)).toEqual({ + expect(appendTranscriptEventSync(scope, event)).toEqual({ ok: false, error: { actualSessionId: "replacement-session", @@ -215,8 +204,8 @@ describe("session accessor seam", () => { }); await upsertSessionEntry(scope, { sessionId: scope.sessionId, updatedAt: 2 }); - expect(appendSqliteTranscriptEventSync(scope, event)).toEqual({ ok: true, value: true }); - expect(appendSqliteTranscriptEventSync(scope, event)).toEqual({ ok: true, value: false }); + expect(appendTranscriptEventSync(scope, event)).toEqual({ ok: true, value: true }); + expect(appendTranscriptEventSync(scope, event)).toEqual({ ok: true, value: false }); }); it("loads, lists, and patches session entries without exposing the file store shape", async () => { @@ -290,7 +279,7 @@ describe("session accessor seam", () => { { sessionKey: "agent:main:logical-entry", storePath }, { sessionId: "logical-entry-session", updatedAt: 10 }, ); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { agentId: "main", sessionId: "transcript-only-session", @@ -305,8 +294,8 @@ describe("session accessor seam", () => { ); const database = openOpenClawAgentDatabase({ agentId: "main", path: databasePath }); - expect(readSqliteSessionEntryCount(database)).toBe(1); - expect(readSqliteSessionEntryKeys(database)).toEqual(["agent:main:logical-entry"]); + expect(readSessionEntryCount(database)).toBe(1); + expect(readSessionEntryKeys(database)).toEqual(["agent:main:logical-entry"]); expect(countSessionEntryRowsReadOnly({ agentId: "main", storePath })).toBe(2); }); @@ -571,7 +560,7 @@ describe("session accessor seam", () => { { sessionKey: "agent:main:main", storePath }, { sessionId: "session-events", updatedAt: 10 }, ); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { agentId: "main", sessionId: "session-events", sessionKey: "agent:main:main", storePath }, [header, message], ); @@ -598,7 +587,7 @@ describe("session accessor seam", () => { { sessionKey: "agent:main:main", storePath }, { sessionId: "session-find", updatedAt: 10 }, ); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { agentId: "main", sessionId: "session-find", sessionKey: "agent:main:main", storePath }, [header, older, newer], ); @@ -615,7 +604,7 @@ describe("session accessor seam", () => { expect(found).toEqual({ event: newer }); expect(seen).toEqual([newer]); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { agentId: "main", sessionId: "session-falsy", sessionKey: "agent:main:falsy", storePath }, [false], ); @@ -1389,7 +1378,7 @@ describe("session accessor seam", () => { sessionKey: "agent:main:telegram:group:1:topic:4", storePath, }; - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { type: "session", version: 3, id: scope.sessionId }, { type: "message", @@ -2212,7 +2201,7 @@ describe("session accessor seam", () => { it("inserts and canonically rekeys through the bulk replacement owner", async () => { const insertedKey = "agent:main:replacement-insert"; - await applySqliteSessionEntryCanonicalReplacements({ + await applySessionEntryCanonicalReplacements({ sessionKeys: [insertedKey], storePath, update: () => ({ @@ -2251,7 +2240,7 @@ describe("session accessor seam", () => { .run(previousKey, "member-1", "test", 1); const identityListener = vi.fn(); const unsubscribe = onSessionIdentityMutation(identityListener); - await applySqliteSessionEntryCanonicalReplacements({ + await applySessionEntryCanonicalReplacements({ sessionKeys: [canonicalKey, previousKey], storePath, update: (entries) => ({ @@ -2300,7 +2289,7 @@ describe("session accessor seam", () => { ); const snapshot = () => [visibleKey, internalKey].map((sessionKey) => - loadExactSqliteSessionEntry({ sessionKey, storePath }), + loadExactSessionEntry({ sessionKey, storePath }), ); const before = snapshot(); const identityListener = vi.fn(); @@ -2320,7 +2309,7 @@ describe("session accessor seam", () => { }, ]) { await expect( - applySqliteSessionEntryCanonicalReplacements({ + applySessionEntryCanonicalReplacements({ sessionKeys: [visibleKey, internalKey], storePath, update: () => ({ replacements: [replacement], result: undefined }), @@ -2378,7 +2367,7 @@ describe("session accessor seam", () => { try { await expect( - applySqliteSessionEntryCanonicalReplacements({ + applySessionEntryCanonicalReplacements({ sessionKeys: [exactKey, canonicalKey, previousKey], storePath, update: (entries) => ({ @@ -2452,7 +2441,7 @@ describe("session accessor seam", () => { await plannerStarted; let replacementError: unknown; try { - replaceSqliteSessionEntrySync(scope, { + replaceSessionEntrySync(scope, { model: "newer", sessionId: "replacement-prepare", updatedAt: 20, @@ -2553,7 +2542,7 @@ describe("session accessor seam", () => { await builderStarted; let replacementError: unknown; try { - replaceSqliteSessionEntrySync(scope, { + replaceSessionEntrySync(scope, { model: "newer", sessionId: "lifecycle-stale", updatedAt: 20, @@ -2590,7 +2579,7 @@ describe("session accessor seam", () => { sessionId: scope.sessionId, updatedAt: 10, }); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { id: "event-1", message: { role: "user", content: "keep me" }, @@ -2768,9 +2757,9 @@ describe("session accessor seam", () => { message: { role: "user", content: `message ${index}`, timestamp: index }, })), ]; - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( scope, - transcriptRecords as Parameters[1], + transcriptRecords as Parameters[1], ); const updates: unknown[] = []; const unsubscribe = onSessionTranscriptUpdate((update) => updates.push(update)); @@ -2823,10 +2812,7 @@ describe("session accessor seam", () => { }; const records = createManualCompactRecords(sessionId); await upsertSessionEntry(scope, { sessionId, updatedAt: 1 }); - await replaceSqliteTranscriptEvents( - scope, - records as Parameters[1], - ); + await replaceTranscriptEvents(scope, records as Parameters[1]); const archiveDirPath = path.join(stateDir, "agents", "main", "sessions"); fs.writeFileSync(archiveDirPath, "not a directory"); @@ -2838,7 +2824,7 @@ describe("session accessor seam", () => { it("keeps no-op manual compaction tolerant of a missing current session entry", async () => { await expect( - trimSqliteTranscriptForManualCompact( + trimTranscriptForManualCompact( { agentId: "main", sessionId: "99999999-9999-4999-8999-999999999999", @@ -2868,10 +2854,7 @@ describe("session accessor seam", () => { totalTokensFresh: true, updatedAt: 100, }); - await replaceSqliteTranscriptEvents( - scope, - records as Parameters[1], - ); + await replaceTranscriptEvents(scope, records as Parameters[1]); const entryBeforeCompact = loadSessionEntry(scope); const databasePath = expectDefined( resolveSqliteTargetFromSessionStorePath(storePath, { agentId: "main" }).path, @@ -2932,10 +2915,7 @@ describe("session accessor seam", () => { ? { sessionId, totalTokens: 30, totalTokensFresh: true, updatedAt: 100 } : { sessionId, updatedAt: 1 }, ); - await replaceSqliteTranscriptEvents( - scope, - records as Parameters[1], - ); + await replaceTranscriptEvents(scope, records as Parameters[1]); const existingArchive = path.join(tempDir, `${sessionId}.jsonl.bak.preexisting`); if (reuseArchive) { fs.writeFileSync(existingArchive, archiveContent); @@ -2946,11 +2926,11 @@ describe("session accessor seam", () => { ? "SQLite session state changed while preparing session.transcript.manual-compact" : `SQLite transcript changed while preparing rewrite for ${sessionId}`; await expect( - trimSqliteTranscriptForManualCompact( + trimTranscriptForManualCompact( scope, (lines) => { if (conflict === "metadata") { - replaceSqliteSessionEntrySync(scope, { + replaceSessionEntrySync(scope, { label: "concurrent metadata", sessionId, totalTokens: 40, @@ -2958,7 +2938,7 @@ describe("session accessor seam", () => { updatedAt: 200, }); } else { - appendSqliteTranscriptEventSync(scope, { + appendTranscriptEventSync(scope, { type: "custom", id: "late-append", timestamp: "2026-06-19T12:00:09.000Z", @@ -3056,10 +3036,7 @@ describe("session accessor seam", () => { }, ]; await upsertSessionEntry(scope, { sessionFile, sessionId, updatedAt: 1 }); - await replaceSqliteTranscriptEvents( - scope, - records as Parameters[1], - ); + await replaceTranscriptEvents(scope, records as Parameters[1]); await expect( trimSessionTranscriptForManualCompact(scope, { maxLines: 5 }), @@ -3162,7 +3139,7 @@ describe("session accessor seam", () => { sessionId: scope.sessionId, updatedAt: 10, }); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { type: "session", version: 3, id: scope.sessionId }, { type: "message", @@ -3949,7 +3926,7 @@ describe("session accessor seam", () => { await predicateStarted; let replacementError: unknown; try { - replaceSqliteSessionEntrySync(scope, { + replaceSessionEntrySync(scope, { lifecycleRevision: "replacement-revision", sessionId: "session-predicate-replacement", updatedAt: 20, @@ -4060,7 +4037,7 @@ describe("session accessor seam", () => { }); await predicateStarted; - replaceSqliteSessionEntrySync(scope, { + replaceSessionEntrySync(scope, { abortedLastRun: false, restartRecoveryDeliveryRunId: "new-run", restartRecoveryDeliverySourceRunId: "new-run", @@ -4171,7 +4148,7 @@ describe("session accessor seam", () => { sessionKey: "agent:main:owned-fence", storePath, }; - replaceSqliteSessionEntrySync(scope, { + replaceSessionEntrySync(scope, { activeWriterRunId: "current-run", sessionId: scope.sessionId, updatedAt: 1, @@ -4216,7 +4193,7 @@ describe("session accessor seam", () => { updatedAt: 10, }); - const readTarget = await resolveSessionTranscriptRuntimeReadTarget(scope); + const readTarget = await resolveSessionTranscriptRuntimeTarget(scope); const writeTarget = await resolveSessionTranscriptRuntimeTarget(scope); expect(readTarget).toEqual(scope); @@ -4238,7 +4215,7 @@ describe("session accessor seam", () => { }); expect( - loadExactSqliteSessionEntry({ + loadExactSessionEntry({ agentId: "main", sessionKey, storePath, @@ -4258,7 +4235,7 @@ describe("session accessor seam", () => { sessionId: scope.sessionId, updatedAt: 10, }); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { sessionId: scope.sessionId, type: "session" }, { timestamp: "1970-01-01T00:00:00.001Z", type: "custom" }, ]); @@ -4284,7 +4261,7 @@ describe("session accessor seam", () => { expect(imported.lastMutationAtMs).toBe(replaced.lastMutationAtMs); expect(imported.lastObservedMutationAtMs).toBe(replaced.lastMutationAtMs); - await replaceSqliteTranscriptEvents(scope, []); + await replaceTranscriptEvents(scope, []); const cleared = readTranscriptStatsSync(scope); dateNow.mockRestore(); @@ -4322,7 +4299,7 @@ describe("session accessor seam", () => { }); expect(readGeneration()?.generation).toBe(first); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { sessionId: scope.sessionId, type: "session" }, { id: "replacement", parentId: null, type: "custom" }, ]); @@ -4330,7 +4307,7 @@ describe("session accessor seam", () => { expect(replaced).toMatch(/^[0-9a-f]{32}$/); expect(replaced).not.toBe(first); - await replaceSqliteTranscriptEvents(scope, []); + await replaceTranscriptEvents(scope, []); expect(readGeneration()?.generation).not.toBe(replaced); }); diff --git a/src/config/sessions/session-accessor.transcript-target.ts b/src/config/sessions/session-accessor.transcript-target.ts index 807ff64abf73..fe478403034c 100644 --- a/src/config/sessions/session-accessor.transcript-target.ts +++ b/src/config/sessions/session-accessor.transcript-target.ts @@ -66,8 +66,6 @@ export function resolveSessionTranscriptDatabasePath( return resolveOpenClawAgentSqlitePath(toDatabaseOptions(resolved)); } -export { resolveSessionTranscriptRuntimeTarget as resolveSessionTranscriptRuntimeReadTarget }; - export function resolveSessionTranscriptReadTarget( scope: SessionTranscriptReadScope, ): SessionTranscriptReadTarget { diff --git a/src/config/sessions/session-accessor.transcript-turn.ts b/src/config/sessions/session-accessor.transcript-turn.ts index 95feda2098c4..74e26ca758b2 100644 --- a/src/config/sessions/session-accessor.transcript-turn.ts +++ b/src/config/sessions/session-accessor.transcript-turn.ts @@ -10,11 +10,11 @@ import { resolveSessionEntrySelection, } from "./session-accessor.entry.js"; import { - readCommittedSqliteTranscriptMessageSequence, - rememberCommittedSqliteTranscriptMessageSequences, + readCommittedTranscriptMessageSequence, + rememberCommittedTranscriptMessageSequences, } from "./session-accessor.sqlite-transcript-sequences.js"; import { redactTranscriptMessageForStorage } from "./session-accessor.sqlite-transcript-store.js"; -import { appendSqliteExpectedSessionTranscriptTurn } from "./session-accessor.sqlite-transcript-write.js"; +import { appendExpectedSessionTranscriptTurn } from "./session-accessor.sqlite-transcript-write.js"; import { appendTranscriptMessage, emitTranscriptUpdate } from "./session-accessor.transcript.js"; import type { SessionTranscriptWriteScope, @@ -164,7 +164,7 @@ async function appendTranscriptTurnMessages( } } // Resolve cursors only after the last explicit parent has chosen the branch. - rememberCommittedSqliteTranscriptMessageSequences(target, appendedMessages); + rememberCommittedTranscriptMessageSequences(target, appendedMessages); return appendedMessages; } @@ -247,7 +247,7 @@ async function persistExpectedSessionTranscriptTurn( sessionTarget: target, }, () => - appendSqliteExpectedSessionTranscriptTurn( + appendExpectedSessionTranscriptTurn( { agentId, sessionKey: resolved.normalizedKey, @@ -428,7 +428,7 @@ async function publishTranscriptTurnUpdate(params: { } const sequencedMessages = appendedMessages.map((message) => ({ message, - messageSeq: readCommittedSqliteTranscriptMessageSequence(message), + messageSeq: readCommittedTranscriptMessageSequence(message), })); if ( sequencedMessages.length > 1 && diff --git a/src/config/sessions/session-accessor.transcript.ts b/src/config/sessions/session-accessor.transcript.ts index f809eeab08f7..bfa91628a679 100644 --- a/src/config/sessions/session-accessor.transcript.ts +++ b/src/config/sessions/session-accessor.transcript.ts @@ -1,34 +1,31 @@ -import { emitSessionTranscriptUpdate } from "../../sessions/transcript-events.js"; -import { readSqliteTranscriptRawDelta as readTranscriptRawDelta } from "./session-accessor.sqlite-delta.js"; -import { resolveSqliteSessionKeyBySessionId as resolveTranscriptSessionKeyBySessionId } from "./session-accessor.sqlite-entry.js"; -import { publishSqliteTranscriptUpdate as publishTranscriptUpdate } from "./session-accessor.sqlite-events.js"; +import { readTranscriptRawDelta } from "./session-accessor.sqlite-delta.js"; +import { resolveSessionKeyBySessionId as resolveTranscriptSessionKeyBySessionId } from "./session-accessor.sqlite-entry.js"; +import { publishTranscriptUpdate } from "./session-accessor.sqlite-events.js"; import { - findSqliteTranscriptEvent, - loadLatestSqliteAssistantText as readLatestTranscriptAssistantText, - loadSqliteTranscriptEventRowsAfterSeqSync as loadTranscriptEventRowsAfterSeqSync, - loadSqliteTranscriptEvents as loadTranscriptEvents, - loadSqliteTranscriptEventsSync as loadTranscriptEventsSync, - loadSqliteTranscriptHeaderSync as loadTranscriptHeaderSync, - loadSqliteTranscriptTailEventsSync as loadTranscriptTailEventsSync, - readSqliteTranscriptStatsSync as readTranscriptStatsSync, - readSqliteTranscriptEventAtSeqSync as readTranscriptEventAtSeqSync, + findTranscriptEvent, + loadLatestAssistantText as readLatestTranscriptAssistantText, + loadTranscriptEventRowsAfterSeqSync, + loadTranscriptEvents, + loadTranscriptEventsSync, + loadTranscriptHeaderSync, + loadTranscriptTailEventsSync, + readTranscriptStatsSync, + readTranscriptEventAtSeqSync, } from "./session-accessor.sqlite-read.js"; import { - appendSqliteTranscriptEvent as appendTranscriptEvent, - appendSqliteTranscriptEventSync as appendTranscriptEventSync, - appendSqliteTranscriptMessage as appendTranscriptMessage, - appendSqliteTranscriptMessageSync as appendTranscriptMessageSync, - replaceSqliteTranscriptEvents as replaceTranscriptEvents, - replaceSqliteTranscriptEventsSync as replaceTranscriptEventsSync, - rewriteSqliteTranscriptEventRowsExact as rewriteTranscriptEventRowsExact, - trimSqliteTranscriptForManualCompact, - withSqliteTranscriptWriteLock as withTranscriptWriteLock, - withSqliteTranscriptWriteTransaction as withTranscriptWriteTransaction, + appendTranscriptEvent, + appendTranscriptEventSync, + appendTranscriptMessage, + appendTranscriptMessageSync, + replaceTranscriptEvents, + replaceTranscriptEventsSync, + rewriteTranscriptEventRowsExact, + trimTranscriptForManualCompact, + withTranscriptWriteLock, + withTranscriptWriteTransaction, } from "./session-accessor.sqlite-transcript-write.js"; import type { SessionTranscriptRuntimeScope, - SessionTranscriptReadScope, - TranscriptEvent, SessionTranscriptManualTrimResult, SessionTranscriptManualTrimPreflightResult, } from "./session-accessor.types.js"; @@ -43,6 +40,7 @@ export { appendTranscriptEventSync, appendTranscriptMessage, appendTranscriptMessageSync, + findTranscriptEvent, loadTranscriptEventRowsAfterSeqSync, loadTranscriptEvents, loadTranscriptEventsSync, @@ -60,26 +58,7 @@ export { withTranscriptWriteLock, withTranscriptWriteTransaction, }; - -/** Keeps transcript event delivery behind the transcript owner boundary. */ -export function emitTranscriptUpdate( - update: Parameters[0], -): void { - emitSessionTranscriptUpdate(update); -} - -/** - * Finds the newest transcript record accepted by the matcher. Reads rows - * newest-first with early exit so hot append-path lookups never parse the - * whole transcript; missing transcripts match nothing. The match is wrapped - * so parsed falsy records stay distinguishable from "no match". - */ -export async function findTranscriptEvent( - scope: SessionTranscriptReadScope, - match: (event: TranscriptEvent) => boolean, -): Promise<{ event: TranscriptEvent } | undefined> { - return findSqliteTranscriptEvent(scope, match); -} +export { emitSessionTranscriptUpdate as emitTranscriptUpdate } from "../../sessions/transcript-events.js"; /** * Trims a transcript for manual sessions.compact and clears stale token metadata. @@ -106,7 +85,7 @@ export async function trimSessionTranscriptForManualCompact( const maxLines = Math.max(1, Math.floor(params.maxLines)); const maxTailLines = Math.max(0, maxLines - 1); let declined: SessionTranscriptManualTrimResult = { compacted: false, reason: "no transcript" }; - const trimmed = await trimSqliteTranscriptForManualCompact( + const trimmed = await trimTranscriptForManualCompact( scope, (lines) => { if (lines.length === 0) { diff --git a/src/config/sessions/session-accessor.ts b/src/config/sessions/session-accessor.ts index 7dc8df158e24..f56f0759c28d 100644 --- a/src/config/sessions/session-accessor.ts +++ b/src/config/sessions/session-accessor.ts @@ -189,7 +189,7 @@ export { resolveSessionTranscriptActiveLeafEntryId, rewindSessionToMessage, switchSessionBranch, -} from "./session-accessor.message-cut.js"; +} from "./session-accessor.sqlite-message-cut.js"; export { commitReplySessionInitialization, loadReplySessionInitializationSnapshot, @@ -265,6 +265,6 @@ export { resolveConcreteSessionStorePath, resolveSessionTranscriptDatabasePath, resolveSessionTranscriptReadTarget, - resolveSessionTranscriptRuntimeReadTarget, resolveSessionTranscriptRuntimeTarget, + resolveSessionTranscriptRuntimeTarget as resolveSessionTranscriptRuntimeReadTarget, } from "./session-accessor.transcript-target.js"; diff --git a/src/config/sessions/session-entry-json.ts b/src/config/sessions/session-entry-json.ts index 19b043115e22..86c4f21e256e 100644 --- a/src/config/sessions/session-entry-json.ts +++ b/src/config/sessions/session-entry-json.ts @@ -1,4 +1,4 @@ -export function hasValidSqliteSessionEntryIdentity(entry: { +export function hasValidSessionEntryIdentity(entry: { sessionId?: unknown; updatedAt?: unknown; }): entry is { sessionId: string; updatedAt: number } { @@ -20,7 +20,7 @@ export function parseSqliteSessionEntryRecord(row: { return null; } const record = parsed as Record; - if (!hasValidSqliteSessionEntryIdentity(record)) { + if (!hasValidSessionEntryIdentity(record)) { return null; } if ( diff --git a/src/config/sessions/session-history-eviction.ts b/src/config/sessions/session-history-eviction.ts index 1f2a46a747d7..799960f9a7cd 100644 --- a/src/config/sessions/session-history-eviction.ts +++ b/src/config/sessions/session-history-eviction.ts @@ -17,13 +17,13 @@ import { type SessionDiskBudgetSweepResult, type SessionPhysicalDiskUsage, } from "./disk-budget.js"; -import { materializeSqliteSessionStateDeletePlans } from "./session-accessor.sqlite-archive.js"; -import { emitArchivedSqliteTranscriptUpdates } from "./session-accessor.sqlite-events.js"; +import { materializeSessionStateDeletePlans } from "./session-accessor.sqlite-archive.js"; +import { emitArchivedTranscriptUpdates } from "./session-accessor.sqlite-events.js"; import { - collectSqliteSessionStateIdsForEntry, - deleteMaterializedSqliteSessionStatePlans, - planSqliteSessionStateDeleteIfUnreferenced, - readReferencedSqliteSessionIds, + collectSessionStateIdsForEntry, + deleteMaterializedSessionStatePlans, + planSessionStateDeleteIfUnreferenced, + readReferencedSessionIds, } from "./session-accessor.sqlite-lifecycle-state.js"; import { getSessionKysely, @@ -32,7 +32,7 @@ import { runExclusiveSqliteSessionWrite, toDatabaseOptions, } from "./session-accessor.sqlite-scope.js"; -import { parseSqliteSessionEntryJson } from "./session-accessor.sqlite-status.js"; +import { parseSessionEntryJson } from "./session-accessor.sqlite-status.js"; import { normalizeStoreSessionKey } from "./store-entry.js"; import { resolveMaintenanceConfig } from "./store-maintenance-runtime.js"; import type { ResolvedSessionMaintenanceConfig } from "./store-maintenance.js"; @@ -108,7 +108,7 @@ function collectProtectedHistoricalSessionIds(params: { database: OpenClawAgentDatabase; storePath: string; }): Set { - const protectedSessionIds = readReferencedSqliteSessionIds(params.database); + const protectedSessionIds = readReferencedSessionIds(params.database); for (const sessionId of collectAdmissionProtectedSessionIds(params)) { protectedSessionIds.add(sessionId); } @@ -144,9 +144,9 @@ export function collectAdmissionProtectedSessionIds(params: { continue; } protectedSessionIds.add(row.current_session_id); - const entry = parseSqliteSessionEntryJson(row); + const entry = parseSessionEntryJson(row); if (entry) { - for (const sessionId of collectSqliteSessionStateIdsForEntry(entry)) { + for (const sessionId of collectSessionStateIdsForEntry(entry)) { protectedSessionIds.add(sessionId); } } @@ -352,7 +352,7 @@ async function enforceSessionHistoryMaintenanceSerialized( database, storePath: params.storePath, }); - const candidate = planSqliteSessionStateDeleteIfUnreferenced({ + const candidate = planSessionStateDeleteIfUnreferenced({ archiveDirectory, archiveTranscript: true, database, @@ -370,17 +370,16 @@ async function enforceSessionHistoryMaintenanceSerialized( } // Extract-before-delete is the retention invariant. The lifecycle hold // fences admission while the store writer is released for archive I/O. - const materialized = await materializeSqliteSessionStateDeletePlans([plan]); + const materialized = await materializeSessionStateDeletePlans([plan]); const committedArchives = await runExclusiveSqliteSessionWrite(resolved, async () => { let deleted = false; - let archivedTranscripts: ReturnType = - []; + let archivedTranscripts: ReturnType = []; runOpenClawAgentWriteTransaction((transactionDb) => { const protectedAtDelete = collectProtectedHistoricalSessionIds({ database: transactionDb, storePath: params.storePath, }); - archivedTranscripts = deleteMaterializedSqliteSessionStatePlans( + archivedTranscripts = deleteMaterializedSessionStatePlans( transactionDb, materialized, protectedAtDelete, @@ -421,7 +420,7 @@ async function enforceSessionHistoryMaintenanceSerialized( continue; } removedEntries += 1; - emitArchivedSqliteTranscriptUpdates(eviction.archivedTranscripts); + emitArchivedTranscriptUpdates(eviction.archivedTranscripts); usage = eviction.usage; if (usage.totalBytes > highWaterBytes) { // Reclaim archives (oldest first, including ones this pass committed) diff --git a/src/config/sessions/session-history.ts b/src/config/sessions/session-history.ts index aa6f10e52ea2..134a4de49440 100644 --- a/src/config/sessions/session-history.ts +++ b/src/config/sessions/session-history.ts @@ -1,30 +1,7 @@ -import type { - SessionAccessScope, - SessionEntrySummary, - SessionTranscriptInstance, -} from "./session-accessor.sqlite-contract.js"; import { - listSqliteSessionEntriesByStatus, - listSqliteSessionTranscriptInstances, + listSessionEntriesByStatus, + listSessionTranscriptInstances, } from "./session-accessor.sqlite-entry.js"; -import type { SessionEntry } from "./types.js"; - -type SessionEntryListScope = Partial>; -type SessionEntryStatus = NonNullable; export type { SessionTranscriptInstance } from "./session-accessor.sqlite-contract.js"; - -/** Lists entries selected by the indexed normalized session status. */ -export function listSessionEntriesByStatus( - scope: SessionEntryListScope, - statuses: readonly SessionEntryStatus[], -): SessionEntrySummary[] { - return listSqliteSessionEntriesByStatus(scope, statuses); -} - -/** Lists every retained transcript instance, including prior ids for rotated logical sessions. */ -export function listSessionTranscriptInstances( - scope: SessionEntryListScope = {}, -): SessionTranscriptInstance[] { - return listSqliteSessionTranscriptInstances(scope); -} +export { listSessionEntriesByStatus, listSessionTranscriptInstances }; diff --git a/src/config/sessions/session-transcript-search.test.ts b/src/config/sessions/session-transcript-search.test.ts index 105b930f2afe..da4499a501a1 100644 --- a/src/config/sessions/session-transcript-search.test.ts +++ b/src/config/sessions/session-transcript-search.test.ts @@ -12,9 +12,9 @@ import { import { closeOpenClawStateDatabaseForTest } from "../../state/openclaw-state-db.js"; import type { TranscriptEvent } from "./session-accessor.js"; import { - appendSqliteTranscriptEvent, - appendSqliteTranscriptMessage, - replaceSqliteTranscriptEvents, + appendTranscriptEvent, + appendTranscriptMessage, + replaceTranscriptEvents, } from "./session-accessor.sqlite-transcript-write.js"; import { listSessionsNeedingTranscriptIndexReconcile } from "./session-transcript-index.js"; import { searchSessionTranscripts } from "./session-transcript-search.js"; @@ -50,13 +50,13 @@ function transcriptScope(sessionId: string, sessionKey: string) { } async function appendUserMessage(sessionId: string, sessionKey: string, text: string) { - await appendSqliteTranscriptMessage(transcriptScope(sessionId, sessionKey), { + await appendTranscriptMessage(transcriptScope(sessionId, sessionKey), { message: { role: "user", content: [{ type: "text", text }] }, }); } async function appendAssistantMessage(sessionId: string, sessionKey: string, text: string) { - await appendSqliteTranscriptMessage(transcriptScope(sessionId, sessionKey), { + await appendTranscriptMessage(transcriptScope(sessionId, sessionKey), { message: { role: "assistant", content: [{ type: "text", text }] }, }); } @@ -120,7 +120,7 @@ describe("searchSessionTranscripts", () => { it("ignores non-message events and misses non-matching queries", async () => { await appendUserMessage("session-1", "agent:main:main", "alpha topic"); - await appendSqliteTranscriptEvent(transcriptScope("session-1", "agent:main:main"), { + await appendTranscriptEvent(transcriptScope("session-1", "agent:main:main"), { type: "model_change", id: "model-change-1", model: "sonnet-4.6", @@ -159,7 +159,7 @@ describe("searchSessionTranscripts", () => { it("reindexes synchronously when a linear transcript is replaced", async () => { await appendUserMessage("session-1", "agent:main:main", "obsolete branch text"); - await replaceSqliteTranscriptEvents(transcriptScope("session-1", "agent:main:main"), [ + await replaceTranscriptEvents(transcriptScope("session-1", "agent:main:main"), [ { type: "message", id: "m-new", @@ -178,7 +178,7 @@ describe("searchSessionTranscripts", () => { it("only surfaces the active branch after a deferred leaf-control rebuild", async () => { const scope = transcriptScope("session-1", "agent:main:main"); - await replaceSqliteTranscriptEvents(scope, [ + await replaceTranscriptEvents(scope, [ { type: "message", id: "m1", @@ -192,7 +192,7 @@ describe("searchSessionTranscripts", () => { message: { role: "assistant", content: [{ type: "text", text: "beta abandoned" }] }, }, ] as unknown as TranscriptEvent[]); - await appendSqliteTranscriptEvent(scope, { + await appendTranscriptEvent(scope, { type: "leaf", id: "leaf-1", parentId: "m2", @@ -211,7 +211,7 @@ describe("searchSessionTranscripts", () => { it("streams large searchable projections to the writer in bounded chunks", async () => { const scope = transcriptScope("session-1", "agent:main:main"); const largeText = "x".repeat(140 * 1024); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( scope, ["alpha-stream", "beta-stream", "gamma-stream"].map((marker, index) => ({ type: "message", @@ -220,7 +220,7 @@ describe("searchSessionTranscripts", () => { message: { role: "user", content: [{ type: "text", text: `${marker} ${largeText}` }] }, })) as unknown as TranscriptEvent[], ); - await appendSqliteTranscriptEvent(scope, { + await appendTranscriptEvent(scope, { type: "leaf", id: "leaf-large", parentId: "m3", diff --git a/src/config/sessions/targets-read-availability.ts b/src/config/sessions/targets-read-availability.ts index 3d92f3bf6b41..a19e46d17558 100644 --- a/src/config/sessions/targets-read-availability.ts +++ b/src/config/sessions/targets-read-availability.ts @@ -5,7 +5,7 @@ import { normalizeAgentId, parseAgentSessionKey } from "../../routing/session-ke import { withOpenClawAgentDatabaseReadOnly } from "../../state/openclaw-agent-db-readonly.js"; import type { OpenClawConfig } from "../types.openclaw.js"; import { resolveStorePath } from "./paths.js"; -import { readSqliteSessionEntryKeys } from "./session-accessor.sqlite-entry-store.js"; +import { readSessionEntryKeys } from "./session-accessor.sqlite-entry-store.js"; import { resolveSqliteTargetFromSessionStorePath } from "./session-sqlite-target.js"; import { dedupeSessionStoreTargetsBySqliteTarget, @@ -56,7 +56,7 @@ function readSessionStoreTargetSnapshot(params: { (database) => { const scopedAgentIds = new Set(); let hasUnscopedRow = false; - for (const sessionKey of readSqliteSessionEntryKeys(database)) { + for (const sessionKey of readSessionEntryKeys(database)) { const parsed = parseAgentSessionKey(sessionKey); if (parsed) { scopedAgentIds.add(normalizeAgentId(parsed.agentId)); diff --git a/src/config/sessions/targets.ts b/src/config/sessions/targets.ts index 68f4e67c5dae..14348ffa3d24 100644 --- a/src/config/sessions/targets.ts +++ b/src/config/sessions/targets.ts @@ -17,7 +17,7 @@ import { import { resolveStateDir } from "../paths.js"; import type { OpenClawConfig } from "../types.openclaw.js"; import { resolveAgentsDirFromSessionStorePath, resolveStorePath } from "./paths.js"; -import { readSqliteSessionEntryKeys } from "./session-accessor.sqlite-entry-store.js"; +import { readSessionEntryKeys } from "./session-accessor.sqlite-entry-store.js"; import { listDurableSqliteTargetOwnersForSessionStorePath, resolveSqliteTargetFromSessionStorePath, @@ -152,7 +152,7 @@ export function listKnownSessionStoreAgentIds( try { const logicalOwners = withOpenClawAgentDatabaseReadOnly( (database) => - readSqliteSessionEntryKeys(database).flatMap((sessionKey) => { + readSessionEntryKeys(database).flatMap((sessionKey) => { const parsed = parseAgentSessionKey(sessionKey); return parsed ? [normalizeAgentId(parsed.agentId)] : []; }), @@ -453,7 +453,7 @@ export function resolveExistingAgentSessionStoreTargetsSync( : requested; const result = withOpenClawAgentDatabaseReadOnly( (database) => - readSqliteSessionEntryKeys(database).some((sessionKey) => { + readSessionEntryKeys(database).some((sessionKey) => { const parsed = parseAgentSessionKey(sessionKey); // Unscoped keys belong to the validated database owner. Explicit agent keys must // match so a fixed store containing only another agent's rows proves nothing. diff --git a/src/gateway/managed-image-actions.e2e.test.ts b/src/gateway/managed-image-actions.e2e.test.ts index 578a63a68e28..540e26c876e1 100644 --- a/src/gateway/managed-image-actions.e2e.test.ts +++ b/src/gateway/managed-image-actions.e2e.test.ts @@ -47,6 +47,8 @@ describe("managed image actions Gateway E2E", () => { if (!block || typeof block.artifactId !== "string" || typeof block.url !== "string") { throw new Error("managed image fixture did not produce an artifact"); } + const artifactId = block.artifactId; + const imageUrl = block.url; const sessionId = "managed-image-actions-session"; const transcriptPath = path.join(stateDir, `${sessionId}.jsonl`); @@ -96,10 +98,10 @@ describe("managed image actions Gateway E2E", () => { expiresAt?: string; }>("artifacts.download", { sessionKey: SESSION_KEY, - artifactId: block.artifactId, + artifactId, }); expect(download.artifact).toMatchObject({ - id: block.artifactId, + id: artifactId, source: "session-transcript", }); expect(download.expiresAt).toEqual(expect.any(String)); @@ -122,7 +124,7 @@ describe("managed image actions Gateway E2E", () => { height: 84, }); - const authenticated = await fetch(new URL(String(block.url), fullUrl), { + const authenticated = await fetch(new URL(imageUrl, fullUrl), { headers: { Authorization: `Bearer ${GATEWAY_TOKEN}` }, }); expect(authenticated.status).toBe(200); diff --git a/src/gateway/managed-image-attachments.ts b/src/gateway/managed-image-attachments.ts index 03d48d22aa37..a3fdf886137a 100644 --- a/src/gateway/managed-image-attachments.ts +++ b/src/gateway/managed-image-attachments.ts @@ -17,7 +17,7 @@ import type { ReplyMediaAttachment } from "../auto-reply/reply-payload.js"; import { getRuntimeConfig } from "../config/config.js"; import { resolveStateDir } from "../config/paths.js"; import { loadExactSessionEntryReadOnlyResult } from "../config/sessions/session-accessor.sqlite-entry-availability.js"; -import { resolveSqliteSessionEntry } from "../config/sessions/session-accessor.sqlite-entry.js"; +import { resolveSessionEntry } from "../config/sessions/session-accessor.sqlite-entry.js"; import { resolveExistingAgentSessionStoreTargetsReadOnlyResult, type SessionStoreTargetsReadCache, @@ -993,7 +993,7 @@ async function getSessionManagedOutgoingAttachmentIndex( let targetEntry = exact.value?.entry; if (!targetEntry) { try { - targetEntry = resolveSqliteSessionEntry( + targetEntry = resolveSessionEntry( { agentId: ownerAgentId, clone: false, diff --git a/src/gateway/minimal-gateway.test-helpers.ts b/src/gateway/minimal-gateway.test-helpers.ts index eeaf28b7582a..6cd4a3fa83c2 100644 --- a/src/gateway/minimal-gateway.test-helpers.ts +++ b/src/gateway/minimal-gateway.test-helpers.ts @@ -114,7 +114,7 @@ export async function startMinimalRealGateway( } try { for (const session of sessions) { - await sessionStore.upsertSqliteSessionEntry( + await sessionStore.upsertSessionEntry( { agentId: session.agentId, sessionKey: toAgentRequestSessionKey(session.key)!, diff --git a/src/gateway/server-methods.authorization.test.ts b/src/gateway/server-methods.authorization.test.ts index eb83dcddc466..b10c69903f10 100644 --- a/src/gateway/server-methods.authorization.test.ts +++ b/src/gateway/server-methods.authorization.test.ts @@ -4,7 +4,7 @@ import { patchSessionEntry, upsertSessionEntry, } from "../config/sessions/session-accessor.js"; -import { applySqliteSessionEntryCanonicalReplacements } from "../config/sessions/session-accessor.sqlite-replacement-projection.js"; +import { applySessionEntryCanonicalReplacements } from "../config/sessions/session-accessor.sqlite-replacement-projection.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { createEmptyPluginRegistry } from "../plugins/registry-empty.js"; import { setActivePluginRegistry } from "../plugins/runtime.js"; @@ -591,7 +591,7 @@ describe("sessions.patchMany orchestration", () => { }).storePath; const writerStarted = createDeferred(); const insertConflictingAlias = createDeferred(); - const writer = applySqliteSessionEntryCanonicalReplacements({ + const writer = applySessionEntryCanonicalReplacements({ agentId: "main", sessionKeys: [conflictingAlias], storePath, @@ -688,7 +688,7 @@ describe("sessions.patchMany orchestration", () => { }).storePath; const writerStarted = createDeferred(); const insertConflictingAlias = createDeferred(); - const writer = applySqliteSessionEntryCanonicalReplacements({ + const writer = applySessionEntryCanonicalReplacements({ agentId: "main", sessionKeys: [conflictingAlias], storePath, diff --git a/src/gateway/server-methods/sessions-patch-engine.ts b/src/gateway/server-methods/sessions-patch-engine.ts index 8c8ede7557ca..dd7562c6a237 100644 --- a/src/gateway/server-methods/sessions-patch-engine.ts +++ b/src/gateway/server-methods/sessions-patch-engine.ts @@ -9,7 +9,7 @@ import { import type { SessionEntry } from "../../config/sessions.js"; import { isInternalSessionEffectsKey } from "../../config/sessions/internal-session-key.js"; import { - applySqliteSessionEntryCanonicalReplacements, + applySessionEntryCanonicalReplacements, type SessionEntryCanonicalReplacement, } from "../../config/sessions/session-accessor.sqlite-replacement-projection.js"; import { SessionLabelOwnerIndex } from "../../config/sessions/session-entry-selection.js"; @@ -322,7 +322,7 @@ async function executeSessionPatchMutations(params: { new Set([first.key, first.canonicalKey, ...first.initialStoreKeys]), ) : undefined; - const groupOutcomes = await applySqliteSessionEntryCanonicalReplacements({ + const groupOutcomes = await applySessionEntryCanonicalReplacements({ agentId: first.targetAgentId, ...(selectedSessionKeys ? { sessionKeys: selectedSessionKeys } : {}), storePath: first.storePath, diff --git a/src/gateway/server-methods/sessions-rewind.ts b/src/gateway/server-methods/sessions-rewind.ts index cf7c79450016..157ef1f1e23e 100644 --- a/src/gateway/server-methods/sessions-rewind.ts +++ b/src/gateway/server-methods/sessions-rewind.ts @@ -17,9 +17,9 @@ import { type SessionMessageCutMutationResult, } from "../../config/sessions/session-accessor.js"; import { - forkSqliteSessionAtMessage as forkSessionAtMessage, - rewindSqliteSessionToMessage as rewindSessionToMessage, - switchSqliteSessionBranch as switchSessionBranch, + forkSessionAtMessage, + rewindSessionToMessage, + switchSessionBranch, } from "../../config/sessions/session-accessor.sqlite-message-cut.js"; import { MEDIA_MAX_BYTES, readMediaBuffer } from "../../media/store.js"; import { diff --git a/src/gateway/server.chat.gateway-server-chat.test.ts b/src/gateway/server.chat.gateway-server-chat.test.ts index 5c06b7c05255..0f73e453fd87 100644 --- a/src/gateway/server.chat.gateway-server-chat.test.ts +++ b/src/gateway/server.chat.gateway-server-chat.test.ts @@ -7,7 +7,7 @@ import { beforeEach, describe, expect, test, vi } from "vitest"; import { WebSocket } from "ws"; import { createDeferred } from "../../test/helpers/promise.js"; import { loadSessionEntry } from "../config/sessions/session-accessor.js"; -import { replaceSqliteTranscriptEvents } from "../config/sessions/session-accessor.sqlite-transcript-write.js"; +import { replaceTranscriptEvents } from "../config/sessions/session-accessor.sqlite-transcript-write.js"; import { emitAgentEvent } from "../infra/agent-events.js"; import { registerAgentRunContext } from "../infra/agent-run-registry.js"; import { @@ -151,7 +151,7 @@ describe("gateway server chat", () => { id: `message-${index}`, type: "message", })); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { agentId: "main", sessionId: "sess-main", sessionKey: "main", storePath }, events, ); @@ -836,7 +836,7 @@ describe("gateway server chat", () => { if (!storePath) { throw new Error("session store path was not initialized"); } - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { agentId: "main", sessionId: "sess-main", sessionKey: "main", storePath }, [ { type: "message", id: "old", parentId: null, message: { role: "user", content: "old" } }, diff --git a/src/gateway/server.sessions.delete-lifecycle.test.ts b/src/gateway/server.sessions.delete-lifecycle.test.ts index bca74a4dd62d..8b7fe8d0692a 100644 --- a/src/gateway/server.sessions.delete-lifecycle.test.ts +++ b/src/gateway/server.sessions.delete-lifecycle.test.ts @@ -16,7 +16,7 @@ import { loadTranscriptEvents, replaceSessionEntry, } from "../config/sessions/session-accessor.js"; -import { replaceSqliteTranscriptEvents } from "../config/sessions/session-accessor.sqlite-transcript-write.js"; +import { replaceTranscriptEvents } from "../config/sessions/session-accessor.sqlite-transcript-write.js"; import { beginSessionWorkAdmission, runExclusiveSessionLifecycleMutation, @@ -320,7 +320,7 @@ test("sessions.delete removes a locked plugin-owned session from its persisted a }), ); for (const sessionId of [canonicalSessionId, aliasSessionId]) { - await replaceSqliteTranscriptEvents({ sessionKey: requestedKey, sessionId, storePath }, [ + await replaceTranscriptEvents({ sessionKey: requestedKey, sessionId, storePath }, [ { type: "session", id: sessionId, content: sessionId }, ]); } diff --git a/src/gateway/session-compaction-checkpoints.ts b/src/gateway/session-compaction-checkpoints.ts index 240335fdfa7a..ddb5522973c5 100644 --- a/src/gateway/session-compaction-checkpoints.ts +++ b/src/gateway/session-compaction-checkpoints.ts @@ -24,8 +24,8 @@ import { updateSessionEntry, } from "../config/sessions/session-accessor.js"; import { - branchSqliteCompactionCheckpointSession, - restoreSqliteCompactionCheckpointSession, + branchCompactionCheckpointSession, + restoreCompactionCheckpointSession, } from "../config/sessions/session-accessor.sqlite-checkpoint.js"; import type { SessionTranscriptRuntimeTarget } from "../config/sessions/session-accessor.types.js"; import { streamSessionTranscriptLines } from "../config/sessions/transcript-stream.js"; @@ -539,7 +539,7 @@ async function branchCheckpointSessionFromStoredBoundary( const legacySource = await prepareLegacyCheckpointSource( findCheckpoint(entry, params.checkpointId), ); - return await branchSqliteCompactionCheckpointSession({ + return await branchCompactionCheckpointSession({ ...(params.agentId ? { agentId: params.agentId } : {}), storePath: params.storePath, sourceKey: params.sourceKey, @@ -562,7 +562,7 @@ async function restoreCheckpointSessionFromStoredBoundary( const legacySource = await prepareLegacyCheckpointSource( findCheckpoint(entry, params.checkpointId), ); - return await restoreSqliteCompactionCheckpointSession({ + return await restoreCompactionCheckpointSession({ ...(params.agentId ? { agentId: params.agentId } : {}), storePath: params.storePath, sessionKey: params.sessionKey, diff --git a/src/gateway/session-utils-search.ts b/src/gateway/session-utils-search.ts index 4bc4ddfefda9..c00892750454 100644 --- a/src/gateway/session-utils-search.ts +++ b/src/gateway/session-utils-search.ts @@ -27,7 +27,7 @@ import { import { buildGatewaySessionRow } from "./session-utils-row.js"; import { isGroupOrChannelDisplaySession, - loadSessionEntryReadOnly, + loadGatewaySessionEntryReadOnly, parseGroupKey, } from "./session-utils-store.js"; import type { GatewaySessionRow } from "./session-utils.types.js"; @@ -164,11 +164,14 @@ export function loadGatewaySessionLifecycleSnapshot( options?: LoadGatewaySessionRowOptions, ): { lifecycleRunId?: string; row: GatewaySessionRow | null } { const now = options?.now ?? Date.now(); - const { cfg, storePath, store, entry, canonicalKey } = loadSessionEntryReadOnly(sessionKey, { - clone: false, - includeStoreChildEntries: true, - ...(options?.agentId ? { agentId: options.agentId } : {}), - }); + const { cfg, storePath, store, entry, canonicalKey } = loadGatewaySessionEntryReadOnly( + sessionKey, + { + clone: false, + includeStoreChildEntries: true, + ...(options?.agentId ? { agentId: options.agentId } : {}), + }, + ); if (!entry) { return { row: null }; } diff --git a/src/gateway/session-utils-store.ts b/src/gateway/session-utils-store.ts index 24c3e2f412e7..060f4c823e46 100644 --- a/src/gateway/session-utils-store.ts +++ b/src/gateway/session-utils-store.ts @@ -160,11 +160,14 @@ function loadSessionEntryWithMode( }; } -export function loadSessionEntry(sessionKey: string, opts?: { agentId?: string; clone?: boolean }) { +export function loadGatewaySessionEntry( + sessionKey: string, + opts?: { agentId?: string; clone?: boolean }, +) { return loadSessionEntryWithMode(sessionKey, opts, false); } -export function loadSessionEntryReadOnly( +export function loadGatewaySessionEntryReadOnly( sessionKey: string, opts?: { agentId?: string; clone?: boolean; includeStoreChildEntries?: boolean }, ) { diff --git a/src/gateway/session-utils.ts b/src/gateway/session-utils.ts index aec058e92dcd..8983681716e3 100644 --- a/src/gateway/session-utils.ts +++ b/src/gateway/session-utils.ts @@ -14,8 +14,8 @@ export { resolveSessionModelRef } from "../agents/session-model-ref.js"; export { loadCombinedSessionStoreForGateway } from "../config/sessions/combined-store-gateway.js"; export { deriveSessionTitle } from "./session-utils-core.js"; export { resolveDeletedAgentIdFromSessionKey } from "./session-utils-store.js"; -export { loadSessionEntry } from "./session-utils-store.js"; -export { loadSessionEntryReadOnly } from "./session-utils-store.js"; +export { loadGatewaySessionEntry as loadSessionEntry } from "./session-utils-store.js"; +export { loadGatewaySessionEntryReadOnly as loadSessionEntryReadOnly } from "./session-utils-store.js"; export { resolveCanonicalSessionStoreMatchFromStoreKeys } from "./session-utils-store.js"; export { resolveCanonicalSessionEntryFromStoreKeys } from "./session-utils-store.js"; export { resolveCanonicalGatewaySessionStoreKey } from "./session-utils-store.js"; diff --git a/src/plugin-sdk/session-transcript-runtime.ts b/src/plugin-sdk/session-transcript-runtime.ts index 16792fc15255..1237237f287b 100644 --- a/src/plugin-sdk/session-transcript-runtime.ts +++ b/src/plugin-sdk/session-transcript-runtime.ts @@ -11,7 +11,6 @@ import { readTranscriptRawDelta, readSessionTranscriptVisibleMessageDelta as readVisibleMessageDelta, readLatestTranscriptAssistantText, - resolveSessionTranscriptRuntimeReadTarget, resolveSessionTranscriptRuntimeTarget, withTranscriptWriteLock, type TranscriptMessageAppendOptions, @@ -182,7 +181,7 @@ type SessionTranscriptMirrorAppendResult = export async function resolveSessionTranscriptIdentity( params: SessionTranscriptReadParams, ): Promise { - const target = await resolveSessionTranscriptRuntimeReadTarget(params); + const target = await resolveSessionTranscriptRuntimeTarget(params); const agentId = normalizeAgentId(target.agentId); return { agentId, @@ -199,7 +198,7 @@ export async function resolveSessionTranscriptIdentity( export async function resolveSessionTranscriptTarget( params: SessionTranscriptTargetParams, ): Promise { - const target = await resolveSessionTranscriptRuntimeReadTarget(params); + const target = await resolveSessionTranscriptRuntimeTarget(params); return projectPublicTarget({ ...target, targetKind: "runtime-session", @@ -314,7 +313,7 @@ export async function appendAssistantMirrorMessageByIdentity( ...params, sessionId: currentEntry.sessionId, }; - const target = await resolveSessionTranscriptRuntimeReadTarget(scope); + const target = await resolveSessionTranscriptRuntimeTarget(scope); const latestEquivalentAssistantId = !params.idempotencyKey && isDeliveryMirrorAssistantMessage(message) ? findLatestEquivalentAssistantMessageId( diff --git a/test/scripts/sqlite-sessions-transcripts-flip-proof.built-cli.e2e.test.ts b/test/scripts/sqlite-sessions-transcripts-flip-proof.built-cli.e2e.test.ts index f4e918ac9460..28fc9e8c9101 100644 --- a/test/scripts/sqlite-sessions-transcripts-flip-proof.built-cli.e2e.test.ts +++ b/test/scripts/sqlite-sessions-transcripts-flip-proof.built-cli.e2e.test.ts @@ -11,7 +11,7 @@ import { loadTranscriptEvents, replaceSessionEntry, } from "../../src/config/sessions/session-accessor.js"; -import { replaceSqliteTranscriptEvents } from "../../src/config/sessions/session-accessor.sqlite-transcript-write.js"; +import { replaceTranscriptEvents } from "../../src/config/sessions/session-accessor.sqlite-transcript-write.js"; import { resolveSqliteTargetFromSessionStorePath } from "../../src/config/sessions/session-sqlite-target.js"; import { connectGatewayClient, @@ -58,12 +58,12 @@ describe("SQLite sessions/transcripts flip built CLI proof", () => { { sessionKey: writerSessionKey, storePath }, { sessionId: "sqlite-large-archive-writer", updatedAt: Date.now() }, ); - await replaceSqliteTranscriptEvents({ sessionKey, sessionId, storePath }, events); + await replaceTranscriptEvents({ sessionKey, sessionId, storePath }, events); await replaceSessionEntry( { sessionKey: warmupSessionKey, storePath }, { sessionId: warmupSessionId, updatedAt: Date.now() }, ); - await replaceSqliteTranscriptEvents( + await replaceTranscriptEvents( { sessionKey: warmupSessionKey, sessionId: warmupSessionId, storePath }, [ { @@ -205,7 +205,7 @@ describe("SQLite sessions/transcripts flip built CLI proof", () => { }, 180_000); }); -type TestTranscriptEvent = Parameters[1][number]; +type TestTranscriptEvent = Parameters[1][number]; function createLargeTranscriptEvents(sessionId: string): TestTranscriptEvent[] { const indexedMessage = {