@ax-llm/ax 12.0.8 → 12.0.9

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
@@ -161,6 +161,10 @@ __export(index_exports, {
161
161
  axAITogetherDefaultConfig: () => axAITogetherDefaultConfig,
162
162
  axBaseAIDefaultConfig: () => axBaseAIDefaultConfig,
163
163
  axBaseAIDefaultCreativeConfig: () => axBaseAIDefaultCreativeConfig,
164
+ axCreateDefaultLogger: () => axCreateDefaultLogger,
165
+ axCreateDefaultTextLogger: () => axCreateDefaultTextLogger,
166
+ axCreateOptimizerLogger: () => axCreateOptimizerLogger,
167
+ axDefaultOptimizerLogger: () => axDefaultOptimizerLogger,
164
168
  axGlobals: () => axGlobals,
165
169
  axModelInfoAnthropic: () => axModelInfoAnthropic,
166
170
  axModelInfoCohere: () => axModelInfoCohere,
@@ -496,6 +500,17 @@ var AxAIServiceAuthenticationError = class extends AxAIServiceError {
496
500
  this.name = this.constructor.name;
497
501
  }
498
502
  };
503
+ async function safeReadResponseBody(response) {
504
+ try {
505
+ if (response.headers.get("content-type")?.includes("application/json")) {
506
+ return await response.json();
507
+ }
508
+ const clonedResponse = response.clone();
509
+ return await clonedResponse.text();
510
+ } catch (e) {
511
+ return `[ReadableStream - read failed: ${e.message}]`;
512
+ }
513
+ }
499
514
  function calculateRetryDelay(attempt, config) {
500
515
  const delay = Math.min(
501
516
  config.maxDelayMs,
@@ -589,9 +604,15 @@ var apiCall = async (api, json) => {
589
604
  });
590
605
  clearTimeout(timeoutId);
591
606
  if (res.status === 401 || res.status === 403) {
592
- throw new AxAIServiceAuthenticationError(apiUrl.href, json, res.body, {
593
- metrics
594
- });
607
+ const responseBody = await safeReadResponseBody(res);
608
+ throw new AxAIServiceAuthenticationError(
609
+ apiUrl.href,
610
+ json,
611
+ responseBody,
612
+ {
613
+ metrics
614
+ }
615
+ );
595
616
  }
596
617
  if (res.status >= 400 && shouldRetry(new Error(), res.status, attempt, retryConfig)) {
597
618
  const delay = calculateRetryDelay(attempt, retryConfig);
@@ -609,12 +630,13 @@ var apiCall = async (api, json) => {
609
630
  continue;
610
631
  }
611
632
  if (res.status >= 400) {
633
+ const responseBody = await safeReadResponseBody(res);
612
634
  throw new AxAIServiceStatusError(
613
635
  res.status,
614
636
  res.statusText,
615
637
  apiUrl.href,
616
638
  json,
617
- res.body,
639
+ responseBody,
618
640
  { metrics }
619
641
  );
620
642
  }
@@ -712,7 +734,7 @@ var apiCall = async (api, json) => {
712
734
  error,
713
735
  apiUrl.href,
714
736
  json,
715
- res.body,
737
+ "[ReadableStream - consumed during streaming]",
716
738
  {
717
739
  streamMetrics
718
740
  }
@@ -841,12 +863,12 @@ var ColorLog = class {
841
863
  }
842
864
  };
843
865
 
844
- // ai/debug.ts
866
+ // dsp/loggers.ts
845
867
  var colorLog = new ColorLog();
846
868
  var defaultOutput = (message) => {
847
869
  process.stdout.write(message);
848
870
  };
849
- var createDefaultLogger = (output = defaultOutput) => {
871
+ var axCreateDefaultLogger = (output = defaultOutput) => {
850
872
  return (message, options) => {
851
873
  const tags = options?.tags ?? [];
852
874
  let formattedMessage = message;
@@ -855,11 +877,18 @@ var createDefaultLogger = (output = defaultOutput) => {
855
877
  } else if (tags.includes("success") || tags.includes("responseContent")) {
856
878
  formattedMessage = colorLog.greenBright(formattedMessage);
857
879
  } else if (tags.includes("functionName")) {
858
- formattedMessage = colorLog.whiteBright(formattedMessage);
859
- } else if (tags.includes("functionArg") || tags.includes("systemContent") || tags.includes("assistantContent")) {
880
+ if (tags.includes("firstFunction")) {
881
+ formattedMessage = `
882
+ ${colorLog.whiteBright(formattedMessage)}`;
883
+ } else {
884
+ formattedMessage = `${colorLog.whiteBright(formattedMessage)}`;
885
+ }
886
+ } else if (tags.includes("systemContent") || tags.includes("assistantContent")) {
860
887
  formattedMessage = colorLog.blueBright(formattedMessage);
861
888
  } else if (tags.includes("warning") || tags.includes("discovery")) {
862
889
  formattedMessage = colorLog.yellow(formattedMessage);
890
+ } else if (tags.includes("functionArg")) {
891
+ formattedMessage = "";
863
892
  }
864
893
  if (tags.includes("responseStart") || tags.includes("systemStart") || tags.includes("userStart")) {
865
894
  formattedMessage = `
@@ -874,6 +903,31 @@ ${formattedMessage}
874
903
  } else if (tags.includes("error")) {
875
904
  formattedMessage = `
876
905
  ${formattedMessage}
906
+ `;
907
+ } else if (tags.includes("functionEnd")) {
908
+ formattedMessage = `
909
+ `;
910
+ }
911
+ output(formattedMessage);
912
+ };
913
+ };
914
+ var axCreateDefaultTextLogger = (output = defaultOutput) => {
915
+ return (message, options) => {
916
+ const tags = options?.tags ?? [];
917
+ let formattedMessage = message;
918
+ if (tags.includes("responseStart") || tags.includes("systemStart") || tags.includes("userStart")) {
919
+ formattedMessage = `
920
+ ${formattedMessage}`;
921
+ } else if (tags.includes("responseEnd") || tags.includes("systemEnd") || tags.includes("userEnd")) {
922
+ formattedMessage = `${formattedMessage}
923
+ `;
924
+ } else if (tags.includes("assistantStart")) {
925
+ formattedMessage = `
926
+ ${formattedMessage}
927
+ `;
928
+ } else if (tags.includes("error")) {
929
+ formattedMessage = `
930
+ ${formattedMessage}
877
931
  `;
878
932
  } else if (tags.includes("functionEnd")) {
879
933
  formattedMessage = `${formattedMessage}
@@ -882,7 +936,137 @@ ${formattedMessage}
882
936
  output(formattedMessage);
883
937
  };
884
938
  };
885
- var defaultLogger = createDefaultLogger();
939
+ var axCreateOptimizerLogger = (output = (msg) => process.stdout.write(msg)) => {
940
+ const baseLogger = axCreateDefaultLogger(output);
941
+ let isFirstPhase = true;
942
+ return (message, options) => {
943
+ const tags = options?.tags ?? [];
944
+ let formattedMessage = message;
945
+ if (tags.includes("optimizer")) {
946
+ if (tags.includes("start")) {
947
+ const trialsMatch = message.match(/with (\d+) trials?/) || message.match(/(\d+) trials?/);
948
+ const optimizerMatch = message.match(
949
+ /(MIPROv2|BootstrapFewshot|[A-Z][a-zA-Z]+)/
950
+ );
951
+ const optimizerName = optimizerMatch ? optimizerMatch[1] : "Optimizer";
952
+ if (trialsMatch && trialsMatch[1]) {
953
+ formattedMessage = `
954
+ \u250C\u2500 ${optimizerName} optimization (${trialsMatch[1]} trials)
955
+ `;
956
+ } else {
957
+ formattedMessage = `
958
+ \u250C\u2500 ${optimizerName} optimization
959
+ `;
960
+ }
961
+ isFirstPhase = true;
962
+ } else if (tags.includes("config")) {
963
+ if (message.includes("examples") && message.includes("training")) {
964
+ const match = message.match(
965
+ /(\d+) examples for training and (\d+) for validation/
966
+ ) || message.match(/(\d+) training.*?(\d+) validation/);
967
+ if (match && match[1] && match[2]) {
968
+ formattedMessage = `\u2502 Dataset: ${match[1]} training, ${match[2]} validation
969
+ `;
970
+ } else {
971
+ const simpleMatch = message.match(/(\d+) examples/);
972
+ if (simpleMatch && simpleMatch[1]) {
973
+ formattedMessage = `\u2502 Dataset: ${simpleMatch[1]} examples
974
+ `;
975
+ }
976
+ }
977
+ } else if (message.includes("teacher")) {
978
+ formattedMessage = `\u2502 Using teacher model
979
+ `;
980
+ } else {
981
+ formattedMessage = `\u2502 ${message}
982
+ `;
983
+ }
984
+ } else if (tags.includes("phase")) {
985
+ if (isFirstPhase) {
986
+ formattedMessage = `\u251C\u2500 ${message}
987
+ `;
988
+ isFirstPhase = false;
989
+ } else {
990
+ formattedMessage = `\u251C\u2500 ${message}
991
+ `;
992
+ }
993
+ } else if (tags.includes("result")) {
994
+ if (message.includes("Generated") || message.includes("Selected")) {
995
+ const match = message.match(/(\d+)/);
996
+ if (match && match[1]) {
997
+ formattedMessage = `\u2502 \u2713 ${message}
998
+ `;
999
+ } else {
1000
+ formattedMessage = `\u2502 \u2713 ${message}
1001
+ `;
1002
+ }
1003
+ } else if (message.includes("configuration")) {
1004
+ formattedMessage = `\u2502 Applied best configuration
1005
+ `;
1006
+ } else {
1007
+ formattedMessage = `\u2502 ${message}
1008
+ `;
1009
+ }
1010
+ } else if (tags.includes("progress")) {
1011
+ formattedMessage = `\u2502 ${message}
1012
+ `;
1013
+ } else if (tags.includes("complete")) {
1014
+ const scoreMatch = message.match(/(score|performance):\s*([\d.]+)/);
1015
+ if (scoreMatch && scoreMatch[2]) {
1016
+ const score = parseFloat(scoreMatch[2]);
1017
+ const percentage = score <= 1 ? (score * 100).toFixed(1) + "%" : score.toFixed(3);
1018
+ formattedMessage = `\u251C\u2500 Complete! Best: ${percentage}
1019
+ `;
1020
+ } else if (message.includes("Bootstrap")) {
1021
+ formattedMessage = `\u251C\u2500 ${message}
1022
+ `;
1023
+ } else {
1024
+ formattedMessage = `\u251C\u2500 Optimization complete
1025
+ `;
1026
+ }
1027
+ } else if (tags.includes("checkpoint")) {
1028
+ if (message.includes("Resuming")) {
1029
+ formattedMessage = `\u2502 ${message}
1030
+ `;
1031
+ } else {
1032
+ const match = message.match(/checkpoint:\s*(.+)/) || message.match(/Saved\s+(.+)/);
1033
+ if (match && match[1]) {
1034
+ formattedMessage = `\u2514\u2500 Saved: ${match[1]}
1035
+ `;
1036
+ } else {
1037
+ formattedMessage = `\u2514\u2500 Checkpoint saved
1038
+ `;
1039
+ }
1040
+ }
1041
+ }
1042
+ } else if (tags.includes("discovery")) {
1043
+ if (message.includes("Found") && message.includes("examples")) {
1044
+ const match = message.match(/Found (\d+)/);
1045
+ if (match && match[1]) {
1046
+ formattedMessage = `\u2502 Found ${match[1]} examples
1047
+ `;
1048
+ }
1049
+ }
1050
+ }
1051
+ if (tags.includes("error")) {
1052
+ formattedMessage = `
1053
+ \u2717 ${message}
1054
+ `;
1055
+ } else if (tags.includes("warning")) {
1056
+ formattedMessage = `
1057
+ \u26A0 ${message}
1058
+ `;
1059
+ } else if (tags.includes("success") && !tags.includes("optimizer")) {
1060
+ formattedMessage = `\u2713 ${message}
1061
+ `;
1062
+ }
1063
+ baseLogger(formattedMessage, options);
1064
+ };
1065
+ };
1066
+ var axDefaultOptimizerLogger = axCreateOptimizerLogger();
1067
+
1068
+ // ai/debug.ts
1069
+ var defaultLogger = axCreateDefaultLogger();
886
1070
  var formatChatMessage = (msg, hideContent, hideSystemPrompt) => {
887
1071
  switch (msg.role) {
888
1072
  case "system":
@@ -959,9 +1143,14 @@ var logResponseResult = (r, logger = defaultLogger) => {
959
1143
  if (r.functionCalls && r.functionCalls.length > 0) {
960
1144
  for (const [i, f2] of r.functionCalls.entries()) {
961
1145
  if (f2.function.name) {
962
- logger(`[${i + 1}] ${f2.function.name}`, {
963
- tags: ["functionName"]
964
- });
1146
+ const tags = ["functionName"];
1147
+ if (i === 0) {
1148
+ tags.push("firstFunction");
1149
+ }
1150
+ if (r.functionCalls.length > 1) {
1151
+ tags.push("multipleFunctions");
1152
+ }
1153
+ logger(`[${i + 1}] ${f2.function.name}`, { tags });
965
1154
  }
966
1155
  if (f2.function.params) {
967
1156
  const params = typeof f2.function.params === "string" ? f2.function.params : JSON.stringify(f2.function.params, null, 2);
@@ -1632,6 +1821,16 @@ function validateAxMessageArray(values) {
1632
1821
  function validateChatPrompt(chatPrompt) {
1633
1822
  for (let i = 0; i < chatPrompt.length; i++) {
1634
1823
  const message = chatPrompt[i];
1824
+ if (message && "functionCalls" in message && Array.isArray(message.functionCalls) && message.functionCalls.length === 0) {
1825
+ throw new Error(
1826
+ `Chat prompt validation failed: Message at index ${i} has empty functionCalls`
1827
+ );
1828
+ }
1829
+ if (message && "content" in message && Array.isArray(message.content) && message.content.length === 0) {
1830
+ throw new Error(
1831
+ `Chat prompt validation failed: Message at index ${i} has empty content`
1832
+ );
1833
+ }
1635
1834
  if (message && "content" in message && typeof message.content === "string" && message.content.trim() === "") {
1636
1835
  throw new Error(
1637
1836
  `Chat prompt validation failed: Message at index ${i} has empty content`
@@ -5955,9 +6154,11 @@ var updateProgressBar = (current, total, success, elapsedTime, msg, progressBarW
5955
6154
  const emptyBarLength = progressBarWidth - filledBarLength;
5956
6155
  const filledBar = colorLog3.blueBright("\u2588".repeat(filledBarLength));
5957
6156
  const emptyBar = " ".repeat(emptyBarLength);
5958
- const itemsPerSecond = elapsedTime > 0 ? (current / elapsedTime).toFixed(2) : "0.00";
6157
+ const successRate = total > 0 ? (success / total * 100).toFixed(1) : "0.0";
6158
+ const friendlyMsg = msg.includes("Running MIPROv2 optimization") ? "Testing prompt variations" : msg.includes("Tuning Prompt") ? "Generating training examples" : msg;
5959
6159
  process.stdout.write(
5960
- `\r${msg}: ${current} / ${total} (${colorLog3.yellow(percentage)}%): 100%|${filledBar}${emptyBar}| Success: ${success}/${total} [${colorLog3.red(elapsedTime.toFixed(2))}, ${itemsPerSecond}it/s]`
6160
+ `\u2502 ${friendlyMsg}: ${current}/${total} (${colorLog3.yellow(percentage)}%) |${filledBar}${emptyBar}| Success rate: ${colorLog3.greenBright(successRate)}%
6161
+ `
5961
6162
  );
5962
6163
  };
5963
6164
  var validateValue = (field, value) => {
@@ -6164,19 +6365,15 @@ function matchesContent(content, prefix, startIndex = 0, prefixCache = globalPre
6164
6365
  if (!prefixCache.get(prefix)) {
6165
6366
  prefixCache.set(prefix, prefixes);
6166
6367
  }
6167
- const contentEnd = content.slice(
6168
- Math.max(startIndex, content.length - prefix.length)
6169
- );
6170
- for (let i = 0; i < prefixes.length - 1; i++) {
6368
+ let longestPartialMatch = -1;
6369
+ for (let i = prefixes.length - 1; i >= 0; i--) {
6171
6370
  const partialPrefix = prefixes[i];
6172
- if (partialPrefix === "\n" || partialPrefix === ":") {
6173
- continue;
6174
- }
6175
- if (partialPrefix && contentEnd.endsWith(partialPrefix)) {
6176
- return -2;
6371
+ if (content.endsWith(partialPrefix)) {
6372
+ longestPartialMatch = i;
6373
+ break;
6177
6374
  }
6178
6375
  }
6179
- return -1;
6376
+ return longestPartialMatch >= 0 ? -2 : -1;
6180
6377
  }
6181
6378
  var formatTime = (ms) => {
6182
6379
  const seconds = Math.floor(ms / 1e3);
@@ -6199,11 +6396,10 @@ var updateDetailedProgress = (roundIndex, current, total, elapsedTime, example,
6199
6396
  process.stdout.write("\r\x1B[K");
6200
6397
  const percentage = (current / total * 100).toFixed(1);
6201
6398
  const formattedTime = formatTime(elapsedTime);
6202
- const itemsPerSecond = elapsedTime > 0 ? (current / elapsedTime * 1e3).toFixed(2) : "0.00";
6203
6399
  const eta = calculateETA(current, total, elapsedTime);
6204
- let output = `Round ${roundIndex + 1}/${configInfo.maxRounds}: ${current}/${total} (${percentage}%) [${formattedTime}, ${itemsPerSecond} it/s, ETA: ${eta}]`;
6400
+ let output = `Training round ${roundIndex + 1}/${configInfo.maxRounds}: ${current}/${total} (${percentage}%) [${formattedTime}, ETA: ${eta}]`;
6205
6401
  const successRate = stats.totalCalls > 0 ? stats.successfulDemos / stats.totalCalls * 100 : 0;
6206
- output += ` | Success: ${stats.successfulDemos}/${stats.totalCalls} (${successRate.toFixed(1)}%)`;
6402
+ output += ` | Success rate: ${successRate.toFixed(1)}% (${stats.successfulDemos}/${stats.totalCalls})`;
6207
6403
  if (configInfo.verboseMode || configInfo.debugMode) {
6208
6404
  if (configInfo.costMonitoring) {
6209
6405
  output += `
@@ -6329,7 +6525,7 @@ ${outputFields}`);
6329
6525
  content: systemContent
6330
6526
  };
6331
6527
  if (Array.isArray(values)) {
6332
- let userMessages = [];
6528
+ let messages = [];
6333
6529
  const history = values;
6334
6530
  for (const [index, message] of history.entries()) {
6335
6531
  let content;
@@ -6349,7 +6545,7 @@ ${outputFields}`);
6349
6545
  );
6350
6546
  }
6351
6547
  if (message.role === "user") {
6352
- userMessages.push({ role: "user", content });
6548
+ messages.push({ role: "user", content });
6353
6549
  continue;
6354
6550
  }
6355
6551
  if (message.role !== "assistant") {
@@ -6360,9 +6556,9 @@ ${outputFields}`);
6360
6556
  "Assistant message cannot contain non-text content like images, files,etc"
6361
6557
  );
6362
6558
  }
6363
- userMessages.push({ role: "assistant", content });
6559
+ messages.push({ role: "assistant", content });
6364
6560
  }
6365
- return [systemPrompt, ...userMessages];
6561
+ return [systemPrompt, ...messages];
6366
6562
  }
6367
6563
  const userContent = this.renderSingleValueUserContent(
6368
6564
  values,
@@ -6815,9 +7011,9 @@ var formatDateWithTimezone = (date) => {
6815
7011
  };
6816
7012
 
6817
7013
  // dsp/extract.ts
6818
- var extractValues = (sig, values, content) => {
7014
+ var extractValues = (sig, values, content, strictMode = false) => {
6819
7015
  const xstate = { extractedFields: [], streamedIndex: {}, s: -1 };
6820
- streamingExtractValues(sig, values, xstate, content);
7016
+ streamingExtractValues(sig, values, xstate, content, strictMode);
6821
7017
  streamingExtractFinalValue(sig, values, xstate, content);
6822
7018
  for (const field of sig.getOutputFields()) {
6823
7019
  if (field.isInternal) {
@@ -6825,10 +7021,9 @@ var extractValues = (sig, values, content) => {
6825
7021
  }
6826
7022
  }
6827
7023
  };
6828
- var checkMissingRequiredFields = (xstate, values, currentIndex) => {
7024
+ var checkMissingRequiredFields = (xstate, values, outputFields) => {
6829
7025
  const missingFields = [];
6830
- for (let i = 0; i < currentIndex; i++) {
6831
- const field = xstate.extractedFields[i];
7026
+ for (const field of outputFields) {
6832
7027
  if (field && !field.isOptional && values[field.name] === void 0) {
6833
7028
  missingFields.push(field);
6834
7029
  }
@@ -6840,23 +7035,34 @@ var checkMissingRequiredFields = (xstate, values, currentIndex) => {
6840
7035
  });
6841
7036
  }
6842
7037
  };
6843
- var streamingExtractValues = (sig, values, xstate, content, streamingValidation = false) => {
7038
+ var streamingExtractValues = (sig, values, xstate, content, strictMode = false) => {
6844
7039
  const fields = sig.getOutputFields();
7040
+ let expectedField;
6845
7041
  for (const [index, field] of fields.entries()) {
7042
+ if (index === xstate.currFieldIndex) {
7043
+ continue;
7044
+ }
6846
7045
  if (field.name in values) {
6847
7046
  continue;
6848
7047
  }
6849
7048
  const isFirst = xstate.extractedFields.length === 0;
6850
7049
  const prefix = (isFirst ? "" : "\n") + field.title + ":";
6851
7050
  let e = matchesContent(content, prefix, xstate.s);
7051
+ let prefixLen = prefix.length;
6852
7052
  switch (e) {
6853
7053
  case -1:
6854
- if (streamingValidation && values.length == 0 && !field.isOptional) {
7054
+ if (!strictMode && fields.length === 1 && xstate.currField === void 0) {
7055
+ prefixLen = 0;
7056
+ e = 0;
7057
+ break;
7058
+ }
7059
+ if (xstate.currField === void 0 && !field.isOptional) {
6855
7060
  throw new ValidationError({
6856
- message: "Required field not found",
7061
+ message: "Expected (Required) field not found",
6857
7062
  fields: [field]
6858
7063
  });
6859
7064
  }
7065
+ expectedField = field.isOptional ? void 0 : field;
6860
7066
  continue;
6861
7067
  // Field is not found, continue to the next field
6862
7068
  case -2:
@@ -6869,7 +7075,12 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
6869
7075
  xstate.inBlock = true;
6870
7076
  return true;
6871
7077
  }
6872
- let prefixLen = prefix.length;
7078
+ if (expectedField && expectedField.name !== field.name) {
7079
+ throw new ValidationError({
7080
+ message: "Expected (Required) field not found",
7081
+ fields: [expectedField]
7082
+ });
7083
+ }
6873
7084
  if (xstate.currField) {
6874
7085
  const val = content.substring(xstate.s, e).trim();
6875
7086
  const parsedValue = validateAndParseFieldValue(xstate.currField, val);
@@ -6882,7 +7093,6 @@ var streamingExtractValues = (sig, values, xstate, content, streamingValidation
6882
7093
  xstate.prevFields = [{ field: xstate.currField, s: xstate.s, e }];
6883
7094
  }
6884
7095
  }
6885
- checkMissingRequiredFields(xstate, values, index);
6886
7096
  xstate.s = e + prefixLen;
6887
7097
  xstate.currField = field;
6888
7098
  xstate.currFieldIndex = index;
@@ -6902,8 +7112,7 @@ var streamingExtractFinalValue = (sig, values, xstate, content) => {
6902
7112
  values[xstate.currField.name] = parsedValue;
6903
7113
  }
6904
7114
  }
6905
- const sigFields = sig.getOutputFields();
6906
- checkMissingRequiredFields(xstate, values, sigFields.length);
7115
+ checkMissingRequiredFields(xstate, values, sig.getOutputFields());
6907
7116
  };
6908
7117
  var convertValueToType = (field, val, required = false) => {
6909
7118
  switch (field.type?.name) {
@@ -9106,7 +9315,7 @@ var AxGen = class extends AxProgramWithSignature {
9106
9315
  traceContext
9107
9316
  }) {
9108
9317
  const { sessionId, traceId, functions: _functions } = options ?? {};
9109
- const fastFail = options?.fastFail ?? this.options?.fastFail;
9318
+ const strictMode = options?.strictMode ?? false;
9110
9319
  const model = options.model;
9111
9320
  const functions = _functions?.map((f2) => "toFunction" in f2 ? f2.toFunction() : f2)?.flat();
9112
9321
  const res = await this.forwardSendRequest({
@@ -9125,7 +9334,7 @@ var AxGen = class extends AxProgramWithSignature {
9125
9334
  traceId,
9126
9335
  sessionId,
9127
9336
  functions,
9128
- fastFail,
9337
+ strictMode,
9129
9338
  span
9130
9339
  });
9131
9340
  this.getLogger(ai, options)?.("", { tags: ["responseEnd"] });
@@ -9138,7 +9347,8 @@ var AxGen = class extends AxProgramWithSignature {
9138
9347
  traceId,
9139
9348
  sessionId,
9140
9349
  functions,
9141
- span
9350
+ span,
9351
+ strictMode
9142
9352
  });
9143
9353
  }
9144
9354
  }
@@ -9150,10 +9360,9 @@ var AxGen = class extends AxProgramWithSignature {
9150
9360
  sessionId,
9151
9361
  traceId,
9152
9362
  functions,
9153
- fastFail,
9363
+ strictMode,
9154
9364
  span
9155
9365
  }) {
9156
- const streamingValidation = fastFail ?? ai.getFeatures(model).functionCot !== true;
9157
9366
  const functionCalls = [];
9158
9367
  this.values = {};
9159
9368
  const xstate = {
@@ -9204,7 +9413,7 @@ var AxGen = class extends AxProgramWithSignature {
9204
9413
  this.values,
9205
9414
  xstate,
9206
9415
  content,
9207
- streamingValidation
9416
+ strictMode
9208
9417
  );
9209
9418
  if (skip) {
9210
9419
  continue;
@@ -9305,7 +9514,8 @@ Content: ${content}`
9305
9514
  sessionId,
9306
9515
  traceId,
9307
9516
  functions,
9308
- span
9517
+ span,
9518
+ strictMode
9309
9519
  }) {
9310
9520
  this.values = {};
9311
9521
  let results = res.results ?? [];
@@ -9339,7 +9549,7 @@ Content: ${content}`
9339
9549
  if (result.thought && result.thought.length > 0) {
9340
9550
  this.values[this.thoughtFieldName] = result.thought;
9341
9551
  }
9342
- extractValues(this.signature, this.values, result.content);
9552
+ extractValues(this.signature, this.values, result.content, strictMode);
9343
9553
  await assertAssertions(this.asserts, this.values);
9344
9554
  if (this.fieldProcessors.length) {
9345
9555
  await processFieldProcessors(
@@ -9511,8 +9721,7 @@ Content: ${result.content}`
9511
9721
  ...options?.thinkingTokenBudget ? { thinking_token_budget: options.thinkingTokenBudget } : {},
9512
9722
  ...options?.showThoughts ? { show_thoughts: options.showThoughts } : {},
9513
9723
  ...options?.maxSteps ? { max_steps: options.maxSteps } : {},
9514
- ...options?.maxRetries ? { max_retries: options.maxRetries } : {},
9515
- ...options?.fastFail ? { fast_fail: options.fastFail } : {}
9724
+ ...options?.maxRetries ? { max_retries: options.maxRetries } : {}
9516
9725
  };
9517
9726
  const traceLabel = options.traceLabel ?? this.options?.traceLabel;
9518
9727
  const spanName = traceLabel ? `${traceLabel} (AxGen)` : "AxGen";
@@ -10277,6 +10486,9 @@ var AxBaseOptimizer = class {
10277
10486
  checkpointLoad;
10278
10487
  checkpointInterval;
10279
10488
  resumeFromCheckpoint;
10489
+ // Logging fields
10490
+ logger;
10491
+ verbose;
10280
10492
  // Checkpoint state
10281
10493
  currentRound = 0;
10282
10494
  scoreHistory = [];
@@ -10300,6 +10512,8 @@ var AxBaseOptimizer = class {
10300
10512
  this.checkpointLoad = args.checkpointLoad;
10301
10513
  this.checkpointInterval = args.checkpointInterval ?? 10;
10302
10514
  this.resumeFromCheckpoint = args.resumeFromCheckpoint;
10515
+ this.logger = args.logger;
10516
+ this.verbose = args.verbose;
10303
10517
  const costTracker = new AxDefaultCostTracker({
10304
10518
  maxTokens: 1e6
10305
10519
  });
@@ -10478,8 +10692,14 @@ var AxBaseOptimizer = class {
10478
10692
  async compilePareto(program, metricFn, options) {
10479
10693
  const startTime = Date.now();
10480
10694
  if (options?.verbose) {
10481
- console.log("Starting Pareto optimization using base implementation");
10482
- console.log("This will run multiple single-objective optimizations");
10695
+ this.getLogger(options)?.(
10696
+ "Starting Pareto optimization using base implementation",
10697
+ { tags: ["discovery"] }
10698
+ );
10699
+ this.getLogger(options)?.(
10700
+ "This will run multiple single-objective optimizations",
10701
+ { tags: ["discovery"] }
10702
+ );
10483
10703
  }
10484
10704
  const solutions = await this.generateWeightedSolutions(
10485
10705
  program,
@@ -10493,13 +10713,22 @@ var AxBaseOptimizer = class {
10493
10713
  );
10494
10714
  const allSolutions = [...solutions, ...constraintSolutions];
10495
10715
  if (options?.verbose) {
10496
- console.log(`Generated ${allSolutions.length} candidate solutions`);
10716
+ this.getLogger(options)?.(
10717
+ `Generated ${allSolutions.length} candidate solutions`,
10718
+ { tags: ["discovery"] }
10719
+ );
10497
10720
  }
10498
10721
  const paretoFront = this.findParetoFrontier(allSolutions);
10499
10722
  const hypervolume = this.calculateHypervolume(paretoFront);
10500
10723
  if (options?.verbose) {
10501
- console.log(`Found ${paretoFront.length} non-dominated solutions`);
10502
- console.log(`Hypervolume: ${hypervolume?.toFixed(4) || "N/A"}`);
10724
+ this.getLogger(options)?.(
10725
+ `Found ${paretoFront.length} non-dominated solutions`,
10726
+ { tags: ["discovery"] }
10727
+ );
10728
+ this.getLogger(options)?.(
10729
+ `Hypervolume: ${hypervolume?.toFixed(4) || "N/A"}`,
10730
+ { tags: ["discovery"] }
10731
+ );
10503
10732
  }
10504
10733
  this.updateResourceUsage(startTime);
10505
10734
  this.stats.convergenceInfo.converged = true;
@@ -10537,13 +10766,19 @@ var AxBaseOptimizer = class {
10537
10766
  });
10538
10767
  const objectives = Object.keys(sampleScores);
10539
10768
  if (options?.verbose) {
10540
- console.log(`Detected objectives: ${objectives.join(", ")}`);
10769
+ this.getLogger(options)?.(
10770
+ `Detected objectives: ${objectives.join(", ")}`,
10771
+ { tags: ["discovery"] }
10772
+ );
10541
10773
  }
10542
10774
  const weightCombinations = this.generateWeightCombinations(objectives);
10543
10775
  for (let i = 0; i < weightCombinations.length; i++) {
10544
10776
  const weights = weightCombinations[i];
10545
10777
  if (options?.verbose) {
10546
- console.log(`Optimizing with weights: ${JSON.stringify(weights)}`);
10778
+ this.getLogger(options)?.(
10779
+ `Optimizing with weights: ${JSON.stringify(weights)}`,
10780
+ { tags: ["discovery"] }
10781
+ );
10547
10782
  }
10548
10783
  const weightedMetric = async ({ prediction, example }) => {
10549
10784
  const scores = await metricFn({ prediction, example });
@@ -10575,9 +10810,9 @@ var AxBaseOptimizer = class {
10575
10810
  });
10576
10811
  } catch (error) {
10577
10812
  if (options?.verbose) {
10578
- console.warn(
10579
- `Failed optimization with weights ${JSON.stringify(weights)}:`,
10580
- error
10813
+ this.getLogger(options)?.(
10814
+ `Failed optimization with weights ${JSON.stringify(weights)}: ${error}`,
10815
+ { tags: ["warning"] }
10581
10816
  );
10582
10817
  }
10583
10818
  continue;
@@ -10602,8 +10837,9 @@ var AxBaseOptimizer = class {
10602
10837
  const objectives = Object.keys(sampleScores);
10603
10838
  for (const primaryObjective of objectives) {
10604
10839
  if (options?.verbose) {
10605
- console.log(
10606
- `Optimizing ${primaryObjective} with constraints on other objectives`
10840
+ this.getLogger(options)?.(
10841
+ `Optimizing ${primaryObjective} with constraints on other objectives`,
10842
+ { tags: ["discovery"] }
10607
10843
  );
10608
10844
  }
10609
10845
  const constraintMetric = async ({ prediction, example }) => {
@@ -10640,9 +10876,9 @@ var AxBaseOptimizer = class {
10640
10876
  });
10641
10877
  } catch (error) {
10642
10878
  if (options?.verbose) {
10643
- console.warn(
10644
- `Failed constraint optimization for ${primaryObjective}:`,
10645
- error
10879
+ this.getLogger(options)?.(
10880
+ `Failed constraint optimization for ${primaryObjective}: ${error}`,
10881
+ { tags: ["warning"] }
10646
10882
  );
10647
10883
  }
10648
10884
  continue;
@@ -10877,6 +11113,39 @@ var AxBaseOptimizer = class {
10877
11113
  );
10878
11114
  }
10879
11115
  }
11116
+ /**
11117
+ * Get the logger function with fallback hierarchy:
11118
+ * 1. Explicit logger passed to optimizer
11119
+ * 2. Logger from student AI service
11120
+ * 3. Default optimizer logger
11121
+ * 4. undefined if verbose is false
11122
+ */
11123
+ getLogger(options) {
11124
+ const isVerbose = this.isLoggingEnabled(options);
11125
+ if (!isVerbose) {
11126
+ return void 0;
11127
+ }
11128
+ if (this.logger) {
11129
+ return this.logger;
11130
+ }
11131
+ try {
11132
+ const aiLogger = this.studentAI.getLogger();
11133
+ if (aiLogger) {
11134
+ return aiLogger;
11135
+ }
11136
+ } catch {
11137
+ }
11138
+ return axDefaultOptimizerLogger;
11139
+ }
11140
+ /**
11141
+ * Check if logging is enabled based on verbose settings
11142
+ */
11143
+ isLoggingEnabled(options) {
11144
+ if (options?.verbose !== void 0) {
11145
+ return options.verbose;
11146
+ }
11147
+ return this.verbose ?? true;
11148
+ }
10880
11149
  };
10881
11150
 
10882
11151
  // db/base.ts
@@ -12459,9 +12728,9 @@ var AxBootstrapFewShot = class extends AxBaseOptimizer {
12459
12728
  this.stats.earlyStopped = true;
12460
12729
  this.stats.earlyStopping.reason = `No improvement for ${this.earlyStoppingPatience} rounds`;
12461
12730
  if (this.verboseMode || this.debugMode) {
12462
- console.log(
12463
- `
12464
- Early stopping triggered after ${roundIndex + 1} rounds. No improvement for ${this.earlyStoppingPatience} rounds.`
12731
+ this.getLogger()?.(
12732
+ `Early stopping after ${roundIndex + 1} rounds (no improvement for ${this.earlyStoppingPatience} rounds)`,
12733
+ { tags: ["optimizer", "warning"] }
12465
12734
  );
12466
12735
  }
12467
12736
  return;
@@ -12472,6 +12741,16 @@ Early stopping triggered after ${roundIndex + 1} rounds. No improvement for ${th
12472
12741
  const maxRounds = options?.maxIterations ?? this.maxRounds;
12473
12742
  this.traces = [];
12474
12743
  this.reset();
12744
+ if (this.verboseMode || this.debugMode) {
12745
+ this.getLogger()?.(
12746
+ `Starting BootstrapFewshot optimization with ${maxRounds} rounds`,
12747
+ { tags: ["optimizer", "start"] }
12748
+ );
12749
+ this.getLogger()?.(
12750
+ `Using ${this.examples.length} examples, max ${this.maxDemos} demos`,
12751
+ { tags: ["optimizer", "config"] }
12752
+ );
12753
+ }
12475
12754
  for (let i = 0; i < maxRounds; i++) {
12476
12755
  await this.compileRound(program, i, metricFn, options);
12477
12756
  if (this.stats.earlyStopped) {
@@ -12488,6 +12767,12 @@ Early stopping triggered after ${roundIndex + 1} rounds. No improvement for ${th
12488
12767
  if (this.traces.length > 0) {
12489
12768
  bestScore = this.stats.successfulDemos / Math.max(1, this.stats.totalCalls);
12490
12769
  }
12770
+ if (this.verboseMode || this.debugMode) {
12771
+ this.getLogger()?.(
12772
+ `Bootstrap complete. Generated ${demos.length} demos with ${bestScore.toFixed(3)} success rate`,
12773
+ { tags: ["optimizer", "complete"] }
12774
+ );
12775
+ }
12491
12776
  return {
12492
12777
  demos,
12493
12778
  stats: this.stats,
@@ -12553,7 +12838,6 @@ var AxMiPRO = class extends AxBaseOptimizer {
12553
12838
  viewDataBatchSize;
12554
12839
  tipAwareProposer;
12555
12840
  fewshotAwareProposer;
12556
- verbose;
12557
12841
  earlyStoppingTrials;
12558
12842
  minImprovementThreshold;
12559
12843
  bayesianOptimization;
@@ -12575,7 +12859,6 @@ var AxMiPRO = class extends AxBaseOptimizer {
12575
12859
  this.viewDataBatchSize = options.viewDataBatchSize ?? 10;
12576
12860
  this.tipAwareProposer = options.tipAwareProposer ?? true;
12577
12861
  this.fewshotAwareProposer = options.fewshotAwareProposer ?? true;
12578
- this.verbose = options.verbose ?? false;
12579
12862
  this.earlyStoppingTrials = options.earlyStoppingTrials ?? 5;
12580
12863
  this.minImprovementThreshold = options.minImprovementThreshold ?? 0.01;
12581
12864
  this.bayesianOptimization = options.bayesianOptimization ?? false;
@@ -12666,8 +12949,10 @@ var AxMiPRO = class extends AxBaseOptimizer {
12666
12949
  * Bootstraps few-shot examples for the program
12667
12950
  */
12668
12951
  async bootstrapFewShotExamples(program, metricFn) {
12669
- if (this.verbose) {
12670
- console.log("Bootstrapping few-shot examples...");
12952
+ if (this.isLoggingEnabled()) {
12953
+ this.getLogger()?.("Bootstrapping few-shot examples...", {
12954
+ tags: ["optimizer", "phase"]
12955
+ });
12671
12956
  }
12672
12957
  const bootstrapper = new AxBootstrapFewShot({
12673
12958
  studentAI: this.studentAI,
@@ -12675,7 +12960,7 @@ var AxMiPRO = class extends AxBaseOptimizer {
12675
12960
  options: {
12676
12961
  maxDemos: this.maxBootstrappedDemos,
12677
12962
  maxRounds: 3,
12678
- verboseMode: this.verbose
12963
+ verboseMode: this.isLoggingEnabled()
12679
12964
  }
12680
12965
  });
12681
12966
  const result = await bootstrapper.compile(program, metricFn, {
@@ -12720,9 +13005,10 @@ var AxMiPRO = class extends AxBaseOptimizer {
12720
13005
  options
12721
13006
  );
12722
13007
  if (checkpoint && checkpoint.optimizerType === "MiPRO") {
12723
- if (this.verbose || options?.verbose) {
12724
- console.log(
12725
- `Resuming from checkpoint at round ${checkpoint.currentRound}`
13008
+ if (this.isLoggingEnabled(options)) {
13009
+ this.getLogger(options)?.(
13010
+ `Resuming from checkpoint at round ${checkpoint.currentRound}`,
13011
+ { tags: ["optimizer", "checkpoint"] }
12726
13012
  );
12727
13013
  }
12728
13014
  this.restoreFromCheckpoint(checkpoint);
@@ -12732,6 +13018,12 @@ var AxMiPRO = class extends AxBaseOptimizer {
12732
13018
  stagnationRounds = checkpoint.stats.convergenceInfo?.stagnationRounds || 0;
12733
13019
  }
12734
13020
  }
13021
+ if (this.isLoggingEnabled(options)) {
13022
+ this.getLogger(options)?.(
13023
+ `Running optimization trials (${this.numTrials} total)`,
13024
+ { tags: ["optimizer", "phase"] }
13025
+ );
13026
+ }
12735
13027
  for (let i = startRound; i < this.numTrials; i++) {
12736
13028
  const config = {
12737
13029
  instruction: instructions[i % instructions.length] || instructions[0] || "",
@@ -12758,6 +13050,12 @@ var AxMiPRO = class extends AxBaseOptimizer {
12758
13050
  bestScore = score;
12759
13051
  bestConfig = config;
12760
13052
  stagnationRounds = 0;
13053
+ if (this.isLoggingEnabled(options)) {
13054
+ this.getLogger(options)?.(
13055
+ `Trial ${i + 1}/${this.numTrials}: New best score ${bestScore.toFixed(3)}`,
13056
+ { tags: ["optimizer", "progress"] }
13057
+ );
13058
+ }
12761
13059
  } else {
12762
13060
  stagnationRounds++;
12763
13061
  }
@@ -12876,38 +13174,53 @@ var AxMiPRO = class extends AxBaseOptimizer {
12876
13174
  this.configureAuto(miproOptions.auto);
12877
13175
  }
12878
13176
  const valset = this.getValidationSet(options) || (miproOptions?.valset ?? this.examples.slice(0, Math.floor(this.examples.length * 0.2)));
12879
- if (this.verbose || options?.verbose) {
12880
- console.log(`Starting MIPROv2 optimization with ${this.numTrials} trials`);
12881
- console.log(
12882
- `Using ${this.examples.length} examples for training and ${valset.length} for validation`
13177
+ if (this.isLoggingEnabled(options)) {
13178
+ this.getLogger(options)?.(
13179
+ `Starting MIPROv2 optimization with ${this.numTrials} trials`,
13180
+ { tags: ["optimizer", "start"] }
13181
+ );
13182
+ this.getLogger(options)?.(
13183
+ `Using ${this.examples.length} examples for training and ${valset.length} for validation`,
13184
+ { tags: ["optimizer", "config"] }
12883
13185
  );
12884
13186
  if (this.teacherAI) {
12885
- console.log("Using separate teacher model for instruction generation");
13187
+ this.getLogger(options)?.(
13188
+ "Using separate teacher model for instruction generation",
13189
+ { tags: ["optimizer", "config"] }
13190
+ );
12886
13191
  }
12887
13192
  }
12888
13193
  let bootstrappedDemos = [];
12889
13194
  if (this.maxBootstrappedDemos > 0) {
12890
13195
  bootstrappedDemos = await this.bootstrapFewShotExamples(program, metricFn);
12891
- if (this.verbose) {
12892
- console.log(
12893
- `Generated ${bootstrappedDemos.length} bootstrapped demonstrations`
13196
+ if (this.isLoggingEnabled(options)) {
13197
+ this.getLogger(options)?.(
13198
+ `Generated ${bootstrappedDemos.length} bootstrapped demonstrations`,
13199
+ { tags: ["optimizer", "result"] }
12894
13200
  );
12895
13201
  }
12896
13202
  }
12897
13203
  let labeledExamples = [];
12898
13204
  if (this.maxLabeledDemos > 0) {
12899
13205
  labeledExamples = this.selectLabeledExamples();
12900
- if (this.verbose) {
12901
- console.log(
12902
- `Selected ${labeledExamples.length} labeled examples from training set`
13206
+ if (this.isLoggingEnabled(options)) {
13207
+ this.getLogger(options)?.(
13208
+ `Selected ${labeledExamples.length} labeled examples from training set`,
13209
+ { tags: ["optimizer", "result"] }
12903
13210
  );
12904
13211
  }
12905
13212
  }
12906
13213
  const instructions = await this.proposeInstructionCandidates(options);
12907
- if (this.verbose) {
12908
- console.log(`Generated ${instructions.length} instruction candidates`);
13214
+ if (this.isLoggingEnabled(options)) {
13215
+ this.getLogger(options)?.(
13216
+ `Generated ${instructions.length} instruction candidates`,
13217
+ { tags: ["optimizer", "result"] }
13218
+ );
12909
13219
  if (this.hasTeacherAI(options)) {
12910
- console.log("Using teacher AI for instruction generation");
13220
+ this.getLogger(options)?.(
13221
+ "Using teacher AI for instruction generation",
13222
+ { tags: ["optimizer", "config"] }
13223
+ );
12911
13224
  }
12912
13225
  }
12913
13226
  const { bestConfig, bestScore } = await this.runOptimization(
@@ -12919,9 +13232,15 @@ var AxMiPRO = class extends AxBaseOptimizer {
12919
13232
  metricFn,
12920
13233
  options
12921
13234
  );
12922
- if (this.verbose || options?.verbose) {
12923
- console.log(`Optimization complete. Best score: ${bestScore}`);
12924
- console.log(`Best configuration: ${JSON.stringify(bestConfig)}`);
13235
+ if (this.isLoggingEnabled(options)) {
13236
+ this.getLogger(options)?.(
13237
+ `Optimization complete. Best score: ${bestScore}`,
13238
+ { tags: ["optimizer", "complete"] }
13239
+ );
13240
+ this.getLogger(options)?.(
13241
+ `Best configuration: ${JSON.stringify(bestConfig)}`,
13242
+ { tags: ["optimizer", "result"] }
13243
+ );
12925
13244
  }
12926
13245
  if (this.checkTargetScore(bestScore)) {
12927
13246
  this.triggerEarlyStopping(
@@ -13048,9 +13367,6 @@ var AxMiPRO = class extends AxBaseOptimizer {
13048
13367
  if (config.minImprovementThreshold !== void 0) {
13049
13368
  this.minImprovementThreshold = config.minImprovementThreshold;
13050
13369
  }
13051
- if (config.verbose !== void 0) {
13052
- this.verbose = config.verbose;
13053
- }
13054
13370
  }
13055
13371
  /**
13056
13372
  * Reset optimizer state for reuse with different programs
@@ -15525,6 +15841,10 @@ var AxRAG = class extends AxChainOfThought {
15525
15841
  axAITogetherDefaultConfig,
15526
15842
  axBaseAIDefaultConfig,
15527
15843
  axBaseAIDefaultCreativeConfig,
15844
+ axCreateDefaultLogger,
15845
+ axCreateDefaultTextLogger,
15846
+ axCreateOptimizerLogger,
15847
+ axDefaultOptimizerLogger,
15528
15848
  axGlobals,
15529
15849
  axModelInfoAnthropic,
15530
15850
  axModelInfoCohere,