@earendil-works/pi-durable 0.87.1 → 0.99.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 (168) hide show
  1. package/README.md +46 -4
  2. package/dist/documents.d.ts +66 -0
  3. package/dist/documents.d.ts.map +1 -0
  4. package/dist/documents.js +98 -0
  5. package/dist/documents.js.map +1 -0
  6. package/dist/entries.d.ts +13 -0
  7. package/dist/entries.d.ts.map +1 -0
  8. package/dist/entries.js +18 -0
  9. package/dist/entries.js.map +1 -0
  10. package/dist/env/index.d.ts +131 -0
  11. package/dist/env/index.d.ts.map +1 -0
  12. package/dist/env/index.js +45 -0
  13. package/dist/env/index.js.map +1 -0
  14. package/dist/env/node.d.ts +45 -0
  15. package/dist/env/node.d.ts.map +1 -0
  16. package/dist/env/node.js +908 -0
  17. package/dist/env/node.js.map +1 -0
  18. package/dist/env/utils/adaptive-publisher.d.ts +24 -0
  19. package/dist/env/utils/adaptive-publisher.d.ts.map +1 -0
  20. package/dist/env/utils/adaptive-publisher.js +79 -0
  21. package/dist/env/utils/adaptive-publisher.js.map +1 -0
  22. package/dist/env/utils/output-capture.d.ts +31 -0
  23. package/dist/env/utils/output-capture.d.ts.map +1 -0
  24. package/dist/env/utils/output-capture.js +238 -0
  25. package/dist/env/utils/output-capture.js.map +1 -0
  26. package/dist/env/utils/truncate.d.ts +71 -0
  27. package/dist/env/utils/truncate.d.ts.map +1 -0
  28. package/dist/env/utils/truncate.js +294 -0
  29. package/dist/env/utils/truncate.js.map +1 -0
  30. package/dist/errors.d.ts +15 -0
  31. package/dist/errors.d.ts.map +1 -0
  32. package/dist/errors.js +24 -0
  33. package/dist/errors.js.map +1 -0
  34. package/dist/harness/config.d.ts +20 -0
  35. package/dist/harness/config.d.ts.map +1 -0
  36. package/dist/harness/config.js +18 -0
  37. package/dist/harness/config.js.map +1 -0
  38. package/dist/harness/context.d.ts +27 -0
  39. package/dist/harness/context.d.ts.map +1 -0
  40. package/dist/harness/context.js +109 -0
  41. package/dist/harness/context.js.map +1 -0
  42. package/dist/harness/generation.d.ts +36 -0
  43. package/dist/harness/generation.d.ts.map +1 -0
  44. package/dist/harness/generation.js +266 -0
  45. package/dist/harness/generation.js.map +1 -0
  46. package/dist/harness/harness.d.ts +10 -0
  47. package/dist/harness/harness.d.ts.map +1 -0
  48. package/dist/harness/harness.js +266 -0
  49. package/dist/harness/harness.js.map +1 -0
  50. package/dist/harness/live.d.ts +40 -0
  51. package/dist/harness/live.d.ts.map +1 -0
  52. package/dist/harness/live.js +41 -0
  53. package/dist/harness/live.js.map +1 -0
  54. package/dist/harness/prompt.d.ts +24 -0
  55. package/dist/harness/prompt.d.ts.map +1 -0
  56. package/dist/harness/prompt.js +88 -0
  57. package/dist/harness/prompt.js.map +1 -0
  58. package/dist/harness/registry.d.ts +7 -0
  59. package/dist/harness/registry.d.ts.map +1 -0
  60. package/dist/harness/registry.js +309 -0
  61. package/dist/harness/registry.js.map +1 -0
  62. package/dist/harness/scheduler.d.ts +63 -0
  63. package/dist/harness/scheduler.d.ts.map +1 -0
  64. package/dist/harness/scheduler.js +605 -0
  65. package/dist/harness/scheduler.js.map +1 -0
  66. package/dist/harness/submissions.d.ts +24 -0
  67. package/dist/harness/submissions.d.ts.map +1 -0
  68. package/dist/harness/submissions.js +133 -0
  69. package/dist/harness/submissions.js.map +1 -0
  70. package/dist/harness/types.d.ts +358 -0
  71. package/dist/harness/types.d.ts.map +1 -0
  72. package/dist/harness/types.js +2 -0
  73. package/dist/harness/types.js.map +1 -0
  74. package/dist/harness/util.d.ts +14 -0
  75. package/dist/harness/util.d.ts.map +1 -0
  76. package/dist/harness/util.js +55 -0
  77. package/dist/harness/util.js.map +1 -0
  78. package/dist/ids.d.ts +6 -0
  79. package/dist/ids.d.ts.map +1 -0
  80. package/dist/ids.js +9 -0
  81. package/dist/ids.js.map +1 -0
  82. package/dist/index.d.ts +12 -1
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +10 -0
  85. package/dist/index.js.map +1 -1
  86. package/dist/session/forks.d.ts +10 -0
  87. package/dist/session/forks.d.ts.map +1 -0
  88. package/dist/session/forks.js +42 -0
  89. package/dist/session/forks.js.map +1 -0
  90. package/dist/session/observation.d.ts +28 -0
  91. package/dist/session/observation.d.ts.map +1 -0
  92. package/dist/session/observation.js +280 -0
  93. package/dist/session/observation.js.map +1 -0
  94. package/dist/session/session.d.ts +59 -0
  95. package/dist/session/session.d.ts.map +1 -0
  96. package/dist/session/session.js +380 -0
  97. package/dist/session/session.js.map +1 -0
  98. package/dist/session/transaction.d.ts +105 -0
  99. package/dist/session/transaction.d.ts.map +1 -0
  100. package/dist/session/transaction.js +718 -0
  101. package/dist/session/transaction.js.map +1 -0
  102. package/dist/storage/jsonl/index.d.ts +2 -0
  103. package/dist/storage/jsonl/index.d.ts.map +1 -0
  104. package/dist/storage/jsonl/index.js +2 -0
  105. package/dist/storage/jsonl/index.js.map +1 -0
  106. package/dist/storage/jsonl/node.d.ts +6 -0
  107. package/dist/storage/jsonl/node.d.ts.map +1 -0
  108. package/dist/storage/jsonl/node.js +8 -0
  109. package/dist/storage/jsonl/node.js.map +1 -0
  110. package/dist/storage/jsonl/storage.d.ts +115 -0
  111. package/dist/storage/jsonl/storage.d.ts.map +1 -0
  112. package/dist/storage/jsonl/storage.js +681 -0
  113. package/dist/storage/jsonl/storage.js.map +1 -0
  114. package/dist/storage/memory.d.ts +31 -14
  115. package/dist/storage/memory.d.ts.map +1 -1
  116. package/dist/storage/memory.js +208 -61
  117. package/dist/storage/memory.js.map +1 -1
  118. package/dist/storage/sqlite/database.d.ts +5 -1
  119. package/dist/storage/sqlite/database.d.ts.map +1 -1
  120. package/dist/storage/sqlite/database.js.map +1 -1
  121. package/dist/storage/sqlite/index.d.ts.map +1 -1
  122. package/dist/storage/sqlite/migrations.d.ts +1 -1
  123. package/dist/storage/sqlite/migrations.d.ts.map +1 -1
  124. package/dist/storage/sqlite/migrations.js +8 -1
  125. package/dist/storage/sqlite/migrations.js.map +1 -1
  126. package/dist/storage/sqlite/node.d.ts.map +1 -1
  127. package/dist/storage/sqlite/node.js +2 -2
  128. package/dist/storage/sqlite/node.js.map +1 -1
  129. package/dist/storage/sqlite/storage.d.ts +20 -14
  130. package/dist/storage/sqlite/storage.d.ts.map +1 -1
  131. package/dist/storage/sqlite/storage.js +159 -55
  132. package/dist/storage/sqlite/storage.js.map +1 -1
  133. package/dist/tasks.d.ts +6 -0
  134. package/dist/tasks.d.ts.map +1 -0
  135. package/dist/tasks.js +5 -0
  136. package/dist/tasks.js.map +1 -0
  137. package/dist/testing/assertions.d.ts +5 -0
  138. package/dist/testing/assertions.d.ts.map +1 -0
  139. package/dist/testing/assertions.js +25 -0
  140. package/dist/testing/assertions.js.map +1 -0
  141. package/dist/testing/index.d.ts +6 -0
  142. package/dist/testing/index.d.ts.map +1 -0
  143. package/dist/testing/index.js +5 -0
  144. package/dist/testing/index.js.map +1 -0
  145. package/dist/testing/runner.d.ts +10 -0
  146. package/dist/testing/runner.d.ts.map +1 -0
  147. package/dist/testing/runner.js +14 -0
  148. package/dist/testing/runner.js.map +1 -0
  149. package/dist/testing/storage-benchmark.d.ts +41 -0
  150. package/dist/testing/storage-benchmark.d.ts.map +1 -0
  151. package/dist/testing/storage-benchmark.js +351 -0
  152. package/dist/testing/storage-benchmark.js.map +1 -0
  153. package/dist/testing/storage-conformance.d.ts +4 -0
  154. package/dist/testing/storage-conformance.d.ts.map +1 -0
  155. package/dist/testing/storage-conformance.js +1122 -0
  156. package/dist/testing/storage-conformance.js.map +1 -0
  157. package/dist/testing/types.d.ts +19 -0
  158. package/dist/testing/types.d.ts.map +1 -0
  159. package/dist/testing/types.js +2 -0
  160. package/dist/testing/types.js.map +1 -0
  161. package/dist/types.d.ts +422 -54
  162. package/dist/types.d.ts.map +1 -1
  163. package/dist/types.js.map +1 -1
  164. package/docs/chord-delta-findings.md +1 -1
  165. package/docs/pico-v5-chord-usage.md +47 -60
  166. package/docs/pico-v5-handoff.md +469 -264
  167. package/docs/pico-v5.md +1523 -639
  168. package/package.json +30 -5
