@earendil-works/pi-durable 0.99.1 → 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.
Files changed (203) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +557 -46
  3. package/dist/entries.d.ts +20 -2
  4. package/dist/entries.d.ts.map +1 -1
  5. package/dist/entries.js +14 -1
  6. package/dist/entries.js.map +1 -1
  7. package/dist/env/index.d.ts +18 -38
  8. package/dist/env/index.d.ts.map +1 -1
  9. package/dist/env/index.js +2 -0
  10. package/dist/env/index.js.map +1 -1
  11. package/dist/env/node.d.ts +2 -0
  12. package/dist/env/node.d.ts.map +1 -1
  13. package/dist/env/node.js +53 -58
  14. package/dist/env/node.js.map +1 -1
  15. package/dist/harness/agent.d.ts +31 -0
  16. package/dist/harness/agent.d.ts.map +1 -0
  17. package/dist/harness/agent.js +209 -0
  18. package/dist/harness/agent.js.map +1 -0
  19. package/dist/harness/compaction.d.ts +56 -0
  20. package/dist/harness/compaction.d.ts.map +1 -0
  21. package/dist/harness/compaction.js +382 -0
  22. package/dist/harness/compaction.js.map +1 -0
  23. package/dist/harness/context.d.ts +8 -0
  24. package/dist/harness/context.d.ts.map +1 -1
  25. package/dist/harness/context.js +32 -21
  26. package/dist/harness/context.js.map +1 -1
  27. package/dist/harness/define.d.ts +18 -0
  28. package/dist/harness/define.d.ts.map +1 -0
  29. package/dist/harness/define.js +25 -0
  30. package/dist/harness/define.js.map +1 -0
  31. package/dist/harness/events.d.ts +166 -0
  32. package/dist/harness/events.d.ts.map +1 -0
  33. package/dist/harness/events.js +319 -0
  34. package/dist/harness/events.js.map +1 -0
  35. package/dist/harness/generation.d.ts +36 -7
  36. package/dist/harness/generation.d.ts.map +1 -1
  37. package/dist/harness/generation.js +356 -82
  38. package/dist/harness/generation.js.map +1 -1
  39. package/dist/harness/harness.d.ts.map +1 -1
  40. package/dist/harness/harness.js +141 -106
  41. package/dist/harness/harness.js.map +1 -1
  42. package/dist/harness/inbox.d.ts +59 -0
  43. package/dist/harness/inbox.d.ts.map +1 -0
  44. package/dist/harness/inbox.js +97 -0
  45. package/dist/harness/inbox.js.map +1 -0
  46. package/dist/harness/json.d.ts +10 -0
  47. package/dist/harness/json.d.ts.map +1 -0
  48. package/dist/harness/json.js +33 -0
  49. package/dist/harness/json.js.map +1 -0
  50. package/dist/harness/live.d.ts +66 -7
  51. package/dist/harness/live.d.ts.map +1 -1
  52. package/dist/harness/live.js +71 -7
  53. package/dist/harness/live.js.map +1 -1
  54. package/dist/harness/output.d.ts +62 -0
  55. package/dist/harness/output.d.ts.map +1 -0
  56. package/dist/harness/output.js +261 -0
  57. package/dist/harness/output.js.map +1 -0
  58. package/dist/harness/prompt.d.ts +9 -6
  59. package/dist/harness/prompt.d.ts.map +1 -1
  60. package/dist/harness/prompt.js +57 -14
  61. package/dist/harness/prompt.js.map +1 -1
  62. package/dist/harness/registry.d.ts +2 -3
  63. package/dist/harness/registry.d.ts.map +1 -1
  64. package/dist/harness/registry.js +69 -277
  65. package/dist/harness/registry.js.map +1 -1
  66. package/dist/harness/scheduler.d.ts +42 -12
  67. package/dist/harness/scheduler.d.ts.map +1 -1
  68. package/dist/harness/scheduler.js +649 -75
  69. package/dist/harness/scheduler.js.map +1 -1
  70. package/dist/harness/submissions.d.ts +14 -9
  71. package/dist/harness/submissions.d.ts.map +1 -1
  72. package/dist/harness/submissions.js +76 -34
  73. package/dist/harness/submissions.js.map +1 -1
  74. package/dist/harness/task-graph.d.ts +49 -0
  75. package/dist/harness/task-graph.d.ts.map +1 -0
  76. package/dist/harness/task-graph.js +163 -0
  77. package/dist/harness/task-graph.js.map +1 -0
  78. package/dist/harness/tool.d.ts +36 -0
  79. package/dist/harness/tool.d.ts.map +1 -0
  80. package/dist/harness/tool.js +415 -0
  81. package/dist/harness/tool.js.map +1 -0
  82. package/dist/harness/types.d.ts +330 -125
  83. package/dist/harness/types.d.ts.map +1 -1
  84. package/dist/harness/types.js.map +1 -1
  85. package/dist/harness/usage.d.ts +18 -0
  86. package/dist/harness/usage.d.ts.map +1 -0
  87. package/dist/harness/usage.js +57 -0
  88. package/dist/harness/usage.js.map +1 -0
  89. package/dist/harness/view.d.ts +43 -0
  90. package/dist/harness/view.d.ts.map +1 -0
  91. package/dist/harness/view.js +189 -0
  92. package/dist/harness/view.js.map +1 -0
  93. package/dist/index.d.ts +13 -5
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +8 -2
  96. package/dist/index.js.map +1 -1
  97. package/dist/session/observation.d.ts +18 -11
  98. package/dist/session/observation.d.ts.map +1 -1
  99. package/dist/session/observation.js +24 -13
  100. package/dist/session/observation.js.map +1 -1
  101. package/dist/session/session.d.ts +10 -1
  102. package/dist/session/session.d.ts.map +1 -1
  103. package/dist/session/session.js +23 -5
  104. package/dist/session/session.js.map +1 -1
  105. package/dist/session/transaction.d.ts +12 -3
  106. package/dist/session/transaction.d.ts.map +1 -1
  107. package/dist/session/transaction.js +90 -31
  108. package/dist/session/transaction.js.map +1 -1
  109. package/dist/storage/jsonl/storage.d.ts +22 -2
  110. package/dist/storage/jsonl/storage.d.ts.map +1 -1
  111. package/dist/storage/jsonl/storage.js +1 -1
  112. package/dist/storage/jsonl/storage.js.map +1 -1
  113. package/dist/storage/memory.js +1 -1
  114. package/dist/storage/memory.js.map +1 -1
  115. package/dist/storage/sqlite/database.d.ts +26 -19
  116. package/dist/storage/sqlite/database.d.ts.map +1 -1
  117. package/dist/storage/sqlite/database.js.map +1 -1
  118. package/dist/storage/sqlite/index.d.ts +1 -1
  119. package/dist/storage/sqlite/index.d.ts.map +1 -1
  120. package/dist/storage/sqlite/index.js.map +1 -1
  121. package/dist/storage/sqlite/migrations.js +7 -7
  122. package/dist/storage/sqlite/migrations.js.map +1 -1
  123. package/dist/storage/sqlite/node.d.ts +23 -7
  124. package/dist/storage/sqlite/node.d.ts.map +1 -1
  125. package/dist/storage/sqlite/node.js +129 -47
  126. package/dist/storage/sqlite/node.js.map +1 -1
  127. package/dist/storage/sqlite/storage.d.ts +12 -0
  128. package/dist/storage/sqlite/storage.d.ts.map +1 -1
  129. package/dist/storage/sqlite/storage.js +121 -129
  130. package/dist/storage/sqlite/storage.js.map +1 -1
  131. package/dist/testing/storage-benchmark.d.ts.map +1 -1
  132. package/dist/testing/storage-benchmark.js +0 -1
  133. package/dist/testing/storage-benchmark.js.map +1 -1
  134. package/dist/testing/storage-conformance.d.ts.map +1 -1
  135. package/dist/testing/storage-conformance.js +34 -2
  136. package/dist/testing/storage-conformance.js.map +1 -1
  137. package/dist/tools/bash.d.ts +28 -0
  138. package/dist/tools/bash.d.ts.map +1 -0
  139. package/dist/tools/bash.js +70 -0
  140. package/dist/tools/bash.js.map +1 -0
  141. package/dist/tools/edit-diff.d.ts +89 -0
  142. package/dist/tools/edit-diff.d.ts.map +1 -0
  143. package/dist/tools/edit-diff.js +386 -0
  144. package/dist/tools/edit-diff.js.map +1 -0
  145. package/dist/tools/edit.d.ts +18 -0
  146. package/dist/tools/edit.d.ts.map +1 -0
  147. package/dist/tools/edit.js +117 -0
  148. package/dist/tools/edit.js.map +1 -0
  149. package/dist/tools/env.d.ts +5 -0
  150. package/dist/tools/env.d.ts.map +1 -0
  151. package/dist/tools/env.js +7 -0
  152. package/dist/tools/env.js.map +1 -0
  153. package/dist/tools/file-mutation-queue.d.ts +9 -0
  154. package/dist/tools/file-mutation-queue.d.ts.map +1 -0
  155. package/dist/tools/file-mutation-queue.js +52 -0
  156. package/dist/tools/file-mutation-queue.js.map +1 -0
  157. package/dist/tools/image.d.ts +2 -0
  158. package/dist/tools/image.d.ts.map +1 -0
  159. package/dist/tools/image.js +92 -0
  160. package/dist/tools/image.js.map +1 -0
  161. package/dist/tools/index.d.ts +23 -0
  162. package/dist/tools/index.d.ts.map +1 -0
  163. package/dist/tools/index.js +15 -0
  164. package/dist/tools/index.js.map +1 -0
  165. package/dist/tools/path-utils.d.ts +5 -0
  166. package/dist/tools/path-utils.d.ts.map +1 -0
  167. package/dist/tools/path-utils.js +26 -0
  168. package/dist/tools/path-utils.js.map +1 -0
  169. package/dist/tools/read.d.ts +17 -0
  170. package/dist/tools/read.d.ts.map +1 -0
  171. package/dist/tools/read.js +101 -0
  172. package/dist/tools/read.js.map +1 -0
  173. package/dist/tools/write.d.ts +10 -0
  174. package/dist/tools/write.d.ts.map +1 -0
  175. package/dist/tools/write.js +31 -0
  176. package/dist/tools/write.js.map +1 -0
  177. package/dist/{env/utils/truncate.d.ts → truncate.d.ts} +1 -17
  178. package/dist/truncate.d.ts.map +1 -0
  179. package/dist/truncate.js +146 -0
  180. package/dist/truncate.js.map +1 -0
  181. package/dist/types.d.ts +97 -19
  182. package/dist/types.d.ts.map +1 -1
  183. package/dist/types.js.map +1 -1
  184. package/package.json +32 -14
  185. package/dist/env/utils/adaptive-publisher.d.ts +0 -24
  186. package/dist/env/utils/adaptive-publisher.d.ts.map +0 -1
  187. package/dist/env/utils/adaptive-publisher.js +0 -79
  188. package/dist/env/utils/adaptive-publisher.js.map +0 -1
  189. package/dist/env/utils/output-capture.d.ts +0 -31
  190. package/dist/env/utils/output-capture.d.ts.map +0 -1
  191. package/dist/env/utils/output-capture.js +0 -238
  192. package/dist/env/utils/output-capture.js.map +0 -1
  193. package/dist/env/utils/truncate.d.ts.map +0 -1
  194. package/dist/env/utils/truncate.js +0 -294
  195. package/dist/env/utils/truncate.js.map +0 -1
  196. package/dist/harness/config.d.ts +0 -20
  197. package/dist/harness/config.d.ts.map +0 -1
  198. package/dist/harness/config.js +0 -18
  199. package/dist/harness/config.js.map +0 -1
  200. package/docs/chord-delta-findings.md +0 -358
  201. package/docs/pico-v5-chord-usage.md +0 -373
  202. package/docs/pico-v5-handoff.md +0 -581
  203. package/docs/pico-v5.md +0 -3084
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/harness/registry.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACX,OAAO,EAQP,QAAQ,EAGR,gBAAgB,EAEhB,MAAM,YAAY,CAAC;AAIpB,iGAAiG;AACjG,eAAO,MAAM,aAAa,EAAE,SAAS,OAAO,EAAqB,CAAC;AAElE,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAgUtC,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,IAAI,SAAS,gBAAgB,GAAG,gBAAgB,KAAK,QAAQ,CAAC,IAAI,CAAC,CAMjG"}
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"}
@@ -1,176 +1,53 @@
1
- import { ConversationConfig } from "./config.js";
1
+ import { INSTRUCTIONS_KEY } from "./agent.js";
2
+ import { CompactionTask } from "./compaction.js";
2
3
  import { GenerationTask } from "./generation.js";
