@ax-llm/ax 10.0.46 → 10.0.48

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/index.js CHANGED
@@ -74,16 +74,16 @@ var AxSpanKindValues = /* @__PURE__ */ ((AxSpanKindValues2) => {
74
74
  })(AxSpanKindValues || {});
75
75
 
76
76
  // util/apicall.ts
77
- import path from "path";
78
77
  import {
79
78
  ReadableStream,
80
- TextDecoderStream as TextDecoderStreamNative
79
+ TextDecoderStream as TextDecoderStreamNative,
80
+ TransformStream as TransformStream3
81
81
  } from "stream/web";
82
82
  import "@opentelemetry/api";
83
83
 
84
84
  // util/sse.ts
85
- import { TransformStream as TransformStream2 } from "stream/web";
86
- var SSEParser = class extends TransformStream2 {
85
+ import { TransformStream } from "stream/web";
86
+ var SSEParser = class extends TransformStream {
87
87
  buffer = "";
88
88
  currentEvent = { rawData: "" };
89
89
  dataParser;
@@ -173,7 +173,7 @@ var SSEParser = class extends TransformStream2 {
173
173
 
174
174
  // util/stream.ts
175
175
  import {
176
- TransformStream as TransformStream3
176
+ TransformStream as TransformStream2
177
177
  } from "stream/web";
178
178
  var TextDecodeTransformer = class {
179
179
  decoder;
@@ -196,7 +196,7 @@ var TextDecodeTransformer = class {
196
196
  }
197
197
  }
198
198
  };
199
- var TextDecoderStreamPolyfill = class extends TransformStream3 {
199
+ var TextDecoderStreamPolyfill = class extends TransformStream2 {
200
200
  constructor() {
201
201
  super(new TextDecodeTransformer());
202
202
  }
@@ -207,7 +207,6 @@ var defaultRetryConfig = {
207
207
  maxRetries: 3,
208
208
  initialDelayMs: 1e3,
209
209
  maxDelayMs: 6e4,
210
- // Increased to 60 seconds
211
210
  backoffFactor: 2,
212
211
  retryableStatusCodes: [500, 408, 429, 502, 503, 504]
213
212
  };
@@ -218,18 +217,19 @@ var AxAIServiceError = class extends Error {
218
217
  super(message);
219
218
  this.url = url;
220
219
  this.requestBody = requestBody;
221
- this.context = context;
222
- this.name = "AxAIServiceError";
220
+ this.name = this.constructor.name;
223
221
  this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
224
222
  this.errorId = crypto.randomUUID();
223
+ this.context = context;
225
224
  }
226
225
  timestamp;
227
226
  errorId;
227
+ context;
228
228
  toString() {
229
229
  return `${this.name} [${this.errorId}]: ${this.message}
230
230
  Timestamp: ${this.timestamp}
231
231
  URL: ${this.url}${this.requestBody ? `
232
- Request Body: ${JSON.stringify(this.requestBody, null, 2)}` : ""}${this.context ? `
232
+ Request Body: ${JSON.stringify(this.requestBody, null, 2)}` : ""}${Object.keys(this.context).length ? `
233
233
  Context: ${JSON.stringify(this.context, null, 2)}` : ""}`;
234
234
  }
235
235
  toJSON() {
@@ -254,7 +254,7 @@ var AxAIServiceStatusError = class extends AxAIServiceError {
254
254
  });
255
255
  this.status = status;
256
256
  this.statusText = statusText;
257
- this.name = "AxAIServiceStatusError";
257
+ this.name = this.constructor.name;
258
258
  }
259
259
  };
260
260
  var AxAIServiceNetworkError = class extends AxAIServiceError {
@@ -265,14 +265,14 @@ var AxAIServiceNetworkError = class extends AxAIServiceError {
265
265
  ...context
266
266
  });
267
267
  this.originalError = originalError;
268
- this.name = "AxAIServiceNetworkError";
268
+ this.name = this.constructor.name;
269
269
  this.stack = originalError.stack;
270
270
  }
271
271
  };
272
272
  var AxAIServiceResponseError = class extends AxAIServiceError {
273
273
  constructor(message, url, requestBody, context) {
274
274
  super(message, url, requestBody, context);
275
- this.name = "AxAIServiceResponseError";
275
+ this.name = this.constructor.name;
276
276
  }
277
277
  };