@@ -0,0 +1,309 @@
1
+ import { ConversationConfig } from "./config.js";
2
+ import { GenerationTask } from "./generation.js";
3
+ import { LiveDoc } from "./live.js";
4
+ 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. */
16
+ 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;
39
+ }
40
+ return undefined;
41
+ }
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;
48
+ }
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;
55
+ }
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;
64
+ }
65
+ sections() {
66
+ return this.#composed().sections;
67
+ }
68
+ failures() {
69
+ return this.#composed().failures;
70
+ }
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;
123
+ }
124
+ }
125
+ class RegistryImpl {
126
+ #current = new RegistryState([]);
127
+ #batch;
128
+ /** First position of every key ever published; re-registered keys keep it. */
129
+ #positions = new Map();
130
+ #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
+ snapshot() {
175
+ return this.#current;
176
+ }
177
+ subscribe(listener) {
178
+ this.#listeners.add(listener);
179
+ return () => this.#listeners.delete(listener);
180
+ }
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) };
229
+ }
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)
249
+ 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";
277
+ for (const listener of [...this.#listeners])
278
+ listener();
279
+ }
280
+ }
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");
307
+ }
308
+ }
309
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +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"]}
@@ -0,0 +1,63 @@
1
+ import { type Context, type JsonValue } from "@earendil-works/chord";
2
+ import type { Models } from "@earendil-works/pi-ai";
3
+ import type { SessionImpl } from "../session/session.ts";
4
+ import type { Transaction } from "../session/transaction.ts";
5
+ import type { ConversationId, Storage, TaskId, TaskOutcome, TaskRecord } from "../types.ts";
6
+ import type { HarnessInspection, RegistryReader, RegistrySnapshot, SettledTask, TaskInspection } from "./types.ts";
7
+ type AnyTaskRecord = TaskRecord<JsonValue, JsonValue, JsonValue>;
8
+ /** Terminal outcomes the scheduler writes without running task code. */
9
+ export type SchedulerOutcome = Extract<TaskOutcome<JsonValue>, {
10
+ readonly status: "faulted" | "orphaned";
11
+ }>;
12
+ export type TaskSchedulerOptions = {
13
+ readonly session: SessionImpl;
14
+ readonly storage: Storage;
15
+ readonly registry: RegistryReader;
16
+ readonly models: Models;
17
+ readonly now: () => number;
18
+ readonly report: (error: unknown) => void;
19
+ /** Harness cleanup staged in the same commit as every terminal outcome the scheduler writes itself. */
20
+ readonly settleOutcome: (tx: Transaction, record: AnyTaskRecord, outcome: SchedulerOutcome) => Promise<void>;
21
+ /** Context for scheduler commits and invocations; carries no caller cancellation. */
22
+ readonly context: Context;
23
+ };
24
+ /**
25
+ * Durable task scheduler of one Harness.
26
+ *
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.
29
+ *
30
+ * 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.
34
+ */
35
+ export declare class TaskScheduler {
36
+ #private;
37
+ constructor(options: TaskSchedulerOptions);
38
+ /** Load live tasks and change surviving `running` tasks back to `pending`. Dispatches nothing. */
39
+ open(context: Context): Promise<void>;
40
+ /** Enable scheduling. Idempotent; the kick does nothing once closing. */
41
+ resume(): void;
42
+ /** Wait for every invocation signalled by `#seal()`. Writes nothing. */
43
+ join(): Promise<void>;
44
+ /**
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.
47
+ */
48
+ abort(id: TaskId, context: Context): Promise<"marked" | "terminal">;
49
+ waitForTask(id: TaskId, context: Context): Promise<SettledTask<JsonValue>>;
50
+ /** Resolve when no live non-background task exists, optionally within one conversation. */
51
+ waitForIdle(conversationId: ConversationId | undefined, context: Context): Promise<void>;
52
+ /**
53
+ * Scheduling state and every live task with its derived state, read on the Session line. Runs no task code: a
54
+ * pending migration shows as `ready` with `migrates`, and only a migration the scheduler already tried, or one that
55
+ * cannot exist, shows as failed.
56
+ */
57
+ inspect(snapshot: RegistrySnapshot): {
58
+ scheduling: HarnessInspection["scheduling"];
59
+ tasks: TaskInspection[];
60
+ };
61
+ }
62
+ export {};
63
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +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"}