@yielded/agent-storage-cloudflare 0.1.0-beta.170 → 0.1.0-beta.172

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,8 @@
1
1
  import { backfillPeerMessageRetention } from "@yielded/agent-storage-sql/sql-message-delivery-store";
2
- import { SQL_PROMPT_PREDICATE } from "@yielded/agent-storage-sql/sql-thread-native-reads";
2
+ import {
3
+ SQL_PROMPT_PREDICATE,
4
+ upgradeExecutionCheckpoints,
5
+ } from "@yielded/agent-storage-sql/sql-thread-native-reads";
3
6
  import { createSqlThreadWorkTables } from "@yielded/agent-storage-sql/sql-thread-work";
4
7
  import { makeSqliteLayoutInspection } from "@yielded/agent-storage-sql/sqlite-layout-inspection";
5
8
  import { CURRENT_RECORD_FORMAT } from "@yielded/agent/records";
@@ -13,7 +16,7 @@ import {
13
16
  DoStorageError,
14
17
  } from "../DoStorageError.ts";
15
18
 
16
- export const CurrentDoStorageVersion = 26;
19
+ export const CurrentDoStorageVersion = 27;
17
20
 
18
21
  /** Fresh layout only. Unsupported stores are rejected before these statements execute. */
19
22
  const layoutStatements = [
@@ -134,7 +137,7 @@ const inspection = (version: number, statements: ReadonlyArray<string>) =>
134
137
  }),
135
138
  });
136
139
 
137
- // Only the released predecessor is eligible; its record format and canonical tables are unchanged.
140
+ // Released predecessors retain the same record format and canonical tables.
138
141
  const addedIndexes = new Set(["effect_agent_message_deliveries_peer_retained"]);
139
142
 
140
143
  const layout25Statements = layoutObjects(layoutStatements)
@@ -149,7 +152,8 @@ const layout25Statements = layoutObjects(layoutStatements)
149
152
  );
150
153
 
151
154
  const { decode, readObjects, readHeader } = inspection(CurrentDoStorageVersion, layoutStatements);
152
- const predecessor = inspection(25, layout25Statements);
155
+ const layout25 = inspection(25, layout25Statements);
156
+ const layout26 = inspection(26, layoutStatements);
153
157
 
