@ax-llm/ax 11.0.16 → 11.0.17

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
@@ -325,28 +325,24 @@ var AxAIServiceError = class extends Error {
325
325
  this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
326
326
  this.errorId = crypto.randomUUID();
327
327
  this.context = context;
328
+ this.stack = this.toString();
328
329
  }
329
330
  timestamp;
330
331
  errorId;
331
332
  context;
332
333
  toString() {
333
- return `${this.name} [${this.errorId}]: ${this.message}
334
- Timestamp: ${this.timestamp}
335
- URL: ${this.url}${this.requestBody ? `
336
- Request Body: ${JSON.stringify(this.requestBody, null, 2)}` : ""}${Object.keys(this.context).length ? `
337
- Context: ${JSON.stringify(this.context, null, 2)}` : ""}`;
338
- }
339
- toJSON() {
340
- return {
341
- name: this.name,
342
- errorId: this.errorId,
343
- message: this.message,
344
- timestamp: this.timestamp,
345
- url: this.url,
346
- requestBody: this.requestBody,
347
- context: this.context,
348
- stack: this.stack
349
- };
334
+ return [
335
+ `${this.name}: ${this.message}`,
336
+ `URL: ${this.url}`,
337
+ `Request Body: ${JSON.stringify(this.requestBody, null, 2)}`,
338
+ `Context: ${JSON.stringify(this.context, null, 2)}`,
339
+ `Timestamp: ${this.timestamp}`,
340
+ `Error ID: ${this.errorId}`
341
+ ].join("\n");
342
+ }
343
+ // For Node.js, override the custom inspect method so console.log shows our custom string.
344
+ [Symbol.for("nodejs.util.inspect.custom")](_depth, _options) {
345
+ return this.toString();
350
346
  }
351
347
  };
352
348
  var AxAIServiceStatusError = class extends AxAIServiceError {
@@ -664,6 +660,35 @@ var apiCall = async (api, json) => {
664
660
  }
665
661
  };
666
662
 
663
+ // util/transform.ts
664
+ var import_web4 = require("stream/web");
665
+ var TypeTransformer = class {
666
+ buffer;
667
+ doneCallback;
668
+ transformFn;
669
+ constructor(transformFn, doneCallback) {
670
+ this.transformFn = transformFn;
671
+ this.doneCallback = doneCallback;
672
+ this.buffer = doneCallback ? [] : void 0;
673
+ }
674
+ async transform(obj, controller) {
675
+ const val = this.transformFn(obj);
676
+ if (val) {
677
+ controller.enqueue(val);
678
+ this.buffer?.push(val);
679
+ }
680
+ }
681
+ async flush(controller) {
682
+ await this.doneCallback?.(this.buffer ?? []);
683
+ controller.terminate();
684
+ }
685
+ };
686
+ var RespTransformStream = class extends import_web4.TransformStream {
687
+ constructor(transformFn, doneCallback) {
688
+ super(new TypeTransformer(transformFn, doneCallback));
689
+ }
690
+ };
691
+
667
692
  // util/log.ts
668
693
  var ColorLog = class {
669
694
  // ANSI escape codes for different colors
@@ -695,42 +720,106 @@ var ColorLog = class {
695
720
  }
696
721
  };
697
722
 
