nuabase 2.3.2 → 2.3.4

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.
@@ -13,7 +13,6 @@ function requireLogger() {
13
13
  hasRequiredLogger = 1;
14
14
  Object.defineProperty(logger, "__esModule", { value: true });
15
15
  logger.logLlmCallError = logger.logLlmCallComplete = logger.logLlmCallStart = logger.generateSpanId = logger.ConsoleLogger = void 0;
16
- logger.truncateText = truncateText;
17
16
  logger.pickHeaders = pickHeaders;
18
17
  logger.normalizeError = normalizeError;
19
18
  class ConsoleLogger {
@@ -33,13 +32,6 @@ function requireLogger() {
33
32
  logger.ConsoleLogger = ConsoleLogger;
34
33
  const generateSpanId = () => crypto.randomUUID();
35
34
  logger.generateSpanId = generateSpanId;
36
- function truncateText(text, limit = 500) {
37
- const length = text.length;
38
- if (length <= limit) {
39
- return { preview: text, length };
40
- }
41
- return { preview: text.slice(0, limit), length };
42
- }
43
35
  function pickHeaders(headers, allowlist, redactSet) {
44
36
  const result = {};
45
37
  for (const [key, value] of Object.entries(headers)) {
@@ -74,16 +66,13 @@ function requireLogger() {
74
66
  };
75
67
  logger.logLlmCallStart = logLlmCallStart;
76
68
  const logLlmCallComplete = (logger2, spanId, service, method, response, duration) => {
77
- const { headers, responseText, ...rest } = response;
78
- const { preview: responsePreview, length: responseLength } = truncateText(responseText);
69
+ const { headers, ...rest } = response;
79
70
  logger2.info("LLM call completed", {
80
71
  type: "llm_call_complete",
81
72
  span_id: spanId,
82
73
  service,
83
74
  method,
84
75
  ...rest,
85
- responsePreview,
86
- responseLength,
87
76
  ...pickHeaders(headers, LLM_RESPONSE_HEADER_ALLOWLIST),
88
77
  duration_ms: duration
89
78
  });
@@ -153,7 +142,7 @@ function requireLlmResponseExtraction() {
153
142
  hasRequiredLlmResponseExtraction = 1;
154
143
  Object.defineProperty(llmResponseExtraction, "__esModule", { value: true });
155
144
  llmResponseExtraction.extractThinkingFromResponse = extractThinkingFromResponse;
156
- llmResponseExtraction.extractJsonFromMarkdown = extractJsonFromMarkdown;
145
+ llmResponseExtraction.parseJsonFromLlmResponse = parseJsonFromLlmResponse;
157
146
  function extractThinkingFromResponse(input) {
158
147
  const startTag = "<think>";
159
148
  const endTag = "</think>";
@@ -183,25 +172,71 @@ function requireLlmResponseExtraction() {
183
172
  cleanedResponse
184
173
  };
185
174
  }
186
- function extractJsonFromMarkdown(input) {
175
+ function parseJsonFromLlmResponse(input) {
187
176
  const trimmed = input.trim();
188
177
  const codeFence = "```";
189
178
  const jsonFence = "```json";
190
- if (trimmed.startsWith(jsonFence)) {
191
- const startIndex = jsonFence.length;
192
- const endIndex = trimmed.lastIndexOf(codeFence);
193
- if (endIndex > startIndex) {
194
- return trimmed.substring(startIndex, endIndex).trim();
179
+ const lastJsonFence = trimmed.lastIndexOf(jsonFence);
180
+ if (lastJsonFence !== -1) {
181
+ const startIndex = lastJsonFence + jsonFence.length;
182
+ const endIndex = trimmed.indexOf(codeFence, startIndex);
183
+ if (endIndex !== -1) {
184
+ try {
185
+ return JSON.parse(trimmed.substring(startIndex, endIndex).trim());
186
+ } catch {
187
+ }
195
188
  }
196
189
  }
197
- if (trimmed.startsWith(codeFence) && !trimmed.startsWith(jsonFence)) {
198
- const startIndex = codeFence.length;
199
- const endIndex = trimmed.lastIndexOf(codeFence);
200
- if (endIndex > startIndex) {
201
- return trimmed.substring(startIndex, endIndex).trim();
190
+ const firstCodeFence = trimmed.indexOf(codeFence);
191
+ if (firstCodeFence !== -1) {
192
+ const startIndex = firstCodeFence + codeFence.length;
193
+ const endIndex = trimmed.indexOf(codeFence, startIndex);
194
+ if (endIndex !== -1) {
195
+ try {
196
+ return JSON.parse(trimmed.substring(startIndex, endIndex).trim());
197
+ } catch {
198
+ }
202
199
  }
203
200
  }
204
- return input;
201
+ const matchingClose = new Array(trimmed.length).fill(-1);
202
+ const stack = [];
203
+ let inString = false;
204
+ for (let k = 0; k < trimmed.length; k++) {
205
+ if (inString) {
206
+ if (trimmed[k] === "\\")
207
+ k++;
208
+ else if (trimmed[k] === '"')
209
+ inString = false;
210
+ continue;
211
+ }
212
+ if (trimmed[k] === '"') {
213
+ inString = true;
214
+ continue;
215
+ }
216
+ if (trimmed[k] === "{" || trimmed[k] === "[") {
217
+ stack.push(k);
218
+ } else if (trimmed[k] === "}" || trimmed[k] === "]") {
219
+ if (stack.length > 0) {
220
+ const open = stack.pop();
221
+ const expected = trimmed[open] === "{" ? "}" : "]";
222
+ if (trimmed[k] === expected)
223
+ matchingClose[open] = k;
224
+ }
225
+ }
226
+ }
227
+ for (let i = 0; i < trimmed.length; i++) {
228
+ if (trimmed[i] !== "{" && trimmed[i] !== "[")
229
+ continue;
230
+ const j = matchingClose[i];
231
+ if (j === -1)
232
+ continue;
233
+ try {
234
+ return JSON.parse(trimmed.substring(i, j + 1));
235
+ } catch {
236
+ continue;
237
+ }
238
+ }
239
+ return JSON.parse(trimmed);
205
240
  }
206
241
  return llmResponseExtraction;
207
242
  }
@@ -223,9 +258,8 @@ function requireCallLlmService() {
223
258
  const response = providerResponse.text;
224
259
  let parsedResponse;
225
260
  try {
226
- let { thinking, cleanedResponse } = (0, llm_response_extraction_1.extractThinkingFromResponse)(response);
227
- cleanedResponse = (0, llm_response_extraction_1.extractJsonFromMarkdown)(cleanedResponse);
228
- parsedResponse = JSON.parse(cleanedResponse);
261
+ const { cleanedResponse } = (0, llm_response_extraction_1.extractThinkingFromResponse)(response);
262
+ parsedResponse = (0, llm_response_extraction_1.parseJsonFromLlmResponse)(cleanedResponse);
229
263
  } catch (parseError) {
230
264
  const errorMessage2 = `Failed to parse LLM response as JSON: ${parseError instanceof Error ? parseError.message : "Unknown parsing error"}`;
231
265
  throw new Error(`${errorMessage2}
@@ -5503,6 +5537,7 @@ function requirePattern () {
5503
5537
  hasRequiredPattern = 1;
5504
5538
  Object.defineProperty(pattern, "__esModule", { value: true });
5505
5539
  const code_1 = requireCode();
5540
+ const util_1 = requireUtil();
5506
5541
  const codegen_1 = requireCodegen();
5507
5542
  const error = {
5508
5543
  message: ({ schemaCode }) => (0, codegen_1.str) `must match pattern "${schemaCode}"`,
@@ -5515,11 +5550,19 @@ function requirePattern () {
5515
5550
  $data: true,
5516
5551
  error,
5517
5552
  code(cxt) {
5518
- const { data, $data, schema, schemaCode, it } = cxt;
5519
- // TODO regexp should be wrapped in try/catchs
5553
+ const { gen, data, $data, schema, schemaCode, it } = cxt;
5520
5554
  const u = it.opts.unicodeRegExp ? "u" : "";
5521
- const regExp = $data ? (0, codegen_1._) `(new RegExp(${schemaCode}, ${u}))` : (0, code_1.usePattern)(cxt, schema);
5522
- cxt.fail$data((0, codegen_1._) `!${regExp}.test(${data})`);
5555
+ if ($data) {
5556
+ const { regExp } = it.opts.code;
5557
+ const regExpCode = regExp.code === "new RegExp" ? (0, codegen_1._) `new RegExp` : (0, util_1.useFunc)(gen, regExp);
5558
+ const valid = gen.let("valid");
5559
+ gen.try(() => gen.assign(valid, (0, codegen_1._) `${regExpCode}(${schemaCode}, ${u}).test(${data})`), () => gen.assign(valid, false));
5560
+ cxt.fail$data((0, codegen_1._) `!${valid}`);
5561
+ }
5562
+ else {
5563
+ const regExp = (0, code_1.usePattern)(cxt, schema);
5564
+ cxt.fail$data((0, codegen_1._) `!${regExp}.test(${data})`);
5565
+ }
5523
5566
  },
5524
5567
  };
5525
5568
  pattern.default = def;
@@ -9385,9 +9428,9 @@ function requireAjvInstances() {
9385
9428
  };
9386
9429
  Object.defineProperty(ajvInstances, "__esModule", { value: true });
9387
9430
  ajvInstances.ajvInstances = void 0;
9388
- const ajv_1 = __importDefault(requireAjv());
9389
- const _2019_js_1 = __importDefault(require_2019());
9390
- const _2020_js_1 = __importDefault(require_2020());
9431
+ const ajv_1 = __importDefault(/* @__PURE__ */ requireAjv());
9432
+ const _2019_js_1 = __importDefault(/* @__PURE__ */ require_2019());
9433
+ const _2020_js_1 = __importDefault(/* @__PURE__ */ require_2020());
9391
9434
  const json_schema_draft_07_json_1 = __importDefault(require$$3$2);
9392
9435
  const json_schema_draft_06_json_1 = __importDefault(require$$4);
9393
9436
  const ajvOptions = {
@@ -9455,140 +9498,6 @@ function requireNuaJsonSchemaValueValidation() {
9455
9498
 
9456
9499
  var httpLlmClient = {};
9457
9500
 
9458
- var modelInfo = {};
9459
-
9460
- var hasRequiredModelInfo;
9461
- function requireModelInfo() {
9462
- if (hasRequiredModelInfo) return modelInfo;
9463
- hasRequiredModelInfo = 1;
9464
- (function(exports$1) {
9465
- Object.defineProperty(exports$1, "__esModule", { value: true });
9466
- exports$1.SUPPORTED_MODELS = exports$1.CANONICAL_MODELS = void 0;
9467
- exports$1.parseCanonicalModelName = parseCanonicalModelName;
9468
- exports$1.CANONICAL_MODELS = [
9469
- "qwen3-30b-a3b-instruct-2507",
9470
- "claude-sonnet-4-6",
9471
- "qwen3-vl-235b-a22b-instruct",
9472
- "qwen3-max",
9473
- "gpt-5",
9474
- "gemini-2.5-flash-lite",
9475
- "gemini-2.5-flash",
9476
- "qwen3-coder-flash",
9477
- "gpt-oss-120b",
9478
- "kimi-k2.5"
9479
- ];
9480
- const CANONICAL_SET = new Set(exports$1.CANONICAL_MODELS);
9481
- exports$1.SUPPORTED_MODELS = {
9482
- "gpt-oss-120b": [
9483
- {
9484
- provider: "cerebras",
9485
- providerModelName: "gpt-oss-120b"
9486
- },
9487
- {
9488
- provider: "groq",
9489
- providerModelName: "openai/gpt-oss-120b"
9490
- },
9491
- {
9492
- provider: "openrouter",
9493
- providerModelName: "openai/gpt-oss-120b"
9494
- }
9495
- ],
9496
- "qwen3-30b-a3b-instruct-2507": [
9497
- {
9498
- provider: "openrouter",
9499
- providerModelName: "qwen/qwen3-30b-a3b-instruct-2507"
9500
- }
9501
- ],
9502
- "claude-sonnet-4-6": [
9503
- {
9504
- provider: "openrouter",
9505
- providerModelName: "anthropic/claude-sonnet-4.6"
9506
- }
9507
- ],
9508
- "qwen3-vl-235b-a22b-instruct": [
9509
- {
9510
- provider: "openrouter",
9511
- providerModelName: "qwen/qwen3-vl-235b-a22b-instruct"
9512
- }
9513
- ],
9514
- "qwen3-max": [
9515
- {
9516
- provider: "openrouter",
9517
- providerModelName: "qwen/qwen3-max"
9518
- }
9519
- ],
9520
- "gpt-5": [
9521
- {
9522
- provider: "openrouter",
9523
- providerModelName: "openai/gpt-5"
9524
- }
9525
- ],
9526
- "gemini-2.5-flash-lite": [
9527
- {
9528
- provider: "gemini",
9529
- providerModelName: "gemini-2.5-flash-lite"
9530
- },
9531
- {
9532
- provider: "openrouter",
9533
- providerModelName: "google/gemini-2.5-flash-lite"
9534
- }
9535
- ],
9536
- "gemini-2.5-flash": [
9537
- {
9538
- provider: "gemini",
9539
- providerModelName: "gemini-2.5-flash"
9540
- },
9541
- {
9542
- provider: "openrouter",
9543
- providerModelName: "google/gemini-2.5-flash"
9544
- }
9545
- ],
9546
- "qwen3-coder-flash": [
9547
- {
9548
- provider: "openrouter",
9549
- providerModelName: "qwen/qwen3-coder-flash"
9550
- }
9551
- ],
9552
- "kimi-k2.5": [
9553
- {
9554
- provider: "openrouter",
9555
- providerModelName: "moonshotai/kimi-k2.5"
9556
- }
9557
- ]
9558
- };
9559
- function parseCanonicalModelName(requestedModel) {
9560
- let m = requestedModel || "fast";
9561
- if (CANONICAL_SET.has(m))
9562
- return m;
9563
- let m2;
9564
- switch (m) {
9565
- case "fast":
9566
- m2 = "gpt-oss-120b";
9567
- break;
9568
- case "gemini":
9569
- m2 = "gemini-2.5-flash";
9570
- break;
9571
- case "qwen":
9572
- m2 = "qwen3-vl-235b-a22b-instruct";
9573
- break;
9574
- case "sonnet":
9575
- m2 = "claude-sonnet-4-6";
9576
- break;
9577
- case "gpt":
9578
- m2 = "gpt-5";
9579
- break;
9580
- }
9581
- if (m2)
9582
- return m2;
9583
- return {
9584
- kind: "validation-error",
9585
- message: `Invalid model name: ${m ?? "null/undefined"}`
9586
- };
9587
- }
9588
- })(modelInfo);
9589
- return modelInfo;
9590
- }
9591
-
9592
9501
  var providerConfig = {};
9593
9502
 
9594
9503
  var hasRequiredProviderConfig;
@@ -9597,7 +9506,13 @@ function requireProviderConfig() {
9597
9506
  hasRequiredProviderConfig = 1;
9598
9507
  (function(exports$1) {
9599
9508
  Object.defineProperty(exports$1, "__esModule", { value: true });
9600
- exports$1.providerConfigs = exports$1.extractOpenAiMessageText = exports$1.normalizeGeminiUsage = exports$1.normalizeOpenAiUsage = exports$1.normalizedUsageZero = void 0;
9509
+ exports$1.providerConfigs = exports$1.extractOpenAiMessageText = exports$1.normalizeGeminiUsage = exports$1.normalizeOpenAiUsage = exports$1.normalizedUsageZero = exports$1.LLM_PROVIDER_IDS = void 0;
9510
+ exports$1.LLM_PROVIDER_IDS = [
9511
+ "groq",
9512
+ "cerebras",
9513
+ "gemini",
9514
+ "openrouter"
9515
+ ];
9601
9516
  exports$1.normalizedUsageZero = {
9602
9517
  promptTokens: 0,
9603
9518
  completionTokens: 0,
@@ -10296,7 +10211,6 @@ function requireHttpLlmClient() {
10296
10211
  hasRequiredHttpLlmClient = 1;
10297
10212
  Object.defineProperty(httpLlmClient, "__esModule", { value: true });
10298
10213
  httpLlmClient.HttpLlmClient = void 0;
10299
- const model_info_1 = requireModelInfo();
10300
10214
  const logger_1 = requireLogger();
10301
10215
  const provider_config_1 = requireProviderConfig();
10302
10216
  const provider_formatters_1 = requireProviderFormatters();
@@ -10308,10 +10222,9 @@ function requireHttpLlmClient() {
10308
10222
  }
10309
10223
  async sendRequest(prompt, model, maxTokens, assistantPrefillPrompt) {
10310
10224
  const provider = this.getProviderConfig();
10311
- const providerModelName = this.getProviderModelName(model);
10312
10225
  const requestOptions = provider.buildRequest({
10313
10226
  prompt,
10314
- model: providerModelName,
10227
+ model,
10315
10228
  maxTokens,
10316
10229
  assistantPrefillPrompt
10317
10230
  }, this.apiKey);
@@ -10322,18 +10235,17 @@ function requireHttpLlmClient() {
10322
10235
  apiOperation: provider.apiOperation,
10323
10236
  requestOptions,
10324
10237
  parseResponse: provider.parseResponse,
10325
- getResponsePreview: (parsedResponse) => parsedResponse.text,
10238
+ getResponseLength: (parsedResponse) => parsedResponse.text.length,
10326
10239
  getUsage: (parsedResponse) => parsedResponse.usage
10327
10240
  });
10328
10241
  }
10329
10242
  async sendAgenticRequest(messages, tools, model, maxTokens, systemPrompt, onEvent) {
10330
10243
  const provider = this.getProviderConfig();
10331
- const providerModelName = this.getProviderModelName(model);
10332
10244
  const codec = this.getAgenticProviderCodec(provider.errorLabel);
10333
10245
  const requestOptions = codec.buildRequest({
10334
10246
  messages,
10335
10247
  tools,
10336
- model: providerModelName,
10248
+ model,
10337
10249
  maxTokens,
10338
10250
  systemPrompt,
10339
10251
  stream: !!onEvent
@@ -10346,7 +10258,7 @@ function requireHttpLlmClient() {
10346
10258
  apiOperation: "agentic",
10347
10259
  requestOptions,
10348
10260
  parseResponse,
10349
- getResponsePreview: (parsedResponse) => parsedResponse.message.content.filter((content) => content.type === "text").map((content) => content.text).join(""),
10261
+ getResponseLength: (parsedResponse) => parsedResponse.message.content.reduce((total, content) => total + (content.type === "text" ? content.text.length : 0), 0),
10350
10262
  getUsage: (parsedResponse) => parsedResponse.usage
10351
10263
  });
10352
10264
  }
@@ -10357,13 +10269,6 @@ function requireHttpLlmClient() {
10357
10269
  }
10358
10270
  return provider;
10359
10271
  }
10360
- getProviderModelName(model) {
10361
- const providerSpecificModelName = model_info_1.SUPPORTED_MODELS[model].find((pm) => pm.provider === this.providerId);
10362
- if (!providerSpecificModelName) {
10363
- 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`);
10364
- }
10365
- return providerSpecificModelName.providerModelName;
10366
- }
10367
10272
  async executeProviderCall(params) {
10368
10273
  const method = params.requestOptions.method ?? "POST";
10369
10274
  const headers = params.requestOptions.headers ?? {};
@@ -10386,7 +10291,7 @@ function requireHttpLlmClient() {
10386
10291
  const duration = Date.now() - startTime;
10387
10292
  (0, logger_1.logLlmCallComplete)(this.logger, spanId, params.provider.providerId, params.apiOperation, {
10388
10293
  status: response.status,
10389
- responseText: params.getResponsePreview(parsedResponse),
10294
+ responseLength: params.getResponseLength(parsedResponse),
10390
10295
  headers: Object.fromEntries(response.headers.entries()),
10391
10296
  usage: params.getUsage(parsedResponse)
10392
10297
  }, duration);
@@ -10441,6 +10346,112 @@ function requireHttpLlmClient() {
10441
10346
  return httpLlmClient;
10442
10347
  }
10443
10348
 
10349
+ var modelInfo = {};
10350
+
10351
+ var hasRequiredModelInfo;
10352
+ function requireModelInfo() {
10353
+ if (hasRequiredModelInfo) return modelInfo;
10354
+ hasRequiredModelInfo = 1;
10355
+ (function(exports$1) {
10356
+ Object.defineProperty(exports$1, "__esModule", { value: true });
10357
+ exports$1.MODEL_ALIAS_NAMES = exports$1.MODEL_ALIASES = void 0;
10358
+ exports$1.isLlmProviderId = isLlmProviderId;
10359
+ exports$1.isModelAliasName = isModelAliasName;
10360
+ exports$1.resolveModelInput = resolveModelInput;
10361
+ const provider_config_1 = requireProviderConfig();
10362
+ exports$1.MODEL_ALIASES = {
10363
+ fast: [
10364
+ { provider: "cerebras", model: "gpt-oss-120b" },
10365
+ { provider: "groq", model: "openai/gpt-oss-120b" },
10366
+ { provider: "openrouter", model: "openai/gpt-oss-120b" }
10367
+ ],
10368
+ gemini: [
10369
+ { provider: "gemini", model: "gemini-2.5-flash" },
10370
+ { provider: "openrouter", model: "google/gemini-2.5-flash" }
10371
+ ],
10372
+ qwen: [
10373
+ { provider: "openrouter", model: "qwen/qwen3-vl-235b-a22b-instruct" }
10374
+ ],
10375
+ sonnet: [
10376
+ { provider: "openrouter", model: "anthropic/claude-sonnet-4.6" }
10377
+ ],
10378
+ opus: [
10379
+ { provider: "openrouter", model: "anthropic/claude-opus-4.7" }
10380
+ ],
10381
+ haiku: [
10382
+ { provider: "openrouter", model: "anthropic/claude-haiku-4.5" }
10383
+ ],
10384
+ kimi: [
10385
+ { provider: "openrouter", model: "moonshotai/kimi-k2.6" }
10386
+ ],
10387
+ gpt: [
10388
+ { provider: "openrouter", model: "openai/gpt-5" }
10389
+ ]
10390
+ };
10391
+ exports$1.MODEL_ALIAS_NAMES = Object.keys(exports$1.MODEL_ALIASES);
10392
+ const MODEL_ALIAS_SET = new Set(exports$1.MODEL_ALIAS_NAMES);
10393
+ const LLM_PROVIDER_ID_SET = new Set(provider_config_1.LLM_PROVIDER_IDS);
10394
+ function isLlmProviderId(value) {
10395
+ return typeof value === "string" && LLM_PROVIDER_ID_SET.has(value);
10396
+ }
10397
+ function isModelAliasName(value) {
10398
+ return typeof value === "string" && MODEL_ALIAS_SET.has(value);
10399
+ }
10400
+ function validationError(message) {
10401
+ return {
10402
+ kind: "validation-error",
10403
+ message
10404
+ };
10405
+ }
10406
+ function validateProviderModel(input, configuredProviders) {
10407
+ if (!isLlmProviderId(input.provider)) {
10408
+ return validationError(`Invalid LLM provider: ${String(input.provider)}`);
10409
+ }
10410
+ if (!configuredProviders.has(input.provider)) {
10411
+ return validationError(`LLM provider ${input.provider} is not configured. Please check your API keys.`);
10412
+ }
10413
+ if (typeof input.model !== "string") {
10414
+ return validationError("model.model must be a string");
10415
+ }
10416
+ const model = input.model.trim();
10417
+ if (!model) {
10418
+ return validationError("model.model must be a non-empty string");
10419
+ }
10420
+ if (input.provider === "gemini" && model.startsWith("models/")) {
10421
+ return validationError('Gemini model names must use bare model IDs, for example "gemini-2.5-flash", not "models/gemini-2.5-flash".');
10422
+ }
10423
+ return {
10424
+ provider: input.provider,
10425
+ model
10426
+ };
10427
+ }
10428
+ function resolveModelInput(input, configuredProviders) {
10429
+ if (input == null) {
10430
+ return resolveModelInput({ alias: "fast" }, configuredProviders);
10431
+ }
10432
+ if (typeof input !== "object") {
10433
+ return validationError("model must be an object with either alias or provider/model fields");
10434
+ }
10435
+ if ("provider" in input || "model" in input) {
10436
+ return validateProviderModel(input, configuredProviders);
10437
+ }
10438
+ if ("alias" in input) {
10439
+ const alias = input.alias;
10440
+ if (!isModelAliasName(alias)) {
10441
+ return validationError(`Invalid model alias: ${String(alias)}`);
10442
+ }
10443
+ const configuredTarget = exports$1.MODEL_ALIASES[alias].find((target) => configuredProviders.has(target.provider));
10444
+ if (!configuredTarget) {
10445
+ return validationError(`No configured provider found for model alias ${alias}. Please check your API keys.`);
10446
+ }
10447
+ return configuredTarget;
10448
+ }
10449
+ return validationError("model must include either alias or provider/model fields");
10450
+ }
10451
+ })(modelInfo);
10452
+ return modelInfo;
10453
+ }
10454
+
10444
10455
  var castArrayPromptBuilder = {};
10445
10456
 
10446
10457
  var promptTemplateUtils = {};
@@ -10743,28 +10754,26 @@ function requireNuaLlmClient() {
10743
10754
  }
10744
10755
  });
10745
10756
  }
10746
- getClientForModel(model) {
10747
- const supported = model_info_1.SUPPORTED_MODELS[model];
10748
- if (!supported || supported.length === 0) {
10749
- throw new Error(`Model ${model} is not supported or configuration is missing.`);
10750
- }
10751
- for (const option of supported) {
10752
- if (this.clients.has(option.provider)) {
10753
- return this.clients.get(option.provider);
10754
- }
10755
- }
10756
- throw new Error(`No configured provider found for model ${model}. Please check your API keys.`);
10757
+ getConfiguredProviderIds() {
10758
+ return new Set(this.clients.keys());
10757
10759
  }
10758
- resolveModel(modelName) {
10759
- const result = (0, model_info_1.parseCanonicalModelName)(modelName);
10760
+ resolveModel(model) {
10761
+ const result = (0, model_info_1.resolveModelInput)(model, this.getConfiguredProviderIds());
10760
10762
  if ((0, nua_errors_1.isNuaValidationError)(result)) {
10761
10763
  throw new Error(result.message);
10762
10764
  }
10763
10765
  return result;
10764
10766
  }
10767
+ getClientForProvider(provider) {
10768
+ const client = this.clients.get(provider);
10769
+ if (!client) {
10770
+ throw new Error(`LLM provider ${provider} is not configured. Please check your API keys.`);
10771
+ }
10772
+ return client;
10773
+ }
10765
10774
  async castValue(params) {
10766
- const model = this.resolveModel(params.model);
10767
- const client = this.getClientForModel(model);
10775
+ const providerModel = this.resolveModel(params.model);
10776
+ const client = this.getClientForProvider(providerModel.provider);
10768
10777
  const maxTokens = params.maxTokens || 4096;
10769
10778
  const temperature = params.temperature ?? 0;
10770
10779
  const prompt = cast_prompt_builder_1.default.buildFullPrompt(params);
@@ -10773,7 +10782,7 @@ function requireNuaLlmClient() {
10773
10782
  const result = await (0, call_llm_service_1.callLLM)(
10774
10783
  client,
10775
10784
  prompt,
10776
- model,
10785
+ providerModel.model,
10777
10786
  maxTokens,
10778
10787
  temperature,
10779
10788
  3,
@@ -10795,8 +10804,8 @@ function requireNuaLlmClient() {
10795
10804
  }
10796
10805
  }
10797
10806
  async castArray(params) {
10798
- const model = this.resolveModel(params.model);
10799
- const client = this.getClientForModel(model);
10807
+ const providerModel = this.resolveModel(params.model);
10808
+ const client = this.getClientForProvider(providerModel.provider);
10800
10809
  const maxTokens = params.maxTokens || 4096;
10801
10810
  const temperature = params.temperature ?? 0;
10802
10811
  const validData = (0, validate_mappable_input_data_1.validateMappableInputData)(params.data, params.input.primaryKey);
@@ -10809,7 +10818,7 @@ function requireNuaLlmClient() {
10809
10818
  const prompt = cast_array_prompt_builder_1.default.buildFullPrompt(params, validData);
10810
10819
  const validationFn = (0, nua_json_schema_value_validation_1.buildNuaJsonSchemaValueValidation)("library-req", params.output.effectiveSchema);
10811
10820
  try {
10812
- const result = await (0, call_llm_service_1.callLLM)(client, prompt, model, maxTokens, temperature, 3, validationFn);
10821
+ const result = await (0, call_llm_service_1.callLLM)(client, prompt, providerModel.model, maxTokens, temperature, 3, validationFn);
10813
10822
  return {
10814
10823
  success: true,
10815
10824
  data: result.data,
@@ -10826,8 +10835,8 @@ function requireNuaLlmClient() {
10826
10835
  }
10827
10836
  async runAgent(params) {
10828
10837
  try {
10829
- const model = this.resolveModel(params.model);
10830
- const client = this.getClientForModel(model);
10838
+ const providerModel = this.resolveModel(params.model);
10839
+ const client = this.getClientForProvider(providerModel.provider);
10831
10840
  const maxTokens = params.maxTokens ?? 4096;
10832
10841
  const maxTurns = params.maxTurns ?? 10;
10833
10842
  return (0, agent_loop_1.runAgentLoop)({
@@ -10836,7 +10845,7 @@ function requireNuaLlmClient() {
10836
10845
  systemPrompt: params.systemPrompt,
10837
10846
  maxTurns,
10838
10847
  onEvent: params.onEvent,
10839
- sendRequest: (messages, tools, systemPrompt) => client.sendAgenticRequest(messages, tools, model, maxTokens, systemPrompt, params.onEvent)
10848
+ sendRequest: (messages, tools, systemPrompt) => client.sendAgenticRequest(messages, tools, providerModel.model, maxTokens, systemPrompt, params.onEvent)
10840
10849
  });
10841
10850
  } catch (e) {
10842
10851
  return {
@@ -11021,7 +11030,7 @@ function requireDist() {
11021
11030
  return mod && mod.__esModule ? mod : { "default": mod };
11022
11031
  };
11023
11032
  Object.defineProperty(exports$1, "__esModule", { value: true });
11024
- exports$1.runAgentLoop = exports$1.stableStringify = exports$1.validateJsonSchema = exports$1.providerConfigs = exports$1.normalizedUsageZero = exports$1.castArrayPromptBuilder = exports$1.castPromptBuilder = void 0;
11033
+ exports$1.runAgentLoop = exports$1.stableStringify = exports$1.validateJsonSchema = exports$1.providerConfigs = exports$1.normalizedUsageZero = exports$1.LLM_PROVIDER_IDS = exports$1.castArrayPromptBuilder = exports$1.castPromptBuilder = void 0;
11025
11034
  __exportStar(requireNuaLlmClient(), exports$1);
11026
11035
  __exportStar(requireLogger(), exports$1);
11027
11036
  __exportStar(requireTypes(), exports$1);
@@ -11035,6 +11044,9 @@ function requireDist() {
11035
11044
  return __importDefault(cast_array_prompt_builder_1).default;
11036
11045
  } });
11037
11046
  var provider_config_1 = requireProviderConfig();
11047
+ Object.defineProperty(exports$1, "LLM_PROVIDER_IDS", { enumerable: true, get: function() {
11048
+ return provider_config_1.LLM_PROVIDER_IDS;
11049
+ } });
11038
11050
  Object.defineProperty(exports$1, "normalizedUsageZero", { enumerable: true, get: function() {
11039
11051
  return provider_config_1.normalizedUsageZero;
11040
11052
  } });
@@ -11068,9 +11080,6 @@ const normalizedUsageZero = {
11068
11080
  };
11069
11081
  class DirectBackend {
11070
11082
  constructor(config) {
11071
- if (!config.model) {
11072
- throw new Error("model is required for direct mode");
11073
- }
11074
11083
  this.model = config.model;
11075
11084
  this.client = new distExports.NuaLlmClient({ providers: config.providers });
11076
11085
  }
@@ -11095,7 +11104,7 @@ class DirectBackend {
11095
11104
  success: true,
11096
11105
  data: result.data,
11097
11106
  usage: result.usage || normalizedUsageZero,
11098
- model,
11107
+ model: formatModelInput(model),
11099
11108
  latencyMs,
11100
11109
  source: "direct",
11101
11110
  meta: {}
@@ -11127,13 +11136,18 @@ class DirectBackend {
11127
11136
  success: true,
11128
11137
  data: result.data,
11129
11138
  usage: result.usage || normalizedUsageZero,
11130
- model,
11139
+ model: formatModelInput(model),
11131
11140
  latencyMs,
11132
11141
  source: "direct",
11133
11142
  meta: {}
11134
11143
  };
11135
11144
  }
11136
11145
  }
11146
+ function formatModelInput(model) {
11147
+ if (!model) return "fast";
11148
+ if ("alias" in model) return model.alias;
11149
+ return `${model.provider}:${model.model}`;
11150
+ }
11137
11151
 
11138
11152
  function resolveConfigValue(config, key, envVar) {
11139
11153
  if (config[key]) return config[key];
@@ -1,7 +1,7 @@
1
1
  import { CastArrayParams, CastResult, CastValueParams, LlmBackend } from './types';
2
- import { LlmProviderId } from 'nua-llm-core';
2
+ import type { LlmProviderId, ModelInput } from 'nua-llm-core';
3
3
  export type DirectConfig = {
4
- model: string;
4
+ model?: ModelInput;
5
5
  providers: {
6
6
  [key in LlmProviderId]?: {
7
7
  apiKey: string;