@earendil-works/pi-durable 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/README.md +111 -3
- package/dist/codemode/codemode.d.ts.map +1 -1
- package/dist/codemode/codemode.js +12 -4
- package/dist/codemode/codemode.js.map +1 -1
- package/dist/codemode/models.d.ts.map +1 -1
- package/dist/codemode/models.js +2 -0
- package/dist/codemode/models.js.map +1 -1
- package/dist/documents.d.ts +1 -1
- package/dist/documents.d.ts.map +1 -1
- package/dist/documents.js.map +1 -1
- package/dist/env/node.d.ts.map +1 -1
- package/dist/env/node.js +11 -3
- package/dist/env/node.js.map +1 -1
- package/dist/harness/agent.d.ts +13 -2
- package/dist/harness/agent.d.ts.map +1 -1
- package/dist/harness/agent.js +39 -5
- package/dist/harness/agent.js.map +1 -1
- package/dist/harness/compaction.d.ts +3 -1
- package/dist/harness/compaction.d.ts.map +1 -1
- package/dist/harness/compaction.js +19 -4
- package/dist/harness/compaction.js.map +1 -1
- package/dist/harness/generation.d.ts.map +1 -1
- package/dist/harness/generation.js +67 -27
- package/dist/harness/generation.js.map +1 -1
- package/dist/harness/harness.d.ts +5 -2
- package/dist/harness/harness.d.ts.map +1 -1
- package/dist/harness/harness.js +78 -13
- package/dist/harness/harness.js.map +1 -1
- package/dist/harness/inbox.d.ts +2 -2
- package/dist/harness/inbox.d.ts.map +1 -1
- package/dist/harness/inbox.js +3 -3
- package/dist/harness/inbox.js.map +1 -1
- package/dist/harness/prompt.d.ts +1 -1
- package/dist/harness/prompt.d.ts.map +1 -1
- package/dist/harness/prompt.js +1 -1
- package/dist/harness/prompt.js.map +1 -1
- package/dist/harness/scheduler.d.ts +55 -10
- package/dist/harness/scheduler.d.ts.map +1 -1
- package/dist/harness/scheduler.js +617 -124
- package/dist/harness/scheduler.js.map +1 -1
- package/dist/harness/submissions.d.ts +7 -2
- package/dist/harness/submissions.d.ts.map +1 -1
- package/dist/harness/submissions.js +48 -17
- package/dist/harness/submissions.js.map +1 -1
- package/dist/harness/task-graph.d.ts +18 -1
- package/dist/harness/task-graph.d.ts.map +1 -1
- package/dist/harness/task-graph.js +50 -11
- package/dist/harness/task-graph.js.map +1 -1
- package/dist/harness/telemetry.d.ts +307 -0
- package/dist/harness/telemetry.d.ts.map +1 -0
- package/dist/harness/telemetry.js +136 -0
- package/dist/harness/telemetry.js.map +1 -0
- package/dist/harness/tool.d.ts.map +1 -1
- package/dist/harness/tool.js +53 -7
- package/dist/harness/tool.js.map +1 -1
- package/dist/harness/types.d.ts +110 -15
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/util.d.ts +4 -0
- package/dist/harness/util.d.ts.map +1 -1
- package/dist/harness/util.js +4 -0
- package/dist/harness/util.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/session/session.d.ts +17 -6
- package/dist/session/session.d.ts.map +1 -1
- package/dist/session/session.js +64 -32
- package/dist/session/session.js.map +1 -1
- package/dist/session/transaction.d.ts +5 -1
- package/dist/session/transaction.d.ts.map +1 -1
- package/dist/session/transaction.js +26 -1
- package/dist/session/transaction.js.map +1 -1
- package/dist/storage/indexeddb.d.ts +60 -0
- package/dist/storage/indexeddb.d.ts.map +1 -0
- package/dist/storage/indexeddb.js +831 -0
- package/dist/storage/indexeddb.js.map +1 -0
- package/dist/storage/jsonl/storage.d.ts +16 -0
- package/dist/storage/jsonl/storage.d.ts.map +1 -1
- package/dist/storage/memory.js +1 -1
- package/dist/storage/memory.js.map +1 -1
- package/dist/storage/sqlite/cloudflare.d.ts +2 -51
- package/dist/storage/sqlite/cloudflare.d.ts.map +1 -1
- package/dist/storage/sqlite/cloudflare.js +2 -133
- package/dist/storage/sqlite/cloudflare.js.map +1 -1
- package/dist/storage/sqlite/database.d.ts +1 -36
- package/dist/storage/sqlite/database.d.ts.map +1 -1
- package/dist/storage/sqlite/database.js.map +1 -1
- package/dist/storage/sqlite/index.d.ts +1 -1
- package/dist/storage/sqlite/index.d.ts.map +1 -1
- package/dist/storage/sqlite/index.js.map +1 -1
- package/dist/storage/sqlite/migrations.d.ts +2 -5
- package/dist/storage/sqlite/migrations.d.ts.map +1 -1
- package/dist/storage/sqlite/migrations.js +28 -28
- package/dist/storage/sqlite/migrations.js.map +1 -1
- package/dist/storage/sqlite/node.d.ts +2 -37
- package/dist/storage/sqlite/node.d.ts.map +1 -1
- package/dist/storage/sqlite/node.js +3 -174
- package/dist/storage/sqlite/node.js.map +1 -1
- package/dist/storage/sqlite/schema.d.ts +1 -3
- package/dist/storage/sqlite/schema.d.ts.map +1 -1
- package/dist/storage/sqlite/schema.js +2 -9
- package/dist/storage/sqlite/schema.js.map +1 -1
- package/dist/storage/sqlite/storage.d.ts +1 -1
- package/dist/storage/sqlite/storage.d.ts.map +1 -1
- package/dist/storage/sqlite/storage.js.map +1 -1
- package/dist/testing/storage-conformance.d.ts.map +1 -1
- package/dist/testing/storage-conformance.js +17 -0
- package/dist/testing/storage-conformance.js.map +1 -1
- package/dist/timers.d.ts +21 -0
- package/dist/timers.d.ts.map +1 -0
- package/dist/timers.js +72 -0
- package/dist/timers.js.map +1 -0
- package/dist/types.d.ts +130 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +15 -5
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/** Durable's content-free span, event, and metric vocabulary. IDs address durable records, never content. */
|
|
2
|
+
export declare const DURABLE_TELEMETRY_SCHEMA: {
|
|
3
|
+
readonly version: 1;
|
|
4
|
+
readonly spans: {
|
|
5
|
+
readonly "pi.durable.submit": {
|
|
6
|
+
readonly description: "Public submission admission and its commit. Inputs start root traces linked to their callers; writes are children. Internal admissions emit phase events only.";
|
|
7
|
+
readonly parents: {
|
|
8
|
+
readonly kind: "any";
|
|
9
|
+
};
|
|
10
|
+
readonly startAttributes: {
|
|
11
|
+
readonly "submission.type": {
|
|
12
|
+
readonly type: "string";
|
|
13
|
+
readonly required: true;
|
|
14
|
+
readonly values: readonly ["input", "write"];
|
|
15
|
+
readonly description: "Submission type.";
|
|
16
|
+
};
|
|
17
|
+
readonly "conversation.id": {
|
|
18
|
+
readonly type: "number";
|
|
19
|
+
readonly required: true;
|
|
20
|
+
readonly description: "Conversation ID.";
|
|
21
|
+
readonly cardinality: "high";
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
readonly endAttributes: {
|
|
25
|
+
readonly "submission.id": {
|
|
26
|
+
readonly type: "number";
|
|
27
|
+
readonly description: "Admitted submission ID.";
|
|
28
|
+
readonly cardinality: "high";
|
|
29
|
+
};
|
|
30
|
+
readonly result: {
|
|
31
|
+
readonly type: "string";
|
|
32
|
+
readonly values: readonly ["queued", "placed", "done"];
|
|
33
|
+
readonly description: "Admission result; stale writes report done.";
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
readonly events: {
|
|
37
|
+
"pi.durable.entry": {
|
|
38
|
+
readonly description: "A transcript entry was committed; content remains in the transcript.";
|
|
39
|
+
readonly attributes: {
|
|
40
|
+
readonly "entry.id": {
|
|
41
|
+
readonly type: "number";
|
|
42
|
+
readonly required: true;
|
|
43
|
+
readonly description: "Transcript entry ID.";
|
|
44
|
+
readonly cardinality: "high";
|
|
45
|
+
};
|
|
46
|
+
readonly "entry.kind": {
|
|
47
|
+
readonly type: "string";
|
|
48
|
+
readonly required: true;
|
|
49
|
+
readonly description: "Entry kind.";
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
"pi.durable.submission": {
|
|
54
|
+
readonly description: "A submission was settled.";
|
|
55
|
+
readonly attributes: {
|
|
56
|
+
readonly "submission.id": {
|
|
57
|
+
readonly type: "number";
|
|
58
|
+
readonly required: true;
|
|
59
|
+
readonly description: "Submission ID.";
|
|
60
|
+
readonly cardinality: "high";
|
|
61
|
+
};
|
|
62
|
+
readonly status: {
|
|
63
|
+
readonly type: "string";
|
|
64
|
+
readonly required: true;
|
|
65
|
+
readonly values: readonly ["done", "unanswered"];
|
|
66
|
+
readonly description: "Settlement.";
|
|
67
|
+
};
|
|
68
|
+
readonly "answer.entry_id": {
|
|
69
|
+
readonly type: "number";
|
|
70
|
+
readonly required: false;
|
|
71
|
+
readonly description: "Answer entry ID.";
|
|
72
|
+
readonly cardinality: "high";
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
"pi.durable.report": {
|
|
77
|
+
readonly description: "A report was raised; no error payload is recorded.";
|
|
78
|
+
readonly attributes: {
|
|
79
|
+
readonly type: {
|
|
80
|
+
readonly type: "string";
|
|
81
|
+
readonly required: true;
|
|
82
|
+
readonly description: "ReportInfo type.";
|
|
83
|
+
readonly values: readonly ["session_failed", "task_faulted", "task_parked", "migration_failed", "task_outdated", "task_error", "extension_error", "host_error", "listener_error"];
|
|
84
|
+
};
|
|
85
|
+
readonly reason: {
|
|
86
|
+
readonly type: "string";
|
|
87
|
+
readonly required: false;
|
|
88
|
+
readonly description: "Fixed report reason, when present.";
|
|
89
|
+
readonly values: readonly ["threw", "restart_limit", "missing_task", "incompatible_task"];
|
|
90
|
+
};
|
|
91
|
+
readonly extension: {
|
|
92
|
+
readonly type: "string";
|
|
93
|
+
readonly required: false;
|
|
94
|
+
readonly description: "Registered extension name, when present.";
|
|
95
|
+
};
|
|
96
|
+
readonly "task.id": {
|
|
97
|
+
readonly type: "number";
|
|
98
|
+
readonly required: false;
|
|
99
|
+
readonly description: "Task ID, when present.";
|
|
100
|
+
readonly cardinality: "high";
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
readonly status: {
|
|
106
|
+
readonly default: "ok";
|
|
107
|
+
readonly errorWhen: "Admission failed.";
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
readonly "pi.durable.phase": {
|
|
111
|
+
readonly description: "One task phase invocation, including its decision commit, never a wait or restart.";
|
|
112
|
+
readonly parents: {
|
|
113
|
+
readonly kind: "any";
|
|
114
|
+
};
|
|
115
|
+
readonly startAttributes: {
|
|
116
|
+
readonly "task.id": {
|
|
117
|
+
readonly type: "number";
|
|
118
|
+
readonly required: true;
|
|
119
|
+
readonly description: "Task ID.";
|
|
120
|
+
readonly cardinality: "high";
|
|
121
|
+
};
|
|
122
|
+
readonly "task.name": {
|
|
123
|
+
readonly type: "string";
|
|
124
|
+
readonly required: true;
|
|
125
|
+
readonly description: "Registered task name.";
|
|
126
|
+
};
|
|
127
|
+
readonly phase: {
|
|
128
|
+
readonly type: "string";
|
|
129
|
+
readonly required: true;
|
|
130
|
+
readonly description: "Invoked checkpoint phase.";
|
|
131
|
+
};
|
|
132
|
+
readonly kind: {
|
|
133
|
+
readonly type: "string";
|
|
134
|
+
readonly required: true;
|
|
135
|
+
readonly values: readonly ["run", "abort"];
|
|
136
|
+
readonly description: "Invocation kind.";
|
|
137
|
+
};
|
|
138
|
+
readonly attempt: {
|
|
139
|
+
readonly type: "number";
|
|
140
|
+
readonly required: false;
|
|
141
|
+
readonly description: "Checkpoint attempt, when present.";
|
|
142
|
+
};
|
|
143
|
+
readonly resumed: {
|
|
144
|
+
readonly type: "boolean";
|
|
145
|
+
readonly required: true;
|
|
146
|
+
readonly description: "First invocation of a task loaded in this process.";
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
readonly endAttributes: {
|
|
150
|
+
readonly outcome: {
|
|
151
|
+
readonly type: "string";
|
|
152
|
+
readonly description: "next=<phase>, waiting, sleeping, done, faulted, or aborted.";
|
|
153
|
+
};
|
|
154
|
+
readonly "tool.name": {
|
|
155
|
+
readonly type: "string";
|
|
156
|
+
readonly description: "Called tool name.";
|
|
157
|
+
};
|
|
158
|
+
readonly "tool.call_id": {
|
|
159
|
+
readonly type: "string";
|
|
160
|
+
readonly description: "Transcript tool call ID.";
|
|
161
|
+
readonly cardinality: "high";
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
readonly events: {
|
|
165
|
+
readonly "pi.durable.entry": {
|
|
166
|
+
readonly description: "A transcript entry was committed; content remains in the transcript.";
|
|
167
|
+
readonly attributes: {
|
|
168
|
+
readonly "entry.id": {
|
|
169
|
+
readonly type: "number";
|
|
170
|
+
readonly required: true;
|
|
171
|
+
readonly description: "Transcript entry ID.";
|
|
172
|
+
readonly cardinality: "high";
|
|
173
|
+
};
|
|
174
|
+
readonly "entry.kind": {
|
|
175
|
+
readonly type: "string";
|
|
176
|
+
readonly required: true;
|
|
177
|
+
readonly description: "Entry kind.";
|
|
178
|
+
};
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
readonly "pi.durable.submission": {
|
|
182
|
+
readonly description: "A submission was settled.";
|
|
183
|
+
readonly attributes: {
|
|
184
|
+
readonly "submission.id": {
|
|
185
|
+
readonly type: "number";
|
|
186
|
+
readonly required: true;
|
|
187
|
+
readonly description: "Submission ID.";
|
|
188
|
+
readonly cardinality: "high";
|
|
189
|
+
};
|
|
190
|
+
readonly status: {
|
|
191
|
+
readonly type: "string";
|
|
192
|
+
readonly required: true;
|
|
193
|
+
readonly values: readonly ["done", "unanswered"];
|
|
194
|
+
readonly description: "Settlement.";
|
|
195
|
+
};
|
|
196
|
+
readonly "answer.entry_id": {
|
|
197
|
+
readonly type: "number";
|
|
198
|
+
readonly required: false;
|
|
199
|
+
readonly description: "Answer entry ID.";
|
|
200
|
+
readonly cardinality: "high";
|
|
201
|
+
};
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
readonly "pi.durable.report": {
|
|
205
|
+
readonly description: "A report was raised; no error payload is recorded.";
|
|
206
|
+
readonly attributes: {
|
|
207
|
+
readonly type: {
|
|
208
|
+
readonly type: "string";
|
|
209
|
+
readonly required: true;
|
|
210
|
+
readonly description: "ReportInfo type.";
|
|
211
|
+
readonly values: readonly ["session_failed", "task_faulted", "task_parked", "migration_failed", "task_outdated", "task_error", "extension_error", "host_error", "listener_error"];
|
|
212
|
+
};
|
|
213
|
+
readonly reason: {
|
|
214
|
+
readonly type: "string";
|
|
215
|
+
readonly required: false;
|
|
216
|
+
readonly description: "Fixed report reason, when present.";
|
|
217
|
+
readonly values: readonly ["threw", "restart_limit", "missing_task", "incompatible_task"];
|
|
218
|
+
};
|
|
219
|
+
readonly extension: {
|
|
220
|
+
readonly type: "string";
|
|
221
|
+
readonly required: false;
|
|
222
|
+
readonly description: "Registered extension name, when present.";
|
|
223
|
+
};
|
|
224
|
+
readonly "task.id": {
|
|
225
|
+
readonly type: "number";
|
|
226
|
+
readonly required: false;
|
|
227
|
+
readonly description: "Task ID, when present.";
|
|
228
|
+
readonly cardinality: "high";
|
|
229
|
+
};
|
|
230
|
+
};
|
|
231
|
+
};
|
|
232
|
+
readonly "pi.durable.checkpoint": {
|
|
233
|
+
readonly description: "The running checkpoint's phase changed while the invocation continued.";
|
|
234
|
+
readonly attributes: {
|
|
235
|
+
readonly phase: {
|
|
236
|
+
readonly type: "string";
|
|
237
|
+
readonly required: true;
|
|
238
|
+
readonly description: "Committed checkpoint phase.";
|
|
239
|
+
};
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
readonly "pi.durable.replay": {
|
|
243
|
+
readonly description: "A nested tool call was answered from its stored result.";
|
|
244
|
+
readonly attributes: {
|
|
245
|
+
readonly "tool.name": {
|
|
246
|
+
readonly type: "string";
|
|
247
|
+
readonly required: true;
|
|
248
|
+
readonly description: "Called tool name.";
|
|
249
|
+
};
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
readonly status: {
|
|
254
|
+
readonly default: "ok";
|
|
255
|
+
readonly errorWhen: "Faulted, failed, and orphaned outcomes use task_faulted, task_failed, and task_orphaned with a diagnostic capped at 500 characters. Aborted outcomes keep status ok.";
|
|
256
|
+
};
|
|
257
|
+
};
|
|
258
|
+
};
|
|
259
|
+
readonly metrics: {
|
|
260
|
+
readonly "pi.durable.reports": {
|
|
261
|
+
readonly kind: "counter";
|
|
262
|
+
readonly description: "Reports raised, grouped by their fixed ReportInfo type.";
|
|
263
|
+
readonly attributes: {
|
|
264
|
+
type: {
|
|
265
|
+
readonly type: "string";
|
|
266
|
+
readonly required: true;
|
|
267
|
+
readonly description: "ReportInfo type.";
|
|
268
|
+
readonly values: readonly ["session_failed", "task_faulted", "task_parked", "migration_failed", "task_outdated", "task_error", "extension_error", "host_error", "listener_error"];
|
|
269
|
+
};
|
|
270
|
+
};
|
|
271
|
+
};
|
|
272
|
+
readonly "pi.durable.phase.duration": {
|
|
273
|
+
readonly kind: "histogram";
|
|
274
|
+
readonly unit: "ms";
|
|
275
|
+
readonly description: "Duration of a phase invocation and its decision commit.";
|
|
276
|
+
readonly attributes: {
|
|
277
|
+
readonly task: {
|
|
278
|
+
readonly type: "string";
|
|
279
|
+
readonly required: true;
|
|
280
|
+
readonly description: "Registered task name.";
|
|
281
|
+
};
|
|
282
|
+
readonly phase: {
|
|
283
|
+
readonly type: "string";
|
|
284
|
+
readonly required: true;
|
|
285
|
+
readonly description: "Invoked checkpoint phase.";
|
|
286
|
+
};
|
|
287
|
+
readonly outcome: {
|
|
288
|
+
readonly type: "string";
|
|
289
|
+
readonly required: true;
|
|
290
|
+
readonly description: "Phase outcome.";
|
|
291
|
+
};
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
readonly "pi.durable.tasks.active": {
|
|
295
|
+
readonly kind: "upDownCounter";
|
|
296
|
+
readonly description: "Live tasks held by this Harness; decremented at terminal settlement or close.";
|
|
297
|
+
readonly attributes: {
|
|
298
|
+
readonly task: {
|
|
299
|
+
readonly type: "string";
|
|
300
|
+
readonly required: true;
|
|
301
|
+
readonly description: "Registered task name.";
|
|
302
|
+
};
|
|
303
|
+
};
|
|
304
|
+
};
|
|
305
|
+
};
|
|
306
|
+
};
|
|
307
|
+
//# sourceMappingURL=telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/harness/telemetry.ts"],"names":[],"mappings":"AAgDA,6GAA6G;AAC7G,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAwBxB,kBAAkB;0CAtEjB,sEAAsE;;iCAElF,UAAU;qCAAI,IAAI,EAAE,QAAQ;qCAAE,QAAQ;qCAAQ,WAAW,EAAE,sBAAsB;qCAAE,WAAW,EAAE,MAAM;;iCACtG,YAAY;qCAAI,IAAI,EAAE,QAAQ;qCAAE,QAAQ;qCAAQ,WAAW,EAAE,aAAa;;;;gBAmEpC,uBAAuB;0CAjCjD,2BAA2B;;iCAEvC,eAAe;qCAAI,IAAI,EAAE,QAAQ;qCAAE,QAAQ;qCAAQ,WAAW,EAAE,gBAAgB;qCAAE,WAAW,EAAE,MAAM;;iCACrG,MAAM;qCAAI,IAAI,EAAE,QAAQ;qCAAE,QAAQ;qCAAQ,MAAM,YAAG,MAAM,EAAE,YAAY;qCAAG,WAAW,EAAE,aAAa;;iCACpG,iBAAiB;qCAAI,IAAI,EAAE,QAAQ;qCAAE,QAAQ;qCAAS,WAAW,EAAE,kBAAkB;qCAAE,WAAW,EAAE,MAAM;;;;gBA6B/B,mBAAmB;0CArClF,oDAAoD;;;qCAzBhE,IAAI,EAAE,QAAQ;qCACd,QAAQ;qCACR,WAAW,EAAE,kBAAkB;qCAC/B,MAAM,YACL,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,gBAAgB;;;qCAIjB,IAAI,EAAE,QAAQ;qCACd,QAAQ;qCACR,WAAW,EAAE,oCAAoC;qCACjD,MAAM,YAAG,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,mBAAmB;;;qCAE1D,IAAI,EAAE,QAAQ;qCAAE,QAAQ;qCAAS,WAAW,EAAE,0CAA0C;;;qCACxF,IAAI,EAAE,QAAQ;qCAAE,QAAQ;qCAAS,WAAW,EAAE,wBAAwB;qCAAE,WAAW,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAuFxF,IAAI;mCA7Gb,QAAQ;;0CAED,kBAAkB;+CAE9B,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmHjB,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { defineTelemetrySchema } from "@earendil-works/pi-telemetry";
|
|
2
|
+
const entry = {
|
|
3
|
+
description: "A transcript entry was committed; content remains in the transcript.",
|
|
4
|
+
attributes: {
|
|
5
|
+
"entry.id": { type: "number", required: true, description: "Transcript entry ID.", cardinality: "high" },
|
|
6
|
+
"entry.kind": { type: "string", required: true, description: "Entry kind." },
|
|
7
|
+
},
|
|
8
|
+
};
|
|
9
|
+
const reportAttributes = {
|
|
10
|
+
type: {
|
|
11
|
+
type: "string",
|
|
12
|
+
required: true,
|
|
13
|
+
description: "ReportInfo type.",
|
|
14
|
+
values: [
|
|
15
|
+
"session_failed",
|
|
16
|
+
"task_faulted",
|
|
17
|
+
"task_parked",
|
|
18
|
+
"migration_failed",
|
|
19
|
+
"task_outdated",
|
|
20
|
+
"task_error",
|
|
21
|
+
"extension_error",
|
|
22
|
+
"host_error",
|
|
23
|
+
"listener_error",
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
reason: {
|
|
27
|
+
type: "string",
|
|
28
|
+
required: false,
|
|
29
|
+
description: "Fixed report reason, when present.",
|
|
30
|
+
values: ["threw", "restart_limit", "missing_task", "incompatible_task"],
|
|
31
|
+
},
|
|
32
|
+
extension: { type: "string", required: false, description: "Registered extension name, when present." },
|
|
33
|
+
"task.id": { type: "number", required: false, description: "Task ID, when present.", cardinality: "high" },
|
|
34
|
+
};
|
|
35
|
+
const report = {
|
|
36
|
+
description: "A report was raised; no error payload is recorded.",
|
|
37
|
+
attributes: reportAttributes,
|
|
38
|
+
};
|
|
39
|
+
const submission = {
|
|
40
|
+
description: "A submission was settled.",
|
|
41
|
+
attributes: {
|
|
42
|
+
"submission.id": { type: "number", required: true, description: "Submission ID.", cardinality: "high" },
|
|
43
|
+
status: { type: "string", required: true, values: ["done", "unanswered"], description: "Settlement." },
|
|
44
|
+
"answer.entry_id": { type: "number", required: false, description: "Answer entry ID.", cardinality: "high" },
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
/** Durable's content-free span, event, and metric vocabulary. IDs address durable records, never content. */
|
|
48
|
+
export const DURABLE_TELEMETRY_SCHEMA = defineTelemetrySchema({
|
|
49
|
+
version: 1,
|
|
50
|
+
spans: {
|
|
51
|
+
"pi.durable.submit": {
|
|
52
|
+
description: "Public submission admission and its commit. Inputs start root traces linked to their callers; writes are children. Internal admissions emit phase events only.",
|
|
53
|
+
parents: { kind: "any" },
|
|
54
|
+
startAttributes: {
|
|
55
|
+
"submission.type": {
|
|
56
|
+
type: "string",
|
|
57
|
+
required: true,
|
|
58
|
+
values: ["input", "write"],
|
|
59
|
+
description: "Submission type.",
|
|
60
|
+
},
|
|
61
|
+
"conversation.id": { type: "number", required: true, description: "Conversation ID.", cardinality: "high" },
|
|
62
|
+
},
|
|
63
|
+
endAttributes: {
|
|
64
|
+
"submission.id": { type: "number", description: "Admitted submission ID.", cardinality: "high" },
|
|
65
|
+
result: {
|
|
66
|
+
type: "string",
|
|
67
|
+
values: ["queued", "placed", "done"],
|
|
68
|
+
description: "Admission result; stale writes report done.",
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
events: { "pi.durable.entry": entry, "pi.durable.submission": submission, "pi.durable.report": report },
|
|
72
|
+
status: { default: "ok", errorWhen: "Admission failed." },
|
|
73
|
+
},
|
|
74
|
+
"pi.durable.phase": {
|
|
75
|
+
description: "One task phase invocation, including its decision commit, never a wait or restart.",
|
|
76
|
+
parents: { kind: "any" },
|
|
77
|
+
startAttributes: {
|
|
78
|
+
"task.id": { type: "number", required: true, description: "Task ID.", cardinality: "high" },
|
|
79
|
+
"task.name": { type: "string", required: true, description: "Registered task name." },
|
|
80
|
+
phase: { type: "string", required: true, description: "Invoked checkpoint phase." },
|
|
81
|
+
kind: { type: "string", required: true, values: ["run", "abort"], description: "Invocation kind." },
|
|
82
|
+
attempt: { type: "number", required: false, description: "Checkpoint attempt, when present." },
|
|
83
|
+
resumed: {
|
|
84
|
+
type: "boolean",
|
|
85
|
+
required: true,
|
|
86
|
+
description: "First invocation of a task loaded in this process.",
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
endAttributes: {
|
|
90
|
+
outcome: { type: "string", description: "next=<phase>, waiting, sleeping, done, faulted, or aborted." },
|
|
91
|
+
"tool.name": { type: "string", description: "Called tool name." },
|
|
92
|
+
"tool.call_id": { type: "string", description: "Transcript tool call ID.", cardinality: "high" },
|
|
93
|
+
},
|
|
94
|
+
events: {
|
|
95
|
+
"pi.durable.entry": entry,
|
|
96
|
+
"pi.durable.submission": submission,
|
|
97
|
+
"pi.durable.report": report,
|
|
98
|
+
"pi.durable.checkpoint": {
|
|
99
|
+
description: "The running checkpoint's phase changed while the invocation continued.",
|
|
100
|
+
attributes: { phase: { type: "string", required: true, description: "Committed checkpoint phase." } },
|
|
101
|
+
},
|
|
102
|
+
"pi.durable.replay": {
|
|
103
|
+
description: "A nested tool call was answered from its stored result.",
|
|
104
|
+
attributes: { "tool.name": { type: "string", required: true, description: "Called tool name." } },
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
status: {
|
|
108
|
+
default: "ok",
|
|
109
|
+
errorWhen: "Faulted, failed, and orphaned outcomes use task_faulted, task_failed, and task_orphaned with a diagnostic capped at 500 characters. Aborted outcomes keep status ok.",
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
metrics: {
|
|
114
|
+
"pi.durable.reports": {
|
|
115
|
+
kind: "counter",
|
|
116
|
+
description: "Reports raised, grouped by their fixed ReportInfo type.",
|
|
117
|
+
attributes: { type: reportAttributes.type },
|
|
118
|
+
},
|
|
119
|
+
"pi.durable.phase.duration": {
|
|
120
|
+
kind: "histogram",
|
|
121
|
+
unit: "ms",
|
|
122
|
+
description: "Duration of a phase invocation and its decision commit.",
|
|
123
|
+
attributes: {
|
|
124
|
+
task: { type: "string", required: true, description: "Registered task name." },
|
|
125
|
+
phase: { type: "string", required: true, description: "Invoked checkpoint phase." },
|
|
126
|
+
outcome: { type: "string", required: true, description: "Phase outcome." },
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
"pi.durable.tasks.active": {
|
|
130
|
+
kind: "upDownCounter",
|
|
131
|
+
description: "Live tasks held by this Harness; decremented at terminal settlement or close.",
|
|
132
|
+
attributes: { task: { type: "string", required: true, description: "Registered task name." } },
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/harness/telemetry.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineTelemetrySchema } from \"@earendil-works/pi-telemetry\";\n\nconst entry = {\n\tdescription: \"A transcript entry was committed; content remains in the transcript.\",\n\tattributes: {\n\t\t\"entry.id\": { type: \"number\", required: true, description: \"Transcript entry ID.\", cardinality: \"high\" },\n\t\t\"entry.kind\": { type: \"string\", required: true, description: \"Entry kind.\" },\n\t},\n} as const;\nconst reportAttributes = {\n\ttype: {\n\t\ttype: \"string\",\n\t\trequired: true,\n\t\tdescription: \"ReportInfo type.\",\n\t\tvalues: [\n\t\t\t\"session_failed\",\n\t\t\t\"task_faulted\",\n\t\t\t\"task_parked\",\n\t\t\t\"migration_failed\",\n\t\t\t\"task_outdated\",\n\t\t\t\"task_error\",\n\t\t\t\"extension_error\",\n\t\t\t\"host_error\",\n\t\t\t\"listener_error\",\n\t\t],\n\t},\n\treason: {\n\t\ttype: \"string\",\n\t\trequired: false,\n\t\tdescription: \"Fixed report reason, when present.\",\n\t\tvalues: [\"threw\", \"restart_limit\", \"missing_task\", \"incompatible_task\"],\n\t},\n\textension: { type: \"string\", required: false, description: \"Registered extension name, when present.\" },\n\t\"task.id\": { type: \"number\", required: false, description: \"Task ID, when present.\", cardinality: \"high\" },\n} as const;\nconst report = {\n\tdescription: \"A report was raised; no error payload is recorded.\",\n\tattributes: reportAttributes,\n} as const;\nconst submission = {\n\tdescription: \"A submission was settled.\",\n\tattributes: {\n\t\t\"submission.id\": { type: \"number\", required: true, description: \"Submission ID.\", cardinality: \"high\" },\n\t\tstatus: { type: \"string\", required: true, values: [\"done\", \"unanswered\"], description: \"Settlement.\" },\n\t\t\"answer.entry_id\": { type: \"number\", required: false, description: \"Answer entry ID.\", cardinality: \"high\" },\n\t},\n} as const;\n\n/** Durable's content-free span, event, and metric vocabulary. IDs address durable records, never content. */\nexport const DURABLE_TELEMETRY_SCHEMA = defineTelemetrySchema({\n\tversion: 1,\n\tspans: {\n\t\t\"pi.durable.submit\": {\n\t\t\tdescription:\n\t\t\t\t\"Public submission admission and its commit. Inputs start root traces linked to their callers; writes are children. Internal admissions emit phase events only.\",\n\t\t\tparents: { kind: \"any\" },\n\t\t\tstartAttributes: {\n\t\t\t\t\"submission.type\": {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tvalues: [\"input\", \"write\"],\n\t\t\t\t\tdescription: \"Submission type.\",\n\t\t\t\t},\n\t\t\t\t\"conversation.id\": { type: \"number\", required: true, description: \"Conversation ID.\", cardinality: \"high\" },\n\t\t\t},\n\t\t\tendAttributes: {\n\t\t\t\t\"submission.id\": { type: \"number\", description: \"Admitted submission ID.\", cardinality: \"high\" },\n\t\t\t\tresult: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tvalues: [\"queued\", \"placed\", \"done\"],\n\t\t\t\t\tdescription: \"Admission result; stale writes report done.\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tevents: { \"pi.durable.entry\": entry, \"pi.durable.submission\": submission, \"pi.durable.report\": report },\n\t\t\tstatus: { default: \"ok\", errorWhen: \"Admission failed.\" },\n\t\t},\n\t\t\"pi.durable.phase\": {\n\t\t\tdescription: \"One task phase invocation, including its decision commit, never a wait or restart.\",\n\t\t\tparents: { kind: \"any\" },\n\t\t\tstartAttributes: {\n\t\t\t\t\"task.id\": { type: \"number\", required: true, description: \"Task ID.\", cardinality: \"high\" },\n\t\t\t\t\"task.name\": { type: \"string\", required: true, description: \"Registered task name.\" },\n\t\t\t\tphase: { type: \"string\", required: true, description: \"Invoked checkpoint phase.\" },\n\t\t\t\tkind: { type: \"string\", required: true, values: [\"run\", \"abort\"], description: \"Invocation kind.\" },\n\t\t\t\tattempt: { type: \"number\", required: false, description: \"Checkpoint attempt, when present.\" },\n\t\t\t\tresumed: {\n\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\trequired: true,\n\t\t\t\t\tdescription: \"First invocation of a task loaded in this process.\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tendAttributes: {\n\t\t\t\toutcome: { type: \"string\", description: \"next=<phase>, waiting, sleeping, done, faulted, or aborted.\" },\n\t\t\t\t\"tool.name\": { type: \"string\", description: \"Called tool name.\" },\n\t\t\t\t\"tool.call_id\": { type: \"string\", description: \"Transcript tool call ID.\", cardinality: \"high\" },\n\t\t\t},\n\t\t\tevents: {\n\t\t\t\t\"pi.durable.entry\": entry,\n\t\t\t\t\"pi.durable.submission\": submission,\n\t\t\t\t\"pi.durable.report\": report,\n\t\t\t\t\"pi.durable.checkpoint\": {\n\t\t\t\t\tdescription: \"The running checkpoint's phase changed while the invocation continued.\",\n\t\t\t\t\tattributes: { phase: { type: \"string\", required: true, description: \"Committed checkpoint phase.\" } },\n\t\t\t\t},\n\t\t\t\t\"pi.durable.replay\": {\n\t\t\t\t\tdescription: \"A nested tool call was answered from its stored result.\",\n\t\t\t\t\tattributes: { \"tool.name\": { type: \"string\", required: true, description: \"Called tool name.\" } },\n\t\t\t\t},\n\t\t\t},\n\t\t\tstatus: {\n\t\t\t\tdefault: \"ok\",\n\t\t\t\terrorWhen:\n\t\t\t\t\t\"Faulted, failed, and orphaned outcomes use task_faulted, task_failed, and task_orphaned with a diagnostic capped at 500 characters. Aborted outcomes keep status ok.\",\n\t\t\t},\n\t\t},\n\t},\n\tmetrics: {\n\t\t\"pi.durable.reports\": {\n\t\t\tkind: \"counter\",\n\t\t\tdescription: \"Reports raised, grouped by their fixed ReportInfo type.\",\n\t\t\tattributes: { type: reportAttributes.type },\n\t\t},\n\t\t\"pi.durable.phase.duration\": {\n\t\t\tkind: \"histogram\",\n\t\t\tunit: \"ms\",\n\t\t\tdescription: \"Duration of a phase invocation and its decision commit.\",\n\t\t\tattributes: {\n\t\t\t\ttask: { type: \"string\", required: true, description: \"Registered task name.\" },\n\t\t\t\tphase: { type: \"string\", required: true, description: \"Invoked checkpoint phase.\" },\n\t\t\t\toutcome: { type: \"string\", required: true, description: \"Phase outcome.\" },\n\t\t\t},\n\t\t},\n\t\t\"pi.durable.tasks.active\": {\n\t\t\tkind: \"upDownCounter\",\n\t\t\tdescription: \"Live tasks held by this Harness; decremented at terminal settlement or close.\",\n\t\t\tattributes: { task: { type: \"string\", required: true, description: \"Registered task name.\" } },\n\t\t},\n\t},\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/harness/tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,kBAAkB,EAAkB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/harness/tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,kBAAkB,EAAkB,MAAM,uBAAuB,CAAC;AAWpH,OAAO,KAAK,EAA6B,QAAQ,EAAqB,MAAM,uBAAuB,CAAC;AASpG,OAAO,KAAK,EACX,cAAc,EACd,OAAO,EACP,UAAU,EACV,IAAI,EACJ,MAAM,EAIN,EAAE,EACF,UAAU,EACV,MAAM,aAAa,CAAC;AAarB,OAAO,KAAK,EACX,yBAAyB,EACzB,WAAW,EACX,cAAc,EAEd,mBAAmB,EAEnB,SAAS,EAET,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,MAAM,MAAM,aAAa,GACtB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrD;IACA,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,CAAC;IACf,0GAA0G;IAC1G,QAAQ,CAAC,EAAE,KAAK,CAAC;CAChB,CAAC;AAEL,MAAM,MAAM,kBAAkB,GAC3B;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE;AACnB,2FAA2F;GACzF;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAA;CAAE,CAAC;AAE1E;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,WAAW,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAQ7G,kFAAkF;AAClF,MAAM,MAAM,eAAe,GAAG;IAC7B,mGAAmG;IACnG,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;IAChC,oHAAoH;IACpH,MAAM,CAAC,EAAE,kBAAkB,CAAC,yBAAyB,CAAC,CAAC;CACvD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,iEAQxB,CAAC;AAKH;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,oEAuFnB,CAAC;AAsnBH,oGAAoG;AACpG,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAE/E;AAwCD;;;GAGG;AACH,wBAAsB,gBAAgB,CACrC,EAAE,EAAE,EAAE,EACN,cAAc,EAAE,cAAc,EAC9B,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,mBAAmB,EAC3B,IAAI,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAChE,OAAO,CAAC,UAAU,CAAC;IAAE,WAAW,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC,CAAC,CAkBxD"}
|
package/dist/harness/tool.js
CHANGED
|
@@ -9,9 +9,11 @@ import { AssistantEntry, ToolResultEntry } from "../entries.js";
|
|
|
9
9
|
import { errorMessage } from "../errors.js";
|
|
10
10
|
import { defineTask } from "../tasks.js";
|
|
11
11
|
import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, utf8ByteLength } from "../truncate.js";
|
|
12
|
+
import { toolExtension } from "./agent.js";
|
|
12
13
|
import { assignJson } from "./json.js";
|
|
13
14
|
import { clearProgress, finishSlot, LiveDoc, removeNestedSlots, toolSlot, } from "./live.js";
|
|
14
15
|
import { recordUsage } from "./usage.js";
|
|
16
|
+
import { optionalExtension } from "./util.js";
|
|
15
17
|
/**
|
|
16
18
|
* Memo of a tool task that made a nested call, in any attempt, committed before the first admission of each attempt:
|
|
17
19
|
* only then can `pi.live` hold slots below it, which settling removes. A crash between the two only costs a scan.
|
|
@@ -28,6 +30,8 @@ export const NestedCallDoc = defineDocFamily({
|
|
|
28
30
|
scope: "task",
|
|
29
31
|
family: true,
|
|
30
32
|
initial: () => ({}),
|
|
33
|
+
// The document retires with its task.
|
|
34
|
+
checkpointWhen: () => false,
|
|
31
35
|
});
|
|
32
36
|
/**
|
|
33
37
|
* Built-in tool task: resolves the called tool among its phase agent's tools, validates, runs `beforeTool`, records intent,
|
|
@@ -137,8 +141,13 @@ async function resolveTool(runtime, input, name, context) {
|
|
|
137
141
|
}
|
|
138
142
|
/** The call: from the input for a nested call, which hooks see with its parent, else from the assistant entry. */
|
|
139
143
|
async function readCall(runtime, input, context) {
|
|
140
|
-
if (input.kind === "nested")
|
|
144
|
+
if (input.kind === "nested") {
|
|
145
|
+
context.telemetry.setAttributes({
|
|
146
|
+
"tool.name": input.call.name,
|
|
147
|
+
"tool.call_id": input.call.id,
|
|
148
|
+
});
|
|
141
149
|
return { ...input.call, parent: { taskId: input.parent, callId: input.parentCallId } };
|
|
150
|
+
}
|
|
142
151
|
const entry = await runtime.entry(AssistantEntry, input.assistant, context);
|
|
143
152
|
const message = entry?.model?.[0];
|
|
144
153
|
const call = message?.role === "assistant"
|
|
@@ -146,6 +155,10 @@ async function readCall(runtime, input, context) {
|
|
|
146
155
|
: undefined;
|
|
147
156
|
if (call === undefined)
|
|
148
157
|
throw new Error(`Entry ${input.assistant} has no tool call ${input.callId}`);
|
|
158
|
+
context.telemetry.setAttributes({
|
|
159
|
+
"tool.name": call.name,
|
|
160
|
+
"tool.call_id": call.id,
|
|
161
|
+
});
|
|
149
162
|
return call;
|
|
150
163
|
}
|
|
151
164
|
/** The call's arguments as repaired by the tool; a throwing repair makes them invalid. */
|
|
@@ -195,13 +208,21 @@ async function run(runtime, input, call, tool, args, context) {
|
|
|
195
208
|
if (ended)
|
|
196
209
|
throw new Error(`Tool call ${call.id} has settled`);
|
|
197
210
|
};
|
|
211
|
+
/** Built for this call, below, so a rerun after recovery gets the conversation's environment at that time. */
|
|
212
|
+
let env;
|
|
198
213
|
const api = {
|
|
199
214
|
taskId: runtime.taskId,
|
|
200
215
|
conversationId: runtime.conversationId,
|
|
201
216
|
callId: call.id,
|
|
202
217
|
registry: runtime.registry,
|
|
203
218
|
agent: runtime.agent,
|
|
204
|
-
models
|
|
219
|
+
get models() {
|
|
220
|
+
return runtime.models;
|
|
221
|
+
},
|
|
222
|
+
get env() {
|
|
223
|
+
return env;
|
|
224
|
+
},
|
|
225
|
+
now: () => runtime.now(),
|
|
205
226
|
output: (chunk, skipped) => {
|
|
206
227
|
assertLive();
|
|
207
228
|
if (reported.output.push(chunk, skipped))
|
|
@@ -285,11 +306,10 @@ async function run(runtime, input, call, tool, args, context) {
|
|
|
285
306
|
// Execution time of this attempt; a rerun after recovery measures only itself.
|
|
286
307
|
let durationMs;
|
|
287
308
|
try {
|
|
288
|
-
|
|
289
|
-
const env = await runtime.env(context);
|
|
309
|
+
env = await runtime.env(context);
|
|
290
310
|
const startedAt = performance.now();
|
|
291
311
|
try {
|
|
292
|
-
result = await tool.execute(args,
|
|
312
|
+
result = await tool.execute(args, api, context);
|
|
293
313
|
}
|
|
294
314
|
finally {
|
|
295
315
|
durationMs = Math.round(performance.now() - startedAt);
|
|
@@ -325,6 +345,25 @@ async function run(runtime, input, call, tool, args, context) {
|
|
|
325
345
|
for (const waiter of pending)
|
|
326
346
|
waiter.resolve();
|
|
327
347
|
}
|
|
348
|
+
/**
|
|
349
|
+
* The Harness clock and timers for progress pacing. After the invocation ends nothing more commits, and the clock
|
|
350
|
+
* answers with the last time it read.
|
|
351
|
+
*/
|
|
352
|
+
function progressClock(runtime) {
|
|
353
|
+
let last = 0;
|
|
354
|
+
return {
|
|
355
|
+
now: () => {
|
|
356
|
+
try {
|
|
357
|
+
last = runtime.now();
|
|
358
|
+
}
|
|
359
|
+
catch {
|
|
360
|
+
// The invocation ended.
|
|
361
|
+
}
|
|
362
|
+
return last;
|
|
363
|
+
},
|
|
364
|
+
setTimer: (callback, delayMs) => runtime.setTimer(callback, delayMs),
|
|
365
|
+
};
|
|
366
|
+
}
|
|
328
367
|
/**
|
|
329
368
|
* Throttled commits of what the tool reported into its slot, in `pi.live.tools` or `pi.live.nestedTools`, each writing
|
|
330
369
|
* only what changed since the last one; none when `enabled` is false.
|
|
@@ -382,7 +421,7 @@ function publishProgress(runtime, reported, enabled, context) {
|
|
|
382
421
|
// Rejections after an abort mark or close are expected; the committed state stays consistent.
|
|
383
422
|
if (!runtime.signal.aborted)
|
|
384
423
|
runtime.report(error);
|
|
385
|
-
}, runtime.settings.progress.outputIntervalMs);
|
|
424
|
+
}, runtime.settings.progress.outputIntervalMs, progressClock(runtime));
|
|
386
425
|
}
|
|
387
426
|
/**
|
|
388
427
|
* The settled result: the tool's result with the retained output and last details as fallbacks, its diagnostics after
|
|
@@ -420,7 +459,9 @@ async function finalResult(runtime, input, call, tool, result, reported, context
|
|
|
420
459
|
else {
|
|
421
460
|
// The model never sees structured output, so its call stands; the host learns of the broken tool.
|
|
422
461
|
final = rest;
|
|
423
|
-
|
|
462
|
+
// Only names the extension: a failed resolution leaves the report without the name.
|
|
463
|
+
const extension = await runtime.agent(context).then((agent) => toolExtension(agent, tool.name), () => undefined);
|
|
464
|
+
runtime.report(new Error(broken), { type: "extension", ...optionalExtension(extension) });
|
|
424
465
|
}
|
|
425
466
|
}
|
|
426
467
|
// Programs get the tool's own value: without a schema, its output. The model reads only `output`, so model-issued
|
|
@@ -561,6 +602,7 @@ async function startNestedCall(runtime, parentCallId, name, args, options, conte
|
|
|
561
602
|
arguments: copyJson(args, { omitUndefinedProperties: true }),
|
|
562
603
|
};
|
|
563
604
|
let id;
|
|
605
|
+
let replayed = false;
|
|
564
606
|
await runtime.commit(async (tx) => {
|
|
565
607
|
// Opened, or created empty for a key not made yet.
|
|
566
608
|
const state = await tx.doc(NestedCallDoc, runtime.taskId, key, null);
|
|
@@ -573,6 +615,7 @@ async function startNestedCall(runtime, parentCallId, name, args, options, conte
|
|
|
573
615
|
if (!same)
|
|
574
616
|
throw new Error(`Nested call ${call.id} was already made with another tool or other arguments`);
|
|
575
617
|
id = existing;
|
|
618
|
+
replayed = state.result !== undefined;
|
|
576
619
|
return undefined;
|
|
577
620
|
}
|
|
578
621
|
const input = {
|
|
@@ -603,6 +646,9 @@ async function startNestedCall(runtime, parentCallId, name, args, options, conte
|
|
|
603
646
|
id = created;
|
|
604
647
|
return undefined;
|
|
605
648
|
}, context);
|
|
649
|
+
if (replayed) {
|
|
650
|
+
context.telemetry.addEvent("pi.durable.replay", { "tool.name": name });
|
|
651
|
+
}
|
|
606
652
|
return id;
|
|
607
653
|
}
|
|
608
654
|
/**
|