@earendil-works/pi-durable 0.99.2 → 1.0.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.
- package/CHANGELOG.md +7 -0
- package/README.md +196 -74
- package/dist/env/index.d.ts +5 -0
- package/dist/env/index.d.ts.map +1 -1
- package/dist/env/index.js.map +1 -1
- package/dist/env/node.d.ts +2 -0
- package/dist/env/node.d.ts.map +1 -1
- package/dist/env/node.js +2 -0
- package/dist/env/node.js.map +1 -1
- package/dist/harness/agent.d.ts +31 -0
- package/dist/harness/agent.d.ts.map +1 -0
- package/dist/harness/agent.js +209 -0
- package/dist/harness/agent.js.map +1 -0
- package/dist/harness/compaction.d.ts.map +1 -1
- package/dist/harness/compaction.js +8 -11
- package/dist/harness/compaction.js.map +1 -1
- package/dist/harness/define.d.ts +18 -0
- package/dist/harness/define.d.ts.map +1 -0
- package/dist/harness/define.js +25 -0
- package/dist/harness/define.js.map +1 -0
- package/dist/harness/events.d.ts +5 -5
- package/dist/harness/events.d.ts.map +1 -1
- package/dist/harness/events.js +6 -6
- package/dist/harness/events.js.map +1 -1
- package/dist/harness/generation.d.ts +2 -4
- package/dist/harness/generation.d.ts.map +1 -1
- package/dist/harness/generation.js +39 -43
- package/dist/harness/generation.js.map +1 -1
- package/dist/harness/harness.d.ts.map +1 -1
- package/dist/harness/harness.js +68 -154
- package/dist/harness/harness.js.map +1 -1
- package/dist/harness/inbox.d.ts +4 -2
- package/dist/harness/inbox.d.ts.map +1 -1
- package/dist/harness/inbox.js +3 -5
- package/dist/harness/inbox.js.map +1 -1
- package/dist/harness/prompt.d.ts +1 -3
- package/dist/harness/prompt.d.ts.map +1 -1
- package/dist/harness/prompt.js +1 -11
- package/dist/harness/prompt.js.map +1 -1
- package/dist/harness/registry.d.ts +2 -3
- package/dist/harness/registry.d.ts.map +1 -1
- package/dist/harness/registry.js +66 -283
- package/dist/harness/registry.js.map +1 -1
- package/dist/harness/scheduler.d.ts +7 -2
- package/dist/harness/scheduler.d.ts.map +1 -1
- package/dist/harness/scheduler.js +41 -27
- package/dist/harness/scheduler.js.map +1 -1
- package/dist/harness/submissions.d.ts +4 -4
- package/dist/harness/submissions.d.ts.map +1 -1
- package/dist/harness/submissions.js +7 -4
- package/dist/harness/submissions.js.map +1 -1
- package/dist/harness/task-graph.d.ts +49 -0
- package/dist/harness/task-graph.d.ts.map +1 -0
- package/dist/harness/task-graph.js +163 -0
- package/dist/harness/task-graph.js.map +1 -0
- package/dist/harness/tool.d.ts +1 -1
- package/dist/harness/tool.d.ts.map +1 -1
- package/dist/harness/tool.js +9 -6
- package/dist/harness/tool.js.map +1 -1
- package/dist/harness/types.d.ts +171 -140
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/view.d.ts +1 -1
- package/dist/harness/view.d.ts.map +1 -1
- package/dist/harness/view.js +2 -7
- package/dist/harness/view.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/session/session.d.ts.map +1 -1
- package/dist/session/session.js +5 -1
- package/dist/session/session.js.map +1 -1
- package/dist/session/transaction.d.ts +2 -2
- package/dist/session/transaction.d.ts.map +1 -1
- package/dist/session/transaction.js +7 -4
- package/dist/session/transaction.js.map +1 -1
- package/dist/storage/sqlite/database.d.ts +26 -19
- package/dist/storage/sqlite/database.d.ts.map +1 -1
- package/dist/storage/sqlite/database.js.map +1 -1
- package/dist/storage/sqlite/index.d.ts +1 -1
- package/dist/storage/sqlite/index.d.ts.map +1 -1
- package/dist/storage/sqlite/index.js.map +1 -1
- package/dist/storage/sqlite/migrations.js +6 -6
- package/dist/storage/sqlite/migrations.js.map +1 -1
- package/dist/storage/sqlite/node.d.ts +23 -7
- package/dist/storage/sqlite/node.d.ts.map +1 -1
- package/dist/storage/sqlite/node.js +129 -47
- package/dist/storage/sqlite/node.js.map +1 -1
- package/dist/storage/sqlite/storage.d.ts +12 -0
- package/dist/storage/sqlite/storage.d.ts.map +1 -1
- package/dist/storage/sqlite/storage.js +121 -129
- package/dist/storage/sqlite/storage.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 +3 -2
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts +3 -3
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +5 -4
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/file-mutation-queue.d.ts +5 -1
- package/dist/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/tools/file-mutation-queue.js +39 -33
- package/dist/tools/file-mutation-queue.js.map +1 -1
- package/dist/tools/index.d.ts +18 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +10 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/read.d.ts +3 -3
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +4 -3
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/write.d.ts +1 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +3 -2
- package/dist/tools/write.js.map +1 -1
- package/dist/types.d.ts +15 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +25 -15
- package/dist/harness/config.d.ts +0 -29
- package/dist/harness/config.d.ts.map +0 -1
- package/dist/harness/config.js +0 -24
- package/dist/harness/config.js.map +0 -1
- package/docs/chord-delta-findings.md +0 -358
- package/docs/pico-v5-chord-usage.md +0 -373
- package/docs/pico-v5-handoff.md +0 -861
- package/docs/pico-v5.md +0 -4174
package/dist/harness/prompt.d.ts
CHANGED
|
@@ -5,13 +5,11 @@ import type { ContextView, PromptInput, PromptSection, ToolRegistration } from "
|
|
|
5
5
|
/** Sections in effect after replaying system messages in order: set in place, `null` deletes, re-adding appends. */
|
|
6
6
|
export declare function replaySections(messages: readonly Message[]): Map<string, string>;
|
|
7
7
|
/**
|
|
8
|
-
* Render sections in
|
|
8
|
+
* Render the agent's sections in order. `undefined` omits a section; tagged text is wrapped as `<key>\n...\n</key>`. A
|
|
9
9
|
* section that throws keeps its shown text, if any, and is reported; errors after `context` is aborted propagate.
|
|
10
10
|
*/
|
|
11
11
|
export declare function renderSections<Tool extends ToolRegistration>(sections: readonly PromptSection<Tool>[], input: PromptInput<Tool>, shown: ReadonlyMap<string, string>, report: (error: unknown) => void, context: Context): Promise<Map<string, string>>;
|
|
12
12
|
type SystemDraft = TypedEntryDraft<never>;
|
|
13
|
-
/** Active names the snapshot resolves, first occurrence of each, in configured order, as composed by wrappers. */
|
|
14
|
-
export declare function desiredTools<T extends ToolRegistration>(activeTools: readonly string[], resolve: (name: string) => T | undefined): T[];
|
|
15
13
|
/**
|
|
16
14
|
* Plan the `pi.system` entries that make the replayed sections and tools of `view` equal `desired` and `tools` in values
|
|
17
15
|
* and order.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/harness/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,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,KAAK,IAAI,EAChC,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAiB9B;AAED,KAAK,WAAW,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/harness/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,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,KAAK,IAAI,EAChC,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"}
|
package/dist/harness/prompt.js
CHANGED
|
@@ -16,7 +16,7 @@ export function replaySections(messages) {
|
|
|
16
16
|
return shown;
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
|
-
* Render sections in
|
|
19
|
+
* Render the agent's sections in order. `undefined` omits a section; tagged text is wrapped as `<key>\n...\n</key>`. A
|
|
20
20
|
* section that throws keeps its shown text, if any, and is reported; errors after `context` is aborted propagate.
|
|
21
21
|
*/
|
|
22
22
|
export async function renderSections(sections, input, shown, report, context) {
|
|
@@ -41,16 +41,6 @@ export async function renderSections(sections, input, shown, report, context) {
|
|
|
41
41
|
}
|
|
42
42
|
return desired;
|
|
43
43
|
}
|
|
44
|
-
/** Active names the snapshot resolves, first occurrence of each, in configured order, as composed by wrappers. */
|
|
45
|
-
export function desiredTools(activeTools, resolve) {
|
|
46
|
-
const tools = new Map();
|
|
47
|
-
for (const name of activeTools) {
|
|
48
|
-
const tool = tools.has(name) ? undefined : resolve(name);
|
|
49
|
-
if (tool !== undefined)
|
|
50
|
-
tools.set(name, tool);
|
|
51
|
-
}
|
|
52
|
-
return [...tools.values()];
|
|
53
|
-
}
|
|
54
44
|
/**
|
|
55
45
|
* Plan the `pi.system` entries that make the replayed sections and tools of `view` equal `desired` and `tools` in values
|
|
56
46
|
* and order.
|
|
@@ -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 sections in registry 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) => 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);\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\n/** Active names the snapshot resolves, first occurrence of each, in configured order, as composed by wrappers. */\nexport function desiredTools<T extends ToolRegistration>(\n\tactiveTools: readonly string[],\n\tresolve: (name: string) => T | undefined,\n): T[] {\n\tconst tools = new Map<string, T>();\n\tfor (const name of activeTools) {\n\t\tconst tool = tools.has(name) ? undefined : resolve(name);\n\t\tif (tool !== undefined) tools.set(name, tool);\n\t}\n\treturn [...tools.values()];\n}\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\";\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) => 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);\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,7 +1,6 @@
|
|
|
1
1
|
import type { AnyTask, Registry, ToolRegistration } from "./types.ts";
|
|
2
|
-
/** Built-in task definitions every registry
|
|
2
|
+
/** Built-in task definitions every registry holds; they are not an extension and cannot be removed or replaced. */
|
|
3
3
|
export declare const BUILTIN_TASKS: readonly AnyTask[];
|
|
4
|
-
|
|
5
|
-
/** Create an application-owned registry holding only the built-ins. */
|
|
4
|
+
/** Create an application-owned registry holding only the built-in tasks. */
|
|
6
5
|
export declare function createRegistry<Tool extends ToolRegistration = ToolRegistration>(): Registry<Tool>;
|
|
7
6
|
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/harness/registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/harness/registry.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAA4B,QAAQ,EAAoB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAIlH,mHAAmH;AACnH,eAAO,MAAM,aAAa,EAAE,SAAS,OAAO,EAA+C,CAAC;AAqG5F,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,IAAI,SAAS,gBAAgB,GAAG,gBAAgB,KAAK,QAAQ,CAAC,IAAI,CAAC,CAEjG"}
|
package/dist/harness/registry.js
CHANGED
|
@@ -1,185 +1,53 @@
|
|
|
1
|
+
import { INSTRUCTIONS_KEY } from "./agent.js";
|
|
1
2
|
import { CompactionTask } from "./compaction.js";
|
|
2
|
-
import { ConversationConfig } from "./config.js";
|
|
3
3
|
import { GenerationTask } from "./generation.js";
|
|
4
|
-
import { InboxDoc } from "./inbox.js";
|
|
5
|
-
import { LiveDoc } from "./live.js";
|
|
6
4
|
import { ToolTask } from "./tool.js";
|
|
7
|
-
import { UsageDoc } from "./usage.js";
|
|
8
5
|
const SECTION_KEY = /^[a-z][a-z0-9_-]*$/;
|
|
9
|
-
/** Built-in task definitions every registry
|
|
6
|
+
/** Built-in task definitions every registry holds; they are not an extension and cannot be removed or replaced. */
|
|
10
7
|
export const BUILTIN_TASKS = [GenerationTask, ToolTask, CompactionTask];
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Built-in documents: empty `pi.live`, `pi.inbox`, and `pi.usage`, and for a new conversation the default
|
|
14
|
-
* configuration with every registered tool active.
|
|
15
|
-
*/
|
|
16
|
-
async function builtinSetup(tx, conversation, registry) {
|
|
17
|
-
await tx.doc(LiveDoc, conversation.id);
|
|
18
|
-
await tx.doc(InboxDoc, conversation.id);
|
|
19
|
-
await tx.doc(UsageDoc, conversation.id);
|
|
20
|
-
if (conversation.parent !== undefined)
|
|
21
|
-
return;
|
|
22
|
-
(await tx.doc(ConversationConfig, conversation.id)).activeTools = [...registry.toolNames()];
|
|
23
|
-
}
|
|
24
|
-
/** Immutable published registry state; wrappers are composed lazily once per state. */
|
|
8
|
+
/** Immutable published registry state. */
|
|
25
9
|
class RegistryState {
|
|
26
|
-
|
|
27
|
-
#
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return names;
|
|
43
|
-
}
|
|
44
|
-
task(name) {
|
|
45
|
-
for (const record of this.records) {
|
|
46
|
-
if (record.slot.kind === "task" && record.slot.task.definition.name === name)
|
|
47
|
-
return record.slot.task;
|
|
10
|
+
#extensions;
|
|
11
|
+
#byName;
|
|
12
|
+
#tasks;
|
|
13
|
+
constructor(extensions) {
|
|
14
|
+
this.#extensions = extensions;
|
|
15
|
+
this.#byName = new Map(extensions.map((extension) => [extension.name, extension]));
|
|
16
|
+
const tasks = new Map();
|
|
17
|
+
for (const task of BUILTIN_TASKS)
|
|
18
|
+
tasks.set(task.definition.name, task);
|
|
19
|
+
for (const extension of extensions) {
|
|
20
|
+
for (const task of extension.tasks ?? []) {
|
|
21
|
+
const name = task.definition.name;
|
|
22
|
+
if (tasks.has(name))
|
|
23
|
+
throw new Error(`Task ${name} of extension ${extension.name} is already installed`);
|
|
24
|
+
tasks.set(name, task);
|
|
25
|
+
}
|
|
48
26
|
}
|
|
49
|
-
|
|
27
|
+
this.#tasks = tasks;
|
|
50
28
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
for (const record of this.records)
|
|
54
|
-
if (record.slot.kind === "setup")
|
|
55
|
-
setups.push(record.slot);
|
|
56
|
-
return setups;
|
|
29
|
+
installed() {
|
|
30
|
+
return this.#extensions;
|
|
57
31
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
for (const record of this.records)
|
|
61
|
-
if (record.slot.kind === "task")
|
|
62
|
-
tasks.push(record.slot.task);
|
|
63
|
-
return tasks;
|
|
32
|
+
extension(name) {
|
|
33
|
+
return this.#byName.get(name);
|
|
64
34
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const hooks = [];
|
|
68
|
-
for (const record of this.records) {
|
|
69
|
-
if (record.slot.kind === "hook" && record.slot.taskName === task.definition.name)
|
|
70
|
-
hooks.push(record.slot.hook);
|
|
71
|
-
}
|
|
72
|
-
return hooks;
|
|
35
|
+
tools() {
|
|
36
|
+
return this.#extensions.flatMap((extension) => (extension.tools ?? []).map((tool) => ({ extension, tool })));
|
|
73
37
|
}
|
|
74
38
|
sections() {
|
|
75
|
-
return this.#
|
|
39
|
+
return this.#extensions.flatMap((extension) => (extension.sections ?? []).map((section) => ({ extension, section })));
|
|
76
40
|
}
|
|
77
|
-
|
|
78
|
-
return this.#
|
|
41
|
+
tasks() {
|
|
42
|
+
return [...this.#tasks.values()];
|
|
79
43
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
return this.#composition;
|
|
83
|
-
const failures = [];
|
|
84
|
-
const toolWraps = new Map();
|
|
85
|
-
const sectionWraps = new Map();
|
|
86
|
-
for (const record of this.records) {
|
|
87
|
-
const slot = record.slot;
|
|
88
|
-
if (slot.kind === "toolWrap")
|
|
89
|
-
appendTo(toolWraps, slot.name, slot.wrapper);
|
|
90
|
-
if (slot.kind === "sectionWrap")
|
|
91
|
-
appendTo(sectionWraps, slot.key, slot.wrapper);
|
|
92
|
-
}
|
|
93
|
-
const tools = [];
|
|
94
|
-
const toolsByName = new Map();
|
|
95
|
-
const sections = [];
|
|
96
|
-
for (const record of this.records) {
|
|
97
|
-
const slot = record.slot;
|
|
98
|
-
if (slot.kind === "tool") {
|
|
99
|
-
const name = slot.tool.name;
|
|
100
|
-
try {
|
|
101
|
-
let tool = slot.tool;
|
|
102
|
-
for (const wrap of toolWraps.get(name) ?? []) {
|
|
103
|
-
tool = wrap(tool);
|
|
104
|
-
if (tool.name !== name)
|
|
105
|
-
throw new Error(`Tool wrapper renamed ${name} to ${tool.name}`);
|
|
106
|
-
}
|
|
107
|
-
tools.push(tool);
|
|
108
|
-
toolsByName.set(name, tool);
|
|
109
|
-
}
|
|
110
|
-
catch (error) {
|
|
111
|
-
failures.push({ kind: "tool", name, error });
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
else if (slot.kind === "section") {
|
|
115
|
-
const key = slot.section.key;
|
|
116
|
-
try {
|
|
117
|
-
let section = slot.section;
|
|
118
|
-
for (const wrap of sectionWraps.get(key) ?? []) {
|
|
119
|
-
section = wrap(section);
|
|
120
|
-
if (section.key !== key)
|
|
121
|
-
throw new Error(`Section wrapper renamed ${key} to ${section.key}`);
|
|
122
|
-
}
|
|
123
|
-
sections.push(section);
|
|
124
|
-
}
|
|
125
|
-
catch (error) {
|
|
126
|
-
failures.push({ kind: "section", name: key, error });
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
this.#composition = { tools, toolsByName, sections, failures };
|
|
131
|
-
return this.#composition;
|
|
44
|
+
task(name) {
|
|
45
|
+
return this.#tasks.get(name);
|
|
132
46
|
}
|
|
133
47
|
}
|
|
134
48
|
class RegistryImpl {
|
|
135
49
|
#current = new RegistryState([]);
|
|
136
|
-
#batch;
|
|
137
|
-
/** First position of every key ever published; re-registered keys keep it. */
|
|
138
|
-
#positions = new Map();
|
|
139
50
|
#listeners = new Set();
|
|
140
|
-
#nextPosition = 0;
|
|
141
|
-
tools;
|
|
142
|
-
hooks;
|
|
143
|
-
tasks;
|
|
144
|
-
conversations;
|
|
145
|
-
systemPrompt;
|
|
146
|
-
constructor() {
|
|
147
|
-
this.tools = {
|
|
148
|
-
add: (tool) => this.#register({ kind: "tool", tool }, `tool\0${tool.name}`, `Tool ${tool.name}`),
|
|
149
|
-
wrap: (name, key, wrapper) => this.#register({ kind: "toolWrap", name, wrapper }, `toolWrap\0${name}\0${key}`, `Tool wrapper ${key} for ${name}`),
|
|
150
|
-
list: () => this.#current.tools(),
|
|
151
|
-
};
|
|
152
|
-
this.hooks = {
|
|
153
|
-
add: (task, handlers, options) => {
|
|
154
|
-
const taskName = task.definition.name;
|
|
155
|
-
const hook = options?.scope === undefined ? { handlers } : { handlers, scope: options.scope };
|
|
156
|
-
const key = options?.key;
|
|
157
|
-
return this.#register({ kind: "hook", taskName, hook }, key === undefined ? undefined : `hook\0${taskName}\0${key}`, `Hook ${key} for ${taskName}`);
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
this.tasks = {
|
|
161
|
-
add: (task) => {
|
|
162
|
-
const name = task.definition.name;
|
|
163
|
-
return this.#register({ kind: "task", task }, `task\0${name}`, `Task ${name}`);
|
|
164
|
-
},
|
|
165
|
-
list: () => this.#current.tasks(),
|
|
166
|
-
};
|
|
167
|
-
this.conversations = {
|
|
168
|
-
setup: (key, setup) => this.#register({ kind: "setup", key, setup }, `setup\0${key}`, `Setup ${key}`),
|
|
169
|
-
};
|
|
170
|
-
this.systemPrompt = {
|
|
171
|
-
section: (key, render, options) => {
|
|
172
|
-
requireSectionKey(key);
|
|
173
|
-
const section = options?.tag === undefined ? { key, render } : { key, render, tag: options.tag };
|
|
174
|
-
return this.#register({ kind: "section", section }, `section\0${key}`, `Section ${key}`);
|
|
175
|
-
},
|
|
176
|
-
wrap: (key, wrapperKey, wrapper) => {
|
|
177
|
-
requireSectionKey(key);
|
|
178
|
-
return this.#register({ kind: "sectionWrap", key, wrapper }, `sectionWrap\0${key}\0${wrapperKey}`, `Section wrapper ${wrapperKey} for ${key}`);
|
|
179
|
-
},
|
|
180
|
-
sections: () => this.#current.sections(),
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
51
|
snapshot() {
|
|
184
52
|
return this.#current;
|
|
185
53
|
}
|
|
@@ -187,132 +55,47 @@ class RegistryImpl {
|
|
|
187
55
|
this.#listeners.add(listener);
|
|
188
56
|
return () => this.#listeners.delete(listener);
|
|
189
57
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
try {
|
|
197
|
-
rejectThenable(register());
|
|
198
|
-
added = [...batch.added];
|
|
199
|
-
this.#batch = undefined;
|
|
200
|
-
this.#publish(batch);
|
|
201
|
-
}
|
|
202
|
-
catch (error) {
|
|
203
|
-
this.#batch = undefined;
|
|
204
|
-
for (const record of batch.added)
|
|
205
|
-
record.status = "rejected";
|
|
206
|
-
throw error;
|
|
207
|
-
}
|
|
208
|
-
return {
|
|
209
|
-
dispose: () => {
|
|
210
|
-
if (this.#batch !== undefined) {
|
|
211
|
-
for (const record of added)
|
|
212
|
-
this.#dispose(record);
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
this.batch(() => {
|
|
216
|
-
for (const record of added)
|
|
217
|
-
this.#dispose(record);
|
|
218
|
-
});
|
|
219
|
-
},
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
#register(slot, key, label) {
|
|
223
|
-
const record = { slot, key, label, position: -1, status: "staged" };
|
|
224
|
-
const batch = this.#batch;
|
|
225
|
-
if (batch !== undefined) {
|
|
226
|
-
batch.added.push(record);
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
try {
|
|
230
|
-
this.#publish({ added: [record], disposed: new Set() });
|
|
231
|
-
}
|
|
232
|
-
catch (error) {
|
|
233
|
-
record.status = "rejected";
|
|
234
|
-
throw error;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
return { dispose: () => this.#dispose(record) };
|
|
58
|
+
install(extension) {
|
|
59
|
+
validateExtension(extension);
|
|
60
|
+
const current = this.#current.installed();
|
|
61
|
+
const index = current.findIndex((installed) => installed.name === extension.name);
|
|
62
|
+
const next = index < 0 ? [...current, extension] : current.map((installed, at) => (at === index ? extension : installed));
|
|
63
|
+
this.#publish(next);
|
|
238
64
|
}
|
|
239
|
-
|
|
240
|
-
const
|
|
241
|
-
if (
|
|
242
|
-
const index = batch?.added.indexOf(record) ?? -1;
|
|
243
|
-
if (index < 0)
|
|
244
|
-
return;
|
|
245
|
-
batch.added.splice(index, 1);
|
|
246
|
-
record.status = "disposed";
|
|
247
|
-
}
|
|
248
|
-
else if (record.status === "published") {
|
|
249
|
-
if (batch !== undefined)
|
|
250
|
-
batch.disposed.add(record);
|
|
251
|
-
else
|
|
252
|
-
this.#publish({ added: [], disposed: new Set([record]) });
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
/** Validate the final staged state, then publish it synchronously. */
|
|
256
|
-
#publish(batch) {
|
|
257
|
-
if (batch.added.length === 0 && batch.disposed.size === 0)
|
|
65
|
+
uninstall(extension) {
|
|
66
|
+
const current = this.#current.installed();
|
|
67
|
+
if (!current.some((installed) => installed.name === extension.name))
|
|
258
68
|
return;
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if (keys.has(record.key))
|
|
265
|
-
throw new Error(`${record.label} is already registered`);
|
|
266
|
-
keys.add(record.key);
|
|
267
|
-
}
|
|
268
|
-
for (const record of batch.added) {
|
|
269
|
-
if (record.key === undefined) {
|
|
270
|
-
record.position = this.#nextPosition++;
|
|
271
|
-
continue;
|
|
272
|
-
}
|
|
273
|
-
let position = this.#positions.get(record.key);
|
|
274
|
-
if (position === undefined) {
|
|
275
|
-
position = this.#nextPosition++;
|
|
276
|
-
this.#positions.set(record.key, position);
|
|
277
|
-
}
|
|
278
|
-
record.position = position;
|
|
279
|
-
}
|
|
280
|
-
records.sort((left, right) => left.position - right.position);
|
|
281
|
-
this.#current = new RegistryState(records);
|
|
282
|
-
for (const record of batch.added)
|
|
283
|
-
record.status = "published";
|
|
284
|
-
for (const record of batch.disposed)
|
|
285
|
-
record.status = "disposed";
|
|
69
|
+
this.#publish(current.filter((installed) => installed.name !== extension.name));
|
|
70
|
+
}
|
|
71
|
+
/** Build and validate the next state, which throws on a task name collision, then publish it synchronously. */
|
|
72
|
+
#publish(extensions) {
|
|
73
|
+
this.#current = new RegistryState(extensions);
|
|
286
74
|
for (const listener of [...this.#listeners])
|
|
287
75
|
listener();
|
|
288
76
|
}
|
|
289
77
|
}
|
|
290
|
-
/**
|
|
291
|
-
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (!SECTION_KEY.test(key))
|
|
308
|
-
throw new TypeError(`Section key ${JSON.stringify(key)} must match ${SECTION_KEY}`);
|
|
309
|
-
}
|
|
310
|
-
function rejectThenable(result) {
|
|
311
|
-
if ((typeof result === "object" || typeof result === "function") &&
|
|
312
|
-
result !== null &&
|
|
313
|
-
typeof result.then === "function") {
|
|
314
|
-
result.then(undefined, () => undefined);
|
|
315
|
-
throw new TypeError("Registry batch callbacks must be synchronous");
|
|
78
|
+
/** Unique tool names and section keys within one extension; valid, unreserved section keys. */
|
|
79
|
+
function validateExtension(extension) {
|
|
80
|
+
const tools = new Set();
|
|
81
|
+
for (const tool of extension.tools ?? []) {
|
|
82
|
+
if (tools.has(tool.name))
|
|
83
|
+
throw new Error(`Extension ${extension.name} has two tools named ${tool.name}`);
|
|
84
|
+
tools.add(tool.name);
|
|
85
|
+
}
|
|
86
|
+
const sections = new Set();
|
|
87
|
+
for (const { key } of extension.sections ?? []) {
|
|
88
|
+
if (!SECTION_KEY.test(key))
|
|
89
|
+
throw new TypeError(`Section key ${JSON.stringify(key)} must match ${SECTION_KEY}`);
|
|
90
|
+
if (key === INSTRUCTIONS_KEY)
|
|
91
|
+
throw new Error(`Section key ${key} is reserved for the agent's instructions`);
|
|
92
|
+
if (sections.has(key))
|
|
93
|
+
throw new Error(`Extension ${extension.name} has two sections with key ${key}`);
|
|
94
|
+
sections.add(key);
|
|
316
95
|
}
|
|
317
96
|
}
|
|
97
|
+
/** Create an application-owned registry holding only the built-in tasks. */
|
|
98
|
+
export function createRegistry() {
|
|
99
|
+
return new RegistryImpl();
|
|
100
|
+
}
|
|
318
101
|
//# sourceMappingURL=registry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/harness/registry.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ConversationRecord, Tx } from \"../types.ts\";\nimport { CompactionTask } from \"./compaction.ts\";\nimport { ConversationConfig } from \"./config.ts\";\nimport { GenerationTask } from \"./generation.ts\";\nimport { InboxDoc } from \"./inbox.ts\";\nimport { LiveDoc } from \"./live.ts\";\nimport { ToolTask } from \"./tool.ts\";\nimport type {\n\tAnyTask,\n\tConversationSetup,\n\tHookRegistration,\n\tHookScope,\n\tHooksOf,\n\tPromptSection,\n\tPromptSectionWrapper,\n\tRegistration,\n\tRegistry,\n\tRegistryFailure,\n\tRegistrySnapshot,\n\tToolRegistration,\n\tToolWrapper,\n} from \"./types.ts\";\nimport { UsageDoc } from \"./usage.ts\";\n\nconst SECTION_KEY = /^[a-z][a-z0-9_-]*$/;\n\n/** Built-in task definitions every registry starts with; they cannot be disposed or replaced. */\nexport const BUILTIN_TASKS: readonly AnyTask[] = [GenerationTask, ToolTask, CompactionTask];\n\nexport const BUILTIN_SETUP_KEY = \"pi\";\n\n/**\n * Built-in documents: empty `pi.live`, `pi.inbox`, and `pi.usage`, and for a new conversation the default\n * configuration with every registered tool active.\n */\nasync function builtinSetup(tx: Tx, conversation: ConversationRecord, registry: RegistrySnapshot): Promise<void> {\n\tawait tx.doc(LiveDoc, conversation.id);\n\tawait tx.doc(InboxDoc, conversation.id);\n\tawait tx.doc(UsageDoc, conversation.id);\n\tif (conversation.parent !== undefined) return;\n\t(await tx.doc(ConversationConfig, conversation.id)).activeTools = [...registry.toolNames()];\n}\n\ntype Slot<Tool extends ToolRegistration> =\n\t| { readonly kind: \"tool\"; readonly tool: Tool }\n\t| { readonly kind: \"toolWrap\"; readonly name: string; readonly wrapper: ToolWrapper<Tool> }\n\t| { readonly kind: \"hook\"; readonly taskName: string; readonly hook: StoredHook }\n\t| { readonly kind: \"task\"; readonly task: AnyTask }\n\t| { readonly kind: \"setup\"; readonly key: string; readonly setup: ConversationSetup }\n\t| { readonly kind: \"section\"; readonly section: PromptSection<Tool> }\n\t| { readonly kind: \"sectionWrap\"; readonly key: string; readonly wrapper: PromptSectionWrapper<Tool> };\n\n/** Hook handlers erased across task definitions; lookup by task token restores their type. */\ntype StoredHook = {\n\treadonly handlers: unknown;\n\treadonly scope?: HookScope;\n};\n\n/** One registration and its lifecycle. */\ntype RegistryRecord<Tool extends ToolRegistration> = {\n\treadonly slot: Slot<Tool>;\n\t/** Uniqueness and position key; absent for keyless hooks, which always append. */\n\treadonly key: string | undefined;\n\t/** Human-readable identity for duplicate errors. */\n\treadonly label: string;\n\tposition: number;\n\tstatus: \"staged\" | \"published\" | \"disposed\" | \"rejected\";\n};\n\ntype Batch<Tool extends ToolRegistration> = {\n\t/** Records to publish; a record disposed while staged is removed. */\n\treadonly added: RegistryRecord<Tool>[];\n\treadonly disposed: Set<RegistryRecord<Tool>>;\n};\n\ntype Composition<Tool extends ToolRegistration> = {\n\treadonly tools: readonly Tool[];\n\treadonly toolsByName: ReadonlyMap<string, Tool>;\n\treadonly sections: readonly PromptSection<Tool>[];\n\treadonly failures: readonly RegistryFailure[];\n};\n\n/** Immutable published registry state; wrappers are composed lazily once per state. */\nclass RegistryState<Tool extends ToolRegistration> implements RegistrySnapshot<Tool> {\n\treadonly records: readonly RegistryRecord<Tool>[];\n\t#composition: Composition<Tool> | undefined;\n\n\tconstructor(records: readonly RegistryRecord<Tool>[]) {\n\t\tthis.records = records;\n\t}\n\n\ttools(): readonly Tool[] {\n\t\treturn this.#composed().tools;\n\t}\n\n\ttool(name: string): Tool | undefined {\n\t\treturn this.#composed().toolsByName.get(name);\n\t}\n\n\ttoolNames(): readonly string[] {\n\t\tconst names: string[] = [];\n\t\tfor (const record of this.records) if (record.slot.kind === \"tool\") names.push(record.slot.tool.name);\n\t\treturn names;\n\t}\n\n\ttask(name: string): AnyTask | undefined {\n\t\tfor (const record of this.records) {\n\t\t\tif (record.slot.kind === \"task\" && record.slot.task.definition.name === name) return record.slot.task;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tconversationSetups(): readonly { readonly key: string; readonly setup: ConversationSetup }[] {\n\t\tconst setups: { key: string; setup: ConversationSetup }[] = [];\n\t\tfor (const record of this.records) if (record.slot.kind === \"setup\") setups.push(record.slot);\n\t\treturn setups;\n\t}\n\n\ttasks(): AnyTask[] {\n\t\tconst tasks: AnyTask[] = [];\n\t\tfor (const record of this.records) if (record.slot.kind === \"task\") tasks.push(record.slot.task);\n\t\treturn tasks;\n\t}\n\n\thooks<K extends AnyTask>(task: K): readonly HookRegistration<K>[] {\n\t\t// Registration was typed by a token with this name; matching by name lets hooks survive a task reload.\n\t\tconst hooks: StoredHook[] = [];\n\t\tfor (const record of this.records) {\n\t\t\tif (record.slot.kind === \"hook\" && record.slot.taskName === task.definition.name) hooks.push(record.slot.hook);\n\t\t}\n\t\treturn hooks as readonly HookRegistration<K>[];\n\t}\n\n\tsections(): readonly PromptSection<Tool>[] {\n\t\treturn this.#composed().sections;\n\t}\n\n\tfailures(): readonly RegistryFailure[] {\n\t\treturn this.#composed().failures;\n\t}\n\n\t#composed(): Composition<Tool> {\n\t\tif (this.#composition !== undefined) return this.#composition;\n\t\tconst failures: RegistryFailure[] = [];\n\t\tconst toolWraps = new Map<string, ToolWrapper<Tool>[]>();\n\t\tconst sectionWraps = new Map<string, PromptSectionWrapper<Tool>[]>();\n\t\tfor (const record of this.records) {\n\t\t\tconst slot = record.slot;\n\t\t\tif (slot.kind === \"toolWrap\") appendTo(toolWraps, slot.name, slot.wrapper);\n\t\t\tif (slot.kind === \"sectionWrap\") appendTo(sectionWraps, slot.key, slot.wrapper);\n\t\t}\n\t\tconst tools: Tool[] = [];\n\t\tconst toolsByName = new Map<string, Tool>();\n\t\tconst sections: PromptSection<Tool>[] = [];\n\t\tfor (const record of this.records) {\n\t\t\tconst slot = record.slot;\n\t\t\tif (slot.kind === \"tool\") {\n\t\t\t\tconst name = slot.tool.name;\n\t\t\t\ttry {\n\t\t\t\t\tlet tool = slot.tool;\n\t\t\t\t\tfor (const wrap of toolWraps.get(name) ?? []) {\n\t\t\t\t\t\ttool = wrap(tool);\n\t\t\t\t\t\tif (tool.name !== name) throw new Error(`Tool wrapper renamed ${name} to ${tool.name}`);\n\t\t\t\t\t}\n\t\t\t\t\ttools.push(tool);\n\t\t\t\t\ttoolsByName.set(name, tool);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tfailures.push({ kind: \"tool\", name, error });\n\t\t\t\t}\n\t\t\t} else if (slot.kind === \"section\") {\n\t\t\t\tconst key = slot.section.key;\n\t\t\t\ttry {\n\t\t\t\t\tlet section = slot.section;\n\t\t\t\t\tfor (const wrap of sectionWraps.get(key) ?? []) {\n\t\t\t\t\t\tsection = wrap(section);\n\t\t\t\t\t\tif (section.key !== key) throw new Error(`Section wrapper renamed ${key} to ${section.key}`);\n\t\t\t\t\t}\n\t\t\t\t\tsections.push(section);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tfailures.push({ kind: \"section\", name: key, error });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.#composition = { tools, toolsByName, sections, failures };\n\t\treturn this.#composition;\n\t}\n}\n\nclass RegistryImpl<Tool extends ToolRegistration> implements Registry<Tool> {\n\t#current = new RegistryState<Tool>([]);\n\t#batch: Batch<Tool> | undefined;\n\t/** First position of every key ever published; re-registered keys keep it. */\n\treadonly #positions = new Map<string, number>();\n\treadonly #listeners = new Set<() => void>();\n\t#nextPosition = 0;\n\n\treadonly tools: Registry<Tool>[\"tools\"];\n\treadonly hooks: Registry<Tool>[\"hooks\"];\n\treadonly tasks: Registry<Tool>[\"tasks\"];\n\treadonly conversations: Registry<Tool>[\"conversations\"];\n\treadonly systemPrompt: Registry<Tool>[\"systemPrompt\"];\n\n\tconstructor() {\n\t\tthis.tools = {\n\t\t\tadd: (tool) => this.#register({ kind: \"tool\", tool }, `tool\\0${tool.name}`, `Tool ${tool.name}`),\n\t\t\twrap: (name, key, wrapper) =>\n\t\t\t\tthis.#register(\n\t\t\t\t\t{ kind: \"toolWrap\", name, wrapper },\n\t\t\t\t\t`toolWrap\\0${name}\\0${key}`,\n\t\t\t\t\t`Tool wrapper ${key} for ${name}`,\n\t\t\t\t),\n\t\t\tlist: () => this.#current.tools(),\n\t\t};\n\t\tthis.hooks = {\n\t\t\tadd: <K extends AnyTask>(\n\t\t\t\ttask: K,\n\t\t\t\thandlers: Partial<HooksOf<K>>,\n\t\t\t\toptions?: { readonly scope?: HookScope; readonly key?: string },\n\t\t\t) => {\n\t\t\t\tconst taskName = task.definition.name;\n\t\t\t\tconst hook: StoredHook = options?.scope === undefined ? { handlers } : { handlers, scope: options.scope };\n\t\t\t\tconst key = options?.key;\n\t\t\t\treturn this.#register(\n\t\t\t\t\t{ kind: \"hook\", taskName, hook },\n\t\t\t\t\tkey === undefined ? undefined : `hook\\0${taskName}\\0${key}`,\n\t\t\t\t\t`Hook ${key} for ${taskName}`,\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t\tthis.tasks = {\n\t\t\tadd: (task) => {\n\t\t\t\tconst name = task.definition.name;\n\t\t\t\treturn this.#register({ kind: \"task\", task }, `task\\0${name}`, `Task ${name}`);\n\t\t\t},\n\t\t\tlist: () => this.#current.tasks(),\n\t\t};\n\t\tthis.conversations = {\n\t\t\tsetup: (key, setup) => this.#register({ kind: \"setup\", key, setup }, `setup\\0${key}`, `Setup ${key}`),\n\t\t};\n\t\tthis.systemPrompt = {\n\t\t\tsection: (key, render, options) => {\n\t\t\t\trequireSectionKey(key);\n\t\t\t\tconst section: PromptSection<Tool> =\n\t\t\t\t\toptions?.tag === undefined ? { key, render } : { key, render, tag: options.tag };\n\t\t\t\treturn this.#register({ kind: \"section\", section }, `section\\0${key}`, `Section ${key}`);\n\t\t\t},\n\t\t\twrap: (key, wrapperKey, wrapper) => {\n\t\t\t\trequireSectionKey(key);\n\t\t\t\treturn this.#register(\n\t\t\t\t\t{ kind: \"sectionWrap\", key, wrapper },\n\t\t\t\t\t`sectionWrap\\0${key}\\0${wrapperKey}`,\n\t\t\t\t\t`Section wrapper ${wrapperKey} for ${key}`,\n\t\t\t\t);\n\t\t\t},\n\t\t\tsections: () => this.#current.sections(),\n\t\t};\n\t}\n\n\tsnapshot(): RegistrySnapshot<Tool> {\n\t\treturn this.#current;\n\t}\n\n\tsubscribe(listener: () => void): () => void {\n\t\tthis.#listeners.add(listener);\n\t\treturn () => this.#listeners.delete(listener);\n\t}\n\n\tbatch(register: () => void): Registration {\n\t\tif (this.#batch !== undefined) throw new Error(\"Registry batches cannot be nested\");\n\t\tconst batch: Batch<Tool> = { added: [], disposed: new Set() };\n\t\tthis.#batch = batch;\n\t\tlet added: RegistryRecord<Tool>[];\n\t\ttry {\n\t\t\trejectThenable(register());\n\t\t\tadded = [...batch.added];\n\t\t\tthis.#batch = undefined;\n\t\t\tthis.#publish(batch);\n\t\t} catch (error) {\n\t\t\tthis.#batch = undefined;\n\t\t\tfor (const record of batch.added) record.status = \"rejected\";\n\t\t\tthrow error;\n\t\t}\n\t\treturn {\n\t\t\tdispose: () => {\n\t\t\t\tif (this.#batch !== undefined) {\n\t\t\t\t\tfor (const record of added) this.#dispose(record);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.batch(() => {\n\t\t\t\t\tfor (const record of added) this.#dispose(record);\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t}\n\n\t#register(slot: Slot<Tool>, key: string | undefined, label: string): Registration {\n\t\tconst record: RegistryRecord<Tool> = { slot, key, label, position: -1, status: \"staged\" };\n\t\tconst batch = this.#batch;\n\t\tif (batch !== undefined) {\n\t\t\tbatch.added.push(record);\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tthis.#publish({ added: [record], disposed: new Set() });\n\t\t\t} catch (error) {\n\t\t\t\trecord.status = \"rejected\";\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t\treturn { dispose: () => this.#dispose(record) };\n\t}\n\n\t#dispose(record: RegistryRecord<Tool>): void {\n\t\tconst batch = this.#batch;\n\t\tif (record.status === \"staged\") {\n\t\t\tconst index = batch?.added.indexOf(record) ?? -1;\n\t\t\tif (index < 0) return;\n\t\t\tbatch!.added.splice(index, 1);\n\t\t\trecord.status = \"disposed\";\n\t\t} else if (record.status === \"published\") {\n\t\t\tif (batch !== undefined) batch.disposed.add(record);\n\t\t\telse this.#publish({ added: [], disposed: new Set([record]) });\n\t\t}\n\t}\n\n\t/** Validate the final staged state, then publish it synchronously. */\n\t#publish(batch: Batch<Tool>): void {\n\t\tif (batch.added.length === 0 && batch.disposed.size === 0) return;\n\t\tconst records = [...this.#current.records.filter((record) => !batch.disposed.has(record)), ...batch.added];\n\t\tconst keys = new Set<string>();\n\t\tfor (const record of records) {\n\t\t\tif (record.key === undefined) continue;\n\t\t\tif (keys.has(record.key)) throw new Error(`${record.label} is already registered`);\n\t\t\tkeys.add(record.key);\n\t\t}\n\t\tfor (const record of batch.added) {\n\t\t\tif (record.key === undefined) {\n\t\t\t\trecord.position = this.#nextPosition++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet position = this.#positions.get(record.key);\n\t\t\tif (position === undefined) {\n\t\t\t\tposition = this.#nextPosition++;\n\t\t\t\tthis.#positions.set(record.key, position);\n\t\t\t}\n\t\t\trecord.position = position;\n\t\t}\n\t\trecords.sort((left, right) => left.position - right.position);\n\t\tthis.#current = new RegistryState(records);\n\t\tfor (const record of batch.added) record.status = \"published\";\n\t\tfor (const record of batch.disposed) record.status = \"disposed\";\n\t\tfor (const listener of [...this.#listeners]) listener();\n\t}\n}\n\n/** Create an application-owned registry holding only the built-ins. */\nexport function createRegistry<Tool extends ToolRegistration = ToolRegistration>(): Registry<Tool> {\n\tconst registry = new RegistryImpl<Tool>();\n\t// Their registrations are dropped, so nothing can dispose them.\n\tfor (const task of BUILTIN_TASKS) registry.tasks.add(task);\n\tregistry.conversations.setup(BUILTIN_SETUP_KEY, builtinSetup);\n\treturn registry;\n}\n\nfunction appendTo<T>(map: Map<string, T[]>, key: string, value: T): void {\n\tconst list = map.get(key);\n\tif (list === undefined) map.set(key, [value]);\n\telse list.push(value);\n}\n\nfunction requireSectionKey(key: string): void {\n\tif (!SECTION_KEY.test(key)) throw new TypeError(`Section key ${JSON.stringify(key)} must match ${SECTION_KEY}`);\n}\n\nfunction rejectThenable(result: unknown): void {\n\tif (\n\t\t(typeof result === \"object\" || typeof result === \"function\") &&\n\t\tresult !== null &&\n\t\ttypeof (result as { then?: unknown }).then === \"function\"\n\t) {\n\t\t(result as PromiseLike<unknown>).then(undefined, () => undefined);\n\t\tthrow new TypeError(\"Registry batch callbacks must be synchronous\");\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/harness/registry.ts"],"names":[],"mappings":"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","sourcesContent":["import { INSTRUCTIONS_KEY } from \"./agent.ts\";\nimport { CompactionTask } from \"./compaction.ts\";\nimport { GenerationTask } from \"./generation.ts\";\nimport { ToolTask } from \"./tool.ts\";\nimport type { AnyTask, Extension, PromptSection, Registry, RegistrySnapshot, ToolRegistration } from \"./types.ts\";\n\nconst SECTION_KEY = /^[a-z][a-z0-9_-]*$/;\n\n/** Built-in task definitions every registry holds; they are not an extension and cannot be removed or replaced. */\nexport const BUILTIN_TASKS: readonly AnyTask[] = [GenerationTask, ToolTask, CompactionTask];\n\n/** Immutable published registry state. */\nclass RegistryState<Tool extends ToolRegistration> implements RegistrySnapshot<Tool> {\n\treadonly #extensions: readonly Extension<Tool>[];\n\treadonly #byName: ReadonlyMap<string, Extension<Tool>>;\n\treadonly #tasks: ReadonlyMap<string, AnyTask>;\n\n\tconstructor(extensions: readonly Extension<Tool>[]) {\n\t\tthis.#extensions = extensions;\n\t\tthis.#byName = new Map(extensions.map((extension) => [extension.name, extension]));\n\t\tconst tasks = new Map<string, AnyTask>();\n\t\tfor (const task of BUILTIN_TASKS) tasks.set(task.definition.name, task);\n\t\tfor (const extension of extensions) {\n\t\t\tfor (const task of extension.tasks ?? []) {\n\t\t\t\tconst name = task.definition.name;\n\t\t\t\tif (tasks.has(name)) throw new Error(`Task ${name} of extension ${extension.name} is already installed`);\n\t\t\t\ttasks.set(name, task);\n\t\t\t}\n\t\t}\n\t\tthis.#tasks = tasks;\n\t}\n\n\tinstalled(): readonly Extension<Tool>[] {\n\t\treturn this.#extensions;\n\t}\n\n\textension(name: string): Extension<Tool> | undefined {\n\t\treturn this.#byName.get(name);\n\t}\n\n\ttools(): readonly { readonly extension: Extension<Tool>; readonly tool: Tool }[] {\n\t\treturn this.#extensions.flatMap((extension) => (extension.tools ?? []).map((tool) => ({ extension, tool })));\n\t}\n\n\tsections(): readonly { readonly extension: Extension<Tool>; readonly section: PromptSection<Tool> }[] {\n\t\treturn this.#extensions.flatMap((extension) =>\n\t\t\t(extension.sections ?? []).map((section) => ({ extension, section })),\n\t\t);\n\t}\n\n\ttasks(): readonly AnyTask[] {\n\t\treturn [...this.#tasks.values()];\n\t}\n\n\ttask(name: string): AnyTask | undefined {\n\t\treturn this.#tasks.get(name);\n\t}\n}\n\nclass RegistryImpl<Tool extends ToolRegistration> implements Registry<Tool> {\n\t#current = new RegistryState<Tool>([]);\n\treadonly #listeners = new Set<() => void>();\n\n\tsnapshot(): RegistrySnapshot<Tool> {\n\t\treturn this.#current;\n\t}\n\n\tsubscribe(listener: () => void): () => void {\n\t\tthis.#listeners.add(listener);\n\t\treturn () => this.#listeners.delete(listener);\n\t}\n\n\tinstall(extension: Extension<Tool>): void {\n\t\tvalidateExtension(extension);\n\t\tconst current = this.#current.installed();\n\t\tconst index = current.findIndex((installed) => installed.name === extension.name);\n\t\tconst next =\n\t\t\tindex < 0 ? [...current, extension] : current.map((installed, at) => (at === index ? extension : installed));\n\t\tthis.#publish(next);\n\t}\n\n\tuninstall(extension: Extension): void {\n\t\tconst current = this.#current.installed();\n\t\tif (!current.some((installed) => installed.name === extension.name)) return;\n\t\tthis.#publish(current.filter((installed) => installed.name !== extension.name));\n\t}\n\n\t/** Build and validate the next state, which throws on a task name collision, then publish it synchronously. */\n\t#publish(extensions: readonly Extension<Tool>[]): void {\n\t\tthis.#current = new RegistryState(extensions);\n\t\tfor (const listener of [...this.#listeners]) listener();\n\t}\n}\n\n/** Unique tool names and section keys within one extension; valid, unreserved section keys. */\nfunction validateExtension(extension: Extension): void {\n\tconst tools = new Set<string>();\n\tfor (const tool of extension.tools ?? []) {\n\t\tif (tools.has(tool.name)) throw new Error(`Extension ${extension.name} has two tools named ${tool.name}`);\n\t\ttools.add(tool.name);\n\t}\n\tconst sections = new Set<string>();\n\tfor (const { key } of extension.sections ?? []) {\n\t\tif (!SECTION_KEY.test(key)) throw new TypeError(`Section key ${JSON.stringify(key)} must match ${SECTION_KEY}`);\n\t\tif (key === INSTRUCTIONS_KEY) throw new Error(`Section key ${key} is reserved for the agent's instructions`);\n\t\tif (sections.has(key)) throw new Error(`Extension ${extension.name} has two sections with key ${key}`);\n\t\tsections.add(key);\n\t}\n}\n\n/** Create an application-owned registry holding only the built-in tasks. */\nexport function createRegistry<Tool extends ToolRegistration = ToolRegistration>(): Registry<Tool> {\n\treturn new RegistryImpl<Tool>();\n}\n"]}
|
|
@@ -4,7 +4,7 @@ import type { ExecutionEnv } from "../env/index.ts";
|
|
|
4
4
|
import type { SessionImpl } from "../session/session.ts";
|
|
5
5
|
import type { Transaction } from "../session/transaction.ts";
|
|
6
6
|
import type { ConversationId, Storage, TaskId, TaskOutcome, TaskRecord } from "../types.ts";
|
|
7
|
-
import type { ConversationHandle, HarnessInspection, RegistryReader, RegistrySnapshot, SettledTask, TaskInspection } from "./types.ts";
|
|
7
|
+
import type { Agent, ConversationHandle, HarnessInspection, RegistryReader, RegistrySnapshot, Settings, SettledTask, TaskInspection } from "./types.ts";
|
|
8
8
|
type AnyTaskRecord = TaskRecord<JsonValue, JsonValue, JsonValue>;
|
|
9
9
|
/** Terminal outcomes the scheduler writes without running task code. */
|
|
10
10
|
export type SchedulerOutcome = Extract<TaskOutcome<JsonValue>, {
|
|
@@ -20,7 +20,12 @@ export type TaskSchedulerOptions = {
|
|
|
20
20
|
readonly storage: Storage;
|
|
21
21
|
readonly registry: RegistryReader;
|
|
22
22
|
readonly models: Models;
|
|
23
|
-
|
|
23
|
+
/** Resolve a conversation's agent against a snapshot; the runtime calls it at most once per phase. */
|
|
24
|
+
readonly agent: (conversationId: ConversationId, snapshot: RegistrySnapshot, context: Context) => Promise<Agent>;
|
|
25
|
+
/** Resolve the settings; read at each access. */
|
|
26
|
+
readonly settings: () => Settings;
|
|
27
|
+
/** Build a conversation's environment with `HarnessOptions.env`. */
|
|
28
|
+
readonly env: (conversationId: ConversationId, context: Context) => Promise<ExecutionEnv | undefined>;
|
|
24
29
|
readonly now: () => number;
|
|
25
30
|
readonly report: (error: unknown) => void;
|
|
26
31
|
/** Harness cleanup staged in the commit that makes an outcome the scheduler wrote itself terminal. */
|