@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.cjs CHANGED
@@ -84,6 +84,7 @@ __export(index_exports, {
84
84
  AxDefaultResultReranker: () => AxDefaultResultReranker,
85
85
  AxDockerSession: () => AxDockerSession,
86
86
  AxEmbeddingAdapter: () => AxEmbeddingAdapter,
87
+ AxFunctionError: () => AxFunctionError,
87
88
  AxFunctionProcessor: () => AxFunctionProcessor,
88
89
  AxGen: () => AxGen,
89
90
  AxHFDataLoader: () => AxHFDataLoader,
@@ -182,7 +183,6 @@ var AxSpanKindValues = /* @__PURE__ */ ((AxSpanKindValues2) => {
182
183
  })(AxSpanKindValues || {});
183
184
 
184
185
  // util/apicall.ts
185
- var import_path = __toESM(require("path"), 1);
186
186
  var import_web3 = require("stream/web");
187
187
  var import_api = require("@opentelemetry/api");
188
188
 
@@ -310,7 +310,6 @@ var defaultRetryConfig = {
310
310
  maxRetries: 3,
311
311
  initialDelayMs: 1e3,
312
312
  maxDelayMs: 6e4,
313
- // Increased to 60 seconds
314
313
  backoffFactor: 2,
315
314
  retryableStatusCodes: [500, 408, 429, 502, 503, 504]
316
315
  };
@@ -321,18 +320,19 @@ var AxAIServiceError = class extends Error {
321
320
  super(message);
322
321
  this.url = url;
323
322
  this.requestBody = requestBody;
324
- this.context = context;
325
- this.name = "AxAIServiceError";
323
+ this.name = this.constructor.name;
326
324
  this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
327
325
  this.errorId = crypto.randomUUID();
326
+ this.context = context;
328
327
  }
329
328
  timestamp;
330
329
  errorId;
330
+ context;
331
331
  toString() {
332
332
  return `${this.name} [${this.errorId}]: ${this.message}
333
333
  Timestamp: ${this.timestamp}
334
334
  URL: ${this.url}${this.requestBody ? `
335
- Request Body: ${JSON.stringify(this.requestBody, null, 2)}` : ""}${this.context ? `
335
+ Request Body: ${JSON.stringify(this.requestBody, null, 2)}` : ""}${Object.keys(this.context).length ? `
336
336
  Context: ${JSON.stringify(this.context, null, 2)}` : ""}`;
337
337
  }
338
338
  toJSON() {
@@ -357,7 +357,7 @@ var AxAIServiceStatusError = class extends AxAIServiceError {
357
357
  });
358
358
  this.status = status;
359
359
  this.statusText = statusText;
360
- this.name = "AxAIServiceStatusError";
360
+ this.name = this.constructor.name;
361
361
  }
362
362
  };
363
363
  var AxAIServiceNetworkError = class extends AxAIServiceError {
@@ -368,14 +368,14 @@ var AxAIServiceNetworkError = class extends AxAIServiceError {
368
368
  ...context
369
369
  });
370
370
  this.originalError = originalError;
371
- this.name = "AxAIServiceNetworkError";
371
+ this.name = this.constructor.name;
372
372
  this.stack = originalError.stack;
373
373
  }
374
374
  };
375
375
  var AxAIServiceResponseError = class extends AxAIServiceError {
376
376
  constructor(message, url, requestBody, context) {
377
377
  super(message, url, requestBody, context);
378
- this.name = "AxAIServiceResponseError";
378
+ this.name = this.constructor.name;
379
379
  }
380
380
  };
381
381
  var AxAIServiceStreamTerminatedError = class extends AxAIServiceError {
@@ -385,7 +385,7 @@ var AxAIServiceStreamTerminatedError = class extends AxAIServiceError {
385
385
  ...context
386
386
  });
387
387
  this.lastChunk = lastChunk;
388
- this.name = "AxAIServiceStreamTerminatedError";
388
+ this.name = this.constructor.name;
389
389
  }
390
390
  };
391
391
  var AxAIServiceTimeoutError = class extends AxAIServiceError {
@@ -394,13 +394,13 @@ var AxAIServiceTimeoutError = class extends AxAIServiceError {
394
394
  timeoutMs,
395
395
  ...context
396
396
  });
