@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.js CHANGED
@@ -221,28 +221,24 @@ var AxAIServiceError = class extends Error {
221
221
  this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
222
222
  this.errorId = crypto.randomUUID();
223
223
  this.context = context;
224
+ this.stack = this.toString();
224
225
  }
225
226
  timestamp;
226
227
  errorId;
227
228
  context;
228
229
  toString() {
229
- return `${this.name} [${this.errorId}]: ${this.message}
230
- Timestamp: ${this.timestamp}
231
- URL: ${this.url}${this.requestBody ? `
232
- Request Body: ${JSON.stringify(this.requestBody, null, 2)}` : ""}${Object.keys(this.context).length ? `
233
- Context: ${JSON.stringify(this.context, null, 2)}` : ""}`;
234
- }
235
- toJSON() {
236
- return {
237
- name: this.name,
238
- errorId: this.errorId,
239
- message: this.message,
240
- timestamp: this.timestamp,
241
- url: this.url,
242
- requestBody: this.requestBody,
243
- context: this.context,
244
- stack: this.stack
245
- };
230
+ return [
231
+ `${this.name}: ${this.message}`,
232
+ `URL: ${this.url}`,
233
+ `Request Body: ${JSON.stringify(this.requestBody, null, 2)}`,
234
+ `Context: ${JSON.stringify(this.context, null, 2)}`,
235
+ `Timestamp: ${this.timestamp}`,
236
+ `Error ID: ${this.errorId}`
237
+ ].join("\n");
238
+ }
239
+ // For Node.js, override the custom inspect method so console.log shows our custom string.
240
+ [Symbol.for("nodejs.util.inspect.custom")](_depth, _options) {
241
+ return this.toString();
246
242
  }
247
243
  };
248
244
  var AxAIServiceStatusError = class extends AxAIServiceError {
@@ -560,6 +556,37 @@ var apiCall = async (api, json) => {
560
556
  }
561
557
  };
562
558
 
559
+ // util/transform.ts
560
+ import {
561
+ TransformStream as TransformStream4
562
+ } from "stream/web";
563
+ var TypeTransformer = class {
564
+ buffer;
565
+ doneCallback;
566
+ transformFn;
567
+ constructor(transformFn, doneCallback) {
568
+ this.transformFn = transformFn;
569
+ this.doneCallback = doneCallback;
570
+ this.buffer = doneCallback ? [] : void 0;
571
+ }
572
+ async transform(obj, controller) {
573
+ const val = this.transformFn(obj);
574
+ if (val) {
575
+ controller.enqueue(val);
576
+ this.buffer?.push(val);
577
+ }
578
+ }
579
+ async flush(controller) {
580
+ await this.doneCallback?.(this.buffer ?? []);
581
+ controller.terminate();
582
+ }
583
+ };
584
+ var RespTransformStream = class extends TransformStream4 {
585
+ constructor(transformFn, doneCallback) {
586
+ super(new TypeTransformer(transformFn, doneCallback));
587
+ }
588
+ };
589
+
563
590
  // util/log.ts
564
591
  var ColorLog = class {
565
592
  // ANSI escape codes for different colors
@@ -591,44 +618,106 @@ var ColorLog = class {
591
618
  }
592
619
  };
593
620
 
