nuabase 2.3.3 → 2.3.5
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/README.md +96 -31
- package/dist/cjs/chunks/logger-Co5uZG0A.cjs +90 -0
- package/dist/cjs/index.cjs +1510 -1444
- package/dist/cjs/local-agent.cjs +886 -0
- package/dist/esm/chunks/logger-DnkHzkX_.mjs +88 -0
- package/dist/esm/index.mjs +1511 -1445
- package/dist/esm/local-agent.mjs +884 -0
- package/dist/types/__tests__/helpers/client-factory.d.ts +33 -11
- package/dist/types/__tests__/helpers/index.d.ts +2 -1
- package/dist/types/backend/direct.d.ts +20 -8
- package/dist/types/backend/types.d.ts +9 -4
- package/dist/types/index.d.cts +3 -2
- package/dist/types/index.d.mts +3 -2
- package/dist/types/local-agent.d.cts +2 -0
- package/dist/types/local-agent.d.mts +2 -0
- package/dist/types/nua-llm-core/index.d.ts +23 -0
- package/dist/types/nua-llm-core/lib/error-utils.d.ts +6 -0
- package/dist/types/nua-llm-core/lib/logger.d.ts +44 -0
- package/dist/types/nua-llm-core/lib/nua-errors.d.ts +12 -0
- package/dist/types/nua-llm-core/lib/prompt-template-utils.d.ts +2 -0
- package/dist/types/nua-llm-core/lib/schema-utils.d.ts +1 -0
- package/dist/types/nua-llm-core/lib/stable-stringify.d.ts +1 -0
- package/dist/types/nua-llm-core/lib/strict-json-schema.d.ts +7 -0
- package/dist/types/nua-llm-core/lib/types.d.ts +8 -0
- package/dist/types/nua-llm-core/lib/validate-mappable-input-data.d.ts +4 -0
- package/dist/types/nua-llm-core/local-agent.d.ts +7 -0
- package/dist/types/nua-llm-core/modules/agent/agent-loop.d.ts +10 -0
- package/dist/types/nua-llm-core/modules/agent/agent-turn.d.ts +17 -0
- package/dist/types/nua-llm-core/modules/agent/provider-formatters.d.ts +22 -0
- package/dist/types/nua-llm-core/modules/agent/run-agent.d.ts +7 -0
- package/dist/types/nua-llm-core/modules/agent/types.d.ts +90 -0
- package/dist/types/nua-llm-core/modules/cast/cast-request.d.ts +32 -0
- package/dist/types/nua-llm-core/modules/cast/envelope.d.ts +9 -0
- package/dist/types/nua-llm-core/modules/cast/list-schema.d.ts +32 -0
- package/dist/types/nua-llm-core/modules/cast/prompts/list-prompt.d.ts +3 -0
- package/dist/types/nua-llm-core/modules/cast/prompts/render-prompt.d.ts +7 -0
- package/dist/types/nua-llm-core/modules/cast/prompts/value-prompt.d.ts +3 -0
- package/dist/types/nua-llm-core/modules/cast/run-cast.d.ts +44 -0
- package/dist/types/nua-llm-core/modules/engine/engine-router.d.ts +23 -0
- package/dist/types/nua-llm-core/modules/engine/http/http-engine.d.ts +12 -0
- package/dist/types/nua-llm-core/modules/engine/http/provider-call.d.ts +33 -0
- package/dist/types/nua-llm-core/modules/engine/http/provider-config.d.ts +65 -0
- package/dist/types/nua-llm-core/modules/engine/http/provider-engines.d.ts +35 -0
- package/dist/types/nua-llm-core/modules/engine/llm-engine.d.ts +73 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/adapters/claude-code.d.ts +2 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/adapters/codex.d.ts +2 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/adapters/failure-classification.d.ts +4 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/adapters/index.d.ts +3 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/adapters/types.d.ts +61 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/agent-id.d.ts +4 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/create-local-agent.d.ts +36 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/detect.d.ts +20 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/local-agent-engine.d.ts +32 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/local-agent.d.ts +25 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/process-runner.d.ts +16 -0
- package/dist/types/nua-llm-core/modules/engine/local-agent/semaphore.d.ts +8 -0
- package/dist/types/nua-llm-core/modules/execution/llm-response-extraction.d.ts +5 -0
- package/dist/types/nua-llm-core/modules/json-schema-validation/ajv-instances.d.ts +12 -0
- package/dist/types/nua-llm-core/modules/json-schema-validation/nua-json-schema-value-validation.d.ts +10 -0
- package/dist/types/nua-llm-core/modules/json-schema-validation/validate-json-schema.d.ts +2 -0
- package/dist/types/nua-llm-core/modules/model-info/index.d.ts +15 -0
- package/dist/types/nua-llm-core/modules/streaming/sse-parser.d.ts +7 -0
- package/dist/types/nua-llm-core/nua-llm-client.d.ts +37 -0
- package/dist/types/nua.d.ts +8 -2
- package/package.json +19 -2
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,107 +1,33 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var logger = require('./chunks/logger-Co5uZG0A.cjs');
|
|
3
4
|
var zod = require('zod');
|
|
4
5
|
|
|
5
6
|
var dist = {};
|
|
6
7
|
|
|
7
8
|
var nuaLlmClient = {};
|
|
8
9
|
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
var
|
|
12
|
-
function
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
Object.defineProperty(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
logger.normalizeError = normalizeError;
|
|
20
|
-
class ConsoleLogger {
|
|
21
|
-
debug(message, context) {
|
|
22
|
-
console.debug(`[DEBUG] ${message}`, context || "");
|
|
23
|
-
}
|
|
24
|
-
info(message, context) {
|
|
25
|
-
console.info(`[INFO] ${message}`, context || "");
|
|
26
|
-
}
|
|
27
|
-
warn(message, context) {
|
|
28
|
-
console.warn(`[WARN] ${message}`, context || "");
|
|
29
|
-
}
|
|
30
|
-
error(message, context) {
|
|
31
|
-
console.error(`[ERROR] ${message}`, context || "");
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
logger.ConsoleLogger = ConsoleLogger;
|
|
35
|
-
const generateSpanId = () => crypto.randomUUID();
|
|
36
|
-
logger.generateSpanId = generateSpanId;
|
|
37
|
-
function truncateText(text, limit = 500) {
|
|
38
|
-
const length = text.length;
|
|
39
|
-
if (length <= limit) {
|
|
40
|
-
return { preview: text, length };
|
|
41
|
-
}
|
|
42
|
-
return { preview: text.slice(0, limit), length };
|
|
43
|
-
}
|
|
44
|
-
function pickHeaders(headers, allowlist, redactSet) {
|
|
45
|
-
const result = {};
|
|
46
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
47
|
-
const lowerKey = key.toLowerCase();
|
|
48
|
-
if (redactSet?.has(lowerKey)) {
|
|
49
|
-
result[key] = "[REDACTED]";
|
|
50
|
-
} else if (allowlist.has(lowerKey)) {
|
|
51
|
-
result[key] = Array.isArray(value) ? value.join(", ") : value ?? "";
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return result;
|
|
55
|
-
}
|
|
56
|
-
function normalizeError(error) {
|
|
57
|
-
return error instanceof Error ? { message: error.message, stack: error.stack } : String(error);
|
|
58
|
-
}
|
|
59
|
-
const LLM_RESPONSE_HEADER_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
60
|
-
"x-request-id",
|
|
61
|
-
"x-ratelimit-limit-requests",
|
|
62
|
-
"x-ratelimit-limit-tokens",
|
|
63
|
-
"x-ratelimit-remaining-requests",
|
|
64
|
-
"x-ratelimit-remaining-tokens",
|
|
65
|
-
"x-groq-region"
|
|
66
|
-
]);
|
|
67
|
-
const logLlmCallStart = (logger2, spanId, service, method, request) => {
|
|
68
|
-
logger2.info("LLM call started", {
|
|
69
|
-
type: "llm_call_start",
|
|
70
|
-
span_id: spanId,
|
|
71
|
-
service,
|
|
72
|
-
method,
|
|
73
|
-
...request
|
|
74
|
-
});
|
|
10
|
+
var nuaErrors = {};
|
|
11
|
+
|
|
12
|
+
var hasRequiredNuaErrors;
|
|
13
|
+
function requireNuaErrors() {
|
|
14
|
+
if (hasRequiredNuaErrors) return nuaErrors;
|
|
15
|
+
hasRequiredNuaErrors = 1;
|
|
16
|
+
Object.defineProperty(nuaErrors, "__esModule", { value: true });
|
|
17
|
+
nuaErrors.isNuaError = nuaErrors.isNuaInternalError = nuaErrors.isNuaValidationError = void 0;
|
|
18
|
+
const isNuaValidationError = (a) => {
|
|
19
|
+
return typeof a == "object" && a != null && "kind" in a && a.kind == "validation-error";
|
|
75
20
|
};
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
const { preview: responsePreview, length: responseLength } = truncateText(responseText);
|
|
80
|
-
logger2.info("LLM call completed", {
|
|
81
|
-
type: "llm_call_complete",
|
|
82
|
-
span_id: spanId,
|
|
83
|
-
service,
|
|
84
|
-
method,
|
|
85
|
-
...rest,
|
|
86
|
-
responsePreview,
|
|
87
|
-
responseLength,
|
|
88
|
-
...pickHeaders(headers, LLM_RESPONSE_HEADER_ALLOWLIST),
|
|
89
|
-
duration_ms: duration
|
|
90
|
-
});
|
|
21
|
+
nuaErrors.isNuaValidationError = isNuaValidationError;
|
|
22
|
+
const isNuaInternalError = (a) => {
|
|
23
|
+
return typeof a == "object" && a != null && "kind" in a && a.kind == "internal-error";
|
|
91
24
|
};
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
type: "llm_call_error",
|
|
96
|
-
span_id: spanId,
|
|
97
|
-
service,
|
|
98
|
-
method,
|
|
99
|
-
error: normalizeError(error),
|
|
100
|
-
duration_ms: duration
|
|
101
|
-
});
|
|
25
|
+
nuaErrors.isNuaInternalError = isNuaInternalError;
|
|
26
|
+
const isNuaError = (a) => {
|
|
27
|
+
return typeof a == "object" && a != null && "kind" in a && (a.kind == "internal-error" || a.kind == "validation-error");
|
|
102
28
|
};
|
|
103
|
-
|
|
104
|
-
return
|
|
29
|
+
nuaErrors.isNuaError = isNuaError;
|
|
30
|
+
return nuaErrors;
|
|
105
31
|
}
|
|
106
32
|
|
|
107
33
|
var validateMappableInputData = {};
|
|
@@ -144,7 +70,7 @@ function requireValidateMappableInputData() {
|
|
|
144
70
|
return validateMappableInputData;
|
|
145
71
|
}
|
|
146
72
|
|
|
147
|
-
var
|
|
73
|
+
var runCast = {};
|
|
148
74
|
|
|
149
75
|
var llmResponseExtraction = {};
|
|
150
76
|
|
|
@@ -253,60 +179,6 @@ function requireLlmResponseExtraction() {
|
|
|
253
179
|
return llmResponseExtraction;
|
|
254
180
|
}
|
|
255
181
|
|
|
256
|
-
var hasRequiredCallLlmService;
|
|
257
|
-
function requireCallLlmService() {
|
|
258
|
-
if (hasRequiredCallLlmService) return callLlmService;
|
|
259
|
-
hasRequiredCallLlmService = 1;
|
|
260
|
-
Object.defineProperty(callLlmService, "__esModule", { value: true });
|
|
261
|
-
callLlmService.callLLM = callLLM;
|
|
262
|
-
const llm_response_extraction_1 = requireLlmResponseExtraction();
|
|
263
|
-
const delay = (ms) => {
|
|
264
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
265
|
-
};
|
|
266
|
-
async function callLLM(llmClient, prompt, model, maxTokens, temperature, maxRetries, validationFunction) {
|
|
267
|
-
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
268
|
-
try {
|
|
269
|
-
const providerResponse = await llmClient.sendRequest(prompt, model, maxTokens);
|
|
270
|
-
const response = providerResponse.text;
|
|
271
|
-
let parsedResponse;
|
|
272
|
-
try {
|
|
273
|
-
const { cleanedResponse } = (0, llm_response_extraction_1.extractThinkingFromResponse)(response);
|
|
274
|
-
parsedResponse = (0, llm_response_extraction_1.parseJsonFromLlmResponse)(cleanedResponse);
|
|
275
|
-
} catch (parseError) {
|
|
276
|
-
const errorMessage2 = `Failed to parse LLM response as JSON: ${parseError instanceof Error ? parseError.message : "Unknown parsing error"}`;
|
|
277
|
-
throw new Error(`${errorMessage2}
|
|
278
|
-
|
|
279
|
-
Raw LLM response:
|
|
280
|
-
${response}`);
|
|
281
|
-
}
|
|
282
|
-
const validationResult = validationFunction(parsedResponse);
|
|
283
|
-
if (validationResult.success && validationResult.data) {
|
|
284
|
-
return {
|
|
285
|
-
data: validationResult.data,
|
|
286
|
-
usage: providerResponse.usage
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
const errorMessage = `Validation failed: ${validationResult.error || "Unknown validation error"}`;
|
|
290
|
-
throw new Error(`${errorMessage}
|
|
291
|
-
|
|
292
|
-
Raw LLM response:
|
|
293
|
-
${response}`);
|
|
294
|
-
} catch (error) {
|
|
295
|
-
const isLastAttempt = attempt === maxRetries;
|
|
296
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
297
|
-
if (isLastAttempt) {
|
|
298
|
-
throw new Error(`LLM call failed after ${maxRetries} attempts. Last error: ${errorMessage}`);
|
|
299
|
-
}
|
|
300
|
-
const backoffDelay = Math.pow(2, attempt - 1) * 1e3;
|
|
301
|
-
console.warn(`LLM call attempt ${attempt} failed: ${errorMessage}. Retrying in ${backoffDelay}ms...`);
|
|
302
|
-
await delay(backoffDelay);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
throw new Error("Unexpected error: retry loop completed without success or failure");
|
|
306
|
-
}
|
|
307
|
-
return callLlmService;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
182
|
var nuaJsonSchemaValueValidation = {};
|
|
311
183
|
|
|
312
184
|
var ajvInstances = {};
|
|
@@ -9508,170 +9380,417 @@ function requireNuaJsonSchemaValueValidation() {
|
|
|
9508
9380
|
return nuaJsonSchemaValueValidation;
|
|
9509
9381
|
}
|
|
9510
9382
|
|
|
9511
|
-
var
|
|
9512
|
-
|
|
9513
|
-
var modelInfo = {};
|
|
9383
|
+
var envelope = {};
|
|
9514
9384
|
|
|
9515
|
-
var
|
|
9516
|
-
function
|
|
9517
|
-
if (
|
|
9518
|
-
|
|
9385
|
+
var hasRequiredEnvelope;
|
|
9386
|
+
function requireEnvelope() {
|
|
9387
|
+
if (hasRequiredEnvelope) return envelope;
|
|
9388
|
+
hasRequiredEnvelope = 1;
|
|
9519
9389
|
(function(exports$1) {
|
|
9520
9390
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
9521
|
-
exports$1.
|
|
9522
|
-
exports$1.
|
|
9523
|
-
exports$1.
|
|
9524
|
-
|
|
9525
|
-
|
|
9526
|
-
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
|
|
9531
|
-
|
|
9532
|
-
|
|
9533
|
-
|
|
9534
|
-
"
|
|
9535
|
-
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
"
|
|
9541
|
-
|
|
9542
|
-
|
|
9543
|
-
|
|
9544
|
-
|
|
9545
|
-
|
|
9546
|
-
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
"
|
|
9555
|
-
|
|
9556
|
-
|
|
9557
|
-
|
|
9558
|
-
|
|
9559
|
-
|
|
9560
|
-
"
|
|
9561
|
-
|
|
9562
|
-
|
|
9563
|
-
|
|
9564
|
-
|
|
9565
|
-
|
|
9566
|
-
|
|
9567
|
-
|
|
9568
|
-
|
|
9569
|
-
|
|
9570
|
-
|
|
9571
|
-
|
|
9572
|
-
|
|
9573
|
-
{
|
|
9574
|
-
|
|
9575
|
-
providerModelName: "anthropic/claude-haiku-4.5"
|
|
9576
|
-
}
|
|
9577
|
-
],
|
|
9578
|
-
"qwen3-vl-235b-a22b-instruct": [
|
|
9579
|
-
{
|
|
9580
|
-
provider: "openrouter",
|
|
9581
|
-
providerModelName: "qwen/qwen3-vl-235b-a22b-instruct"
|
|
9582
|
-
}
|
|
9583
|
-
],
|
|
9584
|
-
"qwen3-max": [
|
|
9585
|
-
{
|
|
9586
|
-
provider: "openrouter",
|
|
9587
|
-
providerModelName: "qwen/qwen3-max"
|
|
9588
|
-
}
|
|
9589
|
-
],
|
|
9590
|
-
"gpt-5": [
|
|
9591
|
-
{
|
|
9592
|
-
provider: "openrouter",
|
|
9593
|
-
providerModelName: "openai/gpt-5"
|
|
9594
|
-
}
|
|
9595
|
-
],
|
|
9596
|
-
"gemini-2.5-flash-lite": [
|
|
9597
|
-
{
|
|
9598
|
-
provider: "gemini",
|
|
9599
|
-
providerModelName: "gemini-2.5-flash-lite"
|
|
9600
|
-
},
|
|
9601
|
-
{
|
|
9602
|
-
provider: "openrouter",
|
|
9603
|
-
providerModelName: "google/gemini-2.5-flash-lite"
|
|
9604
|
-
}
|
|
9605
|
-
],
|
|
9606
|
-
"gemini-2.5-flash": [
|
|
9607
|
-
{
|
|
9608
|
-
provider: "gemini",
|
|
9609
|
-
providerModelName: "gemini-2.5-flash"
|
|
9610
|
-
},
|
|
9611
|
-
{
|
|
9612
|
-
provider: "openrouter",
|
|
9613
|
-
providerModelName: "google/gemini-2.5-flash"
|
|
9614
|
-
}
|
|
9615
|
-
],
|
|
9616
|
-
"qwen3-coder-flash": [
|
|
9617
|
-
{
|
|
9618
|
-
provider: "openrouter",
|
|
9619
|
-
providerModelName: "qwen/qwen3-coder-flash"
|
|
9620
|
-
}
|
|
9621
|
-
],
|
|
9622
|
-
"kimi-k2.5": [
|
|
9623
|
-
{
|
|
9624
|
-
provider: "openrouter",
|
|
9625
|
-
providerModelName: "moonshotai/kimi-k2.5"
|
|
9626
|
-
}
|
|
9627
|
-
],
|
|
9628
|
-
"kimi-k2.6": [
|
|
9629
|
-
{
|
|
9630
|
-
provider: "openrouter",
|
|
9631
|
-
providerModelName: "moonshotai/kimi-k2.6"
|
|
9391
|
+
exports$1.ENVELOPE_KEY = void 0;
|
|
9392
|
+
exports$1.wrapInEnvelope = wrapInEnvelope;
|
|
9393
|
+
exports$1.unwrapEnvelope = unwrapEnvelope;
|
|
9394
|
+
exports$1.ENVELOPE_KEY = "value";
|
|
9395
|
+
function wrapInEnvelope(schema) {
|
|
9396
|
+
return {
|
|
9397
|
+
type: "object",
|
|
9398
|
+
properties: { [exports$1.ENVELOPE_KEY]: withoutSchemaKeyword(schema) },
|
|
9399
|
+
required: [exports$1.ENVELOPE_KEY],
|
|
9400
|
+
additionalProperties: false
|
|
9401
|
+
};
|
|
9402
|
+
}
|
|
9403
|
+
function unwrapEnvelope(envelope2) {
|
|
9404
|
+
if (typeof envelope2 !== "object" || envelope2 === null || !(exports$1.ENVELOPE_KEY in envelope2)) {
|
|
9405
|
+
return { found: false };
|
|
9406
|
+
}
|
|
9407
|
+
return { found: true, value: envelope2[exports$1.ENVELOPE_KEY] };
|
|
9408
|
+
}
|
|
9409
|
+
const SUBSCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
|
|
9410
|
+
"items",
|
|
9411
|
+
"additionalItems",
|
|
9412
|
+
"prefixItems",
|
|
9413
|
+
"contains",
|
|
9414
|
+
"additionalProperties",
|
|
9415
|
+
"propertyNames",
|
|
9416
|
+
"unevaluatedItems",
|
|
9417
|
+
"unevaluatedProperties",
|
|
9418
|
+
"not",
|
|
9419
|
+
"if",
|
|
9420
|
+
"then",
|
|
9421
|
+
"else",
|
|
9422
|
+
"allOf",
|
|
9423
|
+
"anyOf",
|
|
9424
|
+
"oneOf"
|
|
9425
|
+
]);
|
|
9426
|
+
const SUBSCHEMA_MAP_KEYWORDS = /* @__PURE__ */ new Set([
|
|
9427
|
+
"properties",
|
|
9428
|
+
"patternProperties",
|
|
9429
|
+
"dependentSchemas",
|
|
9430
|
+
"dependencies",
|
|
9431
|
+
"$defs",
|
|
9432
|
+
"definitions"
|
|
9433
|
+
]);
|
|
9434
|
+
function withoutSchemaKeyword(schema) {
|
|
9435
|
+
const result = {};
|
|
9436
|
+
for (const [keyword, value] of Object.entries(schema)) {
|
|
9437
|
+
if (keyword === "$schema")
|
|
9438
|
+
continue;
|
|
9439
|
+
if (SUBSCHEMA_KEYWORDS.has(keyword)) {
|
|
9440
|
+
result[keyword] = Array.isArray(value) ? value.map(subschema) : subschema(value);
|
|
9441
|
+
} else if (SUBSCHEMA_MAP_KEYWORDS.has(keyword) && isObject(value)) {
|
|
9442
|
+
result[keyword] = Object.fromEntries(Object.entries(value).map(([name, child]) => [name, subschema(child)]));
|
|
9443
|
+
} else {
|
|
9444
|
+
result[keyword] = value;
|
|
9632
9445
|
}
|
|
9633
|
-
]
|
|
9634
|
-
};
|
|
9635
|
-
function parseCanonicalModelName(requestedModel) {
|
|
9636
|
-
let m = requestedModel || "fast";
|
|
9637
|
-
if (CANONICAL_SET.has(m))
|
|
9638
|
-
return m;
|
|
9639
|
-
let m2;
|
|
9640
|
-
switch (m) {
|
|
9641
|
-
case "fast":
|
|
9642
|
-
m2 = "gpt-oss-120b";
|
|
9643
|
-
break;
|
|
9644
|
-
case "gemini":
|
|
9645
|
-
m2 = "gemini-2.5-flash";
|
|
9646
|
-
break;
|
|
9647
|
-
case "qwen":
|
|
9648
|
-
m2 = "qwen3-vl-235b-a22b-instruct";
|
|
9649
|
-
break;
|
|
9650
|
-
case "sonnet":
|
|
9651
|
-
m2 = "claude-sonnet-4-6";
|
|
9652
|
-
break;
|
|
9653
|
-
case "opus":
|
|
9654
|
-
m2 = "claude-opus-4-7";
|
|
9655
|
-
break;
|
|
9656
|
-
case "haiku":
|
|
9657
|
-
m2 = "claude-haiku-4-5";
|
|
9658
|
-
break;
|
|
9659
|
-
case "kimi":
|
|
9660
|
-
m2 = "kimi-k2.6";
|
|
9661
|
-
break;
|
|
9662
|
-
case "gpt":
|
|
9663
|
-
m2 = "gpt-5";
|
|
9664
|
-
break;
|
|
9665
9446
|
}
|
|
9666
|
-
|
|
9667
|
-
|
|
9447
|
+
return result;
|
|
9448
|
+
}
|
|
9449
|
+
function subschema(value) {
|
|
9450
|
+
return isObject(value) ? withoutSchemaKeyword(value) : value;
|
|
9451
|
+
}
|
|
9452
|
+
function isObject(value) {
|
|
9453
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9454
|
+
}
|
|
9455
|
+
})(envelope);
|
|
9456
|
+
return envelope;
|
|
9457
|
+
}
|
|
9458
|
+
|
|
9459
|
+
var renderPrompt = {};
|
|
9460
|
+
|
|
9461
|
+
var listPrompt = {};
|
|
9462
|
+
|
|
9463
|
+
var promptTemplateUtils = {};
|
|
9464
|
+
|
|
9465
|
+
var hasRequiredPromptTemplateUtils;
|
|
9466
|
+
function requirePromptTemplateUtils() {
|
|
9467
|
+
if (hasRequiredPromptTemplateUtils) return promptTemplateUtils;
|
|
9468
|
+
hasRequiredPromptTemplateUtils = 1;
|
|
9469
|
+
(function(exports$1) {
|
|
9470
|
+
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
9471
|
+
exports$1.replaceTemplateVarName = exports$1.templateVarName = void 0;
|
|
9472
|
+
const templateVarName = (varName) => `<<{${varName}}>>`;
|
|
9473
|
+
exports$1.templateVarName = templateVarName;
|
|
9474
|
+
const replaceTemplateVarName = (str, varName, value) => str.replaceAll((0, exports$1.templateVarName)(varName), value);
|
|
9475
|
+
exports$1.replaceTemplateVarName = replaceTemplateVarName;
|
|
9476
|
+
})(promptTemplateUtils);
|
|
9477
|
+
return promptTemplateUtils;
|
|
9478
|
+
}
|
|
9479
|
+
|
|
9480
|
+
var hasRequiredListPrompt;
|
|
9481
|
+
function requireListPrompt() {
|
|
9482
|
+
if (hasRequiredListPrompt) return listPrompt;
|
|
9483
|
+
hasRequiredListPrompt = 1;
|
|
9484
|
+
Object.defineProperty(listPrompt, "__esModule", { value: true });
|
|
9485
|
+
listPrompt.renderListPrompt = renderListPrompt;
|
|
9486
|
+
const prompt_template_utils_1 = requirePromptTemplateUtils();
|
|
9487
|
+
const envelope_1 = requireEnvelope();
|
|
9488
|
+
const DESCRIBE_OUTPUT = [
|
|
9489
|
+
`Your task is to transform the provided <input-data> into a JSON array, that represents a list of`,
|
|
9490
|
+
`${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}. The schema for this JSON array is defined below in <json-schema-spec> for you reference.`,
|
|
9491
|
+
`It uses the JSON Schema spec.`
|
|
9492
|
+
];
|
|
9493
|
+
const MATCH_PRIMARY_KEYS = [
|
|
9494
|
+
`Note that the primary key of each element in the input-data is '${(0, prompt_template_utils_1.templateVarName)("PRIMARY_KEY")}'. In the output JSON array,`,
|
|
9495
|
+
`each object should have the same key with the same value of the original data, so we can map the input element against the output element.`
|
|
9496
|
+
];
|
|
9497
|
+
const SYSTEM_PROMPTS = {
|
|
9498
|
+
"in-prompt": [
|
|
9499
|
+
...DESCRIBE_OUTPUT,
|
|
9500
|
+
`Respond with only the instance, not the schema. It should not be wrapped in any wrapper object -- return exactly what the JSON schema is expecting.`,
|
|
9501
|
+
`Your entire response should be just the value of the JSON array containing objects with '${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}'`,
|
|
9502
|
+
`and its primary key '${(0, prompt_template_utils_1.templateVarName)("PRIMARY_KEY")}', as valid JSON.`,
|
|
9503
|
+
`We will validate the result with the AJV Node library, using ajv.parse, against the JSON schema, and we expect it to validate correctly.`,
|
|
9504
|
+
...MATCH_PRIMARY_KEYS
|
|
9505
|
+
].join(" "),
|
|
9506
|
+
native: [
|
|
9507
|
+
...DESCRIBE_OUTPUT,
|
|
9508
|
+
`Respond with only the instance, not the schema. Your reply is enforced by a JSON schema that wraps the result in an object:`,
|
|
9509
|
+
`put the JSON array, containing objects with '${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}' and its primary key '${(0, prompt_template_utils_1.templateVarName)("PRIMARY_KEY")}', in its "${envelope_1.ENVELOPE_KEY}" field.`,
|
|
9510
|
+
`We will validate the "${envelope_1.ENVELOPE_KEY}" field with the AJV Node library against the JSON schema, and we expect it to validate correctly.`,
|
|
9511
|
+
...MATCH_PRIMARY_KEYS
|
|
9512
|
+
].join(" ")
|
|
9513
|
+
};
|
|
9514
|
+
function renderListPrompt(cast, enforcement) {
|
|
9515
|
+
const withPrimaryKey = (0, prompt_template_utils_1.replaceTemplateVarName)(SYSTEM_PROMPTS[enforcement], "PRIMARY_KEY", cast.primaryKey);
|
|
9516
|
+
const system = (0, prompt_template_utils_1.replaceTemplateVarName)(withPrimaryKey, "OUTPUT_TYPE_NAME", cast.outputName);
|
|
9517
|
+
const full = [
|
|
9518
|
+
cast.prompt || "Transform the provided data according to the schema.",
|
|
9519
|
+
system,
|
|
9520
|
+
`<json-schema-spec> ${JSON.stringify(cast.schema)} </json-schema-spec>`,
|
|
9521
|
+
`<input-data>${JSON.stringify(cast.rows)}</input-data>`
|
|
9522
|
+
].join("\n");
|
|
9523
|
+
return { system, full };
|
|
9524
|
+
}
|
|
9525
|
+
return listPrompt;
|
|
9526
|
+
}
|
|
9527
|
+
|
|
9528
|
+
var valuePrompt = {};
|
|
9529
|
+
|
|
9530
|
+
var hasRequiredValuePrompt;
|
|
9531
|
+
function requireValuePrompt() {
|
|
9532
|
+
if (hasRequiredValuePrompt) return valuePrompt;
|
|
9533
|
+
hasRequiredValuePrompt = 1;
|
|
9534
|
+
Object.defineProperty(valuePrompt, "__esModule", { value: true });
|
|
9535
|
+
valuePrompt.renderValuePrompt = renderValuePrompt;
|
|
9536
|
+
const prompt_template_utils_1 = requirePromptTemplateUtils();
|
|
9537
|
+
const envelope_1 = requireEnvelope();
|
|
9538
|
+
const DESCRIBE_OUTPUT = [
|
|
9539
|
+
`Please respond with a single JSON object that represents '${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}'.`,
|
|
9540
|
+
`The schema for this object (which uses the JSON Schema spec), is defined below for your reference.`,
|
|
9541
|
+
`Your task is to create an instance of this object. Respond with only the instance, not the schema.`
|
|
9542
|
+
];
|
|
9543
|
+
const SYSTEM_PROMPTS = {
|
|
9544
|
+
"in-prompt": [
|
|
9545
|
+
...DESCRIBE_OUTPUT,
|
|
9546
|
+
`Your entire response should be just the value of '${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}', as valid JSON.`,
|
|
9547
|
+
`And it should not be wrapped in any wrapper object -- return exactly what the JSON schema is expecting.`,
|
|
9548
|
+
`We will validate the result with the AJV Node library, using ajv.parse, against the given schema, and we expect`,
|
|
9549
|
+
`it to validate correctly.`,
|
|
9550
|
+
`IMPORTANT: Output raw JSON only. No markdown code fences, no explanation, no commentary, no extra fields beyond the schema. Do not correct yourself -- produce the right answer on the first try.`
|
|
9551
|
+
].join(" "),
|
|
9552
|
+
native: [
|
|
9553
|
+
...DESCRIBE_OUTPUT,
|
|
9554
|
+
`Your reply is enforced by a JSON schema that wraps the result in an object:`,
|
|
9555
|
+
`put the value of '${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}' in its "${envelope_1.ENVELOPE_KEY}" field.`,
|
|
9556
|
+
`We will validate the "${envelope_1.ENVELOPE_KEY}" field with the AJV Node library against the schema below, and we expect`,
|
|
9557
|
+
`it to validate correctly.`
|
|
9558
|
+
].join(" ")
|
|
9559
|
+
};
|
|
9560
|
+
function renderValuePrompt(cast, enforcement) {
|
|
9561
|
+
const system = (0, prompt_template_utils_1.replaceTemplateVarName)(SYSTEM_PROMPTS[enforcement], "OUTPUT_TYPE_NAME", cast.outputName);
|
|
9562
|
+
const full = [
|
|
9563
|
+
cast.prompt || "Transform the provided data according to the schema.",
|
|
9564
|
+
system,
|
|
9565
|
+
`<json-schema-spec> ${JSON.stringify(cast.schema)} </json-schema-spec>`,
|
|
9566
|
+
cast.data ? `<input-data>${JSON.stringify(cast.data)}</input-data>` : ""
|
|
9567
|
+
].join("\n");
|
|
9568
|
+
return { system, full };
|
|
9569
|
+
}
|
|
9570
|
+
return valuePrompt;
|
|
9571
|
+
}
|
|
9572
|
+
|
|
9573
|
+
var hasRequiredRenderPrompt;
|
|
9574
|
+
function requireRenderPrompt() {
|
|
9575
|
+
if (hasRequiredRenderPrompt) return renderPrompt;
|
|
9576
|
+
hasRequiredRenderPrompt = 1;
|
|
9577
|
+
Object.defineProperty(renderPrompt, "__esModule", { value: true });
|
|
9578
|
+
renderPrompt.renderPrompt = renderPrompt$1;
|
|
9579
|
+
const list_prompt_1 = requireListPrompt();
|
|
9580
|
+
const value_prompt_1 = requireValuePrompt();
|
|
9581
|
+
function renderPrompt$1(cast, enforcement) {
|
|
9582
|
+
switch (cast.kind) {
|
|
9583
|
+
case "value":
|
|
9584
|
+
return (0, value_prompt_1.renderValuePrompt)(cast, enforcement);
|
|
9585
|
+
case "list":
|
|
9586
|
+
return (0, list_prompt_1.renderListPrompt)(cast, enforcement);
|
|
9587
|
+
}
|
|
9588
|
+
}
|
|
9589
|
+
return renderPrompt;
|
|
9590
|
+
}
|
|
9591
|
+
|
|
9592
|
+
var hasRequiredRunCast;
|
|
9593
|
+
function requireRunCast() {
|
|
9594
|
+
if (hasRequiredRunCast) return runCast;
|
|
9595
|
+
hasRequiredRunCast = 1;
|
|
9596
|
+
Object.defineProperty(runCast, "__esModule", { value: true });
|
|
9597
|
+
runCast.runCast = runCast$1;
|
|
9598
|
+
runCast.judgeOutcome = judgeOutcome;
|
|
9599
|
+
const llm_response_extraction_1 = requireLlmResponseExtraction();
|
|
9600
|
+
const nua_json_schema_value_validation_1 = requireNuaJsonSchemaValueValidation();
|
|
9601
|
+
const envelope_1 = requireEnvelope();
|
|
9602
|
+
const render_prompt_1 = requireRenderPrompt();
|
|
9603
|
+
const RETRY_DELAYS_MS = [1e3, 2e3];
|
|
9604
|
+
const MAX_ATTEMPTS = RETRY_DELAYS_MS.length + 1;
|
|
9605
|
+
async function runCast$1(engine, request, logger) {
|
|
9606
|
+
let validate;
|
|
9607
|
+
try {
|
|
9608
|
+
validate = (0, nua_json_schema_value_validation_1.buildNuaJsonSchemaValueValidation)("library-req", request.schema);
|
|
9609
|
+
} catch (error) {
|
|
9610
|
+
return { success: false, error: `Invalid output schema: ${errorMessage(error)}` };
|
|
9611
|
+
}
|
|
9612
|
+
let plan = planAttempt(request, chooseEnforcement(engine, request.schema));
|
|
9613
|
+
let lastFailure = { error: "", prompt: plan.prompt };
|
|
9614
|
+
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
|
9615
|
+
const outcome = await engine.attempt({
|
|
9616
|
+
prompt: plan.prompt.full,
|
|
9617
|
+
maxTokens: request.maxTokens,
|
|
9618
|
+
enforcement: plan.enforcement
|
|
9619
|
+
});
|
|
9620
|
+
const verdict = judgeOutcome(outcome, validate);
|
|
9621
|
+
if (verdict.kind === "accept") {
|
|
9622
|
+
return {
|
|
9623
|
+
success: true,
|
|
9624
|
+
data: verdict.data,
|
|
9625
|
+
usage: verdict.usage,
|
|
9626
|
+
prompt: plan.prompt,
|
|
9627
|
+
origin: verdict.origin,
|
|
9628
|
+
schemaEnforcement: plan.enforcement.kind
|
|
9629
|
+
};
|
|
9630
|
+
}
|
|
9631
|
+
if (verdict.kind === "give-up") {
|
|
9632
|
+
return { success: false, error: verdict.error, prompt: plan.prompt };
|
|
9633
|
+
}
|
|
9634
|
+
lastFailure = { error: verdict.error, prompt: plan.prompt };
|
|
9635
|
+
if (verdict.kind === "retry-in-prompt") {
|
|
9636
|
+
logger.warn("Engine rejected the native output schema; retrying with the schema in the prompt", {
|
|
9637
|
+
attempt,
|
|
9638
|
+
error: verdict.error
|
|
9639
|
+
});
|
|
9640
|
+
plan = planAttempt(request, { kind: "in-prompt" });
|
|
9641
|
+
continue;
|
|
9642
|
+
}
|
|
9643
|
+
if (attempt < MAX_ATTEMPTS) {
|
|
9644
|
+
const delayMs = RETRY_DELAYS_MS[attempt - 1];
|
|
9645
|
+
logger.warn("LLM call attempt failed; retrying", { attempt, delayMs, error: verdict.error });
|
|
9646
|
+
await delay(delayMs);
|
|
9647
|
+
}
|
|
9648
|
+
}
|
|
9649
|
+
return {
|
|
9650
|
+
success: false,
|
|
9651
|
+
error: `LLM call failed after ${MAX_ATTEMPTS} attempts. Last error: ${lastFailure.error}`,
|
|
9652
|
+
prompt: lastFailure.prompt
|
|
9653
|
+
};
|
|
9654
|
+
}
|
|
9655
|
+
function chooseEnforcement(engine, schema) {
|
|
9656
|
+
const nativeSchema = engine.nativeSchema((0, envelope_1.wrapInEnvelope)(schema));
|
|
9657
|
+
return nativeSchema ? { kind: "native", schema: nativeSchema } : { kind: "in-prompt" };
|
|
9658
|
+
}
|
|
9659
|
+
function planAttempt(request, enforcement) {
|
|
9660
|
+
return { enforcement, prompt: (0, render_prompt_1.renderPrompt)(request, enforcement.kind) };
|
|
9661
|
+
}
|
|
9662
|
+
function judgeOutcome(outcome, validate) {
|
|
9663
|
+
if (outcome.kind === "failed") {
|
|
9664
|
+
return verdictForFailure(outcome.failure);
|
|
9665
|
+
}
|
|
9666
|
+
const candidate = readAnswer(outcome.answer);
|
|
9667
|
+
if (!candidate.ok) {
|
|
9668
|
+
return { kind: "retry", error: candidate.error };
|
|
9669
|
+
}
|
|
9670
|
+
const validation = validate(candidate.value);
|
|
9671
|
+
if (!validation.success) {
|
|
9668
9672
|
return {
|
|
9669
|
-
kind: "
|
|
9670
|
-
|
|
9673
|
+
kind: "retry",
|
|
9674
|
+
error: `Validation failed: ${validation.error || "Unknown validation error"}
|
|
9675
|
+
|
|
9676
|
+
Raw LLM response:
|
|
9677
|
+
${candidate.raw}`
|
|
9671
9678
|
};
|
|
9672
9679
|
}
|
|
9673
|
-
|
|
9674
|
-
|
|
9680
|
+
return { kind: "accept", data: candidate.value, usage: outcome.usage, origin: outcome.origin };
|
|
9681
|
+
}
|
|
9682
|
+
function verdictForFailure(failure) {
|
|
9683
|
+
switch (failure.kind) {
|
|
9684
|
+
case "transient":
|
|
9685
|
+
return { kind: "retry", error: failure.message };
|
|
9686
|
+
case "schema-rejected":
|
|
9687
|
+
return { kind: "retry-in-prompt", error: failure.message };
|
|
9688
|
+
case "fatal":
|
|
9689
|
+
return { kind: "give-up", error: failure.message };
|
|
9690
|
+
}
|
|
9691
|
+
}
|
|
9692
|
+
function readAnswer(answer) {
|
|
9693
|
+
switch (answer.kind) {
|
|
9694
|
+
case "text":
|
|
9695
|
+
return readTextAnswer(answer.text);
|
|
9696
|
+
case "structured":
|
|
9697
|
+
return readStructuredAnswer(answer.envelope);
|
|
9698
|
+
}
|
|
9699
|
+
}
|
|
9700
|
+
function readTextAnswer(text) {
|
|
9701
|
+
try {
|
|
9702
|
+
const { cleanedResponse } = (0, llm_response_extraction_1.extractThinkingFromResponse)(text);
|
|
9703
|
+
return { ok: true, value: (0, llm_response_extraction_1.parseJsonFromLlmResponse)(cleanedResponse), raw: text };
|
|
9704
|
+
} catch (error) {
|
|
9705
|
+
return {
|
|
9706
|
+
ok: false,
|
|
9707
|
+
error: `Failed to parse LLM response as JSON: ${errorMessage(error)}
|
|
9708
|
+
|
|
9709
|
+
Raw LLM response:
|
|
9710
|
+
${text}`
|
|
9711
|
+
};
|
|
9712
|
+
}
|
|
9713
|
+
}
|
|
9714
|
+
function readStructuredAnswer(envelope) {
|
|
9715
|
+
const raw = JSON.stringify(envelope);
|
|
9716
|
+
const unwrapped = (0, envelope_1.unwrapEnvelope)(envelope);
|
|
9717
|
+
if (!unwrapped.found) {
|
|
9718
|
+
return { ok: false, error: `Structured output has no "${envelope_1.ENVELOPE_KEY}" field: ${raw}` };
|
|
9719
|
+
}
|
|
9720
|
+
return { ok: true, value: unwrapped.value, raw };
|
|
9721
|
+
}
|
|
9722
|
+
function errorMessage(error) {
|
|
9723
|
+
return error instanceof Error ? error.message : String(error);
|
|
9724
|
+
}
|
|
9725
|
+
function delay(ms) {
|
|
9726
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
9727
|
+
}
|
|
9728
|
+
return runCast;
|
|
9729
|
+
}
|
|
9730
|
+
|
|
9731
|
+
var hasRequiredNuaLlmClient;
|
|
9732
|
+
function requireNuaLlmClient() {
|
|
9733
|
+
if (hasRequiredNuaLlmClient) return nuaLlmClient;
|
|
9734
|
+
hasRequiredNuaLlmClient = 1;
|
|
9735
|
+
Object.defineProperty(nuaLlmClient, "__esModule", { value: true });
|
|
9736
|
+
nuaLlmClient.NuaLlmClient = void 0;
|
|
9737
|
+
const nua_errors_1 = requireNuaErrors();
|
|
9738
|
+
const validate_mappable_input_data_1 = requireValidateMappableInputData();
|
|
9739
|
+
const run_cast_1 = requireRunCast();
|
|
9740
|
+
const DEFAULT_MAX_TOKENS = 4096;
|
|
9741
|
+
class NuaLlmClient {
|
|
9742
|
+
constructor(engines) {
|
|
9743
|
+
this.engines = engines;
|
|
9744
|
+
}
|
|
9745
|
+
async castValue(params) {
|
|
9746
|
+
const route = this.engines.route(params.model);
|
|
9747
|
+
if (route.kind === "unroutable") {
|
|
9748
|
+
return { success: false, error: route.message };
|
|
9749
|
+
}
|
|
9750
|
+
const request = {
|
|
9751
|
+
kind: "value",
|
|
9752
|
+
prompt: params.input.prompt,
|
|
9753
|
+
data: params.input.data,
|
|
9754
|
+
outputName: params.output.name,
|
|
9755
|
+
schema: params.output.schema,
|
|
9756
|
+
maxTokens: params.maxTokens ?? DEFAULT_MAX_TOKENS
|
|
9757
|
+
};
|
|
9758
|
+
return (0, run_cast_1.runCast)(route.engine, request, this.engines.logger);
|
|
9759
|
+
}
|
|
9760
|
+
async castArray(params) {
|
|
9761
|
+
const { primaryKey, outputName, jsonSchema } = params.output;
|
|
9762
|
+
const rows = (0, validate_mappable_input_data_1.validateMappableInputData)(params.input.data, primaryKey);
|
|
9763
|
+
if ((0, nua_errors_1.isNuaValidationError)(rows)) {
|
|
9764
|
+
return { success: false, error: rows.message };
|
|
9765
|
+
}
|
|
9766
|
+
const route = this.engines.route(params.model);
|
|
9767
|
+
if (route.kind === "unroutable") {
|
|
9768
|
+
return { success: false, error: route.message };
|
|
9769
|
+
}
|
|
9770
|
+
const request = {
|
|
9771
|
+
kind: "list",
|
|
9772
|
+
prompt: params.input.prompt,
|
|
9773
|
+
rows,
|
|
9774
|
+
primaryKey,
|
|
9775
|
+
outputName,
|
|
9776
|
+
schema: jsonSchema,
|
|
9777
|
+
maxTokens: params.maxTokens ?? DEFAULT_MAX_TOKENS
|
|
9778
|
+
};
|
|
9779
|
+
return (0, run_cast_1.runCast)(route.engine, request, this.engines.logger);
|
|
9780
|
+
}
|
|
9781
|
+
}
|
|
9782
|
+
nuaLlmClient.NuaLlmClient = NuaLlmClient;
|
|
9783
|
+
return nuaLlmClient;
|
|
9784
|
+
}
|
|
9785
|
+
|
|
9786
|
+
var types = {};
|
|
9787
|
+
|
|
9788
|
+
var hasRequiredTypes;
|
|
9789
|
+
function requireTypes() {
|
|
9790
|
+
if (hasRequiredTypes) return types;
|
|
9791
|
+
hasRequiredTypes = 1;
|
|
9792
|
+
Object.defineProperty(types, "__esModule", { value: true });
|
|
9793
|
+
return types;
|
|
9675
9794
|
}
|
|
9676
9795
|
|
|
9677
9796
|
var providerConfig = {};
|
|
@@ -9682,7 +9801,13 @@ function requireProviderConfig() {
|
|
|
9682
9801
|
hasRequiredProviderConfig = 1;
|
|
9683
9802
|
(function(exports$1) {
|
|
9684
9803
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
9685
|
-
exports$1.providerConfigs = exports$1.extractOpenAiMessageText = exports$1.normalizeGeminiUsage = exports$1.normalizeOpenAiUsage = exports$1.normalizedUsageZero = void 0;
|
|
9804
|
+
exports$1.providerConfigs = exports$1.extractOpenAiMessageText = exports$1.normalizeGeminiUsage = exports$1.normalizeOpenAiUsage = exports$1.normalizedUsageZero = exports$1.LLM_PROVIDER_IDS = void 0;
|
|
9805
|
+
exports$1.LLM_PROVIDER_IDS = [
|
|
9806
|
+
"groq",
|
|
9807
|
+
"cerebras",
|
|
9808
|
+
"gemini",
|
|
9809
|
+
"openrouter"
|
|
9810
|
+
];
|
|
9686
9811
|
exports$1.normalizedUsageZero = {
|
|
9687
9812
|
promptTokens: 0,
|
|
9688
9813
|
completionTokens: 0,
|
|
@@ -9885,346 +10010,433 @@ function requireProviderConfig() {
|
|
|
9885
10010
|
return providerConfig;
|
|
9886
10011
|
}
|
|
9887
10012
|
|
|
9888
|
-
var
|
|
10013
|
+
var providerEngines = {};
|
|
9889
10014
|
|
|
9890
|
-
var
|
|
10015
|
+
var modelInfo = {};
|
|
9891
10016
|
|
|
9892
|
-
var
|
|
9893
|
-
function
|
|
9894
|
-
if (
|
|
9895
|
-
|
|
9896
|
-
|
|
9897
|
-
|
|
9898
|
-
|
|
9899
|
-
|
|
9900
|
-
|
|
9901
|
-
|
|
9902
|
-
|
|
9903
|
-
|
|
9904
|
-
|
|
9905
|
-
|
|
9906
|
-
|
|
9907
|
-
|
|
9908
|
-
|
|
9909
|
-
|
|
9910
|
-
|
|
9911
|
-
|
|
9912
|
-
|
|
9913
|
-
|
|
9914
|
-
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
9919
|
-
|
|
9920
|
-
}
|
|
10017
|
+
var hasRequiredModelInfo;
|
|
10018
|
+
function requireModelInfo() {
|
|
10019
|
+
if (hasRequiredModelInfo) return modelInfo;
|
|
10020
|
+
hasRequiredModelInfo = 1;
|
|
10021
|
+
(function(exports$1) {
|
|
10022
|
+
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
10023
|
+
exports$1.MODEL_ALIAS_NAMES = exports$1.MODEL_ALIASES = void 0;
|
|
10024
|
+
exports$1.isLlmProviderId = isLlmProviderId;
|
|
10025
|
+
exports$1.isModelAliasName = isModelAliasName;
|
|
10026
|
+
exports$1.resolveModelInput = resolveModelInput;
|
|
10027
|
+
const provider_config_1 = requireProviderConfig();
|
|
10028
|
+
exports$1.MODEL_ALIASES = {
|
|
10029
|
+
fast: [
|
|
10030
|
+
{ provider: "cerebras", model: "qwen-3.8-27b" },
|
|
10031
|
+
{ provider: "groq", model: "qwen/qwen3.8-27b" },
|
|
10032
|
+
{ provider: "openrouter", model: "z-ai/glm-5.2" }
|
|
10033
|
+
],
|
|
10034
|
+
gemini: [
|
|
10035
|
+
{ provider: "gemini", model: "gemini-2.5-flash" },
|
|
10036
|
+
{ provider: "openrouter", model: "google/gemini-2.5-flash" }
|
|
10037
|
+
],
|
|
10038
|
+
qwen: [
|
|
10039
|
+
{ provider: "openrouter", model: "qwen/qwen3-vl-235b-a22b-instruct" }
|
|
10040
|
+
],
|
|
10041
|
+
sonnet: [
|
|
10042
|
+
{ provider: "openrouter", model: "anthropic/claude-sonnet-4.6" }
|
|
10043
|
+
],
|
|
10044
|
+
opus: [
|
|
10045
|
+
{ provider: "openrouter", model: "anthropic/claude-opus-4.7" }
|
|
10046
|
+
],
|
|
10047
|
+
haiku: [
|
|
10048
|
+
{ provider: "openrouter", model: "anthropic/claude-haiku-4.5" }
|
|
10049
|
+
],
|
|
10050
|
+
kimi: [
|
|
10051
|
+
{ provider: "openrouter", model: "moonshotai/kimi-k2.7-code" }
|
|
10052
|
+
],
|
|
10053
|
+
gpt: [
|
|
10054
|
+
{ provider: "openrouter", model: "openai/gpt-5" }
|
|
10055
|
+
]
|
|
10056
|
+
};
|
|
10057
|
+
exports$1.MODEL_ALIAS_NAMES = Object.keys(exports$1.MODEL_ALIASES);
|
|
10058
|
+
const MODEL_ALIAS_SET = new Set(exports$1.MODEL_ALIAS_NAMES);
|
|
10059
|
+
const LLM_PROVIDER_ID_SET = new Set(provider_config_1.LLM_PROVIDER_IDS);
|
|
10060
|
+
function isLlmProviderId(value) {
|
|
10061
|
+
return typeof value === "string" && LLM_PROVIDER_ID_SET.has(value);
|
|
10062
|
+
}
|
|
10063
|
+
function isModelAliasName(value) {
|
|
10064
|
+
return typeof value === "string" && MODEL_ALIAS_SET.has(value);
|
|
10065
|
+
}
|
|
10066
|
+
function validationError(message) {
|
|
10067
|
+
return {
|
|
10068
|
+
kind: "validation-error",
|
|
10069
|
+
message
|
|
10070
|
+
};
|
|
10071
|
+
}
|
|
10072
|
+
function validateProviderModel(input, configuredProviders) {
|
|
10073
|
+
if (!isLlmProviderId(input.provider)) {
|
|
10074
|
+
return validationError(`Invalid LLM provider: ${String(input.provider)}`);
|
|
9921
10075
|
}
|
|
9922
|
-
if (
|
|
9923
|
-
|
|
9924
|
-
|
|
9925
|
-
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
|
|
9929
|
-
|
|
9930
|
-
|
|
10076
|
+
if (!configuredProviders.has(input.provider)) {
|
|
10077
|
+
return validationError(`LLM provider ${input.provider} is not configured. Please check your API keys.`);
|
|
10078
|
+
}
|
|
10079
|
+
if (typeof input.model !== "string") {
|
|
10080
|
+
return validationError("model.model must be a string");
|
|
10081
|
+
}
|
|
10082
|
+
const model = input.model.trim();
|
|
10083
|
+
if (!model) {
|
|
10084
|
+
return validationError("model.model must be a non-empty string");
|
|
10085
|
+
}
|
|
10086
|
+
if (input.provider === "gemini" && model.startsWith("models/")) {
|
|
10087
|
+
return validationError('Gemini model names must use bare model IDs, for example "gemini-2.5-flash", not "models/gemini-2.5-flash".');
|
|
10088
|
+
}
|
|
10089
|
+
return {
|
|
10090
|
+
provider: input.provider,
|
|
10091
|
+
model
|
|
10092
|
+
};
|
|
10093
|
+
}
|
|
10094
|
+
function resolveModelInput(input, configuredProviders) {
|
|
10095
|
+
if (input == null) {
|
|
10096
|
+
return resolveModelInput({ alias: "fast" }, configuredProviders);
|
|
10097
|
+
}
|
|
10098
|
+
if (typeof input !== "object") {
|
|
10099
|
+
return validationError("model must be an object with either alias or provider/model fields");
|
|
10100
|
+
}
|
|
10101
|
+
if ("provider" in input || "model" in input) {
|
|
10102
|
+
return validateProviderModel(input, configuredProviders);
|
|
10103
|
+
}
|
|
10104
|
+
if ("alias" in input) {
|
|
10105
|
+
const alias = input.alias;
|
|
10106
|
+
if (!isModelAliasName(alias)) {
|
|
10107
|
+
return validationError(`Invalid model alias: ${String(alias)}`);
|
|
10108
|
+
}
|
|
10109
|
+
const configuredTarget = exports$1.MODEL_ALIASES[alias].find((target) => configuredProviders.has(target.provider));
|
|
10110
|
+
if (!configuredTarget) {
|
|
10111
|
+
return validationError(`No configured provider found for model alias ${alias}. Please check your API keys.`);
|
|
9931
10112
|
}
|
|
10113
|
+
return configuredTarget;
|
|
9932
10114
|
}
|
|
9933
|
-
|
|
9934
|
-
|
|
10115
|
+
return validationError("model must include either alias or provider/model fields");
|
|
10116
|
+
}
|
|
10117
|
+
})(modelInfo);
|
|
10118
|
+
return modelInfo;
|
|
10119
|
+
}
|
|
10120
|
+
|
|
10121
|
+
var httpEngine = {};
|
|
10122
|
+
|
|
10123
|
+
var providerCall = {};
|
|
10124
|
+
|
|
10125
|
+
var hasRequiredProviderCall;
|
|
10126
|
+
function requireProviderCall() {
|
|
10127
|
+
if (hasRequiredProviderCall) return providerCall;
|
|
10128
|
+
hasRequiredProviderCall = 1;
|
|
10129
|
+
Object.defineProperty(providerCall, "__esModule", { value: true });
|
|
10130
|
+
providerCall.callProvider = callProvider;
|
|
10131
|
+
const logger_1 = logger.requireLogger();
|
|
10132
|
+
const provider_config_1 = requireProviderConfig();
|
|
10133
|
+
async function callProvider(call, logger) {
|
|
10134
|
+
const { target, apiOperation, request } = call;
|
|
10135
|
+
const method = request.method ?? "POST";
|
|
10136
|
+
const spanId = (0, logger_1.generateSpanId)();
|
|
10137
|
+
const startTime = Date.now();
|
|
10138
|
+
let status;
|
|
10139
|
+
(0, logger_1.logLlmCallStart)(logger, spanId, target.provider, apiOperation, {
|
|
10140
|
+
url: request.loggableUrl ?? request.url,
|
|
10141
|
+
httpMethod: method,
|
|
10142
|
+
model: target.model,
|
|
10143
|
+
maxTokens: call.maxTokens
|
|
10144
|
+
});
|
|
10145
|
+
try {
|
|
10146
|
+
const response = await fetch(request.url, {
|
|
10147
|
+
method,
|
|
10148
|
+
headers: request.headers ?? {},
|
|
10149
|
+
body: toFetchableBody(request.body)
|
|
10150
|
+
});
|
|
10151
|
+
status = response.status;
|
|
10152
|
+
const reply = await call.parseResponse(response);
|
|
10153
|
+
(0, logger_1.logLlmCallComplete)(logger, spanId, target.provider, apiOperation, {
|
|
10154
|
+
status: response.status,
|
|
10155
|
+
responseLength: call.responseLength(reply),
|
|
10156
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
10157
|
+
usage: call.usage(reply)
|
|
10158
|
+
}, Date.now() - startTime);
|
|
10159
|
+
return { kind: "ok", reply };
|
|
10160
|
+
} catch (error) {
|
|
10161
|
+
(0, logger_1.logLlmCallError)(logger, spanId, target.provider, apiOperation, error, Date.now() - startTime);
|
|
10162
|
+
return {
|
|
10163
|
+
kind: "failed",
|
|
10164
|
+
status,
|
|
10165
|
+
message: `${provider_config_1.providerConfigs[target.provider].errorLabel} API request failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
10166
|
+
};
|
|
9935
10167
|
}
|
|
9936
10168
|
}
|
|
9937
|
-
|
|
10169
|
+
function toFetchableBody(body) {
|
|
10170
|
+
if (typeof body === "string" || body === void 0) {
|
|
10171
|
+
return body;
|
|
10172
|
+
}
|
|
10173
|
+
return JSON.stringify(body);
|
|
10174
|
+
}
|
|
10175
|
+
return providerCall;
|
|
9938
10176
|
}
|
|
9939
10177
|
|
|
9940
|
-
var
|
|
9941
|
-
function
|
|
9942
|
-
if (
|
|
9943
|
-
|
|
9944
|
-
Object.defineProperty(
|
|
9945
|
-
|
|
9946
|
-
|
|
9947
|
-
providerFormatters.buildGeminiAgenticRequest = buildGeminiAgenticRequest;
|
|
9948
|
-
providerFormatters.parseGeminiAgenticResponse = parseGeminiAgenticResponse;
|
|
9949
|
-
providerFormatters.streamOpenAiAgenticResponse = streamOpenAiAgenticResponse;
|
|
9950
|
-
providerFormatters.streamGeminiAgenticResponse = streamGeminiAgenticResponse;
|
|
10178
|
+
var hasRequiredHttpEngine;
|
|
10179
|
+
function requireHttpEngine() {
|
|
10180
|
+
if (hasRequiredHttpEngine) return httpEngine;
|
|
10181
|
+
hasRequiredHttpEngine = 1;
|
|
10182
|
+
Object.defineProperty(httpEngine, "__esModule", { value: true });
|
|
10183
|
+
httpEngine.HttpEngine = void 0;
|
|
10184
|
+
const provider_call_1 = requireProviderCall();
|
|
9951
10185
|
const provider_config_1 = requireProviderConfig();
|
|
9952
|
-
const
|
|
9953
|
-
|
|
9954
|
-
|
|
9955
|
-
|
|
9956
|
-
|
|
10186
|
+
const FATAL_HTTP_STATUSES = /* @__PURE__ */ new Set([401, 403, 404]);
|
|
10187
|
+
class HttpEngine {
|
|
10188
|
+
constructor(target, logger) {
|
|
10189
|
+
this.target = target;
|
|
10190
|
+
this.logger = logger;
|
|
9957
10191
|
}
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
|
|
9970
|
-
|
|
9971
|
-
|
|
9972
|
-
|
|
9973
|
-
|
|
9974
|
-
|
|
9975
|
-
|
|
9976
|
-
...toolCalls.length > 0 ? { tool_calls: toolCalls } : {}
|
|
9977
|
-
};
|
|
9978
|
-
result.push(openAiMsg);
|
|
9979
|
-
break;
|
|
9980
|
-
}
|
|
9981
|
-
case "toolResult":
|
|
9982
|
-
result.push({
|
|
9983
|
-
role: "tool",
|
|
9984
|
-
tool_call_id: msg.toolCallId,
|
|
9985
|
-
content: msg.content
|
|
9986
|
-
});
|
|
9987
|
-
break;
|
|
10192
|
+
/** Provider APIs are given the schema in the prompt; none is enforced natively yet. */
|
|
10193
|
+
nativeSchema() {
|
|
10194
|
+
return null;
|
|
10195
|
+
}
|
|
10196
|
+
async attempt(request) {
|
|
10197
|
+
const { provider, model, apiKey } = this.target;
|
|
10198
|
+
const config = provider_config_1.providerConfigs[provider];
|
|
10199
|
+
const call = await (0, provider_call_1.callProvider)({
|
|
10200
|
+
target: this.target,
|
|
10201
|
+
apiOperation: config.apiOperation,
|
|
10202
|
+
maxTokens: request.maxTokens,
|
|
10203
|
+
request: config.buildRequest({ prompt: request.prompt, model, maxTokens: request.maxTokens }, apiKey),
|
|
10204
|
+
parseResponse: config.parseResponse,
|
|
10205
|
+
responseLength: (reply) => reply.text.length,
|
|
10206
|
+
usage: (reply) => reply.usage
|
|
10207
|
+
}, this.logger);
|
|
10208
|
+
if (call.kind === "failed") {
|
|
10209
|
+
return { kind: "failed", failure: failureForStatus(call.status, call.message) };
|
|
9988
10210
|
}
|
|
10211
|
+
return {
|
|
10212
|
+
kind: "answered",
|
|
10213
|
+
answer: { kind: "text", text: call.reply.text },
|
|
10214
|
+
usage: call.reply.usage,
|
|
10215
|
+
origin: { engine: "http", provider, model }
|
|
10216
|
+
};
|
|
9989
10217
|
}
|
|
9990
|
-
return result;
|
|
9991
10218
|
}
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
name: t.name,
|
|
9997
|
-
description: t.description,
|
|
9998
|
-
parameters: t.parameters
|
|
9999
|
-
}
|
|
10000
|
-
}));
|
|
10219
|
+
httpEngine.HttpEngine = HttpEngine;
|
|
10220
|
+
function failureForStatus(status, message) {
|
|
10221
|
+
const fatal = status !== void 0 && FATAL_HTTP_STATUSES.has(status);
|
|
10222
|
+
return { kind: fatal ? "fatal" : "transient", message };
|
|
10001
10223
|
}
|
|
10002
|
-
|
|
10003
|
-
|
|
10004
|
-
|
|
10005
|
-
|
|
10006
|
-
|
|
10007
|
-
|
|
10008
|
-
|
|
10009
|
-
|
|
10010
|
-
|
|
10011
|
-
|
|
10012
|
-
|
|
10013
|
-
|
|
10014
|
-
|
|
10015
|
-
|
|
10016
|
-
|
|
10017
|
-
|
|
10018
|
-
};
|
|
10019
|
-
return {
|
|
10020
|
-
url: baseUrl,
|
|
10021
|
-
method: "POST",
|
|
10022
|
-
headers,
|
|
10023
|
-
body,
|
|
10024
|
-
loggableHeaders: {
|
|
10025
|
-
...headers,
|
|
10026
|
-
Authorization: "Bearer [REDACTED]"
|
|
10027
|
-
},
|
|
10028
|
-
loggableBody: body
|
|
10029
|
-
};
|
|
10224
|
+
return httpEngine;
|
|
10225
|
+
}
|
|
10226
|
+
|
|
10227
|
+
var hasRequiredProviderEngines;
|
|
10228
|
+
function requireProviderEngines() {
|
|
10229
|
+
if (hasRequiredProviderEngines) return providerEngines;
|
|
10230
|
+
hasRequiredProviderEngines = 1;
|
|
10231
|
+
Object.defineProperty(providerEngines, "__esModule", { value: true });
|
|
10232
|
+
providerEngines.ProviderEngines = void 0;
|
|
10233
|
+
providerEngines.providerEngines = providerEngines$1;
|
|
10234
|
+
const logger_1 = logger.requireLogger();
|
|
10235
|
+
const nua_errors_1 = requireNuaErrors();
|
|
10236
|
+
const model_info_1 = requireModelInfo();
|
|
10237
|
+
const http_engine_1 = requireHttpEngine();
|
|
10238
|
+
function providerEngines$1(config) {
|
|
10239
|
+
return new ProviderEngines(config);
|
|
10030
10240
|
}
|
|
10031
|
-
|
|
10032
|
-
|
|
10033
|
-
|
|
10241
|
+
class ProviderEngines {
|
|
10242
|
+
constructor(config) {
|
|
10243
|
+
this.logger = config.logger ?? new logger_1.ConsoleLogger();
|
|
10244
|
+
this.defaultModel = config.model;
|
|
10245
|
+
const apiKeys = /* @__PURE__ */ new Map();
|
|
10246
|
+
for (const [id, provider] of Object.entries(config.providers)) {
|
|
10247
|
+
if (provider?.apiKey) {
|
|
10248
|
+
apiKeys.set(id, provider.apiKey);
|
|
10249
|
+
}
|
|
10250
|
+
}
|
|
10251
|
+
this.apiKeys = apiKeys;
|
|
10034
10252
|
}
|
|
10035
|
-
|
|
10036
|
-
|
|
10037
|
-
|
|
10038
|
-
|
|
10039
|
-
|
|
10040
|
-
|
|
10253
|
+
route(model) {
|
|
10254
|
+
const resolved = this.resolve(model);
|
|
10255
|
+
if (resolved.kind === "unroutable") {
|
|
10256
|
+
return resolved;
|
|
10257
|
+
}
|
|
10258
|
+
return { kind: "routed", engine: new http_engine_1.HttpEngine(resolved.target, this.logger) };
|
|
10041
10259
|
}
|
|
10042
|
-
|
|
10043
|
-
|
|
10260
|
+
/** The provider model, with its API key, that a model choice runs on. */
|
|
10261
|
+
resolve(model) {
|
|
10262
|
+
const providerModel = (0, model_info_1.resolveModelInput)(model ?? this.defaultModel, new Set(this.apiKeys.keys()));
|
|
10263
|
+
if ((0, nua_errors_1.isNuaValidationError)(providerModel)) {
|
|
10264
|
+
return { kind: "unroutable", message: providerModel.message };
|
|
10265
|
+
}
|
|
10266
|
+
const apiKey = this.apiKeys.get(providerModel.provider);
|
|
10267
|
+
if (apiKey === void 0) {
|
|
10268
|
+
return { kind: "unroutable", message: `LLM provider ${providerModel.provider} is not configured.` };
|
|
10269
|
+
}
|
|
10270
|
+
return { kind: "resolved", target: { ...providerModel, apiKey } };
|
|
10044
10271
|
}
|
|
10045
|
-
return parsed;
|
|
10046
10272
|
}
|
|
10047
|
-
|
|
10048
|
-
|
|
10049
|
-
|
|
10273
|
+
providerEngines.ProviderEngines = ProviderEngines;
|
|
10274
|
+
return providerEngines;
|
|
10275
|
+
}
|
|
10276
|
+
|
|
10277
|
+
var validateJsonSchema = {};
|
|
10278
|
+
|
|
10279
|
+
var errorUtils = {};
|
|
10280
|
+
|
|
10281
|
+
var hasRequiredErrorUtils;
|
|
10282
|
+
function requireErrorUtils() {
|
|
10283
|
+
if (hasRequiredErrorUtils) return errorUtils;
|
|
10284
|
+
hasRequiredErrorUtils = 1;
|
|
10285
|
+
Object.defineProperty(errorUtils, "__esModule", { value: true });
|
|
10286
|
+
errorUtils.getErrorMessageFromException = getErrorMessageFromException;
|
|
10287
|
+
function isErrorWithMessage(error) {
|
|
10288
|
+
return typeof error === "object" && error !== null && "message" in error && typeof error.message === "string";
|
|
10289
|
+
}
|
|
10290
|
+
function getErrorMessageFromException(error) {
|
|
10291
|
+
if (isErrorWithMessage(error)) {
|
|
10292
|
+
return error.message;
|
|
10293
|
+
}
|
|
10294
|
+
return String(error);
|
|
10295
|
+
}
|
|
10296
|
+
return errorUtils;
|
|
10297
|
+
}
|
|
10298
|
+
|
|
10299
|
+
var hasRequiredValidateJsonSchema;
|
|
10300
|
+
function requireValidateJsonSchema() {
|
|
10301
|
+
if (hasRequiredValidateJsonSchema) return validateJsonSchema;
|
|
10302
|
+
hasRequiredValidateJsonSchema = 1;
|
|
10303
|
+
Object.defineProperty(validateJsonSchema, "__esModule", { value: true });
|
|
10304
|
+
validateJsonSchema.validateJsonSchema = void 0;
|
|
10305
|
+
const error_utils_1 = requireErrorUtils();
|
|
10306
|
+
const ajv_instances_1 = requireAjvInstances();
|
|
10307
|
+
const validateJsonSchema$1 = (schema) => {
|
|
10308
|
+
if (!schema || typeof schema !== "object") {
|
|
10309
|
+
return {
|
|
10310
|
+
kind: "validation-error",
|
|
10311
|
+
message: "Schema must be a valid object"
|
|
10312
|
+
};
|
|
10313
|
+
}
|
|
10314
|
+
const ajvInstance = ajv_instances_1.ajvInstances.getInstanceForSchema(schema);
|
|
10315
|
+
const isValidSchema = ajvInstance.validateSchema(schema);
|
|
10316
|
+
let errors = "";
|
|
10317
|
+
if (ajvInstance.errors) {
|
|
10318
|
+
errors = ajvInstance.errors.map((e) => JSON.stringify(e, null, 2)).join("; ");
|
|
10319
|
+
} else if (isValidSchema) {
|
|
10050
10320
|
try {
|
|
10051
|
-
|
|
10052
|
-
|
|
10053
|
-
throw new Error(`${errorLabel} API error: ${response.status} - ${message}`);
|
|
10321
|
+
ajvInstance.compile(schema);
|
|
10322
|
+
return true;
|
|
10054
10323
|
} catch (e) {
|
|
10055
|
-
|
|
10056
|
-
throw e;
|
|
10057
|
-
throw new Error(`${errorLabel} API error: ${response.status} - ${errorBody}`);
|
|
10324
|
+
errors = (0, error_utils_1.getErrorMessageFromException)(e);
|
|
10058
10325
|
}
|
|
10326
|
+
} else {
|
|
10327
|
+
errors = "unexpected-situation-no-errors-found-for-invalid-schema";
|
|
10059
10328
|
}
|
|
10060
|
-
const responseBody = await response.json();
|
|
10061
|
-
const choice = responseBody.choices?.[0];
|
|
10062
|
-
if (!choice?.message) {
|
|
10063
|
-
throw new Error(`${errorLabel} API error: No message in response. Body: ${JSON.stringify(responseBody)}`);
|
|
10064
|
-
}
|
|
10065
|
-
const contentBlocks = [];
|
|
10066
|
-
const assistantText = (0, provider_config_1.extractOpenAiMessageText)(choice.message);
|
|
10067
|
-
if (assistantText) {
|
|
10068
|
-
contentBlocks.push({
|
|
10069
|
-
type: "text",
|
|
10070
|
-
text: assistantText
|
|
10071
|
-
});
|
|
10072
|
-
}
|
|
10073
|
-
if (choice.message.tool_calls) {
|
|
10074
|
-
for (const tc of choice.message.tool_calls) {
|
|
10075
|
-
contentBlocks.push({
|
|
10076
|
-
type: "toolCall",
|
|
10077
|
-
id: tc.id,
|
|
10078
|
-
name: tc.function.name,
|
|
10079
|
-
arguments: parseOpenAiToolArguments(tc.function.arguments, tc.function.name, errorLabel)
|
|
10080
|
-
});
|
|
10081
|
-
}
|
|
10082
|
-
}
|
|
10083
|
-
const usage = (0, provider_config_1.normalizeOpenAiUsage)(responseBody.usage);
|
|
10084
|
-
const stopReason = choice.finish_reason === "tool_calls" || choice.finish_reason === "stop" ? choice.finish_reason === "tool_calls" ? "tool_use" : "stop" : choice.message.tool_calls && choice.message.tool_calls.length > 0 ? "tool_use" : "stop";
|
|
10085
10329
|
return {
|
|
10086
|
-
|
|
10087
|
-
|
|
10088
|
-
content: contentBlocks
|
|
10089
|
-
},
|
|
10090
|
-
usage,
|
|
10091
|
-
stopReason
|
|
10330
|
+
kind: "validation-error",
|
|
10331
|
+
message: `Unable to validate JSON schema: ${errors}`
|
|
10092
10332
|
};
|
|
10093
|
-
}
|
|
10094
|
-
|
|
10095
|
-
|
|
10096
|
-
|
|
10097
|
-
|
|
10098
|
-
|
|
10099
|
-
|
|
10100
|
-
|
|
10101
|
-
|
|
10102
|
-
|
|
10103
|
-
|
|
10104
|
-
|
|
10105
|
-
|
|
10106
|
-
|
|
10107
|
-
|
|
10108
|
-
|
|
10109
|
-
|
|
10110
|
-
|
|
10111
|
-
|
|
10112
|
-
name: block.name,
|
|
10113
|
-
args: block.arguments
|
|
10114
|
-
}
|
|
10115
|
-
});
|
|
10116
|
-
}
|
|
10117
|
-
}
|
|
10118
|
-
result.push({ role: "model", parts });
|
|
10119
|
-
break;
|
|
10120
|
-
}
|
|
10121
|
-
case "toolResult": {
|
|
10122
|
-
result.push({
|
|
10123
|
-
role: "user",
|
|
10124
|
-
parts: [
|
|
10125
|
-
{
|
|
10126
|
-
functionResponse: {
|
|
10127
|
-
name: msg.toolName,
|
|
10128
|
-
response: { content: msg.content }
|
|
10129
|
-
}
|
|
10130
|
-
}
|
|
10131
|
-
]
|
|
10132
|
-
});
|
|
10133
|
-
break;
|
|
10333
|
+
};
|
|
10334
|
+
validateJsonSchema.validateJsonSchema = validateJsonSchema$1;
|
|
10335
|
+
return validateJsonSchema;
|
|
10336
|
+
}
|
|
10337
|
+
|
|
10338
|
+
var stableStringify = {};
|
|
10339
|
+
|
|
10340
|
+
var hasRequiredStableStringify;
|
|
10341
|
+
function requireStableStringify() {
|
|
10342
|
+
if (hasRequiredStableStringify) return stableStringify;
|
|
10343
|
+
hasRequiredStableStringify = 1;
|
|
10344
|
+
Object.defineProperty(stableStringify, "__esModule", { value: true });
|
|
10345
|
+
stableStringify.stableStringify = stableStringify$1;
|
|
10346
|
+
function stableStringify$1(value) {
|
|
10347
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
10348
|
+
const sorter = (_key, currentValue) => {
|
|
10349
|
+
if (currentValue && typeof currentValue === "object" && !Array.isArray(currentValue)) {
|
|
10350
|
+
if (seen.has(currentValue)) {
|
|
10351
|
+
return currentValue;
|
|
10134
10352
|
}
|
|
10353
|
+
seen.add(currentValue);
|
|
10354
|
+
return Object.keys(currentValue).sort().reduce((acc, key) => {
|
|
10355
|
+
acc[key] = currentValue[key];
|
|
10356
|
+
return acc;
|
|
10357
|
+
}, {});
|
|
10135
10358
|
}
|
|
10136
|
-
|
|
10137
|
-
|
|
10138
|
-
|
|
10139
|
-
function convertToolsToGemini(tools) {
|
|
10140
|
-
if (tools.length === 0)
|
|
10141
|
-
return [];
|
|
10142
|
-
return [
|
|
10143
|
-
{
|
|
10144
|
-
functionDeclarations: tools.map((t) => ({
|
|
10145
|
-
name: t.name,
|
|
10146
|
-
description: t.description,
|
|
10147
|
-
parameters: t.parameters
|
|
10148
|
-
}))
|
|
10149
|
-
}
|
|
10150
|
-
];
|
|
10359
|
+
return currentValue;
|
|
10360
|
+
};
|
|
10361
|
+
return JSON.stringify(value, sorter) ?? "";
|
|
10151
10362
|
}
|
|
10152
|
-
|
|
10153
|
-
|
|
10154
|
-
|
|
10155
|
-
|
|
10156
|
-
|
|
10157
|
-
|
|
10158
|
-
|
|
10363
|
+
return stableStringify;
|
|
10364
|
+
}
|
|
10365
|
+
|
|
10366
|
+
var schemaUtils = {};
|
|
10367
|
+
|
|
10368
|
+
var hasRequiredSchemaUtils;
|
|
10369
|
+
function requireSchemaUtils() {
|
|
10370
|
+
if (hasRequiredSchemaUtils) return schemaUtils;
|
|
10371
|
+
hasRequiredSchemaUtils = 1;
|
|
10372
|
+
Object.defineProperty(schemaUtils, "__esModule", { value: true });
|
|
10373
|
+
return schemaUtils;
|
|
10374
|
+
}
|
|
10375
|
+
|
|
10376
|
+
var listSchema = {};
|
|
10377
|
+
|
|
10378
|
+
var hasRequiredListSchema;
|
|
10379
|
+
function requireListSchema() {
|
|
10380
|
+
if (hasRequiredListSchema) return listSchema;
|
|
10381
|
+
hasRequiredListSchema = 1;
|
|
10382
|
+
Object.defineProperty(listSchema, "__esModule", { value: true });
|
|
10383
|
+
listSchema.listSchema = listSchema$1;
|
|
10384
|
+
listSchema.parseListSchema = parseListSchema;
|
|
10385
|
+
function listSchema$1(itemSchema, keys) {
|
|
10386
|
+
const jsonSchema = {
|
|
10387
|
+
type: "array",
|
|
10388
|
+
items: {
|
|
10389
|
+
type: "object",
|
|
10390
|
+
required: [keys.primaryKey, keys.outputName],
|
|
10391
|
+
properties: {
|
|
10392
|
+
[keys.primaryKey]: {
|
|
10393
|
+
anyOf: [{ type: "string" }, { type: "number" }, { type: "integer" }]
|
|
10394
|
+
},
|
|
10395
|
+
[keys.outputName]: itemSchema
|
|
10396
|
+
}
|
|
10159
10397
|
}
|
|
10160
10398
|
};
|
|
10161
|
-
if (
|
|
10162
|
-
|
|
10399
|
+
if (typeof itemSchema.$schema === "string") {
|
|
10400
|
+
jsonSchema.$schema = itemSchema.$schema;
|
|
10163
10401
|
}
|
|
10164
|
-
|
|
10165
|
-
|
|
10166
|
-
|
|
10167
|
-
|
|
10402
|
+
return brand(keys, jsonSchema);
|
|
10403
|
+
}
|
|
10404
|
+
function parseListSchema(jsonSchema, keys) {
|
|
10405
|
+
if (isObject(jsonSchema) && jsonSchema.type === "array" && rowsHoldKeys(jsonSchema.items, keys)) {
|
|
10406
|
+
return brand(keys, jsonSchema);
|
|
10168
10407
|
}
|
|
10169
|
-
const action = options.stream ? "streamGenerateContent" : "generateContent";
|
|
10170
|
-
const altParam = options.stream ? "&alt=sse" : "";
|
|
10171
|
-
const url = `https://generativelanguage.googleapis.com/v1beta/models/${options.model}:${action}?key=${apiKey}${altParam}`;
|
|
10172
10408
|
return {
|
|
10173
|
-
|
|
10174
|
-
|
|
10175
|
-
headers: {
|
|
10176
|
-
"Content-Type": "application/json"
|
|
10177
|
-
},
|
|
10178
|
-
body,
|
|
10179
|
-
loggableUrl: url.replace(/key=[^&]+/, "key=[REDACTED]"),
|
|
10180
|
-
loggableBody: body
|
|
10409
|
+
kind: "validation-error",
|
|
10410
|
+
message: `Not a list schema with rows keyed by "${keys.primaryKey}" holding "${keys.outputName}"`
|
|
10181
10411
|
};
|
|
10182
10412
|
}
|
|
10183
|
-
|
|
10184
|
-
if (
|
|
10185
|
-
|
|
10186
|
-
try {
|
|
10187
|
-
const parsed = JSON.parse(errorBody);
|
|
10188
|
-
const message = parsed?.error?.message || errorBody;
|
|
10189
|
-
throw new Error(`Gemini API error: ${response.status} - ${message}`);
|
|
10190
|
-
} catch (e) {
|
|
10191
|
-
if (e instanceof Error && e.message.startsWith("Gemini API error:"))
|
|
10192
|
-
throw e;
|
|
10193
|
-
throw new Error(`Gemini API error: ${response.status} - ${errorBody}`);
|
|
10194
|
-
}
|
|
10195
|
-
}
|
|
10196
|
-
const responseBody = await response.json();
|
|
10197
|
-
const candidate = responseBody.candidates?.[0];
|
|
10198
|
-
if (!candidate?.content?.parts) {
|
|
10199
|
-
throw new Error(`Gemini API error: No content in response. Body: ${JSON.stringify(responseBody)}`);
|
|
10200
|
-
}
|
|
10201
|
-
const contentBlocks = [];
|
|
10202
|
-
let hasToolCalls = false;
|
|
10203
|
-
for (const part of candidate.content.parts) {
|
|
10204
|
-
if (part.text) {
|
|
10205
|
-
contentBlocks.push({ type: "text", text: part.text });
|
|
10206
|
-
}
|
|
10207
|
-
if (part.functionCall) {
|
|
10208
|
-
hasToolCalls = true;
|
|
10209
|
-
contentBlocks.push({
|
|
10210
|
-
type: "toolCall",
|
|
10211
|
-
id: crypto.randomUUID(),
|
|
10212
|
-
name: part.functionCall.name,
|
|
10213
|
-
arguments: part.functionCall.args
|
|
10214
|
-
});
|
|
10215
|
-
}
|
|
10413
|
+
function rowsHoldKeys(items, keys) {
|
|
10414
|
+
if (!isObject(items) || !isObject(items.properties) || !Array.isArray(items.required)) {
|
|
10415
|
+
return false;
|
|
10216
10416
|
}
|
|
10217
|
-
const
|
|
10218
|
-
|
|
10219
|
-
|
|
10220
|
-
|
|
10221
|
-
|
|
10222
|
-
|
|
10223
|
-
|
|
10224
|
-
|
|
10225
|
-
stopReason
|
|
10226
|
-
};
|
|
10417
|
+
const { properties, required } = items;
|
|
10418
|
+
return [keys.primaryKey, keys.outputName].every((key) => key in properties && required.includes(key));
|
|
10419
|
+
}
|
|
10420
|
+
function brand(keys, jsonSchema) {
|
|
10421
|
+
return { primaryKey: keys.primaryKey, outputName: keys.outputName, jsonSchema };
|
|
10422
|
+
}
|
|
10423
|
+
function isObject(value) {
|
|
10424
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10227
10425
|
}
|
|
10426
|
+
return listSchema;
|
|
10427
|
+
}
|
|
10428
|
+
|
|
10429
|
+
var runAgent = {};
|
|
10430
|
+
|
|
10431
|
+
var agentLoop = {};
|
|
10432
|
+
|
|
10433
|
+
var hasRequiredAgentLoop;
|
|
10434
|
+
function requireAgentLoop() {
|
|
10435
|
+
if (hasRequiredAgentLoop) return agentLoop;
|
|
10436
|
+
hasRequiredAgentLoop = 1;
|
|
10437
|
+
Object.defineProperty(agentLoop, "__esModule", { value: true });
|
|
10438
|
+
agentLoop.runAgentLoop = runAgentLoop;
|
|
10439
|
+
const provider_config_1 = requireProviderConfig();
|
|
10228
10440
|
function safeEmit(onEvent, event) {
|
|
10229
10441
|
if (!onEvent)
|
|
10230
10442
|
return;
|
|
@@ -10233,441 +10445,470 @@ function requireProviderFormatters() {
|
|
|
10233
10445
|
} catch {
|
|
10234
10446
|
}
|
|
10235
10447
|
}
|
|
10236
|
-
async function
|
|
10237
|
-
|
|
10238
|
-
|
|
10448
|
+
async function runAgentLoop(params) {
|
|
10449
|
+
const messages = [...params.messages];
|
|
10450
|
+
let totalUsage = { ...provider_config_1.normalizedUsageZero };
|
|
10451
|
+
const toolsByName = new Map(params.tools.map((tool) => [tool.name, tool]));
|
|
10452
|
+
let completionReason = "max_turns";
|
|
10453
|
+
const onEvent = params.onEvent;
|
|
10454
|
+
for (let turn = 0; turn < params.maxTurns; turn++) {
|
|
10455
|
+
safeEmit(onEvent, { type: "turn_start", turn });
|
|
10456
|
+
let response;
|
|
10239
10457
|
try {
|
|
10240
|
-
|
|
10241
|
-
|
|
10242
|
-
|
|
10243
|
-
|
|
10244
|
-
|
|
10245
|
-
throw e;
|
|
10246
|
-
throw new Error(`${errorLabel} API error: ${response.status} - ${errorBody}`);
|
|
10458
|
+
response = await params.sendRequest(messages, params.tools, params.systemPrompt);
|
|
10459
|
+
} catch (error) {
|
|
10460
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
10461
|
+
safeEmit(onEvent, { type: "error", error: errorMessage });
|
|
10462
|
+
return buildAgentResult(messages, totalUsage, "error", errorMessage);
|
|
10247
10463
|
}
|
|
10248
|
-
|
|
10249
|
-
|
|
10250
|
-
|
|
10251
|
-
|
|
10252
|
-
|
|
10253
|
-
|
|
10254
|
-
|
|
10255
|
-
|
|
10256
|
-
|
|
10257
|
-
|
|
10258
|
-
|
|
10259
|
-
|
|
10260
|
-
} catch {
|
|
10261
|
-
continue;
|
|
10464
|
+
messages.push(response.message);
|
|
10465
|
+
totalUsage = addUsage(totalUsage, response.usage);
|
|
10466
|
+
safeEmit(onEvent, {
|
|
10467
|
+
type: "response_complete",
|
|
10468
|
+
message: response.message,
|
|
10469
|
+
usage: response.usage,
|
|
10470
|
+
stopReason: response.stopReason
|
|
10471
|
+
});
|
|
10472
|
+
const toolCalls = response.message.content.filter((c) => c.type === "toolCall");
|
|
10473
|
+
if (toolCalls.length === 0 || response.stopReason === "stop") {
|
|
10474
|
+
completionReason = "stop";
|
|
10475
|
+
return buildAgentResult(messages, totalUsage, completionReason);
|
|
10262
10476
|
}
|
|
10263
|
-
|
|
10264
|
-
|
|
10265
|
-
|
|
10266
|
-
|
|
10267
|
-
|
|
10268
|
-
|
|
10269
|
-
|
|
10270
|
-
|
|
10477
|
+
for (const toolCall of toolCalls) {
|
|
10478
|
+
safeEmit(onEvent, {
|
|
10479
|
+
type: "tool_start",
|
|
10480
|
+
toolCallId: toolCall.id,
|
|
10481
|
+
toolName: toolCall.name,
|
|
10482
|
+
arguments: toolCall.arguments
|
|
10483
|
+
});
|
|
10484
|
+
const tool = toolsByName.get(toolCall.name);
|
|
10485
|
+
if (!tool) {
|
|
10486
|
+
const result = {
|
|
10487
|
+
content: `Tool "${toolCall.name}" not found`,
|
|
10488
|
+
isError: true
|
|
10489
|
+
};
|
|
10490
|
+
messages.push({
|
|
10491
|
+
role: "toolResult",
|
|
10492
|
+
toolCallId: toolCall.id,
|
|
10493
|
+
toolName: toolCall.name,
|
|
10494
|
+
content: result.content,
|
|
10495
|
+
isError: true
|
|
10496
|
+
});
|
|
10497
|
+
safeEmit(onEvent, {
|
|
10498
|
+
type: "tool_complete",
|
|
10499
|
+
toolCallId: toolCall.id,
|
|
10500
|
+
toolName: toolCall.name,
|
|
10501
|
+
result
|
|
10502
|
+
});
|
|
10503
|
+
continue;
|
|
10504
|
+
}
|
|
10505
|
+
try {
|
|
10506
|
+
const result = await tool.execute(toolCall.arguments);
|
|
10507
|
+
messages.push({
|
|
10508
|
+
role: "toolResult",
|
|
10509
|
+
toolCallId: toolCall.id,
|
|
10510
|
+
toolName: toolCall.name,
|
|
10511
|
+
content: result.content,
|
|
10512
|
+
isError: result.isError ?? false
|
|
10513
|
+
});
|
|
10514
|
+
safeEmit(onEvent, {
|
|
10515
|
+
type: "tool_complete",
|
|
10516
|
+
toolCallId: toolCall.id,
|
|
10517
|
+
toolName: toolCall.name,
|
|
10518
|
+
result
|
|
10519
|
+
});
|
|
10520
|
+
} catch (error) {
|
|
10521
|
+
const errorContent = `Tool execution error: ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
10522
|
+
const result = { content: errorContent, isError: true };
|
|
10523
|
+
messages.push({
|
|
10524
|
+
role: "toolResult",
|
|
10525
|
+
toolCallId: toolCall.id,
|
|
10526
|
+
toolName: toolCall.name,
|
|
10527
|
+
content: errorContent,
|
|
10528
|
+
isError: true
|
|
10529
|
+
});
|
|
10530
|
+
safeEmit(onEvent, {
|
|
10531
|
+
type: "tool_complete",
|
|
10532
|
+
toolCallId: toolCall.id,
|
|
10533
|
+
toolName: toolCall.name,
|
|
10534
|
+
result
|
|
10535
|
+
});
|
|
10536
|
+
}
|
|
10271
10537
|
}
|
|
10272
|
-
|
|
10273
|
-
|
|
10274
|
-
|
|
10275
|
-
|
|
10276
|
-
|
|
10277
|
-
|
|
10538
|
+
}
|
|
10539
|
+
return buildAgentResult(messages, totalUsage, completionReason, `Reached maxTurns limit (${params.maxTurns}) before receiving a final response`);
|
|
10540
|
+
}
|
|
10541
|
+
function addUsage(a, b) {
|
|
10542
|
+
return {
|
|
10543
|
+
promptTokens: a.promptTokens + b.promptTokens,
|
|
10544
|
+
completionTokens: a.completionTokens + b.completionTokens,
|
|
10545
|
+
totalTokens: a.totalTokens + b.totalTokens
|
|
10546
|
+
};
|
|
10547
|
+
}
|
|
10548
|
+
function extractLastAssistantText(messages) {
|
|
10549
|
+
const lastAssistant = [...messages].reverse().find((m) => m.role === "assistant");
|
|
10550
|
+
if (lastAssistant?.role !== "assistant") {
|
|
10551
|
+
return void 0;
|
|
10552
|
+
}
|
|
10553
|
+
const text = lastAssistant.content.filter((c) => c.type === "text").map((c) => c.text).join("");
|
|
10554
|
+
return text || void 0;
|
|
10555
|
+
}
|
|
10556
|
+
function buildAgentResult(messages, usage, completionReason, error) {
|
|
10557
|
+
const success = completionReason === "stop" && !error;
|
|
10558
|
+
return {
|
|
10559
|
+
success,
|
|
10560
|
+
completionReason,
|
|
10561
|
+
messages,
|
|
10562
|
+
textResponse: extractLastAssistantText(messages),
|
|
10563
|
+
usage,
|
|
10564
|
+
error
|
|
10565
|
+
};
|
|
10566
|
+
}
|
|
10567
|
+
return agentLoop;
|
|
10568
|
+
}
|
|
10569
|
+
|
|
10570
|
+
var agentTurn = {};
|
|
10571
|
+
|
|
10572
|
+
var providerFormatters = {};
|
|
10573
|
+
|
|
10574
|
+
var sseParser = {};
|
|
10575
|
+
|
|
10576
|
+
var hasRequiredSseParser;
|
|
10577
|
+
function requireSseParser() {
|
|
10578
|
+
if (hasRequiredSseParser) return sseParser;
|
|
10579
|
+
hasRequiredSseParser = 1;
|
|
10580
|
+
Object.defineProperty(sseParser, "__esModule", { value: true });
|
|
10581
|
+
sseParser.parseSSEStream = parseSSEStream;
|
|
10582
|
+
async function* parseSSEStream(stream) {
|
|
10583
|
+
const reader = stream.getReader();
|
|
10584
|
+
const decoder = new TextDecoder();
|
|
10585
|
+
let buffer = "";
|
|
10586
|
+
try {
|
|
10587
|
+
while (true) {
|
|
10588
|
+
const { done, value } = await reader.read();
|
|
10589
|
+
if (done)
|
|
10590
|
+
break;
|
|
10591
|
+
buffer += decoder.decode(value, { stream: true });
|
|
10592
|
+
const parts = buffer.split(/\r?\n\r?\n/);
|
|
10593
|
+
buffer = parts.pop();
|
|
10594
|
+
for (const part of parts) {
|
|
10595
|
+
for (const line of part.split(/\r?\n/)) {
|
|
10596
|
+
if (line.startsWith("data: ")) {
|
|
10597
|
+
const data = line.slice(6);
|
|
10598
|
+
if (data === "[DONE]") {
|
|
10599
|
+
return;
|
|
10600
|
+
}
|
|
10601
|
+
yield data;
|
|
10602
|
+
}
|
|
10603
|
+
}
|
|
10604
|
+
}
|
|
10278
10605
|
}
|
|
10279
|
-
if (
|
|
10280
|
-
for (const
|
|
10281
|
-
|
|
10282
|
-
|
|
10283
|
-
if (
|
|
10284
|
-
|
|
10606
|
+
if (buffer.trim()) {
|
|
10607
|
+
for (const line of buffer.split(/\r?\n/)) {
|
|
10608
|
+
if (line.startsWith("data: ")) {
|
|
10609
|
+
const data = line.slice(6);
|
|
10610
|
+
if (data === "[DONE]") {
|
|
10611
|
+
return;
|
|
10285
10612
|
}
|
|
10286
|
-
|
|
10287
|
-
toolCallAccumulators.set(tc.index, {
|
|
10288
|
-
id: tc.id ?? "",
|
|
10289
|
-
name: tc.function?.name ?? "",
|
|
10290
|
-
arguments: tc.function?.arguments ?? ""
|
|
10291
|
-
});
|
|
10613
|
+
yield data;
|
|
10292
10614
|
}
|
|
10293
10615
|
}
|
|
10294
10616
|
}
|
|
10617
|
+
} finally {
|
|
10618
|
+
reader.releaseLock();
|
|
10295
10619
|
}
|
|
10296
|
-
|
|
10297
|
-
|
|
10298
|
-
|
|
10620
|
+
}
|
|
10621
|
+
return sseParser;
|
|
10622
|
+
}
|
|
10623
|
+
|
|
10624
|
+
var hasRequiredProviderFormatters;
|
|
10625
|
+
function requireProviderFormatters() {
|
|
10626
|
+
if (hasRequiredProviderFormatters) return providerFormatters;
|
|
10627
|
+
hasRequiredProviderFormatters = 1;
|
|
10628
|
+
Object.defineProperty(providerFormatters, "__esModule", { value: true });
|
|
10629
|
+
providerFormatters.buildOpenAiAgenticRequest = buildOpenAiAgenticRequest;
|
|
10630
|
+
providerFormatters.parseOpenAiAgenticResponse = parseOpenAiAgenticResponse;
|
|
10631
|
+
providerFormatters.buildGeminiAgenticRequest = buildGeminiAgenticRequest;
|
|
10632
|
+
providerFormatters.parseGeminiAgenticResponse = parseGeminiAgenticResponse;
|
|
10633
|
+
providerFormatters.streamOpenAiAgenticResponse = streamOpenAiAgenticResponse;
|
|
10634
|
+
providerFormatters.streamGeminiAgenticResponse = streamGeminiAgenticResponse;
|
|
10635
|
+
const provider_config_1 = requireProviderConfig();
|
|
10636
|
+
const sse_parser_1 = requireSseParser();
|
|
10637
|
+
function convertMessagesToOpenAi(messages, systemPrompt) {
|
|
10638
|
+
const result = [];
|
|
10639
|
+
if (systemPrompt) {
|
|
10640
|
+
result.push({ role: "system", content: systemPrompt });
|
|
10299
10641
|
}
|
|
10300
|
-
const
|
|
10301
|
-
|
|
10302
|
-
|
|
10303
|
-
|
|
10304
|
-
|
|
10305
|
-
|
|
10306
|
-
|
|
10307
|
-
|
|
10642
|
+
for (const msg of messages) {
|
|
10643
|
+
switch (msg.role) {
|
|
10644
|
+
case "user":
|
|
10645
|
+
result.push({ role: "user", content: msg.content });
|
|
10646
|
+
break;
|
|
10647
|
+
case "assistant": {
|
|
10648
|
+
const textParts = msg.content.filter((c) => c.type === "text").map((c) => c.text).join("");
|
|
10649
|
+
const toolCalls = msg.content.filter((c) => c.type === "toolCall").map((c) => ({
|
|
10650
|
+
id: c.id,
|
|
10651
|
+
type: "function",
|
|
10652
|
+
function: {
|
|
10653
|
+
name: c.name,
|
|
10654
|
+
arguments: JSON.stringify(c.arguments)
|
|
10655
|
+
}
|
|
10656
|
+
}));
|
|
10657
|
+
const openAiMsg = {
|
|
10658
|
+
role: "assistant",
|
|
10659
|
+
content: textParts || null,
|
|
10660
|
+
...toolCalls.length > 0 ? { tool_calls: toolCalls } : {}
|
|
10661
|
+
};
|
|
10662
|
+
result.push(openAiMsg);
|
|
10663
|
+
break;
|
|
10664
|
+
}
|
|
10665
|
+
case "toolResult":
|
|
10666
|
+
result.push({
|
|
10667
|
+
role: "tool",
|
|
10668
|
+
tool_call_id: msg.toolCallId,
|
|
10669
|
+
content: msg.content
|
|
10670
|
+
});
|
|
10671
|
+
break;
|
|
10672
|
+
}
|
|
10308
10673
|
}
|
|
10309
|
-
|
|
10674
|
+
return result;
|
|
10675
|
+
}
|
|
10676
|
+
function convertToolsToOpenAi(tools) {
|
|
10677
|
+
return tools.map((t) => ({
|
|
10678
|
+
type: "function",
|
|
10679
|
+
function: {
|
|
10680
|
+
name: t.name,
|
|
10681
|
+
description: t.description,
|
|
10682
|
+
parameters: t.parameters
|
|
10683
|
+
}
|
|
10684
|
+
}));
|
|
10685
|
+
}
|
|
10686
|
+
function buildOpenAiAgenticRequest(options, baseUrl, apiKey) {
|
|
10687
|
+
const messages = convertMessagesToOpenAi(options.messages, options.systemPrompt);
|
|
10688
|
+
const tools = convertToolsToOpenAi(options.tools);
|
|
10689
|
+
const body = {
|
|
10690
|
+
messages,
|
|
10691
|
+
tools: tools.length > 0 ? tools : void 0,
|
|
10692
|
+
model: options.model,
|
|
10693
|
+
max_completion_tokens: options.maxTokens,
|
|
10694
|
+
stream: options.stream ?? false
|
|
10695
|
+
};
|
|
10696
|
+
if (options.stream) {
|
|
10697
|
+
body.stream_options = { include_usage: true };
|
|
10698
|
+
}
|
|
10699
|
+
const headers = {
|
|
10700
|
+
"Content-Type": "application/json",
|
|
10701
|
+
Authorization: `Bearer ${apiKey}`
|
|
10702
|
+
};
|
|
10310
10703
|
return {
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
|
|
10704
|
+
url: baseUrl,
|
|
10705
|
+
method: "POST",
|
|
10706
|
+
headers,
|
|
10707
|
+
body,
|
|
10708
|
+
loggableHeaders: {
|
|
10709
|
+
...headers,
|
|
10710
|
+
Authorization: "Bearer [REDACTED]"
|
|
10711
|
+
},
|
|
10712
|
+
loggableBody: body
|
|
10314
10713
|
};
|
|
10315
10714
|
}
|
|
10316
|
-
|
|
10715
|
+
function parseOpenAiToolArguments(rawArguments, toolName, errorLabel) {
|
|
10716
|
+
if (!rawArguments.trim()) {
|
|
10717
|
+
return {};
|
|
10718
|
+
}
|
|
10719
|
+
let parsed;
|
|
10720
|
+
try {
|
|
10721
|
+
parsed = JSON.parse(rawArguments);
|
|
10722
|
+
} catch {
|
|
10723
|
+
const preview = rawArguments.length > 500 ? rawArguments.slice(0, 500) + "..." : rawArguments;
|
|
10724
|
+
throw new Error(`${errorLabel} API error: Invalid JSON arguments for tool "${toolName}": ${preview}`);
|
|
10725
|
+
}
|
|
10726
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
10727
|
+
throw new Error(`${errorLabel} API error: Tool "${toolName}" arguments must be a JSON object`);
|
|
10728
|
+
}
|
|
10729
|
+
return parsed;
|
|
10730
|
+
}
|
|
10731
|
+
async function parseOpenAiAgenticResponse(response, errorLabel) {
|
|
10317
10732
|
if (response.status !== 200) {
|
|
10318
10733
|
const errorBody = await response.text();
|
|
10319
10734
|
try {
|
|
10320
10735
|
const parsed = JSON.parse(errorBody);
|
|
10321
10736
|
const message = parsed?.error?.message || errorBody;
|
|
10322
|
-
throw new Error(
|
|
10737
|
+
throw new Error(`${errorLabel} API error: ${response.status} - ${message}`);
|
|
10323
10738
|
} catch (e) {
|
|
10324
|
-
if (e instanceof Error && e.message.startsWith(
|
|
10739
|
+
if (e instanceof Error && e.message.startsWith(`${errorLabel} API error:`))
|
|
10325
10740
|
throw e;
|
|
10326
|
-
throw new Error(
|
|
10741
|
+
throw new Error(`${errorLabel} API error: ${response.status} - ${errorBody}`);
|
|
10327
10742
|
}
|
|
10328
10743
|
}
|
|
10329
|
-
|
|
10330
|
-
|
|
10744
|
+
const responseBody = await response.json();
|
|
10745
|
+
const choice = responseBody.choices?.[0];
|
|
10746
|
+
if (!choice?.message) {
|
|
10747
|
+
throw new Error(`${errorLabel} API error: No message in response. Body: ${JSON.stringify(responseBody)}`);
|
|
10331
10748
|
}
|
|
10332
10749
|
const contentBlocks = [];
|
|
10333
|
-
|
|
10334
|
-
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
|
|
10339
|
-
chunk = JSON.parse(data);
|
|
10340
|
-
} catch {
|
|
10341
|
-
continue;
|
|
10342
|
-
}
|
|
10343
|
-
if (chunk.usageMetadata) {
|
|
10344
|
-
usage2 = (0, provider_config_1.normalizeGeminiUsage)(chunk.usageMetadata);
|
|
10345
|
-
}
|
|
10346
|
-
const candidate = chunk.candidates?.[0];
|
|
10347
|
-
if (!candidate?.content?.parts)
|
|
10348
|
-
continue;
|
|
10349
|
-
for (const part of candidate.content.parts) {
|
|
10350
|
-
if (part.text) {
|
|
10351
|
-
textContent2 += part.text;
|
|
10352
|
-
safeEmit(onEvent, { type: "text_delta", text: part.text });
|
|
10353
|
-
}
|
|
10354
|
-
if (part.functionCall) {
|
|
10355
|
-
hasToolCalls2 = true;
|
|
10356
|
-
contentBlocks.push({
|
|
10357
|
-
type: "toolCall",
|
|
10358
|
-
id: crypto.randomUUID(),
|
|
10359
|
-
name: part.functionCall.name,
|
|
10360
|
-
arguments: part.functionCall.args
|
|
10361
|
-
});
|
|
10362
|
-
}
|
|
10363
|
-
}
|
|
10750
|
+
const assistantText = (0, provider_config_1.extractOpenAiMessageText)(choice.message);
|
|
10751
|
+
if (assistantText) {
|
|
10752
|
+
contentBlocks.push({
|
|
10753
|
+
type: "text",
|
|
10754
|
+
text: assistantText
|
|
10755
|
+
});
|
|
10364
10756
|
}
|
|
10365
|
-
if (
|
|
10366
|
-
|
|
10757
|
+
if (choice.message.tool_calls) {
|
|
10758
|
+
for (const tc of choice.message.tool_calls) {
|
|
10759
|
+
contentBlocks.push({
|
|
10760
|
+
type: "toolCall",
|
|
10761
|
+
id: tc.id,
|
|
10762
|
+
name: tc.function.name,
|
|
10763
|
+
arguments: parseOpenAiToolArguments(tc.function.arguments, tc.function.name, errorLabel)
|
|
10764
|
+
});
|
|
10765
|
+
}
|
|
10367
10766
|
}
|
|
10368
|
-
const
|
|
10767
|
+
const usage = (0, provider_config_1.normalizeOpenAiUsage)(responseBody.usage);
|
|
10768
|
+
const stopReason = choice.finish_reason === "tool_calls" || choice.finish_reason === "stop" ? choice.finish_reason === "tool_calls" ? "tool_use" : "stop" : choice.message.tool_calls && choice.message.tool_calls.length > 0 ? "tool_use" : "stop";
|
|
10369
10769
|
return {
|
|
10370
|
-
message: {
|
|
10371
|
-
|
|
10372
|
-
|
|
10770
|
+
message: {
|
|
10771
|
+
role: "assistant",
|
|
10772
|
+
content: contentBlocks
|
|
10773
|
+
},
|
|
10774
|
+
usage,
|
|
10775
|
+
stopReason
|
|
10373
10776
|
};
|
|
10374
10777
|
}
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
|
|
10378
|
-
|
|
10379
|
-
|
|
10380
|
-
|
|
10381
|
-
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10398
|
-
|
|
10399
|
-
|
|
10400
|
-
|
|
10401
|
-
|
|
10402
|
-
|
|
10403
|
-
|
|
10404
|
-
|
|
10405
|
-
|
|
10406
|
-
|
|
10407
|
-
|
|
10408
|
-
|
|
10409
|
-
|
|
10410
|
-
|
|
10411
|
-
|
|
10412
|
-
|
|
10413
|
-
|
|
10414
|
-
|
|
10415
|
-
|
|
10416
|
-
const providerModelName = this.getProviderModelName(model);
|
|
10417
|
-
const codec = this.getAgenticProviderCodec(provider.errorLabel);
|
|
10418
|
-
const requestOptions = codec.buildRequest({
|
|
10419
|
-
messages,
|
|
10420
|
-
tools,
|
|
10421
|
-
model: providerModelName,
|
|
10422
|
-
maxTokens,
|
|
10423
|
-
systemPrompt,
|
|
10424
|
-
stream: !!onEvent
|
|
10425
|
-
});
|
|
10426
|
-
const parseResponse = onEvent ? (response) => codec.parseStreamingResponse(response, onEvent) : codec.parseResponse;
|
|
10427
|
-
return this.executeProviderCall({
|
|
10428
|
-
provider,
|
|
10429
|
-
model,
|
|
10430
|
-
maxTokens,
|
|
10431
|
-
apiOperation: "agentic",
|
|
10432
|
-
requestOptions,
|
|
10433
|
-
parseResponse,
|
|
10434
|
-
getResponsePreview: (parsedResponse) => parsedResponse.message.content.filter((content) => content.type === "text").map((content) => content.text).join(""),
|
|
10435
|
-
getUsage: (parsedResponse) => parsedResponse.usage
|
|
10436
|
-
});
|
|
10437
|
-
}
|
|
10438
|
-
getProviderConfig() {
|
|
10439
|
-
const provider = provider_config_1.providerConfigs[this.providerId];
|
|
10440
|
-
if (!provider) {
|
|
10441
|
-
throw new Error(`Unknown LLM provider: ${this.providerId}`);
|
|
10442
|
-
}
|
|
10443
|
-
return provider;
|
|
10444
|
-
}
|
|
10445
|
-
getProviderModelName(model) {
|
|
10446
|
-
const providerSpecificModelName = model_info_1.SUPPORTED_MODELS[model].find((pm) => pm.provider === this.providerId);
|
|
10447
|
-
if (!providerSpecificModelName) {
|
|
10448
|
-
throw new Error(`LLM Provider ${this.providerId} does not support model ${model}. If this is an error and the provider does support this model, please contact us to fix it`);
|
|
10449
|
-
}
|
|
10450
|
-
return providerSpecificModelName.providerModelName;
|
|
10451
|
-
}
|
|
10452
|
-
async executeProviderCall(params) {
|
|
10453
|
-
const method = params.requestOptions.method ?? "POST";
|
|
10454
|
-
const headers = params.requestOptions.headers ?? {};
|
|
10455
|
-
const body = this.toFetchableBody(params.requestOptions.body);
|
|
10456
|
-
const spanId = (0, logger_1.generateSpanId)();
|
|
10457
|
-
const startTime = Date.now();
|
|
10458
|
-
(0, logger_1.logLlmCallStart)(this.logger, spanId, params.provider.providerId, params.apiOperation, {
|
|
10459
|
-
url: params.requestOptions.loggableUrl ?? params.requestOptions.url,
|
|
10460
|
-
httpMethod: method,
|
|
10461
|
-
model: params.model,
|
|
10462
|
-
maxTokens: params.maxTokens
|
|
10463
|
-
});
|
|
10464
|
-
try {
|
|
10465
|
-
const response = await fetch(params.requestOptions.url, {
|
|
10466
|
-
method,
|
|
10467
|
-
headers,
|
|
10468
|
-
body
|
|
10469
|
-
});
|
|
10470
|
-
const parsedResponse = await params.parseResponse(response);
|
|
10471
|
-
const duration = Date.now() - startTime;
|
|
10472
|
-
(0, logger_1.logLlmCallComplete)(this.logger, spanId, params.provider.providerId, params.apiOperation, {
|
|
10473
|
-
status: response.status,
|
|
10474
|
-
responseText: params.getResponsePreview(parsedResponse),
|
|
10475
|
-
headers: Object.fromEntries(response.headers.entries()),
|
|
10476
|
-
usage: params.getUsage(parsedResponse)
|
|
10477
|
-
}, duration);
|
|
10478
|
-
return parsedResponse;
|
|
10479
|
-
} catch (error) {
|
|
10480
|
-
const duration = Date.now() - startTime;
|
|
10481
|
-
(0, logger_1.logLlmCallError)(this.logger, spanId, params.provider.providerId, params.apiOperation, error, duration);
|
|
10482
|
-
throw new Error(`${params.provider.errorLabel} API request failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
10778
|
+
function convertMessagesToGemini(messages) {
|
|
10779
|
+
const result = [];
|
|
10780
|
+
for (const msg of messages) {
|
|
10781
|
+
switch (msg.role) {
|
|
10782
|
+
case "user":
|
|
10783
|
+
result.push({
|
|
10784
|
+
role: "user",
|
|
10785
|
+
parts: [{ text: msg.content }]
|
|
10786
|
+
});
|
|
10787
|
+
break;
|
|
10788
|
+
case "assistant": {
|
|
10789
|
+
const parts = [];
|
|
10790
|
+
for (const block of msg.content) {
|
|
10791
|
+
if (block.type === "text") {
|
|
10792
|
+
parts.push({ text: block.text });
|
|
10793
|
+
} else if (block.type === "toolCall") {
|
|
10794
|
+
parts.push({
|
|
10795
|
+
functionCall: {
|
|
10796
|
+
name: block.name,
|
|
10797
|
+
args: block.arguments
|
|
10798
|
+
}
|
|
10799
|
+
});
|
|
10800
|
+
}
|
|
10801
|
+
}
|
|
10802
|
+
result.push({ role: "model", parts });
|
|
10803
|
+
break;
|
|
10804
|
+
}
|
|
10805
|
+
case "toolResult": {
|
|
10806
|
+
result.push({
|
|
10807
|
+
role: "user",
|
|
10808
|
+
parts: [
|
|
10809
|
+
{
|
|
10810
|
+
functionResponse: {
|
|
10811
|
+
name: msg.toolName,
|
|
10812
|
+
response: { content: msg.content }
|
|
10813
|
+
}
|
|
10814
|
+
}
|
|
10815
|
+
]
|
|
10816
|
+
});
|
|
10817
|
+
break;
|
|
10818
|
+
}
|
|
10483
10819
|
}
|
|
10484
10820
|
}
|
|
10485
|
-
|
|
10486
|
-
|
|
10487
|
-
|
|
10821
|
+
return result;
|
|
10822
|
+
}
|
|
10823
|
+
function convertToolsToGemini(tools) {
|
|
10824
|
+
if (tools.length === 0)
|
|
10825
|
+
return [];
|
|
10826
|
+
return [
|
|
10827
|
+
{
|
|
10828
|
+
functionDeclarations: tools.map((t) => ({
|
|
10829
|
+
name: t.name,
|
|
10830
|
+
description: t.description,
|
|
10831
|
+
parameters: t.parameters
|
|
10832
|
+
}))
|
|
10488
10833
|
}
|
|
10489
|
-
|
|
10490
|
-
|
|
10834
|
+
];
|
|
10835
|
+
}
|
|
10836
|
+
function buildGeminiAgenticRequest(options, apiKey) {
|
|
10837
|
+
const contents = convertMessagesToGemini(options.messages);
|
|
10838
|
+
const tools = convertToolsToGemini(options.tools);
|
|
10839
|
+
const body = {
|
|
10840
|
+
contents,
|
|
10841
|
+
generationConfig: {
|
|
10842
|
+
maxOutputTokens: options.maxTokens
|
|
10491
10843
|
}
|
|
10492
|
-
|
|
10844
|
+
};
|
|
10845
|
+
if (tools.length > 0) {
|
|
10846
|
+
body.tools = tools;
|
|
10493
10847
|
}
|
|
10494
|
-
|
|
10495
|
-
|
|
10496
|
-
|
|
10497
|
-
|
|
10498
|
-
buildRequest: (options) => (0, provider_formatters_1.buildOpenAiAgenticRequest)(options, "https://api.groq.com/openai/v1/chat/completions", this.apiKey),
|
|
10499
|
-
parseResponse: (response) => (0, provider_formatters_1.parseOpenAiAgenticResponse)(response, errorLabel),
|
|
10500
|
-
parseStreamingResponse: (response, onEvent) => (0, provider_formatters_1.streamOpenAiAgenticResponse)(response, errorLabel, onEvent)
|
|
10501
|
-
};
|
|
10502
|
-
case "cerebras":
|
|
10503
|
-
return {
|
|
10504
|
-
buildRequest: (options) => (0, provider_formatters_1.buildOpenAiAgenticRequest)(options, "https://api.cerebras.ai/v1/chat/completions", this.apiKey),
|
|
10505
|
-
parseResponse: (response) => (0, provider_formatters_1.parseOpenAiAgenticResponse)(response, errorLabel),
|
|
10506
|
-
parseStreamingResponse: (response, onEvent) => (0, provider_formatters_1.streamOpenAiAgenticResponse)(response, errorLabel, onEvent)
|
|
10507
|
-
};
|
|
10508
|
-
case "openrouter":
|
|
10509
|
-
return {
|
|
10510
|
-
buildRequest: (options) => (0, provider_formatters_1.buildOpenAiAgenticRequest)(options, "https://openrouter.ai/api/v1/chat/completions", this.apiKey),
|
|
10511
|
-
parseResponse: (response) => (0, provider_formatters_1.parseOpenAiAgenticResponse)(response, errorLabel),
|
|
10512
|
-
parseStreamingResponse: (response, onEvent) => (0, provider_formatters_1.streamOpenAiAgenticResponse)(response, errorLabel, onEvent)
|
|
10513
|
-
};
|
|
10514
|
-
case "gemini":
|
|
10515
|
-
return {
|
|
10516
|
-
buildRequest: (options) => (0, provider_formatters_1.buildGeminiAgenticRequest)(options, this.apiKey),
|
|
10517
|
-
parseResponse: provider_formatters_1.parseGeminiAgenticResponse,
|
|
10518
|
-
parseStreamingResponse: (response, onEvent) => (0, provider_formatters_1.streamGeminiAgenticResponse)(response, onEvent)
|
|
10519
|
-
};
|
|
10520
|
-
default:
|
|
10521
|
-
throw new Error(`Unsupported provider for agentic requests: ${this.providerId}`);
|
|
10522
|
-
}
|
|
10848
|
+
if (options.systemPrompt) {
|
|
10849
|
+
body.systemInstruction = {
|
|
10850
|
+
parts: [{ text: options.systemPrompt }]
|
|
10851
|
+
};
|
|
10523
10852
|
}
|
|
10524
|
-
|
|
10525
|
-
|
|
10526
|
-
|
|
10527
|
-
}
|
|
10528
|
-
|
|
10529
|
-
var castArrayPromptBuilder = {};
|
|
10530
|
-
|
|
10531
|
-
var promptTemplateUtils = {};
|
|
10532
|
-
|
|
10533
|
-
var hasRequiredPromptTemplateUtils;
|
|
10534
|
-
function requirePromptTemplateUtils() {
|
|
10535
|
-
if (hasRequiredPromptTemplateUtils) return promptTemplateUtils;
|
|
10536
|
-
hasRequiredPromptTemplateUtils = 1;
|
|
10537
|
-
(function(exports$1) {
|
|
10538
|
-
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
10539
|
-
exports$1.replaceTemplateVarName = exports$1.templateVarName = void 0;
|
|
10540
|
-
const templateVarName = (varName) => `<<{${varName}}>>`;
|
|
10541
|
-
exports$1.templateVarName = templateVarName;
|
|
10542
|
-
const replaceTemplateVarName = (str, varName, value) => str.replaceAll((0, exports$1.templateVarName)(varName), value);
|
|
10543
|
-
exports$1.replaceTemplateVarName = replaceTemplateVarName;
|
|
10544
|
-
})(promptTemplateUtils);
|
|
10545
|
-
return promptTemplateUtils;
|
|
10546
|
-
}
|
|
10547
|
-
|
|
10548
|
-
var hasRequiredCastArrayPromptBuilder;
|
|
10549
|
-
function requireCastArrayPromptBuilder() {
|
|
10550
|
-
if (hasRequiredCastArrayPromptBuilder) return castArrayPromptBuilder;
|
|
10551
|
-
hasRequiredCastArrayPromptBuilder = 1;
|
|
10552
|
-
Object.defineProperty(castArrayPromptBuilder, "__esModule", { value: true });
|
|
10553
|
-
const prompt_template_utils_1 = requirePromptTemplateUtils();
|
|
10554
|
-
const builder = () => {
|
|
10555
|
-
const BASE_SYSTEM_PROMPT_WHEN_OUTPUT_TYPE_NAME_PROVIDED = [
|
|
10556
|
-
`Your task is to transform the provided <input-data> into a JSON array, that represents a list of`,
|
|
10557
|
-
`${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}. The schema for this JSON array is defined below in <json-schema-spec> for you reference.`,
|
|
10558
|
-
`It uses the JSON Schema spec.`,
|
|
10559
|
-
`Respond with only the instance, not the schema. It should not be wrapped in any wrapper object -- return exactly what the JSON schema is expecting.`,
|
|
10560
|
-
`Your entire response should be just the value of the JSON array containing objects with '${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}'`,
|
|
10561
|
-
`and its primary key '${(0, prompt_template_utils_1.templateVarName)("PRIMARY_KEY")}', as valid JSON.`,
|
|
10562
|
-
`We will validate the result with the AJV Node library, using ajv.parse, against the JSON schema, and we expect it to validate correctly.`,
|
|
10563
|
-
`Note that the primary key of each element in the input-data is '${(0, prompt_template_utils_1.templateVarName)("PRIMARY_KEY")}'. In the output JSON array,`,
|
|
10564
|
-
`each object should have the same key with the same value of the original data, so we can map the input element against the output element.`
|
|
10565
|
-
].join(" ");
|
|
10566
|
-
const buildSystemPrompt = (primaryKey, outputName) => {
|
|
10567
|
-
let a = BASE_SYSTEM_PROMPT_WHEN_OUTPUT_TYPE_NAME_PROVIDED;
|
|
10568
|
-
a = (0, prompt_template_utils_1.replaceTemplateVarName)(a, "PRIMARY_KEY", primaryKey);
|
|
10569
|
-
a = (0, prompt_template_utils_1.replaceTemplateVarName)(a, "OUTPUT_TYPE_NAME", outputName);
|
|
10570
|
-
return a;
|
|
10571
|
-
};
|
|
10572
|
-
const buildFullPrompt = (req, uncachedInputDataRows) => {
|
|
10573
|
-
const prompt = req.input.prompt;
|
|
10574
|
-
const fullPrompt = [
|
|
10575
|
-
prompt || "Transform the provided data according to the schema.",
|
|
10576
|
-
// user prompt
|
|
10577
|
-
buildSystemPrompt(req.input.primaryKey, req.output.name),
|
|
10578
|
-
`<json-schema-spec> ${JSON.stringify(req.output.effectiveSchema)} </json-schema-spec>`,
|
|
10579
|
-
`<input-data>${JSON.stringify(uncachedInputDataRows)}</input-data>`
|
|
10580
|
-
].join("\n");
|
|
10581
|
-
return fullPrompt;
|
|
10582
|
-
};
|
|
10853
|
+
const action = options.stream ? "streamGenerateContent" : "generateContent";
|
|
10854
|
+
const altParam = options.stream ? "&alt=sse" : "";
|
|
10855
|
+
const url = `https://generativelanguage.googleapis.com/v1beta/models/${options.model}:${action}?key=${apiKey}${altParam}`;
|
|
10583
10856
|
return {
|
|
10584
|
-
|
|
10585
|
-
|
|
10586
|
-
|
|
10587
|
-
|
|
10588
|
-
|
|
10589
|
-
|
|
10590
|
-
|
|
10591
|
-
|
|
10592
|
-
|
|
10593
|
-
var castPromptBuilder = {};
|
|
10594
|
-
|
|
10595
|
-
var hasRequiredCastPromptBuilder;
|
|
10596
|
-
function requireCastPromptBuilder() {
|
|
10597
|
-
if (hasRequiredCastPromptBuilder) return castPromptBuilder;
|
|
10598
|
-
hasRequiredCastPromptBuilder = 1;
|
|
10599
|
-
Object.defineProperty(castPromptBuilder, "__esModule", { value: true });
|
|
10600
|
-
const prompt_template_utils_1 = requirePromptTemplateUtils();
|
|
10601
|
-
const builder = () => {
|
|
10602
|
-
const BASE_SYSTEM_PROMPT_WHEN_OUTPUT_TYPE_NAME_PROVIDED = [
|
|
10603
|
-
`Please respond with a single JSON object that represents '${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}'.`,
|
|
10604
|
-
`The schema for this object (which uses the JSON Schema spec), is defined below for your reference.`,
|
|
10605
|
-
`Your task is to create an instance of this object. Respond with only the instance, not the schema.`,
|
|
10606
|
-
`Your entire response should be just the value of '${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}', as valid JSON.`,
|
|
10607
|
-
`And it should not be wrapped in any wrapper object -- return exactly what the JSON schema is expecting.`,
|
|
10608
|
-
`We will validate the result with the AJV Node library, using ajv.parse, against the given schema, and we expect`,
|
|
10609
|
-
`it to validate correctly.`,
|
|
10610
|
-
`IMPORTANT: Output raw JSON only. No markdown code fences, no explanation, no commentary, no extra fields beyond the schema. Do not correct yourself -- produce the right answer on the first try.`
|
|
10611
|
-
].join(" ");
|
|
10612
|
-
const buildSystemPrompt = (reqParams) => {
|
|
10613
|
-
let a = BASE_SYSTEM_PROMPT_WHEN_OUTPUT_TYPE_NAME_PROVIDED;
|
|
10614
|
-
a = (0, prompt_template_utils_1.replaceTemplateVarName)(a, "OUTPUT_TYPE_NAME", reqParams.output.name);
|
|
10615
|
-
return a;
|
|
10616
|
-
};
|
|
10617
|
-
const buildFullPrompt = (reqParams) => {
|
|
10618
|
-
const { prompt, data } = reqParams.input;
|
|
10619
|
-
const { effectiveSchema } = reqParams.output;
|
|
10620
|
-
const fullPrompt = [
|
|
10621
|
-
prompt || "Transform the provided data according to the schema.",
|
|
10622
|
-
// user prompt
|
|
10623
|
-
buildSystemPrompt(reqParams),
|
|
10624
|
-
`<json-schema-spec> ${JSON.stringify(effectiveSchema)} </json-schema-spec>`,
|
|
10625
|
-
data ? `<input-data>${JSON.stringify(data)}</input-data>` : ""
|
|
10626
|
-
].join("\n");
|
|
10627
|
-
return fullPrompt;
|
|
10857
|
+
url,
|
|
10858
|
+
method: "POST",
|
|
10859
|
+
headers: {
|
|
10860
|
+
"Content-Type": "application/json"
|
|
10861
|
+
},
|
|
10862
|
+
body,
|
|
10863
|
+
loggableUrl: url.replace(/key=[^&]+/, "key=[REDACTED]"),
|
|
10864
|
+
loggableBody: body
|
|
10628
10865
|
};
|
|
10866
|
+
}
|
|
10867
|
+
async function parseGeminiAgenticResponse(response) {
|
|
10868
|
+
if (response.status !== 200) {
|
|
10869
|
+
const errorBody = await response.text();
|
|
10870
|
+
try {
|
|
10871
|
+
const parsed = JSON.parse(errorBody);
|
|
10872
|
+
const message = parsed?.error?.message || errorBody;
|
|
10873
|
+
throw new Error(`Gemini API error: ${response.status} - ${message}`);
|
|
10874
|
+
} catch (e) {
|
|
10875
|
+
if (e instanceof Error && e.message.startsWith("Gemini API error:"))
|
|
10876
|
+
throw e;
|
|
10877
|
+
throw new Error(`Gemini API error: ${response.status} - ${errorBody}`);
|
|
10878
|
+
}
|
|
10879
|
+
}
|
|
10880
|
+
const responseBody = await response.json();
|
|
10881
|
+
const candidate = responseBody.candidates?.[0];
|
|
10882
|
+
if (!candidate?.content?.parts) {
|
|
10883
|
+
throw new Error(`Gemini API error: No content in response. Body: ${JSON.stringify(responseBody)}`);
|
|
10884
|
+
}
|
|
10885
|
+
const contentBlocks = [];
|
|
10886
|
+
let hasToolCalls = false;
|
|
10887
|
+
for (const part of candidate.content.parts) {
|
|
10888
|
+
if (part.text) {
|
|
10889
|
+
contentBlocks.push({ type: "text", text: part.text });
|
|
10890
|
+
}
|
|
10891
|
+
if (part.functionCall) {
|
|
10892
|
+
hasToolCalls = true;
|
|
10893
|
+
contentBlocks.push({
|
|
10894
|
+
type: "toolCall",
|
|
10895
|
+
id: crypto.randomUUID(),
|
|
10896
|
+
name: part.functionCall.name,
|
|
10897
|
+
arguments: part.functionCall.args
|
|
10898
|
+
});
|
|
10899
|
+
}
|
|
10900
|
+
}
|
|
10901
|
+
const usage = (0, provider_config_1.normalizeGeminiUsage)(responseBody.usageMetadata);
|
|
10902
|
+
const stopReason = hasToolCalls ? "tool_use" : "stop";
|
|
10629
10903
|
return {
|
|
10630
|
-
|
|
10631
|
-
|
|
10904
|
+
message: {
|
|
10905
|
+
role: "assistant",
|
|
10906
|
+
content: contentBlocks
|
|
10907
|
+
},
|
|
10908
|
+
usage,
|
|
10909
|
+
stopReason
|
|
10632
10910
|
};
|
|
10633
|
-
}
|
|
10634
|
-
const castPromptBuilder$1 = builder();
|
|
10635
|
-
castPromptBuilder.default = castPromptBuilder$1;
|
|
10636
|
-
return castPromptBuilder;
|
|
10637
|
-
}
|
|
10638
|
-
|
|
10639
|
-
var nuaErrors = {};
|
|
10640
|
-
|
|
10641
|
-
var hasRequiredNuaErrors;
|
|
10642
|
-
function requireNuaErrors() {
|
|
10643
|
-
if (hasRequiredNuaErrors) return nuaErrors;
|
|
10644
|
-
hasRequiredNuaErrors = 1;
|
|
10645
|
-
Object.defineProperty(nuaErrors, "__esModule", { value: true });
|
|
10646
|
-
nuaErrors.isNuaError = nuaErrors.isNuaInternalError = nuaErrors.isNuaValidationError = void 0;
|
|
10647
|
-
const isNuaValidationError = (a) => {
|
|
10648
|
-
return typeof a == "object" && a != null && "kind" in a && a.kind == "validation-error";
|
|
10649
|
-
};
|
|
10650
|
-
nuaErrors.isNuaValidationError = isNuaValidationError;
|
|
10651
|
-
const isNuaInternalError = (a) => {
|
|
10652
|
-
return typeof a == "object" && a != null && "kind" in a && a.kind == "internal-error";
|
|
10653
|
-
};
|
|
10654
|
-
nuaErrors.isNuaInternalError = isNuaInternalError;
|
|
10655
|
-
const isNuaError = (a) => {
|
|
10656
|
-
return typeof a == "object" && a != null && "kind" in a && (a.kind == "internal-error" || a.kind == "validation-error");
|
|
10657
|
-
};
|
|
10658
|
-
nuaErrors.isNuaError = isNuaError;
|
|
10659
|
-
return nuaErrors;
|
|
10660
|
-
}
|
|
10661
|
-
|
|
10662
|
-
var agentLoop = {};
|
|
10663
|
-
|
|
10664
|
-
var hasRequiredAgentLoop;
|
|
10665
|
-
function requireAgentLoop() {
|
|
10666
|
-
if (hasRequiredAgentLoop) return agentLoop;
|
|
10667
|
-
hasRequiredAgentLoop = 1;
|
|
10668
|
-
Object.defineProperty(agentLoop, "__esModule", { value: true });
|
|
10669
|
-
agentLoop.runAgentLoop = runAgentLoop;
|
|
10670
|
-
const provider_config_1 = requireProviderConfig();
|
|
10911
|
+
}
|
|
10671
10912
|
function safeEmit(onEvent, event) {
|
|
10672
10913
|
if (!onEvent)
|
|
10673
10914
|
return;
|
|
@@ -10676,409 +10917,241 @@ function requireAgentLoop() {
|
|
|
10676
10917
|
} catch {
|
|
10677
10918
|
}
|
|
10678
10919
|
}
|
|
10679
|
-
async function
|
|
10680
|
-
|
|
10681
|
-
|
|
10682
|
-
const toolsByName = new Map(params.tools.map((tool) => [tool.name, tool]));
|
|
10683
|
-
let completionReason = "max_turns";
|
|
10684
|
-
const onEvent = params.onEvent;
|
|
10685
|
-
for (let turn = 0; turn < params.maxTurns; turn++) {
|
|
10686
|
-
safeEmit(onEvent, { type: "turn_start", turn });
|
|
10687
|
-
let response;
|
|
10920
|
+
async function streamOpenAiAgenticResponse(response, errorLabel, onEvent) {
|
|
10921
|
+
if (response.status !== 200) {
|
|
10922
|
+
const errorBody = await response.text();
|
|
10688
10923
|
try {
|
|
10689
|
-
|
|
10690
|
-
|
|
10691
|
-
|
|
10692
|
-
|
|
10693
|
-
|
|
10924
|
+
const parsed = JSON.parse(errorBody);
|
|
10925
|
+
const message = parsed?.error?.message || errorBody;
|
|
10926
|
+
throw new Error(`${errorLabel} API error: ${response.status} - ${message}`);
|
|
10927
|
+
} catch (e) {
|
|
10928
|
+
if (e instanceof Error && e.message.startsWith(`${errorLabel} API error:`))
|
|
10929
|
+
throw e;
|
|
10930
|
+
throw new Error(`${errorLabel} API error: ${response.status} - ${errorBody}`);
|
|
10694
10931
|
}
|
|
10695
|
-
|
|
10696
|
-
|
|
10697
|
-
|
|
10698
|
-
|
|
10699
|
-
|
|
10700
|
-
|
|
10701
|
-
|
|
10702
|
-
|
|
10703
|
-
|
|
10704
|
-
|
|
10705
|
-
|
|
10706
|
-
|
|
10932
|
+
}
|
|
10933
|
+
if (!response.body) {
|
|
10934
|
+
throw new Error(`${errorLabel} API error: Response body is null`);
|
|
10935
|
+
}
|
|
10936
|
+
let textContent = "";
|
|
10937
|
+
const toolCallAccumulators = /* @__PURE__ */ new Map();
|
|
10938
|
+
let finishReason = null;
|
|
10939
|
+
let usage = { ...provider_config_1.normalizedUsageZero };
|
|
10940
|
+
for await (const data of (0, sse_parser_1.parseSSEStream)(response.body)) {
|
|
10941
|
+
let chunk;
|
|
10942
|
+
try {
|
|
10943
|
+
chunk = JSON.parse(data);
|
|
10944
|
+
} catch {
|
|
10945
|
+
continue;
|
|
10707
10946
|
}
|
|
10708
|
-
|
|
10709
|
-
|
|
10710
|
-
|
|
10711
|
-
|
|
10712
|
-
|
|
10713
|
-
|
|
10714
|
-
|
|
10715
|
-
|
|
10716
|
-
|
|
10717
|
-
|
|
10718
|
-
|
|
10719
|
-
|
|
10720
|
-
|
|
10721
|
-
|
|
10722
|
-
|
|
10723
|
-
|
|
10724
|
-
|
|
10725
|
-
|
|
10726
|
-
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
|
|
10731
|
-
|
|
10732
|
-
|
|
10733
|
-
|
|
10734
|
-
|
|
10735
|
-
|
|
10736
|
-
|
|
10737
|
-
|
|
10738
|
-
messages.push({
|
|
10739
|
-
role: "toolResult",
|
|
10740
|
-
toolCallId: toolCall.id,
|
|
10741
|
-
toolName: toolCall.name,
|
|
10742
|
-
content: result.content,
|
|
10743
|
-
isError: result.isError ?? false
|
|
10744
|
-
});
|
|
10745
|
-
safeEmit(onEvent, {
|
|
10746
|
-
type: "tool_complete",
|
|
10747
|
-
toolCallId: toolCall.id,
|
|
10748
|
-
toolName: toolCall.name,
|
|
10749
|
-
result
|
|
10750
|
-
});
|
|
10751
|
-
} catch (error) {
|
|
10752
|
-
const errorContent = `Tool execution error: ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
10753
|
-
const result = { content: errorContent, isError: true };
|
|
10754
|
-
messages.push({
|
|
10755
|
-
role: "toolResult",
|
|
10756
|
-
toolCallId: toolCall.id,
|
|
10757
|
-
toolName: toolCall.name,
|
|
10758
|
-
content: errorContent,
|
|
10759
|
-
isError: true
|
|
10760
|
-
});
|
|
10761
|
-
safeEmit(onEvent, {
|
|
10762
|
-
type: "tool_complete",
|
|
10763
|
-
toolCallId: toolCall.id,
|
|
10764
|
-
toolName: toolCall.name,
|
|
10765
|
-
result
|
|
10766
|
-
});
|
|
10947
|
+
if (chunk.usage) {
|
|
10948
|
+
usage = (0, provider_config_1.normalizeOpenAiUsage)(chunk.usage);
|
|
10949
|
+
}
|
|
10950
|
+
const choice = chunk.choices?.[0];
|
|
10951
|
+
if (!choice)
|
|
10952
|
+
continue;
|
|
10953
|
+
if (choice.finish_reason) {
|
|
10954
|
+
finishReason = choice.finish_reason;
|
|
10955
|
+
}
|
|
10956
|
+
const delta = choice.delta;
|
|
10957
|
+
if (!delta)
|
|
10958
|
+
continue;
|
|
10959
|
+
if (delta.content) {
|
|
10960
|
+
textContent += delta.content;
|
|
10961
|
+
safeEmit(onEvent, { type: "text_delta", text: delta.content });
|
|
10962
|
+
}
|
|
10963
|
+
if (delta.tool_calls) {
|
|
10964
|
+
for (const tc of delta.tool_calls) {
|
|
10965
|
+
const existing = toolCallAccumulators.get(tc.index);
|
|
10966
|
+
if (existing) {
|
|
10967
|
+
if (tc.function?.arguments) {
|
|
10968
|
+
existing.arguments += tc.function.arguments;
|
|
10969
|
+
}
|
|
10970
|
+
} else {
|
|
10971
|
+
toolCallAccumulators.set(tc.index, {
|
|
10972
|
+
id: tc.id ?? "",
|
|
10973
|
+
name: tc.function?.name ?? "",
|
|
10974
|
+
arguments: tc.function?.arguments ?? ""
|
|
10975
|
+
});
|
|
10976
|
+
}
|
|
10767
10977
|
}
|
|
10768
10978
|
}
|
|
10769
10979
|
}
|
|
10770
|
-
|
|
10771
|
-
|
|
10772
|
-
|
|
10773
|
-
return {
|
|
10774
|
-
promptTokens: a.promptTokens + b.promptTokens,
|
|
10775
|
-
completionTokens: a.completionTokens + b.completionTokens,
|
|
10776
|
-
totalTokens: a.totalTokens + b.totalTokens
|
|
10777
|
-
};
|
|
10778
|
-
}
|
|
10779
|
-
function extractLastAssistantText(messages) {
|
|
10780
|
-
const lastAssistant = [...messages].reverse().find((m) => m.role === "assistant");
|
|
10781
|
-
if (lastAssistant?.role !== "assistant") {
|
|
10782
|
-
return void 0;
|
|
10980
|
+
const contentBlocks = [];
|
|
10981
|
+
if (textContent) {
|
|
10982
|
+
contentBlocks.push({ type: "text", text: textContent });
|
|
10783
10983
|
}
|
|
10784
|
-
const
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
|
|
10789
|
-
|
|
10790
|
-
|
|
10791
|
-
completionReason,
|
|
10792
|
-
messages,
|
|
10793
|
-
textResponse: extractLastAssistantText(messages),
|
|
10794
|
-
usage,
|
|
10795
|
-
error
|
|
10796
|
-
};
|
|
10797
|
-
}
|
|
10798
|
-
return agentLoop;
|
|
10799
|
-
}
|
|
10800
|
-
|
|
10801
|
-
var hasRequiredNuaLlmClient;
|
|
10802
|
-
function requireNuaLlmClient() {
|
|
10803
|
-
if (hasRequiredNuaLlmClient) return nuaLlmClient;
|
|
10804
|
-
hasRequiredNuaLlmClient = 1;
|
|
10805
|
-
var __importDefault = nuaLlmClient && nuaLlmClient.__importDefault || function(mod) {
|
|
10806
|
-
return mod && mod.__esModule ? mod : { "default": mod };
|
|
10807
|
-
};
|
|
10808
|
-
Object.defineProperty(nuaLlmClient, "__esModule", { value: true });
|
|
10809
|
-
nuaLlmClient.NuaLlmClient = void 0;
|
|
10810
|
-
const logger_1 = requireLogger();
|
|
10811
|
-
const validate_mappable_input_data_1 = requireValidateMappableInputData();
|
|
10812
|
-
const call_llm_service_1 = requireCallLlmService();
|
|
10813
|
-
const nua_json_schema_value_validation_1 = requireNuaJsonSchemaValueValidation();
|
|
10814
|
-
const http_llm_client_1 = requireHttpLlmClient();
|
|
10815
|
-
const provider_config_1 = requireProviderConfig();
|
|
10816
|
-
const model_info_1 = requireModelInfo();
|
|
10817
|
-
const cast_array_prompt_builder_1 = __importDefault(requireCastArrayPromptBuilder());
|
|
10818
|
-
const cast_prompt_builder_1 = __importDefault(requireCastPromptBuilder());
|
|
10819
|
-
const nua_errors_1 = requireNuaErrors();
|
|
10820
|
-
const agent_loop_1 = requireAgentLoop();
|
|
10821
|
-
class NuaLlmClient {
|
|
10822
|
-
constructor(config) {
|
|
10823
|
-
this.logger = config.logger || new logger_1.ConsoleLogger();
|
|
10824
|
-
this.clients = /* @__PURE__ */ new Map();
|
|
10825
|
-
Object.entries(config.providers).forEach(([providerId, providerConfig]) => {
|
|
10826
|
-
if (providerConfig?.apiKey) {
|
|
10827
|
-
this.clients.set(providerId, new http_llm_client_1.HttpLlmClient(providerId, providerConfig.apiKey, this.logger));
|
|
10828
|
-
}
|
|
10984
|
+
const sortedToolCalls = [...toolCallAccumulators.entries()].sort(([a], [b]) => a - b);
|
|
10985
|
+
for (const [, tc] of sortedToolCalls) {
|
|
10986
|
+
contentBlocks.push({
|
|
10987
|
+
type: "toolCall",
|
|
10988
|
+
id: tc.id,
|
|
10989
|
+
name: tc.name,
|
|
10990
|
+
arguments: parseOpenAiToolArguments(tc.arguments, tc.name, errorLabel)
|
|
10829
10991
|
});
|
|
10830
10992
|
}
|
|
10831
|
-
|
|
10832
|
-
|
|
10833
|
-
|
|
10834
|
-
|
|
10835
|
-
|
|
10836
|
-
|
|
10837
|
-
|
|
10838
|
-
|
|
10839
|
-
|
|
10993
|
+
const stopReason2 = finishReason === "tool_calls" || sortedToolCalls.length > 0 ? "tool_use" : "stop";
|
|
10994
|
+
return {
|
|
10995
|
+
message: { role: "assistant", content: contentBlocks },
|
|
10996
|
+
usage,
|
|
10997
|
+
stopReason: stopReason2
|
|
10998
|
+
};
|
|
10999
|
+
}
|
|
11000
|
+
async function streamGeminiAgenticResponse(response, onEvent) {
|
|
11001
|
+
if (response.status !== 200) {
|
|
11002
|
+
const errorBody = await response.text();
|
|
11003
|
+
try {
|
|
11004
|
+
const parsed = JSON.parse(errorBody);
|
|
11005
|
+
const message = parsed?.error?.message || errorBody;
|
|
11006
|
+
throw new Error(`Gemini API error: ${response.status} - ${message}`);
|
|
11007
|
+
} catch (e) {
|
|
11008
|
+
if (e instanceof Error && e.message.startsWith("Gemini API error:"))
|
|
11009
|
+
throw e;
|
|
11010
|
+
throw new Error(`Gemini API error: ${response.status} - ${errorBody}`);
|
|
10840
11011
|
}
|
|
10841
|
-
throw new Error(`No configured provider found for model ${model}. Please check your API keys.`);
|
|
10842
11012
|
}
|
|
10843
|
-
|
|
10844
|
-
|
|
10845
|
-
if ((0, nua_errors_1.isNuaValidationError)(result)) {
|
|
10846
|
-
throw new Error(result.message);
|
|
10847
|
-
}
|
|
10848
|
-
return result;
|
|
11013
|
+
if (!response.body) {
|
|
11014
|
+
throw new Error("Gemini API error: Response body is null");
|
|
10849
11015
|
}
|
|
10850
|
-
|
|
10851
|
-
|
|
10852
|
-
|
|
10853
|
-
|
|
10854
|
-
|
|
10855
|
-
|
|
10856
|
-
const validationFn = (0, nua_json_schema_value_validation_1.buildNuaJsonSchemaValueValidation)("library-req", params.output.effectiveSchema);
|
|
11016
|
+
const contentBlocks = [];
|
|
11017
|
+
let hasToolCalls2 = false;
|
|
11018
|
+
let textContent2 = "";
|
|
11019
|
+
let usage2 = { ...provider_config_1.normalizedUsageZero };
|
|
11020
|
+
for await (const data of (0, sse_parser_1.parseSSEStream)(response.body)) {
|
|
11021
|
+
let chunk;
|
|
10857
11022
|
try {
|
|
10858
|
-
|
|
10859
|
-
|
|
10860
|
-
|
|
10861
|
-
model,
|
|
10862
|
-
maxTokens,
|
|
10863
|
-
temperature,
|
|
10864
|
-
3,
|
|
10865
|
-
// default retries
|
|
10866
|
-
validationFn
|
|
10867
|
-
);
|
|
10868
|
-
return {
|
|
10869
|
-
success: true,
|
|
10870
|
-
data: result.data,
|
|
10871
|
-
usage: result.usage,
|
|
10872
|
-
prompt
|
|
10873
|
-
};
|
|
10874
|
-
} catch (e) {
|
|
10875
|
-
return {
|
|
10876
|
-
success: false,
|
|
10877
|
-
error: e instanceof Error ? e.message : String(e),
|
|
10878
|
-
prompt
|
|
10879
|
-
};
|
|
11023
|
+
chunk = JSON.parse(data);
|
|
11024
|
+
} catch {
|
|
11025
|
+
continue;
|
|
10880
11026
|
}
|
|
10881
|
-
|
|
10882
|
-
|
|
10883
|
-
const model = this.resolveModel(params.model);
|
|
10884
|
-
const client = this.getClientForModel(model);
|
|
10885
|
-
const maxTokens = params.maxTokens || 4096;
|
|
10886
|
-
const temperature = params.temperature ?? 0;
|
|
10887
|
-
const validData = (0, validate_mappable_input_data_1.validateMappableInputData)(params.data, params.input.primaryKey);
|
|
10888
|
-
if ((0, nua_errors_1.isNuaValidationError)(validData)) {
|
|
10889
|
-
return {
|
|
10890
|
-
success: false,
|
|
10891
|
-
error: validData.message
|
|
10892
|
-
};
|
|
11027
|
+
if (chunk.usageMetadata) {
|
|
11028
|
+
usage2 = (0, provider_config_1.normalizeGeminiUsage)(chunk.usageMetadata);
|
|
10893
11029
|
}
|
|
10894
|
-
const
|
|
10895
|
-
|
|
10896
|
-
|
|
10897
|
-
|
|
10898
|
-
|
|
10899
|
-
|
|
10900
|
-
|
|
10901
|
-
|
|
10902
|
-
|
|
10903
|
-
|
|
10904
|
-
|
|
10905
|
-
|
|
10906
|
-
|
|
10907
|
-
|
|
10908
|
-
|
|
10909
|
-
|
|
11030
|
+
const candidate = chunk.candidates?.[0];
|
|
11031
|
+
if (!candidate?.content?.parts)
|
|
11032
|
+
continue;
|
|
11033
|
+
for (const part of candidate.content.parts) {
|
|
11034
|
+
if (part.text) {
|
|
11035
|
+
textContent2 += part.text;
|
|
11036
|
+
safeEmit(onEvent, { type: "text_delta", text: part.text });
|
|
11037
|
+
}
|
|
11038
|
+
if (part.functionCall) {
|
|
11039
|
+
hasToolCalls2 = true;
|
|
11040
|
+
contentBlocks.push({
|
|
11041
|
+
type: "toolCall",
|
|
11042
|
+
id: crypto.randomUUID(),
|
|
11043
|
+
name: part.functionCall.name,
|
|
11044
|
+
arguments: part.functionCall.args
|
|
11045
|
+
});
|
|
11046
|
+
}
|
|
10910
11047
|
}
|
|
10911
11048
|
}
|
|
10912
|
-
|
|
10913
|
-
|
|
10914
|
-
const model = this.resolveModel(params.model);
|
|
10915
|
-
const client = this.getClientForModel(model);
|
|
10916
|
-
const maxTokens = params.maxTokens ?? 4096;
|
|
10917
|
-
const maxTurns = params.maxTurns ?? 10;
|
|
10918
|
-
return (0, agent_loop_1.runAgentLoop)({
|
|
10919
|
-
messages: params.messages,
|
|
10920
|
-
tools: params.tools,
|
|
10921
|
-
systemPrompt: params.systemPrompt,
|
|
10922
|
-
maxTurns,
|
|
10923
|
-
onEvent: params.onEvent,
|
|
10924
|
-
sendRequest: (messages, tools, systemPrompt) => client.sendAgenticRequest(messages, tools, model, maxTokens, systemPrompt, params.onEvent)
|
|
10925
|
-
});
|
|
10926
|
-
} catch (e) {
|
|
10927
|
-
return {
|
|
10928
|
-
success: false,
|
|
10929
|
-
completionReason: "error",
|
|
10930
|
-
messages: params.messages,
|
|
10931
|
-
usage: provider_config_1.normalizedUsageZero,
|
|
10932
|
-
error: e instanceof Error ? e.message : String(e)
|
|
10933
|
-
};
|
|
10934
|
-
}
|
|
11049
|
+
if (textContent2) {
|
|
11050
|
+
contentBlocks.unshift({ type: "text", text: textContent2 });
|
|
10935
11051
|
}
|
|
11052
|
+
const stopReason3 = hasToolCalls2 ? "tool_use" : "stop";
|
|
11053
|
+
return {
|
|
11054
|
+
message: { role: "assistant", content: contentBlocks },
|
|
11055
|
+
usage: usage2,
|
|
11056
|
+
stopReason: stopReason3
|
|
11057
|
+
};
|
|
10936
11058
|
}
|
|
10937
|
-
|
|
10938
|
-
return nuaLlmClient;
|
|
10939
|
-
}
|
|
10940
|
-
|
|
10941
|
-
var types = {};
|
|
10942
|
-
|
|
10943
|
-
var hasRequiredTypes;
|
|
10944
|
-
function requireTypes() {
|
|
10945
|
-
if (hasRequiredTypes) return types;
|
|
10946
|
-
hasRequiredTypes = 1;
|
|
10947
|
-
Object.defineProperty(types, "__esModule", { value: true });
|
|
10948
|
-
return types;
|
|
11059
|
+
return providerFormatters;
|
|
10949
11060
|
}
|
|
10950
11061
|
|
|
10951
|
-
var
|
|
10952
|
-
|
|
10953
|
-
|
|
10954
|
-
|
|
10955
|
-
|
|
10956
|
-
|
|
10957
|
-
|
|
10958
|
-
|
|
10959
|
-
|
|
10960
|
-
|
|
10961
|
-
|
|
10962
|
-
|
|
10963
|
-
|
|
10964
|
-
|
|
10965
|
-
|
|
10966
|
-
|
|
11062
|
+
var hasRequiredAgentTurn;
|
|
11063
|
+
function requireAgentTurn() {
|
|
11064
|
+
if (hasRequiredAgentTurn) return agentTurn;
|
|
11065
|
+
hasRequiredAgentTurn = 1;
|
|
11066
|
+
Object.defineProperty(agentTurn, "__esModule", { value: true });
|
|
11067
|
+
agentTurn.sendAgentTurn = sendAgentTurn;
|
|
11068
|
+
const provider_call_1 = requireProviderCall();
|
|
11069
|
+
const provider_config_1 = requireProviderConfig();
|
|
11070
|
+
const provider_formatters_1 = requireProviderFormatters();
|
|
11071
|
+
async function sendAgentTurn(turn, logger) {
|
|
11072
|
+
const codec = agentCodec(turn.target);
|
|
11073
|
+
const onEvent = turn.onEvent;
|
|
11074
|
+
const call = await (0, provider_call_1.callProvider)({
|
|
11075
|
+
target: turn.target,
|
|
11076
|
+
apiOperation: "agentic",
|
|
11077
|
+
maxTokens: turn.maxTokens,
|
|
11078
|
+
request: codec.buildRequest({
|
|
11079
|
+
messages: turn.messages,
|
|
11080
|
+
tools: turn.tools,
|
|
11081
|
+
model: turn.target.model,
|
|
11082
|
+
maxTokens: turn.maxTokens,
|
|
11083
|
+
systemPrompt: turn.systemPrompt,
|
|
11084
|
+
stream: onEvent !== void 0
|
|
11085
|
+
}),
|
|
11086
|
+
parseResponse: onEvent ? (response) => codec.parseStreamingResponse(response, onEvent) : codec.parseResponse,
|
|
11087
|
+
responseLength: (reply) => reply.message.content.reduce((total, content) => total + (content.type === "text" ? content.text.length : 0), 0),
|
|
11088
|
+
usage: (reply) => reply.usage
|
|
11089
|
+
}, logger);
|
|
11090
|
+
if (call.kind === "failed") {
|
|
11091
|
+
throw new Error(call.message);
|
|
10967
11092
|
}
|
|
10968
|
-
return
|
|
11093
|
+
return call.reply;
|
|
10969
11094
|
}
|
|
10970
|
-
|
|
10971
|
-
|
|
10972
|
-
|
|
10973
|
-
|
|
10974
|
-
|
|
10975
|
-
|
|
10976
|
-
|
|
10977
|
-
|
|
10978
|
-
|
|
10979
|
-
|
|
10980
|
-
|
|
10981
|
-
|
|
10982
|
-
|
|
10983
|
-
|
|
10984
|
-
|
|
10985
|
-
message: "Schema must be a valid object"
|
|
10986
|
-
};
|
|
10987
|
-
}
|
|
10988
|
-
const ajvInstance = ajv_instances_1.ajvInstances.getInstanceForSchema(schema);
|
|
10989
|
-
const isValidSchema = ajvInstance.validateSchema(schema);
|
|
10990
|
-
let errors = "";
|
|
10991
|
-
if (ajvInstance.errors) {
|
|
10992
|
-
errors = ajvInstance.errors.map((e) => JSON.stringify(e, null, 2)).join("; ");
|
|
10993
|
-
} else if (isValidSchema) {
|
|
10994
|
-
try {
|
|
10995
|
-
ajvInstance.compile(schema);
|
|
10996
|
-
return true;
|
|
10997
|
-
} catch (e) {
|
|
10998
|
-
errors = (0, error_utils_1.getErrorMessageFromException)(e);
|
|
10999
|
-
}
|
|
11000
|
-
} else {
|
|
11001
|
-
errors = "unexpected-situation-no-errors-found-for-invalid-schema";
|
|
11095
|
+
function agentCodec({ provider, apiKey }) {
|
|
11096
|
+
const errorLabel = provider_config_1.providerConfigs[provider].errorLabel;
|
|
11097
|
+
switch (provider) {
|
|
11098
|
+
case "groq":
|
|
11099
|
+
return openAiStyleCodec("https://api.groq.com/openai/v1/chat/completions", apiKey, errorLabel);
|
|
11100
|
+
case "cerebras":
|
|
11101
|
+
return openAiStyleCodec("https://api.cerebras.ai/v1/chat/completions", apiKey, errorLabel);
|
|
11102
|
+
case "openrouter":
|
|
11103
|
+
return openAiStyleCodec("https://openrouter.ai/api/v1/chat/completions", apiKey, errorLabel);
|
|
11104
|
+
case "gemini":
|
|
11105
|
+
return {
|
|
11106
|
+
buildRequest: (options) => (0, provider_formatters_1.buildGeminiAgenticRequest)(options, apiKey),
|
|
11107
|
+
parseResponse: provider_formatters_1.parseGeminiAgenticResponse,
|
|
11108
|
+
parseStreamingResponse: provider_formatters_1.streamGeminiAgenticResponse
|
|
11109
|
+
};
|
|
11002
11110
|
}
|
|
11111
|
+
}
|
|
11112
|
+
function openAiStyleCodec(url, apiKey, errorLabel) {
|
|
11003
11113
|
return {
|
|
11004
|
-
|
|
11005
|
-
|
|
11006
|
-
|
|
11007
|
-
};
|
|
11008
|
-
validateJsonSchema.validateJsonSchema = validateJsonSchema$1;
|
|
11009
|
-
return validateJsonSchema;
|
|
11010
|
-
}
|
|
11011
|
-
|
|
11012
|
-
var stableStringify = {};
|
|
11013
|
-
|
|
11014
|
-
var hasRequiredStableStringify;
|
|
11015
|
-
function requireStableStringify() {
|
|
11016
|
-
if (hasRequiredStableStringify) return stableStringify;
|
|
11017
|
-
hasRequiredStableStringify = 1;
|
|
11018
|
-
Object.defineProperty(stableStringify, "__esModule", { value: true });
|
|
11019
|
-
stableStringify.stableStringify = stableStringify$1;
|
|
11020
|
-
function stableStringify$1(value) {
|
|
11021
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
11022
|
-
const sorter = (_key, currentValue) => {
|
|
11023
|
-
if (currentValue && typeof currentValue === "object" && !Array.isArray(currentValue)) {
|
|
11024
|
-
if (seen.has(currentValue)) {
|
|
11025
|
-
return currentValue;
|
|
11026
|
-
}
|
|
11027
|
-
seen.add(currentValue);
|
|
11028
|
-
return Object.keys(currentValue).sort().reduce((acc, key) => {
|
|
11029
|
-
acc[key] = currentValue[key];
|
|
11030
|
-
return acc;
|
|
11031
|
-
}, {});
|
|
11032
|
-
}
|
|
11033
|
-
return currentValue;
|
|
11114
|
+
buildRequest: (options) => (0, provider_formatters_1.buildOpenAiAgenticRequest)(options, url, apiKey),
|
|
11115
|
+
parseResponse: (response) => (0, provider_formatters_1.parseOpenAiAgenticResponse)(response, errorLabel),
|
|
11116
|
+
parseStreamingResponse: (response, onEvent) => (0, provider_formatters_1.streamOpenAiAgenticResponse)(response, errorLabel, onEvent)
|
|
11034
11117
|
};
|
|
11035
|
-
return JSON.stringify(value, sorter) ?? "";
|
|
11036
11118
|
}
|
|
11037
|
-
return
|
|
11119
|
+
return agentTurn;
|
|
11038
11120
|
}
|
|
11039
11121
|
|
|
11040
|
-
var
|
|
11041
|
-
|
|
11042
|
-
|
|
11043
|
-
|
|
11044
|
-
|
|
11045
|
-
|
|
11046
|
-
|
|
11047
|
-
|
|
11048
|
-
|
|
11049
|
-
|
|
11050
|
-
|
|
11051
|
-
|
|
11052
|
-
const
|
|
11053
|
-
|
|
11054
|
-
|
|
11055
|
-
|
|
11056
|
-
|
|
11057
|
-
|
|
11058
|
-
|
|
11059
|
-
|
|
11060
|
-
|
|
11061
|
-
[outputName]: schema
|
|
11062
|
-
}
|
|
11063
|
-
}
|
|
11064
|
-
};
|
|
11065
|
-
if (schemaVersion) {
|
|
11066
|
-
wrappedSchema.$schema = schemaVersion;
|
|
11067
|
-
}
|
|
11068
|
-
return wrappedSchema;
|
|
11069
|
-
}
|
|
11070
|
-
function unwrapArraySchema(wrappedSchema, outputName) {
|
|
11071
|
-
const items = wrappedSchema.items;
|
|
11072
|
-
if (!items || typeof items !== "object") {
|
|
11073
|
-
return null;
|
|
11074
|
-
}
|
|
11075
|
-
const properties = items.properties;
|
|
11076
|
-
if (!properties || typeof properties !== "object") {
|
|
11077
|
-
return null;
|
|
11122
|
+
var hasRequiredRunAgent;
|
|
11123
|
+
function requireRunAgent() {
|
|
11124
|
+
if (hasRequiredRunAgent) return runAgent;
|
|
11125
|
+
hasRequiredRunAgent = 1;
|
|
11126
|
+
Object.defineProperty(runAgent, "__esModule", { value: true });
|
|
11127
|
+
runAgent.runAgent = runAgent$1;
|
|
11128
|
+
const provider_config_1 = requireProviderConfig();
|
|
11129
|
+
const agent_loop_1 = requireAgentLoop();
|
|
11130
|
+
const agent_turn_1 = requireAgentTurn();
|
|
11131
|
+
const DEFAULT_MAX_TOKENS = 4096;
|
|
11132
|
+
const DEFAULT_MAX_TURNS = 10;
|
|
11133
|
+
async function runAgent$1(providers, params) {
|
|
11134
|
+
const resolved = providers.resolve(params.model);
|
|
11135
|
+
if (resolved.kind === "unroutable") {
|
|
11136
|
+
return {
|
|
11137
|
+
success: false,
|
|
11138
|
+
completionReason: "error",
|
|
11139
|
+
messages: params.messages,
|
|
11140
|
+
usage: provider_config_1.normalizedUsageZero,
|
|
11141
|
+
error: resolved.message
|
|
11142
|
+
};
|
|
11078
11143
|
}
|
|
11079
|
-
|
|
11144
|
+
const maxTokens = params.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
11145
|
+
return (0, agent_loop_1.runAgentLoop)({
|
|
11146
|
+
messages: params.messages,
|
|
11147
|
+
tools: params.tools,
|
|
11148
|
+
systemPrompt: params.systemPrompt,
|
|
11149
|
+
maxTurns: params.maxTurns ?? DEFAULT_MAX_TURNS,
|
|
11150
|
+
onEvent: params.onEvent,
|
|
11151
|
+
sendRequest: (messages, tools, systemPrompt) => (0, agent_turn_1.sendAgentTurn)({ target: resolved.target, maxTokens, messages, tools, systemPrompt, onEvent: params.onEvent }, providers.logger)
|
|
11152
|
+
});
|
|
11080
11153
|
}
|
|
11081
|
-
return
|
|
11154
|
+
return runAgent;
|
|
11082
11155
|
}
|
|
11083
11156
|
|
|
11084
11157
|
var hasRequiredDist;
|
|
@@ -11102,30 +11175,26 @@ function requireDist() {
|
|
|
11102
11175
|
var __exportStar = dist && dist.__exportStar || function(m, exports2) {
|
|
11103
11176
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p)) __createBinding(exports2, m, p);
|
|
11104
11177
|
};
|
|
11105
|
-
var __importDefault = dist && dist.__importDefault || function(mod) {
|
|
11106
|
-
return mod && mod.__esModule ? mod : { "default": mod };
|
|
11107
|
-
};
|
|
11108
11178
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
11109
|
-
exports$1.runAgentLoop = exports$1.stableStringify = exports$1.validateJsonSchema = exports$1.
|
|
11179
|
+
exports$1.runAgentLoop = exports$1.runAgent = exports$1.parseListSchema = exports$1.listSchema = exports$1.stableStringify = exports$1.validateJsonSchema = exports$1.providerEngines = exports$1.providerConfigs = exports$1.normalizedUsageZero = exports$1.LLM_PROVIDER_IDS = void 0;
|
|
11110
11180
|
__exportStar(requireNuaLlmClient(), exports$1);
|
|
11111
|
-
__exportStar(requireLogger(), exports$1);
|
|
11181
|
+
__exportStar(logger.requireLogger(), exports$1);
|
|
11112
11182
|
__exportStar(requireTypes(), exports$1);
|
|
11113
11183
|
__exportStar(requireNuaErrors(), exports$1);
|
|
11114
|
-
var cast_prompt_builder_1 = requireCastPromptBuilder();
|
|
11115
|
-
Object.defineProperty(exports$1, "castPromptBuilder", { enumerable: true, get: function() {
|
|
11116
|
-
return __importDefault(cast_prompt_builder_1).default;
|
|
11117
|
-
} });
|
|
11118
|
-
var cast_array_prompt_builder_1 = requireCastArrayPromptBuilder();
|
|
11119
|
-
Object.defineProperty(exports$1, "castArrayPromptBuilder", { enumerable: true, get: function() {
|
|
11120
|
-
return __importDefault(cast_array_prompt_builder_1).default;
|
|
11121
|
-
} });
|
|
11122
11184
|
var provider_config_1 = requireProviderConfig();
|
|
11185
|
+
Object.defineProperty(exports$1, "LLM_PROVIDER_IDS", { enumerable: true, get: function() {
|
|
11186
|
+
return provider_config_1.LLM_PROVIDER_IDS;
|
|
11187
|
+
} });
|
|
11123
11188
|
Object.defineProperty(exports$1, "normalizedUsageZero", { enumerable: true, get: function() {
|
|
11124
11189
|
return provider_config_1.normalizedUsageZero;
|
|
11125
11190
|
} });
|
|
11126
11191
|
Object.defineProperty(exports$1, "providerConfigs", { enumerable: true, get: function() {
|
|
11127
11192
|
return provider_config_1.providerConfigs;
|
|
11128
11193
|
} });
|
|
11194
|
+
var provider_engines_1 = requireProviderEngines();
|
|
11195
|
+
Object.defineProperty(exports$1, "providerEngines", { enumerable: true, get: function() {
|
|
11196
|
+
return provider_engines_1.providerEngines;
|
|
11197
|
+
} });
|
|
11129
11198
|
var validate_json_schema_1 = requireValidateJsonSchema();
|
|
11130
11199
|
Object.defineProperty(exports$1, "validateJsonSchema", { enumerable: true, get: function() {
|
|
11131
11200
|
return validate_json_schema_1.validateJsonSchema;
|
|
@@ -11136,6 +11205,17 @@ function requireDist() {
|
|
|
11136
11205
|
} });
|
|
11137
11206
|
__exportStar(requireModelInfo(), exports$1);
|
|
11138
11207
|
__exportStar(requireSchemaUtils(), exports$1);
|
|
11208
|
+
var list_schema_1 = requireListSchema();
|
|
11209
|
+
Object.defineProperty(exports$1, "listSchema", { enumerable: true, get: function() {
|
|
11210
|
+
return list_schema_1.listSchema;
|
|
11211
|
+
} });
|
|
11212
|
+
Object.defineProperty(exports$1, "parseListSchema", { enumerable: true, get: function() {
|
|
11213
|
+
return list_schema_1.parseListSchema;
|
|
11214
|
+
} });
|
|
11215
|
+
var run_agent_1 = requireRunAgent();
|
|
11216
|
+
Object.defineProperty(exports$1, "runAgent", { enumerable: true, get: function() {
|
|
11217
|
+
return run_agent_1.runAgent;
|
|
11218
|
+
} });
|
|
11139
11219
|
var agent_loop_1 = requireAgentLoop();
|
|
11140
11220
|
Object.defineProperty(exports$1, "runAgentLoop", { enumerable: true, get: function() {
|
|
11141
11221
|
return agent_loop_1.runAgentLoop;
|
|
@@ -11146,77 +11226,58 @@ function requireDist() {
|
|
|
11146
11226
|
|
|
11147
11227
|
var distExports = requireDist();
|
|
11148
11228
|
|
|
11149
|
-
const normalizedUsageZero = {
|
|
11150
|
-
promptTokens: 0,
|
|
11151
|
-
completionTokens: 0,
|
|
11152
|
-
totalTokens: 0
|
|
11153
|
-
};
|
|
11154
11229
|
class DirectBackend {
|
|
11155
11230
|
constructor(config) {
|
|
11156
|
-
|
|
11157
|
-
throw new Error("model is required for direct mode");
|
|
11158
|
-
}
|
|
11159
|
-
this.model = config.model;
|
|
11160
|
-
this.client = new distExports.NuaLlmClient({ providers: config.providers });
|
|
11231
|
+
this.client = new distExports.NuaLlmClient(enginesFor(config));
|
|
11161
11232
|
}
|
|
11162
11233
|
async castValue(params) {
|
|
11163
|
-
const model = params.model ?? this.model;
|
|
11164
11234
|
const startTime = Date.now();
|
|
11165
11235
|
const result = await this.client.castValue({
|
|
11166
|
-
model,
|
|
11236
|
+
model: params.model,
|
|
11167
11237
|
input: { prompt: params.prompt, data: params.data },
|
|
11168
|
-
output: { name: params.outputName,
|
|
11238
|
+
output: { name: params.outputName, schema: params.outputSchema }
|
|
11169
11239
|
});
|
|
11170
|
-
|
|
11171
|
-
if (!result.success) {
|
|
11172
|
-
return {
|
|
11173
|
-
success: false,
|
|
11174
|
-
error: result.error || "Unknown error",
|
|
11175
|
-
source: "direct",
|
|
11176
|
-
latencyMs
|
|
11177
|
-
};
|
|
11178
|
-
}
|
|
11179
|
-
return {
|
|
11180
|
-
success: true,
|
|
11181
|
-
data: result.data,
|
|
11182
|
-
usage: result.usage || normalizedUsageZero,
|
|
11183
|
-
model,
|
|
11184
|
-
latencyMs,
|
|
11185
|
-
source: "direct",
|
|
11186
|
-
meta: {}
|
|
11187
|
-
};
|
|
11240
|
+
return toDirectResult(result, Date.now() - startTime);
|
|
11188
11241
|
}
|
|
11189
11242
|
async castArray(params) {
|
|
11190
|
-
const model = params.model ?? this.model;
|
|
11191
11243
|
const startTime = Date.now();
|
|
11192
|
-
const wrappedSchema = distExports.wrapArraySchema(params.outputSchema, {
|
|
11193
|
-
primaryKey: params.primaryKey,
|
|
11194
|
-
outputName: params.outputName
|
|
11195
|
-
});
|
|
11196
11244
|
const result = await this.client.castArray({
|
|
11197
|
-
model,
|
|
11198
|
-
data: params.data,
|
|
11199
|
-
|
|
11200
|
-
|
|
11245
|
+
model: params.model,
|
|
11246
|
+
input: { prompt: params.prompt, data: params.data },
|
|
11247
|
+
output: distExports.listSchema(params.outputSchema, {
|
|
11248
|
+
primaryKey: params.primaryKey,
|
|
11249
|
+
outputName: params.outputName
|
|
11250
|
+
})
|
|
11201
11251
|
});
|
|
11202
|
-
|
|
11203
|
-
|
|
11204
|
-
|
|
11205
|
-
|
|
11206
|
-
|
|
11207
|
-
|
|
11208
|
-
|
|
11209
|
-
|
|
11210
|
-
|
|
11211
|
-
|
|
11212
|
-
|
|
11213
|
-
|
|
11214
|
-
|
|
11215
|
-
|
|
11216
|
-
|
|
11217
|
-
|
|
11218
|
-
|
|
11219
|
-
|
|
11252
|
+
return toDirectResult(result, Date.now() - startTime);
|
|
11253
|
+
}
|
|
11254
|
+
}
|
|
11255
|
+
function enginesFor(config) {
|
|
11256
|
+
if (config.localAgent) {
|
|
11257
|
+
return config.localAgent;
|
|
11258
|
+
}
|
|
11259
|
+
return distExports.providerEngines({ providers: config.providers, model: config.model });
|
|
11260
|
+
}
|
|
11261
|
+
function toDirectResult(result, latencyMs) {
|
|
11262
|
+
if (!result.success) {
|
|
11263
|
+
return { success: false, error: result.error, source: "direct", latencyMs };
|
|
11264
|
+
}
|
|
11265
|
+
return {
|
|
11266
|
+
success: true,
|
|
11267
|
+
data: result.data,
|
|
11268
|
+
usage: result.usage,
|
|
11269
|
+
model: describeModel(result.origin),
|
|
11270
|
+
latencyMs,
|
|
11271
|
+
source: "direct",
|
|
11272
|
+
meta: { ...result.origin, schemaEnforcement: result.schemaEnforcement }
|
|
11273
|
+
};
|
|
11274
|
+
}
|
|
11275
|
+
function describeModel(origin) {
|
|
11276
|
+
switch (origin.engine) {
|
|
11277
|
+
case "http":
|
|
11278
|
+
return `${origin.provider}:${origin.model}`;
|
|
11279
|
+
case "local-agent":
|
|
11280
|
+
return `${origin.agent}:${origin.model ?? "default"}`;
|
|
11220
11281
|
}
|
|
11221
11282
|
}
|
|
11222
11283
|
|
|
@@ -11467,6 +11528,11 @@ class Nua {
|
|
|
11467
11528
|
static gateway(config) {
|
|
11468
11529
|
return new Nua(new GatewayBackend(config));
|
|
11469
11530
|
}
|
|
11531
|
+
/**
|
|
11532
|
+
* Runs casts in this process: on LLM providers' APIs with your API keys (`providers`), or
|
|
11533
|
+
* on a coding-agent CLI installed on this machine (`localAgent`, set up with `localAgent()` or
|
|
11534
|
+
* `findLocalAgent()` from "nuabase/local-agent").
|
|
11535
|
+
*/
|
|
11470
11536
|
static direct(config) {
|
|
11471
11537
|
return new Nua(new DirectBackend(config));
|
|
11472
11538
|
}
|