nuabase 2.2.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +864 -96
- package/dist/esm/index.mjs +864 -95
- package/dist/types/backend/gateway.d.ts +1 -0
- package/dist/types/backend/types.d.ts +2 -0
- package/dist/types/lib/auth.d.ts +2 -0
- package/dist/types/nua.d.ts +2 -0
- package/package.json +1 -1
package/dist/esm/index.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { createRequire } from 'node:module';
|
|
2
1
|
import require$$0 from 'ajv';
|
|
3
|
-
import require$$1 from 'ajv/dist/2019';
|
|
4
|
-
import require$$2 from 'ajv/dist/2020';
|
|
2
|
+
import require$$1 from 'ajv/dist/2019.js';
|
|
3
|
+
import require$$2 from 'ajv/dist/2020.js';
|
|
5
4
|
import require$$3 from 'ajv/dist/refs/json-schema-draft-07.json';
|
|
6
5
|
import require$$4 from 'ajv/dist/refs/json-schema-draft-06.json';
|
|
7
6
|
import { z } from 'zod';
|
|
@@ -13,9 +12,6 @@ var nuaLlmClient = {};
|
|
|
13
12
|
|
|
14
13
|
var logger = {};
|
|
15
14
|
|
|
16
|
-
const require$1 = createRequire(import.meta.url);
|
|
17
|
-
function __require() { return require$1("node:crypto"); }
|
|
18
|
-
|
|
19
15
|
var hasRequiredLogger;
|
|
20
16
|
function requireLogger() {
|
|
21
17
|
if (hasRequiredLogger) return logger;
|
|
@@ -25,7 +21,6 @@ function requireLogger() {
|
|
|
25
21
|
logger.truncateText = truncateText;
|
|
26
22
|
logger.pickHeaders = pickHeaders;
|
|
27
23
|
logger.normalizeError = normalizeError;
|
|
28
|
-
const node_crypto_1 = __require();
|
|
29
24
|
class ConsoleLogger {
|
|
30
25
|
debug(message, context) {
|
|
31
26
|
console.debug(`[DEBUG] ${message}`, context || "");
|
|
@@ -41,7 +36,7 @@ function requireLogger() {
|
|
|
41
36
|
}
|
|
42
37
|
}
|
|
43
38
|
logger.ConsoleLogger = ConsoleLogger;
|
|
44
|
-
const generateSpanId = () =>
|
|
39
|
+
const generateSpanId = () => crypto.randomUUID();
|
|
45
40
|
logger.generateSpanId = generateSpanId;
|
|
46
41
|
function truncateText(text, limit = 500) {
|
|
47
42
|
const length = text.length;
|
|
@@ -279,8 +274,8 @@ function requireAjvInstances() {
|
|
|
279
274
|
Object.defineProperty(ajvInstances, "__esModule", { value: true });
|
|
280
275
|
ajvInstances.ajvInstances = void 0;
|
|
281
276
|
const ajv_1 = __importDefault(require$$0);
|
|
282
|
-
const
|
|
283
|
-
const
|
|
277
|
+
const _2019_js_1 = __importDefault(require$$1);
|
|
278
|
+
const _2020_js_1 = __importDefault(require$$2);
|
|
284
279
|
const json_schema_draft_07_json_1 = __importDefault(require$$3);
|
|
285
280
|
const json_schema_draft_06_json_1 = __importDefault(require$$4);
|
|
286
281
|
const ajvOptions = {
|
|
@@ -293,10 +288,10 @@ function requireAjvInstances() {
|
|
|
293
288
|
class AjvInstances {
|
|
294
289
|
constructor() {
|
|
295
290
|
this.draft07 = new ajv_1.default(ajvOptions);
|
|
296
|
-
this.draft2019 = new
|
|
291
|
+
this.draft2019 = new _2019_js_1.default(ajvOptions);
|
|
297
292
|
this.draft2019.addMetaSchema(json_schema_draft_07_json_1.default);
|
|
298
293
|
this.draft2019.addMetaSchema(json_schema_draft_06_json_1.default);
|
|
299
|
-
this.draft2020 = new
|
|
294
|
+
this.draft2020 = new _2020_js_1.default(ajvOptions);
|
|
300
295
|
}
|
|
301
296
|
getInstanceForSchema(schema) {
|
|
302
297
|
const schemaVersion = schema.$schema;
|
|
@@ -360,17 +355,15 @@ function requireModelInfo() {
|
|
|
360
355
|
exports$1.parseCanonicalModelName = parseCanonicalModelName;
|
|
361
356
|
exports$1.CANONICAL_MODELS = [
|
|
362
357
|
"qwen3-30b-a3b-instruct-2507",
|
|
363
|
-
"claude-sonnet-4-
|
|
358
|
+
"claude-sonnet-4-6",
|
|
364
359
|
"qwen3-vl-235b-a22b-instruct",
|
|
365
360
|
"qwen3-max",
|
|
366
361
|
"gpt-5",
|
|
367
|
-
"gemini-2.5-flash-lite
|
|
362
|
+
"gemini-2.5-flash-lite",
|
|
363
|
+
"gemini-2.5-flash",
|
|
368
364
|
"qwen3-coder-flash",
|
|
369
365
|
"gpt-oss-120b",
|
|
370
|
-
"
|
|
371
|
-
"gpt-4o",
|
|
372
|
-
"llama-3.3-70b",
|
|
373
|
-
"gemini-2.0-flash"
|
|
366
|
+
"kimi-k2.5"
|
|
374
367
|
];
|
|
375
368
|
const CANONICAL_SET = new Set(exports$1.CANONICAL_MODELS);
|
|
376
369
|
exports$1.SUPPORTED_MODELS = {
|
|
@@ -379,6 +372,10 @@ function requireModelInfo() {
|
|
|
379
372
|
provider: "cerebras",
|
|
380
373
|
providerModelName: "gpt-oss-120b"
|
|
381
374
|
},
|
|
375
|
+
{
|
|
376
|
+
provider: "groq",
|
|
377
|
+
providerModelName: "openai/gpt-oss-120b"
|
|
378
|
+
},
|
|
382
379
|
{
|
|
383
380
|
provider: "openrouter",
|
|
384
381
|
providerModelName: "openai/gpt-oss-120b"
|
|
@@ -390,10 +387,10 @@ function requireModelInfo() {
|
|
|
390
387
|
providerModelName: "qwen/qwen3-30b-a3b-instruct-2507"
|
|
391
388
|
}
|
|
392
389
|
],
|
|
393
|
-
"claude-sonnet-4-
|
|
390
|
+
"claude-sonnet-4-6": [
|
|
394
391
|
{
|
|
395
392
|
provider: "openrouter",
|
|
396
|
-
providerModelName: "anthropic/claude-sonnet-4.
|
|
393
|
+
providerModelName: "anthropic/claude-sonnet-4.6"
|
|
397
394
|
}
|
|
398
395
|
],
|
|
399
396
|
"qwen3-vl-235b-a22b-instruct": [
|
|
@@ -414,40 +411,36 @@ function requireModelInfo() {
|
|
|
414
411
|
providerModelName: "openai/gpt-5"
|
|
415
412
|
}
|
|
416
413
|
],
|
|
417
|
-
"gemini-2.5-flash-lite
|
|
414
|
+
"gemini-2.5-flash-lite": [
|
|
418
415
|
{
|
|
419
|
-
provider: "
|
|
420
|
-
providerModelName: "
|
|
421
|
-
}
|
|
422
|
-
],
|
|
423
|
-
"qwen3-coder-flash": [
|
|
416
|
+
provider: "gemini",
|
|
417
|
+
providerModelName: "gemini-2.5-flash-lite"
|
|
418
|
+
},
|
|
424
419
|
{
|
|
425
420
|
provider: "openrouter",
|
|
426
|
-
providerModelName: "
|
|
421
|
+
providerModelName: "google/gemini-2.5-flash-lite"
|
|
427
422
|
}
|
|
428
423
|
],
|
|
429
|
-
"
|
|
424
|
+
"gemini-2.5-flash": [
|
|
430
425
|
{
|
|
431
|
-
provider: "
|
|
432
|
-
providerModelName: "
|
|
433
|
-
}
|
|
434
|
-
],
|
|
435
|
-
"gpt-4o": [
|
|
426
|
+
provider: "gemini",
|
|
427
|
+
providerModelName: "gemini-2.5-flash"
|
|
428
|
+
},
|
|
436
429
|
{
|
|
437
430
|
provider: "openrouter",
|
|
438
|
-
providerModelName: "
|
|
431
|
+
providerModelName: "google/gemini-2.5-flash"
|
|
439
432
|
}
|
|
440
433
|
],
|
|
441
|
-
"
|
|
434
|
+
"qwen3-coder-flash": [
|
|
442
435
|
{
|
|
443
|
-
provider: "
|
|
444
|
-
providerModelName: "
|
|
436
|
+
provider: "openrouter",
|
|
437
|
+
providerModelName: "qwen/qwen3-coder-flash"
|
|
445
438
|
}
|
|
446
439
|
],
|
|
447
|
-
"
|
|
440
|
+
"kimi-k2.5": [
|
|
448
441
|
{
|
|
449
|
-
provider: "
|
|
450
|
-
providerModelName: "
|
|
442
|
+
provider: "openrouter",
|
|
443
|
+
providerModelName: "moonshotai/kimi-k2.5"
|
|
451
444
|
}
|
|
452
445
|
]
|
|
453
446
|
};
|
|
@@ -460,11 +453,14 @@ function requireModelInfo() {
|
|
|
460
453
|
case "fast":
|
|
461
454
|
m2 = "gpt-oss-120b";
|
|
462
455
|
break;
|
|
456
|
+
case "gemini":
|
|
457
|
+
m2 = "gemini-2.5-flash";
|
|
458
|
+
break;
|
|
463
459
|
case "qwen":
|
|
464
460
|
m2 = "qwen3-vl-235b-a22b-instruct";
|
|
465
461
|
break;
|
|
466
462
|
case "sonnet":
|
|
467
|
-
m2 = "claude-sonnet-4-
|
|
463
|
+
m2 = "claude-sonnet-4-6";
|
|
468
464
|
break;
|
|
469
465
|
case "gpt":
|
|
470
466
|
m2 = "gpt-5";
|
|
@@ -489,7 +485,7 @@ function requireProviderConfig() {
|
|
|
489
485
|
hasRequiredProviderConfig = 1;
|
|
490
486
|
(function(exports$1) {
|
|
491
487
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
492
|
-
exports$1.providerConfigs = exports$1.normalizedUsageZero = void 0;
|
|
488
|
+
exports$1.providerConfigs = exports$1.extractOpenAiMessageText = exports$1.normalizeGeminiUsage = exports$1.normalizeOpenAiUsage = exports$1.normalizedUsageZero = void 0;
|
|
493
489
|
exports$1.normalizedUsageZero = {
|
|
494
490
|
promptTokens: 0,
|
|
495
491
|
completionTokens: 0,
|
|
@@ -508,6 +504,7 @@ function requireProviderConfig() {
|
|
|
508
504
|
totalTokens: usage.total_tokens
|
|
509
505
|
};
|
|
510
506
|
};
|
|
507
|
+
exports$1.normalizeOpenAiUsage = normalizeOpenAiUsage;
|
|
511
508
|
const normalizeGeminiUsage = (usage) => {
|
|
512
509
|
if (!usage) {
|
|
513
510
|
return exports$1.normalizedUsageZero;
|
|
@@ -521,6 +518,7 @@ function requireProviderConfig() {
|
|
|
521
518
|
totalTokens: usage.totalTokenCount
|
|
522
519
|
};
|
|
523
520
|
};
|
|
521
|
+
exports$1.normalizeGeminiUsage = normalizeGeminiUsage;
|
|
524
522
|
const buildOpenAiStyleRequest = (baseUrl) => ({ prompt, model, maxTokens, assistantPrefillPrompt }, apiKey) => {
|
|
525
523
|
const messages = [];
|
|
526
524
|
messages.push({ role: "user", content: prompt });
|
|
@@ -555,11 +553,11 @@ function requireProviderConfig() {
|
|
|
555
553
|
const parseOpenAiStyleResponse = (errorLabel) => async (response) => {
|
|
556
554
|
if (response.status === 200) {
|
|
557
555
|
const responseBody = await response.json();
|
|
558
|
-
const responseText = responseBody.choices?.[0]?.message
|
|
556
|
+
const responseText = (0, exports$1.extractOpenAiMessageText)(responseBody.choices?.[0]?.message);
|
|
559
557
|
if (responseText) {
|
|
560
558
|
return {
|
|
561
559
|
text: responseText,
|
|
562
|
-
usage: normalizeOpenAiUsage(responseBody.usage)
|
|
560
|
+
usage: (0, exports$1.normalizeOpenAiUsage)(responseBody.usage)
|
|
563
561
|
};
|
|
564
562
|
}
|
|
565
563
|
throw new Error(`${errorLabel} API error: Could not extract text from response. Body: ${JSON.stringify(responseBody)}`);
|
|
@@ -573,22 +571,28 @@ function requireProviderConfig() {
|
|
|
573
571
|
throw new Error(`${errorLabel} API error: ${response.status} - ${errorBody}`);
|
|
574
572
|
}
|
|
575
573
|
};
|
|
574
|
+
const normalizeOpenAiText = (value) => {
|
|
575
|
+
if (typeof value !== "string") {
|
|
576
|
+
return void 0;
|
|
577
|
+
}
|
|
578
|
+
const trimmed = value.trim();
|
|
579
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
580
|
+
};
|
|
581
|
+
const extractOpenAiMessageText = (message) => {
|
|
582
|
+
if (!message) {
|
|
583
|
+
return void 0;
|
|
584
|
+
}
|
|
585
|
+
return normalizeOpenAiText(message.content) ?? normalizeOpenAiText(message.reasoning) ?? normalizeOpenAiText(message.reasoning_details?.map((detail) => typeof detail === "object" && detail !== null ? "summary" in detail ? detail.summary : void 0 : void 0).find((summary) => summary !== void 0));
|
|
586
|
+
};
|
|
587
|
+
exports$1.extractOpenAiMessageText = extractOpenAiMessageText;
|
|
576
588
|
const parseOpenAiGPT5ThinkingStyleResponse = (errorLabel) => async (response) => {
|
|
577
|
-
const normalize = (value) => {
|
|
578
|
-
if (typeof value !== "string") {
|
|
579
|
-
return void 0;
|
|
580
|
-
}
|
|
581
|
-
const trimmed = value.trim();
|
|
582
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
583
|
-
};
|
|
584
589
|
if (response.status === 200) {
|
|
585
590
|
const responseBody = await response.json();
|
|
586
|
-
const
|
|
587
|
-
const content = normalize(message?.content) ?? normalize(message?.reasoning) ?? normalize(message?.reasoning_details?.map((detail) => typeof detail === "object" && detail !== null ? "summary" in detail ? detail.summary : void 0 : void 0).find((summary) => summary !== void 0));
|
|
591
|
+
const content = (0, exports$1.extractOpenAiMessageText)(responseBody.choices?.[0]?.message);
|
|
588
592
|
if (content) {
|
|
589
593
|
return {
|
|
590
594
|
text: content,
|
|
591
|
-
usage: normalizeOpenAiUsage(responseBody.usage)
|
|
595
|
+
usage: (0, exports$1.normalizeOpenAiUsage)(responseBody.usage)
|
|
592
596
|
};
|
|
593
597
|
}
|
|
594
598
|
throw new Error(`${errorLabel} API error: Could not extract text from thinking response. Body: ${JSON.stringify(responseBody)}`);
|
|
@@ -636,7 +640,7 @@ function requireProviderConfig() {
|
|
|
636
640
|
if (responseText) {
|
|
637
641
|
return {
|
|
638
642
|
text: responseText,
|
|
639
|
-
usage: normalizeGeminiUsage(responseBody.usageMetadata)
|
|
643
|
+
usage: (0, exports$1.normalizeGeminiUsage)(responseBody.usageMetadata)
|
|
640
644
|
};
|
|
641
645
|
}
|
|
642
646
|
throw new Error(`Gemini API error: Could not extract text from response. Body: ${JSON.stringify(responseBody)}`);
|
|
@@ -684,6 +688,496 @@ function requireProviderConfig() {
|
|
|
684
688
|
return providerConfig;
|
|
685
689
|
}
|
|
686
690
|
|
|
691
|
+
var providerFormatters = {};
|
|
692
|
+
|
|
693
|
+
var sseParser = {};
|
|
694
|
+
|
|
695
|
+
var hasRequiredSseParser;
|
|
696
|
+
function requireSseParser() {
|
|
697
|
+
if (hasRequiredSseParser) return sseParser;
|
|
698
|
+
hasRequiredSseParser = 1;
|
|
699
|
+
Object.defineProperty(sseParser, "__esModule", { value: true });
|
|
700
|
+
sseParser.parseSSEStream = parseSSEStream;
|
|
701
|
+
async function* parseSSEStream(stream) {
|
|
702
|
+
const reader = stream.getReader();
|
|
703
|
+
const decoder = new TextDecoder();
|
|
704
|
+
let buffer = "";
|
|
705
|
+
try {
|
|
706
|
+
while (true) {
|
|
707
|
+
const { done, value } = await reader.read();
|
|
708
|
+
if (done)
|
|
709
|
+
break;
|
|
710
|
+
buffer += decoder.decode(value, { stream: true });
|
|
711
|
+
const parts = buffer.split(/\r?\n\r?\n/);
|
|
712
|
+
buffer = parts.pop();
|
|
713
|
+
for (const part of parts) {
|
|
714
|
+
for (const line of part.split(/\r?\n/)) {
|
|
715
|
+
if (line.startsWith("data: ")) {
|
|
716
|
+
const data = line.slice(6);
|
|
717
|
+
if (data === "[DONE]") {
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
yield data;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
if (buffer.trim()) {
|
|
726
|
+
for (const line of buffer.split(/\r?\n/)) {
|
|
727
|
+
if (line.startsWith("data: ")) {
|
|
728
|
+
const data = line.slice(6);
|
|
729
|
+
if (data === "[DONE]") {
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
yield data;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
} finally {
|
|
737
|
+
reader.releaseLock();
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
return sseParser;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
var hasRequiredProviderFormatters;
|
|
744
|
+
function requireProviderFormatters() {
|
|
745
|
+
if (hasRequiredProviderFormatters) return providerFormatters;
|
|
746
|
+
hasRequiredProviderFormatters = 1;
|
|
747
|
+
Object.defineProperty(providerFormatters, "__esModule", { value: true });
|
|
748
|
+
providerFormatters.buildOpenAiAgenticRequest = buildOpenAiAgenticRequest;
|
|
749
|
+
providerFormatters.parseOpenAiAgenticResponse = parseOpenAiAgenticResponse;
|
|
750
|
+
providerFormatters.buildGeminiAgenticRequest = buildGeminiAgenticRequest;
|
|
751
|
+
providerFormatters.parseGeminiAgenticResponse = parseGeminiAgenticResponse;
|
|
752
|
+
providerFormatters.streamOpenAiAgenticResponse = streamOpenAiAgenticResponse;
|
|
753
|
+
providerFormatters.streamGeminiAgenticResponse = streamGeminiAgenticResponse;
|
|
754
|
+
const provider_config_1 = requireProviderConfig();
|
|
755
|
+
const sse_parser_1 = requireSseParser();
|
|
756
|
+
function convertMessagesToOpenAi(messages, systemPrompt) {
|
|
757
|
+
const result = [];
|
|
758
|
+
if (systemPrompt) {
|
|
759
|
+
result.push({ role: "system", content: systemPrompt });
|
|
760
|
+
}
|
|
761
|
+
for (const msg of messages) {
|
|
762
|
+
switch (msg.role) {
|
|
763
|
+
case "user":
|
|
764
|
+
result.push({ role: "user", content: msg.content });
|
|
765
|
+
break;
|
|
766
|
+
case "assistant": {
|
|
767
|
+
const textParts = msg.content.filter((c) => c.type === "text").map((c) => c.text).join("");
|
|
768
|
+
const toolCalls = msg.content.filter((c) => c.type === "toolCall").map((c) => ({
|
|
769
|
+
id: c.id,
|
|
770
|
+
type: "function",
|
|
771
|
+
function: {
|
|
772
|
+
name: c.name,
|
|
773
|
+
arguments: JSON.stringify(c.arguments)
|
|
774
|
+
}
|
|
775
|
+
}));
|
|
776
|
+
const openAiMsg = {
|
|
777
|
+
role: "assistant",
|
|
778
|
+
content: textParts || null,
|
|
779
|
+
...toolCalls.length > 0 ? { tool_calls: toolCalls } : {}
|
|
780
|
+
};
|
|
781
|
+
result.push(openAiMsg);
|
|
782
|
+
break;
|
|
783
|
+
}
|
|
784
|
+
case "toolResult":
|
|
785
|
+
result.push({
|
|
786
|
+
role: "tool",
|
|
787
|
+
tool_call_id: msg.toolCallId,
|
|
788
|
+
content: msg.content
|
|
789
|
+
});
|
|
790
|
+
break;
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
return result;
|
|
794
|
+
}
|
|
795
|
+
function convertToolsToOpenAi(tools) {
|
|
796
|
+
return tools.map((t) => ({
|
|
797
|
+
type: "function",
|
|
798
|
+
function: {
|
|
799
|
+
name: t.name,
|
|
800
|
+
description: t.description,
|
|
801
|
+
parameters: t.parameters
|
|
802
|
+
}
|
|
803
|
+
}));
|
|
804
|
+
}
|
|
805
|
+
function buildOpenAiAgenticRequest(options, baseUrl, apiKey) {
|
|
806
|
+
const messages = convertMessagesToOpenAi(options.messages, options.systemPrompt);
|
|
807
|
+
const tools = convertToolsToOpenAi(options.tools);
|
|
808
|
+
const body = {
|
|
809
|
+
messages,
|
|
810
|
+
tools: tools.length > 0 ? tools : void 0,
|
|
811
|
+
model: options.model,
|
|
812
|
+
max_completion_tokens: options.maxTokens,
|
|
813
|
+
stream: options.stream ?? false
|
|
814
|
+
};
|
|
815
|
+
if (options.stream) {
|
|
816
|
+
body.stream_options = { include_usage: true };
|
|
817
|
+
}
|
|
818
|
+
const headers = {
|
|
819
|
+
"Content-Type": "application/json",
|
|
820
|
+
Authorization: `Bearer ${apiKey}`
|
|
821
|
+
};
|
|
822
|
+
return {
|
|
823
|
+
url: baseUrl,
|
|
824
|
+
method: "POST",
|
|
825
|
+
headers,
|
|
826
|
+
body,
|
|
827
|
+
loggableHeaders: {
|
|
828
|
+
...headers,
|
|
829
|
+
Authorization: "Bearer [REDACTED]"
|
|
830
|
+
},
|
|
831
|
+
loggableBody: body
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
function parseOpenAiToolArguments(rawArguments, toolName, errorLabel) {
|
|
835
|
+
if (!rawArguments.trim()) {
|
|
836
|
+
return {};
|
|
837
|
+
}
|
|
838
|
+
let parsed;
|
|
839
|
+
try {
|
|
840
|
+
parsed = JSON.parse(rawArguments);
|
|
841
|
+
} catch {
|
|
842
|
+
const preview = rawArguments.length > 500 ? rawArguments.slice(0, 500) + "..." : rawArguments;
|
|
843
|
+
throw new Error(`${errorLabel} API error: Invalid JSON arguments for tool "${toolName}": ${preview}`);
|
|
844
|
+
}
|
|
845
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
846
|
+
throw new Error(`${errorLabel} API error: Tool "${toolName}" arguments must be a JSON object`);
|
|
847
|
+
}
|
|
848
|
+
return parsed;
|
|
849
|
+
}
|
|
850
|
+
async function parseOpenAiAgenticResponse(response, errorLabel) {
|
|
851
|
+
if (response.status !== 200) {
|
|
852
|
+
const errorBody = await response.text();
|
|
853
|
+
try {
|
|
854
|
+
const parsed = JSON.parse(errorBody);
|
|
855
|
+
const message = parsed?.error?.message || errorBody;
|
|
856
|
+
throw new Error(`${errorLabel} API error: ${response.status} - ${message}`);
|
|
857
|
+
} catch (e) {
|
|
858
|
+
if (e instanceof Error && e.message.startsWith(`${errorLabel} API error:`))
|
|
859
|
+
throw e;
|
|
860
|
+
throw new Error(`${errorLabel} API error: ${response.status} - ${errorBody}`);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
const responseBody = await response.json();
|
|
864
|
+
const choice = responseBody.choices?.[0];
|
|
865
|
+
if (!choice?.message) {
|
|
866
|
+
throw new Error(`${errorLabel} API error: No message in response. Body: ${JSON.stringify(responseBody)}`);
|
|
867
|
+
}
|
|
868
|
+
const contentBlocks = [];
|
|
869
|
+
const assistantText = (0, provider_config_1.extractOpenAiMessageText)(choice.message);
|
|
870
|
+
if (assistantText) {
|
|
871
|
+
contentBlocks.push({
|
|
872
|
+
type: "text",
|
|
873
|
+
text: assistantText
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
if (choice.message.tool_calls) {
|
|
877
|
+
for (const tc of choice.message.tool_calls) {
|
|
878
|
+
contentBlocks.push({
|
|
879
|
+
type: "toolCall",
|
|
880
|
+
id: tc.id,
|
|
881
|
+
name: tc.function.name,
|
|
882
|
+
arguments: parseOpenAiToolArguments(tc.function.arguments, tc.function.name, errorLabel)
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
const usage = (0, provider_config_1.normalizeOpenAiUsage)(responseBody.usage);
|
|
887
|
+
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";
|
|
888
|
+
return {
|
|
889
|
+
message: {
|
|
890
|
+
role: "assistant",
|
|
891
|
+
content: contentBlocks
|
|
892
|
+
},
|
|
893
|
+
usage,
|
|
894
|
+
stopReason
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
function convertMessagesToGemini(messages) {
|
|
898
|
+
const result = [];
|
|
899
|
+
for (const msg of messages) {
|
|
900
|
+
switch (msg.role) {
|
|
901
|
+
case "user":
|
|
902
|
+
result.push({
|
|
903
|
+
role: "user",
|
|
904
|
+
parts: [{ text: msg.content }]
|
|
905
|
+
});
|
|
906
|
+
break;
|
|
907
|
+
case "assistant": {
|
|
908
|
+
const parts = [];
|
|
909
|
+
for (const block of msg.content) {
|
|
910
|
+
if (block.type === "text") {
|
|
911
|
+
parts.push({ text: block.text });
|
|
912
|
+
} else if (block.type === "toolCall") {
|
|
913
|
+
parts.push({
|
|
914
|
+
functionCall: {
|
|
915
|
+
name: block.name,
|
|
916
|
+
args: block.arguments
|
|
917
|
+
}
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
result.push({ role: "model", parts });
|
|
922
|
+
break;
|
|
923
|
+
}
|
|
924
|
+
case "toolResult": {
|
|
925
|
+
result.push({
|
|
926
|
+
role: "user",
|
|
927
|
+
parts: [
|
|
928
|
+
{
|
|
929
|
+
functionResponse: {
|
|
930
|
+
name: msg.toolName,
|
|
931
|
+
response: { content: msg.content }
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
]
|
|
935
|
+
});
|
|
936
|
+
break;
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
return result;
|
|
941
|
+
}
|
|
942
|
+
function convertToolsToGemini(tools) {
|
|
943
|
+
if (tools.length === 0)
|
|
944
|
+
return [];
|
|
945
|
+
return [
|
|
946
|
+
{
|
|
947
|
+
functionDeclarations: tools.map((t) => ({
|
|
948
|
+
name: t.name,
|
|
949
|
+
description: t.description,
|
|
950
|
+
parameters: t.parameters
|
|
951
|
+
}))
|
|
952
|
+
}
|
|
953
|
+
];
|
|
954
|
+
}
|
|
955
|
+
function buildGeminiAgenticRequest(options, apiKey) {
|
|
956
|
+
const contents = convertMessagesToGemini(options.messages);
|
|
957
|
+
const tools = convertToolsToGemini(options.tools);
|
|
958
|
+
const body = {
|
|
959
|
+
contents,
|
|
960
|
+
generationConfig: {
|
|
961
|
+
maxOutputTokens: options.maxTokens
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
if (tools.length > 0) {
|
|
965
|
+
body.tools = tools;
|
|
966
|
+
}
|
|
967
|
+
if (options.systemPrompt) {
|
|
968
|
+
body.systemInstruction = {
|
|
969
|
+
parts: [{ text: options.systemPrompt }]
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
const action = options.stream ? "streamGenerateContent" : "generateContent";
|
|
973
|
+
const altParam = options.stream ? "&alt=sse" : "";
|
|
974
|
+
const url = `https://generativelanguage.googleapis.com/v1beta/models/${options.model}:${action}?key=${apiKey}${altParam}`;
|
|
975
|
+
return {
|
|
976
|
+
url,
|
|
977
|
+
method: "POST",
|
|
978
|
+
headers: {
|
|
979
|
+
"Content-Type": "application/json"
|
|
980
|
+
},
|
|
981
|
+
body,
|
|
982
|
+
loggableUrl: url.replace(/key=[^&]+/, "key=[REDACTED]"),
|
|
983
|
+
loggableBody: body
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
async function parseGeminiAgenticResponse(response) {
|
|
987
|
+
if (response.status !== 200) {
|
|
988
|
+
const errorBody = await response.text();
|
|
989
|
+
try {
|
|
990
|
+
const parsed = JSON.parse(errorBody);
|
|
991
|
+
const message = parsed?.error?.message || errorBody;
|
|
992
|
+
throw new Error(`Gemini API error: ${response.status} - ${message}`);
|
|
993
|
+
} catch (e) {
|
|
994
|
+
if (e instanceof Error && e.message.startsWith("Gemini API error:"))
|
|
995
|
+
throw e;
|
|
996
|
+
throw new Error(`Gemini API error: ${response.status} - ${errorBody}`);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
const responseBody = await response.json();
|
|
1000
|
+
const candidate = responseBody.candidates?.[0];
|
|
1001
|
+
if (!candidate?.content?.parts) {
|
|
1002
|
+
throw new Error(`Gemini API error: No content in response. Body: ${JSON.stringify(responseBody)}`);
|
|
1003
|
+
}
|
|
1004
|
+
const contentBlocks = [];
|
|
1005
|
+
let hasToolCalls = false;
|
|
1006
|
+
for (const part of candidate.content.parts) {
|
|
1007
|
+
if (part.text) {
|
|
1008
|
+
contentBlocks.push({ type: "text", text: part.text });
|
|
1009
|
+
}
|
|
1010
|
+
if (part.functionCall) {
|
|
1011
|
+
hasToolCalls = true;
|
|
1012
|
+
contentBlocks.push({
|
|
1013
|
+
type: "toolCall",
|
|
1014
|
+
id: crypto.randomUUID(),
|
|
1015
|
+
name: part.functionCall.name,
|
|
1016
|
+
arguments: part.functionCall.args
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
const usage = (0, provider_config_1.normalizeGeminiUsage)(responseBody.usageMetadata);
|
|
1021
|
+
const stopReason = hasToolCalls ? "tool_use" : "stop";
|
|
1022
|
+
return {
|
|
1023
|
+
message: {
|
|
1024
|
+
role: "assistant",
|
|
1025
|
+
content: contentBlocks
|
|
1026
|
+
},
|
|
1027
|
+
usage,
|
|
1028
|
+
stopReason
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
function safeEmit(onEvent, event) {
|
|
1032
|
+
if (!onEvent)
|
|
1033
|
+
return;
|
|
1034
|
+
try {
|
|
1035
|
+
onEvent(event);
|
|
1036
|
+
} catch {
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
async function streamOpenAiAgenticResponse(response, errorLabel, onEvent) {
|
|
1040
|
+
if (response.status !== 200) {
|
|
1041
|
+
const errorBody = await response.text();
|
|
1042
|
+
try {
|
|
1043
|
+
const parsed = JSON.parse(errorBody);
|
|
1044
|
+
const message = parsed?.error?.message || errorBody;
|
|
1045
|
+
throw new Error(`${errorLabel} API error: ${response.status} - ${message}`);
|
|
1046
|
+
} catch (e) {
|
|
1047
|
+
if (e instanceof Error && e.message.startsWith(`${errorLabel} API error:`))
|
|
1048
|
+
throw e;
|
|
1049
|
+
throw new Error(`${errorLabel} API error: ${response.status} - ${errorBody}`);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
if (!response.body) {
|
|
1053
|
+
throw new Error(`${errorLabel} API error: Response body is null`);
|
|
1054
|
+
}
|
|
1055
|
+
let textContent = "";
|
|
1056
|
+
const toolCallAccumulators = /* @__PURE__ */ new Map();
|
|
1057
|
+
let finishReason = null;
|
|
1058
|
+
let usage = { ...provider_config_1.normalizedUsageZero };
|
|
1059
|
+
for await (const data of (0, sse_parser_1.parseSSEStream)(response.body)) {
|
|
1060
|
+
let chunk;
|
|
1061
|
+
try {
|
|
1062
|
+
chunk = JSON.parse(data);
|
|
1063
|
+
} catch {
|
|
1064
|
+
continue;
|
|
1065
|
+
}
|
|
1066
|
+
if (chunk.usage) {
|
|
1067
|
+
usage = (0, provider_config_1.normalizeOpenAiUsage)(chunk.usage);
|
|
1068
|
+
}
|
|
1069
|
+
const choice = chunk.choices?.[0];
|
|
1070
|
+
if (!choice)
|
|
1071
|
+
continue;
|
|
1072
|
+
if (choice.finish_reason) {
|
|
1073
|
+
finishReason = choice.finish_reason;
|
|
1074
|
+
}
|
|
1075
|
+
const delta = choice.delta;
|
|
1076
|
+
if (!delta)
|
|
1077
|
+
continue;
|
|
1078
|
+
if (delta.content) {
|
|
1079
|
+
textContent += delta.content;
|
|
1080
|
+
safeEmit(onEvent, { type: "text_delta", text: delta.content });
|
|
1081
|
+
}
|
|
1082
|
+
if (delta.tool_calls) {
|
|
1083
|
+
for (const tc of delta.tool_calls) {
|
|
1084
|
+
const existing = toolCallAccumulators.get(tc.index);
|
|
1085
|
+
if (existing) {
|
|
1086
|
+
if (tc.function?.arguments) {
|
|
1087
|
+
existing.arguments += tc.function.arguments;
|
|
1088
|
+
}
|
|
1089
|
+
} else {
|
|
1090
|
+
toolCallAccumulators.set(tc.index, {
|
|
1091
|
+
id: tc.id ?? "",
|
|
1092
|
+
name: tc.function?.name ?? "",
|
|
1093
|
+
arguments: tc.function?.arguments ?? ""
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
const contentBlocks = [];
|
|
1100
|
+
if (textContent) {
|
|
1101
|
+
contentBlocks.push({ type: "text", text: textContent });
|
|
1102
|
+
}
|
|
1103
|
+
const sortedToolCalls = [...toolCallAccumulators.entries()].sort(([a], [b]) => a - b);
|
|
1104
|
+
for (const [, tc] of sortedToolCalls) {
|
|
1105
|
+
contentBlocks.push({
|
|
1106
|
+
type: "toolCall",
|
|
1107
|
+
id: tc.id,
|
|
1108
|
+
name: tc.name,
|
|
1109
|
+
arguments: parseOpenAiToolArguments(tc.arguments, tc.name, errorLabel)
|
|
1110
|
+
});
|
|
1111
|
+
}
|
|
1112
|
+
const stopReason2 = finishReason === "tool_calls" || sortedToolCalls.length > 0 ? "tool_use" : "stop";
|
|
1113
|
+
return {
|
|
1114
|
+
message: { role: "assistant", content: contentBlocks },
|
|
1115
|
+
usage,
|
|
1116
|
+
stopReason: stopReason2
|
|
1117
|
+
};
|
|
1118
|
+
}
|
|
1119
|
+
async function streamGeminiAgenticResponse(response, onEvent) {
|
|
1120
|
+
if (response.status !== 200) {
|
|
1121
|
+
const errorBody = await response.text();
|
|
1122
|
+
try {
|
|
1123
|
+
const parsed = JSON.parse(errorBody);
|
|
1124
|
+
const message = parsed?.error?.message || errorBody;
|
|
1125
|
+
throw new Error(`Gemini API error: ${response.status} - ${message}`);
|
|
1126
|
+
} catch (e) {
|
|
1127
|
+
if (e instanceof Error && e.message.startsWith("Gemini API error:"))
|
|
1128
|
+
throw e;
|
|
1129
|
+
throw new Error(`Gemini API error: ${response.status} - ${errorBody}`);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
if (!response.body) {
|
|
1133
|
+
throw new Error("Gemini API error: Response body is null");
|
|
1134
|
+
}
|
|
1135
|
+
const contentBlocks = [];
|
|
1136
|
+
let hasToolCalls2 = false;
|
|
1137
|
+
let textContent2 = "";
|
|
1138
|
+
let usage2 = { ...provider_config_1.normalizedUsageZero };
|
|
1139
|
+
for await (const data of (0, sse_parser_1.parseSSEStream)(response.body)) {
|
|
1140
|
+
let chunk;
|
|
1141
|
+
try {
|
|
1142
|
+
chunk = JSON.parse(data);
|
|
1143
|
+
} catch {
|
|
1144
|
+
continue;
|
|
1145
|
+
}
|
|
1146
|
+
if (chunk.usageMetadata) {
|
|
1147
|
+
usage2 = (0, provider_config_1.normalizeGeminiUsage)(chunk.usageMetadata);
|
|
1148
|
+
}
|
|
1149
|
+
const candidate = chunk.candidates?.[0];
|
|
1150
|
+
if (!candidate?.content?.parts)
|
|
1151
|
+
continue;
|
|
1152
|
+
for (const part of candidate.content.parts) {
|
|
1153
|
+
if (part.text) {
|
|
1154
|
+
textContent2 += part.text;
|
|
1155
|
+
safeEmit(onEvent, { type: "text_delta", text: part.text });
|
|
1156
|
+
}
|
|
1157
|
+
if (part.functionCall) {
|
|
1158
|
+
hasToolCalls2 = true;
|
|
1159
|
+
contentBlocks.push({
|
|
1160
|
+
type: "toolCall",
|
|
1161
|
+
id: crypto.randomUUID(),
|
|
1162
|
+
name: part.functionCall.name,
|
|
1163
|
+
arguments: part.functionCall.args
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
if (textContent2) {
|
|
1169
|
+
contentBlocks.unshift({ type: "text", text: textContent2 });
|
|
1170
|
+
}
|
|
1171
|
+
const stopReason3 = hasToolCalls2 ? "tool_use" : "stop";
|
|
1172
|
+
return {
|
|
1173
|
+
message: { role: "assistant", content: contentBlocks },
|
|
1174
|
+
usage: usage2,
|
|
1175
|
+
stopReason: stopReason3
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
return providerFormatters;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
687
1181
|
var hasRequiredHttpLlmClient;
|
|
688
1182
|
function requireHttpLlmClient() {
|
|
689
1183
|
if (hasRequiredHttpLlmClient) return httpLlmClient;
|
|
@@ -693,6 +1187,7 @@ function requireHttpLlmClient() {
|
|
|
693
1187
|
const model_info_1 = requireModelInfo();
|
|
694
1188
|
const logger_1 = requireLogger();
|
|
695
1189
|
const provider_config_1 = requireProviderConfig();
|
|
1190
|
+
const provider_formatters_1 = requireProviderFormatters();
|
|
696
1191
|
class HttpLlmClient {
|
|
697
1192
|
constructor(providerId, apiKey, logger) {
|
|
698
1193
|
this.providerId = providerId;
|
|
@@ -700,51 +1195,133 @@ function requireHttpLlmClient() {
|
|
|
700
1195
|
this.logger = logger;
|
|
701
1196
|
}
|
|
702
1197
|
async sendRequest(prompt, model, maxTokens, assistantPrefillPrompt) {
|
|
1198
|
+
const provider = this.getProviderConfig();
|
|
1199
|
+
const providerModelName = this.getProviderModelName(model);
|
|
1200
|
+
const requestOptions = provider.buildRequest({
|
|
1201
|
+
prompt,
|
|
1202
|
+
model: providerModelName,
|
|
1203
|
+
maxTokens,
|
|
1204
|
+
assistantPrefillPrompt
|
|
1205
|
+
}, this.apiKey);
|
|
1206
|
+
return this.executeProviderCall({
|
|
1207
|
+
provider,
|
|
1208
|
+
model,
|
|
1209
|
+
maxTokens,
|
|
1210
|
+
apiOperation: provider.apiOperation,
|
|
1211
|
+
requestOptions,
|
|
1212
|
+
parseResponse: provider.parseResponse,
|
|
1213
|
+
getResponsePreview: (parsedResponse) => parsedResponse.text,
|
|
1214
|
+
getUsage: (parsedResponse) => parsedResponse.usage
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
async sendAgenticRequest(messages, tools, model, maxTokens, systemPrompt, onEvent) {
|
|
1218
|
+
const provider = this.getProviderConfig();
|
|
1219
|
+
const providerModelName = this.getProviderModelName(model);
|
|
1220
|
+
const codec = this.getAgenticProviderCodec(provider.errorLabel);
|
|
1221
|
+
const requestOptions = codec.buildRequest({
|
|
1222
|
+
messages,
|
|
1223
|
+
tools,
|
|
1224
|
+
model: providerModelName,
|
|
1225
|
+
maxTokens,
|
|
1226
|
+
systemPrompt,
|
|
1227
|
+
stream: !!onEvent
|
|
1228
|
+
});
|
|
1229
|
+
const parseResponse = onEvent ? (response) => codec.parseStreamingResponse(response, onEvent) : codec.parseResponse;
|
|
1230
|
+
return this.executeProviderCall({
|
|
1231
|
+
provider,
|
|
1232
|
+
model,
|
|
1233
|
+
maxTokens,
|
|
1234
|
+
apiOperation: "agentic",
|
|
1235
|
+
requestOptions,
|
|
1236
|
+
parseResponse,
|
|
1237
|
+
getResponsePreview: (parsedResponse) => parsedResponse.message.content.filter((content) => content.type === "text").map((content) => content.text).join(""),
|
|
1238
|
+
getUsage: (parsedResponse) => parsedResponse.usage
|
|
1239
|
+
});
|
|
1240
|
+
}
|
|
1241
|
+
getProviderConfig() {
|
|
703
1242
|
const provider = provider_config_1.providerConfigs[this.providerId];
|
|
704
1243
|
if (!provider) {
|
|
705
1244
|
throw new Error(`Unknown LLM provider: ${this.providerId}`);
|
|
706
1245
|
}
|
|
1246
|
+
return provider;
|
|
1247
|
+
}
|
|
1248
|
+
getProviderModelName(model) {
|
|
707
1249
|
const providerSpecificModelName = model_info_1.SUPPORTED_MODELS[model].find((pm) => pm.provider === this.providerId);
|
|
708
1250
|
if (!providerSpecificModelName) {
|
|
709
1251
|
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`);
|
|
710
1252
|
}
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
const method = requestOptions.method ?? "POST";
|
|
718
|
-
const headers = requestOptions.headers ?? {};
|
|
719
|
-
const bodyPayload = requestOptions.body;
|
|
720
|
-
const body = typeof bodyPayload === "string" ? bodyPayload : bodyPayload !== void 0 ? JSON.stringify(bodyPayload) : void 0;
|
|
1253
|
+
return providerSpecificModelName.providerModelName;
|
|
1254
|
+
}
|
|
1255
|
+
async executeProviderCall(params) {
|
|
1256
|
+
const method = params.requestOptions.method ?? "POST";
|
|
1257
|
+
const headers = params.requestOptions.headers ?? {};
|
|
1258
|
+
const body = this.toFetchableBody(params.requestOptions.body);
|
|
721
1259
|
const spanId = (0, logger_1.generateSpanId)();
|
|
722
1260
|
const startTime = Date.now();
|
|
723
|
-
(0, logger_1.logLlmCallStart)(this.logger, spanId, provider.providerId,
|
|
724
|
-
url: requestOptions.loggableUrl ?? requestOptions.url,
|
|
1261
|
+
(0, logger_1.logLlmCallStart)(this.logger, spanId, params.provider.providerId, params.apiOperation, {
|
|
1262
|
+
url: params.requestOptions.loggableUrl ?? params.requestOptions.url,
|
|
725
1263
|
httpMethod: method,
|
|
726
|
-
model,
|
|
727
|
-
maxTokens
|
|
1264
|
+
model: params.model,
|
|
1265
|
+
maxTokens: params.maxTokens
|
|
728
1266
|
});
|
|
729
1267
|
try {
|
|
730
|
-
const response = await fetch(requestOptions.url, {
|
|
1268
|
+
const response = await fetch(params.requestOptions.url, {
|
|
731
1269
|
method,
|
|
732
1270
|
headers,
|
|
733
1271
|
body
|
|
734
1272
|
});
|
|
735
|
-
const parsedResponse = await
|
|
1273
|
+
const parsedResponse = await params.parseResponse(response);
|
|
736
1274
|
const duration = Date.now() - startTime;
|
|
737
|
-
(0, logger_1.logLlmCallComplete)(this.logger, spanId, provider.providerId,
|
|
1275
|
+
(0, logger_1.logLlmCallComplete)(this.logger, spanId, params.provider.providerId, params.apiOperation, {
|
|
738
1276
|
status: response.status,
|
|
739
|
-
responseText: parsedResponse
|
|
1277
|
+
responseText: params.getResponsePreview(parsedResponse),
|
|
740
1278
|
headers: Object.fromEntries(response.headers.entries()),
|
|
741
|
-
usage: parsedResponse
|
|
1279
|
+
usage: params.getUsage(parsedResponse)
|
|
742
1280
|
}, duration);
|
|
743
1281
|
return parsedResponse;
|
|
744
1282
|
} catch (error) {
|
|
745
1283
|
const duration = Date.now() - startTime;
|
|
746
|
-
(0, logger_1.logLlmCallError)(this.logger, spanId, provider.providerId,
|
|
747
|
-
throw new Error(`${provider.errorLabel} API request failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1284
|
+
(0, logger_1.logLlmCallError)(this.logger, spanId, params.provider.providerId, params.apiOperation, error, duration);
|
|
1285
|
+
throw new Error(`${params.provider.errorLabel} API request failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
toFetchableBody(bodyPayload) {
|
|
1289
|
+
if (typeof bodyPayload === "string") {
|
|
1290
|
+
return bodyPayload;
|
|
1291
|
+
}
|
|
1292
|
+
if (bodyPayload === void 0) {
|
|
1293
|
+
return void 0;
|
|
1294
|
+
}
|
|
1295
|
+
return JSON.stringify(bodyPayload);
|
|
1296
|
+
}
|
|
1297
|
+
getAgenticProviderCodec(errorLabel) {
|
|
1298
|
+
switch (this.providerId) {
|
|
1299
|
+
case "groq":
|
|
1300
|
+
return {
|
|
1301
|
+
buildRequest: (options) => (0, provider_formatters_1.buildOpenAiAgenticRequest)(options, "https://api.groq.com/openai/v1/chat/completions", this.apiKey),
|
|
1302
|
+
parseResponse: (response) => (0, provider_formatters_1.parseOpenAiAgenticResponse)(response, errorLabel),
|
|
1303
|
+
parseStreamingResponse: (response, onEvent) => (0, provider_formatters_1.streamOpenAiAgenticResponse)(response, errorLabel, onEvent)
|
|
1304
|
+
};
|
|
1305
|
+
case "cerebras":
|
|
1306
|
+
return {
|
|
1307
|
+
buildRequest: (options) => (0, provider_formatters_1.buildOpenAiAgenticRequest)(options, "https://api.cerebras.ai/v1/chat/completions", this.apiKey),
|
|
1308
|
+
parseResponse: (response) => (0, provider_formatters_1.parseOpenAiAgenticResponse)(response, errorLabel),
|
|
1309
|
+
parseStreamingResponse: (response, onEvent) => (0, provider_formatters_1.streamOpenAiAgenticResponse)(response, errorLabel, onEvent)
|
|
1310
|
+
};
|
|
1311
|
+
case "openrouter":
|
|
1312
|
+
return {
|
|
1313
|
+
buildRequest: (options) => (0, provider_formatters_1.buildOpenAiAgenticRequest)(options, "https://openrouter.ai/api/v1/chat/completions", this.apiKey),
|
|
1314
|
+
parseResponse: (response) => (0, provider_formatters_1.parseOpenAiAgenticResponse)(response, errorLabel),
|
|
1315
|
+
parseStreamingResponse: (response, onEvent) => (0, provider_formatters_1.streamOpenAiAgenticResponse)(response, errorLabel, onEvent)
|
|
1316
|
+
};
|
|
1317
|
+
case "gemini":
|
|
1318
|
+
return {
|
|
1319
|
+
buildRequest: (options) => (0, provider_formatters_1.buildGeminiAgenticRequest)(options, this.apiKey),
|
|
1320
|
+
parseResponse: provider_formatters_1.parseGeminiAgenticResponse,
|
|
1321
|
+
parseStreamingResponse: (response, onEvent) => (0, provider_formatters_1.streamGeminiAgenticResponse)(response, onEvent)
|
|
1322
|
+
};
|
|
1323
|
+
default:
|
|
1324
|
+
throw new Error(`Unsupported provider for agentic requests: ${this.providerId}`);
|
|
748
1325
|
}
|
|
749
1326
|
}
|
|
750
1327
|
}
|
|
@@ -832,7 +1409,8 @@ function requireCastPromptBuilder() {
|
|
|
832
1409
|
`Your entire response should be just the value of '${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}', as valid JSON.`,
|
|
833
1410
|
`And it should not be wrapped in any wrapper object -- return exactly what the JSON schema is expecting.`,
|
|
834
1411
|
`We will validate the result with the AJV Node library, using ajv.parse, against the given schema, and we expect`,
|
|
835
|
-
`it to validate correctly
|
|
1412
|
+
`it to validate correctly.`,
|
|
1413
|
+
`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.`
|
|
836
1414
|
].join(" ");
|
|
837
1415
|
const buildSystemPrompt = (reqParams) => {
|
|
838
1416
|
let a = BASE_SYSTEM_PROMPT_WHEN_OUTPUT_TYPE_NAME_PROVIDED;
|
|
@@ -884,6 +1462,145 @@ function requireNuaErrors() {
|
|
|
884
1462
|
return nuaErrors;
|
|
885
1463
|
}
|
|
886
1464
|
|
|
1465
|
+
var agentLoop = {};
|
|
1466
|
+
|
|
1467
|
+
var hasRequiredAgentLoop;
|
|
1468
|
+
function requireAgentLoop() {
|
|
1469
|
+
if (hasRequiredAgentLoop) return agentLoop;
|
|
1470
|
+
hasRequiredAgentLoop = 1;
|
|
1471
|
+
Object.defineProperty(agentLoop, "__esModule", { value: true });
|
|
1472
|
+
agentLoop.runAgentLoop = runAgentLoop;
|
|
1473
|
+
const provider_config_1 = requireProviderConfig();
|
|
1474
|
+
function safeEmit(onEvent, event) {
|
|
1475
|
+
if (!onEvent)
|
|
1476
|
+
return;
|
|
1477
|
+
try {
|
|
1478
|
+
onEvent(event);
|
|
1479
|
+
} catch {
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
async function runAgentLoop(params) {
|
|
1483
|
+
const messages = [...params.messages];
|
|
1484
|
+
let totalUsage = { ...provider_config_1.normalizedUsageZero };
|
|
1485
|
+
const toolsByName = new Map(params.tools.map((tool) => [tool.name, tool]));
|
|
1486
|
+
let completionReason = "max_turns";
|
|
1487
|
+
const onEvent = params.onEvent;
|
|
1488
|
+
for (let turn = 0; turn < params.maxTurns; turn++) {
|
|
1489
|
+
safeEmit(onEvent, { type: "turn_start", turn });
|
|
1490
|
+
let response;
|
|
1491
|
+
try {
|
|
1492
|
+
response = await params.sendRequest(messages, params.tools, params.systemPrompt);
|
|
1493
|
+
} catch (error) {
|
|
1494
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
1495
|
+
safeEmit(onEvent, { type: "error", error: errorMessage });
|
|
1496
|
+
return buildAgentResult(messages, totalUsage, "error", errorMessage);
|
|
1497
|
+
}
|
|
1498
|
+
messages.push(response.message);
|
|
1499
|
+
totalUsage = addUsage(totalUsage, response.usage);
|
|
1500
|
+
safeEmit(onEvent, {
|
|
1501
|
+
type: "response_complete",
|
|
1502
|
+
message: response.message,
|
|
1503
|
+
usage: response.usage,
|
|
1504
|
+
stopReason: response.stopReason
|
|
1505
|
+
});
|
|
1506
|
+
const toolCalls = response.message.content.filter((c) => c.type === "toolCall");
|
|
1507
|
+
if (toolCalls.length === 0 || response.stopReason === "stop") {
|
|
1508
|
+
completionReason = "stop";
|
|
1509
|
+
return buildAgentResult(messages, totalUsage, completionReason);
|
|
1510
|
+
}
|
|
1511
|
+
for (const toolCall of toolCalls) {
|
|
1512
|
+
safeEmit(onEvent, {
|
|
1513
|
+
type: "tool_start",
|
|
1514
|
+
toolCallId: toolCall.id,
|
|
1515
|
+
toolName: toolCall.name,
|
|
1516
|
+
arguments: toolCall.arguments
|
|
1517
|
+
});
|
|
1518
|
+
const tool = toolsByName.get(toolCall.name);
|
|
1519
|
+
if (!tool) {
|
|
1520
|
+
const result = {
|
|
1521
|
+
content: `Tool "${toolCall.name}" not found`,
|
|
1522
|
+
isError: true
|
|
1523
|
+
};
|
|
1524
|
+
messages.push({
|
|
1525
|
+
role: "toolResult",
|
|
1526
|
+
toolCallId: toolCall.id,
|
|
1527
|
+
toolName: toolCall.name,
|
|
1528
|
+
content: result.content,
|
|
1529
|
+
isError: true
|
|
1530
|
+
});
|
|
1531
|
+
safeEmit(onEvent, {
|
|
1532
|
+
type: "tool_complete",
|
|
1533
|
+
toolCallId: toolCall.id,
|
|
1534
|
+
toolName: toolCall.name,
|
|
1535
|
+
result
|
|
1536
|
+
});
|
|
1537
|
+
continue;
|
|
1538
|
+
}
|
|
1539
|
+
try {
|
|
1540
|
+
const result = await tool.execute(toolCall.arguments);
|
|
1541
|
+
messages.push({
|
|
1542
|
+
role: "toolResult",
|
|
1543
|
+
toolCallId: toolCall.id,
|
|
1544
|
+
toolName: toolCall.name,
|
|
1545
|
+
content: result.content,
|
|
1546
|
+
isError: result.isError ?? false
|
|
1547
|
+
});
|
|
1548
|
+
safeEmit(onEvent, {
|
|
1549
|
+
type: "tool_complete",
|
|
1550
|
+
toolCallId: toolCall.id,
|
|
1551
|
+
toolName: toolCall.name,
|
|
1552
|
+
result
|
|
1553
|
+
});
|
|
1554
|
+
} catch (error) {
|
|
1555
|
+
const errorContent = `Tool execution error: ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
1556
|
+
const result = { content: errorContent, isError: true };
|
|
1557
|
+
messages.push({
|
|
1558
|
+
role: "toolResult",
|
|
1559
|
+
toolCallId: toolCall.id,
|
|
1560
|
+
toolName: toolCall.name,
|
|
1561
|
+
content: errorContent,
|
|
1562
|
+
isError: true
|
|
1563
|
+
});
|
|
1564
|
+
safeEmit(onEvent, {
|
|
1565
|
+
type: "tool_complete",
|
|
1566
|
+
toolCallId: toolCall.id,
|
|
1567
|
+
toolName: toolCall.name,
|
|
1568
|
+
result
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
return buildAgentResult(messages, totalUsage, completionReason, `Reached maxTurns limit (${params.maxTurns}) before receiving a final response`);
|
|
1574
|
+
}
|
|
1575
|
+
function addUsage(a, b) {
|
|
1576
|
+
return {
|
|
1577
|
+
promptTokens: a.promptTokens + b.promptTokens,
|
|
1578
|
+
completionTokens: a.completionTokens + b.completionTokens,
|
|
1579
|
+
totalTokens: a.totalTokens + b.totalTokens
|
|
1580
|
+
};
|
|
1581
|
+
}
|
|
1582
|
+
function extractLastAssistantText(messages) {
|
|
1583
|
+
const lastAssistant = [...messages].reverse().find((m) => m.role === "assistant");
|
|
1584
|
+
if (lastAssistant?.role !== "assistant") {
|
|
1585
|
+
return void 0;
|
|
1586
|
+
}
|
|
1587
|
+
const text = lastAssistant.content.filter((c) => c.type === "text").map((c) => c.text).join("");
|
|
1588
|
+
return text || void 0;
|
|
1589
|
+
}
|
|
1590
|
+
function buildAgentResult(messages, usage, completionReason, error) {
|
|
1591
|
+
const success = completionReason === "stop" && !error;
|
|
1592
|
+
return {
|
|
1593
|
+
success,
|
|
1594
|
+
completionReason,
|
|
1595
|
+
messages,
|
|
1596
|
+
textResponse: extractLastAssistantText(messages),
|
|
1597
|
+
usage,
|
|
1598
|
+
error
|
|
1599
|
+
};
|
|
1600
|
+
}
|
|
1601
|
+
return agentLoop;
|
|
1602
|
+
}
|
|
1603
|
+
|
|
887
1604
|
var hasRequiredNuaLlmClient;
|
|
888
1605
|
function requireNuaLlmClient() {
|
|
889
1606
|
if (hasRequiredNuaLlmClient) return nuaLlmClient;
|
|
@@ -898,10 +1615,12 @@ function requireNuaLlmClient() {
|
|
|
898
1615
|
const call_llm_service_1 = requireCallLlmService();
|
|
899
1616
|
const nua_json_schema_value_validation_1 = requireNuaJsonSchemaValueValidation();
|
|
900
1617
|
const http_llm_client_1 = requireHttpLlmClient();
|
|
1618
|
+
const provider_config_1 = requireProviderConfig();
|
|
901
1619
|
const model_info_1 = requireModelInfo();
|
|
902
1620
|
const cast_array_prompt_builder_1 = __importDefault(requireCastArrayPromptBuilder());
|
|
903
1621
|
const cast_prompt_builder_1 = __importDefault(requireCastPromptBuilder());
|
|
904
1622
|
const nua_errors_1 = requireNuaErrors();
|
|
1623
|
+
const agent_loop_1 = requireAgentLoop();
|
|
905
1624
|
class NuaLlmClient {
|
|
906
1625
|
constructor(config) {
|
|
907
1626
|
this.logger = config.logger || new logger_1.ConsoleLogger();
|
|
@@ -991,6 +1710,30 @@ function requireNuaLlmClient() {
|
|
|
991
1710
|
};
|
|
992
1711
|
}
|
|
993
1712
|
}
|
|
1713
|
+
async runAgent(params) {
|
|
1714
|
+
try {
|
|
1715
|
+
const model = this.resolveModel(params.model);
|
|
1716
|
+
const client = this.getClientForModel(model);
|
|
1717
|
+
const maxTokens = params.maxTokens ?? 4096;
|
|
1718
|
+
const maxTurns = params.maxTurns ?? 10;
|
|
1719
|
+
return (0, agent_loop_1.runAgentLoop)({
|
|
1720
|
+
messages: params.messages,
|
|
1721
|
+
tools: params.tools,
|
|
1722
|
+
systemPrompt: params.systemPrompt,
|
|
1723
|
+
maxTurns,
|
|
1724
|
+
onEvent: params.onEvent,
|
|
1725
|
+
sendRequest: (messages, tools, systemPrompt) => client.sendAgenticRequest(messages, tools, model, maxTokens, systemPrompt, params.onEvent)
|
|
1726
|
+
});
|
|
1727
|
+
} catch (e) {
|
|
1728
|
+
return {
|
|
1729
|
+
success: false,
|
|
1730
|
+
completionReason: "error",
|
|
1731
|
+
messages: params.messages,
|
|
1732
|
+
usage: provider_config_1.normalizedUsageZero,
|
|
1733
|
+
error: e instanceof Error ? e.message : String(e)
|
|
1734
|
+
};
|
|
1735
|
+
}
|
|
1736
|
+
}
|
|
994
1737
|
}
|
|
995
1738
|
nuaLlmClient.NuaLlmClient = NuaLlmClient;
|
|
996
1739
|
return nuaLlmClient;
|
|
@@ -1164,7 +1907,7 @@ function requireDist() {
|
|
|
1164
1907
|
return mod && mod.__esModule ? mod : { "default": mod };
|
|
1165
1908
|
};
|
|
1166
1909
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
1167
|
-
exports$1.stableStringify = exports$1.validateJsonSchema = exports$1.providerConfigs = exports$1.normalizedUsageZero = exports$1.castArrayPromptBuilder = exports$1.castPromptBuilder = void 0;
|
|
1910
|
+
exports$1.runAgentLoop = exports$1.stableStringify = exports$1.validateJsonSchema = exports$1.providerConfigs = exports$1.normalizedUsageZero = exports$1.castArrayPromptBuilder = exports$1.castPromptBuilder = void 0;
|
|
1168
1911
|
__exportStar(requireNuaLlmClient(), exports$1);
|
|
1169
1912
|
__exportStar(requireLogger(), exports$1);
|
|
1170
1913
|
__exportStar(requireTypes(), exports$1);
|
|
@@ -1194,6 +1937,10 @@ function requireDist() {
|
|
|
1194
1937
|
} });
|
|
1195
1938
|
__exportStar(requireModelInfo(), exports$1);
|
|
1196
1939
|
__exportStar(requireSchemaUtils(), exports$1);
|
|
1940
|
+
var agent_loop_1 = requireAgentLoop();
|
|
1941
|
+
Object.defineProperty(exports$1, "runAgentLoop", { enumerable: true, get: function() {
|
|
1942
|
+
return agent_loop_1.runAgentLoop;
|
|
1943
|
+
} });
|
|
1197
1944
|
})(dist);
|
|
1198
1945
|
return dist;
|
|
1199
1946
|
}
|
|
@@ -1214,9 +1961,10 @@ class DirectBackend {
|
|
|
1214
1961
|
this.client = new distExports.NuaLlmClient({ providers: config.providers });
|
|
1215
1962
|
}
|
|
1216
1963
|
async castValue(params) {
|
|
1964
|
+
const model = params.model ?? this.model;
|
|
1217
1965
|
const startTime = Date.now();
|
|
1218
1966
|
const result = await this.client.castValue({
|
|
1219
|
-
model
|
|
1967
|
+
model,
|
|
1220
1968
|
input: { prompt: params.prompt, data: params.data },
|
|
1221
1969
|
output: { name: params.outputName, effectiveSchema: params.outputSchema }
|
|
1222
1970
|
});
|
|
@@ -1233,20 +1981,21 @@ class DirectBackend {
|
|
|
1233
1981
|
success: true,
|
|
1234
1982
|
data: result.data,
|
|
1235
1983
|
usage: result.usage || normalizedUsageZero,
|
|
1236
|
-
model
|
|
1984
|
+
model,
|
|
1237
1985
|
latencyMs,
|
|
1238
1986
|
source: "direct",
|
|
1239
1987
|
meta: {}
|
|
1240
1988
|
};
|
|
1241
1989
|
}
|
|
1242
1990
|
async castArray(params) {
|
|
1991
|
+
const model = params.model ?? this.model;
|
|
1243
1992
|
const startTime = Date.now();
|
|
1244
1993
|
const wrappedSchema = distExports.wrapArraySchema(params.outputSchema, {
|
|
1245
1994
|
primaryKey: params.primaryKey,
|
|
1246
1995
|
outputName: params.outputName
|
|
1247
1996
|
});
|
|
1248
1997
|
const result = await this.client.castArray({
|
|
1249
|
-
model
|
|
1998
|
+
model,
|
|
1250
1999
|
data: params.data,
|
|
1251
2000
|
input: { prompt: params.prompt, primaryKey: params.primaryKey },
|
|
1252
2001
|
output: { name: params.outputName, effectiveSchema: wrappedSchema }
|
|
@@ -1264,7 +2013,7 @@ class DirectBackend {
|
|
|
1264
2013
|
success: true,
|
|
1265
2014
|
data: result.data,
|
|
1266
2015
|
usage: result.usage || normalizedUsageZero,
|
|
1267
|
-
model
|
|
2016
|
+
model,
|
|
1268
2017
|
latencyMs,
|
|
1269
2018
|
source: "direct",
|
|
1270
2019
|
meta: {}
|
|
@@ -1283,6 +2032,17 @@ function resolveConfigValue(config, key, envVar) {
|
|
|
1283
2032
|
}
|
|
1284
2033
|
|
|
1285
2034
|
const isBrowserEnvironment = () => typeof window !== "undefined" && !!window.document;
|
|
2035
|
+
const isDevelopmentLikeBrowserEnvironment = () => {
|
|
2036
|
+
if (typeof window === "undefined") return false;
|
|
2037
|
+
const host = window.location.hostname;
|
|
2038
|
+
if (host === "localhost" || host === "127.0.0.1") return true;
|
|
2039
|
+
if (typeof process !== "undefined") {
|
|
2040
|
+
if (process.env?.NODE_ENV === "development") {
|
|
2041
|
+
return true;
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
return false;
|
|
2045
|
+
};
|
|
1286
2046
|
class AuthTokenManager {
|
|
1287
2047
|
constructor(config) {
|
|
1288
2048
|
this.apiKey = resolveConfigValue(config, "apiKey", "NUABASE_API_KEY") || void 0;
|
|
@@ -1296,9 +2056,10 @@ class AuthTokenManager {
|
|
|
1296
2056
|
);
|
|
1297
2057
|
}
|
|
1298
2058
|
if (this.apiKey && isBrowserEnvironment()) {
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
2059
|
+
if (!(config.dangerouslyAllowBrowserApiKeyInLocalhost && isDevelopmentLikeBrowserEnvironment()))
|
|
2060
|
+
throw new Error(
|
|
2061
|
+
"found config.apiKey. It is a private secret that must only be used in server environments."
|
|
2062
|
+
);
|
|
1302
2063
|
}
|
|
1303
2064
|
}
|
|
1304
2065
|
async getToken() {
|
|
@@ -1389,7 +2150,8 @@ class GatewayBackend {
|
|
|
1389
2150
|
const startTime = Date.now();
|
|
1390
2151
|
const response = await this.post("cast/value/now", {
|
|
1391
2152
|
input: { prompt: params.prompt, data: params.data },
|
|
1392
|
-
output: { name: params.outputName, schema: params.outputSchema }
|
|
2153
|
+
output: { name: params.outputName, schema: params.outputSchema },
|
|
2154
|
+
...params.model && { model: params.model }
|
|
1393
2155
|
});
|
|
1394
2156
|
const latencyMs = Date.now() - startTime;
|
|
1395
2157
|
if (isErrorResponse(response)) {
|
|
@@ -1405,7 +2167,7 @@ class GatewayBackend {
|
|
|
1405
2167
|
success: true,
|
|
1406
2168
|
data: apiResponse.data,
|
|
1407
2169
|
usage,
|
|
1408
|
-
model: apiResponse.model
|
|
2170
|
+
model: apiResponse.model,
|
|
1409
2171
|
latencyMs,
|
|
1410
2172
|
source: "gateway",
|
|
1411
2173
|
meta: {
|
|
@@ -1420,7 +2182,8 @@ class GatewayBackend {
|
|
|
1420
2182
|
const startTime = Date.now();
|
|
1421
2183
|
const response = await this.post("cast/array/now", {
|
|
1422
2184
|
input: { prompt: params.prompt, data: params.data, primaryKey: params.primaryKey },
|
|
1423
|
-
output: { name: params.outputName, schema: params.outputSchema }
|
|
2185
|
+
output: { name: params.outputName, schema: params.outputSchema },
|
|
2186
|
+
...params.model && { model: params.model }
|
|
1424
2187
|
});
|
|
1425
2188
|
const latencyMs = Date.now() - startTime;
|
|
1426
2189
|
if (isErrorResponse(response)) {
|
|
@@ -1436,7 +2199,7 @@ class GatewayBackend {
|
|
|
1436
2199
|
success: true,
|
|
1437
2200
|
data: apiResponse.data,
|
|
1438
2201
|
usage,
|
|
1439
|
-
model: apiResponse.model
|
|
2202
|
+
model: apiResponse.model,
|
|
1440
2203
|
latencyMs,
|
|
1441
2204
|
source: "gateway",
|
|
1442
2205
|
meta: {
|
|
@@ -1450,7 +2213,8 @@ class GatewayBackend {
|
|
|
1450
2213
|
async queueCastValue(params) {
|
|
1451
2214
|
const response = await this.post("cast/value", {
|
|
1452
2215
|
input: { prompt: params.prompt, data: params.data },
|
|
1453
|
-
output: { name: params.outputName, schema: params.outputSchema }
|
|
2216
|
+
output: { name: params.outputName, schema: params.outputSchema },
|
|
2217
|
+
...params.model && { model: params.model }
|
|
1454
2218
|
});
|
|
1455
2219
|
if (isErrorResponse(response)) {
|
|
1456
2220
|
return { success: false, error: response.error, source: "gateway" };
|
|
@@ -1461,7 +2225,8 @@ class GatewayBackend {
|
|
|
1461
2225
|
async queueCastArray(params) {
|
|
1462
2226
|
const response = await this.post("cast/array", {
|
|
1463
2227
|
input: { prompt: params.prompt, data: params.data, primaryKey: params.primaryKey },
|
|
1464
|
-
output: { name: params.outputName, schema: params.outputSchema }
|
|
2228
|
+
output: { name: params.outputName, schema: params.outputSchema },
|
|
2229
|
+
...params.model && { model: params.model }
|
|
1465
2230
|
});
|
|
1466
2231
|
if (isErrorResponse(response)) {
|
|
1467
2232
|
return { success: false, error: response.error, source: "gateway" };
|
|
@@ -1518,7 +2283,8 @@ class Nua {
|
|
|
1518
2283
|
prompt,
|
|
1519
2284
|
data: options?.input ?? null,
|
|
1520
2285
|
outputName,
|
|
1521
|
-
outputSchema: jsonSchema
|
|
2286
|
+
outputSchema: jsonSchema,
|
|
2287
|
+
model: options?.model
|
|
1522
2288
|
});
|
|
1523
2289
|
}
|
|
1524
2290
|
// ========== list() - Array Operations ==========
|
|
@@ -1538,7 +2304,8 @@ class Nua {
|
|
|
1538
2304
|
data: options.input,
|
|
1539
2305
|
primaryKey: options.primaryKey,
|
|
1540
2306
|
outputName: options.output.name,
|
|
1541
|
-
outputSchema: jsonSchema
|
|
2307
|
+
outputSchema: jsonSchema,
|
|
2308
|
+
model: options.model
|
|
1542
2309
|
});
|
|
1543
2310
|
}
|
|
1544
2311
|
// Implementation
|
|
@@ -1556,7 +2323,8 @@ class Nua {
|
|
|
1556
2323
|
prompt,
|
|
1557
2324
|
data: options?.input ?? null,
|
|
1558
2325
|
outputName,
|
|
1559
|
-
outputSchema: jsonSchema
|
|
2326
|
+
outputSchema: jsonSchema,
|
|
2327
|
+
model: options?.model
|
|
1560
2328
|
});
|
|
1561
2329
|
}
|
|
1562
2330
|
// ========== queueList() - Async Array Operations ==========
|
|
@@ -1579,7 +2347,8 @@ class Nua {
|
|
|
1579
2347
|
data: options.input,
|
|
1580
2348
|
primaryKey: options.primaryKey,
|
|
1581
2349
|
outputName: options.output.name,
|
|
1582
|
-
outputSchema: jsonSchema
|
|
2350
|
+
outputSchema: jsonSchema,
|
|
2351
|
+
model: options.model
|
|
1583
2352
|
});
|
|
1584
2353
|
}
|
|
1585
2354
|
}
|