@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.js CHANGED
@@ -525,9 +525,11 @@ var AxBaseAI = class {
525
525
  }
526
526
  },
527
527
  async (span) => {
528
- const res = await this._chat2(model, modelConfig, req, options, span);
529
- span.end();
530
- return res;
528
+ try {
529
+ return await this._chat2(model, modelConfig, req, options, span);
530
+ } finally {
531
+ span.end();
532
+ }
531
533
  }
532
534
  );
533
535
  }
@@ -650,9 +652,11 @@ var AxBaseAI = class {
650
652
  }
651
653
  },
652
654
  async (span) => {
653
- const res = await this._embed2(embedModel, req, options, span);
654
- span.end();
655
- return res;
655
+ try {
656
+ return await this._embed2(embedModel, req, options, span);
657
+ } finally {
658
+ span.end();
659
+ }
656
660
  }
657
661
  );
658
662
  }
@@ -720,7 +724,7 @@ ${colorLog.whiteBright(msg.content)}`;
720
724
  const items2 = msg.content.map((v) => {
721
725
  switch (v.type) {
722
726
  case "text":
723
- return `(Text) ${colorLog.whiteBright(v.text)}`;
727
+ return `${colorLog.whiteBright(v.text)}`;
724
728
  case "image":
725
729
  return `(Image, ${v.mimeType}) ${colorLog.whiteBright(v.image.substring(0, 10))}`;
726
730
  default:
@@ -875,6 +879,30 @@ var AxAIAnthropicImpl = class {
875
879
  const apiConfig = {
876
880
  name: "/messages"
877
881
  };
882
+ let toolsChoice;
883
+ if (req.functionCall && req.functions && req.functions.length > 0) {
884
+ if (typeof req.functionCall === "string") {
885
+ switch (req.functionCall) {
886
+ case "auto":
887
+ toolsChoice = { tool_choice: { type: "auto" } };
888
+ break;
889
+ case "required":
890
+ toolsChoice = { tool_choice: { type: "any" } };
891
+ break;
892
+ case "none":
893
+ throw new Error("functionCall none not supported");
894
+ }
895
+ } else if ("function" in req.functionCall) {
896
+ toolsChoice = {
897
+ tool_choice: {
898
+ type: "tool",
899
+ name: req.functionCall.function.name
900
+ }
901
+ };
902
+ } else {
903
+ throw new Error("Invalid function call type, must be string or object");
904
+ }
905
+ }
878
906
  const system = req.chatPrompt.filter((msg) => msg.role === "system").map((msg) => ({
879
907
  type: "text",
880
908
  text: msg.content,
@@ -897,7 +925,8 @@ var AxAIAnthropicImpl = class {
897
925
  temperature: req.modelConfig?.temperature ?? this.config.temperature,
898
926
  top_p: req.modelConfig?.topP ?? this.config.topP,
899
927
  top_k: req.modelConfig?.topK ?? this.config.topK,
900
- ...tools && tools.length > 0 ? { tools, tool_choice: { type: "auto" } } : {},
928
+ ...toolsChoice,
929
+ ...tools && tools.length > 0 ? { tools } : {},
901
930
  ...stream ? { stream: true } : {},
902
931
  ...system ? { system } : {},
903
932
  messages
@@ -3206,9 +3235,6 @@ var AxAI = class {
3206
3235
  }
3207
3236
  };
3208
3237
 
3209
- // prompts/agent.ts
3210
- import { SpanKind as SpanKind3 } from "@opentelemetry/api";
3211
-
3212
3238
  // dsp/generate.ts
3213
3239
  import { ReadableStream } from "stream/web";
3214
3240
  import { SpanKind as SpanKind2 } from "@opentelemetry/api";
@@ -3397,7 +3423,7 @@ var AxAssertionError = class extends Error {
3397
3423
  extraFields.push({
3398
3424
  name: "error",
3399
3425
  title: "Error In Output",
3400
- description: this.message
3426
+ description: `You must follow the following instructions, "${this.message}".`
3401
3427
  });
3402
3428
  return extraFields;
3403
3429
  };
@@ -3436,18 +3462,6 @@ var assertStreamingAssertions = (asserts, values, xstate, content, final) => {
3436
3462
  }
3437
3463
  }
3438
3464
  };
3439
- var assertRequiredFields = (sig, values) => {
3440
- const fields = sig.getOutputFields();
3441
- const missingFields = fields.filter(
3442
- (f) => !f.isOptional && !(f.name in values)
3443
- );
3444
- if (missingFields.length > 0) {
3445
- throw new AxAssertionError({
3446
- message: `Output must include: ${missingFields.map((f) => `\`${f.title}:\``).join(", ")}`,
3447
- values
3448
- });
3449
- }
3450
- };
3451
3465
 
3452
3466
  // dsp/extract.ts
3453
3467
  import JSON5 from "json5";
@@ -3995,6 +4009,21 @@ var parseMarkdownList = (input) => {
3995
4009
  }
3996
4010
  return list;
3997
4011
  };
4012
+ function mergeDeltas(base, delta) {
4013
+ const merged = { ...base };
4014
+ for (const key in delta) {
4015
+ const baseValue = base[key];
4016
+ const deltaValue = delta[key];
4017
+ if (Array.isArray(baseValue) && Array.isArray(deltaValue)) {
4018
+ merged[key] = [...baseValue, ...deltaValue];
4019
+ } else if (typeof baseValue === "string" && typeof deltaValue === "string") {
4020
+ merged[key] = baseValue + deltaValue;
4021
+ } else {
4022
+ merged[key] = deltaValue;
4023
+ }
4024
+ }
4025
+ return merged;
4026
+ }
3998
4027
 
3999
4028
  // dsp/program.ts
4000
4029
  var AxProgramWithSignature = class {
@@ -4027,6 +4056,9 @@ var AxProgramWithSignature = class {
4027
4056
  async forward(_ai, _values, _options) {
4028
4057
  throw new Error("forward() not implemented");
4029
4058
  }
4059
+ async *streamingForward(_ai, _values, _options) {
4060
+ throw new Error("streamingForward() not implemented");
4061
+ }
4030
4062
  setId(id) {
4031
4063
  this.key = { id, custom: true };
4032
4064
  for (const child of this.children) {
@@ -4121,6 +4153,9 @@ var AxProgram = class {
4121
4153
  async forward(_ai, _values, _options) {
4122
4154
  throw new Error("forward() not implemented");
4123
4155
  }
4156
+ async *streamingForward(_ai, _values, _options) {
4157
+ throw new Error("streamingForward() not implemented");
4158
+ }
4124
4159
  setId(id) {
4125
4160
  this.key = { id, custom: true };
4126
4161
  for (const child of this.children) {
@@ -4218,9 +4253,10 @@ ${outputFields}`);
4218
4253
  task.push(formattingRules.trim());
