agentv 4.25.1 → 4.25.3-next.1
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/dist/{agentv-provider-TXM4UEUT-SUZSAXWZ.js → agentv-provider-MUIGGIP3-QCGXJ3CT.js} +2 -2
- package/dist/{artifact-writer-HGCLGCCA.js → artifact-writer-ARFT3NKG.js} +5 -7
- package/dist/chunk-55QZVA5X.js +616 -0
- package/dist/chunk-55QZVA5X.js.map +1 -0
- package/dist/{chunk-5Z3QIGCT.js → chunk-7QHCH76N.js} +11 -15
- package/dist/chunk-7QHCH76N.js.map +1 -0
- package/dist/{chunk-BTHPLK43.js → chunk-FFDOEJ4U.js} +18334 -14538
- package/dist/chunk-FFDOEJ4U.js.map +1 -0
- package/dist/{chunk-VBMGJOS6.js → chunk-GKARL6LO.js} +3 -3
- package/dist/{chunk-BAUNAXHT.js → chunk-HSHTTN6C.js} +6 -6
- package/dist/{chunk-SR4I5KET.js → chunk-R3CXYNTN.js} +8 -8
- package/dist/{chunk-ZQ5YI3RR.js → chunk-TCW46QGJ.js} +6 -6
- package/dist/{chunk-AWSSD3XU.js → chunk-YKILE6GM.js} +27 -12
- package/dist/chunk-YKILE6GM.js.map +1 -0
- package/dist/cli.js +6 -8
- package/dist/cli.js.map +1 -1
- package/dist/{dist-ACKVXAB3.js → dist-NRGR7DDX.js} +4 -6
- package/dist/{esm-UYZ3HJBU.js → esm-NNMQYIKT.js} +4 -4
- package/dist/{esm-QNEMCJPL.js → esm-TTEMJEVV.js} +3 -3
- package/dist/{esm-ZADQ4XQH-5LX2IKZV.js → esm-ZADQ4XQH-QUFGGZL4.js} +8 -8
- package/dist/index.js +6 -8
- package/dist/{interactive-A42HOUBD.js → interactive-GZ22O32V.js} +6 -8
- package/dist/{interactive-A42HOUBD.js.map → interactive-GZ22O32V.js.map} +1 -1
- package/dist/{src-PXDA7QIS.js → src-76ISS3LH.js} +9 -9
- package/dist/templates/.agentv/targets.yaml +31 -0
- package/dist/{ts-eval-loader-4CFPGHGT-CVAN5S2D.js → ts-eval-loader-E6MROJGR-DBF6BDCY.js} +3 -5
- package/package.json +2 -2
- package/dist/chunk-5Z3QIGCT.js.map +0 -1
- package/dist/chunk-AWSSD3XU.js.map +0 -1
- package/dist/chunk-BTHPLK43.js.map +0 -1
- package/dist/chunk-HQDCIXVH.js +0 -51
- package/dist/chunk-HQDCIXVH.js.map +0 -1
- package/dist/chunk-JFD3TI3N.js +0 -456
- package/dist/chunk-JFD3TI3N.js.map +0 -1
- package/dist/chunk-ZKO2LGRR.js +0 -25365
- package/dist/chunk-ZKO2LGRR.js.map +0 -1
- package/dist/token-OWTDW6LT.js +0 -66
- package/dist/token-OWTDW6LT.js.map +0 -1
- package/dist/token-util-S5R2C23V.js +0 -8
- package/dist/ts-eval-loader-4CFPGHGT-CVAN5S2D.js.map +0 -1
- /package/dist/{agentv-provider-TXM4UEUT-SUZSAXWZ.js.map → agentv-provider-MUIGGIP3-QCGXJ3CT.js.map} +0 -0
- /package/dist/{artifact-writer-HGCLGCCA.js.map → artifact-writer-ARFT3NKG.js.map} +0 -0
- /package/dist/{chunk-VBMGJOS6.js.map → chunk-GKARL6LO.js.map} +0 -0
- /package/dist/{chunk-BAUNAXHT.js.map → chunk-HSHTTN6C.js.map} +0 -0
- /package/dist/{chunk-SR4I5KET.js.map → chunk-R3CXYNTN.js.map} +0 -0
- /package/dist/{chunk-ZQ5YI3RR.js.map → chunk-TCW46QGJ.js.map} +0 -0
- /package/dist/{dist-ACKVXAB3.js.map → dist-NRGR7DDX.js.map} +0 -0
- /package/dist/{esm-UYZ3HJBU.js.map → esm-NNMQYIKT.js.map} +0 -0
- /package/dist/{esm-QNEMCJPL.js.map → esm-TTEMJEVV.js.map} +0 -0
- /package/dist/{esm-ZADQ4XQH-5LX2IKZV.js.map → esm-ZADQ4XQH-QUFGGZL4.js.map} +0 -0
- /package/dist/{src-PXDA7QIS.js.map → src-76ISS3LH.js.map} +0 -0
- /package/dist/{token-util-S5R2C23V.js.map → ts-eval-loader-E6MROJGR-DBF6BDCY.js.map} +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
AgentvProvider
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-55QZVA5X.js";
|
|
5
5
|
import "./chunk-5H446C7X.js";
|
|
6
6
|
export {
|
|
7
7
|
AgentvProvider
|
|
8
8
|
};
|
|
9
|
-
//# sourceMappingURL=agentv-provider-
|
|
9
|
+
//# sourceMappingURL=agentv-provider-MUIGGIP3-QCGXJ3CT.js.map
|
|
@@ -13,15 +13,13 @@ import {
|
|
|
13
13
|
writeArtifacts,
|
|
14
14
|
writeArtifactsFromResults,
|
|
15
15
|
writePerTestArtifacts
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-GKARL6LO.js";
|
|
17
|
+
import "./chunk-7QHCH76N.js";
|
|
18
18
|
import "./chunk-QOBQ5XYF.js";
|
|
19
19
|
import "./chunk-BPGJ4HBU.js";
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-ZKO2LGRR.js";
|
|
20
|
+
import "./chunk-FFDOEJ4U.js";
|
|
22
21
|
import "./chunk-NPVGBFF6.js";
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-LRULMAAA.js";
|
|
22
|
+
import "./chunk-55QZVA5X.js";
|
|
25
23
|
import "./chunk-5H446C7X.js";
|
|
26
24
|
export {
|
|
27
25
|
aggregateRunDir,
|
|
@@ -38,4 +36,4 @@ export {
|
|
|
38
36
|
writeArtifactsFromResults,
|
|
39
37
|
writePerTestArtifacts
|
|
40
38
|
};
|
|
41
|
-
//# sourceMappingURL=artifact-writer-
|
|
39
|
+
//# sourceMappingURL=artifact-writer-ARFT3NKG.js.map
|
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// ../../packages/core/dist/chunk-5XV3FAAD.js
|
|
4
|
+
import {
|
|
5
|
+
complete as piComplete,
|
|
6
|
+
getModel as piGetModel,
|
|
7
|
+
registerBuiltInApiProviders
|
|
8
|
+
} from "@mariozechner/pi-ai";
|
|
9
|
+
registerBuiltInApiProviders();
|
|
10
|
+
var DEFAULT_SYSTEM_PROMPT = "You are a careful assistant. Follow all provided instructions and do not fabricate results.";
|
|
11
|
+
var OpenAIProvider = class {
|
|
12
|
+
id;
|
|
13
|
+
kind = "openai";
|
|
14
|
+
targetName;
|
|
15
|
+
piModel;
|
|
16
|
+
defaults;
|
|
17
|
+
retryConfig;
|
|
18
|
+
apiKey;
|
|
19
|
+
constructor(targetName, config) {
|
|
20
|
+
this.id = `openai:${targetName}`;
|
|
21
|
+
this.targetName = targetName;
|
|
22
|
+
this.apiKey = config.apiKey;
|
|
23
|
+
this.defaults = {
|
|
24
|
+
temperature: config.temperature,
|
|
25
|
+
maxOutputTokens: config.maxOutputTokens
|
|
26
|
+
};
|
|
27
|
+
this.retryConfig = config.retry;
|
|
28
|
+
this.piModel = resolvePiModel({
|
|
29
|
+
providerName: "openai",
|
|
30
|
+
apiId: config.apiFormat === "responses" ? "openai-responses" : "openai-completions",
|
|
31
|
+
modelId: config.model,
|
|
32
|
+
baseUrl: config.baseURL
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async invoke(request) {
|
|
36
|
+
return invokePiAi({
|
|
37
|
+
model: this.piModel,
|
|
38
|
+
apiKey: this.apiKey,
|
|
39
|
+
request,
|
|
40
|
+
defaults: this.defaults,
|
|
41
|
+
retryConfig: this.retryConfig
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
var OpenRouterProvider = class {
|
|
46
|
+
id;
|
|
47
|
+
kind = "openrouter";
|
|
48
|
+
targetName;
|
|
49
|
+
piModel;
|
|
50
|
+
defaults;
|
|
51
|
+
retryConfig;
|
|
52
|
+
apiKey;
|
|
53
|
+
constructor(targetName, config) {
|
|
54
|
+
this.id = `openrouter:${targetName}`;
|
|
55
|
+
this.targetName = targetName;
|
|
56
|
+
this.apiKey = config.apiKey;
|
|
57
|
+
this.defaults = {
|
|
58
|
+
temperature: config.temperature,
|
|
59
|
+
maxOutputTokens: config.maxOutputTokens
|
|
60
|
+
};
|
|
61
|
+
this.retryConfig = config.retry;
|
|
62
|
+
this.piModel = resolvePiModel({
|
|
63
|
+
providerName: "openrouter",
|
|
64
|
+
apiId: "openai-completions",
|
|
65
|
+
modelId: config.model,
|
|
66
|
+
baseUrl: "https://openrouter.ai/api/v1"
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
async invoke(request) {
|
|
70
|
+
return invokePiAi({
|
|
71
|
+
model: this.piModel,
|
|
72
|
+
apiKey: this.apiKey,
|
|
73
|
+
request,
|
|
74
|
+
defaults: this.defaults,
|
|
75
|
+
retryConfig: this.retryConfig
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
var AnthropicProvider = class {
|
|
80
|
+
id;
|
|
81
|
+
kind = "anthropic";
|
|
82
|
+
targetName;
|
|
83
|
+
piModel;
|
|
84
|
+
defaults;
|
|
85
|
+
retryConfig;
|
|
86
|
+
apiKey;
|
|
87
|
+
thinkingBudget;
|
|
88
|
+
constructor(targetName, config) {
|
|
89
|
+
this.id = `anthropic:${targetName}`;
|
|
90
|
+
this.targetName = targetName;
|
|
91
|
+
this.apiKey = config.apiKey;
|
|
92
|
+
this.thinkingBudget = config.thinkingBudget;
|
|
93
|
+
this.defaults = {
|
|
94
|
+
temperature: config.temperature,
|
|
95
|
+
maxOutputTokens: config.maxOutputTokens,
|
|
96
|
+
thinkingBudget: config.thinkingBudget
|
|
97
|
+
};
|
|
98
|
+
this.retryConfig = config.retry;
|
|
99
|
+
this.piModel = resolvePiModel({
|
|
100
|
+
providerName: "anthropic",
|
|
101
|
+
apiId: "anthropic-messages",
|
|
102
|
+
modelId: config.model
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
async invoke(request) {
|
|
106
|
+
const providerOptions = this.thinkingBudget !== void 0 ? { thinkingEnabled: true, thinkingBudgetTokens: this.thinkingBudget } : void 0;
|
|
107
|
+
return invokePiAi({
|
|
108
|
+
model: this.piModel,
|
|
109
|
+
apiKey: this.apiKey,
|
|
110
|
+
request,
|
|
111
|
+
defaults: this.defaults,
|
|
112
|
+
retryConfig: this.retryConfig,
|
|
113
|
+
...providerOptions ? { providerOptions } : {}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
var GeminiProvider = class {
|
|
118
|
+
id;
|
|
119
|
+
kind = "gemini";
|
|
120
|
+
targetName;
|
|
121
|
+
piModel;
|
|
122
|
+
defaults;
|
|
123
|
+
retryConfig;
|
|
124
|
+
apiKey;
|
|
125
|
+
constructor(targetName, config) {
|
|
126
|
+
this.id = `gemini:${targetName}`;
|
|
127
|
+
this.targetName = targetName;
|
|
128
|
+
this.apiKey = config.apiKey;
|
|
129
|
+
this.defaults = {
|
|
130
|
+
temperature: config.temperature,
|
|
131
|
+
maxOutputTokens: config.maxOutputTokens
|
|
132
|
+
};
|
|
133
|
+
this.retryConfig = config.retry;
|
|
134
|
+
this.piModel = resolvePiModel({
|
|
135
|
+
providerName: "google",
|
|
136
|
+
apiId: "google-generative-ai",
|
|
137
|
+
modelId: config.model
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
async invoke(request) {
|
|
141
|
+
return invokePiAi({
|
|
142
|
+
model: this.piModel,
|
|
143
|
+
apiKey: this.apiKey,
|
|
144
|
+
request,
|
|
145
|
+
defaults: this.defaults,
|
|
146
|
+
retryConfig: this.retryConfig
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
var AzureProvider = class {
|
|
151
|
+
id;
|
|
152
|
+
kind = "azure";
|
|
153
|
+
targetName;
|
|
154
|
+
piModel;
|
|
155
|
+
defaults;
|
|
156
|
+
retryConfig;
|
|
157
|
+
apiKey;
|
|
158
|
+
providerOptions;
|
|
159
|
+
constructor(targetName, config) {
|
|
160
|
+
this.id = `azure:${targetName}`;
|
|
161
|
+
this.targetName = targetName;
|
|
162
|
+
this.apiKey = config.apiKey;
|
|
163
|
+
this.defaults = {
|
|
164
|
+
temperature: config.temperature,
|
|
165
|
+
maxOutputTokens: config.maxOutputTokens
|
|
166
|
+
};
|
|
167
|
+
this.retryConfig = config.retry;
|
|
168
|
+
const trimmed = config.resourceName.trim();
|
|
169
|
+
const isFullUrl = /^https?:\/\//i.test(trimmed);
|
|
170
|
+
const baseUrl = isFullUrl ? buildAzureBaseUrl(trimmed) : void 0;
|
|
171
|
+
this.providerOptions = {
|
|
172
|
+
...baseUrl ? { azureBaseUrl: baseUrl } : { azureResourceName: trimmed },
|
|
173
|
+
...config.version ? { azureApiVersion: config.version } : {}
|
|
174
|
+
};
|
|
175
|
+
this.piModel = resolvePiModel({
|
|
176
|
+
providerName: "azure-openai-responses",
|
|
177
|
+
apiId: "azure-openai-responses",
|
|
178
|
+
// The "model id" for Azure is the deployment name.
|
|
179
|
+
modelId: config.deploymentName,
|
|
180
|
+
...baseUrl ? { baseUrl } : {}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
async invoke(request) {
|
|
184
|
+
return invokePiAi({
|
|
185
|
+
model: this.piModel,
|
|
186
|
+
apiKey: this.apiKey,
|
|
187
|
+
request,
|
|
188
|
+
defaults: this.defaults,
|
|
189
|
+
retryConfig: this.retryConfig,
|
|
190
|
+
providerOptions: this.providerOptions
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
function buildAzureBaseUrl(input) {
|
|
195
|
+
const trimmed = input.replace(/\/+$/, "");
|
|
196
|
+
if (trimmed.endsWith("/openai/v1")) return trimmed;
|
|
197
|
+
if (trimmed.endsWith("/openai")) return `${trimmed}/v1`;
|
|
198
|
+
return `${trimmed}/openai/v1`;
|
|
199
|
+
}
|
|
200
|
+
async function invokePiAi(options) {
|
|
201
|
+
const { model, apiKey, request, defaults, retryConfig, providerOptions } = options;
|
|
202
|
+
const tools = request.tools && request.tools.length > 0 ? request.tools : void 0;
|
|
203
|
+
const maxSteps = tools ? Math.max(1, request.maxSteps ?? 1) : 1;
|
|
204
|
+
const { systemPrompt, messages } = chatPromptToPiContext(buildChatPrompt(request));
|
|
205
|
+
if (request.images && request.images.length > 0) {
|
|
206
|
+
attachImagesToLastUserMessage(messages, request.images);
|
|
207
|
+
}
|
|
208
|
+
const piTools = tools ? tools.map((t) => ({
|
|
209
|
+
name: t.name,
|
|
210
|
+
description: t.description,
|
|
211
|
+
parameters: t.parameters
|
|
212
|
+
})) : void 0;
|
|
213
|
+
const ctx = { systemPrompt, messages, ...piTools ? { tools: piTools } : {} };
|
|
214
|
+
const { temperature, maxOutputTokens } = resolveModelSettings(request, defaults);
|
|
215
|
+
const callOptions = {
|
|
216
|
+
...apiKey !== void 0 ? { apiKey } : {},
|
|
217
|
+
temperature,
|
|
218
|
+
...maxOutputTokens !== void 0 ? { maxTokens: maxOutputTokens } : {},
|
|
219
|
+
signal: request.signal,
|
|
220
|
+
...providerOptions ?? {}
|
|
221
|
+
};
|
|
222
|
+
const startTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
223
|
+
const startMs = Date.now();
|
|
224
|
+
const aggregateUsage = { input: 0, output: 0, cacheRead: 0, cost: 0 };
|
|
225
|
+
let stepCount = 0;
|
|
226
|
+
let toolCallCount = 0;
|
|
227
|
+
let result = await withRetry(
|
|
228
|
+
() => piComplete(model, ctx, callOptions),
|
|
229
|
+
retryConfig,
|
|
230
|
+
request.signal
|
|
231
|
+
);
|
|
232
|
+
ctx.messages.push(result);
|
|
233
|
+
stepCount = 1;
|
|
234
|
+
accumulateUsage(aggregateUsage, result.usage);
|
|
235
|
+
while (tools) {
|
|
236
|
+
const calls = result.content.filter(
|
|
237
|
+
(b) => b.type === "toolCall"
|
|
238
|
+
);
|
|
239
|
+
if (calls.length === 0) break;
|
|
240
|
+
if (stepCount >= maxSteps) break;
|
|
241
|
+
toolCallCount += calls.length;
|
|
242
|
+
for (const call of calls) {
|
|
243
|
+
const tool = tools.find((t) => t.name === call.name);
|
|
244
|
+
let output;
|
|
245
|
+
let isError = false;
|
|
246
|
+
try {
|
|
247
|
+
if (!tool) {
|
|
248
|
+
throw new Error(`pi-ai adapter: model called unknown tool '${call.name}'`);
|
|
249
|
+
}
|
|
250
|
+
output = await tool.execute(call.arguments);
|
|
251
|
+
} catch (err) {
|
|
252
|
+
output = err instanceof Error ? err.message : String(err);
|
|
253
|
+
isError = true;
|
|
254
|
+
}
|
|
255
|
+
ctx.messages.push({
|
|
256
|
+
role: "toolResult",
|
|
257
|
+
toolCallId: call.id,
|
|
258
|
+
toolName: call.name,
|
|
259
|
+
content: [
|
|
260
|
+
{ type: "text", text: typeof output === "string" ? output : JSON.stringify(output) }
|
|
261
|
+
],
|
|
262
|
+
isError,
|
|
263
|
+
timestamp: Date.now()
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
result = await withRetry(
|
|
267
|
+
() => piComplete(model, ctx, callOptions),
|
|
268
|
+
retryConfig,
|
|
269
|
+
request.signal
|
|
270
|
+
);
|
|
271
|
+
ctx.messages.push(result);
|
|
272
|
+
stepCount += 1;
|
|
273
|
+
accumulateUsage(aggregateUsage, result.usage);
|
|
274
|
+
}
|
|
275
|
+
const endTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
276
|
+
const durationMs = Date.now() - startMs;
|
|
277
|
+
return mapPiResponse(result, {
|
|
278
|
+
durationMs,
|
|
279
|
+
startTime,
|
|
280
|
+
endTime,
|
|
281
|
+
aggregateUsage,
|
|
282
|
+
steps: tools ? { count: stepCount, toolCallCount } : void 0
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
function accumulateUsage(agg, u) {
|
|
286
|
+
agg.input += u.input;
|
|
287
|
+
agg.output += u.output;
|
|
288
|
+
agg.cacheRead += u.cacheRead;
|
|
289
|
+
agg.cost += u.cost.total;
|
|
290
|
+
}
|
|
291
|
+
function resolvePiModel(args) {
|
|
292
|
+
const { providerName, apiId, modelId, baseUrl } = args;
|
|
293
|
+
let model;
|
|
294
|
+
try {
|
|
295
|
+
model = piGetModel(providerName, modelId);
|
|
296
|
+
} catch {
|
|
297
|
+
model = void 0;
|
|
298
|
+
}
|
|
299
|
+
if (!model) {
|
|
300
|
+
const fallbackBaseUrl = baseUrl ?? defaultBaseUrlFor(providerName);
|
|
301
|
+
if (!fallbackBaseUrl) {
|
|
302
|
+
throw new Error(
|
|
303
|
+
`pi-ai adapter cannot resolve a baseUrl for provider '${providerName}' / model '${modelId}'. Either set the target's baseUrl/endpoint or use a model id pi-ai recognizes.`
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
model = {
|
|
307
|
+
id: modelId,
|
|
308
|
+
name: modelId,
|
|
309
|
+
api: apiId,
|
|
310
|
+
provider: providerName,
|
|
311
|
+
baseUrl: fallbackBaseUrl,
|
|
312
|
+
reasoning: false,
|
|
313
|
+
input: ["text"],
|
|
314
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
315
|
+
contextWindow: 128e3,
|
|
316
|
+
maxTokens: 16384
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
if (model.api !== apiId) {
|
|
320
|
+
model = { ...model, api: apiId };
|
|
321
|
+
}
|
|
322
|
+
if (baseUrl) {
|
|
323
|
+
model = { ...model, baseUrl };
|
|
324
|
+
}
|
|
325
|
+
return model;
|
|
326
|
+
}
|
|
327
|
+
function defaultBaseUrlFor(providerName) {
|
|
328
|
+
if (providerName === "openai") return "https://api.openai.com/v1";
|
|
329
|
+
if (providerName === "openrouter") return "https://openrouter.ai/api/v1";
|
|
330
|
+
return void 0;
|
|
331
|
+
}
|
|
332
|
+
function chatPromptToPiContext(chatPrompt) {
|
|
333
|
+
const systemSegments = [];
|
|
334
|
+
const messages = [];
|
|
335
|
+
const now = Date.now();
|
|
336
|
+
for (const message of chatPrompt) {
|
|
337
|
+
if (message.role === "system") {
|
|
338
|
+
systemSegments.push(message.content);
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
if (message.role === "user") {
|
|
342
|
+
messages.push({ role: "user", content: message.content, timestamp: now });
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
if (message.role === "assistant") {
|
|
346
|
+
messages.push({
|
|
347
|
+
role: "assistant",
|
|
348
|
+
content: [{ type: "text", text: message.content }],
|
|
349
|
+
api: "",
|
|
350
|
+
provider: "",
|
|
351
|
+
model: "",
|
|
352
|
+
usage: {
|
|
353
|
+
input: 0,
|
|
354
|
+
output: 0,
|
|
355
|
+
cacheRead: 0,
|
|
356
|
+
cacheWrite: 0,
|
|
357
|
+
totalTokens: 0,
|
|
358
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
|
|
359
|
+
},
|
|
360
|
+
stopReason: "stop",
|
|
361
|
+
timestamp: now
|
|
362
|
+
});
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (message.role === "tool" || message.role === "function") {
|
|
366
|
+
const prefix = message.name ? `@[${message.name}]: ` : "@[Tool]: ";
|
|
367
|
+
messages.push({
|
|
368
|
+
role: "assistant",
|
|
369
|
+
content: [{ type: "text", text: `${prefix}${message.content}` }],
|
|
370
|
+
api: "",
|
|
371
|
+
provider: "",
|
|
372
|
+
model: "",
|
|
373
|
+
usage: {
|
|
374
|
+
input: 0,
|
|
375
|
+
output: 0,
|
|
376
|
+
cacheRead: 0,
|
|
377
|
+
cacheWrite: 0,
|
|
378
|
+
totalTokens: 0,
|
|
379
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
|
|
380
|
+
},
|
|
381
|
+
stopReason: "stop",
|
|
382
|
+
timestamp: now
|
|
383
|
+
});
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
throw new Error(`pi-ai adapter received unsupported message role '${message.role}'.`);
|
|
387
|
+
}
|
|
388
|
+
return {
|
|
389
|
+
systemPrompt: systemSegments.length > 0 ? systemSegments.join("\n\n") : void 0,
|
|
390
|
+
messages
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
function attachImagesToLastUserMessage(messages, images) {
|
|
394
|
+
if (!images || images.length === 0) return;
|
|
395
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
396
|
+
const m = messages[i];
|
|
397
|
+
if (m.role !== "user") continue;
|
|
398
|
+
const text = typeof m.content === "string" ? m.content : "";
|
|
399
|
+
messages[i] = {
|
|
400
|
+
...m,
|
|
401
|
+
content: [
|
|
402
|
+
...text ? [{ type: "text", text }] : [],
|
|
403
|
+
...images.map((img) => ({
|
|
404
|
+
type: "image",
|
|
405
|
+
data: img.source,
|
|
406
|
+
mimeType: img.media_type
|
|
407
|
+
}))
|
|
408
|
+
]
|
|
409
|
+
};
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
messages.push({
|
|
413
|
+
role: "user",
|
|
414
|
+
content: images.map((img) => ({
|
|
415
|
+
type: "image",
|
|
416
|
+
data: img.source,
|
|
417
|
+
mimeType: img.media_type
|
|
418
|
+
})),
|
|
419
|
+
timestamp: Date.now()
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
function mapPiResponse(result, timing) {
|
|
423
|
+
const text = result.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
424
|
+
const cached = timing.aggregateUsage.cacheRead > 0 ? timing.aggregateUsage.cacheRead : void 0;
|
|
425
|
+
const tokenUsage = {
|
|
426
|
+
input: timing.aggregateUsage.input,
|
|
427
|
+
output: timing.aggregateUsage.output,
|
|
428
|
+
...cached !== void 0 ? { cached } : {}
|
|
429
|
+
};
|
|
430
|
+
const costUsd = timing.aggregateUsage.cost > 0 ? timing.aggregateUsage.cost : void 0;
|
|
431
|
+
return {
|
|
432
|
+
raw: result,
|
|
433
|
+
usage: toJsonObject(result.usage),
|
|
434
|
+
output: [{ role: "assistant", content: text }],
|
|
435
|
+
tokenUsage,
|
|
436
|
+
...costUsd !== void 0 ? { costUsd } : {},
|
|
437
|
+
durationMs: timing.durationMs,
|
|
438
|
+
startTime: timing.startTime,
|
|
439
|
+
endTime: timing.endTime,
|
|
440
|
+
...timing.steps ? { steps: timing.steps } : {}
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
function buildChatPrompt(request) {
|
|
444
|
+
const provided = request.chatPrompt?.length ? request.chatPrompt : void 0;
|
|
445
|
+
if (provided) {
|
|
446
|
+
const hasSystemMessage = provided.some((message) => message.role === "system");
|
|
447
|
+
if (hasSystemMessage) {
|
|
448
|
+
return provided;
|
|
449
|
+
}
|
|
450
|
+
const systemContent2 = resolveSystemContent(request);
|
|
451
|
+
return [{ role: "system", content: systemContent2 }, ...provided];
|
|
452
|
+
}
|
|
453
|
+
const systemContent = resolveSystemContent(request);
|
|
454
|
+
const userContent = request.question.trim();
|
|
455
|
+
return [
|
|
456
|
+
{ role: "system", content: systemContent },
|
|
457
|
+
{ role: "user", content: userContent }
|
|
458
|
+
];
|
|
459
|
+
}
|
|
460
|
+
function resolveSystemContent(request) {
|
|
461
|
+
if (request.systemPrompt && request.systemPrompt.trim().length > 0) {
|
|
462
|
+
return request.systemPrompt.trim();
|
|
463
|
+
}
|
|
464
|
+
return DEFAULT_SYSTEM_PROMPT;
|
|
465
|
+
}
|
|
466
|
+
function resolveModelSettings(request, defaults) {
|
|
467
|
+
return {
|
|
468
|
+
temperature: request.temperature ?? defaults.temperature,
|
|
469
|
+
maxOutputTokens: request.maxOutputTokens ?? defaults.maxOutputTokens
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
function toJsonObject(value) {
|
|
473
|
+
if (!value || typeof value !== "object") {
|
|
474
|
+
return void 0;
|
|
475
|
+
}
|
|
476
|
+
try {
|
|
477
|
+
return JSON.parse(JSON.stringify(value));
|
|
478
|
+
} catch {
|
|
479
|
+
return void 0;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
function extractStatus(error) {
|
|
483
|
+
if (!error || typeof error !== "object") return void 0;
|
|
484
|
+
const candidate = error;
|
|
485
|
+
const directStatus = candidate.status ?? candidate.statusCode;
|
|
486
|
+
if (typeof directStatus === "number" && Number.isFinite(directStatus)) {
|
|
487
|
+
return directStatus;
|
|
488
|
+
}
|
|
489
|
+
const responseStatus = typeof candidate.response === "object" && candidate.response ? candidate.response.status : void 0;
|
|
490
|
+
if (typeof responseStatus === "number" && Number.isFinite(responseStatus)) {
|
|
491
|
+
return responseStatus;
|
|
492
|
+
}
|
|
493
|
+
const message = typeof candidate.message === "string" ? candidate.message : void 0;
|
|
494
|
+
if (message) {
|
|
495
|
+
const match = message.match(/HTTP\s+(\d{3})/i);
|
|
496
|
+
if (match) {
|
|
497
|
+
const parsed = Number.parseInt(match[1], 10);
|
|
498
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return void 0;
|
|
502
|
+
}
|
|
503
|
+
function isNetworkError(error) {
|
|
504
|
+
if (!error || typeof error !== "object") return false;
|
|
505
|
+
const candidate = error;
|
|
506
|
+
if (candidate.name === "AbortError") return false;
|
|
507
|
+
const code = candidate.code;
|
|
508
|
+
if (typeof code === "string" && /^E(AI|CONN|HOST|NET|PIPE|TIME|REFUSED|RESET)/i.test(code)) {
|
|
509
|
+
return true;
|
|
510
|
+
}
|
|
511
|
+
const message = typeof candidate.message === "string" ? candidate.message : void 0;
|
|
512
|
+
if (message && /(network|fetch failed|ECONNRESET|ENOTFOUND|EAI_AGAIN|ETIMEDOUT|ECONNREFUSED)/i.test(message)) {
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
function isRetryableError(error, retryableStatusCodes) {
|
|
518
|
+
const status = extractStatus(error);
|
|
519
|
+
if (status === 401 || status === 403) return false;
|
|
520
|
+
if (typeof status === "number") return retryableStatusCodes.includes(status);
|
|
521
|
+
return isNetworkError(error);
|
|
522
|
+
}
|
|
523
|
+
function calculateRetryDelay(attempt, config) {
|
|
524
|
+
const delay = Math.min(
|
|
525
|
+
config.maxDelayMs,
|
|
526
|
+
config.initialDelayMs * config.backoffFactor ** attempt
|
|
527
|
+
);
|
|
528
|
+
return delay * (0.75 + Math.random() * 0.5);
|
|
529
|
+
}
|
|
530
|
+
async function sleep(ms) {
|
|
531
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
532
|
+
}
|
|
533
|
+
async function withRetry(fn, retryConfig, signal) {
|
|
534
|
+
const config = {
|
|
535
|
+
maxRetries: retryConfig?.maxRetries ?? 3,
|
|
536
|
+
initialDelayMs: retryConfig?.initialDelayMs ?? 1e3,
|
|
537
|
+
maxDelayMs: retryConfig?.maxDelayMs ?? 6e4,
|
|
538
|
+
backoffFactor: retryConfig?.backoffFactor ?? 2,
|
|
539
|
+
retryableStatusCodes: retryConfig?.retryableStatusCodes ?? [500, 408, 429, 502, 503, 504]
|
|
540
|
+
};
|
|
541
|
+
let lastError;
|
|
542
|
+
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
|
|
543
|
+
if (signal?.aborted) {
|
|
544
|
+
throw new Error(`Request aborted: ${signal.reason ?? "Unknown reason"}`);
|
|
545
|
+
}
|
|
546
|
+
try {
|
|
547
|
+
return await fn();
|
|
548
|
+
} catch (error) {
|
|
549
|
+
lastError = error;
|
|
550
|
+
if (attempt >= config.maxRetries) break;
|
|
551
|
+
if (!isRetryableError(error, config.retryableStatusCodes)) throw error;
|
|
552
|
+
const delay = calculateRetryDelay(attempt, config);
|
|
553
|
+
await sleep(delay);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
throw lastError;
|
|
557
|
+
}
|
|
558
|
+
var AgentvProvider = class {
|
|
559
|
+
id;
|
|
560
|
+
kind = "agentv";
|
|
561
|
+
targetName;
|
|
562
|
+
piModel;
|
|
563
|
+
defaults;
|
|
564
|
+
constructor(targetName, config) {
|
|
565
|
+
this.id = `agentv:${targetName}`;
|
|
566
|
+
this.targetName = targetName;
|
|
567
|
+
const { providerName, apiId, modelId } = parseAgentvModel(config.model);
|
|
568
|
+
this.piModel = resolvePiModel({ providerName, apiId, modelId });
|
|
569
|
+
this.defaults = { temperature: config.temperature };
|
|
570
|
+
}
|
|
571
|
+
async invoke(request) {
|
|
572
|
+
return invokePiAi({
|
|
573
|
+
model: this.piModel,
|
|
574
|
+
request,
|
|
575
|
+
defaults: this.defaults
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
};
|
|
579
|
+
function parseAgentvModel(model) {
|
|
580
|
+
const colonIndex = model.indexOf(":");
|
|
581
|
+
if (colonIndex === -1) {
|
|
582
|
+
throw new Error(
|
|
583
|
+
`Invalid agentv model "${model}". Expected "provider:model" (e.g., "openai:gpt-5-mini").`
|
|
584
|
+
);
|
|
585
|
+
}
|
|
586
|
+
const provider = model.slice(0, colonIndex);
|
|
587
|
+
const modelId = model.slice(colonIndex + 1);
|
|
588
|
+
switch (provider) {
|
|
589
|
+
case "openai":
|
|
590
|
+
return { providerName: "openai", apiId: "openai-completions", modelId };
|
|
591
|
+
case "anthropic":
|
|
592
|
+
return { providerName: "anthropic", apiId: "anthropic-messages", modelId };
|
|
593
|
+
case "azure":
|
|
594
|
+
return {
|
|
595
|
+
providerName: "azure-openai-responses",
|
|
596
|
+
apiId: "azure-openai-responses",
|
|
597
|
+
modelId
|
|
598
|
+
};
|
|
599
|
+
case "google":
|
|
600
|
+
return { providerName: "google", apiId: "google-generative-ai", modelId };
|
|
601
|
+
default:
|
|
602
|
+
throw new Error(
|
|
603
|
+
`Unsupported agentv provider "${provider}" in "${model}". Supported: openai, anthropic, azure, google.`
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
export {
|
|
609
|
+
OpenAIProvider,
|
|
610
|
+
OpenRouterProvider,
|
|
611
|
+
AnthropicProvider,
|
|
612
|
+
GeminiProvider,
|
|
613
|
+
AzureProvider,
|
|
614
|
+
AgentvProvider
|
|
615
|
+
};
|
|
616
|
+
//# sourceMappingURL=chunk-55QZVA5X.js.map
|