@earendil-works/pi-durable 1.0.3 → 1.1.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 (83) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +2 -0
  3. package/dist/env/node-watch.d.ts.map +1 -1
  4. package/dist/env/node-watch.js +89 -35
  5. package/dist/env/node-watch.js.map +1 -1
  6. package/dist/harness/agent.d.ts.map +1 -1
  7. package/dist/harness/agent.js +8 -1
  8. package/dist/harness/agent.js.map +1 -1
  9. package/dist/harness/compaction.js +1 -1
  10. package/dist/harness/compaction.js.map +1 -1
  11. package/dist/harness/context.d.ts +29 -1
  12. package/dist/harness/context.d.ts.map +1 -1
  13. package/dist/harness/context.js +125 -24
  14. package/dist/harness/context.js.map +1 -1
  15. package/dist/harness/generation.d.ts.map +1 -1
  16. package/dist/harness/generation.js +3 -3
  17. package/dist/harness/generation.js.map +1 -1
  18. package/dist/harness/harness.d.ts.map +1 -1
  19. package/dist/harness/harness.js +4 -3
  20. package/dist/harness/harness.js.map +1 -1
  21. package/dist/harness/output.d.ts.map +1 -1
  22. package/dist/harness/output.js +15 -3
  23. package/dist/harness/output.js.map +1 -1
  24. package/dist/harness/scheduler.d.ts.map +1 -1
  25. package/dist/harness/scheduler.js +98 -5
  26. package/dist/harness/scheduler.js.map +1 -1
  27. package/dist/harness/tool.d.ts +1 -1
  28. package/dist/harness/tool.d.ts.map +1 -1
  29. package/dist/harness/tool.js +15 -5
  30. package/dist/harness/tool.js.map +1 -1
  31. package/dist/harness/types.d.ts +18 -2
  32. package/dist/harness/types.d.ts.map +1 -1
  33. package/dist/harness/types.js.map +1 -1
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/session/session.d.ts +5 -3
  38. package/dist/session/session.d.ts.map +1 -1
  39. package/dist/session/session.js +5 -4
  40. package/dist/session/session.js.map +1 -1
  41. package/dist/session/transaction.d.ts +2 -0
  42. package/dist/session/transaction.d.ts.map +1 -1
  43. package/dist/session/transaction.js +18 -1
  44. package/dist/session/transaction.js.map +1 -1
  45. package/dist/storage/jsonl/storage.d.ts +4 -0
  46. package/dist/storage/jsonl/storage.d.ts.map +1 -1
  47. package/dist/storage/memory.d.ts +2 -0
  48. package/dist/storage/memory.d.ts.map +1 -1
  49. package/dist/storage/memory.js +72 -18
  50. package/dist/storage/memory.js.map +1 -1
  51. package/dist/storage/scan.d.ts +18 -0
  52. package/dist/storage/scan.d.ts.map +1 -0
  53. package/dist/storage/scan.js +28 -0
  54. package/dist/storage/scan.js.map +1 -0
  55. package/dist/storage/sqlite/cloudflare.d.ts +46 -0
  56. package/dist/storage/sqlite/cloudflare.d.ts.map +1 -0
  57. package/dist/storage/sqlite/cloudflare.js +106 -0
  58. package/dist/storage/sqlite/cloudflare.js.map +1 -0
  59. package/dist/storage/sqlite/storage.d.ts +2 -0
  60. package/dist/storage/sqlite/storage.d.ts.map +1 -1
  61. package/dist/storage/sqlite/storage.js +68 -16
  62. package/dist/storage/sqlite/storage.js.map +1 -1
  63. package/dist/testing/env-conformance.d.ts.map +1 -1
  64. package/dist/testing/env-conformance.js +34 -0
  65. package/dist/testing/env-conformance.js.map +1 -1
  66. package/dist/testing/storage-conformance.d.ts.map +1 -1
  67. package/dist/testing/storage-conformance.js +58 -0
  68. package/dist/testing/storage-conformance.js.map +1 -1
  69. package/dist/tools/bash.d.ts +21 -3
  70. package/dist/tools/bash.d.ts.map +1 -1
  71. package/dist/tools/bash.js +85 -38
  72. package/dist/tools/bash.js.map +1 -1
  73. package/dist/tools/index.d.ts +2 -2
  74. package/dist/tools/index.d.ts.map +1 -1
  75. package/dist/tools/index.js +2 -2
  76. package/dist/tools/index.js.map +1 -1
  77. package/dist/tools/read.d.ts.map +1 -1
  78. package/dist/tools/read.js +4 -2
  79. package/dist/tools/read.js.map +1 -1
  80. package/dist/types.d.ts +30 -7
  81. package/dist/types.d.ts.map +1 -1
  82. package/dist/types.js.map +1 -1
  83. package/package.json +10 -4
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/harness/output.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ShellOutputSkip } from \"../env/index.ts\";\nimport { utf8ByteLength } from \"../truncate.ts\";\n\n/** Retention limits of one tool's output. */\nexport type OutputLimits = { readonly maxBytes: number; readonly maxLines: number; readonly retain: \"head\" | \"tail\" };\n\n/** Retained output and what the limits dropped. */\nexport type BoundedOutput = { readonly text: string; readonly droppedBytes: number; readonly droppedLines: number };\n\n/** An exact slice of the input within the limits, and what it left out. */\nexport type OutputSlice = {\n\treadonly text: string;\n\treadonly bytes: number;\n\treadonly droppedBytes: number;\n\treadonly droppedLines: number;\n};\n\nconst NEWLINE = 0x0a;\nconst INVALID_OUTPUT = /[\\x00-\\x08\\x0b-\\x1f\\ufff9-\\ufffb]/g;\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/** Remove control characters that break display and transcripts; tabs and newlines stay. */\nexport function sanitizeOutput(text: string): string {\n\treturn text.replace(INVALID_OUTPUT, \"\");\n}\n\n/**\n * Bound `text` to whole lines within the limits: the first lines for `head`, the last lines for `tail`. The result is an\n * exact slice, trailing newline included. A single line longer than `maxBytes` is cut at the byte limit on a character\n * boundary.\n */\nexport function boundOutput(text: string, limits: OutputLimits): OutputSlice {\n\tconst bytes = encoder.encode(text);\n\tconst [from, to] = limits.retain === \"head\" ? headRange(bytes, limits) : tailRange(bytes, limits);\n\tconst kept = bytes.subarray(from, to);\n\treturn {\n\t\ttext: kept.length === bytes.length ? text : decoder.decode(kept),\n\t\tbytes: kept.length,\n\t\tdroppedBytes: bytes.length - kept.length,\n\t\tdroppedLines: lineCount(bytes) - lineCount(kept),\n\t};\n}\n\nfunction headRange(bytes: Uint8Array, limits: OutputLimits): [number, number] {\n\tif (limits.maxLines === 0 || limits.maxBytes === 0) return [0, 0];\n\tlet end = bytes.length;\n\tlet lines = 0;\n\tfor (let index = bytes.indexOf(NEWLINE); index !== -1; index = bytes.indexOf(NEWLINE, index + 1)) {\n\t\tif (++lines === limits.maxLines) {\n\t\t\tend = index + 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (end > limits.maxBytes) {\n\t\tconst newline = bytes.lastIndexOf(NEWLINE, limits.maxBytes - 1);\n\t\tend = newline === -1 ? characterEnd(bytes, limits.maxBytes) : newline + 1;\n\t}\n\treturn [0, end];\n}\n\nfunction tailRange(bytes: Uint8Array, limits: OutputLimits): [number, number] {\n\tif (limits.maxLines === 0 || limits.maxBytes === 0) return [bytes.length, bytes.length];\n\t// A trailing newline ends the last line rather than starting another.\n\tconst last = bytes[bytes.length - 1] === NEWLINE ? bytes.length - 2 : bytes.length - 1;\n\tlet start = 0;\n\tlet lines = 1;\n\tfor (let index = last < 0 ? -1 : bytes.lastIndexOf(NEWLINE, last); index !== -1; ) {\n\t\tif (lines === limits.maxLines) {\n\t\t\tstart = index + 1;\n\t\t\tbreak;\n\t\t}\n\t\tlines++;\n\t\tindex = index === 0 ? -1 : bytes.lastIndexOf(NEWLINE, index - 1);\n\t}\n\tif (bytes.length - start > limits.maxBytes) {\n\t\tconst from = bytes.length - limits.maxBytes;\n\t\tconst newline = bytes.indexOf(NEWLINE, from - 1);\n\t\t// The first line starting inside the byte window, or a cut of the last line when it alone is too long.\n\t\tstart = newline !== -1 && newline + 1 < bytes.length ? newline + 1 : characterStart(bytes, from);\n\t}\n\treturn [start, bytes.length];\n}\n\n/** The last character boundary at or before `index`. */\nexport function characterEnd(bytes: Uint8Array, index: number): number {\n\tlet end = index;\n\twhile (end > 0 && ((bytes[end] ?? 0) & 0xc0) === 0x80) end--;\n\treturn end;\n}\n\n/** The first character boundary at or after `index`. */\nfunction characterStart(bytes: Uint8Array, index: number): number {\n\tlet start = index;\n\twhile (start < bytes.length && ((bytes[start] ?? 0) & 0xc0) === 0x80) start++;\n\treturn start;\n}\n\nfunction lineCount(bytes: Uint8Array): number {\n\tif (bytes.length === 0) return 0;\n\tlet newlines = 0;\n\tfor (let index = bytes.indexOf(NEWLINE); index !== -1; index = bytes.indexOf(NEWLINE, index + 1)) newlines++;\n\treturn newlines + (bytes[bytes.length - 1] === NEWLINE ? 0 : 1);\n}\n\n/**\n * Bounded running output of one tool call. Accepting a chunk costs time proportional to the chunk: head retention stops\n * storing once the window is full, and tail retention drops stored text the window no longer needs when it snapshots.\n * Counts of the whole stream are kept so the dropped totals stay exact.\n */\nexport class OutputBuffer {\n\treadonly #limits: OutputLimits;\n\treadonly #decoder = new TextDecoder();\n\t/** Stored chunks: for head the start of the stream, for tail a suffix that still contains the next window. */\n\t#chunks: { readonly text: string; readonly bytes: number; readonly newlines: number }[] = [];\n\t#storedBytes = 0;\n\t#storedNewlines = 0;\n\t#full = false;\n\t#totalBytes = 0;\n\t#totalNewlines = 0;\n\t#endsWithNewline = true;\n\n\tconstructor(limits: OutputLimits) {\n\t\tthis.#limits = limits;\n\t}\n\n\t/** Bytes currently held; bounded by the limits plus one chunk. */\n\tget storedBytes(): number {\n\t\treturn this.#storedBytes;\n\t}\n\n\t/**\n\t * Accept a chunk; returns whether anything was accepted. `skipped` is output omitted right before the chunk, which\n\t * must be more than the tail window by at least one byte or line (`ShellOutputInfo.skipped`); only tail retention\n\t * accepts it.\n\t */\n\tpush(chunk: string | Uint8Array, skipped?: ShellOutputSkip): boolean {\n\t\t// Bytes of an incomplete character from an earlier byte chunk come first.\n\t\tconst pending = typeof chunk === \"string\" || skipped !== undefined ? this.#decoder.decode() : \"\";\n\t\tconst text = typeof chunk === \"string\" ? chunk : this.#decoder.decode(chunk, { stream: true });\n\t\tif (skipped === undefined) return this.#accept(pending + text);\n\t\tif (this.#limits.retain !== \"tail\") throw new Error(\"Skipped output requires tail retention\");\n\t\tthis.#accept(pending);\n\t\tthis.#skip(skipped);\n\t\tthis.#accept(text);\n\t\treturn true;\n\t}\n\n\t/** Count omitted output; nothing stored before it can be in the window once the text after it arrives. */\n\t#skip(skipped: ShellOutputSkip): void {\n\t\tif (skipped.bytes === 0) return;\n\t\tthis.#totalBytes += skipped.bytes;\n\t\tthis.#totalNewlines += skipped.newlines;\n\t\tthis.#endsWithNewline = skipped.endsWithNewline;\n\t\tthis.#chunks = [];\n\t\tthis.#storedBytes = 0;\n\t\tthis.#storedNewlines = 0;\n\t}\n\n\t/** Flush an incomplete trailing character as a replacement character; call when the stream ends. */\n\tend(): void {\n\t\tthis.#accept(this.#decoder.decode());\n\t}\n\n\t#accept(text: string): boolean {\n\t\tif (text.length === 0) return false;\n\t\tconst bytes = utf8ByteLength(text);\n\t\tconst newlines = countNewlines(text);\n\t\tthis.#totalBytes += bytes;\n\t\tthis.#totalNewlines += newlines;\n\t\tthis.#endsWithNewline = text.endsWith(\"\\n\");\n\t\tif (this.#full) return true;\n\t\tthis.#chunks.push({ text, bytes, newlines });\n\t\tthis.#storedBytes += bytes;\n\t\tthis.#storedNewlines += newlines;\n\t\tif (this.#limits.retain === \"head\") {\n\t\t\t// Nothing past a full window is ever needed.\n\t\t\tthis.#full = this.#storedBytes > this.#limits.maxBytes || this.#storedNewlines >= this.#limits.maxLines;\n\t\t\treturn true;\n\t\t}\n\t\t// Drop leading chunks while the rest still holds more than a window: more than `maxBytes` bytes or `maxLines`\n\t\t// newlines, plus one, so the window's line start can still be found. Each chunk is dropped once.\n\t\twhile (this.#chunks.length > 1) {\n\t\t\tconst first = this.#chunks[0]!;\n\t\t\tconst bytesAfter = this.#storedBytes - first.bytes;\n\t\t\tconst newlinesAfter = this.#storedNewlines - first.newlines;\n\t\t\tif (bytesAfter <= this.#limits.maxBytes + 1 && newlinesAfter <= this.#limits.maxLines + 1) break;\n\t\t\tthis.#chunks.shift();\n\t\t\tthis.#storedBytes = bytesAfter;\n\t\t\tthis.#storedNewlines = newlinesAfter;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/** Retained, sanitized output and what the limits dropped from the whole stream. */\n\tsnapshot(): BoundedOutput {\n\t\tconst stored =\n\t\t\tthis.#chunks.length === 1 ? this.#chunks[0]!.text : this.#chunks.map((chunk) => chunk.text).join(\"\");\n\t\tconst kept = boundOutput(stored, this.#limits);\n\t\tconst storedLines = lines(this.#storedNewlines, stored === \"\" || stored.endsWith(\"\\n\"));\n\t\tconst keptLines = storedLines - kept.droppedLines;\n\t\t// Tail windows never reach back before this one, but finding a later window's first line needs what precedes it:\n\t\t// keep the shortest suffix longer than the window by a byte or a line, as `#accept` does.\n\t\tif (this.#limits.retain === \"tail\" || this.#chunks.length > 1) {\n\t\t\tconst text = this.#limits.retain === \"tail\" ? tailMargin(stored, this.#limits) : stored;\n\t\t\tconst bytes = this.#limits.retain === \"tail\" ? utf8ByteLength(text) : this.#storedBytes;\n\t\t\tthis.#chunks = text === \"\" ? [] : [{ text, bytes, newlines: countNewlines(text) }];\n\t\t\tthis.#storedBytes = bytes;\n\t\t\tthis.#storedNewlines = this.#chunks[0]?.newlines ?? 0;\n\t\t}\n\t\treturn {\n\t\t\ttext: sanitizeOutput(kept.text),\n\t\t\tdroppedBytes: this.#totalBytes - kept.bytes,\n\t\t\tdroppedLines: lines(this.#totalNewlines, this.#endsWithNewline) - keptLines,\n\t\t};\n\t}\n}\n\n/**\n * The shortest suffix of `text` with more than `maxBytes` bytes or more than `maxLines` newlines, or all of it. The\n * tail window of any text that ends with this suffix, followed by anything, is the same as of `text` followed by it.\n */\nfunction tailMargin(text: string, limits: OutputLimits): string {\n\tconst bytes = encoder.encode(text);\n\tconst byteStart = bytes.length > limits.maxBytes ? characterEnd(bytes, bytes.length - limits.maxBytes - 1) : 0;\n\tlet lineStart = 0;\n\tlet newlines = 0;\n\tfor (let index = bytes.lastIndexOf(NEWLINE); index !== -1; index = bytes.lastIndexOf(NEWLINE, index - 1)) {\n\t\tif (++newlines > limits.maxLines) {\n\t\t\tlineStart = index;\n\t\t\tbreak;\n\t\t}\n\t\tif (index === 0) break;\n\t}\n\tconst start = Math.max(byteStart, lineStart);\n\treturn start === 0 ? text : decoder.decode(bytes.subarray(start));\n}\n\n/** Lines of text with `newlines` newlines; a final unterminated line counts. */\nfunction lines(newlines: number, terminated: boolean): number {\n\treturn newlines + (terminated ? 0 : 1);\n}\n\nfunction countNewlines(text: string): number {\n\tlet count = 0;\n\tfor (let index = text.indexOf(\"\\n\"); index !== -1; index = text.indexOf(\"\\n\", index + 1)) count++;\n\treturn count;\n}\n\n/** Each progress commit also buys a pause proportional to what it wrote. */\nexport const PROGRESS_BYTES_PER_SECOND = 100 * 1024;\n\n/**\n * Adaptive progress commits: the first change after an idle period commits at once; each commit then delays the next\n * by at least `minIntervalMs` and by its written size at 100 KiB/s. At most one commit is in flight; changes made\n * meanwhile coalesce into the next one.\n */\nexport class Progress {\n\treadonly #write: () => Promise<number>;\n\treadonly #onError: (error: unknown) => void;\n\treadonly #minIntervalMs: number;\n\t#waiters: PromiseWithResolvers<void>[] = [];\n\t#timer: ReturnType<typeof setTimeout> | undefined;\n\t#inFlight: Promise<void> | undefined;\n\t#nextAt = 0;\n\t#dirty = false;\n\t#stopped = false;\n\n\tconstructor(write: () => Promise<number>, onError: (error: unknown) => void, minIntervalMs: number) {\n\t\tthis.#write = write;\n\t\tthis.#onError = onError;\n\t\tthis.#minIntervalMs = minIntervalMs;\n\t}\n\n\t/** Schedule a commit. */\n\tmark(): void {\n\t\tthis.#dirty = true;\n\t\tthis.#schedule();\n\t}\n\n\t/** Schedule a commit; the promise settles with the commit that includes this change. */\n\tmarkAndWait(): Promise<void> {\n\t\tconst waiter = Promise.withResolvers<void>();\n\t\tthis.#waiters.push(waiter);\n\t\tthis.mark();\n\t\treturn waiter.promise;\n\t}\n\n\t/** Stop committing and wait for the commit in flight; returns the waiters the final commit must settle. */\n\tasync stop(): Promise<PromiseWithResolvers<void>[]> {\n\t\tthis.#stopped = true;\n\t\tclearTimeout(this.#timer);\n\t\tthis.#timer = undefined;\n\t\tawait this.#inFlight;\n\t\treturn this.#waiters.splice(0);\n\t}\n\n\t#schedule(): void {\n\t\tif (this.#stopped || this.#timer !== undefined || this.#inFlight !== undefined) return;\n\t\tconst wait = this.#nextAt - Date.now();\n\t\tif (wait <= 0) this.#flush();\n\t\telse\n\t\t\tthis.#timer = setTimeout(() => {\n\t\t\t\tthis.#timer = undefined;\n\t\t\t\tthis.#flush();\n\t\t\t}, wait);\n\t}\n\n\t#flush(): void {\n\t\tif (this.#stopped || !this.#dirty) return;\n\t\tthis.#dirty = false;\n\t\tconst waiters = this.#waiters.splice(0);\n\t\tconst started = Date.now();\n\t\tthis.#inFlight = this.#write()\n\t\t\t.then(\n\t\t\t\t(bytes) => {\n\t\t\t\t\tthis.#nextAt = started + Math.max(this.#minIntervalMs, (bytes * 1000) / PROGRESS_BYTES_PER_SECOND);\n\t\t\t\t\tfor (const waiter of waiters) waiter.resolve();\n\t\t\t\t},\n\t\t\t\t(error: unknown) => {\n\t\t\t\t\tthis.#nextAt = started + this.#minIntervalMs;\n\t\t\t\t\tfor (const waiter of waiters) waiter.reject(error);\n\t\t\t\t\tthis.#onError(error);\n\t\t\t\t},\n\t\t\t)\n\t\t\t.finally(() => {\n\t\t\t\tthis.#inFlight = undefined;\n\t\t\t\tif (this.#dirty) this.#schedule();\n\t\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/harness/output.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ShellOutputSkip } from \"../env/index.ts\";\nimport { utf8ByteLength } from \"../truncate.ts\";\n\n/** Retention limits of one tool's output. */\nexport type OutputLimits = { readonly maxBytes: number; readonly maxLines: number; readonly retain: \"head\" | \"tail\" };\n\n/** Retained output and what the limits dropped. */\nexport type BoundedOutput = { readonly text: string; readonly droppedBytes: number; readonly droppedLines: number };\n\n/** An exact slice of the input within the limits, and what it left out. */\nexport type OutputSlice = {\n\treadonly text: string;\n\treadonly bytes: number;\n\treadonly droppedBytes: number;\n\treadonly droppedLines: number;\n};\n\nconst NEWLINE = 0x0a;\nconst INVALID_OUTPUT = /[\\x00-\\x08\\x0b-\\x1f\\ufff9-\\ufffb]/g;\nconst encoder = new TextEncoder();\n/** Slices decode exactly: a U+FEFF at a slice's start is text, not a byte-order mark. */\nconst decoder = new TextDecoder(\"utf-8\", { ignoreBOM: true });\n\n/** Remove control characters that break display and transcripts; tabs and newlines stay. */\nexport function sanitizeOutput(text: string): string {\n\treturn text.replace(INVALID_OUTPUT, \"\");\n}\n\n/**\n * Bound `text` to whole lines within the limits: the first lines for `head`, the last lines for `tail`. The result is an\n * exact slice, trailing newline included. A single line longer than `maxBytes` is cut at the byte limit on a character\n * boundary.\n */\nexport function boundOutput(text: string, limits: OutputLimits): OutputSlice {\n\tconst bytes = encoder.encode(text);\n\tconst [from, to] = limits.retain === \"head\" ? headRange(bytes, limits) : tailRange(bytes, limits);\n\tconst kept = bytes.subarray(from, to);\n\treturn {\n\t\ttext: kept.length === bytes.length ? text : decoder.decode(kept),\n\t\tbytes: kept.length,\n\t\tdroppedBytes: bytes.length - kept.length,\n\t\tdroppedLines: lineCount(bytes) - lineCount(kept),\n\t};\n}\n\nfunction headRange(bytes: Uint8Array, limits: OutputLimits): [number, number] {\n\tif (limits.maxLines === 0 || limits.maxBytes === 0) return [0, 0];\n\tlet end = bytes.length;\n\tlet lines = 0;\n\tfor (let index = bytes.indexOf(NEWLINE); index !== -1; index = bytes.indexOf(NEWLINE, index + 1)) {\n\t\tif (++lines === limits.maxLines) {\n\t\t\tend = index + 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (end > limits.maxBytes) {\n\t\tconst newline = bytes.lastIndexOf(NEWLINE, limits.maxBytes - 1);\n\t\tend = newline === -1 ? characterEnd(bytes, limits.maxBytes) : newline + 1;\n\t}\n\treturn [0, end];\n}\n\nfunction tailRange(bytes: Uint8Array, limits: OutputLimits): [number, number] {\n\tif (limits.maxLines === 0 || limits.maxBytes === 0) return [bytes.length, bytes.length];\n\t// A trailing newline ends the last line rather than starting another.\n\tconst last = bytes[bytes.length - 1] === NEWLINE ? bytes.length - 2 : bytes.length - 1;\n\tlet start = 0;\n\tlet lines = 1;\n\tfor (let index = last < 0 ? -1 : bytes.lastIndexOf(NEWLINE, last); index !== -1; ) {\n\t\tif (lines === limits.maxLines) {\n\t\t\tstart = index + 1;\n\t\t\tbreak;\n\t\t}\n\t\tlines++;\n\t\tindex = index === 0 ? -1 : bytes.lastIndexOf(NEWLINE, index - 1);\n\t}\n\tif (bytes.length - start > limits.maxBytes) {\n\t\tconst from = bytes.length - limits.maxBytes;\n\t\tconst newline = bytes.indexOf(NEWLINE, from - 1);\n\t\t// The first line starting inside the byte window, or a cut of the last line when it alone is too long.\n\t\tstart = newline !== -1 && newline + 1 < bytes.length ? newline + 1 : characterStart(bytes, from);\n\t}\n\treturn [start, bytes.length];\n}\n\n/** The last character boundary at or before `index`. */\nexport function characterEnd(bytes: Uint8Array, index: number): number {\n\tlet end = index;\n\twhile (end > 0 && ((bytes[end] ?? 0) & 0xc0) === 0x80) end--;\n\treturn end;\n}\n\n/** The first character boundary at or after `index`. */\nfunction characterStart(bytes: Uint8Array, index: number): number {\n\tlet start = index;\n\twhile (start < bytes.length && ((bytes[start] ?? 0) & 0xc0) === 0x80) start++;\n\treturn start;\n}\n\nfunction lineCount(bytes: Uint8Array): number {\n\tif (bytes.length === 0) return 0;\n\tlet newlines = 0;\n\tfor (let index = bytes.indexOf(NEWLINE); index !== -1; index = bytes.indexOf(NEWLINE, index + 1)) newlines++;\n\treturn newlines + (bytes[bytes.length - 1] === NEWLINE ? 0 : 1);\n}\n\n/**\n * Bounded running output of one tool call. Accepting a chunk costs time proportional to the chunk: head retention stops\n * storing once the window is full, and tail retention drops stored text the window no longer needs when it snapshots.\n * Counts of the whole stream are kept so the dropped totals stay exact.\n */\nexport class OutputBuffer {\n\treadonly #limits: OutputLimits;\n\t/**\n\t * Decoder of byte chunks. A string chunk or a skip ends an incomplete character of earlier bytes (it becomes U+FFFD);\n\t * the next byte chunk then starts a new character. As in `StreamDecoder`, only a byte-order mark at the very start of\n\t * the output is dropped, never a U+FEFF later in it.\n\t */\n\treadonly #decoder = new TextDecoder(\"utf-8\", { ignoreBOM: true });\n\t#started = false;\n\t/** Stored chunks: for head the start of the stream, for tail a suffix that still contains the next window. */\n\t#chunks: { readonly text: string; readonly bytes: number; readonly newlines: number }[] = [];\n\t#storedBytes = 0;\n\t#storedNewlines = 0;\n\t#full = false;\n\t#totalBytes = 0;\n\t#totalNewlines = 0;\n\t#endsWithNewline = true;\n\n\tconstructor(limits: OutputLimits) {\n\t\tthis.#limits = limits;\n\t}\n\n\t/** Bytes currently held; bounded by the limits plus one chunk. */\n\tget storedBytes(): number {\n\t\treturn this.#storedBytes;\n\t}\n\n\t/**\n\t * Accept a chunk; returns whether anything was accepted. `skipped` is output omitted right before the chunk, which\n\t * must be more than the tail window by at least one byte or line (`ShellOutputInfo.skipped`); only tail retention\n\t * accepts it.\n\t */\n\tpush(chunk: string | Uint8Array, skipped?: ShellOutputSkip): boolean {\n\t\t// Bytes of an incomplete character from an earlier byte chunk come first.\n\t\tconst pending = typeof chunk === \"string\" || skipped !== undefined ? this.#decoder.decode() : \"\";\n\t\tlet text = typeof chunk === \"string\" ? chunk : this.#decoder.decode(chunk, { stream: true });\n\t\tconst first = !this.#started && pending === \"\" && skipped === undefined;\n\t\tif (pending !== \"\" || text !== \"\" || skipped !== undefined) this.#started = true;\n\t\tif (first && typeof chunk !== \"string\" && text.startsWith(\"\\ufeff\")) text = text.slice(1);\n\t\tif (skipped === undefined) return this.#accept(pending + text);\n\t\tif (this.#limits.retain !== \"tail\") throw new Error(\"Skipped output requires tail retention\");\n\t\tthis.#accept(pending);\n\t\tthis.#skip(skipped);\n\t\tthis.#accept(text);\n\t\treturn true;\n\t}\n\n\t/** Count omitted output; nothing stored before it can be in the window once the text after it arrives. */\n\t#skip(skipped: ShellOutputSkip): void {\n\t\tif (skipped.bytes === 0) return;\n\t\tthis.#totalBytes += skipped.bytes;\n\t\tthis.#totalNewlines += skipped.newlines;\n\t\tthis.#endsWithNewline = skipped.endsWithNewline;\n\t\tthis.#chunks = [];\n\t\tthis.#storedBytes = 0;\n\t\tthis.#storedNewlines = 0;\n\t}\n\n\t/** Flush an incomplete trailing character as a replacement character; call when the stream ends. */\n\tend(): void {\n\t\tthis.#accept(this.#decoder.decode());\n\t}\n\n\t#accept(text: string): boolean {\n\t\tif (text.length === 0) return false;\n\t\tconst bytes = utf8ByteLength(text);\n\t\tconst newlines = countNewlines(text);\n\t\tthis.#totalBytes += bytes;\n\t\tthis.#totalNewlines += newlines;\n\t\tthis.#endsWithNewline = text.endsWith(\"\\n\");\n\t\tif (this.#full) return true;\n\t\tthis.#chunks.push({ text, bytes, newlines });\n\t\tthis.#storedBytes += bytes;\n\t\tthis.#storedNewlines += newlines;\n\t\tif (this.#limits.retain === \"head\") {\n\t\t\t// Nothing past a full window is ever needed.\n\t\t\tthis.#full = this.#storedBytes > this.#limits.maxBytes || this.#storedNewlines >= this.#limits.maxLines;\n\t\t\treturn true;\n\t\t}\n\t\t// Drop leading chunks while the rest still holds more than a window: more than `maxBytes` bytes or `maxLines`\n\t\t// newlines, plus one, so the window's line start can still be found. Each chunk is dropped once.\n\t\twhile (this.#chunks.length > 1) {\n\t\t\tconst first = this.#chunks[0]!;\n\t\t\tconst bytesAfter = this.#storedBytes - first.bytes;\n\t\t\tconst newlinesAfter = this.#storedNewlines - first.newlines;\n\t\t\tif (bytesAfter <= this.#limits.maxBytes + 1 && newlinesAfter <= this.#limits.maxLines + 1) break;\n\t\t\tthis.#chunks.shift();\n\t\t\tthis.#storedBytes = bytesAfter;\n\t\t\tthis.#storedNewlines = newlinesAfter;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/** Retained, sanitized output and what the limits dropped from the whole stream. */\n\tsnapshot(): BoundedOutput {\n\t\tconst stored =\n\t\t\tthis.#chunks.length === 1 ? this.#chunks[0]!.text : this.#chunks.map((chunk) => chunk.text).join(\"\");\n\t\tconst kept = boundOutput(stored, this.#limits);\n\t\tconst storedLines = lines(this.#storedNewlines, stored === \"\" || stored.endsWith(\"\\n\"));\n\t\tconst keptLines = storedLines - kept.droppedLines;\n\t\t// Tail windows never reach back before this one, but finding a later window's first line needs what precedes it:\n\t\t// keep the shortest suffix longer than the window by a byte or a line, as `#accept` does.\n\t\tif (this.#limits.retain === \"tail\" || this.#chunks.length > 1) {\n\t\t\tconst text = this.#limits.retain === \"tail\" ? tailMargin(stored, this.#limits) : stored;\n\t\t\tconst bytes = this.#limits.retain === \"tail\" ? utf8ByteLength(text) : this.#storedBytes;\n\t\t\tthis.#chunks = text === \"\" ? [] : [{ text, bytes, newlines: countNewlines(text) }];\n\t\t\tthis.#storedBytes = bytes;\n\t\t\tthis.#storedNewlines = this.#chunks[0]?.newlines ?? 0;\n\t\t}\n\t\treturn {\n\t\t\ttext: sanitizeOutput(kept.text),\n\t\t\tdroppedBytes: this.#totalBytes - kept.bytes,\n\t\t\tdroppedLines: lines(this.#totalNewlines, this.#endsWithNewline) - keptLines,\n\t\t};\n\t}\n}\n\n/**\n * The shortest suffix of `text` with more than `maxBytes` bytes or more than `maxLines` newlines, or all of it. The\n * tail window of any text that ends with this suffix, followed by anything, is the same as of `text` followed by it.\n */\nfunction tailMargin(text: string, limits: OutputLimits): string {\n\tconst bytes = encoder.encode(text);\n\tconst byteStart = bytes.length > limits.maxBytes ? characterEnd(bytes, bytes.length - limits.maxBytes - 1) : 0;\n\tlet lineStart = 0;\n\tlet newlines = 0;\n\tfor (let index = bytes.lastIndexOf(NEWLINE); index !== -1; index = bytes.lastIndexOf(NEWLINE, index - 1)) {\n\t\tif (++newlines > limits.maxLines) {\n\t\t\tlineStart = index;\n\t\t\tbreak;\n\t\t}\n\t\tif (index === 0) break;\n\t}\n\tconst start = Math.max(byteStart, lineStart);\n\treturn start === 0 ? text : decoder.decode(bytes.subarray(start));\n}\n\n/** Lines of text with `newlines` newlines; a final unterminated line counts. */\nfunction lines(newlines: number, terminated: boolean): number {\n\treturn newlines + (terminated ? 0 : 1);\n}\n\nfunction countNewlines(text: string): number {\n\tlet count = 0;\n\tfor (let index = text.indexOf(\"\\n\"); index !== -1; index = text.indexOf(\"\\n\", index + 1)) count++;\n\treturn count;\n}\n\n/** Each progress commit also buys a pause proportional to what it wrote. */\nexport const PROGRESS_BYTES_PER_SECOND = 100 * 1024;\n\n/**\n * Adaptive progress commits: the first change after an idle period commits at once; each commit then delays the next\n * by at least `minIntervalMs` and by its written size at 100 KiB/s. At most one commit is in flight; changes made\n * meanwhile coalesce into the next one.\n */\nexport class Progress {\n\treadonly #write: () => Promise<number>;\n\treadonly #onError: (error: unknown) => void;\n\treadonly #minIntervalMs: number;\n\t#waiters: PromiseWithResolvers<void>[] = [];\n\t#timer: ReturnType<typeof setTimeout> | undefined;\n\t#inFlight: Promise<void> | undefined;\n\t#nextAt = 0;\n\t#dirty = false;\n\t#stopped = false;\n\n\tconstructor(write: () => Promise<number>, onError: (error: unknown) => void, minIntervalMs: number) {\n\t\tthis.#write = write;\n\t\tthis.#onError = onError;\n\t\tthis.#minIntervalMs = minIntervalMs;\n\t}\n\n\t/** Schedule a commit. */\n\tmark(): void {\n\t\tthis.#dirty = true;\n\t\tthis.#schedule();\n\t}\n\n\t/** Schedule a commit; the promise settles with the commit that includes this change. */\n\tmarkAndWait(): Promise<void> {\n\t\tconst waiter = Promise.withResolvers<void>();\n\t\tthis.#waiters.push(waiter);\n\t\tthis.mark();\n\t\treturn waiter.promise;\n\t}\n\n\t/** Stop committing and wait for the commit in flight; returns the waiters the final commit must settle. */\n\tasync stop(): Promise<PromiseWithResolvers<void>[]> {\n\t\tthis.#stopped = true;\n\t\tclearTimeout(this.#timer);\n\t\tthis.#timer = undefined;\n\t\tawait this.#inFlight;\n\t\treturn this.#waiters.splice(0);\n\t}\n\n\t#schedule(): void {\n\t\tif (this.#stopped || this.#timer !== undefined || this.#inFlight !== undefined) return;\n\t\tconst wait = this.#nextAt - Date.now();\n\t\tif (wait <= 0) this.#flush();\n\t\telse\n\t\t\tthis.#timer = setTimeout(() => {\n\t\t\t\tthis.#timer = undefined;\n\t\t\t\tthis.#flush();\n\t\t\t}, wait);\n\t}\n\n\t#flush(): void {\n\t\tif (this.#stopped || !this.#dirty) return;\n\t\tthis.#dirty = false;\n\t\tconst waiters = this.#waiters.splice(0);\n\t\tconst started = Date.now();\n\t\tthis.#inFlight = this.#write()\n\t\t\t.then(\n\t\t\t\t(bytes) => {\n\t\t\t\t\tthis.#nextAt = started + Math.max(this.#minIntervalMs, (bytes * 1000) / PROGRESS_BYTES_PER_SECOND);\n\t\t\t\t\tfor (const waiter of waiters) waiter.resolve();\n\t\t\t\t},\n\t\t\t\t(error: unknown) => {\n\t\t\t\t\tthis.#nextAt = started + this.#minIntervalMs;\n\t\t\t\t\tfor (const waiter of waiters) waiter.reject(error);\n\t\t\t\t\tthis.#onError(error);\n\t\t\t\t},\n\t\t\t)\n\t\t\t.finally(() => {\n\t\t\t\tthis.#inFlight = undefined;\n\t\t\t\tif (this.#dirty) this.#schedule();\n\t\t\t});\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/harness/scheduler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/harness/scheduler.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { copyJson } from "@earendil-works/chord";
2
2
  import { awaitWithContext, withAbortSignal } from "@earendil-works/chord/context";
