@earendil-works/pi-durable 1.2.0 → 1.3.0

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.
Files changed (51) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +17 -0
  3. package/dist/env/index.d.ts +1 -0
  4. package/dist/env/index.d.ts.map +1 -1
  5. package/dist/env/index.js.map +1 -1
  6. package/dist/harness/context.d.ts +5 -0
  7. package/dist/harness/context.d.ts.map +1 -1
  8. package/dist/harness/context.js +46 -12
  9. package/dist/harness/context.js.map +1 -1
  10. package/dist/harness/tool.d.ts.map +1 -1
  11. package/dist/harness/tool.js +1 -1
  12. package/dist/harness/tool.js.map +1 -1
  13. package/dist/storage/sqlite/cloudflare.d.ts +17 -5
  14. package/dist/storage/sqlite/cloudflare.d.ts.map +1 -1
  15. package/dist/storage/sqlite/cloudflare.js +57 -21
  16. package/dist/storage/sqlite/cloudflare.js.map +1 -1
  17. package/dist/storage/sqlite/index.d.ts +1 -1
  18. package/dist/storage/sqlite/index.d.ts.map +1 -1
  19. package/dist/storage/sqlite/index.js.map +1 -1
  20. package/dist/storage/sqlite/migrations.d.ts +5 -1
  21. package/dist/storage/sqlite/migrations.d.ts.map +1 -1
  22. package/dist/storage/sqlite/migrations.js +94 -84
  23. package/dist/storage/sqlite/migrations.js.map +1 -1
  24. package/dist/storage/sqlite/node.d.ts +6 -4
  25. package/dist/storage/sqlite/node.d.ts.map +1 -1
  26. package/dist/storage/sqlite/node.js +6 -2
  27. package/dist/storage/sqlite/node.js.map +1 -1
  28. package/dist/storage/sqlite/schema.d.ts +47 -0
  29. package/dist/storage/sqlite/schema.d.ts.map +1 -0
  30. package/dist/storage/sqlite/schema.js +57 -0
  31. package/dist/storage/sqlite/schema.js.map +1 -0
  32. package/dist/storage/sqlite/storage.d.ts +9 -1
  33. package/dist/storage/sqlite/storage.d.ts.map +1 -1
  34. package/dist/storage/sqlite/storage.js +46 -43
  35. package/dist/storage/sqlite/storage.js.map +1 -1
  36. package/dist/tools/image-processor.d.ts +4 -1
  37. package/dist/tools/image-processor.d.ts.map +1 -1
  38. package/dist/tools/image-processor.js +8 -18
  39. package/dist/tools/image-processor.js.map +1 -1
  40. package/dist/tools/read.d.ts.map +1 -1
  41. package/dist/tools/read.js +1 -1
  42. package/dist/tools/read.js.map +1 -1
  43. package/dist/truncate.d.ts +3 -2
  44. package/dist/truncate.d.ts.map +1 -1
  45. package/dist/truncate.js +4 -34
  46. package/dist/truncate.js.map +1 -1
  47. package/package.json +4 -4
  48. package/dist/harness/output.d.ts +0 -69
  49. package/dist/harness/output.d.ts.map +0 -1
  50. package/dist/harness/output.js +0 -318
  51. package/dist/harness/output.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/storage/sqlite/storage.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, JsonValue } from \"@earendil-works/chord\";\nimport { apply, type Op } from \"@earendil-works/chord/delta\";\nimport { StorageRequestError } from \"../../errors.ts\";\nimport { idFromNumber, seqFromNumber } from \"../../ids.ts\";\nimport type {\n\tConversationId,\n\tConversationQuery,\n\tConversationRecord,\n\tCursor,\n\tDocumentAddress,\n\tDocumentContent,\n\tDocumentCreate,\n\tDocumentId,\n\tDocumentPoint,\n\tDocumentQuery,\n\tDocumentRecord,\n\tEntryId,\n\tEntryQuery,\n\tEntryRecord,\n\tId,\n\tJsonObject,\n\tPage,\n\tScanOrder,\n\tSeq,\n\tStorage,\n\tStorageWrite,\n\tStoredDocument,\n\tSubmissionId,\n\tSubmissionQuery,\n\tSubmissionRecord,\n\tTaskId,\n\tTaskQuery,\n\tTaskRecord,\n} from \"../../types.ts\";\nimport { nextCursor, type ScanStart, scanStart } from \"../scan.ts\";\nimport type { SqliteDatabase, SqliteExecutor, SqliteValue } from \"./database.ts\";\nimport { applySqliteMigrations } from \"./migrations.ts\";\n\ntype StoredTask = TaskRecord<JsonValue, JsonValue, JsonValue>;\ntype TableName = \"conversation\" | \"entry\" | \"task\" | \"submission\" | \"document\";\ntype RecordIdRow = { readonly record_type: TableName };\ntype JsonRow = { readonly record: string };\ntype EntryJsonRow = { readonly record: string; readonly commit_seq: number };\ntype RevisionRow = {\n\treadonly seq: number;\n\treadonly kind: DocumentContent[\"kind\"];\n\treadonly version: number;\n\treadonly content: string;\n};\ntype IdRow = { readonly id: number };\ntype MetadataRow = { readonly next_id: string; readonly next_seq: number };\ntype DocumentAction = {\n\tcreate?: DocumentCreate;\n\tcopy?: Extract<StorageWrite, { readonly type: \"document.copy\" }>[\"source\"];\n\tcontent?: DocumentContent;\n\tretire: boolean;\n};\ntype ScopeColumns = {\n\treadonly scopeKind: DocumentRecord[\"scope\"][\"kind\"];\n\treadonly ownerId: number;\n};\n\nconst parseJson = <T>(value: string): T => JSON.parse(value) as T;\nconst encodeJson = (value: unknown): string => JSON.stringify(value) as string;\n// Some SQLite bindings replace lone UTF-16 surrogates. JSON encoding keeps indexed identities lossless.\nconst encodeIndexedString = (value: string): string => JSON.stringify(value);\n\nconst cursorId = <I extends Id<string>>(cursor: Cursor | undefined): I | undefined => {\n\tconst after = cursor?.after;\n\tif (after === undefined) return undefined;\n\tif (typeof after !== \"number\" || !Number.isSafeInteger(after))\n\t\tthrow new StorageRequestError(\"Invalid storage cursor\");\n\treturn idFromNumber<I>(after);\n};\n\nconst page = <T extends { readonly id: Id<string> }>(\n\tvalues: readonly T[],\n\tlimit: number,\n\torder: ScanOrder = \"ascending\",\n): Page<T, Cursor> => {\n\tconst items = values.slice(0, limit);\n\tif (values.length <= limit) return { items };\n\treturn { items, next: nextCursor(items.at(-1)!.id, order) };\n};\n\n/** The ID condition, its parameter, and the `ORDER BY` direction of a table scan. */\nconst scanSql = (start: ScanStart): { readonly clause: string; readonly param: number; readonly direction: string } =>\n\tstart.order === \"ascending\"\n\t\t? { clause: \"id > ?\", param: start.after ?? -1, direction: \"ASC\" }\n\t\t: { clause: \"id < ?\", param: start.after ?? Number.MAX_SAFE_INTEGER, direction: \"DESC\" };\n\nconst scopeColumns = (scope: DocumentRecord[\"scope\"]): ScopeColumns => {\n\tswitch (scope.kind) {\n\t\tcase \"session\":\n\t\t\treturn { scopeKind: \"session\", ownerId: 0 };\n\t\tcase \"conversation\":\n\t\t\treturn { scopeKind: \"conversation\", ownerId: scope.conversationId };\n\t\tcase \"task\":\n\t\t\treturn { scopeKind: \"task\", ownerId: scope.taskId };\n\t}\n};\n\nconst addressParts = (address: DocumentAddress | DocumentCreate | DocumentRecord) => {\n\tconst scope = scopeColumns(address.scope);\n\treturn {\n\t\tkind: encodeIndexedString(address.kind),\n\t\t...scope,\n\t\tfamily: address.key === undefined ? 0 : 1,\n\t\tkeyValue: encodeIndexedString(address.key ?? \"\"),\n\t};\n};\n\nconst addressKey = (address: DocumentAddress | DocumentCreate | DocumentRecord): string => {\n\tconst parts = addressParts(address);\n\treturn JSON.stringify([parts.kind, parts.scopeKind, parts.ownerId, parts.family, parts.keyValue]);\n};\n\nconst isAliveAt = (record: DocumentRecord, at: DocumentPoint): boolean => {\n\tif (at === \"current\") return record.retiredAt === undefined;\n\treturn record.createdAt <= at && (record.retiredAt === undefined || at < record.retiredAt);\n};\n\nconst isCurrentOnly = (record: DocumentRecord): boolean =>\n\trecord.scope.kind !== \"conversation\" || record.history === \"latest\";\n\nconst writeId = (write: StorageWrite): Id<string> | undefined => {\n\tswitch (write.type) {\n\t\tcase \"conversation\":\n\t\tcase \"entry\":\n\t\tcase \"task\":\n\t\tcase \"submission\":\n\t\t\treturn write.value.id;\n\t\tcase \"document.create\":\n\t\tcase \"document.copy\":\n\t\t\treturn write.record.id;\n\t\tcase \"document.change\":\n\t\tcase \"document.retire\":\n\t\t\treturn undefined;\n\t}\n};\n\n/** Portable SQLite implementation of the Pico storage contract. */\nexport class SqliteStorage implements Storage {\n\tprivate readonly db: SqliteDatabase;\n\tprivate nextId: number;\n\tprivate closed = false;\n\tprivate closing: Promise<void> | undefined;\n\tprivate admittedReads = 0;\n\tprivate readsDrained: (() => void) | undefined;\n\n\tprivate constructor(db: SqliteDatabase, nextId: number) {\n\t\tthis.db = db;\n\t\tthis.nextId = nextId;\n\t}\n\n\t/** Initialize storage over an owned SQLite database facade. */\n\tstatic async open(db: SqliteDatabase): Promise<SqliteStorage> {\n\t\ttry {\n\t\t\tawait applySqliteMigrations(db);\n\t\t\tconst metadata = await db.get<MetadataRow>(\n\t\t\t\t\"SELECT next_id, next_seq FROM durable_metadata WHERE singleton = 1\",\n\t\t\t);\n\t\t\tif (metadata === undefined) throw new Error(\"Durable SQLite metadata is missing\");\n\t\t\treturn new SqliteStorage(db, Number(metadata.next_id));\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tawait db.close();\n\t\t\t} catch {\n\t\t\t\t// Preserve the initialization failure.\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync commit(writes: readonly StorageWrite[], _context: Context): Promise<Seq> {\n\t\tthis.assertOpen();\n\t\tconst documentActions = this.prepareDocumentActions(writes);\n\t\tconst candidateNextId = this.candidateNextId(writes);\n\t\tconst seq = await this.db.transaction(async (transaction) => {\n\t\t\tconst metadata = await transaction.get<MetadataRow>(\n\t\t\t\t\"SELECT next_id, next_seq FROM durable_metadata WHERE singleton = 1\",\n\t\t\t);\n\t\t\tif (metadata === undefined) throw new Error(\"Durable SQLite metadata is missing\");\n\t\t\tconst committedSeq = seqFromNumber(metadata.next_seq);\n\t\t\tawait this.checkGlobalIds(transaction, writes);\n\t\t\tawait this.checkDocumentActions(transaction, documentActions);\n\t\t\tfor (const write of writes) await this.applyTableWrite(transaction, write, committedSeq);\n\t\t\tawait this.applyDocumentActions(transaction, documentActions, committedSeq);\n\t\t\tawait transaction.run(\n\t\t\t\t\"UPDATE durable_metadata SET next_id = ?, next_seq = ? WHERE singleton = 1\",\n\t\t\t\tString(Math.max(Number(metadata.next_id), candidateNextId)),\n\t\t\t\tcommittedSeq + 1,\n\t\t\t);\n\t\t\treturn committedSeq;\n\t\t});\n\t\tthis.nextId = Math.max(this.nextId, candidateNextId);\n\t\treturn seq;\n\t}\n\n\tasync mintId<I extends Id<string>>(): Promise<I> {\n\t\tthis.assertOpen();\n\t\tif (!Number.isSafeInteger(this.nextId)) throw new Error(\"ID space is exhausted\");\n\t\treturn idFromNumber<I>(this.nextId++);\n\t}\n\n\tasync conversation(id: ConversationId, _context: Context): Promise<ConversationRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM conversations WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<ConversationRecord>(row.record);\n\t}\n\n\tasync scanConversations(\n\t\tquery: ConversationQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<ConversationRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\tconst scan = scanSql(start);\n\t\tconst clauses = [scan.clause];\n\t\tconst params: SqliteValue[] = [scan.param];\n\t\tif (query.ownerConversationId !== undefined) {\n\t\t\tclauses.push(\"owner_conversation_id = ?\");\n\t\t\tparams.push(query.ownerConversationId);\n\t\t}\n\t\tif (query.ownerTaskId !== undefined) {\n\t\t\tclauses.push(\"owner_task_id = ?\");\n\t\t\tparams.push(query.ownerTaskId);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM conversations WHERE ${clauses.join(\" AND \")} ORDER BY id ${scan.direction} LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<ConversationRecord>(row.record)),\n\t\t\tlimit,\n\t\t\tstart.order,\n\t\t);\n\t}\n\n\tentry(id: EntryId, context: Context): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tentry(\n\t\tconversationId: ConversationId,\n\t\tid: EntryId,\n\t\tcontext: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tentry(\n\t\tidOrConversationId: EntryId | ConversationId,\n\t\tidOrContext: EntryId | Context,\n\t\tcontext?: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined> {\n\t\treturn this.admitRead(() => this.readEntry(idOrConversationId, idOrContext, context));\n\t}\n\n\tfindLatestHeadMarker(\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t\t_context: Context,\n\t): Promise<(EntryRecord & { readonly head: EntryId }) | undefined> {\n\t\treturn this.admitRead(() => this.readLatestHeadMarker(conversationId, atOrBeforeEntryId));\n\t}\n\n\tscanEntries(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\treturn this.admitRead(() => this.readEntries(query, limit, cursor));\n\t}\n\n\tprivate async readEntry(\n\t\tidOrConversationId: EntryId | ConversationId,\n\t\tidOrContext: EntryId | Context,\n\t\tcontext?: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined> {\n\t\tconst id =\n\t\t\tcontext === undefined\n\t\t\t\t? idFromNumber<EntryId>(idOrConversationId)\n\t\t\t\t: typeof idOrContext === \"number\"\n\t\t\t\t\t? idFromNumber<EntryId>(idOrContext)\n\t\t\t\t\t: undefined;\n\t\tif (id === undefined) throw new StorageRequestError(\"Storage.entry() requires an entry ID\");\n\t\tlet conversation: ConversationRecord | undefined;\n\t\tif (context !== undefined) {\n\t\t\tconst conversationId = idFromNumber<ConversationId>(idOrConversationId);\n\t\t\tconversation = await this.readConversation(conversationId);\n\t\t\tif (conversation === undefined) throw new StorageRequestError(`Unknown conversation: ${conversationId}`);\n\t\t}\n\t\tconst row = await this.db.get<EntryJsonRow>(\"SELECT record, commit_seq FROM entries WHERE id = ?\", id);\n\t\tif (row === undefined) return undefined;\n\t\tconst entry = parseJson<EntryRecord>(row.record);\n\t\tif (conversation !== undefined) {\n\t\t\tlet upperEntryId = Number.POSITIVE_INFINITY;\n\t\t\twhile (conversation.id !== entry.conversationId) {\n\t\t\t\tif (conversation.parent === undefined) return undefined;\n\t\t\t\tupperEntryId = Math.min(upperEntryId, conversation.parent.at);\n\t\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t\t}\n\t\t\tif (entry.id > upperEntryId) return undefined;\n\t\t}\n\t\treturn { entry, commitSeq: seqFromNumber(row.commit_seq) };\n\t}\n\n\tprivate async readLatestHeadMarker(\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t): Promise<(EntryRecord & { readonly head: EntryId }) | undefined> {\n\t\tlet conversation = await this.readConversation(conversationId);\n\t\tif (conversation === undefined) throw new StorageRequestError(`Unknown conversation: ${conversationId}`);\n\t\tlet upper: number | undefined = atOrBeforeEntryId;\n\t\twhile (true) {\n\t\t\tconst row =\n\t\t\t\tupper === undefined\n\t\t\t\t\t? await this.db.get<JsonRow>(\n\t\t\t\t\t\t\t\"SELECT record FROM entries WHERE conversation_id = ? AND head IS NOT NULL ORDER BY id DESC LIMIT 1\",\n\t\t\t\t\t\t\tconversation.id,\n\t\t\t\t\t\t)\n\t\t\t\t\t: await this.db.get<JsonRow>(\n\t\t\t\t\t\t\t\"SELECT record FROM entries WHERE conversation_id = ? AND head IS NOT NULL AND id <= ? ORDER BY id DESC LIMIT 1\",\n\t\t\t\t\t\t\tconversation.id,\n\t\t\t\t\t\t\tupper,\n\t\t\t\t\t\t);\n\t\t\tif (row !== undefined) return parseJson<EntryRecord & { readonly head: EntryId }>(row.record);\n\t\t\tif (conversation.parent === undefined) return undefined;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t}\n\t}\n\n\tprivate async readEntries(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\tconst { order, after } = scanStart(query.order, cursor, \"descending\");\n\t\tif (order === \"ascending\") return this.readEntriesAscending(query, limit, after);\n\t\tlet conversation = await this.readConversation(query.conversationId);\n\t\tif (conversation === undefined) throw new StorageRequestError(`Unknown conversation: ${query.conversationId}`);\n\t\tlet upper: number | undefined = query.maxEntryId;\n\t\tif (after !== undefined) upper = Math.min(upper ?? Number.MAX_SAFE_INTEGER, after - 1);\n\t\tconst values: EntryRecord[] = [];\n\t\twhile (true) {\n\t\t\tconst clauses = [\"conversation_id = ?\"];\n\t\t\tconst params: SqliteValue[] = [conversation.id];\n\t\t\tif (query.minEntryId !== undefined) {\n\t\t\t\tclauses.push(\"id >= ?\");\n\t\t\t\tparams.push(query.minEntryId);\n\t\t\t}\n\t\t\tif (upper !== undefined) {\n\t\t\t\tclauses.push(\"id <= ?\");\n\t\t\t\tparams.push(upper);\n\t\t\t}\n\t\t\tparams.push(limit + 1 - values.length);\n\t\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t\t`SELECT record FROM entries WHERE ${clauses.join(\" AND \")} ORDER BY id DESC LIMIT ?`,\n\t\t\t\t...params,\n\t\t\t);\n\t\t\tvalues.push(...rows.map((row) => parseJson<EntryRecord>(row.record)));\n\t\t\tif (values.length > limit || conversation.parent === undefined) break;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tif (query.minEntryId !== undefined && upper < query.minEntryId) break;\n\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t}\n\t\treturn page(values, limit, \"descending\");\n\t}\n\n\t/** Oldest first: the fork chain's segments from the root conversation forward, each up to its fork point. */\n\tprivate async readEntriesAscending(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tafter: number | undefined,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\tconst segments: { readonly conversationId: ConversationId; readonly upper: number | undefined }[] = [];\n\t\tlet conversation = await this.readConversation(query.conversationId);\n\t\tif (conversation === undefined) throw new StorageRequestError(`Unknown conversation: ${query.conversationId}`);\n\t\tlet upper: number | undefined = query.maxEntryId;\n\t\twhile (true) {\n\t\t\tsegments.push({ conversationId: conversation.id, upper });\n\t\t\tif (conversation.parent === undefined) break;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tif (query.minEntryId !== undefined && upper < query.minEntryId) break;\n\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t}\n\t\tlet lower: number | undefined = query.minEntryId;\n\t\tif (after !== undefined) lower = Math.max(lower ?? after + 1, after + 1);\n\t\tconst values: EntryRecord[] = [];\n\t\tfor (const segment of segments.reverse()) {\n\t\t\tconst clauses = [\"conversation_id = ?\"];\n\t\t\tconst params: SqliteValue[] = [segment.conversationId];\n\t\t\tif (lower !== undefined) {\n\t\t\t\tclauses.push(\"id >= ?\");\n\t\t\t\tparams.push(lower);\n\t\t\t}\n\t\t\tif (segment.upper !== undefined) {\n\t\t\t\tclauses.push(\"id <= ?\");\n\t\t\t\tparams.push(segment.upper);\n\t\t\t}\n\t\t\tparams.push(limit + 1 - values.length);\n\t\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t\t`SELECT record FROM entries WHERE ${clauses.join(\" AND \")} ORDER BY id ASC LIMIT ?`,\n\t\t\t\t...params,\n\t\t\t);\n\t\t\tvalues.push(...rows.map((row) => parseJson<EntryRecord>(row.record)));\n\t\t\tif (values.length > limit) break;\n\t\t}\n\t\treturn page(values, limit, \"ascending\");\n\t}\n\n\tasync task(id: TaskId, _context: Context): Promise<StoredTask | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM tasks WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<StoredTask>(row.record);\n\t}\n\n\tasync scanTasks(\n\t\tquery: TaskQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<StoredTask, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\tconst scan = scanSql(start);\n\t\tconst clauses = [scan.clause];\n\t\tconst params: SqliteValue[] = [scan.param];\n\t\tif (query.conversationId !== undefined) {\n\t\t\tclauses.push(\"conversation_id = ?\");\n\t\t\tparams.push(query.conversationId);\n\t\t}\n\t\tif (query.kind !== undefined) {\n\t\t\tclauses.push(\"kind = ?\");\n\t\t\tparams.push(encodeIndexedString(query.kind));\n\t\t}\n\t\tif (query.status !== undefined) {\n\t\t\tclauses.push(\"status = ?\");\n\t\t\tparams.push(query.status);\n\t\t}\n\t\tif (query.abortRequested !== undefined) {\n\t\t\tclauses.push(\"abort_requested = ?\");\n\t\t\tparams.push(query.abortRequested ? 1 : 0);\n\t\t}\n\t\tif (query.background !== undefined) {\n\t\t\tclauses.push(\"background = ?\");\n\t\t\tparams.push(query.background ? 1 : 0);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM tasks WHERE ${clauses.join(\" AND \")} ORDER BY id ${scan.direction} LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<StoredTask>(row.record)),\n\t\t\tlimit,\n\t\t\tstart.order,\n\t\t);\n\t}\n\n\tasync submission(id: SubmissionId, _context: Context): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM submissions WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<SubmissionRecord>(row.record);\n\t}\n\n\tasync scanSubmissions(\n\t\tquery: SubmissionQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<SubmissionRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\tconst scan = scanSql(start);\n\t\tconst clauses = [scan.clause];\n\t\tconst params: SqliteValue[] = [scan.param];\n\t\tif (query.conversationId !== undefined) {\n\t\t\tclauses.push(\"conversation_id = ?\");\n\t\t\tparams.push(query.conversationId);\n\t\t}\n\t\tif (query.status !== undefined) {\n\t\t\tclauses.push(\"status = ?\");\n\t\t\tparams.push(query.status);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM submissions WHERE ${clauses.join(\" AND \")} ORDER BY id ${scan.direction} LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<SubmissionRecord>(row.record)),\n\t\t\tlimit,\n\t\t\tstart.order,\n\t\t);\n\t}\n\n\tasync submissionByRequest(\n\t\tconversationId: ConversationId,\n\t\trequestId: string,\n\t\t_context: Context,\n\t): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\n\t\t\t\"SELECT record FROM submissions WHERE conversation_id = ? AND request_id = ?\",\n\t\t\tconversationId,\n\t\t\tencodeIndexedString(requestId),\n\t\t);\n\t\treturn row === undefined ? undefined : parseJson<SubmissionRecord>(row.record);\n\t}\n\n\tasync findDocument(\n\t\taddress: DocumentAddress,\n\t\tat: DocumentPoint,\n\t\t_context: Context,\n\t): Promise<DocumentRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst parts = addressParts(address);\n\t\tconst sql =\n\t\t\tat === \"current\"\n\t\t\t\t? `SELECT record FROM documents\n\t\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ?\n\t\t\t\t\tAND retired_at IS NULL ORDER BY created_at DESC LIMIT 1`\n\t\t\t\t: `SELECT record FROM documents\n\t\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ?\n\t\t\t\t\tAND created_at <= ? AND (retired_at IS NULL OR retired_at > ?)\n\t\t\t\t\tORDER BY created_at DESC LIMIT 1`;\n\t\tconst params: SqliteValue[] = [parts.kind, parts.scopeKind, parts.ownerId, parts.family, parts.keyValue];\n\t\tif (at !== \"current\") params.push(at, at);\n\t\tconst row = await this.db.get<JsonRow>(sql, ...params);\n\t\treturn row === undefined ? undefined : parseJson<DocumentRecord>(row.record);\n\t}\n\n\tasync document(id: DocumentId, at: DocumentPoint, _context: Context): Promise<StoredDocument | undefined> {\n\t\tthis.assertOpen();\n\t\t// The record and revision queries must observe one committed state; a commit between them can replace the base.\n\t\treturn this.db.transaction((transaction) => this.materializeDocument(transaction, id, at));\n\t}\n\n\tasync scanDocuments(\n\t\tquery: DocumentQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<DocumentRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst scope = scopeColumns(query.scope);\n\t\tconst clauses = [\"scope_kind = ?\", \"owner_id = ?\", \"id > ?\"];\n\t\tconst params: SqliteValue[] = [scope.scopeKind, scope.ownerId, cursorId(cursor) ?? -1];\n\t\tif (query.kind !== undefined) {\n\t\t\tclauses.push(\"kind = ?\");\n\t\t\tparams.push(encodeIndexedString(query.kind));\n\t\t}\n\t\tif (query.at === \"current\") {\n\t\t\tclauses.push(\"retired_at IS NULL\");\n\t\t} else {\n\t\t\tclauses.push(\"created_at <= ?\", \"(retired_at IS NULL OR retired_at > ?)\");\n\t\t\tparams.push(query.at, query.at);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM documents WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<DocumentRecord>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closing === undefined) {\n\t\t\tthis.closed = true;\n\t\t\tthis.closing = this.closeDatabase();\n\t\t}\n\t\treturn this.closing;\n\t}\n\n\tprivate async closeDatabase(): Promise<void> {\n\t\tif (this.admittedReads > 0) {\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tthis.readsDrained = resolve;\n\t\t\t});\n\t\t}\n\t\tawait this.db.close();\n\t}\n\n\t/**\n\t * Run a read that issues several queries. Close waits for admitted reads, so their later queries never reach a\n\t * closed database. Single-query reads and transactions are already ordered before close by the database.\n\t */\n\tprivate async admitRead<T>(read: () => Promise<T>): Promise<T> {\n\t\tthis.assertOpen();\n\t\tthis.admittedReads++;\n\t\ttry {\n\t\t\treturn await read();\n\t\t} finally {\n\t\t\tif (--this.admittedReads === 0) this.readsDrained?.();\n\t\t}\n\t}\n\n\tprivate async readConversation(id: ConversationId): Promise<ConversationRecord | undefined> {\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM conversations WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<ConversationRecord>(row.record);\n\t}\n\n\tprivate async materializeDocument(\n\t\texecutor: SqliteExecutor,\n\t\tid: DocumentId,\n\t\tat: DocumentPoint,\n\t): Promise<StoredDocument | undefined> {\n\t\tconst row = await executor.get<JsonRow>(\"SELECT record FROM documents WHERE id = ?\", id);\n\t\tif (row === undefined) return undefined;\n\t\tconst record = parseJson<DocumentRecord>(row.record);\n\t\tif (at !== \"current\" && isCurrentOnly(record)) {\n\t\t\tthrow new StorageRequestError(`Document ${id} does not retain historical content`);\n\t\t}\n\t\tif (!isAliveAt(record, at)) return undefined;\n\t\tconst upper = at === \"current\" ? Number.MAX_SAFE_INTEGER : at;\n\t\tconst base = await executor.get<RevisionRow>(\n\t\t\t`SELECT seq, kind, version, content FROM document_revisions\n\t\t\t\tWHERE document_id = ? AND kind = 'base' AND seq <= ? ORDER BY seq DESC LIMIT 1`,\n\t\t\tid,\n\t\t\tupper,\n\t\t);\n\t\tif (base === undefined) throw new Error(`Document ${id} is missing a required base`);\n\t\tlet value = parseJson<JsonObject>(base.content);\n\t\tconst tail = await executor.all<RevisionRow>(\n\t\t\t`SELECT seq, kind, version, content FROM document_revisions\n\t\t\t\tWHERE document_id = ? AND seq > ? AND seq <= ? ORDER BY seq`,\n\t\t\tid,\n\t\t\tbase.seq,\n\t\t\tupper,\n\t\t);\n\t\tfor (const revision of tail) {\n\t\t\tif (revision.kind !== \"delta\" || revision.version !== base.version) {\n\t\t\t\tthrow new Error(`Document ${id} crosses a stored version boundary without a base`);\n\t\t\t}\n\t\t\tvalue = apply(value, parseJson<readonly Op[]>(revision.content)) as JsonObject;\n\t\t}\n\t\treturn { record, version: base.version, value, deltasSinceBase: tail.length };\n\t}\n\n\tprivate candidateNextId(writes: readonly StorageWrite[]): number {\n\t\tlet nextId = this.nextId;\n\t\tfor (const write of writes) {\n\t\t\tconst id = writeId(write);\n\t\t\tif (id !== undefined) nextId = Math.max(nextId, id + 1);\n\t\t}\n\t\treturn nextId;\n\t}\n\n\tprivate async checkGlobalIds(executor: SqliteExecutor, writes: readonly StorageWrite[]): Promise<void> {\n\t\tconst claimed = new Map<Id<string>, TableName>();\n\t\tfor (const write of writes) {\n\t\t\tif (write.type === \"document.change\" || write.type === \"document.retire\") continue;\n\t\t\tconst document = write.type === \"document.create\" || write.type === \"document.copy\";\n\t\t\tconst table: TableName = document ? \"document\" : write.type;\n\t\t\tconst id = document ? write.record.id : write.value.id;\n\t\t\tconst existing = (await executor.get<RecordIdRow>(\"SELECT record_type FROM record_ids WHERE id = ?\", id))\n\t\t\t\t?.record_type;\n\t\t\tconst earlier = claimed.get(id);\n\t\t\tif (table === \"conversation\" || table === \"entry\" || table === \"document\") {\n\t\t\t\tif (existing !== undefined) throw new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\tif (earlier !== undefined) throw new Error(`ID ${id} is written more than once`);\n\t\t\t} else {\n\t\t\t\tif (existing !== undefined && existing !== table)\n\t\t\t\t\tthrow new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\tif (earlier !== undefined && earlier !== table) throw new Error(`ID ${id} is written as two record types`);\n\t\t\t}\n\t\t\tclaimed.set(id, table);\n\t\t}\n\t}\n\n\tprivate prepareDocumentActions(writes: readonly StorageWrite[]): Map<DocumentId, DocumentAction> {\n\t\tconst actions = new Map<DocumentId, DocumentAction>();\n\t\tfor (const write of writes) {\n\t\t\tif (\n\t\t\t\twrite.type !== \"document.create\" &&\n\t\t\t\twrite.type !== \"document.copy\" &&\n\t\t\t\twrite.type !== \"document.change\" &&\n\t\t\t\twrite.type !== \"document.retire\"\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst id = write.type === \"document.create\" || write.type === \"document.copy\" ? write.record.id : write.id;\n\t\t\tlet action = actions.get(id);\n\t\t\tif (action === undefined) {\n\t\t\t\taction = { retire: false };\n\t\t\t\tactions.set(id, action);\n\t\t\t}\n\t\t\tswitch (write.type) {\n\t\t\t\tcase \"document.create\":\n\t\t\t\t\tif (action.create !== undefined || action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.create = write.record;\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.copy\":\n\t\t\t\t\tif (action.create !== undefined || action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.create = write.record;\n\t\t\t\t\taction.copy = write.source;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.change\":\n\t\t\t\t\tif (action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.retire\":\n\t\t\t\t\tif (action.retire) throw new Error(`Document ${id} is retired more than once`);\n\t\t\t\t\taction.retire = true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn actions;\n\t}\n\n\tprivate async checkDocumentActions(\n\t\texecutor: SqliteExecutor,\n\t\tactions: ReadonlyMap<DocumentId, DocumentAction>,\n\t): Promise<void> {\n\t\tconst liveCounts = new Map<string, number>();\n\t\tfor (const [id, action] of actions) {\n\t\t\tif (action.copy !== undefined && actions.has(action.copy.id)) {\n\t\t\t\tthrow new Error(`Document copy ${id} source is changed in the copy batch`);\n\t\t\t}\n\t\t\tconst row = await executor.get<JsonRow>(\"SELECT record FROM documents WHERE id = ?\", id);\n\t\t\tconst existing = row === undefined ? undefined : parseJson<DocumentRecord>(row.record);\n\t\t\tif (action.create === undefined && existing === undefined) throw new Error(`Unknown document: ${id}`);\n\t\t\tif (action.create !== undefined && existing !== undefined) throw new Error(`Document ${id} already exists`);\n\t\t\tif (existing?.retiredAt !== undefined) throw new Error(`Document ${id} is retired`);\n\t\t\tif (action.content?.kind === \"delta\") {\n\t\t\t\tconst previous = await executor.get<{ readonly version: number }>(\n\t\t\t\t\t\"SELECT version FROM document_revisions WHERE document_id = ? ORDER BY seq DESC LIMIT 1\",\n\t\t\t\t\tid,\n\t\t\t\t);\n\t\t\t\tif (previous === undefined) throw new Error(`Document ${id} delta has no base`);\n\t\t\t\tif (previous.version !== action.content.version) {\n\t\t\t\t\tthrow new Error(`Document ${id} version transition requires a base`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst record = action.create ?? existing!;\n\t\t\tconst key = addressKey(record);\n\t\t\tlet live = liveCounts.get(key);\n\t\t\tif (live === undefined) live = (await this.currentDocumentId(executor, record)) === undefined ? 0 : 1;\n\t\t\tif (action.retire && existing !== undefined) live--;\n\t\t\tif (action.create !== undefined && !action.retire) live++;\n\t\t\tliveCounts.set(key, live);\n\t\t}\n\t\tfor (const live of liveCounts.values()) {\n\t\t\tif (live > 1) throw new Error(\"Document address already has a current incarnation\");\n\t\t}\n\t}\n\n\tprivate async currentDocumentId(\n\t\texecutor: SqliteExecutor,\n\t\taddress: DocumentAddress | DocumentCreate | DocumentRecord,\n\t): Promise<DocumentId | undefined> {\n\t\tconst parts = addressParts(address);\n\t\tconst id = (\n\t\t\tawait executor.get<IdRow>(\n\t\t\t\t`SELECT id FROM documents\n\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ? AND retired_at IS NULL\n\t\t\t\tLIMIT 1`,\n\t\t\t\tparts.kind,\n\t\t\t\tparts.scopeKind,\n\t\t\t\tparts.ownerId,\n\t\t\t\tparts.family,\n\t\t\t\tparts.keyValue,\n\t\t\t)\n\t\t)?.id;\n\t\treturn id === undefined ? undefined : idFromNumber<DocumentId>(id);\n\t}\n\n\tprivate async applyTableWrite(executor: SqliteExecutor, write: StorageWrite, seq: Seq): Promise<void> {\n\t\tswitch (write.type) {\n\t\t\tcase \"conversation\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"conversation\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t\"INSERT INTO conversations (id, owner_conversation_id, owner_task_id, record) VALUES (?, ?, ?, ?)\",\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.owner?.conversationId ?? null,\n\t\t\t\t\twrite.value.owner?.taskId ?? null,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"entry\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"entry\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t\"INSERT INTO entries (id, conversation_id, head, commit_seq, record) VALUES (?, ?, ?, ?, ?)\",\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\twrite.value.head ?? null,\n\t\t\t\t\tseq,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"task\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"task\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO tasks (id, conversation_id, kind, status, abort_requested, background, record)\n\t\t\t\t\t\tVALUES (?, ?, ?, ?, ?, ?, ?)\n\t\t\t\t\t\tON CONFLICT(id) DO UPDATE SET conversation_id = excluded.conversation_id, kind = excluded.kind,\n\t\t\t\t\t\tstatus = excluded.status, abort_requested = excluded.abort_requested,\n\t\t\t\t\t\tbackground = excluded.background, record = excluded.record`,\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\tencodeIndexedString(write.value.kind),\n\t\t\t\t\twrite.value.state.status,\n\t\t\t\t\twrite.value.abortRequested ? 1 : 0,\n\t\t\t\t\twrite.value.background ? 1 : 0,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"submission\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"submission\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO submissions (id, conversation_id, request_id, status, record) VALUES (?, ?, ?, ?, ?)\n\t\t\t\t\t\tON CONFLICT(id) DO UPDATE SET conversation_id = excluded.conversation_id,\n\t\t\t\t\t\trequest_id = excluded.request_id, status = excluded.status, record = excluded.record`,\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\twrite.value.requestId === undefined ? null : encodeIndexedString(write.value.requestId),\n\t\t\t\t\twrite.value.status,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"document.create\":\n\t\t\tcase \"document.copy\":\n\t\t\tcase \"document.change\":\n\t\t\tcase \"document.retire\":\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate async claimId(executor: SqliteExecutor, id: Id<string>, table: TableName): Promise<void> {\n\t\tawait executor.run(\"INSERT OR IGNORE INTO record_ids (id, record_type) VALUES (?, ?)\", id, table);\n\t}\n\n\tprivate async applyDocumentActions(\n\t\texecutor: SqliteExecutor,\n\t\tactions: ReadonlyMap<DocumentId, DocumentAction>,\n\t\tseq: Seq,\n\t): Promise<void> {\n\t\tfor (const [id, action] of actions) {\n\t\t\tlet content = action.content;\n\t\t\tif (action.copy !== undefined) {\n\t\t\t\ttry {\n\t\t\t\t\tconst stored = await this.materializeDocument(executor, action.copy.id, action.copy.at);\n\t\t\t\t\tif (stored === undefined) throw new Error(`Fork source document ${action.copy.id} cannot be read`);\n\t\t\t\t\tconst create = action.create!;\n\t\t\t\t\tif (\n\t\t\t\t\t\tstored.record.scope.kind !== \"conversation\" ||\n\t\t\t\t\t\tcreate.scope.kind !== \"conversation\" ||\n\t\t\t\t\t\tstored.record.kind !== create.kind ||\n\t\t\t\t\t\tstored.record.key !== create.key ||\n\t\t\t\t\t\tstored.record.history !== create.history ||\n\t\t\t\t\t\tstored.record.fork !== create.fork\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new Error(`Fork source document ${action.copy.id} does not match the copied record`);\n\t\t\t\t\t}\n\t\t\t\t\tcontent = { kind: \"base\", version: stored.version, value: stored.value };\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow new Error(`Document copy ${id} was rejected`, { cause: error });\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet record: DocumentRecord;\n\t\t\tif (action.create !== undefined) {\n\t\t\t\trecord = {\n\t\t\t\t\t...action.create,\n\t\t\t\t\tcreatedAt: seq,\n\t\t\t\t\t...(action.retire ? { retiredAt: seq } : {}),\n\t\t\t\t};\n\t\t\t\tconst parts = addressParts(record);\n\t\t\t\tawait this.claimId(executor, id, \"document\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO documents\n\t\t\t\t\t\t(id, kind, family, key_value, scope_kind, owner_id, created_at, retired_at, record)\n\t\t\t\t\t\tVALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t\t\t\tid,\n\t\t\t\t\tparts.kind,\n\t\t\t\t\tparts.family,\n\t\t\t\t\tparts.keyValue,\n\t\t\t\t\tparts.scopeKind,\n\t\t\t\t\tparts.ownerId,\n\t\t\t\t\tseq,\n\t\t\t\t\taction.retire ? seq : null,\n\t\t\t\t\tencodeJson(record),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst row = (await executor.get<JsonRow>(\"SELECT record FROM documents WHERE id = ?\", id))!;\n\t\t\t\trecord = parseJson<DocumentRecord>(row.record);\n\t\t\t}\n\n\t\t\tif (content !== undefined) {\n\t\t\t\tif (content.kind === \"base\" && isCurrentOnly(record)) {\n\t\t\t\t\tawait executor.run(\"DELETE FROM document_revisions WHERE document_id = ?\", id);\n\t\t\t\t}\n\t\t\t\tconst encodedContent = content.kind === \"base\" ? encodeJson(content.value) : encodeJson(content.ops);\n\t\t\t\tawait executor.run(\n\t\t\t\t\t\"INSERT INTO document_revisions (document_id, seq, kind, version, content) VALUES (?, ?, ?, ?, ?)\",\n\t\t\t\t\tid,\n\t\t\t\t\tseq,\n\t\t\t\t\tcontent.kind,\n\t\t\t\t\tcontent.version,\n\t\t\t\t\tencodedContent,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (action.retire) {\n\t\t\t\tif (action.create === undefined) {\n\t\t\t\t\trecord = { ...record, retiredAt: seq };\n\t\t\t\t\tawait executor.run(\n\t\t\t\t\t\t\"UPDATE documents SET retired_at = ?, record = ? WHERE id = ?\",\n\t\t\t\t\t\tseq,\n\t\t\t\t\t\tencodeJson(record),\n\t\t\t\t\t\tid,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (isCurrentOnly(record)) {\n\t\t\t\t\tawait executor.run(\"DELETE FROM document_revisions WHERE document_id = ?\", id);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"SqliteStorage is closed\");\n\t}\n}\n"]}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/storage/sqlite/storage.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, JsonValue } from \"@earendil-works/chord\";\nimport { apply, type Op } from \"@earendil-works/chord/delta\";\nimport { StorageRequestError } from \"../../errors.ts\";\nimport { idFromNumber, seqFromNumber } from \"../../ids.ts\";\nimport type {\n\tConversationId,\n\tConversationQuery,\n\tConversationRecord,\n\tCursor,\n\tDocumentAddress,\n\tDocumentContent,\n\tDocumentCreate,\n\tDocumentId,\n\tDocumentPoint,\n\tDocumentQuery,\n\tDocumentRecord,\n\tEntryId,\n\tEntryQuery,\n\tEntryRecord,\n\tId,\n\tJsonObject,\n\tPage,\n\tScanOrder,\n\tSeq,\n\tStorage,\n\tStorageWrite,\n\tStoredDocument,\n\tSubmissionId,\n\tSubmissionQuery,\n\tSubmissionRecord,\n\tTaskId,\n\tTaskQuery,\n\tTaskRecord,\n} from \"../../types.ts\";\nimport { nextCursor, type ScanStart, scanStart } from \"../scan.ts\";\nimport type { SqliteDatabase, SqliteExecutor, SqliteValue } from \"./database.ts\";\nimport { applySqliteMigrationsForSchema } from \"./migrations.ts\";\nimport { createSqliteSchema, type SqliteSchema } from \"./schema.ts\";\n\ntype StoredTask = TaskRecord<JsonValue, JsonValue, JsonValue>;\ntype TableName = \"conversation\" | \"entry\" | \"task\" | \"submission\" | \"document\";\ntype RecordIdRow = { readonly record_type: TableName };\ntype JsonRow = { readonly record: string };\ntype EntryJsonRow = { readonly record: string; readonly commit_seq: number };\ntype RevisionRow = {\n\treadonly seq: number;\n\treadonly kind: DocumentContent[\"kind\"];\n\treadonly version: number;\n\treadonly content: string;\n};\ntype IdRow = { readonly id: number };\ntype MetadataRow = { readonly next_id: string; readonly next_seq: number };\ntype DocumentAction = {\n\tcreate?: DocumentCreate;\n\tcopy?: Extract<StorageWrite, { readonly type: \"document.copy\" }>[\"source\"];\n\tcontent?: DocumentContent;\n\tretire: boolean;\n};\ntype ScopeColumns = {\n\treadonly scopeKind: DocumentRecord[\"scope\"][\"kind\"];\n\treadonly ownerId: number;\n};\n\nexport type SqliteStorageOptions = {\n\t/**\n\t * Prefix for every table and index in the durable schema. It must be a SQLite identifier and must not use\n\t * SQLite's reserved `sqlite_` prefix. Existing data is not migrated when this changes.\n\t */\n\treadonly prefix?: string;\n};\n\nconst parseJson = <T>(value: string): T => JSON.parse(value) as T;\nconst encodeJson = (value: unknown): string => JSON.stringify(value) as string;\n// Some SQLite bindings replace lone UTF-16 surrogates. JSON encoding keeps indexed identities lossless.\nconst encodeIndexedString = (value: string): string => JSON.stringify(value);\n\nconst cursorId = <I extends Id<string>>(cursor: Cursor | undefined): I | undefined => {\n\tconst after = cursor?.after;\n\tif (after === undefined) return undefined;\n\tif (typeof after !== \"number\" || !Number.isSafeInteger(after))\n\t\tthrow new StorageRequestError(\"Invalid storage cursor\");\n\treturn idFromNumber<I>(after);\n};\n\nconst page = <T extends { readonly id: Id<string> }>(\n\tvalues: readonly T[],\n\tlimit: number,\n\torder: ScanOrder = \"ascending\",\n): Page<T, Cursor> => {\n\tconst items = values.slice(0, limit);\n\tif (values.length <= limit) return { items };\n\treturn { items, next: nextCursor(items.at(-1)!.id, order) };\n};\n\n/** The ID condition, its parameter, and the `ORDER BY` direction of a table scan. */\nconst scanSql = (start: ScanStart): { readonly clause: string; readonly param: number; readonly direction: string } =>\n\tstart.order === \"ascending\"\n\t\t? { clause: \"id > ?\", param: start.after ?? -1, direction: \"ASC\" }\n\t\t: { clause: \"id < ?\", param: start.after ?? Number.MAX_SAFE_INTEGER, direction: \"DESC\" };\n\nconst scopeColumns = (scope: DocumentRecord[\"scope\"]): ScopeColumns => {\n\tswitch (scope.kind) {\n\t\tcase \"session\":\n\t\t\treturn { scopeKind: \"session\", ownerId: 0 };\n\t\tcase \"conversation\":\n\t\t\treturn { scopeKind: \"conversation\", ownerId: scope.conversationId };\n\t\tcase \"task\":\n\t\t\treturn { scopeKind: \"task\", ownerId: scope.taskId };\n\t}\n};\n\nconst addressParts = (address: DocumentAddress | DocumentCreate | DocumentRecord) => {\n\tconst scope = scopeColumns(address.scope);\n\treturn {\n\t\tkind: encodeIndexedString(address.kind),\n\t\t...scope,\n\t\tfamily: address.key === undefined ? 0 : 1,\n\t\tkeyValue: encodeIndexedString(address.key ?? \"\"),\n\t};\n};\n\nconst addressKey = (address: DocumentAddress | DocumentCreate | DocumentRecord): string => {\n\tconst parts = addressParts(address);\n\treturn JSON.stringify([parts.kind, parts.scopeKind, parts.ownerId, parts.family, parts.keyValue]);\n};\n\nconst isAliveAt = (record: DocumentRecord, at: DocumentPoint): boolean => {\n\tif (at === \"current\") return record.retiredAt === undefined;\n\treturn record.createdAt <= at && (record.retiredAt === undefined || at < record.retiredAt);\n};\n\nconst isCurrentOnly = (record: DocumentRecord): boolean =>\n\trecord.scope.kind !== \"conversation\" || record.history === \"latest\";\n\nconst writeId = (write: StorageWrite): Id<string> | undefined => {\n\tswitch (write.type) {\n\t\tcase \"conversation\":\n\t\tcase \"entry\":\n\t\tcase \"task\":\n\t\tcase \"submission\":\n\t\t\treturn write.value.id;\n\t\tcase \"document.create\":\n\t\tcase \"document.copy\":\n\t\t\treturn write.record.id;\n\t\tcase \"document.change\":\n\t\tcase \"document.retire\":\n\t\t\treturn undefined;\n\t}\n};\n\n/** Portable SQLite implementation of the Pico storage contract. */\nexport class SqliteStorage implements Storage {\n\tprivate readonly db: SqliteDatabase;\n\tprivate readonly schema: SqliteSchema;\n\tprivate nextId: number;\n\tprivate closed = false;\n\tprivate closing: Promise<void> | undefined;\n\tprivate admittedReads = 0;\n\tprivate readsDrained: (() => void) | undefined;\n\n\tprivate constructor(db: SqliteDatabase, schema: SqliteSchema, nextId: number) {\n\t\tthis.db = db;\n\t\tthis.schema = schema;\n\t\tthis.nextId = nextId;\n\t}\n\n\t/** Initialize storage over an owned SQLite database facade. */\n\tstatic async open(db: SqliteDatabase, options: SqliteStorageOptions = {}): Promise<SqliteStorage> {\n\t\ttry {\n\t\t\tconst schema = createSqliteSchema(options.prefix);\n\t\t\tawait applySqliteMigrationsForSchema(db, schema);\n\t\t\tconst metadata = await db.get<MetadataRow>(\n\t\t\t\t`SELECT next_id, next_seq FROM ${schema.tables.durableMetadata} WHERE singleton = 1`,\n\t\t\t);\n\t\t\tif (metadata === undefined) throw new Error(\"Durable SQLite metadata is missing\");\n\t\t\treturn new SqliteStorage(db, schema, Number(metadata.next_id));\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tawait db.close();\n\t\t\t} catch {\n\t\t\t\t// Preserve the initialization failure.\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync commit(writes: readonly StorageWrite[], _context: Context): Promise<Seq> {\n\t\tthis.assertOpen();\n\t\tconst documentActions = this.prepareDocumentActions(writes);\n\t\tconst candidateNextId = this.candidateNextId(writes);\n\t\tconst seq = await this.db.transaction(async (transaction) => {\n\t\t\tconst metadata = await transaction.get<MetadataRow>(\n\t\t\t\t`SELECT next_id, next_seq FROM ${this.schema.tables.durableMetadata} WHERE singleton = 1`,\n\t\t\t);\n\t\t\tif (metadata === undefined) throw new Error(\"Durable SQLite metadata is missing\");\n\t\t\tconst committedSeq = seqFromNumber(metadata.next_seq);\n\t\t\tawait this.checkGlobalIds(transaction, writes);\n\t\t\tawait this.checkDocumentActions(transaction, documentActions);\n\t\t\tfor (const write of writes) await this.applyTableWrite(transaction, write, committedSeq);\n\t\t\tawait this.applyDocumentActions(transaction, documentActions, committedSeq);\n\t\t\tawait transaction.run(\n\t\t\t\t`UPDATE ${this.schema.tables.durableMetadata} SET next_id = ?, next_seq = ? WHERE singleton = 1`,\n\t\t\t\tString(Math.max(Number(metadata.next_id), candidateNextId)),\n\t\t\t\tcommittedSeq + 1,\n\t\t\t);\n\t\t\treturn committedSeq;\n\t\t});\n\t\tthis.nextId = Math.max(this.nextId, candidateNextId);\n\t\treturn seq;\n\t}\n\n\tasync mintId<I extends Id<string>>(): Promise<I> {\n\t\tthis.assertOpen();\n\t\tif (!Number.isSafeInteger(this.nextId)) throw new Error(\"ID space is exhausted\");\n\t\treturn idFromNumber<I>(this.nextId++);\n\t}\n\n\tasync conversation(id: ConversationId, _context: Context): Promise<ConversationRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(`SELECT record FROM ${this.schema.tables.conversations} WHERE id = ?`, id);\n\t\treturn row === undefined ? undefined : parseJson<ConversationRecord>(row.record);\n\t}\n\n\tasync scanConversations(\n\t\tquery: ConversationQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<ConversationRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\tconst scan = scanSql(start);\n\t\tconst clauses = [scan.clause];\n\t\tconst params: SqliteValue[] = [scan.param];\n\t\tif (query.ownerConversationId !== undefined) {\n\t\t\tclauses.push(\"owner_conversation_id = ?\");\n\t\t\tparams.push(query.ownerConversationId);\n\t\t}\n\t\tif (query.ownerTaskId !== undefined) {\n\t\t\tclauses.push(\"owner_task_id = ?\");\n\t\t\tparams.push(query.ownerTaskId);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM ${this.schema.tables.conversations} WHERE ${clauses.join(\" AND \")} ORDER BY id ${scan.direction} LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<ConversationRecord>(row.record)),\n\t\t\tlimit,\n\t\t\tstart.order,\n\t\t);\n\t}\n\n\tentry(id: EntryId, context: Context): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tentry(\n\t\tconversationId: ConversationId,\n\t\tid: EntryId,\n\t\tcontext: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tentry(\n\t\tidOrConversationId: EntryId | ConversationId,\n\t\tidOrContext: EntryId | Context,\n\t\tcontext?: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined> {\n\t\treturn this.admitRead(() => this.readEntry(idOrConversationId, idOrContext, context));\n\t}\n\n\tfindLatestHeadMarker(\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t\t_context: Context,\n\t): Promise<(EntryRecord & { readonly head: EntryId }) | undefined> {\n\t\treturn this.admitRead(() => this.readLatestHeadMarker(conversationId, atOrBeforeEntryId));\n\t}\n\n\tscanEntries(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\treturn this.admitRead(() => this.readEntries(query, limit, cursor));\n\t}\n\n\tprivate async readEntry(\n\t\tidOrConversationId: EntryId | ConversationId,\n\t\tidOrContext: EntryId | Context,\n\t\tcontext?: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined> {\n\t\tconst id =\n\t\t\tcontext === undefined\n\t\t\t\t? idFromNumber<EntryId>(idOrConversationId)\n\t\t\t\t: typeof idOrContext === \"number\"\n\t\t\t\t\t? idFromNumber<EntryId>(idOrContext)\n\t\t\t\t\t: undefined;\n\t\tif (id === undefined) throw new StorageRequestError(\"Storage.entry() requires an entry ID\");\n\t\tlet conversation: ConversationRecord | undefined;\n\t\tif (context !== undefined) {\n\t\t\tconst conversationId = idFromNumber<ConversationId>(idOrConversationId);\n\t\t\tconversation = await this.readConversation(conversationId);\n\t\t\tif (conversation === undefined) throw new StorageRequestError(`Unknown conversation: ${conversationId}`);\n\t\t}\n\t\tconst row = await this.db.get<EntryJsonRow>(\n\t\t\t`SELECT record, commit_seq FROM ${this.schema.tables.entries} WHERE id = ?`,\n\t\t\tid,\n\t\t);\n\t\tif (row === undefined) return undefined;\n\t\tconst entry = parseJson<EntryRecord>(row.record);\n\t\tif (conversation !== undefined) {\n\t\t\tlet upperEntryId = Number.POSITIVE_INFINITY;\n\t\t\twhile (conversation.id !== entry.conversationId) {\n\t\t\t\tif (conversation.parent === undefined) return undefined;\n\t\t\t\tupperEntryId = Math.min(upperEntryId, conversation.parent.at);\n\t\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t\t}\n\t\t\tif (entry.id > upperEntryId) return undefined;\n\t\t}\n\t\treturn { entry, commitSeq: seqFromNumber(row.commit_seq) };\n\t}\n\n\tprivate async readLatestHeadMarker(\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t): Promise<(EntryRecord & { readonly head: EntryId }) | undefined> {\n\t\tlet conversation = await this.readConversation(conversationId);\n\t\tif (conversation === undefined) throw new StorageRequestError(`Unknown conversation: ${conversationId}`);\n\t\tlet upper: number | undefined = atOrBeforeEntryId;\n\t\twhile (true) {\n\t\t\tconst row =\n\t\t\t\tupper === undefined\n\t\t\t\t\t? await this.db.get<JsonRow>(\n\t\t\t\t\t\t\t`SELECT record FROM ${this.schema.tables.entries} WHERE conversation_id = ? AND head IS NOT NULL ORDER BY id DESC LIMIT 1`,\n\t\t\t\t\t\t\tconversation.id,\n\t\t\t\t\t\t)\n\t\t\t\t\t: await this.db.get<JsonRow>(\n\t\t\t\t\t\t\t`SELECT record FROM ${this.schema.tables.entries} WHERE conversation_id = ? AND head IS NOT NULL AND id <= ? ORDER BY id DESC LIMIT 1`,\n\t\t\t\t\t\t\tconversation.id,\n\t\t\t\t\t\t\tupper,\n\t\t\t\t\t\t);\n\t\t\tif (row !== undefined) return parseJson<EntryRecord & { readonly head: EntryId }>(row.record);\n\t\t\tif (conversation.parent === undefined) return undefined;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t}\n\t}\n\n\tprivate async readEntries(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\tconst { order, after } = scanStart(query.order, cursor, \"descending\");\n\t\tif (order === \"ascending\") return this.readEntriesAscending(query, limit, after);\n\t\tlet conversation = await this.readConversation(query.conversationId);\n\t\tif (conversation === undefined) throw new StorageRequestError(`Unknown conversation: ${query.conversationId}`);\n\t\tlet upper: number | undefined = query.maxEntryId;\n\t\tif (after !== undefined) upper = Math.min(upper ?? Number.MAX_SAFE_INTEGER, after - 1);\n\t\tconst values: EntryRecord[] = [];\n\t\twhile (true) {\n\t\t\tconst clauses = [\"conversation_id = ?\"];\n\t\t\tconst params: SqliteValue[] = [conversation.id];\n\t\t\tif (query.minEntryId !== undefined) {\n\t\t\t\tclauses.push(\"id >= ?\");\n\t\t\t\tparams.push(query.minEntryId);\n\t\t\t}\n\t\t\tif (upper !== undefined) {\n\t\t\t\tclauses.push(\"id <= ?\");\n\t\t\t\tparams.push(upper);\n\t\t\t}\n\t\t\tparams.push(limit + 1 - values.length);\n\t\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t\t`SELECT record FROM ${this.schema.tables.entries} WHERE ${clauses.join(\" AND \")} ORDER BY id DESC LIMIT ?`,\n\t\t\t\t...params,\n\t\t\t);\n\t\t\tvalues.push(...rows.map((row) => parseJson<EntryRecord>(row.record)));\n\t\t\tif (values.length > limit || conversation.parent === undefined) break;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tif (query.minEntryId !== undefined && upper < query.minEntryId) break;\n\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t}\n\t\treturn page(values, limit, \"descending\");\n\t}\n\n\t/** Oldest first: the fork chain's segments from the root conversation forward, each up to its fork point. */\n\tprivate async readEntriesAscending(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tafter: number | undefined,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\tconst segments: { readonly conversationId: ConversationId; readonly upper: number | undefined }[] = [];\n\t\tlet conversation = await this.readConversation(query.conversationId);\n\t\tif (conversation === undefined) throw new StorageRequestError(`Unknown conversation: ${query.conversationId}`);\n\t\tlet upper: number | undefined = query.maxEntryId;\n\t\twhile (true) {\n\t\t\tsegments.push({ conversationId: conversation.id, upper });\n\t\t\tif (conversation.parent === undefined) break;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tif (query.minEntryId !== undefined && upper < query.minEntryId) break;\n\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t}\n\t\tlet lower: number | undefined = query.minEntryId;\n\t\tif (after !== undefined) lower = Math.max(lower ?? after + 1, after + 1);\n\t\tconst values: EntryRecord[] = [];\n\t\tfor (const segment of segments.reverse()) {\n\t\t\tconst clauses = [\"conversation_id = ?\"];\n\t\t\tconst params: SqliteValue[] = [segment.conversationId];\n\t\t\tif (lower !== undefined) {\n\t\t\t\tclauses.push(\"id >= ?\");\n\t\t\t\tparams.push(lower);\n\t\t\t}\n\t\t\tif (segment.upper !== undefined) {\n\t\t\t\tclauses.push(\"id <= ?\");\n\t\t\t\tparams.push(segment.upper);\n\t\t\t}\n\t\t\tparams.push(limit + 1 - values.length);\n\t\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t\t`SELECT record FROM ${this.schema.tables.entries} WHERE ${clauses.join(\" AND \")} ORDER BY id ASC LIMIT ?`,\n\t\t\t\t...params,\n\t\t\t);\n\t\t\tvalues.push(...rows.map((row) => parseJson<EntryRecord>(row.record)));\n\t\t\tif (values.length > limit) break;\n\t\t}\n\t\treturn page(values, limit, \"ascending\");\n\t}\n\n\tasync task(id: TaskId, _context: Context): Promise<StoredTask | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(`SELECT record FROM ${this.schema.tables.tasks} WHERE id = ?`, id);\n\t\treturn row === undefined ? undefined : parseJson<StoredTask>(row.record);\n\t}\n\n\tasync scanTasks(\n\t\tquery: TaskQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<StoredTask, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\tconst scan = scanSql(start);\n\t\tconst clauses = [scan.clause];\n\t\tconst params: SqliteValue[] = [scan.param];\n\t\tif (query.conversationId !== undefined) {\n\t\t\tclauses.push(\"conversation_id = ?\");\n\t\t\tparams.push(query.conversationId);\n\t\t}\n\t\tif (query.kind !== undefined) {\n\t\t\tclauses.push(\"kind = ?\");\n\t\t\tparams.push(encodeIndexedString(query.kind));\n\t\t}\n\t\tif (query.status !== undefined) {\n\t\t\tclauses.push(\"status = ?\");\n\t\t\tparams.push(query.status);\n\t\t}\n\t\tif (query.abortRequested !== undefined) {\n\t\t\tclauses.push(\"abort_requested = ?\");\n\t\t\tparams.push(query.abortRequested ? 1 : 0);\n\t\t}\n\t\tif (query.background !== undefined) {\n\t\t\tclauses.push(\"background = ?\");\n\t\t\tparams.push(query.background ? 1 : 0);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM ${this.schema.tables.tasks} WHERE ${clauses.join(\" AND \")} ORDER BY id ${scan.direction} LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<StoredTask>(row.record)),\n\t\t\tlimit,\n\t\t\tstart.order,\n\t\t);\n\t}\n\n\tasync submission(id: SubmissionId, _context: Context): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(`SELECT record FROM ${this.schema.tables.submissions} WHERE id = ?`, id);\n\t\treturn row === undefined ? undefined : parseJson<SubmissionRecord>(row.record);\n\t}\n\n\tasync scanSubmissions(\n\t\tquery: SubmissionQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<SubmissionRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\tconst scan = scanSql(start);\n\t\tconst clauses = [scan.clause];\n\t\tconst params: SqliteValue[] = [scan.param];\n\t\tif (query.conversationId !== undefined) {\n\t\t\tclauses.push(\"conversation_id = ?\");\n\t\t\tparams.push(query.conversationId);\n\t\t}\n\t\tif (query.status !== undefined) {\n\t\t\tclauses.push(\"status = ?\");\n\t\t\tparams.push(query.status);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM ${this.schema.tables.submissions} WHERE ${clauses.join(\" AND \")} ORDER BY id ${scan.direction} LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<SubmissionRecord>(row.record)),\n\t\t\tlimit,\n\t\t\tstart.order,\n\t\t);\n\t}\n\n\tasync submissionByRequest(\n\t\tconversationId: ConversationId,\n\t\trequestId: string,\n\t\t_context: Context,\n\t): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\n\t\t\t`SELECT record FROM ${this.schema.tables.submissions} WHERE conversation_id = ? AND request_id = ?`,\n\t\t\tconversationId,\n\t\t\tencodeIndexedString(requestId),\n\t\t);\n\t\treturn row === undefined ? undefined : parseJson<SubmissionRecord>(row.record);\n\t}\n\n\tasync findDocument(\n\t\taddress: DocumentAddress,\n\t\tat: DocumentPoint,\n\t\t_context: Context,\n\t): Promise<DocumentRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst parts = addressParts(address);\n\t\tconst sql =\n\t\t\tat === \"current\"\n\t\t\t\t? `SELECT record FROM ${this.schema.tables.documents}\n\t\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ?\n\t\t\t\t\tAND retired_at IS NULL ORDER BY created_at DESC LIMIT 1`\n\t\t\t\t: `SELECT record FROM ${this.schema.tables.documents}\n\t\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ?\n\t\t\t\t\tAND created_at <= ? AND (retired_at IS NULL OR retired_at > ?)\n\t\t\t\t\tORDER BY created_at DESC LIMIT 1`;\n\t\tconst params: SqliteValue[] = [parts.kind, parts.scopeKind, parts.ownerId, parts.family, parts.keyValue];\n\t\tif (at !== \"current\") params.push(at, at);\n\t\tconst row = await this.db.get<JsonRow>(sql, ...params);\n\t\treturn row === undefined ? undefined : parseJson<DocumentRecord>(row.record);\n\t}\n\n\tasync document(id: DocumentId, at: DocumentPoint, _context: Context): Promise<StoredDocument | undefined> {\n\t\tthis.assertOpen();\n\t\t// The record and revision queries must observe one committed state; a commit between them can replace the base.\n\t\treturn this.db.transaction((transaction) => this.materializeDocument(transaction, id, at));\n\t}\n\n\tasync scanDocuments(\n\t\tquery: DocumentQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<DocumentRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst scope = scopeColumns(query.scope);\n\t\tconst clauses = [\"scope_kind = ?\", \"owner_id = ?\", \"id > ?\"];\n\t\tconst params: SqliteValue[] = [scope.scopeKind, scope.ownerId, cursorId(cursor) ?? -1];\n\t\tif (query.kind !== undefined) {\n\t\t\tclauses.push(\"kind = ?\");\n\t\t\tparams.push(encodeIndexedString(query.kind));\n\t\t}\n\t\tif (query.at === \"current\") {\n\t\t\tclauses.push(\"retired_at IS NULL\");\n\t\t} else {\n\t\t\tclauses.push(\"created_at <= ?\", \"(retired_at IS NULL OR retired_at > ?)\");\n\t\t\tparams.push(query.at, query.at);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM ${this.schema.tables.documents} WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<DocumentRecord>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closing === undefined) {\n\t\t\tthis.closed = true;\n\t\t\tthis.closing = this.closeDatabase();\n\t\t}\n\t\treturn this.closing;\n\t}\n\n\tprivate async closeDatabase(): Promise<void> {\n\t\tif (this.admittedReads > 0) {\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tthis.readsDrained = resolve;\n\t\t\t});\n\t\t}\n\t\tawait this.db.close();\n\t}\n\n\t/**\n\t * Run a read that issues several queries. Close waits for admitted reads, so their later queries never reach a\n\t * closed database. Single-query reads and transactions are already ordered before close by the database.\n\t */\n\tprivate async admitRead<T>(read: () => Promise<T>): Promise<T> {\n\t\tthis.assertOpen();\n\t\tthis.admittedReads++;\n\t\ttry {\n\t\t\treturn await read();\n\t\t} finally {\n\t\t\tif (--this.admittedReads === 0) this.readsDrained?.();\n\t\t}\n\t}\n\n\tprivate async readConversation(id: ConversationId): Promise<ConversationRecord | undefined> {\n\t\tconst row = await this.db.get<JsonRow>(`SELECT record FROM ${this.schema.tables.conversations} WHERE id = ?`, id);\n\t\treturn row === undefined ? undefined : parseJson<ConversationRecord>(row.record);\n\t}\n\n\tprivate async materializeDocument(\n\t\texecutor: SqliteExecutor,\n\t\tid: DocumentId,\n\t\tat: DocumentPoint,\n\t): Promise<StoredDocument | undefined> {\n\t\tconst row = await executor.get<JsonRow>(`SELECT record FROM ${this.schema.tables.documents} WHERE id = ?`, id);\n\t\tif (row === undefined) return undefined;\n\t\tconst record = parseJson<DocumentRecord>(row.record);\n\t\tif (at !== \"current\" && isCurrentOnly(record)) {\n\t\t\tthrow new StorageRequestError(`Document ${id} does not retain historical content`);\n\t\t}\n\t\tif (!isAliveAt(record, at)) return undefined;\n\t\tconst upper = at === \"current\" ? Number.MAX_SAFE_INTEGER : at;\n\t\tconst base = await executor.get<RevisionRow>(\n\t\t\t`SELECT seq, kind, version, content FROM ${this.schema.tables.documentRevisions}\n\t\t\t\tWHERE document_id = ? AND kind = 'base' AND seq <= ? ORDER BY seq DESC LIMIT 1`,\n\t\t\tid,\n\t\t\tupper,\n\t\t);\n\t\tif (base === undefined) throw new Error(`Document ${id} is missing a required base`);\n\t\tlet value = parseJson<JsonObject>(base.content);\n\t\tconst tail = await executor.all<RevisionRow>(\n\t\t\t`SELECT seq, kind, version, content FROM ${this.schema.tables.documentRevisions}\n\t\t\t\tWHERE document_id = ? AND seq > ? AND seq <= ? ORDER BY seq`,\n\t\t\tid,\n\t\t\tbase.seq,\n\t\t\tupper,\n\t\t);\n\t\tfor (const revision of tail) {\n\t\t\tif (revision.kind !== \"delta\" || revision.version !== base.version) {\n\t\t\t\tthrow new Error(`Document ${id} crosses a stored version boundary without a base`);\n\t\t\t}\n\t\t\tvalue = apply(value, parseJson<readonly Op[]>(revision.content)) as JsonObject;\n\t\t}\n\t\treturn { record, version: base.version, value, deltasSinceBase: tail.length };\n\t}\n\n\tprivate candidateNextId(writes: readonly StorageWrite[]): number {\n\t\tlet nextId = this.nextId;\n\t\tfor (const write of writes) {\n\t\t\tconst id = writeId(write);\n\t\t\tif (id !== undefined) nextId = Math.max(nextId, id + 1);\n\t\t}\n\t\treturn nextId;\n\t}\n\n\tprivate async checkGlobalIds(executor: SqliteExecutor, writes: readonly StorageWrite[]): Promise<void> {\n\t\tconst claimed = new Map<Id<string>, TableName>();\n\t\tfor (const write of writes) {\n\t\t\tif (write.type === \"document.change\" || write.type === \"document.retire\") continue;\n\t\t\tconst document = write.type === \"document.create\" || write.type === \"document.copy\";\n\t\t\tconst table: TableName = document ? \"document\" : write.type;\n\t\t\tconst id = document ? write.record.id : write.value.id;\n\t\t\tconst existing = (\n\t\t\t\tawait executor.get<RecordIdRow>(`SELECT record_type FROM ${this.schema.tables.recordIds} WHERE id = ?`, id)\n\t\t\t)?.record_type;\n\t\t\tconst earlier = claimed.get(id);\n\t\t\tif (table === \"conversation\" || table === \"entry\" || table === \"document\") {\n\t\t\t\tif (existing !== undefined) throw new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\tif (earlier !== undefined) throw new Error(`ID ${id} is written more than once`);\n\t\t\t} else {\n\t\t\t\tif (existing !== undefined && existing !== table)\n\t\t\t\t\tthrow new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\tif (earlier !== undefined && earlier !== table) throw new Error(`ID ${id} is written as two record types`);\n\t\t\t}\n\t\t\tclaimed.set(id, table);\n\t\t}\n\t}\n\n\tprivate prepareDocumentActions(writes: readonly StorageWrite[]): Map<DocumentId, DocumentAction> {\n\t\tconst actions = new Map<DocumentId, DocumentAction>();\n\t\tfor (const write of writes) {\n\t\t\tif (\n\t\t\t\twrite.type !== \"document.create\" &&\n\t\t\t\twrite.type !== \"document.copy\" &&\n\t\t\t\twrite.type !== \"document.change\" &&\n\t\t\t\twrite.type !== \"document.retire\"\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst id = write.type === \"document.create\" || write.type === \"document.copy\" ? write.record.id : write.id;\n\t\t\tlet action = actions.get(id);\n\t\t\tif (action === undefined) {\n\t\t\t\taction = { retire: false };\n\t\t\t\tactions.set(id, action);\n\t\t\t}\n\t\t\tswitch (write.type) {\n\t\t\t\tcase \"document.create\":\n\t\t\t\t\tif (action.create !== undefined || action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.create = write.record;\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.copy\":\n\t\t\t\t\tif (action.create !== undefined || action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.create = write.record;\n\t\t\t\t\taction.copy = write.source;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.change\":\n\t\t\t\t\tif (action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.retire\":\n\t\t\t\t\tif (action.retire) throw new Error(`Document ${id} is retired more than once`);\n\t\t\t\t\taction.retire = true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn actions;\n\t}\n\n\tprivate async checkDocumentActions(\n\t\texecutor: SqliteExecutor,\n\t\tactions: ReadonlyMap<DocumentId, DocumentAction>,\n\t): Promise<void> {\n\t\tconst liveCounts = new Map<string, number>();\n\t\tfor (const [id, action] of actions) {\n\t\t\tif (action.copy !== undefined && actions.has(action.copy.id)) {\n\t\t\t\tthrow new Error(`Document copy ${id} source is changed in the copy batch`);\n\t\t\t}\n\t\t\tconst row = await executor.get<JsonRow>(`SELECT record FROM ${this.schema.tables.documents} WHERE id = ?`, id);\n\t\t\tconst existing = row === undefined ? undefined : parseJson<DocumentRecord>(row.record);\n\t\t\tif (action.create === undefined && existing === undefined) throw new Error(`Unknown document: ${id}`);\n\t\t\tif (action.create !== undefined && existing !== undefined) throw new Error(`Document ${id} already exists`);\n\t\t\tif (existing?.retiredAt !== undefined) throw new Error(`Document ${id} is retired`);\n\t\t\tif (action.content?.kind === \"delta\") {\n\t\t\t\tconst previous = await executor.get<{ readonly version: number }>(\n\t\t\t\t\t`SELECT version FROM ${this.schema.tables.documentRevisions} WHERE document_id = ? ORDER BY seq DESC LIMIT 1`,\n\t\t\t\t\tid,\n\t\t\t\t);\n\t\t\t\tif (previous === undefined) throw new Error(`Document ${id} delta has no base`);\n\t\t\t\tif (previous.version !== action.content.version) {\n\t\t\t\t\tthrow new Error(`Document ${id} version transition requires a base`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst record = action.create ?? existing!;\n\t\t\tconst key = addressKey(record);\n\t\t\tlet live = liveCounts.get(key);\n\t\t\tif (live === undefined) live = (await this.currentDocumentId(executor, record)) === undefined ? 0 : 1;\n\t\t\tif (action.retire && existing !== undefined) live--;\n\t\t\tif (action.create !== undefined && !action.retire) live++;\n\t\t\tliveCounts.set(key, live);\n\t\t}\n\t\tfor (const live of liveCounts.values()) {\n\t\t\tif (live > 1) throw new Error(\"Document address already has a current incarnation\");\n\t\t}\n\t}\n\n\tprivate async currentDocumentId(\n\t\texecutor: SqliteExecutor,\n\t\taddress: DocumentAddress | DocumentCreate | DocumentRecord,\n\t): Promise<DocumentId | undefined> {\n\t\tconst parts = addressParts(address);\n\t\tconst id = (\n\t\t\tawait executor.get<IdRow>(\n\t\t\t\t`SELECT id FROM ${this.schema.tables.documents}\n\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ? AND retired_at IS NULL\n\t\t\t\tLIMIT 1`,\n\t\t\t\tparts.kind,\n\t\t\t\tparts.scopeKind,\n\t\t\t\tparts.ownerId,\n\t\t\t\tparts.family,\n\t\t\t\tparts.keyValue,\n\t\t\t)\n\t\t)?.id;\n\t\treturn id === undefined ? undefined : idFromNumber<DocumentId>(id);\n\t}\n\n\tprivate async applyTableWrite(executor: SqliteExecutor, write: StorageWrite, seq: Seq): Promise<void> {\n\t\tswitch (write.type) {\n\t\t\tcase \"conversation\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"conversation\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO ${this.schema.tables.conversations} (id, owner_conversation_id, owner_task_id, record) VALUES (?, ?, ?, ?)`,\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.owner?.conversationId ?? null,\n\t\t\t\t\twrite.value.owner?.taskId ?? null,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"entry\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"entry\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO ${this.schema.tables.entries} (id, conversation_id, head, commit_seq, record) VALUES (?, ?, ?, ?, ?)`,\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\twrite.value.head ?? null,\n\t\t\t\t\tseq,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"task\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"task\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO ${this.schema.tables.tasks} (id, conversation_id, kind, status, abort_requested, background, record)\n\t\t\t\t\t\tVALUES (?, ?, ?, ?, ?, ?, ?)\n\t\t\t\t\t\tON CONFLICT(id) DO UPDATE SET conversation_id = excluded.conversation_id, kind = excluded.kind,\n\t\t\t\t\t\tstatus = excluded.status, abort_requested = excluded.abort_requested,\n\t\t\t\t\t\tbackground = excluded.background, record = excluded.record`,\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\tencodeIndexedString(write.value.kind),\n\t\t\t\t\twrite.value.state.status,\n\t\t\t\t\twrite.value.abortRequested ? 1 : 0,\n\t\t\t\t\twrite.value.background ? 1 : 0,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"submission\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"submission\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO ${this.schema.tables.submissions} (id, conversation_id, request_id, status, record) VALUES (?, ?, ?, ?, ?)\n\t\t\t\t\t\tON CONFLICT(id) DO UPDATE SET conversation_id = excluded.conversation_id,\n\t\t\t\t\t\trequest_id = excluded.request_id, status = excluded.status, record = excluded.record`,\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\twrite.value.requestId === undefined ? null : encodeIndexedString(write.value.requestId),\n\t\t\t\t\twrite.value.status,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"document.create\":\n\t\t\tcase \"document.copy\":\n\t\t\tcase \"document.change\":\n\t\t\tcase \"document.retire\":\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate async claimId(executor: SqliteExecutor, id: Id<string>, table: TableName): Promise<void> {\n\t\tawait executor.run(\n\t\t\t`INSERT OR IGNORE INTO ${this.schema.tables.recordIds} (id, record_type) VALUES (?, ?)`,\n\t\t\tid,\n\t\t\ttable,\n\t\t);\n\t}\n\n\tprivate async applyDocumentActions(\n\t\texecutor: SqliteExecutor,\n\t\tactions: ReadonlyMap<DocumentId, DocumentAction>,\n\t\tseq: Seq,\n\t): Promise<void> {\n\t\tfor (const [id, action] of actions) {\n\t\t\tlet content = action.content;\n\t\t\tif (action.copy !== undefined) {\n\t\t\t\ttry {\n\t\t\t\t\tconst stored = await this.materializeDocument(executor, action.copy.id, action.copy.at);\n\t\t\t\t\tif (stored === undefined) throw new Error(`Fork source document ${action.copy.id} cannot be read`);\n\t\t\t\t\tconst create = action.create!;\n\t\t\t\t\tif (\n\t\t\t\t\t\tstored.record.scope.kind !== \"conversation\" ||\n\t\t\t\t\t\tcreate.scope.kind !== \"conversation\" ||\n\t\t\t\t\t\tstored.record.kind !== create.kind ||\n\t\t\t\t\t\tstored.record.key !== create.key ||\n\t\t\t\t\t\tstored.record.history !== create.history ||\n\t\t\t\t\t\tstored.record.fork !== create.fork\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new Error(`Fork source document ${action.copy.id} does not match the copied record`);\n\t\t\t\t\t}\n\t\t\t\t\tcontent = { kind: \"base\", version: stored.version, value: stored.value };\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow new Error(`Document copy ${id} was rejected`, { cause: error });\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet record: DocumentRecord;\n\t\t\tif (action.create !== undefined) {\n\t\t\t\trecord = {\n\t\t\t\t\t...action.create,\n\t\t\t\t\tcreatedAt: seq,\n\t\t\t\t\t...(action.retire ? { retiredAt: seq } : {}),\n\t\t\t\t};\n\t\t\t\tconst parts = addressParts(record);\n\t\t\t\tawait this.claimId(executor, id, \"document\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO ${this.schema.tables.documents}\n\t\t\t\t\t\t(id, kind, family, key_value, scope_kind, owner_id, created_at, retired_at, record)\n\t\t\t\t\t\tVALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t\t\t\tid,\n\t\t\t\t\tparts.kind,\n\t\t\t\t\tparts.family,\n\t\t\t\t\tparts.keyValue,\n\t\t\t\t\tparts.scopeKind,\n\t\t\t\t\tparts.ownerId,\n\t\t\t\t\tseq,\n\t\t\t\t\taction.retire ? seq : null,\n\t\t\t\t\tencodeJson(record),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst row = (await executor.get<JsonRow>(\n\t\t\t\t\t`SELECT record FROM ${this.schema.tables.documents} WHERE id = ?`,\n\t\t\t\t\tid,\n\t\t\t\t))!;\n\t\t\t\trecord = parseJson<DocumentRecord>(row.record);\n\t\t\t}\n\n\t\t\tif (content !== undefined) {\n\t\t\t\tif (content.kind === \"base\" && isCurrentOnly(record)) {\n\t\t\t\t\tawait executor.run(`DELETE FROM ${this.schema.tables.documentRevisions} WHERE document_id = ?`, id);\n\t\t\t\t}\n\t\t\t\tconst encodedContent = content.kind === \"base\" ? encodeJson(content.value) : encodeJson(content.ops);\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO ${this.schema.tables.documentRevisions} (document_id, seq, kind, version, content) VALUES (?, ?, ?, ?, ?)`,\n\t\t\t\t\tid,\n\t\t\t\t\tseq,\n\t\t\t\t\tcontent.kind,\n\t\t\t\t\tcontent.version,\n\t\t\t\t\tencodedContent,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (action.retire) {\n\t\t\t\tif (action.create === undefined) {\n\t\t\t\t\trecord = { ...record, retiredAt: seq };\n\t\t\t\t\tawait executor.run(\n\t\t\t\t\t\t`UPDATE ${this.schema.tables.documents} SET retired_at = ?, record = ? WHERE id = ?`,\n\t\t\t\t\t\tseq,\n\t\t\t\t\t\tencodeJson(record),\n\t\t\t\t\t\tid,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (isCurrentOnly(record)) {\n\t\t\t\t\tawait executor.run(`DELETE FROM ${this.schema.tables.documentRevisions} WHERE document_id = ?`, id);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"SqliteStorage is closed\");\n\t}\n}\n"]}
