@vitest-evals/harness-pi-ai 0.9.0-beta.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/LICENSE +201 -0
- package/README.md +106 -0
- package/dist/index.d.mts +73 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.js +670 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +657 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +35 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,670 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
piAiHarness: () => piAiHarness
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
var import_harness = require("vitest-evals/harness");
|
|
27
|
+
var import_replay = require("vitest-evals/replay");
|
|
28
|
+
var ORIGINAL_NATIVE_EXECUTE = Symbol("vitest-evals.originalNativeExecute");
|
|
29
|
+
function piAiHarness(options) {
|
|
30
|
+
return {
|
|
31
|
+
name: options.name ?? "pi-ai",
|
|
32
|
+
run: async (input, context) => {
|
|
33
|
+
const agent = await resolveAgent(options);
|
|
34
|
+
const messages = [
|
|
35
|
+
{
|
|
36
|
+
role: "user",
|
|
37
|
+
content: (0, import_harness.normalizeContent)(input)
|
|
38
|
+
}
|
|
39
|
+
];
|
|
40
|
+
const inferredTools = resolveInferredToolSurfaces(
|
|
41
|
+
agent
|
|
42
|
+
);
|
|
43
|
+
if (hasExplicitToolset(options)) {
|
|
44
|
+
return executePiHarnessRun(
|
|
45
|
+
options,
|
|
46
|
+
agent,
|
|
47
|
+
input,
|
|
48
|
+
context,
|
|
49
|
+
messages,
|
|
50
|
+
options.tools,
|
|
51
|
+
inferredTools.nativeToolsets
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
return executePiHarnessRun(
|
|
55
|
+
options,
|
|
56
|
+
agent,
|
|
57
|
+
input,
|
|
58
|
+
context,
|
|
59
|
+
messages,
|
|
60
|
+
inferredTools.runtimeTools,
|
|
61
|
+
inferredTools.nativeToolsets
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
async function executePiHarnessRun(options, agent, input, context, messages, runtimeTools, nativeToolsets) {
|
|
67
|
+
const runtime = createRuntime({
|
|
68
|
+
input,
|
|
69
|
+
context,
|
|
70
|
+
tools: runtimeTools,
|
|
71
|
+
messages
|
|
72
|
+
});
|
|
73
|
+
try {
|
|
74
|
+
const result = await withInstrumentedAgentTools(
|
|
75
|
+
agent,
|
|
76
|
+
nativeToolsets,
|
|
77
|
+
{
|
|
78
|
+
input,
|
|
79
|
+
context,
|
|
80
|
+
messages,
|
|
81
|
+
toolCalls: runtime.toolCalls
|
|
82
|
+
},
|
|
83
|
+
() => runAgent(options, {
|
|
84
|
+
agent,
|
|
85
|
+
input,
|
|
86
|
+
context,
|
|
87
|
+
runtime
|
|
88
|
+
})
|
|
89
|
+
);
|
|
90
|
+
if ((0, import_harness.isHarnessRun)(result) && !hasResultOverrides(options)) {
|
|
91
|
+
if (Object.keys(context.artifacts).length > 0 && !result.artifacts) {
|
|
92
|
+
result.artifacts = context.artifacts;
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
const normalizeResult = result;
|
|
97
|
+
const resultArgs = {
|
|
98
|
+
agent,
|
|
99
|
+
input,
|
|
100
|
+
context,
|
|
101
|
+
runtime,
|
|
102
|
+
result: normalizeResult
|
|
103
|
+
};
|
|
104
|
+
const output = options.normalize?.output ? await options.normalize.output(resultArgs) : resolveOutput(normalizeResult);
|
|
105
|
+
const usage = options.normalize?.usage ? await options.normalize.usage(resultArgs) : resolveUsage(normalizeResult, runtime.toolCalls.length);
|
|
106
|
+
const session = options.normalize?.session ? await options.normalize.session(resultArgs) : resolveSession(normalizeResult, messages, output, usage);
|
|
107
|
+
return {
|
|
108
|
+
session,
|
|
109
|
+
output,
|
|
110
|
+
usage,
|
|
111
|
+
timings: options.normalize?.timings ? await options.normalize.timings(resultArgs) : void 0,
|
|
112
|
+
artifacts: Object.keys(context.artifacts).length > 0 ? context.artifacts : void 0,
|
|
113
|
+
errors: options.normalize?.errors ? await options.normalize.errors(resultArgs) : resolveErrors(normalizeResult)
|
|
114
|
+
};
|
|
115
|
+
} catch (error) {
|
|
116
|
+
const usage = resolveUsage(void 0, runtime.toolCalls.length);
|
|
117
|
+
const run = {
|
|
118
|
+
session: resolveSession(void 0, messages, void 0, usage),
|
|
119
|
+
output: void 0,
|
|
120
|
+
usage,
|
|
121
|
+
artifacts: Object.keys(context.artifacts).length > 0 ? context.artifacts : void 0,
|
|
122
|
+
errors: [(0, import_harness.serializeError)(error)]
|
|
123
|
+
};
|
|
124
|
+
throw (0, import_harness.attachHarnessRunToError)(error, run);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async function resolveAgent(options) {
|
|
128
|
+
if (options.agent !== void 0) {
|
|
129
|
+
return options.agent;
|
|
130
|
+
}
|
|
131
|
+
if (options.createAgent) {
|
|
132
|
+
return options.createAgent();
|
|
133
|
+
}
|
|
134
|
+
throw new Error(
|
|
135
|
+
"piAiHarness requires either an agent instance or a createAgent() function."
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
function hasResultOverrides(options) {
|
|
139
|
+
return Boolean(
|
|
140
|
+
options.normalize?.output ?? options.normalize?.session ?? options.normalize?.usage ?? options.normalize?.timings ?? options.normalize?.errors
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
function resolveInferredToolSurfaces(agent) {
|
|
144
|
+
let runtimeTools;
|
|
145
|
+
const nativeToolsets = [];
|
|
146
|
+
const seenToolsets = /* @__PURE__ */ new Set();
|
|
147
|
+
for (const candidate of getAgentToolCandidates(agent)) {
|
|
148
|
+
const nextRuntimeTools = getRuntimeToolset(candidate);
|
|
149
|
+
if (runtimeTools === void 0 && nextRuntimeTools !== void 0) {
|
|
150
|
+
runtimeTools = nextRuntimeTools;
|
|
151
|
+
}
|
|
152
|
+
const nativeTools = getNativeToolArray(candidate);
|
|
153
|
+
if (nativeTools && !seenToolsets.has(nativeTools)) {
|
|
154
|
+
seenToolsets.add(nativeTools);
|
|
155
|
+
nativeToolsets.push(nativeTools);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
...runtimeTools ? { runtimeTools } : {},
|
|
160
|
+
...nativeToolsets.length > 0 ? { nativeToolsets } : {}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function getAgentToolCandidates(agent) {
|
|
164
|
+
const roots = getAgentRoots(agent);
|
|
165
|
+
const candidates = [];
|
|
166
|
+
const seen = /* @__PURE__ */ new Set();
|
|
167
|
+
for (const root of roots) {
|
|
168
|
+
addUniqueObject(candidates, seen, root);
|
|
169
|
+
addUniqueObject(candidates, seen, getObjectProperty(root, "state"));
|
|
170
|
+
addUniqueObject(candidates, seen, getObjectProperty(root, "initialState"));
|
|
171
|
+
}
|
|
172
|
+
return candidates;
|
|
173
|
+
}
|
|
174
|
+
function getAgentRoots(agent) {
|
|
175
|
+
return [asObject(agent)].concat(asObject(getObjectProperty(agent, "agent"))).filter((value) => value !== void 0);
|
|
176
|
+
}
|
|
177
|
+
function addUniqueObject(candidates, seen, value) {
|
|
178
|
+
if (!value || typeof value !== "object" || seen.has(value)) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
seen.add(value);
|
|
182
|
+
candidates.push(value);
|
|
183
|
+
}
|
|
184
|
+
function asObject(value) {
|
|
185
|
+
return value && typeof value === "object" ? value : void 0;
|
|
186
|
+
}
|
|
187
|
+
function getObjectProperty(value, key) {
|
|
188
|
+
return value && typeof value === "object" ? value[key] : void 0;
|
|
189
|
+
}
|
|
190
|
+
function getRuntimeToolset(value) {
|
|
191
|
+
const candidate = getObjectProperty(value, "tools") ?? getObjectProperty(value, "toolset");
|
|
192
|
+
return isPiAiToolset(candidate) ? candidate : void 0;
|
|
193
|
+
}
|
|
194
|
+
function getNativeToolArray(value) {
|
|
195
|
+
const candidate = getObjectProperty(value, "tools");
|
|
196
|
+
if (isAgentToolArray(candidate)) {
|
|
197
|
+
return candidate;
|
|
198
|
+
}
|
|
199
|
+
return void 0;
|
|
200
|
+
}
|
|
201
|
+
async function runAgent(options, args) {
|
|
202
|
+
if (options.run) {
|
|
203
|
+
return options.run(args);
|
|
204
|
+
}
|
|
205
|
+
if (hasPiAiRunMethod(args.agent)) {
|
|
206
|
+
return args.agent.run(args.input, args.runtime);
|
|
207
|
+
}
|
|
208
|
+
throw new Error(
|
|
209
|
+
"piAiHarness requires a run() function unless the provided agent exposes run(input, runtime)."
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
function hasExplicitToolset(options) {
|
|
213
|
+
return options.tools !== void 0;
|
|
214
|
+
}
|
|
215
|
+
function hasPiAiRunMethod(agent) {
|
|
216
|
+
if (!agent || typeof agent !== "object") {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
return "run" in agent && typeof agent.run === "function";
|
|
220
|
+
}
|
|
221
|
+
function isPiAiToolset(value) {
|
|
222
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
const tools = Object.values(value);
|
|
226
|
+
return tools.length > 0 && tools.every(
|
|
227
|
+
(tool) => Boolean(
|
|
228
|
+
tool && typeof tool === "object" && "execute" in tool && typeof tool.execute === "function"
|
|
229
|
+
)
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
function isAgentToolArray(value) {
|
|
233
|
+
return Array.isArray(value) && value.every(
|
|
234
|
+
(tool) => Boolean(
|
|
235
|
+
tool && typeof tool === "object" && "name" in tool && typeof tool.name === "string" && "execute" in tool && typeof tool.execute === "function"
|
|
236
|
+
)
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
async function withInstrumentedAgentTools(agent, toolsets, args, callback) {
|
|
240
|
+
if (!toolsets || toolsets.length === 0) {
|
|
241
|
+
return callback();
|
|
242
|
+
}
|
|
243
|
+
const originalExecutions = /* @__PURE__ */ new Map();
|
|
244
|
+
const originalResets = /* @__PURE__ */ new Map();
|
|
245
|
+
const patchTool = (tool) => {
|
|
246
|
+
if (originalExecutions.has(tool)) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
const originalExecute = getNativeToolExecuteOrigin(tool.execute);
|
|
250
|
+
originalExecutions.set(tool, originalExecute);
|
|
251
|
+
const instrumentedExecute = async (toolCallId, rawArgs) => {
|
|
252
|
+
const startedAt = /* @__PURE__ */ new Date();
|
|
253
|
+
const toolContext = {
|
|
254
|
+
input: args.input,
|
|
255
|
+
metadata: args.context.metadata,
|
|
256
|
+
signal: args.context.signal,
|
|
257
|
+
setArtifact: args.context.setArtifact
|
|
258
|
+
};
|
|
259
|
+
try {
|
|
260
|
+
const execution = await executeNativeToolWithReplay({
|
|
261
|
+
toolName: tool.name,
|
|
262
|
+
toolCallId,
|
|
263
|
+
execute: originalExecute,
|
|
264
|
+
replay: tool.replay,
|
|
265
|
+
args: rawArgs,
|
|
266
|
+
context: toolContext
|
|
267
|
+
});
|
|
268
|
+
const finishedAt = /* @__PURE__ */ new Date();
|
|
269
|
+
const call = {
|
|
270
|
+
name: tool.name,
|
|
271
|
+
arguments: rawArgs,
|
|
272
|
+
result: execution.normalizedResult,
|
|
273
|
+
startedAt: startedAt.toISOString(),
|
|
274
|
+
finishedAt: finishedAt.toISOString(),
|
|
275
|
+
durationMs: finishedAt.getTime() - startedAt.getTime(),
|
|
276
|
+
metadata: (0, import_replay.normalizeReplayMetadata)(execution.replay)
|
|
277
|
+
};
|
|
278
|
+
args.toolCalls.push(call);
|
|
279
|
+
args.messages.push({
|
|
280
|
+
role: "assistant",
|
|
281
|
+
toolCalls: [call]
|
|
282
|
+
});
|
|
283
|
+
args.messages.push({
|
|
284
|
+
role: "tool",
|
|
285
|
+
content: execution.normalizedResult,
|
|
286
|
+
metadata: {
|
|
287
|
+
name: tool.name
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
return execution.result;
|
|
291
|
+
} catch (error) {
|
|
292
|
+
const finishedAt = /* @__PURE__ */ new Date();
|
|
293
|
+
const call = {
|
|
294
|
+
name: tool.name,
|
|
295
|
+
arguments: rawArgs,
|
|
296
|
+
error: serializeToolCallError(error),
|
|
297
|
+
startedAt: startedAt.toISOString(),
|
|
298
|
+
finishedAt: finishedAt.toISOString(),
|
|
299
|
+
durationMs: finishedAt.getTime() - startedAt.getTime(),
|
|
300
|
+
metadata: (0, import_replay.normalizeReplayMetadata)((0, import_replay.getReplayMetadataFromError)(error))
|
|
301
|
+
};
|
|
302
|
+
args.toolCalls.push(call);
|
|
303
|
+
args.messages.push({
|
|
304
|
+
role: "assistant",
|
|
305
|
+
toolCalls: [call]
|
|
306
|
+
});
|
|
307
|
+
throw error;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
instrumentedExecute[ORIGINAL_NATIVE_EXECUTE] = originalExecute;
|
|
311
|
+
tool.execute = instrumentedExecute;
|
|
312
|
+
};
|
|
313
|
+
const patchToolsets = (nextToolsets) => {
|
|
314
|
+
for (const toolset of nextToolsets) {
|
|
315
|
+
for (const tool of toolset) {
|
|
316
|
+
patchTool(tool);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
patchToolsets(toolsets);
|
|
321
|
+
for (const target of getAgentResetTargets(agent)) {
|
|
322
|
+
const originalReset = target.reset;
|
|
323
|
+
originalResets.set(target, originalReset);
|
|
324
|
+
target.reset = function patchedReset(...resetArgs) {
|
|
325
|
+
const resetResult = originalReset.apply(this, resetArgs);
|
|
326
|
+
if (isPromiseLike(resetResult)) {
|
|
327
|
+
return resetResult.finally(() => {
|
|
328
|
+
patchToolsets(
|
|
329
|
+
resolveInferredNativeToolsets(agent)
|
|
330
|
+
);
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
patchToolsets(resolveInferredNativeToolsets(agent));
|
|
334
|
+
return resetResult;
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
try {
|
|
338
|
+
return await callback();
|
|
339
|
+
} finally {
|
|
340
|
+
for (const [target, originalReset] of originalResets) {
|
|
341
|
+
target.reset = originalReset;
|
|
342
|
+
}
|
|
343
|
+
for (const [tool, originalExecute] of originalExecutions) {
|
|
344
|
+
tool.execute = originalExecute;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
function getAgentResetTargets(agent) {
|
|
349
|
+
return getAgentRoots(agent).filter(isResettableAgent);
|
|
350
|
+
}
|
|
351
|
+
function isResettableAgent(value) {
|
|
352
|
+
return "reset" in value && typeof value.reset === "function";
|
|
353
|
+
}
|
|
354
|
+
function resolveInferredNativeToolsets(agent) {
|
|
355
|
+
const toolsets = [];
|
|
356
|
+
const seenToolsets = /* @__PURE__ */ new Set();
|
|
357
|
+
for (const candidate of getAgentToolCandidates(agent)) {
|
|
358
|
+
const nativeTools = getNativeToolArray(candidate);
|
|
359
|
+
if (nativeTools && !seenToolsets.has(nativeTools)) {
|
|
360
|
+
seenToolsets.add(nativeTools);
|
|
361
|
+
toolsets.push(nativeTools);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return toolsets;
|
|
365
|
+
}
|
|
366
|
+
function isPromiseLike(value) {
|
|
367
|
+
return Boolean(
|
|
368
|
+
value && typeof value.then === "function"
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
function serializeToolCallError(error) {
|
|
372
|
+
const serialized = (0, import_harness.serializeError)(error);
|
|
373
|
+
const { message, type, ...details } = serialized;
|
|
374
|
+
return {
|
|
375
|
+
...details,
|
|
376
|
+
message: typeof message === "string" ? message : String(message),
|
|
377
|
+
...typeof type === "string" ? { type } : {}
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
function getNativeToolExecuteOrigin(execute) {
|
|
381
|
+
const nativeExecute = execute;
|
|
382
|
+
return nativeExecute[ORIGINAL_NATIVE_EXECUTE] ?? nativeExecute;
|
|
383
|
+
}
|
|
384
|
+
async function executeNativeToolWithReplay({
|
|
385
|
+
toolName,
|
|
386
|
+
toolCallId,
|
|
387
|
+
execute,
|
|
388
|
+
replay,
|
|
389
|
+
args,
|
|
390
|
+
context
|
|
391
|
+
}) {
|
|
392
|
+
let didExecute = false;
|
|
393
|
+
let liveResult;
|
|
394
|
+
const execution = await (0, import_replay.executeWithReplay)({
|
|
395
|
+
toolName,
|
|
396
|
+
args,
|
|
397
|
+
context,
|
|
398
|
+
execute: async (toolArgs) => {
|
|
399
|
+
didExecute = true;
|
|
400
|
+
liveResult = await execute(toolCallId, toolArgs);
|
|
401
|
+
return createNativeToolReplayEnvelope(liveResult);
|
|
402
|
+
},
|
|
403
|
+
replay
|
|
404
|
+
});
|
|
405
|
+
if (didExecute) {
|
|
406
|
+
return {
|
|
407
|
+
result: liveResult,
|
|
408
|
+
normalizedResult: normalizeReplayToolResult(liveResult),
|
|
409
|
+
replay: execution.replay
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
return {
|
|
413
|
+
...resolveNativeToolReplayResult(execution.result),
|
|
414
|
+
replay: execution.replay
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
function createRuntime({
|
|
418
|
+
input,
|
|
419
|
+
context,
|
|
420
|
+
tools,
|
|
421
|
+
messages
|
|
422
|
+
}) {
|
|
423
|
+
const toolCalls = [];
|
|
424
|
+
const eventSink = {
|
|
425
|
+
message: (message) => {
|
|
426
|
+
messages.push(message);
|
|
427
|
+
},
|
|
428
|
+
system: (content, metadata) => {
|
|
429
|
+
messages.push({
|
|
430
|
+
role: "system",
|
|
431
|
+
content,
|
|
432
|
+
metadata
|
|
433
|
+
});
|
|
434
|
+
},
|
|
435
|
+
user: (content, metadata) => {
|
|
436
|
+
messages.push({
|
|
437
|
+
role: "user",
|
|
438
|
+
content,
|
|
439
|
+
metadata
|
|
440
|
+
});
|
|
441
|
+
},
|
|
442
|
+
assistant: (content, metadata) => {
|
|
443
|
+
messages.push({
|
|
444
|
+
role: "assistant",
|
|
445
|
+
content,
|
|
446
|
+
metadata
|
|
447
|
+
});
|
|
448
|
+
},
|
|
449
|
+
tool: (name, content, metadata) => {
|
|
450
|
+
messages.push({
|
|
451
|
+
role: "tool",
|
|
452
|
+
content,
|
|
453
|
+
metadata: {
|
|
454
|
+
name,
|
|
455
|
+
...metadata ?? {}
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
const runtimeTools = Object.fromEntries(
|
|
461
|
+
Object.entries(tools ?? {}).map(([toolName, tool]) => [
|
|
462
|
+
toolName,
|
|
463
|
+
async (args) => {
|
|
464
|
+
const startedAt = /* @__PURE__ */ new Date();
|
|
465
|
+
const toolContext = {
|
|
466
|
+
input,
|
|
467
|
+
metadata: context.metadata,
|
|
468
|
+
signal: context.signal,
|
|
469
|
+
setArtifact: context.setArtifact
|
|
470
|
+
};
|
|
471
|
+
try {
|
|
472
|
+
const execution = await executeToolWithReplay({
|
|
473
|
+
toolName,
|
|
474
|
+
tool,
|
|
475
|
+
args,
|
|
476
|
+
context: toolContext
|
|
477
|
+
});
|
|
478
|
+
const finishedAt = /* @__PURE__ */ new Date();
|
|
479
|
+
const call = {
|
|
480
|
+
name: toolName,
|
|
481
|
+
arguments: args,
|
|
482
|
+
result: execution.result,
|
|
483
|
+
startedAt: startedAt.toISOString(),
|
|
484
|
+
finishedAt: finishedAt.toISOString(),
|
|
485
|
+
durationMs: finishedAt.getTime() - startedAt.getTime(),
|
|
486
|
+
metadata: (0, import_replay.normalizeReplayMetadata)(execution.replay)
|
|
487
|
+
};
|
|
488
|
+
toolCalls.push(call);
|
|
489
|
+
messages.push({
|
|
490
|
+
role: "assistant",
|
|
491
|
+
toolCalls: [call]
|
|
492
|
+
});
|
|
493
|
+
messages.push({
|
|
494
|
+
role: "tool",
|
|
495
|
+
content: execution.result,
|
|
496
|
+
metadata: {
|
|
497
|
+
name: toolName
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
return execution.result;
|
|
501
|
+
} catch (error) {
|
|
502
|
+
const finishedAt = /* @__PURE__ */ new Date();
|
|
503
|
+
const call = {
|
|
504
|
+
name: toolName,
|
|
505
|
+
arguments: args,
|
|
506
|
+
error: serializeToolCallError(error),
|
|
507
|
+
startedAt: startedAt.toISOString(),
|
|
508
|
+
finishedAt: finishedAt.toISOString(),
|
|
509
|
+
durationMs: finishedAt.getTime() - startedAt.getTime(),
|
|
510
|
+
metadata: (0, import_replay.normalizeReplayMetadata)(
|
|
511
|
+
(0, import_replay.getReplayMetadataFromError)(error)
|
|
512
|
+
)
|
|
513
|
+
};
|
|
514
|
+
toolCalls.push(call);
|
|
515
|
+
messages.push({
|
|
516
|
+
role: "assistant",
|
|
517
|
+
toolCalls: [call]
|
|
518
|
+
});
|
|
519
|
+
throw error;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
])
|
|
523
|
+
);
|
|
524
|
+
return {
|
|
525
|
+
tools: runtimeTools,
|
|
526
|
+
events: eventSink,
|
|
527
|
+
signal: context.signal,
|
|
528
|
+
toolCalls
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
function resolveOutput(result) {
|
|
532
|
+
if (!result || typeof result !== "object") {
|
|
533
|
+
return (0, import_harness.toJsonValue)(result);
|
|
534
|
+
}
|
|
535
|
+
const candidates = [
|
|
536
|
+
"output",
|
|
537
|
+
"decision",
|
|
538
|
+
"result",
|
|
539
|
+
"final"
|
|
540
|
+
];
|
|
541
|
+
for (const key of candidates) {
|
|
542
|
+
const value = result[key];
|
|
543
|
+
const normalized = (0, import_harness.toJsonValue)(value);
|
|
544
|
+
if (normalized !== void 0) {
|
|
545
|
+
return normalized;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
return void 0;
|
|
549
|
+
}
|
|
550
|
+
function normalizeToolResult(result) {
|
|
551
|
+
const details = result && typeof result === "object" ? (0, import_harness.toJsonValue)(result.details) : void 0;
|
|
552
|
+
if (details !== void 0) {
|
|
553
|
+
return details;
|
|
554
|
+
}
|
|
555
|
+
return (0, import_harness.toJsonValue)(result) ?? (result === void 0 ? void 0 : String(result));
|
|
556
|
+
}
|
|
557
|
+
function normalizeReplayToolResult(result) {
|
|
558
|
+
return normalizeToolResult(result) ?? null;
|
|
559
|
+
}
|
|
560
|
+
function createNativeToolReplayEnvelope(result) {
|
|
561
|
+
const normalizedResult = normalizeReplayToolResult(result);
|
|
562
|
+
return {
|
|
563
|
+
__vitestEvals: {
|
|
564
|
+
kind: "pi-ai-native-tool-result",
|
|
565
|
+
version: 2
|
|
566
|
+
},
|
|
567
|
+
agentResult: (0, import_harness.toJsonValue)(result) ?? normalizedResult,
|
|
568
|
+
normalizedResult
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
function resolveNativeToolReplayResult(result) {
|
|
572
|
+
if (isNativeToolReplayEnvelope(result)) {
|
|
573
|
+
return {
|
|
574
|
+
result: result.agentResult,
|
|
575
|
+
normalizedResult: result.normalizedResult
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
if (isLegacyNativeToolReplayEnvelope(result)) {
|
|
579
|
+
return {
|
|
580
|
+
result: result.agentResult ?? result.normalizedResult,
|
|
581
|
+
normalizedResult: result.normalizedResult
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
return {
|
|
585
|
+
result,
|
|
586
|
+
normalizedResult: normalizeReplayToolResult(result)
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
function isNativeToolReplayEnvelope(value) {
|
|
590
|
+
return Boolean(
|
|
591
|
+
value && typeof value === "object" && "__vitestEvals" in value && isNativeToolReplayMarker(
|
|
592
|
+
value.__vitestEvals
|
|
593
|
+
) && "agentResult" in value && "normalizedResult" in value
|
|
594
|
+
);
|
|
595
|
+
}
|
|
596
|
+
function isNativeToolReplayMarker(value) {
|
|
597
|
+
return Boolean(
|
|
598
|
+
value && typeof value === "object" && "kind" in value && value.kind === "pi-ai-native-tool-result" && "version" in value && value.version === 2
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
function isLegacyNativeToolReplayEnvelope(value) {
|
|
602
|
+
return Boolean(
|
|
603
|
+
value && typeof value === "object" && "__vitestEvals" in value && isLegacyNativeToolReplayMarker(
|
|
604
|
+
value.__vitestEvals
|
|
605
|
+
) && "normalizedResult" in value
|
|
606
|
+
);
|
|
607
|
+
}
|
|
608
|
+
function isLegacyNativeToolReplayMarker(value) {
|
|
609
|
+
return Boolean(
|
|
610
|
+
value && typeof value === "object" && "kind" in value && value.kind === "pi-ai-native-tool-result" && "version" in value && value.version === 1
|
|
611
|
+
);
|
|
612
|
+
}
|
|
613
|
+
function resolveUsage(result, toolCallCount) {
|
|
614
|
+
if (!result || typeof result !== "object") {
|
|
615
|
+
return toolCallCount > 0 ? { toolCalls: toolCallCount } : {};
|
|
616
|
+
}
|
|
617
|
+
const usageValue = result.usage ?? result.metrics;
|
|
618
|
+
const usage = usageValue && typeof usageValue === "object" ? { ...usageValue } : {};
|
|
619
|
+
if (usage.toolCalls === void 0 && toolCallCount > 0) {
|
|
620
|
+
usage.toolCalls = toolCallCount;
|
|
621
|
+
}
|
|
622
|
+
return usage;
|
|
623
|
+
}
|
|
624
|
+
function resolveSession(result, messages, output, usage) {
|
|
625
|
+
if ((0, import_harness.isNormalizedSession)(
|
|
626
|
+
result?.session
|
|
627
|
+
)) {
|
|
628
|
+
return result.session;
|
|
629
|
+
}
|
|
630
|
+
if ((0, import_harness.isNormalizedSession)(result?.trace)) {
|
|
631
|
+
return result.trace;
|
|
632
|
+
}
|
|
633
|
+
const sessionMessages = [...messages];
|
|
634
|
+
if (output !== void 0 && !sessionMessages.some(
|
|
635
|
+
(message) => message.role === "assistant" && message.content !== void 0
|
|
636
|
+
)) {
|
|
637
|
+
sessionMessages.push({
|
|
638
|
+
role: "assistant",
|
|
639
|
+
content: output
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
return {
|
|
643
|
+
messages: sessionMessages,
|
|
644
|
+
outputText: typeof output === "string" ? output : void 0,
|
|
645
|
+
provider: result?.provider ?? usage.provider,
|
|
646
|
+
model: result?.model ?? usage.model
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
function resolveErrors(result) {
|
|
650
|
+
return (0, import_harness.resolveHarnessRunErrors)(result);
|
|
651
|
+
}
|
|
652
|
+
async function executeToolWithReplay({
|
|
653
|
+
toolName,
|
|
654
|
+
tool,
|
|
655
|
+
args,
|
|
656
|
+
context
|
|
657
|
+
}) {
|
|
658
|
+
return (0, import_replay.executeWithReplay)({
|
|
659
|
+
toolName,
|
|
660
|
+
args,
|
|
661
|
+
context,
|
|
662
|
+
execute: tool.execute,
|
|
663
|
+
replay: tool.replay
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
667
|
+
0 && (module.exports = {
|
|
668
|
+
piAiHarness
|
|
669
|
+
});
|
|
670
|
+
//# sourceMappingURL=index.js.map
|