@ax-llm/ax 10.0.39 → 10.0.40

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
  AxJSInterpreterPermission: () => AxJSInterpreterPermission,
85
85
  AxLLMRequestTypeValues: () => AxLLMRequestTypeValues,
86
86
  AxMemory: () => AxMemory,
87
+ AxMockAIService: () => AxMockAIService,
87
88
  AxProgram: () => AxProgram,
88
89
  AxProgramWithSignature: () => AxProgramWithSignature,
89
90
  AxPromptTemplate: () => AxPromptTemplate,
@@ -618,9 +619,11 @@ var AxBaseAI = class {
618
619
  }
619
620
  },
620
621
  async (span) => {
621
- const res = await this._chat2(model, modelConfig, req, options, span);
622
- span.end();
623
- return res;
622
+ try {
623
+ return await this._chat2(model, modelConfig, req, options, span);
624
+ } finally {
625
+ span.end();
626
+ }
624
627
  }
625
628
  );
626
629
  }
@@ -743,9 +746,11 @@ var AxBaseAI = class {
743
746
  }
744
747
  },
745
748
  async (span) => {
746
- const res = await this._embed2(embedModel, req, options, span);
747
- span.end();
748
- return res;
749
+ try {
750
+ return await this._embed2(embedModel, req, options, span);
751
+ } finally {
752
+ span.end();
753
+ }
749
754
  }
750
755
  );
751
756
  }
@@ -813,7 +818,7 @@ ${colorLog.whiteBright(msg.content)}`;
813
818
  const items2 = msg.content.map((v) => {
814
819
  switch (v.type) {
815
820
  case "text":
816
- return `(Text) ${colorLog.whiteBright(v.text)}`;
821
+ return `${colorLog.whiteBright(v.text)}`;
817
822
  case "image":
818
823
  return `(Image, ${v.mimeType}) ${colorLog.whiteBright(v.image.substring(0, 10))}`;
819
824
  default:
@@ -968,6 +973,30 @@ var AxAIAnthropicImpl = class {
968
973
  const apiConfig = {
969
974
  name: "/messages"
970
975
  };
976
+ let toolsChoice;
977
+ if (req.functionCall && req.functions && req.functions.length > 0) {
978
+ if (typeof req.functionCall === "string") {
979
+ switch (req.functionCall) {
980
+ case "auto":
981
+ toolsChoice = { tool_choice: { type: "auto" } };
982
+ break;
983
+ case "required":
984
+ toolsChoice = { tool_choice: { type: "any" } };
985
+ break;
986
+ case "none":
987
+ throw new Error("functionCall none not supported");
988
+ }
989
+ } else if ("function" in req.functionCall) {
990
+ toolsChoice = {
991
+ tool_choice: {
992
+ type: "tool",
993
+ name: req.functionCall.function.name
994
+ }
995
+ };
996
+ } else {
997
+ throw new Error("Invalid function call type, must be string or object");
998
+ }
999
+ }
971
1000
  const system = req.chatPrompt.filter((msg) => msg.role === "system").map((msg) => ({
972
1001
  type: "text",
973
1002
  text: msg.content,
@@ -990,7 +1019,8 @@ var AxAIAnthropicImpl = class {
990
1019
  temperature: req.modelConfig?.temperature ?? this.config.temperature,
991
1020
  top_p: req.modelConfig?.topP ?? this.config.topP,
992
1021
  top_k: req.modelConfig?.topK ?? this.config.topK,
993
- ...tools && tools.length > 0 ? { tools, tool_choice: { type: "auto" } } : {},
1022
+ ...toolsChoice,
1023
+ ...tools && tools.length > 0 ? { tools } : {},
994
1024
  ...stream ? { stream: true } : {},
995
1025
  ...system ? { system } : {},
996
1026
  messages
@@ -3299,9 +3329,6 @@ var AxAI = class {
3299
3329
  }
3300
3330
  };
3301
3331
 
3302
- // prompts/agent.ts
3303
- var import_api23 = require("@opentelemetry/api");
3304
-
3305
3332
  // dsp/generate.ts
3306
3333
  var import_web5 = require("stream/web");
3307
3334
  var import_api22 = require("@opentelemetry/api");
@@ -3490,7 +3517,7 @@ var AxAssertionError = class extends Error {
3490
3517
  extraFields.push({
3491
3518
  name: "error",
3492
3519
  title: "Error In Output",
3493
- description: this.message
3520
+ description: `You must follow the following instructions, "${this.message}".`
3494
3521
  });
3495
3522
  return extraFields;
3496
3523
  };
@@ -3529,18 +3556,6 @@ var assertStreamingAssertions = (asserts, values, xstate, content, final) => {
3529
3556
  }
3530
3557
  }
3531
3558
  };
3532
- var assertRequiredFields = (sig, values) => {
3533
- const fields = sig.getOutputFields();
3534
- const missingFields = fields.filter(
3535
- (f) => !f.isOptional && !(f.name in values)
3536
- );
3537
- if (missingFields.length > 0) {
3538
- throw new AxAssertionError({
3539
- message: `Output must include: ${missingFields.map((f) => `\`${f.title}:\``).join(", ")}`,
3540
- values
3541
- });
3542
- }
3543
- };
3544
3559
 
3545
3560
  // dsp/extract.ts
3546
3561
  var import_json5 = __toESM(require("json5"), 1);
@@ -4088,6 +4103,21 @@ var parseMarkdownList = (input) => {
4088
4103
  }
4089
4104
  return list;
4090
4105
  };
4106
+ function mergeDeltas(base, delta) {
4107
+ const merged = { ...base };
4108
+ for (const key in delta) {
4109
+ const baseValue = base[key];
4110
+ const deltaValue = delta[key];
4111
+ if (Array.isArray(baseValue) && Array.isArray(deltaValue)) {
4112
+ merged[key] = [...baseValue, ...deltaValue];
4113
+ } else if (typeof baseValue === "string" && typeof deltaValue === "string") {
4114
+ merged[key] = baseValue + deltaValue;
4115
+ } else {
4116
+ merged[key] = deltaValue;
4117
+ }
4118
+ }
4119
+ return merged;
4120
+ }
4091
4121
 
4092
4122
  // dsp/program.ts
4093
4123
  var AxProgramWithSignature = class {
@@ -4120,6 +4150,9 @@ var AxProgramWithSignature = class {
4120
4150
  async forward(_ai, _values, _options) {
4121
4151
  throw new Error("forward() not implemented");
4122
4152
  }
4153
+ async *streamingForward(_ai, _values, _options) {
4154
+ throw new Error("streamingForward() not implemented");
4155
+ }
4123
4156
  setId(id) {
4124
4157
  this.key = { id, custom: true };
4125
4158
  for (const child of this.children) {
@@ -4214,6 +4247,9 @@ var AxProgram = class {
4214
4247
  async forward(_ai, _values, _options) {
4215
4248
  throw new Error("forward() not implemented");
4216
4249
  }
4250
+ async *streamingForward(_ai, _values, _options) {
4251
+ throw new Error("streamingForward() not implemented");
4252
+ }
4217
4253
  setId(id) {
4218
4254
  this.key = { id, custom: true };
4219
4255
  for (const child of this.children) {
@@ -4311,9 +4347,10 @@ ${outputFields}`);
4311
4347
  task.push(formattingRules.trim());