594
- // util/transform.ts
595
- import {
596
- TransformStream as TransformStream4
597
- } from "stream/web";
598
- var TypeTransformer = class {
599
- buffer;
600
- doneCallback;
601
- transformFn;
602
- constructor(transformFn, doneCallback) {
603
- this.transformFn = transformFn;
604
- this.doneCallback = doneCallback;
605
- this.buffer = doneCallback ? [] : void 0;
606
- }
607
- async transform(obj, controller) {
608
- const val = this.transformFn(obj);
609
- if (val) {
610
- controller.enqueue(val);
611
- this.buffer?.push(val);
621
+ // ai/debug.ts
622
+ var colorLog = new ColorLog();
623
+ var formatChatMessage = (msg, hideContent) => {
624
+ switch (msg.role) {
625
+ case "system":
626
+ return `
627
+ ${colorLog.blueBright("System:")}
628
+ ${colorLog.whiteBright(msg.content)}`;
629
+ case "function":
630
+ return `
631
+ ${colorLog.blueBright("Function Result:")}
632
+ ${colorLog.whiteBright(msg.result)}`;
633
+ case "user": {
634
+ if (typeof msg.content === "string") {
635
+ return `
636
+ ${colorLog.blueBright("User:")}
637
+ ${colorLog.whiteBright(msg.content)}`;
638
+ }
639
+ const items = msg.content.map((v) => {
640
+ switch (v.type) {
641
+ case "text":
642
+ return `${colorLog.whiteBright(v.text)}`;
643
+ case "image":
644
+ return `(Image, ${v.mimeType}) ${colorLog.whiteBright(v.image.substring(0, 10))}`;
645
+ default:
646
+ throw new Error("Invalid content type");
647
+ }
648
+ });
649
+ return `
650
+ ${colorLog.blueBright("User:")}
651
+ ${items.join("\n")}`;
652
+ }
653
+ case "assistant": {
654
+ if (msg.functionCalls) {
655
+ const fns = msg.functionCalls?.map(({ function: fn }) => {
656
+ const args = typeof fn.params !== "string" ? JSON.stringify(fn.params, null, 2) : fn.params;
657
+ return `${fn.name}(${args})`;
658
+ });
659
+ return `
660
+ ${colorLog.blueBright("\nFunctions:")}
661
+ ${colorLog.whiteBright(fns.join("\n"))}`;
662
+ }
663
+ return `
664
+ ${colorLog.blueBright("\nAssistant:")}
665
+ ${hideContent ? "" : colorLog.whiteBright(msg.content ?? "<empty>")}`;
612
666
  }
667
+ default:
668
+ throw new Error("Invalid role");
613
669
  }
614
- async flush(controller) {
615
- await this.doneCallback?.(this.buffer ?? []);
616
- controller.terminate();
670
+ };
671
+ var logChatRequestMessage = (msg) => {
672
+ process.stdout.write(formatChatMessage(msg) + "\n");
673
+ process.stdout.write(colorLog.blueBright("\nAssistant:\n"));
674
+ };
675
+ var logChatRequest = (chatPrompt) => {
676
+ const items = chatPrompt?.map((msg) => formatChatMessage(msg));
677
+ if (items) {
678
+ process.stdout.write(items.join("\n"));
679
+ process.stdout.write(colorLog.blueBright("\nAssistant:\n"));
617
680
  }
618
681
  };
619
- var RespTransformStream = class extends TransformStream4 {
620
- constructor(transformFn, doneCallback) {
621
- super(new TypeTransformer(transformFn, doneCallback));
682
+ var logResponseResult = (r) => {
683
+ if (r.content) {
684
+ process.stdout.write(colorLog.greenBright(r.content));
685
+ }
686
+ if (r.functionCalls) {
687
+ for (const [i, f] of r.functionCalls.entries()) {
688
+ if (f.function.name) {
689
+ if (i > 0) {
690
+ process.stdout.write("\n");
691
+ }
692
+ process.stdout.write(
693
+ `Function ${i + 1} -> ${colorLog.greenBright(f.function.name)}`
694
+ );
695
+ }
696
+ if (f.function.params) {
697
+ const params = typeof f.function.params === "string" ? f.function.params : JSON.stringify(f.function.params, null, 2);
698
+ process.stdout.write(`${colorLog.greenBright(params)}`);
699
+ }
700
+ }
701
+ }
702
+ };
703
+ var logResponse = (resp) => {
704
+ if (!resp.results) {
705
+ return;
622
706
  }
707
+ for (const r of resp.results) {
708
+ logResponseResult(r);
709
+ }
710
+ };
711
+ var logResponseDelta = (delta) => {
712
+ process.stdout.write(colorLog.greenBright(delta));
623
713
  };
624
714
 
625
715
  // ai/base.ts
626
- var colorLog = new ColorLog();
627
716
  var axBaseAIDefaultConfig = () => structuredClone({
628
717
  maxTokens: 2e3,
629
718
  temperature: 0,
630
719
  topK: 40,
631
- frequencyPenalty: 0.2
720
+ topP: 0.9
632
721
  });
633
722
  var AxBaseAI = class {
634
723
  constructor(aiImpl, {
@@ -908,8 +997,8 @@ var AxBaseAI = class {
908
997
  );
909
998
  return res2;
910
999
  };
911
- if (this.debug) {
912
- logChatRequest(req);
1000
+ if (options?.debug ?? this.debug) {
1001
+ logChatRequest(req["chatPrompt"]);
913
1002
  }
914
1003
  const rt = options?.rateLimiter ?? this.rt;
915
1004
  const rv = rt ? await rt(fn, { modelUsage: this.modelUsage }) : await fn();
@@ -927,13 +1016,13 @@ var AxBaseAI = class {
927
1016
  if (span?.isRecording()) {
928
1017
  setResponseAttr(res2, span);
929
1018
  }
930
- if (this.debug) {
1019
+ if (options?.debug ?? this.debug) {
931
1020
  logResponse(res2);
932
1021
  }
933
1022
  return res2;
934
1023
  };
935
1024
  const doneCb = async (_values) => {
936
- if (this.debug) {
1025
+ if (options?.debug ?? this.debug) {
937
1026
  process.stdout.write("\n");
938
1027
  }
939
1028
  };
@@ -956,7 +1045,7 @@ var AxBaseAI = class {
956
1045
  if (span?.isRecording()) {
957
1046
  setResponseAttr(res, span);
958
1047
  }
959
- if (this.debug) {
1048
+ if (options?.debug ?? this.debug) {
960
1049
  logResponse(res);
961
1050
  }
962
1051
  span?.end();
@@ -1047,83 +1136,6 @@ var AxBaseAI = class {
1047
1136
  return { ...headers, ...await this.headers() };
1048
1137
  }
1049
1138
  };
1050
- var logChatRequest = (req) => {
1051
- const hasAssistant = req.chatPrompt?.some((msg) => msg.role === "assistant");
1052
- const items = req.chatPrompt?.map((msg) => {
1053
- if (hasAssistant && msg.role === "system") {
1054
- return "";
1055
- }
1056
- switch (msg.role) {
1057
- case "system":
1058
- return `${colorLog.blueBright("System:")}
1059
- ${colorLog.whiteBright(msg.content)}`;
1060
- case "function":
1061
- return `${colorLog.blueBright("Function Result:")}
1062
- ${colorLog.whiteBright(msg.result)}`;
1063
- case "user": {
1064
- if (typeof msg.content === "string") {
1065
- return `${colorLog.blueBright("User:")}
1066
- ${colorLog.whiteBright(msg.content)}`;
1067
- }
1068
- const items2 = msg.content.map((v) => {
1069
- switch (v.type) {
1070
- case "text":
1071
- return `${colorLog.whiteBright(v.text)}`;
1072
- case "image":
1073
- return `(Image, ${v.mimeType}) ${colorLog.whiteBright(v.image.substring(0, 10))}`;
1074
- default:
1075
- throw new Error("Invalid content type");
1076
- }
1077
- });
1078
- return `${colorLog.blueBright("User:")}
1079
- ${items2.join("\n")}`;
1080
- }
1081
- case "assistant": {
1082
- if (msg.functionCalls) {
1083
- const fns = msg.functionCalls?.map(({ function: fn }) => {
1084
- const args = typeof fn.params !== "string" ? JSON.stringify(fn.params, null, 2) : fn.params;
1085
- return `${fn.name}(${args})`;
1086
- });
1087
- return `${colorLog.blueBright("\nFunctions:")}
1088
- ${colorLog.whiteBright(fns.join("\n"))}`;
1089
- }
1090
- return `${colorLog.blueBright("\nAssistant:")}
1091
- ${colorLog.whiteBright(msg.content ?? "<empty>")}`;
1092
- }
1093
- default:
1094
- throw new Error("Invalid role");
1095
- }
1096
- });
1097
- if (items) {
1098
- process.stdout.write("\n===\n" + items.join("\n") + "\n\n---\n");
1099
- }
1100
- };
1101
- var logResponse = (resp) => {
1102
- if (!resp.results) {
1103
- return;
1104
- }
1105
- for (const r of resp.results) {
1106
- if (r.content) {
1107
- process.stdout.write(colorLog.greenBright(r.content));
1108
- }
1109
- if (r.functionCalls) {
1110
- for (const [i, f] of r.functionCalls.entries()) {
1111
- if (f.function.name) {
1112
- if (i > 0) {
1113
- process.stdout.write("\n\n");
1114
- }
1115
- process.stdout.write(
1116
- `Function ${i + 1} -> ${colorLog.greenBright(f.function.name)} `
1117
- );
1118
- }
1119
- if (f.function.params) {
1120
- const params = typeof f.function.params === "string" ? f.function.params : JSON.stringify(f.function.params, null, 2);
1121
- process.stdout.write(`${colorLog.greenBright(params)}`);
1122
- }
1123
- }
1124
- }
1125
- }
1126
- };
1127
1139
  var setResponseAttr = (res, span) => {
1128
1140
  if (res.modelUsage) {
1129
1141
  span.setAttributes({
@@ -2584,9 +2596,10 @@ var axAIGoogleGeminiDefaultConfig = () => structuredClone({
2584
2596
  ...axBaseAIDefaultConfig()
2585
2597
  });
2586
2598
  var AxAIGoogleGeminiImpl = class {
2587
- constructor(config, isVertex, apiKey, options) {
2599
+ constructor(config, isVertex, endpoint, apiKey, options) {
2588
2600
  this.config = config;
2589
2601
  this.isVertex = isVertex;
2602
+ this.endpoint = endpoint;
2590
2603
  this.apiKey = apiKey;
2591
2604
  this.options = options;
2592
2605
  }
@@ -2611,9 +2624,16 @@ var AxAIGoogleGeminiImpl = class {
2611
2624
  if (!req.chatPrompt || req.chatPrompt.length === 0) {
2612
2625
  throw new Error("Chat prompt is empty");
2613
2626
  }
2614
- const apiConfig = {
2615
- name: stream ? `/models/${model}:streamGenerateContent?alt=sse` : `/models/${model}:generateContent`
2616
- };
2627
+ let apiConfig;
2628
+ if (this.endpoint) {
2629
+ apiConfig = {
2630
+ name: stream ? `/${this.endpoint}:streamGenerateContent?alt=sse` : `/${this.endpoint}:generateContent`
2631
+ };
2632
+ } else {
2633
+ apiConfig = {
2634
+ name: stream ? `/models/${model}:streamGenerateContent?alt=sse` : `/models/${model}:generateContent`
2635
+ };
2636
+ }
2617
2637
  if (!this.isVertex) {
2618
2638
  const pf = stream ? "&" : "?";
2619
2639
  apiConfig.name += `${pf}key=${this.apiKey}`;
@@ -2739,8 +2759,10 @@ var AxAIGoogleGeminiImpl = class {
2739
2759
  temperature: req.modelConfig?.temperature ?? this.config.temperature,
2740
2760
  topP: req.modelConfig?.topP ?? this.config.topP,
2741
2761
  topK: req.modelConfig?.topK ?? this.config.topK,
2762
+ frequencyPenalty: req.modelConfig?.frequencyPenalty ?? this.config.frequencyPenalty,
2742
2763
  candidateCount: 1,
2743
- stopSequences: req.modelConfig?.stopSequences ?? this.config.stopSequences
2764
+ stopSequences: req.modelConfig?.stopSequences ?? this.config.stopSequences,
2765
+ responseMimeType: "text/plain"
2744
2766
  };
2745
2767
  const safetySettings2 = this.config.safetySettings;
2746
2768
  const reqValue = {
@@ -2764,9 +2786,15 @@ var AxAIGoogleGeminiImpl = class {
2764
2786
  let apiConfig;
2765
2787
  let reqValue;
2766
2788
  if (this.isVertex) {
2767
- apiConfig = {
2768
- name: `/models/${model}:predict`
2769
- };
2789
+ if (this.endpoint) {
2790
+ apiConfig = {
2791
+ name: `/${this.endpoint}:predict`
2792
+ };
2793
+ } else {
2794
+ apiConfig = {
2795
+ name: `/models/${model}:predict`
2796
+ };
2797
+ }
2770
2798
  reqValue = {
2771
2799
  instances: req.texts.map((text) => ({
2772
2800
  content: text
@@ -2864,6 +2892,7 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2864
2892
  apiKey,
2865
2893
  projectId,
2866
2894
  region,
2895
+ endpoint,
2867
2896
  config,
2868
2897
  options,
2869
2898
  models
@@ -2872,7 +2901,13 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2872
2901
  let apiURL;
2873
2902
  let headers;
2874
2903
  if (isVertex) {
2875
- apiURL = `https://${region}-aiplatform.googleapis.com/v1/projects/${projectId}/locations/${region}/publishers/google/`;
2904
+ let path;
2905
+ if (endpoint) {
2906
+ path = "endpoints";
2907
+ } else {
2908
+ path = "publishers/google";
2909
+ }
2910
+ apiURL = `https://${region}-aiplatform.googleapis.com/v1/projects/${projectId}/locations/${region}/${path}`;
2876
2911
  if (apiKey) {
2877
2912
  headers = async () => ({ Authorization: `Bearer ${apiKey}` });
2878
2913
  } else {
@@ -2892,7 +2927,13 @@ var AxAIGoogleGemini = class extends AxBaseAI {
2892
2927
  ...axAIGoogleGeminiDefaultConfig(),
2893
2928
  ...config
2894
2929
  };
2895
- const aiImpl = new AxAIGoogleGeminiImpl(_config, isVertex, apiKey, options);
2930
+ const aiImpl = new AxAIGoogleGeminiImpl(
2931
+ _config,
2932
+ isVertex,
2933
+ endpoint,
2934
+ apiKey,
2935
+ options
2936
+ );
2896
2937
  super(aiImpl, {
2897
2938
  name: "GoogleGeminiAI",
2898
2939
  apiURL,
@@ -3666,14 +3707,15 @@ function mergeFunctionCalls(functionCalls, functionCallDeltas) {
3666
3707
  // mem/memory.ts
3667
3708
  var defaultLimit = 1e4;
3668
3709
  var MemoryImpl = class {
3669
- constructor(limit = defaultLimit) {
3710
+ constructor(limit = defaultLimit, debug = false) {
3670
3711
  this.limit = limit;
3712
+ this.debug = debug;
3671
3713
  if (limit <= 0) {
3672
3714
  throw Error("argument 'limit' must be greater than 0");
3673
3715
  }
3674
3716
  }
3675
3717
  data = [];
3676
- add(value) {
3718
+ addMemory(value) {
3677
3719
  if (Array.isArray(value)) {
3678
3720
  this.data.push(...value.map((chat) => ({ chat: structuredClone(chat) })));
3679
3721
  } else {
@@ -3686,7 +3728,13 @@ var MemoryImpl = class {
3686
3728
  this.data.splice(0, removeCount);
3687
3729
  }
3688
3730
  }
3689
- addResult({
3731
+ add(value) {
3732
+ this.addMemory(value);
3733
+ if (this.debug) {
3734
+ debugRequest(value);
3735
+ }
3736
+ }
3737
+ addResultMessage({
3690
3738
  content,
3691
3739
  name,
3692
3740
  functionCalls
@@ -3694,26 +3742,44 @@ var MemoryImpl = class {
3694
3742
  if (!content && (!functionCalls || functionCalls.length === 0)) {
3695
3743
  return;
3696
3744
  }
3697
- this.add({ content, name, role: "assistant", functionCalls });
3745
+ this.addMemory({ content, name, role: "assistant", functionCalls });
3698
3746
  }
3699
- updateResult({
3747
+ addResult({
3700
3748
  content,
3701
3749
  name,
3702
3750
  functionCalls
3751
+ }) {
3752
+ this.addResultMessage({ content, name, functionCalls });
3753
+ if (this.debug) {
3754
+ debugResponse({ content, name, functionCalls });
3755
+ }
3756
+ }
3757
+ updateResult({
3758
+ content,
3759
+ name,
3760
+ functionCalls,
3761
+ delta
3703
3762
  }) {
3704
3763
  const lastItem = this.data.at(-1);
3705
3764
  if (!lastItem || lastItem.chat.role !== "assistant") {
3706
- this.addResult({ content, name, functionCalls });
3707
- return;
3708
- }
3709
- if ("content" in lastItem.chat && content) {
3710
- lastItem.chat.content = content;
3711
- }
3712
- if ("name" in lastItem.chat && name) {
3713
- lastItem.chat.name = name;
3765
+ this.addResultMessage({ content, name, functionCalls });
3766
+ } else {
3767
+ if ("content" in lastItem.chat && content) {
3768
+ lastItem.chat.content = content;
3769
+ }
3770
+ if ("name" in lastItem.chat && name) {
3771
+ lastItem.chat.name = name;
3772
+ }
3773
+ if ("functionCalls" in lastItem.chat && functionCalls) {
3774
+ lastItem.chat.functionCalls = functionCalls;
3775
+ }
3714
3776
  }
3715
- if ("functionCalls" in lastItem.chat && functionCalls) {
3716
- lastItem.chat.functionCalls = functionCalls;
3777
+ if (this.debug) {
3778
+ if (delta) {
3779
+ debugResponseDelta(delta);
3780
+ } else if (lastItem) {
3781
+ debugResponse({ content, name, functionCalls });
3782
+ }
3717
3783
  }
3718
3784
  }
3719
3785
  addTag(name) {
@@ -3753,16 +3819,21 @@ var MemoryImpl = class {
3753
3819
  }
3754
3820
  getLast() {
3755
3821
  const lastItem = this.data.at(-1);
3756
- return lastItem?.chat;
3822
+ if (!lastItem) return void 0;
3823
+ return {
3824
+ chat: lastItem.chat,
3825
+ tags: lastItem.tags
3826
+ };
3757
3827
  }
3758
3828
  reset() {
3759
3829
  this.data = [];
3760
3830
  }
3761
3831
  };
3762
3832
  var AxMemory = class {
3763
- constructor(limit = defaultLimit) {
3833
+ constructor(limit = defaultLimit, debug = false) {
3764
3834
  this.limit = limit;
3765
- this.defaultMemory = new MemoryImpl(limit);
3835
+ this.debug = debug;
3836
+ this.defaultMemory = new MemoryImpl(limit, debug);
3766
3837
  }
3767
3838
  memories = /* @__PURE__ */ new Map();
3768
3839
  defaultMemory;
@@ -3804,6 +3875,19 @@ var AxMemory = class {
3804
3875
  }
3805
3876
  }
3806
3877
  };
3878
+ function debugRequest(value) {
3879
+ if (Array.isArray(value)) {
3880
+ logChatRequest(value);
3881
+ } else {
3882
+ logChatRequestMessage(value);
3883
+ }
3884
+ }
3885
+ function debugResponse(value) {
3886
+ logResponseResult(value);
3887
+ }
3888
+ function debugResponseDelta(delta) {
3889
+ logResponseDelta(delta);
3890
+ }
3807
3891
 
3808
3892
  // dsp/asserts.ts
3809
3893
  var AxAssertionError = class extends Error {
@@ -3838,7 +3922,7 @@ var assertAssertions = (asserts, values) => {
3838
3922
  }
3839
3923
  }
3840
3924
  };
3841
- var assertStreamingAssertions = (asserts, values, xstate, content, final) => {
3925
+ var assertStreamingAssertions = (asserts, xstate, content, final = false) => {
3842
3926
  if (!xstate.currField || xstate.s === -1 || !asserts || asserts.length === 0) {
3843
3927
  return;
3844
3928
  }
@@ -4041,7 +4125,8 @@ ${pointer}`;
4041
4125
  "image",
4042
4126
  "audio",
4043
4127
  "datetime",
4044
- "date"
4128
+ "date",
4129
+ "code"
4045
4130
  ];
4046
4131
  const foundType = types.find((type) => this.match(type));
4047
4132
  if (!foundType) {
@@ -4348,6 +4433,10 @@ var validateValue = (field, value) => {
4348
4433
  const ft = field.type ?? { name: "string", isArray: false };
4349
4434
  const validateSingleValue = (expectedType, val) => {
4350
4435
  switch (expectedType) {
4436
+ case "code":
4437
+ return typeof val === "string";
4438
+ case "json":
4439
+ return typeof val === "object";
4351
4440
  case "string":
4352
4441
  return typeof val === "string";
4353
4442
  case "number":
@@ -4519,7 +4608,10 @@ var LRUCache = class {
4519
4608
  };
4520
4609
  var globalPrefixCache = new LRUCache(500);
4521
4610
  function matchesContent(content, prefix, startIndex = 0, prefixCache = globalPrefixCache) {
4522
- if (/^\s*$/.test(content)) {
4611
+ if (/^```[a-zA-Z]*\s*$/.test(content)) {
4612
+ return -4;
4613
+ }
4614
+ if (/^[\s`]*$/.test(content)) {
4523
4615
  return -3;
4524
4616
  }
4525
4617
  const exactMatchIndex = content.indexOf(prefix, startIndex);
@@ -4731,12 +4823,11 @@ var functionCallInstructions = `
4731
4823
  - Call functions step-by-step, using the output of one function as input to the next.
4732
4824
  - Use the function results to generate the output fields.`;
4733
4825
  var formattingRules = `
4734
- ## Output Formatting Rules
4735
- - Output must strictly follow the defined plain-text \`key: value\` field format.
4736
- - Each output key, value must strictly adhere to the specified output field formatting rules.
4737
- - No preamble, postscript, or supplementary information.
4738
- - Do not repeat output fields.
4739
- - Do not use JSON to format the output.`;
4826
+ ## Strict Output Formatting Rules
4827
+ - Output must strictly follow the defined plain-text \`field name: value\` field format.
4828
+ - Output field, values must strictly adhere to the specified output field formatting rules.
4829
+ - Do not add any text before or after the output fields, just the field name and value.
4830
+ - Do not use code blocks.`;
4740
4831
  var AxPromptTemplate = class {
4741
4832
  sig;
4742
4833
  fieldTemplates;
@@ -4745,25 +4836,23 @@ var AxPromptTemplate = class {
4745
4836
  this.sig = sig;
4746
4837
  this.fieldTemplates = fieldTemplates;
4747
4838
  const task = [];
4748
- const inArgs = this.renderDescFields(this.sig.getInputFields());
4749
- const outArgs = this.renderDescFields(this.sig.getOutputFields());
4839
+ const inArgs = renderDescFields(this.sig.getInputFields());
4840
+ const outArgs = renderDescFields(this.sig.getOutputFields());
4750
4841
  task.push(
4751
4842
  `You will be provided with the following fields: ${inArgs}. Your task is to generate new fields: ${outArgs}.`
4752
4843
  );
4753
4844
  const funcs = functions?.map(
4754
4845
  (f) => "toFunction" in f ? f.toFunction() : f
4755
4846
  );
4756
- const funcList = funcs?.map(
4757
- (fn) => `- \`${fn.name}\`: ${capitalizeFirstLetter(fn.description)}.`
4758
- ).join("\n");
4847
+ const funcList = funcs?.map((fn) => `- \`${fn.name}\`: ${formatDescription(fn.description)}`).join("\n");
4759
4848
  if (funcList && funcList.length > 0) {
4760
4849
  task.push(`## Available Functions
4761
4850
  ${funcList}`);
4762
4851
  }
4763
- const inputFields = this.renderFields(this.sig.getInputFields());
4852
+ const inputFields = renderInputFields(this.sig.getInputFields());
4764
4853
  task.push(`## Input Fields
4765
4854
  ${inputFields}`);
4766
- const outputFields = this.renderFields(this.sig.getOutputFields());
4855
+ const outputFields = renderOutputFields(this.sig.getOutputFields());
4767
4856
  task.push(`## Output Fields
4768
4857
  ${outputFields}`);
4769
4858
  if (funcList && funcList.length > 0) {
@@ -4772,10 +4861,8 @@ ${outputFields}`);
4772
4861
  task.push(formattingRules.trim());
4773
4862
  const desc = this.sig.getDescription();
4774
4863
  if (desc) {
4775
- const capitalized = capitalizeFirstLetter(desc.trim());
4776
- const text = capitalized.endsWith(".") ? capitalized : capitalized + ".";
4777
- task.push(`---
4778
- ${text}`);
4864
+ const text = formatDescription(desc);
4865
+ task.push(text);
4779
4866
  }
4780
4867
  this.task = {
4781
4868
  type: "text",
@@ -4798,7 +4885,7 @@ ${text}`);
4798
4885
  let systemContent = this.task.text;
4799
4886
  if (examplesInSystemPrompt) {
4800
4887
  const combinedItems = [
4801
- { type: "text", text: systemContent + "\n\n" },
4888
+ { type: "text", text: systemContent },
4802
4889
  ...renderedExamples,
4803
4890
  ...renderedDemos
4804
4891
  ];
@@ -5014,17 +5101,27 @@ ${text}`);
5014
5101
  }
5015
5102
  return [{ type: "text", text: text.join("") }];
5016
5103
  };
5017
- renderDescFields = (list) => list.map((v) => `\`${v.title}\``).join(", ");
5018
- renderFields = (fields) => {
5019
- const rows = fields.map((field) => {
5020
- const name = field.title;
5021
- const type = field.type?.name ? toFieldType(field.type) : "string";
5022
- const required = field.isOptional ? "optional" : "required";
5023
- const description = field.description ? `: ${capitalizeFirstLetter(field.description)}` : "";
5024
- return `- \`${name}:\` (${type}, ${required}) ${description}.`.trim();
5025
- });
5026
- return rows.join("\n");
5027
- };
5104
+ };
5105
+ var renderDescFields = (list) => list.map((v) => `\`${v.title}\``).join(", ");
5106
+ var renderInputFields = (fields) => {
5107
+ const rows = fields.map((field) => {
5108
+ const name = field.title;
5109
+ const type = field.type?.name ? toFieldType(field.type) : "string";
5110
+ const requiredMsg = field.isOptional ? `This optional ${type} field may be omitted` : `A ${type} field`;
5111
+ const description = field.description ? ` ${formatDescription(field.description)}` : "";
5112
+ return `${name}: (${requiredMsg})${description}`.trim();
5113
+ });
5114
+ return rows.join("\n");
5115
+ };
5116
+ var renderOutputFields = (fields) => {
5117
+ const rows = fields.map((field) => {
5118
+ const name = field.title;
5119
+ const type = field.type?.name ? toFieldType(field.type) : "string";
5120
+ const requiredMsg = field.isOptional ? `Only include this ${type} field is it's value is available` : `This ${type} field must be included`;
5121
+ const description = field.description ? ` ${formatDescription(field.description)}` : "";
5122
+ return `${name}: (${requiredMsg})${description}`.trim();
5123
+ });
5124
+ return rows.join("\n");
5028
5125
  };
5029
5126
  var processValue = (field, value) => {
5030
5127
  if (field.type?.name === "date" && value instanceof Date) {
@@ -5065,6 +5162,8 @@ var toFieldType = (type) => {
5065
5162
  return "JSON object";
5066
5163
  case "class":
5067
5164
  return `classification class (allowed classes: ${type.classes?.join(", ")})`;
5165
+ case "code":
5166
+ return "code";
5068
5167
  default:
5069
5168
  return "string";
5070
5169
  }
@@ -5098,11 +5197,9 @@ var isEmptyValue = (field, value) => {
5098
5197
  }
5099
5198
  return false;
5100
5199
  };
5101
- function capitalizeFirstLetter(str) {
5102
- if (str.length === 0) {
5103
- return "";
5104
- }
5105
- return `${str.charAt(0).toUpperCase()}${str.slice(1)}`;
5200
+ function formatDescription(str) {
5201
+ const value = str.trim();
5202
+ return value.length > 0 ? `${value.charAt(0).toUpperCase()}${value.slice(1)}${value.endsWith(".") ? "" : "."}` : "";
5106
5203
  }
5107
5204
 
5108
5205
  // dsp/validate.ts
@@ -5237,7 +5334,7 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
5237
5334
  let e = matchesContent(content, prefix, xstate.s + 1);
5238
5335
  switch (e) {
5239
5336
  case -1:
5240
- if (streamingValidation && xstate.s == -1 && !field.isOptional) {
5337
+ if (streamingValidation && values.length == 0 && !field.isOptional) {
5241
5338
  throw new ValidationError({
5242
5339
  message: "Required field not found",
5243
5340
  fields: [field]
@@ -5250,6 +5347,10 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
5250
5347
  // Partial match at end, skip and gather more content
5251
5348
  case -3:
5252
5349
  return true;
5350
+ // String is only whitespace, skip and gather more content
5351
+ case -4:
5352
+ xstate.inBlock = true;
5353
+ return true;
5253
5354
  }
5254
5355
  let prefixLen = prefix.length;
5255
5356
  if (xstate.currField) {
@@ -5258,6 +5359,7 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
5258
5359
  if (parsedValue !== void 0) {
5259
5360
  values[xstate.currField.name] = parsedValue;
5260
5361
  }
5362
+ xstate.lastDelta = val;
5261
5363
  }
5262
5364
  checkMissingRequiredFields(xstate, values, index);
5263
5365
  xstate.s = e + prefixLen;
@@ -5270,7 +5372,7 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
5270
5372
  };
5271
5373
  var streamingExtractFinalValue = (sig, values, xstate, content) => {
5272
5374
  if (xstate.currField) {
5273
- const val = content.substring(xstate.s).trim();
5375
+ let val = content.substring(xstate.s).trim();
5274
5376
  const parsedValue = validateAndParseFieldValue(xstate.currField, val);
5275
5377
  if (parsedValue !== void 0) {
5276
5378
  values[xstate.currField.name] = parsedValue;
@@ -5281,6 +5383,8 @@ var streamingExtractFinalValue = (sig, values, xstate, content) => {
5281
5383
  };
5282
5384
  var convertValueToType = (field, val) => {
5283
5385
  switch (field.type?.name) {
5386
+ case "code":
5387
+ return extractBlock(val);
5284
5388
  case "string":
5285
5389
  return val;
5286
5390
  case "number": {
@@ -5319,47 +5423,79 @@ var convertValueToType = (field, val) => {
5319
5423
  return val;
5320
5424
  }
5321
5425
  };
5322
- function* streamValues(sig, values, xstate, content, final = false) {
5426
+ function processStreamingDelta(content, xstate) {
5323
5427
  if (!xstate.currField) {
5324
- return;
5428
+ return null;
5325
5429
  }
5326
- const fieldName = xstate.currField.name;
5430
+ const { name: fieldName, type: fieldType } = xstate.currField ?? {};
5431
+ const { isArray: fieldIsArray, name: fieldTypeName } = fieldType ?? {};
5327
5432
  if (!xstate.streamedIndex) {
5328
- xstate.streamedIndex = { [fieldName]: 0 };
5329
- }
5330
- if (!final) {
5331
- if (!xstate.currField.type || !xstate.currField.type.isArray && xstate.currField.type.name === "string") {
5332
- const pos = xstate.streamedIndex[fieldName] ?? 0;
5333
- const s = xstate.s + pos;
5334
- const v = content.substring(s);
5335
- const v1 = v.replace(/[\s\n\t]+$/, "");
5336
- const v2 = pos === 0 ? v1.trimStart() : v1;
5337
- if (v2.length > 0) {
5338
- yield { [fieldName]: v2 };
5339
- xstate.streamedIndex[fieldName] = pos + v1.length;
5340
- }
5341
- return;
5433
+ xstate.streamedIndex = {};
5434
+ }
5435
+ if (fieldIsArray) {
5436
+ if (xstate.streamedIndex[fieldName] === void 0) {
5437
+ xstate.streamedIndex[fieldName] = 0;
5438
+ }
5439
+ return null;
5440
+ }
5441
+ if (fieldTypeName !== "string" && fieldTypeName !== "code") {
5442
+ if (xstate.streamedIndex[fieldName] === void 0) {
5443
+ xstate.streamedIndex[fieldName] = 0;
5342
5444
  }
5445
+ return null;
5446
+ }
5447
+ const pos = xstate.streamedIndex[fieldName] ?? 0;
5448
+ const s = xstate.s + pos;
5449
+ const isFirstChunk = pos === 0;
5450
+ const d1 = content.substring(s);
5451
+ let d2 = d1.replace(/\s+$/, "");
5452
+ if (xstate.currField?.type?.name === "code") {
5453
+ d2 = d2.replace(/\s*```\s*$/, "");
5454
+ }
5455
+ let d3 = isFirstChunk ? d2.trimStart() : d2;
5456
+ if (xstate.currField?.type?.name === "code") {
5457
+ d3 = d3.replace(/^[ ]*```[a-zA-Z0-9]*\n\s*/, "");
5458
+ }
5459
+ if (d3.length > 0) {
5460
+ xstate.streamedIndex[fieldName] = pos + d2.length;
5461
+ }
5462
+ return d3;
5463
+ }
5464
+ function getStreamingDelta(content, xstate) {
5465
+ if (xstate.lastDelta) {
5466
+ processStreamingDelta(xstate.lastDelta, xstate);
5467
+ xstate.lastDelta = void 0;
5468
+ }
5469
+ return processStreamingDelta(content, xstate);
5470
+ }
5471
+ function* streamValues(sig, values, xstate, delta) {
5472
+ if (!xstate.currField) {
5473
+ return;
5474
+ }
5475
+ const fieldName = xstate.currField.name;
5476
+ if (delta && delta.length > 0) {
5477
+ yield { [fieldName]: delta };
5478
+ return;
5343
5479
  }
5344
5480
  for (const key of Object.keys(values)) {
5345
5481
  const value = values[key];
5346
5482
  if (Array.isArray(value)) {
5347
- const s = xstate.streamedIndex[key] ?? 0;
5483
+ if (xstate.streamedIndex?.[key] === void 0) {
5484
+ throw new Error("Streamed index is not set for array field " + key);
5485
+ }
5486
+ const s = xstate.streamedIndex[key];
5348
5487
  const v = value.slice(s);
5349
5488
  if (v && v.length > 0) {
5350
5489
  yield { [key]: v };
5351
5490
  xstate.streamedIndex[key] = s + 1;
5352
5491
  }
5353
- continue;
5354
- }
5355
- if (!xstate.streamedIndex[key]) {
5492
+ } else {
5356
5493
  yield { [key]: value };
5357
- xstate.streamedIndex[key] = 1;
5358
5494
  }
5359
5495
  }
5360
5496
  }
5361
5497
  function validateAndParseFieldValue(field, fieldValue) {
5362
- if (!fieldValue || fieldValue === "" || fieldValue === "null" || fieldValue === "NULL" || fieldValue === "undefined") {
5498
+ if (!fieldValue || fieldValue === "" || /^(null|undefined)\s*$/i.test(fieldValue)) {
5363
5499
  if (field.isOptional) {
5364
5500
  return;
5365
5501
  }
@@ -5425,8 +5561,8 @@ function validateAndParseFieldValue(field, fieldValue) {
5425
5561
  return value;
5426
5562
  }
5427
5563
  var extractBlock = (input) => {
5428
- const jsonBlockPattern = /```([A-Za-z]+)?\s*([\s\S]*?)\s*```/g;
5429
- const match = jsonBlockPattern.exec(input);
5564
+ const markdownBlockPattern = /```([A-Za-z]*)\n([\s\S]*?)\n```/g;
5565
+ const match = markdownBlockPattern.exec(input);
5430
5566
  if (!match) {
5431
5567
  return input;
5432
5568
  }
@@ -5439,6 +5575,61 @@ var extractBlock = (input) => {
5439
5575
  return input;
5440
5576
  };
5441
5577
 
5578
+ // dsp/fieldProcessor.ts
5579
+ async function processFieldProcessors(fieldProcessors, values, mem, sessionId) {
5580
+ for (const processor of fieldProcessors) {
5581
+ if (values[processor.field.name] === void 0) {
5582
+ continue;
5583
+ }
5584
+ const result = await processor.process(values[processor.field.name], {
5585
+ sessionId,
5586
+ values,
5587
+ done: true
5588
+ });
5589
+ addToMemory(processor.field, mem, result, sessionId);
5590
+ }
5591
+ }
5592
+ async function processStreamingFieldProcessors(fieldProcessors, content, xstate, mem, values, sessionId, done = false) {
5593
+ for (const processor of fieldProcessors) {
5594
+ if (xstate.currField?.name !== processor.field.name) {
5595
+ continue;
5596
+ }
5597
+ let value = content.substring(xstate.s);
5598
+ if (xstate.currField?.type?.name === "code") {
5599
+ value = value.replace(/^[ ]*```[a-zA-Z0-9]*\n\s*/, "");
5600
+ value = value.replace(/\s*```\s*$/, "");
5601
+ }
5602
+ const result = await processor.process(value, {
5603
+ sessionId,
5604
+ values,
5605
+ done
5606
+ });
5607
+ addToMemory(xstate.currField, mem, result, sessionId);
5608
+ }
5609
+ }
5610
+ var addToMemory = (field, mem, result, sessionId) => {
5611
+ if (result === void 0 || typeof result === "string" && (result === "" || /^(null|undefined)\s*$/i.test(result))) {
5612
+ return;
5613
+ }
5614
+ let resultText = JSON.stringify(
5615
+ result,
5616
+ (key, value) => typeof value === "bigint" ? Number(value) : value,
5617
+ 2
5618
+ );
5619
+ const text = getFieldProcessingMessage(field, resultText);
5620
+ mem.add({ role: "user", content: [{ type: "text", text }] }, sessionId);
5621
+ mem.addTag(`processor`, sessionId);
5622
+ };
5623
+ function getFieldProcessingMessage(field, resultText) {
5624
+ const isCodeField = field.type?.name === "code";
5625
+ const fieldTitle = field.title;
5626
+ if (isCodeField) {
5627
+ return `Code in the field "${fieldTitle}" was executed. The code execution produced the following output: ${resultText}`;
5628
+ } else {
5629
+ return `The field "${fieldTitle}" was processed. The field contents were transformed into the following output: ${resultText}`;
5630
+ }
5631
+ }
5632
+
5442
5633
  // dsp/jsonschema.ts
5443
5634
  var validateJSONSchema = (schema) => {
5444
5635
  const errors = [];
@@ -5656,6 +5847,8 @@ var AxGen = class extends AxProgramWithSignature {
5656
5847
  options;
5657
5848
  functions;
5658
5849
  functionsExecuted = /* @__PURE__ */ new Set();
5850
+ fieldProcessors = [];
5851
+ streamingFieldProcessors = [];
5659
5852
  constructor(signature, options) {
5660
5853
  super(signature, { description: options?.description });
5661
5854
  this.options = options;
@@ -5676,6 +5869,24 @@ var AxGen = class extends AxProgramWithSignature {
5676
5869
  addStreamingAssert = (fieldName, fn, message) => {
5677
5870
  this.streamingAsserts.push({ fieldName, fn, message });
5678
5871
  };
5872
+ addFieldProcessor = (fieldName, fn, streaming = false) => {
5873
+ const field = this.signature.getOutputFields().find((f) => f.name === fieldName);
5874
+ if (!field) {
5875
+ throw new Error(`addFieldProcessor: field ${fieldName} not found`);
5876
+ }
5877
+ if (streaming) {
5878
+ const ft = field.type?.name;
5879
+ const isText = !ft || ft === "string" || ft === "code";
5880
+ if (!isText) {
5881
+ throw new Error(
5882
+ `addFieldProcessor: field ${fieldName} is must be a text field`
5883
+ );
5884
+ }
5885
+ this.streamingFieldProcessors.push({ field, process: fn });
5886
+ } else {
5887
+ this.fieldProcessors.push({ field, process: fn });
5888
+ }
5889
+ };
5679
5890
  async forwardSendRequest({
5680
5891
  ai,
5681
5892
  mem,
@@ -5708,7 +5919,8 @@ var AxGen = class extends AxProgramWithSignature {
5708
5919
  sessionId,
5709
5920
  traceId,
5710
5921
  rateLimiter,
5711
- stream
5922
+ stream,
5923
+ debug: false
5712
5924
  }
5713
5925
  );
5714
5926
  return res;
@@ -5718,7 +5930,8 @@ var AxGen = class extends AxProgramWithSignature {
5718
5930
  mem,
5719
5931
  options
5720
5932
  }) {
5721
- const { sessionId, traceId, model, functions, earlyFail } = options ?? {};
5933
+ const { sessionId, traceId, model, functions } = options ?? {};
5934
+ const fastFail = options?.fastFail ?? this.options?.fastFail;
5722
5935
  const usageInfo = {
5723
5936
  ai: ai.getName(),
5724
5937
  model: ai.getModelInfo().name
@@ -5738,7 +5951,7 @@ var AxGen = class extends AxProgramWithSignature {
5738
5951
  traceId,
5739
5952
  sessionId,
5740
5953
  functions,
5741
- earlyFail
5954
+ fastFail
5742
5955
  });
5743
5956
  } else {
5744
5957
  yield await this.processResponse({
@@ -5762,9 +5975,9 @@ var AxGen = class extends AxProgramWithSignature {
5762
5975
  sessionId,
5763
5976
  traceId,
5764
5977
  functions,
5765
- earlyFail
5978
+ fastFail
5766
5979
  }) {
5767
- const streamingValidation = earlyFail ?? ai.getFeatures().functionCot !== true;
5980
+ const streamingValidation = fastFail ?? ai.getFeatures().functionCot !== true;
5768
5981
  const functionCalls = [];
5769
5982
  const values = {};
5770
5983
  const xstate = {
@@ -5783,12 +5996,20 @@ var AxGen = class extends AxProgramWithSignature {
5783
5996
  if (result.functionCalls) {
5784
5997
  mergeFunctionCalls(functionCalls, result.functionCalls);
5785
5998
  mem.updateResult(
5786
- { name: result.name, content, functionCalls },
5999
+ {
6000
+ name: result.name,
6001
+ content,
6002
+ functionCalls,
6003
+ delta: result.functionCalls?.[0]?.function?.params
6004
+ },
5787
6005
  sessionId
5788
6006
  );
5789
6007
  } else if (result.content) {
5790
6008
  content += result.content;
5791
- mem.updateResult({ name: result.name, content }, sessionId);
6009
+ mem.updateResult(
6010
+ { name: result.name, content, delta: result.content },
6011
+ sessionId
6012
+ );
5792
6013
  const skip = streamingExtractValues(
5793
6014
  this.signature,
5794
6015
  values,
@@ -5799,15 +6020,20 @@ var AxGen = class extends AxProgramWithSignature {
5799
6020
  if (skip) {
5800
6021
  continue;
5801
6022
  }
5802
- assertStreamingAssertions(
5803
- this.streamingAsserts,
5804
- values,
5805
- xstate,
5806
- content,
5807
- false
5808
- );
6023
+ assertStreamingAssertions(this.streamingAsserts, xstate, content);
5809
6024
  assertAssertions(this.asserts, values);
5810
- yield* streamValues(this.signature, values, xstate, content);
6025
+ if (this.streamingFieldProcessors.length !== 0) {
6026
+ await processStreamingFieldProcessors(
6027
+ this.streamingFieldProcessors,
6028
+ content,
6029
+ xstate,
6030
+ mem,
6031
+ values,
6032
+ sessionId
6033
+ );
6034
+ }
6035
+ const delta = getStreamingDelta(content, xstate);
6036
+ yield* streamValues(this.signature, values, xstate, delta);
5811
6037
  }
5812
6038
  if (result.finishReason === "length") {
5813
6039
  throw new Error("Max tokens reached before completion");
@@ -5829,15 +6055,29 @@ var AxGen = class extends AxProgramWithSignature {
5829
6055
  this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
5830
6056
  } else {
5831
6057
  streamingExtractFinalValue(this.signature, values, xstate, content);
5832
- assertStreamingAssertions(
5833
- this.streamingAsserts,
5834
- values,
5835
- xstate,
5836
- content,
5837
- true
5838
- );
6058
+ assertStreamingAssertions(this.streamingAsserts, xstate, content, true);
5839
6059
  assertAssertions(this.asserts, values);
5840
- yield* streamValues(this.signature, values, xstate, content, true);
6060
+ if (this.fieldProcessors.length) {
6061
+ await processFieldProcessors(
6062
+ this.fieldProcessors,
6063
+ values,
6064
+ mem,
6065
+ sessionId
6066
+ );
6067
+ }
6068
+ if (this.streamingFieldProcessors.length !== 0) {
6069
+ await processStreamingFieldProcessors(
6070
+ this.streamingFieldProcessors,
6071
+ content,
6072
+ xstate,
6073
+ mem,
6074
+ values,
6075
+ sessionId,
6076
+ true
6077
+ );
6078
+ }
6079
+ const delta = getStreamingDelta(content, xstate);
6080
+ yield* streamValues(this.signature, values, xstate, delta);
5841
6081
  }
5842
6082
  }
5843
6083
  async processResponse({
@@ -5878,6 +6118,14 @@ var AxGen = class extends AxProgramWithSignature {
5878
6118
  } else if (result.content) {
5879
6119
  extractValues(this.signature, values, result.content);
5880
6120
  assertAssertions(this.asserts, values);
6121
+ if (this.fieldProcessors.length) {
6122
+ await processFieldProcessors(
6123
+ this.fieldProcessors,
6124
+ values,
6125
+ mem,
6126
+ sessionId
6127
+ );
6128
+ }
5881
6129
  }
5882
6130
  if (result.finishReason === "length") {
5883
6131
  throw new Error("Max tokens reached before completion");
@@ -5889,7 +6137,8 @@ var AxGen = class extends AxProgramWithSignature {
5889
6137
  const stopFunction = (options?.stopFunction ?? this.options?.stopFunction)?.toLowerCase();
5890
6138
  const maxRetries = options.maxRetries ?? this.options?.maxRetries ?? 10;
5891
6139
  const maxSteps = options.maxSteps ?? this.options?.maxSteps ?? 10;
5892
- const mem = options.mem ?? this.options?.mem ?? new AxMemory();
6140
+ const debug = options.debug ?? ai.getOptions().debug;
6141
+ const mem = options.mem ?? this.options?.mem ?? new AxMemory(1e4, debug);
5893
6142
  let err;
5894
6143
  if (options?.functions && options.functions.length > 0) {
5895
6144
  const promptTemplate = this.options?.promptTemplate ?? AxPromptTemplate;
@@ -5920,6 +6169,9 @@ var AxGen = class extends AxProgramWithSignature {
5920
6169
  if (shouldContinue) {
5921
6170
  continue multiStepLoop;
5922
6171
  }
6172
+ if (debug) {
6173
+ process.stdout.write("\n");
6174
+ }
5923
6175
  return;
5924
6176
  } catch (e) {
5925
6177
  let errorFields;
@@ -5952,10 +6204,12 @@ var AxGen = class extends AxProgramWithSignature {
5952
6204
  }
5953
6205
  shouldContinueSteps(lastMemItem, stopFunction) {
5954
6206
  const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
5955
- if (lastMemItem?.role === "function" && stopFunction && stopFunctionExecuted) {
6207
+ const isFunction = lastMemItem?.chat?.role === "function";
6208
+ const isProcessor = lastMemItem?.tags ? lastMemItem.tags.some((tag) => tag === "processor") : false;
6209
+ if (isFunction && stopFunction && stopFunctionExecuted) {
5956
6210
  return false;
5957
6211
  }
5958
- if (lastMemItem?.role === "function") {
6212
+ if (isFunction || isProcessor) {
5959
6213
  return true;
5960
6214
  }
5961
6215
  return false;
@@ -6035,17 +6289,18 @@ function processChildAgentFunction(childFunction, parentValues, parentInputKeys,
6035
6289
  injectionKeys
6036
6290
  );
6037
6291
  const originalFunc = processedFunction.func;
6038
- processedFunction.func = (childArgs, funcOptions) => {
6292
+ processedFunction.func = async (childArgs, funcOptions) => {
6039
6293
  const updatedChildArgs = {
6040
6294
  ...childArgs,
6041
6295
  ...pick(parentValues, injectionKeys)
6042
6296
  };
6043
6297
  if (options.debug && injectionKeys.length > 0) {
6044
6298
  process.stdout.write(
6045
- `Function Params: ${JSON.stringify(updatedChildArgs, null, 2)}`
6299
+ `
6300
+ Function Params: ${JSON.stringify(updatedChildArgs, null, 2)}`
6046
6301
  );
6047
6302
  }
6048
- return originalFunc(updatedChildArgs, funcOptions);
6303
+ return await originalFunc(updatedChildArgs, funcOptions);
6049
6304
  };
6050
6305
  }
6051
6306
  return processedFunction;
@@ -6071,6 +6326,7 @@ var AxAgent = class {
6071
6326
  agents;
6072
6327
  disableSmartModelRouting;
6073
6328
  excludeFieldsFromPassthrough;
6329
+ debug;
6074
6330
  name;
6075
6331
  // private subAgentList?: string
6076
6332
  func;
@@ -6083,12 +6339,13 @@ var AxAgent = class {
6083
6339
  agents,
6084
6340
  functions
6085
6341
  }, options) {
6086
- const { disableSmartModelRouting, excludeFieldsFromPassthrough } = options ?? {};
6342
+ const { disableSmartModelRouting, excludeFieldsFromPassthrough, debug } = options ?? {};
6087
6343
  this.ai = ai;
6088
6344
  this.agents = agents;
6089
6345
  this.functions = functions;
6090
6346
  this.disableSmartModelRouting = disableSmartModelRouting;
6091
6347
  this.excludeFieldsFromPassthrough = excludeFieldsFromPassthrough ?? [];
6348
+ this.debug = debug;
6092
6349
  if (!name || name.length < 5) {
6093
6350
  throw new Error(
6094
6351
  `Agent name must be at least 10 characters (more descriptive)`
@@ -6148,10 +6405,21 @@ var AxAgent = class {
6148
6405
  if (!ai) {
6149
6406
  throw new Error("AI service is required to run the agent");
6150
6407
  }
6408
+ const debug = this.getDebug(ai, options);
6409
+ if (debug) {
6410
+ process.stdout.write(`
6411
+ --- Agent Engaged: ${this.name} ---
6412
+ `);
6413
+ }
6151
6414
  const ret = await boundFunc(ai, values, {
6152
6415
  ...options,
6153
6416
  model
6154
6417
  });
6418
+ if (debug) {
6419
+ process.stdout.write(`
6420
+ --- Agent Done: ${this.name} ---
6421
+ `);
6422
+ }
6155
6423
  const sig = this.program.getSignature();
6156
6424
  const outFields = sig.getOutputFields();
6157
6425
  const result = Object.keys(ret).map((k) => {
@@ -6182,10 +6450,11 @@ var AxAgent = class {
6182
6450
  const mm = ai?.getModelList();
6183
6451
  const parentSchema = this.program.getSignature().getInputFields();
6184
6452
  const parentKeys = parentSchema.map((p) => p.name);
6453
+ const debug = this.getDebug(ai, options);
6185
6454
  const agentFuncs = this.agents?.map((agent) => {
6186
6455
  const f = agent.getFeatures();
6187
6456
  const processOptions = {
6188
- debug: ai?.getOptions()?.debug ?? false,
6457
+ debug,
6189
6458
  disableSmartModelRouting: !!this.disableSmartModelRouting,
6190
6459
  excludeFieldsFromPassthrough: f.excludeFieldsFromPassthrough,
6191
6460
  canConfigureSmartModelRouting: f.canConfigureSmartModelRouting
@@ -6202,16 +6471,21 @@ var AxAgent = class {
6202
6471
  ...options?.functions ?? this.functions ?? [],
6203
6472
  ...agentFuncs ?? []
6204
6473
  ];
6205
- return { ai, functions };
6474
+ return { ai, functions, debug };
6206
6475
  }
6207
6476
  async forward(parentAi, values, options) {
6208
- const { ai, functions } = this.init(parentAi, values, options);
6209
- return await this.program.forward(ai, values, { ...options, functions });
6477
+ const { ai, functions, debug } = this.init(parentAi, values, options);
6478
+ return await this.program.forward(ai, values, {
6479
+ ...options,
6480
+ debug,
6481
+ functions
6482
+ });
6210
6483
  }
6211
6484
  async *streamingForward(parentAi, values, options) {
6212
- const { ai, functions } = this.init(parentAi, values, options);
6485
+ const { ai, functions, debug } = this.init(parentAi, values, options);
6213
6486
  return yield* this.program.streamingForward(ai, values, {
6214
6487
  ...options,
6488
+ debug,
6215
6489
  functions
6216
6490
  });
6217
6491
  }
@@ -6235,6 +6509,9 @@ var AxAgent = class {
6235
6509
  }
6236
6510
  this.program.getSignature().setDescription(definition);
6237
6511
  }
6512
+ getDebug(ai, options) {
6513
+ return options?.debug ?? this.debug ?? ai?.getOptions()?.debug ?? false;
6514
+ }
6238
6515
  };
6239
6516
  function toCamelCase(inputString) {
6240
6517
  const words = inputString.split(/[^a-zA-Z0-9]/);