@earendil-works/pi-durable 1.5.0 → 1.5.1
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.
- package/CHANGELOG.md +18 -0
- package/README.md +17 -4
- package/dist/codemode/codemode.d.ts +2 -1
- package/dist/codemode/codemode.d.ts.map +1 -1
- package/dist/codemode/codemode.js +1 -37
- package/dist/codemode/codemode.js.map +1 -1
- package/dist/codemode/models.d.ts +2 -1
- package/dist/codemode/models.d.ts.map +1 -1
- package/dist/codemode/models.js.map +1 -1
- package/dist/documents.d.ts +1 -1
- package/dist/documents.d.ts.map +1 -1
- package/dist/documents.js +1 -1
- package/dist/documents.js.map +1 -1
- package/dist/entries.d.ts +1 -1
- package/dist/entries.d.ts.map +1 -1
- package/dist/entries.js.map +1 -1
- package/dist/env/index.d.ts +1 -1
- package/dist/env/index.d.ts.map +1 -1
- package/dist/env/index.js.map +1 -1
- package/dist/env/node-watch.d.ts +1 -1
- package/dist/env/node-watch.d.ts.map +1 -1
- package/dist/env/node-watch.js.map +1 -1
- package/dist/env/node.d.ts +1 -1
- package/dist/env/node.d.ts.map +1 -1
- package/dist/env/node.js.map +1 -1
- package/dist/harness/agent.d.ts.map +1 -1
- package/dist/harness/agent.js +27 -1
- package/dist/harness/agent.js.map +1 -1
- package/dist/harness/compaction.d.ts +8 -3
- package/dist/harness/compaction.d.ts.map +1 -1
- package/dist/harness/compaction.js +21 -9
- package/dist/harness/compaction.js.map +1 -1
- package/dist/harness/context.d.ts +1 -1
- package/dist/harness/context.d.ts.map +1 -1
- package/dist/harness/context.js.map +1 -1
- package/dist/harness/define.d.ts +1 -1
- package/dist/harness/define.d.ts.map +1 -1
- package/dist/harness/define.js.map +1 -1
- package/dist/harness/generation.d.ts +1 -1
- package/dist/harness/generation.d.ts.map +1 -1
- package/dist/harness/generation.js +6 -4
- package/dist/harness/generation.js.map +1 -1
- package/dist/harness/harness.d.ts +1 -1
- package/dist/harness/harness.d.ts.map +1 -1
- package/dist/harness/harness.js.map +1 -1
- package/dist/harness/inbox.d.ts +2 -1
- package/dist/harness/inbox.d.ts.map +1 -1
- package/dist/harness/inbox.js +1 -1
- package/dist/harness/inbox.js.map +1 -1
- package/dist/harness/json.d.ts +1 -1
- package/dist/harness/json.d.ts.map +1 -1
- package/dist/harness/json.js.map +1 -1
- package/dist/harness/live.d.ts +2 -1
- package/dist/harness/live.d.ts.map +1 -1
- package/dist/harness/live.js.map +1 -1
- package/dist/harness/partial-changes.d.ts +1 -1
- package/dist/harness/partial-changes.d.ts.map +1 -1
- package/dist/harness/partial-changes.js +1 -0
- package/dist/harness/partial-changes.js.map +1 -1
- package/dist/harness/prompt.d.ts +1 -1
- package/dist/harness/prompt.d.ts.map +1 -1
- package/dist/harness/prompt.js.map +1 -1
- package/dist/harness/provider.d.ts +1 -1
- package/dist/harness/provider.d.ts.map +1 -1
- package/dist/harness/provider.js.map +1 -1
- package/dist/harness/registry-reader.d.ts +1 -1
- package/dist/harness/registry-reader.d.ts.map +1 -1
- package/dist/harness/registry-reader.js.map +1 -1
- package/dist/harness/scheduler.d.ts +2 -1
- package/dist/harness/scheduler.d.ts.map +1 -1
- package/dist/harness/scheduler.js +42 -13
- package/dist/harness/scheduler.js.map +1 -1
- package/dist/harness/submissions.d.ts +1 -1
- package/dist/harness/submissions.d.ts.map +1 -1
- package/dist/harness/submissions.js +1 -1
- package/dist/harness/submissions.js.map +1 -1
- package/dist/harness/task-graph.d.ts +3 -1
- package/dist/harness/task-graph.d.ts.map +1 -1
- package/dist/harness/task-graph.js +1 -1
- package/dist/harness/task-graph.js.map +1 -1
- package/dist/harness/tool.d.ts +1 -1
- package/dist/harness/tool.d.ts.map +1 -1
- package/dist/harness/tool.js +1 -1
- package/dist/harness/tool.js.map +1 -1
- package/dist/harness/transcript.d.ts +1 -1
- package/dist/harness/transcript.d.ts.map +1 -1
- package/dist/harness/transcript.js.map +1 -1
- package/dist/harness/types.d.ts +21 -4
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/usage.d.ts +2 -1
- package/dist/harness/usage.d.ts.map +1 -1
- package/dist/harness/usage.js +1 -1
- package/dist/harness/usage.js.map +1 -1
- package/dist/harness/util.d.ts +1 -1
- package/dist/harness/util.d.ts.map +1 -1
- package/dist/harness/util.js.map +1 -1
- package/dist/harness/view.d.ts +2 -1
- package/dist/harness/view.d.ts.map +1 -1
- package/dist/harness/view.js +1 -1
- package/dist/harness/view.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/session/cached-storage.d.ts +2 -1
- package/dist/session/cached-storage.d.ts.map +1 -1
- package/dist/session/cached-storage.js.map +1 -1
- package/dist/session/forks.d.ts +1 -1
- package/dist/session/forks.d.ts.map +1 -1
- package/dist/session/forks.js.map +1 -1
- package/dist/session/keys.d.ts +2 -1
- package/dist/session/keys.d.ts.map +1 -1
- package/dist/session/keys.js.map +1 -1
- package/dist/session/session.d.ts +3 -1
- package/dist/session/session.d.ts.map +1 -1
- package/dist/session/session.js +1 -1
- package/dist/session/session.js.map +1 -1
- package/dist/session/transaction.d.ts +4 -3
- package/dist/session/transaction.d.ts.map +1 -1
- package/dist/session/transaction.js +3 -3
- package/dist/session/transaction.js.map +1 -1
- package/dist/session/writer.d.ts +1 -1
- package/dist/session/writer.d.ts.map +1 -1
- package/dist/session/writer.js.map +1 -1
- package/dist/storage/indexeddb.d.ts +2 -1
- package/dist/storage/indexeddb.d.ts.map +1 -1
- package/dist/storage/indexeddb.js.map +1 -1
- package/dist/storage/jsonl/index.d.ts +1 -1
- package/dist/storage/jsonl/index.d.ts.map +1 -1
- package/dist/storage/jsonl/index.js +1 -1
- package/dist/storage/jsonl/index.js.map +1 -1
- package/dist/storage/jsonl/node.d.ts +3 -3
- package/dist/storage/jsonl/node.d.ts.map +1 -1
- package/dist/storage/jsonl/node.js +2 -2
- package/dist/storage/jsonl/node.js.map +1 -1
- package/dist/storage/jsonl/storage.d.ts +32 -3
- package/dist/storage/jsonl/storage.d.ts.map +1 -1
- package/dist/storage/jsonl/storage.js +70 -19
- package/dist/storage/jsonl/storage.js.map +1 -1
- package/dist/storage/memory.d.ts +2 -1
- package/dist/storage/memory.d.ts.map +1 -1
- package/dist/storage/memory.js.map +1 -1
- package/dist/storage/sqlite/commit.d.ts +52 -0
- package/dist/storage/sqlite/commit.d.ts.map +1 -0
- package/dist/storage/sqlite/commit.js +371 -0
- package/dist/storage/sqlite/commit.js.map +1 -0
- package/dist/storage/sqlite/rows.d.ts +33 -0
- package/dist/storage/sqlite/rows.d.ts.map +1 -0
- package/dist/storage/sqlite/rows.js +53 -0
- package/dist/storage/sqlite/rows.js.map +1 -0
- package/dist/storage/sqlite/statements.d.ts +13 -0
- package/dist/storage/sqlite/statements.d.ts.map +1 -0
- package/dist/storage/sqlite/statements.js +88 -0
- package/dist/storage/sqlite/statements.js.map +1 -0
- package/dist/storage/sqlite/storage.d.ts +12 -11
- package/dist/storage/sqlite/storage.d.ts.map +1 -1
- package/dist/storage/sqlite/storage.js +44 -259
- package/dist/storage/sqlite/storage.js.map +1 -1
- package/dist/storage/store/commit.d.ts +2 -2
- package/dist/storage/store/commit.d.ts.map +1 -1
- package/dist/storage/store/commit.js +1 -1
- package/dist/storage/store/commit.js.map +1 -1
- package/dist/storage/store/documents.d.ts +1 -1
- package/dist/storage/store/documents.d.ts.map +1 -1
- package/dist/storage/store/documents.js +1 -1
- package/dist/storage/store/documents.js.map +1 -1
- package/dist/storage/store/queries.d.ts +2 -2
- package/dist/storage/store/queries.d.ts.map +1 -1
- package/dist/storage/store/queries.js.map +1 -1
- package/dist/storage/store/storage.d.ts +3 -2
- package/dist/storage/store/storage.d.ts.map +1 -1
- package/dist/storage/store/storage.js +1 -1
- package/dist/storage/store/storage.js.map +1 -1
- package/dist/storage/store/tables.d.ts +31 -31
- package/dist/storage/store/tables.d.ts.map +1 -1
- package/dist/storage/store/tables.js +1 -1
- package/dist/storage/store/tables.js.map +1 -1
- package/dist/testing/commit-writes.d.ts +1 -1
- package/dist/testing/commit-writes.d.ts.map +1 -1
- package/dist/testing/commit-writes.js.map +1 -1
- package/dist/testing/env-conformance.js.map +1 -1
- package/dist/testing/storage-benchmark.js.map +1 -1
- package/dist/testing/storage-conformance.js.map +1 -1
- package/dist/tool-search/tool-search.d.ts +2 -2
- package/dist/tool-search/tool-search.d.ts.map +1 -1
- package/dist/tool-search/tool-search.js +18 -6
- package/dist/tool-search/tool-search.js.map +1 -1
- package/dist/tools/bash.d.ts +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/file-mutation-queue.d.ts +1 -1
- package/dist/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/tools/file-mutation-queue.js.map +1 -1
- package/dist/tools/path-utils.d.ts +1 -1
- package/dist/tools/path-utils.d.ts.map +1 -1
- package/dist/tools/path-utils.js.map +1 -1
- package/dist/tools/read.js.map +1 -1
- package/dist/types.d.ts +6 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"partial-changes.js","sourceRoot":"","sources":["../../src/harness/partial-changes.ts"],"names":[],"mappings":"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","sourcesContent":["// What a streamed answer changed in its partial message between two partial commits, so a commit costs the new text.\nimport type { JsonRepresentation, JsonValue } from \"@earendil-works/chord\";\nimport { appendText, type Draft } from \"@earendil-works/chord/delta\";\nimport type { AssistantMessage, AssistantMessageEvent, ToolCall } from \"@earendil-works/pi-ai\";\nimport { type JsonChange, StreamingJsonParser } from \"@earendil-works/pi-ai/utils/streaming-json\";\nimport { type AssignPlan, assignJson } from \"./json.ts\";\nimport type { LiveState } from \"./live.ts\";\n\ntype JsonContainer = Record<string, JsonValue> | JsonValue[];\n\n/** A partial message as `pi.live.generation.message` holds it. */\nexport type PartialMessage = JsonRepresentation<AssistantMessage>;\n\n/** Committed arguments of a streamed tool call. */\ntype Arguments = JsonRepresentation<ToolCall>[\"arguments\"];\n\n/** What one partial commit writes besides the partial message itself; from `PartialChanges.take()`. */\nexport type PartialCommit = {\n\t/** The plan `assignJson()` writes the message with: text appends, and the arguments it leaves to `changes`. */\n\treadonly plan: AssignPlan;\n\t/** Each tracked tool call by content index: its argument changes since the last commit, in order, and its snapshot. */\n\treadonly toolCalls: ReadonlyMap<number, { readonly changes: readonly JsonChange[]; readonly snapshot: Arguments }>;\n};\n\n/** What a tracked tool call changed since the last commit, and whether any commit took its changes yet. */\ntype ToolCallState = { readonly parser: StreamingJsonParser; changes: JsonChange[]; committed: boolean };\n\n/**\n * Collects, from a response's events, what changed in its partial message since the last commit, so the commit appends\n * new text instead of reassigning growing strings. Reassigning makes Chord compare the old and new string, which costs\n * O(length) per commit.\n *\n * - Text and thinking: the `text_delta` and `thinking_delta` events. The commit appends them where the committed string\n * plus the deltas has the new string's length, and compares otherwise. A block's `*_end` event drops them, because\n * providers may replace the text when a block ends.\n * - Tool-call arguments: a `StreamingJsonParser` per call, fed with the raw argument text of each `toolcall_delta`,\n * reports what each piece changed. The commit applies those changes to the committed arguments in order and leaves\n * the arguments out of the message assignment, so the committed arguments are exactly the parsed text so far.\n * `toolcall_end` ends the tracking; the call's last commit assigns its final arguments.\n */\nexport class PartialChanges {\n\t#text = new Map<number, { readonly field: \"text\" | \"thinking\"; text: string }>();\n\treadonly #toolCalls = new Map<number, ToolCallState>();\n\n\t/** Record what `event` changed. */\n\tobserve(event: AssistantMessageEvent): void {\n\t\tswitch (event.type) {\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"thinking_delta\": {\n\t\t\t\tconst field = event.type === \"text_delta\" ? \"text\" : \"thinking\";\n\t\t\t\tconst pending = this.#text.get(event.contentIndex);\n\t\t\t\tif (pending?.field === field) pending.text += event.delta;\n\t\t\t\telse this.#text.set(event.contentIndex, { field, text: event.delta });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"toolcall_start\":\n\t\t\t\tthis.#toolCalls.set(event.contentIndex, {\n\t\t\t\t\tparser: new StreamingJsonParser(),\n\t\t\t\t\tchanges: [],\n\t\t\t\t\tcommitted: false,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\tcase \"toolcall_delta\": {\n\t\t\t\tconst call = this.#toolCalls.get(event.contentIndex);\n\t\t\t\tif (call === undefined) return;\n\t\t\t\tfor (const change of call.parser.append(event.delta)) {\n\t\t\t\t\t// Arguments are an object: any other root shows as no arguments, so the snapshot is committed instead.\n\t\t\t\t\tif (change.path.length === 0 && !isRecord(change.kind === \"set\" ? value(change) : null)) {\n\t\t\t\t\t\tthis.#toolCalls.delete(event.contentIndex);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcall.changes.push(change);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_end\":\n\t\t\t\tthis.#text.delete(event.contentIndex);\n\t\t\t\treturn;\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tthis.#toolCalls.delete(event.contentIndex);\n\t\t\t\treturn;\n\t\t}\n\t}\n\n\t/**\n\t * Take what changed since the last call, for a commit of `message`, a copy of the partial. Clears the arguments of\n\t * tracked tool calls in `message`: the commit writes them from the changes. Call `restore()` if the commit fails.\n\t */\n\ttake(message: PartialMessage): PartialCommit {\n\t\tconst blocks = new Map<string | number, AssignPlan>();\n\t\tfor (const [index, { field, text }] of this.#text) {\n\t\t\tblocks.set(index, { kind: \"fields\", fields: new Map([[field, { kind: \"append\", text }]]) });\n\t\t}\n\t\tthis.#text = new Map();\n\t\tconst toolCalls = new Map<number, { readonly changes: readonly JsonChange[]; readonly snapshot: Arguments }>();\n\t\tfor (const [index, call] of this.#toolCalls) {\n\t\t\tconst block = message.content[index];\n\t\t\t// A tracked call is the tool call its `toolcall_start` named; the narrowing only tells TypeScript.\n\t\t\tif (block?.type !== \"toolCall\") continue;\n\t\t\ttoolCalls.set(index, { changes: call.changes, snapshot: block.arguments });\n\t\t\tblock.arguments = {};\n\t\t\tblocks.set(index, { kind: \"fields\", fields: new Map([[\"arguments\", { kind: \"keep\" }]]) });\n\t\t\tcall.changes = [];\n\t\t}\n\t\treturn {\n\t\t\tplan: { kind: \"fields\", fields: new Map([[\"content\", { kind: \"fields\", fields: blocks }]]) },\n\t\t\ttoolCalls,\n\t\t};\n\t}\n\n\t/**\n\t * Write `message` with what `commit` took into `generation.message`: the message leaf by leaf with the plan, then the\n\t * argument changes. A tracked call whose block is new here gets its arguments from its changes, which then start at\n\t * its first piece; when the committed message lost a call whose changes were already committed (another writer reset\n\t * it), the call falls back to its snapshot from now on.\n\t */\n\tcommit(\n\t\tgeneration: Draft<NonNullable<LiveState[\"generation\"]>>,\n\t\tmessage: PartialMessage,\n\t\tcommit: PartialCommit,\n\t): void {\n\t\tconst committedBlocks = generation.message?.content.length ?? 0;\n\t\tconst apply: [number, readonly JsonChange[]][] = [];\n\t\tfor (const [index, { changes, snapshot }] of commit.toolCalls) {\n\t\t\tconst call = this.#toolCalls.get(index);\n\t\t\tif (call === undefined) continue;\n\t\t\tconst block = message.content[index];\n\t\t\tif (index >= committedBlocks && call.committed && block?.type === \"toolCall\") {\n\t\t\t\t// The earlier changes are not in the committed message: commit the snapshot and stop tracking the call.\n\t\t\t\tthis.#toolCalls.delete(index);\n\t\t\t\tblock.arguments = snapshot;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tcall.committed = true;\n\t\t\tapply.push([index, changes]);\n\t\t}\n\t\tassignJson(generation, \"message\", message, commit.plan);\n\t\tconst content = generation.message?.content ?? [];\n\t\tfor (const [index, changes] of apply) {\n\t\t\tconst block = content[index];\n\t\t\tif (block?.type !== \"toolCall\") continue;\n\t\t\tfor (const change of changes) applyChange(block, change);\n\t\t}\n\t}\n\n\t/** Put back what a failed commit took, so the next commit applies it first. */\n\trestore(commit: PartialCommit): void {\n\t\tfor (const [index, { changes }] of commit.toolCalls) {\n\t\t\tconst call = this.#toolCalls.get(index);\n\t\t\tif (call !== undefined) call.changes = [...changes, ...call.changes];\n\t\t}\n\t}\n}\n\n/** Apply one argument change to the committed arguments of `block`. */\nfunction applyChange(block: Draft<JsonRepresentation<ToolCall>>, change: JsonChange): void {\n\tconst key = change.path.at(-1);\n\tif (key === undefined) {\n\t\t// Only an object root is tracked (`observe()` drops any other), and only `set` starts it.\n\t\tconst root = change.kind === \"set\" ? value(change) : undefined;\n\t\tif (isRecord(root)) block.arguments = root;\n\t\treturn;\n\t}\n\t// The path follows the parsed argument text, not a type: each segment names a container `observe()` saw set.\n\tlet parent = block.arguments as Draft<JsonContainer>;\n\tfor (const segment of change.path.slice(0, -1)) {\n\t\tparent = (parent as Record<string | number, Draft<JsonContainer>>)[segment]!;\n\t}\n\tconst slots = parent as Record<string | number, JsonValue>;\n\tif (change.kind === \"set\") slots[key] = value(change);\n\t// appendText() takes object members; a string in an array is reassigned, which compares it whole.\n\telse if (Array.isArray(parent)) slots[key] = `${slots[key] as string}${change.text}`;\n\telse appendText(parent as Draft<Record<string, string>>, String(key), change.text);\n}\n\n/** The value a `set` change reports: JSON data, which pi-ai types with read-only arrays. */\nfunction value(change: Extract<JsonChange, { kind: \"set\" }>): JsonValue {\n\treturn change.value as JsonValue;\n}\n\nfunction isRecord(value: JsonValue | undefined): value is Record<string, JsonValue> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"partial-changes.js","sourceRoot":"","sources":["../../src/harness/partial-changes.ts"],"names":[],"mappings":"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","sourcesContent":["// What a streamed answer changed in its partial message between two partial commits, so a commit costs the new text.\n\nimport { appendText, type Draft } from \"@earendil-works/chord/delta\";\nimport type { JsonRepresentation, JsonValue } from \"@earendil-works/chord/json\";\nimport type { AssistantMessage, AssistantMessageEvent, ToolCall } from \"@earendil-works/pi-ai\";\nimport { type JsonChange, StreamingJsonParser } from \"@earendil-works/pi-ai/utils/streaming-json\";\nimport { type AssignPlan, assignJson } from \"./json.ts\";\nimport type { LiveState } from \"./live.ts\";\n\ntype JsonContainer = Record<string, JsonValue> | JsonValue[];\n\n/** A partial message as `pi.live.generation.message` holds it. */\nexport type PartialMessage = JsonRepresentation<AssistantMessage>;\n\n/** Committed arguments of a streamed tool call. */\ntype Arguments = JsonRepresentation<ToolCall>[\"arguments\"];\n\n/** What one partial commit writes besides the partial message itself; from `PartialChanges.take()`. */\nexport type PartialCommit = {\n\t/** The plan `assignJson()` writes the message with: text appends, and the arguments it leaves to `changes`. */\n\treadonly plan: AssignPlan;\n\t/** Each tracked tool call by content index: its argument changes since the last commit, in order, and its snapshot. */\n\treadonly toolCalls: ReadonlyMap<number, { readonly changes: readonly JsonChange[]; readonly snapshot: Arguments }>;\n};\n\n/** What a tracked tool call changed since the last commit, and whether any commit took its changes yet. */\ntype ToolCallState = { readonly parser: StreamingJsonParser; changes: JsonChange[]; committed: boolean };\n\n/**\n * Collects, from a response's events, what changed in its partial message since the last commit, so the commit appends\n * new text instead of reassigning growing strings. Reassigning makes Chord compare the old and new string, which costs\n * O(length) per commit.\n *\n * - Text and thinking: the `text_delta` and `thinking_delta` events. The commit appends them where the committed string\n * plus the deltas has the new string's length, and compares otherwise. A block's `*_end` event drops them, because\n * providers may replace the text when a block ends.\n * - Tool-call arguments: a `StreamingJsonParser` per call, fed with the raw argument text of each `toolcall_delta`,\n * reports what each piece changed. The commit applies those changes to the committed arguments in order and leaves\n * the arguments out of the message assignment, so the committed arguments are exactly the parsed text so far.\n * `toolcall_end` ends the tracking; the call's last commit assigns its final arguments.\n */\nexport class PartialChanges {\n\t#text = new Map<number, { readonly field: \"text\" | \"thinking\"; text: string }>();\n\treadonly #toolCalls = new Map<number, ToolCallState>();\n\n\t/** Record what `event` changed. */\n\tobserve(event: AssistantMessageEvent): void {\n\t\tswitch (event.type) {\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"thinking_delta\": {\n\t\t\t\tconst field = event.type === \"text_delta\" ? \"text\" : \"thinking\";\n\t\t\t\tconst pending = this.#text.get(event.contentIndex);\n\t\t\t\tif (pending?.field === field) pending.text += event.delta;\n\t\t\t\telse this.#text.set(event.contentIndex, { field, text: event.delta });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"toolcall_start\":\n\t\t\t\tthis.#toolCalls.set(event.contentIndex, {\n\t\t\t\t\tparser: new StreamingJsonParser(),\n\t\t\t\t\tchanges: [],\n\t\t\t\t\tcommitted: false,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\tcase \"toolcall_delta\": {\n\t\t\t\tconst call = this.#toolCalls.get(event.contentIndex);\n\t\t\t\tif (call === undefined) return;\n\t\t\t\tfor (const change of call.parser.append(event.delta)) {\n\t\t\t\t\t// Arguments are an object: any other root shows as no arguments, so the snapshot is committed instead.\n\t\t\t\t\tif (change.path.length === 0 && !isRecord(change.kind === \"set\" ? value(change) : null)) {\n\t\t\t\t\t\tthis.#toolCalls.delete(event.contentIndex);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcall.changes.push(change);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_end\":\n\t\t\t\tthis.#text.delete(event.contentIndex);\n\t\t\t\treturn;\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tthis.#toolCalls.delete(event.contentIndex);\n\t\t\t\treturn;\n\t\t}\n\t}\n\n\t/**\n\t * Take what changed since the last call, for a commit of `message`, a copy of the partial. Clears the arguments of\n\t * tracked tool calls in `message`: the commit writes them from the changes. Call `restore()` if the commit fails.\n\t */\n\ttake(message: PartialMessage): PartialCommit {\n\t\tconst blocks = new Map<string | number, AssignPlan>();\n\t\tfor (const [index, { field, text }] of this.#text) {\n\t\t\tblocks.set(index, { kind: \"fields\", fields: new Map([[field, { kind: \"append\", text }]]) });\n\t\t}\n\t\tthis.#text = new Map();\n\t\tconst toolCalls = new Map<number, { readonly changes: readonly JsonChange[]; readonly snapshot: Arguments }>();\n\t\tfor (const [index, call] of this.#toolCalls) {\n\t\t\tconst block = message.content[index];\n\t\t\t// A tracked call is the tool call its `toolcall_start` named; the narrowing only tells TypeScript.\n\t\t\tif (block?.type !== \"toolCall\") continue;\n\t\t\ttoolCalls.set(index, { changes: call.changes, snapshot: block.arguments });\n\t\t\tblock.arguments = {};\n\t\t\tblocks.set(index, { kind: \"fields\", fields: new Map([[\"arguments\", { kind: \"keep\" }]]) });\n\t\t\tcall.changes = [];\n\t\t}\n\t\treturn {\n\t\t\tplan: { kind: \"fields\", fields: new Map([[\"content\", { kind: \"fields\", fields: blocks }]]) },\n\t\t\ttoolCalls,\n\t\t};\n\t}\n\n\t/**\n\t * Write `message` with what `commit` took into `generation.message`: the message leaf by leaf with the plan, then the\n\t * argument changes. A tracked call whose block is new here gets its arguments from its changes, which then start at\n\t * its first piece; when the committed message lost a call whose changes were already committed (another writer reset\n\t * it), the call falls back to its snapshot from now on.\n\t */\n\tcommit(\n\t\tgeneration: Draft<NonNullable<LiveState[\"generation\"]>>,\n\t\tmessage: PartialMessage,\n\t\tcommit: PartialCommit,\n\t): void {\n\t\tconst committedBlocks = generation.message?.content.length ?? 0;\n\t\tconst apply: [number, readonly JsonChange[]][] = [];\n\t\tfor (const [index, { changes, snapshot }] of commit.toolCalls) {\n\t\t\tconst call = this.#toolCalls.get(index);\n\t\t\tif (call === undefined) continue;\n\t\t\tconst block = message.content[index];\n\t\t\tif (index >= committedBlocks && call.committed && block?.type === \"toolCall\") {\n\t\t\t\t// The earlier changes are not in the committed message: commit the snapshot and stop tracking the call.\n\t\t\t\tthis.#toolCalls.delete(index);\n\t\t\t\tblock.arguments = snapshot;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tcall.committed = true;\n\t\t\tapply.push([index, changes]);\n\t\t}\n\t\tassignJson(generation, \"message\", message, commit.plan);\n\t\tconst content = generation.message?.content ?? [];\n\t\tfor (const [index, changes] of apply) {\n\t\t\tconst block = content[index];\n\t\t\tif (block?.type !== \"toolCall\") continue;\n\t\t\tfor (const change of changes) applyChange(block, change);\n\t\t}\n\t}\n\n\t/** Put back what a failed commit took, so the next commit applies it first. */\n\trestore(commit: PartialCommit): void {\n\t\tfor (const [index, { changes }] of commit.toolCalls) {\n\t\t\tconst call = this.#toolCalls.get(index);\n\t\t\tif (call !== undefined) call.changes = [...changes, ...call.changes];\n\t\t}\n\t}\n}\n\n/** Apply one argument change to the committed arguments of `block`. */\nfunction applyChange(block: Draft<JsonRepresentation<ToolCall>>, change: JsonChange): void {\n\tconst key = change.path.at(-1);\n\tif (key === undefined) {\n\t\t// Only an object root is tracked (`observe()` drops any other), and only `set` starts it.\n\t\tconst root = change.kind === \"set\" ? value(change) : undefined;\n\t\tif (isRecord(root)) block.arguments = root;\n\t\treturn;\n\t}\n\t// The path follows the parsed argument text, not a type: each segment names a container `observe()` saw set.\n\tlet parent = block.arguments as Draft<JsonContainer>;\n\tfor (const segment of change.path.slice(0, -1)) {\n\t\tparent = (parent as Record<string | number, Draft<JsonContainer>>)[segment]!;\n\t}\n\tconst slots = parent as Record<string | number, JsonValue>;\n\tif (change.kind === \"set\") slots[key] = value(change);\n\t// appendText() takes object members; a string in an array is reassigned, which compares it whole.\n\telse if (Array.isArray(parent)) slots[key] = `${slots[key] as string}${change.text}`;\n\telse appendText(parent as Draft<Record<string, string>>, String(key), change.text);\n}\n\n/** The value a `set` change reports: JSON data, which pi-ai types with read-only arrays. */\nfunction value(change: Extract<JsonChange, { kind: \"set\" }>): JsonValue {\n\treturn change.value as JsonValue;\n}\n\nfunction isRecord(value: JsonValue | undefined): value is Record<string, JsonValue> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"]}
|
package/dist/harness/prompt.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Context } from "@earendil-works/chord";
|
|
1
|
+
import type { Context } from "@earendil-works/chord/context";
|
|
2
2
|
import type { Message, Tool } from "@earendil-works/pi-ai";
|
|
3
3
|
import type { TypedEntryDraft } from "../types.ts";
|
|
4
4
|
import type { ContextView, PromptInput, PromptSection, ToolRegistration } from "./types.ts";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/harness/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/harness/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAiB,IAAI,EAAiB,MAAM,uBAAuB,CAAC;AAGzF,OAAO,KAAK,EAAe,eAAe,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE5F,oHAAoH;AACpH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAUhF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,SAAS,gBAAgB,EACjE,QAAQ,EAAE,SAAS,aAAa,CAAC,IAAI,CAAC,EAAE,EACxC,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,EACxB,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,IAAI,EAC9D,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAiB9B;AAED,KAAK,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;AAI1C;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,SAAS,EAAE,MAAM,GACf,WAAW,EAAE,CAsBf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/harness/prompt.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport type { Message, SystemMessage, Tool, ToolReference } from \"@earendil-works/pi-ai\";\nimport { declarationsEqual, getCurrentTools, toToolDeclaration } from \"@earendil-works/pi-ai/utils/transcript\";\nimport { SystemEntry } from \"../entries.ts\";\nimport type { ContextEdit, TypedEntryDraft } from \"../types.ts\";\nimport type { ContextView, PromptInput, PromptSection, ToolRegistration } from \"./types.ts\";\n\n/** Sections in effect after replaying system messages in order: set in place, `null` deletes, re-adding appends. */\nexport function replaySections(messages: readonly Message[]): Map<string, string> {\n\tconst shown = new Map<string, string>();\n\tfor (const message of messages) {\n\t\tif (message.role !== \"system\" || message.sections === undefined) continue;\n\t\tfor (const [key, value] of Object.entries(message.sections)) {\n\t\t\tif (value === null) shown.delete(key);\n\t\t\telse shown.set(key, value);\n\t\t}\n\t}\n\treturn shown;\n}\n\n/**\n * Render the agent's sections in order. `undefined` omits a section; tagged text is wrapped as `<key>\\n...\\n</key>`. A\n * section that throws keeps its shown text, if any, and is reported; errors after `context` is aborted propagate.\n */\nexport async function renderSections<Tool extends ToolRegistration>(\n\tsections: readonly PromptSection<Tool>[],\n\tinput: PromptInput<Tool>,\n\tshown: ReadonlyMap<string, string>,\n\treport: (error: unknown, section: PromptSection<Tool>) => void,\n\tcontext: Context,\n): Promise<Map<string, string>> {\n\tconst desired = new Map<string, string>();\n\tfor (const section of sections) {\n\t\tlet text: string | undefined;\n\t\ttry {\n\t\t\ttext = await section.render(input, context);\n\t\t} catch (error) {\n\t\t\tif (context.abortSignal?.aborted) throw error;\n\t\t\treport(error, section);\n\t\t\tconst kept = shown.get(section.key);\n\t\t\tif (kept !== undefined) desired.set(section.key, kept);\n\t\t\tcontinue;\n\t\t}\n\t\tif (text === undefined) continue;\n\t\tdesired.set(section.key, section.tag === false ? text : `<${section.key}>\\n${text}\\n</${section.key}>`);\n\t}\n\treturn desired;\n}\n\ntype SystemDraft = TypedEntryDraft<never>;\n\ntype ToolChanges = { readonly toolsRemoved: ToolReference[]; readonly toolsAdded: Tool[] };\n\n/**\n * Plan the `pi.system` entries that make the replayed sections and tools of `view` equal `desired` and `tools` in values\n * and order.\n *\n * - A head marker with no later `pi.system` entry in context: one complete baseline that omits every retained earlier\n * `pi.system` entry, written even when it restates the replayed values.\n * - Otherwise, when a minimal section patch would leave a different order: remove every shown section, then re-add\n * every desired section in order.\n * - Otherwise the minimal patch of changed values and `null` removals, or nothing.\n *\n * Tool changes ride on the last planned entry, or on one entry of their own.\n */\nexport function planSystemEntries(\n\tview: ContextView,\n\tdesired: ReadonlyMap<string, string>,\n\ttools: readonly Tool[],\n\ttimestamp: number,\n): SystemDraft[] {\n\tconst head = view.head;\n\tif (head !== undefined && !view.entries.some((entry) => SystemEntry.is(entry) && entry.id > head.id)) {\n\t\tconst edits: ContextEdit[] = view.entries\n\t\t\t.filter((entry) => SystemEntry.is(entry))\n\t\t\t.map((entry) => ({ target: entry.id, action: \"omit\" }));\n\t\tconst baseline = systemEntry(\n\t\t\tObject.fromEntries(desired),\n\t\t\t{ toolsRemoved: [], toolsAdded: tools.map(toToolDeclaration) },\n\t\t\ttimestamp,\n\t\t);\n\t\treturn [edits.length === 0 ? baseline : { ...baseline, edits }];\n\t}\n\tconst sections = planSections(replaySections(view.messages), desired);\n\tconst changes = planTools(getCurrentTools(view.messages), tools);\n\tif (changes.toolsRemoved.length === 0 && changes.toolsAdded.length === 0) {\n\t\treturn sections.map((patch) => systemEntry(patch, undefined, timestamp));\n\t}\n\tif (sections.length === 0) return [systemEntry(undefined, changes, timestamp)];\n\treturn sections.map((patch, index) =>\n\t\tsystemEntry(patch, index === sections.length - 1 ? changes : undefined, timestamp),\n\t);\n}\n\n/**\n * Tool changes from `offered` to `desired`. A changed declaration is removed and re-added. Replay keeps retained tools\n * in place and appends additions; when that would not yield the desired order, every offered tool is removed and\n * every desired tool re-added in order.\n */\nfunction planTools(offered: readonly Tool[], desired: readonly Tool[]): ToolChanges {\n\tconst wanted = new Map(desired.map((tool) => [tool.name, tool]));\n\tconst kept = offered.filter((tool) => {\n\t\tconst next = wanted.get(tool.name);\n\t\treturn next !== undefined && declarationsEqual(tool, next);\n\t});\n\tconst keptNames = new Set(kept.map((tool) => tool.name));\n\tconst added = desired.filter((tool) => !keptNames.has(tool.name));\n\tconst replayed = [...kept, ...added];\n\tif (replayed.some((tool, index) => tool.name !== desired[index]!.name)) {\n\t\treturn {\n\t\t\ttoolsRemoved: offered.map((tool) => ({ name: tool.name })),\n\t\t\ttoolsAdded: desired.map(toToolDeclaration),\n\t\t};\n\t}\n\treturn {\n\t\ttoolsRemoved: offered.filter((tool) => !keptNames.has(tool.name)).map((tool) => ({ name: tool.name })),\n\t\ttoolsAdded: added.map(toToolDeclaration),\n\t};\n}\n\n/** Section patches: none, the minimal patch, or a remove-all/re-add-all pair when the order would differ. */\nfunction planSections(\n\tshown: ReadonlyMap<string, string>,\n\tdesired: ReadonlyMap<string, string>,\n): Record<string, string | null>[] {\n\tconst patchedOrder = [\n\t\t...[...shown.keys()].filter((key) => desired.has(key)),\n\t\t...[...desired.keys()].filter((key) => !shown.has(key)),\n\t];\n\tconst desiredOrder = [...desired.keys()];\n\tif (patchedOrder.some((key, index) => key !== desiredOrder[index])) {\n\t\treturn [Object.fromEntries([...shown.keys()].map((key) => [key, null])), Object.fromEntries(desired)];\n\t}\n\n\tconst patch: Record<string, string | null> = {};\n\tfor (const [key, value] of shown) {\n\t\tconst next = desired.get(key);\n\t\tif (next !== value) patch[key] = next ?? null;\n\t}\n\tfor (const [key, value] of desired) if (!shown.has(key)) patch[key] = value;\n\treturn Object.keys(patch).length === 0 ? [] : [patch];\n}\n\nfunction systemEntry(\n\tsections: Record<string, string | null> | undefined,\n\ttools: ToolChanges | undefined,\n\ttimestamp: number,\n): SystemDraft {\n\tconst message: SystemMessage = {\n\t\trole: \"system\",\n\t\tcontent: \"\",\n\t\t...(sections === undefined ? {} : { sections }),\n\t\t...(tools === undefined || tools.toolsRemoved.length === 0 ? {} : { toolsRemoved: tools.toolsRemoved }),\n\t\t...(tools === undefined || tools.toolsAdded.length === 0 ? {} : { toolsAdded: tools.toolsAdded }),\n\t\ttimestamp,\n\t};\n\treturn { model: [message] };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/harness/prompt.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context } from \"@earendil-works/chord/context\";\nimport type { Message, SystemMessage, Tool, ToolReference } from \"@earendil-works/pi-ai\";\nimport { declarationsEqual, getCurrentTools, toToolDeclaration } from \"@earendil-works/pi-ai/utils/transcript\";\nimport { SystemEntry } from \"../entries.ts\";\nimport type { ContextEdit, TypedEntryDraft } from \"../types.ts\";\nimport type { ContextView, PromptInput, PromptSection, ToolRegistration } from \"./types.ts\";\n\n/** Sections in effect after replaying system messages in order: set in place, `null` deletes, re-adding appends. */\nexport function replaySections(messages: readonly Message[]): Map<string, string> {\n\tconst shown = new Map<string, string>();\n\tfor (const message of messages) {\n\t\tif (message.role !== \"system\" || message.sections === undefined) continue;\n\t\tfor (const [key, value] of Object.entries(message.sections)) {\n\t\t\tif (value === null) shown.delete(key);\n\t\t\telse shown.set(key, value);\n\t\t}\n\t}\n\treturn shown;\n}\n\n/**\n * Render the agent's sections in order. `undefined` omits a section; tagged text is wrapped as `<key>\\n...\\n</key>`. A\n * section that throws keeps its shown text, if any, and is reported; errors after `context` is aborted propagate.\n */\nexport async function renderSections<Tool extends ToolRegistration>(\n\tsections: readonly PromptSection<Tool>[],\n\tinput: PromptInput<Tool>,\n\tshown: ReadonlyMap<string, string>,\n\treport: (error: unknown, section: PromptSection<Tool>) => void,\n\tcontext: Context,\n): Promise<Map<string, string>> {\n\tconst desired = new Map<string, string>();\n\tfor (const section of sections) {\n\t\tlet text: string | undefined;\n\t\ttry {\n\t\t\ttext = await section.render(input, context);\n\t\t} catch (error) {\n\t\t\tif (context.abortSignal?.aborted) throw error;\n\t\t\treport(error, section);\n\t\t\tconst kept = shown.get(section.key);\n\t\t\tif (kept !== undefined) desired.set(section.key, kept);\n\t\t\tcontinue;\n\t\t}\n\t\tif (text === undefined) continue;\n\t\tdesired.set(section.key, section.tag === false ? text : `<${section.key}>\\n${text}\\n</${section.key}>`);\n\t}\n\treturn desired;\n}\n\ntype SystemDraft = TypedEntryDraft<never>;\n\ntype ToolChanges = { readonly toolsRemoved: ToolReference[]; readonly toolsAdded: Tool[] };\n\n/**\n * Plan the `pi.system` entries that make the replayed sections and tools of `view` equal `desired` and `tools` in values\n * and order.\n *\n * - A head marker with no later `pi.system` entry in context: one complete baseline that omits every retained earlier\n * `pi.system` entry, written even when it restates the replayed values.\n * - Otherwise, when a minimal section patch would leave a different order: remove every shown section, then re-add\n * every desired section in order.\n * - Otherwise the minimal patch of changed values and `null` removals, or nothing.\n *\n * Tool changes ride on the last planned entry, or on one entry of their own.\n */\nexport function planSystemEntries(\n\tview: ContextView,\n\tdesired: ReadonlyMap<string, string>,\n\ttools: readonly Tool[],\n\ttimestamp: number,\n): SystemDraft[] {\n\tconst head = view.head;\n\tif (head !== undefined && !view.entries.some((entry) => SystemEntry.is(entry) && entry.id > head.id)) {\n\t\tconst edits: ContextEdit[] = view.entries\n\t\t\t.filter((entry) => SystemEntry.is(entry))\n\t\t\t.map((entry) => ({ target: entry.id, action: \"omit\" }));\n\t\tconst baseline = systemEntry(\n\t\t\tObject.fromEntries(desired),\n\t\t\t{ toolsRemoved: [], toolsAdded: tools.map(toToolDeclaration) },\n\t\t\ttimestamp,\n\t\t);\n\t\treturn [edits.length === 0 ? baseline : { ...baseline, edits }];\n\t}\n\tconst sections = planSections(replaySections(view.messages), desired);\n\tconst changes = planTools(getCurrentTools(view.messages), tools);\n\tif (changes.toolsRemoved.length === 0 && changes.toolsAdded.length === 0) {\n\t\treturn sections.map((patch) => systemEntry(patch, undefined, timestamp));\n\t}\n\tif (sections.length === 0) return [systemEntry(undefined, changes, timestamp)];\n\treturn sections.map((patch, index) =>\n\t\tsystemEntry(patch, index === sections.length - 1 ? changes : undefined, timestamp),\n\t);\n}\n\n/**\n * Tool changes from `offered` to `desired`. A changed declaration is removed and re-added. Replay keeps retained tools\n * in place and appends additions; when that would not yield the desired order, every offered tool is removed and\n * every desired tool re-added in order.\n */\nfunction planTools(offered: readonly Tool[], desired: readonly Tool[]): ToolChanges {\n\tconst wanted = new Map(desired.map((tool) => [tool.name, tool]));\n\tconst kept = offered.filter((tool) => {\n\t\tconst next = wanted.get(tool.name);\n\t\treturn next !== undefined && declarationsEqual(tool, next);\n\t});\n\tconst keptNames = new Set(kept.map((tool) => tool.name));\n\tconst added = desired.filter((tool) => !keptNames.has(tool.name));\n\tconst replayed = [...kept, ...added];\n\tif (replayed.some((tool, index) => tool.name !== desired[index]!.name)) {\n\t\treturn {\n\t\t\ttoolsRemoved: offered.map((tool) => ({ name: tool.name })),\n\t\t\ttoolsAdded: desired.map(toToolDeclaration),\n\t\t};\n\t}\n\treturn {\n\t\ttoolsRemoved: offered.filter((tool) => !keptNames.has(tool.name)).map((tool) => ({ name: tool.name })),\n\t\ttoolsAdded: added.map(toToolDeclaration),\n\t};\n}\n\n/** Section patches: none, the minimal patch, or a remove-all/re-add-all pair when the order would differ. */\nfunction planSections(\n\tshown: ReadonlyMap<string, string>,\n\tdesired: ReadonlyMap<string, string>,\n): Record<string, string | null>[] {\n\tconst patchedOrder = [\n\t\t...[...shown.keys()].filter((key) => desired.has(key)),\n\t\t...[...desired.keys()].filter((key) => !shown.has(key)),\n\t];\n\tconst desiredOrder = [...desired.keys()];\n\tif (patchedOrder.some((key, index) => key !== desiredOrder[index])) {\n\t\treturn [Object.fromEntries([...shown.keys()].map((key) => [key, null])), Object.fromEntries(desired)];\n\t}\n\n\tconst patch: Record<string, string | null> = {};\n\tfor (const [key, value] of shown) {\n\t\tconst next = desired.get(key);\n\t\tif (next !== value) patch[key] = next ?? null;\n\t}\n\tfor (const [key, value] of desired) if (!shown.has(key)) patch[key] = value;\n\treturn Object.keys(patch).length === 0 ? [] : [patch];\n}\n\nfunction systemEntry(\n\tsections: Record<string, string | null> | undefined,\n\ttools: ToolChanges | undefined,\n\ttimestamp: number,\n): SystemDraft {\n\tconst message: SystemMessage = {\n\t\trole: \"system\",\n\t\tcontent: \"\",\n\t\t...(sections === undefined ? {} : { sections }),\n\t\t...(tools === undefined || tools.toolsRemoved.length === 0 ? {} : { toolsRemoved: tools.toolsRemoved }),\n\t\t...(tools === undefined || tools.toolsAdded.length === 0 ? {} : { toolsAdded: tools.toolsAdded }),\n\t\ttimestamp,\n\t};\n\treturn { model: [message] };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/harness/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/harness/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAG7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,2DAA2D;AAC3D,MAAM,MAAM,aAAa,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,sGAAsG;AACtG,eAAO,MAAM,WAAW,2DAQtB,CAAC;AAEH;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,MAAM,EACtE,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAChC,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,MAAM,CAAC,CAUjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/harness/provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAQ5C,sGAAsG;AACtG,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAgB;IACnD,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,cAAc;IACrB,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;IACxC,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI;CAC1B,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC5C,OAAgC,EAChC,OAAgB;IAEhB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACtF,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC,SAAS,CAAC;IACtD,IAAI,OAA2B,CAAC;IAChC,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QACjC,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;QACxE,OAAO,SAAS,CAAC;IAClB,CAAC,EAAE,OAAO,CAAC,CAAC;IACZ,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,OAAO,CAAC,cAAc,6BAA6B,CAAC,CAAC;IAChH,OAAO,OAAO,CAAC;AAChB,CAAC","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport { uuidv7 } from \"@earendil-works/pi-ai/utils/uuid\";\nimport { defineDoc } from \"../documents.ts\";\nimport type { TaskRuntime } from \"../types.ts\";\n\n/** Stable provider-facing identity of one conversation. */\nexport type ProviderState = {\n\tsessionId: string;\n};\n\n/** Built-in provider state; every fork starts with a fresh identity instead of copying its parent. */\nexport const ProviderDoc = defineDoc<ProviderState>({\n\tkind: \"pi.provider\",\n\tversion: 1,\n\tscope: \"conversation\",\n\thistory: \"latest\",\n\tfork: \"initial\",\n\tinitial: () => ({ sessionId: uuidv7() }),\n\tcheckpointWhen: () => true,\n});\n\n/**\n * Return the persisted identity without writing in the normal path. A legacy conversation without `pi.provider` gets\n * one migration commit whose `tx.doc()` runs `initial()` before the provider request starts.\n */\nexport async function ensureProviderSessionId<I, S, R, H extends object>(\n\truntime: TaskRuntime<I, S, R, H>,\n\tcontext: Context,\n): Promise<string> {\n\tconst existing = await runtime.snapshot(ProviderDoc, runtime.conversationId, context);\n\tif (existing !== undefined) return existing.sessionId;\n\tlet created: string | undefined;\n\tawait runtime.commit(async (tx) => {\n\t\tcreated = (await tx.doc(ProviderDoc, runtime.conversationId)).sessionId;\n\t\treturn undefined;\n\t}, context);\n\tif (created === undefined) throw new Error(`Conversation ${runtime.conversationId} has no provider session ID`);\n\treturn created;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/harness/provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAQ5C,sGAAsG;AACtG,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAgB;IACnD,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,cAAc;IACrB,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;IACxC,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI;CAC1B,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC5C,OAAgC,EAChC,OAAgB;IAEhB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACtF,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC,SAAS,CAAC;IACtD,IAAI,OAA2B,CAAC;IAChC,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QACjC,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;QACxE,OAAO,SAAS,CAAC;IAClB,CAAC,EAAE,OAAO,CAAC,CAAC;IACZ,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,OAAO,CAAC,cAAc,6BAA6B,CAAC,CAAC;IAChH,OAAO,OAAO,CAAC;AAChB,CAAC","sourcesContent":["import type { Context } from \"@earendil-works/chord/context\";\nimport { uuidv7 } from \"@earendil-works/pi-ai/utils/uuid\";\nimport { defineDoc } from \"../documents.ts\";\nimport type { TaskRuntime } from \"../types.ts\";\n\n/** Stable provider-facing identity of one conversation. */\nexport type ProviderState = {\n\tsessionId: string;\n};\n\n/** Built-in provider state; every fork starts with a fresh identity instead of copying its parent. */\nexport const ProviderDoc = defineDoc<ProviderState>({\n\tkind: \"pi.provider\",\n\tversion: 1,\n\tscope: \"conversation\",\n\thistory: \"latest\",\n\tfork: \"initial\",\n\tinitial: () => ({ sessionId: uuidv7() }),\n\tcheckpointWhen: () => true,\n});\n\n/**\n * Return the persisted identity without writing in the normal path. A legacy conversation without `pi.provider` gets\n * one migration commit whose `tx.doc()` runs `initial()` before the provider request starts.\n */\nexport async function ensureProviderSessionId<I, S, R, H extends object>(\n\truntime: TaskRuntime<I, S, R, H>,\n\tcontext: Context,\n): Promise<string> {\n\tconst existing = await runtime.snapshot(ProviderDoc, runtime.conversationId, context);\n\tif (existing !== undefined) return existing.sessionId;\n\tlet created: string | undefined;\n\tawait runtime.commit(async (tx) => {\n\t\tcreated = (await tx.doc(ProviderDoc, runtime.conversationId)).sessionId;\n\t\treturn undefined;\n\t}, context);\n\tif (created === undefined) throw new Error(`Conversation ${runtime.conversationId} has no provider session ID`);\n\treturn created;\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { RegistryValue } from "@earendil-works/chord";
|
|
1
2
|
import type { Context } from "@earendil-works/chord/context";
|
|
2
|
-
import type { RegistryValue } from "@earendil-works/chord/next";
|
|
3
3
|
import type { RegistryReader, RegistrySnapshot, ToolRegistration } from "./types.ts";
|
|
4
4
|
/**
|
|
5
5
|
* A `RegistryReader` over a Chord registry value whose composition is a registry snapshot: `snapshot()` reads the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry-reader.d.ts","sourceRoot":"","sources":["../../src/harness/registry-reader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"registry-reader.d.ts","sourceRoot":"","sources":["../../src/harness/registry-reader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAErF;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,SAAS,gBAAgB,GAAG,gBAAgB,EAC9E,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAC5C,OAAO,EAAE,OAAO,GACd,cAAc,CAAC,IAAI,CAAC,CAiBtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry-reader.js","sourceRoot":"","sources":["../../src/harness/registry-reader.ts"],"names":[],"mappings":"AAAA,oHAAoH;AACpH,sCAAsC;AAMtC;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC7B,KAA4C,EAC5C,OAAgB;IAEhB,OAAO;QACN,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK;QAC3B,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE;YACvB,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAChC;gBACC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;oBACjB,uEAAuE;oBACvE,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;wBAAE,QAAQ,EAAE,CAAC;gBACvC,CAAC;gBACD,GAAG,EAAE,GAAG,EAAE,GAAE,CAAC;aACb,EACD,OAAO,CACP,CAAC;YACF,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QACnC,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["// A Harness's registry over a Chord registry (Chord v2 slice 8 §5): the composed value of p3's extensions registry,\n// read as Durable's `RegistryReader`.\n\nimport type {
|
|
1
|
+
{"version":3,"file":"registry-reader.js","sourceRoot":"","sources":["../../src/harness/registry-reader.ts"],"names":[],"mappings":"AAAA,oHAAoH;AACpH,sCAAsC;AAMtC;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC7B,KAA4C,EAC5C,OAAgB;IAEhB,OAAO;QACN,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK;QAC3B,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE;YACvB,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAChC;gBACC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;oBACjB,uEAAuE;oBACvE,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;wBAAE,QAAQ,EAAE,CAAC;gBACvC,CAAC;gBACD,GAAG,EAAE,GAAG,EAAE,GAAE,CAAC;aACb,EACD,OAAO,CACP,CAAC;YACF,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QACnC,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["// A Harness's registry over a Chord registry (Chord v2 slice 8 §5): the composed value of p3's extensions registry,\n// read as Durable's `RegistryReader`.\n\nimport type { RegistryValue } from \"@earendil-works/chord\";\nimport type { Context } from \"@earendil-works/chord/context\";\nimport type { RegistryReader, RegistrySnapshot, ToolRegistration } from \"./types.ts\";\n\n/**\n * A `RegistryReader` over a Chord registry value whose composition is a registry snapshot: `snapshot()` reads the\n * current composition (the last good one while `compose` fails), `subscribe` observes its compositions, its listener\n * called synchronously inside the Chord batch that composed (so it only wakes the scheduler; a Chord call there\n * throws `invalid/reentrant`). `context` is the observation's: aborting it detaches every listener.\n */\nexport function registryReader<Tool extends ToolRegistration = ToolRegistration>(\n\tvalue: RegistryValue<RegistrySnapshot<Tool>>,\n\tcontext: Context,\n): RegistryReader<Tool> {\n\treturn {\n\t\tsnapshot: () => value.value,\n\t\tsubscribe: (listener) => {\n\t\t\tconst observation = value.observe(\n\t\t\t\t{\n\t\t\t\t\tadvance: (call) => {\n\t\t\t\t\t\t// A failed composition keeps the last snapshot: nothing to reconsider.\n\t\t\t\t\t\tif (call.kind === \"value\") listener();\n\t\t\t\t\t},\n\t\t\t\t\tend: () => {},\n\t\t\t\t},\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\treturn () => observation.detach();\n\t\t},\n\t};\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type Context
|
|
1
|
+
import { type Context } from "@earendil-works/chord/context";
|
|
2
|
+
import { type JsonValue } from "@earendil-works/chord/json";
|
|
2
3
|
import type { Models } from "@earendil-works/pi-ai";
|
|
3
4
|
import type { ExecutionEnv } from "../env/index.ts";
|
|
4
5
|
import type { SessionImpl } from "../session/session.ts";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/harness/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/harness/scheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { awaitWithContext, withAbortSignal, withoutAbortSignal, withTelemetry } from "@earendil-works/chord/context";
|
|
1
|
+
import { awaitWithContext, withAbortSignal, withoutAbortSignal, withTelemetry, } from "@earendil-works/chord/context";
|
|
3
2
|
import { ownedSlice } from "@earendil-works/chord/delta";
|
|
3
|
+
import { copyJson } from "@earendil-works/chord/json";
|
|
4
4
|
import { createTypedMetrics, createTypedSpanStarter, NOOP_TELEMETRY_CONTEXT, NOOP_TELEMETRY_METRICS, } from "@earendil-works/pi-telemetry";
|
|
5
5
|
import { errorMessage, ReadOnlySession } from "../errors.js";
|
|
6
6
|
import { ALL_KEYS, conversationKey, INTENT_KEY, ownedKey, ROOTS_KEY, taskKey } from "../session/keys.js";
|
|
@@ -139,9 +139,15 @@ export class TaskScheduler {
|
|
|
139
139
|
#unloaded = new Set();
|
|
140
140
|
/** Live tasks with cancellation intent, the sources of abort cascades (spec §5.4). */
|
|
141
141
|
#intent = new Set();
|
|
142
|
-
/**
|
|
142
|
+
/**
|
|
143
|
+
* Live tasks that are not `completing`, the candidates of a reservation pass; ones found waiting leave it. A pass
|
|
144
|
+
* takes the set while it plans, so a task made a candidate meanwhile is not dropped by its stale decision.
|
|
145
|
+
*/
|
|
143
146
|
#runnable = new Set();
|
|
144
|
-
/**
|
|
147
|
+
/**
|
|
148
|
+
* `completing` tasks the next finalize pass checks: those that started holding, and holders of ended work. A pass
|
|
149
|
+
* takes them before it plans, so a check asked for meanwhile stays for the next pass.
|
|
150
|
+
*/
|
|
145
151
|
#finalizeChecks = new Set();
|
|
146
152
|
/** Live waiting tasks by each task in their `on`. */
|
|
147
153
|
#waiters = new Map();
|
|
@@ -967,12 +973,11 @@ export class TaskScheduler {
|
|
|
967
973
|
const done = new Set();
|
|
968
974
|
// The commit's candidates, kept in step with the terminal records each round stages.
|
|
969
975
|
const overlay = overlayOf(tx);
|
|
970
|
-
let round;
|
|
976
|
+
let round = [...this.#finalizeChecks];
|
|
977
|
+
this.#finalizeChecks.clear();
|
|
971
978
|
for (;;) {
|
|
972
979
|
const ids = round;
|
|
973
|
-
const plan = await this.#region(() => this.#planRound(ids
|
|
974
|
-
if (ids === undefined)
|
|
975
|
-
this.#finalizeChecks.clear();
|
|
980
|
+
const plan = await this.#region(() => this.#planRound(ids, overlay, done), this.#reloadScopes);
|
|
976
981
|
for (const { record, terminal } of plan.finalized) {
|
|
977
982
|
tx.setTask(terminal);
|
|
978
983
|
overlay.tasks.set(record.id, terminal);
|
|
@@ -1757,9 +1762,7 @@ export class TaskScheduler {
|
|
|
1757
1762
|
// Every pass picks up sleeps whose time has come: a pass started by any change may be the first to run after
|
|
1758
1763
|
// a deadline, and the wake it schedules no longer keeps a timer for a due sleep.
|
|
1759
1764
|
this.#wakeDue();
|
|
1760
|
-
const plan = await this.#
|
|
1761
|
-
for (const id of plan.dropped)
|
|
1762
|
-
this.#runnable.delete(id);
|
|
1765
|
+
const plan = await this.#planCandidates();
|
|
1763
1766
|
// Work below an owner with cancellation intent waits for its cascade mark instead of running a phase; schedule
|
|
1764
1767
|
// the cascade, which may not have run yet.
|
|
1765
1768
|
if (plan.cascade) {
|
|
@@ -1831,17 +1834,43 @@ export class TaskScheduler {
|
|
|
1831
1834
|
this.#dirty = true;
|
|
1832
1835
|
return reservations;
|
|
1833
1836
|
}
|
|
1837
|
+
/**
|
|
1838
|
+
* Plan a reservation pass over the candidates, taken out of `#runnable` while it plans: a task made a candidate
|
|
1839
|
+
* meanwhile, such as a waiter whose last task ended, lands in the fresh set, so the pass's decision to drop it cannot
|
|
1840
|
+
* erase that. The candidates not dropped go back in front of the fresh set, unless they ended or hold meanwhile.
|
|
1841
|
+
*/
|
|
1842
|
+
async #planCandidates() {
|
|
1843
|
+
const candidates = this.#runnable;
|
|
1844
|
+
this.#runnable = new Set();
|
|
1845
|
+
let dropped = new Set();
|
|
1846
|
+
try {
|
|
1847
|
+
const plan = await this.#region(() => this.#planReservation(candidates), this.#reloadScopes);
|
|
1848
|
+
dropped = new Set(plan.dropped);
|
|
1849
|
+
return plan;
|
|
1850
|
+
}
|
|
1851
|
+
finally {
|
|
1852
|
+
const merged = new Set();
|
|
1853
|
+
for (const id of candidates) {
|
|
1854
|
+
const status = this.#live.get(id)?.state.status;
|
|
1855
|
+
if (!dropped.has(id) && status !== undefined && status !== "completing")
|
|
1856
|
+
merged.add(id);
|
|
1857
|
+
}
|
|
1858
|
+
for (const id of this.#runnable)
|
|
1859
|
+
merged.add(id);
|
|
1860
|
+
this.#runnable = merged;
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1834
1863
|
/**
|
|
1835
1864
|
* A reservation pass's decision region: the candidates it drops (gone, holding, waiting, asleep, or with an
|
|
1836
1865
|
* invocation), whether one waits for a cascade, and the runnable records to resolve. Iterating the candidates is not
|
|
1837
1866
|
* keyed: a pass that misses a task a pending commit makes runnable only delays it, as does skipping one with an
|
|
1838
1867
|
* invocation without reading its record, or a waiter's check whether what it waits on is still live.
|
|
1839
1868
|
*/
|
|
1840
|
-
#planReservation() {
|
|
1869
|
+
#planReservation(candidates) {
|
|
1841
1870
|
const dropped = [];
|
|
1842
1871
|
const ready = [];
|
|
1843
1872
|
let cascade = false;
|
|
1844
|
-
for (const id of
|
|
1873
|
+
for (const id of candidates) {
|
|
1845
1874
|
if (this.#invocations.has(id)) {
|
|
1846
1875
|
dropped.push(id);
|
|
1847
1876
|
continue;
|