3
3
  import { agentHooks } from "./agent.js";
4
- import { readContext } from "./context.js";
4
+ import { readContextFrom } from "./context.js";
5
5
  import { closedError, scanAll, Waiters } from "./util.js";
6
6
  const SCAN_PAGE_SIZE = 256;
7
7
  /** Longest delay `setTimeout` supports; longer sleeps wait in several steps. */
@@ -37,6 +37,14 @@ export class TaskScheduler {
37
37
  #conversation;
38
38
  #context;
39
39
  #live = new Map();
40
+ /**
41
+ * Context range last read through a task runtime, per conversation: a later read, by any of its tasks, scans only
42
+ * newer entries. `idleSince` is the Harness time it was first seen idle. Derived and never persisted; dropped at the
43
+ * first idle check after `settings.contextRetentionMs` of idleness, and at close.
44
+ */
45
+ #contexts = new Map();
46
+ /** Timer for the earliest expiry of an idle context, only where timers can be unreferenced (see `#scheduleExpiry`). */
47
+ #expiry;
40
48
  #invocations = new Map();
41
49
  #taskWaiters = new Waiters();
42
50
  /** Idle waiters by conversation; `undefined` waits for the whole Harness. */
@@ -279,14 +287,77 @@ export class TaskScheduler {
279
287
  this.#scheduleReconcile();
280
288
  if (!changed)
281
289
  return;
282
- this.#resolveIdleWaiters();
290
+ this.#settleIdle();
283
291
  this.#kick();
284
292
  }
285
- #resolveIdleWaiters() {
293
+ /**
294
+ * `settings.contextRetentionMs`, or 0 when the host's settings throw. Kept contexts are only a cache, so dropping them
295
+ * is safe, while a throw here would escape commit listeners, reconciliation, and the expiry timer.
296
+ */
297
+ #contextRetentionMs() {
298
+ try {
299
+ return this.#settings().contextRetentionMs;
300
+ }
301
+ catch (error) {
302
+ this.#report(error);
303
+ return 0;
304
+ }
305
+ }
306
+ /** Resolve idle waiters, and drop each kept context whose conversation has been idle for the retention period. */
307
+ #settleIdle() {
286
308
  for (const conversationId of this.#idleWaiters.keys()) {
287
309
  if (this.#idle(conversationId))
288
310
  this.#idleWaiters.resolve(conversationId);
289
311
  }
312
+ const now = this.#now();
313
+ const retention = this.#contextRetentionMs();
314
+ for (const [conversationId, kept] of this.#contexts) {
315
+ if (kept.idleSince !== undefined && now - kept.idleSince >= retention) {
316
+ this.#contexts.delete(conversationId);
317
+ }
318
+ else if (!this.#idle(conversationId)) {
319
+ kept.idleSince = undefined;
320
+ }
321
+ else if (retention > 0) {
322
+ kept.idleSince ??= now;
323
+ }
324
+ else {
325
+ this.#contexts.delete(conversationId);
326
+ }
327
+ }
328
+ this.#scheduleExpiry();
329
+ }
330
+ /**
331
+ * Run `#settleIdle()` when the earliest idle context expires. The timer is unreferenced, so it never keeps the process
332
+ * alive. Where timers cannot be unreferenced, as in Cloudflare Workers, none is kept: a pending timer could keep a
333
+ * Durable Object from being evicted, and eviction frees the contexts. There, task changes alone check expiry.
334
+ */
335
+ #scheduleExpiry() {
336
+ const retention = this.#contextRetentionMs();
337
+ let at;
338
+ for (const kept of this.#contexts.values()) {
339
+ if (kept.idleSince !== undefined && (at === undefined || kept.idleSince + retention < at)) {
340
+ at = kept.idleSince + retention;
341
+ }
342
+ }
343
+ if (this.#expiry !== undefined && this.#expiry.at === at)
344
+ return;
345
+ if (this.#expiry !== undefined)
346
+ clearTimeout(this.#expiry.timer);
347
+ this.#expiry = undefined;
348
+ if (at === undefined || this.#closing)
349
+ return;
350
+ const timer = setTimeout(() => {
351
+ this.#expiry = undefined;
352
+ this.#settleIdle();
353
+ }, Math.min(Math.max(0, at - this.#now()), MAX_TIMER_DELAY));
354
+ const unref = timer.unref;
355
+ if (typeof unref !== "function") {
356
+ clearTimeout(timer);
357
+ return;
358
+ }
359
+ unref.call(timer);
360
+ this.#expiry = { at, timer };
290
361
  }
291
362
  // ─── Ownership ───────────────────────────────────────────────────────────
292
363
  #scheduleReconcile() {
@@ -349,7 +420,7 @@ export class TaskScheduler {
349
420
  if (!this.#closing)
350
421
  this.#report(error);
351
422
  }
352
- this.#resolveIdleWaiters();
423
+ this.#settleIdle();
353
424
  }
354
425
  /** Whether any of `ids` holds or ended with an outcome other than `completed`. */
355
426
  async #anyFailed(ids) {
@@ -552,6 +623,10 @@ export class TaskScheduler {
552
623
  const error = closedError();
553
624
  this.#taskWaiters.rejectAll(error);
554
625
  this.#idleWaiters.rejectAll(error);
626
+ this.#contexts.clear();
627
+ if (this.#expiry !== undefined)
628
+ clearTimeout(this.#expiry.timer);
629
+ this.#expiry = undefined;
555
630
  for (const invocation of this.#invocations.values())
556
631
  invocation.controller.abort();
557
632
  }
@@ -1022,7 +1097,25 @@ export class TaskScheduler {
1022
1097
  return token === undefined || entry?.kind === token.kind ? entry : undefined;
1023
1098
  });
1024
1099
  }),
1025
- context: (conversationId, context, at) => this.#read(invocation, () => readContext(this.#session, this.#storage, conversationId, context, at)),
1100
+ context: (conversationId, context, options) => this.#read(invocation, async () => {
1101
+ const { view, range } = await readContextFrom(this.#session, this.#storage, conversationId, context, options?.at, this.#contexts.get(conversationId)?.range);
1102
+ // Keep it unless the invocation ended or a concurrent read already kept a newer range.
1103
+ const kept = this.#contexts.get(conversationId);
1104
+ if (range !== undefined &&
1105
+ !this.#closing &&
1106
+ !invocation.ended &&
1107
+ (kept === undefined || kept.range.bounds.tail <= range.bounds.tail)) {
1108
+ // A read of another, idle conversation starts or continues its retention period.
1109
+ if (!this.#idle(conversationId)) {
1110
+ this.#contexts.set(conversationId, { range, idleSince: undefined });
1111
+ }
1112
+ else if (this.#contextRetentionMs() > 0) {
1113
+ this.#contexts.set(conversationId, { range, idleSince: kept?.idleSince ?? this.#now() });
1114
+ this.#scheduleExpiry();
1115
+ }
1116
+ }
1117
+ return view;
1118
+ }),
1026
1119
  now: () => {
1027
1120
  if (invocation.ended)
1028
1121
  throw endedError(invocation);