3
- import { LiveDoc } from "./live.js";
4
+ import { ToolTask } from "./tool.js";
4
5
  const SECTION_KEY = /^[a-z][a-z0-9_-]*$/;
5
- /** Built-in task definitions every registry starts with; they cannot be disposed or replaced. */
6
- export const BUILTIN_TASKS = [GenerationTask];
7
- export const BUILTIN_SETUP_KEY = "pi";
8
- /** Built-in documents: an empty `pi.live`, and for a new conversation the default configuration with every registered tool active. */
9
- async function builtinSetup(tx, conversation, registry) {
10
- await tx.doc(LiveDoc, conversation.id);
11
- if (conversation.parent !== undefined)
12
- return;
13
- (await tx.doc(ConversationConfig, conversation.id)).activeTools = [...registry.toolNames()];
14
- }
15
- /** Immutable published registry state; wrappers are composed lazily once per state. */
6
+ /** Built-in task definitions every registry holds; they are not an extension and cannot be removed or replaced. */
7
+ export const BUILTIN_TASKS = [GenerationTask, ToolTask, CompactionTask];
8
+ /** Immutable published registry state. */
16
9
  class RegistryState {
17
- records;
18
- #composition;
19
- constructor(records) {
20
- this.records = records;
21
- }
22
- tools() {
23
- return this.#composed().tools;
24
- }
25
- tool(name) {
26
- return this.#composed().toolsByName.get(name);
27
- }
28
- toolNames() {
29
- const names = [];
30
- for (const record of this.records)
31
- if (record.slot.kind === "tool")
32
- names.push(record.slot.tool.name);
33
- return names;
34
- }
35
- task(name) {
36
- for (const record of this.records) {
37
- if (record.slot.kind === "task" && record.slot.task.definition.name === name)
38
- 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
+ }
39
26
  }
40
- return undefined;
27
+ this.#tasks = tasks;
41
28
  }
