agents 0.25.0 → 0.26.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.
@@ -2,10 +2,10 @@ import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, r as _ass
2
2
  import { t as _classPrivateMethodInitSpec } from "../../classPrivateMethodInitSpec-qMjJ6sHQ.js";
3
3
  import { t as LifecycleCapability } from "../../capability-B4WbF81e.js";
4
4
  import "../../lifecycle-CFu6OV03.js";
5
- import { ConversationConfig, LiveDoc, ROOT_CONVERSATION_ID, watchEvents } from "@earendil-works/pi-durable";
5
+ import { LiveDoc, ROOT_CONVERSATION_ID, watchEvents } from "@earendil-works/pi-durable";
6
6
  import { SQLITE_MIGRATIONS, SqliteStorage } from "@earendil-works/pi-durable/storage/sqlite";
7
7
  import { Type } from "@earendil-works/pi-ai";
8
- //#region src/harnesses/pi/context.ts
8
+ //#region src/harness/pi/context.ts
9
9
  /** chord's `BACKGROUND_CONTEXT`: no values, never cancelled. */
10
10
  const BACKGROUND_CONTEXT = Object.freeze({
11
11
  abortSignal: void 0,
@@ -25,7 +25,7 @@ function withAbortSignal(signal, parent) {
25
25
  });
26
26
  }
27
27
  //#endregion
28
- //#region src/harnesses/pi/session-store.ts
28
+ //#region src/harness/pi/session-store.ts
29
29
  const DEFAULT_PREFIX = "pi_";
30
30
  /** Open pi-durable's storage over this object's SQLite database. */
31
31
  function openPiSessionStore(storage, options = {}) {
@@ -81,64 +81,174 @@ function row(raw) {
81
81
  }
82
82
  return raw;
83
83
  }
84
+ var _tail = /* @__PURE__ */ new WeakMap();
85
+ var _pending = /* @__PURE__ */ new WeakMap();
86
+ var _OperationQueue_brand = /* @__PURE__ */ new WeakSet();
87
+ /**
88
+ * Orders calls on the one SQLite connection. A statement runs at once,
89
+ * directly, when nothing is waiting; while a transaction is open, it and
90
+ * every call after it wait, in call order, for the transaction to settle,
91
+ * so none runs inside it. A failure does not stop the calls behind it.
92
+ *
93
+ * The queue holds calls, not data: a caller has no result until its call
94
+ * runs, so an isolate that dies loses only calls nobody has seen succeed,
95
+ * as it would without the queue. pi's transactions await only their own
96
+ * synchronous statements, so a transaction holds the queue for microtasks,
97
+ * never for I/O.
98
+ */
99
+ var OperationQueue = class {
100
+ constructor() {
101
+ _classPrivateMethodInitSpec(this, _OperationQueue_brand);
102
+ _classPrivateFieldInitSpec(this, _tail, Promise.resolve());
103
+ _classPrivateFieldInitSpec(this, _pending, 0);
104
+ }
105
+ /** A synchronous statement: runs now unless something is ahead of it. */
106
+ run(statement) {
107
+ if (_classPrivateFieldGet2(_pending, this) > 0) return _assertClassBrand(_OperationQueue_brand, this, _enqueue).call(this, statement);
108
+ try {
109
+ return Promise.resolve(statement());
110
+ } catch (error) {
111
+ return Promise.reject(error);
112
+ }
113
+ }
114
+ /** An asynchronous call that holds the queue until it settles. */
115
+ hold(call) {
116
+ return _assertClassBrand(_OperationQueue_brand, this, _enqueue).call(this, call);
117
+ }
118
+ };
119
+ function _enqueue(call) {
120
+ _classPrivateFieldSet2(_pending, this, _classPrivateFieldGet2(_pending, this) + 1);
121
+ const settled = _classPrivateFieldGet2(_tail, this).then(call).finally(() => {
122
+ _classPrivateFieldSet2(_pending, this, _classPrivateFieldGet2(_pending, this) - 1);
123
+ });
124
+ _classPrivateFieldSet2(_tail, this, settled.then(() => void 0, () => void 0));
125
+ return settled;
126
+ }
84
127
  var _sql = /* @__PURE__ */ new WeakMap();