4219
4254
  const desc = this.sig.getDescription();
4220
4255
  if (desc) {
4256
+ const capitalized = capitalizeFirstLetter(desc.trim());
4221
4257
  task.push(
4222
4258
  `## TASK DESCRIPTION
4223
- ${capitalizeFirstLetter(desc.endsWith(".") ? desc : desc + ".")}`
4259
+ ${capitalized.endsWith(".") ? capitalized : capitalized + "."}`
4224
4260
  );
4225
4261
  }
4226
4262
  this.task = {
@@ -4268,16 +4304,42 @@ ${capitalizeFirstLetter(desc.endsWith(".") ? desc : desc + ".")}`
4268
4304
  };
4269
4305
  renderExtraFields = (extraFields) => {
4270
4306
  const prompt = [];
4271
- if (extraFields && extraFields.length > 0) {
4272
- extraFields.forEach((field) => {
4273
- const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
4274
- prompt.push(...fn(field, field.description));
4275
- });
4276
- }
4277
- if (prompt.every((v) => v.type === "text")) {
4278
- return prompt.map((v) => v.text).join("\n\n");
4279
- }
4280
- return prompt.reduce(combineConsecutiveStrings("\n"), []);
4307
+ if (!extraFields || extraFields.length === 0) {
4308
+ return prompt;
4309
+ }
4310
+ const groupedFields = extraFields.reduce(
4311
+ (acc, field) => {
4312
+ const title = field.title;
4313
+ if (!acc[title]) {
4314
+ acc[title] = [];
4315
+ }
4316
+ acc[title].push(field);
4317
+ return acc;
4318
+ },
4319
+ {}
4320
+ );
4321
+ const formattedGroupedFields = Object.entries(groupedFields).map(([title, fields]) => {
4322
+ if (fields.length === 1) {
4323
+ const field = fields[0];
4324
+ return {
4325
+ title,
4326
+ name: field.name,
4327
+ description: field.description
4328
+ };
4329
+ } else if (fields.length > 1) {
4330
+ const valuesList = fields.map((field) => `- ${field.description}`).join("\n");
4331
+ return {
4332
+ title,
4333
+ name: fields[0].name,
4334
+ description: valuesList
4335
+ };
4336
+ }
4337
+ }).filter(Boolean);
4338
+ formattedGroupedFields.forEach((field) => {
4339
+ const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
4340
+ prompt.push(...fn(field, field.description));
4341
+ });
4342
+ return prompt;
4281
4343
  };
4282
4344
  renderExamples = (data) => {
4283
4345
  const list = [];
@@ -4526,34 +4588,47 @@ function capitalizeFirstLetter(str) {
4526
4588
  }
4527
4589
 
4528
4590
  // dsp/validate.ts
4591
+ var colorLog4 = new ColorLog();
4529
4592
  var ValidationError = class extends Error {
4530
- field;
4531
- value;
4593
+ fields;
4532
4594
  constructor({
4533
4595
  message,
4534
- field,
4535
- value
4596
+ fields
4536
4597
  }) {
4537
4598
  super(message);
4538
- this.field = field;
4539
- this.value = value;
4599
+ this.fields = fields;
4540
4600
  this.name = this.constructor.name;
4541
4601
  Error.captureStackTrace(this, this.constructor);
4542
4602
  }
4543
- getField = () => this.field;
4544
- getValue = () => this.value;
4603
+ getFields = () => this.fields;
4545
4604
  getFixingInstructions = () => {
4546
- const f = this.field;
4547
- const extraFields = [
4548
- {
4549
- name: `outputError`,
4550
- title: `Invalid Output Field`,
4551
- description: `Invalid format for field \`${f.title}\` of type \`${toFieldType(f.type)}\`, format should match: \`${f.description}\``
4552
- }
4553
- ];
4554
- return extraFields;
4605
+ return this.fields.map((field) => ({
4606
+ name: "outputError",
4607
+ title: "Error In Output",
4608
+ description: `Please fix and return the field \`${field.title}\` of type \`${toFieldType(field.type)}\`, ${this.message}.`
4609
+ }));
4555
4610
  };
4556
4611
  };
4612
+ function handleValidationError(mem, errorFields, ai, promptTemplate, sessionId) {
4613
+ mem.add(
4614
+ {
4615
+ role: "user",
4616
+ content: promptTemplate.renderExtraFields(errorFields)
4617
+ },
4618
+ sessionId
4619
+ );
4620
+ mem.addTag("error");
4621
+ if (ai.getOptions().debug) {
4622
+ process.stdout.write(
4623
+ colorLog4.red(
4624
+ `
4625
+ Error Correction:
4626
+ ${JSON.stringify(errorFields, null, 2)}
4627
+ `
4628
+ )
4629
+ );
4630
+ }
4631
+ }
4557
4632
 
4558
4633
  // dsp/datetime.ts
4559
4634
  function parseLLMFriendlyDate(field, dateStr) {
@@ -4561,7 +4636,7 @@ function parseLLMFriendlyDate(field, dateStr) {
4561
4636
  return _parseLLMFriendlyDate(dateStr);
4562
4637
  } catch (err) {
4563
4638
  const message = err.message;
4564
- throw new ValidationError({ field, message, value: dateStr });
4639
+ throw new ValidationError({ fields: [field], message, value: dateStr });
4565
4640
  }
4566
4641
  }
4567
4642
  function _parseLLMFriendlyDate(dateStr) {
@@ -4578,7 +4653,7 @@ function parseLLMFriendlyDateTime(field, dateStr) {
4578
4653
  return _parseLLMFriendlyDateTime(dateStr);
4579
4654
  } catch (err) {
4580
4655
  const message = err.message;
4581
- throw new ValidationError({ field, message, value: dateStr });
4656
+ throw new ValidationError({ fields: [field], message, value: dateStr });
4582
4657
  }
4583
4658
  }
4584
4659
  function _parseLLMFriendlyDateTime(dateTimeStr) {
@@ -4620,41 +4695,61 @@ var formatDateWithTimezone = (date) => {
4620
4695
 
4621
4696
  // dsp/extract.ts
4622
4697
  var extractValues = (sig, values, content) => {
4623
- const xstate = { s: -1 };
4698
+ const xstate = { extractedFields: [], s: -1 };
4624
4699
  streamingExtractValues(sig, values, xstate, content);
4625
- streamingExtractFinalValue(values, xstate, content);
4700
+ streamingExtractFinalValue(sig, values, xstate, content);
4701
+ };
4702
+ var checkMissingRequiredFields = (xstate, values, currentIndex) => {
4703
+ const missingFields = [];
4704
+ for (let i = 0; i < currentIndex; i++) {
4705
+ const field = xstate.extractedFields[i];
4706
+ if (field && !field.isOptional && values[field.name] === void 0) {
4707
+ missingFields.push(field);
4708
+ }
4709
+ }
4710
+ if (missingFields.length > 0) {
4711
+ throw new ValidationError({
4712
+ message: `Required ${missingFields.length === 1 ? "field" : "fields"} not found`,
4713
+ fields: missingFields
4714
+ });
4715
+ }
4626
4716
  };
4627
- var streamingExtractValues = (sig, values, state, content) => {
4717
+ var streamingExtractValues = (sig, values, xstate, content) => {
4628
4718
  const fields = sig.getOutputFields();
4629
- for (const field of fields) {
4719
+ for (const [index, field] of fields.entries()) {
4630
4720
  if (field.name in values) {
4631
4721
  continue;
4632
4722
  }
4633
4723
  const prefix = field.title + ":";
4634
- const e = content.indexOf(prefix, state.s + 1);
4724
+ const e = content.indexOf(prefix, xstate.s + 1);
4635
4725
  if (e === -1) {
4636
4726
  continue;
4637
4727
  }
4638
- if (state.currField) {
4639
- const val = content.substring(state.s, e).trim().replace(/---+$/, "").trim();
4640
- values[state.currField.name] = validateAndParseFieldValue(
4641
- state.currField,
4642
- val
4643
- );
4728
+ if (xstate.currField) {
4729
+ const val = content.substring(xstate.s, e);
4730
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
4731
+ if (parsedValue !== void 0) {
4732
+ values[xstate.currField.name] = parsedValue;
4733
+ }
4734
+ }
4735
+ checkMissingRequiredFields(xstate, values, index);
4736
+ xstate.s = e + prefix.length;
4737
+ xstate.currField = field;
4738
+ if (!xstate.extractedFields.includes(field)) {
4739
+ xstate.extractedFields.push(field);
4644
4740
  }
4645
- state.s = e + prefix.length;
4646
- state.currField = field;
4647
4741
  }
4648
4742
  };
4649
- var streamingExtractFinalValue = (values, state, content) => {
4650
- if (!state.currField) {
4651
- return;
4743
+ var streamingExtractFinalValue = (sig, values, xstate, content) => {
4744
+ if (xstate.currField) {
4745
+ const val = content.substring(xstate.s);
4746
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
4747
+ if (parsedValue !== void 0) {
4748
+ values[xstate.currField.name] = parsedValue;
4749
+ }
4652
4750
  }
4653
- const val = content.substring(state.s).trim().replace(/---+$/, "").trim();
4654
- values[state.currField.name] = validateAndParseFieldValue(
4655
- state.currField,
4656
- val
4657
- );
4751
+ const fields = sig.getOutputFields();
4752
+ checkMissingRequiredFields(xstate, values, fields.length - 1);
4658
4753
  };
4659
4754
  var convertValueToType = (field, val) => {
4660
4755
  switch (field.type?.name) {
@@ -4692,59 +4787,98 @@ var convertValueToType = (field, val) => {
4692
4787
  return val;
4693
4788
  }
4694
4789
  };
4695
- var expectedTypeError = (field, err, value = "") => {
4696
- const exp = field.type?.isArray ? `array of ${field.type.name}` : field.type?.name;
4697
- const message = `Error '${err.message}', expected '${exp}' got '${value}'`;
4698
- return new ValidationError({ message, field, value });
4699
- };
4790
+ function* streamingValues(sig, values, xstate, content) {
4791
+ if (!xstate.currField) {
4792
+ return;
4793
+ }
4794
+ const fieldName = xstate.currField.name;
4795
+ if (!xstate.streamedIndex) {
4796
+ xstate.streamedIndex = { [fieldName]: 0 };
4797
+ }
4798
+ if (!xstate.currField.type || !xstate.currField.type.isArray && xstate.currField.type.name === "string") {
4799
+ const s = xstate.s + (xstate.streamedIndex[fieldName] ?? 0);
4800
+ const v = content.substring(s);
4801
+ yield { [fieldName]: v };
4802
+ xstate.streamedIndex[fieldName] = v.length;
4803
+ return;
4804
+ }
4805
+ for (const key of Object.keys(values)) {
4806
+ const value = values[key];
4807
+ if (Array.isArray(value)) {
4808
+ const s = xstate.streamedIndex[fieldName] ?? 0;
4809
+ const v = value.slice(s);
4810
+ if (v) {
4811
+ yield { [fieldName]: v };
4812
+ xstate.streamedIndex[fieldName] = s + 1;
4813
+ }
4814
+ continue;
4815
+ }
4816
+ if (!xstate.streamedIndex[fieldName]) {
4817
+ yield { [fieldName]: value };
4818
+ xstate.streamedIndex[fieldName] = 1;
4819
+ }
4820
+ }
4821
+ }
4700
4822
  function validateAndParseFieldValue(field, fieldValue) {
4701
- const fv = fieldValue?.toLocaleLowerCase();
4702
- if (!fieldValue || !fv || fv === "" || fv === "null" || fv === "undefined") {
4823
+ const fv = fieldValue?.trim();
4824
+ if (!fv || !fv || fv === "" || fv === "null" || fv === "NULL" || fv === "undefined") {
4703
4825
  if (field.isOptional) {
4704
4826
  return;
4705
4827
  }
4706
- throw expectedTypeError(field, new Error("Empty value"), fieldValue);
4828
+ throw new ValidationError({
4829
+ message: "Required field is missing",
4830
+ fields: [field],
4831
+ value: fv
4832
+ });
4707
4833
  }
4708
- let value = fieldValue;
4834
+ let value;
4709
4835
  if (field.type?.name === "json") {
4710
4836
  try {
4711
- const text = extractBlock(fieldValue);
4837
+ const text = extractBlock(fv);
4712
4838
  value = JSON5.parse(text);
4713
4839
  return value;
4714
4840
  } catch (e) {
4715
- throw expectedTypeError(field, e, fieldValue);
4841
+ throw new ValidationError({
4842
+ message: "Invalid JSON: " + e.message,
4843
+ fields: [field],
4844
+ value: fv
4845
+ });
4716
4846
  }
4717
4847
  }
4718
4848
  if (field.type?.isArray) {
4719
4849
  try {
4720
4850
  try {
4721
- value = JSON5.parse(fieldValue);
4851
+ value = JSON5.parse(fv);
4722
4852
  } catch {
4723
- value = parseMarkdownList(fieldValue);
4853
+ value = parseMarkdownList(fv);
4724
4854
  }
4725
4855
  if (!Array.isArray(value)) {
4726
4856
  throw new Error("Expected an array");
4727
4857
  }
4728
4858
  } catch (e) {
4729
- throw expectedTypeError(field, e, fieldValue);
4859
+ throw new ValidationError({
4860
+ message: "Invalid array: " + e.message,
4861
+ fields: [field],
4862
+ value: fv
4863
+ });
4730
4864
  }
4731
4865
  }
4732
- if (Array.isArray(value)) {
4733
- for (const [index, item] of value.entries()) {
4734
- try {
4866
+ try {
4867
+ if (Array.isArray(value)) {
4868
+ for (const [index, item] of value.entries()) {
4735
4869
  value[index] = convertValueToType(field, item);
4736
- } catch (e) {
4737
- throw expectedTypeError(field, e, item);
4738
4870
  }
4871
+ } else {
4872
+ value = convertValueToType(field, fv);
4739
4873
  }
4740
- } else {
4741
- try {
4742
- value = convertValueToType(field, fieldValue);
4743
- } catch (e) {
4744
- throw expectedTypeError(field, e, fieldValue);
4745
- }
4874
+ } catch (e) {
4875
+ throw new ValidationError({
4876
+ message: e.message,
4877
+ fields: [field],
4878
+ value: fieldValue
4879
+ });
4746
4880
  }
4747
- return value;
4881
+ return value ?? fv;
4748
4882
  }
4749
4883
  var extractBlock = (input) => {
4750
4884
  const jsonBlockPattern = /```([A-Za-z]+)?\s*([\s\S]*?)\s*```/g;
@@ -4911,7 +5045,6 @@ function parseFunctionCalls(ai, functionCalls, values, model) {
4911
5045
  }
4912
5046
 
4913
5047
  // dsp/generate.ts
4914
- var colorLog4 = new ColorLog();
4915
5048
  var AxGen = class extends AxProgramWithSignature {
4916
5049
  promptTemplate;
4917
5050
  asserts;
@@ -4976,7 +5109,7 @@ var AxGen = class extends AxProgramWithSignature {
4976
5109
  );
4977
5110
  return res;
4978
5111
  }
4979
- async forwardCore({
5112
+ async *forwardCore({
4980
5113
  ai,
4981
5114
  mem,
4982
5115
  options
@@ -4992,7 +5125,18 @@ var AxGen = class extends AxProgramWithSignature {
4992
5125
  options
4993
5126
  });
4994
5127
  if (res instanceof ReadableStream) {
4995
- return await this.processSteamingResponse({
5128
+ yield* this.processStreamingResponse({
5129
+ ai,
5130
+ model,
5131
+ res,
5132
+ usageInfo,
5133
+ mem,
5134
+ traceId,
5135
+ sessionId,
5136
+ functions
5137
+ });
5138
+ } else {
5139
+ yield await this.processResponse({
4996
5140
  ai,
4997
5141
  model,
4998
5142
  res,
@@ -5003,18 +5147,8 @@ var AxGen = class extends AxProgramWithSignature {
5003
5147
  functions
5004
5148
  });
5005
5149
  }
5006
- return await this.processResponse({
5007
- ai,
5008
- model,
5009
- res,
5010
- usageInfo,
5011
- mem,
5012
- traceId,
5013
- sessionId,
5014
- functions
5015
- });
5016
5150
  }
5017
- async processSteamingResponse({
5151
+ async *processStreamingResponse({
5018
5152
  ai,
5019
5153
  model,
5020
5154
  res,
@@ -5026,36 +5160,39 @@ var AxGen = class extends AxProgramWithSignature {
5026
5160
  }) {
5027
5161
  const functionCalls = [];
5028
5162
  const values = {};
5029
- const xstate = { s: -1 };
5163
+ const xstate = { extractedFields: [], s: -1 };
5030
5164
  let content = "";
5031
5165
  for await (const v of res) {
5032
- for (const result of v.results ?? []) {
5033
- if (v.modelUsage) {
5034
- this.usage.push({ ...usageInfo, ...v.modelUsage });
5035
- }
5036
- if (result.content) {
5037
- content += result.content;
5038
- mem.updateResult({ name: result.name, content }, sessionId);
5039
- assertStreamingAssertions(
5040
- this.streamingAsserts,
5041
- values,
5042
- xstate,
5043
- content,
5044
- false
5045
- );
5046
- streamingExtractValues(this.signature, values, xstate, content);
5047
- assertAssertions(this.asserts, values);
5048
- }
5049
- if (result.functionCalls) {
5050
- mergeFunctionCalls(functionCalls, result.functionCalls);
5051
- mem.updateResult(
5052
- { name: result.name, content, functionCalls },
5053
- sessionId
5054
- );
5055
- }
5056
- if (result.finishReason === "length") {
5057
- throw new Error("Max tokens reached before completion");
5058
- }
5166
+ const result = v.results[0];
5167
+ if (!result) {
5168
+ continue;
5169
+ }
5170
+ if (v.modelUsage) {
5171
+ this.usage.push({ ...usageInfo, ...v.modelUsage });
5172
+ }
5173
+ if (result.content) {
5174
+ content += result.content;
5175
+ mem.updateResult({ name: result.name, content }, sessionId);
5176
+ assertStreamingAssertions(
5177
+ this.streamingAsserts,
5178
+ values,
5179
+ xstate,
5180
+ content,
5181
+ false
5182
+ );
5183
+ streamingExtractValues(this.signature, values, xstate, content);
5184
+ assertAssertions(this.asserts, values);
5185
+ yield* streamingValues(this.signature, values, xstate, content);
5186
+ }
5187
+ if (result.functionCalls) {
5188
+ mergeFunctionCalls(functionCalls, result.functionCalls);
5189
+ mem.updateResult(
5190
+ { name: result.name, content, functionCalls },
5191
+ sessionId
5192
+ );
5193
+ }
5194
+ if (result.finishReason === "length") {
5195
+ throw new Error("Max tokens reached before completion");
5059
5196
  }
5060
5197
  }
5061
5198
  const funcs = parseFunctionCalls(ai, functionCalls, values, model);
@@ -5073,7 +5210,6 @@ var AxGen = class extends AxProgramWithSignature {
5073
5210
  );
5074
5211
  this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5075
5212
  }
5076
- streamingExtractFinalValue(values, xstate, content);
5077
5213
  assertStreamingAssertions(
5078
5214
  this.streamingAsserts,
5079
5215
  values,
@@ -5081,8 +5217,9 @@ var AxGen = class extends AxProgramWithSignature {
5081
5217
  content,
5082
5218
  true
5083
5219
  );
5220
+ streamingExtractFinalValue(this.signature, values, xstate, content);
5084
5221
  assertAssertions(this.asserts, values);
5085
- return { ...values };
5222
+ return values;
5086
5223
  }
5087
5224
  async processResponse({
5088
5225
  ai,
@@ -5094,45 +5231,47 @@ var AxGen = class extends AxProgramWithSignature {
5094
5231
  functions
5095
5232
  }) {
5096
5233
  const values = {};
5097
- for (const result of res.results ?? []) {
5098
- if (res.modelUsage) {
5099
- this.usage.push({ ...usageInfo, ...res.modelUsage });
5100
- }
5101
- mem.addResult(result, sessionId);
5102
- if (result.content) {
5103
- extractValues(this.signature, values, result.content);
5104
- assertAssertions(this.asserts, values);
5105
- }
5106
- if (result.functionCalls) {
5107
- const funcs = parseFunctionCalls(ai, result.functionCalls, values);
5108
- if (funcs) {
5109
- if (!functions) {
5110
- throw new Error("Functions are not defined");
5111
- }
5112
- const fx = await processFunctions(
5113
- ai,
5114
- functions,
5115
- funcs,
5116
- mem,
5117
- sessionId,
5118
- traceId
5119
- );
5120
- this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5234
+ const result = res.results[0];
5235
+ if (!result) {
5236
+ throw new Error("No result found");
5237
+ }
5238
+ if (res.modelUsage) {
5239
+ this.usage.push({ ...usageInfo, ...res.modelUsage });
5240
+ }
5241
+ mem.addResult(result, sessionId);
5242
+ if (result.content) {
5243
+ extractValues(this.signature, values, result.content);
5244
+ assertAssertions(this.asserts, values);
5245
+ }
5246
+ if (result.functionCalls) {
5247
+ const funcs = parseFunctionCalls(ai, result.functionCalls, values);
5248
+ if (funcs) {
5249
+ if (!functions) {
5250
+ throw new Error("Functions are not defined");
5121
5251
  }
5122
- }
5123
- if (result.finishReason === "length") {
5124
- throw new Error("Max tokens reached before completion");
5252
+ const fx = await processFunctions(
5253
+ ai,
5254
+ functions,
5255
+ funcs,
5256
+ mem,
5257
+ sessionId,
5258
+ traceId
5259
+ );
5260
+ this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5125
5261
  }
5126
5262
  }
5263
+ if (result.finishReason === "length") {
5264
+ throw new Error("Max tokens reached before completion");
5265
+ }
5127
5266
  return { ...values };
5128
5267
  }
5129
- async _forward(ai, values, options, span) {
5268
+ async *_forward2(ai, values, options, span) {
5130
5269
  const stopFunction = (options?.stopFunction ?? this.options?.stopFunction)?.toLowerCase();
5131
- const maxRetries = options?.maxRetries ?? this.options?.maxRetries ?? 3;
5132
- const maxSteps = options?.maxSteps ?? this.options?.maxSteps ?? 10;
5133
- const mem = options?.mem ?? this.options?.mem ?? new AxMemory();
5270
+ const maxRetries = options.maxRetries ?? this.options?.maxRetries ?? 10;
5271
+ const maxSteps = options.maxSteps ?? this.options?.maxSteps ?? 10;
5272
+ const mem = options.mem ?? this.options?.mem ?? new AxMemory();
5134
5273
  let err;
5135
- if (options?.functions && options?.functions.length > 0) {
5274
+ if (options?.functions && options.functions.length > 0) {
5136
5275
  const promptTemplate = this.options?.promptTemplate ?? AxPromptTemplate;
5137
5276
  this.promptTemplate = new promptTemplate(
5138
5277
  this.signature,
@@ -5147,25 +5286,22 @@ var AxGen = class extends AxProgramWithSignature {
5147
5286
  multiStepLoop: for (let n = 0; n < maxSteps; n++) {
5148
5287
  for (let errCount = 0; errCount < maxRetries; errCount++) {
5149
5288
  try {
5150
- const output = await this.forwardCore({
5151
- options,
5152
- ai,
5153
- mem
5154
- });
5289
+ const generator = this.forwardCore({ options, ai, mem });
5290
+ for await (const delta of generator) {
5291
+ yield {
5292
+ version: errCount,
5293
+ delta
5294
+ };
5295
+ }
5155
5296
  const lastMemItem = mem.getLast(options?.sessionId);
5156
- if (lastMemItem) {
5157
- const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
5158
- if (lastMemItem.role === "function") {
5159
- if (!stopFunction || !stopFunctionExecuted) {
5160
- continue multiStepLoop;
5161
- }
5162
- }
5163
- if (!stopFunctionExecuted) {
5164
- assertRequiredFields(this.signature, output);
5165
- }
5297
+ const shouldContinue = this.shouldContinueSteps(
5298
+ lastMemItem,
5299
+ stopFunction
5300
+ );
5301
+ if (shouldContinue) {
5302
+ continue multiStepLoop;
5166
5303
  }
5167
- this.trace = { ...values, ...output };
5168
- return output;
5304
+ return;
5169
5305
  } catch (e) {
5170
5306
  let errorFields;
5171
5307
  span?.recordException(e);
@@ -5180,23 +5316,13 @@ var AxGen = class extends AxProgramWithSignature {
5180
5316
  throw e;
5181
5317
  }
5182
5318
  if (errorFields) {
5183
- mem.add(
5184
- {
5185
- role: "user",
5186
- content: this.promptTemplate.renderExtraFields(errorFields)
5187
- },
5188
- options?.sessionId
5319
+ handleValidationError(
5320
+ mem,
5321
+ errorFields,
5322
+ ai,
5323
+ this.promptTemplate,
5324
+ options.sessionId
5189
5325
  );
5190
- mem.addTag("error");
5191
- if (ai.getOptions().debug) {
5192
- process.stdout.write(
5193
- colorLog4.red(
5194
- `Error Correction:
5195
- ${JSON.stringify(errorFields, null, 2)}
5196
- `
5197
- )
5198
- );
5199
- }
5200
5326
  }
5201
5327
  }
5202
5328
  }
@@ -5207,35 +5333,68 @@ ${JSON.stringify(errorFields, null, 2)}
5207
5333
  }
5208
5334
  throw new Error(`Max steps reached: ${maxSteps}`);
5209
5335
  }
5210
- async forward(ai, values, options) {
5336
+ shouldContinueSteps(lastMemItem, stopFunction) {
5337
+ const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
5338
+ if (lastMemItem?.role === "function" && stopFunction && stopFunctionExecuted) {
5339
+ return false;
5340
+ }
5341
+ if (lastMemItem?.role === "function") {
5342
+ return true;
5343
+ }
5344
+ return false;
5345
+ }
5346
+ async *_forward1(ai, values, options) {
5211
5347
  const tracer = this.options?.tracer ?? options?.tracer;
5212
5348
  let functions = this.functions;
5213
5349
  if (options?.functions) {
5214
5350
  functions = parseFunctions(options.functions, this.functions);
5215
5351
  }
5216
5352
  if (!tracer) {
5217
- return await this._forward(ai, values, {
5353
+ yield* this._forward2(ai, values, {
5218
5354
  ...options,
5219
5355
  functions
5220
5356
  });
5357
+ return;
5221
5358
  }
5222
5359
  const funcNames = functions?.map((f) => f.name).join(",");
5223
5360
  const attributes = {
5224
5361
  ["generate.signature"]: this.signature.toString(),
5225
5362
  ["generate.functions"]: funcNames ?? ""
5226
5363
  };
5227
- return await tracer.startActiveSpan(
5228
- "Generate",
5229
- {
5230
- kind: SpanKind2.SERVER,
5231
- attributes
5232
- },
5233
- async (span) => {
5234
- const res = this._forward(ai, values, options, span);
5235
- span.end();
5236
- return res;
5237
- }
5238
- );
5364
+ const span = tracer.startSpan("Generate", {
5365
+ kind: SpanKind2.SERVER,
5366
+ attributes
5367
+ });
5368
+ try {
5369
+ yield* this._forward2(
5370
+ ai,
5371
+ values,
5372
+ {
5373
+ ...options,
5374
+ functions
5375
+ },
5376
+ span
5377
+ );
5378
+ } finally {
5379
+ span.end();
5380
+ }
5381
+ }
5382
+ async forward(ai, values, options) {
5383
+ const generator = this._forward1(ai, values, {
5384
+ ...options
5385
+ });
5386
+ let buffer = {};
5387
+ for await (const delta of generator) {
5388
+ buffer = mergeDeltas(buffer, delta.delta);
5389
+ }
5390
+ this.trace = { ...values, ...buffer };
5391
+ return buffer;
5392
+ }
5393
+ async *streamingForward(ai, values, options) {
5394
+ yield* this._forward1(ai, values, {
5395
+ ...options,
5396
+ stream: true
5397
+ });
5239
5398
  }
5240
5399
  };
5241
5400
 
@@ -5325,7 +5484,7 @@ var AxAgent = class {
5325
5484
  func: wrappedFunc
5326
5485
  };
5327
5486
  }
5328
- async forward(ai, values, options) {
5487
+ init(ai, options) {
5329
5488
  const _ai = this.ai ?? ai;
5330
5489
  const funcs = [
5331
5490
  ...options?.functions ?? [],
@@ -5336,26 +5495,15 @@ var AxAgent = class {
5336
5495
  const opt2 = { ...options, functions: funcs };
5337
5496
  this.program = new AxGen(this.signature, opt2);
5338
5497
  }
5339
- if (!options?.tracer) {
5340
- return await this.program.forward(_ai, values, opt);
5341
- }
5342
- const attributes = {
5343
- ["agent.name"]: this.name,
5344
- ["agent.description"]: this.description,
5345
- ["agent.subAgents"]: this.subAgentList ?? "none"
5346
- };
5347
- return await options?.tracer.startActiveSpan(
5348
- "Agent",
5349
- {
5350
- kind: SpanKind3.SERVER,
5351
- attributes
5352
- },
5353
- async (span) => {
5354
- const res = await this.program.forward(_ai, values, opt);
5355
- span.end();
5356
- return res;
5357
- }
5358
- );
5498
+ return { _ai, opt };
5499
+ }
5500
+ async forward(ai, values, options) {
5501
+ const { _ai, opt } = this.init(ai, options);
5502
+ return await this.program.forward(_ai, values, opt);
5503
+ }
5504
+ async *streamingForward(ai, values, options) {
5505
+ const { _ai, opt } = this.init(ai, options);
5506
+ return yield* this.program.streamingForward(_ai, values, opt);
5359
5507
  }
5360
5508
  };
5361
5509
  function toCamelCase(inputString) {
@@ -5626,7 +5774,7 @@ var randomSample = (array, n) => {
5626
5774
  };
5627
5775
 
5628
5776
  // db/base.ts
5629
- import { SpanKind as SpanKind4 } from "@opentelemetry/api";
5777
+ import { SpanKind as SpanKind3 } from "@opentelemetry/api";
5630
5778
  var AxDBBase = class {
5631
5779
  name;
5632
5780
  fetch;
@@ -5653,7 +5801,7 @@ var AxDBBase = class {
5653
5801
  return await this.tracer?.startActiveSpan(
5654
5802
  "DB Upsert Request",
5655
5803
  {
5656
- kind: SpanKind4.SERVER,
5804
+ kind: SpanKind3.SERVER,
5657
5805
  attributes: {
5658
5806
  [axSpanAttributes.DB_SYSTEM]: this.name,
5659
5807
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5663,9 +5811,11 @@ var AxDBBase = class {
5663
5811
  }
5664
5812
  },
5665
5813
  async (span) => {
5666
- const res = await this._upsert(req, update, { span });
5667
- span.end();
5668
- return res;
5814
+ try {
5815
+ return await this._upsert(req, update, { span });
5816
+ } finally {
5817
+ span.end();
5818
+ }
5669
5819
  }
5670
5820
  );
5671
5821
  }
@@ -5685,7 +5835,7 @@ var AxDBBase = class {
5685
5835
  return await this.tracer?.startActiveSpan(
5686
5836
  "DB Batch Upsert Request",
5687
5837
  {
5688
- kind: SpanKind4.SERVER,
5838
+ kind: SpanKind3.SERVER,
5689
5839
  attributes: {
5690
5840
  [axSpanAttributes.DB_SYSTEM]: this.name,
5691
5841
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5695,9 +5845,11 @@ var AxDBBase = class {
5695
5845
  }
5696
5846
  },
5697
5847
  async (span) => {
5698
- const res = await this._batchUpsert(req, update, { span });
5699
- span.end();
5700
- return res;
5848
+ try {
5849
+ return await this._batchUpsert(req, update, { span });
5850
+ } finally {
5851
+ span.end();
5852
+ }
5701
5853
  }
5702
5854
  );
5703
5855
  }
@@ -5711,7 +5863,7 @@ var AxDBBase = class {
5711
5863
  return await this.tracer?.startActiveSpan(
5712
5864
  "DB Query Request",
5713
5865
  {
5714
- kind: SpanKind4.SERVER,
5866
+ kind: SpanKind3.SERVER,
5715
5867
  attributes: {
5716
5868
  [axSpanAttributes.DB_SYSTEM]: this.name,
5717
5869
  [axSpanAttributes.DB_OPERATION_NAME]: "upsert",
@@ -5721,9 +5873,11 @@ var AxDBBase = class {
5721
5873
  }
5722
5874
  },
5723
5875
  async (span) => {
5724
- const res = await this._query(req, { span });
5725
- span.end();
5726
- return res;
5876
+ try {
5877
+ return await this._query(req, { span });
5878
+ } finally {
5879
+ span.end();
5880
+ }
5727
5881
  }
5728
5882
  );
5729
5883
  }
@@ -6990,6 +7144,122 @@ var AxEmbeddingAdapter = class {
6990
7144
  }
6991
7145
  };
6992
7146
 
7147
+ // ai/mock/api.ts
7148
+ var AxMockAIService = class {
7149
+ constructor(config = {}) {
7150
+ this.config = config;
7151
+ }
7152
+ options = {};
7153
+ metrics = {
7154
+ latency: {
7155
+ chat: { mean: 0, p95: 0, p99: 0, samples: [] },
7156
+ embed: { mean: 0, p95: 0, p99: 0, samples: [] }
7157
+ },
7158
+ errors: {
7159
+ chat: { count: 0, rate: 0, total: 0 },
7160
+ embed: { count: 0, rate: 0, total: 0 }
7161
+ }
7162
+ };
7163
+ getName() {
7164
+ return this.config.name ?? "mock-ai-service";
7165
+ }
7166
+ getModelInfo() {
7167
+ return {
7168
+ name: "mock-model",
7169
+ provider: "mock-provider",
7170
+ promptTokenCostPer1M: 100,
7171
+ completionTokenCostPer1M: 100,
7172
+ ...this.config.modelInfo
7173
+ };
7174
+ }
7175
+ getEmbedModelInfo() {
7176
+ return this.config.embedModelInfo;
7177
+ }
7178
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
7179
+ getFeatures(_model) {
7180
+ return {
7181
+ functions: this.config.features?.functions ?? false,
7182
+ streaming: this.config.features?.streaming ?? false
7183
+ };
7184
+ }
7185
+ getModelMap() {
7186
+ return this.config.modelMap;
7187
+ }
7188
+ getMetrics() {
7189
+ return this.metrics;
7190
+ }
7191
+ async chat(req, _options) {
7192
+ if (this.config.latencyMs) {
7193
+ await new Promise((resolve) => setTimeout(resolve, this.config.latencyMs));
7194
+ }
7195
+ if (this.config.shouldError) {
7196
+ throw new Error(this.config.errorMessage ?? "Mock chat error");
7197
+ }
7198
+ this.updateMetrics("chat");
7199
+ if (typeof this.config.chatResponse === "function") {
7200
+ return this.config.chatResponse(req);
7201
+ }
7202
+ return this.config.chatResponse ?? {
7203
+ results: [
7204
+ {
7205
+ content: "Mock response",
7206
+ finishReason: "stop"
7207
+ }
7208
+ ],
7209
+ modelUsage: {
7210
+ promptTokens: 10,
7211
+ completionTokens: 5,
7212
+ totalTokens: 15
7213
+ }
7214
+ };
7215
+ }
7216
+ async embed(req, _options) {
7217
+ if (this.config.latencyMs) {
7218
+ await new Promise((resolve) => setTimeout(resolve, this.config.latencyMs));
7219
+ }
7220
+ if (this.config.shouldError) {
7221
+ throw new Error(this.config.errorMessage ?? "Mock embed error");
7222
+ }
7223
+ this.updateMetrics("embed");
7224
+ if (typeof this.config.embedResponse === "function") {
7225
+ return this.config.embedResponse(req);
7226
+ }
7227
+ return this.config.embedResponse ?? {
7228
+ embeddings: [[0.1, 0.2, 0.3]],
7229
+ modelUsage: {
7230
+ promptTokens: 5,
7231
+ completionTokens: 0,
7232
+ totalTokens: 5
7233
+ }
7234
+ };
7235
+ }
7236
+ setOptions(options) {
7237
+ this.options = options;
7238
+ }
7239
+ getOptions() {
7240
+ return this.options;
7241
+ }
7242
+ updateMetrics(type) {
7243
+ const latency = this.config.latencyMs ?? 0;
7244
+ this.metrics.latency[type].samples.push(latency);
7245
+ const samples = this.metrics.latency[type].samples;
7246
+ this.metrics.latency[type].mean = samples.reduce((a, b) => a + b, 0) / samples.length;
7247
+ if (samples.length > 0) {
7248
+ const sortedSamples = [...samples].sort((a, b) => a - b);
7249
+ const p95Index = Math.max(0, Math.floor(sortedSamples.length * 0.95) - 1);
7250
+ this.metrics.latency[type].p95 = sortedSamples[p95Index] ?? latency;
7251
+ const p99Index = Math.max(0, Math.floor(sortedSamples.length * 0.99) - 1);
7252
+ this.metrics.latency[type].p99 = sortedSamples[p99Index] ?? latency;
7253
+ }
7254
+ if (this.config.shouldError) {
7255
+ this.metrics.errors[type].count++;
7256
+ this.metrics.errors[type].total++;
7257
+ const totalRequests = this.metrics.latency[type].samples.length;
7258
+ this.metrics.errors[type].rate = totalRequests > 0 ? this.metrics.errors[type].count / totalRequests : 0;
7259
+ }
7260
+ }
7261
+ };
7262
+
6993
7263
  // prompts/rag.ts
6994
7264
  var AxRAG = class extends AxChainOfThought {
6995
7265
  genQuery;
@@ -7078,6 +7348,7 @@ export {
7078
7348
  AxJSInterpreterPermission,
7079
7349
  AxLLMRequestTypeValues,
7080
7350
  AxMemory,
7351
+ AxMockAIService,
7081
7352
  AxProgram,
7082
7353
  AxProgramWithSignature,
7083
7354
  AxPromptTemplate,