nuabase 2.3.4 → 2.3.7
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 +53 -2
- package/dist/cjs/chunks/logger-Co5uZG0A.cjs +90 -0
- package/dist/cjs/index.cjs +1516 -1380
- package/dist/cjs/local-agent.cjs +1043 -0
- package/dist/esm/chunks/logger-DnkHzkX_.mjs +88 -0
- package/dist/esm/index.mjs +1516 -1380
- package/dist/esm/local-agent.mjs +1041 -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 +19 -7
- package/dist/types/backend/types.d.ts +7 -3
- 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/pi.d.ts +2 -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 +6 -1
- package/package.json +19 -2
package/dist/cjs/index.cjs
CHANGED
|
@@ -1,96 +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
|
-
class ConsoleLogger {
|
|
20
|
-
debug(message, context) {
|
|
21
|
-
console.debug(`[DEBUG] ${message}`, context || "");
|
|
22
|
-
}
|
|
23
|
-
info(message, context) {
|
|
24
|
-
console.info(`[INFO] ${message}`, context || "");
|
|
25
|
-
}
|
|
26
|
-
warn(message, context) {
|
|
27
|
-
console.warn(`[WARN] ${message}`, context || "");
|
|
28
|
-
}
|
|
29
|
-
error(message, context) {
|
|
30
|
-
console.error(`[ERROR] ${message}`, context || "");
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
logger.ConsoleLogger = ConsoleLogger;
|
|
34
|
-
const generateSpanId = () => crypto.randomUUID();
|
|
35
|
-
logger.generateSpanId = generateSpanId;
|
|
36
|
-
function pickHeaders(headers, allowlist, redactSet) {
|
|
37
|
-
const result = {};
|
|
38
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
39
|
-
const lowerKey = key.toLowerCase();
|
|
40
|
-
if (redactSet?.has(lowerKey)) {
|
|
41
|
-
result[key] = "[REDACTED]";
|
|
42
|
-
} else if (allowlist.has(lowerKey)) {
|
|
43
|
-
result[key] = Array.isArray(value) ? value.join(", ") : value ?? "";
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return result;
|
|
47
|
-
}
|
|
48
|
-
function normalizeError(error) {
|
|
49
|
-
return error instanceof Error ? { message: error.message, stack: error.stack } : String(error);
|
|
50
|
-
}
|
|
51
|
-
const LLM_RESPONSE_HEADER_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
52
|
-
"x-request-id",
|
|
53
|
-
"x-ratelimit-limit-requests",
|
|
54
|
-
"x-ratelimit-limit-tokens",
|
|
55
|
-
"x-ratelimit-remaining-requests",
|
|
56
|
-
"x-ratelimit-remaining-tokens",
|
|
57
|
-
"x-groq-region"
|
|
58
|
-
]);
|
|
59
|
-
const logLlmCallStart = (logger2, spanId, service, method, request) => {
|
|
60
|
-
logger2.info("LLM call started", {
|
|
61
|
-
type: "llm_call_start",
|
|
62
|
-
span_id: spanId,
|
|
63
|
-
service,
|
|
64
|
-
method,
|
|
65
|
-
...request
|
|
66
|
-
});
|
|
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";
|
|
67
20
|
};
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
logger2.info("LLM call completed", {
|
|
72
|
-
type: "llm_call_complete",
|
|
73
|
-
span_id: spanId,
|
|
74
|
-
service,
|
|
75
|
-
method,
|
|
76
|
-
...rest,
|
|
77
|
-
...pickHeaders(headers, LLM_RESPONSE_HEADER_ALLOWLIST),
|
|
78
|
-
duration_ms: duration
|
|
79
|
-
});
|
|
21
|
+
nuaErrors.isNuaValidationError = isNuaValidationError;
|
|
22
|
+
const isNuaInternalError = (a) => {
|
|
23
|
+
return typeof a == "object" && a != null && "kind" in a && a.kind == "internal-error";
|
|
80
24
|
};
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
type: "llm_call_error",
|
|
85
|
-
span_id: spanId,
|
|
86
|
-
service,
|
|
87
|
-
method,
|
|
88
|
-
error: normalizeError(error),
|
|
89
|
-
duration_ms: duration
|
|
90
|
-
});
|
|
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");
|
|
91
28
|
};
|
|
92
|
-
|
|
93
|
-
return
|
|
29
|
+
nuaErrors.isNuaError = isNuaError;
|
|
30
|
+
return nuaErrors;
|
|
94
31
|
}
|
|
95
32
|
|
|
96
33
|
var validateMappableInputData = {};
|
|
@@ -133,7 +70,7 @@ function requireValidateMappableInputData() {
|
|
|
133
70
|
return validateMappableInputData;
|
|
134
71
|
}
|
|
135
72
|
|
|
136
|
-
var
|
|
73
|
+
var runCast = {};
|
|
137
74
|
|
|
138
75
|
var llmResponseExtraction = {};
|
|
139
76
|
|
|
@@ -242,60 +179,6 @@ function requireLlmResponseExtraction() {
|
|
|
242
179
|
return llmResponseExtraction;
|
|
243
180
|
}
|
|
244
181
|
|
|
245
|
-
var hasRequiredCallLlmService;
|
|
246
|
-
function requireCallLlmService() {
|
|
247
|
-
if (hasRequiredCallLlmService) return callLlmService;
|
|
248
|
-
hasRequiredCallLlmService = 1;
|
|
249
|
-
Object.defineProperty(callLlmService, "__esModule", { value: true });
|
|
250
|
-
callLlmService.callLLM = callLLM;
|
|
251
|
-
const llm_response_extraction_1 = requireLlmResponseExtraction();
|
|
252
|
-
const delay = (ms) => {
|
|
253
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
254
|
-
};
|
|
255
|
-
async function callLLM(llmClient, prompt, model, maxTokens, temperature, maxRetries, validationFunction) {
|
|
256
|
-
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
257
|
-
try {
|
|
258
|
-
const providerResponse = await llmClient.sendRequest(prompt, model, maxTokens);
|
|
259
|
-
const response = providerResponse.text;
|
|
260
|
-
let parsedResponse;
|
|
261
|
-
try {
|
|
262
|
-
const { cleanedResponse } = (0, llm_response_extraction_1.extractThinkingFromResponse)(response);
|
|
263
|
-
parsedResponse = (0, llm_response_extraction_1.parseJsonFromLlmResponse)(cleanedResponse);
|
|
264
|
-
} catch (parseError) {
|
|
265
|
-
const errorMessage2 = `Failed to parse LLM response as JSON: ${parseError instanceof Error ? parseError.message : "Unknown parsing error"}`;
|
|
266
|
-
throw new Error(`${errorMessage2}
|
|
267
|
-
|
|
268
|
-
Raw LLM response:
|
|
269
|
-
${response}`);
|
|
270
|
-
}
|
|
271
|
-
const validationResult = validationFunction(parsedResponse);
|
|
272
|
-
if (validationResult.success && validationResult.data) {
|
|
273
|
-
return {
|
|
274
|
-
data: validationResult.data,
|
|
275
|
-
usage: providerResponse.usage
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
|
-
const errorMessage = `Validation failed: ${validationResult.error || "Unknown validation error"}`;
|
|
279
|
-
throw new Error(`${errorMessage}
|
|
280
|
-
|
|
281
|
-
Raw LLM response:
|
|
282
|
-
${response}`);
|
|
283
|
-
} catch (error) {
|
|
284
|
-
const isLastAttempt = attempt === maxRetries;
|
|
285
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
286
|
-
if (isLastAttempt) {
|
|
287
|
-
throw new Error(`LLM call failed after ${maxRetries} attempts. Last error: ${errorMessage}`);
|
|
288
|
-
}
|
|
289
|
-
const backoffDelay = Math.pow(2, attempt - 1) * 1e3;
|
|
290
|
-
console.warn(`LLM call attempt ${attempt} failed: ${errorMessage}. Retrying in ${backoffDelay}ms...`);
|
|
291
|
-
await delay(backoffDelay);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
throw new Error("Unexpected error: retry loop completed without success or failure");
|
|
295
|
-
}
|
|
296
|
-
return callLlmService;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
182
|
var nuaJsonSchemaValueValidation = {};
|
|
300
183
|
|
|
301
184
|
var ajvInstances = {};
|
|
@@ -9497,7 +9380,418 @@ function requireNuaJsonSchemaValueValidation() {
|
|
|
9497
9380
|
return nuaJsonSchemaValueValidation;
|
|
9498
9381
|
}
|
|
9499
9382
|
|
|
9500
|
-
var
|
|
9383
|
+
var envelope = {};
|
|
9384
|
+
|
|
9385
|
+
var hasRequiredEnvelope;
|
|
9386
|
+
function requireEnvelope() {
|
|
9387
|
+
if (hasRequiredEnvelope) return envelope;
|
|
9388
|
+
hasRequiredEnvelope = 1;
|
|
9389
|
+
(function(exports$1) {
|
|
9390
|
+
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
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;
|
|
9445
|
+
}
|
|
9446
|
+
}
|
|
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) {
|
|
9672
|
+
return {
|
|
9673
|
+
kind: "retry",
|
|
9674
|
+
error: `Validation failed: ${validation.error || "Unknown validation error"}
|
|
9675
|
+
|
|
9676
|
+
Raw LLM response:
|
|
9677
|
+
${candidate.raw}`
|
|
9678
|
+
};
|
|
9679
|
+
}
|
|
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;
|
|
9794
|
+
}
|
|
9501
9795
|
|
|
9502
9796
|
var providerConfig = {};
|
|
9503
9797
|
|
|
@@ -9716,346 +10010,433 @@ function requireProviderConfig() {
|
|
|
9716
10010
|
return providerConfig;
|
|
9717
10011
|
}
|
|
9718
10012
|
|
|
9719
|
-
var
|
|
9720
|
-
|
|
9721
|
-
var sseParser = {};
|
|
10013
|
+
var providerEngines = {};
|
|
9722
10014
|
|
|
9723
|
-
var
|
|
9724
|
-
function requireSseParser() {
|
|
9725
|
-
if (hasRequiredSseParser) return sseParser;
|
|
9726
|
-
hasRequiredSseParser = 1;
|
|
9727
|
-
Object.defineProperty(sseParser, "__esModule", { value: true });
|
|
9728
|
-
sseParser.parseSSEStream = parseSSEStream;
|
|
9729
|
-
async function* parseSSEStream(stream) {
|
|
9730
|
-
const reader = stream.getReader();
|
|
9731
|
-
const decoder = new TextDecoder();
|
|
9732
|
-
let buffer = "";
|
|
9733
|
-
try {
|
|
9734
|
-
while (true) {
|
|
9735
|
-
const { done, value } = await reader.read();
|
|
9736
|
-
if (done)
|
|
9737
|
-
break;
|
|
9738
|
-
buffer += decoder.decode(value, { stream: true });
|
|
9739
|
-
const parts = buffer.split(/\r?\n\r?\n/);
|
|
9740
|
-
buffer = parts.pop();
|
|
9741
|
-
for (const part of parts) {
|
|
9742
|
-
for (const line of part.split(/\r?\n/)) {
|
|
9743
|
-
if (line.startsWith("data: ")) {
|
|
9744
|
-
const data = line.slice(6);
|
|
9745
|
-
if (data === "[DONE]") {
|
|
9746
|
-
return;
|
|
9747
|
-
}
|
|
9748
|
-
yield data;
|
|
9749
|
-
}
|
|
9750
|
-
}
|
|
9751
|
-
}
|
|
9752
|
-
}
|
|
9753
|
-
if (buffer.trim()) {
|
|
9754
|
-
for (const line of buffer.split(/\r?\n/)) {
|
|
9755
|
-
if (line.startsWith("data: ")) {
|
|
9756
|
-
const data = line.slice(6);
|
|
9757
|
-
if (data === "[DONE]") {
|
|
9758
|
-
return;
|
|
9759
|
-
}
|
|
9760
|
-
yield data;
|
|
9761
|
-
}
|
|
9762
|
-
}
|
|
9763
|
-
}
|
|
9764
|
-
} finally {
|
|
9765
|
-
reader.releaseLock();
|
|
9766
|
-
}
|
|
9767
|
-
}
|
|
9768
|
-
return sseParser;
|
|
9769
|
-
}
|
|
10015
|
+
var modelInfo = {};
|
|
9770
10016
|
|
|
9771
|
-
var
|
|
9772
|
-
function
|
|
9773
|
-
if (
|
|
9774
|
-
|
|
9775
|
-
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
|
|
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);
|
|
9788
10062
|
}
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
|
|
9799
|
-
|
|
9800
|
-
|
|
9801
|
-
|
|
9802
|
-
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
|
|
9808
|
-
|
|
9809
|
-
|
|
9810
|
-
|
|
9811
|
-
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
role: "tool",
|
|
9815
|
-
tool_call_id: msg.toolCallId,
|
|
9816
|
-
content: msg.content
|
|
9817
|
-
});
|
|
9818
|
-
break;
|
|
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)}`);
|
|
10075
|
+
}
|
|
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".');
|
|
9819
10088
|
}
|
|
10089
|
+
return {
|
|
10090
|
+
provider: input.provider,
|
|
10091
|
+
model
|
|
10092
|
+
};
|
|
9820
10093
|
}
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
return tools.map((t) => ({
|
|
9825
|
-
type: "function",
|
|
9826
|
-
function: {
|
|
9827
|
-
name: t.name,
|
|
9828
|
-
description: t.description,
|
|
9829
|
-
parameters: t.parameters
|
|
10094
|
+
function resolveModelInput(input, configuredProviders) {
|
|
10095
|
+
if (input == null) {
|
|
10096
|
+
return resolveModelInput({ alias: "fast" }, configuredProviders);
|
|
9830
10097
|
}
|
|
9831
|
-
|
|
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.`);
|
|
10112
|
+
}
|
|
10113
|
+
return configuredTarget;
|
|
10114
|
+
}
|
|
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
|
+
};
|
|
10167
|
+
}
|
|
9832
10168
|
}
|
|
9833
|
-
function
|
|
9834
|
-
|
|
9835
|
-
|
|
9836
|
-
const body = {
|
|
9837
|
-
messages,
|
|
9838
|
-
tools: tools.length > 0 ? tools : void 0,
|
|
9839
|
-
model: options.model,
|
|
9840
|
-
max_completion_tokens: options.maxTokens,
|
|
9841
|
-
stream: options.stream ?? false
|
|
9842
|
-
};
|
|
9843
|
-
if (options.stream) {
|
|
9844
|
-
body.stream_options = { include_usage: true };
|
|
10169
|
+
function toFetchableBody(body) {
|
|
10170
|
+
if (typeof body === "string" || body === void 0) {
|
|
10171
|
+
return body;
|
|
9845
10172
|
}
|
|
9846
|
-
|
|
9847
|
-
"Content-Type": "application/json",
|
|
9848
|
-
Authorization: `Bearer ${apiKey}`
|
|
9849
|
-
};
|
|
9850
|
-
return {
|
|
9851
|
-
url: baseUrl,
|
|
9852
|
-
method: "POST",
|
|
9853
|
-
headers,
|
|
9854
|
-
body,
|
|
9855
|
-
loggableHeaders: {
|
|
9856
|
-
...headers,
|
|
9857
|
-
Authorization: "Bearer [REDACTED]"
|
|
9858
|
-
},
|
|
9859
|
-
loggableBody: body
|
|
9860
|
-
};
|
|
10173
|
+
return JSON.stringify(body);
|
|
9861
10174
|
}
|
|
9862
|
-
|
|
9863
|
-
|
|
9864
|
-
|
|
10175
|
+
return providerCall;
|
|
10176
|
+
}
|
|
10177
|
+
|
|
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();
|
|
10185
|
+
const provider_config_1 = requireProviderConfig();
|
|
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;
|
|
9865
10191
|
}
|
|
9866
|
-
|
|
9867
|
-
|
|
9868
|
-
|
|
9869
|
-
} catch {
|
|
9870
|
-
const preview = rawArguments.length > 500 ? rawArguments.slice(0, 500) + "..." : rawArguments;
|
|
9871
|
-
throw new Error(`${errorLabel} API error: Invalid JSON arguments for tool "${toolName}": ${preview}`);
|
|
10192
|
+
/** Provider APIs are given the schema in the prompt; none is enforced natively yet. */
|
|
10193
|
+
nativeSchema() {
|
|
10194
|
+
return null;
|
|
9872
10195
|
}
|
|
9873
|
-
|
|
9874
|
-
|
|
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) };
|
|
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
|
+
};
|
|
9875
10217
|
}
|
|
9876
|
-
return parsed;
|
|
9877
10218
|
}
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
|
|
9883
|
-
|
|
9884
|
-
|
|
9885
|
-
|
|
9886
|
-
|
|
9887
|
-
|
|
9888
|
-
|
|
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 };
|
|
10223
|
+
}
|
|
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);
|
|
10240
|
+
}
|
|
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
|
+
}
|
|
9889
10250
|
}
|
|
10251
|
+
this.apiKeys = apiKeys;
|
|
9890
10252
|
}
|
|
9891
|
-
|
|
9892
|
-
|
|
9893
|
-
|
|
9894
|
-
|
|
9895
|
-
|
|
9896
|
-
|
|
9897
|
-
const assistantText = (0, provider_config_1.extractOpenAiMessageText)(choice.message);
|
|
9898
|
-
if (assistantText) {
|
|
9899
|
-
contentBlocks.push({
|
|
9900
|
-
type: "text",
|
|
9901
|
-
text: assistantText
|
|
9902
|
-
});
|
|
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) };
|
|
9903
10259
|
}
|
|
9904
|
-
|
|
9905
|
-
|
|
9906
|
-
|
|
9907
|
-
|
|
9908
|
-
|
|
9909
|
-
name: tc.function.name,
|
|
9910
|
-
arguments: parseOpenAiToolArguments(tc.function.arguments, tc.function.name, errorLabel)
|
|
9911
|
-
});
|
|
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 };
|
|
9912
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 } };
|
|
9913
10271
|
}
|
|
9914
|
-
const usage = (0, provider_config_1.normalizeOpenAiUsage)(responseBody.usage);
|
|
9915
|
-
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";
|
|
9916
|
-
return {
|
|
9917
|
-
message: {
|
|
9918
|
-
role: "assistant",
|
|
9919
|
-
content: contentBlocks
|
|
9920
|
-
},
|
|
9921
|
-
usage,
|
|
9922
|
-
stopReason
|
|
9923
|
-
};
|
|
9924
10272
|
}
|
|
9925
|
-
|
|
9926
|
-
|
|
9927
|
-
|
|
9928
|
-
|
|
9929
|
-
|
|
9930
|
-
|
|
9931
|
-
|
|
9932
|
-
|
|
9933
|
-
|
|
9934
|
-
|
|
9935
|
-
|
|
9936
|
-
|
|
9937
|
-
|
|
9938
|
-
|
|
9939
|
-
|
|
9940
|
-
|
|
9941
|
-
parts.push({
|
|
9942
|
-
functionCall: {
|
|
9943
|
-
name: block.name,
|
|
9944
|
-
args: block.arguments
|
|
9945
|
-
}
|
|
9946
|
-
});
|
|
9947
|
-
}
|
|
9948
|
-
}
|
|
9949
|
-
result.push({ role: "model", parts });
|
|
9950
|
-
break;
|
|
9951
|
-
}
|
|
9952
|
-
case "toolResult": {
|
|
9953
|
-
result.push({
|
|
9954
|
-
role: "user",
|
|
9955
|
-
parts: [
|
|
9956
|
-
{
|
|
9957
|
-
functionResponse: {
|
|
9958
|
-
name: msg.toolName,
|
|
9959
|
-
response: { content: msg.content }
|
|
9960
|
-
}
|
|
9961
|
-
}
|
|
9962
|
-
]
|
|
9963
|
-
});
|
|
9964
|
-
break;
|
|
9965
|
-
}
|
|
9966
|
-
}
|
|
9967
|
-
}
|
|
9968
|
-
return result;
|
|
9969
|
-
}
|
|
9970
|
-
function convertToolsToGemini(tools) {
|
|
9971
|
-
if (tools.length === 0)
|
|
9972
|
-
return [];
|
|
9973
|
-
return [
|
|
9974
|
-
{
|
|
9975
|
-
functionDeclarations: tools.map((t) => ({
|
|
9976
|
-
name: t.name,
|
|
9977
|
-
description: t.description,
|
|
9978
|
-
parameters: t.parameters
|
|
9979
|
-
}))
|
|
9980
|
-
}
|
|
9981
|
-
];
|
|
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";
|
|
9982
10289
|
}
|
|
9983
|
-
function
|
|
9984
|
-
|
|
9985
|
-
|
|
9986
|
-
const body = {
|
|
9987
|
-
contents,
|
|
9988
|
-
generationConfig: {
|
|
9989
|
-
maxOutputTokens: options.maxTokens
|
|
9990
|
-
}
|
|
9991
|
-
};
|
|
9992
|
-
if (tools.length > 0) {
|
|
9993
|
-
body.tools = tools;
|
|
10290
|
+
function getErrorMessageFromException(error) {
|
|
10291
|
+
if (isErrorWithMessage(error)) {
|
|
10292
|
+
return error.message;
|
|
9994
10293
|
}
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
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"
|
|
9998
10312
|
};
|
|
9999
10313
|
}
|
|
10000
|
-
const
|
|
10001
|
-
const
|
|
10002
|
-
|
|
10003
|
-
|
|
10004
|
-
|
|
10005
|
-
|
|
10006
|
-
headers: {
|
|
10007
|
-
"Content-Type": "application/json"
|
|
10008
|
-
},
|
|
10009
|
-
body,
|
|
10010
|
-
loggableUrl: url.replace(/key=[^&]+/, "key=[REDACTED]"),
|
|
10011
|
-
loggableBody: body
|
|
10012
|
-
};
|
|
10013
|
-
}
|
|
10014
|
-
async function parseGeminiAgenticResponse(response) {
|
|
10015
|
-
if (response.status !== 200) {
|
|
10016
|
-
const errorBody = await response.text();
|
|
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) {
|
|
10017
10320
|
try {
|
|
10018
|
-
|
|
10019
|
-
|
|
10020
|
-
throw new Error(`Gemini API error: ${response.status} - ${message}`);
|
|
10321
|
+
ajvInstance.compile(schema);
|
|
10322
|
+
return true;
|
|
10021
10323
|
} catch (e) {
|
|
10022
|
-
|
|
10023
|
-
throw e;
|
|
10024
|
-
throw new Error(`Gemini API error: ${response.status} - ${errorBody}`);
|
|
10324
|
+
errors = (0, error_utils_1.getErrorMessageFromException)(e);
|
|
10025
10325
|
}
|
|
10326
|
+
} else {
|
|
10327
|
+
errors = "unexpected-situation-no-errors-found-for-invalid-schema";
|
|
10026
10328
|
}
|
|
10027
|
-
|
|
10028
|
-
|
|
10029
|
-
|
|
10030
|
-
|
|
10031
|
-
|
|
10032
|
-
|
|
10033
|
-
|
|
10034
|
-
|
|
10035
|
-
|
|
10036
|
-
|
|
10329
|
+
return {
|
|
10330
|
+
kind: "validation-error",
|
|
10331
|
+
message: `Unable to validate JSON schema: ${errors}`
|
|
10332
|
+
};
|
|
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;
|
|
10352
|
+
}
|
|
10353
|
+
seen.add(currentValue);
|
|
10354
|
+
return Object.keys(currentValue).sort().reduce((acc, key) => {
|
|
10355
|
+
acc[key] = currentValue[key];
|
|
10356
|
+
return acc;
|
|
10357
|
+
}, {});
|
|
10037
10358
|
}
|
|
10038
|
-
|
|
10039
|
-
|
|
10040
|
-
|
|
10041
|
-
|
|
10042
|
-
|
|
10043
|
-
|
|
10044
|
-
|
|
10045
|
-
|
|
10359
|
+
return currentValue;
|
|
10360
|
+
};
|
|
10361
|
+
return JSON.stringify(value, sorter) ?? "";
|
|
10362
|
+
}
|
|
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
|
+
}
|
|
10046
10397
|
}
|
|
10398
|
+
};
|
|
10399
|
+
if (typeof itemSchema.$schema === "string") {
|
|
10400
|
+
jsonSchema.$schema = itemSchema.$schema;
|
|
10401
|
+
}
|
|
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);
|
|
10047
10407
|
}
|
|
10048
|
-
const usage = (0, provider_config_1.normalizeGeminiUsage)(responseBody.usageMetadata);
|
|
10049
|
-
const stopReason = hasToolCalls ? "tool_use" : "stop";
|
|
10050
10408
|
return {
|
|
10051
|
-
|
|
10052
|
-
|
|
10053
|
-
content: contentBlocks
|
|
10054
|
-
},
|
|
10055
|
-
usage,
|
|
10056
|
-
stopReason
|
|
10409
|
+
kind: "validation-error",
|
|
10410
|
+
message: `Not a list schema with rows keyed by "${keys.primaryKey}" holding "${keys.outputName}"`
|
|
10057
10411
|
};
|
|
10058
10412
|
}
|
|
10413
|
+
function rowsHoldKeys(items, keys) {
|
|
10414
|
+
if (!isObject(items) || !isObject(items.properties) || !Array.isArray(items.required)) {
|
|
10415
|
+
return false;
|
|
10416
|
+
}
|
|
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);
|
|
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();
|
|
10059
10440
|
function safeEmit(onEvent, event) {
|
|
10060
10441
|
if (!onEvent)
|
|
10061
10442
|
return;
|
|
@@ -10064,946 +10445,713 @@ function requireProviderFormatters() {
|
|
|
10064
10445
|
} catch {
|
|
10065
10446
|
}
|
|
10066
10447
|
}
|
|
10067
|
-
async function
|
|
10068
|
-
|
|
10069
|
-
|
|
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;
|
|
10070
10457
|
try {
|
|
10071
|
-
|
|
10072
|
-
|
|
10073
|
-
|
|
10074
|
-
|
|
10075
|
-
|
|
10076
|
-
throw e;
|
|
10077
|
-
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);
|
|
10078
10463
|
}
|
|
10079
|
-
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
10085
|
-
|
|
10086
|
-
let usage = { ...provider_config_1.normalizedUsageZero };
|
|
10087
|
-
for await (const data of (0, sse_parser_1.parseSSEStream)(response.body)) {
|
|
10088
|
-
let chunk;
|
|
10089
|
-
try {
|
|
10090
|
-
chunk = JSON.parse(data);
|
|
10091
|
-
} catch {
|
|
10092
|
-
continue;
|
|
10093
|
-
}
|
|
10094
|
-
if (chunk.usage) {
|
|
10095
|
-
usage = (0, provider_config_1.normalizeOpenAiUsage)(chunk.usage);
|
|
10096
|
-
}
|
|
10097
|
-
const choice = chunk.choices?.[0];
|
|
10098
|
-
if (!choice)
|
|
10099
|
-
continue;
|
|
10100
|
-
if (choice.finish_reason) {
|
|
10101
|
-
finishReason = choice.finish_reason;
|
|
10102
|
-
}
|
|
10103
|
-
const delta = choice.delta;
|
|
10104
|
-
if (!delta)
|
|
10105
|
-
continue;
|
|
10106
|
-
if (delta.content) {
|
|
10107
|
-
textContent += delta.content;
|
|
10108
|
-
safeEmit(onEvent, { type: "text_delta", text: delta.content });
|
|
10109
|
-
}
|
|
10110
|
-
if (delta.tool_calls) {
|
|
10111
|
-
for (const tc of delta.tool_calls) {
|
|
10112
|
-
const existing = toolCallAccumulators.get(tc.index);
|
|
10113
|
-
if (existing) {
|
|
10114
|
-
if (tc.function?.arguments) {
|
|
10115
|
-
existing.arguments += tc.function.arguments;
|
|
10116
|
-
}
|
|
10117
|
-
} else {
|
|
10118
|
-
toolCallAccumulators.set(tc.index, {
|
|
10119
|
-
id: tc.id ?? "",
|
|
10120
|
-
name: tc.function?.name ?? "",
|
|
10121
|
-
arguments: tc.function?.arguments ?? ""
|
|
10122
|
-
});
|
|
10123
|
-
}
|
|
10124
|
-
}
|
|
10125
|
-
}
|
|
10126
|
-
}
|
|
10127
|
-
const contentBlocks = [];
|
|
10128
|
-
if (textContent) {
|
|
10129
|
-
contentBlocks.push({ type: "text", text: textContent });
|
|
10130
|
-
}
|
|
10131
|
-
const sortedToolCalls = [...toolCallAccumulators.entries()].sort(([a], [b]) => a - b);
|
|
10132
|
-
for (const [, tc] of sortedToolCalls) {
|
|
10133
|
-
contentBlocks.push({
|
|
10134
|
-
type: "toolCall",
|
|
10135
|
-
id: tc.id,
|
|
10136
|
-
name: tc.name,
|
|
10137
|
-
arguments: parseOpenAiToolArguments(tc.arguments, tc.name, errorLabel)
|
|
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
|
|
10138
10471
|
});
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
usage,
|
|
10144
|
-
stopReason: stopReason2
|
|
10145
|
-
};
|
|
10146
|
-
}
|
|
10147
|
-
async function streamGeminiAgenticResponse(response, onEvent) {
|
|
10148
|
-
if (response.status !== 200) {
|
|
10149
|
-
const errorBody = await response.text();
|
|
10150
|
-
try {
|
|
10151
|
-
const parsed = JSON.parse(errorBody);
|
|
10152
|
-
const message = parsed?.error?.message || errorBody;
|
|
10153
|
-
throw new Error(`Gemini API error: ${response.status} - ${message}`);
|
|
10154
|
-
} catch (e) {
|
|
10155
|
-
if (e instanceof Error && e.message.startsWith("Gemini API error:"))
|
|
10156
|
-
throw e;
|
|
10157
|
-
throw new Error(`Gemini API error: ${response.status} - ${errorBody}`);
|
|
10158
|
-
}
|
|
10159
|
-
}
|
|
10160
|
-
if (!response.body) {
|
|
10161
|
-
throw new Error("Gemini API error: Response body is null");
|
|
10162
|
-
}
|
|
10163
|
-
const contentBlocks = [];
|
|
10164
|
-
let hasToolCalls2 = false;
|
|
10165
|
-
let textContent2 = "";
|
|
10166
|
-
let usage2 = { ...provider_config_1.normalizedUsageZero };
|
|
10167
|
-
for await (const data of (0, sse_parser_1.parseSSEStream)(response.body)) {
|
|
10168
|
-
let chunk;
|
|
10169
|
-
try {
|
|
10170
|
-
chunk = JSON.parse(data);
|
|
10171
|
-
} catch {
|
|
10172
|
-
continue;
|
|
10173
|
-
}
|
|
10174
|
-
if (chunk.usageMetadata) {
|
|
10175
|
-
usage2 = (0, provider_config_1.normalizeGeminiUsage)(chunk.usageMetadata);
|
|
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);
|
|
10176
10476
|
}
|
|
10177
|
-
const
|
|
10178
|
-
|
|
10179
|
-
|
|
10180
|
-
|
|
10181
|
-
|
|
10182
|
-
|
|
10183
|
-
|
|
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;
|
|
10184
10504
|
}
|
|
10185
|
-
|
|
10186
|
-
|
|
10187
|
-
|
|
10188
|
-
|
|
10189
|
-
|
|
10190
|
-
|
|
10191
|
-
|
|
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
|
|
10192
10535
|
});
|
|
10193
10536
|
}
|
|
10194
10537
|
}
|
|
10195
10538
|
}
|
|
10196
|
-
|
|
10197
|
-
|
|
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;
|
|
10198
10552
|
}
|
|
10199
|
-
const
|
|
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;
|
|
10200
10558
|
return {
|
|
10201
|
-
|
|
10202
|
-
|
|
10203
|
-
|
|
10559
|
+
success,
|
|
10560
|
+
completionReason,
|
|
10561
|
+
messages,
|
|
10562
|
+
textResponse: extractLastAssistantText(messages),
|
|
10563
|
+
usage,
|
|
10564
|
+
error
|
|
10204
10565
|
};
|
|
10205
10566
|
}
|
|
10206
|
-
return
|
|
10567
|
+
return agentLoop;
|
|
10207
10568
|
}
|
|
10208
10569
|
|
|
10209
|
-
var
|
|
10210
|
-
|
|
10211
|
-
|
|
10212
|
-
|
|
10213
|
-
|
|
10214
|
-
|
|
10215
|
-
|
|
10216
|
-
|
|
10217
|
-
|
|
10218
|
-
|
|
10219
|
-
|
|
10220
|
-
|
|
10221
|
-
|
|
10222
|
-
|
|
10223
|
-
|
|
10224
|
-
|
|
10225
|
-
|
|
10226
|
-
|
|
10227
|
-
|
|
10228
|
-
|
|
10229
|
-
|
|
10230
|
-
|
|
10231
|
-
|
|
10232
|
-
|
|
10233
|
-
|
|
10234
|
-
|
|
10235
|
-
|
|
10236
|
-
|
|
10237
|
-
|
|
10238
|
-
|
|
10239
|
-
|
|
10240
|
-
|
|
10241
|
-
|
|
10242
|
-
|
|
10243
|
-
|
|
10244
|
-
const provider = this.getProviderConfig();
|
|
10245
|
-
const codec = this.getAgenticProviderCodec(provider.errorLabel);
|
|
10246
|
-
const requestOptions = codec.buildRequest({
|
|
10247
|
-
messages,
|
|
10248
|
-
tools,
|
|
10249
|
-
model,
|
|
10250
|
-
maxTokens,
|
|
10251
|
-
systemPrompt,
|
|
10252
|
-
stream: !!onEvent
|
|
10253
|
-
});
|
|
10254
|
-
const parseResponse = onEvent ? (response) => codec.parseStreamingResponse(response, onEvent) : codec.parseResponse;
|
|
10255
|
-
return this.executeProviderCall({
|
|
10256
|
-
provider,
|
|
10257
|
-
model,
|
|
10258
|
-
maxTokens,
|
|
10259
|
-
apiOperation: "agentic",
|
|
10260
|
-
requestOptions,
|
|
10261
|
-
parseResponse,
|
|
10262
|
-
getResponseLength: (parsedResponse) => parsedResponse.message.content.reduce((total, content) => total + (content.type === "text" ? content.text.length : 0), 0),
|
|
10263
|
-
getUsage: (parsedResponse) => parsedResponse.usage
|
|
10264
|
-
});
|
|
10265
|
-
}
|
|
10266
|
-
getProviderConfig() {
|
|
10267
|
-
const provider = provider_config_1.providerConfigs[this.providerId];
|
|
10268
|
-
if (!provider) {
|
|
10269
|
-
throw new Error(`Unknown LLM provider: ${this.providerId}`);
|
|
10270
|
-
}
|
|
10271
|
-
return provider;
|
|
10272
|
-
}
|
|
10273
|
-
async executeProviderCall(params) {
|
|
10274
|
-
const method = params.requestOptions.method ?? "POST";
|
|
10275
|
-
const headers = params.requestOptions.headers ?? {};
|
|
10276
|
-
const body = this.toFetchableBody(params.requestOptions.body);
|
|
10277
|
-
const spanId = (0, logger_1.generateSpanId)();
|
|
10278
|
-
const startTime = Date.now();
|
|
10279
|
-
(0, logger_1.logLlmCallStart)(this.logger, spanId, params.provider.providerId, params.apiOperation, {
|
|
10280
|
-
url: params.requestOptions.loggableUrl ?? params.requestOptions.url,
|
|
10281
|
-
httpMethod: method,
|
|
10282
|
-
model: params.model,
|
|
10283
|
-
maxTokens: params.maxTokens
|
|
10284
|
-
});
|
|
10285
|
-
try {
|
|
10286
|
-
const response = await fetch(params.requestOptions.url, {
|
|
10287
|
-
method,
|
|
10288
|
-
headers,
|
|
10289
|
-
body
|
|
10290
|
-
});
|
|
10291
|
-
const parsedResponse = await params.parseResponse(response);
|
|
10292
|
-
const duration = Date.now() - startTime;
|
|
10293
|
-
(0, logger_1.logLlmCallComplete)(this.logger, spanId, params.provider.providerId, params.apiOperation, {
|
|
10294
|
-
status: response.status,
|
|
10295
|
-
responseLength: params.getResponseLength(parsedResponse),
|
|
10296
|
-
headers: Object.fromEntries(response.headers.entries()),
|
|
10297
|
-
usage: params.getUsage(parsedResponse)
|
|
10298
|
-
}, duration);
|
|
10299
|
-
return parsedResponse;
|
|
10300
|
-
} catch (error) {
|
|
10301
|
-
const duration = Date.now() - startTime;
|
|
10302
|
-
(0, logger_1.logLlmCallError)(this.logger, spanId, params.provider.providerId, params.apiOperation, error, duration);
|
|
10303
|
-
throw new Error(`${params.provider.errorLabel} API request failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
10304
|
-
}
|
|
10305
|
-
}
|
|
10306
|
-
toFetchableBody(bodyPayload) {
|
|
10307
|
-
if (typeof bodyPayload === "string") {
|
|
10308
|
-
return bodyPayload;
|
|
10309
|
-
}
|
|
10310
|
-
if (bodyPayload === void 0) {
|
|
10311
|
-
return void 0;
|
|
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
|
+
}
|
|
10312
10605
|
}
|
|
10313
|
-
|
|
10314
|
-
|
|
10315
|
-
|
|
10316
|
-
|
|
10317
|
-
|
|
10318
|
-
|
|
10319
|
-
|
|
10320
|
-
|
|
10321
|
-
|
|
10322
|
-
|
|
10323
|
-
case "cerebras":
|
|
10324
|
-
return {
|
|
10325
|
-
buildRequest: (options) => (0, provider_formatters_1.buildOpenAiAgenticRequest)(options, "https://api.cerebras.ai/v1/chat/completions", this.apiKey),
|
|
10326
|
-
parseResponse: (response) => (0, provider_formatters_1.parseOpenAiAgenticResponse)(response, errorLabel),
|
|
10327
|
-
parseStreamingResponse: (response, onEvent) => (0, provider_formatters_1.streamOpenAiAgenticResponse)(response, errorLabel, onEvent)
|
|
10328
|
-
};
|
|
10329
|
-
case "openrouter":
|
|
10330
|
-
return {
|
|
10331
|
-
buildRequest: (options) => (0, provider_formatters_1.buildOpenAiAgenticRequest)(options, "https://openrouter.ai/api/v1/chat/completions", this.apiKey),
|
|
10332
|
-
parseResponse: (response) => (0, provider_formatters_1.parseOpenAiAgenticResponse)(response, errorLabel),
|
|
10333
|
-
parseStreamingResponse: (response, onEvent) => (0, provider_formatters_1.streamOpenAiAgenticResponse)(response, errorLabel, onEvent)
|
|
10334
|
-
};
|
|
10335
|
-
case "gemini":
|
|
10336
|
-
return {
|
|
10337
|
-
buildRequest: (options) => (0, provider_formatters_1.buildGeminiAgenticRequest)(options, this.apiKey),
|
|
10338
|
-
parseResponse: provider_formatters_1.parseGeminiAgenticResponse,
|
|
10339
|
-
parseStreamingResponse: (response, onEvent) => (0, provider_formatters_1.streamGeminiAgenticResponse)(response, onEvent)
|
|
10340
|
-
};
|
|
10341
|
-
default:
|
|
10342
|
-
throw new Error(`Unsupported provider for agentic requests: ${this.providerId}`);
|
|
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;
|
|
10612
|
+
}
|
|
10613
|
+
yield data;
|
|
10614
|
+
}
|
|
10615
|
+
}
|
|
10343
10616
|
}
|
|
10617
|
+
} finally {
|
|
10618
|
+
reader.releaseLock();
|
|
10344
10619
|
}
|
|
10345
10620
|
}
|
|
10346
|
-
|
|
10347
|
-
return httpLlmClient;
|
|
10621
|
+
return sseParser;
|
|
10348
10622
|
}
|
|
10349
10623
|
|
|
10350
|
-
var
|
|
10351
|
-
|
|
10352
|
-
|
|
10353
|
-
|
|
10354
|
-
|
|
10355
|
-
|
|
10356
|
-
|
|
10357
|
-
|
|
10358
|
-
|
|
10359
|
-
|
|
10360
|
-
|
|
10361
|
-
|
|
10362
|
-
|
|
10363
|
-
|
|
10364
|
-
|
|
10365
|
-
|
|
10366
|
-
|
|
10367
|
-
|
|
10368
|
-
|
|
10369
|
-
|
|
10370
|
-
|
|
10371
|
-
|
|
10372
|
-
|
|
10373
|
-
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
|
|
10378
|
-
|
|
10379
|
-
|
|
10380
|
-
|
|
10381
|
-
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
]
|
|
10391
|
-
};
|
|
10392
|
-
exports$1.MODEL_ALIAS_NAMES = Object.keys(exports$1.MODEL_ALIASES);
|
|
10393
|
-
const MODEL_ALIAS_SET = new Set(exports$1.MODEL_ALIAS_NAMES);
|
|
10394
|
-
const LLM_PROVIDER_ID_SET = new Set(provider_config_1.LLM_PROVIDER_IDS);
|
|
10395
|
-
function isLlmProviderId(value) {
|
|
10396
|
-
return typeof value === "string" && LLM_PROVIDER_ID_SET.has(value);
|
|
10397
|
-
}
|
|
10398
|
-
function isModelAliasName(value) {
|
|
10399
|
-
return typeof value === "string" && MODEL_ALIAS_SET.has(value);
|
|
10400
|
-
}
|
|
10401
|
-
function validationError(message) {
|
|
10402
|
-
return {
|
|
10403
|
-
kind: "validation-error",
|
|
10404
|
-
message
|
|
10405
|
-
};
|
|
10406
|
-
}
|
|
10407
|
-
function validateProviderModel(input, configuredProviders) {
|
|
10408
|
-
if (!isLlmProviderId(input.provider)) {
|
|
10409
|
-
return validationError(`Invalid LLM provider: ${String(input.provider)}`);
|
|
10410
|
-
}
|
|
10411
|
-
if (!configuredProviders.has(input.provider)) {
|
|
10412
|
-
return validationError(`LLM provider ${input.provider} is not configured. Please check your API keys.`);
|
|
10413
|
-
}
|
|
10414
|
-
if (typeof input.model !== "string") {
|
|
10415
|
-
return validationError("model.model must be a string");
|
|
10416
|
-
}
|
|
10417
|
-
const model = input.model.trim();
|
|
10418
|
-
if (!model) {
|
|
10419
|
-
return validationError("model.model must be a non-empty string");
|
|
10420
|
-
}
|
|
10421
|
-
if (input.provider === "gemini" && model.startsWith("models/")) {
|
|
10422
|
-
return validationError('Gemini model names must use bare model IDs, for example "gemini-2.5-flash", not "models/gemini-2.5-flash".');
|
|
10423
|
-
}
|
|
10424
|
-
return {
|
|
10425
|
-
provider: input.provider,
|
|
10426
|
-
model
|
|
10427
|
-
};
|
|
10428
|
-
}
|
|
10429
|
-
function resolveModelInput(input, configuredProviders) {
|
|
10430
|
-
if (input == null) {
|
|
10431
|
-
return resolveModelInput({ alias: "fast" }, configuredProviders);
|
|
10432
|
-
}
|
|
10433
|
-
if (typeof input !== "object") {
|
|
10434
|
-
return validationError("model must be an object with either alias or provider/model fields");
|
|
10435
|
-
}
|
|
10436
|
-
if ("provider" in input || "model" in input) {
|
|
10437
|
-
return validateProviderModel(input, configuredProviders);
|
|
10438
|
-
}
|
|
10439
|
-
if ("alias" in input) {
|
|
10440
|
-
const alias = input.alias;
|
|
10441
|
-
if (!isModelAliasName(alias)) {
|
|
10442
|
-
return validationError(`Invalid model alias: ${String(alias)}`);
|
|
10443
|
-
}
|
|
10444
|
-
const configuredTarget = exports$1.MODEL_ALIASES[alias].find((target) => configuredProviders.has(target.provider));
|
|
10445
|
-
if (!configuredTarget) {
|
|
10446
|
-
return validationError(`No configured provider found for model alias ${alias}. Please check your API keys.`);
|
|
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 });
|
|
10641
|
+
}
|
|
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;
|
|
10447
10664
|
}
|
|
10448
|
-
|
|
10665
|
+
case "toolResult":
|
|
10666
|
+
result.push({
|
|
10667
|
+
role: "tool",
|
|
10668
|
+
tool_call_id: msg.toolCallId,
|
|
10669
|
+
content: msg.content
|
|
10670
|
+
});
|
|
10671
|
+
break;
|
|
10449
10672
|
}
|
|
10450
|
-
return validationError("model must include either alias or provider/model fields");
|
|
10451
10673
|
}
|
|
10452
|
-
|
|
10453
|
-
|
|
10454
|
-
|
|
10455
|
-
|
|
10456
|
-
|
|
10457
|
-
|
|
10458
|
-
|
|
10459
|
-
|
|
10460
|
-
|
|
10461
|
-
|
|
10462
|
-
|
|
10463
|
-
|
|
10464
|
-
|
|
10465
|
-
|
|
10466
|
-
|
|
10467
|
-
const
|
|
10468
|
-
|
|
10469
|
-
|
|
10470
|
-
|
|
10471
|
-
|
|
10472
|
-
|
|
10473
|
-
}
|
|
10474
|
-
|
|
10475
|
-
var hasRequiredCastArrayPromptBuilder;
|
|
10476
|
-
function requireCastArrayPromptBuilder() {
|
|
10477
|
-
if (hasRequiredCastArrayPromptBuilder) return castArrayPromptBuilder;
|
|
10478
|
-
hasRequiredCastArrayPromptBuilder = 1;
|
|
10479
|
-
Object.defineProperty(castArrayPromptBuilder, "__esModule", { value: true });
|
|
10480
|
-
const prompt_template_utils_1 = requirePromptTemplateUtils();
|
|
10481
|
-
const builder = () => {
|
|
10482
|
-
const BASE_SYSTEM_PROMPT_WHEN_OUTPUT_TYPE_NAME_PROVIDED = [
|
|
10483
|
-
`Your task is to transform the provided <input-data> into a JSON array, that represents a list of`,
|
|
10484
|
-
`${(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.`,
|
|
10485
|
-
`It uses the JSON Schema spec.`,
|
|
10486
|
-
`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.`,
|
|
10487
|
-
`Your entire response should be just the value of the JSON array containing objects with '${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}'`,
|
|
10488
|
-
`and its primary key '${(0, prompt_template_utils_1.templateVarName)("PRIMARY_KEY")}', as valid JSON.`,
|
|
10489
|
-
`We will validate the result with the AJV Node library, using ajv.parse, against the JSON schema, and we expect it to validate correctly.`,
|
|
10490
|
-
`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,`,
|
|
10491
|
-
`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.`
|
|
10492
|
-
].join(" ");
|
|
10493
|
-
const buildSystemPrompt = (primaryKey, outputName) => {
|
|
10494
|
-
let a = BASE_SYSTEM_PROMPT_WHEN_OUTPUT_TYPE_NAME_PROVIDED;
|
|
10495
|
-
a = (0, prompt_template_utils_1.replaceTemplateVarName)(a, "PRIMARY_KEY", primaryKey);
|
|
10496
|
-
a = (0, prompt_template_utils_1.replaceTemplateVarName)(a, "OUTPUT_TYPE_NAME", outputName);
|
|
10497
|
-
return a;
|
|
10498
|
-
};
|
|
10499
|
-
const buildFullPrompt = (req, uncachedInputDataRows) => {
|
|
10500
|
-
const prompt = req.input.prompt;
|
|
10501
|
-
const fullPrompt = [
|
|
10502
|
-
prompt || "Transform the provided data according to the schema.",
|
|
10503
|
-
// user prompt
|
|
10504
|
-
buildSystemPrompt(req.input.primaryKey, req.output.name),
|
|
10505
|
-
`<json-schema-spec> ${JSON.stringify(req.output.effectiveSchema)} </json-schema-spec>`,
|
|
10506
|
-
`<input-data>${JSON.stringify(uncachedInputDataRows)}</input-data>`
|
|
10507
|
-
].join("\n");
|
|
10508
|
-
return fullPrompt;
|
|
10509
|
-
};
|
|
10510
|
-
return {
|
|
10511
|
-
buildSystemPrompt,
|
|
10512
|
-
buildFullPrompt
|
|
10513
|
-
};
|
|
10514
|
-
};
|
|
10515
|
-
const castArrayPromptBuilder$1 = builder();
|
|
10516
|
-
castArrayPromptBuilder.default = castArrayPromptBuilder$1;
|
|
10517
|
-
return castArrayPromptBuilder;
|
|
10518
|
-
}
|
|
10519
|
-
|
|
10520
|
-
var castPromptBuilder = {};
|
|
10521
|
-
|
|
10522
|
-
var hasRequiredCastPromptBuilder;
|
|
10523
|
-
function requireCastPromptBuilder() {
|
|
10524
|
-
if (hasRequiredCastPromptBuilder) return castPromptBuilder;
|
|
10525
|
-
hasRequiredCastPromptBuilder = 1;
|
|
10526
|
-
Object.defineProperty(castPromptBuilder, "__esModule", { value: true });
|
|
10527
|
-
const prompt_template_utils_1 = requirePromptTemplateUtils();
|
|
10528
|
-
const builder = () => {
|
|
10529
|
-
const BASE_SYSTEM_PROMPT_WHEN_OUTPUT_TYPE_NAME_PROVIDED = [
|
|
10530
|
-
`Please respond with a single JSON object that represents '${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}'.`,
|
|
10531
|
-
`The schema for this object (which uses the JSON Schema spec), is defined below for your reference.`,
|
|
10532
|
-
`Your task is to create an instance of this object. Respond with only the instance, not the schema.`,
|
|
10533
|
-
`Your entire response should be just the value of '${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}', as valid JSON.`,
|
|
10534
|
-
`And it should not be wrapped in any wrapper object -- return exactly what the JSON schema is expecting.`,
|
|
10535
|
-
`We will validate the result with the AJV Node library, using ajv.parse, against the given schema, and we expect`,
|
|
10536
|
-
`it to validate correctly.`,
|
|
10537
|
-
`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.`
|
|
10538
|
-
].join(" ");
|
|
10539
|
-
const buildSystemPrompt = (reqParams) => {
|
|
10540
|
-
let a = BASE_SYSTEM_PROMPT_WHEN_OUTPUT_TYPE_NAME_PROVIDED;
|
|
10541
|
-
a = (0, prompt_template_utils_1.replaceTemplateVarName)(a, "OUTPUT_TYPE_NAME", reqParams.output.name);
|
|
10542
|
-
return a;
|
|
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
|
|
10543
10695
|
};
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
|
|
10547
|
-
|
|
10548
|
-
|
|
10549
|
-
|
|
10550
|
-
buildSystemPrompt(reqParams),
|
|
10551
|
-
`<json-schema-spec> ${JSON.stringify(effectiveSchema)} </json-schema-spec>`,
|
|
10552
|
-
data ? `<input-data>${JSON.stringify(data)}</input-data>` : ""
|
|
10553
|
-
].join("\n");
|
|
10554
|
-
return fullPrompt;
|
|
10696
|
+
if (options.stream) {
|
|
10697
|
+
body.stream_options = { include_usage: true };
|
|
10698
|
+
}
|
|
10699
|
+
const headers = {
|
|
10700
|
+
"Content-Type": "application/json",
|
|
10701
|
+
Authorization: `Bearer ${apiKey}`
|
|
10555
10702
|
};
|
|
10556
10703
|
return {
|
|
10557
|
-
|
|
10558
|
-
|
|
10704
|
+
url: baseUrl,
|
|
10705
|
+
method: "POST",
|
|
10706
|
+
headers,
|
|
10707
|
+
body,
|
|
10708
|
+
loggableHeaders: {
|
|
10709
|
+
...headers,
|
|
10710
|
+
Authorization: "Bearer [REDACTED]"
|
|
10711
|
+
},
|
|
10712
|
+
loggableBody: body
|
|
10559
10713
|
};
|
|
10560
|
-
}
|
|
10561
|
-
|
|
10562
|
-
|
|
10563
|
-
|
|
10564
|
-
}
|
|
10565
|
-
|
|
10566
|
-
var nuaErrors = {};
|
|
10567
|
-
|
|
10568
|
-
var hasRequiredNuaErrors;
|
|
10569
|
-
function requireNuaErrors() {
|
|
10570
|
-
if (hasRequiredNuaErrors) return nuaErrors;
|
|
10571
|
-
hasRequiredNuaErrors = 1;
|
|
10572
|
-
Object.defineProperty(nuaErrors, "__esModule", { value: true });
|
|
10573
|
-
nuaErrors.isNuaError = nuaErrors.isNuaInternalError = nuaErrors.isNuaValidationError = void 0;
|
|
10574
|
-
const isNuaValidationError = (a) => {
|
|
10575
|
-
return typeof a == "object" && a != null && "kind" in a && a.kind == "validation-error";
|
|
10576
|
-
};
|
|
10577
|
-
nuaErrors.isNuaValidationError = isNuaValidationError;
|
|
10578
|
-
const isNuaInternalError = (a) => {
|
|
10579
|
-
return typeof a == "object" && a != null && "kind" in a && a.kind == "internal-error";
|
|
10580
|
-
};
|
|
10581
|
-
nuaErrors.isNuaInternalError = isNuaInternalError;
|
|
10582
|
-
const isNuaError = (a) => {
|
|
10583
|
-
return typeof a == "object" && a != null && "kind" in a && (a.kind == "internal-error" || a.kind == "validation-error");
|
|
10584
|
-
};
|
|
10585
|
-
nuaErrors.isNuaError = isNuaError;
|
|
10586
|
-
return nuaErrors;
|
|
10587
|
-
}
|
|
10588
|
-
|
|
10589
|
-
var agentLoop = {};
|
|
10590
|
-
|
|
10591
|
-
var hasRequiredAgentLoop;
|
|
10592
|
-
function requireAgentLoop() {
|
|
10593
|
-
if (hasRequiredAgentLoop) return agentLoop;
|
|
10594
|
-
hasRequiredAgentLoop = 1;
|
|
10595
|
-
Object.defineProperty(agentLoop, "__esModule", { value: true });
|
|
10596
|
-
agentLoop.runAgentLoop = runAgentLoop;
|
|
10597
|
-
const provider_config_1 = requireProviderConfig();
|
|
10598
|
-
function safeEmit(onEvent, event) {
|
|
10599
|
-
if (!onEvent)
|
|
10600
|
-
return;
|
|
10714
|
+
}
|
|
10715
|
+
function parseOpenAiToolArguments(rawArguments, toolName, errorLabel) {
|
|
10716
|
+
if (!rawArguments.trim()) {
|
|
10717
|
+
return {};
|
|
10718
|
+
}
|
|
10719
|
+
let parsed;
|
|
10601
10720
|
try {
|
|
10602
|
-
|
|
10721
|
+
parsed = JSON.parse(rawArguments);
|
|
10603
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`);
|
|
10604
10728
|
}
|
|
10729
|
+
return parsed;
|
|
10605
10730
|
}
|
|
10606
|
-
async function
|
|
10607
|
-
|
|
10608
|
-
|
|
10609
|
-
const toolsByName = new Map(params.tools.map((tool) => [tool.name, tool]));
|
|
10610
|
-
let completionReason = "max_turns";
|
|
10611
|
-
const onEvent = params.onEvent;
|
|
10612
|
-
for (let turn = 0; turn < params.maxTurns; turn++) {
|
|
10613
|
-
safeEmit(onEvent, { type: "turn_start", turn });
|
|
10614
|
-
let response;
|
|
10731
|
+
async function parseOpenAiAgenticResponse(response, errorLabel) {
|
|
10732
|
+
if (response.status !== 200) {
|
|
10733
|
+
const errorBody = await response.text();
|
|
10615
10734
|
try {
|
|
10616
|
-
|
|
10617
|
-
|
|
10618
|
-
|
|
10619
|
-
|
|
10620
|
-
|
|
10735
|
+
const parsed = JSON.parse(errorBody);
|
|
10736
|
+
const message = parsed?.error?.message || errorBody;
|
|
10737
|
+
throw new Error(`${errorLabel} API error: ${response.status} - ${message}`);
|
|
10738
|
+
} catch (e) {
|
|
10739
|
+
if (e instanceof Error && e.message.startsWith(`${errorLabel} API error:`))
|
|
10740
|
+
throw e;
|
|
10741
|
+
throw new Error(`${errorLabel} API error: ${response.status} - ${errorBody}`);
|
|
10621
10742
|
}
|
|
10622
|
-
|
|
10623
|
-
|
|
10624
|
-
|
|
10625
|
-
|
|
10626
|
-
|
|
10627
|
-
|
|
10628
|
-
|
|
10743
|
+
}
|
|
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)}`);
|
|
10748
|
+
}
|
|
10749
|
+
const contentBlocks = [];
|
|
10750
|
+
const assistantText = (0, provider_config_1.extractOpenAiMessageText)(choice.message);
|
|
10751
|
+
if (assistantText) {
|
|
10752
|
+
contentBlocks.push({
|
|
10753
|
+
type: "text",
|
|
10754
|
+
text: assistantText
|
|
10629
10755
|
});
|
|
10630
|
-
|
|
10631
|
-
|
|
10632
|
-
|
|
10633
|
-
|
|
10634
|
-
|
|
10635
|
-
|
|
10636
|
-
|
|
10637
|
-
|
|
10638
|
-
toolCallId: toolCall.id,
|
|
10639
|
-
toolName: toolCall.name,
|
|
10640
|
-
arguments: toolCall.arguments
|
|
10756
|
+
}
|
|
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)
|
|
10641
10764
|
});
|
|
10642
|
-
|
|
10643
|
-
|
|
10644
|
-
|
|
10645
|
-
|
|
10646
|
-
|
|
10647
|
-
|
|
10648
|
-
|
|
10649
|
-
|
|
10650
|
-
|
|
10651
|
-
|
|
10652
|
-
|
|
10653
|
-
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10765
|
+
}
|
|
10766
|
+
}
|
|
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";
|
|
10769
|
+
return {
|
|
10770
|
+
message: {
|
|
10771
|
+
role: "assistant",
|
|
10772
|
+
content: contentBlocks
|
|
10773
|
+
},
|
|
10774
|
+
usage,
|
|
10775
|
+
stopReason
|
|
10776
|
+
};
|
|
10777
|
+
}
|
|
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 }]
|
|
10660
10786
|
});
|
|
10661
|
-
|
|
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;
|
|
10662
10804
|
}
|
|
10663
|
-
|
|
10664
|
-
|
|
10665
|
-
|
|
10666
|
-
|
|
10667
|
-
|
|
10668
|
-
|
|
10669
|
-
|
|
10670
|
-
|
|
10671
|
-
|
|
10672
|
-
|
|
10673
|
-
|
|
10674
|
-
toolCallId: toolCall.id,
|
|
10675
|
-
toolName: toolCall.name,
|
|
10676
|
-
result
|
|
10677
|
-
});
|
|
10678
|
-
} catch (error) {
|
|
10679
|
-
const errorContent = `Tool execution error: ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
10680
|
-
const result = { content: errorContent, isError: true };
|
|
10681
|
-
messages.push({
|
|
10682
|
-
role: "toolResult",
|
|
10683
|
-
toolCallId: toolCall.id,
|
|
10684
|
-
toolName: toolCall.name,
|
|
10685
|
-
content: errorContent,
|
|
10686
|
-
isError: true
|
|
10687
|
-
});
|
|
10688
|
-
safeEmit(onEvent, {
|
|
10689
|
-
type: "tool_complete",
|
|
10690
|
-
toolCallId: toolCall.id,
|
|
10691
|
-
toolName: toolCall.name,
|
|
10692
|
-
result
|
|
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
|
+
]
|
|
10693
10816
|
});
|
|
10817
|
+
break;
|
|
10694
10818
|
}
|
|
10695
10819
|
}
|
|
10696
10820
|
}
|
|
10697
|
-
return
|
|
10821
|
+
return result;
|
|
10698
10822
|
}
|
|
10699
|
-
function
|
|
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
|
+
}))
|
|
10833
|
+
}
|
|
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
|
|
10843
|
+
}
|
|
10844
|
+
};
|
|
10845
|
+
if (tools.length > 0) {
|
|
10846
|
+
body.tools = tools;
|
|
10847
|
+
}
|
|
10848
|
+
if (options.systemPrompt) {
|
|
10849
|
+
body.systemInstruction = {
|
|
10850
|
+
parts: [{ text: options.systemPrompt }]
|
|
10851
|
+
};
|
|
10852
|
+
}
|
|
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}`;
|
|
10700
10856
|
return {
|
|
10701
|
-
|
|
10702
|
-
|
|
10703
|
-
|
|
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
|
|
10704
10865
|
};
|
|
10705
10866
|
}
|
|
10706
|
-
function
|
|
10707
|
-
|
|
10708
|
-
|
|
10709
|
-
|
|
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
|
+
}
|
|
10710
10879
|
}
|
|
10711
|
-
const
|
|
10712
|
-
|
|
10713
|
-
|
|
10714
|
-
|
|
10715
|
-
|
|
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";
|
|
10716
10903
|
return {
|
|
10717
|
-
|
|
10718
|
-
|
|
10719
|
-
|
|
10720
|
-
|
|
10904
|
+
message: {
|
|
10905
|
+
role: "assistant",
|
|
10906
|
+
content: contentBlocks
|
|
10907
|
+
},
|
|
10721
10908
|
usage,
|
|
10722
|
-
|
|
10909
|
+
stopReason
|
|
10723
10910
|
};
|
|
10724
10911
|
}
|
|
10725
|
-
|
|
10726
|
-
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
|
|
10731
|
-
|
|
10732
|
-
|
|
10733
|
-
|
|
10734
|
-
|
|
10735
|
-
|
|
10736
|
-
|
|
10737
|
-
|
|
10738
|
-
|
|
10739
|
-
|
|
10740
|
-
|
|
10741
|
-
|
|
10742
|
-
|
|
10743
|
-
|
|
10744
|
-
|
|
10745
|
-
const cast_prompt_builder_1 = __importDefault(requireCastPromptBuilder());
|
|
10746
|
-
const nua_errors_1 = requireNuaErrors();
|
|
10747
|
-
const agent_loop_1 = requireAgentLoop();
|
|
10748
|
-
class NuaLlmClient {
|
|
10749
|
-
constructor(config) {
|
|
10750
|
-
this.logger = config.logger || new logger_1.ConsoleLogger();
|
|
10751
|
-
this.clients = /* @__PURE__ */ new Map();
|
|
10752
|
-
Object.entries(config.providers).forEach(([providerId, providerConfig]) => {
|
|
10753
|
-
if (providerConfig?.apiKey) {
|
|
10754
|
-
this.clients.set(providerId, new http_llm_client_1.HttpLlmClient(providerId, providerConfig.apiKey, this.logger));
|
|
10755
|
-
}
|
|
10756
|
-
});
|
|
10912
|
+
function safeEmit(onEvent, event) {
|
|
10913
|
+
if (!onEvent)
|
|
10914
|
+
return;
|
|
10915
|
+
try {
|
|
10916
|
+
onEvent(event);
|
|
10917
|
+
} catch {
|
|
10918
|
+
}
|
|
10919
|
+
}
|
|
10920
|
+
async function streamOpenAiAgenticResponse(response, errorLabel, onEvent) {
|
|
10921
|
+
if (response.status !== 200) {
|
|
10922
|
+
const errorBody = await response.text();
|
|
10923
|
+
try {
|
|
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}`);
|
|
10931
|
+
}
|
|
10757
10932
|
}
|
|
10758
|
-
|
|
10759
|
-
|
|
10933
|
+
if (!response.body) {
|
|
10934
|
+
throw new Error(`${errorLabel} API error: Response body is null`);
|
|
10760
10935
|
}
|
|
10761
|
-
|
|
10762
|
-
|
|
10763
|
-
|
|
10764
|
-
|
|
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;
|
|
10946
|
+
}
|
|
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
|
+
}
|
|
10977
|
+
}
|
|
10765
10978
|
}
|
|
10766
|
-
return result;
|
|
10767
10979
|
}
|
|
10768
|
-
|
|
10769
|
-
|
|
10770
|
-
|
|
10771
|
-
throw new Error(`LLM provider ${provider} is not configured. Please check your API keys.`);
|
|
10772
|
-
}
|
|
10773
|
-
return client;
|
|
10980
|
+
const contentBlocks = [];
|
|
10981
|
+
if (textContent) {
|
|
10982
|
+
contentBlocks.push({ type: "text", text: textContent });
|
|
10774
10983
|
}
|
|
10775
|
-
|
|
10776
|
-
|
|
10777
|
-
|
|
10778
|
-
|
|
10779
|
-
|
|
10780
|
-
|
|
10781
|
-
|
|
10782
|
-
|
|
10783
|
-
const result = await (0, call_llm_service_1.callLLM)(
|
|
10784
|
-
client,
|
|
10785
|
-
prompt,
|
|
10786
|
-
providerModel.model,
|
|
10787
|
-
maxTokens,
|
|
10788
|
-
temperature,
|
|
10789
|
-
3,
|
|
10790
|
-
// default retries
|
|
10791
|
-
validationFn
|
|
10792
|
-
);
|
|
10793
|
-
return {
|
|
10794
|
-
success: true,
|
|
10795
|
-
data: result.data,
|
|
10796
|
-
usage: result.usage,
|
|
10797
|
-
prompt
|
|
10798
|
-
};
|
|
10799
|
-
} catch (e) {
|
|
10800
|
-
return {
|
|
10801
|
-
success: false,
|
|
10802
|
-
error: e instanceof Error ? e.message : String(e),
|
|
10803
|
-
prompt
|
|
10804
|
-
};
|
|
10805
|
-
}
|
|
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)
|
|
10991
|
+
});
|
|
10806
10992
|
}
|
|
10807
|
-
|
|
10808
|
-
|
|
10809
|
-
|
|
10810
|
-
|
|
10811
|
-
|
|
10812
|
-
|
|
10813
|
-
|
|
10814
|
-
|
|
10815
|
-
|
|
10816
|
-
|
|
10817
|
-
};
|
|
10818
|
-
}
|
|
10819
|
-
const prompt = cast_array_prompt_builder_1.default.buildFullPrompt(params, validData);
|
|
10820
|
-
const validationFn = (0, nua_json_schema_value_validation_1.buildNuaJsonSchemaValueValidation)("library-req", params.output.effectiveSchema);
|
|
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();
|
|
10821
11003
|
try {
|
|
10822
|
-
const
|
|
10823
|
-
|
|
10824
|
-
|
|
10825
|
-
data: result.data,
|
|
10826
|
-
usage: result.usage,
|
|
10827
|
-
prompt
|
|
10828
|
-
};
|
|
11004
|
+
const parsed = JSON.parse(errorBody);
|
|
11005
|
+
const message = parsed?.error?.message || errorBody;
|
|
11006
|
+
throw new Error(`Gemini API error: ${response.status} - ${message}`);
|
|
10829
11007
|
} catch (e) {
|
|
10830
|
-
|
|
10831
|
-
|
|
10832
|
-
|
|
10833
|
-
prompt
|
|
10834
|
-
};
|
|
11008
|
+
if (e instanceof Error && e.message.startsWith("Gemini API error:"))
|
|
11009
|
+
throw e;
|
|
11010
|
+
throw new Error(`Gemini API error: ${response.status} - ${errorBody}`);
|
|
10835
11011
|
}
|
|
10836
11012
|
}
|
|
10837
|
-
|
|
11013
|
+
if (!response.body) {
|
|
11014
|
+
throw new Error("Gemini API error: Response body is null");
|
|
11015
|
+
}
|
|
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;
|
|
10838
11022
|
try {
|
|
10839
|
-
|
|
10840
|
-
|
|
10841
|
-
|
|
10842
|
-
|
|
10843
|
-
|
|
10844
|
-
|
|
10845
|
-
|
|
10846
|
-
|
|
10847
|
-
|
|
10848
|
-
|
|
10849
|
-
|
|
10850
|
-
|
|
10851
|
-
|
|
10852
|
-
|
|
10853
|
-
|
|
10854
|
-
|
|
10855
|
-
|
|
10856
|
-
|
|
10857
|
-
|
|
10858
|
-
|
|
11023
|
+
chunk = JSON.parse(data);
|
|
11024
|
+
} catch {
|
|
11025
|
+
continue;
|
|
11026
|
+
}
|
|
11027
|
+
if (chunk.usageMetadata) {
|
|
11028
|
+
usage2 = (0, provider_config_1.normalizeGeminiUsage)(chunk.usageMetadata);
|
|
11029
|
+
}
|
|
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
|
+
}
|
|
10859
11047
|
}
|
|
10860
11048
|
}
|
|
10861
|
-
|
|
10862
|
-
|
|
10863
|
-
return nuaLlmClient;
|
|
10864
|
-
}
|
|
10865
|
-
|
|
10866
|
-
var types = {};
|
|
10867
|
-
|
|
10868
|
-
var hasRequiredTypes;
|
|
10869
|
-
function requireTypes() {
|
|
10870
|
-
if (hasRequiredTypes) return types;
|
|
10871
|
-
hasRequiredTypes = 1;
|
|
10872
|
-
Object.defineProperty(types, "__esModule", { value: true });
|
|
10873
|
-
return types;
|
|
10874
|
-
}
|
|
10875
|
-
|
|
10876
|
-
var validateJsonSchema = {};
|
|
10877
|
-
|
|
10878
|
-
var errorUtils = {};
|
|
10879
|
-
|
|
10880
|
-
var hasRequiredErrorUtils;
|
|
10881
|
-
function requireErrorUtils() {
|
|
10882
|
-
if (hasRequiredErrorUtils) return errorUtils;
|
|
10883
|
-
hasRequiredErrorUtils = 1;
|
|
10884
|
-
Object.defineProperty(errorUtils, "__esModule", { value: true });
|
|
10885
|
-
errorUtils.getErrorMessageFromException = getErrorMessageFromException;
|
|
10886
|
-
function isErrorWithMessage(error) {
|
|
10887
|
-
return typeof error === "object" && error !== null && "message" in error && typeof error.message === "string";
|
|
10888
|
-
}
|
|
10889
|
-
function getErrorMessageFromException(error) {
|
|
10890
|
-
if (isErrorWithMessage(error)) {
|
|
10891
|
-
return error.message;
|
|
11049
|
+
if (textContent2) {
|
|
11050
|
+
contentBlocks.unshift({ type: "text", text: textContent2 });
|
|
10892
11051
|
}
|
|
10893
|
-
|
|
11052
|
+
const stopReason3 = hasToolCalls2 ? "tool_use" : "stop";
|
|
11053
|
+
return {
|
|
11054
|
+
message: { role: "assistant", content: contentBlocks },
|
|
11055
|
+
usage: usage2,
|
|
11056
|
+
stopReason: stopReason3
|
|
11057
|
+
};
|
|
10894
11058
|
}
|
|
10895
|
-
return
|
|
11059
|
+
return providerFormatters;
|
|
10896
11060
|
}
|
|
10897
11061
|
|
|
10898
|
-
var
|
|
10899
|
-
function
|
|
10900
|
-
if (
|
|
10901
|
-
|
|
10902
|
-
Object.defineProperty(
|
|
10903
|
-
|
|
10904
|
-
const
|
|
10905
|
-
const
|
|
10906
|
-
const
|
|
10907
|
-
|
|
10908
|
-
|
|
10909
|
-
|
|
10910
|
-
|
|
10911
|
-
|
|
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);
|
|
10912
11092
|
}
|
|
10913
|
-
|
|
10914
|
-
|
|
10915
|
-
|
|
10916
|
-
|
|
10917
|
-
|
|
10918
|
-
|
|
10919
|
-
|
|
10920
|
-
|
|
10921
|
-
return
|
|
10922
|
-
|
|
10923
|
-
|
|
10924
|
-
|
|
10925
|
-
|
|
10926
|
-
|
|
11093
|
+
return call.reply;
|
|
11094
|
+
}
|
|
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
|
+
};
|
|
10927
11110
|
}
|
|
11111
|
+
}
|
|
11112
|
+
function openAiStyleCodec(url, apiKey, errorLabel) {
|
|
10928
11113
|
return {
|
|
10929
|
-
|
|
10930
|
-
|
|
10931
|
-
|
|
10932
|
-
};
|
|
10933
|
-
validateJsonSchema.validateJsonSchema = validateJsonSchema$1;
|
|
10934
|
-
return validateJsonSchema;
|
|
10935
|
-
}
|
|
10936
|
-
|
|
10937
|
-
var stableStringify = {};
|
|
10938
|
-
|
|
10939
|
-
var hasRequiredStableStringify;
|
|
10940
|
-
function requireStableStringify() {
|
|
10941
|
-
if (hasRequiredStableStringify) return stableStringify;
|
|
10942
|
-
hasRequiredStableStringify = 1;
|
|
10943
|
-
Object.defineProperty(stableStringify, "__esModule", { value: true });
|
|
10944
|
-
stableStringify.stableStringify = stableStringify$1;
|
|
10945
|
-
function stableStringify$1(value) {
|
|
10946
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
10947
|
-
const sorter = (_key, currentValue) => {
|
|
10948
|
-
if (currentValue && typeof currentValue === "object" && !Array.isArray(currentValue)) {
|
|
10949
|
-
if (seen.has(currentValue)) {
|
|
10950
|
-
return currentValue;
|
|
10951
|
-
}
|
|
10952
|
-
seen.add(currentValue);
|
|
10953
|
-
return Object.keys(currentValue).sort().reduce((acc, key) => {
|
|
10954
|
-
acc[key] = currentValue[key];
|
|
10955
|
-
return acc;
|
|
10956
|
-
}, {});
|
|
10957
|
-
}
|
|
10958
|
-
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)
|
|
10959
11117
|
};
|
|
10960
|
-
return JSON.stringify(value, sorter) ?? "";
|
|
10961
11118
|
}
|
|
10962
|
-
return
|
|
11119
|
+
return agentTurn;
|
|
10963
11120
|
}
|
|
10964
11121
|
|
|
10965
|
-
var
|
|
10966
|
-
|
|
10967
|
-
|
|
10968
|
-
|
|
10969
|
-
|
|
10970
|
-
|
|
10971
|
-
|
|
10972
|
-
|
|
10973
|
-
|
|
10974
|
-
|
|
10975
|
-
|
|
10976
|
-
|
|
10977
|
-
const
|
|
10978
|
-
|
|
10979
|
-
|
|
10980
|
-
|
|
10981
|
-
|
|
10982
|
-
|
|
10983
|
-
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
[outputName]: schema
|
|
10987
|
-
}
|
|
10988
|
-
}
|
|
10989
|
-
};
|
|
10990
|
-
if (schemaVersion) {
|
|
10991
|
-
wrappedSchema.$schema = schemaVersion;
|
|
10992
|
-
}
|
|
10993
|
-
return wrappedSchema;
|
|
10994
|
-
}
|
|
10995
|
-
function unwrapArraySchema(wrappedSchema, outputName) {
|
|
10996
|
-
const items = wrappedSchema.items;
|
|
10997
|
-
if (!items || typeof items !== "object") {
|
|
10998
|
-
return null;
|
|
10999
|
-
}
|
|
11000
|
-
const properties = items.properties;
|
|
11001
|
-
if (!properties || typeof properties !== "object") {
|
|
11002
|
-
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
|
+
};
|
|
11003
11143
|
}
|
|
11004
|
-
|
|
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
|
+
});
|
|
11005
11153
|
}
|
|
11006
|
-
return
|
|
11154
|
+
return runAgent;
|
|
11007
11155
|
}
|
|
11008
11156
|
|
|
11009
11157
|
var hasRequiredDist;
|
|
@@ -11027,23 +11175,12 @@ function requireDist() {
|
|
|
11027
11175
|
var __exportStar = dist && dist.__exportStar || function(m, exports2) {
|
|
11028
11176
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p)) __createBinding(exports2, m, p);
|
|
11029
11177
|
};
|
|
11030
|
-
var __importDefault = dist && dist.__importDefault || function(mod) {
|
|
11031
|
-
return mod && mod.__esModule ? mod : { "default": mod };
|
|
11032
|
-
};
|
|
11033
11178
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
11034
|
-
exports$1.runAgentLoop = 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;
|
|
11035
11180
|
__exportStar(requireNuaLlmClient(), exports$1);
|
|
11036
|
-
__exportStar(requireLogger(), exports$1);
|
|
11181
|
+
__exportStar(logger.requireLogger(), exports$1);
|
|
11037
11182
|
__exportStar(requireTypes(), exports$1);
|
|
11038
11183
|
__exportStar(requireNuaErrors(), exports$1);
|
|
11039
|
-
var cast_prompt_builder_1 = requireCastPromptBuilder();
|
|
11040
|
-
Object.defineProperty(exports$1, "castPromptBuilder", { enumerable: true, get: function() {
|
|
11041
|
-
return __importDefault(cast_prompt_builder_1).default;
|
|
11042
|
-
} });
|
|
11043
|
-
var cast_array_prompt_builder_1 = requireCastArrayPromptBuilder();
|
|
11044
|
-
Object.defineProperty(exports$1, "castArrayPromptBuilder", { enumerable: true, get: function() {
|
|
11045
|
-
return __importDefault(cast_array_prompt_builder_1).default;
|
|
11046
|
-
} });
|
|
11047
11184
|
var provider_config_1 = requireProviderConfig();
|
|
11048
11185
|
Object.defineProperty(exports$1, "LLM_PROVIDER_IDS", { enumerable: true, get: function() {
|
|
11049
11186
|
return provider_config_1.LLM_PROVIDER_IDS;
|
|
@@ -11054,6 +11191,10 @@ function requireDist() {
|
|
|
11054
11191
|
Object.defineProperty(exports$1, "providerConfigs", { enumerable: true, get: function() {
|
|
11055
11192
|
return provider_config_1.providerConfigs;
|
|
11056
11193
|
} });
|
|
11194
|
+
var provider_engines_1 = requireProviderEngines();
|
|
11195
|
+
Object.defineProperty(exports$1, "providerEngines", { enumerable: true, get: function() {
|
|
11196
|
+
return provider_engines_1.providerEngines;
|
|
11197
|
+
} });
|
|
11057
11198
|
var validate_json_schema_1 = requireValidateJsonSchema();
|
|
11058
11199
|
Object.defineProperty(exports$1, "validateJsonSchema", { enumerable: true, get: function() {
|
|
11059
11200
|
return validate_json_schema_1.validateJsonSchema;
|
|
@@ -11064,6 +11205,17 @@ function requireDist() {
|
|
|
11064
11205
|
} });
|
|
11065
11206
|
__exportStar(requireModelInfo(), exports$1);
|
|
11066
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
|
+
} });
|
|
11067
11219
|
var agent_loop_1 = requireAgentLoop();
|
|
11068
11220
|
Object.defineProperty(exports$1, "runAgentLoop", { enumerable: true, get: function() {
|
|
11069
11221
|
return agent_loop_1.runAgentLoop;
|
|
@@ -11074,80 +11226,59 @@ function requireDist() {
|
|
|
11074
11226
|
|
|
11075
11227
|
var distExports = requireDist();
|
|
11076
11228
|
|
|
11077
|
-
const normalizedUsageZero = {
|
|
11078
|
-
promptTokens: 0,
|
|
11079
|
-
completionTokens: 0,
|
|
11080
|
-
totalTokens: 0
|
|
11081
|
-
};
|
|
11082
11229
|
class DirectBackend {
|
|
11083
11230
|
constructor(config) {
|
|
11084
|
-
this.
|
|
11085
|
-
this.client = new distExports.NuaLlmClient({ providers: config.providers });
|
|
11231
|
+
this.client = new distExports.NuaLlmClient(enginesFor(config));
|
|
11086
11232
|
}
|
|
11087
11233
|
async castValue(params) {
|
|
11088
|
-
const model = params.model ?? this.model;
|
|
11089
11234
|
const startTime = Date.now();
|
|
11090
11235
|
const result = await this.client.castValue({
|
|
11091
|
-
model,
|
|
11236
|
+
model: params.model,
|
|
11092
11237
|
input: { prompt: params.prompt, data: params.data },
|
|
11093
|
-
output: { name: params.outputName,
|
|
11238
|
+
output: { name: params.outputName, schema: params.outputSchema }
|
|
11094
11239
|
});
|
|
11095
|
-
|
|
11096
|
-
if (!result.success) {
|
|
11097
|
-
return {
|
|
11098
|
-
success: false,
|
|
11099
|
-
error: result.error || "Unknown error",
|
|
11100
|
-
source: "direct",
|
|
11101
|
-
latencyMs
|
|
11102
|
-
};
|
|
11103
|
-
}
|
|
11104
|
-
return {
|
|
11105
|
-
success: true,
|
|
11106
|
-
data: result.data,
|
|
11107
|
-
usage: result.usage || normalizedUsageZero,
|
|
11108
|
-
model: formatModelInput(model),
|
|
11109
|
-
latencyMs,
|
|
11110
|
-
source: "direct",
|
|
11111
|
-
meta: {}
|
|
11112
|
-
};
|
|
11240
|
+
return toDirectResult(result, Date.now() - startTime);
|
|
11113
11241
|
}
|
|
11114
11242
|
async castArray(params) {
|
|
11115
|
-
const model = params.model ?? this.model;
|
|
11116
11243
|
const startTime = Date.now();
|
|
11117
|
-
const wrappedSchema = distExports.wrapArraySchema(params.outputSchema, {
|
|
11118
|
-
primaryKey: params.primaryKey,
|
|
11119
|
-
outputName: params.outputName
|
|
11120
|
-
});
|
|
11121
11244
|
const result = await this.client.castArray({
|
|
11122
|
-
model,
|
|
11123
|
-
data: params.data,
|
|
11124
|
-
|
|
11125
|
-
|
|
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
|
+
})
|
|
11126
11251
|
});
|
|
11127
|
-
|
|
11128
|
-
|
|
11129
|
-
|
|
11130
|
-
|
|
11131
|
-
|
|
11132
|
-
|
|
11133
|
-
latencyMs
|
|
11134
|
-
};
|
|
11135
|
-
}
|
|
11136
|
-
return {
|
|
11137
|
-
success: true,
|
|
11138
|
-
data: result.data,
|
|
11139
|
-
usage: result.usage || normalizedUsageZero,
|
|
11140
|
-
model: formatModelInput(model),
|
|
11141
|
-
latencyMs,
|
|
11142
|
-
source: "direct",
|
|
11143
|
-
meta: {}
|
|
11144
|
-
};
|
|
11252
|
+
return toDirectResult(result, Date.now() - startTime);
|
|
11253
|
+
}
|
|
11254
|
+
}
|
|
11255
|
+
function enginesFor(config) {
|
|
11256
|
+
if (config.localAgent) {
|
|
11257
|
+
return config.localAgent;
|
|
11145
11258
|
}
|
|
11259
|
+
return distExports.providerEngines({ providers: config.providers, model: config.model });
|
|
11146
11260
|
}
|
|
11147
|
-
function
|
|
11148
|
-
if (!
|
|
11149
|
-
|
|
11150
|
-
|
|
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"}`;
|
|
11281
|
+
}
|
|
11151
11282
|
}
|
|
11152
11283
|
|
|
11153
11284
|
function resolveConfigValue(config, key, envVar) {
|
|
@@ -11397,6 +11528,11 @@ class Nua {
|
|
|
11397
11528
|
static gateway(config) {
|
|
11398
11529
|
return new Nua(new GatewayBackend(config));
|
|
11399
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
|
+
*/
|
|
11400
11536
|
static direct(config) {
|
|
11401
11537
|
return new Nua(new DirectBackend(config));
|
|
11402
11538
|
}
|