42
- conversationSetups() {
43
- const setups = [];
44
- for (const record of this.records)
45
- if (record.slot.kind === "setup")
46
- setups.push(record.slot);
47
- return setups;
29
+ installed() {
30
+ return this.#extensions;
48
31
  }
49
- tasks() {
50
- const tasks = [];
51
- for (const record of this.records)
52
- if (record.slot.kind === "task")
53
- tasks.push(record.slot.task);
54
- return tasks;
32
+ extension(name) {
33
+ return this.#byName.get(name);
55
34
  }
56
- hooks(task) {
57
- // Registration was typed by a token with this name; matching by name lets hooks survive a task reload.
58
- const hooks = [];
59
- for (const record of this.records) {
60
- if (record.slot.kind === "hook" && record.slot.taskName === task.definition.name)
61
- hooks.push(record.slot.hook);
62
- }
63
- return hooks;
35
+ tools() {
36
+ return this.#extensions.flatMap((extension) => (extension.tools ?? []).map((tool) => ({ extension, tool })));
64
37
  }
65
38
  sections() {
66
- return this.#composed().sections;
39
+ return this.#extensions.flatMap((extension) => (extension.sections ?? []).map((section) => ({ extension, section })));
67
40
  }
68
- failures() {
69
- return this.#composed().failures;
41
+ tasks() {
42
+ return [...this.#tasks.values()];
70
43
  }
71
- #composed() {
72
- if (this.#composition !== undefined)
73
- return this.#composition;
74
- const failures = [];
75
- const toolWraps = new Map();
76
- const sectionWraps = new Map();
77
- for (const record of this.records) {
78
- const slot = record.slot;
79
- if (slot.kind === "toolWrap")
80
- appendTo(toolWraps, slot.name, slot.wrapper);
81
- if (slot.kind === "sectionWrap")
82
- appendTo(sectionWraps, slot.key, slot.wrapper);
83
- }
84
- const tools = [];
85
- const toolsByName = new Map();
86
- const sections = [];
87
- for (const record of this.records) {
88
- const slot = record.slot;
89
- if (slot.kind === "tool") {
90
- const name = slot.tool.name;
91
- try {
92
- let tool = slot.tool;
93
- for (const wrap of toolWraps.get(name) ?? []) {
94
- tool = wrap(tool);
95
- if (tool.name !== name)
96
- throw new Error(`Tool wrapper renamed ${name} to ${tool.name}`);
97
- }
98
- tools.push(tool);
99
- toolsByName.set(name, tool);
100
- }
101
- catch (error) {
102
- failures.push({ kind: "tool", name, error });
103
- }
104
- }
105
- else if (slot.kind === "section") {
106
- const key = slot.section.key;
107
- try {
108
- let section = slot.section;
109
- for (const wrap of sectionWraps.get(key) ?? []) {
110
- section = wrap(section);
111
- if (section.key !== key)
112
- throw new Error(`Section wrapper renamed ${key} to ${section.key}`);
113
- }
114
- sections.push(section);
115
- }
116
- catch (error) {
117
- failures.push({ kind: "section", name: key, error });
118
- }
119
- }
120
- }
121
- this.#composition = { tools, toolsByName, sections, failures };
122
- return this.#composition;
44
+ task(name) {
45
+ return this.#tasks.get(name);
123
46
  }
124
47
  }
125
48
  class RegistryImpl {
126
49
  #current = new RegistryState([]);
127
- #batch;
128
- /** First position of every key ever published; re-registered keys keep it. */
129
- #positions = new Map();
130
50
  #listeners = new Set();
131
- #nextPosition = 0;
132
- tools;
133
- hooks;
134
- tasks;
135
- conversations;
136
- systemPrompt;
137
- constructor() {
138
- this.tools = {
139
- add: (tool) => this.#register({ kind: "tool", tool }, `tool\0${tool.name}`, `Tool ${tool.name}`),
140
- wrap: (name, key, wrapper) => this.#register({ kind: "toolWrap", name, wrapper }, `toolWrap\0${name}\0${key}`, `Tool wrapper ${key} for ${name}`),
141
- list: () => this.#current.tools(),
142
- };
143
- this.hooks = {
144
- add: (task, handlers, options) => {
145
- const taskName = task.definition.name;
146
- const hook = options?.scope === undefined ? { handlers } : { handlers, scope: options.scope };
147
- const key = options?.key;
148
- return this.#register({ kind: "hook", taskName, hook }, key === undefined ? undefined : `hook\0${taskName}\0${key}`, `Hook ${key} for ${taskName}`);
149
- },
150
- };
151
- this.tasks = {
152
- add: (task) => {
153
- const name = task.definition.name;
154
- return this.#register({ kind: "task", task }, `task\0${name}`, `Task ${name}`);
155
- },
156
- list: () => this.#current.tasks(),
157
- };
158
- this.conversations = {
159
- setup: (key, setup) => this.#register({ kind: "setup", key, setup }, `setup\0${key}`, `Setup ${key}`),
160
- };
161
- this.systemPrompt = {
162
- section: (key, render, options) => {
163
- requireSectionKey(key);
164
- const section = options?.tag === undefined ? { key, render } : { key, render, tag: options.tag };
165
- return this.#register({ kind: "section", section }, `section\0${key}`, `Section ${key}`);
166
- },
167
- wrap: (key, wrapperKey, wrapper) => {
168
- requireSectionKey(key);
169
- return this.#register({ kind: "sectionWrap", key, wrapper }, `sectionWrap\0${key}\0${wrapperKey}`, `Section wrapper ${wrapperKey} for ${key}`);
170
- },
171
- sections: () => this.#current.sections(),
172
- };
173
- }
174
51
  snapshot() {
175
52
  return this.#current;
176
53
  }
@@ -178,132 +55,47 @@ class RegistryImpl {
178
55
  this.#listeners.add(listener);
179
56
  return () => this.#listeners.delete(listener);
180
57
  }
181
- batch(register) {
182
- if (this.#batch !== undefined)
183
- throw new Error("Registry batches cannot be nested");
184
- const batch = { added: [], disposed: new Set() };
185
- this.#batch = batch;
186
- let added;
187
- try {
188
- rejectThenable(register());
189
- added = [...batch.added];
190
- this.#batch = undefined;
191
- this.#publish(batch);
192
- }
193
- catch (error) {
194
- this.#batch = undefined;
195
- for (const record of batch.added)
196
- record.status = "rejected";
197
- throw error;
198
- }
199
- return {
200
- dispose: () => {
201
- if (this.#batch !== undefined) {
202
- for (const record of added)
203
- this.#dispose(record);
204
- return;
205
- }
206
- this.batch(() => {
207
- for (const record of added)
208
- this.#dispose(record);
209
- });
210
- },
211
- };
212
- }
213
- #register(slot, key, label) {
214
- const record = { slot, key, label, position: -1, status: "staged" };
215
- const batch = this.#batch;
216
- if (batch !== undefined) {
217
- batch.added.push(record);
218
- }
219
- else {
220
- try {
221
- this.#publish({ added: [record], disposed: new Set() });
222
- }
223
- catch (error) {
224
- record.status = "rejected";
225
- throw error;
226
- }
227
- }
228
- 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);
229
64
  }
230
- #dispose(record) {
231
- const batch = this.#batch;
232
- if (record.status === "staged") {
233
- const index = batch?.added.indexOf(record) ?? -1;
234
- if (index < 0)
235
- return;
236
- batch.added.splice(index, 1);
237
- record.status = "disposed";
238
- }
239
- else if (record.status === "published") {
240
- if (batch !== undefined)
241
- batch.disposed.add(record);
242
- else
243
- this.#publish({ added: [], disposed: new Set([record]) });
244
- }
245
- }
246
- /** Validate the final staged state, then publish it synchronously. */
247
- #publish(batch) {
248
- 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))
249
68
  return;
250
- const records = [...this.#current.records.filter((record) => !batch.disposed.has(record)), ...batch.added];
251
- const keys = new Set();
252
- for (const record of records) {
253
- if (record.key === undefined)
254
- continue;
255
- if (keys.has(record.key))
256
- throw new Error(`${record.label} is already registered`);
257
- keys.add(record.key);
258
- }
259
- for (const record of batch.added) {
260
- if (record.key === undefined) {
261
- record.position = this.#nextPosition++;
262
- continue;
263
- }
264
- let position = this.#positions.get(record.key);
265
- if (position === undefined) {
266
- position = this.#nextPosition++;
267
- this.#positions.set(record.key, position);
268
- }
269
- record.position = position;
270
- }
271
- records.sort((left, right) => left.position - right.position);
272
- this.#current = new RegistryState(records);
273
- for (const record of batch.added)
274
- record.status = "published";
275
- for (const record of batch.disposed)
276
- 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);
277
74
  for (const listener of [...this.#listeners])
278
75
  listener();
279
76
  }
280
77
  }
281
- /** Create an application-owned registry holding only the built-ins. */
282
- export function createRegistry() {
283
- const registry = new RegistryImpl();
284
- // Their registrations are dropped, so nothing can dispose them.
285
- for (const task of BUILTIN_TASKS)
286
- registry.tasks.add(task);
287
- registry.conversations.setup(BUILTIN_SETUP_KEY, builtinSetup);
288
- return registry;
289
- }
290
- function appendTo(map, key, value) {
291
- const list = map.get(key);
292
- if (list === undefined)
293
- map.set(key, [value]);
294
- else
295
- list.push(value);
296
- }
297
- function requireSectionKey(key) {
298
- if (!SECTION_KEY.test(key))
299
- throw new TypeError(`Section key ${JSON.stringify(key)} must match ${SECTION_KEY}`);
300
- }
301
- function rejectThenable(result) {
302
- if ((typeof result === "object" || typeof result === "function") &&
303
- result !== null &&
304
- typeof result.then === "function") {
305
- result.then(undefined, () => undefined);
306
- 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);
307
95
  }
308
96
  }
97
+ /** Create an application-owned registry holding only the built-in tasks. */
98
+ export function createRegistry() {
99
+ return new RegistryImpl();
100
+ }
309
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 { ConversationConfig } from \"./config.ts\";\nimport { GenerationTask } from \"./generation.ts\";\nimport { LiveDoc } from \"./live.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\";\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];\n\nexport const BUILTIN_SETUP_KEY = \"pi\";\n\n/** Built-in documents: an empty `pi.live`, and for a new conversation the default configuration with every registered tool active. */\nasync function builtinSetup(tx: Tx, conversation: ConversationRecord, registry: RegistrySnapshot): Promise<void> {\n\tawait tx.doc(LiveDoc, 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":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGrC,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAEzC,mHAAmH;AACnH,MAAM,CAAC,MAAM,aAAa,GAAuB,CAAC,cAAc,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;AAE5F,0CAA0C;AAC1C,MAAM,aAAa;IACT,WAAW,CAA6B;IACxC,OAAO,CAAuC;IAC9C,MAAM,CAA+B;IAE9C,YAAY,UAAsC;QACjD,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;QACnF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;QACzC,KAAK,MAAM,IAAI,IAAI,aAAa;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACxE,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACpC,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;gBAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBAClC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,iBAAiB,SAAS,CAAC,IAAI,uBAAuB,CAAC,CAAC;gBACzG,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACvB,CAAC;QACF,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,SAAS;QACR,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAED,SAAS,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK;QACJ,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9G,CAAC;IAED,QAAQ;QACP,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAC7C,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,CACrE,CAAC;IACH,CAAC;IAED,KAAK;QACJ,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,CAAC,IAAY;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;CACD;AAED,MAAM,YAAY;IACjB,QAAQ,GAAG,IAAI,aAAa,CAAO,EAAE,CAAC,CAAC;IAC9B,UAAU,GAAG,IAAI,GAAG,EAAc,CAAC;IAE5C,QAAQ;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;IAED,SAAS,CAAC,QAAoB;QAC7B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,CAAC,SAA0B;QACjC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;QAClF,MAAM,IAAI,GACT,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9G,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED,SAAS,CAAC,SAAoB;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC;YAAE,OAAO;QAC5E,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACjF,CAAC;IAED,+GAA+G;IAC/G,QAAQ,CAAC,UAAsC;QAC9C,IAAI,CAAC,QAAQ,GAAG,IAAI,aAAa,CAAC,UAAU,CAAC,CAAC;QAC9C,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;YAAE,QAAQ,EAAE,CAAC;IACzD,CAAC;CACD;AAED,+FAA+F;AAC/F,SAAS,iBAAiB,CAAC,SAAoB;IAC9C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;QAC1C,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,aAAa,SAAS,CAAC,IAAI,wBAAwB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1G,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,SAAS,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QAChD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,eAAe,WAAW,EAAE,CAAC,CAAC;QAChH,IAAI,GAAG,KAAK,gBAAgB;YAAE,MAAM,IAAI,KAAK,CAAC,eAAe,GAAG,2CAA2C,CAAC,CAAC;QAC7G,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,aAAa,SAAS,CAAC,IAAI,8BAA8B,GAAG,EAAE,CAAC,CAAC;QACvG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;AACF,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,cAAc;IAC7B,OAAO,IAAI,YAAY,EAAQ,CAAC;AACjC,CAAC","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"]}
@@ -1,36 +1,56 @@
1
1
  import { type Context, type JsonValue } from "@earendil-works/chord";
2
2
  import type { Models } from "@earendil-works/pi-ai";
3
+ import type { ExecutionEnv } from "../env/index.ts";
3
4
  import type { SessionImpl } from "../session/session.ts";
4
5
  import type { Transaction } from "../session/transaction.ts";
5
6
  import type { ConversationId, Storage, TaskId, TaskOutcome, TaskRecord } from "../types.ts";
6
- import type { HarnessInspection, RegistryReader, RegistrySnapshot, SettledTask, TaskInspection } from "./types.ts";
7
+ import type { Agent, ConversationHandle, HarnessInspection, RegistryReader, RegistrySnapshot, Settings, SettledTask, TaskInspection } from "./types.ts";
7
8
  type AnyTaskRecord = TaskRecord<JsonValue, JsonValue, JsonValue>;
8
9
  /** Terminal outcomes the scheduler writes without running task code. */
9
10
  export type SchedulerOutcome = Extract<TaskOutcome<JsonValue>, {
10
11
  readonly status: "faulted" | "orphaned";
11
12
  }>;
13
+ /** An invocation a conversation handle is bound to: its signal, and a check that throws once it ended. */
14
+ export type InvocationBinding = {
15
+ readonly signal: AbortSignal;
16
+ check(): void;
17
+ };
12
18
  export type TaskSchedulerOptions = {
13
19
  readonly session: SessionImpl;
14
20
  readonly storage: Storage;
15
21
  readonly registry: RegistryReader;
16
22
  readonly models: Models;
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>;
17
29
  readonly now: () => number;
18
30
  readonly report: (error: unknown) => void;
19
- /** Harness cleanup staged in the same commit as every terminal outcome the scheduler writes itself. */
31
+ /** Harness cleanup staged in the commit that makes an outcome the scheduler wrote itself terminal. */
20
32
  readonly settleOutcome: (tx: Transaction, record: AnyTaskRecord, outcome: SchedulerOutcome) => Promise<void>;
33
+ /** Withdraw a conversation's queued inputs, for conversation abort and abort cascades. */
34
+ readonly withdrawInputs: (tx: Transaction, conversationId: ConversationId) => Promise<void>;
35
+ /** Invocation-bound handle of an existing conversation, for task runtimes and tools. */
36
+ readonly conversation: (id: ConversationId, binding: InvocationBinding, context: Context) => Promise<ConversationHandle | undefined>;
21
37
  /** Context for scheduler commits and invocations; carries no caller cancellation. */
22
38
  readonly context: Context;
23
39
  };
24
40
  /**
25
41
  * Durable task scheduler of one Harness.
26
42
  *
27
- * `#live` mirrors every committed pending/running task record. The synchronous commit listener updates it on the
28
- * Session line, so code running on the line reads exactly the committed state from it.
43
+ * `#live` mirrors every committed non-terminal task record: pending, running, waiting, and completing. The synchronous
44
+ * commit listener updates it on the Session line, so code running on the line reads exactly the committed state from it.
45
+ *
46
+ * Tasks and conversations form one ownership tree (spec §5.5): a task's parent is its owner task, or its conversation;
47
+ * a conversation's parent is its owner task, if any. Walks up that tree decide cascades, idle scopes, and whether a
48
+ * task's ordinary owned work is live, which holds its outcome as `completing` and delays its abort handler.
29
49
  *
30
50
  * Invariant: every task transition is decided and written by one callback serialized on the Session line. That covers
31
- * reservation, marks, runtime commits, and the synchronous step before each phase, which applies the precedence rules
32
- * and writes a fault or handover. Handlers and joins run off the line. An invocation ends inside the step that decides its end,
33
- * so a runtime commit it queued either lands before that decision or is rejected.
51
+ * reservation, marks, runtime commits, finalization, and the synchronous step before each phase, which applies the
52
+ * precedence rules and writes a fault or handover. Handlers and joins run off the line. An invocation ends inside the
53
+ * step that decides its end, so a runtime commit it queued either lands before that decision or is rejected.
34
54
  */
35
55
  export declare class TaskScheduler {
36
56
  #private;
@@ -42,22 +62,32 @@ export declare class TaskScheduler {
42
62
  /** Wait for every invocation signalled by `#seal()`. Writes nothing. */
43
63
  join(): Promise<void>;
44
64
  /**
45
- * Commit the abort mark, or settle a task that no registered definition can take as `orphaned`, then signal and
46
- * join the run invocation seen on the line. The next drain starts the abort invocation.
65
+ * Commit the abort mark, or settle a task that no registered definition can take as `orphaned` when nothing it owns
66
+ * is live, then join the run invocation seen on the line; the commit listener signalled it. The abort invocation
67
+ * starts once the task's ordinary owned work is gone. A `completing` task is only marked.
47
68
  */
48
69
  abort(id: TaskId, context: Context): Promise<"marked" | "terminal">;
49
70
  waitForTask(id: TaskId, context: Context): Promise<SettledTask<JsonValue>>;
50
- /** Resolve when no live non-background task exists, optionally within one conversation. */
71
+ /**
72
+ * Resolve when ordinary traversal from the conversation, or from every ownerless conversation, reaches no live
73
+ * non-background task.
74
+ */
51
75
  waitForIdle(conversationId: ConversationId | undefined, context: Context): Promise<void>;
76
+ /**
77
+ * `Conversation.abort()`: in one commit, withdraw the queued inputs and mark every live non-background task that
78
+ * ordinary traversal from the conversation reaches; resolves once the scope is idle. With `background`, traversal
79
+ * crosses background boundaries, and the wait also covers every task it reached.
80
+ */
81
+ abortConversation(conversationId: ConversationId, background: boolean, context: Context): Promise<void>;
52
82
  /**
53
83
  * Scheduling state and every live task with its derived state, read on the Session line. Runs no task code: a
54
84
  * pending migration shows as `ready` with `migrates`, and only a migration the scheduler already tried, or one that
55
85
  * cannot exist, shows as failed.
56
86
  */
57
- inspect(snapshot: RegistrySnapshot): {
87
+ inspect(snapshot: RegistrySnapshot): Promise<{
58
88
  scheduling: HarnessInspection["scheduling"];
59
89
  tasks: TaskInspection[];
60
- };
90
+ }>;
61
91
  }
62
92
  export {};
63
93
  //# sourceMappingURL=scheduler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/harness/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE/E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAEX,cAAc,EAId,OAAO,EAEP,MAAM,EACN,WAAW,EACX,UAAU,EAGV,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAEX,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,MAAM,YAAY,CAAC;AAGpB,KAAK,aAAa,GAAG,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAqDjE,wEAAwE;AACxE,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CAAA;CAAE,CAAC,CAAC;AAE5G,MAAM,MAAM,oBAAoB,GAAG;IAClC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,uGAAuG;IACvG,QAAQ,CAAC,aAAa,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7G,qFAAqF;IACrF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,qBAAa,aAAa;;IAsBzB,YAAY,OAAO,EAAE,oBAAoB,EASxC;IAED,kGAAkG;IAC5F,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAc1C;IAED,yEAAyE;IACzE,MAAM,IAAI,IAAI,CAGb;IAED,wEAAwE;IAClE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAE1B;IAED;;;OAGG;IACG,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,UAAU,CAAC,CAsBxE;IAEK,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAU/E;IAED,2FAA2F;IAC3F,WAAW,CAAC,cAAc,EAAE,cAAc,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvF;IAsID;;;;OAIG;IACH,OAAO,CAAC,QAAQ,EAAE,gBAAgB,GAAG;QAAE,UAAU,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC;QAAC,KAAK,EAAE,cAAc,EAAE,CAAA;KAAE,CAK5G;CAyRD"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/harness/scheduler.ts"],"names":[],"mappings":"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"}