154
158
  const inspectStorage = Effect.fnUntraced(function* (
155
159
  allowUpgrade = false,
@@ -180,9 +184,10 @@ const inspectStorage = Effect.fnUntraced(function* (
180
184
 
181
185
  const version = legacy.value;
182
186
 
183
- if (allowUpgrade && version === 25) {
184
- if (objects.some(({ name }) => addedIndexes.has(name)))
187
+ if (allowUpgrade && (version === 25 || version === 26)) {
188
+ if (version === 25 && objects.some(({ name }) => addedIndexes.has(name)))
185
189
  return yield* incompatible(version, "Mixed layout 25 and 26 objects.");
190
+ const predecessor = version === 25 ? layout25 : layout26;
186
191
  const header = yield* predecessor.readHeader(objects, version);
187
192
 
188
193
  yield* predecessor.readManagedTriggers(true);
@@ -203,7 +208,7 @@ export const readDoStorageHeader = Effect.fnUntraced(function* () {
203
208
  return header;
204
209
  });
205
210
 
206
- /** Initialize fresh storage or atomically upgrade the exact released layout 25. */
211
+ /** Initialize fresh storage or atomically upgrade the exact released layouts 25 and 26. */
207
212
  export const ensureDoStorageLayout = Effect.fn("DoStorage.initializeLayout")(function* () {
208
213
  const sql = (yield* SqlClient.SqlClient).withoutTransforms();
209
214
 
@@ -227,6 +232,17 @@ export const ensureDoStorageLayout = Effect.fn("DoStorage.initializeLayout")(fun
227
232
  for (const [, name, index] of layoutObjects(layoutStatements))
228
233
  if (addedIndexes.has(name) || name === "effect_agent_message_deliveries_peer")
229
234
  yield* sql.unsafe(layoutStatements[index]).withoutTransform;
235
+ }
236
+ if (header?.layoutVersion === 25 || header?.layoutVersion === 26) {
237
+ yield* upgradeExecutionCheckpoints(undefined).pipe(
238
+ Effect.catchTag("ThreadStoreError", (cause) =>
239
+ DoStorageCorruptionError.make({
240
+ table: "effect_agent_executions",
241
+ rowKey: "upgrade",
242
+ message: `Invalid retained execution; upgrade rolled back: ${cause.message}`,
243
+ }),
244
+ ),
245
+ );
230
246
  yield* sql`UPDATE effect_agent_schema SET layout_version=${CurrentDoStorageVersion} WHERE singleton=1`;
231
247
  yield* sql`UPDATE effect_agent_meta SET value=${String(CurrentDoStorageVersion)} WHERE key='storage_version'`;
232
248
 
@@ -1 +0,0 @@
1
- {"version":3,"file":"DoThreadStore-C6E5gsYe.mjs","names":[],"sources":["../src/internal/canonical-append.ts","../src/internal/prompt-checkpoint.ts","../src/DoThreadStore.ts"],"sourcesContent":["import { prepareSqlAppend } from \"@yielded/agent-storage-sql/sql-thread-store\";\nimport type { AppendRequest } from \"@yielded/agent/thread-store\";\nimport { PreparedAppend } from \"@yielded/agent/thread-store\";\nimport { Effect } from \"effect\";\n\nexport const DO_OFFSET_PREFIX = \"effect-agent-do@1:\";\n\n/** Prepare the publisher's privately captured canonical request before the writer. */\nexport const prepareCanonicalAppend = Effect.fnUntraced(function* (input: AppendRequest) {\n const request = yield* PreparedAppend.capture(input);\n\n const raw = yield* prepareSqlAppend(request, DO_OFFSET_PREFIX);\n\n return { request, raw };\n});\n","import { utf8ByteLength } from \"@yielded/agent/digest\";\nimport {\n MAX_PROMPT_CHECKPOINT_BYTES,\n PromptCheckpoint,\n PromptCheckpointHead,\n PromptCheckpointRead,\n ThreadStoreError,\n type PromptCheckpoints,\n} from \"@yielded/agent/thread-store\";\nimport { Effect, Option, Schema } from \"effect\";\nimport { SqlClient } from \"effect/sql/SqlClient\";\n\nimport type { DoJournal } from \"./do-journal.ts\";\n\nconst Header = Schema.Struct({\n ...PromptCheckpointHead.fields,\n chunks: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 64 })),\n});\n\nconst decodeHeader = Schema.decodeEffect(Schema.fromJsonString(Header));\nconst encodeHeader = Schema.encodeEffect(Schema.fromJsonString(Header));\n\nconst decodeRows = Schema.decodeUnknownEffect(\n Schema.Array(\n Schema.Struct({\n key: Schema.String,\n value: Schema.String.check(Schema.isMaxLength(2_000_000)),\n }),\n ).check(Schema.isMaxLength(65)),\n);\n\nconst decodeWrite = Schema.decodeEffect(PromptCheckpoint);\nconst decodeRead = Schema.decodeEffect(PromptCheckpointRead);\n\nexport const promptCheckpointPrefix = (threadId: string) =>\n `prompt-checkpoint/${JSON.stringify(threadId)}/`;\n\nconst keyFor = (prefix: string, chunk: number) => prefix + String(chunk).padStart(5, \"0\");\n\n/**\n * Versioned derivative keys use the adapter's existing metadata store. Canonical layout and\n * export are unchanged. Chunking keeps SQL values below the DO limit; loading is one bounded\n * query followed by one parse of the native prompt. Only the latest checkpoint is retained.\n */\nexport const makePromptCheckpoints = (\n sql: SqlClient,\n journal: DoJournal,\n maxValueBytes: number,\n): PromptCheckpoints => ({\n load: (input) =>\n journal.state\n .read(\n Effect.gen(function* () {\n const request = yield* decodeRead(input);\n const prefix = promptCheckpointPrefix(request.threadId);\n\n // Every row repeats the Thread ID. Bound those known key bytes separately from\n // the prompt and header so supported long IDs do not consume the prompt allowance.\n const maxHydratedBytes =\n MAX_PROMPT_CHECKPOINT_BYTES + 16_384 + 65 * utf8ByteLength(keyFor(prefix, 0));\n\n const rows = yield* decodeRows(\n yield* sql`\n SELECT key, value FROM effect_agent_meta\n WHERE key >= ${prefix} AND key < ${prefix + \"~\"}\n AND (SELECT sum(length(CAST(key AS BLOB)) + length(CAST(value AS BLOB)))\n FROM effect_agent_meta\n WHERE key >= ${prefix} AND key < ${prefix + \"~\"})\n <= ${maxHydratedBytes}\n ORDER BY key LIMIT 66`,\n );\n\n const first = rows[0];\n\n if (first === undefined || first.key !== keyFor(prefix, 0)) return Option.none();\n const header = yield* decodeHeader(first.value);\n\n if (\n header.threadId !== request.threadId ||\n header.historyThrough >= header.throughSequence ||\n header.chunks !== rows.length - 1 ||\n rows.some((row, index) => row.key !== keyFor(prefix, index))\n )\n return Option.none();\n const [head] = yield* journal.getThread(request.threadId);\n\n if (\n head === undefined ||\n head.tail_sequence !== request.throughSequence ||\n head.tail_sequence < header.throughSequence\n )\n return Option.none();\n let bytes = 0;\n\n for (const row of rows) {\n bytes += utf8ByteLength(row.value);\n if (bytes > MAX_PROMPT_CHECKPOINT_BYTES + 16_384) return Option.none();\n }\n\n return Option.some({\n ...header,\n promptJson: rows\n .slice(1)\n .map((row) => row.value)\n .join(\"\"),\n });\n }),\n )\n .pipe(Effect.orElseSucceed(() => Option.none())),\n save: (input) =>\n Effect.gen(function* () {\n const checkpoint = yield* decodeWrite(input);\n\n if (\n utf8ByteLength(checkpoint.promptJson) > MAX_PROMPT_CHECKPOINT_BYTES ||\n checkpoint.historyThrough >= checkpoint.throughSequence\n )\n return;\n const prefix = promptCheckpointPrefix(checkpoint.threadId);\n const chunks: Array<string> = [];\n // Three UTF-8 bytes per UTF-16 code unit is a conservative bound. Keep surrogate pairs\n // together so SQLite never normalizes an isolated half while persisting a chunk.\n const chars = Math.floor(Math.min(maxValueBytes - 4_096, 1_000_000) / 3);\n\n if (chars < 1) return;\n for (let offset = 0; offset < checkpoint.promptJson.length;) {\n let end = Math.min(offset + chars, checkpoint.promptJson.length);\n const last = checkpoint.promptJson.charCodeAt(end - 1);\n\n if (last >= 0xd800 && last <= 0xdbff) end--;\n if (end <= offset || chunks.length >= 64) return;\n chunks.push(checkpoint.promptJson.slice(offset, end));\n offset = end;\n }\n const header = yield* encodeHeader({ ...checkpoint, chunks: chunks.length });\n\n yield* journal.state\n .transaction(\n Effect.gen(function* () {\n const [head] = yield* journal.getThread(checkpoint.threadId);\n\n if (head === undefined || head.tail_sequence !== checkpoint.throughSequence) return;\n yield* sql`DELETE FROM effect_agent_meta WHERE key >= ${prefix} AND key < ${prefix + \"~\"}`;\n for (const [index, value] of [header, ...chunks].entries())\n yield* sql`INSERT INTO effect_agent_meta (key, value) VALUES (${keyFor(prefix, index)}, ${value})`;\n }),\n )\n .pipe(Effect.provideService(SqlClient, sql));\n }).pipe(\n Effect.mapError((cause) =>\n ThreadStoreError.make({\n operation: \"save prompt checkpoint\",\n message: \"Unable to retain a disposable prompt checkpoint\",\n cause,\n }),\n ),\n ),\n});\n","import { BrowserCrypto } from \"@effect/platform-browser\";\nimport { SqliteClient } from \"@effect/sql-sqlite-do\";\nimport { makeSqlThreadImport } from \"@yielded/agent-storage-sql/sql-thread-import\";\nimport {\n makeSelectedReads,\n SelectedReadOwner,\n} from \"@yielded/agent-storage-sql/sql-thread-native-reads\";\nimport { ExportRecord } from \"@yielded/agent/record-format\";\nimport {\n CanonicalRecordEnvelope,\n CanonicalSequence,\n ObservationOffset,\n} from \"@yielded/agent/records\";\nimport { StorageOwner } from \"@yielded/agent/run-storage\";\nimport { SqlStorageOwner } from \"@yielded/agent/sql-memory-store\";\nimport { MAX_ARCHIVE_RANGE_PAGE } from \"@yielded/agent/thread-archive-range\";\nimport { ThreadImport } from \"@yielded/agent/thread-import\";\nimport {\n type ThreadExportRequest,\n AppendConflict,\n AppendResult,\n CheckpointRejected,\n ThreadCheckpoint,\n ThreadMaterialization,\n ThreadNotMaterialized,\n ThreadObservation,\n ThreadReadRequest,\n ThreadStore,\n ThreadReader,\n type ThreadCheckpoints,\n ThreadStoreError,\n ThreadStoreDiagnostic,\n ThreadTail,\n ThreadTailRequest,\n type AppendRequest,\n PreparedAppend,\n LoadCheckpointRequest,\n SaveCheckpointRequest,\n} from \"@yielded/agent/thread-store\";\nimport { checkExportSource } from \"@yielded/agent/thread-transfer\";\nimport { Clock, Context, Crypto, Effect, Layer, Option, Ref, Schema, Stream } from \"effect\";\nimport * as SqlClientService from \"effect/sql/SqlClient\";\nimport { isSqlError } from \"effect/sql/SqlError\";\n\nimport {\n DEFAULT_MAX_STORED_VALUE_BYTES,\n DoStorageConfig,\n DoStorageConfigValue,\n} from \"./DoStorageConfig.ts\";\nimport {\n type DoStorageCompatibilityError,\n DoAppendConflict,\n DoCheckpointConflict,\n type DoStorageFailpointLocation,\n DoStorageCorruptionError,\n DoStorageError,\n} from \"./DoStorageError.ts\";\nimport { DoStorageFailpoint, type DoStorageFailpointHandler } from \"./DoStorageFailpoint.ts\";\nimport { DO_OFFSET_PREFIX, prepareCanonicalAppend } from \"./internal/canonical-append.ts\";\nimport {\n initializeDoJournal,\n RawCheckpoint,\n RawReadRequest,\n type DoJournal,\n} from \"./internal/do-journal.ts\";\nimport { readDoStorageHeader } from \"./internal/migrations.ts\";\nimport { invalidateOwnedState, ownedState } from \"./internal/owned-state.ts\";\nimport { makePromptCheckpoints, promptCheckpointPrefix } from \"./internal/prompt-checkpoint.ts\";\nimport { isAppendContention, withStorageSpan } from \"./internal/storage-span.ts\";\n\n/**\n * Convenience-layer construction options. `storage` is the Durable Object's own\n * `ctx.storage` handle, injected as a value (DEPLOY-010: platform bindings enter only\n * through Layers; this package never imports `cloudflare:workers`).\n */\nexport interface DoStorageOptions {\n readonly storage: DurableObjectStorage;\n readonly observationPollInterval?: number | undefined;\n /**\n * Maximum bytes for any single stored value; must stay under the platform's 2 MB\n * per-value limit. Defaults to `DEFAULT_MAX_STORED_VALUE_BYTES`.\n */\n readonly maxStoredValueBytes?: number | undefined;\n /**\n * Audit journal payloads, ownership, and batch coverage in bounded pages on open, including\n * orphan rows and rows outside declared ranges. Defaults to false. Full reads validate\n * canonical records; readPrompt trusts write-time validation of the omitted fields.\n */\n readonly verifyOnOpen?: boolean | undefined;\n readonly failpoint?: DoStorageFailpointHandler | undefined;\n}\n\nexport type DoStorageInitializationError =\n | DoStorageCompatibilityError\n | DoStorageCorruptionError\n | DoStorageError;\n\nconst OffsetText = Schema.String.check(Schema.isMaxLength(4 * 1024));\nconst ZERO_CANONICAL_SEQUENCE = Schema.decodeSync(CanonicalSequence)(0);\nconst isDoAppendConflict = Schema.is(DoAppendConflict);\nconst isDoCheckpointConflict = Schema.is(DoCheckpointConflict);\n// Reuse the same AST/parser across reads. Reconstructing a JSON codec per row\n// defeats Schema's parser cache and repeatedly walks the canonical union.\nconst CanonicalRecordJson = Schema.fromJsonString(ExportRecord);\nconst ThreadCheckpointJson = Schema.fromJsonString(ThreadCheckpoint);\nconst decodeCanonicalRecord = Schema.decodeEffect(CanonicalRecordJson);\n\nconst storeError = (\n operation: string,\n error: { readonly message: string; readonly diagnostic?: ThreadStoreDiagnostic },\n) =>\n ThreadStoreError.make({\n cause: error,\n operation,\n message: error.message,\n ...(error.diagnostic === undefined ? {} : { diagnostic: error.diagnostic }),\n });\n\nconst schemaStoreError = (operation: string, error: Schema.SchemaError) =>\n ThreadStoreError.make({\n operation,\n message: \"A Thread storage value does not satisfy its schema\",\n diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation,\n issueTag: error.issue._tag,\n }),\n });\n\nconst makeOffset = (\n threadId: ThreadMaterialization[\"threadId\"],\n sequence: number,\n): Effect.Effect<ObservationOffset, ThreadStoreError> =>\n Schema.decodeEffect(CanonicalSequence)(sequence).pipe(\n Effect.flatMap((validatedSequence) =>\n Schema.decodeEffect(ObservationOffset)(\n `${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:${validatedSequence}`,\n ),\n ),\n Effect.mapError((error) => schemaStoreError(\"encode observation offset\", error)),\n );\n\nconst parseOffset = Effect.fnUntraced(function* (\n threadId: ThreadMaterialization[\"threadId\"],\n offset: ObservationOffset | undefined,\n): Effect.fn.Return<CanonicalSequence, ThreadStoreError> {\n if (offset === undefined) return ZERO_CANONICAL_SEQUENCE;\n\n const text = yield* Schema.decodeEffect(OffsetText)(offset).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode observation offset\", error)),\n );\n\n const threadPrefix = `${DO_OFFSET_PREFIX}${encodeURIComponent(threadId)}:`;\n\n if (!text.startsWith(threadPrefix)) {\n return yield* ThreadStoreError.make({\n operation: \"decode observation offset\",\n message: \"The observation offset belongs to a different adapter, storage version, or Thread.\",\n });\n }\n const sequenceText = text.slice(threadPrefix.length);\n\n if (!/^(0|[1-9][0-9]*)$/.test(sequenceText)) {\n return yield* ThreadStoreError.make({\n operation: \"decode observation offset\",\n message: \"The observation offset is malformed.\",\n });\n }\n\n return yield* Schema.decodeEffect(CanonicalSequence)(Number(sequenceText)).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode observation offset\", error)),\n );\n});\n\nconst encodeCheckpoint = (checkpoint: ThreadCheckpoint): Effect.Effect<string, ThreadStoreError> =>\n Schema.encodeEffect(ThreadCheckpointJson)(checkpoint).pipe(\n Effect.mapError((error) => schemaStoreError(\"encode checkpoint\", error)),\n );\n\nconst envelopes = new WeakMap<object, CanonicalRecordEnvelope>();\n\nconst decodeEnvelope = Effect.fnUntraced(function* (row: {\n readonly batch_id: string;\n readonly thread_id: string;\n readonly record_json: string;\n readonly sequence: CanonicalSequence;\n}) {\n const cached = envelopes.get(row);\n\n if (cached !== undefined) return cached;\n\n const record = yield* decodeCanonicalRecord(row.record_json).pipe(\n Effect.mapError((error) =>\n ThreadStoreError.make({\n operation: \"decode canonical record\",\n message: \"The canonical record does not satisfy its schema\",\n diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation: \"decode canonical record\",\n decoder: \"CanonicalRecord\",\n sequence: row.sequence,\n issueTag: error.issue._tag,\n }),\n }),\n ),\n Effect.tapError((error) =>\n Effect.annotateCurrentSpan({\n \"storage.failure.operation\": error.diagnostic?.operation,\n \"storage.failure.cause\": error.diagnostic?.causeTag,\n \"storage.failure.decoder\": error.diagnostic?.decoder,\n \"storage.failure.sequence\": row.sequence,\n \"storage.failure.issue\": error.diagnostic?.issueTag,\n }),\n ),\n );\n\n const threadId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.threadId)(\n row.thread_id,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"decode thread identity\", error)));\n\n const offset = yield* makeOffset(threadId, row.sequence);\n\n const batchId = yield* Schema.decodeEffect(CanonicalRecordEnvelope.fields.batchId)(\n row.batch_id,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"decode batch identity\", error)));\n\n const envelope = new CanonicalRecordEnvelope(\n { threadId, batchId, sequence: row.sequence, offset, record },\n { disableChecks: true },\n );\n\n envelopes.set(row, envelope);\n\n return envelope;\n});\n\nconst decodeCheckpoint = (\n checkpointJson: string,\n): Effect.Effect<ThreadCheckpoint, ThreadStoreError> =>\n Schema.decodeEffect(Schema.fromJsonString(ThreadCheckpoint))(checkpointJson).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode checkpoint\", error)),\n );\n\nconst requireThread = Effect.fnUntraced(function* (\n journal: DoJournal,\n threadId: ThreadMaterialization[\"threadId\"],\n) {\n const rows = yield* journal\n .getThread(threadId)\n .pipe(Effect.mapError((error) => storeError(\"read thread\", error)));\n\n if (rows.length === 0) {\n return yield* ThreadNotMaterialized.make({ threadId });\n }\n\n return rows[0];\n});\n\nconst requireBatchBoundary = Effect.fnUntraced(function* (\n journal: DoJournal,\n threadId: ThreadMaterialization[\"threadId\"],\n sequence: CanonicalSequence,\n) {\n const valid = yield* journal\n .isBatchBoundary(threadId, sequence)\n .pipe(Effect.mapError((error) => storeError(\"read checkpoint boundary\", error)));\n\n if (!valid) {\n return yield* CheckpointRejected.make({\n threadId,\n reason: \"not-batch-boundary\",\n });\n }\n});\n\n/** Audit excluded rows before paging owners and bounded ranges; never collect Thread payloads. */\nconst decodeStartupPayloads = Effect.fnUntraced(function* (journal: DoJournal) {\n yield* journal.archiveRanges.verifyCoverage;\n let afterThreadId: string | undefined;\n\n while (true) {\n const owners = yield* journal.archiveRanges.threadPage(afterThreadId);\n\n for (const owner of owners) {\n yield* journal.archiveRanges.verifyThread(owner.thread_id);\n afterThreadId = owner.thread_id;\n }\n if (owners.length < MAX_ARCHIVE_RANGE_PAGE) break;\n }\n});\n\nconst makeServices = Effect.fnUntraced(function* () {\n const config = yield* DoStorageConfig;\n const failpoint = yield* DoStorageFailpoint;\n const sql = yield* SqlClientService.SqlClient;\n const crypto = yield* Crypto.Crypto;\n const journal = yield* initializeDoJournal(sql, failpoint.hit, config.maxStoredValueBytes);\n\n if (config.verifyOnOpen) {\n yield* journal.state.read(decodeStartupPayloads(journal)).pipe(\n Effect.mapError((cause) =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_journal_ranges\",\n rowKey: \"verification\",\n message: cause.message,\n }),\n ),\n );\n }\n\n const hitFailpoint = (\n location: DoStorageFailpointLocation,\n ): Effect.Effect<void, ThreadStoreError> =>\n failpoint\n .hit(location)\n .pipe(Effect.mapError((error) => storeError(`storage failpoint ${location}`, error)));\n\n const materialize: ThreadStore[\"Service\"][\"materialize\"] = Effect.fnUntraced(function* (\n request: ThreadMaterialization,\n ) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadMaterialization))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate materialization\", error)));\n\n const now = yield* Clock.currentTimeMillis;\n\n yield* hitFailpoint(\"materialize:before\");\n yield* journal\n .materialize(validated.threadId, new Date(now).toISOString())\n .pipe(Effect.mapError((error) => storeError(\"materialize thread\", error)));\n yield* hitFailpoint(\"materialize:after\");\n }, withStorageSpan(\"DoThreadStore.materialize\"));\n\n const append: ThreadStore[\"Service\"][\"append\"] = Effect.fnUntraced(\n function* (request: AppendRequest) {\n const validated = yield* PreparedAppend.capture(request);\n const observed = yield* requireThread(journal, validated.threadId);\n\n const { raw: rawRequest } = yield* prepareCanonicalAppend(validated).pipe(\n Effect.provideService(Crypto.Crypto, crypto),\n );\n\n yield* hitFailpoint(\"append:before\");\n\n const result = yield* journal.state.owner\n .withProgress(rawRequest.threadId, journal.append(rawRequest, observed))\n .pipe(\n Effect.mapError((error) => {\n if (isDoAppendConflict(error)) {\n return error.actualTailSequence !== undefined\n ? AppendConflict.make({\n threadId: validated.threadId,\n batchId: validated.batch.batchId,\n reason: error.reason,\n actualTailSequence: error.actualTailSequence,\n })\n : AppendConflict.make({\n threadId: validated.threadId,\n batchId: validated.batch.batchId,\n reason: error.reason,\n });\n }\n\n return storeError(\"append canonical batch\", error);\n }),\n Effect.flatMap((result) =>\n Schema.decodeEffect(AppendResult)(result).pipe(\n Effect.mapError((error) => schemaStoreError(\"decode append result\", error)),\n ),\n ),\n );\n\n yield* hitFailpoint(\"append:after\");\n\n return result;\n },\n withStorageSpan(\"DoThreadStore.append\", isAppendContention),\n );\n\n const loadRecords = Effect.fnUntraced(function* (request: RawReadRequest) {\n const result = yield* journal\n .read(request)\n .pipe(Effect.mapError((error) => storeError(\"read canonical records\", error)));\n\n return {\n count: result.count,\n records: result.records.pipe(\n Stream.mapError((error) => storeError(\"read canonical records\", error)),\n Stream.mapEffect(decodeEnvelope),\n ),\n };\n });\n\n const readEffect = Effect.fnUntraced(function* (request: ThreadReadRequest) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadReadRequest))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate thread read\", error)),\n );\n\n if (\"selection\" in validated) return Stream.fromIterable(yield* selectedReads.read(validated));\n yield* requireThread(journal, validated.threadId);\n\n const result = yield* loadRecords(\n RawReadRequest.make({\n threadId: validated.threadId,\n fromSequenceExclusive: validated.afterSequence ?? ZERO_CANONICAL_SEQUENCE,\n limit: validated.limit,\n }),\n );\n\n return result.records;\n });\n\n const read: ThreadStore[\"Service\"][\"read\"] = (request) => Stream.unwrap(readEffect(request));\n\n const observeEffect = Effect.fnUntraced(function* (request: ThreadObservation) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadObservation))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate thread observation\", error)),\n );\n\n yield* requireThread(journal, validated.threadId);\n const initialSequence = yield* parseOffset(validated.threadId, validated.afterOffset);\n const cursor = yield* Ref.make(initialSequence);\n let polls = 0;\n let emptyPolls = 0;\n let deliveredRecords = 0;\n\n const poll = Effect.fnUntraced(function* () {\n polls++;\n const fromSequenceExclusive = yield* Ref.get(cursor);\n\n const result = yield* loadRecords(\n RawReadRequest.make({\n threadId: validated.threadId,\n fromSequenceExclusive,\n limit: 1_024,\n }),\n );\n\n if (result.count === 0) {\n emptyPolls++;\n yield* Effect.sleep(config.observationPollInterval);\n\n return Stream.empty;\n }\n\n return result.records.pipe(\n Stream.tap((record) => {\n deliveredRecords++;\n\n return Ref.set(cursor, record.sequence);\n }),\n );\n });\n\n return Stream.fromEffectRepeat(poll()).pipe(\n Stream.flatten,\n Stream.ensuring(\n Effect.suspend(() =>\n Effect.annotateCurrentSpan({\n \"effect_agent.observation.polls\": polls,\n \"effect_agent.observation.empty_polls\": emptyPolls,\n \"effect_agent.observation.records\": deliveredRecords,\n }),\n ),\n ),\n );\n });\n\n const observe: ThreadStore[\"Service\"][\"observe\"] = (request) =>\n Stream.unwrap(observeEffect(request)).pipe(Stream.withSpan(\"DoThreadStore.observe\"));\n\n const transfer = yield* makeSqlThreadImport({\n owner: journal.state.owner,\n offsetPrefix: DO_OFFSET_PREFIX,\n maxValueBytes: config.maxStoredValueBytes,\n // Import establishes a new sequence space; discard derivatives in this same transaction.\n afterImport: ({ result }) =>\n Effect.gen(function* () {\n const prefix = promptCheckpointPrefix(result.threadId);\n\n yield* sql`DELETE FROM effect_agent_meta WHERE key >= ${prefix} AND key < ${prefix + \"~\"}`;\n // Closed imported history must not emit historical lifecycle notifications again.\n if (journal.lifecycle !== undefined)\n yield* sql`INSERT INTO effect_agent_lifecycle_cursors(thread_id, through_sequence) VALUES (${result.threadId}, ${result.tailSequence})`;\n }).pipe(\n Effect.catchTag(\"SqlError\", (cause) => storeError(\"rebuild imported derivatives\", cause)),\n ),\n afterThreadRead: hitFailpoint(\"export:after-thread-read\"),\n read: (body) =>\n journal.owner.transaction(body).pipe(\n Effect.provideService(SqlClientService.SqlClient, sql),\n Effect.catchIf(isSqlError, (cause) => storeError(\"export transaction\", cause)),\n ),\n write: (body) =>\n journal.owner.transaction(body.pipe(Effect.tap(() => journal.state.invalidate))).pipe(\n Effect.provideService(SqlClientService.SqlClient, sql),\n Effect.catchIf(isSqlError, (cause) => storeError(\"import transaction\", cause)),\n ),\n });\n\n const inspectTail: ThreadStore[\"Service\"][\"inspectTail\"] = Effect.fnUntraced(function* (\n request: ThreadTailRequest,\n ) {\n const validated = yield* Schema.decodeEffect(Schema.toType(ThreadTailRequest))(request).pipe(\n Effect.mapError((error) => schemaStoreError(\"validate tail inspection\", error)),\n );\n\n const thread = yield* requireThread(journal, validated.threadId);\n\n return ThreadTail.make({\n threadId: validated.threadId,\n tailSequence: thread.tail_sequence,\n });\n });\n\n const saveCheckpoint: ThreadCheckpoints[\"save\"] = Effect.fnUntraced(function* (\n request: SaveCheckpointRequest,\n ) {\n const validated = yield* Schema.decodeEffect(Schema.toType(SaveCheckpointRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate checkpoint\", error)));\n\n const thread = yield* requireThread(journal, validated.checkpoint.threadId);\n\n if (validated.checkpoint.throughSequence > thread.tail_sequence) {\n return yield* CheckpointRejected.make({\n threadId: validated.checkpoint.threadId,\n reason: \"ahead-of-tail\",\n });\n }\n\n yield* requireBatchBoundary(\n journal,\n validated.checkpoint.threadId,\n validated.checkpoint.throughSequence,\n );\n const checkpointJson = yield* encodeCheckpoint(validated.checkpoint);\n\n const raw = RawCheckpoint.make({\n threadId: validated.checkpoint.threadId,\n throughSequence: validated.checkpoint.throughSequence,\n checkpointJson,\n });\n\n yield* hitFailpoint(\"save-checkpoint:before\");\n yield* journal.saveCheckpoint(raw).pipe(\n Effect.mapError((error) =>\n isDoCheckpointConflict(error)\n ? CheckpointRejected.make({\n threadId: validated.checkpoint.threadId,\n reason: error.reason,\n })\n : storeError(\"save checkpoint\", error),\n ),\n );\n yield* hitFailpoint(\"save-checkpoint:after\");\n });\n\n const loadCheckpoint: ThreadCheckpoints[\"load\"] = Effect.fnUntraced(function* (\n request: LoadCheckpointRequest,\n ) {\n const validated = yield* Schema.decodeEffect(Schema.toType(LoadCheckpointRequest))(\n request,\n ).pipe(Effect.mapError((error) => schemaStoreError(\"validate checkpoint lookup\", error)));\n\n const thread = yield* requireThread(journal, validated.threadId);\n\n const rows = yield* journal\n .loadCheckpoint(validated.threadId, validated.atOrBeforeSequence ?? thread.tail_sequence)\n .pipe(Effect.mapError((error) => storeError(\"load checkpoint\", error)));\n\n if (rows.length === 0) return Option.none();\n if (rows.length !== 1) {\n return yield* ThreadStoreError.make({\n operation: \"load checkpoint\",\n message: `Expected at most one checkpoint row but found ${rows.length}.`,\n });\n }\n const row = rows[0];\n const checkpoint = yield* decodeCheckpoint(row.checkpoint_json);\n\n if (\n row.thread_id !== validated.threadId ||\n checkpoint.threadId !== row.thread_id ||\n checkpoint.throughSequence !== row.through_sequence\n ) {\n return yield* ThreadStoreError.make({\n operation: \"load checkpoint\",\n message: \"Stored checkpoint metadata does not match its canonical row.\",\n });\n }\n\n yield* requireBatchBoundary(journal, checkpoint.threadId, checkpoint.throughSequence);\n\n return Option.some(checkpoint);\n });\n\n const selectedReads = yield* makeSelectedReads(decodeEnvelope).pipe(\n Effect.provideService(SelectedReadOwner, {\n snapshot: journal.state.read,\n tail: (threadId) =>\n journal.getThread(threadId).pipe(\n Effect.flatMap((rows) =>\n Schema.decodeEffect(\n Schema.UndefinedOr(\n Schema.Struct({\n tail_sequence: CanonicalSequence,\n }),\n ),\n )(rows[0]),\n ),\n Effect.mapError((error) => storeError(\"native thread tail\", error)),\n ),\n }),\n );\n\n const threadStore = ThreadStore.of({\n archives: journal.archives,\n work: journal.work.storage,\n ...(journal.lifecycle === undefined\n ? {}\n : { lifecyclePublications: journal.lifecycle.storage }),\n readIdentity: selectedReads.readIdentity,\n readExecution: (request) =>\n journal.state.read(\n requireThread(journal, request.threadId).pipe(\n Effect.andThen(journal.readExecution(request)),\n ),\n ),\n readWorkerCapacity: selectedReads.readWorkerCapacity,\n verification: transfer.verification,\n countPeerMessages: selectedReads.countPeerMessages,\n append,\n export: transfer.export,\n inspectTail,\n materialize,\n observe,\n read,\n readPrompt: (request) => Stream.fromIterableEffect(selectedReads.readPrompt(request)),\n checkpoints: { save: saveCheckpoint, load: loadCheckpoint },\n promptCheckpoints: makePromptCheckpoints(sql, journal, config.maxStoredValueBytes),\n });\n\n return Context.make(ThreadStore, threadStore).pipe(\n Context.add(ThreadImport, transfer.importer),\n Context.add(StorageOwner, journal.state.owner),\n );\n});\n\n/**\n * Durable Object Thread Store implementation with configuration, failpoint, SQL, and\n * Crypto authority kept visible in its input channel.\n */\nexport const threadStoreLayer: Layer.Layer<\n ThreadStore | ThreadReader | ThreadImport | StorageOwner,\n DoStorageInitializationError,\n DoStorageConfig | DoStorageFailpoint | SqlClientService.SqlClient | Crypto.Crypto\n> = ThreadReader.layer().pipe(Layer.provideMerge(Layer.effectContext(makeServices())));\n\n/**\n * Validated Durable Object storage configuration Layer with the documented defaults applied.\n * Shared by the ThreadStore and SubmissionLedger convenience layers so their defaults\n * cannot drift.\n */\nexport const storageConfigLayer = (\n options: DoStorageOptions,\n): Layer.Layer<DoStorageConfig, DoStorageError> =>\n Layer.effect(DoStorageConfig)(\n Schema.decodeEffect(DoStorageConfigValue)({\n observationPollInterval: options.observationPollInterval ?? 25,\n maxStoredValueBytes: options.maxStoredValueBytes ?? DEFAULT_MAX_STORED_VALUE_BYTES,\n verifyOnOpen: options.verifyOnOpen ?? false,\n }).pipe(\n Effect.mapError((error) =>\n DoStorageError.make({\n cause: error,\n operation: \"configure Durable Object storage\",\n message: error.message,\n }),\n ),\n ),\n );\n\n/** The failpoint Layer selected by convenience options: explicit handler or the no-op default. */\nexport const storageFailpointLayer = (\n options: DoStorageOptions,\n): Layer.Layer<DoStorageFailpoint> =>\n options.failpoint === undefined\n ? DoStorageFailpoint.layer\n : Layer.succeed(DoStorageFailpoint)({ hit: options.failpoint });\n\n/**\n * A composition-root convenience Layer for canonical Threads inside one Durable Object,\n * built over `ctx.storage`. Durable accepted work is served by the separate SubmissionLedger\n * port; point both at the SAME `ctx.storage` so both share the same scoped storage owner\n * (ADR-0011 D7's \"same file\" rule, transposed to one object's private database).\n */\nexport const layer = (\n options: DoStorageOptions,\n): Layer.Layer<\n ThreadStore | ThreadReader | ThreadImport | StorageOwner,\n DoStorageInitializationError\n> =>\n Layer.unwrap(\n Effect.map(DoStorageConfig, (config) =>\n threadStoreLayer.pipe(\n Layer.provide(\n Layer.mergeAll(\n Layer.succeed(DoStorageConfig)(config),\n storageFailpointLayer(options),\n SqliteClient.layer({ storage: options.storage }),\n BrowserCrypto.layer,\n ),\n ),\n ),\n ),\n ).pipe(Layer.provide(storageConfigLayer(options)));\n\n/** Read a quiesced current-layout Object without initializing its layout or ownership. */\nexport const exportThread = Effect.fn(\"DoThreadStore.exportThread\")(function* (\n options: Pick<DoStorageOptions, \"storage\">,\n request: ThreadExportRequest,\n) {\n yield* checkExportSource(request.threadId);\n\n return yield* Effect.gen(function* () {\n const sql = yield* SqlClientService.SqlClient;\n const state = yield* ownedState(sql);\n\n return yield* state\n .transaction(\n Effect.gen(function* () {\n yield* readDoStorageHeader();\n\n const transfer = yield* makeSqlThreadImport({\n owner: state.owner,\n offsetPrefix: DO_OFFSET_PREFIX,\n read: (body) => body,\n write: () => Effect.die(\"A read-only exporter cannot import\"),\n });\n\n return yield* transfer.export(request);\n }),\n )\n .pipe(\n Effect.catchTag(\"SqlError\", (cause) =>\n DoStorageError.make({\n operation: \"export Thread snapshot\",\n message: cause.message,\n cause,\n }),\n ),\n );\n }).pipe(\n Effect.provide(\n Layer.merge(SqliteClient.layer({ storage: options.storage }), BrowserCrypto.layer),\n ),\n );\n});\n\n/**\n * Discard the Object's derived thread and ledger state after direct SQL maintenance.\n * Quiesce port operations during the raw write and invalidation, and enroll the write with\n * the host mutation gate. Ordinary ThreadStore/SubmissionLedger writes maintain this view.\n */\nexport const invalidate = invalidateOwnedState;\n\n/** Share the Object's transaction gate with owner-local SQL Memory compositions. */\nexport const sqlOwnerLayer = Layer.effectContext(\n Effect.flatMap(SqlClientService.SqlClient, ownedState).pipe(\n Effect.map((state) =>\n Context.make(SqlStorageOwner, state).pipe(Context.add(StorageOwner, state.owner)),\n ),\n ),\n);\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"migrations-Dh8VYfg7.mjs","names":["SqlClient"],"sources":["../src/internal/migrations.ts"],"sourcesContent":["import { backfillPeerMessageRetention } from \"@yielded/agent-storage-sql/sql-message-delivery-store\";\nimport { SQL_PROMPT_PREDICATE } from \"@yielded/agent-storage-sql/sql-thread-native-reads\";\nimport { createSqlThreadWorkTables } from \"@yielded/agent-storage-sql/sql-thread-work\";\nimport { makeSqliteLayoutInspection } from \"@yielded/agent-storage-sql/sqlite-layout-inspection\";\nimport { CURRENT_RECORD_FORMAT } from \"@yielded/agent/records\";\nimport { Effect, Schema } from \"effect\";\nimport * as SqlClient from \"effect/sql/SqlClient\";\nimport type { SqlError } from \"effect/sql/SqlError\";\n\nimport {\n DoStorageCompatibilityError,\n DoStorageCorruptionError,\n DoStorageError,\n} from \"../DoStorageError.ts\";\n\nexport const CurrentDoStorageVersion = 26;\n\n/** Fresh layout only. Unsupported stores are rejected before these statements execute. */\nconst layoutStatements = [\n \"CREATE TABLE effect_agent_threads ( thread_id TEXT PRIMARY KEY NOT NULL, created_at TEXT, tail_sequence INTEGER NOT NULL, work_version INTEGER NOT NULL DEFAULT 3, work_state TEXT NOT NULL DEFAULT 'ready', work_through_sequence INTEGER NOT NULL DEFAULT 0, work_reporting INTEGER NOT NULL DEFAULT 0, work_entry_count INTEGER NOT NULL DEFAULT 0, worker_input_sequence INTEGER, worker_settlement_sequence INTEGER )\",\n \"CREATE TABLE effect_agent_envelopes (envelope_key INTEGER PRIMARY KEY NOT NULL, content_digest TEXT UNIQUE NOT NULL, prefix TEXT NOT NULL, before_payload TEXT NOT NULL, before_record_id TEXT NOT NULL, suffix TEXT NOT NULL)\",\n \"CREATE TABLE effect_agent_run_keys (run_key INTEGER PRIMARY KEY NOT NULL, thread_id TEXT NOT NULL, run_id TEXT NOT NULL, UNIQUE (thread_id, run_id), FOREIGN KEY (thread_id) REFERENCES effect_agent_threads(thread_id) ON DELETE RESTRICT)\",\n \"CREATE TABLE effect_agent_definitions (definition_key INTEGER PRIMARY KEY NOT NULL, content_digest TEXT UNIQUE NOT NULL, value_json TEXT NOT NULL)\",\n \"CREATE TABLE effect_agent_executions (thread_id TEXT NOT NULL, run_id TEXT NOT NULL, input_sequence INTEGER NOT NULL, revision INTEGER NOT NULL, checkpoint_json TEXT NOT NULL, last_commit_id TEXT, last_commit_digest TEXT, PRIMARY KEY (thread_id, run_id), FOREIGN KEY (thread_id) REFERENCES effect_agent_threads(thread_id) ON DELETE RESTRICT)\",\n \"CREATE TABLE effect_agent_canonical_batches ( thread_id TEXT NOT NULL, batch_id TEXT NOT NULL, first_sequence INTEGER NOT NULL, last_sequence INTEGER NOT NULL, producer_id_json TEXT NOT NULL, CONSTRAINT effect_agent_canonical_batches_span CHECK (first_sequence >= 1 AND last_sequence >= first_sequence AND last_sequence - first_sequence < 256), PRIMARY KEY (thread_id, batch_id), FOREIGN KEY (thread_id) REFERENCES effect_agent_threads(thread_id) ON DELETE RESTRICT )\",\n \"CREATE TABLE effect_agent_canonical_records ( thread_id TEXT NOT NULL, sequence INTEGER NOT NULL, record_id TEXT NOT NULL, created_at_json TEXT NOT NULL, envelope_key INTEGER NOT NULL, payload_json TEXT, record_tag INTEGER NOT NULL, run_id INTEGER, tool_call_id TEXT, input_kind TEXT, source_submission_id TEXT, message_id TEXT, submission_id TEXT, application_input INTEGER NOT NULL, context_through INTEGER, context_kind TEXT, worker_thread_id TEXT, handoff INTEGER NOT NULL, PRIMARY KEY (thread_id, sequence), UNIQUE (thread_id, record_id), FOREIGN KEY (thread_id) REFERENCES effect_agent_threads(thread_id) ON DELETE RESTRICT )\",\n 'CREATE TABLE \"effect_agent_record_runs\" ( thread_id TEXT NOT NULL, run_id INTEGER NOT NULL, sequence INTEGER NOT NULL, PRIMARY KEY (thread_id, run_id, sequence), FOREIGN KEY (thread_id, sequence) REFERENCES \"effect_agent_canonical_records\"(thread_id, sequence) ON DELETE RESTRICT ) WITHOUT ROWID',\n \"CREATE TABLE effect_agent_rollover_buckets (thread_id TEXT NOT NULL, height INTEGER NOT NULL, bucket INTEGER NOT NULL, sequence INTEGER NOT NULL, PRIMARY KEY (thread_id, height, bucket, sequence), FOREIGN KEY (thread_id, sequence) REFERENCES effect_agent_canonical_records(thread_id, sequence) ON DELETE RESTRICT) WITHOUT ROWID\",\n \"CREATE TABLE effect_agent_tool_declarations (thread_id TEXT NOT NULL, settlement_record_id TEXT NOT NULL, sequence INTEGER NOT NULL, PRIMARY KEY (thread_id, settlement_record_id, sequence), FOREIGN KEY (thread_id, sequence) REFERENCES effect_agent_canonical_records(thread_id, sequence) ON DELETE RESTRICT)\",\n \"CREATE INDEX effect_agent_tool_declarations_sequence ON effect_agent_tool_declarations(thread_id, sequence)\",\n \"CREATE TABLE effect_agent_record_refusals (thread_id TEXT NOT NULL, reservation_record_id TEXT NOT NULL, sequence INTEGER NOT NULL, PRIMARY KEY (thread_id, reservation_record_id, sequence), FOREIGN KEY (thread_id, sequence) REFERENCES effect_agent_canonical_records(thread_id, sequence) ON DELETE RESTRICT)\",\n \"CREATE INDEX effect_agent_record_refusals_sequence ON effect_agent_record_refusals(thread_id, sequence)\",\n \"CREATE TABLE effect_agent_checkpoints ( thread_id TEXT NOT NULL, through_sequence INTEGER NOT NULL, checkpoint_json TEXT NOT NULL, PRIMARY KEY (thread_id, through_sequence), FOREIGN KEY (thread_id) REFERENCES effect_agent_threads(thread_id) ON DELETE RESTRICT )\",\n \"CREATE TABLE effect_agent_submissions ( submission_id TEXT PRIMARY KEY NOT NULL, thread_id TEXT NOT NULL, queue_sequence INTEGER NOT NULL, principal TEXT NOT NULL, idempotency_key TEXT NOT NULL, agent_id TEXT NOT NULL, definition_key INTEGER NOT NULL, deployment_id TEXT NOT NULL, input_json TEXT NOT NULL, input_digest TEXT NOT NULL, receipt_id TEXT NOT NULL, state TEXT NOT NULL, settled_outcome TEXT, settled_record_id TEXT, finalized_at TEXT, created_at TEXT NOT NULL, ready_at TEXT, input_applied_record_id TEXT, input_applied_sequence INTEGER, joined_host_submission_id TEXT, suspended_reason_json TEXT, suspended_at TEXT, unknown_reason TEXT, unknown_tool_call_ids_json TEXT, parent_submission_id TEXT, parent_tool_call_id TEXT, admission_group TEXT, admission_fence_json TEXT, worker_admission_json TEXT, message_admission_json TEXT, UNIQUE (thread_id, principal, idempotency_key), UNIQUE (thread_id, queue_sequence) )\",\n \"CREATE INDEX effect_agent_submissions_joined_host ON effect_agent_submissions (joined_host_submission_id) WHERE joined_host_submission_id IS NOT NULL\",\n \"CREATE INDEX effect_agent_submissions_parent ON effect_agent_submissions (parent_submission_id) WHERE parent_submission_id IS NOT NULL\",\n \"CREATE INDEX effect_agent_submissions_group ON effect_agent_submissions (thread_id, admission_group) WHERE admission_group IS NOT NULL AND state <> 'settled'\",\n \"CREATE TABLE effect_agent_abort_intents ( submission_id TEXT PRIMARY KEY NOT NULL, author TEXT NOT NULL, reason TEXT NOT NULL, requested_at TEXT NOT NULL, canonical_record_id TEXT, FOREIGN KEY (submission_id) REFERENCES effect_agent_submissions(submission_id) ON DELETE RESTRICT )\",\n \"CREATE TABLE effect_agent_approval_decisions ( submission_id TEXT NOT NULL, tool_call_id TEXT NOT NULL, decision TEXT NOT NULL, resolver TEXT NOT NULL, reason TEXT NOT NULL, decided_at TEXT NOT NULL, PRIMARY KEY (submission_id, tool_call_id), FOREIGN KEY (submission_id) REFERENCES effect_agent_submissions(submission_id) ON DELETE RESTRICT )\",\n \"CREATE TABLE effect_agent_unknown_resolutions ( submission_id TEXT NOT NULL, tool_call_id TEXT NOT NULL, resolution_kind TEXT NOT NULL, author TEXT NOT NULL, reason TEXT NOT NULL, resolution_json TEXT NOT NULL, resolved_at TEXT NOT NULL, PRIMARY KEY (submission_id, tool_call_id, resolution_kind), FOREIGN KEY (submission_id) REFERENCES effect_agent_submissions(submission_id) ON DELETE RESTRICT )\",\n \"CREATE TABLE effect_agent_child_reservations ( reservation_id TEXT PRIMARY KEY NOT NULL, parent_submission_id TEXT NOT NULL, parent_tool_call_id TEXT NOT NULL, child_submission_id TEXT, status TEXT NOT NULL, allocation_json TEXT NOT NULL, allocation_digest TEXT NOT NULL, accounting_json TEXT, reserved_at TEXT NOT NULL, release_began_at TEXT, released_at TEXT, UNIQUE (parent_submission_id, parent_tool_call_id), FOREIGN KEY (parent_submission_id) REFERENCES effect_agent_submissions(submission_id) ON DELETE RESTRICT )\",\n \"CREATE TABLE effect_agent_child_settlements ( parent_submission_id TEXT NOT NULL, child_submission_id TEXT NOT NULL, child_outcome TEXT, recorded_at TEXT NOT NULL, PRIMARY KEY (parent_submission_id, child_submission_id) )\",\n 'CREATE INDEX effect_agent_records_call ON \"effect_agent_canonical_records\"(thread_id, record_tag, run_id, tool_call_id) WHERE tool_call_id IS NOT NULL',\n \"CREATE INDEX effect_agent_records_run_input ON \\\"effect_agent_canonical_records\\\"(thread_id, run_id) WHERE record_tag = 30 AND input_kind = 'user'\",\n 'CREATE INDEX effect_agent_records_subtree ON \"effect_agent_canonical_records\"(thread_id, source_submission_id, sequence) WHERE record_tag = 22',\n 'CREATE INDEX effect_agent_records_worker_input ON \"effect_agent_canonical_records\"(thread_id, message_id) WHERE record_tag = 34',\n \"CREATE INDEX effect_agent_submissions_nonterminal ON effect_agent_submissions (thread_id, queue_sequence) WHERE state <> 'settled'\",\n \"CREATE TABLE effect_agent_message_deliveries ( owner_thread_id TEXT NOT NULL, message_id TEXT NOT NULL, version INTEGER NOT NULL, state TEXT NOT NULL, deadline_at_millis INTEGER, record_json TEXT NOT NULL, peer_retained_until_millis INTEGER, PRIMARY KEY (owner_thread_id, message_id) )\",\n \"CREATE INDEX effect_agent_message_deliveries_due ON effect_agent_message_deliveries (deadline_at_millis, owner_thread_id, message_id) WHERE deadline_at_millis IS NOT NULL\",\n \"CREATE INDEX effect_agent_message_deliveries_pending ON \\\"effect_agent_message_deliveries\\\"(owner_thread_id, message_id) WHERE state NOT IN ('processed', 'refused')\",\n \"CREATE TABLE effect_agent_worker_stops (thread_id TEXT PRIMARY KEY NOT NULL, terminal TEXT)\",\n \"CREATE INDEX effect_agent_worker_starts ON effect_agent_message_deliveries(owner_thread_id, json_extract(record_json, '$.envelope.workerAdmission.origin.worker.delegationId'), json_extract(record_json, '$.envelope.workerAdmission.origin.worker.targetAgentId'), message_id) WHERE message_id = json_extract(record_json, '$.envelope.workerAdmission.origin.firstMessageId')\",\n \"CREATE INDEX effect_agent_worker_pending ON effect_agent_message_deliveries(owner_thread_id, json_extract(record_json, '$.envelope.workerAdmission.origin.worker.threadId'), message_id) WHERE state IN ('pending', 'parked') AND json_extract(record_json, '$.receipt') IS NULL\",\n \"CREATE TABLE effect_agent_meta ( key TEXT PRIMARY KEY NOT NULL, value TEXT NOT NULL )\",\n 'CREATE INDEX effect_agent_records_tag ON \"effect_agent_canonical_records\"(thread_id, record_tag, sequence)',\n 'CREATE INDEX effect_agent_records_handoff ON \"effect_agent_canonical_records\"(thread_id, sequence) WHERE handoff = 1',\n \"CREATE INDEX effect_agent_records_application_input ON effect_agent_canonical_records(thread_id, sequence) WHERE application_input = 1\",\n `CREATE INDEX effect_agent_records_prompt ON effect_agent_canonical_records(thread_id, sequence) WHERE ${SQL_PROMPT_PREDICATE}`,\n \"CREATE INDEX effect_agent_records_admitted_input ON effect_agent_canonical_records(thread_id, sequence) WHERE record_tag = 30 AND submission_id IS NOT NULL\",\n \"CREATE INDEX effect_agent_records_worker_funding ON effect_agent_canonical_records(thread_id, source_submission_id, sequence, message_id) WHERE record_tag = 34\",\n \"CREATE INDEX effect_agent_records_worker_completed ON effect_agent_canonical_records(thread_id, message_id, sequence) WHERE record_tag = 32\",\n \"CREATE INDEX effect_agent_records_worker_stop ON effect_agent_canonical_records(thread_id, worker_thread_id, sequence) WHERE record_tag = 38\",\n \"CREATE INDEX effect_agent_message_deliveries_identity ON effect_agent_message_deliveries(owner_thread_id, json_quote(message_id))\",\n \"CREATE INDEX effect_agent_message_deliveries_peer_retained ON effect_agent_message_deliveries(owner_thread_id, peer_retained_until_millis, message_id) WHERE peer_retained_until_millis IS NOT NULL\",\n \"CREATE INDEX effect_agent_message_deliveries_peer ON effect_agent_message_deliveries(owner_thread_id, message_id) WHERE state NOT IN ('processed', 'refused') AND json_extract(record_json, '$.envelope.messageAdmission.peerName') IS NOT NULL\",\n \"CREATE TABLE effect_agent_journal_ranges (thread_id TEXT NOT NULL, first_sequence INTEGER NOT NULL, last_sequence INTEGER NOT NULL, record_count INTEGER NOT NULL, batch_count INTEGER NOT NULL, byte_count INTEGER NOT NULL, state TEXT NOT NULL, locator TEXT, PRIMARY KEY (thread_id, first_sequence), FOREIGN KEY (thread_id) REFERENCES effect_agent_threads(thread_id) ON DELETE RESTRICT)\",\n \"CREATE TABLE effect_agent_archive_batches (thread_id TEXT NOT NULL, batch_id TEXT NOT NULL, range_first_sequence INTEGER NOT NULL, batch_json TEXT NOT NULL, PRIMARY KEY (thread_id, batch_id), FOREIGN KEY (thread_id, batch_id) REFERENCES effect_agent_canonical_batches(thread_id, batch_id) ON DELETE RESTRICT, CONSTRAINT effect_agent_archive_batches_range_fkey FOREIGN KEY (thread_id, range_first_sequence) REFERENCES effect_agent_journal_ranges(thread_id, first_sequence) ON DELETE RESTRICT)\",\n \"CREATE TABLE effect_agent_archive_records (thread_id TEXT NOT NULL, sequence INTEGER NOT NULL, range_first_sequence INTEGER NOT NULL, record_json TEXT NOT NULL, PRIMARY KEY (thread_id, sequence), FOREIGN KEY (thread_id, sequence) REFERENCES effect_agent_canonical_records(thread_id, sequence) ON DELETE RESTRICT, CONSTRAINT effect_agent_archive_records_range_fkey FOREIGN KEY (thread_id, range_first_sequence) REFERENCES effect_agent_journal_ranges(thread_id, first_sequence) ON DELETE RESTRICT)\",\n \"CREATE UNIQUE INDEX effect_agent_canonical_batches_sequence ON effect_agent_canonical_batches(thread_id, first_sequence)\",\n \"CREATE INDEX effect_agent_canonical_batches_last ON effect_agent_canonical_batches(thread_id, last_sequence)\",\n \"CREATE TABLE effect_agent_live_child_reservations (reservation_id TEXT PRIMARY KEY NOT NULL, thread_id TEXT NOT NULL)\",\n \"CREATE INDEX effect_agent_live_child_reservations_thread ON effect_agent_live_child_reservations(thread_id, reservation_id)\",\n // Compact native positions keep accepted identities out of bounded export cursors.\n // Persistent scalar FIFO derivatives; rebuild from canonical input/settlement boundaries.\n // Writer-local import indexes; rows are removed before publication.\n \"CREATE TABLE effect_agent_import_delivery_visits (thread_id TEXT NOT NULL, message_id TEXT NOT NULL, path_id TEXT NOT NULL, completed INTEGER NOT NULL, PRIMARY KEY (thread_id, message_id))\",\n \"CREATE INDEX effect_agent_import_delivery_visits_path ON effect_agent_import_delivery_visits(thread_id, path_id)\",\n \"CREATE TRIGGER effect_agent_live_child_insert AFTER INSERT ON effect_agent_child_reservations FOR EACH ROW BEGIN INSERT INTO effect_agent_live_child_reservations (reservation_id, thread_id) SELECT NEW.reservation_id, thread_id FROM effect_agent_submissions WHERE submission_id=NEW.parent_submission_id AND NEW.status<>'released'; END\",\n \"CREATE TRIGGER effect_agent_live_child_update AFTER UPDATE ON effect_agent_child_reservations FOR EACH ROW WHEN OLD.reservation_id IS NOT NEW.reservation_id OR OLD.parent_submission_id IS NOT NEW.parent_submission_id OR OLD.parent_tool_call_id IS NOT NEW.parent_tool_call_id OR OLD.child_submission_id IS NOT NEW.child_submission_id OR OLD.status IS NOT NEW.status OR OLD.allocation_json IS NOT NEW.allocation_json OR OLD.allocation_digest IS NOT NEW.allocation_digest OR OLD.accounting_json IS NOT NEW.accounting_json OR OLD.reserved_at IS NOT NEW.reserved_at OR OLD.release_began_at IS NOT NEW.release_began_at OR OLD.released_at IS NOT NEW.released_at BEGIN DELETE FROM effect_agent_live_child_reservations WHERE reservation_id=OLD.reservation_id; INSERT INTO effect_agent_live_child_reservations (reservation_id, thread_id) SELECT NEW.reservation_id, thread_id FROM effect_agent_submissions WHERE submission_id=NEW.parent_submission_id AND NEW.status<>'released'; END\",\n \"CREATE TRIGGER effect_agent_live_child_delete AFTER DELETE ON effect_agent_child_reservations FOR EACH ROW BEGIN DELETE FROM effect_agent_live_child_reservations WHERE reservation_id=OLD.reservation_id; END\",\n \"CREATE INDEX effect_agent_message_deliveries_capacity ON effect_agent_message_deliveries(owner_thread_id, (COALESCE(json_extract(record_json, '$.envelope.messageAdmission._tag'), '') = 'WorkerUpdate'), message_id) WHERE state IN ('pending', 'accepted', 'parked')\",\n] as const;\n\nconst headerStatement =\n \"CREATE TABLE effect_agent_schema (singleton INTEGER PRIMARY KEY NOT NULL CHECK (singleton = 1), layout_version INTEGER NOT NULL CHECK (layout_version > 0), record_format TEXT NOT NULL CHECK (length(record_format) > 0))\";\n\nconst layoutObjects = (statements: ReadonlyArray<string>) =>\n statements.map((statement, index) => {\n const name = /^CREATE (TABLE|(?:UNIQUE )?INDEX|TRIGGER) \"?([a-z_][a-z_0-9]*)\"?/.exec(statement);\n\n if (name === null) throw new Error(\"Invalid fresh layout statement\");\n\n return [name[1].replace(\"UNIQUE \", \"\").toLowerCase(), name[2], index] as const;\n });\n\nconst Legacy = Schema.Tuple([\n Schema.Struct({\n key: Schema.Literal(\"storage_version\"),\n value: Schema.String.check(Schema.isPattern(/^(0|[1-9][0-9]*)$/)).pipe(\n Schema.decodeTo(Schema.FiniteFromString),\n Schema.decodeTo(Schema.Int),\n ),\n }),\n]);\n\nexport interface DoStorageHeader {\n readonly layoutVersion: number;\n readonly recordFormat: string;\n}\n\nconst incompatible = (actualVersion: number, message: string) =>\n DoStorageCompatibilityError.make({\n actualVersion,\n supportedVersion: CurrentDoStorageVersion,\n message: `${message} Keep the original store; the store was not changed.`,\n });\n\nconst storageError = (cause: SqlError) =>\n DoStorageError.make({ operation: \"inspect storage layout\", cause, message: cause.message });\n\nconst inspection = (version: number, statements: ReadonlyArray<string>) =>\n makeSqliteLayoutInspection({\n version,\n statements,\n objects: layoutObjects(statements),\n headerStatement,\n incompatible,\n storageError,\n corruption: (table) =>\n DoStorageCorruptionError.make({\n table,\n rowKey: \"schema\",\n message: \"Malformed storage layout or version header.\",\n }),\n });\n\n// Only the released predecessor is eligible; its record format and canonical tables are unchanged.\nconst addedIndexes = new Set([\"effect_agent_message_deliveries_peer_retained\"]);\n\nconst layout25Statements = layoutObjects(layoutStatements)\n .filter(([, name]) => !addedIndexes.has(name))\n .map(([, , index]) =>\n layoutStatements[index]\n .replace(\", peer_retained_until_millis INTEGER\", \"\")\n .replace(\n \"'$.envelope.messageAdmission.peerName') IS NOT NULL\",\n \"'$.envelope.messageAdmission.schemaVersion') = 1\",\n ),\n );\n\nconst { decode, readObjects, readHeader } = inspection(CurrentDoStorageVersion, layoutStatements);\nconst predecessor = inspection(25, layout25Statements);\n\nconst inspectStorage = Effect.fnUntraced(function* (\n allowUpgrade = false,\n): Effect.fn.Return<\n DoStorageHeader | undefined,\n DoStorageCompatibilityError | DoStorageCorruptionError | DoStorageError,\n SqlClient.SqlClient\n> {\n const sql = (yield* SqlClient.SqlClient).withoutTransforms();\n\n const objects = yield* readObjects();\n\n const meta = objects.find((row) => row.name === \"effect_agent_meta\");\n\n if (meta === undefined) {\n if (objects.length === 0) return undefined;\n\n return yield* incompatible(0, \"Unversioned or incomplete Effect Agent storage.\");\n }\n\n const [legacy] = yield* decode(\n Legacy,\n yield* sql<Record<string, unknown>>`\n SELECT * FROM effect_agent_meta WHERE key = 'storage_version'\n `.pipe(Effect.mapError(storageError)),\n \"effect_agent_meta\",\n );\n\n const version = legacy.value;\n\n if (allowUpgrade && version === 25) {\n if (objects.some(({ name }) => addedIndexes.has(name)))\n return yield* incompatible(version, \"Mixed layout 25 and 26 objects.\");\n const header = yield* predecessor.readHeader(objects, version);\n\n yield* predecessor.readManagedTriggers(true);\n\n return header;\n }\n\n return yield* readHeader(objects, version);\n});\n\n/** Read-only inspection. The caller owns a snapshot covering this check and its export reads. */\nexport const readDoStorageHeader = Effect.fnUntraced(function* () {\n const header = yield* inspectStorage();\n\n if (header === undefined)\n return yield* incompatible(0, \"No initialized Thread storage to export.\");\n\n return header;\n});\n\n/** Initialize fresh storage or atomically upgrade the exact released layout 25. */\nexport const ensureDoStorageLayout = Effect.fn(\"DoStorage.initializeLayout\")(function* () {\n const sql = (yield* SqlClient.SqlClient).withoutTransforms();\n\n return yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const header = yield* inspectStorage(true);\n\n if (header?.layoutVersion === 25) {\n yield* sql`ALTER TABLE effect_agent_message_deliveries ADD COLUMN peer_retained_until_millis INTEGER`;\n yield* backfillPeerMessageRetention().pipe(\n Effect.catchTag(\"MessageDeliveryError\", () =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_message_deliveries\",\n rowKey: \"upgrade\",\n message: \"Invalid layout-25 delivery evidence; upgrade rolled back.\",\n }),\n ),\n );\n yield* sql`DROP INDEX effect_agent_message_deliveries_peer`;\n for (const [, name, index] of layoutObjects(layoutStatements))\n if (addedIndexes.has(name) || name === \"effect_agent_message_deliveries_peer\")\n yield* sql.unsafe(layoutStatements[index]).withoutTransform;\n yield* sql`UPDATE effect_agent_schema SET layout_version=${CurrentDoStorageVersion} WHERE singleton=1`;\n yield* sql`UPDATE effect_agent_meta SET value=${String(CurrentDoStorageVersion)} WHERE key='storage_version'`;\n\n return yield* readDoStorageHeader();\n }\n if (header !== undefined) return header;\n for (const statement of layoutStatements) yield* sql.unsafe(statement).withoutTransform;\n yield* createSqlThreadWorkTables().pipe(\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"initialize work catalogue\",\n message: cause.message,\n cause,\n }),\n ),\n );\n yield* sql.unsafe(headerStatement).withoutTransform;\n yield* sql`INSERT INTO effect_agent_schema (singleton, layout_version, record_format) VALUES (1, ${CurrentDoStorageVersion}, ${CURRENT_RECORD_FORMAT})`;\n yield* sql`INSERT INTO effect_agent_meta (key, value) VALUES ('storage_version', ${String(CurrentDoStorageVersion)})`;\n\n return yield* readDoStorageHeader();\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", storageError));\n});\n"],"mappings":"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"}