@ax-llm/ax 11.0.52 → 11.0.53

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
@@ -292,10 +292,25 @@ var AxAIServiceStreamTerminatedError = class extends AxAIServiceError {
292
292
  };
293
293
  var AxAIServiceTimeoutError = class extends AxAIServiceError {
294
294
  constructor(url, timeoutMs, requestBody, context3) {
295
- super(`Request timeout after ${timeoutMs}ms`, url, requestBody, void 0, {
296
- timeoutMs,
297
- ...context3
298
- });
295
+ super(
296
+ `Request timed out after ${timeoutMs}ms`,
297
+ url,
298
+ requestBody,
299
+ void 0,
300
+ { timeoutMs, ...context3 }
301
+ );
302
+ this.name = this.constructor.name;
303
+ }
304
+ };
305
+ var AxAIServiceAbortedError = class extends AxAIServiceError {
306
+ constructor(url, reason, requestBody, context3) {
307
+ super(
308
+ `Request aborted${reason ? `: ${reason}` : ""}`,
309
+ url,
310
+ requestBody,
311
+ void 0,
312
+ { abortReason: reason, ...context3 }
313
+ );
299
314
  this.name = this.constructor.name;
300
315
  }
301
316
  };
@@ -355,9 +370,34 @@ var apiCall = async (api, json) => {
355
370
  });
356
371
  let attempt = 0;
