nuabase 2.3.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.
@@ -1,6 +1,6 @@
1
1
  import require$$0 from 'ajv';
2
- import require$$1 from 'ajv/dist/2019';
3
- 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';
4
4
  import require$$3 from 'ajv/dist/refs/json-schema-draft-07.json';
5
5
  import require$$4 from 'ajv/dist/refs/json-schema-draft-06.json';
6
6
  import { z } from 'zod';
@@ -274,8 +274,8 @@ function requireAjvInstances() {
274
274
  Object.defineProperty(ajvInstances, "__esModule", { value: true });
275
275
  ajvInstances.ajvInstances = void 0;
276
276
  const ajv_1 = __importDefault(require$$0);
277
- const _2019_1 = __importDefault(require$$1);
278
- const _2020_1 = __importDefault(require$$2);
277
+ const _2019_js_1 = __importDefault(require$$1);
278
+ const _2020_js_1 = __importDefault(require$$2);
279
279
  const json_schema_draft_07_json_1 = __importDefault(require$$3);
280
280
  const json_schema_draft_06_json_1 = __importDefault(require$$4);
281
281
  const ajvOptions = {
@@ -288,10 +288,10 @@ function requireAjvInstances() {
288
288
  class AjvInstances {
289
289
  constructor() {
290
290
  this.draft07 = new ajv_1.default(ajvOptions);
291
- this.draft2019 = new _2019_1.default(ajvOptions);
291
+ this.draft2019 = new _2019_js_1.default(ajvOptions);
292
292
  this.draft2019.addMetaSchema(json_schema_draft_07_json_1.default);
293
293
  this.draft2019.addMetaSchema(json_schema_draft_06_json_1.default);
294
- this.draft2020 = new _2020_1.default(ajvOptions);
294
+ this.draft2020 = new _2020_js_1.default(ajvOptions);
295
295
  }
296
296
  getInstanceForSchema(schema) {
297
297
  const schemaVersion = schema.$schema;
@@ -355,17 +355,15 @@ function requireModelInfo() {
355
355
  exports$1.parseCanonicalModelName = parseCanonicalModelName;
356
356
  exports$1.CANONICAL_MODELS = [
357
357
  "qwen3-30b-a3b-instruct-2507",
358
- "claude-sonnet-4-5",
358
+ "claude-sonnet-4-6",
359
359
  "qwen3-vl-235b-a22b-instruct",
360
360
  "qwen3-max",
361
361
  "gpt-5",
362
- "gemini-2.5-flash-lite-preview-09-2025",
362
+ "gemini-2.5-flash-lite",
363
+ "gemini-2.5-flash",
363
364
  "qwen3-coder-flash",
364
365
  "gpt-oss-120b",
365
- "llama-3.3-70b-versatile",
366
- "gpt-4o",
367
- "llama-3.3-70b",
368
- "gemini-2.0-flash"
366
+ "kimi-k2.5"
369
367
  ];
370
368
  const CANONICAL_SET = new Set(exports$1.CANONICAL_MODELS);
371
369
  exports$1.SUPPORTED_MODELS = {
@@ -374,6 +372,10 @@ function requireModelInfo() {
374
372
  provider: "cerebras",
375
373
  providerModelName: "gpt-oss-120b"
376
374
  },
375
+ {
376
+ provider: "groq",
377
+ providerModelName: "openai/gpt-oss-120b"
378
+ },
377
379
  {
378
380
  provider: "openrouter",
379
381
  providerModelName: "openai/gpt-oss-120b"
@@ -385,10 +387,10 @@ function requireModelInfo() {
385
387
  providerModelName: "qwen/qwen3-30b-a3b-instruct-2507"
386
388
  }
387
389
  ],
388
- "claude-sonnet-4-5": [
390
+ "claude-sonnet-4-6": [
389
391
  {
390
392
  provider: "openrouter",
391
- providerModelName: "anthropic/claude-sonnet-4.5"
393
+ providerModelName: "anthropic/claude-sonnet-4.6"
392
394
  }
393
395
  ],
394
396
  "qwen3-vl-235b-a22b-instruct": [
@@ -409,40 +411,36 @@ function requireModelInfo() {
409
411
  providerModelName: "openai/gpt-5"
410
412
  }
411
413
  ],
412
- "gemini-2.5-flash-lite-preview-09-2025": [
414
+ "gemini-2.5-flash-lite": [
413
415
  {
414
- provider: "openrouter",
415
- providerModelName: "google/gemini-2.5-flash-lite-preview-09-2025"
416
- }
417
- ],
418
- "qwen3-coder-flash": [
416
+ provider: "gemini",
417
+ providerModelName: "gemini-2.5-flash-lite"
418
+ },
419
419
  {
420
420
  provider: "openrouter",
421
- providerModelName: "qwen/qwen3-coder-flash"
421
+ providerModelName: "google/gemini-2.5-flash-lite"
422
422
  }
423
423
  ],
424
- "llama-3.3-70b-versatile": [
424
+ "gemini-2.5-flash": [
425
425
  {
426
- provider: "groq",
427
- providerModelName: "llama-3.3-70b-versatile"
428
- }
429
- ],
430
- "gpt-4o": [
426
+ provider: "gemini",
427
+ providerModelName: "gemini-2.5-flash"
428
+ },
431
429
  {
432
430
  provider: "openrouter",
433
- providerModelName: "openai/gpt-4o"
431
+ providerModelName: "google/gemini-2.5-flash"
434
432
  }
435
433
  ],
436
- "llama-3.3-70b": [
434
+ "qwen3-coder-flash": [
437
435
  {
438
- provider: "cerebras",
439
- providerModelName: "llama-3.3-70b"
436
+ provider: "openrouter",
437
+ providerModelName: "qwen/qwen3-coder-flash"
440
438
  }
441
439
  ],
442
- "gemini-2.0-flash": [
440
+ "kimi-k2.5": [
443
441
  {
444
- provider: "gemini",
445
- providerModelName: "gemini-2.0-flash"
442
+ provider: "openrouter",
443
+ providerModelName: "moonshotai/kimi-k2.5"
446
444
  }
447
445
  ]
448
446
  };
@@ -455,11 +453,14 @@ function requireModelInfo() {
455
453
  case "fast":
456
454
  m2 = "gpt-oss-120b";
457
455
  break;
456
+ case "gemini":
457
+ m2 = "gemini-2.5-flash";
458
+ break;
458
459
  case "qwen":
459
460
  m2 = "qwen3-vl-235b-a22b-instruct";
460
461
  break;
461
462
  case "sonnet":
462
- m2 = "claude-sonnet-4-5";
463
+ m2 = "claude-sonnet-4-6";
463
464
  break;
464
465
  case "gpt":
465
466
  m2 = "gpt-5";
@@ -484,7 +485,7 @@ function requireProviderConfig() {
484
485
  hasRequiredProviderConfig = 1;
485
486
  (function(exports$1) {
486
487
  Object.defineProperty(exports$1, "__esModule", { value: true });
487
- 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;
488
489
  exports$1.normalizedUsageZero = {
489
490
  promptTokens: 0,
490
491
  completionTokens: 0,
@@ -503,6 +504,7 @@ function requireProviderConfig() {
503
504
  totalTokens: usage.total_tokens
504
505
  };
505
506
  };
507
+ exports$1.normalizeOpenAiUsage = normalizeOpenAiUsage;
506
508
  const normalizeGeminiUsage = (usage) => {
507
509
  if (!usage) {
508
510
  return exports$1.normalizedUsageZero;
@@ -516,6 +518,7 @@ function requireProviderConfig() {
516
518
  totalTokens: usage.totalTokenCount
517
519
  };
518
520
  };
521
+ exports$1.normalizeGeminiUsage = normalizeGeminiUsage;
519
522
  const buildOpenAiStyleRequest = (baseUrl) => ({ prompt, model, maxTokens, assistantPrefillPrompt }, apiKey) => {
520
523
  const messages = [];
521
524
  messages.push({ role: "user", content: prompt });
@@ -550,11 +553,11 @@ function requireProviderConfig() {
550
553
  const parseOpenAiStyleResponse = (errorLabel) => async (response) => {
551
554
  if (response.status === 200) {
552
555
  const responseBody = await response.json();
553
- const responseText = responseBody.choices?.[0]?.message?.content;
556
+ const responseText = (0, exports$1.extractOpenAiMessageText)(responseBody.choices?.[0]?.message);
554
557
  if (responseText) {
555
558
  return {
556
559
  text: responseText,
557
- usage: normalizeOpenAiUsage(responseBody.usage)
560
+ usage: (0, exports$1.normalizeOpenAiUsage)(responseBody.usage)
558
561
  };
559
562
  }
560
563
  throw new Error(`${errorLabel} API error: Could not extract text from response. Body: ${JSON.stringify(responseBody)}`);
@@ -568,22 +571,28 @@ function requireProviderConfig() {
568
571
  throw new Error(`${errorLabel} API error: ${response.status} - ${errorBody}`);
569
572
  }
570
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;
571
588
  const parseOpenAiGPT5ThinkingStyleResponse = (errorLabel) => async (response) => {
572
- const normalize = (value) => {
573
- if (typeof value !== "string") {
574
- return void 0;
575
- }
576
- const trimmed = value.trim();
577
- return trimmed.length > 0 ? trimmed : void 0;
578
- };
579
589
  if (response.status === 200) {
580
590
  const responseBody = await response.json();
581
- const message = responseBody.choices?.[0]?.message;
582
- 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);
583
592
  if (content) {
584
593
  return {
585
594
  text: content,
586
- usage: normalizeOpenAiUsage(responseBody.usage)
595
+ usage: (0, exports$1.normalizeOpenAiUsage)(responseBody.usage)
587
596
  };
588
597
  }
589
598
  throw new Error(`${errorLabel} API error: Could not extract text from thinking response. Body: ${JSON.stringify(responseBody)}`);
@@ -631,7 +640,7 @@ function requireProviderConfig() {
631
640
  if (responseText) {
632
641
  return {
633
642
  text: responseText,
634
- usage: normalizeGeminiUsage(responseBody.usageMetadata)
643
+ usage: (0, exports$1.normalizeGeminiUsage)(responseBody.usageMetadata)
635
644
  };
636
645
  }
637
646
  throw new Error(`Gemini API error: Could not extract text from response. Body: ${JSON.stringify(responseBody)}`);
@@ -679,6 +688,496 @@ function requireProviderConfig() {
679
688
  return providerConfig;
680
689
  }
681
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
+
682
1181
  var hasRequiredHttpLlmClient;
683
1182
  function requireHttpLlmClient() {
684
1183
  if (hasRequiredHttpLlmClient) return httpLlmClient;
@@ -688,6 +1187,7 @@ function requireHttpLlmClient() {
688
1187
  const model_info_1 = requireModelInfo();
689
1188
  const logger_1 = requireLogger();
690
1189
  const provider_config_1 = requireProviderConfig();
1190
+ const provider_formatters_1 = requireProviderFormatters();
691
1191
  class HttpLlmClient {
692
1192
  constructor(providerId, apiKey, logger) {
693
1193
  this.providerId = providerId;
@@ -695,51 +1195,133 @@ function requireHttpLlmClient() {
695
1195
  this.logger = logger;
696
1196
  }
697
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() {
698
1242
  const provider = provider_config_1.providerConfigs[this.providerId];
699
1243
  if (!provider) {
700
1244
  throw new Error(`Unknown LLM provider: ${this.providerId}`);
701
1245
  }
1246
+ return provider;
1247
+ }
1248
+ getProviderModelName(model) {
702
1249
  const providerSpecificModelName = model_info_1.SUPPORTED_MODELS[model].find((pm) => pm.provider === this.providerId);
703
1250
  if (!providerSpecificModelName) {
704
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`);
705
1252
  }
706
- const requestOptions = provider.buildRequest({
707
- prompt,
708
- model: providerSpecificModelName.providerModelName,
709
- maxTokens,
710
- assistantPrefillPrompt
711
- }, this.apiKey);
712
- const method = requestOptions.method ?? "POST";
713
- const headers = requestOptions.headers ?? {};
714
- const bodyPayload = requestOptions.body;
715
- 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);
716
1259
  const spanId = (0, logger_1.generateSpanId)();
717
1260
  const startTime = Date.now();
718
- (0, logger_1.logLlmCallStart)(this.logger, spanId, provider.providerId, provider.apiOperation, {
719
- 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,
720
1263
  httpMethod: method,
721
- model,
722
- maxTokens
1264
+ model: params.model,
1265
+ maxTokens: params.maxTokens
723
1266
  });
724
1267
  try {
725
- const response = await fetch(requestOptions.url, {
1268
+ const response = await fetch(params.requestOptions.url, {
726
1269
  method,
727
1270
  headers,
728
1271
  body
729
1272
  });
730
- const parsedResponse = await provider.parseResponse(response);
1273
+ const parsedResponse = await params.parseResponse(response);
731
1274
  const duration = Date.now() - startTime;
732
- (0, logger_1.logLlmCallComplete)(this.logger, spanId, provider.providerId, provider.apiOperation, {
1275
+ (0, logger_1.logLlmCallComplete)(this.logger, spanId, params.provider.providerId, params.apiOperation, {
733
1276
  status: response.status,
734
- responseText: parsedResponse.text,
1277
+ responseText: params.getResponsePreview(parsedResponse),
735
1278
  headers: Object.fromEntries(response.headers.entries()),
736
- usage: parsedResponse.usage
1279
+ usage: params.getUsage(parsedResponse)
737
1280
  }, duration);
738
1281
  return parsedResponse;
739
1282
  } catch (error) {
740
1283
  const duration = Date.now() - startTime;
741
- (0, logger_1.logLlmCallError)(this.logger, spanId, provider.providerId, provider.apiOperation, error, duration);
742
- 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}`);
743
1325
  }
744
1326
  }
745
1327
  }
@@ -827,7 +1409,8 @@ function requireCastPromptBuilder() {
827
1409
  `Your entire response should be just the value of '${(0, prompt_template_utils_1.templateVarName)("OUTPUT_TYPE_NAME")}', as valid JSON.`,
828
1410
  `And it should not be wrapped in any wrapper object -- return exactly what the JSON schema is expecting.`,
829
1411
  `We will validate the result with the AJV Node library, using ajv.parse, against the given schema, and we expect`,
830
- `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.`
831
1414
  ].join(" ");
832
1415
  const buildSystemPrompt = (reqParams) => {
833
1416
  let a = BASE_SYSTEM_PROMPT_WHEN_OUTPUT_TYPE_NAME_PROVIDED;
@@ -879,6 +1462,145 @@ function requireNuaErrors() {
879
1462
  return nuaErrors;
880
1463
  }
881
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
+
882
1604
  var hasRequiredNuaLlmClient;
883
1605
  function requireNuaLlmClient() {
884
1606
  if (hasRequiredNuaLlmClient) return nuaLlmClient;
@@ -893,10 +1615,12 @@ function requireNuaLlmClient() {
893
1615
  const call_llm_service_1 = requireCallLlmService();
894
1616
  const nua_json_schema_value_validation_1 = requireNuaJsonSchemaValueValidation();
895
1617
  const http_llm_client_1 = requireHttpLlmClient();
1618
+ const provider_config_1 = requireProviderConfig();
896
1619
  const model_info_1 = requireModelInfo();
897
1620
  const cast_array_prompt_builder_1 = __importDefault(requireCastArrayPromptBuilder());
898
1621
  const cast_prompt_builder_1 = __importDefault(requireCastPromptBuilder());
899
1622
  const nua_errors_1 = requireNuaErrors();
1623
+ const agent_loop_1 = requireAgentLoop();
900
1624
  class NuaLlmClient {
901
1625
  constructor(config) {
902
1626
  this.logger = config.logger || new logger_1.ConsoleLogger();
@@ -986,6 +1710,30 @@ function requireNuaLlmClient() {
986
1710
  };
987
1711
  }
988
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
+ }
989
1737
  }
990
1738
  nuaLlmClient.NuaLlmClient = NuaLlmClient;
991
1739
  return nuaLlmClient;
@@ -1159,7 +1907,7 @@ function requireDist() {
1159
1907
  return mod && mod.__esModule ? mod : { "default": mod };
1160
1908
  };
1161
1909
  Object.defineProperty(exports$1, "__esModule", { value: true });
1162
- 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;
1163
1911
  __exportStar(requireNuaLlmClient(), exports$1);
1164
1912
  __exportStar(requireLogger(), exports$1);
1165
1913
  __exportStar(requireTypes(), exports$1);
@@ -1189,6 +1937,10 @@ function requireDist() {
1189
1937
  } });
1190
1938
  __exportStar(requireModelInfo(), exports$1);
1191
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
+ } });
1192
1944
  })(dist);
1193
1945
  return dist;
1194
1946
  }
@@ -1280,12 +2032,16 @@ function resolveConfigValue(config, key, envVar) {
1280
2032
  }
1281
2033
 
1282
2034
  const isBrowserEnvironment = () => typeof window !== "undefined" && !!window.document;
1283
- const isLocalhost = () => {
1284
- if (typeof window === "undefined" || !window.location) {
1285
- return false;
1286
- }
2035
+ const isDevelopmentLikeBrowserEnvironment = () => {
2036
+ if (typeof window === "undefined") return false;
1287
2037
  const host = window.location.hostname;
1288
- return host === "localhost" || host === "127.0.0.1";
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;
1289
2045
  };
1290
2046
  class AuthTokenManager {
1291
2047
  constructor(config) {
@@ -1300,12 +2056,10 @@ class AuthTokenManager {
1300
2056
  );
1301
2057
  }
1302
2058
  if (this.apiKey && isBrowserEnvironment()) {
1303
- const allowedLocally = config.dangerouslyAllowBrowserApiKeyInLocalhost && isLocalhost();
1304
- if (!allowedLocally) {
2059
+ if (!(config.dangerouslyAllowBrowserApiKeyInLocalhost && isDevelopmentLikeBrowserEnvironment()))
1305
2060
  throw new Error(
1306
2061
  "found config.apiKey. It is a private secret that must only be used in server environments."
1307
2062
  );
1308
- }
1309
2063
  }
1310
2064
  }
1311
2065
  async getToken() {
@@ -1413,7 +2167,7 @@ class GatewayBackend {
1413
2167
  success: true,
1414
2168
  data: apiResponse.data,
1415
2169
  usage,
1416
- model: apiResponse.model ?? "unknown",
2170
+ model: apiResponse.model,
1417
2171
  latencyMs,
1418
2172
  source: "gateway",
1419
2173
  meta: {
@@ -1445,7 +2199,7 @@ class GatewayBackend {
1445
2199
  success: true,
1446
2200
  data: apiResponse.data,
1447
2201
  usage,
1448
- model: apiResponse.model ?? "unknown",
2202
+ model: apiResponse.model,
1449
2203
  latencyMs,
1450
2204
  source: "gateway",
1451
2205
  meta: {