@@ -40,7 +40,10 @@ export type ImageProcessor = {
40
40
  };
41
41
  /** Formats every provider takes inline; others, such as BMP, need converting. */
42
42
  export declare const INLINE_IMAGE_TYPES: ReadonlySet<string>;
43
- /** Standard base64 of `bytes`, without platform APIs such as `Buffer` or `btoa`. */
43
+ /**
44
+ * Standard base64 of `bytes`. `btoa` takes a binary string, built 8 KiB at a time: a single `String.fromCharCode`
45
+ * call with megabytes of arguments overflows the stack.
46
+ */
44
47
  export declare function toBase64(bytes: Uint8Array): string;
45
48
  /** The length of the base64 of `byteLength` bytes. */
46
49
  export declare function base64Length(byteLength: number): number;
@@ -1 +1 @@
1
- {"version":3,"file":"image-processor.d.ts","sourceRoot":"","sources":["../../src/tools/image-processor.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,MAAM,MAAM,WAAW,GAAG;IACzB,4BAA4B;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,4BAA4B;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,WAA8E,CAAC;AAElH,qFAAqF;AACrF,MAAM,MAAM,aAAa,GAAG;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wGAAwG;IACxG,QAAQ,CAAC,OAAO,CAAC,EAAE;QAClB,QAAQ,CAAC,IAAI,EAAE;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QACnE,QAAQ,CAAC,EAAE,EAAE;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KACjE,CAAC;IACF,8GAA8G;IAC9G,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;CACtG,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAmE,CAAC;AAIvH,oFAAoF;AACpF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAmBlD;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEvD"}
1
+ {"version":3,"file":"image-processor.d.ts","sourceRoot":"","sources":["../../src/tools/image-processor.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,MAAM,MAAM,WAAW,GAAG;IACzB,4BAA4B;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,4BAA4B;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,WAA8E,CAAC;AAElH,qFAAqF;AACrF,MAAM,MAAM,aAAa,GAAG;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wGAAwG;IACxG,QAAQ,CAAC,OAAO,CAAC,EAAE;QAClB,QAAQ,CAAC,IAAI,EAAE;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QACnE,QAAQ,CAAC,EAAE,EAAE;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KACjE,CAAC;IACF,8GAA8G;IAC9G,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;CACtG,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAmE,CAAC;AAEvH;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAOlD;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEvD"}
@@ -1,27 +1,17 @@
1
1
  export const DEFAULT_IMAGE_LIMITS = { maxWidth: 2000, maxHeight: 2000, maxBytes: 4.5 * 1024 * 1024 };
2
2
  /** Formats every provider takes inline; others, such as BMP, need converting. */
3
3
  export const INLINE_IMAGE_TYPES = new Set(["image/png", "image/jpeg", "image/gif", "image/webp"]);
4
- const BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
5
- /** Standard base64 of `bytes`, without platform APIs such as `Buffer` or `btoa`. */
4
+ /**
5
+ * Standard base64 of `bytes`. `btoa` takes a binary string, built 8 KiB at a time: a single `String.fromCharCode`
6
+ * call with megabytes of arguments overflows the stack.
7
+ */
6
8
  export function toBase64(bytes) {
7
9
  const parts = [];
8
- let chunk = "";
9
- for (let i = 0; i < bytes.length; i += 3) {
10
- const a = bytes[i];
11
- const b = bytes[i + 1];
12
- const c = bytes[i + 2];
13
- chunk += BASE64[a >> 2];
14
- chunk += BASE64[((a & 3) << 4) | ((b ?? 0) >> 4)];
15
- chunk += b === undefined ? "=" : BASE64[((b & 15) << 2) | ((c ?? 0) >> 6)];
16
- chunk += c === undefined ? "=" : BASE64[c & 63];
17
- // Join in pieces: one string grown a character at a time is slow for megabytes.
18
- if (chunk.length >= 8192) {
19
- parts.push(chunk);
20
- chunk = "";
21
- }
10
+ for (let i = 0; i < bytes.length; i += 8192) {
11
+ // `apply` takes any array-like, though its type asks for an array.
12
+ parts.push(String.fromCharCode.apply(null, bytes.subarray(i, i + 8192)));
22
13
  }
23
- parts.push(chunk);
24
- return parts.join("");
14
+ return btoa(parts.join(""));
25
15
  }
26
16
  /** The length of the base64 of `byteLength` bytes. */
27
17
  export function base64Length(byteLength) {
@@ -1 +1 @@
1
- {"version":3,"file":"image-processor.js","sourceRoot":"","sources":["../../src/tools/image-processor.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,oBAAoB,GAAgB,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;AA4BlH,iFAAiF;AACjF,MAAM,CAAC,MAAM,kBAAkB,GAAwB,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;AAEvH,MAAM,MAAM,GAAG,kEAAkE,CAAC;AAElF,oFAAoF;AACpF,MAAM,UAAU,QAAQ,CAAC,KAAiB;IACzC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACpB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,KAAK,IAAI,MAAM,CAAC,CAAC,IAAI,CAAC,CAAE,CAAC;QACzB,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC;QACnD,KAAK,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC;QAC5E,KAAK,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAE,CAAC;QACjD,gFAAgF;QAChF,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClB,KAAK,GAAG,EAAE,CAAC;QACZ,CAAC;IACF,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACvB,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,YAAY,CAAC,UAAkB;IAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AACtC,CAAC","sourcesContent":["/** Limits an image the model sees must keep; the defaults below are the coding agent's. */\nexport type ImageLimits = {\n\t/** Pixels. Default 2000. */\n\treadonly maxWidth: number;\n\t/** Pixels. Default 2000. */\n\treadonly maxHeight: number;\n\t/** Bytes of base64. Default 4.5 MiB, below Anthropic's 5 MB. */\n\treadonly maxBytes: number;\n};\n\nexport const DEFAULT_IMAGE_LIMITS: ImageLimits = { maxWidth: 2000, maxHeight: 2000, maxBytes: 4.5 * 1024 * 1024 };\n\n/** An image the model can take: a supported format, within the limits, as base64. */\nexport type PreparedImage = {\n\treadonly data: string;\n\treadonly mimeType: string;\n\t/** Set when the image was resized: its size before and after, for the model to map coordinates back. */\n\treadonly resized?: {\n\t\treadonly from: { readonly width: number; readonly height: number };\n\t\treadonly to: { readonly width: number; readonly height: number };\n\t};\n\t/** The original format, set when it differs from `mimeType`: BMP becomes PNG, a large PNG may become JPEG. */\n\treadonly convertedFrom?: string;\n};\n\n/**\n * Decodes, orients, resizes, and re-encodes images so the model can take them. `read` uses one when given; without\n * one, it passes supported images within the byte limit through as they are. `@earendil-works/pi-durable/images`\n * provides a Photon-based one.\n */\nexport type ImageProcessor = {\n\t/**\n\t * The image, prepared to fit `limits`, or `undefined` when it cannot be decoded or made to fit. A promise, so a\n\t * processor can do the work off the event loop.\n\t */\n\tprepare(bytes: Uint8Array, mimeType: string, limits: ImageLimits): Promise<PreparedImage | undefined>;\n};\n\n/** Formats every provider takes inline; others, such as BMP, need converting. */\nexport const INLINE_IMAGE_TYPES: ReadonlySet<string> = new Set([\"image/png\", \"image/jpeg\", \"image/gif\", \"image/webp\"]);\n\nconst BASE64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n/** Standard base64 of `bytes`, without platform APIs such as `Buffer` or `btoa`. */\nexport function toBase64(bytes: Uint8Array): string {\n\tconst parts: string[] = [];\n\tlet chunk = \"\";\n\tfor (let i = 0; i < bytes.length; i += 3) {\n\t\tconst a = bytes[i]!;\n\t\tconst b = bytes[i + 1];\n\t\tconst c = bytes[i + 2];\n\t\tchunk += BASE64[a >> 2]!;\n\t\tchunk += BASE64[((a & 3) << 4) | ((b ?? 0) >> 4)]!;\n\t\tchunk += b === undefined ? \"=\" : BASE64[((b & 15) << 2) | ((c ?? 0) >> 6)]!;\n\t\tchunk += c === undefined ? \"=\" : BASE64[c & 63]!;\n\t\t// Join in pieces: one string grown a character at a time is slow for megabytes.\n\t\tif (chunk.length >= 8192) {\n\t\t\tparts.push(chunk);\n\t\t\tchunk = \"\";\n\t\t}\n\t}\n\tparts.push(chunk);\n\treturn parts.join(\"\");\n}\n\n/** The length of the base64 of `byteLength` bytes. */\nexport function base64Length(byteLength: number): number {\n\treturn Math.ceil(byteLength / 3) * 4;\n}\n"]}
1
+ {"version":3,"file":"image-processor.js","sourceRoot":"","sources":["../../src/tools/image-processor.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,oBAAoB,GAAgB,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;AA4BlH,iFAAiF;AACjF,MAAM,CAAC,MAAM,kBAAkB,GAAwB,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;AAEvH;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAiB;IACzC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC7C,mEAAmE;QACnE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAwB,CAAC,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,YAAY,CAAC,UAAkB;IAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AACtC,CAAC","sourcesContent":["/** Limits an image the model sees must keep; the defaults below are the coding agent's. */\nexport type ImageLimits = {\n\t/** Pixels. Default 2000. */\n\treadonly maxWidth: number;\n\t/** Pixels. Default 2000. */\n\treadonly maxHeight: number;\n\t/** Bytes of base64. Default 4.5 MiB, below Anthropic's 5 MB. */\n\treadonly maxBytes: number;\n};\n\nexport const DEFAULT_IMAGE_LIMITS: ImageLimits = { maxWidth: 2000, maxHeight: 2000, maxBytes: 4.5 * 1024 * 1024 };\n\n/** An image the model can take: a supported format, within the limits, as base64. */\nexport type PreparedImage = {\n\treadonly data: string;\n\treadonly mimeType: string;\n\t/** Set when the image was resized: its size before and after, for the model to map coordinates back. */\n\treadonly resized?: {\n\t\treadonly from: { readonly width: number; readonly height: number };\n\t\treadonly to: { readonly width: number; readonly height: number };\n\t};\n\t/** The original format, set when it differs from `mimeType`: BMP becomes PNG, a large PNG may become JPEG. */\n\treadonly convertedFrom?: string;\n};\n\n/**\n * Decodes, orients, resizes, and re-encodes images so the model can take them. `read` uses one when given; without\n * one, it passes supported images within the byte limit through as they are. `@earendil-works/pi-durable/images`\n * provides a Photon-based one.\n */\nexport type ImageProcessor = {\n\t/**\n\t * The image, prepared to fit `limits`, or `undefined` when it cannot be decoded or made to fit. A promise, so a\n\t * processor can do the work off the event loop.\n\t */\n\tprepare(bytes: Uint8Array, mimeType: string, limits: ImageLimits): Promise<PreparedImage | undefined>;\n};\n\n/** Formats every provider takes inline; others, such as BMP, need converting. */\nexport const INLINE_IMAGE_TYPES: ReadonlySet<string> = new Set([\"image/png\", \"image/jpeg\", \"image/gif\", \"image/webp\"]);\n\n/**\n * Standard base64 of `bytes`. `btoa` takes a binary string, built 8 KiB at a time: a single `String.fromCharCode`\n * call with megabytes of arguments overflows the stack.\n */\nexport function toBase64(bytes: Uint8Array): string {\n\tconst parts: string[] = [];\n\tfor (let i = 0; i < bytes.length; i += 8192) {\n\t\t// `apply` takes any array-like, though its type asks for an array.\n\t\tparts.push(String.fromCharCode.apply(null, bytes.subarray(i, i + 8192) as unknown as number[]));\n\t}\n\treturn btoa(parts.join(\"\"));\n}\n\n/** The length of the base64 of `byteLength` bytes. */\nexport function base64Length(byteLength: number): number {\n\treturn Math.ceil(byteLength / 3) * 4;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAW5C,OAAO,KAAK,EAAyD,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACnH,OAAO,EAIN,KAAK,gBAAgB,EAGrB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAIN,KAAK,cAAc,EAGnB,MAAM,sBAAsB,CAAC;AAG9B,QAAA,MAAM,UAAU;;;;EAId,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,MAAM,MAAM,eAAe,GAAG;IAC7B,yEAAyE;IACzE,UAAU,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;CAC/C,CAAC;AAmCF,MAAM,MAAM,eAAe,GAAG;IAC7B,wHAAwH;IACxH,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAoB,GAAG,gBAAgB,CAAC,OAAO,UAAU,EAAE,eAAe,CAAC,CA0ClH"}
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAU5C,OAAO,KAAK,EAAyD,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACnH,OAAO,EAIN,KAAK,gBAAgB,EAGrB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAIN,KAAK,cAAc,EAGnB,MAAM,sBAAsB,CAAC;AAG9B,QAAA,MAAM,UAAU;;;;EAId,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,MAAM,MAAM,eAAe,GAAG;IAC7B,yEAAyE;IACzE,UAAU,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;CAC/C,CAAC;AAmCF,MAAM,MAAM,eAAe,GAAG;IAC7B,wHAAwH;IACxH,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAoB,GAAG,gBAAgB,CAAC,OAAO,UAAU,EAAE,eAAe,CAAC,CA0ClH"}
@@ -1,7 +1,7 @@
1
+ import { characterEnd } from "@earendil-works/chord/output";
1
2
  import { Type } from "typebox";
2
3
  import { getOrThrow, rangeDecoder, startsWithBom, } from "../env/index.js";
3
4
  import { defineTool } from "../harness/define.js";
4
- import { characterEnd } from "../harness/output.js";
5
5
  import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHeadOf, utf8ByteLength, } from "../truncate.js";
6
6
  import { requireEnv } from "./env.js";
7
7
  import { detectSupportedImageMimeTypeOf, imageDimensions } from "./image.js";
@@ -1 +1 @@
1
- {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAGN,UAAU,EAEV,YAAY,EACZ,aAAa,GACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EACN,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EAEV,cAAc,EACd,cAAc,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,8BAA8B,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EACN,YAAY,EACZ,oBAAoB,EAGpB,kBAAkB,EAClB,QAAQ,GACR,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;IAC9B,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,iDAAiD,EAAE,CAAC;IACrF,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,+CAA+C,EAAE,CAAC,CAAC;IACpG,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,iCAAiC,EAAE,CAAC,CAAC;CACrF,CAAC,CAAC;AASH,MAAM,UAAU,GAAG,EAAE,GAAG,IAAI,CAAC;AAE7B,qGAAqG;AACrG,SAAS,UAAU,CAAC,KAAa;IAChC,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,QAAQ,CACtB,MAAoB,EACpB,KAAa,EACb,GAAW,EACX,OAAgB,EAChB,OAAgB;IAEhB,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC;IAC/B,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,IAAI,QAAQ,GAAG,OAAO,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,GAAG,GAAG,GAAI,CAAC;QAC1E,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,GAAG,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACrG,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM;QAC9B,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC;QACzB,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,IAAI,IAAI,OAAO,CAAC;QAChB,KAAK,IAAI,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC;YAAE,QAAQ,EAAE,CAAC;QAC3G,IAAI,QAAQ,IAAI,iBAAiB,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,iBAAiB,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IAChG,CAAC;IACD,OAAO,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;AAChC,CAAC;AAOD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,OAAO,GAAoB,EAAE;IAC3D,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,0BAA0B,CAAC;IAClG,OAAO,UAAU,CAAC;QACjB,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,gEAAgE,OAAO,6EAA6E,iBAAiB,aAAa,iBAAiB,GAAG,IAAI,kIAAkI;QACzV,UAAU,EAAE,UAAU;QACtB,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO;YAC/B,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;YACrC,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;YAC5B,MAAM,YAAY,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YACnE,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,gBAAgB,CAAC,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;YACxF,IAAI,CAAC;gBACJ,2GAA2G;gBAC3G,6FAA6F;gBAC7F,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;oBACnC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;oBACtD,MAAM,QAAQ,GAAG,MAAM,8BAA8B,CAAC;wBACrD,IAAI,EAAE,MAAM,CAAC,IAAI;wBACjB,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;qBAC1F,CAAC,CAAC;oBACH,MAAM,MAAM,GACX,QAAQ,KAAK,SAAS;wBACrB,CAAC,CAAC,MAAM,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC;wBACtD,CAAC,CAAC,MAAM,SAAS,CACf,MAAM,EACN,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,OAAO,CAAC,MAAM,EACd,MAAM,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,EAC9B,OAAO,CACP,CAAC;oBACL,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;oBACrD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC;oBACjF,IAAI,SAAS,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;wBAAE,OAAO,MAAM,CAAC;oBACrF,IAAI,OAAO,KAAK,CAAC;wBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,4BAA4B,CAAC,CAAC;gBACzE,CAAC;YACF,CAAC;oBAAS,CAAC;gBACV,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;QACF,CAAC;KACD,CAAC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,SAAS,CACvB,MAAoB,EACpB,IAAc,EACd,IAAY,EACZ,QAAgB,EAChB,SAAqC,EACrC,EAAE,MAAM,EAAE,MAAM,EAAc,EAC9B,OAAgB;IAEhB,IAAI,KAA2D,CAAC;IAChE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAClE,IAAI,QAAQ,KAAK,SAAS;YACzB,OAAO,UAAU,CAAC,GAAG,IAAI,iBAAiB,QAAQ,yCAAyC,CAAC,CAAC;QAC9F,KAAK,GAAG,QAAQ,CAAC;QACjB,IAAI,QAAQ,CAAC,aAAa,KAAK,SAAS;YACvC,KAAK,CAAC,IAAI,CAAC,kBAAkB,QAAQ,CAAC,aAAa,OAAO,QAAQ,CAAC,QAAQ,GAAG,CAAC,CAAC;QACjF,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC;YACtC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACjD,KAAK,CAAC,IAAI,CACT,gBAAgB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,OAAO,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,MAAM,6BAA6B,KAAK,+BAA+B,CACtI,CAAC;QACH,CAAC;IACF,CAAC;SAAM,CAAC;QACP,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvC,OAAO,UAAU,CAChB,GAAG,IAAI,iBAAiB,QAAQ,+DAA+D,CAC/F,CAAC;QACH,CAAC;QACD,MAAM,YAAY,GAAG,mDAAmD,CAAC;QACzE,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC/C,OAAO,UAAU,CAChB,GAAG,IAAI,iBAAiB,QAAQ,QAAQ,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,YAAY,EAAE,CACnG,CAAC;QACH,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACnE,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC9C,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,UAAU,CAAC,GAAG,IAAI,iBAAiB,QAAQ,6BAA6B,CAAC,CAAC;QACzG,IAAI,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;YACpE,OAAO,UAAU,CAChB,GAAG,IAAI,iBAAiB,QAAQ,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,iBAAiB,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,SAAS,KAAK,YAAY,EAAE,CACxI,CAAC;QACH,CAAC;QACD,KAAK,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC7C,CAAC;IACD,IAAI,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;IACrG,MAAM,WAAW,GAAqB;QACrC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,oBAAoB,KAAK,CAAC,QAAQ,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;KAC1G,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC;AACjG,CAAC;AAKD;;;GAGG;AACH,KAAK,UAAU,UAAU,CAAC,GAAqB,EAAE,OAAgB;IAChE,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7C,MAAM,KAAK,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7F,MAAM,MAAM,GAAG,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC;IAClD,OAAO;QACN,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI;QAC9C,MAAM,EAAE;YACP,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,oBAAoB,CAAC,QAAQ;YAC3D,SAAS,EAAE,MAAM,EAAE,SAAS,IAAI,oBAAoB,CAAC,SAAS;YAC9D,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,oBAAoB,CAAC,QAAQ;SAC3D;KACD,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,OAAe;IAClC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AAChH,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,QAAQ,CACtB,MAAoB,EACpB,IAAY,EACZ,MAA0B,EAC1B,KAAyB,EACzB,OAAgB;IAEhB,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,gBAAgB,GAAG,SAAS,GAAG,CAAC,CAAC;IACvC,oGAAoG;IACpG,MAAM,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACzC,iHAAiH;IACjH,uFAAuF;IACvF,8GAA8G;IAC9G,MAAM,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,YAAY,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,UAAU,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC;IAC9G,MAAM,OAAO,GAAG,YAAY,KAAK,SAAS,IAAI,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5G,MAAM,MAAM,GAAG,KAAK,EAAE,OAA2B,EAAqB,EAAE,CACvE,UAAU,CACT,MAAM,MAAM,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,CACxG,CAAC;IACH,IAAI,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IACzC,IAAI,SAAS,IAAI,cAAc,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,UAAU,MAAM,2BAA2B,cAAc,eAAe,CAAC,CAAC;IAC3F,CAAC;IAED,IAAI,gBAAoC,CAAC;IACzC,IAAI,iBAAiB,GAAG,cAAc,GAAG,UAAU,CAAC;IACpD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,KAAK,EAAE,cAAc,CAAC,CAAC;QAC5D,gBAAgB,GAAG,OAAO,GAAG,SAAS,CAAC;QACvC,+GAA+G;QAC/G,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,GAAG,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QAC3F,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC,CAAC;QACvD,IAAI,iBAAiB,GAAG,CAAC,IAAI,WAAW,GAAG,CAAC;YAAE,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7E,CAAC;IACD,MAAM,KAAK,GAAG,iBAAiB,KAAK,CAAC,CAAC;IACtC,yFAAyF;IACzF,MAAM,eAAe,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC;IACrG,MAAM,MAAM,GAAG;QACd,KAAK,EAAE,KAAK,IAAI,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa;KACrC,CAAC;IACF,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;IAE3G,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,UAAU,EAAE,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1E,MAAM,WAAW,GAAqB,EAAE,CAAC;IACzC,IAAI,UAAU,GAAG,QAAQ,CAAC;IAC1B,IAAI,OAAoC,CAAC;IACzC,IAAI,UAAU,CAAC,qBAAqB,EAAE,CAAC;QACtC,2GAA2G;QAC3G,uCAAuC;QACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxF,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;QACvD,UAAU,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAClE,WAAW,CAAC,IAAI,CAAC;YAChB,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,QAAQ,gBAAgB,OAAO,UAAU,CAAC,QAAQ,CAAC,iBAAiB,UAAU,CAAC,iBAAiB,CAAC,6BAA6B,UAAU,CAAC,GAAG,CAAC,uBAAuB,gBAAgB,MAAM,IAAI,eAAe,GAAG,GAAG,CAAC,EAAE;SAC/N,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;IAC/E,CAAC;SAAM,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;QACjC,MAAM,cAAc,GAAG,gBAAgB,GAAG,UAAU,CAAC,WAAW,GAAG,CAAC,CAAC;QACrE,MAAM,UAAU,GAAG,cAAc,GAAG,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,iBAAiB,CAAC,SAAS,CAAC;QACxG,WAAW,CAAC,IAAI,CAAC;YAChB,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,iBAAiB,gBAAgB,IAAI,cAAc,OAAO,cAAc,GAAG,SAAS,gBAAgB,UAAU,eAAe;SACtI,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,UAAU,EAAE,CAAC;IAC1B,CAAC;SAAM,IAAI,gBAAgB,KAAK,SAAS,IAAI,SAAS,GAAG,gBAAgB,GAAG,cAAc,EAAE,CAAC;QAC5F,MAAM,SAAS,GAAG,cAAc,GAAG,CAAC,SAAS,GAAG,gBAAgB,CAAC,CAAC;QAClE,MAAM,UAAU,GAAG,SAAS,GAAG,gBAAgB,GAAG,CAAC,CAAC;QACpD,WAAW,CAAC,IAAI,CAAC;YAChB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,GAAG,SAAS,mCAAmC,UAAU,eAAe;SACjF,CAAC,CAAC;IACJ,CAAC;IAED,OAAO;QACN,MAAM,EAAE,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QAC9E,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;QAC7C,WAAW;KACX,CAAC;AACH,CAAC","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport { type Static, Type } from \"typebox\";\nimport {\n\ttype BinaryReader,\n\ttype FileInfo,\n\tgetOrThrow,\n\ttype LineScan,\n\trangeDecoder,\n\tstartsWithBom,\n} from \"../env/index.ts\";\nimport { defineTool } from \"../harness/define.ts\";\nimport { characterEnd } from \"../harness/output.ts\";\nimport type { ToolDiagnostic, ToolExecutionApi, ToolExecutionResult, ToolRegistration } from \"../harness/types.ts\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationResult,\n\ttruncateHeadOf,\n\tutf8ByteLength,\n} from \"../truncate.ts\";\nimport { requireEnv } from \"./env.ts\";\nimport { detectSupportedImageMimeTypeOf, imageDimensions } from \"./image.ts\";\nimport {\n\tbase64Length,\n\tDEFAULT_IMAGE_LIMITS,\n\ttype ImageLimits,\n\ttype ImageProcessor,\n\tINLINE_IMAGE_TYPES,\n\ttoBase64,\n} from \"./image-processor.ts\";\nimport { resolveReadToolPath } from \"./path-utils.ts\";\n\nconst readSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to read (relative or absolute)\" }),\n\toffset: Type.Optional(Type.Number({ description: \"Line number to start reading from (1-indexed)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of lines to read\" })),\n});\n\nexport type ReadToolInput = Static<typeof readSchema>;\n\nexport type ReadToolDetails = {\n\t/** How the shown text was cut; the text itself is the result content. */\n\ttruncation?: Omit<TruncationResult, \"content\">;\n};\n\nconst READ_CHUNK = 64 * 1024;\n\n/** `Array.prototype.slice`'s conversion of an index: NaN is 0, other values truncate toward zero. */\nfunction sliceIndex(value: number): number {\n\treturn Number.isNaN(value) ? 0 : Math.trunc(value);\n}\n\n/**\n * The decoded start of bytes `[start, end)` of the file, decoded as part of the whole file: all of it, or enough for\n * `truncateHeadOf` (more than `DEFAULT_MAX_BYTES + 1` bytes, or `DEFAULT_MAX_LINES` newlines).\n */\nasync function readHead(\n\treader: BinaryReader,\n\tstart: number,\n\tend: number,\n\tskipBom: boolean,\n\tcontext: Context,\n): Promise<string> {\n\tconst decoder = rangeDecoder();\n\tlet text = \"\";\n\tlet newlines = 0;\n\tfor (let position = skipBom && start === 0 ? 3 : start; position < end; ) {\n\t\tconst bytes = getOrThrow(await reader.read(position, Math.min(READ_CHUNK, end - position), context));\n\t\tif (bytes.length === 0) break;\n\t\tposition += bytes.length;\n\t\tconst decoded = decoder.decode(bytes, { stream: true });\n\t\ttext += decoded;\n\t\tfor (let index = decoded.indexOf(\"\\n\"); index !== -1; index = decoded.indexOf(\"\\n\", index + 1)) newlines++;\n\t\tif (newlines >= DEFAULT_MAX_LINES || utf8ByteLength(text) > DEFAULT_MAX_BYTES + 1) return text;\n\t}\n\treturn text + decoder.decode();\n}\n\nexport type ReadToolOptions = {\n\t/** Resizes and converts images; without one, images within `DEFAULT_IMAGE_LIMITS.maxBytes` pass through as they are. */\n\treadonly images?: ImageProcessor;\n};\n\n/**\n * Reads text files and images. Remarks about truncation, continuation, and image processing are diagnostics; the content\n * is only file text, or one image, which programs get as its `ImageContent`.\n */\nexport function createReadTool(options: ReadToolOptions = {}): ToolRegistration<typeof readSchema, ReadToolDetails> {\n\tconst formats = options.images === undefined ? \"jpg, png, gif, webp\" : \"jpg, png, gif, webp, bmp\";\n\treturn defineTool({\n\t\tname: \"read\",\n\t\tdescription: `Read the contents of a file. Supports text files and images (${formats}). Images are sent as attachments. For text files, output is truncated to ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.`,\n\t\tparameters: readSchema,\n\t\tasync execute(args, api, context) {\n\t\t\tconst { path, offset, limit } = args;\n\t\t\tconst env = requireEnv(api);\n\t\t\tconst absolutePath = await resolveReadToolPath(env, path, context);\n\t\t\tconst reader = getOrThrow(await env.openBinaryReader(absolutePath, undefined, context));\n\t\t\ttry {\n\t\t\t\t// A concurrent writer can change the file between the scan and the reads. Appending (a growing log) leaves\n\t\t\t\t// the scanned text as it was; an image must be whole. Otherwise the file is read again once.\n\t\t\t\tfor (let attempt = 0; ; attempt++) {\n\t\t\t\t\tconst before = getOrThrow(await reader.info(context));\n\t\t\t\t\tconst mimeType = await detectSupportedImageMimeTypeOf({\n\t\t\t\t\t\tsize: before.size,\n\t\t\t\t\t\tread: async (position, length) => getOrThrow(await reader.read(position, length, context)),\n\t\t\t\t\t});\n\t\t\t\t\tconst result =\n\t\t\t\t\t\tmimeType === undefined\n\t\t\t\t\t\t\t? await readText(reader, path, offset, limit, context)\n\t\t\t\t\t\t\t: await readImage(\n\t\t\t\t\t\t\t\t\treader,\n\t\t\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\t\t\tmimeType,\n\t\t\t\t\t\t\t\t\toptions.images,\n\t\t\t\t\t\t\t\t\tawait imageModel(api, context),\n\t\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\tconst after = getOrThrow(await reader.info(context));\n\t\t\t\t\tconst unchanged = after.size === before.size && after.mtimeMs === before.mtimeMs;\n\t\t\t\t\tif (unchanged || (mimeType === undefined && after.size > before.size)) return result;\n\t\t\t\t\tif (attempt === 1) throw new Error(`${path} changed while it was read`);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tawait reader.close(context);\n\t\t\t}\n\t\t},\n\t});\n}\n\n/**\n * One image block, prepared by `processor` or, without one, as it is when its format is inline and it fits the limits\n * (its size is checked before reading it, its dimensions from its header); otherwise an error result saying why. What happened to the image is an `info` diagnostic, so programs get the\n * bare `ImageContent`. A model without image input sees pi-ai's placeholder instead; a diagnostic says so.\n */\nasync function readImage(\n\treader: BinaryReader,\n\tinfo: FileInfo,\n\tpath: string,\n\tmimeType: string,\n\tprocessor: ImageProcessor | undefined,\n\t{ vision, limits }: ImageModel,\n\tcontext: Context,\n): Promise<ToolExecutionResult<ReadToolDetails>> {\n\tlet image: { readonly data: string; readonly mimeType: string };\n\tconst notes: string[] = [];\n\tif (processor !== undefined) {\n\t\tconst bytes = getOrThrow(await reader.read(0, info.size, context));\n\t\tconst prepared = await processor.prepare(bytes, mimeType, limits);\n\t\tif (prepared === undefined)\n\t\t\treturn imageError(`${path} is an image (${mimeType}) that cannot be prepared for the model`);\n\t\timage = prepared;\n\t\tif (prepared.convertedFrom !== undefined)\n\t\t\tnotes.push(`Converted from ${prepared.convertedFrom} to ${prepared.mimeType}.`);\n\t\tif (prepared.resized !== undefined) {\n\t\t\tconst { from, to } = prepared.resized;\n\t\t\tconst scale = (from.width / to.width).toFixed(2);\n\t\t\tnotes.push(\n\t\t\t\t`Resized from ${from.width}x${from.height} to ${to.width}x${to.height}. Multiply coordinates by ${scale} to map them to the original.`,\n\t\t\t);\n\t\t}\n\t} else {\n\t\tif (!INLINE_IMAGE_TYPES.has(mimeType)) {\n\t\t\treturn imageError(\n\t\t\t\t`${path} is an image (${mimeType}) that needs converting, and no image processor is configured`,\n\t\t\t);\n\t\t}\n\t\tconst unshrinkable = \"and no image processor is configured to shrink it\";\n\t\tif (base64Length(info.size) > limits.maxBytes) {\n\t\t\treturn imageError(\n\t\t\t\t`${path} is an image (${mimeType}) of ${formatSize(info.size)}, too large to send, ${unshrinkable}`,\n\t\t\t);\n\t\t}\n\t\tconst bytes = getOrThrow(await reader.read(0, info.size, context));\n\t\tconst size = imageDimensions(bytes, mimeType);\n\t\tif (size === undefined) return imageError(`${path} is an image (${mimeType}) whose size cannot be read`);\n\t\tif (size.width > limits.maxWidth || size.height > limits.maxHeight) {\n\t\t\treturn imageError(\n\t\t\t\t`${path} is an image (${mimeType}) of ${size.width}x${size.height}, larger than ${limits.maxWidth}x${limits.maxHeight}, ${unshrinkable}`,\n\t\t\t);\n\t\t}\n\t\timage = { data: toBase64(bytes), mimeType };\n\t}\n\tif (!vision) notes.push(\"The current model does not support images; it sees a placeholder instead.\");\n\tconst diagnostics: ToolDiagnostic[] = [\n\t\t{ severity: \"info\", code: \"image\", message: [`Read image file [${image.mimeType}].`, ...notes].join(\" \") },\n\t];\n\treturn { output: [{ type: \"image\", data: image.data, mimeType: image.mimeType }], diagnostics };\n}\n\n/** What the conversation's model takes: whether images, and within which limits. */\ntype ImageModel = { readonly vision: boolean; readonly limits: ImageLimits };\n\n/**\n * The conversation model's image input: `DEFAULT_IMAGE_LIMITS` overridden by its `inputLimits.images.resize`. Without\n * a resolvable model, it counts as one that takes images within the defaults.\n */\nasync function imageModel(api: ToolExecutionApi, context: Context): Promise<ImageModel> {\n\tconst ref = (await api.agent(context)).model;\n\tconst model = ref === undefined ? undefined : api.models.getModel(ref.provider, ref.modelId);\n\tconst resize = model?.inputLimits?.images?.resize;\n\treturn {\n\t\tvision: model?.input.includes(\"image\") ?? true,\n\t\tlimits: {\n\t\t\tmaxWidth: resize?.maxWidth ?? DEFAULT_IMAGE_LIMITS.maxWidth,\n\t\t\tmaxHeight: resize?.maxHeight ?? DEFAULT_IMAGE_LIMITS.maxHeight,\n\t\t\tmaxBytes: resize?.maxBytes ?? DEFAULT_IMAGE_LIMITS.maxBytes,\n\t\t},\n\t};\n}\n\nfunction imageError(message: string): ToolExecutionResult<ReadToolDetails> {\n\treturn { output: [], isError: true, diagnostics: [{ severity: \"error\", code: \"unsupported_image\", message }] };\n}\n\n/**\n * The read result for the opened file. It equals decoding the whole file with `TextDecoder`, splitting it on `\\n`,\n * and bounding the selected lines with `truncateHead`, while reading only one scan's worth of the file plus the head.\n */\nasync function readText(\n\treader: BinaryReader,\n\tpath: string,\n\toffset: number | undefined,\n\tlimit: number | undefined,\n\tcontext: Context,\n) {\n\tconst startLine = offset ? Math.max(0, offset - 1) : 0;\n\tconst startLineDisplay = startLine + 1;\n\t// Lines are selected like `allLines.slice(startLine, endLine)`, which truncates fractional indices.\n\tconst sliceStart = sliceIndex(startLine);\n\t// One pass finds the line count and the selection; a selection past the last line ends with it, as `slice` does,\n\t// and an empty one (a zero or negative limit) is scanned as one line and then ignored.\n\t// A start beyond any file is scanned from 0 only to count lines; the offset check below then fails as before.\n\tconst scanStart = Number.isSafeInteger(sliceStart) ? sliceStart : 0;\n\tconst requestedEnd = limit === undefined ? undefined : Math.max(scanStart + 1, sliceIndex(startLine + limit));\n\tconst scanEnd = requestedEnd !== undefined && Number.isSafeInteger(requestedEnd) ? requestedEnd : undefined;\n\tconst scanOf = async (endLine: number | undefined): Promise<LineScan> =>\n\t\tgetOrThrow(\n\t\t\tawait reader.scanLines({ startLine: scanStart, ...(endLine === undefined ? {} : { endLine }) }, context),\n\t\t);\n\tlet scan = await scanOf(scanEnd);\n\tconst totalFileLines = scan.newlines + 1;\n\tif (startLine >= totalFileLines) {\n\t\tthrow new Error(`Offset ${offset} is beyond end of file (${totalFileLines} lines total)`);\n\t}\n\n\tlet userLimitedLines: number | undefined;\n\tlet selectedLineCount = totalFileLines - sliceStart;\n\tif (limit !== undefined) {\n\t\tconst endLine = Math.min(startLine + limit, totalFileLines);\n\t\tuserLimitedLines = endLine - startLine;\n\t\t// `slice` counts a negative end from the end of the lines, which only the line count tells; scan again for it.\n\t\tconst relativeEnd = sliceIndex(endLine);\n\t\tconst sliceEnd = relativeEnd < 0 ? Math.max(totalFileLines + relativeEnd, 0) : relativeEnd;\n\t\tselectedLineCount = Math.max(0, sliceEnd - sliceStart);\n\t\tif (selectedLineCount > 0 && relativeEnd < 0) scan = await scanOf(sliceEnd);\n\t}\n\tconst empty = selectedLineCount === 0;\n\t// Counted like `truncateHead`: a trailing newline adds no line, and empty text has none.\n\tconst endsWithNewline = !empty && scan.lastLineStart === scan.end && scan.lastLineStart > scan.start;\n\tconst totals = {\n\t\tlines: empty || scan.selectedBytes === 0 ? 0 : selectedLineCount - (endsWithNewline ? 1 : 0),\n\t\tbytes: empty ? 0 : scan.selectedBytes,\n\t};\n\tconst firstBytes = getOrThrow(await reader.read(0, 3, context));\n\tconst head = empty ? \"\" : await readHead(reader, scan.start, scan.end, startsWithBom(firstBytes), context);\n\n\tconst { content: headText, ...truncation } = truncateHeadOf(head, totals);\n\tconst diagnostics: ToolDiagnostic[] = [];\n\tlet outputText = headText;\n\tlet details: ReadToolDetails | undefined;\n\tif (truncation.firstLineExceedsLimit) {\n\t\t// Show the start of the line, cut at the byte limit on a character boundary. Like `allLines[startLine]`, a\n\t\t// fractional start line names no line.\n\t\tconst integral = Number.isInteger(startLine);\n\t\tconst lineBytes = new TextEncoder().encode(integral ? (head.split(\"\\n\")[0] ?? \"\") : \"\");\n\t\tconst lineSize = integral ? scan.firstLineBytes : 0;\n\t\tconst end = characterEnd(lineBytes, DEFAULT_MAX_BYTES);\n\t\toutputText = new TextDecoder().decode(lineBytes.subarray(0, end));\n\t\tdiagnostics.push({\n\t\t\tseverity: \"warn\",\n\t\t\tcode: \"truncated\",\n\t\t\tmessage: `Line ${startLineDisplay} is ${formatSize(lineSize)}, exceeds the ${formatSize(DEFAULT_MAX_BYTES)} limit; showing its first ${formatSize(end)}. Use bash: sed -n '${startLineDisplay}p' ${path} | tail -c +${end + 1}`,\n\t\t});\n\t\tdetails = { truncation: { ...truncation, outputBytes: end, outputLines: 1 } };\n\t} else if (truncation.truncated) {\n\t\tconst endLineDisplay = startLineDisplay + truncation.outputLines - 1;\n\t\tconst nextOffset = endLineDisplay + 1;\n\t\tconst limitText = truncation.truncatedBy === \"lines\" ? \"\" : ` (${formatSize(DEFAULT_MAX_BYTES)} limit)`;\n\t\tdiagnostics.push({\n\t\t\tseverity: \"info\",\n\t\t\tcode: \"truncated\",\n\t\t\tmessage: `Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines}${limitText}. Use offset=${nextOffset} to continue.`,\n\t\t});\n\t\tdetails = { truncation };\n\t} else if (userLimitedLines !== undefined && startLine + userLimitedLines < totalFileLines) {\n\t\tconst remaining = totalFileLines - (startLine + userLimitedLines);\n\t\tconst nextOffset = startLine + userLimitedLines + 1;\n\t\tdiagnostics.push({\n\t\t\tseverity: \"info\",\n\t\t\tmessage: `${remaining} more lines in file. Use offset=${nextOffset} to continue.`,\n\t\t});\n\t}\n\n\treturn {\n\t\toutput: outputText === \"\" ? [] : [{ type: \"text\" as const, text: outputText }],\n\t\t...(details === undefined ? {} : { details }),\n\t\tdiagnostics,\n\t};\n}\n"]}
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport { characterEnd } from \"@earendil-works/chord/output\";\nimport { type Static, Type } from \"typebox\";\nimport {\n\ttype BinaryReader,\n\ttype FileInfo,\n\tgetOrThrow,\n\ttype LineScan,\n\trangeDecoder,\n\tstartsWithBom,\n} from \"../env/index.ts\";\nimport { defineTool } from \"../harness/define.ts\";\nimport type { ToolDiagnostic, ToolExecutionApi, ToolExecutionResult, ToolRegistration } from \"../harness/types.ts\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationResult,\n\ttruncateHeadOf,\n\tutf8ByteLength,\n} from \"../truncate.ts\";\nimport { requireEnv } from \"./env.ts\";\nimport { detectSupportedImageMimeTypeOf, imageDimensions } from \"./image.ts\";\nimport {\n\tbase64Length,\n\tDEFAULT_IMAGE_LIMITS,\n\ttype ImageLimits,\n\ttype ImageProcessor,\n\tINLINE_IMAGE_TYPES,\n\ttoBase64,\n} from \"./image-processor.ts\";\nimport { resolveReadToolPath } from \"./path-utils.ts\";\n\nconst readSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to read (relative or absolute)\" }),\n\toffset: Type.Optional(Type.Number({ description: \"Line number to start reading from (1-indexed)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of lines to read\" })),\n});\n\nexport type ReadToolInput = Static<typeof readSchema>;\n\nexport type ReadToolDetails = {\n\t/** How the shown text was cut; the text itself is the result content. */\n\ttruncation?: Omit<TruncationResult, \"content\">;\n};\n\nconst READ_CHUNK = 64 * 1024;\n\n/** `Array.prototype.slice`'s conversion of an index: NaN is 0, other values truncate toward zero. */\nfunction sliceIndex(value: number): number {\n\treturn Number.isNaN(value) ? 0 : Math.trunc(value);\n}\n\n/**\n * The decoded start of bytes `[start, end)` of the file, decoded as part of the whole file: all of it, or enough for\n * `truncateHeadOf` (more than `DEFAULT_MAX_BYTES + 1` bytes, or `DEFAULT_MAX_LINES` newlines).\n */\nasync function readHead(\n\treader: BinaryReader,\n\tstart: number,\n\tend: number,\n\tskipBom: boolean,\n\tcontext: Context,\n): Promise<string> {\n\tconst decoder = rangeDecoder();\n\tlet text = \"\";\n\tlet newlines = 0;\n\tfor (let position = skipBom && start === 0 ? 3 : start; position < end; ) {\n\t\tconst bytes = getOrThrow(await reader.read(position, Math.min(READ_CHUNK, end - position), context));\n\t\tif (bytes.length === 0) break;\n\t\tposition += bytes.length;\n\t\tconst decoded = decoder.decode(bytes, { stream: true });\n\t\ttext += decoded;\n\t\tfor (let index = decoded.indexOf(\"\\n\"); index !== -1; index = decoded.indexOf(\"\\n\", index + 1)) newlines++;\n\t\tif (newlines >= DEFAULT_MAX_LINES || utf8ByteLength(text) > DEFAULT_MAX_BYTES + 1) return text;\n\t}\n\treturn text + decoder.decode();\n}\n\nexport type ReadToolOptions = {\n\t/** Resizes and converts images; without one, images within `DEFAULT_IMAGE_LIMITS.maxBytes` pass through as they are. */\n\treadonly images?: ImageProcessor;\n};\n\n/**\n * Reads text files and images. Remarks about truncation, continuation, and image processing are diagnostics; the content\n * is only file text, or one image, which programs get as its `ImageContent`.\n */\nexport function createReadTool(options: ReadToolOptions = {}): ToolRegistration<typeof readSchema, ReadToolDetails> {\n\tconst formats = options.images === undefined ? \"jpg, png, gif, webp\" : \"jpg, png, gif, webp, bmp\";\n\treturn defineTool({\n\t\tname: \"read\",\n\t\tdescription: `Read the contents of a file. Supports text files and images (${formats}). Images are sent as attachments. For text files, output is truncated to ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.`,\n\t\tparameters: readSchema,\n\t\tasync execute(args, api, context) {\n\t\t\tconst { path, offset, limit } = args;\n\t\t\tconst env = requireEnv(api);\n\t\t\tconst absolutePath = await resolveReadToolPath(env, path, context);\n\t\t\tconst reader = getOrThrow(await env.openBinaryReader(absolutePath, undefined, context));\n\t\t\ttry {\n\t\t\t\t// A concurrent writer can change the file between the scan and the reads. Appending (a growing log) leaves\n\t\t\t\t// the scanned text as it was; an image must be whole. Otherwise the file is read again once.\n\t\t\t\tfor (let attempt = 0; ; attempt++) {\n\t\t\t\t\tconst before = getOrThrow(await reader.info(context));\n\t\t\t\t\tconst mimeType = await detectSupportedImageMimeTypeOf({\n\t\t\t\t\t\tsize: before.size,\n\t\t\t\t\t\tread: async (position, length) => getOrThrow(await reader.read(position, length, context)),\n\t\t\t\t\t});\n\t\t\t\t\tconst result =\n\t\t\t\t\t\tmimeType === undefined\n\t\t\t\t\t\t\t? await readText(reader, path, offset, limit, context)\n\t\t\t\t\t\t\t: await readImage(\n\t\t\t\t\t\t\t\t\treader,\n\t\t\t\t\t\t\t\t\tbefore,\n\t\t\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\t\t\tmimeType,\n\t\t\t\t\t\t\t\t\toptions.images,\n\t\t\t\t\t\t\t\t\tawait imageModel(api, context),\n\t\t\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\tconst after = getOrThrow(await reader.info(context));\n\t\t\t\t\tconst unchanged = after.size === before.size && after.mtimeMs === before.mtimeMs;\n\t\t\t\t\tif (unchanged || (mimeType === undefined && after.size > before.size)) return result;\n\t\t\t\t\tif (attempt === 1) throw new Error(`${path} changed while it was read`);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tawait reader.close(context);\n\t\t\t}\n\t\t},\n\t});\n}\n\n/**\n * One image block, prepared by `processor` or, without one, as it is when its format is inline and it fits the limits\n * (its size is checked before reading it, its dimensions from its header); otherwise an error result saying why. What happened to the image is an `info` diagnostic, so programs get the\n * bare `ImageContent`. A model without image input sees pi-ai's placeholder instead; a diagnostic says so.\n */\nasync function readImage(\n\treader: BinaryReader,\n\tinfo: FileInfo,\n\tpath: string,\n\tmimeType: string,\n\tprocessor: ImageProcessor | undefined,\n\t{ vision, limits }: ImageModel,\n\tcontext: Context,\n): Promise<ToolExecutionResult<ReadToolDetails>> {\n\tlet image: { readonly data: string; readonly mimeType: string };\n\tconst notes: string[] = [];\n\tif (processor !== undefined) {\n\t\tconst bytes = getOrThrow(await reader.read(0, info.size, context));\n\t\tconst prepared = await processor.prepare(bytes, mimeType, limits);\n\t\tif (prepared === undefined)\n\t\t\treturn imageError(`${path} is an image (${mimeType}) that cannot be prepared for the model`);\n\t\timage = prepared;\n\t\tif (prepared.convertedFrom !== undefined)\n\t\t\tnotes.push(`Converted from ${prepared.convertedFrom} to ${prepared.mimeType}.`);\n\t\tif (prepared.resized !== undefined) {\n\t\t\tconst { from, to } = prepared.resized;\n\t\t\tconst scale = (from.width / to.width).toFixed(2);\n\t\t\tnotes.push(\n\t\t\t\t`Resized from ${from.width}x${from.height} to ${to.width}x${to.height}. Multiply coordinates by ${scale} to map them to the original.`,\n\t\t\t);\n\t\t}\n\t} else {\n\t\tif (!INLINE_IMAGE_TYPES.has(mimeType)) {\n\t\t\treturn imageError(\n\t\t\t\t`${path} is an image (${mimeType}) that needs converting, and no image processor is configured`,\n\t\t\t);\n\t\t}\n\t\tconst unshrinkable = \"and no image processor is configured to shrink it\";\n\t\tif (base64Length(info.size) > limits.maxBytes) {\n\t\t\treturn imageError(\n\t\t\t\t`${path} is an image (${mimeType}) of ${formatSize(info.size)}, too large to send, ${unshrinkable}`,\n\t\t\t);\n\t\t}\n\t\tconst bytes = getOrThrow(await reader.read(0, info.size, context));\n\t\tconst size = imageDimensions(bytes, mimeType);\n\t\tif (size === undefined) return imageError(`${path} is an image (${mimeType}) whose size cannot be read`);\n\t\tif (size.width > limits.maxWidth || size.height > limits.maxHeight) {\n\t\t\treturn imageError(\n\t\t\t\t`${path} is an image (${mimeType}) of ${size.width}x${size.height}, larger than ${limits.maxWidth}x${limits.maxHeight}, ${unshrinkable}`,\n\t\t\t);\n\t\t}\n\t\timage = { data: toBase64(bytes), mimeType };\n\t}\n\tif (!vision) notes.push(\"The current model does not support images; it sees a placeholder instead.\");\n\tconst diagnostics: ToolDiagnostic[] = [\n\t\t{ severity: \"info\", code: \"image\", message: [`Read image file [${image.mimeType}].`, ...notes].join(\" \") },\n\t];\n\treturn { output: [{ type: \"image\", data: image.data, mimeType: image.mimeType }], diagnostics };\n}\n\n/** What the conversation's model takes: whether images, and within which limits. */\ntype ImageModel = { readonly vision: boolean; readonly limits: ImageLimits };\n\n/**\n * The conversation model's image input: `DEFAULT_IMAGE_LIMITS` overridden by its `inputLimits.images.resize`. Without\n * a resolvable model, it counts as one that takes images within the defaults.\n */\nasync function imageModel(api: ToolExecutionApi, context: Context): Promise<ImageModel> {\n\tconst ref = (await api.agent(context)).model;\n\tconst model = ref === undefined ? undefined : api.models.getModel(ref.provider, ref.modelId);\n\tconst resize = model?.inputLimits?.images?.resize;\n\treturn {\n\t\tvision: model?.input.includes(\"image\") ?? true,\n\t\tlimits: {\n\t\t\tmaxWidth: resize?.maxWidth ?? DEFAULT_IMAGE_LIMITS.maxWidth,\n\t\t\tmaxHeight: resize?.maxHeight ?? DEFAULT_IMAGE_LIMITS.maxHeight,\n\t\t\tmaxBytes: resize?.maxBytes ?? DEFAULT_IMAGE_LIMITS.maxBytes,\n\t\t},\n\t};\n}\n\nfunction imageError(message: string): ToolExecutionResult<ReadToolDetails> {\n\treturn { output: [], isError: true, diagnostics: [{ severity: \"error\", code: \"unsupported_image\", message }] };\n}\n\n/**\n * The read result for the opened file. It equals decoding the whole file with `TextDecoder`, splitting it on `\\n`,\n * and bounding the selected lines with `truncateHead`, while reading only one scan's worth of the file plus the head.\n */\nasync function readText(\n\treader: BinaryReader,\n\tpath: string,\n\toffset: number | undefined,\n\tlimit: number | undefined,\n\tcontext: Context,\n) {\n\tconst startLine = offset ? Math.max(0, offset - 1) : 0;\n\tconst startLineDisplay = startLine + 1;\n\t// Lines are selected like `allLines.slice(startLine, endLine)`, which truncates fractional indices.\n\tconst sliceStart = sliceIndex(startLine);\n\t// One pass finds the line count and the selection; a selection past the last line ends with it, as `slice` does,\n\t// and an empty one (a zero or negative limit) is scanned as one line and then ignored.\n\t// A start beyond any file is scanned from 0 only to count lines; the offset check below then fails as before.\n\tconst scanStart = Number.isSafeInteger(sliceStart) ? sliceStart : 0;\n\tconst requestedEnd = limit === undefined ? undefined : Math.max(scanStart + 1, sliceIndex(startLine + limit));\n\tconst scanEnd = requestedEnd !== undefined && Number.isSafeInteger(requestedEnd) ? requestedEnd : undefined;\n\tconst scanOf = async (endLine: number | undefined): Promise<LineScan> =>\n\t\tgetOrThrow(\n\t\t\tawait reader.scanLines({ startLine: scanStart, ...(endLine === undefined ? {} : { endLine }) }, context),\n\t\t);\n\tlet scan = await scanOf(scanEnd);\n\tconst totalFileLines = scan.newlines + 1;\n\tif (startLine >= totalFileLines) {\n\t\tthrow new Error(`Offset ${offset} is beyond end of file (${totalFileLines} lines total)`);\n\t}\n\n\tlet userLimitedLines: number | undefined;\n\tlet selectedLineCount = totalFileLines - sliceStart;\n\tif (limit !== undefined) {\n\t\tconst endLine = Math.min(startLine + limit, totalFileLines);\n\t\tuserLimitedLines = endLine - startLine;\n\t\t// `slice` counts a negative end from the end of the lines, which only the line count tells; scan again for it.\n\t\tconst relativeEnd = sliceIndex(endLine);\n\t\tconst sliceEnd = relativeEnd < 0 ? Math.max(totalFileLines + relativeEnd, 0) : relativeEnd;\n\t\tselectedLineCount = Math.max(0, sliceEnd - sliceStart);\n\t\tif (selectedLineCount > 0 && relativeEnd < 0) scan = await scanOf(sliceEnd);\n\t}\n\tconst empty = selectedLineCount === 0;\n\t// Counted like `truncateHead`: a trailing newline adds no line, and empty text has none.\n\tconst endsWithNewline = !empty && scan.lastLineStart === scan.end && scan.lastLineStart > scan.start;\n\tconst totals = {\n\t\tlines: empty || scan.selectedBytes === 0 ? 0 : selectedLineCount - (endsWithNewline ? 1 : 0),\n\t\tbytes: empty ? 0 : scan.selectedBytes,\n\t};\n\tconst firstBytes = getOrThrow(await reader.read(0, 3, context));\n\tconst head = empty ? \"\" : await readHead(reader, scan.start, scan.end, startsWithBom(firstBytes), context);\n\n\tconst { content: headText, ...truncation } = truncateHeadOf(head, totals);\n\tconst diagnostics: ToolDiagnostic[] = [];\n\tlet outputText = headText;\n\tlet details: ReadToolDetails | undefined;\n\tif (truncation.firstLineExceedsLimit) {\n\t\t// Show the start of the line, cut at the byte limit on a character boundary. Like `allLines[startLine]`, a\n\t\t// fractional start line names no line.\n\t\tconst integral = Number.isInteger(startLine);\n\t\tconst lineBytes = new TextEncoder().encode(integral ? (head.split(\"\\n\")[0] ?? \"\") : \"\");\n\t\tconst lineSize = integral ? scan.firstLineBytes : 0;\n\t\tconst end = characterEnd(lineBytes, DEFAULT_MAX_BYTES);\n\t\toutputText = new TextDecoder().decode(lineBytes.subarray(0, end));\n\t\tdiagnostics.push({\n\t\t\tseverity: \"warn\",\n\t\t\tcode: \"truncated\",\n\t\t\tmessage: `Line ${startLineDisplay} is ${formatSize(lineSize)}, exceeds the ${formatSize(DEFAULT_MAX_BYTES)} limit; showing its first ${formatSize(end)}. Use bash: sed -n '${startLineDisplay}p' ${path} | tail -c +${end + 1}`,\n\t\t});\n\t\tdetails = { truncation: { ...truncation, outputBytes: end, outputLines: 1 } };\n\t} else if (truncation.truncated) {\n\t\tconst endLineDisplay = startLineDisplay + truncation.outputLines - 1;\n\t\tconst nextOffset = endLineDisplay + 1;\n\t\tconst limitText = truncation.truncatedBy === \"lines\" ? \"\" : ` (${formatSize(DEFAULT_MAX_BYTES)} limit)`;\n\t\tdiagnostics.push({\n\t\t\tseverity: \"info\",\n\t\t\tcode: \"truncated\",\n\t\t\tmessage: `Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines}${limitText}. Use offset=${nextOffset} to continue.`,\n\t\t});\n\t\tdetails = { truncation };\n\t} else if (userLimitedLines !== undefined && startLine + userLimitedLines < totalFileLines) {\n\t\tconst remaining = totalFileLines - (startLine + userLimitedLines);\n\t\tconst nextOffset = startLine + userLimitedLines + 1;\n\t\tdiagnostics.push({\n\t\t\tseverity: \"info\",\n\t\t\tmessage: `${remaining} more lines in file. Use offset=${nextOffset} to continue.`,\n\t\t});\n\t}\n\n\treturn {\n\t\toutput: outputText === \"\" ? [] : [{ type: \"text\" as const, text: outputText }],\n\t\t...(details === undefined ? {} : { details }),\n\t\tdiagnostics,\n\t};\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { utf8ByteLength } from "@earendil-works/chord/output";
1
2
  /**
2
3
  * Shared truncation utilities for tool outputs.
3
4
  *
@@ -5,7 +6,7 @@
5
6
  * - Line limit (default: 2000 lines)
6
7
  * - Byte limit (default: 50KB)
7
8
  *
8
- * Never returns partial lines. Tool output streams are bounded by `src/harness/output.ts` instead.
9
+ * Never returns partial lines. Tool output streams are bounded by `OutputBuffer` from `@earendil-works/chord/output` instead.
9
10
  */
10
11
  export declare const DEFAULT_MAX_LINES = 2000;
11
12
  export declare const DEFAULT_MAX_BYTES: number;
@@ -39,7 +40,7 @@ export interface TruncationOptions {
39
40
  /** Maximum number of bytes (default: 50KB) */
40
41
  maxBytes?: number;
41
42
  }
42
- export declare function utf8ByteLength(content: string): number;
43
+ export { utf8ByteLength };
43
44
  /**
44
45
  * Format bytes as human-readable size.
45
46
  */