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