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