397
- this.name = "AxAIServiceTimeoutError";
397
+ this.name = this.constructor.name;
398
398
  }
399
399
  };
400
400
  var AxAIServiceAuthenticationError = class extends AxAIServiceError {
401
401
  constructor(url, requestBody, context) {
402
402
  super("Authentication failed", url, requestBody, context);
403
- this.name = "AxAIServiceAuthenticationError";
403
+ this.name = this.constructor.name;
404
404
  }
405
405
  };
406
406
  function calculateRetryDelay(attempt, config) {
@@ -420,14 +420,31 @@ function updateRetryMetrics(metrics) {
420
420
  metrics.retryCount++;
421
421
  metrics.lastRetryTime = Date.now();
422
422
  }
423
+ function shouldRetry(error, status, attempt, config) {
424
+ if (attempt >= config.maxRetries) return false;
425
+ if (status && config.retryableStatusCodes.includes(status)) return true;
426
+ return error instanceof AxAIServiceNetworkError && !(error instanceof AxAIServiceAuthenticationError);
427
+ }
423
428
  var apiCall = async (api, json) => {
424
429
  const retryConfig = { ...defaultRetryConfig, ...api.retry };
425
430
  const timeoutMs = api.timeout ?? defaultTimeoutMs;
426
431
  const metrics = createRequestMetrics();
432
+ let timeoutId;
427
433
  const baseUrl = new URL(process.env["PROXY"] ?? api.url);
428
- const apiPath = import_path.default.join(baseUrl.pathname, api.name ?? "/", baseUrl.search);
434
+ const apiPath = [baseUrl.pathname, api.name].filter(Boolean).join("/").replace(/\/+/g, "/");
429
435
  const apiUrl = new URL(apiPath, baseUrl);
430
436
  const requestId = crypto.randomUUID();
437
+ if (api.validateRequest) {
438
+ const isValid = await api.validateRequest(json);
439
+ if (!isValid) {
440
+ throw new AxAIServiceResponseError(
441
+ "Invalid request data",
442
+ apiUrl.href,
443
+ json,
444
+ { validation: "request" }
445
+ );
446
+ }
447
+ }
431
448
  if (api.span?.isRecording()) {
432
449
  api.span.setAttributes({
433
450
  "http.request.method": api.put ? "PUT" : "POST",
@@ -439,7 +456,7 @@ var apiCall = async (api, json) => {
439
456
  let attempt = 0;
440
457
  while (true) {
441
458
  const controller = new AbortController();
442
- let timeoutId = setTimeout(() => {
459
+ timeoutId = setTimeout(() => {
443
460
  controller.abort("Request timeout");
444
461
  }, timeoutMs);
445
462
  try {
@@ -458,7 +475,7 @@ var apiCall = async (api, json) => {
458
475
  if (res.status === 401 || res.status === 403) {
459
476
  throw new AxAIServiceAuthenticationError(apiUrl.href, json, { metrics });
460
477
  }
461
- if (res.status >= 400 && attempt < retryConfig.maxRetries && retryConfig.retryableStatusCodes.includes(res.status)) {
478
+ if (res.status >= 400 && shouldRetry(new Error(), res.status, attempt, retryConfig)) {
462
479
  const delay = calculateRetryDelay(attempt, retryConfig);
463
480
  attempt++;
464
481
  updateRetryMetrics(metrics);
@@ -472,7 +489,7 @@ var apiCall = async (api, json) => {
472
489
  "metrics.lastRetryTime": metrics.lastRetryTime
473
490
  });
474
491
  }
475
- clearTimeout(timeoutId);
492
+ await new Promise((resolve) => setTimeout(resolve, delay));
476
493
  continue;
477
494
  }
478
495
  if (res.status >= 400) {
@@ -486,6 +503,17 @@ var apiCall = async (api, json) => {
486
503
  }
487
504
  if (!api.stream) {
488
505
  const resJson = await res.json();
506
+ if (api.validateResponse) {
507
+ const isValid = await api.validateResponse(resJson);
508
+ if (!isValid) {
509
+ throw new AxAIServiceResponseError(
510
+ "Invalid response data",
511
+ apiUrl.href,
512
+ json,
513
+ { validation: "response" }
514
+ );
515
+ }
516
+ }
489
517
  if (api.span?.isRecording()) {
490
518
  api.span.setAttributes({
491
519
  "response.time": Date.now() - metrics.startTime,
@@ -504,7 +532,7 @@ var apiCall = async (api, json) => {
504
532
  }
505
533
  let lastChunk;
506
534
  let chunkCount = 0;
507
- const trackingStream = new TransformStream({
535
+ const trackingStream = new import_web3.TransformStream({
508
536
  transform(chunk, controller2) {
509
537
  lastChunk = chunk;
510
538
  chunkCount++;
@@ -512,7 +540,7 @@ var apiCall = async (api, json) => {
512
540
  metrics.lastChunkTime = Date.now();
513
541
  controller2.enqueue(chunk);
514
542
  },
515
- flush(controller2) {
543
+ flush() {
516
544
  if (api.span?.isRecording()) {
517
545
  api.span.setAttributes({
518
546
  "stream.chunks": chunkCount,
@@ -520,10 +548,10 @@ var apiCall = async (api, json) => {
520
548
  "response.retries": metrics.retryCount
521
549
  });
522
550
  }
523
- controller2.terminate();
524
551
  }
525
552
  });
526
- const wrappedStream = new import_web3.ReadableStream({
553
+ let closed = false;
554
+ return new import_web3.ReadableStream({
527
555
  start(controller2) {
528
556
  const reader = res.body.pipeThrough(new textDecoderStream()).pipeThrough(new SSEParser()).pipeThrough(trackingStream).getReader();
529
557
  async function read() {
@@ -531,11 +559,14 @@ var apiCall = async (api, json) => {
531
559
  while (true) {
532
560
  const { done, value } = await reader.read();
533
561
  if (done) {
534
- controller2.close();
562
+ if (!closed) {
563
+ closed = true;
564
+ controller2.close();
565
+ }
535
566
  break;
536
- } else {
537
- controller2.enqueue(value);
538
567
  }
568
+ if (closed) break;
569
+ controller2.enqueue(value);
539
570
  }
540
571
  } catch (e) {
541
572
  const error = e;
@@ -552,26 +583,42 @@ var apiCall = async (api, json) => {
552
583
  { streamMetrics }
553
584
  )
554
585
  );
555
- } else {
586
+ } else if (error instanceof TypeError && error.message.includes("cancelled")) {
556
587
  controller2.error(
557
- new AxAIServiceResponseError(
558
- `Stream processing error: ${error.message}`,
588
+ new AxAIServiceStreamTerminatedError(
559
589
  apiUrl.href,
560
590
  json,
561
- { streamMetrics }
591
+ lastChunk,
592
+ {
593
+ streamMetrics,
594
+ cancelReason: "Stream cancelled by client"
595
+ }
562
596
  )
563
597
  );
598
+ } else {
599
+ controller2.error(
600
+ new AxAIServiceNetworkError(error, apiUrl.href, json, {
601
+ streamMetrics
602
+ })
603
+ );
564
604
  }
605
+ throw error;
565
606
  } finally {
607
+ clearTimeout(timeoutId);
566
608
  reader.releaseLock();
609
+ if (api.span?.isRecording()) {
610
+ api.span.end();
611
+ }
567
612
  }
568
613
  }
569
614
  read();
615
+ },
616
+ // When the consumer cancels the stream, set our flag to stop processing further.
617
+ cancel() {
618
+ closed = true;
570
619
  }
571
620
  });
572
- return wrappedStream;
573
621
  } catch (error) {
574
- clearTimeout(timeoutId);
575
622
  if (error instanceof Error && error.name === "AbortError") {
576
623
  throw new AxAIServiceTimeoutError(apiUrl.href, timeoutMs, json, {
577
624
  metrics
@@ -584,7 +631,7 @@ var apiCall = async (api, json) => {
584
631
  "error.retries": metrics.retryCount
585
632
  });
586
633
  }
587
- if (error instanceof AxAIServiceNetworkError && attempt < retryConfig.maxRetries) {
634
+ if (error instanceof AxAIServiceNetworkError && shouldRetry(error, void 0, attempt, retryConfig)) {
588
635
  const delay = calculateRetryDelay(attempt, retryConfig);
589
636
  attempt++;
590
637
  updateRetryMetrics(metrics);
@@ -598,12 +645,20 @@ var apiCall = async (api, json) => {
598
645
  "metrics.lastRetryTime": metrics.lastRetryTime
599
646
  });
600
647
  }
648
+ await new Promise((resolve) => setTimeout(resolve, delay));
601
649
  continue;
602
650
  }
603
651
  if (error instanceof AxAIServiceError) {
604
652
  error.context["metrics"] = metrics;
605
653
  }
606
654
  throw error;
655
+ } finally {
656
+ if (timeoutId !== void 0) {
657
+ clearTimeout(timeoutId);
658
+ }
659
+ if (api.span?.isRecording()) {
660
+ api.span.end();
661
+ }
607
662
  }
608
663
  }
609
664
  };
@@ -1653,8 +1708,9 @@ function mapFinishReason(stopReason) {
1653
1708
 
1654
1709
  // ai/openai/types.ts
1655
1710
  var AxAIOpenAIModel = /* @__PURE__ */ ((AxAIOpenAIModel2) => {
1656
- AxAIOpenAIModel2["O1Preview"] = "o1-preview";
1711
+ AxAIOpenAIModel2["O1"] = "o1";
1657
1712
  AxAIOpenAIModel2["O1Mini"] = "o1-mini";
1713
+ AxAIOpenAIModel2["O3Mini"] = "o3-mini";
1658
1714
  AxAIOpenAIModel2["GPT4"] = "gpt-4";
1659
1715
  AxAIOpenAIModel2["GPT4O"] = "gpt-4o";
1660
1716
  AxAIOpenAIModel2["GPT4OMini"] = "gpt-4o-mini";
@@ -1677,7 +1733,7 @@ var AxAIOpenAIEmbedModel = /* @__PURE__ */ ((AxAIOpenAIEmbedModel2) => {
1677
1733
  // ai/openai/info.ts
1678
1734
  var axModelInfoOpenAI = [
1679
1735
  {
1680
- name: "o1-preview" /* O1Preview */,
1736
+ name: "o1" /* O1 */,
1681
1737
  currency: "usd",
1682
1738
  promptTokenCostPer1M: 15,
1683
1739
  completionTokenCostPer1M: 60
@@ -1685,8 +1741,14 @@ var axModelInfoOpenAI = [
1685
1741
  {
1686
1742
  name: "o1-mini" /* O1Mini */,
1687
1743
  currency: "usd",
1688
- promptTokenCostPer1M: 3,
1689
- completionTokenCostPer1M: 12
1744
+ promptTokenCostPer1M: 1.1,
1745
+ completionTokenCostPer1M: 14.4
1746
+ },
1747
+ {
1748
+ name: "o3-mini" /* O3Mini */,
1749
+ currency: "usd",
1750
+ promptTokenCostPer1M: 1.1,
1751
+ completionTokenCostPer1M: 4.4
1690
1752
  },
1691
1753
  {
1692
1754
  name: "gpt-4" /* GPT4 */,
@@ -1786,16 +1848,12 @@ var AxAIOpenAIImpl = class {
1786
1848
  parameters: v.parameters
1787
1849
  }
1788
1850
  }));
1789
- if (tools && isO1Model(model)) {
1790
- throw new Error("Functions are not supported for O1 models");
1791
- }
1792
1851
  const toolsChoice = !req.functionCall && req.functions && req.functions.length > 0 ? "auto" : req.functionCall;
1793
1852
  const messages = createMessages2(req);
1794
1853
  const frequencyPenalty = req.modelConfig?.frequencyPenalty ?? this.config.frequencyPenalty;
1795
1854
  const stream = req.modelConfig?.stream ?? this.config.stream;
1796
- if (stream && isO1Model(model)) {
1797
- throw new Error("Streaming is not supported for O1 models");
1798
- }
1855
+ const reasoningEffort = isReasoningModel(model) ? this.config.reasoningEffort : void 0;
1856
+ const store = this.config.store;
1799
1857
  const reqValue = {
1800
1858
  model,
1801
1859
  messages,
@@ -1810,7 +1868,9 @@ var AxAIOpenAIImpl = class {
1810
1868
  presence_penalty: req.modelConfig?.presencePenalty ?? this.config.presencePenalty,
1811
1869
  logit_bias: this.config.logitBias,
1812
1870
  ...frequencyPenalty ? { frequency_penalty: frequencyPenalty } : {},
1813
- ...stream && this.streamingUsage ? { stream: true, stream_options: { include_usage: true } } : {}
1871
+ ...stream && this.streamingUsage ? { stream: true, stream_options: { include_usage: true } } : {},
1872
+ ...reasoningEffort ? { reasoning_effort: reasoningEffort } : {},
1873
+ ...store ? { store } : {}
1814
1874
  };
1815
1875
  return [apiConfig, reqValue];
1816
1876
  }
@@ -1936,12 +1996,6 @@ var mapFinishReason2 = (finishReason) => {
1936
1996
  };
1937
1997
  function createMessages2(req) {
1938
1998
  return req.chatPrompt.map((msg) => {
1939
- if (msg.role === "system" && isO1Model(req.model)) {
1940
- msg = {
1941
- role: "user",
1942
- content: msg.content
1943
- };
1944
- }
1945
1999
  switch (msg.role) {
1946
2000
  case "system":
1947
2001
  return { role: "system", content: msg.content };
@@ -2031,14 +2085,14 @@ var AxAIOpenAI = class extends AxBaseAI {
2031
2085
  embedModel: _config.embedModel
2032
2086
  },
2033
2087
  options,
2034
- supportFor: (model) => {
2035
- return isO1Model(model) ? { functions: false, streaming: false } : { functions: true, streaming: true };
2088
+ supportFor: () => {
2089
+ return { functions: true, streaming: true };
2036
2090
  },
2037
2091
  modelMap
2038
2092
  });
2039
2093
  }
2040
2094
  };
2041
- var isO1Model = (model) => ["o1-mini" /* O1Mini */, "o1-preview" /* O1Preview */].includes(
2095
+ var isReasoningModel = (model) => ["o1-mini" /* O1Mini */, "o1" /* O1 */, "o3-mini" /* O3Mini */].includes(
2042
2096
  model
2043
2097
  );
2044
2098
 
@@ -3764,21 +3818,13 @@ var AxMemory = class {
3764
3818
 
3765
3819
  // dsp/asserts.ts
3766
3820
  var AxAssertionError = class extends Error {
3767
- values;
3768
- optional;
3769
3821
  constructor({
3770
- message,
3771
- values,
3772
- optional
3822
+ message
3773
3823
  }) {
3774
3824
  super(message);
3775
- this.values = values;
3776
- this.optional = optional;
3777
3825
  this.name = this.constructor.name;
3778
3826
  this.stack = new Error().stack;
3779
3827
  }
3780
- getValue = () => this.values;
3781
- getOptional = () => this.optional;
3782
3828
  getFixingInstructions = () => {
3783
3829
  const extraFields = [];
3784
3830
  extraFields.push({
@@ -3791,13 +3837,16 @@ var AxAssertionError = class extends Error {
3791
3837
  };
3792
3838
  var assertAssertions = (asserts, values) => {
3793
3839
  for (const assert of asserts) {
3794
- const { fn, message, optional } = assert;
3840
+ const { fn, message } = assert;
3795
3841
  const res = fn(values);
3796
3842
  if (res === void 0) {
3797
3843
  continue;
3798
3844
  }
3799
- if (!res && message) {
3800
- throw new AxAssertionError({ message, values, optional });
3845
+ if (!res) {
3846
+ if (!message) {
3847
+ throw new Error(`Assertion Failed: No message provided for assertion`);
3848
+ }
3849
+ throw new AxAssertionError({ message });
3801
3850
  }
3802
3851
  }
3803
3852
  };
@@ -3813,13 +3862,13 @@ var assertStreamingAssertions = (asserts, values, xstate, content, final) => {
3813
3862
  }
3814
3863
  const currValue = content.substring(xstate.s);
3815
3864
  for (const assert of fieldAsserts) {
3816
- const { message, optional, fn } = assert;
3865
+ const { message, fn } = assert;
3817
3866
  const res = fn(currValue, final);
3818
3867
  if (res === void 0) {
3819
3868
  continue;
3820
3869
  }
3821
3870
  if (!res && message) {
3822
- throw new AxAssertionError({ message, values, optional });
3871
+ throw new AxAssertionError({ message });
3823
3872
  }
3824
3873
  }
3825
3874
  };
@@ -5073,13 +5122,11 @@ var ValidationError = class extends Error {
5073
5122
  super(message);
5074
5123
  this.fields = fields;
5075
5124
  this.name = this.constructor.name;
5076
- Error.captureStackTrace(this, this.constructor);
5077
5125
  }
5078
- getFields = () => this.fields;
5079
5126
  getFixingInstructions = () => {
5080
5127
  return this.fields.map((field) => ({
5081
5128
  name: "outputError",
5082
- title: "Error In Output",
5129
+ title: "Errors In Output Fields",
5083
5130
  description: `Please fix and return the field \`${field.title}\` of type \`${toFieldType(field.type)}\`, ${this.message}.`
5084
5131
  }));
5085
5132
  };
@@ -5283,8 +5330,10 @@ function* streamValues(sig, values, xstate, content, final = false) {
5283
5330
  const v = content.substring(s);
5284
5331
  const v1 = v.replace(/[\s\n\t]+$/, "");
5285
5332
  const v2 = pos === 0 ? v1.trimStart() : v1;
5286
- yield { [fieldName]: v2 };
5287
- xstate.streamedIndex[fieldName] = pos + v1.length;
5333
+ if (v2.length > 0) {
5334
+ yield { [fieldName]: v2 };
5335
+ xstate.streamedIndex[fieldName] = pos + v1.length;
5336
+ }
5288
5337
  return;
5289
5338
  }
5290
5339
  }
@@ -5293,7 +5342,7 @@ function* streamValues(sig, values, xstate, content, final = false) {
5293
5342
  if (Array.isArray(value)) {
5294
5343
  const s = xstate.streamedIndex[key] ?? 0;
5295
5344
  const v = value.slice(s);
5296
- if (v) {
5345
+ if (v && v.length > 0) {
5297
5346
  yield { [key]: v };
5298
5347
  xstate.streamedIndex[key] = s + 1;
5299
5348
  }
@@ -5389,7 +5438,7 @@ var extractBlock = (input) => {
5389
5438
  // dsp/jsonschema.ts
5390
5439
  var validateJSONSchema = (schema) => {
5391
5440
  const errors = [];
5392
- const validateSchemaObject = (schema2, path2 = "") => {
5441
+ const validateSchemaObject = (schema2, path = "") => {
5393
5442
  const validTypes = [
5394
5443
  "array",
5395
5444
  "integer",
@@ -5400,31 +5449,31 @@ var validateJSONSchema = (schema) => {
5400
5449
  "object"
5401
5450
  ];
5402
5451
  if (!validTypes.includes(schema2.type)) {
5403
- errors.push(`Invalid type '${schema2.type}' at ${path2 || "root"}`);
5452
+ errors.push(`Invalid type '${schema2.type}' at ${path || "root"}`);
5404
5453
  return;
5405
5454
  }
5406
5455
  if (schema2.type === "object" && schema2.properties) {
5407
5456
  if (typeof schema2.properties !== "object" || Array.isArray(schema2.properties)) {
5408
- errors.push(`Invalid properties object at ${path2 || "root"}`);
5457
+ errors.push(`Invalid properties object at ${path || "root"}`);
5409
5458
  } else {
5410
5459
  for (const key in schema2.properties) {
5411
5460
  const value = schema2.properties[key];
5412
5461
  if (typeof value !== "object") {
5413
- errors.push(`Invalid schema object at ${path2}${key}`);
5462
+ errors.push(`Invalid schema object at ${path}${key}`);
5414
5463
  continue;
5415
5464
  }
5416
- validateSchemaObject(value, `${path2}${key}.`);
5465
+ validateSchemaObject(value, `${path}${key}.`);
5417
5466
  }
5418
5467
  }
5419
5468
  if (schema2.required && !Array.isArray(schema2.required)) {
5420
- errors.push(`'required' should be an array at ${path2 || "root"}`);
5469
+ errors.push(`'required' should be an array at ${path || "root"}`);
5421
5470
  }
5422
5471
  }
5423
5472
  if (schema2.type === "array" && schema2.items) {
5424
5473
  if (typeof schema2.items !== "object") {
5425
- errors.push(`Invalid items schema at ${path2 || "root"}`);
5474
+ errors.push(`Invalid items schema at ${path || "root"}`);
5426
5475
  } else {
5427
- validateSchemaObject(schema2.items, `${path2}items.`);
5476
+ validateSchemaObject(schema2.items, `${path}items.`);
5428
5477
  }
5429
5478
  }
5430
5479
  };
@@ -5435,6 +5484,49 @@ var validateJSONSchema = (schema) => {
5435
5484
  };
5436
5485
 
5437
5486
  // dsp/functions.ts
5487
+ var AxFunctionError = class extends Error {
5488
+ constructor(fields) {
5489
+ super();
5490
+ this.fields = fields;
5491
+ this.name = this.constructor.name;
5492
+ }
5493
+ getFields = () => this.fields;
5494
+ };
5495
+ var FunctionError = class extends Error {
5496
+ fields;
5497
+ func;
5498
+ constructor({
5499
+ fields,
5500
+ func
5501
+ }) {
5502
+ super();
5503
+ this.fields = fields;
5504
+ this.func = func;
5505
+ this.name = this.constructor.name;
5506
+ }
5507
+ getFieldDescription(fieldName) {
5508
+ if (!this.func.parameters?.properties?.[fieldName]) {
5509
+ return "";
5510
+ }
5511
+ const fieldSchema = this.func.parameters.properties[fieldName];
5512
+ let description = fieldSchema.description;
5513
+ if (fieldSchema.enum?.length) {
5514
+ description += ` Allowed values are: ${fieldSchema.enum.join(", ")}`;
5515
+ }
5516
+ return description;
5517
+ }
5518
+ getFixingInstructions = () => {
5519
+ return this.fields.map((fieldError) => {
5520
+ const schemaDescription = this.getFieldDescription(fieldError.field);
5521
+ const fullDescription = schemaDescription ? `${fieldError.message}. ${schemaDescription}` : fieldError.message;
5522
+ return {
5523
+ name: "functionArgumentError",
5524
+ title: `Errors in Function '${this.func.name}' Arguments`,
5525
+ description: `Please fix the argument '${fieldError.field}' in function '${this.func.name}': ${fullDescription}`
5526
+ };
5527
+ });
5528
+ };
5529
+ };
5438
5530
  var AxFunctionProcessor = class {
5439
5531
  funcList = [];
5440
5532
  constructor(funcList) {
@@ -5475,7 +5567,17 @@ var AxFunctionProcessor = class {
5475
5567
  if (!fnSpec.func) {
5476
5568
  throw new Error("No handler for function: " + func.name);
5477
5569
  }
5478
- return await this.executeFunction(fnSpec, func, options);
5570
+ try {
5571
+ return await this.executeFunction(fnSpec, func, options);
5572
+ } catch (e) {
5573
+ if (e instanceof AxFunctionError) {
5574
+ throw new FunctionError({
5575
+ fields: e.getFields(),
5576
+ func: fnSpec
5577
+ });
5578
+ }
5579
+ throw e;
5580
+ }
5479
5581
  };
5480
5582
  };
5481
5583
  var parseFunctions = (newFuncs, existingFuncs) => {
@@ -5554,11 +5656,11 @@ var AxGen = class extends AxProgramWithSignature {
5554
5656
  this.functions = parseFunctions(options.functions);
5555
5657
  }
5556
5658
  }
5557
- addAssert = (fn, message, optional) => {
5558
- this.asserts.push({ fn, message, optional });
5659
+ addAssert = (fn, message) => {
5660
+ this.asserts.push({ fn, message });
5559
5661
  };
5560
- addStreamingAssert = (fieldName, fn, message, optional) => {
5561
- this.streamingAsserts.push({ fieldName, fn, message, optional });
5662
+ addStreamingAssert = (fieldName, fn, message) => {
5663
+ this.streamingAsserts.push({ fieldName, fn, message });
5562
5664
  };
5563
5665
  async forwardSendRequest({
5564
5666
  ai,
@@ -5808,6 +5910,10 @@ var AxGen = class extends AxProgramWithSignature {
5808
5910
  const e1 = e;
5809
5911
  errorFields = e1.getFixingInstructions();
5810
5912
  err = e;
5913
+ } else if (e instanceof FunctionError) {
5914
+ errorFields = e.getFixingInstructions();
5915
+ err = e;
5916
+ } else if (e instanceof AxAIServiceStreamTerminatedError) {
5811
5917
  } else {
5812
5918
  throw e;
5813
5919
  }
@@ -5822,9 +5928,6 @@ var AxGen = class extends AxProgramWithSignature {
5822
5928
  }
5823
5929
  }
5824
5930
  }
5825
- if (err instanceof AxAssertionError && err.getOptional()) {
5826
- return err.getValue();
5827
- }
5828
5931
  throw new Error(`Unable to fix validation error: ${err?.message}`);
5829
5932
  }
5830
5933
  throw new Error(`Max steps reached: ${maxSteps}`);
@@ -6071,6 +6174,7 @@ var AxBalancer = class _AxBalancer {
6071
6174
  services;
6072
6175
  currentServiceIndex = 0;
6073
6176
  currentService;
6177
+ debug;
6074
6178
  constructor(services, options) {
6075
6179
  if (services.length === 0) {
6076
6180
  throw new Error("No AI services provided.");
@@ -6083,6 +6187,7 @@ var AxBalancer = class _AxBalancer {
6083
6187
  throw new Error("Error initializing the AI services.");
6084
6188
  }
6085
6189
  this.currentService = cs;
6190
+ this.debug = options?.debug ?? true;
6086
6191
  }
6087
6192
  /**
6088
6193
  * Service comparator that respects the input order of services.
@@ -6157,16 +6262,20 @@ var AxBalancer = class _AxBalancer {
6157
6262
  default:
6158
6263
  throw e;
6159
6264
  }
6160
- console.warn(
6161
- `AxBalancer: Service ${this.currentService.getName()} failed`,
6162
- e
6163
- );
6265
+ if (this.debug) {
6266
+ console.warn(
6267
+ `AxBalancer: Service ${this.currentService.getName()} failed`,
6268
+ e
6269
+ );
6270
+ }
6164
6271
  if (!this.getNextService()) {
6165
6272
  throw e;
6166
6273
  }
6167
- console.warn(
6168
- `AxBalancer: Switching to service ${this.currentService.getName()}`
6169
- );
6274
+ if (this.debug) {
6275
+ console.warn(
6276
+ `AxBalancer: Switching to service ${this.currentService.getName()}`
6277
+ );
6278
+ }
6170
6279
  }
6171
6280
  }
6172
6281
  }
@@ -6176,11 +6285,15 @@ var AxBalancer = class _AxBalancer {
6176
6285
  try {
6177
6286
  return await this.currentService.embed(req, options);
6178
6287
  } catch (e) {
6179
- console.warn(`Service ${this.currentService.getName()} failed`);
6288
+ if (this.debug) {
6289
+ console.warn(`Service ${this.currentService.getName()} failed`);
6290
+ }
6180
6291
  if (!this.getNextService()) {
6181
6292
  throw e;
6182
6293
  }
6183
- console.warn(`Switching to service ${this.currentService.getName()}`);
6294
+ if (this.debug) {
6295
+ console.warn(`Switching to service ${this.currentService.getName()}`);
6296
+ }
6184
6297
  }
6185
6298
  }
6186
6299
  }
@@ -7874,6 +7987,7 @@ var AxRAG = class extends AxChainOfThought {
7874
7987
  AxDefaultResultReranker,
7875
7988
  AxDockerSession,
7876
7989
  AxEmbeddingAdapter,
7990
+ AxFunctionError,
7877
7991
  AxFunctionProcessor,
7878
7992
  AxGen,
7879
7993
  AxHFDataLoader,