357
372
  while (true) {
358
- const controller = new AbortController();
373
+ const combinedAbortController = new AbortController();
374
+ if (api.abortSignal) {
375
+ if (api.abortSignal.aborted) {
376
+ throw new AxAIServiceAbortedError(
377
+ apiUrl.href,
378
+ api.abortSignal.reason,
379
+ json,
380
+ { metrics }
381
+ );
382
+ }
383
+ const userAbortHandler = () => {
384
+ combinedAbortController.abort(
385
+ api.abortSignal.reason || "User aborted request"
386
+ );
387
+ };
388
+ api.abortSignal.addEventListener("abort", userAbortHandler, {
389
+ once: true
390
+ });
391
+ const originalAbort = combinedAbortController.abort.bind(
392
+ combinedAbortController
393
+ );
394
+ combinedAbortController.abort = (reason) => {
395
+ api.abortSignal.removeEventListener("abort", userAbortHandler);
396
+ originalAbort(reason);
397
+ };
398
+ }
359
399
  timeoutId = setTimeout(() => {
360
- controller.abort("Request timeout");
400
+ combinedAbortController.abort("Request timeout");
361
401
  }, timeoutMs);
362
402
  try {
363
403
  const res = await (api.fetch ?? fetch)(apiUrl, {
@@ -369,7 +409,7 @@ var apiCall = async (api, json) => {
369
409
  ...api.headers
370
410
  },
371
411
  body: JSON.stringify(json),
372
- signal: controller.signal
412
+ signal: combinedAbortController.signal
373
413
  });
374
414
  clearTimeout(timeoutId);
375
415
  if (res.status === 401 || res.status === 403) {
@@ -432,12 +472,12 @@ var apiCall = async (api, json) => {
432
472
  let lastChunk;
433
473
  let chunkCount = 0;
434
474
  const trackingStream = new TransformStream3({
435
- transform(chunk, controller2) {
475
+ transform(chunk, controller) {
436
476
  lastChunk = chunk;
437
477
  chunkCount++;
438
478
  metrics.streamChunks = chunkCount;
439
479
  metrics.lastChunkTime = Date.now();
440
- controller2.enqueue(chunk);
480
+ controller.enqueue(chunk);
441
481
  api.span?.addEvent("stream.chunk", {
442
482
  "stream.chunks": chunkCount,
443
483
  "stream.duration": Date.now() - metrics.startTime,
@@ -447,7 +487,7 @@ var apiCall = async (api, json) => {
447
487
  });
448
488
  let closed = false;
449
489
  return new ReadableStream2({
450
- start(controller2) {
490
+ start(controller) {
451
491
  const reader = res.body.pipeThrough(new textDecoderStream()).pipeThrough(new SSEParser()).pipeThrough(trackingStream).getReader();
452
492
  async function read() {
453
493
  try {
@@ -456,12 +496,12 @@ var apiCall = async (api, json) => {
456
496
  if (done) {
457
497
  if (!closed) {
458
498
  closed = true;
459
- controller2.close();
499
+ controller.close();
460
500
  }
461
501
  break;
462
502
  }
463
503
  if (closed) break;
464
- controller2.enqueue(value);
504
+ controller.enqueue(value);
465
505
  }
466
506
  } catch (e) {
467
507
  const error = e;
@@ -470,7 +510,7 @@ var apiCall = async (api, json) => {
470
510
  streamDuration: Date.now() - metrics.startTime
471
511
  };
472
512
  if (error.name === "AbortError" || error.message?.includes("aborted")) {
473
- controller2.error(
513
+ controller.error(
474
514
  new AxAIServiceStreamTerminatedError(
475
515
  apiUrl.href,
476
516
  json,
@@ -479,7 +519,7 @@ var apiCall = async (api, json) => {
479
519
  )
480
520
  );
481
521
  } else if (error instanceof TypeError && error.message.includes("cancelled")) {
482
- controller2.error(
522
+ controller.error(
483
523
  new AxAIServiceStreamTerminatedError(
484
524
  apiUrl.href,
485
525
  json,
@@ -491,7 +531,7 @@ var apiCall = async (api, json) => {
491
531
  )
492
532
  );
493
533
  } else {
494
- controller2.error(
534
+ controller.error(
495
535
  new AxAIServiceNetworkError(
496
536
  error,
497
537
  apiUrl.href,
@@ -518,9 +558,18 @@ var apiCall = async (api, json) => {
518
558
  });
519
559
  } catch (error) {
520
560
  if (error instanceof Error && error.name === "AbortError") {
521
- throw new AxAIServiceTimeoutError(apiUrl.href, timeoutMs, json, {
522
- metrics
523
- });
561
+ if (api.abortSignal?.aborted) {
562
+ throw new AxAIServiceAbortedError(
563
+ apiUrl.href,
564
+ api.abortSignal.reason,
565
+ json,
566
+ { metrics }
567
+ );
568
+ } else {
569
+ throw new AxAIServiceTimeoutError(apiUrl.href, timeoutMs, json, {
570
+ metrics
571
+ });
572
+ }
524
573
  }
525
574
  if (api.span?.isRecording()) {
526
575
  api.span.recordException(error);
@@ -767,6 +816,7 @@ var AxBaseAI = class {
767
816
  timeout;
768
817
  excludeContentFromTrace;
769
818
  models;
819
+ abortSignal;
770
820
  modelInfo;
771
821
  modelUsage;
772
822
  embedModelUsage;
@@ -827,6 +877,7 @@ var AxBaseAI = class {
827
877
  this.timeout = options.timeout;
828
878
  this.tracer = options.tracer;
829
879
  this.excludeContentFromTrace = options.excludeContentFromTrace;
880
+ this.abortSignal = options.abortSignal;
830
881
  }
831
882
  getOptions() {
832
883
  return {
@@ -835,7 +886,8 @@ var AxBaseAI = class {
835
886
  fetch: this.fetch,
836
887
  tracer: this.tracer,
837
888
  timeout: this.timeout,
838
- excludeContentFromTrace: this.excludeContentFromTrace
889
+ excludeContentFromTrace: this.excludeContentFromTrace,
890
+ abortSignal: this.abortSignal
839
891
  };
840
892
  }
841
893
  getModelList() {
@@ -1017,7 +1069,8 @@ var AxBaseAI = class {
1017
1069
  timeout: this.timeout,
1018
1070
  debug,
1019
1071
  fetch: this.fetch,
1020
- span
1072
+ span,
1073
+ abortSignal: options?.abortSignal ?? this.abortSignal
1021
1074
  },
1022
1075
  reqValue
1023
1076
  );
@@ -1174,7 +1227,8 @@ var AxBaseAI = class {
1174
1227
  debug,
1175
1228
  fetch: this.fetch,
1176
1229
  timeout: this.timeout,
1177
- span
1230
+ span,
1231
+ abortSignal: options?.abortSignal ?? this.abortSignal
1178
1232
  },
1179
1233
  reqValue
1180
1234
  );
@@ -5470,6 +5524,8 @@ var validateValue = (field, value) => {
5470
5524
  const ft = field.type ?? { name: "string", isArray: false };
5471
5525
  const validateSingleValue = (expectedType, val) => {
5472
5526
  switch (expectedType) {
5527
+ case "class":
5528
+ return typeof val === "string";
5473
5529
  case "code":
5474
5530
  return typeof val === "string";
5475
5531
  case "string":
@@ -5508,7 +5564,7 @@ var validateValue = (field, value) => {
5508
5564
  }
5509
5565
  if (msg) {
5510
5566
  throw new Error(
5511
- `Validation failed: Expected '${field.name}' to be a ${msg} instead got '${value}'`
5567
+ `Validation failed: Expected '${field.name}' to be type '${msg}' instead got '${value}'`
5512
5568
  );
5513
5569
  }
5514
5570
  return;
@@ -5533,7 +5589,7 @@ var validateValue = (field, value) => {
5533
5589
  }
5534
5590
  if (msg) {
5535
5591
  throw new Error(
5536
- `Validation failed: Expected '${field.name}' to be a ${msg} instead got '${value}'`
5592
+ `Validation failed: Expected '${field.name}' to be type '${msg}' instead got '${value}'`
5537
5593
  );
5538
5594
  }
5539
5595
  return;
@@ -5554,8 +5610,9 @@ var validateValue = (field, value) => {
5554
5610
  isValid = validateSingleValue(ft.name, value);
5555
5611
  }
5556
5612
  if (!isValid) {
5613
+ const gotType = Array.isArray(value) ? "array" : typeof value;
5557
5614
  throw new Error(
5558
- `Validation failed: Expected '${field.name}' to be a ${field.type?.isArray ? "an array of " : ""}${ft.name} instead got '${typeof value}' (${value})`
5615
+ `Validation failed: Expected '${field.name}' to be a ${field.type?.isArray ? "an array of " : ""}${ft.name} instead got '${gotType}' (${JSON.stringify(value)})`
5559
5616
  );
5560
5617
  }
5561
5618
  };
@@ -5760,11 +5817,15 @@ var AxPromptTemplate = class {
5760
5817
  task;
5761
5818
  thoughtFieldName;
5762
5819
  functions;
5820
+ strictExamples;
5821
+ optionalOutputFields;
5763
5822
  constructor(sig, options, fieldTemplates) {
5764
5823
  this.sig = sig;
5765
5824
  this.fieldTemplates = fieldTemplates;
5766
5825
  this.thoughtFieldName = options?.thoughtFieldName ?? "thought";
5767
5826
  this.functions = options?.functions;
5827
+ this.strictExamples = options?.strictExamples ?? false;
5828
+ this.optionalOutputFields = options?.optionalOutputFields ?? [];
5768
5829
  const task = [];
5769
5830
  const inArgs = renderDescFields(this.sig.getInputFields());
5770
5831
  const outArgs = renderDescFields(this.sig.getOutputFields());
@@ -5934,13 +5995,32 @@ ${outputFields}`);
5934
5995
  };
5935
5996
  renderExamples = (data) => {
5936
5997
  const list = [];
5998
+ const inputExampleContext = {
5999
+ isExample: true,
6000
+ strictExamples: this.strictExamples,
6001
+ optionalOutputFields: this.optionalOutputFields,
6002
+ isInputField: true
6003
+ };
6004
+ const outputExampleContext = {
6005
+ isExample: true,
6006
+ strictExamples: this.strictExamples,
6007
+ optionalOutputFields: this.optionalOutputFields,
6008
+ isInputField: false
6009
+ };
5937
6010
  for (const [index, item] of data.entries()) {
5938
- const renderedInputItem = this.sig.getInputFields().map((field) => this.renderInField(field, item)).filter((v) => v !== void 0).flat();
5939
- const renderedOutputItem = this.sig.getOutputFields().map((field) => this.renderInField(field, item)).filter((v) => v !== void 0).flat();
6011
+ const renderedInputItem = this.sig.getInputFields().map((field) => this.renderInField(field, item, inputExampleContext)).filter((v) => v !== void 0).flat();
6012
+ const outputFields = this.sig.getOutputFields();
6013
+ const renderedOutputItem = outputFields.map((field) => this.renderInField(field, item, outputExampleContext)).filter((v) => v !== void 0).flat();
5940
6014
  if (renderedOutputItem.length === 0) {
5941
- throw new Error(
5942
- `Output fields are required in examples: index: ${index}, data: ${JSON.stringify(item)}`
6015
+ const missingFields = outputFields.filter((field) => !item[field.name]);
6016
+ const allMissingFieldsAreOptional = missingFields.every(
6017
+ (field) => this.optionalOutputFields.includes(field.name)
5943
6018
  );
6019
+ if (!allMissingFieldsAreOptional) {
6020
+ throw new Error(
6021
+ `Output fields are required in examples: index: ${index}, data: ${JSON.stringify(item)}`
6022
+ );
6023
+ }
5944
6024
  }
5945
6025
  const renderedItem = [...renderedInputItem, ...renderedOutputItem];
5946
6026
  if (index > 0 && renderedItem.length > 0 && renderedItem[0]?.type === "text") {
@@ -5960,9 +6040,26 @@ ${outputFields}`);
5960
6040
  };
5961
6041
  renderDemos = (data) => {
5962
6042
  const list = [];
5963
- const fields = [...this.sig.getInputFields(), ...this.sig.getOutputFields()];
6043
+ const inputFields = this.sig.getInputFields();
6044
+ const outputFields = this.sig.getOutputFields();
5964
6045
  for (const item of data) {
5965
- const renderedItem = fields.map((field) => this.renderInField(field, item)).filter((v) => v !== void 0).flat();
6046
+ const inputRenderedItems = inputFields.map(
6047
+ (field) => this.renderInField(field, item, {
6048
+ isExample: true,
6049
+ strictExamples: this.strictExamples,
6050
+ optionalOutputFields: this.optionalOutputFields,
6051
+ isInputField: true
6052
+ })
6053
+ ).filter((v) => v !== void 0).flat();
6054
+ const outputRenderedItems = outputFields.map(
6055
+ (field) => this.renderInField(field, item, {
6056
+ isExample: true,
6057
+ strictExamples: this.strictExamples,
6058
+ optionalOutputFields: this.optionalOutputFields,
6059
+ isInputField: false
6060
+ })
6061
+ ).filter((v) => v !== void 0).flat();
6062
+ const renderedItem = [...inputRenderedItems, ...outputRenderedItems];
5966
6063
  renderedItem.slice(0, -1).forEach((v) => {
5967
6064
  if ("text" in v) {
5968
6065
  v.text = v.text + "\n";
@@ -5976,15 +6073,15 @@ ${outputFields}`);
5976
6073
  return list;
5977
6074
  };
5978
6075
  renderInputFields = (values) => {
5979
- const renderedItems = this.sig.getInputFields().map((field) => this.renderInField(field, values)).filter((v) => v !== void 0).flat();
6076
+ const renderedItems = this.sig.getInputFields().map((field) => this.renderInField(field, values, void 0)).filter((v) => v !== void 0).flat();
5980
6077
  renderedItems.filter((v) => v.type === "text").forEach((v) => {
5981
6078
  v.text = v.text + "\n";
5982
6079
  });
5983
6080
  return renderedItems;
5984
6081
  };
5985
- renderInField = (field, values) => {
6082
+ renderInField = (field, values, context3) => {
5986
6083
  const value = values[field.name];
5987
- if (isEmptyValue(field, value)) {
6084
+ if (isEmptyValue(field, value, context3)) {
5988
6085
  return;
5989
6086
  }
5990
6087
  if (field.type) {
@@ -6168,15 +6265,34 @@ function combineConsecutiveStrings(separator) {
6168
6265
  return acc;
6169
6266
  };
6170
6267
  }
6171
- var isEmptyValue = (field, value) => {
6268
+ var isEmptyValue = (field, value, context3) => {
6172
6269
  if (typeof value === "boolean") {
6173
6270
  return false;
6174
6271
  }
6175
6272
  if (!value || (Array.isArray(value) || typeof value === "string") && value.length === 0) {
6176
- if (field.isOptional || field.isInternal) {
6273
+ if (context3?.isExample) {
6274
+ const isInputField = context3?.isInputField ?? true;
6275
+ if (isInputField) {
6276
+ if (!context3?.strictExamples) {
6277
+ return true;
6278
+ } else {
6279
+ if (field.isOptional || field.isInternal) {
6280
+ return true;
6281
+ }
6282
+ throw new Error(`Value for input field '${field.name}' is required.`);
6283
+ }
6284
+ } else {
6285
+ if (field.isOptional || field.isInternal || context3?.optionalOutputFields?.includes(field.name)) {
6286
+ return true;
6287
+ }
6288
+ throw new Error(`Value for output field '${field.name}' is required.`);
6289
+ }
6290
+ }
6291
+ if (field.isOptional || field.isInternal || context3?.optionalOutputFields?.includes(field.name)) {
6177
6292
  return true;
6178
6293
  }
6179
- throw new Error(`Value for input field '${field.name}' is required.`);
6294
+ const fieldType = context3?.isInputField !== false ? "input" : "output";
6295
+ throw new Error(`Value for ${fieldType} field '${field.name}' is required.`);
6180
6296
  }
6181
6297
  return false;
6182
6298
  };
@@ -7436,6 +7552,7 @@ var AxProgramWithSignature = class {
7436
7552
  signature;
7437
7553
  sigHash;
7438
7554
  examples;
7555
+ examplesOptions;
7439
7556
  demos;
7440
7557
  trace;
7441
7558
  usage = [];
@@ -7477,16 +7594,16 @@ var AxProgramWithSignature = class {
7477
7594
  this.key.id = [parentId, this.key.id].join("/");
7478
7595
  }
7479
7596
  }
7480
- setExamples(examples) {
7481
- this._setExamples(examples);
7597
+ setExamples(examples, options) {
7598
+ this._setExamples(examples, options);
7482
7599
  if (!("programId" in examples)) {
7483
7600
  return;
7484
7601
  }
7485
7602
  for (const child of this.children) {
7486
- child.setExamples(examples);
7603
+ child.setExamples(examples, options);
7487
7604
  }
7488
7605
  }
7489
- _setExamples(examples) {
7606
+ _setExamples(examples, options) {
7490
7607
  let traces = [];
7491
7608
  if ("programId" in examples && examples.programId === this.key.id) {
7492
7609
  traces = examples.traces;
@@ -7495,6 +7612,7 @@ var AxProgramWithSignature = class {
7495
7612
  traces = examples;
7496
7613
  }
7497
7614
  if (traces) {
7615
+ this.examplesOptions = options;
7498
7616
  const sig = this.signature;
7499
7617
  const fields = [...sig.getInputFields(), ...sig.getOutputFields()];
7500
7618
  this.examples = traces.map((e) => {
@@ -7575,12 +7693,12 @@ var AxProgram = class {
7575
7693
  this.key.id = [parentId, this.key.id].join("/");
7576
7694
  }
7577
7695
  }
7578
- setExamples(examples) {
7696
+ setExamples(examples, options) {
7579
7697
  if (!("programId" in examples)) {
7580
7698
  return;
7581
7699
  }
7582
7700
  for (const child of this.children) {
7583
- child.setExamples(examples);
7701
+ child.setExamples(examples, options);
7584
7702
  }
7585
7703
  }
7586
7704
  getTraces() {
@@ -7634,7 +7752,9 @@ var AxGen = class extends AxProgramWithSignature {
7634
7752
  this.thoughtFieldName = options?.thoughtFieldName ?? "thought";
7635
7753
  const promptTemplateOptions = {
7636
7754
  functions: options?.functions,
7637
- thoughtFieldName: this.thoughtFieldName
7755
+ thoughtFieldName: this.thoughtFieldName,
7756
+ strictExamples: options?.strictExamples,
7757
+ optionalOutputFields: options?.optionalOutputFields
7638
7758
  };
7639
7759
  this.promptTemplate = new (options?.promptTemplate ?? AxPromptTemplate)(
7640
7760
  this.signature,
@@ -7720,7 +7840,8 @@ var AxGen = class extends AxProgramWithSignature {
7720
7840
  stream,
7721
7841
  debug: false,
7722
7842
  thinkingTokenBudget,
7723
- traceContext
7843
+ traceContext,
7844
+ abortSignal: options?.abortSignal
7724
7845
  }
7725
7846
  );
7726
7847
  return res;
@@ -7997,7 +8118,9 @@ Content: ${result.content}`
7997
8118
  const promptTemplateClass = this.options?.promptTemplate ?? AxPromptTemplate;
7998
8119
  const currentPromptTemplateOptions = {
7999
8120
  functions: options.functions,
8000
- thoughtFieldName: this.thoughtFieldName
8121
+ thoughtFieldName: this.thoughtFieldName,
8122
+ strictExamples: this.options?.strictExamples,
8123
+ optionalOutputFields: this.options?.optionalOutputFields
8001
8124
  };
8002
8125
  this.promptTemplate = new promptTemplateClass(
8003
8126
  this.signature,
@@ -8183,6 +8306,22 @@ Content: ${result.content}`
8183
8306
  stream: true
8184
8307
  });
8185
8308
  }
8309
+ setExamples(examples, options) {
8310
+ super.setExamples(examples, options);
8311
+ if (options?.optionalOutputFields) {
8312
+ const promptTemplateClass = this.options?.promptTemplate ?? AxPromptTemplate;
8313
+ const currentPromptTemplateOptions = {
8314
+ functions: this.functions,
8315
+ thoughtFieldName: this.thoughtFieldName,
8316
+ strictExamples: this.options?.strictExamples,
8317
+ optionalOutputFields: options.optionalOutputFields
8318
+ };
8319
+ this.promptTemplate = new promptTemplateClass(
8320
+ this.signature,
8321
+ currentPromptTemplateOptions
8322
+ );
8323
+ }
8324
+ }
8186
8325
  };
8187
8326
  var AxGenerateError = class extends Error {
8188
8327
  details;
@@ -8313,8 +8452,8 @@ var AxAgent = class {
8313
8452
  this.func.parameters = addModelParameter(this.func.parameters, mm);
8314
8453
  }
8315
8454
  }
8316
- setExamples(examples) {
8317
- this.program.setExamples(examples);
8455
+ setExamples(examples, options) {
8456
+ this.program.setExamples(examples, options);
8318
8457
  }
8319
8458
  setId(id) {
8320
8459
  this.program.setId(id);
@@ -9608,7 +9747,12 @@ var AxDBManager = class {
9608
9747
  const bs = options?.batchSize ?? 10;
9609
9748
  for (let i = 0; i < chunks.length; i += bs) {
9610
9749
  const batch = chunks.slice(i, i + bs);
9611
- const ret = await this.ai.embed({ texts: batch });
9750
+ const ret = await this.ai.embed(
9751
+ { texts: batch },
9752
+ {
9753
+ abortSignal: options?.abortSignal
9754
+ }
9755
+ );
9612
9756
  const embeddings = ret.embeddings.map((embedding, index) => ({
9613
9757
  id: `chunk_${Date.now() + index}`,
9614
9758
  // Unique ID for each chunk, adjusted by index
@@ -9624,7 +9768,10 @@ var AxDBManager = class {
9624
9768
  throw new Error(`Error processing text: ${error}`);
9625
9769
  }
9626
9770
  };
9627
- query = async (query, { topPercent } = {}) => {
9771
+ query = async (query, {
9772
+ topPercent,
9773
+ abortSignal
9774
+ } = {}) => {
9628
9775
  const texts = Array.isArray(query) ? query : [query];
9629
9776
  if (typeof texts[0] === "string" && this.rewriter) {
9630
9777
  for (const [i, text] of texts.entries()) {
@@ -9636,7 +9783,12 @@ var AxDBManager = class {
9636
9783
  }
9637
9784
  let queries;
9638
9785
  if (typeof texts[0] === "string") {
9639
- const embedResults = await this.ai.embed({ texts });
9786
+ const embedResults = await this.ai.embed(
9787
+ { texts },
9788
+ {
9789
+ abortSignal
9790
+ }
9791
+ );
9640
9792
  queries = embedResults.embeddings.map(
9641
9793
  (values) => this.db.query({ table, values })
9642
9794
  );
@@ -11231,9 +11383,14 @@ var AxSimpleClassifier = class {
11231
11383
  setState(state) {
11232
11384
  this.db.setDB(state);
11233
11385
  }
11234
- setClasses = async (classes) => {
11386
+ setClasses = async (classes, options) => {
11235
11387
  for (const c of classes) {
11236
- const ret = await this.ai.embed({ texts: c.getContext() });
11388
+ const ret = await this.ai.embed(
11389
+ { texts: c.getContext() },
11390
+ {
11391
+ abortSignal: options?.abortSignal
11392
+ }
11393
+ );
11237
11394
  await this.db.upsert({
11238
11395
  id: c.getName(),
11239
11396
  table: "classes",
@@ -11242,7 +11399,12 @@ var AxSimpleClassifier = class {
11242
11399
  }
11243
11400
  };
11244
11401
  async forward(text, options) {
11245
- const { embeddings } = await this.ai.embed({ texts: [text] });
11402
+ const { embeddings } = await this.ai.embed(
11403
+ { texts: [text] },
11404
+ {
11405
+ abortSignal: options?.abortSignal
11406
+ }
11407
+ );
11246
11408
  const matches = await this.db.query({
11247
11409
  table: "classes",
11248
11410
  values: embeddings[0]
@@ -11317,6 +11479,79 @@ var AxTestPrompt = class {
11317
11479
  }
11318
11480
  };
11319
11481
 
11482
+ // ai/abortable.ts
11483
+ var AxAbortableAI = class {
11484
+ abortController;
11485
+ ai;
11486
+ constructor(ai) {
11487
+ this.ai = ai;
11488
+ this.abortController = new AbortController();
11489
+ }
11490
+ /**
11491
+ * Get the current abort signal
11492
+ */
11493
+ get signal() {
11494
+ return this.abortController.signal;
11495
+ }
11496
+ /**
11497
+ * Check if the request has been aborted
11498
+ */
11499
+ get aborted() {
11500
+ return this.abortController.signal.aborted;
11501
+ }
11502
+ /**
11503
+ * Abort the ongoing request
11504
+ * @param reason Optional reason for the abort
11505
+ */
11506
+ abort(reason) {
11507
+ this.abortController.abort(reason);
11508
+ }
11509
+ /**
11510
+ * Reset the abort controller to allow new requests
11511
+ * This creates a new AbortController, allowing fresh requests
11512
+ */
11513
+ reset() {
11514
+ this.abortController = new AbortController();
11515
+ }
11516
+ /**
11517
+ * Send a chat request with abort support
11518
+ */
11519
+ async chat(req, options) {
11520
+ return this.ai.chat(req, {
11521
+ ...options,
11522
+ abortSignal: this.abortController.signal
11523
+ });
11524
+ }
11525
+ /**
11526
+ * Send an embed request with abort support
11527
+ */
11528
+ async embed(req, options) {
11529
+ return this.ai.embed(req, {
11530
+ ...options,
11531
+ abortSignal: this.abortController.signal
11532
+ });
11533
+ }
11534
+ /**
11535
+ * Create a timeout-based abort after specified milliseconds
11536
+ * @param timeoutMs Timeout in milliseconds
11537
+ * @param reason Optional reason for the timeout abort
11538
+ * @returns Timeout ID that can be cleared
11539
+ */
11540
+ abortAfter(timeoutMs, reason = "Request timeout") {
11541
+ return setTimeout(() => {
11542
+ this.abort(reason);
11543
+ }, timeoutMs);
11544
+ }
11545
+ /**
11546
+ * Add an event listener for abort events
11547
+ */
11548
+ onAbort(callback) {
11549
+ this.abortController.signal.addEventListener("abort", () => {
11550
+ callback(this.abortController.signal.reason);
11551
+ });
11552
+ }
11553
+ };
11554
+
11320
11555
  // prompts/cot.ts
11321
11556
  var AxChainOfThought = class extends AxGen {
11322
11557
  constructor(signature, options) {
@@ -11443,7 +11678,10 @@ var AxEmbeddingAdapter = class {
11443
11678
  async embedAdapter(text, extra) {
11444
11679
  const embedRes = await this.aiService.embed(
11445
11680
  { texts: [text] },
11446
- { sessionId: extra?.sessionId }
11681
+ {
11682
+ sessionId: extra?.sessionId,
11683
+ abortSignal: extra?.abortSignal
11684
+ }
11447
11685
  );
11448
11686
  const embeds = embedRes.embeddings.at(0);
11449
11687
  if (!embeds) {
@@ -13206,6 +13444,7 @@ export {
13206
13444
  AxAIOpenAIResponsesImpl,
13207
13445
  AxAIReka,
13208
13446
  AxAIRekaModel,
13447
+ AxAIServiceAbortedError,
13209
13448
  AxAIServiceAuthenticationError,
13210
13449
  AxAIServiceError,
13211
13450
  AxAIServiceNetworkError,
@@ -13214,6 +13453,7 @@ export {
13214
13453
  AxAIServiceStreamTerminatedError,
13215
13454
  AxAIServiceTimeoutError,
13216
13455
  AxAITogether,
13456
+ AxAbortableAI,
13217
13457
  AxAgent,
13218
13458
  AxApacheTika,
13219
13459
  AxAssertionError,