4312
4348
  const desc = this.sig.getDescription();
4313
4349
  if (desc) {
4350
+ const capitalized = capitalizeFirstLetter(desc.trim());
4314
4351
  task.push(
4315
4352
  `## TASK DESCRIPTION
4316
- ${capitalizeFirstLetter(desc.endsWith(".") ? desc : desc + ".")}`
4353
+ ${capitalized.endsWith(".") ? capitalized : capitalized + "."}`
4317
4354
  );
4318
4355
  }
4319
4356
  this.task = {
@@ -4361,16 +4398,42 @@ ${capitalizeFirstLetter(desc.endsWith(".") ? desc : desc + ".")}`
4361
4398
  };
4362
4399
  renderExtraFields = (extraFields) => {
4363
4400
  const prompt = [];
4364
- if (extraFields && extraFields.length > 0) {
4365
- extraFields.forEach((field) => {
4366
- const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
4367
- prompt.push(...fn(field, field.description));
4368
- });
4369
- }
4370
- if (prompt.every((v) => v.type === "text")) {
4371
- return prompt.map((v) => v.text).join("\n\n");
4372
- }
4373
- return prompt.reduce(combineConsecutiveStrings("\n"), []);
4401
+ if (!extraFields || extraFields.length === 0) {
4402
+ return prompt;
4403
+ }
4404
+ const groupedFields = extraFields.reduce(
4405
+ (acc, field) => {
4406
+ const title = field.title;
4407
+ if (!acc[title]) {
4408
+ acc[title] = [];
4409
+ }
4410
+ acc[title].push(field);
4411
+ return acc;
4412
+ },
4413
+ {}
4414
+ );
4415
+ const formattedGroupedFields = Object.entries(groupedFields).map(([title, fields]) => {
4416
+ if (fields.length === 1) {
4417
+ const field = fields[0];
4418
+ return {
4419
+ title,
4420
+ name: field.name,
4421
+ description: field.description
4422
+ };
4423
+ } else if (fields.length > 1) {
4424
+ const valuesList = fields.map((field) => `- ${field.description}`).join("\n");
4425
+ return {
4426
+ title,
4427
+ name: fields[0].name,
4428
+ description: valuesList
4429
+ };
4430
+ }
4431
+ }).filter(Boolean);
4432
+ formattedGroupedFields.forEach((field) => {
4433
+ const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
4434
+ prompt.push(...fn(field, field.description));
4435
+ });
4436
+ return prompt;
4374
4437
  };
4375
4438
  renderExamples = (data) => {
4376
4439
  const list = [];
@@ -4619,34 +4682,47 @@ function capitalizeFirstLetter(str) {
4619
4682
  }
4620
4683
 
4621
4684
  // dsp/validate.ts
4685
+ var colorLog4 = new ColorLog();
4622
4686
  var ValidationError = class extends Error {
4623
- field;
4624
- value;
4687
+ fields;
4625
4688
  constructor({
4626
4689
  message,
4627
- field,
4628
- value
4690
+ fields
4629
4691
  }) {
4630
4692
  super(message);
4631
- this.field = field;
4632
- this.value = value;
4693
+ this.fields = fields;
4633
4694
  this.name = this.constructor.name;
4634
4695
  Error.captureStackTrace(this, this.constructor);
4635
4696
  }
4636
- getField = () => this.field;
4637
- getValue = () => this.value;
4697
+ getFields = () => this.fields;
4638
4698
  getFixingInstructions = () => {
4639
- const f = this.field;
4640
- const extraFields = [
4641
- {
4642
- name: `outputError`,
4643
- title: `Invalid Output Field`,
4644
- description: `Invalid format for field \`${f.title}\` of type \`${toFieldType(f.type)}\`, format should match: \`${f.description}\``
4645
- }
4646
- ];
4647
- return extraFields;
4699
+ return this.fields.map((field) => ({
4700
+ name: "outputError",
4701
+ title: "Error In Output",
4702
+ description: `Please fix and return the field \`${field.title}\` of type \`${toFieldType(field.type)}\`, ${this.message}.`
4703
+ }));
4648
4704
  };
4649
4705
  };
4706
+ function handleValidationError(mem, errorFields, ai, promptTemplate, sessionId) {
4707
+ mem.add(
4708
+ {
4709
+ role: "user",
4710
+ content: promptTemplate.renderExtraFields(errorFields)
4711
+ },
4712
+ sessionId
4713
+ );
4714
+ mem.addTag("error");
4715
+ if (ai.getOptions().debug) {
4716
+ process.stdout.write(
4717
+ colorLog4.red(
4718
+ `
4719
+ Error Correction:
4720
+ ${JSON.stringify(errorFields, null, 2)}
4721
+ `
4722
+ )
4723
+ );
4724
+ }
4725
+ }
4650
4726
 
4651
4727
  // dsp/datetime.ts
4652
4728
  function parseLLMFriendlyDate(field, dateStr) {
@@ -4654,7 +4730,7 @@ function parseLLMFriendlyDate(field, dateStr) {
4654
4730
  return _parseLLMFriendlyDate(dateStr);
4655
4731
  } catch (err) {
4656
4732
  const message = err.message;
4657
- throw new ValidationError({ field, message, value: dateStr });
4733
+ throw new ValidationError({ fields: [field], message, value: dateStr });
4658
4734
  }
4659
4735
  }
4660
4736
  function _parseLLMFriendlyDate(dateStr) {
@@ -4671,7 +4747,7 @@ function parseLLMFriendlyDateTime(field, dateStr) {
4671
4747
  return _parseLLMFriendlyDateTime(dateStr);
4672
4748
  } catch (err) {
4673
4749
  const message = err.message;
4674
- throw new ValidationError({ field, message, value: dateStr });
4750
+ throw new ValidationError({ fields: [field], message, value: dateStr });
4675
4751
  }
4676
4752
  }
4677
4753
  function _parseLLMFriendlyDateTime(dateTimeStr) {
@@ -4713,41 +4789,61 @@ var formatDateWithTimezone = (date) => {
4713
4789
 
4714
4790
  // dsp/extract.ts
4715
4791
  var extractValues = (sig, values, content) => {
4716
- const xstate = { s: -1 };
4792
+ const xstate = { extractedFields: [], s: -1 };
4717
4793
  streamingExtractValues(sig, values, xstate, content);
4718
- streamingExtractFinalValue(values, xstate, content);
4794
+ streamingExtractFinalValue(sig, values, xstate, content);
4795
+ };
4796
+ var checkMissingRequiredFields = (xstate, values, currentIndex) => {
4797
+ const missingFields = [];
4798
+ for (let i = 0; i < currentIndex; i++) {
4799
+ const field = xstate.extractedFields[i];
4800
+ if (field && !field.isOptional && values[field.name] === void 0) {
4801
+ missingFields.push(field);
4802
+ }
4803
+ }
4804
+ if (missingFields.length > 0) {
4805
+ throw new ValidationError({
4806
+ message: `Required ${missingFields.length === 1 ? "field" : "fields"} not found`,
4807
+ fields: missingFields
4808
+ });
4809
+ }
4719
4810
  };
4720
- var streamingExtractValues = (sig, values, state, content) => {
4811
+ var streamingExtractValues = (sig, values, xstate, content) => {
4721
4812
  const fields = sig.getOutputFields();
4722
- for (const field of fields) {
4813
+ for (const [index, field] of fields.entries()) {
4723
4814
  if (field.name in values) {
4724
4815
  continue;
4725
4816
  }
4726
4817
  const prefix = field.title + ":";
4727
- const e = content.indexOf(prefix, state.s + 1);
4818
+ const e = content.indexOf(prefix, xstate.s + 1);
4728
4819
  if (e === -1) {
4729
4820
  continue;
4730
4821
  }
4731
- if (state.currField) {
4732
- const val = content.substring(state.s, e).trim().replace(/---+$/, "").trim();
4733
- values[state.currField.name] = validateAndParseFieldValue(
4734
- state.currField,
4735
- val
4736
- );
4822
+ if (xstate.currField) {
4823
+ const val = content.substring(xstate.s, e);
4824
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
4825
+ if (parsedValue !== void 0) {
4826
+ values[xstate.currField.name] = parsedValue;
4827
+ }
4828
+ }
4829
+ checkMissingRequiredFields(xstate, values, index);
4830
+ xstate.s = e + prefix.length;
4831
+ xstate.currField = field;
4832
+ if (!xstate.extractedFields.includes(field)) {
4833
+ xstate.extractedFields.push(field);
4737
4834
  }
4738
- state.s = e + prefix.length;
4739
- state.currField = field;
4740
4835
  }
4741
4836
  };
4742
- var streamingExtractFinalValue = (values, state, content) => {
4743
- if (!state.currField) {
4744
- return;
4837
+ var streamingExtractFinalValue = (sig, values, xstate, content) => {
4838
+ if (xstate.currField) {
4839
+ const val = content.substring(xstate.s);
4840
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
4841
+ if (parsedValue !== void 0) {
4842
+ values[xstate.currField.name] = parsedValue;
4843
+ }
4745
4844
  }
4746
- const val = content.substring(state.s).trim().replace(/---+$/, "").trim();
4747
- values[state.currField.name] = validateAndParseFieldValue(
4748
- state.currField,
4749
- val
4750
- );
4845
+ const fields = sig.getOutputFields();
4846
+ checkMissingRequiredFields(xstate, values, fields.length - 1);
4751
4847
  };
4752
4848
  var convertValueToType = (field, val) => {
4753
4849
  switch (field.type?.name) {
@@ -4785,59 +4881,98 @@ var convertValueToType = (field, val) => {
4785
4881
  return val;
4786
4882
  }
4787
4883
  };
4788
- var expectedTypeError = (field, err, value = "") => {
4789
- const exp = field.type?.isArray ? `array of ${field.type.name}` : field.type?.name;
4790
- const message = `Error '${err.message}', expected '${exp}' got '${value}'`;
4791
- return new ValidationError({ message, field, value });
4792
- };
4884
+ function* streamingValues(sig, values, xstate, content) {
4885
+ if (!xstate.currField) {
4886
+ return;
4887
+ }
4888
+ const fieldName = xstate.currField.name;
4889
+ if (!xstate.streamedIndex) {
4890
+ xstate.streamedIndex = { [fieldName]: 0 };
4891
+ }
4892
+ if (!xstate.currField.type || !xstate.currField.type.isArray && xstate.currField.type.name === "string") {
4893
+ const s = xstate.s + (xstate.streamedIndex[fieldName] ?? 0);
4894
+ const v = content.substring(s);
4895
+ yield { [fieldName]: v };
4896
+ xstate.streamedIndex[fieldName] = v.length;
4897
+ return;
4898
+ }
4899
+ for (const key of Object.keys(values)) {
4900
+ const value = values[key];
4901
+ if (Array.isArray(value)) {
4902
+ const s = xstate.streamedIndex[fieldName] ?? 0;
4903
+ const v = value.slice(s);
4904
+ if (v) {
4905
+ yield { [fieldName]: v };
4906
+ xstate.streamedIndex[fieldName] = s + 1;
4907
+ }
4908
+ continue;
4909
+ }
4910
+ if (!xstate.streamedIndex[fieldName]) {
4911
+ yield { [fieldName]: value };
4912
+ xstate.streamedIndex[fieldName] = 1;
4913
+ }
4914
+ }
4915
+ }
4793
4916
  function validateAndParseFieldValue(field, fieldValue) {
4794
- const fv = fieldValue?.toLocaleLowerCase();
4795
- if (!fieldValue || !fv || fv === "" || fv === "null" || fv === "undefined") {
4917
+ const fv = fieldValue?.trim();
4918
+ if (!fv || !fv || fv === "" || fv === "null" || fv === "NULL" || fv === "undefined") {
4796
4919
  if (field.isOptional) {
4797
4920
  return;
4798
4921
  }
4799
- throw expectedTypeError(field, new Error("Empty value"), fieldValue);
4922
+ throw new ValidationError({
4923
+ message: "Required field is missing",
4924
+ fields: [field],
4925
+ value: fv
4926
+ });
4800
4927
  }
4801
- let value = fieldValue;
4928
+ let value;
4802
4929
  if (field.type?.name === "json") {
4803
4930
  try {
4804
- const text = extractBlock(fieldValue);
4931
+ const text = extractBlock(fv);
4805
4932
  value = import_json5.default.parse(text);
4806
4933
  return value;
4807
4934
  } catch (e) {
4808
- throw expectedTypeError(field, e, fieldValue);
4935
+ throw new ValidationError({
4936
+ message: "Invalid JSON: " + e.message,
4937
+ fields: [field],
4938
+ value: fv
4939
+ });
4809
4940
  }
4810
4941
  }
4811
4942
  if (field.type?.isArray) {
4812
4943
  try {
4813
4944
  try {
4814
- value = import_json5.default.parse(fieldValue);
4945
+ value = import_json5.default.parse(fv);
4815
4946
  } catch {
4816
- value = parseMarkdownList(fieldValue);
4947
+ value = parseMarkdownList(fv);
4817
4948
  }
4818
4949
  if (!Array.isArray(value)) {
4819
4950
  throw new Error("Expected an array");
4820
4951
  }
4821
4952
  } catch (e) {
4822
- throw expectedTypeError(field, e, fieldValue);
4953
+ throw new ValidationError({
4954
+ message: "Invalid array: " + e.message,
4955
+ fields: [field],
4956
+ value: fv
4957
+ });
4823
4958
  }
4824
4959
  }
4825
- if (Array.isArray(value)) {
4826
- for (const [index, item] of value.entries()) {
4827
- try {
4960
+ try {
4961
+ if (Array.isArray(value)) {
4962
+ for (const [index, item] of value.entries()) {
4828
4963
  value[index] = convertValueToType(field, item);
4829
- } catch (e) {
4830
- throw expectedTypeError(field, e, item);
4831
4964
  }
4965
+ } else {
4966
+ value = convertValueToType(field, fv);
4832
4967
  }
4833
- } else {
4834
- try {
4835
- value = convertValueToType(field, fieldValue);
4836
- } catch (e) {
4837
- throw expectedTypeError(field, e, fieldValue);
4838
- }
4968
+ } catch (e) {
4969
+ throw new ValidationError({
4970
+ message: e.message,
4971
+ fields: [field],
4972
+ value: fieldValue
4973
+ });
4839
4974
  }
4840
- return value;
4975
+ return value ?? fv;
4841
4976
  }
4842
4977
  var extractBlock = (input) => {
4843
4978
  const jsonBlockPattern = /```([A-Za-z]+)?\s*([\s\S]*?)\s*```/g;
@@ -5004,7 +5139,6 @@ function parseFunctionCalls(ai, functionCalls, values, model) {
5004
5139
  }
5005
5140
 
5006
5141
  // dsp/generate.ts
5007
- var colorLog4 = new ColorLog();
5008
5142
  var AxGen = class extends AxProgramWithSignature {
5009
5143
  promptTemplate;
5010
5144
  asserts;
@@ -5069,7 +5203,7 @@ var AxGen = class extends AxProgramWithSignature {
5069
5203
  );
5070
5204
  return res;
5071
5205
  }
5072
- async forwardCore({
5206
+ async *forwardCore({
5073
5207
  ai,
5074
5208
  mem,
5075
5209
  options
@@ -5085,7 +5219,18 @@ var AxGen = class extends AxProgramWithSignature {
5085
5219
  options
5086
5220
  });
5087
5221
  if (res instanceof import_web5.ReadableStream) {
5088
- return await this.processSteamingResponse({
5222
+ yield* this.processStreamingResponse({
5223
+ ai,
5224
+ model,
5225
+ res,
5226
+ usageInfo,
5227
+ mem,
5228
+ traceId,
5229
+ sessionId,
5230
+ functions
5231
+ });
5232
+ } else {
5233
+ yield await this.processResponse({
5089
5234
  ai,
5090
5235
  model,
5091
5236
  res,
@@ -5096,18 +5241,8 @@ var AxGen = class extends AxProgramWithSignature {
5096
5241
  functions
5097
5242
  });
5098
5243
  }
5099
- return await this.processResponse({
5100
- ai,
5101
- model,
5102
- res,
5103
- usageInfo,
5104
- mem,
5105
- traceId,
5106
- sessionId,
5107
- functions
5108
- });
5109
5244
  }
5110
- async processSteamingResponse({
5245
+ async *processStreamingResponse({
5111
5246
  ai,
5112
5247
  model,
5113
5248
  res,
@@ -5119,36 +5254,39 @@ var AxGen = class extends AxProgramWithSignature {
5119
5254
  }) {
5120
5255
  const functionCalls = [];
5121
5256
  const values = {};
5122
- const xstate = { s: -1 };
5257
+ const xstate = { extractedFields: [], s: -1 };
5123
5258
  let content = "";
5124
5259
  for await (const v of res) {
5125
- for (const result of v.results ?? []) {
5126
- if (v.modelUsage) {
5127
- this.usage.push({ ...usageInfo, ...v.modelUsage });
5128
- }
5129
- if (result.content) {
5130
- content += result.content;
5131
- mem.updateResult({ name: result.name, content }, sessionId);
5132
- assertStreamingAssertions(
5133
- this.streamingAsserts,
5134
- values,
5135
- xstate,
5136
- content,
5137
- false
5138
- );
5139
- streamingExtractValues(this.signature, values, xstate, content);
5140
- assertAssertions(this.asserts, values);
5141
- }
5142
- if (result.functionCalls) {
5143
- mergeFunctionCalls(functionCalls, result.functionCalls);
5144
- mem.updateResult(
5145
- { name: result.name, content, functionCalls },
5146
- sessionId
5147
- );
5148
- }
5149
- if (result.finishReason === "length") {
5150
- throw new Error("Max tokens reached before completion");
5151
- }
5260
+ const result = v.results[0];
5261
+ if (!result) {
5262
+ continue;
5263
+ }
5264
+ if (v.modelUsage) {
5265
+ this.usage.push({ ...usageInfo, ...v.modelUsage });
5266
+ }
5267
+ if (result.content) {
5268
+ content += result.content;
5269
+ mem.updateResult({ name: result.name, content }, sessionId);
5270
+ assertStreamingAssertions(
5271
+ this.streamingAsserts,
5272
+ values,
5273
+ xstate,
5274
+ content,
5275
+ false
5276
+ );
5277
+ streamingExtractValues(this.signature, values, xstate, content);
5278
+ assertAssertions(this.asserts, values);
5279
+ yield* streamingValues(this.signature, values, xstate, content);
5280
+ }
5281
+ if (result.functionCalls) {
5282
+ mergeFunctionCalls(functionCalls, result.functionCalls);
5283
+ mem.updateResult(
5284
+ { name: result.name, content, functionCalls },
5285
+ sessionId
5286
+ );
5287
+ }
5288
+ if (result.finishReason === "length") {
5289
+ throw new Error("Max tokens reached before completion");
5152
5290
  }
5153
5291
  }
5154
5292
  const funcs = parseFunctionCalls(ai, functionCalls, values, model);
@@ -5166,7 +5304,6 @@ var AxGen = class extends AxProgramWithSignature {
5166
5304
  );
5167
5305
  this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5168
5306
  }
5169
- streamingExtractFinalValue(values, xstate, content);
5170
5307
  assertStreamingAssertions(
5171
5308
  this.streamingAsserts,
5172
5309
  values,
@@ -5174,8 +5311,9 @@ var AxGen = class extends AxProgramWithSignature {
5174
5311
  content,
5175
5312
  true
5176
5313
  );
5314
+ streamingExtractFinalValue(this.signature, values, xstate, content);
5177
5315
  assertAssertions(this.asserts, values);
5178
- return { ...values };
5316
+ return values;
5179
5317
  }
5180
5318
  async processResponse({
5181
5319
  ai,
@@ -5187,45 +5325,47 @@ var AxGen = class extends AxProgramWithSignature {
5187
5325
  functions
5188
5326
  }) {
5189
5327
  const values = {};
5190
- for (const result of res.results ?? []) {
5191
- if (res.modelUsage) {
5192
- this.usage.push({ ...usageInfo, ...res.modelUsage });
5193
- }
5194
- mem.addResult(result, sessionId);
5195
- if (result.content) {
5196
- extractValues(this.signature, values, result.content);
5197
- assertAssertions(this.asserts, values);
5198
- }
5199
- if (result.functionCalls) {
5200
- const funcs = parseFunctionCalls(ai, result.functionCalls, values);
5201
- if (funcs) {
5202
- if (!functions) {
5203
- throw new Error("Functions are not defined");
5204
- }
5205
- const fx = await processFunctions(
5206
- ai,
5207
- functions,
5208
- funcs,
5209
- mem,
5210
- sessionId,
5211
- traceId
5212
- );
5213
- this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5328
+ const result = res.results[0];
5329
+ if (!result) {
5330
+ throw new Error("No result found");
5331
+ }
5332
+ if (res.modelUsage) {
5333
+ this.usage.push({ ...usageInfo, ...res.modelUsage });
5334
+ }
5335
+ mem.addResult(result, sessionId);
5336
+ if (result.content) {
5337
+ extractValues(this.signature, values, result.content);
5338
+ assertAssertions(this.asserts, values);
5339
+ }
5340
+ if (result.functionCalls) {
5341
+ const funcs = parseFunctionCalls(ai, result.functionCalls, values);
5342
+ if (funcs) {
5343
+ if (!functions) {
5344
+ throw new Error("Functions are not defined");
5214
5345
  }
5215
- }
5216
- if (result.finishReason === "length") {
5217
- throw new Error("Max tokens reached before completion");
5346
+ const fx = await processFunctions(
5347
+ ai,
5348
+ functions,
5349
+ funcs,
5350
+ mem,
5351
+ sessionId,
5352
+ traceId
5353
+ );
5354
+ this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5218
5355
  }
5219
5356
  }
5357
+ if (result.finishReason === "length") {
5358
+ throw new Error("Max tokens reached before completion");
5359
+ }
5220
5360
  return { ...values };
5221
5361
  }
5222
- async _forward(ai, values, options, span) {
5362
+ async *_forward2(ai, values, options, span) {
5223
5363
  const stopFunction = (options?.stopFunction ?? this.options?.stopFunction)?.toLowerCase();
5224
- const maxRetries = options?.maxRetries ?? this.options?.maxRetries ?? 3;
5225
- const maxSteps = options?.maxSteps ?? this.options?.maxSteps ?? 10;
5226
- const mem = options?.mem ?? this.options?.mem ?? new AxMemory();
5364
+ const maxRetries = options.maxRetries ?? this.options?.maxRetries ?? 10;
5365
+ const maxSteps = options.maxSteps ?? this.options?.maxSteps ?? 10;
5366
+ const mem = options.mem ?? this.options?.mem ?? new AxMemory();
5227
5367
  let err;
5228
- if (options?.functions && options?.functions.length > 0) {
5368
+ if (options?.functions && options.functions.length > 0) {
5229
5369
  const promptTemplate = this.options?.promptTemplate ?? AxPromptTemplate;
5230
5370
  this.promptTemplate = new promptTemplate(
5231
5371
  this.signature,
@@ -5240,25 +5380,22 @@ var AxGen = class extends AxProgramWithSignature {
5240
5380
  multiStepLoop: for (let n = 0; n < maxSteps; n++) {
5241
5381
  for (let errCount = 0; errCount < maxRetries; errCount++) {
5242
5382
  try {
5243
- const output = await this.forwardCore({
5244
- options,
5245
- ai,
5246
- mem
5247
- });
5383
+ const generator = this.forwardCore({ options, ai, mem });
5384
+ for await (const delta of generator) {
5385
+ yield {
5386
+ version: errCount,
5387
+ delta
5388
+ };
5389
+ }
5248
5390
  const lastMemItem = mem.getLast(options?.sessionId);
5249
- if (lastMemItem) {
5250
- const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
5251
- if (lastMemItem.role === "function") {
5252
- if (!stopFunction || !stopFunctionExecuted) {
5253
- continue multiStepLoop;
5254
- }
5255
- }
5256
- if (!stopFunctionExecuted) {
5257
- assertRequiredFields(this.signature, output);
5258
- }
5391
+ const shouldContinue = this.shouldContinueSteps(
5392
+ lastMemItem,
5393
+ stopFunction
5394
+ );
5395
+ if (shouldContinue) {
5396
+ continue multiStepLoop;
5259
5397
  }
5260
- this.trace = { ...values, ...output };
5261
- return output;
5398
+ return;
5262
5399
  } catch (e) {
5263
5400
  let errorFields;
5264
5401
  span?.recordException(e);
@@ -5273,23 +5410,13 @@ var AxGen = class extends AxProgramWithSignature {
5273
5410
  throw e;
5274
5411
  }
5275
5412
  if (errorFields) {
5276
- mem.add(
5277
- {
5278
- role: "user",
5279
- content: this.promptTemplate.renderExtraFields(errorFields)
5280
- },
5281
- options?.sessionId
5413
+ handleValidationError(
5414
+ mem,
5415
+ errorFields,
5416
+ ai,
5417
+ this.promptTemplate,
5418
+ options.sessionId
5282
5419
  );
5283
- mem.addTag("error");
5284
- if (ai.getOptions().debug) {
5285
- process.stdout.write(
5286
- colorLog4.red(
5287
- `Error Correction:
5288
- ${JSON.stringify(errorFields, null, 2)}
5289
- `
5290
- )
5291
- );
5292
- }
5293
5420
  }
5294
5421
  }
5295
5422
  }
@@ -5300,35 +5427,68 @@ ${JSON.stringify(errorFields, null, 2)}
5300
5427
  }
5301
5428
  throw new Error(`Max steps reached: ${maxSteps}`);
5302
5429
  }
5303
- async forward(ai, values, options) {
5430
+ shouldContinueSteps(lastMemItem, stopFunction) {
5431
+ const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
5432
+ if (lastMemItem?.role === "function" && stopFunction && stopFunctionExecuted) {
5433
+ return false;
5434
+ }
5435
+ if (lastMemItem?.role === "function") {
5436
+ return true;
5437
+ }
5438
+ return false;
5439
+ }
5440
+ async *_forward1(ai, values, options) {
5304
5441
  const tracer = this.options?.tracer ?? options?.tracer;
5305
5442
  let functions = this.functions;
5306
5443
  if (options?.functions) {
5307
5444
  functions = parseFunctions(options.functions, this.functions);
5308
5445
  }
5309
5446
  if (!tracer) {
5310
- return await this._forward(ai, values, {
5447
+ yield* this._forward2(ai, values, {
5311
5448
  ...options,
5312
5449
  functions
5313
5450
  });
5451
+ return;
5314
5452
  }
5315
5453
  const funcNames = functions?.map((f) => f.name).join(",");
5316
5454
  const attributes = {
5317
5455
  ["generate.signature"]: this.signature.toString(),
5318
5456
  ["generate.functions"]: funcNames ?? ""
5319
5457
  };
5320
- return await tracer.startActiveSpan(
5321
- "Generate",
5322
- {
5323
- kind: import_api22.SpanKind.SERVER,
5324
- attributes
5325
- },
5326
- async (span) => {
5327
- const res = this._forward(ai, values, options, span);
5328
- span.end();
5329
- return res;
5330
- }
5331
- );
5458
+ const span = tracer.startSpan("Generate", {
5459
+ kind: import_api22.SpanKind.SERVER,
5460
+ attributes
5461
+ });
5462
+ try {
5463
+ yield* this._forward2(
5464
+ ai,
5465
+ values,
5466
+ {
5467
+ ...options,
5468
+ functions
5469
+ },
5470
+ span
5471
+ );
5472
+ } finally {
5473
+ span.end();
5474
+ }
5475
+ }
5476
+ async forward(ai, values, options) {
5477
+ const generator = this._forward1(ai, values, {
5478
+ ...options
5479
+ });
5480
+ let buffer = {};
5481
+ for await (const delta of generator) {
5482
+ buffer = mergeDeltas(buffer, delta.delta);
5483
+ }
5484
+ this.trace = { ...values, ...buffer };
5485
+ return buffer;
5486
+ }
5487
+ async *streamingForward(ai, values, options) {
5488
+ yield* this._forward1(ai, values, {
5489
+ ...options,
5490
+ stream: true
5491
+ });
5332
5492
  }
5333
5493
  };
5334
5494
 
@@ -5418,7 +5578,7 @@ var AxAgent = class {
5418
5578
  func: wrappedFunc
5419
5579
  };
5420
5580
  }
5421
- async forward(ai, values, options) {
5581
+ init(ai, options) {
5422
5582
  const _ai = this.ai ?? ai;
5423
5583
  const funcs = [
5424
5584
  ...options?.functions ?? [],
@@ -5429,26 +5589,15 @@ var AxAgent = class {
5429
5589
  const opt2 = { ...options, functions: funcs };
5430
5590
  this.program = new AxGen(this.signature, opt2);
5431
5591
  }
5432
- if (!options?.tracer) {
5433
- return await this.program.forward(_ai, values, opt);
5434
- }
5435
- const attributes = {
5436
- ["agent.name"]: this.name,
5437
- ["agent.description"]: this.description,
5438
- ["agent.subAgents"]: this.subAgentList ?? "none"
5439
- };
5440
- return await options?.tracer.startActiveSpan(
5441
- "Agent",
5442
- {
5443
- kind: import_api23.SpanKind.SERVER,
5444
- attributes
5445
- },
5446
- async (span) => {
5447
- const res = await this.program.forward(_ai, values, opt);
5448
- span.end();
5449
- return res;
5450
- }
5451
- );
5592
+ return { _ai, opt };
5593
+ }
5594
+ async forward(ai, values, options) {
5595
+ const { _ai, opt } = this.init(ai, options);
5596
+ return await this.program.forward(_ai, values, opt);
5597
+ }
5598
+ async *streamingForward(ai, values, options) {
5599
+ const { _ai, opt } = this.init(ai, options);
5600
+ return yield* this.program.streamingForward(_ai, values, opt);
5452
5601
  }
5453
5602
  };
5454
5603
  function toCamelCase(inputString) {
@@ -5719,7 +5868,7 @@ var randomSample = (array, n) => {
5719
5868
  };
5720
5869
 
5721
5870
  // db/base.ts
5722
- var import_api24 = require("@opentelemetry/api");
5871
+ var import_api23 = require("@opentelemetry/api");
5723
5872
  var AxDBBase = class {
5724
5873
  name;
5725
5874
  fetch;
@@ -5746,7 +5895,7 @@ var AxDBBase = class {
5746
5895
  return await this.tracer?.startActiveSpan(
5747
5896
  "DB Upsert Request",
5748
5897
  {
5749
- kind: import_api24.SpanKind.SERVER,
5898
+ kind: import_api23.SpanKind.SERVER,
5750
5899
  attributes: {
5751
5900
  [axSpanAttributes.DB_SYSTEM]: this.name,
5752
5901
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5756,9 +5905,11 @@ var AxDBBase = class {
5756
5905
  }
5757
5906
  },
5758
5907
  async (span) => {
5759
- const res = await this._upsert(req, update, { span });
5760
- span.end();
5761
- return res;
5908
+ try {
5909
+ return await this._upsert(req, update, { span });
5910
+ } finally {
5911
+ span.end();
5912
+ }
5762
5913
  }
5763
5914
  );
5764
5915
  }
@@ -5778,7 +5929,7 @@ var AxDBBase = class {
5778
5929
  return await this.tracer?.startActiveSpan(
5779
5930
  "DB Batch Upsert Request",
5780
5931
  {
5781
- kind: import_api24.SpanKind.SERVER,
5932
+ kind: import_api23.SpanKind.SERVER,
5782
5933
  attributes: {
5783
5934
  [axSpanAttributes.DB_SYSTEM]: this.name,
5784
5935
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5788,9 +5939,11 @@ var AxDBBase = class {
5788
5939
  }
5789
5940
  },
5790
5941
  async (span) => {
5791
- const res = await this._batchUpsert(req, update, { span });
5792
- span.end();
5793
- return res;
5942
+ try {
5943
+ return await this._batchUpsert(req, update, { span });
5944
+ } finally {
5945
+ span.end();
5946
+ }
5794
5947
  }
5795
5948
  );
5796
5949
  }
@@ -5804,7 +5957,7 @@ var AxDBBase = class {
5804
5957
  return await this.tracer?.startActiveSpan(
5805
5958
  "DB Query Request",
5806
5959
  {
5807
- kind: import_api24.SpanKind.SERVER,
5960
+ kind: import_api23.SpanKind.SERVER,
5808
5961
  attributes: {
5809
5962
  [axSpanAttributes.DB_SYSTEM]: this.name,
5810
5963
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5814,9 +5967,11 @@ var AxDBBase = class {
5814
5967
  }
5815
5968
  },
5816
5969
  async (span) => {
5817
- const res = await this._query(req, { span });
5818
- span.end();
5819
- return res;
5970
+ try {
5971
+ return await this._query(req, { span });
5972
+ } finally {
5973
+ span.end();
5974
+ }
5820
5975
  }
5821
5976
  );
5822
5977
  }
@@ -7083,6 +7238,122 @@ var AxEmbeddingAdapter = class {
7083
7238
  }
7084
7239
  };
7085
7240
 
7241
+ // ai/mock/api.ts
7242
+ var AxMockAIService = class {
7243
+ constructor(config = {}) {
7244
+ this.config = config;
7245
+ }
7246
+ options = {};
7247
+ metrics = {
7248
+ latency: {
7249
+ chat: { mean: 0, p95: 0, p99: 0, samples: [] },
7250
+ embed: { mean: 0, p95: 0, p99: 0, samples: [] }
7251
+ },
7252
+ errors: {
7253
+ chat: { count: 0, rate: 0, total: 0 },
7254
+ embed: { count: 0, rate: 0, total: 0 }
7255
+ }
7256
+ };
7257
+ getName() {
7258
+ return this.config.name ?? "mock-ai-service";
7259
+ }
7260
+ getModelInfo() {
7261
+ return {
7262
+ name: "mock-model",
7263
+ provider: "mock-provider",
7264
+ promptTokenCostPer1M: 100,
7265
+ completionTokenCostPer1M: 100,
7266
+ ...this.config.modelInfo
7267
+ };
7268
+ }
7269
+ getEmbedModelInfo() {
7270
+ return this.config.embedModelInfo;
7271
+ }
7272
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
7273
+ getFeatures(_model) {
7274
+ return {
7275
+ functions: this.config.features?.functions ?? false,
7276
+ streaming: this.config.features?.streaming ?? false
7277
+ };
7278
+ }
7279
+ getModelMap() {
7280
+ return this.config.modelMap;
7281
+ }
7282
+ getMetrics() {
7283
+ return this.metrics;
7284
+ }
7285
+ async chat(req, _options) {
7286
+ if (this.config.latencyMs) {
7287
+ await new Promise((resolve) => setTimeout(resolve, this.config.latencyMs));
7288
+ }
7289
+ if (this.config.shouldError) {
7290
+ throw new Error(this.config.errorMessage ?? "Mock chat error");
7291
+ }
7292
+ this.updateMetrics("chat");
7293
+ if (typeof this.config.chatResponse === "function") {
7294
+ return this.config.chatResponse(req);
7295
+ }
7296
+ return this.config.chatResponse ?? {
7297
+ results: [
7298
+ {
7299
+ content: "Mock response",
7300
+ finishReason: "stop"
7301
+ }
7302
+ ],
7303
+ modelUsage: {
7304
+ promptTokens: 10,
7305
+ completionTokens: 5,
7306
+ totalTokens: 15
7307
+ }
7308
+ };
7309
+ }
7310
+ async embed(req, _options) {
7311
+ if (this.config.latencyMs) {
7312
+ await new Promise((resolve) => setTimeout(resolve, this.config.latencyMs));
7313
+ }
7314
+ if (this.config.shouldError) {
7315
+ throw new Error(this.config.errorMessage ?? "Mock embed error");
7316
+ }
7317
+ this.updateMetrics("embed");
7318
+ if (typeof this.config.embedResponse === "function") {
7319
+ return this.config.embedResponse(req);
7320
+ }
7321
+ return this.config.embedResponse ?? {
7322
+ embeddings: [[0.1, 0.2, 0.3]],
7323
+ modelUsage: {
7324
+ promptTokens: 5,
7325
+ completionTokens: 0,
7326
+ totalTokens: 5
7327
+ }
7328
+ };
7329
+ }
7330
+ setOptions(options) {
7331
+ this.options = options;
7332
+ }
7333
+ getOptions() {
7334
+ return this.options;
7335
+ }
7336
+ updateMetrics(type) {
7337
+ const latency = this.config.latencyMs ?? 0;
7338
+ this.metrics.latency[type].samples.push(latency);
7339
+ const samples = this.metrics.latency[type].samples;
7340
+ this.metrics.latency[type].mean = samples.reduce((a, b) => a + b, 0) / samples.length;
7341
+ if (samples.length > 0) {
7342
+ const sortedSamples = [...samples].sort((a, b) => a - b);
7343
+ const p95Index = Math.max(0, Math.floor(sortedSamples.length * 0.95) - 1);
7344
+ this.metrics.latency[type].p95 = sortedSamples[p95Index] ?? latency;
7345
+ const p99Index = Math.max(0, Math.floor(sortedSamples.length * 0.99) - 1);
7346
+ this.metrics.latency[type].p99 = sortedSamples[p99Index] ?? latency;
7347
+ }
7348
+ if (this.config.shouldError) {
7349
+ this.metrics.errors[type].count++;
7350
+ this.metrics.errors[type].total++;
7351
+ const totalRequests = this.metrics.latency[type].samples.length;
7352
+ this.metrics.errors[type].rate = totalRequests > 0 ? this.metrics.errors[type].count / totalRequests : 0;
7353
+ }
7354
+ }
7355
+ };
7356
+
7086
7357
  // prompts/rag.ts
7087
7358
  var AxRAG = class extends AxChainOfThought {
7088
7359
  genQuery;
@@ -7172,6 +7443,7 @@ var AxRAG = class extends AxChainOfThought {
7172
7443
  AxJSInterpreterPermission,
7173
7444
  AxLLMRequestTypeValues,
7174
7445
  AxMemory,
7446
+ AxMockAIService,
7175
7447
  AxProgram,
7176
7448
  AxProgramWithSignature,
7177
7449
  AxPromptTemplate,