85
- var _query = /* @__PURE__ */ new WeakMap();
86
- var DurableObjectSqliteStatement = class {
87
- constructor(sql, query) {
128
+ var _prefixer = /* @__PURE__ */ new WeakMap();
129
+ /** One statement on a Durable Object's synchronous SQL API. */
130
+ var Statements = class {
131
+ constructor(sql, prefixer) {
88
132
  _classPrivateFieldInitSpec(this, _sql, void 0);
89
- _classPrivateFieldInitSpec(this, _query, void 0);
133
+ _classPrivateFieldInitSpec(this, _prefixer, void 0);
90
134
  _classPrivateFieldSet2(_sql, this, sql);
91
- _classPrivateFieldSet2(_query, this, query);
135
+ _classPrivateFieldSet2(_prefixer, this, prefixer);
92
136
  }
93
- run(...params) {
94
- _classPrivateFieldGet2(_sql, this).exec(_classPrivateFieldGet2(_query, this), ...params.map(binding));
137
+ exec(sql) {
138
+ _classPrivateFieldGet2(_sql, this).exec(_classPrivateFieldGet2(_prefixer, this).rewrite(sql));
139
+ }
140
+ run(sql, params) {
141
+ _classPrivateFieldGet2(_sql, this).exec(_classPrivateFieldGet2(_prefixer, this).rewrite(sql), ...params.map(binding));
95
142
  }
96
- get(...params) {
97
- const first = _classPrivateFieldGet2(_sql, this).exec(_classPrivateFieldGet2(_query, this), ...params.map(binding)).next();
143
+ get(sql, params) {
144
+ const first = _classPrivateFieldGet2(_sql, this).exec(_classPrivateFieldGet2(_prefixer, this).rewrite(sql), ...params.map(binding)).next();
98
145
  return first.done ? void 0 : row(first.value);
99
146
  }
100
- all(...params) {
101
- return _classPrivateFieldGet2(_sql, this).exec(_classPrivateFieldGet2(_query, this), ...params.map(binding)).toArray().map((raw) => row(raw));
147
+ all(sql, params) {
148
+ return _classPrivateFieldGet2(_sql, this).exec(_classPrivateFieldGet2(_prefixer, this).rewrite(sql), ...params.map(binding)).toArray().map((raw) => row(raw));
102
149
  }
103
150
  };
151
+ var _statements = /* @__PURE__ */ new WeakMap();
152
+ var _active = /* @__PURE__ */ new WeakMap();
153
+ var _DurableObjectSqliteTransaction_brand = /* @__PURE__ */ new WeakSet();
154
+ /**
155
+ * The handle pi's transaction callback gets. It runs statements directly:
156
+ * the transaction holds the database's queue for as long as it is open.
157
+ */
158
+ var DurableObjectSqliteTransaction = class {
159
+ constructor(statements) {
160
+ _classPrivateMethodInitSpec(this, _DurableObjectSqliteTransaction_brand);
161
+ _classPrivateFieldInitSpec(this, _statements, void 0);
162
+ _classPrivateFieldInitSpec(this, _active, true);
163
+ _classPrivateFieldSet2(_statements, this, statements);
164
+ }
165
+ /** Called once the transaction settles; the handle is unusable after. */
166
+ end() {
167
+ _classPrivateFieldSet2(_active, this, false);
168
+ }
169
+ async exec(sql) {
170
+ _assertClassBrand(_DurableObjectSqliteTransaction_brand, this, _assertActive).call(this);
171
+ _classPrivateFieldGet2(_statements, this).exec(sql);
172
+ }
173
+ async run(sql, ...params) {
174
+ _assertClassBrand(_DurableObjectSqliteTransaction_brand, this, _assertActive).call(this);
175
+ _classPrivateFieldGet2(_statements, this).run(sql, params);
176
+ }
177
+ async get(sql, ...params) {
178
+ _assertClassBrand(_DurableObjectSqliteTransaction_brand, this, _assertActive).call(this);
179
+ return _classPrivateFieldGet2(_statements, this).get(sql, params);
180
+ }
181
+ async all(sql, ...params) {
182
+ _assertClassBrand(_DurableObjectSqliteTransaction_brand, this, _assertActive).call(this);
183
+ return _classPrivateFieldGet2(_statements, this).all(sql, params);
184
+ }
185
+ };
186
+ function _assertActive() {
187
+ if (!_classPrivateFieldGet2(_active, this)) throw new Error("The pi SQLite transaction is no longer active");
188
+ }
104
189
  var _storage = /* @__PURE__ */ new WeakMap();
105
- var _prefixer = /* @__PURE__ */ new WeakMap();
190
+ var _statements2 = /* @__PURE__ */ new WeakMap();
191
+ var _queue = /* @__PURE__ */ new WeakMap();
106
192
  /**
107
193
  * pi's `SqliteDatabase` facade over `DurableObjectStorage`.
108
194
  *
109
- * Durable Objects reject `BEGIN`, so transactions go through
110
- * `transactionSync`, which rolls back when the callback throws and rethrows
111
- * the same error, as pi's contract requires. Durable Objects have no
112
- * prepared statements either; a statement is the query text, executed on
113
- * each call.
195
+ * Durable Object SQL is synchronous, but pi's facade is asynchronous and a
196
+ * transaction's callback awaits between statements. A statement issued
197
+ * outside the transaction while it waits would run inside it: it would see
198
+ * uncommitted rows, and roll back with it. pi's contract therefore has the
199
+ * adapter queue every other call until the transaction settles: every
200
+ * call goes through one `OperationQueue`, which runs a statement at once
201
+ * when no transaction is open. As the contract says, a call on the database from inside a
202
+ * transaction's callback waits for that transaction and never settles; the
203
+ * callback must use its handle.
204
+ *
205
+ * Transactions run in `storage.transaction()`, which rolls back when the
206
+ * callback rejects and rejects with the same error.
114
207
  */
115
208
  var DurableObjectSqliteDatabase = class {
116
209
  constructor(storage, options = {}) {
117
210
  _classPrivateFieldInitSpec(this, _storage, void 0);
118
- _classPrivateFieldInitSpec(this, _prefixer, void 0);
211
+ _classPrivateFieldInitSpec(this, _statements2, void 0);
212
+ _classPrivateFieldInitSpec(this, _queue, new OperationQueue());
119
213
  _classPrivateFieldSet2(_storage, this, storage);
120
- _classPrivateFieldSet2(_prefixer, this, new Prefixer(options.prefix ?? DEFAULT_PREFIX));
214
+ _classPrivateFieldSet2(_statements2, this, new Statements(storage.sql, new Prefixer(options.prefix ?? DEFAULT_PREFIX)));
121
215
  }
122
216
  exec(sql) {
123
- _classPrivateFieldGet2(_storage, this).sql.exec(_classPrivateFieldGet2(_prefixer, this).rewrite(sql));
217
+ return _classPrivateFieldGet2(_queue, this).run(() => _classPrivateFieldGet2(_statements2, this).exec(sql));
218
+ }
219
+ run(sql, ...params) {
220
+ return _classPrivateFieldGet2(_queue, this).run(() => _classPrivateFieldGet2(_statements2, this).run(sql, params));
221
+ }
222
+ get(sql, ...params) {
223
+ return _classPrivateFieldGet2(_queue, this).run(() => _classPrivateFieldGet2(_statements2, this).get(sql, params));
124
224
  }
125
- prepare(sql) {
126
- return new DurableObjectSqliteStatement(_classPrivateFieldGet2(_storage, this).sql, _classPrivateFieldGet2(_prefixer, this).rewrite(sql));
225
+ all(sql, ...params) {
226
+ return _classPrivateFieldGet2(_queue, this).run(() => _classPrivateFieldGet2(_statements2, this).all(sql, params));
127
227
  }
128
228
  transaction(callback) {
129
- return _classPrivateFieldGet2(_storage, this).transactionSync(callback);
229
+ return _classPrivateFieldGet2(_queue, this).hold(() => _classPrivateFieldGet2(_storage, this).transaction(async () => {
230
+ const transaction = new DurableObjectSqliteTransaction(_classPrivateFieldGet2(_statements2, this));
231
+ try {
232
+ return await callback(transaction);
233
+ } finally {
234
+ transaction.end();
235
+ }
236
+ }));
130
237
  }
131
238
  /** The object owns the database; there is nothing to close. */
132
- close() {}
239
+ close() {
240
+ return _classPrivateFieldGet2(_queue, this).run(() => void 0);
241
+ }
133
242
  };
134
243
  //#endregion
135
- //#region src/harnesses/pi/harness.ts
244
+ //#region src/harness/pi/harness.ts
136
245
  const BG = BACKGROUND_CONTEXT;
137
246
  /** The root session's id. */
138
247
  const ROOT_SESSION = String(ROOT_CONVERSATION_ID);
139
248
  /**
140
- * Defaults for the three wake timings; a host overrides them with
141
- * `timing`, which is what the tests do to avoid the real heartbeat.
249
+ * The three wake timings. They suit a real deployment; only tests change
250
+ * them, with `setWakeTimingForTests`, so a suite does not sit on the real
251
+ * heartbeat.
142
252
  *
143
253
  * A pi long wait further away than this is handed to the alarm, so the
144
254
  * alarm, not pi's in-memory timer, is what wakes the object.
@@ -163,6 +273,13 @@ function wakeJobId(session) {
163
273
  function sessionOfJob(payload) {
164
274
  return typeof payload === "object" && payload !== null && "session" in payload && typeof payload.session === "string" ? payload.session : void 0;
165
275
  }
276
+ /** pi-durable's stored reference to a pi-ai model. */
277
+ function modelRef(model) {
278
+ return {
279
+ provider: model.provider,
280
+ modelId: model.id
281
+ };
282
+ }
166
283
  function conversationId(session) {
167
284
  const id = Number(session);
168
285
  if (!Number.isSafeInteger(id) || id < 1) throw new Error(`Invalid pi session ${JSON.stringify(session)}`);
@@ -204,7 +321,7 @@ var _PiHarness_brand = /* @__PURE__ */ new WeakSet();
204
321
  * restarts the object, pi reopens and resumes its own tasks, and the job
205
322
  * waits again.
206
323
  *
207
- * @experimental The API may change between releases.
324
+ * @beta The API may change between releases.
208
325
  */
209
326
  var PiHarness = class extends LifecycleCapability {
210
327
  constructor(options) {
@@ -213,19 +330,11 @@ var PiHarness = class extends LifecycleCapability {
213
330
  _classPrivateFieldInitSpec(this, _options, void 0);
214
331
  _classPrivateFieldInitSpec(this, _waits, /* @__PURE__ */ new Map());
215
332
  _classPrivateFieldInitSpec(this, _admitting, /* @__PURE__ */ new Map());
216
- _classPrivateFieldInitSpec(this, _sleepThresholdMs, void 0);
217
- _classPrivateFieldInitSpec(this, _waitBudgetMs, void 0);
218
- _classPrivateFieldInitSpec(this, _heartbeatMs, void 0);
333
+ _classPrivateFieldInitSpec(this, _sleepThresholdMs, SLEEP_THRESHOLD_MS);
334
+ _classPrivateFieldInitSpec(this, _waitBudgetMs, WAIT_BUDGET_MS);
335
+ _classPrivateFieldInitSpec(this, _heartbeatMs, HEARTBEAT_MS);
219
336
  _classPrivateFieldInitSpec(this, _opening, void 0);
220
337
  _classPrivateFieldSet2(_options, this, options);
221
- _classPrivateFieldSet2(_sleepThresholdMs, this, options.timing?.sleepThresholdMs ?? SLEEP_THRESHOLD_MS);
222
- _classPrivateFieldSet2(_waitBudgetMs, this, options.timing?.waitBudgetMs ?? WAIT_BUDGET_MS);
223
- _classPrivateFieldSet2(_heartbeatMs, this, options.timing?.heartbeatMs ?? HEARTBEAT_MS);
224
- for (const [name, value] of [
225
- ["sleepThresholdMs", _classPrivateFieldGet2(_sleepThresholdMs, this)],
226
- ["waitBudgetMs", _classPrivateFieldGet2(_waitBudgetMs, this)],
227
- ["heartbeatMs", _classPrivateFieldGet2(_heartbeatMs, this)]
228
- ]) if (!Number.isFinite(value) || value <= 0) throw new Error(`PiHarness timing.${name} must be a positive number`);
229
338
  this.sessions = new PiSessions(this);
230
339
  }
231
340
  async onStart(_context) {
@@ -293,10 +402,6 @@ var PiHarness = class extends LifecycleCapability {
293
402
  async storage() {
294
403
  return (await _assertClassBrand(_PiHarness_brand, this, _open).call(this)).storage;
295
404
  }
296
- /** @internal Configure a new session like the root. */
297
- initSession(tx, id) {
298
- return _assertClassBrand(_PiHarness_brand, this, _init).call(this, tx, id);
299
- }
300
405
  /** @internal */
301
406
  async enqueue(session, input, options) {
302
407
  const operationId = options.operationId ?? crypto.randomUUID();
@@ -348,6 +453,14 @@ var PiHarness = class extends LifecycleCapability {
348
453
  };
349
454
  return _assertClassBrand(_PiHarness_brand, this, _result).call(this, session, operationId, await submission.wait(context), context);
350
455
  }
456
+ /** @internal The per-conversation defaults supported by pi-durable. */
457
+ agentDefaults() {
458
+ const defaults = _classPrivateFieldGet2(_options, this).defaults;
459
+ return {
460
+ ...defaults?.model === void 0 ? {} : { model: modelRef(defaults.model) },
461
+ ...defaults?.thinkingLevel === void 0 ? {} : { thinkingLevel: defaults.thinkingLevel }
462
+ };
463
+ }
351
464
  };
352
465
  /** Schedule the session's wake job now, or pull it forward. */
353
466
  function _wake(session, time = Date.now()) {
@@ -398,7 +511,15 @@ async function _waitForIdle(conversation) {
398
511
  clearTimeout(timer);
399
512
  }
400
513
  }
401
- function _open() {
514
+ /**
515
+ * pi, opened. Waits for Lifecycle startup first, so pi is only ever
516
+ * opened inside it: startup holds the input gate (`blockConcurrencyWhile`)
517
+ * and awaits the open in `onStart`, so an open begun before startup would
518
+ * be awaited behind a closed gate, with its timers and I/O held back, and
519
+ * never finish.
520
+ */
521
+ async function _open() {
522
+ await this.lifecycle.ready();
402
523
  _classPrivateFieldGet2(_opening, this) ?? _classPrivateFieldSet2(_opening, this, _assertClassBrand(_PiHarness_brand, this, _doOpen).call(this).catch((error) => {
403
524
  _classPrivateFieldSet2(_opening, this, void 0);
404
525
  throw error;
@@ -406,25 +527,18 @@ function _open() {
406
527
  return _classPrivateFieldGet2(_opening, this);
407
528
  }
408
529
  async function _doOpen() {
409
- const storage = await openPiSessionStore(this.lifecycle.storage, _classPrivateFieldGet2(_options, this).store);
530
+ const storage = await openPiSessionStore(this.lifecycle.storage);
410
531
  const pi = await _classPrivateFieldGet2(_options, this).harness({
411
532
  storage,
412
533
  context: BG
413
534
  });
414
- await pi.root(BG, { init: (tx, id) => _assertClassBrand(_PiHarness_brand, this, _init).call(this, tx, id) });
535
+ await pi.root(BG, { agent: this.agentDefaults() });
415
536
  pi.resume();
416
537
  return {
417
538
  pi,
418
539
  storage
419
540
  };
420
541
  }
421
- async function _init(tx, id) {
422
- const config = await tx.doc(ConversationConfig, id);
423
- const defaults = _classPrivateFieldGet2(_options, this).defaults;
424
- if (defaults?.model) config.model = { ...defaults.model };
425
- if (defaults?.thinkingLevel) config.thinkingLevel = defaults.thinkingLevel;
426
- if (defaults?.retry) config.retry = { ...defaults.retry };
427
- }
428
542
  async function _findSubmission(id, operationId, context) {
429
543
  const { pi, storage } = await _assertClassBrand(_PiHarness_brand, this, _open).call(this);
430
544
  const record = await storage.submissionByRequest(id, operationId, context);
@@ -503,8 +617,12 @@ var PiSession = class {
503
617
  async reset(handoff) {
504
618
  await (await _classPrivateFieldGet2(_harness, this).conversation(this.id)).reset(handoff, BG);
505
619
  }
620
+ /**
621
+ * Change this session's model, by its `provider` and `id`; it must be on
622
+ * the `Models` the factory opened pi with (see `PiModel`).
623
+ */
506
624
  async setModel(model) {
507
- await (await _classPrivateFieldGet2(_harness, this).conversation(this.id)).setModel(model, BG);
625
+ await (await _classPrivateFieldGet2(_harness, this).conversation(this.id)).configure({ model: modelRef(model) }, BG);
508
626
  }
509
627
  /** The active transcript, as pi's entries since the newest reset. */
510
628
  async messages() {
@@ -532,7 +650,7 @@ var PiSessions = class {
532
650
  async create() {
533
651
  const conversation = await (await _classPrivateFieldGet2(_harness2, this).pi()).createConversation({
534
652
  ownership: { kind: "ownerless" },
535
- init: (tx, id) => _classPrivateFieldGet2(_harness2, this).initSession(tx, id)
653
+ agent: _classPrivateFieldGet2(_harness2, this).agentDefaults()
536
654
  }, BG);
537
655
  return _classPrivateFieldGet2(_harness2, this).session(String(conversation.id));
538
656
  }
@@ -569,7 +687,7 @@ var PiSessions = class {
569
687
  }
570
688
  };
571
689
  //#endregion
572
- //#region src/harnesses/pi/skills.ts
690
+ //#region src/harness/pi/skills.ts
573
691
  function skillsFingerprint(sources) {
574
692
  return sources.map((source) => `${source.id}:${source.fingerprint}`).join("|");
575
693
  }
@@ -579,10 +697,6 @@ function textResult(text) {
579
697
  text
580
698
  }] };
581
699
  }
582
- /** pi validates arguments against the schema before `execute` runs. */
583
- function argsOf(args) {
584
- return args;
585
- }
586
700
  function attributes(pairs) {
587
701
  return pairs.filter((pair) => pair[1] !== void 0).map(([key, value]) => ` ${key}="${value.replace(/"/g, "&quot;")}"`).join("");
588
702
  }
@@ -668,8 +782,7 @@ async function resolveSkillSources(sources) {
668
782
  description: "Activate a skill by name. Use this when the user's task matches one of the available skills; the response contains the skill's full instructions.",
669
783
  parameters: Type.Object({ name: nameSchema }),
670
784
  replay: "safe",
671
- async execute(args) {
672
- const input = argsOf(args);
785
+ async execute(input) {
673
786
  const skill = byName.get(input.name);
674
787
  return textResult(skill ? renderSkillContent(skill) : `Skill not found: ${input.name}`);
675
788
  }
@@ -682,8 +795,7 @@ async function resolveSkillSources(sources) {
682
795
  path: Type.String({ minLength: 1 })
683
796
  }),
684
797
  replay: "safe",
685
- async execute(args) {
686
- const input = argsOf(args);
798
+ async execute(input) {
687
799
  const target = resolveResourceTarget(byName, input.name, input.path);
688
800
  if (!target) return textResult(`Skill resource not found: ${input.name ? `${input.name}/` : ""}${input.path}`);
689
801
  const resource = await target.skill.source.readResource?.(target.skill.descriptor.name, target.path).catch(() => null);
@@ -734,21 +846,28 @@ function hasResource(skill, path) {
734
846
  return (skill.content.resources ?? []).some((resource) => resource.path === path);
735
847
  }
736
848
  /**
737
- * Register `agents/skills` sources on a pi registry: the activation tools
738
- * and a "skills" system prompt section. Resolution reads the sources, so a
739
- * host awaits this in its `harness` factory, before `Harness.open`.
849
+ * `agents/skills` sources as a pi extension, named `agents.skills`: the
850
+ * activation tools and a `skills` system prompt section. Install it on
851
+ * pi's registry in the harness factory.
852
+ *
853
+ * ```ts
854
+ * registry.install(await skills(sources));
855
+ * ```
740
856
  */
741
- async function addSkills(registry, sources) {
857
+ async function skills(sources) {
742
858
  const resolved = await resolveSkillSources(sources);
743
859
  for (const warning of resolved.warnings) console.warn(`pi skills: ${warning}`);
744
860
  const catalog = resolved.catalog;
745
- registry.batch(() => {
746
- for (const tool of resolved.tools) registry.tools.add(tool);
747
- if (catalog) registry.systemPrompt.section("skills", () => catalog);
748
- });
749
- return resolved;
861
+ return {
862
+ name: "agents.skills",
863
+ tools: resolved.tools,
864
+ sections: catalog === null ? [] : [{
865
+ key: "skills",
866
+ render: () => catalog
867
+ }]
868
+ };
750
869
  }
751
870
  //#endregion
752
- export { PiHarness, PiSession, PiSessions, ROOT_SESSION, addSkills, openPiSessionStore };
871
+ export { PiHarness, PiSession, PiSessions, ROOT_SESSION, openPiSessionStore, skills };
753
872
 
754
873
  //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/harness/pi/context.ts","../../../src/harness/pi/session-store.ts","../../../src/harness/pi/harness.ts","../../../src/harness/pi/skills.ts"],"sourcesContent":["import type { Harness } from \"@earendil-works/pi-durable\";\n\n/**\n * pi's invocation context, as `@earendil-works/chord` defines it.\n *\n * pi-durable takes a chord `Context` on every call but does not re-export\n * the type or its constructors. The harness needs only a background context\n * and a way to add an abort signal, so both are inlined here instead of\n * depending on chord directly. A chord `Context` is a plain structural\n * interface (an abort signal, keyed values, and a name), so these interoperate\n * with chord's own contexts inside pi.\n *\n * One limit: chord's own derived contexts read the abort signal through a\n * private key rather than `abortSignal`, so a chord `withContextValue`\n * wrapped around one of these would not see its signal. pi-durable does not\n * use `withContextValue` to wrap a caller's context that way; `withAbortSignal`\n * and `withCancel` read `abortSignal` and work.\n *\n * If pi-durable starts re-exporting chord's context helpers, replace this\n * file with those.\n */\nexport type Context = Parameters<Harness[\"close\"]>[0];\n\n/** chord's `BACKGROUND_CONTEXT`: no values, never cancelled. */\nexport const BACKGROUND_CONTEXT: Context = Object.freeze({\n abortSignal: undefined,\n value: () => undefined,\n toString: () => \"[Context pi-harness background]\"\n});\n\n/**\n * chord's `withAbortSignal`: a context cancelled by either the parent's\n * signal or `signal`, carrying the parent's values.\n */\nexport function withAbortSignal(signal: AbortSignal, parent: Context): Context {\n const abortSignal =\n parent.abortSignal === undefined\n ? signal\n : AbortSignal.any([parent.abortSignal, signal]);\n return Object.freeze({\n abortSignal,\n value: parent.value.bind(parent),\n toString: () => `${parent}.WithAbortSignal`\n });\n}\n","import {\n SQLITE_MIGRATIONS,\n SqliteStorage,\n type SqliteDatabase,\n type SqliteExecutor,\n type SqliteValue\n} from \"@earendil-works/pi-durable/storage/sqlite\";\n\n/**\n * pi's session store on a Durable Object's SQLite database.\n *\n * pi owns its sessions: conversations, entries, tasks, submissions, and\n * documents live in pi's own schema, created and migrated by pi's portable\n * `SqliteStorage`. This file only supplies the asynchronous database facade\n * pi asks for, over `ctx.storage.sql`, and moves pi's tables under a prefix\n * so they cannot collide with the SDK's or the host's tables in the same\n * object.\n *\n * It is the Durable Object counterpart of `agents/sessions` for a harness\n * that brings its own session model, and has nothing pi-harness specific in\n * it: any harness built on pi-durable can open its storage with it.\n */\nexport type PiSessionStoreOptions = {\n /**\n * Prefix for every table and index pi creates. Must not start with `_cf_`,\n * which Durable Objects reserve. Default `pi_`.\n */\n readonly prefix?: string;\n};\n\nconst DEFAULT_PREFIX = \"pi_\";\n\n/** Open pi-durable's storage over this object's SQLite database. */\nexport function openPiSessionStore(\n storage: DurableObjectStorage,\n options: PiSessionStoreOptions = {}\n): Promise<SqliteStorage> {\n return SqliteStorage.open(new DurableObjectSqliteDatabase(storage, options));\n}\n\n/** Names pi's migrations create: every table and index, in any version. */\nfunction schemaNames(): readonly string[] {\n const names = new Set<string>([\"durable_schema\"]);\n const pattern =\n /\\bCREATE\\s+(?:UNIQUE\\s+)?(?:TABLE|INDEX)\\s+(?:IF\\s+NOT\\s+EXISTS\\s+)?([A-Za-z_][A-Za-z0-9_]*)/gi;\n for (const migration of SQLITE_MIGRATIONS) {\n for (const statement of migration.statements) {\n for (const match of statement.matchAll(pattern)) names.add(match[1]);\n }\n }\n return [...names];\n}\n\n/**\n * Rewrites pi's schema identifiers outside string literals. Identifiers are\n * matched on word boundaries, so column names such as `record_type` or\n * `document_id` are left alone.\n */\nclass Prefixer {\n readonly #pattern: RegExp;\n readonly #prefix: string;\n readonly #cache = new Map<string, string>();\n\n constructor(prefix: string) {\n if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(prefix)) {\n throw new Error(\n `Invalid pi session store prefix ${JSON.stringify(prefix)}`\n );\n }\n if (prefix.startsWith(\"_cf_\")) {\n throw new Error(\"The pi session store prefix must not start with _cf_\");\n }\n this.#prefix = prefix;\n this.#pattern = new RegExp(`\\\\b(${schemaNames().join(\"|\")})\\\\b`, \"g\");\n }\n\n rewrite(sql: string): string {\n const cached = this.#cache.get(sql);\n if (cached !== undefined) return cached;\n // Split on single-quoted literals ('' escapes stay inside a literal).\n const rewritten = sql\n .split(/('(?:[^']|'')*')/)\n .map((part, index) =>\n index % 2 === 1\n ? part\n : part.replace(this.#pattern, (name) => `${this.#prefix}${name}`)\n )\n .join(\"\");\n this.#cache.set(sql, rewritten);\n return rewritten;\n }\n}\n\n/** Durable Objects bind strings, numbers, null, and ArrayBuffers. */\nfunction binding(value: SqliteValue): SqlStorageValue {\n if (typeof value === \"bigint\") {\n if (\n value > BigInt(Number.MAX_SAFE_INTEGER) ||\n value < BigInt(Number.MIN_SAFE_INTEGER)\n ) {\n throw new RangeError(`SQLite integer ${value} is outside the safe range`);\n }\n return Number(value);\n }\n if (value instanceof Uint8Array) {\n return value.buffer.slice(\n value.byteOffset,\n value.byteOffset + value.byteLength\n ) as ArrayBuffer;\n }\n return value;\n}\n\n/** Blobs come back as ArrayBuffers; pi's contract reads Uint8Arrays. */\nfunction row<T extends object>(raw: Record<string, SqlStorageValue>): T {\n for (const key of Object.keys(raw)) {\n const value = raw[key];\n if (value instanceof ArrayBuffer) {\n (raw as Record<string, unknown>)[key] = new Uint8Array(value);\n }\n }\n return raw as T;\n}\n\n/**\n * Orders calls on the one SQLite connection. A statement runs at once,\n * directly, when nothing is waiting; while a transaction is open, it and\n * every call after it wait, in call order, for the transaction to settle,\n * so none runs inside it. A failure does not stop the calls behind it.\n *\n * The queue holds calls, not data: a caller has no result until its call\n * runs, so an isolate that dies loses only calls nobody has seen succeed,\n * as it would without the queue. pi's transactions await only their own\n * synchronous statements, so a transaction holds the queue for microtasks,\n * never for I/O.\n */\nclass OperationQueue {\n #tail: Promise<void> = Promise.resolve();\n /** Calls queued or holding the queue, not yet settled. */\n #pending = 0;\n\n /** A synchronous statement: runs now unless something is ahead of it. */\n run<T>(statement: () => T): Promise<T> {\n if (this.#pending > 0) return this.#enqueue(statement);\n try {\n return Promise.resolve(statement());\n } catch (error) {\n return Promise.reject(error);\n }\n }\n\n /** An asynchronous call that holds the queue until it settles. */\n hold<T>(call: () => Promise<T>): Promise<T> {\n return this.#enqueue(call);\n }\n\n #enqueue<T>(call: () => T | Promise<T>): Promise<T> {\n this.#pending += 1;\n const settled = this.#tail.then(call).finally(() => {\n this.#pending -= 1;\n });\n this.#tail = settled.then(\n () => undefined,\n () => undefined\n );\n return settled;\n }\n}\n\n/** One statement on a Durable Object's synchronous SQL API. */\nclass Statements {\n readonly #sql: SqlStorage;\n readonly #prefixer: Prefixer;\n\n constructor(sql: SqlStorage, prefixer: Prefixer) {\n this.#sql = sql;\n this.#prefixer = prefixer;\n }\n\n exec(sql: string): void {\n this.#sql.exec(this.#prefixer.rewrite(sql));\n }\n\n run(sql: string, params: readonly SqliteValue[]): void {\n this.#sql.exec(this.#prefixer.rewrite(sql), ...params.map(binding));\n }\n\n get<T extends object>(\n sql: string,\n params: readonly SqliteValue[]\n ): T | undefined {\n const first = this.#sql\n .exec(this.#prefixer.rewrite(sql), ...params.map(binding))\n .next();\n return first.done ? undefined : row<T>(first.value);\n }\n\n all<T extends object>(sql: string, params: readonly SqliteValue[]): T[] {\n return this.#sql\n .exec(this.#prefixer.rewrite(sql), ...params.map(binding))\n .toArray()\n .map((raw) => row<T>(raw));\n }\n}\n\n/**\n * The handle pi's transaction callback gets. It runs statements directly:\n * the transaction holds the database's queue for as long as it is open.\n */\nclass DurableObjectSqliteTransaction implements SqliteExecutor {\n readonly #statements: Statements;\n #active = true;\n\n constructor(statements: Statements) {\n this.#statements = statements;\n }\n\n /** Called once the transaction settles; the handle is unusable after. */\n end(): void {\n this.#active = false;\n }\n\n async exec(sql: string): Promise<void> {\n this.#assertActive();\n this.#statements.exec(sql);\n }\n\n async run(sql: string, ...params: SqliteValue[]): Promise<void> {\n this.#assertActive();\n this.#statements.run(sql, params);\n }\n\n async get<T extends object>(\n sql: string,\n ...params: SqliteValue[]\n ): Promise<T | undefined> {\n this.#assertActive();\n return this.#statements.get<T>(sql, params);\n }\n\n async all<T extends object>(\n sql: string,\n ...params: SqliteValue[]\n ): Promise<T[]> {\n this.#assertActive();\n return this.#statements.all<T>(sql, params);\n }\n\n #assertActive(): void {\n if (!this.#active) {\n throw new Error(\"The pi SQLite transaction is no longer active\");\n }\n }\n}\n\n/**\n * pi's `SqliteDatabase` facade over `DurableObjectStorage`.\n *\n * Durable Object SQL is synchronous, but pi's facade is asynchronous and a\n * transaction's callback awaits between statements. A statement issued\n * outside the transaction while it waits would run inside it: it would see\n * uncommitted rows, and roll back with it. pi's contract therefore has the\n * adapter queue every other call until the transaction settles: every\n * call goes through one `OperationQueue`, which runs a statement at once\n * when no transaction is open. As the contract says, a call on the database from inside a\n * transaction's callback waits for that transaction and never settles; the\n * callback must use its handle.\n *\n * Transactions run in `storage.transaction()`, which rolls back when the\n * callback rejects and rejects with the same error.\n */\nexport class DurableObjectSqliteDatabase implements SqliteDatabase {\n readonly #storage: DurableObjectStorage;\n readonly #statements: Statements;\n readonly #queue = new OperationQueue();\n\n constructor(\n storage: DurableObjectStorage,\n options: PiSessionStoreOptions = {}\n ) {\n this.#storage = storage;\n this.#statements = new Statements(\n storage.sql,\n new Prefixer(options.prefix ?? DEFAULT_PREFIX)\n );\n }\n\n exec(sql: string): Promise<void> {\n return this.#queue.run(() => this.#statements.exec(sql));\n }\n\n run(sql: string, ...params: SqliteValue[]): Promise<void> {\n return this.#queue.run(() => this.#statements.run(sql, params));\n }\n\n get<T extends object>(\n sql: string,\n ...params: SqliteValue[]\n ): Promise<T | undefined> {\n return this.#queue.run(() => this.#statements.get<T>(sql, params));\n }\n\n all<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T[]> {\n return this.#queue.run(() => this.#statements.all<T>(sql, params));\n }\n\n transaction<T>(\n callback: (transaction: SqliteExecutor) => Promise<T>\n ): Promise<T> {\n return this.#queue.hold(() =>\n this.#storage.transaction(async () => {\n const transaction = new DurableObjectSqliteTransaction(\n this.#statements\n );\n try {\n return await callback(transaction);\n } finally {\n transaction.end();\n }\n })\n );\n }\n\n /** The object owns the database; there is nothing to close. */\n close(): Promise<void> {\n return this.#queue.run(() => undefined);\n }\n}\n","import type { Api, Model, ModelThinkingLevel } from \"@earendil-works/pi-ai\";\nimport {\n LiveDoc,\n ROOT_CONVERSATION_ID,\n watchEvents,\n type AgentEventStream,\n type Conversation,\n type ConversationId,\n type AgentChange,\n type EntryRecord,\n type Harness,\n type ModelRef,\n type SettledSubmissionRecord,\n type UserInput\n} from \"@earendil-works/pi-durable\";\nimport type { SqliteStorage } from \"@earendil-works/pi-durable/storage/sqlite\";\nimport {\n LifecycleCapability,\n type CapabilityStartContext,\n type LifecycleJobContext,\n type LifecycleJobOutcome\n} from \"../../lifecycle\";\nimport { BACKGROUND_CONTEXT, withAbortSignal, type Context } from \"./context\";\nimport { openPiSessionStore } from \"./session-store\";\nimport type {\n PiOperationResult,\n PiPendingOperation,\n PiPromptResponse,\n PiReceipt,\n PiSessionId,\n PiSessionInfo,\n PiSessionOptions,\n PiSubmitOptions\n} from \"./types\";\n\nconst BG = BACKGROUND_CONTEXT;\n\n/** The root session's id. */\nexport const ROOT_SESSION: PiSessionId = String(ROOT_CONVERSATION_ID);\n\n/**\n * The three wake timings. They suit a real deployment; only tests change\n * them, with `setWakeTimingForTests`, so a suite does not sit on the real\n * heartbeat.\n *\n * A pi long wait further away than this is handed to the alarm, so the\n * alarm, not pi's in-memory timer, is what wakes the object.\n */\nconst SLEEP_THRESHOLD_MS = 60_000;\n\n/**\n * Longest one wake waits on pi. It waits inside an alarm invocation, which\n * has a 15 minute wall-time limit, so a longer run is waited on across\n * several alarms.\n */\nconst WAIT_BUDGET_MS = 10 * 60_000;\n\n/**\n * The wake job's heartbeat while it waits, and how often it re-checks work\n * it cannot wait on, such as background tasks. If the object is evicted, the\n * job is still due and its alarm restarts the object.\n */\nconst HEARTBEAT_MS = 30_000;\n\nlet setWakeTiming: (harness: PiHarness, timing: WakeTiming) => void;\n\n/**\n * @internal Shorten a harness's wake timings, so a test suite does not sit\n * on the real heartbeat. Not exported from `agents/harness/pi`.\n */\nexport function setWakeTimingForTests(\n harness: PiHarness,\n timing: WakeTiming\n): void {\n setWakeTiming(harness, timing);\n}\n\nconst WAKE_FN = \"wake\";\n\nfunction wakeJobId(session: PiSessionId): string {\n return `pi-wake:${session}`;\n}\n\nfunction sessionOfJob(payload: unknown): PiSessionId | undefined {\n return typeof payload === \"object\" &&\n payload !== null &&\n \"session\" in payload &&\n typeof payload.session === \"string\"\n ? payload.session\n : undefined;\n}\n\n/**\n * What the factory is handed: the two things only the harness can build.\n * Everything else `Harness.open` takes (models, registry, settings, env,\n * onReport) the factory builds itself.\n */\nexport type PiHarnessContext = {\n /** pi's storage over this object's SQLite, its migrations already run. */\n readonly storage: SqliteStorage;\n /** Background context, for the open itself. */\n readonly context: Context;\n};\n\n/**\n * Opens pi's `Harness`. The harness adopts what it returns.\n *\n * ```ts\n * harness: async ({ storage, context }) => {\n * const registry = createRegistry();\n * registry.install(await skills(sources));\n * return Harness.open(storage, { models, registry }, context);\n * }\n * ```\n */\nexport type PiHarnessFactory = (\n context: PiHarnessContext\n) => Harness | Promise<Harness>;\n\n/**\n * A model, as pi-ai describes one: `createAI`'s `ai(\"@cf/…\")` returns one.\n *\n * Only its `provider` and `id` are used. pi stores that reference with\n * the session and resolves it, at each request, against the `Models` the\n * factory opened pi with. So the model must be one those `Models` list,\n * and options passed to `ai(id, options)` here, such as `fallback`, are not\n * applied.\n */\nexport type PiModel = Pick<Model<Api>, \"provider\" | \"id\">;\n\n/**\n * Applied to a session the first time it is created. Without a model, a\n * session's generation fails as unanswered until `session.setModel` sets one.\n */\nexport type PiSessionDefaults = {\n /**\n * Model for new sessions, by its `provider` and `id`; it must be on the\n * `Models` the factory opens pi with (see `PiModel`). Change one\n * session's with `session.setModel`.\n */\n readonly model?: PiModel;\n readonly thinkingLevel?: ModelThinkingLevel;\n};\n\n/** How long the wake waits, and when it hands a wait to the alarm. */\ntype WakeTiming = {\n /** A pi wait further away than this goes to the alarm. Default 60_000. */\n readonly sleepThresholdMs?: number;\n /** Longest one wake waits inside an alarm. Default 600_000. */\n readonly waitBudgetMs?: number;\n /** Heartbeat while waiting, and the re-check for background work. Default 30_000. */\n readonly heartbeatMs?: number;\n};\n\n/** `PiHarness`'s options. Only `harness`, which opens pi, is required. */\nexport type PiHarnessOptions = {\n /** Opens pi's `Harness` over the storage this object prepared. */\n readonly harness: PiHarnessFactory;\n /** What a new session starts with. */\n readonly defaults?: PiSessionDefaults;\n};\n\ntype Opened = {\n readonly pi: Harness;\n readonly storage: SqliteStorage;\n};\n\n/** pi-durable's stored reference to a pi-ai model. */\nfunction modelRef(model: PiModel): ModelRef {\n return { provider: model.provider, modelId: model.id };\n}\n\nfunction conversationId(session: PiSessionId): ConversationId {\n const id = Number(session);\n if (!Number.isSafeInteger(id) || id < 1) {\n throw new Error(`Invalid pi session ${JSON.stringify(session)}`);\n }\n return id as ConversationId;\n}\n\n/** The text of an assistant entry, for an operation's result. */\nfunction assistantText(entry: EntryRecord | undefined): string {\n const message = entry?.model?.[0];\n if (message?.role !== \"assistant\") return \"\";\n return message.content\n .map((part) => (part.type === \"text\" ? part.text : \"\"))\n .join(\"\");\n}\n\nfunction signalContext(signal: AbortSignal | undefined): Context {\n return signal ? withAbortSignal(signal, BG) : BG;\n}\n\n/**\n * pi-durable hosted in a Durable Object, behind a small harness interface:\n * `harness.prompt()`, `harness.sessions`, `harness.session(id)`. How a session reaches a\n * client (sockets, SSE, RPC) is the host's glue, built on `session.events()`.\n *\n * pi owns everything about a run: the transcript, the inbox of steers and\n * follow-ups, generation and tool tasks, retries, crash recovery, and the\n * live view. It keeps all of it in its own tables in this object's SQLite\n * database (see `session-store.ts`).\n *\n * What pi cannot do on a Durable Object is wake itself: its scheduler runs\n * in memory, and an evicted object has no memory. The harness is that wake,\n * with one Lifecycle job per session. Input goes to pi once, in `submit()`,\n * after the session's job is scheduled. The job waits while pi has live\n * tasks in the session, rescheduling itself as a heartbeat, and completes\n * when there are none. An eviction mid-run leaves the job due, so its alarm\n * restarts the object, pi reopens and resumes its own tasks, and the job\n * waits again.\n *\n * @beta The API may change between releases.\n */\nexport class PiHarness extends LifecycleCapability {\n readonly sessions: PiSessions;\n readonly #options: PiHarnessOptions;\n /** In-memory waits on pi, per session, each inside an alarm's work. */\n readonly #waits = new Map<PiSessionId, Promise<void>>();\n /** Submissions between their wake and pi's admission, per session. */\n readonly #admitting = new Map<PiSessionId, number>();\n #sleepThresholdMs = SLEEP_THRESHOLD_MS;\n #waitBudgetMs = WAIT_BUDGET_MS;\n #heartbeatMs = HEARTBEAT_MS;\n #opening: Promise<Opened> | undefined;\n\n static {\n setWakeTiming = (harness, timing) => harness.#setWakeTiming(timing);\n }\n\n constructor(options: PiHarnessOptions) {\n super(\"pi-harness\");\n this.#options = options;\n this.sessions = new PiSessions(this);\n }\n\n #setWakeTiming(timing: WakeTiming): void {\n for (const [name, value] of Object.entries(timing)) {\n if (!Number.isFinite(value) || value <= 0) {\n throw new Error(`PiHarness timing.${name} must be a positive number`);\n }\n }\n this.#sleepThresholdMs = timing.sleepThresholdMs ?? this.#sleepThresholdMs;\n this.#waitBudgetMs = timing.waitBudgetMs ?? this.#waitBudgetMs;\n this.#heartbeatMs = timing.heartbeatMs ?? this.#heartbeatMs;\n }\n\n // ── Lifecycle ────────────────────────────────────────────────────────────\n\n override async onStart(_context: CapabilityStartContext): Promise<void> {\n const { pi } = await this.#open();\n // Every session with live work gets a wake, including ones whose wake\n // failed out or that a subagent created without going through submit().\n const inspection = await pi.inspect(BG);\n const sessions = new Set(\n inspection.tasks.map((task) => String(task.record.conversationId))\n );\n for (const session of sessions) await this.#wake(session);\n }\n\n async onJob(\n context: LifecycleJobContext\n ): Promise<LifecycleJobOutcome | void> {\n if (context.job.fn !== WAKE_FN) return;\n const session = sessionOfJob(context.job.payload);\n if (session !== undefined) return this.#wakeStep(session);\n }\n\n /** Close pi's in-memory resources. Durable state is untouched. */\n async dispose(): Promise<void> {\n const opening = this.#opening;\n this.#opening = undefined;\n const opened = await opening?.catch(() => undefined);\n await opened?.pi.close(BG);\n }\n\n // ── The harness interface ────────────────────────────────────────────────\n\n /** A handle on one session. No I/O until you call it. */\n session(id: PiSessionId = ROOT_SESSION): PiSession {\n return new PiSession(this, id);\n }\n\n /** Submit a prompt and wait for its answer. */\n prompt(\n input: UserInput,\n options: PiSubmitOptions = {}\n ): Promise<PiPromptResponse> {\n return this.session(options.session).prompt(input, options);\n }\n\n /** Durably submit a prompt. Resolves before the model runs. */\n submit(input: UserInput, options: PiSubmitOptions = {}): Promise<PiReceipt> {\n return this.session(options.session).submit(input, options);\n }\n\n /** Stop one operation, or everything running in a session. */\n abort(\n options: PiSessionOptions & { readonly operationId?: string } = {}\n ): Promise<boolean> {\n return this.session(options.session).abort(options.operationId);\n }\n\n wait(\n operationId: string,\n options: PiSessionOptions & { readonly signal?: AbortSignal } = {}\n ): Promise<PiOperationResult> {\n return this.session(options.session).wait(operationId, options.signal);\n }\n\n /** The session's active transcript, as pi's entries. */\n messages(options: PiSessionOptions = {}): Promise<EntryRecord[]> {\n return this.session(options.session).messages();\n }\n\n /** Submissions pi has not settled yet, oldest first. */\n async pending(options: PiSessionOptions = {}): Promise<PiPendingOperation[]> {\n const { pi } = await this.#open();\n const id =\n options.session === undefined\n ? undefined\n : conversationId(options.session);\n return (await pi.inspect(BG)).submissions\n .filter(\n (record) =>\n record.requestId !== undefined &&\n (id === undefined || record.conversationId === id)\n )\n .map((record) => ({\n operationId: record.requestId as string,\n session: String(record.conversationId),\n status: record.status === \"queued\" ? \"queued\" : \"running\"\n }));\n }\n\n /** The opened pi Harness, for anything the interface does not cover. */\n async pi(): Promise<Harness> {\n return (await this.#open()).pi;\n }\n\n // ── Used by PiSession and PiSessions ─────────────────────────────────────\n\n /** @internal */\n async conversation(session: PiSessionId): Promise<Conversation> {\n const { pi } = await this.#open();\n const conversation = await pi.conversation(conversationId(session), BG);\n if (!conversation) throw new Error(`Unknown pi session ${session}`);\n return conversation;\n }\n\n /** @internal */\n async storage(): Promise<SqliteStorage> {\n return (await this.#open()).storage;\n }\n\n /** @internal */\n async enqueue(\n session: PiSessionId,\n input: UserInput,\n options: PiSubmitOptions\n ): Promise<PiReceipt> {\n const operationId = options.operationId ?? crypto.randomUUID();\n const { storage } = await this.#open();\n const conversation = await this.conversation(session);\n this.#admitting.set(session, (this.#admitting.get(session) ?? 0) + 1);\n let accepted: boolean;\n try {\n // 1. The wake first, so a job is scheduled before pi has the work.\n // If the object dies after pi admits the input, that job restarts\n // it. While this admission is in flight the step will not park.\n await this.#wake(session);\n // 2. The one admission. pi deduplicates by request id.\n accepted =\n (await storage.submissionByRequest(\n conversation.id,\n operationId,\n BG\n )) === undefined;\n await conversation.submit(\n {\n type: \"input\",\n content: input,\n whenBusy: options.whenBusy ?? \"followUp\",\n requestId: operationId\n },\n BG\n );\n } finally {\n const left = (this.#admitting.get(session) ?? 1) - 1;\n if (left === 0) this.#admitting.delete(session);\n else this.#admitting.set(session, left);\n }\n // 3. Step now, so the wake sees the work even if it just parked.\n await this.#wake(session);\n return { operationId, session, accepted };\n }\n\n /** @internal Withdraw a queued input, or abort the run it joined. */\n async withdraw(session: PiSessionId, operationId: string): Promise<boolean> {\n const { pi, storage } = await this.#open();\n const id = conversationId(session);\n const record = await storage.submissionByRequest(id, operationId, BG);\n if (!record || record.status === \"done\" || record.status === \"unanswered\") {\n return false;\n }\n const withdrawn = await pi.abortSubmission(record.id, BG, id);\n if (withdrawn === \"already_placed\") {\n await (await pi.conversation(id, BG))?.abort(BG);\n }\n return withdrawn !== \"settled\" && withdrawn !== \"not_found\";\n }\n\n /** @internal Wait for pi to settle an operation, by its request id. */\n async settled(\n session: PiSessionId,\n operationId: string,\n signal?: AbortSignal\n ): Promise<PiOperationResult> {\n const conversation = await this.conversation(session);\n const context = signalContext(signal);\n const submission = await this.#findSubmission(\n conversation.id,\n operationId,\n context\n );\n if (!submission) {\n return {\n operationId,\n session,\n status: \"unanswered\",\n reason: \"not_found\"\n };\n }\n return this.#result(\n session,\n operationId,\n await submission.wait(context),\n context\n );\n }\n\n // ── The wake ─────────────────────────────────────────────────────────────\n\n /** Schedule the session's wake job now, or pull it forward. */\n #wake(session: PiSessionId, time = Date.now()): Promise<unknown> {\n // A push made while the job is dispatching supersedes that dispatch's\n // outcome, so a submit is never lost to a wake that is completing.\n return this.lifecycle.jobs.push({\n id: wakeJobId(session),\n fn: WAKE_FN,\n time,\n payload: { session },\n singleflight: true,\n recoveryLoop: true\n });\n }\n\n /**\n * One run of a session's wake job. It never admits or replays anything:\n * it waits while pi has live tasks in the session and completes when it\n * has none. pi does all the work in between.\n */\n async #wakeStep(session: PiSessionId): Promise<LifecycleJobOutcome> {\n const heartbeat = { rescheduleAt: Date.now() + this.#heartbeatMs };\n if (this.#waits.has(session)) return heartbeat;\n const { pi } = await this.#open();\n const conversation = await pi.conversation(conversationId(session), BG);\n if (!conversation) return undefined;\n\n const tasks = (await pi.inspect(BG)).tasks.filter(\n (task) => task.record.conversationId === conversation.id\n );\n if (tasks.length === 0) {\n // A submit between its wake and pi's admission: check again later.\n return this.#admitting.has(session) ? heartbeat : undefined;\n }\n const wakeAt = await this.#longWait(pi, conversation.id, BG);\n if (wakeAt !== undefined) return { rescheduleAt: wakeAt };\n // Background tasks are outside the conversation's idle wait.\n if (tasks.every((task) => task.record.background)) return heartbeat;\n\n const wait = this.#waitForIdle(conversation).finally(() => {\n this.#waits.delete(session);\n // Re-check now: pi may have started more work, such as a follow-up.\n void this.#wake(session);\n });\n this.#waits.set(session, wait);\n // The wait runs past this dispatch, inside the alarm's work, so the\n // object stays alive for it. The heartbeat covers an eviction.\n this.lifecycle.trackAlarmWork(wait);\n return heartbeat;\n }\n\n async #waitForIdle(conversation: Conversation): Promise<void> {\n const budget = new AbortController();\n const timer = setTimeout(() => budget.abort(), this.#waitBudgetMs);\n try {\n // Cancelling the wait never cancels pi's work.\n await conversation.waitForIdle(withAbortSignal(budget.signal, BG));\n } catch (error) {\n if (!budget.signal.aborted) {\n this.lifecycle.events.emit(\"pi:wake_error\", {\n session: String(conversation.id),\n error: error instanceof Error ? error.message : String(error)\n });\n }\n } finally {\n clearTimeout(timer);\n }\n }\n\n // ── pi ───────────────────────────────────────────────────────────────────\n\n /**\n * pi, opened. Waits for Lifecycle startup first, so pi is only ever\n * opened inside it: startup holds the input gate (`blockConcurrencyWhile`)\n * and awaits the open in `onStart`, so an open begun before startup would\n * be awaited behind a closed gate, with its timers and I/O held back, and\n * never finish.\n */\n async #open(): Promise<Opened> {\n await this.lifecycle.ready();\n this.#opening ??= this.#doOpen().catch((error: unknown) => {\n this.#opening = undefined;\n throw error;\n });\n return this.#opening;\n }\n\n async #doOpen(): Promise<Opened> {\n const storage = await openPiSessionStore(this.lifecycle.storage);\n const pi = await this.#options.harness({ storage, context: BG });\n await pi.root(BG, { agent: this.agentDefaults() });\n // Continue whatever the last isolate left: pi reconciles tasks that were\n // running to pending and schedules them again.\n pi.resume();\n return { pi, storage };\n }\n\n /** @internal The per-conversation defaults supported by pi-durable. */\n agentDefaults(): AgentChange {\n const defaults = this.#options.defaults;\n return {\n ...(defaults?.model === undefined\n ? {}\n : { model: modelRef(defaults.model) }),\n ...(defaults?.thinkingLevel === undefined\n ? {}\n : { thinkingLevel: defaults.thinkingLevel })\n };\n }\n\n async #findSubmission(\n id: ConversationId,\n operationId: string,\n context: Context\n ) {\n const { pi, storage } = await this.#open();\n // Read from pi's storage: the Harness only reacquires submissions by id.\n const record = await storage.submissionByRequest(id, operationId, context);\n return record ? pi.submission(record.id, context) : undefined;\n }\n\n /** When pi's current wait is far enough away to hand to the alarm. */\n async #longWait(\n pi: Harness,\n id: ConversationId,\n context: Context\n ): Promise<number | undefined> {\n const live = await pi.snapshot(LiveDoc, id, context);\n const at =\n live?.generation?.deferred?.pollAt ?? live?.generation?.retry?.at;\n return at !== undefined && at - Date.now() > this.#sleepThresholdMs\n ? at\n : undefined;\n }\n\n async #result(\n session: PiSessionId,\n operationId: string,\n settled: SettledSubmissionRecord,\n context: Context\n ): Promise<PiOperationResult> {\n if (settled.status === \"unanswered\") {\n return {\n operationId,\n session,\n status: \"unanswered\",\n reason: settled.reason\n };\n }\n if (settled.type !== \"input\")\n return { operationId, session, status: \"done\" };\n const conversation = await this.conversation(session);\n const page = await conversation.entries(\n { minEntryId: settled.answer, maxEntryId: settled.answer },\n 1,\n undefined,\n context\n );\n return {\n operationId,\n session,\n status: \"done\",\n text: assistantText(page.items[0])\n };\n }\n}\n\n/** One pi conversation, addressed through the harness. */\nexport class PiSession {\n readonly #harness: PiHarness;\n readonly id: PiSessionId;\n\n constructor(harness: PiHarness, id: PiSessionId) {\n this.#harness = harness;\n this.id = id;\n }\n\n /** Durably submit a prompt. Resolves before the model runs. */\n submit(input: UserInput, options: PiSubmitOptions = {}): Promise<PiReceipt> {\n return this.#harness.enqueue(this.id, input, options);\n }\n\n /** Submit and wait for the answer and the updated transcript. */\n async prompt(\n input: UserInput,\n options: PiSubmitOptions = {}\n ): Promise<PiPromptResponse> {\n const receipt = await this.submit(input, options);\n const result = await this.wait(receipt.operationId);\n return { ...result, messages: await this.messages() };\n }\n\n /** Join the running work after its current tool round. */\n steer(input: UserInput, options: Omit<PiSubmitOptions, \"whenBusy\"> = {}) {\n return this.submit(input, { ...options, whenBusy: \"steer\" });\n }\n\n /** Wait for an operation to settle. Aborting `signal` stops only the wait. */\n wait(operationId: string, signal?: AbortSignal): Promise<PiOperationResult> {\n return this.#harness.settled(this.id, operationId, signal);\n }\n\n /**\n * Withdraw one queued operation (or abort the run it joined), or, with no\n * id, abort the session: pi withdraws queued inputs and aborts the\n * running work.\n */\n async abort(operationId?: string): Promise<boolean> {\n if (operationId !== undefined) {\n return this.#harness.withdraw(this.id, operationId);\n }\n const conversation = await this.#harness.conversation(this.id);\n await conversation.abort(BG);\n return true;\n }\n\n /** Start a new context, optionally from a handoff note. */\n async reset(handoff?: string): Promise<void> {\n await (await this.#harness.conversation(this.id)).reset(handoff, BG);\n }\n\n /**\n * Change this session's model, by its `provider` and `id`; it must be on\n * the `Models` the factory opened pi with (see `PiModel`).\n */\n async setModel(model: PiModel): Promise<void> {\n await (\n await this.#harness.conversation(this.id)\n ).configure({ model: modelRef(model) }, BG);\n }\n\n /** The active transcript, as pi's entries since the newest reset. */\n async messages(): Promise<EntryRecord[]> {\n const view = await (await this.#harness.conversation(this.id)).context(BG);\n return [...view.entries];\n }\n\n /** pi's agent events for this session: a snapshot, then one batch per commit. */\n async events(context: Context = BG): Promise<AgentEventStream> {\n const pi = await this.#harness.pi();\n return watchEvents(pi, conversationId(this.id), context);\n }\n\n async busy(): Promise<boolean> {\n const pi = await this.#harness.pi();\n const live = await pi.snapshot(LiveDoc, conversationId(this.id), BG);\n return live?.run !== undefined;\n }\n}\n\n/** Every pi conversation in this object. */\nexport class PiSessions {\n readonly #harness: PiHarness;\n\n constructor(harness: PiHarness) {\n this.#harness = harness;\n }\n\n get(id: PiSessionId): PiSession {\n return this.#harness.session(id);\n }\n\n /** A new top-level session, configured like the root. */\n async create(): Promise<PiSession> {\n const pi = await this.#harness.pi();\n const conversation = await pi.createConversation(\n {\n ownership: { kind: \"ownerless\" },\n agent: this.#harness.agentDefaults()\n },\n BG\n );\n return this.#harness.session(String(conversation.id));\n }\n\n /** A new session that sees `from`'s history up to its newest entry. */\n async fork(from: PiSessionId): Promise<PiSession> {\n const conversation = await this.#harness.conversation(from);\n const newest = await conversation.entries({}, 1, undefined, BG);\n const at = newest.items[0];\n if (!at) throw new Error(`Session ${from} has no entries to fork from`);\n const fork = await conversation.fork(\n at.id,\n { ownership: { kind: \"ownerless\" } },\n BG\n );\n return this.#harness.session(String(fork.id));\n }\n\n /**\n * Every conversation, including ones subagent tools own. Read from pi's\n * storage directly: the Harness has no conversation listing.\n */\n async list(): Promise<PiSessionInfo[]> {\n const storage = await this.#harness.storage();\n const pi = await this.#harness.pi();\n const sessions: PiSessionInfo[] = [];\n let cursor: Parameters<SqliteStorage[\"scanConversations\"]>[2];\n for (;;) {\n const page = await storage.scanConversations({}, 100, cursor, BG);\n for (const record of page.items) {\n const live = await pi.snapshot(LiveDoc, record.id, BG);\n sessions.push({\n id: String(record.id),\n ...(record.parent\n ? { parent: String(record.parent.conversationId) }\n : {}),\n busy: live?.run !== undefined\n });\n }\n if (page.next === undefined) return sessions;\n cursor = page.next;\n }\n }\n}\n","import { Type } from \"@earendil-works/pi-ai\";\nimport type {\n Extension,\n ToolExecutionResult,\n ToolRegistration\n} from \"@earendil-works/pi-durable\";\nimport type {\n SkillContent,\n SkillDescriptor,\n SkillResourceDescriptor,\n SkillSource\n} from \"../../skills\";\n\n/** Skills resolved from `agents/skills` sources for one process lifetime. */\nexport type ResolvedSkills = {\n /** Changes when any source's fingerprint changes. */\n readonly fingerprint: string;\n /** Model-facing activation tools; empty when there are no skills. */\n readonly tools: readonly ToolRegistration[];\n /** System-prompt catalog, or null when there are no skills. */\n readonly catalog: string | null;\n readonly warnings: readonly string[];\n};\n\ntype ResolvedSkill = {\n readonly descriptor: SkillDescriptor;\n readonly content: SkillContent;\n readonly source: SkillSource;\n};\n\nexport function skillsFingerprint(sources: readonly SkillSource[]): string {\n return sources\n .map((source) => `${source.id}:${source.fingerprint}`)\n .join(\"|\");\n}\n\nfunction textResult(text: string): ToolExecutionResult {\n return { content: [{ type: \"text\", text }] };\n}\n\nfunction attributes(\n pairs: ReadonlyArray<readonly [string, string | undefined]>\n) {\n return pairs\n .filter((pair): pair is readonly [string, string] => pair[1] !== undefined)\n .map(([key, value]) => ` ${key}=\"${value.replace(/\"/g, \"&quot;\")}\"`)\n .join(\"\");\n}\n\nfunction describeResource(resource: SkillResourceDescriptor): string {\n const details = [\n resource.kind,\n resource.encoding ?? \"text\",\n resource.mimeType,\n resource.size === undefined ? undefined : `${resource.size} bytes`\n ].filter((value): value is string => value !== undefined);\n return `- ${resource.path} (${details.join(\", \")})`;\n}\n\nfunction renderSkillContent(skill: ResolvedSkill): string {\n const resources = skill.content.resources ?? [];\n const lines = [\n `<skill_content${attributes([\n [\"name\", skill.descriptor.name],\n [\"version\", skill.descriptor.version]\n ])}>`,\n skill.content.body.trim()\n ];\n if (resources.length > 0) {\n lines.push(\"<skill_resources>\");\n for (const resource of resources) {\n lines.push(\n ` <file${attributes([\n [\"kind\", resource.kind],\n [\"encoding\", resource.encoding ?? \"text\"],\n [\n \"size\",\n resource.size === undefined ? undefined : String(resource.size)\n ]\n ])}>${resource.path}</file>`\n );\n }\n lines.push(\"</skill_resources>\");\n }\n lines.push(\"</skill_content>\", \"\");\n lines.push(\n resources.length === 0\n ? \"No bundled resources.\"\n : [\"Bundled resources:\", ...resources.map(describeResource)].join(\"\\n\")\n );\n return lines.join(\"\\n\");\n}\n\n/**\n * Resolve `agents/skills` sources into a system-prompt catalog and two\n * tools.\n *\n * The first source to list a name wins, as in `SkillRegistry`. pi-durable\n * has no skill concept of its own, so the model activates skills through\n * `activate_skill` and reads bundled files through `read_skill_resource` —\n * the same tools `@cloudflare/think` offers, so skills authored for one\n * framework work in the other.\n */\nexport async function resolveSkillSources(\n sources: readonly SkillSource[]\n): Promise<ResolvedSkills> {\n const fingerprint = skillsFingerprint(sources);\n const warnings: string[] = [];\n const resolved = new Map<string, ResolvedSkill>();\n for (const source of sources) {\n let descriptors: SkillDescriptor[];\n try {\n descriptors = await source.list();\n } catch (error) {\n warnings.push(\n `Skill source \"${source.id}\" failed to list skills: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n continue;\n }\n for (const descriptor of descriptors) {\n if (resolved.has(descriptor.name)) {\n warnings.push(\n `Skill \"${descriptor.name}\" from source \"${source.id}\" is shadowed by an earlier source`\n );\n continue;\n }\n let content: SkillContent | null;\n try {\n content = await source.load(descriptor.name);\n } catch (error) {\n warnings.push(\n `Skill \"${descriptor.name}\" from source \"${source.id}\" failed to load: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n continue;\n }\n if (!content) continue;\n resolved.set(descriptor.name, { descriptor, content, source });\n }\n }\n\n const visible = [...resolved.values()].filter(\n (skill) => skill.descriptor.metadata?.[\"disable-model-invocation\"] !== true\n );\n if (visible.length === 0) {\n return { fingerprint, tools: [], catalog: null, warnings };\n }\n\n const names = visible.map((skill) => skill.descriptor.name);\n const nameSchema = Type.Union(names.map((name) => Type.Literal(name)));\n const byName = new Map(\n visible.map((skill) => [skill.descriptor.name, skill])\n );\n\n const activateParameters = Type.Object({ name: nameSchema });\n const activateSkill: ToolRegistration<typeof activateParameters> = {\n name: \"activate_skill\",\n description:\n \"Activate a skill by name. Use this when the user's task matches one of the available skills; the response contains the skill's full instructions.\",\n parameters: activateParameters,\n replay: \"safe\",\n async execute(input) {\n const skill = byName.get(input.name);\n return textResult(\n skill ? renderSkillContent(skill) : `Skill not found: ${input.name}`\n );\n }\n };\n\n const resourceParameters = Type.Object({\n name: Type.Optional(nameSchema),\n path: Type.String({ minLength: 1 })\n });\n const readResource: ToolRegistration<typeof resourceParameters> = {\n name: \"read_skill_resource\",\n description:\n \"Read a file bundled with a skill, such as a reference document or template. Provide the skill name and the file's path from the skill's resource list.\",\n parameters: resourceParameters,\n replay: \"safe\",\n async execute(input) {\n const target = resolveResourceTarget(byName, input.name, input.path);\n if (!target) {\n return textResult(\n `Skill resource not found: ${input.name ? `${input.name}/` : \"\"}${input.path}`\n );\n }\n const resource = await target.skill.source\n .readResource?.(target.skill.descriptor.name, target.path)\n .catch(() => null);\n if (!resource) {\n return textResult(\n `Skill resource not found: ${target.skill.descriptor.name}/${target.path}`\n );\n }\n return textResult(\n [\n `<skill_resource${attributes([\n [\"name\", target.skill.descriptor.name],\n [\"path\", resource.path],\n [\"kind\", resource.kind],\n [\"encoding\", resource.encoding ?? \"text\"],\n [\"mimeType\", resource.mimeType]\n ])}>`,\n resource.content,\n \"</skill_resource>\"\n ].join(\"\\n\")\n );\n }\n };\n\n const catalog = [\n \"Available skills. When a task matches a skill, use activate_skill with its name before proceeding.\",\n \"\",\n ...visible.map(\n (skill) => `- ${skill.descriptor.name}: ${skill.descriptor.description}`\n )\n ].join(\"\\n\");\n\n return {\n fingerprint,\n tools: [activateSkill, readResource],\n catalog,\n warnings\n };\n}\n\nfunction resolveResourceTarget(\n byName: ReadonlyMap<string, ResolvedSkill>,\n name: string | undefined,\n path: string\n): { readonly skill: ResolvedSkill; readonly path: string } | undefined {\n if (path.split(\"/\").some((segment) => segment === \"..\")) return undefined;\n if (name !== undefined) {\n const skill = byName.get(name);\n return skill && hasResource(skill, path) ? { skill, path } : undefined;\n }\n // A qualified path names the skill in its first segment.\n const [head, ...rest] = path.split(\"/\");\n const skill = head === undefined ? undefined : byName.get(head);\n const relative = rest.join(\"/\");\n return skill && relative && hasResource(skill, relative)\n ? { skill, path: relative }\n : undefined;\n}\n\nfunction hasResource(skill: ResolvedSkill, path: string): boolean {\n return (skill.content.resources ?? []).some(\n (resource) => resource.path === path\n );\n}\n\n/**\n * `agents/skills` sources as a pi extension, named `agents.skills`: the\n * activation tools and a `skills` system prompt section. Install it on\n * pi's registry in the harness factory.\n *\n * ```ts\n * registry.install(await skills(sources));\n * ```\n */\nexport async function skills(\n sources: readonly SkillSource[]\n): Promise<Extension> {\n const resolved = await resolveSkillSources(sources);\n for (const warning of resolved.warnings) {\n console.warn(`pi skills: ${warning}`);\n }\n const catalog = resolved.catalog;\n return {\n name: \"agents.skills\",\n tools: resolved.tools,\n sections: catalog === null ? [] : [{ key: \"skills\", render: () => catalog }]\n };\n}\n"],"mappings":"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"}