@ax-llm/ax 11.0.15 → 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({
@@ -2686,9 +2698,10 @@ var axAIGoogleGeminiDefaultConfig = () => structuredClone({
2686
2698
  ...axBaseAIDefaultConfig()
2687
2699
  });
2688
2700
  var AxAIGoogleGeminiImpl = class {
2689
- constructor(config, isVertex, apiKey, options) {
2701
+ constructor(config, isVertex, endpoint, apiKey, options) {
2690
2702
  this.config = config;
2691
2703
  this.isVertex = isVertex;
2704
+ this.endpoint = endpoint;
2692
2705
  this.apiKey = apiKey;
2693
2706
  this.options = options;
2694
2707
  }
@@ -2713,9 +2726,16 @@ var AxAIGoogleGeminiImpl = class {
2713
2726
  if (!req.chatPrompt || req.chatPrompt.length === 0) {
2714
2727
  throw new Error("Chat prompt is empty");
2715
2728
  }
2716
- const apiConfig = {
2717
- name: stream ? `/models/${model}:streamGenerateContent?alt=sse` : `/models/${model}:generateContent`
2718
- };
2729
+ let apiConfig;
2730
+ if (this.endpoint) {
2731
+ apiConfig = {
2732
+ name: stream ? `/${this.endpoint}:streamGenerateContent?alt=sse` : `/${this.endpoint}:generateContent`
2733
+ };
2734
+ } else {
2735
+ apiConfig = {
2736
+ name: stream ? `/models/${model}:streamGenerateContent?alt=sse` : `/models/${model}:generateContent`
2737
+ };
2738
+ }
2719
2739
  if (!this.isVertex) {
2720
2740
  const pf = stream ? "&" : "?";
2721
2741
  apiConfig.name += `${pf}key=${this.apiKey}`;
@@ -2841,8 +2861,10 @@ var AxAIGoogleGeminiImpl = class {
2841
2861
  temperature: req.modelConfig?.temperature ?? this.config.temperature,
2842
2862
  topP: req.modelConfig?.topP ?? this.config.topP,
2843
2863
  topK: req.modelConfig?.topK ?? this.config.topK,
2864
+ frequencyPenalty: req.modelConfig?.frequencyPenalty ?? this.config.frequencyPenalty,
2844
2865
  candidateCount: 1,
2845
- stopSequences: req.modelConfig?.stopSequences ?? this.config.stopSequences
2866
+ stopSequences: req.modelConfig?.stopSequences ?? this.config.stopSequences,
2867
+ responseMimeType: "text/plain"
2846
2868
  };
2847
2869
  const safetySettings2 = this.config.safetySettings;
2848
2870
  const reqValue = {
@@ -2866,9 +2888,15 @@ var AxAIGoogleGeminiImpl = class {
2866
2888
  let apiConfig;
2867
2889
  let reqValue;
2868
2890
  if (this.isVertex) {
2869
- apiConfig = {
2870
- name: `/models/${model}:predict`
2871
- };
2891
+ if (this.endpoint) {
2892
+ apiConfig = {
2893
+ name: `/${this.endpoint}:predict`
2894
+ };
2895
+ } else {
2896
+ apiConfig = {
2897
+ name: `/models/${model}:predict`
2898
+ };
2899
+ }
2872
2900
  reqValue = {
2873
2901
  instances: req.texts.map((text) => ({
2874
2902
  content: text
@@ -2966,6 +2994,7 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2966
2994
  apiKey,
2967
2995
  projectId,
2968
2996
  region,
2997
+ endpoint,
2969
2998
  config,
2970
2999
  options,
2971
3000
  models
@@ -2974,7 +3003,13 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2974
3003
  let apiURL;
2975
3004
  let headers;
2976
3005
  if (isVertex) {
2977
- apiURL = `https://${region}-aiplatform.googleapis.com/v1/projects/${projectId}/locations/${region}/publishers/google/`;
3006
+ let path;
3007
+ if (endpoint) {
3008
+ path = "endpoints";
3009
+ } else {
3010
+ path = "publishers/google";
3011
+ }
3012
+ apiURL = `https://${region}-aiplatform.googleapis.com/v1/projects/${projectId}/locations/${region}/${path}`;
2978
3013
  if (apiKey) {
2979
3014
  headers = async () => ({ Authorization: `Bearer ${apiKey}` });
2980
3015
  } else {
@@ -2994,7 +3029,13 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2994
3029
  ...axAIGoogleGeminiDefaultConfig(),
2995
3030
  ...config
2996
3031
  };
2997
- const aiImpl = new AxAIGoogleGeminiImpl(_config, isVertex, apiKey, options);
3032
+ const aiImpl = new AxAIGoogleGeminiImpl(
3033
+ _config,
3034
+ isVertex,
3035
+ endpoint,
3036
+ apiKey,
3037
+ options
3038
+ );
2998
3039
  super(aiImpl, {
2999
3040
  name: "GoogleGeminiAI",
3000
3041
  apiURL,
@@ -3768,14 +3809,15 @@ function mergeFunctionCalls(functionCalls, functionCallDeltas) {
3768
3809
  // mem/memory.ts
3769
3810
  var defaultLimit = 1e4;
3770
3811
  var MemoryImpl = class {
3771
- constructor(limit = defaultLimit) {
3812
+ constructor(limit = defaultLimit, debug = false) {
3772
3813
  this.limit = limit;
3814
+ this.debug = debug;
3773
3815
  if (limit <= 0) {
3774
3816
  throw Error("argument 'limit' must be greater than 0");
3775
3817
  }
3776
3818
  }
3777
3819
  data = [];
3778
- add(value) {
3820
+ addMemory(value) {
3779
3821
  if (Array.isArray(value)) {
3780
3822
  this.data.push(...value.map((chat) => ({ chat: structuredClone(chat) })));
3781
3823
  } else {
@@ -3788,7 +3830,13 @@ var MemoryImpl = class {
3788
3830
  this.data.splice(0, removeCount);
3789
3831
  }
3790
3832
  }
3791
- addResult({
3833
+ add(value) {
3834
+ this.addMemory(value);
3835
+ if (this.debug) {
3836
+ debugRequest(value);
3837
+ }
3838
+ }
3839
+ addResultMessage({
3792
3840
  content,
3793
3841
  name,
3794
3842
  functionCalls
@@ -3796,26 +3844,44 @@ var MemoryImpl = class {
3796
3844
  if (!content && (!functionCalls || functionCalls.length === 0)) {
3797
3845
  return;
3798
3846
  }
3799
- this.add({ content, name, role: "assistant", functionCalls });
3847
+ this.addMemory({ content, name, role: "assistant", functionCalls });
3800
3848
  }
3801
- updateResult({
3849
+ addResult({
3802
3850
  content,
3803
3851
  name,
3804
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
3805
3864
  }) {
3806
3865
  const lastItem = this.data.at(-1);
3807
3866
  if (!lastItem || lastItem.chat.role !== "assistant") {
3808
- this.addResult({ content, name, functionCalls });
3809
- return;
3810
- }
3811
- if ("content" in lastItem.chat && content) {
3812
- lastItem.chat.content = content;
3813
- }
3814
- if ("name" in lastItem.chat && name) {
3815
- 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
+ }
3816
3878
  }
3817
- if ("functionCalls" in lastItem.chat && functionCalls) {
3818
- lastItem.chat.functionCalls = functionCalls;
3879
+ if (this.debug) {
3880
+ if (delta) {
3881
+ debugResponseDelta(delta);
3882
+ } else if (lastItem) {
3883
+ debugResponse({ content, name, functionCalls });
3884
+ }
3819
3885
  }
3820
3886
  }
3821
3887
  addTag(name) {
@@ -3855,16 +3921,21 @@ var MemoryImpl = class {
3855
3921
  }
3856
3922
  getLast() {
3857
3923
  const lastItem = this.data.at(-1);
3858
- return lastItem?.chat;
3924
+ if (!lastItem) return void 0;
3925
+ return {
3926
+ chat: lastItem.chat,
3927
+ tags: lastItem.tags
3928
+ };
3859
3929
  }
3860
3930
  reset() {
3861
3931
  this.data = [];
3862
3932
  }
3863
3933
  };
3864
3934
  var AxMemory = class {
3865
- constructor(limit = defaultLimit) {
3935
+ constructor(limit = defaultLimit, debug = false) {
3866
3936
  this.limit = limit;
3867
- this.defaultMemory = new MemoryImpl(limit);
3937
+ this.debug = debug;
3938
+ this.defaultMemory = new MemoryImpl(limit, debug);
3868
3939
  }
3869
3940
  memories = /* @__PURE__ */ new Map();
3870
3941
  defaultMemory;
@@ -3906,6 +3977,19 @@ var AxMemory = class {
3906
3977
  }
3907
3978
  }
3908
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
+ }
3909
3993
 
3910
3994
  // dsp/asserts.ts
3911
3995
  var AxAssertionError = class extends Error {
@@ -3940,7 +4024,7 @@ var assertAssertions = (asserts, values) => {
3940
4024
  }
3941
4025
  }
3942
4026
  };
3943
- var assertStreamingAssertions = (asserts, values, xstate, content, final) => {
4027
+ var assertStreamingAssertions = (asserts, xstate, content, final = false) => {
3944
4028
  if (!xstate.currField || xstate.s === -1 || !asserts || asserts.length === 0) {
3945
4029
  return;
3946
4030
  }
@@ -4143,7 +4227,8 @@ ${pointer}`;
4143
4227
  "image",
4144
4228
  "audio",
4145
4229
  "datetime",
4146
- "date"
4230
+ "date",
4231
+ "code"
4147
4232
  ];
4148
4233
  const foundType = types.find((type) => this.match(type));
4149
4234
  if (!foundType) {
@@ -4450,6 +4535,10 @@ var validateValue = (field, value) => {
4450
4535
  const ft = field.type ?? { name: "string", isArray: false };
4451
4536
  const validateSingleValue = (expectedType, val) => {
4452
4537
  switch (expectedType) {
4538
+ case "code":
4539
+ return typeof val === "string";
4540
+ case "json":
4541
+ return typeof val === "object";
4453
4542
  case "string":
4454
4543
  return typeof val === "string";
4455
4544
  case "number":
@@ -4621,7 +4710,10 @@ var LRUCache = class {
4621
4710
  };
4622
4711
  var globalPrefixCache = new LRUCache(500);
4623
4712
  function matchesContent(content, prefix, startIndex = 0, prefixCache = globalPrefixCache) {
4624
- if (/^\s*$/.test(content)) {
4713
+ if (/^```[a-zA-Z]*\s*$/.test(content)) {
4714
+ return -4;
4715
+ }
4716
+ if (/^[\s`]*$/.test(content)) {
4625
4717
  return -3;
4626
4718
  }
4627
4719
  const exactMatchIndex = content.indexOf(prefix, startIndex);
@@ -4833,12 +4925,11 @@ var functionCallInstructions = `
4833
4925
  - Call functions step-by-step, using the output of one function as input to the next.
4834
4926
  - Use the function results to generate the output fields.`;
4835
4927
  var formattingRules = `
4836
- ## Output Formatting Rules
4837
- - Output must strictly follow the defined plain-text \`key: value\` field format.
4838
- - Each output key, value must strictly adhere to the specified output field formatting rules.
4839
- - No preamble, postscript, or supplementary information.
4840
- - Do not repeat output fields.
4841
- - 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.`;
4842
4933
  var AxPromptTemplate = class {
4843
4934
  sig;
4844
4935
  fieldTemplates;
@@ -4847,25 +4938,23 @@ var AxPromptTemplate = class {
4847
4938
  this.sig = sig;
4848
4939
  this.fieldTemplates = fieldTemplates;
4849
4940
  const task = [];
4850
- const inArgs = this.renderDescFields(this.sig.getInputFields());
4851
- const outArgs = this.renderDescFields(this.sig.getOutputFields());
4941
+ const inArgs = renderDescFields(this.sig.getInputFields());
4942
+ const outArgs = renderDescFields(this.sig.getOutputFields());
4852
4943
  task.push(
4853
4944
  `You will be provided with the following fields: ${inArgs}. Your task is to generate new fields: ${outArgs}.`
4854
4945
  );
4855
4946
  const funcs = functions?.map(
4856
4947
  (f) => "toFunction" in f ? f.toFunction() : f
4857
4948
  );
4858
- const funcList = funcs?.map(
4859
- (fn) => `- \`${fn.name}\`: ${capitalizeFirstLetter(fn.description)}.`
4860
- ).join("\n");
4949
+ const funcList = funcs?.map((fn) => `- \`${fn.name}\`: ${formatDescription(fn.description)}`).join("\n");
4861
4950
  if (funcList && funcList.length > 0) {
4862
4951
  task.push(`## Available Functions
4863
4952
  ${funcList}`);
4864
4953
  }
4865
- const inputFields = this.renderFields(this.sig.getInputFields());
4954
+ const inputFields = renderInputFields(this.sig.getInputFields());
4866
4955
  task.push(`## Input Fields
4867
4956
  ${inputFields}`);
4868
- const outputFields = this.renderFields(this.sig.getOutputFields());
4957
+ const outputFields = renderOutputFields(this.sig.getOutputFields());
4869
4958
  task.push(`## Output Fields
4870
4959
  ${outputFields}`);
4871
4960
  if (funcList && funcList.length > 0) {
@@ -4874,10 +4963,8 @@ ${outputFields}`);
4874
4963
  task.push(formattingRules.trim());
4875
4964
  const desc = this.sig.getDescription();
4876
4965
  if (desc) {
4877
- const capitalized = capitalizeFirstLetter(desc.trim());
4878
- const text = capitalized.endsWith(".") ? capitalized : capitalized + ".";
4879
- task.push(`---
4880
- ${text}`);
4966
+ const text = formatDescription(desc);
4967
+ task.push(text);
4881
4968
  }
4882
4969
  this.task = {
4883
4970
  type: "text",
@@ -4900,7 +4987,7 @@ ${text}`);
4900
4987
  let systemContent = this.task.text;
4901
4988
  if (examplesInSystemPrompt) {
4902
4989
  const combinedItems = [
4903
- { type: "text", text: systemContent + "\n\n" },
4990
+ { type: "text", text: systemContent },
4904
4991
  ...renderedExamples,
4905
4992
  ...renderedDemos
4906
4993
  ];
@@ -5116,17 +5203,27 @@ ${text}`);
5116
5203
  }
5117
5204
  return [{ type: "text", text: text.join("") }];
5118
5205
  };
5119
- renderDescFields = (list) => list.map((v) => `\`${v.title}\``).join(", ");
5120
- renderFields = (fields) => {
5121
- const rows = fields.map((field) => {
5122
- const name = field.title;
5123
- const type = field.type?.name ? toFieldType(field.type) : "string";
5124
- const required = field.isOptional ? "optional" : "required";
5125
- const description = field.description ? `: ${capitalizeFirstLetter(field.description)}` : "";
5126
- return `- \`${name}:\` (${type}, ${required}) ${description}.`.trim();
5127
- });
5128
- return rows.join("\n");
5129
- };
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");
5130
5227
  };
5131
5228
  var processValue = (field, value) => {
5132
5229
  if (field.type?.name === "date" && value instanceof Date) {
@@ -5167,6 +5264,8 @@ var toFieldType = (type) => {
5167
5264
  return "JSON object";
5168
5265
  case "class":
5169
5266
  return `classification class (allowed classes: ${type.classes?.join(", ")})`;
5267
+ case "code":
5268
+ return "code";
5170
5269
  default:
5171
5270
  return "string";
5172
5271
  }
@@ -5200,11 +5299,9 @@ var isEmptyValue = (field, value) => {
5200
5299
  }
5201
5300
  return false;
5202
5301
  };
5203
- function capitalizeFirstLetter(str) {
5204
- if (str.length === 0) {
5205
- return "";
5206
- }
5207
- 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(".") ? "" : "."}` : "";
5208
5305
  }
5209
5306
 
5210
5307
  // dsp/validate.ts
@@ -5339,7 +5436,7 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
5339
5436
  let e = matchesContent(content, prefix, xstate.s + 1);
5340
5437
  switch (e) {
5341
5438
  case -1:
5342
- if (streamingValidation && xstate.s == -1 && !field.isOptional) {
5439
+ if (streamingValidation && values.length == 0 && !field.isOptional) {
5343
5440
  throw new ValidationError({
5344
5441
  message: "Required field not found",
5345
5442
  fields: [field]
@@ -5352,6 +5449,10 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
5352
5449
  // Partial match at end, skip and gather more content
5353
5450
  case -3:
5354
5451
  return true;
5452
+ // String is only whitespace, skip and gather more content
5453
+ case -4:
5454
+ xstate.inBlock = true;
5455
+ return true;
5355
5456
  }
5356
5457
  let prefixLen = prefix.length;
5357
5458
  if (xstate.currField) {
@@ -5360,6 +5461,7 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
5360
5461
  if (parsedValue !== void 0) {
5361
5462
  values[xstate.currField.name] = parsedValue;
5362
5463
  }
5464
+ xstate.lastDelta = val;
5363
5465
  }
5364
5466
  checkMissingRequiredFields(xstate, values, index);
5365
5467
  xstate.s = e + prefixLen;
@@ -5372,7 +5474,7 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
5372
5474
  };
5373
5475
  var streamingExtractFinalValue = (sig, values, xstate, content) => {
5374
5476
  if (xstate.currField) {
5375
- const val = content.substring(xstate.s).trim();
5477
+ let val = content.substring(xstate.s).trim();
5376
5478
  const parsedValue = validateAndParseFieldValue(xstate.currField, val);
5377
5479
  if (parsedValue !== void 0) {
5378
5480
  values[xstate.currField.name] = parsedValue;
@@ -5383,6 +5485,8 @@ var streamingExtractFinalValue = (sig, values, xstate, content) => {
5383
5485
  };
5384
5486
  var convertValueToType = (field, val) => {
5385
5487
  switch (field.type?.name) {
5488
+ case "code":
5489
+ return extractBlock(val);
5386
5490
  case "string":
5387
5491
  return val;
5388
5492
  case "number": {
@@ -5421,47 +5525,79 @@ var convertValueToType = (field, val) => {
5421
5525
  return val;
5422
5526
  }
5423
5527
  };
5424
- function* streamValues(sig, values, xstate, content, final = false) {
5528
+ function processStreamingDelta(content, xstate) {
5425
5529
  if (!xstate.currField) {
5426
- return;
5530
+ return null;
5427
5531
  }
5428
- const fieldName = xstate.currField.name;
5532
+ const { name: fieldName, type: fieldType } = xstate.currField ?? {};
5533
+ const { isArray: fieldIsArray, name: fieldTypeName } = fieldType ?? {};
5429
5534
  if (!xstate.streamedIndex) {
5430
- xstate.streamedIndex = { [fieldName]: 0 };
5431
- }
5432
- if (!final) {
5433
- if (!xstate.currField.type || !xstate.currField.type.isArray && xstate.currField.type.name === "string") {
5434
- const pos = xstate.streamedIndex[fieldName] ?? 0;
5435
- const s = xstate.s + pos;
5436
- const v = content.substring(s);
5437
- const v1 = v.replace(/[\s\n\t]+$/, "");
5438
- const v2 = pos === 0 ? v1.trimStart() : v1;
5439
- if (v2.length > 0) {
5440
- yield { [fieldName]: v2 };
5441
- xstate.streamedIndex[fieldName] = pos + v1.length;
5442
- }
5443
- return;
5535
+ xstate.streamedIndex = {};
5536
+ }
5537
+ if (fieldIsArray) {
5538
+ if (xstate.streamedIndex[fieldName] === void 0) {
5539
+ xstate.streamedIndex[fieldName] = 0;
5540
+ }
5541
+ return null;
5542
+ }
5543
+ if (fieldTypeName !== "string" && fieldTypeName !== "code") {
5544
+ if (xstate.streamedIndex[fieldName] === void 0) {
5545
+ xstate.streamedIndex[fieldName] = 0;
5444
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;
5445
5581
  }
5446
5582
  for (const key of Object.keys(values)) {
5447
5583
  const value = values[key];
5448
5584
  if (Array.isArray(value)) {
5449
- 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];
5450
5589
  const v = value.slice(s);
5451
5590
  if (v && v.length > 0) {
5452
5591
  yield { [key]: v };
5453
5592
  xstate.streamedIndex[key] = s + 1;
5454
5593
  }
5455
- continue;
5456
- }
5457
- if (!xstate.streamedIndex[key]) {
5594
+ } else {
5458
5595
  yield { [key]: value };
5459
- xstate.streamedIndex[key] = 1;
5460
5596
  }
5461
5597
  }
5462
5598
  }
5463
5599
  function validateAndParseFieldValue(field, fieldValue) {
5464
- if (!fieldValue || fieldValue === "" || fieldValue === "null" || fieldValue === "NULL" || fieldValue === "undefined") {
5600
+ if (!fieldValue || fieldValue === "" || /^(null|undefined)\s*$/i.test(fieldValue)) {
5465
5601
  if (field.isOptional) {
5466
5602
  return;
5467
5603
  }
@@ -5527,8 +5663,8 @@ function validateAndParseFieldValue(field, fieldValue) {
5527
5663
  return value;
5528
5664
  }
5529
5665
  var extractBlock = (input) => {
5530
- const jsonBlockPattern = /```([A-Za-z]+)?\s*([\s\S]*?)\s*```/g;
5531
- const match = jsonBlockPattern.exec(input);
5666
+ const markdownBlockPattern = /```([A-Za-z]*)\n([\s\S]*?)\n```/g;
5667
+ const match = markdownBlockPattern.exec(input);
5532
5668
  if (!match) {
5533
5669
  return input;
5534
5670
  }
@@ -5541,6 +5677,61 @@ var extractBlock = (input) => {
5541
5677
  return input;
5542
5678
  };
5543
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
+
5544
5735
  // dsp/jsonschema.ts
5545
5736
  var validateJSONSchema = (schema) => {
5546
5737
  const errors = [];
@@ -5758,6 +5949,8 @@ var AxGen = class extends AxProgramWithSignature {
5758
5949
  options;
5759
5950
  functions;
5760
5951
  functionsExecuted = /* @__PURE__ */ new Set();
5952
+ fieldProcessors = [];
5953
+ streamingFieldProcessors = [];
5761
5954
  constructor(signature, options) {
5762
5955
  super(signature, { description: options?.description });
5763
5956
  this.options = options;
@@ -5778,6 +5971,24 @@ var AxGen = class extends AxProgramWithSignature {
5778
5971
  addStreamingAssert = (fieldName, fn, message) => {
5779
5972
  this.streamingAsserts.push({ fieldName, fn, message });
5780
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
+ };
5781
5992
  async forwardSendRequest({
5782
5993
  ai,
5783
5994
  mem,
@@ -5810,7 +6021,8 @@ var AxGen = class extends AxProgramWithSignature {
5810
6021
  sessionId,
5811
6022
  traceId,
5812
6023
  rateLimiter,
5813
- stream
6024
+ stream,
6025
+ debug: false
5814
6026
  }
5815
6027
  );
5816
6028
  return res;
@@ -5820,7 +6032,8 @@ var AxGen = class extends AxProgramWithSignature {
5820
6032
  mem,
5821
6033
  options
5822
6034
  }) {
5823
- const { sessionId, traceId, model, functions, earlyFail } = options ?? {};
6035
+ const { sessionId, traceId, model, functions } = options ?? {};
6036
+ const fastFail = options?.fastFail ?? this.options?.fastFail;
5824
6037
  const usageInfo = {
5825
6038
  ai: ai.getName(),
5826
6039
  model: ai.getModelInfo().name
@@ -5840,7 +6053,7 @@ var AxGen = class extends AxProgramWithSignature {
5840
6053
  traceId,
5841
6054
  sessionId,
5842
6055
  functions,
5843
- earlyFail
6056
+ fastFail
5844
6057
  });
5845
6058
  } else {
5846
6059
  yield await this.processResponse({
@@ -5864,9 +6077,9 @@ var AxGen = class extends AxProgramWithSignature {
5864
6077
  sessionId,
5865
6078
  traceId,
5866
6079
  functions,
5867
- earlyFail
6080
+ fastFail
5868
6081
  }) {
5869
- const streamingValidation = earlyFail ?? ai.getFeatures().functionCot !== true;
6082
+ const streamingValidation = fastFail ?? ai.getFeatures().functionCot !== true;
5870
6083
  const functionCalls = [];
5871
6084
  const values = {};
5872
6085
  const xstate = {
@@ -5885,12 +6098,20 @@ var AxGen = class extends AxProgramWithSignature {
5885
6098
  if (result.functionCalls) {
5886
6099
  mergeFunctionCalls(functionCalls, result.functionCalls);
5887
6100
  mem.updateResult(
5888
- { name: result.name, content, functionCalls },
6101
+ {
6102
+ name: result.name,
6103
+ content,
6104
+ functionCalls,
6105
+ delta: result.functionCalls?.[0]?.function?.params
6106
+ },
5889
6107
  sessionId
5890
6108
  );
5891
6109
  } else if (result.content) {
5892
6110
  content += result.content;
5893
- mem.updateResult({ name: result.name, content }, sessionId);
6111
+ mem.updateResult(
6112
+ { name: result.name, content, delta: result.content },
6113
+ sessionId
6114
+ );
5894
6115
  const skip = streamingExtractValues(
5895
6116
  this.signature,
5896
6117
  values,
@@ -5901,15 +6122,20 @@ var AxGen = class extends AxProgramWithSignature {
5901
6122
  if (skip) {
5902
6123
  continue;
5903
6124
  }
5904
- assertStreamingAssertions(
5905
- this.streamingAsserts,
5906
- values,
5907
- xstate,
5908
- content,
5909
- false
5910
- );
6125
+ assertStreamingAssertions(this.streamingAsserts, xstate, content);
5911
6126
  assertAssertions(this.asserts, values);
5912
- 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);
5913
6139
  }
5914
6140
  if (result.finishReason === "length") {
5915
6141
  throw new Error("Max tokens reached before completion");
@@ -5931,15 +6157,29 @@ var AxGen = class extends AxProgramWithSignature {
5931
6157
  this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5932
6158
  } else {
5933
6159
  streamingExtractFinalValue(this.signature, values, xstate, content);
5934
- assertStreamingAssertions(
5935
- this.streamingAsserts,
5936
- values,
5937
- xstate,
5938
- content,
5939
- true
5940
- );
6160
+ assertStreamingAssertions(this.streamingAsserts, xstate, content, true);
5941
6161
  assertAssertions(this.asserts, values);
5942
- 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);
5943
6183
  }
5944
6184
  }
5945
6185
  async processResponse({
@@ -5980,6 +6220,14 @@ var AxGen = class extends AxProgramWithSignature {
5980
6220
  } else if (result.content) {
5981
6221
  extractValues(this.signature, values, result.content);
5982
6222
  assertAssertions(this.asserts, values);
6223
+ if (this.fieldProcessors.length) {
6224
+ await processFieldProcessors(
6225
+ this.fieldProcessors,
6226
+ values,
6227
+ mem,
6228
+ sessionId
6229
+ );
6230
+ }
5983
6231
  }
5984
6232
  if (result.finishReason === "length") {
5985
6233
  throw new Error("Max tokens reached before completion");
@@ -5991,7 +6239,8 @@ var AxGen = class extends AxProgramWithSignature {
5991
6239
  const stopFunction = (options?.stopFunction ?? this.options?.stopFunction)?.toLowerCase();
5992
6240
  const maxRetries = options.maxRetries ?? this.options?.maxRetries ?? 10;
5993
6241
  const maxSteps = options.maxSteps ?? this.options?.maxSteps ?? 10;
5994
- 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);
5995
6244
  let err;
5996
6245
  if (options?.functions && options.functions.length > 0) {
5997
6246
  const promptTemplate = this.options?.promptTemplate ?? AxPromptTemplate;
@@ -6022,6 +6271,9 @@ var AxGen = class extends AxProgramWithSignature {
6022
6271
  if (shouldContinue) {
6023
6272
  continue multiStepLoop;
6024
6273
  }
6274
+ if (debug) {
6275
+ process.stdout.write("\n");
6276
+ }
6025
6277
  return;
6026
6278
  } catch (e) {
6027
6279
  let errorFields;
@@ -6054,10 +6306,12 @@ var AxGen = class extends AxProgramWithSignature {
6054
6306
  }
6055
6307
  shouldContinueSteps(lastMemItem, stopFunction) {
6056
6308
  const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
6057
- 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) {
6058
6312
  return false;
6059
6313
  }
6060
- if (lastMemItem?.role === "function") {
6314
+ if (isFunction || isProcessor) {
6061
6315
  return true;
6062
6316
  }
6063
6317
  return false;
@@ -6137,17 +6391,18 @@ function processChildAgentFunction(childFunction, parentValues, parentInputKeys,
6137
6391
  injectionKeys
6138
6392
  );
6139
6393
  const originalFunc = processedFunction.func;
6140
- processedFunction.func = (childArgs, funcOptions) => {
6394
+ processedFunction.func = async (childArgs, funcOptions) => {
6141
6395
  const updatedChildArgs = {
6142
6396
  ...childArgs,
6143
6397
  ...pick(parentValues, injectionKeys)
6144
6398
  };
6145
6399
  if (options.debug && injectionKeys.length > 0) {
6146
6400
  process.stdout.write(
6147
- `Function Params: ${JSON.stringify(updatedChildArgs, null, 2)}`
6401
+ `
6402
+ Function Params: ${JSON.stringify(updatedChildArgs, null, 2)}`
6148
6403
  );
6149
6404
  }
6150
- return originalFunc(updatedChildArgs, funcOptions);
6405
+ return await originalFunc(updatedChildArgs, funcOptions);
6151
6406
  };
6152
6407
  }
6153
6408
  return processedFunction;
@@ -6173,6 +6428,7 @@ var AxAgent = class {
6173
6428
  agents;
6174
6429
  disableSmartModelRouting;
6175
6430
  excludeFieldsFromPassthrough;
6431
+ debug;
6176
6432
  name;
6177
6433
  // private subAgentList?: string
6178
6434
  func;
@@ -6185,12 +6441,13 @@ var AxAgent = class {
6185
6441
  agents,
6186
6442
  functions
6187
6443
  }, options) {
6188
- const { disableSmartModelRouting, excludeFieldsFromPassthrough } = options ?? {};
6444
+ const { disableSmartModelRouting, excludeFieldsFromPassthrough, debug } = options ?? {};
6189
6445
  this.ai = ai;
6190
6446
  this.agents = agents;
6191
6447
  this.functions = functions;
6192
6448
  this.disableSmartModelRouting = disableSmartModelRouting;
6193
6449
  this.excludeFieldsFromPassthrough = excludeFieldsFromPassthrough ?? [];
6450
+ this.debug = debug;
6194
6451
  if (!name || name.length < 5) {
6195
6452
  throw new Error(
6196
6453
  `Agent name must be at least 10 characters (more descriptive)`
@@ -6250,10 +6507,21 @@ var AxAgent = class {
6250
6507
  if (!ai) {
6251
6508
  throw new Error("AI service is required to run the agent");
6252
6509
  }
6510
+ const debug = this.getDebug(ai, options);
6511
+ if (debug) {
6512
+ process.stdout.write(`
6513
+ --- Agent Engaged: ${this.name} ---
6514
+ `);
6515
+ }
6253
6516
  const ret = await boundFunc(ai, values, {
6254
6517
  ...options,
6255
6518
  model
6256
6519
  });
6520
+ if (debug) {
6521
+ process.stdout.write(`
6522
+ --- Agent Done: ${this.name} ---
6523
+ `);
6524
+ }
6257
6525
  const sig = this.program.getSignature();
6258
6526
  const outFields = sig.getOutputFields();
6259
6527
  const result = Object.keys(ret).map((k) => {
@@ -6284,10 +6552,11 @@ var AxAgent = class {
6284
6552
  const mm = ai?.getModelList();
6285
6553
  const parentSchema = this.program.getSignature().getInputFields();
6286
6554
  const parentKeys = parentSchema.map((p) => p.name);
6555
+ const debug = this.getDebug(ai, options);
6287
6556
  const agentFuncs = this.agents?.map((agent) => {
6288
6557
  const f = agent.getFeatures();
6289
6558
  const processOptions = {
6290
- debug: ai?.getOptions()?.debug ?? false,
6559
+ debug,
6291
6560
  disableSmartModelRouting: !!this.disableSmartModelRouting,
6292
6561
  excludeFieldsFromPassthrough: f.excludeFieldsFromPassthrough,
6293
6562
  canConfigureSmartModelRouting: f.canConfigureSmartModelRouting
@@ -6304,16 +6573,21 @@ var AxAgent = class {
6304
6573
  ...options?.functions ?? this.functions ?? [],
6305
6574
  ...agentFuncs ?? []
6306
6575
  ];
6307
- return { ai, functions };
6576
+ return { ai, functions, debug };
6308
6577
  }
6309
6578
  async forward(parentAi, values, options) {
6310
- const { ai, functions } = this.init(parentAi, values, options);
6311
- 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
+ });
6312
6585
  }
6313
6586
  async *streamingForward(parentAi, values, options) {
6314
- const { ai, functions } = this.init(parentAi, values, options);
6587
+ const { ai, functions, debug } = this.init(parentAi, values, options);
6315
6588
  return yield* this.program.streamingForward(ai, values, {
6316
6589
  ...options,
6590
+ debug,
6317
6591
  functions
6318
6592
  });
6319
6593
  }
@@ -6337,6 +6611,9 @@ var AxAgent = class {
6337
6611
  }
6338
6612
  this.program.getSignature().setDescription(definition);
6339
6613
  }
6614
+ getDebug(ai, options) {
6615
+ return options?.debug ?? this.debug ?? ai?.getOptions()?.debug ?? false;
6616
+ }
6340
6617
  };
6341
6618
  function toCamelCase(inputString) {
6342
6619
  const words = inputString.split(/[^a-zA-Z0-9]/);