698
- // util/transform.ts
699
- var import_web4 = require("stream/web");
700
- var TypeTransformer = class {
701
- buffer;
702
- doneCallback;
703
- transformFn;
704
- constructor(transformFn, doneCallback) {
705
- this.transformFn = transformFn;
706
- this.doneCallback = doneCallback;
707
- this.buffer = doneCallback ? [] : void 0;
708
- }
709
- async transform(obj, controller) {
710
- const val = this.transformFn(obj);
711
- if (val) {
712
- controller.enqueue(val);
713
- this.buffer?.push(val);
723
+ // ai/debug.ts
724
+ var colorLog = new ColorLog();
725
+ var formatChatMessage = (msg, hideContent) => {
726
+ switch (msg.role) {
727
+ case "system":
728
+ return `
729
+ ${colorLog.blueBright("System:")}
730
+ ${colorLog.whiteBright(msg.content)}`;
731
+ case "function":
732
+ return `
733
+ ${colorLog.blueBright("Function Result:")}
734
+ ${colorLog.whiteBright(msg.result)}`;
735
+ case "user": {
736
+ if (typeof msg.content === "string") {
737
+ return `
738
+ ${colorLog.blueBright("User:")}
739
+ ${colorLog.whiteBright(msg.content)}`;
740
+ }
741
+ const items = msg.content.map((v) => {
742
+ switch (v.type) {
743
+ case "text":
744
+ return `${colorLog.whiteBright(v.text)}`;
745
+ case "image":
746
+ return `(Image, ${v.mimeType}) ${colorLog.whiteBright(v.image.substring(0, 10))}`;
747
+ default:
748
+ throw new Error("Invalid content type");
749
+ }
750
+ });
751
+ return `
752
+ ${colorLog.blueBright("User:")}
753
+ ${items.join("\n")}`;
754
+ }
755
+ case "assistant": {
756
+ if (msg.functionCalls) {
757
+ const fns = msg.functionCalls?.map(({ function: fn }) => {
758
+ const args = typeof fn.params !== "string" ? JSON.stringify(fn.params, null, 2) : fn.params;
759
+ return `${fn.name}(${args})`;
760
+ });
761
+ return `
762
+ ${colorLog.blueBright("\nFunctions:")}
763
+ ${colorLog.whiteBright(fns.join("\n"))}`;
764
+ }
765
+ return `
766
+ ${colorLog.blueBright("\nAssistant:")}
767
+ ${hideContent ? "" : colorLog.whiteBright(msg.content ?? "<empty>")}`;
714
768
  }
769
+ default:
770
+ throw new Error("Invalid role");
715
771
  }
716
- async flush(controller) {
717
- await this.doneCallback?.(this.buffer ?? []);
718
- controller.terminate();
772
+ };
773
+ var logChatRequestMessage = (msg) => {
774
+ process.stdout.write(formatChatMessage(msg) + "\n");
775
+ process.stdout.write(colorLog.blueBright("\nAssistant:\n"));
776
+ };
777
+ var logChatRequest = (chatPrompt) => {
778
+ const items = chatPrompt?.map((msg) => formatChatMessage(msg));
779
+ if (items) {
780
+ process.stdout.write(items.join("\n"));
781
+ process.stdout.write(colorLog.blueBright("\nAssistant:\n"));
719
782
  }
720
783
  };
721
- var RespTransformStream = class extends import_web4.TransformStream {
722
- constructor(transformFn, doneCallback) {
723
- super(new TypeTransformer(transformFn, doneCallback));
784
+ var logResponseResult = (r) => {
785
+ if (r.content) {
786
+ process.stdout.write(colorLog.greenBright(r.content));
787
+ }
788
+ if (r.functionCalls) {
789
+ for (const [i, f] of r.functionCalls.entries()) {
790
+ if (f.function.name) {
791
+ if (i > 0) {
792
+ process.stdout.write("\n");
793
+ }
794
+ process.stdout.write(
795
+ `Function ${i + 1} -> ${colorLog.greenBright(f.function.name)}`
796
+ );
797
+ }
798
+ if (f.function.params) {
799
+ const params = typeof f.function.params === "string" ? f.function.params : JSON.stringify(f.function.params, null, 2);
800
+ process.stdout.write(`${colorLog.greenBright(params)}`);
801
+ }
802
+ }
803
+ }
804
+ };
805
+ var logResponse = (resp) => {
806
+ if (!resp.results) {
807
+ return;
808
+ }
809
+ for (const r of resp.results) {
810
+ logResponseResult(r);
724
811
  }
725
812
  };
813
+ var logResponseDelta = (delta) => {
814
+ process.stdout.write(colorLog.greenBright(delta));
815
+ };
726
816
 
727
817
  // ai/base.ts
728
- var colorLog = new ColorLog();
729
818
  var axBaseAIDefaultConfig = () => structuredClone({
730
819
  maxTokens: 2e3,
731
820
  temperature: 0,
732
821
  topK: 40,
733
- frequencyPenalty: 0.2
822
+ topP: 0.9
734
823
  });
735
824
  var AxBaseAI = class {
736
825
  constructor(aiImpl, {
@@ -1010,8 +1099,8 @@ var AxBaseAI = class {
1010
1099
  );
1011
1100
  return res2;
1012
1101
  };
1013
- if (this.debug) {
1014
- logChatRequest(req);
1102
+ if (options?.debug ?? this.debug) {
1103
+ logChatRequest(req["chatPrompt"]);
1015
1104
  }
1016
1105
  const rt = options?.rateLimiter ?? this.rt;
1017
1106
  const rv = rt ? await rt(fn, { modelUsage: this.modelUsage }) : await fn();
@@ -1029,13 +1118,13 @@ var AxBaseAI = class {
1029
1118
  if (span?.isRecording()) {
1030
1119
  setResponseAttr(res2, span);
1031
1120
  }
1032
- if (this.debug) {
1121
+ if (options?.debug ?? this.debug) {
1033
1122
  logResponse(res2);
1034
1123
  }
1035
1124
  return res2;
1036
1125
  };
1037
1126
  const doneCb = async (_values) => {
1038
- if (this.debug) {
1127
+ if (options?.debug ?? this.debug) {
1039
1128
  process.stdout.write("\n");
1040
1129
  }
1041
1130
  };
@@ -1058,7 +1147,7 @@ var AxBaseAI = class {
1058
1147
  if (span?.isRecording()) {
1059
1148
  setResponseAttr(res, span);
1060
1149
  }
1061
- if (this.debug) {
1150
+ if (options?.debug ?? this.debug) {
1062
1151
  logResponse(res);
1063
1152
  }
1064
1153
  span?.end();
@@ -1149,83 +1238,6 @@ var AxBaseAI = class {
1149
1238
  return { ...headers, ...await this.headers() };
1150
1239
  }
1151
1240
  };
1152
- var logChatRequest = (req) => {
1153
- const hasAssistant = req.chatPrompt?.some((msg) => msg.role === "assistant");
1154
- const items = req.chatPrompt?.map((msg) => {
1155
- if (hasAssistant && msg.role === "system") {
1156
- return "";
1157
- }
1158
- switch (msg.role) {
1159
- case "system":
1160
- return `${colorLog.blueBright("System:")}
1161
- ${colorLog.whiteBright(msg.content)}`;
1162
- case "function":
1163
- return `${colorLog.blueBright("Function Result:")}
1164
- ${colorLog.whiteBright(msg.result)}`;
1165
- case "user": {
1166
- if (typeof msg.content === "string") {
1167
- return `${colorLog.blueBright("User:")}
1168
- ${colorLog.whiteBright(msg.content)}`;
1169
- }
1170
- const items2 = msg.content.map((v) => {
1171
- switch (v.type) {
1172
- case "text":
1173
- return `${colorLog.whiteBright(v.text)}`;
1174
- case "image":
1175
- return `(Image, ${v.mimeType}) ${colorLog.whiteBright(v.image.substring(0, 10))}`;
1176
- default:
1177
- throw new Error("Invalid content type");
1178
- }
1179
- });
1180
- return `${colorLog.blueBright("User:")}
1181
- ${items2.join("\n")}`;
1182
- }
1183
- case "assistant": {
1184
- if (msg.functionCalls) {
1185
- const fns = msg.functionCalls?.map(({ function: fn }) => {
1186
- const args = typeof fn.params !== "string" ? JSON.stringify(fn.params, null, 2) : fn.params;
1187
- return `${fn.name}(${args})`;
1188
- });
1189
- return `${colorLog.blueBright("\nFunctions:")}
1190
- ${colorLog.whiteBright(fns.join("\n"))}`;
1191
- }
1192
- return `${colorLog.blueBright("\nAssistant:")}
1193
- ${colorLog.whiteBright(msg.content ?? "<empty>")}`;
1194
- }
1195
- default:
1196
- throw new Error("Invalid role");
1197
- }
1198
- });
1199
- if (items) {
1200
- process.stdout.write("\n===\n" + items.join("\n") + "\n\n---\n");
1201
- }
1202
- };
1203
- var logResponse = (resp) => {
1204
- if (!resp.results) {
1205
- return;
1206
- }
1207
- for (const r of resp.results) {
1208
- if (r.content) {
1209
- process.stdout.write(colorLog.greenBright(r.content));
1210
- }
1211
- if (r.functionCalls) {
1212
- for (const [i, f] of r.functionCalls.entries()) {
1213
- if (f.function.name) {
1214
- if (i > 0) {
1215
- process.stdout.write("\n\n");
1216
- }
1217
- process.stdout.write(
1218
- `Function ${i + 1} -> ${colorLog.greenBright(f.function.name)} `
1219
- );
1220
- }
1221
- if (f.function.params) {
1222
- const params = typeof f.function.params === "string" ? f.function.params : JSON.stringify(f.function.params, null, 2);
1223
- process.stdout.write(`${colorLog.greenBright(params)}`);
1224
- }
1225
- }
1226
- }
1227
- }
1228
- };
1229
1241
  var setResponseAttr = (res, span) => {
1230
1242
  if (res.modelUsage) {
1231
1243
  span.setAttributes({
@@ -2849,8 +2861,10 @@ var AxAIGoogleGeminiImpl = class {
2849
2861
  temperature: req.modelConfig?.temperature ?? this.config.temperature,
2850
2862
  topP: req.modelConfig?.topP ?? this.config.topP,
2851
2863
  topK: req.modelConfig?.topK ?? this.config.topK,
2864
+ frequencyPenalty: req.modelConfig?.frequencyPenalty ?? this.config.frequencyPenalty,
2852
2865
  candidateCount: 1,
2853
- stopSequences: req.modelConfig?.stopSequences ?? this.config.stopSequences
2866
+ stopSequences: req.modelConfig?.stopSequences ?? this.config.stopSequences,
2867
+ responseMimeType: "text/plain"
2854
2868
  };
2855
2869
  const safetySettings2 = this.config.safetySettings;
2856
2870
  const reqValue = {
@@ -3795,14 +3809,15 @@ function mergeFunctionCalls(functionCalls, functionCallDeltas) {
3795
3809
  // mem/memory.ts
3796
3810
  var defaultLimit = 1e4;
3797
3811
  var MemoryImpl = class {
3798
- constructor(limit = defaultLimit) {
3812
+ constructor(limit = defaultLimit, debug = false) {
3799
3813
  this.limit = limit;
3814
+ this.debug = debug;
3800
3815
  if (limit <= 0) {
3801
3816
  throw Error("argument 'limit' must be greater than 0");
3802
3817
  }
3803
3818
  }
3804
3819
  data = [];
3805
- add(value) {
3820
+ addMemory(value) {
3806
3821
  if (Array.isArray(value)) {
3807
3822
  this.data.push(...value.map((chat) => ({ chat: structuredClone(chat) })));
3808
3823
  } else {
@@ -3815,7 +3830,13 @@ var MemoryImpl = class {
3815
3830
  this.data.splice(0, removeCount);
3816
3831
  }
3817
3832
  }
3818
- addResult({
3833
+ add(value) {
3834
+ this.addMemory(value);
3835
+ if (this.debug) {
3836
+ debugRequest(value);
3837
+ }
3838
+ }
3839
+ addResultMessage({
3819
3840
  content,
3820
3841
  name,
3821
3842
  functionCalls
@@ -3823,26 +3844,44 @@ var MemoryImpl = class {
3823
3844
  if (!content && (!functionCalls || functionCalls.length === 0)) {
3824
3845
  return;
3825
3846
  }
3826
- this.add({ content, name, role: "assistant", functionCalls });
3847
+ this.addMemory({ content, name, role: "assistant", functionCalls });
3827
3848
  }
3828
- updateResult({
3849
+ addResult({
3829
3850
  content,
3830
3851
  name,
3831
3852
  functionCalls
3853
+ }) {
3854
+ this.addResultMessage({ content, name, functionCalls });
3855
+ if (this.debug) {
3856
+ debugResponse({ content, name, functionCalls });
3857
+ }
3858
+ }
3859
+ updateResult({
3860
+ content,
3861
+ name,
3862
+ functionCalls,
3863
+ delta
3832
3864
  }) {
3833
3865
  const lastItem = this.data.at(-1);
3834
3866
  if (!lastItem || lastItem.chat.role !== "assistant") {
3835
- this.addResult({ content, name, functionCalls });
3836
- return;
3837
- }
3838
- if ("content" in lastItem.chat && content) {
3839
- lastItem.chat.content = content;
3840
- }
3841
- if ("name" in lastItem.chat && name) {
3842
- lastItem.chat.name = name;
3867
+ this.addResultMessage({ content, name, functionCalls });
3868
+ } else {
3869
+ if ("content" in lastItem.chat && content) {
3870
+ lastItem.chat.content = content;
3871
+ }
3872
+ if ("name" in lastItem.chat && name) {
3873
+ lastItem.chat.name = name;
3874
+ }
3875
+ if ("functionCalls" in lastItem.chat && functionCalls) {
3876
+ lastItem.chat.functionCalls = functionCalls;
3877
+ }
3843
3878
  }
3844
- if ("functionCalls" in lastItem.chat && functionCalls) {
3845
- lastItem.chat.functionCalls = functionCalls;
3879
+ if (this.debug) {
3880
+ if (delta) {
3881
+ debugResponseDelta(delta);
3882
+ } else if (lastItem) {
3883
+ debugResponse({ content, name, functionCalls });
3884
+ }
3846
3885
  }
3847
3886
  }
3848
3887
  addTag(name) {
@@ -3882,16 +3921,21 @@ var MemoryImpl = class {
3882
3921
  }
3883
3922
  getLast() {
3884
3923
  const lastItem = this.data.at(-1);
3885
- return lastItem?.chat;
3924
+ if (!lastItem) return void 0;
3925
+ return {
3926
+ chat: lastItem.chat,
3927
+ tags: lastItem.tags
3928
+ };
3886
3929
  }
3887
3930
  reset() {
3888
3931
  this.data = [];
3889
3932
  }
3890
3933
  };
3891
3934
  var AxMemory = class {
3892
- constructor(limit = defaultLimit) {
3935
+ constructor(limit = defaultLimit, debug = false) {
3893
3936
  this.limit = limit;
3894
- this.defaultMemory = new MemoryImpl(limit);
3937
+ this.debug = debug;
3938
+ this.defaultMemory = new MemoryImpl(limit, debug);
3895
3939
  }
3896
3940
  memories = /* @__PURE__ */ new Map();
3897
3941
  defaultMemory;
@@ -3933,6 +3977,19 @@ var AxMemory = class {
3933
3977
  }
3934
3978
  }
3935
3979
  };
3980
+ function debugRequest(value) {
3981
+ if (Array.isArray(value)) {
3982
+ logChatRequest(value);
3983
+ } else {
3984
+ logChatRequestMessage(value);
3985
+ }
3986
+ }
3987
+ function debugResponse(value) {
3988
+ logResponseResult(value);
3989
+ }
3990
+ function debugResponseDelta(delta) {
3991
+ logResponseDelta(delta);
3992
+ }
3936
3993
 
3937
3994
  // dsp/asserts.ts
3938
3995
  var AxAssertionError = class extends Error {
@@ -3967,7 +4024,7 @@ var assertAssertions = (asserts, values) => {
3967
4024
  }
3968
4025
  }
3969
4026
  };
3970
- var assertStreamingAssertions = (asserts, values, xstate, content, final) => {
4027
+ var assertStreamingAssertions = (asserts, xstate, content, final = false) => {
3971
4028
  if (!xstate.currField || xstate.s === -1 || !asserts || asserts.length === 0) {
3972
4029
  return;
3973
4030
  }
@@ -4170,7 +4227,8 @@ ${pointer}`;
4170
4227
  "image",
4171
4228
  "audio",
4172
4229
  "datetime",
4173
- "date"
4230
+ "date",
4231
+ "code"
4174
4232
  ];
4175
4233
  const foundType = types.find((type) => this.match(type));
4176
4234
  if (!foundType) {
@@ -4477,6 +4535,10 @@ var validateValue = (field, value) => {
4477
4535
  const ft = field.type ?? { name: "string", isArray: false };
4478
4536
  const validateSingleValue = (expectedType, val) => {
4479
4537
  switch (expectedType) {
4538
+ case "code":
4539
+ return typeof val === "string";
4540
+ case "json":
4541
+ return typeof val === "object";
4480
4542
  case "string":
4481
4543
  return typeof val === "string";
4482
4544
  case "number":
@@ -4648,7 +4710,10 @@ var LRUCache = class {
4648
4710
  };
4649
4711
  var globalPrefixCache = new LRUCache(500);
4650
4712
  function matchesContent(content, prefix, startIndex = 0, prefixCache = globalPrefixCache) {
4651
- if (/^\s*$/.test(content)) {
4713
+ if (/^```[a-zA-Z]*\s*$/.test(content)) {
4714
+ return -4;
4715
+ }
4716
+ if (/^[\s`]*$/.test(content)) {
4652
4717
  return -3;
4653
4718
  }
4654
4719
  const exactMatchIndex = content.indexOf(prefix, startIndex);
@@ -4860,12 +4925,11 @@ var functionCallInstructions = `
4860
4925
  - Call functions step-by-step, using the output of one function as input to the next.
4861
4926
  - Use the function results to generate the output fields.`;
4862
4927
  var formattingRules = `
4863
- ## Output Formatting Rules
4864
- - Output must strictly follow the defined plain-text \`key: value\` field format.
4865
- - Each output key, value must strictly adhere to the specified output field formatting rules.
4866
- - No preamble, postscript, or supplementary information.
4867
- - Do not repeat output fields.
4868
- - Do not use JSON to format the output.`;
4928
+ ## Strict Output Formatting Rules
4929
+ - Output must strictly follow the defined plain-text \`field name: value\` field format.
4930
+ - Output field, values must strictly adhere to the specified output field formatting rules.
4931
+ - Do not add any text before or after the output fields, just the field name and value.
4932
+ - Do not use code blocks.`;
4869
4933
  var AxPromptTemplate = class {
4870
4934
  sig;
4871
4935
  fieldTemplates;
@@ -4874,25 +4938,23 @@ var AxPromptTemplate = class {
4874
4938
  this.sig = sig;
4875
4939
  this.fieldTemplates = fieldTemplates;
4876
4940
  const task = [];
4877
- const inArgs = this.renderDescFields(this.sig.getInputFields());
4878
- const outArgs = this.renderDescFields(this.sig.getOutputFields());
4941
+ const inArgs = renderDescFields(this.sig.getInputFields());
4942
+ const outArgs = renderDescFields(this.sig.getOutputFields());
4879
4943
  task.push(
4880
4944
  `You will be provided with the following fields: ${inArgs}. Your task is to generate new fields: ${outArgs}.`
4881
4945
  );
4882
4946
  const funcs = functions?.map(
4883
4947
  (f) => "toFunction" in f ? f.toFunction() : f
4884
4948
  );
4885
- const funcList = funcs?.map(
4886
- (fn) => `- \`${fn.name}\`: ${capitalizeFirstLetter(fn.description)}.`
4887
- ).join("\n");
4949
+ const funcList = funcs?.map((fn) => `- \`${fn.name}\`: ${formatDescription(fn.description)}`).join("\n");
4888
4950
  if (funcList && funcList.length > 0) {
4889
4951
  task.push(`## Available Functions
4890
4952
  ${funcList}`);
4891
4953
  }
4892
- const inputFields = this.renderFields(this.sig.getInputFields());
4954
+ const inputFields = renderInputFields(this.sig.getInputFields());
4893
4955
  task.push(`## Input Fields
4894
4956
  ${inputFields}`);
4895
- const outputFields = this.renderFields(this.sig.getOutputFields());
4957
+ const outputFields = renderOutputFields(this.sig.getOutputFields());
4896
4958
  task.push(`## Output Fields
4897
4959
  ${outputFields}`);
4898
4960
  if (funcList && funcList.length > 0) {
@@ -4901,10 +4963,8 @@ ${outputFields}`);
4901
4963
  task.push(formattingRules.trim());
4902
4964
  const desc = this.sig.getDescription();
4903
4965
  if (desc) {
4904
- const capitalized = capitalizeFirstLetter(desc.trim());
4905
- const text = capitalized.endsWith(".") ? capitalized : capitalized + ".";
4906
- task.push(`---
4907
- ${text}`);
4966
+ const text = formatDescription(desc);
4967
+ task.push(text);
4908
4968
  }
4909
4969
  this.task = {
4910
4970
  type: "text",
@@ -4927,7 +4987,7 @@ ${text}`);
4927
4987
  let systemContent = this.task.text;
4928
4988
  if (examplesInSystemPrompt) {
4929
4989
  const combinedItems = [
4930
- { type: "text", text: systemContent + "\n\n" },
4990
+ { type: "text", text: systemContent },
4931
4991
  ...renderedExamples,
4932
4992
  ...renderedDemos
4933
4993
  ];
@@ -5143,17 +5203,27 @@ ${text}`);
5143
5203
  }
5144
5204
  return [{ type: "text", text: text.join("") }];
5145
5205
  };
5146
- renderDescFields = (list) => list.map((v) => `\`${v.title}\``).join(", ");
5147
- renderFields = (fields) => {
5148
- const rows = fields.map((field) => {
5149
- const name = field.title;
5150
- const type = field.type?.name ? toFieldType(field.type) : "string";
5151
- const required = field.isOptional ? "optional" : "required";
5152
- const description = field.description ? `: ${capitalizeFirstLetter(field.description)}` : "";
5153
- return `- \`${name}:\` (${type}, ${required}) ${description}.`.trim();
5154
- });
5155
- return rows.join("\n");
5156
- };
5206
+ };
5207
+ var renderDescFields = (list) => list.map((v) => `\`${v.title}\``).join(", ");
5208
+ var renderInputFields = (fields) => {
5209
+ const rows = fields.map((field) => {
5210
+ const name = field.title;
5211
+ const type = field.type?.name ? toFieldType(field.type) : "string";
5212
+ const requiredMsg = field.isOptional ? `This optional ${type} field may be omitted` : `A ${type} field`;
5213
+ const description = field.description ? ` ${formatDescription(field.description)}` : "";
5214
+ return `${name}: (${requiredMsg})${description}`.trim();
5215
+ });
5216
+ return rows.join("\n");
5217
+ };
5218
+ var renderOutputFields = (fields) => {
5219
+ const rows = fields.map((field) => {
5220
+ const name = field.title;
5221
+ const type = field.type?.name ? toFieldType(field.type) : "string";
5222
+ const requiredMsg = field.isOptional ? `Only include this ${type} field is it's value is available` : `This ${type} field must be included`;
5223
+ const description = field.description ? ` ${formatDescription(field.description)}` : "";
5224
+ return `${name}: (${requiredMsg})${description}`.trim();
5225
+ });
5226
+ return rows.join("\n");
5157
5227
  };
5158
5228
  var processValue = (field, value) => {
5159
5229
  if (field.type?.name === "date" && value instanceof Date) {
@@ -5194,6 +5264,8 @@ var toFieldType = (type) => {
5194
5264
  return "JSON object";
5195
5265
  case "class":
5196
5266
  return `classification class (allowed classes: ${type.classes?.join(", ")})`;
5267
+ case "code":
5268
+ return "code";
5197
5269
  default:
5198
5270
  return "string";
5199
5271
  }
@@ -5227,11 +5299,9 @@ var isEmptyValue = (field, value) => {
5227
5299
  }
5228
5300
  return false;
5229
5301
  };
5230
- function capitalizeFirstLetter(str) {
5231
- if (str.length === 0) {
5232
- return "";
5233
- }
5234
- return `${str.charAt(0).toUpperCase()}${str.slice(1)}`;
5302
+ function formatDescription(str) {
5303
+ const value = str.trim();
5304
+ return value.length > 0 ? `${value.charAt(0).toUpperCase()}${value.slice(1)}${value.endsWith(".") ? "" : "."}` : "";
5235
5305
  }
5236
5306
 
5237
5307
  // dsp/validate.ts
@@ -5366,7 +5436,7 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
5366
5436
  let e = matchesContent(content, prefix, xstate.s + 1);
5367
5437
  switch (e) {
5368
5438
  case -1:
5369
- if (streamingValidation && xstate.s == -1 && !field.isOptional) {
5439
+ if (streamingValidation && values.length == 0 && !field.isOptional) {
5370
5440
  throw new ValidationError({
5371
5441
  message: "Required field not found",
5372
5442
  fields: [field]
@@ -5379,6 +5449,10 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
5379
5449
  // Partial match at end, skip and gather more content
5380
5450
  case -3:
5381
5451
  return true;
5452
+ // String is only whitespace, skip and gather more content
5453
+ case -4:
5454
+ xstate.inBlock = true;
5455
+ return true;
5382
5456
  }
5383
5457
  let prefixLen = prefix.length;
5384
5458
  if (xstate.currField) {
@@ -5387,6 +5461,7 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
5387
5461
  if (parsedValue !== void 0) {
5388
5462
  values[xstate.currField.name] = parsedValue;
5389
5463
  }
5464
+ xstate.lastDelta = val;
5390
5465
  }
5391
5466
  checkMissingRequiredFields(xstate, values, index);
5392
5467
  xstate.s = e + prefixLen;
@@ -5399,7 +5474,7 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
5399
5474
  };
5400
5475
  var streamingExtractFinalValue = (sig, values, xstate, content) => {
5401
5476
  if (xstate.currField) {
5402
- const val = content.substring(xstate.s).trim();
5477
+ let val = content.substring(xstate.s).trim();
5403
5478
  const parsedValue = validateAndParseFieldValue(xstate.currField, val);
5404
5479
  if (parsedValue !== void 0) {
5405
5480
  values[xstate.currField.name] = parsedValue;
@@ -5410,6 +5485,8 @@ var streamingExtractFinalValue = (sig, values, xstate, content) => {
5410
5485
  };
5411
5486
  var convertValueToType = (field, val) => {
5412
5487
  switch (field.type?.name) {
5488
+ case "code":
5489
+ return extractBlock(val);
5413
5490
  case "string":
5414
5491
  return val;
5415
5492
  case "number": {
@@ -5448,47 +5525,79 @@ var convertValueToType = (field, val) => {
5448
5525
  return val;
5449
5526
  }
5450
5527
  };
5451
- function* streamValues(sig, values, xstate, content, final = false) {
5528
+ function processStreamingDelta(content, xstate) {
5452
5529
  if (!xstate.currField) {
5453
- return;
5530
+ return null;
5454
5531
  }
5455
- const fieldName = xstate.currField.name;
5532
+ const { name: fieldName, type: fieldType } = xstate.currField ?? {};
5533
+ const { isArray: fieldIsArray, name: fieldTypeName } = fieldType ?? {};
5456
5534
  if (!xstate.streamedIndex) {
5457
- xstate.streamedIndex = { [fieldName]: 0 };
5458
- }
5459
- if (!final) {
5460
- if (!xstate.currField.type || !xstate.currField.type.isArray && xstate.currField.type.name === "string") {
5461
- const pos = xstate.streamedIndex[fieldName] ?? 0;
5462
- const s = xstate.s + pos;
5463
- const v = content.substring(s);
5464
- const v1 = v.replace(/[\s\n\t]+$/, "");
5465
- const v2 = pos === 0 ? v1.trimStart() : v1;
5466
- if (v2.length > 0) {
5467
- yield { [fieldName]: v2 };
5468
- xstate.streamedIndex[fieldName] = pos + v1.length;
5469
- }
5470
- return;
5535
+ xstate.streamedIndex = {};
5536
+ }
5537
+ if (fieldIsArray) {
5538
+ if (xstate.streamedIndex[fieldName] === void 0) {
5539
+ xstate.streamedIndex[fieldName] = 0;
5471
5540
  }
5541
+ return null;
5542
+ }
5543
+ if (fieldTypeName !== "string" && fieldTypeName !== "code") {
5544
+ if (xstate.streamedIndex[fieldName] === void 0) {
5545
+ xstate.streamedIndex[fieldName] = 0;
5546
+ }
5547
+ return null;
5548
+ }
5549
+ const pos = xstate.streamedIndex[fieldName] ?? 0;
5550
+ const s = xstate.s + pos;
5551
+ const isFirstChunk = pos === 0;
5552
+ const d1 = content.substring(s);
5553
+ let d2 = d1.replace(/\s+$/, "");
5554
+ if (xstate.currField?.type?.name === "code") {
5555
+ d2 = d2.replace(/\s*```\s*$/, "");
5556
+ }
5557
+ let d3 = isFirstChunk ? d2.trimStart() : d2;
5558
+ if (xstate.currField?.type?.name === "code") {
5559
+ d3 = d3.replace(/^[ ]*```[a-zA-Z0-9]*\n\s*/, "");
5560
+ }
5561
+ if (d3.length > 0) {
5562
+ xstate.streamedIndex[fieldName] = pos + d2.length;
5563
+ }
5564
+ return d3;
5565
+ }
5566
+ function getStreamingDelta(content, xstate) {
5567
+ if (xstate.lastDelta) {
5568
+ processStreamingDelta(xstate.lastDelta, xstate);
5569
+ xstate.lastDelta = void 0;
5570
+ }
5571
+ return processStreamingDelta(content, xstate);
5572
+ }
5573
+ function* streamValues(sig, values, xstate, delta) {
5574
+ if (!xstate.currField) {
5575
+ return;
5576
+ }
5577
+ const fieldName = xstate.currField.name;
5578
+ if (delta && delta.length > 0) {
5579
+ yield { [fieldName]: delta };
5580
+ return;
5472
5581
  }
5473
5582
  for (const key of Object.keys(values)) {
5474
5583
  const value = values[key];
5475
5584
  if (Array.isArray(value)) {
5476
- const s = xstate.streamedIndex[key] ?? 0;
5585
+ if (xstate.streamedIndex?.[key] === void 0) {
5586
+ throw new Error("Streamed index is not set for array field " + key);
5587
+ }
5588
+ const s = xstate.streamedIndex[key];
5477
5589
  const v = value.slice(s);
5478
5590
  if (v && v.length > 0) {
5479
5591
  yield { [key]: v };
5480
5592
  xstate.streamedIndex[key] = s + 1;
5481
5593
  }
5482
- continue;
5483
- }
5484
- if (!xstate.streamedIndex[key]) {
5594
+ } else {
5485
5595
  yield { [key]: value };
5486
- xstate.streamedIndex[key] = 1;
5487
5596
  }
5488
5597
  }
5489
5598
  }
5490
5599
  function validateAndParseFieldValue(field, fieldValue) {
5491
- if (!fieldValue || fieldValue === "" || fieldValue === "null" || fieldValue === "NULL" || fieldValue === "undefined") {
5600
+ if (!fieldValue || fieldValue === "" || /^(null|undefined)\s*$/i.test(fieldValue)) {
5492
5601
  if (field.isOptional) {
5493
5602
  return;
5494
5603
  }
@@ -5554,8 +5663,8 @@ function validateAndParseFieldValue(field, fieldValue) {
5554
5663
  return value;
5555
5664
  }
5556
5665
  var extractBlock = (input) => {
5557
- const jsonBlockPattern = /```([A-Za-z]+)?\s*([\s\S]*?)\s*```/g;
5558
- const match = jsonBlockPattern.exec(input);
5666
+ const markdownBlockPattern = /```([A-Za-z]*)\n([\s\S]*?)\n```/g;
5667
+ const match = markdownBlockPattern.exec(input);
5559
5668
  if (!match) {
5560
5669
  return input;
5561
5670
  }
@@ -5568,6 +5677,61 @@ var extractBlock = (input) => {
5568
5677
  return input;
5569
5678
  };
5570
5679
 
5680
+ // dsp/fieldProcessor.ts
5681
+ async function processFieldProcessors(fieldProcessors, values, mem, sessionId) {
5682
+ for (const processor of fieldProcessors) {
5683
+ if (values[processor.field.name] === void 0) {
5684
+ continue;
5685
+ }
5686
+ const result = await processor.process(values[processor.field.name], {
5687
+ sessionId,
5688
+ values,
5689
+ done: true
5690
+ });
5691
+ addToMemory(processor.field, mem, result, sessionId);
5692
+ }
5693
+ }
5694
+ async function processStreamingFieldProcessors(fieldProcessors, content, xstate, mem, values, sessionId, done = false) {
5695
+ for (const processor of fieldProcessors) {
5696
+ if (xstate.currField?.name !== processor.field.name) {
5697
+ continue;
5698
+ }
5699
+ let value = content.substring(xstate.s);
5700
+ if (xstate.currField?.type?.name === "code") {
5701
+ value = value.replace(/^[ ]*```[a-zA-Z0-9]*\n\s*/, "");
5702
+ value = value.replace(/\s*```\s*$/, "");
5703
+ }
5704
+ const result = await processor.process(value, {
5705
+ sessionId,
5706
+ values,
5707
+ done
5708
+ });
5709
+ addToMemory(xstate.currField, mem, result, sessionId);
5710
+ }
5711
+ }
5712
+ var addToMemory = (field, mem, result, sessionId) => {
5713
+ if (result === void 0 || typeof result === "string" && (result === "" || /^(null|undefined)\s*$/i.test(result))) {
5714
+ return;
5715
+ }
5716
+ let resultText = JSON.stringify(
5717
+ result,
5718
+ (key, value) => typeof value === "bigint" ? Number(value) : value,
5719
+ 2
5720
+ );
5721
+ const text = getFieldProcessingMessage(field, resultText);
5722
+ mem.add({ role: "user", content: [{ type: "text", text }] }, sessionId);
5723
+ mem.addTag(`processor`, sessionId);
5724
+ };
5725
+ function getFieldProcessingMessage(field, resultText) {
5726
+ const isCodeField = field.type?.name === "code";
5727
+ const fieldTitle = field.title;
5728
+ if (isCodeField) {
5729
+ return `Code in the field "${fieldTitle}" was executed. The code execution produced the following output: ${resultText}`;
5730
+ } else {
5731
+ return `The field "${fieldTitle}" was processed. The field contents were transformed into the following output: ${resultText}`;
5732
+ }
5733
+ }
5734
+
5571
5735
  // dsp/jsonschema.ts
5572
5736
  var validateJSONSchema = (schema) => {
5573
5737
  const errors = [];
@@ -5785,6 +5949,8 @@ var AxGen = class extends AxProgramWithSignature {
5785
5949
  options;
5786
5950
  functions;
5787
5951
  functionsExecuted = /* @__PURE__ */ new Set();
5952
+ fieldProcessors = [];
5953
+ streamingFieldProcessors = [];
5788
5954
  constructor(signature, options) {
5789
5955
  super(signature, { description: options?.description });
5790
5956
  this.options = options;
@@ -5805,6 +5971,24 @@ var AxGen = class extends AxProgramWithSignature {
5805
5971
  addStreamingAssert = (fieldName, fn, message) => {
5806
5972
  this.streamingAsserts.push({ fieldName, fn, message });
5807
5973
  };
5974
+ addFieldProcessor = (fieldName, fn, streaming = false) => {
5975
+ const field = this.signature.getOutputFields().find((f) => f.name === fieldName);
5976
+ if (!field) {
5977
+ throw new Error(`addFieldProcessor: field ${fieldName} not found`);
5978
+ }
5979
+ if (streaming) {
5980
+ const ft = field.type?.name;
5981
+ const isText = !ft || ft === "string" || ft === "code";
5982
+ if (!isText) {
5983
+ throw new Error(
5984
+ `addFieldProcessor: field ${fieldName} is must be a text field`
5985
+ );
5986
+ }
5987
+ this.streamingFieldProcessors.push({ field, process: fn });
5988
+ } else {
5989
+ this.fieldProcessors.push({ field, process: fn });
5990
+ }
5991
+ };
5808
5992
  async forwardSendRequest({
5809
5993
  ai,
5810
5994
  mem,
@@ -5837,7 +6021,8 @@ var AxGen = class extends AxProgramWithSignature {
5837
6021
  sessionId,
5838
6022
  traceId,
5839
6023
  rateLimiter,
5840
- stream
6024
+ stream,
6025
+ debug: false
5841
6026
  }
5842
6027
  );
5843
6028
  return res;
@@ -5847,7 +6032,8 @@ var AxGen = class extends AxProgramWithSignature {
5847
6032
  mem,
5848
6033
  options
5849
6034
  }) {
5850
- const { sessionId, traceId, model, functions, earlyFail } = options ?? {};
6035
+ const { sessionId, traceId, model, functions } = options ?? {};
6036
+ const fastFail = options?.fastFail ?? this.options?.fastFail;
5851
6037
  const usageInfo = {
5852
6038
  ai: ai.getName(),
5853
6039
  model: ai.getModelInfo().name
@@ -5867,7 +6053,7 @@ var AxGen = class extends AxProgramWithSignature {
5867
6053
  traceId,
5868
6054
  sessionId,
5869
6055
  functions,
5870
- earlyFail
6056
+ fastFail
5871
6057
  });
5872
6058
  } else {
5873
6059
  yield await this.processResponse({
@@ -5891,9 +6077,9 @@ var AxGen = class extends AxProgramWithSignature {
5891
6077
  sessionId,
5892
6078
  traceId,
5893
6079
  functions,
5894
- earlyFail
6080
+ fastFail
5895
6081
  }) {
5896
- const streamingValidation = earlyFail ?? ai.getFeatures().functionCot !== true;
6082
+ const streamingValidation = fastFail ?? ai.getFeatures().functionCot !== true;
5897
6083
  const functionCalls = [];
5898
6084
  const values = {};
5899
6085
  const xstate = {
@@ -5912,12 +6098,20 @@ var AxGen = class extends AxProgramWithSignature {
5912
6098
  if (result.functionCalls) {
5913
6099
  mergeFunctionCalls(functionCalls, result.functionCalls);
5914
6100
  mem.updateResult(
5915
- { name: result.name, content, functionCalls },
6101
+ {
6102
+ name: result.name,
6103
+ content,
6104
+ functionCalls,
6105
+ delta: result.functionCalls?.[0]?.function?.params
6106
+ },
5916
6107
  sessionId
5917
6108
  );
5918
6109
  } else if (result.content) {
5919
6110
  content += result.content;
5920
- mem.updateResult({ name: result.name, content }, sessionId);
6111
+ mem.updateResult(
6112
+ { name: result.name, content, delta: result.content },
6113
+ sessionId
6114
+ );
5921
6115
  const skip = streamingExtractValues(
5922
6116
  this.signature,
5923
6117
  values,
@@ -5928,15 +6122,20 @@ var AxGen = class extends AxProgramWithSignature {
5928
6122
  if (skip) {
5929
6123
  continue;
5930
6124
  }
5931
- assertStreamingAssertions(
5932
- this.streamingAsserts,
5933
- values,
5934
- xstate,
5935
- content,
5936
- false
5937
- );
6125
+ assertStreamingAssertions(this.streamingAsserts, xstate, content);
5938
6126
  assertAssertions(this.asserts, values);
5939
- yield* streamValues(this.signature, values, xstate, content);
6127
+ if (this.streamingFieldProcessors.length !== 0) {
6128
+ await processStreamingFieldProcessors(
6129
+ this.streamingFieldProcessors,
6130
+ content,
6131
+ xstate,
6132
+ mem,
6133
+ values,
6134
+ sessionId
6135
+ );
6136
+ }
6137
+ const delta = getStreamingDelta(content, xstate);
6138
+ yield* streamValues(this.signature, values, xstate, delta);
5940
6139
  }
5941
6140
  if (result.finishReason === "length") {
5942
6141
  throw new Error("Max tokens reached before completion");
@@ -5958,15 +6157,29 @@ var AxGen = class extends AxProgramWithSignature {
5958
6157
  this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5959
6158
  } else {
5960
6159
  streamingExtractFinalValue(this.signature, values, xstate, content);
5961
- assertStreamingAssertions(
5962
- this.streamingAsserts,
5963
- values,
5964
- xstate,
5965
- content,
5966
- true
5967
- );
6160
+ assertStreamingAssertions(this.streamingAsserts, xstate, content, true);
5968
6161
  assertAssertions(this.asserts, values);
5969
- yield* streamValues(this.signature, values, xstate, content, true);
6162
+ if (this.fieldProcessors.length) {
6163
+ await processFieldProcessors(
6164
+ this.fieldProcessors,
6165
+ values,
6166
+ mem,
6167
+ sessionId
6168
+ );
6169
+ }
6170
+ if (this.streamingFieldProcessors.length !== 0) {
6171
+ await processStreamingFieldProcessors(
6172
+ this.streamingFieldProcessors,
6173
+ content,
6174
+ xstate,
6175
+ mem,
6176
+ values,
6177
+ sessionId,
6178
+ true
6179
+ );
6180
+ }
6181
+ const delta = getStreamingDelta(content, xstate);
6182
+ yield* streamValues(this.signature, values, xstate, delta);
5970
6183
  }
5971
6184
  }
5972
6185
  async processResponse({
@@ -6007,6 +6220,14 @@ var AxGen = class extends AxProgramWithSignature {
6007
6220
  } else if (result.content) {
6008
6221
  extractValues(this.signature, values, result.content);
6009
6222
  assertAssertions(this.asserts, values);
6223
+ if (this.fieldProcessors.length) {
6224
+ await processFieldProcessors(
6225
+ this.fieldProcessors,
6226
+ values,
6227
+ mem,
6228
+ sessionId
6229
+ );
6230
+ }
6010
6231
  }
6011
6232
  if (result.finishReason === "length") {
6012
6233
  throw new Error("Max tokens reached before completion");
@@ -6018,7 +6239,8 @@ var AxGen = class extends AxProgramWithSignature {
6018
6239
  const stopFunction = (options?.stopFunction ?? this.options?.stopFunction)?.toLowerCase();
6019
6240
  const maxRetries = options.maxRetries ?? this.options?.maxRetries ?? 10;
6020
6241
  const maxSteps = options.maxSteps ?? this.options?.maxSteps ?? 10;
6021
- const mem = options.mem ?? this.options?.mem ?? new AxMemory();
6242
+ const debug = options.debug ?? ai.getOptions().debug;
6243
+ const mem = options.mem ?? this.options?.mem ?? new AxMemory(1e4, debug);
6022
6244
  let err;
6023
6245
  if (options?.functions && options.functions.length > 0) {
6024
6246
  const promptTemplate = this.options?.promptTemplate ?? AxPromptTemplate;
@@ -6049,6 +6271,9 @@ var AxGen = class extends AxProgramWithSignature {
6049
6271
  if (shouldContinue) {
6050
6272
  continue multiStepLoop;
6051
6273
  }
6274
+ if (debug) {
6275
+ process.stdout.write("\n");
6276
+ }
6052
6277
  return;
6053
6278
  } catch (e) {
6054
6279
  let errorFields;
@@ -6081,10 +6306,12 @@ var AxGen = class extends AxProgramWithSignature {
6081
6306
  }
6082
6307
  shouldContinueSteps(lastMemItem, stopFunction) {
6083
6308
  const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
6084
- if (lastMemItem?.role === "function" && stopFunction && stopFunctionExecuted) {
6309
+ const isFunction = lastMemItem?.chat?.role === "function";
6310
+ const isProcessor = lastMemItem?.tags ? lastMemItem.tags.some((tag) => tag === "processor") : false;
6311
+ if (isFunction && stopFunction && stopFunctionExecuted) {
6085
6312
  return false;
6086
6313
  }
6087
- if (lastMemItem?.role === "function") {
6314
+ if (isFunction || isProcessor) {
6088
6315
  return true;
6089
6316
  }
6090
6317
  return false;
@@ -6164,17 +6391,18 @@ function processChildAgentFunction(childFunction, parentValues, parentInputKeys,
6164
6391
  injectionKeys
6165
6392
  );
6166
6393
  const originalFunc = processedFunction.func;
6167
- processedFunction.func = (childArgs, funcOptions) => {
6394
+ processedFunction.func = async (childArgs, funcOptions) => {
6168
6395
  const updatedChildArgs = {
6169
6396
  ...childArgs,
6170
6397
  ...pick(parentValues, injectionKeys)
6171
6398
  };
6172
6399
  if (options.debug && injectionKeys.length > 0) {
6173
6400
  process.stdout.write(
6174
- `Function Params: ${JSON.stringify(updatedChildArgs, null, 2)}`
6401
+ `
6402
+ Function Params: ${JSON.stringify(updatedChildArgs, null, 2)}`
6175
6403
  );
6176
6404
  }
6177
- return originalFunc(updatedChildArgs, funcOptions);
6405
+ return await originalFunc(updatedChildArgs, funcOptions);
6178
6406
  };
6179
6407
  }
6180
6408
  return processedFunction;
@@ -6200,6 +6428,7 @@ var AxAgent = class {
6200
6428
  agents;
6201
6429
  disableSmartModelRouting;
6202
6430
  excludeFieldsFromPassthrough;
6431
+ debug;
6203
6432
  name;
6204
6433
  // private subAgentList?: string
6205
6434
  func;
@@ -6212,12 +6441,13 @@ var AxAgent = class {
6212
6441
  agents,
6213
6442
  functions
6214
6443
  }, options) {
6215
- const { disableSmartModelRouting, excludeFieldsFromPassthrough } = options ?? {};
6444
+ const { disableSmartModelRouting, excludeFieldsFromPassthrough, debug } = options ?? {};
6216
6445
  this.ai = ai;
6217
6446
  this.agents = agents;
6218
6447
  this.functions = functions;
6219
6448
  this.disableSmartModelRouting = disableSmartModelRouting;
6220
6449
  this.excludeFieldsFromPassthrough = excludeFieldsFromPassthrough ?? [];
6450
+ this.debug = debug;
6221
6451
  if (!name || name.length < 5) {
6222
6452
  throw new Error(
6223
6453
  `Agent name must be at least 10 characters (more descriptive)`
@@ -6277,10 +6507,21 @@ var AxAgent = class {
6277
6507
  if (!ai) {
6278
6508
  throw new Error("AI service is required to run the agent");
6279
6509
  }
6510
+ const debug = this.getDebug(ai, options);
6511
+ if (debug) {
6512
+ process.stdout.write(`
6513
+ --- Agent Engaged: ${this.name} ---
6514
+ `);
6515
+ }
6280
6516
  const ret = await boundFunc(ai, values, {
6281
6517
  ...options,
6282
6518
  model
6283
6519
  });
6520
+ if (debug) {
6521
+ process.stdout.write(`
6522
+ --- Agent Done: ${this.name} ---
6523
+ `);
6524
+ }
6284
6525
  const sig = this.program.getSignature();
6285
6526
  const outFields = sig.getOutputFields();
6286
6527
  const result = Object.keys(ret).map((k) => {
@@ -6311,10 +6552,11 @@ var AxAgent = class {
6311
6552
  const mm = ai?.getModelList();
6312
6553
  const parentSchema = this.program.getSignature().getInputFields();
6313
6554
  const parentKeys = parentSchema.map((p) => p.name);
6555
+ const debug = this.getDebug(ai, options);
6314
6556
  const agentFuncs = this.agents?.map((agent) => {
6315
6557
  const f = agent.getFeatures();
6316
6558
  const processOptions = {
6317
- debug: ai?.getOptions()?.debug ?? false,
6559
+ debug,
6318
6560
  disableSmartModelRouting: !!this.disableSmartModelRouting,
6319
6561
  excludeFieldsFromPassthrough: f.excludeFieldsFromPassthrough,
6320
6562
  canConfigureSmartModelRouting: f.canConfigureSmartModelRouting
@@ -6331,16 +6573,21 @@ var AxAgent = class {
6331
6573
  ...options?.functions ?? this.functions ?? [],
6332
6574
  ...agentFuncs ?? []
6333
6575
  ];
6334
- return { ai, functions };
6576
+ return { ai, functions, debug };
6335
6577
  }
6336
6578
  async forward(parentAi, values, options) {
6337
- const { ai, functions } = this.init(parentAi, values, options);
6338
- return await this.program.forward(ai, values, { ...options, functions });
6579
+ const { ai, functions, debug } = this.init(parentAi, values, options);
6580
+ return await this.program.forward(ai, values, {
6581
+ ...options,
6582
+ debug,
6583
+ functions
6584
+ });
6339
6585
  }
6340
6586
  async *streamingForward(parentAi, values, options) {
6341
- const { ai, functions } = this.init(parentAi, values, options);
6587
+ const { ai, functions, debug } = this.init(parentAi, values, options);
6342
6588
  return yield* this.program.streamingForward(ai, values, {
6343
6589
  ...options,
6590
+ debug,
6344
6591
  functions
6345
6592
  });
6346
6593
  }
@@ -6364,6 +6611,9 @@ var AxAgent = class {
6364
6611
  }
6365
6612
  this.program.getSignature().setDescription(definition);
6366
6613
  }
6614
+ getDebug(ai, options) {
6615
+ return options?.debug ?? this.debug ?? ai?.getOptions()?.debug ?? false;
6616
+ }
6367
6617
  };
6368
6618
  function toCamelCase(inputString) {
6369
6619
  const words = inputString.split(/[^a-zA-Z0-9]/);