278
278
  var AxAIServiceStreamTerminatedError = class extends AxAIServiceError {
@@ -282,7 +282,7 @@ var AxAIServiceStreamTerminatedError = class extends AxAIServiceError {
282
282
  ...context
283
283
  });
284
284
  this.lastChunk = lastChunk;
285
- this.name = "AxAIServiceStreamTerminatedError";
285
+ this.name = this.constructor.name;
286
286
  }
287
287
  };
288
288
  var AxAIServiceTimeoutError = class extends AxAIServiceError {
@@ -291,13 +291,13 @@ var AxAIServiceTimeoutError = class extends AxAIServiceError {
291
291
  timeoutMs,
292
292
  ...context
293
293
  });
294
- this.name = "AxAIServiceTimeoutError";
294
+ this.name = this.constructor.name;
295
295
  }
296
296
  };
297
297
  var AxAIServiceAuthenticationError = class extends AxAIServiceError {
298
298
  constructor(url, requestBody, context) {
299
299
  super("Authentication failed", url, requestBody, context);
300
- this.name = "AxAIServiceAuthenticationError";
300
+ this.name = this.constructor.name;
301
301
  }
302
302
  };
303
303
  function calculateRetryDelay(attempt, config) {
@@ -317,14 +317,31 @@ function updateRetryMetrics(metrics) {
317
317
  metrics.retryCount++;
318
318
  metrics.lastRetryTime = Date.now();
319
319
  }
320
+ function shouldRetry(error, status, attempt, config) {
321
+ if (attempt >= config.maxRetries) return false;
322
+ if (status && config.retryableStatusCodes.includes(status)) return true;
323
+ return error instanceof AxAIServiceNetworkError && !(error instanceof AxAIServiceAuthenticationError);
324
+ }
320
325
  var apiCall = async (api, json) => {
321
326
  const retryConfig = { ...defaultRetryConfig, ...api.retry };
322
327
  const timeoutMs = api.timeout ?? defaultTimeoutMs;
323
328
  const metrics = createRequestMetrics();
329
+ let timeoutId;
324
330
  const baseUrl = new URL(process.env["PROXY"] ?? api.url);
325
- const apiPath = path.join(baseUrl.pathname, api.name ?? "/", baseUrl.search);
331
+ const apiPath = [baseUrl.pathname, api.name].filter(Boolean).join("/").replace(/\/+/g, "/");
326
332
  const apiUrl = new URL(apiPath, baseUrl);
327
333
  const requestId = crypto.randomUUID();
334
+ if (api.validateRequest) {
335
+ const isValid = await api.validateRequest(json);
336
+ if (!isValid) {
337
+ throw new AxAIServiceResponseError(
338
+ "Invalid request data",
339
+ apiUrl.href,
340
+ json,
341
+ { validation: "request" }
342
+ );
343
+ }
344
+ }
328
345
  if (api.span?.isRecording()) {
329
346
  api.span.setAttributes({
330
347
  "http.request.method": api.put ? "PUT" : "POST",
@@ -336,7 +353,7 @@ var apiCall = async (api, json) => {
336
353
  let attempt = 0;
337
354
  while (true) {
338
355
  const controller = new AbortController();
339
- let timeoutId = setTimeout(() => {
356
+ timeoutId = setTimeout(() => {
340
357
  controller.abort("Request timeout");
341
358
  }, timeoutMs);
342
359
  try {
@@ -355,7 +372,7 @@ var apiCall = async (api, json) => {
355
372
  if (res.status === 401 || res.status === 403) {
356
373
  throw new AxAIServiceAuthenticationError(apiUrl.href, json, { metrics });
357
374
  }
358
- if (res.status >= 400 && attempt < retryConfig.maxRetries && retryConfig.retryableStatusCodes.includes(res.status)) {
375
+ if (res.status >= 400 && shouldRetry(new Error(), res.status, attempt, retryConfig)) {
359
376
  const delay = calculateRetryDelay(attempt, retryConfig);
360
377
  attempt++;
361
378
  updateRetryMetrics(metrics);
@@ -369,7 +386,7 @@ var apiCall = async (api, json) => {
369
386
  "metrics.lastRetryTime": metrics.lastRetryTime
370
387
  });
371
388
  }
372
- clearTimeout(timeoutId);
389
+ await new Promise((resolve) => setTimeout(resolve, delay));
373
390
  continue;
374
391
  }
375
392
  if (res.status >= 400) {
@@ -383,6 +400,17 @@ var apiCall = async (api, json) => {
383
400
  }
384
401
  if (!api.stream) {
385
402
  const resJson = await res.json();
403
+ if (api.validateResponse) {
404
+ const isValid = await api.validateResponse(resJson);
405
+ if (!isValid) {
406
+ throw new AxAIServiceResponseError(
407
+ "Invalid response data",
408
+ apiUrl.href,
409
+ json,
410
+ { validation: "response" }
411
+ );
412
+ }
413
+ }
386
414
  if (api.span?.isRecording()) {
387
415
  api.span.setAttributes({
388
416
  "response.time": Date.now() - metrics.startTime,
@@ -401,7 +429,7 @@ var apiCall = async (api, json) => {
401
429
  }
402
430
  let lastChunk;
403
431
  let chunkCount = 0;
404
- const trackingStream = new TransformStream({
432
+ const trackingStream = new TransformStream3({
405
433
  transform(chunk, controller2) {
406
434
  lastChunk = chunk;
407
435
  chunkCount++;
@@ -409,7 +437,7 @@ var apiCall = async (api, json) => {
409
437
  metrics.lastChunkTime = Date.now();
410
438
  controller2.enqueue(chunk);
411
439
  },
412
- flush(controller2) {
440
+ flush() {
413
441
  if (api.span?.isRecording()) {
414
442
  api.span.setAttributes({
415
443
  "stream.chunks": chunkCount,
@@ -417,10 +445,10 @@ var apiCall = async (api, json) => {
417
445
  "response.retries": metrics.retryCount
418
446
  });
419
447
  }
420
- controller2.terminate();
421
448
  }
422
449
  });
423
- const wrappedStream = new ReadableStream({
450
+ let closed = false;
451
+ return new ReadableStream({
424
452
  start(controller2) {
425
453
  const reader = res.body.pipeThrough(new textDecoderStream()).pipeThrough(new SSEParser()).pipeThrough(trackingStream).getReader();
426
454
  async function read() {
@@ -428,11 +456,14 @@ var apiCall = async (api, json) => {
428
456
  while (true) {
429
457
  const { done, value } = await reader.read();
430
458
  if (done) {
431
- controller2.close();
459
+ if (!closed) {
460
+ closed = true;
461
+ controller2.close();
462
+ }
432
463
  break;
433
- } else {
434
- controller2.enqueue(value);
435
464
  }
465
+ if (closed) break;
466
+ controller2.enqueue(value);
436
467
  }
437
468
  } catch (e) {
438
469
  const error = e;
@@ -449,26 +480,42 @@ var apiCall = async (api, json) => {
449
480
  { streamMetrics }
450
481
  )
451
482
  );
452
- } else {
483
+ } else if (error instanceof TypeError && error.message.includes("cancelled")) {
453
484
  controller2.error(
454
- new AxAIServiceResponseError(
455
- `Stream processing error: ${error.message}`,
485
+ new AxAIServiceStreamTerminatedError(
456
486
  apiUrl.href,
457
487
  json,
458
- { streamMetrics }
488
+ lastChunk,
489
+ {
490
+ streamMetrics,
491
+ cancelReason: "Stream cancelled by client"
492
+ }
459
493
  )
460
494
  );
495
+ } else {
496
+ controller2.error(
497
+ new AxAIServiceNetworkError(error, apiUrl.href, json, {
498
+ streamMetrics
499
+ })
500
+ );
461
501
  }
502
+ throw error;
462
503
  } finally {
504
+ clearTimeout(timeoutId);
463
505
  reader.releaseLock();
506
+ if (api.span?.isRecording()) {
507
+ api.span.end();
508
+ }
464
509
  }
465
510
  }
466
511
  read();
512
+ },
513
+ // When the consumer cancels the stream, set our flag to stop processing further.
514
+ cancel() {
515
+ closed = true;
467
516
  }
468
517
  });
469
- return wrappedStream;
470
518
  } catch (error) {
471
- clearTimeout(timeoutId);
472
519
  if (error instanceof Error && error.name === "AbortError") {
473
520
  throw new AxAIServiceTimeoutError(apiUrl.href, timeoutMs, json, {
474
521
  metrics
@@ -481,7 +528,7 @@ var apiCall = async (api, json) => {
481
528
  "error.retries": metrics.retryCount
482
529
  });
483
530
  }
484
- if (error instanceof AxAIServiceNetworkError && attempt < retryConfig.maxRetries) {
531
+ if (error instanceof AxAIServiceNetworkError && shouldRetry(error, void 0, attempt, retryConfig)) {
485
532
  const delay = calculateRetryDelay(attempt, retryConfig);
486
533
  attempt++;
487
534
  updateRetryMetrics(metrics);
@@ -495,12 +542,20 @@ var apiCall = async (api, json) => {
495
542
  "metrics.lastRetryTime": metrics.lastRetryTime
496
543
  });
497
544
  }
545
+ await new Promise((resolve) => setTimeout(resolve, delay));
498
546
  continue;
499
547
  }
500
548
  if (error instanceof AxAIServiceError) {
501
549
  error.context["metrics"] = metrics;
502
550
  }
503
551
  throw error;
552
+ } finally {
553
+ if (timeoutId !== void 0) {
554
+ clearTimeout(timeoutId);
555
+ }
556
+ if (api.span?.isRecording()) {
557
+ api.span.end();
558
+ }
504
559
  }
505
560
  }
506
561
  };
@@ -1552,8 +1607,9 @@ function mapFinishReason(stopReason) {
1552
1607
 
1553
1608
  // ai/openai/types.ts
1554
1609
  var AxAIOpenAIModel = /* @__PURE__ */ ((AxAIOpenAIModel2) => {
1555
- AxAIOpenAIModel2["O1Preview"] = "o1-preview";
1610
+ AxAIOpenAIModel2["O1"] = "o1";
1556
1611
  AxAIOpenAIModel2["O1Mini"] = "o1-mini";
1612
+ AxAIOpenAIModel2["O3Mini"] = "o3-mini";
1557
1613
  AxAIOpenAIModel2["GPT4"] = "gpt-4";
1558
1614
  AxAIOpenAIModel2["GPT4O"] = "gpt-4o";
1559
1615
  AxAIOpenAIModel2["GPT4OMini"] = "gpt-4o-mini";
@@ -1576,7 +1632,7 @@ var AxAIOpenAIEmbedModel = /* @__PURE__ */ ((AxAIOpenAIEmbedModel2) => {
1576
1632
  // ai/openai/info.ts
1577
1633
  var axModelInfoOpenAI = [
1578
1634
  {
1579
- name: "o1-preview" /* O1Preview */,
1635
+ name: "o1" /* O1 */,
1580
1636
  currency: "usd",
1581
1637
  promptTokenCostPer1M: 15,
1582
1638
  completionTokenCostPer1M: 60
@@ -1584,8 +1640,14 @@ var axModelInfoOpenAI = [
1584
1640
  {
1585
1641
  name: "o1-mini" /* O1Mini */,
1586
1642
  currency: "usd",
1587
- promptTokenCostPer1M: 3,
1588
- completionTokenCostPer1M: 12
1643
+ promptTokenCostPer1M: 1.1,
1644
+ completionTokenCostPer1M: 14.4
1645
+ },
1646
+ {
1647
+ name: "o3-mini" /* O3Mini */,
1648
+ currency: "usd",
1649
+ promptTokenCostPer1M: 1.1,
1650
+ completionTokenCostPer1M: 4.4
1589
1651
  },
1590
1652
  {
1591
1653
  name: "gpt-4" /* GPT4 */,
@@ -1685,16 +1747,12 @@ var AxAIOpenAIImpl = class {
1685
1747
  parameters: v.parameters
1686
1748
  }
1687
1749
  }));
1688
- if (tools && isO1Model(model)) {
1689
- throw new Error("Functions are not supported for O1 models");
1690
- }
1691
1750
  const toolsChoice = !req.functionCall && req.functions && req.functions.length > 0 ? "auto" : req.functionCall;
1692
1751
  const messages = createMessages2(req);
1693
1752
  const frequencyPenalty = req.modelConfig?.frequencyPenalty ?? this.config.frequencyPenalty;
1694
1753
  const stream = req.modelConfig?.stream ?? this.config.stream;
1695
- if (stream && isO1Model(model)) {
1696
- throw new Error("Streaming is not supported for O1 models");
1697
- }
1754
+ const reasoningEffort = isReasoningModel(model) ? this.config.reasoningEffort : void 0;
1755
+ const store = this.config.store;
1698
1756
  const reqValue = {
1699
1757
  model,
1700
1758
  messages,
@@ -1709,7 +1767,9 @@ var AxAIOpenAIImpl = class {
1709
1767
  presence_penalty: req.modelConfig?.presencePenalty ?? this.config.presencePenalty,
1710
1768
  logit_bias: this.config.logitBias,
1711
1769
  ...frequencyPenalty ? { frequency_penalty: frequencyPenalty } : {},
1712
- ...stream && this.streamingUsage ? { stream: true, stream_options: { include_usage: true } } : {}
1770
+ ...stream && this.streamingUsage ? { stream: true, stream_options: { include_usage: true } } : {},
1771
+ ...reasoningEffort ? { reasoning_effort: reasoningEffort } : {},
1772
+ ...store ? { store } : {}
1713
1773
  };
1714
1774
  return [apiConfig, reqValue];
1715
1775
  }
@@ -1835,12 +1895,6 @@ var mapFinishReason2 = (finishReason) => {
1835
1895
  };
1836
1896
  function createMessages2(req) {
1837
1897
  return req.chatPrompt.map((msg) => {
1838
- if (msg.role === "system" && isO1Model(req.model)) {
1839
- msg = {
1840
- role: "user",
1841
- content: msg.content
1842
- };
1843
- }
1844
1898
  switch (msg.role) {
1845
1899
  case "system":
1846
1900
  return { role: "system", content: msg.content };
@@ -1930,14 +1984,14 @@ var AxAIOpenAI = class extends AxBaseAI {
1930
1984
  embedModel: _config.embedModel
1931
1985
  },
1932
1986
  options,
1933
- supportFor: (model) => {
1934
- return isO1Model(model) ? { functions: false, streaming: false } : { functions: true, streaming: true };
1987
+ supportFor: () => {
1988
+ return { functions: true, streaming: true };
1935
1989
  },
1936
1990
  modelMap
1937
1991
  });
1938
1992
  }
1939
1993
  };
1940
- var isO1Model = (model) => ["o1-mini" /* O1Mini */, "o1-preview" /* O1Preview */].includes(
1994
+ var isReasoningModel = (model) => ["o1-mini" /* O1Mini */, "o1" /* O1 */, "o3-mini" /* O3Mini */].includes(
1941
1995
  model
1942
1996
  );
1943
1997
 
@@ -3663,21 +3717,13 @@ var AxMemory = class {
3663
3717
 
3664
3718
  // dsp/asserts.ts
3665
3719
  var AxAssertionError = class extends Error {
3666
- values;
3667
- optional;
3668
3720
  constructor({
3669
- message,
3670
- values,
3671
- optional
3721
+ message
3672
3722
  }) {
3673
3723
  super(message);
3674
- this.values = values;
3675
- this.optional = optional;
3676
3724
  this.name = this.constructor.name;
3677
3725
  this.stack = new Error().stack;
3678
3726
  }
3679
- getValue = () => this.values;
3680
- getOptional = () => this.optional;
3681
3727
  getFixingInstructions = () => {
3682
3728
  const extraFields = [];
3683
3729
  extraFields.push({
@@ -3690,13 +3736,16 @@ var AxAssertionError = class extends Error {
3690
3736
  };
3691
3737
  var assertAssertions = (asserts, values) => {
3692
3738
  for (const assert of asserts) {
3693
- const { fn, message, optional } = assert;
3739
+ const { fn, message } = assert;
3694
3740
  const res = fn(values);
3695
3741
  if (res === void 0) {
3696
3742
  continue;
3697
3743
  }
3698
- if (!res && message) {
3699
- throw new AxAssertionError({ message, values, optional });
3744
+ if (!res) {
3745
+ if (!message) {
3746
+ throw new Error(`Assertion Failed: No message provided for assertion`);
3747
+ }
3748
+ throw new AxAssertionError({ message });
3700
3749
  }
3701
3750
  }
3702
3751
  };
@@ -3712,13 +3761,13 @@ var assertStreamingAssertions = (asserts, values, xstate, content, final) => {
3712
3761
  }
3713
3762
  const currValue = content.substring(xstate.s);
3714
3763
  for (const assert of fieldAsserts) {
3715
- const { message, optional, fn } = assert;
3764
+ const { message, fn } = assert;
3716
3765
  const res = fn(currValue, final);
3717
3766
  if (res === void 0) {
3718
3767
  continue;
3719
3768
  }
3720
3769
  if (!res && message) {
3721
- throw new AxAssertionError({ message, values, optional });
3770
+ throw new AxAssertionError({ message });
3722
3771
  }
3723
3772
  }
3724
3773
  };
@@ -4972,13 +5021,11 @@ var ValidationError = class extends Error {
4972
5021
  super(message);
4973
5022
  this.fields = fields;
4974
5023
  this.name = this.constructor.name;
4975
- Error.captureStackTrace(this, this.constructor);
4976
5024
  }
4977
- getFields = () => this.fields;
4978
5025
  getFixingInstructions = () => {
4979
5026
  return this.fields.map((field) => ({
4980
5027
  name: "outputError",
4981
- title: "Error In Output",
5028
+ title: "Errors In Output Fields",
4982
5029
  description: `Please fix and return the field \`${field.title}\` of type \`${toFieldType(field.type)}\`, ${this.message}.`
4983
5030
  }));
4984
5031
  };
@@ -5182,8 +5229,10 @@ function* streamValues(sig, values, xstate, content, final = false) {
5182
5229
  const v = content.substring(s);
5183
5230
  const v1 = v.replace(/[\s\n\t]+$/, "");
5184
5231
  const v2 = pos === 0 ? v1.trimStart() : v1;
5185
- yield { [fieldName]: v2 };
5186
- xstate.streamedIndex[fieldName] = pos + v1.length;
5232
+ if (v2.length > 0) {
5233
+ yield { [fieldName]: v2 };
5234
+ xstate.streamedIndex[fieldName] = pos + v1.length;
5235
+ }
5187
5236
  return;
5188
5237
  }
5189
5238
  }
@@ -5192,7 +5241,7 @@ function* streamValues(sig, values, xstate, content, final = false) {
5192
5241
  if (Array.isArray(value)) {
5193
5242
  const s = xstate.streamedIndex[key] ?? 0;
5194
5243
  const v = value.slice(s);
5195
- if (v) {
5244
+ if (v && v.length > 0) {
5196
5245
  yield { [key]: v };
5197
5246
  xstate.streamedIndex[key] = s + 1;
5198
5247
  }
@@ -5288,7 +5337,7 @@ var extractBlock = (input) => {
5288
5337
  // dsp/jsonschema.ts
5289
5338
  var validateJSONSchema = (schema) => {
5290
5339
  const errors = [];
5291
- const validateSchemaObject = (schema2, path2 = "") => {
5340
+ const validateSchemaObject = (schema2, path = "") => {
5292
5341
  const validTypes = [
5293
5342
  "array",
5294
5343
  "integer",
@@ -5299,31 +5348,31 @@ var validateJSONSchema = (schema) => {
5299
5348
  "object"
5300
5349
  ];
5301
5350
  if (!validTypes.includes(schema2.type)) {
5302
- errors.push(`Invalid type '${schema2.type}' at ${path2 || "root"}`);
5351
+ errors.push(`Invalid type '${schema2.type}' at ${path || "root"}`);
5303
5352
  return;
5304
5353
  }
5305
5354
  if (schema2.type === "object" && schema2.properties) {
5306
5355
  if (typeof schema2.properties !== "object" || Array.isArray(schema2.properties)) {
5307
- errors.push(`Invalid properties object at ${path2 || "root"}`);
5356
+ errors.push(`Invalid properties object at ${path || "root"}`);
5308
5357
  } else {
5309
5358
  for (const key in schema2.properties) {
5310
5359
  const value = schema2.properties[key];
5311
5360
  if (typeof value !== "object") {
5312
- errors.push(`Invalid schema object at ${path2}${key}`);
5361
+ errors.push(`Invalid schema object at ${path}${key}`);
5313
5362
  continue;
5314
5363
  }
5315
- validateSchemaObject(value, `${path2}${key}.`);
5364
+ validateSchemaObject(value, `${path}${key}.`);
5316
5365
  }
5317
5366
  }
5318
5367
  if (schema2.required && !Array.isArray(schema2.required)) {
5319
- errors.push(`'required' should be an array at ${path2 || "root"}`);
5368
+ errors.push(`'required' should be an array at ${path || "root"}`);
5320
5369
  }
5321
5370
  }
5322
5371
  if (schema2.type === "array" && schema2.items) {
5323
5372
  if (typeof schema2.items !== "object") {
5324
- errors.push(`Invalid items schema at ${path2 || "root"}`);
5373
+ errors.push(`Invalid items schema at ${path || "root"}`);
5325
5374
  } else {
5326
- validateSchemaObject(schema2.items, `${path2}items.`);
5375
+ validateSchemaObject(schema2.items, `${path}items.`);
5327
5376
  }
5328
5377
  }
5329
5378
  };
@@ -5334,6 +5383,49 @@ var validateJSONSchema = (schema) => {
5334
5383
  };
5335
5384
 
5336
5385
  // dsp/functions.ts
5386
+ var AxFunctionError = class extends Error {
5387
+ constructor(fields) {
5388
+ super();
5389
+ this.fields = fields;
5390
+ this.name = this.constructor.name;
5391
+ }
5392
+ getFields = () => this.fields;
5393
+ };
5394
+ var FunctionError = class extends Error {
5395
+ fields;
5396
+ func;
5397
+ constructor({
5398
+ fields,
5399
+ func
5400
+ }) {
5401
+ super();
5402
+ this.fields = fields;
5403
+ this.func = func;
5404
+ this.name = this.constructor.name;
5405
+ }
5406
+ getFieldDescription(fieldName) {
5407
+ if (!this.func.parameters?.properties?.[fieldName]) {
5408
+ return "";
5409
+ }
5410
+ const fieldSchema = this.func.parameters.properties[fieldName];
5411
+ let description = fieldSchema.description;
5412
+ if (fieldSchema.enum?.length) {
5413
+ description += ` Allowed values are: ${fieldSchema.enum.join(", ")}`;
5414
+ }
5415
+ return description;
5416
+ }
5417
+ getFixingInstructions = () => {
5418
+ return this.fields.map((fieldError) => {
5419
+ const schemaDescription = this.getFieldDescription(fieldError.field);
5420
+ const fullDescription = schemaDescription ? `${fieldError.message}. ${schemaDescription}` : fieldError.message;
5421
+ return {
5422
+ name: "functionArgumentError",
5423
+ title: `Errors in Function '${this.func.name}' Arguments`,
5424
+ description: `Please fix the argument '${fieldError.field}' in function '${this.func.name}': ${fullDescription}`
5425
+ };
5426
+ });
5427
+ };
5428
+ };
5337
5429
  var AxFunctionProcessor = class {
5338
5430
  funcList = [];
5339
5431
  constructor(funcList) {
@@ -5374,7 +5466,17 @@ var AxFunctionProcessor = class {
5374
5466
  if (!fnSpec.func) {
5375
5467
  throw new Error("No handler for function: " + func.name);
5376
5468
  }
5377
- return await this.executeFunction(fnSpec, func, options);
5469
+ try {
5470
+ return await this.executeFunction(fnSpec, func, options);
5471
+ } catch (e) {
5472
+ if (e instanceof AxFunctionError) {
5473
+ throw new FunctionError({
5474
+ fields: e.getFields(),
5475
+ func: fnSpec
5476
+ });
5477
+ }
5478
+ throw e;
5479
+ }
5378
5480
  };
5379
5481
  };
5380
5482
  var parseFunctions = (newFuncs, existingFuncs) => {
@@ -5453,11 +5555,11 @@ var AxGen = class extends AxProgramWithSignature {
5453
5555
  this.functions = parseFunctions(options.functions);
5454
5556
  }
5455
5557
  }
5456
- addAssert = (fn, message, optional) => {
5457
- this.asserts.push({ fn, message, optional });
5558
+ addAssert = (fn, message) => {
5559
+ this.asserts.push({ fn, message });
5458
5560
  };
5459
- addStreamingAssert = (fieldName, fn, message, optional) => {
5460
- this.streamingAsserts.push({ fieldName, fn, message, optional });
5561
+ addStreamingAssert = (fieldName, fn, message) => {
5562
+ this.streamingAsserts.push({ fieldName, fn, message });
5461
5563
  };
5462
5564
  async forwardSendRequest({
5463
5565
  ai,
@@ -5707,6 +5809,10 @@ var AxGen = class extends AxProgramWithSignature {
5707
5809
  const e1 = e;
5708
5810
  errorFields = e1.getFixingInstructions();
5709
5811
  err = e;
5812
+ } else if (e instanceof FunctionError) {
5813
+ errorFields = e.getFixingInstructions();
5814
+ err = e;
5815
+ } else if (e instanceof AxAIServiceStreamTerminatedError) {
5710
5816
  } else {
5711
5817
  throw e;
5712
5818
  }
@@ -5721,9 +5827,6 @@ var AxGen = class extends AxProgramWithSignature {
5721
5827
  }
5722
5828
  }
5723
5829
  }
5724
- if (err instanceof AxAssertionError && err.getOptional()) {
5725
- return err.getValue();
5726
- }
5727
5830
  throw new Error(`Unable to fix validation error: ${err?.message}`);
5728
5831
  }
5729
5832
  throw new Error(`Max steps reached: ${maxSteps}`);
@@ -5970,6 +6073,7 @@ var AxBalancer = class _AxBalancer {
5970
6073
  services;
5971
6074
  currentServiceIndex = 0;
5972
6075
  currentService;
6076
+ debug;
5973
6077
  constructor(services, options) {
5974
6078
  if (services.length === 0) {
5975
6079
  throw new Error("No AI services provided.");
@@ -5982,6 +6086,7 @@ var AxBalancer = class _AxBalancer {
5982
6086
  throw new Error("Error initializing the AI services.");
5983
6087
  }
5984
6088
  this.currentService = cs;
6089
+ this.debug = options?.debug ?? true;
5985
6090
  }
5986
6091
  /**
5987
6092
  * Service comparator that respects the input order of services.
@@ -6056,16 +6161,20 @@ var AxBalancer = class _AxBalancer {
6056
6161
  default:
6057
6162
  throw e;
6058
6163
  }
6059
- console.warn(
6060
- `AxBalancer: Service ${this.currentService.getName()} failed`,
6061
- e
6062
- );
6164
+ if (this.debug) {
6165
+ console.warn(
6166
+ `AxBalancer: Service ${this.currentService.getName()} failed`,
6167
+ e
6168
+ );
6169
+ }
6063
6170
  if (!this.getNextService()) {
6064
6171
  throw e;
6065
6172
  }
6066
- console.warn(
6067
- `AxBalancer: Switching to service ${this.currentService.getName()}`
6068
- );
6173
+ if (this.debug) {
6174
+ console.warn(
6175
+ `AxBalancer: Switching to service ${this.currentService.getName()}`
6176
+ );
6177
+ }
6069
6178
  }
6070
6179
  }
6071
6180
  }
@@ -6075,11 +6184,15 @@ var AxBalancer = class _AxBalancer {
6075
6184
  try {
6076
6185
  return await this.currentService.embed(req, options);
6077
6186
  } catch (e) {
6078
- console.warn(`Service ${this.currentService.getName()} failed`);
6187
+ if (this.debug) {
6188
+ console.warn(`Service ${this.currentService.getName()} failed`);
6189
+ }
6079
6190
  if (!this.getNextService()) {
6080
6191
  throw e;
6081
6192
  }
6082
- console.warn(`Switching to service ${this.currentService.getName()}`);
6193
+ if (this.debug) {
6194
+ console.warn(`Switching to service ${this.currentService.getName()}`);
6195
+ }
6083
6196
  }
6084
6197
  }
6085
6198
  }
@@ -7772,6 +7885,7 @@ export {
7772
7885
  AxDefaultResultReranker,
7773
7886
  AxDockerSession,
7774
7887
  AxEmbeddingAdapter,
7888
+ AxFunctionError,
7775
7889
  AxFunctionProcessor,
7776
7890
  AxGen,
7777
7891
  AxHFDataLoader,