@ax-llm/ax 12.0.8 → 12.0.12

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
@@ -92,7 +92,6 @@ __export(index_exports, {
92
92
  AxDBPinecone: () => AxDBPinecone,
93
93
  AxDBWeaviate: () => AxDBWeaviate,
94
94
  AxDefaultCostTracker: () => AxDefaultCostTracker,
95
- AxDefaultQueryRewriter: () => AxDefaultQueryRewriter,
96
95
  AxDefaultResultReranker: () => AxDefaultResultReranker,
97
96
  AxDockerSession: () => AxDockerSession,
98
97
  AxEmbeddingAdapter: () => AxEmbeddingAdapter,
@@ -119,7 +118,6 @@ __export(index_exports, {
119
118
  AxPromptTemplate: () => AxPromptTemplate,
120
119
  AxRAG: () => AxRAG,
121
120
  AxRateLimiterTokenUsage: () => AxRateLimiterTokenUsage,
122
- AxRewriter: () => AxRewriter,
123
121
  AxSignature: () => AxSignature,
124
122
  AxSimpleClassifier: () => AxSimpleClassifier,
125
123
  AxSimpleClassifierClass: () => AxSimpleClassifierClass,
@@ -161,6 +159,10 @@ __export(index_exports, {
161
159
  axAITogetherDefaultConfig: () => axAITogetherDefaultConfig,
162
160
  axBaseAIDefaultConfig: () => axBaseAIDefaultConfig,
163
161
  axBaseAIDefaultCreativeConfig: () => axBaseAIDefaultCreativeConfig,
162
+ axCreateDefaultLogger: () => axCreateDefaultLogger,
163
+ axCreateDefaultTextLogger: () => axCreateDefaultTextLogger,
164
+ axCreateOptimizerLogger: () => axCreateOptimizerLogger,
165
+ axDefaultOptimizerLogger: () => axDefaultOptimizerLogger,
164
166
  axGlobals: () => axGlobals,
165
167
  axModelInfoAnthropic: () => axModelInfoAnthropic,
166
168
  axModelInfoCohere: () => axModelInfoCohere,
@@ -175,6 +177,8 @@ __export(index_exports, {
175
177
  axModelInfoTogether: () => axModelInfoTogether,
176
178
  axSpanAttributes: () => axSpanAttributes,
177
179
  axSpanEvents: () => axSpanEvents,
180
+ axValidateChatRequestMessage: () => axValidateChatRequestMessage,
181
+ axValidateChatResponseResult: () => axValidateChatResponseResult,
178
182
  f: () => f,
179
183
  s: () => s
180
184
  });
@@ -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,12 +877,44 @@ 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 = "";
892
+ }
893
+ if (tags.includes("responseStart") || tags.includes("systemStart") || tags.includes("userStart")) {
894
+ formattedMessage = `
895
+ ${formattedMessage}`;
896
+ } else if (tags.includes("responseEnd") || tags.includes("systemEnd") || tags.includes("userEnd")) {
897
+ formattedMessage = `${formattedMessage}
898
+ `;
899
+ } else if (tags.includes("assistantStart")) {
900
+ formattedMessage = `
901
+ ${formattedMessage}
902
+ `;
903
+ } else if (tags.includes("error")) {
904
+ formattedMessage = `
905
+ ${formattedMessage}
906
+ `;
907
+ } else if (tags.includes("functionEnd")) {
908
+ formattedMessage = `
909
+ `;
863
910
  }
911
+ output(formattedMessage);
912
+ };
913
+ };
914
+ var axCreateDefaultTextLogger = (output = defaultOutput) => {
915
+ return (message, options) => {
916
+ const tags = options?.tags ?? [];
917
+ let formattedMessage = message;
864
918
  if (tags.includes("responseStart") || tags.includes("systemStart") || tags.includes("userStart")) {
865
919
  formattedMessage = `
866
920
  ${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);
@@ -1201,6 +1390,9 @@ var AxBaseAI = class {
1201
1390
  }
1202
1391
  async _chat1(req, options) {
1203
1392
  const model = this.getModel(req.model) ?? req.model ?? this.defaults.model;
1393
+ if (req.chatPrompt && Array.isArray(req.chatPrompt)) {
1394
+ validateAxMessageArray(req.chatPrompt);
1395
+ }
1204
1396
  const modelConfig = {
1205
1397
  ...this.aiImpl.getModelConfig(),
1206
1398
  ...req.modelConfig
@@ -1272,7 +1464,6 @@ var AxBaseAI = class {
1272
1464
  if (chatReq.functions && chatReq.functions.length > 0) {
1273
1465
  functions = chatReq.functions.map((fn2) => this.cleanupFunctionSchema(fn2));
1274
1466
  }
1275
- validateChatPrompt(chatReq.chatPrompt);
1276
1467
  const req = {
1277
1468
  ...chatReq,
1278
1469
  model,
@@ -1323,11 +1514,14 @@ var AxBaseAI = class {
1323
1514
  const res2 = respFn(resp, state);
1324
1515
  res2.sessionId = options?.sessionId;
1325
1516
  if (!res2.modelUsage) {
1326
- res2.modelUsage = {
1327
- ai: this.name,
1328
- model,
1329
- tokens: this.aiImpl.getTokenUsage()
1330
- };
1517
+ const tokenUsage = this.aiImpl.getTokenUsage();
1518
+ if (tokenUsage) {
1519
+ res2.modelUsage = {
1520
+ ai: this.name,
1521
+ model,
1522
+ tokens: tokenUsage
1523
+ };
1524
+ }
1331
1525
  }
1332
1526
  this.modelUsage = res2.modelUsage;
1333
1527
  if (span?.isRecording()) {
@@ -1461,11 +1655,14 @@ var AxBaseAI = class {
1461
1655
  const res = this.aiImpl.createEmbedResp(resValue);
1462
1656
  res.sessionId = options?.sessionId;
1463
1657
  if (!res.modelUsage) {
1464
- res.modelUsage = {
1465
- ai: this.name,
1466
- model: embedModel,
1467
- tokens: this.aiImpl.getTokenUsage()
1468
- };
1658
+ const tokenUsage = this.aiImpl.getTokenUsage();
1659
+ if (tokenUsage) {
1660
+ res.modelUsage = {
1661
+ ai: this.name,
1662
+ model: embedModel,
1663
+ tokens: tokenUsage
1664
+ };
1665
+ }
1469
1666
  }
1470
1667
  this.embedModelUsage = res.modelUsage;
1471
1668
  if (span?.isRecording() && res.modelUsage?.tokens) {
@@ -1629,16 +1826,6 @@ function validateAxMessageArray(values) {
1629
1826
  }
1630
1827
  }
1631
1828
  }
1632
- function validateChatPrompt(chatPrompt) {
1633
- for (let i = 0; i < chatPrompt.length; i++) {
1634
- const message = chatPrompt[i];
1635
- if (message && "content" in message && typeof message.content === "string" && message.content.trim() === "") {
1636
- throw new Error(
1637
- `Chat prompt validation failed: Message at index ${i} has empty content`
1638
- );
1639
- }
1640
- }
1641
- }
1642
1829
  function validateModels(models) {
1643
1830
  const keys = /* @__PURE__ */ new Set();
1644
1831
  for (const model of models) {
@@ -1710,14 +1897,18 @@ var axModelInfoAnthropic = [
1710
1897
  currency: "usd",
1711
1898
  promptTokenCostPer1M: 15,
1712
1899
  completionTokenCostPer1M: 75,
1713
- maxTokens: 32e3
1900
+ maxTokens: 32e3,
1901
+ hasThinkingBudget: true,
1902
+ hasShowThoughts: true
1714
1903
  },
1715
1904
  {
1716
1905
  name: "claude-sonnet-4-20250514" /* Claude4Sonnet */,
1717
1906
  currency: "usd",
1718
1907
  promptTokenCostPer1M: 3,
1719
1908
  completionTokenCostPer1M: 15,
1720
- maxTokens: 64e3
1909
+ maxTokens: 64e3,
1910
+ hasThinkingBudget: true,
1911
+ hasShowThoughts: true
1721
1912
  },
1722
1913
  // 3.7
1723
1914
  {
@@ -1725,7 +1916,9 @@ var axModelInfoAnthropic = [
1725
1916
  currency: "usd",
1726
1917
  promptTokenCostPer1M: 3,
1727
1918
  completionTokenCostPer1M: 15,
1728
- maxTokens: 64e3
1919
+ maxTokens: 64e3,
1920
+ hasThinkingBudget: true,
1921
+ hasShowThoughts: true
1729
1922
  },
1730
1923
  // 3.5
1731
1924
  {
@@ -1781,13 +1974,47 @@ var axModelInfoAnthropic = [
1781
1974
  }
1782
1975
  ];
1783
1976
 
1977
+ // dsp/modelinfo.ts
1978
+ function getModelInfo({
1979
+ model,
1980
+ modelInfo,
1981
+ models
1982
+ }) {
1983
+ const modelEntry = models?.find((v) => v.key === model);
1984
+ const mappedModel = modelEntry && "model" in modelEntry ? modelEntry.model : model;
1985
+ const exactMatch = modelInfo.find((v) => v.name === model);
1986
+ if (exactMatch) return exactMatch;
1987
+ const normalizedName = mappedModel.replace(/^(anthropic\.|openai\.)/, "").replace(/-latest$/, "").replace(/-\d{8}$/, "").replace(/-v\d+:\d+$/, "").replace(/@\d{8}$/, "").replace(/-\d{2,}(-[a-zA-Z0-9-]+)?$/, "").replace(/-v\d+@\d{8}$/, "").replace(/-v\d+$/, "");
1988
+ const normalizedMatch = modelInfo.find((v) => v.name === normalizedName);
1989
+ if (normalizedMatch) return normalizedMatch;
1990
+ return null;
1991
+ }
1992
+
1784
1993
  // ai/anthropic/api.ts
1785
1994
  var axAIAnthropicDefaultConfig = () => structuredClone({
1786
1995
  model: "claude-3-7-sonnet-latest" /* Claude37Sonnet */,
1996
+ maxTokens: 4e4,
1997
+ // Ensure maxTokens is higher than highest thinking budget
1998
+ thinkingTokenBudgetLevels: {
1999
+ minimal: 1024,
2000
+ low: 5e3,
2001
+ medium: 1e4,
2002
+ high: 2e4,
2003
+ highest: 32e3
2004
+ },
1787
2005
  ...axBaseAIDefaultConfig()
1788
2006
  });
1789
2007
  var axAIAnthropicVertexDefaultConfig = () => structuredClone({
1790
2008
  model: "claude-3-7-sonnet" /* Claude37Sonnet */,
2009
+ maxTokens: 4e4,
2010
+ // Ensure maxTokens is higher than highest thinking budget
2011
+ thinkingTokenBudgetLevels: {
2012
+ minimal: 1024,
2013
+ low: 5e3,
2014
+ medium: 1e4,
2015
+ high: 2e4,
2016
+ highest: 32e3
2017
+ },
1791
2018
  ...axBaseAIDefaultConfig()
1792
2019
  });
1793
2020
  var AxAIAnthropicImpl = class {
@@ -1796,6 +2023,7 @@ var AxAIAnthropicImpl = class {
1796
2023
  this.isVertex = isVertex;
1797
2024
  }
1798
2025
  tokensUsed;
2026
+ currentPromptConfig;
1799
2027
  getTokenUsage() {
1800
2028
  return this.tokensUsed;
1801
2029
  }
@@ -1814,7 +2042,8 @@ var AxAIAnthropicImpl = class {
1814
2042
  n: config.n
1815
2043
  };
1816
2044
  }
1817
- createChatReq = (req) => {
2045
+ createChatReq = (req, config) => {
2046
+ this.currentPromptConfig = config;
1818
2047
  const model = req.model;
1819
2048
  const stream = req.modelConfig?.stream ?? this.config.stream;
1820
2049
  let apiConfig;
@@ -1870,17 +2099,67 @@ var AxAIAnthropicImpl = class {
1870
2099
  const temperature = req.modelConfig?.temperature ?? this.config.temperature;
1871
2100
  const topP = req.modelConfig?.topP ?? this.config.topP;
1872
2101
  const topK = req.modelConfig?.topK ?? this.config.topK;
2102
+ const n = req.modelConfig?.n ?? this.config.n;
2103
+ if (n && n > 1) {
2104
+ throw new Error("Anthropic does not support sampling (n > 1)");
2105
+ }
2106
+ let thinkingConfig;
2107
+ if (this.config.thinking?.budget_tokens) {
2108
+ thinkingConfig = this.config.thinking;
2109
+ }
2110
+ if (config?.thinkingTokenBudget) {
2111
+ const levels = this.config.thinkingTokenBudgetLevels;
2112
+ switch (config.thinkingTokenBudget) {
2113
+ case "none":
2114
+ thinkingConfig = void 0;
2115
+ break;
2116
+ case "minimal":
2117
+ thinkingConfig = {
2118
+ type: "enabled",
2119
+ budget_tokens: levels?.minimal ?? 1024
2120
+ };
2121
+ break;
2122
+ case "low":
2123
+ thinkingConfig = {
2124
+ type: "enabled",
2125
+ budget_tokens: levels?.low ?? 5e3
2126
+ };
2127
+ break;
2128
+ case "medium":
2129
+ thinkingConfig = {
2130
+ type: "enabled",
2131
+ budget_tokens: levels?.medium ?? 1e4
2132
+ };
2133
+ break;
2134
+ case "high":
2135
+ thinkingConfig = {
2136
+ type: "enabled",
2137
+ budget_tokens: levels?.high ?? 2e4
2138
+ };
2139
+ break;
2140
+ case "highest":
2141
+ thinkingConfig = {
2142
+ type: "enabled",
2143
+ budget_tokens: levels?.highest ?? 32e3
2144
+ };
2145
+ break;
2146
+ }
2147
+ }
1873
2148
  const reqValue = {
1874
2149
  ...this.isVertex ? { anthropic_version: "vertex-2023-10-16" } : { model },
1875
2150
  ...maxTokens ? { max_tokens: maxTokens } : {},
1876
2151
  ...stopSequences && stopSequences.length > 0 ? { stop_sequences: stopSequences } : {},
1877
- ...temperature ? { temperature } : {},
1878
- ...topP ? { top_p: topP } : {},
1879
- ...topK ? { top_k: topK } : {},
2152
+ // Only include temperature when thinking is not enabled
2153
+ ...temperature && !thinkingConfig ? { temperature } : {},
2154
+ // Only include top_p when thinking is not enabled, or when it's >= 0.95
2155
+ ...topP && (!thinkingConfig || topP >= 0.95) ? { top_p: topP } : {},
2156
+ // Only include top_k when thinking is not enabled
2157
+ ...topK && !thinkingConfig ? { top_k: topK } : {},
1880
2158
  ...toolsChoice,
1881
2159
  ...tools && tools.length > 0 ? { tools } : {},
1882
2160
  ...stream ? { stream: true } : {},
1883
2161
  ...system ? { system } : {},
2162
+ ...thinkingConfig ? { thinking: thinkingConfig } : {},
1884
2163
  messages
1885
2164
  };
1886
2165
  return [apiConfig, reqValue];
@@ -1890,9 +2169,11 @@ var AxAIAnthropicImpl = class {
1890
2169
  throw new Error(`Anthropic Chat API Error: ${resp.error.message}`);
1891
2170
  }
1892
2171
  const finishReason = mapFinishReason(resp.stop_reason);
1893
- const results = resp.content.map((msg) => {
2172
+ const showThoughts = this.currentPromptConfig?.thinkingTokenBudget !== "none" && this.currentPromptConfig?.showThoughts !== false;
2173
+ const results = resp.content.map((msg, index) => {
1894
2174
  if (msg.type === "tool_use") {
1895
2175
  return {
2176
+ index,
1896
2177
  id: msg.id,
1897
2178
  functionCalls: [
1898
2179
  {
@@ -1907,12 +2188,23 @@ var AxAIAnthropicImpl = class {
1907
2188
  finishReason
1908
2189
  };
1909
2190
  }
2191
+ if ((msg.type === "thinking" || msg.type === "redacted_thinking") && showThoughts) {
2192
+ return {
2193
+ index,
2194
+ thought: msg.thinking,
2195
+ id: resp.id,
2196
+ finishReason
2197
+ };
2198
+ }
1910
2199
  return {
2200
+ index,
1911
2201
  content: msg.type === "text" ? msg.text : "",
1912
2202
  id: resp.id,
1913
2203
  finishReason
1914
2204
  };
1915
- });
2205
+ }).filter(
2206
+ (result) => result.content !== "" || result.thought !== void 0 || result.functionCalls !== void 0
2207
+ );
1916
2208
  this.tokensUsed = {
1917
2209
  promptTokens: resp.usage.input_tokens,
1918
2210
  completionTokens: resp.usage.output_tokens,
@@ -1932,9 +2224,10 @@ var AxAIAnthropicImpl = class {
1932
2224
  const { error } = resp;
1933
2225
  throw new Error(error.message);
1934
2226
  }
2227
+ const index = 0;
1935
2228
  if (resp.type === "message_start") {
1936
2229
  const { message } = resp;
1937
- const results = [{ content: "", id: message.id }];
2230
+ const results = [{ index, content: "", id: message.id }];
1938
2231
  this.tokensUsed = {
1939
2232
  promptTokens: message.usage?.input_tokens ?? 0,
1940
2233
  completionTokens: message.usage?.output_tokens ?? 0,
@@ -1946,7 +2239,18 @@ var AxAIAnthropicImpl = class {
1946
2239
  const { content_block: contentBlock } = resp;
1947
2240
  if (contentBlock.type === "text") {
1948
2241
  return {
1949
- results: [{ content: contentBlock.text }]
2242
+ results: [{ index, content: contentBlock.text }]
2243
+ };
2244
+ }
2245
+ if (contentBlock.type === "thinking") {
2246
+ const showThoughts = this.currentPromptConfig?.thinkingTokenBudget !== "none" && this.currentPromptConfig?.showThoughts !== false;
2247
+ if (showThoughts) {
2248
+ return {
2249
+ results: [{ index, thought: contentBlock.thinking }]
2250
+ };
2251
+ }
2252
+ return {
2253
+ results: [{ index, content: "" }]
1950
2254
  };
1951
2255
  }
1952
2256
  if (contentBlock.type === "tool_use") {
@@ -1963,7 +2267,7 @@ var AxAIAnthropicImpl = class {
1963
2267
  }
1964
2268
  ];
1965
2269
  return {
1966
- results: [{ functionCalls }]
2270
+ results: [{ index, functionCalls }]
1967
2271
  };
1968
2272
  }
1969
2273
  }
@@ -1972,7 +2276,23 @@ var AxAIAnthropicImpl = class {
1972
2276
  const { delta } = resp;
1973
2277
  if (delta.type === "text_delta") {
1974
2278
  return {
1975
- results: [{ content: delta.text }]
2279
+ results: [{ index, content: delta.text }]
2280
+ };
2281
+ }
2282
+ if (delta.type === "thinking_delta") {
2283
+ const showThoughts = this.currentPromptConfig?.thinkingTokenBudget !== "none" && this.currentPromptConfig?.showThoughts !== false;
2284
+ if (showThoughts) {
2285
+ return {
2286
+ results: [{ index, thought: delta.thinking }]
2287
+ };
2288
+ }
2289
+ return {
2290
+ results: [{ index, content: "" }]
2291
+ };
2292
+ }
2293
+ if (delta.type === "signature_delta") {
2294
+ return {
2295
+ results: [{ index, content: "" }]
1976
2296
  };
1977
2297
  }
1978
2298
  if (delta.type === "input_json_delta") {
@@ -1991,7 +2311,7 @@ var AxAIAnthropicImpl = class {
1991
2311
  }
1992
2312
  ];
1993
2313
  return {
1994
- results: [{ functionCalls }]
2314
+ results: [{ index, functionCalls }]
1995
2315
  };
1996
2316
  }
1997
2317
  }
@@ -2003,12 +2323,16 @@ var AxAIAnthropicImpl = class {
2003
2323
  totalTokens: usage.output_tokens
2004
2324
  };
2005
2325
  const results = [
2006
- { content: "", finishReason: mapFinishReason(delta.stop_reason) }
2326
+ {
2327
+ index,
2328
+ content: "",
2329
+ finishReason: mapFinishReason(delta.stop_reason)
2330
+ }
2007
2331
  ];
2008
2332
  return { results };
2009
2333
  }
2010
2334
  return {
2011
- results: [{ content: "" }]
2335
+ results: [{ index, content: "" }]
2012
2336
  };
2013
2337
  };
2014
2338
  };
@@ -2050,6 +2374,20 @@ var AxAIAnthropic = class extends AxBaseAI {
2050
2374
  ...config
2051
2375
  };
2052
2376
  const aiImpl = new AxAIAnthropicImpl(_config, isVertex);
2377
+ const supportFor = (model) => {
2378
+ const mi = getModelInfo({
2379
+ model,
2380
+ modelInfo: axModelInfoAnthropic,
2381
+ models
2382
+ });
2383
+ return {
2384
+ functions: true,
2385
+ streaming: true,
2386
+ hasThinkingBudget: mi?.hasThinkingBudget ?? false,
2387
+ hasShowThoughts: mi?.hasShowThoughts ?? false,
2388
+ functionCot: true
2389
+ };
2390
+ };
2053
2391
  super(aiImpl, {
2054
2392
  name: "Anthropic",
2055
2393
  apiURL,
@@ -2057,7 +2395,7 @@ var AxAIAnthropic = class extends AxBaseAI {
2057
2395
  modelInfo: axModelInfoAnthropic,
2058
2396
  defaults: { model: _config.model },
2059
2397
  options,
2060
- supportFor: { functions: true, streaming: true, functionCot: true },
2398
+ supportFor,
2061
2399
  models
2062
2400
  });
2063
2401
  }
@@ -2187,22 +2525,6 @@ function mapFinishReason(stopReason) {
2187
2525
  }
2188
2526
  }
2189
2527
 
2190
- // dsp/modelinfo.ts
2191
- function getModelInfo({
2192
- model,
2193
- modelInfo,
2194
- models
2195
- }) {
2196
- const modelEntry = models?.find((v) => v.key === model);
2197
- const mappedModel = modelEntry && "model" in modelEntry ? modelEntry.model : model;
2198
- const exactMatch = modelInfo.find((v) => v.name === model);
2199
- if (exactMatch) return exactMatch;
2200
- const normalizedName = mappedModel.replace(/^(anthropic\.|openai\.)/, "").replace(/-latest$/, "").replace(/-\d{8}$/, "").replace(/-v\d+:\d+$/, "").replace(/@\d{8}$/, "").replace(/-\d{2,}(-[a-zA-Z0-9-]+)?$/, "").replace(/-v\d+@\d{8}$/, "").replace(/-v\d+$/, "");
2201
- const normalizedMatch = modelInfo.find((v) => v.name === normalizedName);
2202
- if (normalizedMatch) return normalizedMatch;
2203
- return null;
2204
- }
2205
-
2206
2528
  // ai/openai/chat_types.ts
2207
2529
  var AxAIOpenAIModel = /* @__PURE__ */ ((AxAIOpenAIModel2) => {
2208
2530
  AxAIOpenAIModel2["O1"] = "o1";
@@ -2537,6 +2859,7 @@ var AxAIOpenAIImpl = class {
2537
2859
  })
2538
2860
  );
2539
2861
  return {
2862
+ index: choice.index,
2540
2863
  id: `${choice.index}`,
2541
2864
  content: choice.message.content,
2542
2865
  thought: choice.message.reasoning_content,
@@ -2562,6 +2885,7 @@ var AxAIOpenAIImpl = class {
2562
2885
  }
2563
2886
  const results = choices.map(
2564
2887
  ({
2888
+ index,
2565
2889
  delta: {
2566
2890
  content,
2567
2891
  role,
@@ -2571,11 +2895,11 @@ var AxAIOpenAIImpl = class {
2571
2895
  finish_reason: oaiFinishReason
2572
2896
  }) => {
2573
2897
  const finishReason = mapFinishReason2(oaiFinishReason);
2574
- const functionCalls = toolCalls?.map(({ id: _id, index, function: { name, arguments: params } }) => {
2575
- if (typeof _id === "string" && typeof index === "number" && !sstate.indexIdMap[index]) {
2576
- sstate.indexIdMap[index] = _id;
2898
+ const functionCalls = toolCalls?.map(({ id: _id, index: index2, function: { name, arguments: params } }) => {
2899
+ if (typeof _id === "string" && typeof index2 === "number" && !sstate.indexIdMap[index2]) {
2900
+ sstate.indexIdMap[index2] = _id;
2577
2901
  }
2578
- const id2 = sstate.indexIdMap[index];
2902
+ const id2 = sstate.indexIdMap[index2];
2579
2903
  if (!id2) {
2580
2904
  return null;
2581
2905
  }
@@ -2586,6 +2910,7 @@ var AxAIOpenAIImpl = class {
2586
2910
  };
2587
2911
  }).filter((v) => v !== null);
2588
2912
  return {
2913
+ index,
2589
2914
  content,
2590
2915
  role,
2591
2916
  thought,
@@ -2620,7 +2945,7 @@ var mapFinishReason2 = (finishReason) => {
2620
2945
  }
2621
2946
  };
2622
2947
  function createMessages2(req) {
2623
- return req.chatPrompt.map((msg) => {
2948
+ const openaiReq = req.chatPrompt.map((msg) => {
2624
2949
  switch (msg.role) {
2625
2950
  case "system":
2626
2951
  return { role: "system", content: msg.content };
@@ -2669,7 +2994,7 @@ function createMessages2(req) {
2669
2994
  tool_calls: toolCalls
2670
2995
  };
2671
2996
  }
2672
- if (!msg.content) {
2997
+ if (msg.content === void 0) {
2673
2998
  throw new Error(
2674
2999
  "Assistant content is required when no tool calls are provided"
2675
3000
  );
@@ -2689,6 +3014,7 @@ function createMessages2(req) {
2689
3014
  throw new Error("Invalid role");
2690
3015
  }
2691
3016
  });
3017
+ return openaiReq;
2692
3018
  }
2693
3019
  var AxAIOpenAIBase = class extends AxBaseAI {
2694
3020
  constructor({
@@ -3042,6 +3368,7 @@ var AxAICohereImpl = class {
3042
3368
  }
3043
3369
  const results = [
3044
3370
  {
3371
+ index: 0,
3045
3372
  id: resp.generation_id,
3046
3373
  content: resp.text,
3047
3374
  functionCalls,
@@ -3674,7 +4001,7 @@ var AxAIGoogleGeminiImpl = class {
3674
4001
  createChatResp = (resp) => {
3675
4002
  const results = resp.candidates?.map(
3676
4003
  (candidate) => {
3677
- const result = {};
4004
+ const result = { index: 0 };
3678
4005
  switch (candidate.finishReason) {
3679
4006
  case "MAX_TOKENS":
3680
4007
  result.finishReason = "length";
@@ -4071,6 +4398,7 @@ ${fc}`;
4071
4398
  return {
4072
4399
  results: [
4073
4400
  {
4401
+ index: 0,
4074
4402
  content: resp.generated_text
4075
4403
  }
4076
4404
  ]
@@ -4712,7 +5040,7 @@ var AxAIOpenAIResponsesImpl = class {
4712
5040
  }
4713
5041
  }
4714
5042
  return {
4715
- results: [currentResult],
5043
+ results: [{ ...currentResult, index: 0 }],
4716
5044
  remoteId: id
4717
5045
  };
4718
5046
  }
@@ -4720,6 +5048,7 @@ var AxAIOpenAIResponsesImpl = class {
4720
5048
  createChatStreamResp(streamEvent) {
4721
5049
  const event = streamEvent;
4722
5050
  const baseResult = {
5051
+ index: 0,
4723
5052
  id: "",
4724
5053
  content: "",
4725
5054
  finishReason: "stop"
@@ -5287,7 +5616,7 @@ var AxAIRekaImpl = class {
5287
5616
  completionTokens: usage.output_tokens,
5288
5617
  totalTokens: usage.input_tokens + usage.output_tokens
5289
5618
  } : void 0;
5290
- const results = responses.map((res) => {
5619
+ const results = responses.map((res, index) => {
5291
5620
  const finishReason = mapFinishReason3(res.finish_reason);
5292
5621
  let content;
5293
5622
  if (typeof res.message.content === "string") {
@@ -5296,6 +5625,7 @@ var AxAIRekaImpl = class {
5296
5625
  content = res.message.content.text;
5297
5626
  }
5298
5627
  return {
5628
+ index,
5299
5629
  id: `${id}`,
5300
5630
  content,
5301
5631
  finishReason
@@ -5310,7 +5640,7 @@ var AxAIRekaImpl = class {
5310
5640
  completionTokens: usage.output_tokens,
5311
5641
  totalTokens: usage.input_tokens + usage.output_tokens
5312
5642
  } : void 0;
5313
- const results = responses.map((res) => {
5643
+ const results = responses.map((res, index) => {
5314
5644
  const finishReason = mapFinishReason3(res.finish_reason);
5315
5645
  let content;
5316
5646
  if (typeof res.chunk.content === "string") {
@@ -5319,6 +5649,7 @@ var AxAIRekaImpl = class {
5319
5649
  content = res.chunk.content.text;
5320
5650
  }
5321
5651
  return {
5652
+ index,
5322
5653
  id: `${id}`,
5323
5654
  content,
5324
5655
  finishReason
@@ -5672,107 +6003,321 @@ var AxAIGrok = class extends AxAIOpenAIBase {
5672
6003
  };
5673
6004
 
5674
6005
  // dsp/generate.ts
5675
- var import_web5 = require("stream/web");
6006
+ var import_web6 = require("stream/web");
5676
6007
  var import_api22 = require("@opentelemetry/api");
5677
6008
 
5678
- // ai/util.ts
5679
- function mergeFunctionCalls(functionCalls, functionCallDeltas) {
5680
- for (const _fc of functionCallDeltas) {
5681
- const fc = functionCalls.find((fc2) => fc2.id === _fc.id);
5682
- if (fc) {
5683
- if (typeof _fc.function.name == "string" && _fc.function.name.length > 0) {
5684
- fc.function.name += _fc.function.name;
5685
- }
5686
- if (typeof _fc.function.params == "string" && _fc.function.params.length > 0) {
5687
- fc.function.params += _fc.function.params;
5688
- }
5689
- if (typeof _fc.function.params == "object") {
5690
- fc.function.params = _fc.function.params;
5691
- }
5692
- } else {
5693
- functionCalls.push(_fc);
5694
- }
5695
- }
5696
- }
5697
-
5698
- // mem/memory.ts
5699
- var defaultLimit = 1e4;
5700
- var MemoryImpl = class {
5701
- constructor(limit = defaultLimit, options) {
5702
- this.limit = limit;
5703
- this.options = options;
5704
- if (limit <= 0) {
5705
- throw Error("argument 'limit' must be greater than 0");
5706
- }
6009
+ // ai/validate.ts
6010
+ function axValidateChatRequestMessage(item) {
6011
+ if (!item) {
6012
+ throw new Error("Chat request message item cannot be null or undefined");
5707
6013
  }
5708
- data = [];
5709
- addMemory(value) {
5710
- if (Array.isArray(value)) {
5711
- this.data.push(...value.map((chat) => ({ chat: structuredClone(chat) })));
5712
- } else {
5713
- this.data.push({
5714
- chat: structuredClone(value)
5715
- });
5716
- }
5717
- if (this.data.length > this.limit) {
5718
- const removeCount = this.data.length - this.limit;
5719
- this.data.splice(0, removeCount);
5720
- }
6014
+ if (!item.role) {
6015
+ throw new Error("Chat request message must have a role");
5721
6016
  }
5722
- add(value) {
5723
- this.addMemory(value);
5724
- if (this.options?.debug) {
5725
- debugRequest(value, this.options?.debugHideSystemPrompt);
5726
- }
6017
+ switch (item.role) {
6018
+ case "system":
6019
+ if (!item.content || item.content.trim() === "") {
6020
+ throw new Error(
6021
+ "System message content cannot be empty or whitespace-only"
6022
+ );
6023
+ }
6024
+ break;
6025
+ case "user":
6026
+ if (!item.content) {
6027
+ throw new Error("User message content cannot be undefined");
6028
+ }
6029
+ if (typeof item.content === "string") {
6030
+ if (item.content.trim() === "") {
6031
+ throw new Error(
6032
+ "User message content cannot be empty or whitespace-only"
6033
+ );
6034
+ }
6035
+ } else if (Array.isArray(item.content)) {
6036
+ if (item.content.length === 0) {
6037
+ throw new Error("User message content array cannot be empty");
6038
+ }
6039
+ for (let index = 0; index < item.content.length; index++) {
6040
+ const contentItem = item.content[index];
6041
+ if (!contentItem || typeof contentItem !== "object") {
6042
+ throw new Error(
6043
+ `User message content item at index ${index} must be an object`
6044
+ );
6045
+ }
6046
+ if (!contentItem.type) {
6047
+ throw new Error(
6048
+ `User message content item at index ${index} must have a type`
6049
+ );
6050
+ }
6051
+ switch (contentItem.type) {
6052
+ case "text":
6053
+ if (!contentItem.text || contentItem.text.trim() === "") {
6054
+ throw new Error(
6055
+ `User message text content at index ${index} cannot be empty or whitespace-only`
6056
+ );
6057
+ }
6058
+ break;
6059
+ case "image":
6060
+ if (!contentItem.image || contentItem.image.trim() === "") {
6061
+ throw new Error(
6062
+ `User message image content at index ${index} cannot be empty`
6063
+ );
6064
+ }
6065
+ if (!contentItem.mimeType || contentItem.mimeType.trim() === "") {
6066
+ throw new Error(
6067
+ `User message image content at index ${index} must have a mimeType`
6068
+ );
6069
+ }
6070
+ break;
6071
+ case "audio":
6072
+ if (!contentItem.data || contentItem.data.trim() === "") {
6073
+ throw new Error(
6074
+ `User message audio content at index ${index} cannot be empty`
6075
+ );
6076
+ }
6077
+ break;
6078
+ default:
6079
+ throw new Error(
6080
+ `User message content item at index ${index} has unsupported type: ${contentItem.type}`
6081
+ );
6082
+ }
6083
+ }
6084
+ } else {
6085
+ throw new Error(
6086
+ "User message content must be a string or array of content objects"
6087
+ );
6088
+ }
6089
+ break;
6090
+ case "assistant":
6091
+ if (!item.content && !item.functionCalls) {
6092
+ throw new Error(
6093
+ "Assistant message must have either content or function calls"
6094
+ );
6095
+ }
6096
+ if (item.content && typeof item.content !== "string") {
6097
+ throw new Error("Assistant message content must be a string");
6098
+ }
6099
+ if (item.functionCalls && !Array.isArray(item.functionCalls)) {
6100
+ throw new Error("Assistant message function calls must be an array");
6101
+ }
6102
+ break;
6103
+ case "function":
6104
+ if (!item.functionId || item.functionId.trim() === "") {
6105
+ throw new Error("Function message must have a non-empty functionId");
6106
+ }
6107
+ if (item.result === void 0 || item.result === null) {
6108
+ throw new Error("Function message must have a result");
6109
+ }
6110
+ if (typeof item.result !== "string") {
6111
+ throw new Error("Function message result must be a string");
6112
+ }
6113
+ break;
6114
+ default:
6115
+ throw new Error(
6116
+ `Unsupported message role: ${item.role}`
6117
+ );
5727
6118
  }
5728
- addResultMessage({
5729
- content,
5730
- name,
5731
- functionCalls
5732
- }) {
5733
- const isContentEmpty = typeof content === "string" && content.trim() === "";
5734
- if (isContentEmpty) {
5735
- this.addMemory({ name, role: "assistant", functionCalls });
5736
- } else {
5737
- this.addMemory({ content, name, role: "assistant", functionCalls });
6119
+ }
6120
+ function axValidateChatResponseResult(results) {
6121
+ const resultsArray = Array.isArray(results) ? results : [results];
6122
+ if (resultsArray.length === 0) {
6123
+ throw new Error("Chat response results cannot be empty");
6124
+ }
6125
+ for (let arrayIndex = 0; arrayIndex < resultsArray.length; arrayIndex++) {
6126
+ const result = resultsArray[arrayIndex];
6127
+ if (!result) {
6128
+ throw new Error(
6129
+ `Chat response result at index ${arrayIndex} cannot be null or undefined`
6130
+ );
6131
+ }
6132
+ if (typeof result.index !== "number") {
6133
+ throw new Error(
6134
+ `Chat response result at index ${arrayIndex} must have a numeric index`
6135
+ );
6136
+ }
6137
+ if (result.index < 0) {
6138
+ throw new Error(
6139
+ `Chat response result at index ${arrayIndex} must have a non-negative index`
6140
+ );
6141
+ }
6142
+ if (!result.content && !result.thought && !result.functionCalls && !result.finishReason) {
6143
+ throw new Error(
6144
+ `Chat response result at index ${arrayIndex} must have at least one of: content, thought, functionCalls, or finishReason`
6145
+ );
6146
+ }
6147
+ if (result.content !== void 0 && typeof result.content !== "string") {
6148
+ throw new Error(
6149
+ `Chat response result content at index ${arrayIndex} must be a string`
6150
+ );
6151
+ }
6152
+ if (result.thought !== void 0 && typeof result.thought !== "string") {
6153
+ throw new Error(
6154
+ `Chat response result thought at index ${arrayIndex} must be a string`
6155
+ );
6156
+ }
6157
+ if (result.name !== void 0) {
6158
+ if (typeof result.name !== "string") {
6159
+ throw new Error(
6160
+ `Chat response result name at index ${arrayIndex} must be a string`
6161
+ );
6162
+ }
6163
+ if (result.name.trim() === "") {
6164
+ throw new Error(
6165
+ `Chat response result name at index ${arrayIndex} cannot be empty or whitespace-only`
6166
+ );
6167
+ }
6168
+ }
6169
+ if (result.id !== void 0) {
6170
+ if (typeof result.id !== "string") {
6171
+ throw new Error(
6172
+ `Chat response result id at index ${arrayIndex} must be a string`
6173
+ );
6174
+ }
6175
+ if (result.id.trim() === "") {
6176
+ throw new Error(
6177
+ `Chat response result id at index ${arrayIndex} cannot be empty or whitespace-only`
6178
+ );
6179
+ }
6180
+ }
6181
+ if (result.functionCalls !== void 0) {
6182
+ if (!Array.isArray(result.functionCalls)) {
6183
+ throw new Error(
6184
+ `Chat response result functionCalls at index ${arrayIndex} must be an array`
6185
+ );
6186
+ }
6187
+ for (let callIndex = 0; callIndex < result.functionCalls.length; callIndex++) {
6188
+ const functionCall = result.functionCalls[callIndex];
6189
+ if (!functionCall) {
6190
+ throw new Error(
6191
+ `Function call at index ${callIndex} in result ${arrayIndex} cannot be null or undefined`
6192
+ );
6193
+ }
6194
+ if (!functionCall.id || typeof functionCall.id !== "string" || functionCall.id.trim() === "") {
6195
+ throw new Error(
6196
+ `Function call at index ${callIndex} in result ${arrayIndex} must have a non-empty string id`
6197
+ );
6198
+ }
6199
+ if (functionCall.type !== "function") {
6200
+ throw new Error(
6201
+ `Function call at index ${callIndex} in result ${arrayIndex} must have type 'function'`
6202
+ );
6203
+ }
6204
+ if (!functionCall.function) {
6205
+ throw new Error(
6206
+ `Function call at index ${callIndex} in result ${arrayIndex} must have a function object`
6207
+ );
6208
+ }
6209
+ if (!functionCall.function.name || typeof functionCall.function.name !== "string" || functionCall.function.name.trim() === "") {
6210
+ throw new Error(
6211
+ `Function call at index ${callIndex} in result ${arrayIndex} must have a non-empty function name`
6212
+ );
6213
+ }
6214
+ if (functionCall.function.params !== void 0) {
6215
+ if (typeof functionCall.function.params !== "string" && typeof functionCall.function.params !== "object") {
6216
+ throw new Error(
6217
+ `Function call params at index ${callIndex} in result ${arrayIndex} must be a string or object`
6218
+ );
6219
+ }
6220
+ }
6221
+ }
6222
+ }
6223
+ if (result.finishReason !== void 0) {
6224
+ const validFinishReasons = [
6225
+ "stop",
6226
+ "length",
6227
+ "function_call",
6228
+ "content_filter",
6229
+ "error"
6230
+ ];
6231
+ if (!validFinishReasons.includes(result.finishReason)) {
6232
+ throw new Error(
6233
+ `Chat response result finishReason at index ${arrayIndex} must be one of: ${validFinishReasons.join(", ")}`
6234
+ );
6235
+ }
5738
6236
  }
5739
6237
  }
5740
- addResult({
5741
- content,
5742
- name,
5743
- functionCalls
5744
- }) {
5745
- this.addResultMessage({ content, name, functionCalls });
6238
+ }
6239
+
6240
+ // mem/memory.ts
6241
+ var MemoryImpl = class {
6242
+ constructor(options) {
6243
+ this.options = options;
6244
+ }
6245
+ data = [];
6246
+ addRequest(items, index) {
6247
+ this.data.push(
6248
+ ...items.map((item) => {
6249
+ const value = structuredClone(item);
6250
+ return {
6251
+ role: item.role,
6252
+ chat: [{ index, value }]
6253
+ };
6254
+ })
6255
+ );
5746
6256
  if (this.options?.debug) {
5747
- debugResponse({ content, name, functionCalls });
6257
+ debugRequest(items, this.options?.debugHideSystemPrompt);
6258
+ }
6259
+ }
6260
+ addResponse(results) {
6261
+ const chat = results.map((result) => ({
6262
+ index: result.index,
6263
+ value: structuredClone(result)
6264
+ }));
6265
+ this.data.push({
6266
+ role: "assistant",
6267
+ chat
6268
+ });
6269
+ if (this.options?.debug) {
6270
+ for (const result of results) {
6271
+ debugResponse(result);
6272
+ }
5748
6273
  }
5749
6274
  }
5750
6275
  updateResult({
5751
6276
  content,
5752
6277
  name,
5753
6278
  functionCalls,
5754
- delta
6279
+ delta,
6280
+ index
5755
6281
  }) {
5756
6282
  const lastItem = this.data.at(-1);
5757
- if (!lastItem || lastItem.chat.role !== "assistant") {
5758
- throw new Error("No assistant message to update");
6283
+ const log = () => {
6284
+ if (this.options?.debug) {
6285
+ if (delta && typeof delta === "string") {
6286
+ debugResponseDelta(delta);
6287
+ } else if (!delta && (content || functionCalls)) {
6288
+ debugResponse({ content, name, functionCalls, index });
6289
+ }
6290
+ }
6291
+ };
6292
+ if (!lastItem || lastItem.role !== "assistant") {
6293
+ this.data.push({
6294
+ role: "assistant",
6295
+ chat: [
6296
+ { index, value: structuredClone({ content, name, functionCalls }) }
6297
+ ]
6298
+ });
6299
+ log();
6300
+ return;
5759
6301
  }
5760
- if (typeof content === "string" && content.trim() !== "") {
5761
- lastItem.chat.content = content;
6302
+ const chat = lastItem.chat.find((v) => v.index === index);
6303
+ if (!chat) {
6304
+ lastItem.chat.push({
6305
+ index,
6306
+ value: structuredClone({ content, name, functionCalls })
6307
+ });
6308
+ log();
6309
+ return;
5762
6310
  }
5763
- if (name && name.trim() !== "") {
5764
- lastItem.chat.name = name;
6311
+ if ("content" in chat.value && typeof content === "string" && content.trim() !== "") {
6312
+ chat.value.content = content;
5765
6313
  }
5766
- if (functionCalls && functionCalls.length > 0) {
5767
- lastItem.chat.functionCalls = functionCalls;
6314
+ if ("name" in chat.value && name && name.trim() !== "") {
6315
+ chat.value.name = name;
5768
6316
  }
5769
- if (this.options?.debug) {
5770
- if (delta && typeof delta === "string") {
5771
- debugResponseDelta(delta);
5772
- } else if (!delta && (content || functionCalls)) {
5773
- debugResponse({ content, name, functionCalls });
5774
- }
6317
+ if ("functionCalls" in chat.value && functionCalls && functionCalls.length > 0) {
6318
+ chat.value.functionCalls = functionCalls;
5775
6319
  }
6320
+ log();
5776
6321
  }
5777
6322
  addTag(name) {
5778
6323
  const lastItem = this.data.at(-1);
@@ -5791,8 +6336,7 @@ var MemoryImpl = class {
5791
6336
  if (tagIndex === -1) {
5792
6337
  throw new Error(`Tag "${name}" not found`);
5793
6338
  }
5794
- const removedItems = this.data.splice(tagIndex);
5795
- return removedItems.map((item) => item.chat);
6339
+ return this.data.splice(tagIndex);
5796
6340
  }
5797
6341
  removeByTag(name) {
5798
6342
  const indices = this.data.reduce((acc, item, index) => {
@@ -5804,28 +6348,29 @@ var MemoryImpl = class {
5804
6348
  if (indices.length === 0) {
5805
6349
  throw new Error(`No items found with tag "${name}"`);
5806
6350
  }
5807
- return indices.reverse().map((index) => this.data.splice(index, 1).at(0)?.chat).filter(Boolean).reverse();
6351
+ return indices.reverse().map((index) => this.data.splice(index, 1).at(0)).filter((item) => item !== void 0).reverse();
5808
6352
  }
5809
- history() {
5810
- return this.data.map((item) => item.chat);
6353
+ history(index) {
6354
+ const result = [];
6355
+ for (const { role, chat } of this.data) {
6356
+ const value = chat.find((v) => v.index === index)?.value;
6357
+ if (value) {
6358
+ result.push({ role, ...value });
6359
+ }
6360
+ }
6361
+ return result;
5811
6362
  }
5812
6363
  getLast() {
5813
- const lastItem = this.data.at(-1);
5814
- if (!lastItem) return void 0;
5815
- return {
5816
- chat: lastItem.chat,
5817
- tags: lastItem.tags
5818
- };
6364
+ return this.data.at(-1);
5819
6365
  }
5820
6366
  reset() {
5821
6367
  this.data = [];
5822
6368
  }
5823
6369
  };
5824
6370
  var AxMemory = class {
5825
- constructor(limit = defaultLimit, options) {
5826
- this.limit = limit;
6371
+ constructor(options) {
5827
6372
  this.options = options;
5828
- this.defaultMemory = new MemoryImpl(limit, options);
6373
+ this.defaultMemory = new MemoryImpl(options);
5829
6374
  }
5830
6375
  memories = /* @__PURE__ */ new Map();
5831
6376
  defaultMemory;
@@ -5834,15 +6379,34 @@ var AxMemory = class {
5834
6379
  return this.defaultMemory;
5835
6380
  }
5836
6381
  if (!this.memories.has(sessionId)) {
5837
- this.memories.set(sessionId, new MemoryImpl(this.limit, this.options));
6382
+ this.memories.set(sessionId, new MemoryImpl(this.options));
5838
6383
  }
5839
6384
  return this.memories.get(sessionId);
5840
6385
  }
5841
- add(value, sessionId) {
5842
- this.getMemory(sessionId).add(value);
5843
- }
5844
- addResult(result, sessionId) {
5845
- this.getMemory(sessionId).addResult(result);
6386
+ addRequest(value, sessionId) {
6387
+ for (const item of value) {
6388
+ axValidateChatRequestMessage(item);
6389
+ }
6390
+ this.getMemory(sessionId).addRequest(value, 0);
6391
+ }
6392
+ addResponse(results, sessionId) {
6393
+ axValidateChatResponseResult(results);
6394
+ this.getMemory(sessionId).addResponse(results);
6395
+ }
6396
+ addFunctionResult({
6397
+ functionId,
6398
+ isError,
6399
+ index,
6400
+ result
6401
+ }, sessionId) {
6402
+ const functionMessage = {
6403
+ role: "function",
6404
+ functionId,
6405
+ isError,
6406
+ result
6407
+ };
6408
+ axValidateChatRequestMessage(functionMessage);
6409
+ this.getMemory(sessionId).addRequest([functionMessage], index);
5846
6410
  }
5847
6411
  updateResult(result, sessionId) {
5848
6412
  this.getMemory(sessionId).updateResult(result);
@@ -5853,8 +6417,8 @@ var AxMemory = class {
5853
6417
  rewindToTag(name, sessionId) {
5854
6418
  return this.getMemory(sessionId).rewindToTag(name);
5855
6419
  }
5856
- history(sessionId) {
5857
- return this.getMemory(sessionId).history();
6420
+ history(index, sessionId) {
6421
+ return this.getMemory(sessionId).history(index);
5858
6422
  }
5859
6423
  getLast(sessionId) {
5860
6424
  return this.getMemory(sessionId).getLast();
@@ -5863,7 +6427,7 @@ var AxMemory = class {
5863
6427
  if (!sessionId) {
5864
6428
  this.defaultMemory.reset();
5865
6429
  } else {
5866
- this.memories.set(sessionId, new MemoryImpl(this.limit, this.options));
6430
+ this.memories.set(sessionId, new MemoryImpl(this.options));
5867
6431
  }
5868
6432
  }
5869
6433
  };
@@ -5944,87 +6508,237 @@ var assertStreamingAssertions = async (asserts, xstate, content, final = false)
5944
6508
  }
5945
6509
  };
5946
6510
 
5947
- // dsp/datetime.ts
5948
- var import_moment_timezone = __toESM(require("moment-timezone"), 1);
5949
-
5950
- // dsp/util.ts
5951
- var colorLog3 = new ColorLog();
5952
- var updateProgressBar = (current, total, success, elapsedTime, msg, progressBarWidth = 20) => {
5953
- const percentage = (current / total * 100).toFixed(1);
5954
- const filledBarLength = Math.round(progressBarWidth * current / total);
5955
- const emptyBarLength = progressBarWidth - filledBarLength;
5956
- const filledBar = colorLog3.blueBright("\u2588".repeat(filledBarLength));
5957
- const emptyBar = " ".repeat(emptyBarLength);
5958
- const itemsPerSecond = elapsedTime > 0 ? (current / elapsedTime).toFixed(2) : "0.00";
5959
- 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]`
5961
- );
5962
- };
5963
- var validateValue = (field, value) => {
5964
- const ft = field.type ?? { name: "string", isArray: false };
5965
- const validateSingleValue = (expectedType, val) => {
5966
- switch (expectedType) {
5967
- case "class":
5968
- return typeof val === "string";
5969
- case "code":
5970
- return typeof val === "string";
5971
- case "string":
5972
- return typeof val === "string";
5973
- case "number":
5974
- return typeof val === "number";
5975
- case "boolean":
5976
- return typeof val === "boolean";
5977
- case "date":
5978
- return val instanceof Date || typeof val === "string";
5979
- case "datetime":
5980
- return val instanceof Date || typeof val === "string";
5981
- case "json":
5982
- return typeof val === "object" || typeof val === "string";
5983
- default:
5984
- return false;
5985
- }
5986
- };
5987
- const validImage = (val) => {
5988
- if (!val || typeof val !== "object" || !("mimeType" in val) || !("data" in val)) {
5989
- return false;
5990
- }
5991
- return true;
5992
- };
5993
- if (field.type?.name === "image") {
5994
- let msg;
5995
- if (Array.isArray(value)) {
5996
- for (const item of value) {
5997
- if (!validImage(item)) {
5998
- msg = "object ({ mimeType: string; data: string })";
5999
- break;
6000
- }
6001
- }
6002
- } else if (!validImage(value)) {
6003
- msg = "object ({ mimeType: string; data: string })";
6004
- }
6005
- if (msg) {
6006
- throw new Error(
6007
- `Validation failed: Expected '${field.name}' to be type '${msg}' instead got '${value}'`
6008
- );
6009
- }
6010
- return;
6511
+ // dsp/errors.ts
6512
+ var ValidationError = class extends Error {
6513
+ fields;
6514
+ constructor({
6515
+ message,
6516
+ fields
6517
+ }) {
6518
+ super(message);
6519
+ this.fields = fields;
6520
+ this.name = this.constructor.name;
6011
6521
  }
6012
- const validAudio = (val) => {
6013
- if (!val || typeof val !== "object" || !("data" in val)) {
6014
- return false;
6015
- }
6016
- return true;
6522
+ getFixingInstructions = () => {
6523
+ const toFieldType2 = (type) => {
6524
+ const baseType = (() => {
6525
+ switch (type?.name) {
6526
+ case "string":
6527
+ return "string";
6528
+ case "number":
6529
+ return "number";
6530
+ case "boolean":
6531
+ return "boolean";
6532
+ case "date":
6533
+ return 'date ("YYYY-MM-DD" format)';
6534
+ case "datetime":
6535
+ return 'date time ("YYYY-MM-DD HH:mm Timezone" format)';
6536
+ case "json":
6537
+ return "JSON object";
6538
+ case "class":
6539
+ return "classification class";
6540
+ case "code":
6541
+ return "code";
6542
+ default:
6543
+ return "string";
6544
+ }
6545
+ })();
6546
+ return type?.isArray ? `json array of ${baseType} items` : baseType;
6547
+ };
6548
+ return this.fields.map((field) => ({
6549
+ name: "outputError",
6550
+ title: "Output Correction Required",
6551
+ description: `The section labeled '${field.title}' does not match the expected format of '${toFieldType2(field.type)}'. ${this.message} Please revise your response to ensure it conforms to the specified format.`
6552
+ }));
6017
6553
  };
6018
- if (field.type?.name === "audio") {
6019
- let msg;
6020
- if (Array.isArray(value)) {
6021
- for (const item of value) {
6022
- if (!validAudio(item)) {
6023
- msg = "object ({ data: string; format?: string })";
6024
- break;
6554
+ toString() {
6555
+ const toFieldType2 = (type) => {
6556
+ const baseType = (() => {
6557
+ switch (type?.name) {
6558
+ case "string":
6559
+ return "string";
6560
+ case "number":
6561
+ return "number";
6562
+ case "boolean":
6563
+ return "boolean";
6564
+ case "date":
6565
+ return 'date ("YYYY-MM-DD" format)';
6566
+ case "datetime":
6567
+ return 'date time ("YYYY-MM-DD HH:mm Timezone" format)';
6568
+ case "json":
6569
+ return "JSON object";
6570
+ case "class":
6571
+ return "classification class";
6572
+ case "code":
6573
+ return "code";
6574
+ default:
6575
+ return "string";
6025
6576
  }
6026
- }
6027
- } else if (!validAudio(value)) {
6577
+ })();
6578
+ return type?.isArray ? `json array of ${baseType} items` : baseType;
6579
+ };
6580
+ return [
6581
+ `${this.name}: ${this.message}`,
6582
+ ...this.fields.map(
6583
+ (field) => ` - ${field.title}: Expected format '${toFieldType2(field.type)}'`
6584
+ )
6585
+ ].join("\n");
6586
+ }
6587
+ [Symbol.for("nodejs.util.inspect.custom")](_depth, _options) {
6588
+ return this.toString();
6589
+ }
6590
+ };
6591
+
6592
+ // dsp/datetime.ts
6593
+ var import_moment_timezone = __toESM(require("moment-timezone"), 1);
6594
+ function parseLLMFriendlyDate(field, dateStr, required = false) {
6595
+ try {
6596
+ return _parseLLMFriendlyDate(dateStr);
6597
+ } catch (err) {
6598
+ if (field.isOptional && !required) {
6599
+ return;
6600
+ }
6601
+ const message = err.message;
6602
+ throw new ValidationError({ fields: [field], message, value: dateStr });
6603
+ }
6604
+ }
6605
+ function _parseLLMFriendlyDate(dateStr) {
6606
+ if (!(0, import_moment_timezone.default)(dateStr, "YYYY-MM-DD", true).isValid()) {
6607
+ throw new Error(
6608
+ 'Invalid date format. Please provide the date in "YYYY-MM-DD" format.'
6609
+ );
6610
+ }
6611
+ const date = import_moment_timezone.default.utc(dateStr, "YYYY-MM-DD").startOf("day");
6612
+ return date.toDate();
6613
+ }
6614
+ function parseLLMFriendlyDateTime(field, dateStr, required = false) {
6615
+ try {
6616
+ return _parseLLMFriendlyDateTime(dateStr);
6617
+ } catch (err) {
6618
+ if (field.isOptional && !required) {
6619
+ return;
6620
+ }
6621
+ const message = err.message;
6622
+ throw new ValidationError({ fields: [field], message, value: dateStr });
6623
+ }
6624
+ }
6625
+ function _parseLLMFriendlyDateTime(dateTimeStr) {
6626
+ const dateTimeRegex = /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}(?::\d{2})?) (.+)$/;
6627
+ const match = dateTimeStr.match(dateTimeRegex);
6628
+ if (!match) {
6629
+ throw new Error(
6630
+ 'Invalid date and time format. Please provide the date and time in "YYYY-MM-DD HH:mm" or "YYYY-MM-DD HH:mm:ss" format, followed by the timezone.'
6631
+ );
6632
+ }
6633
+ const [, dateTime, timeZone] = match;
6634
+ if (!dateTime || !timeZone) {
6635
+ throw new Error(
6636
+ 'Invalid date and time format. Please provide the date and time in "YYYY-MM-DD HH:mm" or "YYYY-MM-DD HH:mm:ss" format, followed by the timezone.'
6637
+ );
6638
+ }
6639
+ const zone = import_moment_timezone.default.tz.zone(timeZone);
6640
+ if (!zone) {
6641
+ throw new Error(
6642
+ `Unrecognized time zone ${timeZone}. Please provide a valid time zone name, abbreviation, or offset. For example, "America/New_York", or "EST".`
6643
+ );
6644
+ }
6645
+ const date = import_moment_timezone.default.tz(
6646
+ dateTime,
6647
+ ["YYYY-MM-DD HH:mm", "YYYY-MM-DD HH:mm:ss"],
6648
+ zone.name
6649
+ );
6650
+ if (!date.isValid()) {
6651
+ throw new Error(
6652
+ "Invalid date and time values. Please ensure all components are correct."
6653
+ );
6654
+ }
6655
+ return date.utc().toDate();
6656
+ }
6657
+ var formatDateWithTimezone = (date) => {
6658
+ const momentDate = (0, import_moment_timezone.default)(date).utc();
6659
+ return momentDate.format(`YYYY-MM-DD HH:mm:ss UTC`);
6660
+ };
6661
+
6662
+ // dsp/util.ts
6663
+ var colorLog3 = new ColorLog();
6664
+ var updateProgressBar = (current, total, success, elapsedTime, msg, progressBarWidth = 20) => {
6665
+ const percentage = (current / total * 100).toFixed(1);
6666
+ const filledBarLength = Math.round(progressBarWidth * current / total);
6667
+ const emptyBarLength = progressBarWidth - filledBarLength;
6668
+ const filledBar = colorLog3.blueBright("\u2588".repeat(filledBarLength));
6669
+ const emptyBar = " ".repeat(emptyBarLength);
6670
+ const successRate = total > 0 ? (success / total * 100).toFixed(1) : "0.0";
6671
+ const friendlyMsg = msg.includes("Running MIPROv2 optimization") ? "Testing prompt variations" : msg.includes("Tuning Prompt") ? "Generating training examples" : msg;
6672
+ process.stdout.write(
6673
+ `\u2502 ${friendlyMsg}: ${current}/${total} (${colorLog3.yellow(percentage)}%) |${filledBar}${emptyBar}| Success rate: ${colorLog3.greenBright(successRate)}%
6674
+ `
6675
+ );
6676
+ };
6677
+ var validateValue = (field, value) => {
6678
+ const ft = field.type ?? { name: "string", isArray: false };
6679
+ const validateSingleValue = (expectedType, val) => {
6680
+ switch (expectedType) {
6681
+ case "class":
6682
+ return typeof val === "string";
6683
+ case "code":
6684
+ return typeof val === "string";
6685
+ case "string":
6686
+ return typeof val === "string";
6687
+ case "number":
6688
+ return typeof val === "number";
6689
+ case "boolean":
6690
+ return typeof val === "boolean";
6691
+ case "date":
6692
+ return val instanceof Date || typeof val === "string";
6693
+ case "datetime":
6694
+ return val instanceof Date || typeof val === "string";
6695
+ case "json":
6696
+ return typeof val === "object" || typeof val === "string";
6697
+ default:
6698
+ return false;
6699
+ }
6700
+ };
6701
+ const validImage = (val) => {
6702
+ if (!val || typeof val !== "object" || !("mimeType" in val) || !("data" in val)) {
6703
+ return false;
6704
+ }
6705
+ return true;
6706
+ };
6707
+ if (field.type?.name === "image") {
6708
+ let msg;
6709
+ if (Array.isArray(value)) {
6710
+ for (const item of value) {
6711
+ if (!validImage(item)) {
6712
+ msg = "object ({ mimeType: string; data: string })";
6713
+ break;
6714
+ }
6715
+ }
6716
+ } else if (!validImage(value)) {
6717
+ msg = "object ({ mimeType: string; data: string })";
6718
+ }
6719
+ if (msg) {
6720
+ throw new Error(
6721
+ `Validation failed: Expected '${field.name}' to be type '${msg}' instead got '${value}'`
6722
+ );
6723
+ }
6724
+ return;
6725
+ }
6726
+ const validAudio = (val) => {
6727
+ if (!val || typeof val !== "object" || !("data" in val)) {
6728
+ return false;
6729
+ }
6730
+ return true;
6731
+ };
6732
+ if (field.type?.name === "audio") {
6733
+ let msg;
6734
+ if (Array.isArray(value)) {
6735
+ for (const item of value) {
6736
+ if (!validAudio(item)) {
6737
+ msg = "object ({ data: string; format?: string })";
6738
+ break;
6739
+ }
6740
+ }
6741
+ } else if (!validAudio(value)) {
6028
6742
  msg = "object ({ data: string; format?: string })";
6029
6743
  }
6030
6744
  if (msg) {
@@ -6106,18 +6820,24 @@ var parseMarkdownList = (input) => {
6106
6820
  }
6107
6821
  return list;
6108
6822
  };
6109
- function mergeDeltas(base, delta) {
6823
+ function mergeDeltas(base, currentDelta) {
6824
+ const { index, delta, version } = currentDelta;
6825
+ const target = base.find((b) => b.index === index)?.delta;
6826
+ if (!target) {
6827
+ base.push({ index, delta, version });
6828
+ return base;
6829
+ }
6110
6830
  for (const key of Object.keys(delta)) {
6111
- const baseValue = base[key];
6831
+ const baseValue = target[key];
6112
6832
  const deltaValue = delta[key];
6113
6833
  if (baseValue === void 0 && Array.isArray(deltaValue)) {
6114
- base[key] = [...deltaValue];
6834
+ target[key] = [...deltaValue];
6115
6835
  } else if (Array.isArray(baseValue) && Array.isArray(deltaValue)) {
6116
- base[key] = [...baseValue ?? [], ...deltaValue];
6836
+ target[key] = [...baseValue, ...deltaValue];
6117
6837
  } else if ((baseValue === void 0 || typeof baseValue === "string") && typeof deltaValue === "string") {
6118
- base[key] = (baseValue ?? "") + deltaValue;
6838
+ target[key] = `${baseValue ?? ""}${deltaValue}`;
6119
6839
  } else {
6120
- base[key] = deltaValue;
6840
+ target[key] = deltaValue;
6121
6841
  }
6122
6842
  }
6123
6843
  return base;
@@ -6164,19 +6884,15 @@ function matchesContent(content, prefix, startIndex = 0, prefixCache = globalPre
6164
6884
  if (!prefixCache.get(prefix)) {
6165
6885
  prefixCache.set(prefix, prefixes);
6166
6886
  }
6167
- const contentEnd = content.slice(
6168
- Math.max(startIndex, content.length - prefix.length)
6169
- );
6170
- for (let i = 0; i < prefixes.length - 1; i++) {
6887
+ let longestPartialMatch = -1;
6888
+ for (let i = prefixes.length - 1; i >= 0; i--) {
6171
6889
  const partialPrefix = prefixes[i];
6172
- if (partialPrefix === "\n" || partialPrefix === ":") {
6173
- continue;
6174
- }
6175
- if (partialPrefix && contentEnd.endsWith(partialPrefix)) {
6176
- return -2;
6890
+ if (content.endsWith(partialPrefix)) {
6891
+ longestPartialMatch = i;
6892
+ break;
6177
6893
  }
6178
6894
  }
6179
- return -1;
6895
+ return longestPartialMatch >= 0 ? -2 : -1;
6180
6896
  }
6181
6897
  var formatTime = (ms) => {
6182
6898
  const seconds = Math.floor(ms / 1e3);
@@ -6199,11 +6915,10 @@ var updateDetailedProgress = (roundIndex, current, total, elapsedTime, example,
6199
6915
  process.stdout.write("\r\x1B[K");
6200
6916
  const percentage = (current / total * 100).toFixed(1);
6201
6917
  const formattedTime = formatTime(elapsedTime);
6202
- const itemsPerSecond = elapsedTime > 0 ? (current / elapsedTime * 1e3).toFixed(2) : "0.00";
6203
6918
  const eta = calculateETA(current, total, elapsedTime);
6204
- let output = `Round ${roundIndex + 1}/${configInfo.maxRounds}: ${current}/${total} (${percentage}%) [${formattedTime}, ${itemsPerSecond} it/s, ETA: ${eta}]`;
6919
+ let output = `Training round ${roundIndex + 1}/${configInfo.maxRounds}: ${current}/${total} (${percentage}%) [${formattedTime}, ETA: ${eta}]`;
6205
6920
  const successRate = stats.totalCalls > 0 ? stats.successfulDemos / stats.totalCalls * 100 : 0;
6206
- output += ` | Success: ${stats.successfulDemos}/${stats.totalCalls} (${successRate.toFixed(1)}%)`;
6921
+ output += ` | Success rate: ${successRate.toFixed(1)}% (${stats.successfulDemos}/${stats.totalCalls})`;
6207
6922
  if (configInfo.verboseMode || configInfo.debugMode) {
6208
6923
  if (configInfo.costMonitoring) {
6209
6924
  output += `
@@ -6239,913 +6954,365 @@ var updateDetailedProgress = (roundIndex, current, total, elapsedTime, example,
6239
6954
  console.log(output);
6240
6955
  };
6241
6956
 
6242
- // dsp/prompt.ts
6243
- var functionCallInstructions = `
6244
- ## Function Call Instructions
6245
- - Complete the task, using the functions defined earlier in this prompt.
6246
- - Call functions step-by-step, using the output of one function as input to the next.
6247
- - Use the function results to generate the output fields.`;
6248
- var formattingRules = `
6249
- ## Strict Output Formatting Rules
6250
- - Output must strictly follow the defined plain-text \`field name: value\` field format.
6251
- - Output field, values must strictly adhere to the specified output field formatting rules.
6252
- - Do not add any text before or after the output fields, just the field name and value.
6253
- - Do not use code blocks.`;
6254
- var AxPromptTemplate = class {
6255
- sig;
6256
- fieldTemplates;
6257
- task;
6258
- thoughtFieldName;
6259
- functions;
6260
- constructor(sig, options, fieldTemplates) {
6261
- this.sig = sig;
6262
- this.fieldTemplates = fieldTemplates;
6263
- this.thoughtFieldName = options?.thoughtFieldName ?? "thought";
6264
- this.functions = options?.functions;
6265
- const task = [];
6266
- const inArgs = renderDescFields(this.sig.getInputFields());
6267
- const outArgs = renderDescFields(this.sig.getOutputFields());
6268
- task.push(
6269
- `You will be provided with the following fields: ${inArgs}. Your task is to generate new fields: ${outArgs}.`
6270
- );
6271
- const funcs = this.functions?.map((f2) => "toFunction" in f2 ? f2.toFunction() : f2)?.flat();
6272
- const funcList = funcs?.map((fn) => `- \`${fn.name}\`: ${formatDescription(fn.description)}`).join("\n");
6273
- if (funcList && funcList.length > 0) {
6274
- task.push(`## Available Functions
6275
- ${funcList}`);
6276
- }
6277
- const inputFields = renderInputFields(this.sig.getInputFields());
6278
- task.push(`## Input Fields
6279
- ${inputFields}`);
6280
- const outputFields = renderOutputFields(this.sig.getOutputFields());
6281
- task.push(`## Output Fields
6282
- ${outputFields}`);
6283
- if (funcList && funcList.length > 0) {
6284
- task.push(functionCallInstructions.trim());
6285
- }
6286
- task.push(formattingRules.trim());
6287
- const desc = this.sig.getDescription();
6288
- if (desc) {
6289
- const text = formatDescription(desc);
6290
- task.push(text);
6957
+ // dsp/extract.ts
6958
+ var extractValues = (sig, values, content, strictMode = false) => {
6959
+ const xstate = { extractedFields: [], streamedIndex: {}, s: -1 };
6960
+ streamingExtractValues(sig, values, xstate, content, { strictMode });
6961
+ streamingExtractFinalValue(sig, values, xstate, content);
6962
+ for (const field of sig.getOutputFields()) {
6963
+ if (field.isInternal) {
6964
+ delete values[field.name];
6291
6965
  }
6292
- this.task = {
6293
- type: "text",
6294
- text: task.join("\n\n")
6295
- };
6296
6966
  }
6297
- renderSingleValueUserContent = (values, renderedExamples, renderedDemos, examplesInSystemPrompt) => {
6298
- const completion = this.renderInputFields(values);
6299
- const promptList = examplesInSystemPrompt ? completion : [...renderedExamples, ...renderedDemos, ...completion];
6300
- const prompt = promptList.filter((v) => v !== void 0);
6301
- return prompt.every((v) => v.type === "text") ? prompt.map((v) => v.text).join("\n") : prompt.reduce(combineConsecutiveStrings("\n"), []);
6302
- };
6303
- render = (values, {
6304
- examples,
6305
- demos
6306
- }) => {
6307
- const renderedExamples = examples ? [
6308
- { type: "text", text: "\n\n## Examples\n" },
6309
- ...this.renderExamples(examples)
6310
- ] : [];
6311
- const renderedDemos = demos ? this.renderDemos(demos) : [];
6312
- const allTextExamples = renderedExamples.every((v) => v.type === "text");
6313
- const allTextDemos = renderedDemos.every((v) => v.type === "text");
6314
- const examplesInSystemPrompt = allTextExamples && allTextDemos;
6315
- let systemContent = this.task.text;
6316
- if (examplesInSystemPrompt) {
6317
- const combinedItems = [
6318
- { type: "text", text: systemContent },
6319
- ...renderedExamples,
6320
- ...renderedDemos
6321
- ];
6322
- combinedItems.reduce(combineConsecutiveStrings(""), []);
6323
- if (combinedItems && combinedItems[0]) {
6324
- systemContent = combinedItems[0].text;
6325
- }
6967
+ };
6968
+ var checkMissingRequiredFields = (xstate, values, outputFields) => {
6969
+ const missingFields = [];
6970
+ for (const field of outputFields) {
6971
+ if (field && !field.isOptional && values[field.name] === void 0) {
6972
+ missingFields.push(field);
6326
6973
  }
6327
- const systemPrompt = {
6328
- role: "system",
6329
- content: systemContent
6330
- };
6331
- if (Array.isArray(values)) {
6332
- let userMessages = [];
6333
- const history = values;
6334
- for (const [index, message] of history.entries()) {
6335
- let content;
6336
- if (index === 0) {
6337
- content = this.renderSingleValueUserContent(
6338
- message.values,
6339
- renderedExamples,
6340
- renderedDemos,
6341
- examplesInSystemPrompt
6342
- );
6343
- } else {
6344
- content = this.renderSingleValueUserContent(
6345
- message.values,
6346
- [],
6347
- [],
6348
- false
6349
- );
6350
- }
6351
- if (message.role === "user") {
6352
- userMessages.push({ role: "user", content });
6974
+ }
6975
+ if (missingFields.length > 0) {
6976
+ throw new ValidationError({
6977
+ message: `Required ${missingFields.length === 1 ? "field" : "fields"} not found`,
6978
+ fields: missingFields
6979
+ });
6980
+ }
6981
+ };
6982
+ var streamingExtractValues = (sig, values, xstate, content, { strictMode, skipEarlyFail } = {}) => {
6983
+ const fields = sig.getOutputFields();
6984
+ let expectedField;
6985
+ for (const [index, field] of fields.entries()) {
6986
+ if (index === xstate.currFieldIndex && !xstate.inAssumedField) {
6987
+ continue;
6988
+ }
6989
+ if (field.name in values && !(index === xstate.currFieldIndex && xstate.inAssumedField)) {
6990
+ continue;
6991
+ }
6992
+ const isFirst = xstate.extractedFields.length === 0;
6993
+ const prefix = (isFirst ? "" : "\n") + field.title + ":";
6994
+ let e = matchesContent(content, prefix, xstate.s);
6995
+ let prefixLen = prefix.length;
6996
+ switch (e) {
6997
+ case -1:
6998
+ if (skipEarlyFail) {
6353
6999
  continue;
6354
7000
  }
6355
- if (message.role !== "assistant") {
6356
- throw new Error("Invalid message role");
7001
+ if (!strictMode && fields.length === 1 && xstate.currField === void 0) {
7002
+ xstate.inAssumedField = true;
7003
+ expectedField = field;
7004
+ prefixLen = 0;
7005
+ e = 0;
7006
+ break;
6357
7007
  }
6358
- if (typeof content !== "string") {
6359
- throw new Error(
6360
- "Assistant message cannot contain non-text content like images, files,etc"
6361
- );
7008
+ if (xstate.currField === void 0 && !field.isOptional) {
7009
+ throw new ValidationError({
7010
+ message: "Expected (Required) field not found",
7011
+ fields: [field]
7012
+ });
6362
7013
  }
6363
- userMessages.push({ role: "assistant", content });
6364
- }
6365
- return [systemPrompt, ...userMessages];
7014
+ expectedField = field.isOptional ? void 0 : field;
7015
+ continue;
7016
+ // Field is not found, continue to the next field
7017
+ case -2:
7018
+ return true;
7019
+ // Partial match at end, skip and gather more content
7020
+ case -3:
7021
+ return true;
7022
+ // String is only whitespace, skip and gather more content
7023
+ case -4:
7024
+ xstate.inBlock = true;
7025
+ return true;
6366
7026
  }
6367
- const userContent = this.renderSingleValueUserContent(
6368
- values,
6369
- renderedExamples,
6370
- renderedDemos,
6371
- examplesInSystemPrompt
6372
- );
6373
- return [systemPrompt, { role: "user", content: userContent }];
6374
- };
6375
- renderExtraFields = (extraFields) => {
6376
- const prompt = [];
6377
- if (!extraFields || extraFields.length === 0) {
6378
- return prompt;
7027
+ if (expectedField && expectedField.name !== field.name) {
7028
+ throw new ValidationError({
7029
+ message: "Expected (Required) field not found",
7030
+ fields: [expectedField]
7031
+ });
6379
7032
  }
6380
- const groupedFields = extraFields.reduce(
6381
- (acc, field) => {
6382
- const title = field.title;
6383
- if (!acc[title]) {
6384
- acc[title] = [];
6385
- }
6386
- acc[title].push(field);
6387
- return acc;
6388
- },
6389
- {}
6390
- );
6391
- const formattedGroupedFields = Object.entries(groupedFields).map(([title, fields]) => {
6392
- if (fields.length === 1) {
6393
- const field = fields[0];
6394
- return {
6395
- title,
6396
- name: field.name,
6397
- description: field.description
6398
- };
6399
- } else if (fields.length > 1) {
6400
- const valuesList = fields.map((field) => `- ${field.description}`).join("\n");
6401
- return {
6402
- title,
6403
- name: fields[0].name,
6404
- description: valuesList
6405
- };
7033
+ if (xstate.currField !== void 0 && xstate.inAssumedField) {
7034
+ xstate.inAssumedField = false;
7035
+ xstate.streamedIndex[xstate.currField.name] = 0;
7036
+ xstate.currField = void 0;
7037
+ }
7038
+ if (xstate.currField) {
7039
+ const val = content.substring(xstate.s, e).trim();
7040
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
7041
+ if (parsedValue !== void 0) {
7042
+ values[xstate.currField.name] = parsedValue;
6406
7043
  }
6407
- }).filter(Boolean);
6408
- formattedGroupedFields.forEach((field) => {
6409
- const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
6410
- prompt.push(...fn(field, field.description));
6411
- });
6412
- return prompt;
6413
- };
6414
- renderExamples = (data) => {
6415
- const list = [];
6416
- const exampleContext = {
6417
- isExample: true
6418
- };
6419
- for (const [index, item] of data.entries()) {
6420
- const renderedInputItem = this.sig.getInputFields().map(
6421
- (field) => this.renderInField(field, item, {
6422
- ...exampleContext,
6423
- isInputField: true
6424
- })
6425
- ).filter((v) => v !== void 0).flat();
6426
- const renderedOutputItem = this.sig.getOutputFields().map(
6427
- (field) => this.renderInField(field, item, {
6428
- ...exampleContext,
6429
- isInputField: false
6430
- })
6431
- ).filter((v) => v !== void 0).flat();
6432
- const renderedItem = [...renderedInputItem, ...renderedOutputItem];
6433
- if (index > 0 && renderedItem.length > 0 && renderedItem[0]?.type === "text") {
6434
- list.push({ type: "text", text: "---\n\n" });
7044
+ if (xstate.prevFields) {
7045
+ xstate.prevFields?.push({ field: xstate.currField, s: xstate.s, e });
7046
+ } else {
7047
+ xstate.prevFields = [{ field: xstate.currField, s: xstate.s, e }];
6435
7048
  }
6436
- renderedItem.forEach((v) => {
6437
- if ("text" in v) {
6438
- v.text = v.text + "\n";
6439
- }
6440
- list.push(v);
6441
- });
6442
7049
  }
6443
- return list;
6444
- };
6445
- renderDemos = (data) => {
6446
- const list = [];
6447
- const inputFields = this.sig.getInputFields();
6448
- const outputFields = this.sig.getOutputFields();
6449
- const demoContext = {
6450
- isExample: true
6451
- };
6452
- for (const item of data) {
6453
- const inputRenderedItems = inputFields.map(
6454
- (field) => this.renderInField(field, item, {
6455
- ...demoContext,
6456
- isInputField: true
6457
- })
6458
- ).filter((v) => v !== void 0).flat();
6459
- const outputRenderedItems = outputFields.map(
6460
- (field) => this.renderInField(field, item, {
6461
- ...demoContext,
6462
- isInputField: false
6463
- })
6464
- ).filter((v) => v !== void 0).flat();
6465
- const renderedItem = [...inputRenderedItems, ...outputRenderedItems];
6466
- renderedItem.slice(0, -1).forEach((v) => {
6467
- if ("text" in v) {
6468
- v.text = v.text + "\n";
6469
- }
6470
- list.push(v);
6471
- });
7050
+ xstate.s = e + prefixLen;
7051
+ xstate.currField = field;
7052
+ xstate.currFieldIndex = index;
7053
+ if (!xstate.extractedFields.includes(field)) {
7054
+ xstate.extractedFields.push(field);
6472
7055
  }
6473
- return list;
6474
- };
6475
- renderInputFields = (values) => {
6476
- const renderedItems = this.sig.getInputFields().map((field) => this.renderInField(field, values, void 0)).filter((v) => v !== void 0).flat();
6477
- renderedItems.filter((v) => v.type === "text").forEach((v) => {
6478
- v.text = v.text + "\n";
6479
- });
6480
- return renderedItems;
6481
- };
6482
- renderInField = (field, values, context3) => {
6483
- const value = values[field.name];
6484
- if (isEmptyValue(field, value, context3)) {
6485
- return;
7056
+ if (xstate.streamedIndex[field.name] === void 0) {
7057
+ xstate.streamedIndex[field.name] = 0;
6486
7058
  }
6487
- if (field.type) {
6488
- validateValue(field, value);
7059
+ }
7060
+ };
7061
+ var streamingExtractFinalValue = (sig, values, xstate, content) => {
7062
+ if (xstate.currField) {
7063
+ let val = content.substring(xstate.s).trim();
7064
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
7065
+ if (parsedValue !== void 0) {
7066
+ values[xstate.currField.name] = parsedValue;
6489
7067
  }
6490
- const processedValue = processValue(field, value);
6491
- const textFieldFn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
6492
- return textFieldFn(field, processedValue);
6493
- };
6494
- defaultRenderInField = (field, value) => {
6495
- if (field.type?.name === "image") {
6496
- const validateImage = (value2) => {
6497
- if (!value2) {
6498
- throw new Error("Image field value is required.");
6499
- }
6500
- if (typeof value2 !== "object") {
6501
- throw new Error("Image field value must be an object.");
6502
- }
6503
- if (!("mimeType" in value2)) {
6504
- throw new Error("Image field must have mimeType");
7068
+ }
7069
+ checkMissingRequiredFields(xstate, values, sig.getOutputFields());
7070
+ };
7071
+ var convertValueToType = (field, val, required = false) => {
7072
+ switch (field.type?.name) {
7073
+ case "code":
7074
+ return extractBlock(val);
7075
+ case "string":
7076
+ return val;
7077
+ case "number": {
7078
+ const v = Number(val);
7079
+ if (Number.isNaN(v)) {
7080
+ if (field.isOptional && !required) {
7081
+ return;
6505
7082
  }
6506
- if (!("data" in value2)) {
6507
- throw new Error("Image field must have data");
7083
+ throw new Error("Invalid number");
7084
+ }
7085
+ return v;
7086
+ }
7087
+ case "boolean": {
7088
+ if (typeof val === "boolean") {
7089
+ return val;
7090
+ }
7091
+ const v = val.toLowerCase();
7092
+ if (v === "true") {
7093
+ return true;
7094
+ } else if (v === "false") {
7095
+ return false;
7096
+ } else {
7097
+ if (field.isOptional && !required) {
7098
+ return;
6508
7099
  }
6509
- return value2;
6510
- };
6511
- let result = [
6512
- { type: "text", text: `${field.title}: ` }
6513
- ];
6514
- if (field.type.isArray) {
6515
- if (!Array.isArray(value)) {
6516
- throw new Error("Image field value must be an array.");
6517
- }
6518
- result = result.concat(
6519
- value.map((v) => {
6520
- const validated = validateImage(v);
6521
- return {
6522
- type: "image",
6523
- mimeType: validated.mimeType,
6524
- image: validated.data
6525
- };
6526
- })
6527
- );
6528
- } else {
6529
- const validated = validateImage(value);
6530
- result.push({
6531
- type: "image",
6532
- mimeType: validated.mimeType,
6533
- image: validated.data
6534
- });
7100
+ throw new Error("Invalid boolean");
6535
7101
  }
6536
- return result;
6537
7102
  }
6538
- if (field.type?.name === "audio") {
6539
- const validateAudio = (value2) => {
6540
- if (!value2) {
6541
- throw new Error("Audio field value is required.");
6542
- }
6543
- if (typeof value2 !== "object") {
6544
- throw new Error("Audio field value must be an object.");
6545
- }
6546
- if (!("data" in value2)) {
6547
- throw new Error("Audio field must have data");
6548
- }
6549
- return value2;
6550
- };
6551
- let result = [
6552
- { type: "text", text: `${field.title}: ` }
6553
- ];
6554
- if (field.type.isArray) {
6555
- if (!Array.isArray(value)) {
6556
- throw new Error("Audio field value must be an array.");
7103
+ case "date":
7104
+ return parseLLMFriendlyDate(field, val, required);
7105
+ case "datetime":
7106
+ return parseLLMFriendlyDateTime(field, val, required);
7107
+ case "class":
7108
+ const className = val;
7109
+ if (field.type.options && !field.type.options.includes(className)) {
7110
+ if (field.isOptional) {
7111
+ return;
6557
7112
  }
6558
- result = result.concat(
6559
- value.map((v) => {
6560
- const validated = validateAudio(v);
6561
- return {
6562
- type: "audio",
6563
- format: validated.format ?? "wav",
6564
- data: validated.data
6565
- };
6566
- })
7113
+ throw new Error(
7114
+ `Invalid class '${val}', expected one of the following: ${field.type.options.join(", ")}`
6567
7115
  );
6568
- } else {
6569
- const validated = validateAudio(value);
6570
- result.push({
6571
- type: "audio",
6572
- format: validated.format ?? "wav",
6573
- data: validated.data
6574
- });
6575
- }
6576
- return result;
6577
- }
6578
- const text = [field.title, ": "];
6579
- if (Array.isArray(value)) {
6580
- text.push("\n");
6581
- text.push(value.map((v) => `- ${v}`).join("\n"));
6582
- } else {
6583
- text.push(value);
6584
- }
6585
- return [{ type: "text", text: text.join("") }];
6586
- };
6587
- };
6588
- var renderDescFields = (list) => list.map((v) => `\`${v.title}\``).join(", ");
6589
- var renderInputFields = (fields) => {
6590
- const rows = fields.map((field) => {
6591
- const name = field.title;
6592
- const type = field.type?.name ? toFieldType(field.type) : "string";
6593
- const requiredMsg = field.isOptional ? `This optional ${type} field may be omitted` : `A ${type} field`;
6594
- const description = field.description ? ` ${formatDescription(field.description)}` : "";
6595
- return `${name}: (${requiredMsg})${description}`.trim();
6596
- });
6597
- return rows.join("\n");
6598
- };
6599
- var renderOutputFields = (fields) => {
6600
- const rows = fields.map((field) => {
6601
- const name = field.title;
6602
- const type = field.type?.name ? toFieldType(field.type) : "string";
6603
- const requiredMsg = field.isOptional ? `Only include this ${type} field if its value is available` : `This ${type} field must be included`;
6604
- let description = "";
6605
- if (field.description && field.description.length > 0) {
6606
- const value = field.type?.name === "class" ? field.description : formatDescription(field.description);
6607
- description = ` ${value}`;
6608
- }
6609
- if (field.type?.options && field.type.options.length > 0) {
6610
- if (description.length > 0) {
6611
- description += `. `;
6612
7116
  }
6613
- description += `Allowed values: ${field.type.options.join(", ")}`;
6614
- }
6615
- return `${name}: (${requiredMsg})${description}`.trim();
6616
- });
6617
- return rows.join("\n");
7117
+ return className;
7118
+ default:
7119
+ return val;
7120
+ }
6618
7121
  };
6619
- var processValue = (field, value) => {
6620
- if (field.type?.name === "date" && value instanceof Date) {
6621
- const v = value.toISOString();
6622
- return v.slice(0, v.indexOf("T"));
7122
+ function* yieldDelta(content, field, s2, e, xstate, index) {
7123
+ const { name: fieldName, isInternal } = field;
7124
+ const { isArray: fieldIsArray, name: fieldTypeName } = field.type ?? {};
7125
+ if (isInternal || fieldIsArray || fieldTypeName && fieldTypeName !== "string" && fieldTypeName !== "code") {
7126
+ return;
6623
7127
  }
6624
- if (field.type?.name === "datetime" && value instanceof Date) {
6625
- return formatDateWithTimezone(value);
7128
+ const pos = xstate.streamedIndex[fieldName] ?? 0;
7129
+ const isFirstChunk = pos === 0;
7130
+ const d1 = content.substring(s2 + pos, e);
7131
+ if (d1.length === 0) {
7132
+ return;
6626
7133
  }
6627
- if (field.type?.name === "image" && typeof value === "object") {
6628
- return value;
7134
+ let d2 = d1.replace(/\s+$/, "");
7135
+ if (xstate.currField?.type?.name === "code") {
7136
+ d2 = d2.replace(/\s*```\s*$/, "");
6629
7137
  }
6630
- if (field.type?.name === "audio" && typeof value === "object") {
6631
- return value;
7138
+ let d3 = isFirstChunk ? d2.trimStart() : d2;
7139
+ if (xstate.currField?.type?.name === "code") {
7140
+ d3 = d3.replace(/^[ ]*```[a-zA-Z0-9]*\n\s*/, "");
6632
7141
  }
6633
- if (typeof value === "string") {
6634
- return value;
7142
+ if (d3.length > 0) {
7143
+ yield { index, delta: { [fieldName]: d3 } };
7144
+ xstate.streamedIndex[fieldName] = pos + d2.length;
6635
7145
  }
6636
- return JSON.stringify(value, null, 2);
6637
- };
6638
- var toFieldType = (type) => {
6639
- const baseType = (() => {
6640
- switch (type?.name) {
6641
- case "string":
6642
- return "string";
6643
- case "number":
6644
- return "number";
6645
- case "boolean":
6646
- return "boolean";
6647
- case "date":
6648
- return 'date ("YYYY-MM-DD" format)';
6649
- case "datetime":
6650
- return 'date time ("YYYY-MM-DD HH:mm Timezone" format)';
6651
- case "json":
6652
- return "JSON object";
6653
- case "class":
6654
- return "classification class";
6655
- case "code":
6656
- return "code";
6657
- default:
6658
- return "string";
6659
- }
6660
- })();
6661
- return type?.isArray ? `json array of ${baseType} items` : baseType;
6662
- };
6663
- function combineConsecutiveStrings(separator) {
6664
- return (acc, current) => {
6665
- if (current.type === "text") {
6666
- const previous = acc.length > 0 ? acc[acc.length - 1] : null;
6667
- if (previous && previous.type === "text") {
6668
- previous.text += separator + current.text;
6669
- } else {
6670
- acc.push(current);
6671
- }
6672
- } else {
6673
- acc.push(current);
6674
- }
6675
- return acc;
6676
- };
6677
7146
  }
6678
- var isEmptyValue = (field, value, context3) => {
6679
- if (typeof value === "boolean") {
6680
- return false;
7147
+ function* streamValues(sig, content, values, xstate, index) {
7148
+ for (const prevField of xstate.prevFields ?? []) {
7149
+ const { field, s: s2, e } = prevField;
7150
+ yield* yieldDelta(content, field, s2, e, xstate, index);
6681
7151
  }
6682
- if (!value || (Array.isArray(value) || typeof value === "string") && value.length === 0) {
6683
- if (context3?.isExample) {
6684
- return true;
7152
+ xstate.prevFields = void 0;
7153
+ if (!xstate.currField || xstate.currField.isInternal) {
7154
+ return;
7155
+ }
7156
+ yield* yieldDelta(
7157
+ content,
7158
+ xstate.currField,
7159
+ xstate.s,
7160
+ content.length,
7161
+ xstate,
7162
+ index
7163
+ );
7164
+ const outputFields = sig.getOutputFields();
7165
+ for (const key of Object.keys(values)) {
7166
+ const field = outputFields.find((f2) => f2.name === key);
7167
+ if (!field || field.isInternal) {
7168
+ continue;
6685
7169
  }
6686
- if (field.isOptional || field.isInternal) {
6687
- return true;
7170
+ const value = values[key];
7171
+ if (Array.isArray(value)) {
7172
+ const s2 = xstate.streamedIndex?.[key] ?? 0;
7173
+ const v = value.slice(s2);
7174
+ if (v && v.length > 0) {
7175
+ yield { index, delta: { [key]: v } };
7176
+ xstate.streamedIndex[key] = s2 + v.length;
7177
+ }
7178
+ continue;
7179
+ }
7180
+ if (!xstate.streamedIndex[key]) {
7181
+ yield { index, delta: { [key]: value } };
7182
+ xstate.streamedIndex[key] = 1;
6688
7183
  }
6689
- const fieldType = context3?.isInputField !== false ? "input" : "output";
6690
- throw new Error(`Value for ${fieldType} field '${field.name}' is required.`);
6691
7184
  }
6692
- return false;
6693
- };
6694
- function formatDescription(str) {
6695
- const value = str.trim();
6696
- return value.length > 0 ? `${value.charAt(0).toUpperCase()}${value.slice(1)}${value.endsWith(".") ? "" : "."}` : "";
6697
7185
  }
6698
-
6699
- // dsp/validate.ts
6700
- var ValidationError = class extends Error {
6701
- fields;
6702
- constructor({
6703
- message,
6704
- fields
6705
- }) {
6706
- super(message);
6707
- this.fields = fields;
6708
- this.name = this.constructor.name;
7186
+ function validateAndParseFieldValue(field, fieldValue) {
7187
+ if (!fieldValue || fieldValue === "" || /^(null|undefined)\s*$/i.test(fieldValue)) {
7188
+ if (field.isOptional) {
7189
+ return;
7190
+ }
7191
+ throw new ValidationError({
7192
+ message: "Required field is missing",
7193
+ fields: [field],
7194
+ value: fieldValue
7195
+ });
6709
7196
  }
6710
- getFixingInstructions = () => {
6711
- return this.fields.map((field) => ({
6712
- name: "outputError",
6713
- title: "Output Correction Required",
6714
- description: `The section labeled '${field.title}' either was not generated by the LLM or does not match the expected format of '${toFieldType(field.type)}'. ${this.message} Please revise your response to ensure it conforms to the specified format.`
6715
- }));
6716
- };
6717
- toString() {
6718
- return [
6719
- `${this.name}: ${this.message}`,
6720
- ...this.fields.map(
6721
- (field) => ` - ${field.title}: Expected format '${toFieldType(field.type)}'`
6722
- )
6723
- ].join("\n");
6724
- }
6725
- [Symbol.for("nodejs.util.inspect.custom")](_depth, _options) {
6726
- return this.toString();
6727
- }
6728
- };
6729
- function handleValidationError(mem, errorFields, ai, promptTemplate, sessionId) {
6730
- mem.add(
6731
- {
6732
- role: "user",
6733
- content: promptTemplate.renderExtraFields(errorFields)
6734
- },
6735
- sessionId
6736
- );
6737
- mem.addTag("error");
6738
- if (ai.getOptions().debug) {
6739
- const errors = errorFields.map((field) => `- ${field.title}: ${field.description}`).join("\n");
6740
- const logger = ai.getLogger();
6741
- logger(`\u274C Error Correction:
6742
- ${errors}`, {
6743
- tags: ["error"]
6744
- });
6745
- }
6746
- }
6747
-
6748
- // dsp/datetime.ts
6749
- function parseLLMFriendlyDate(field, dateStr, required = false) {
6750
- try {
6751
- return _parseLLMFriendlyDate(dateStr);
6752
- } catch (err) {
6753
- if (field.isOptional && !required) {
6754
- return;
7197
+ let value;
7198
+ if (field.type?.name === "json") {
7199
+ try {
7200
+ const text = extractBlock(fieldValue);
7201
+ value = JSON.parse(text);
7202
+ return value;
7203
+ } catch (e) {
7204
+ throw new ValidationError({
7205
+ message: "Invalid JSON: " + e.message,
7206
+ fields: [field],
7207
+ value: fieldValue
7208
+ });
6755
7209
  }
6756
- const message = err.message;
6757
- throw new ValidationError({ fields: [field], message, value: dateStr });
6758
7210
  }
6759
- }
6760
- function _parseLLMFriendlyDate(dateStr) {
6761
- if (!(0, import_moment_timezone.default)(dateStr, "YYYY-MM-DD", true).isValid()) {
6762
- throw new Error(
6763
- 'Invalid date format. Please provide the date in "YYYY-MM-DD" format.'
6764
- );
7211
+ if (field.type?.isArray) {
7212
+ try {
7213
+ try {
7214
+ value = JSON.parse(fieldValue);
7215
+ } catch {
7216
+ value = parseMarkdownList(fieldValue);
7217
+ }
7218
+ if (!Array.isArray(value)) {
7219
+ throw new Error("Expected an array");
7220
+ }
7221
+ } catch (e) {
7222
+ throw new ValidationError({
7223
+ message: "Invalid Array: " + e.message,
7224
+ fields: [field],
7225
+ value: fieldValue
7226
+ });
7227
+ }
6765
7228
  }
6766
- const date = import_moment_timezone.default.utc(dateStr, "YYYY-MM-DD").startOf("day");
6767
- return date.toDate();
6768
- }
6769
- function parseLLMFriendlyDateTime(field, dateStr, required = false) {
6770
7229
  try {
6771
- return _parseLLMFriendlyDateTime(dateStr);
6772
- } catch (err) {
6773
- if (field.isOptional && !required) {
6774
- return;
7230
+ if (Array.isArray(value)) {
7231
+ for (const [index, item] of value.entries()) {
7232
+ if (item !== void 0) {
7233
+ const v = typeof item === "string" ? item.trim() : item;
7234
+ value[index] = convertValueToType(field, v, true);
7235
+ }
7236
+ }
7237
+ } else {
7238
+ value = convertValueToType(field, fieldValue);
6775
7239
  }
6776
- const message = err.message;
6777
- throw new ValidationError({ fields: [field], message, value: dateStr });
7240
+ } catch (e) {
7241
+ throw new ValidationError({
7242
+ message: e.message,
7243
+ fields: [field],
7244
+ value: fieldValue
7245
+ });
7246
+ }
7247
+ if (typeof value === "string" && value === "") {
7248
+ return void 0;
6778
7249
  }
7250
+ return value;
6779
7251
  }
6780
- function _parseLLMFriendlyDateTime(dateTimeStr) {
6781
- const dateTimeRegex = /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}(?::\d{2})?) (.+)$/;
6782
- const match = dateTimeStr.match(dateTimeRegex);
7252
+ var extractBlock = (input) => {
7253
+ const markdownBlockPattern = /```([A-Za-z]*)\n([\s\S]*?)\n```/g;
7254
+ const match = markdownBlockPattern.exec(input);
6783
7255
  if (!match) {
6784
- throw new Error(
6785
- 'Invalid date and time format. Please provide the date and time in "YYYY-MM-DD HH:mm" or "YYYY-MM-DD HH:mm:ss" format, followed by the timezone.'
6786
- );
6787
- }
6788
- const [, dateTime, timeZone] = match;
6789
- if (!dateTime || !timeZone) {
6790
- throw new Error(
6791
- 'Invalid date and time format. Please provide the date and time in "YYYY-MM-DD HH:mm" or "YYYY-MM-DD HH:mm:ss" format, followed by the timezone.'
6792
- );
7256
+ return input;
6793
7257
  }
6794
- const zone = import_moment_timezone.default.tz.zone(timeZone);
6795
- if (!zone) {
6796
- throw new Error(
6797
- `Unrecognized time zone ${timeZone}. Please provide a valid time zone name, abbreviation, or offset. For example, "America/New_York", or "EST".`
6798
- );
7258
+ if (match.length === 3) {
7259
+ return match[2];
6799
7260
  }
6800
- const date = import_moment_timezone.default.tz(
6801
- dateTime,
6802
- ["YYYY-MM-DD HH:mm", "YYYY-MM-DD HH:mm:ss"],
6803
- zone.name
6804
- );
6805
- if (!date.isValid()) {
6806
- throw new Error(
6807
- "Invalid date and time values. Please ensure all components are correct."
6808
- );
7261
+ if (match.length === 2) {
7262
+ return match[1];
6809
7263
  }
6810
- return date.utc().toDate();
6811
- }
6812
- var formatDateWithTimezone = (date) => {
6813
- const momentDate = (0, import_moment_timezone.default)(date).utc();
6814
- return momentDate.format(`YYYY-MM-DD HH:mm:ss UTC`);
7264
+ return input;
6815
7265
  };
6816
7266
 
6817
- // dsp/extract.ts
6818
- var extractValues = (sig, values, content) => {
6819
- const xstate = { extractedFields: [], streamedIndex: {}, s: -1 };
6820
- streamingExtractValues(sig, values, xstate, content);
6821
- streamingExtractFinalValue(sig, values, xstate, content);
6822
- for (const field of sig.getOutputFields()) {
6823
- if (field.isInternal) {
6824
- delete values[field.name];
6825
- }
6826
- }
6827
- };
6828
- var checkMissingRequiredFields = (xstate, values, currentIndex) => {
6829
- const missingFields = [];
6830
- for (let i = 0; i < currentIndex; i++) {
6831
- const field = xstate.extractedFields[i];
6832
- if (field && !field.isOptional && values[field.name] === void 0) {
6833
- missingFields.push(field);
7267
+ // dsp/fieldProcessor.ts
7268
+ async function processFieldProcessors(fieldProcessors, values, mem, sessionId) {
7269
+ for (const processor of fieldProcessors) {
7270
+ if (values[processor.field.name] === void 0) {
7271
+ continue;
6834
7272
  }
6835
- }
6836
- if (missingFields.length > 0) {
6837
- throw new ValidationError({
6838
- message: `Required ${missingFields.length === 1 ? "field" : "fields"} not found`,
6839
- fields: missingFields
7273
+ const processFn = processor.process;
7274
+ const result = await processFn(values[processor.field.name], {
7275
+ sessionId,
7276
+ values,
7277
+ done: true
6840
7278
  });
7279
+ addToMemory(processor.field, mem, result, sessionId);
6841
7280
  }
6842
- };
6843
- var streamingExtractValues = (sig, values, xstate, content, streamingValidation = false) => {
6844
- const fields = sig.getOutputFields();
6845
- for (const [index, field] of fields.entries()) {
6846
- if (field.name in values) {
7281
+ }
7282
+ async function processStreamingFieldProcessors(fieldProcessors, content, xstate, mem, values, sessionId, done = false) {
7283
+ for (const processor of fieldProcessors) {
7284
+ if (xstate.currField?.name !== processor.field.name) {
6847
7285
  continue;
6848
7286
  }
6849
- const isFirst = xstate.extractedFields.length === 0;
6850
- const prefix = (isFirst ? "" : "\n") + field.title + ":";
6851
- let e = matchesContent(content, prefix, xstate.s);
6852
- switch (e) {
6853
- case -1:
6854
- if (streamingValidation && values.length == 0 && !field.isOptional) {
6855
- throw new ValidationError({
6856
- message: "Required field not found",
6857
- fields: [field]
6858
- });
6859
- }
6860
- continue;
6861
- // Field is not found, continue to the next field
6862
- case -2:
6863
- return true;
6864
- // Partial match at end, skip and gather more content
6865
- case -3:
6866
- return true;
6867
- // String is only whitespace, skip and gather more content
6868
- case -4:
6869
- xstate.inBlock = true;
6870
- return true;
6871
- }
6872
- let prefixLen = prefix.length;
6873
- if (xstate.currField) {
6874
- const val = content.substring(xstate.s, e).trim();
6875
- const parsedValue = validateAndParseFieldValue(xstate.currField, val);
6876
- if (parsedValue !== void 0) {
6877
- values[xstate.currField.name] = parsedValue;
6878
- }
6879
- if (xstate.prevFields) {
6880
- xstate.prevFields?.push({ field: xstate.currField, s: xstate.s, e });
6881
- } else {
6882
- xstate.prevFields = [{ field: xstate.currField, s: xstate.s, e }];
6883
- }
6884
- }
6885
- checkMissingRequiredFields(xstate, values, index);
6886
- xstate.s = e + prefixLen;
6887
- xstate.currField = field;
6888
- xstate.currFieldIndex = index;
6889
- if (!xstate.extractedFields.includes(field)) {
6890
- xstate.extractedFields.push(field);
6891
- }
6892
- if (xstate.streamedIndex[field.name] === void 0) {
6893
- xstate.streamedIndex[field.name] = 0;
7287
+ let value = content.substring(xstate.s);
7288
+ if (xstate.currField?.type?.name === "code") {
7289
+ value = value.replace(/^[ ]*```[a-zA-Z0-9]*\n\s*/, "");
7290
+ value = value.replace(/\s*```\s*$/, "");
6894
7291
  }
7292
+ const processFn = processor.process;
7293
+ const result = await processFn(value, {
7294
+ sessionId,
7295
+ values,
7296
+ done
7297
+ });
7298
+ addToMemory(xstate.currField, mem, result, sessionId);
6895
7299
  }
6896
- };
6897
- var streamingExtractFinalValue = (sig, values, xstate, content) => {
6898
- if (xstate.currField) {
6899
- let val = content.substring(xstate.s).trim();
6900
- const parsedValue = validateAndParseFieldValue(xstate.currField, val);
6901
- if (parsedValue !== void 0) {
6902
- values[xstate.currField.name] = parsedValue;
6903
- }
7300
+ }
7301
+ var addToMemory = (field, mem, result, sessionId) => {
7302
+ if (result === void 0 || typeof result === "string" && (result === "" || /^(null|undefined)\s*$/i.test(result))) {
7303
+ return;
6904
7304
  }
6905
- const sigFields = sig.getOutputFields();
6906
- checkMissingRequiredFields(xstate, values, sigFields.length);
6907
- };
6908
- var convertValueToType = (field, val, required = false) => {
6909
- switch (field.type?.name) {
6910
- case "code":
6911
- return extractBlock(val);
6912
- case "string":
6913
- return val;
6914
- case "number": {
6915
- const v = Number(val);
6916
- if (Number.isNaN(v)) {
6917
- if (field.isOptional && !required) {
6918
- return;
6919
- }
6920
- throw new Error("Invalid number");
6921
- }
6922
- return v;
6923
- }
6924
- case "boolean": {
6925
- if (typeof val === "boolean") {
6926
- return val;
6927
- }
6928
- const v = val.toLowerCase();
6929
- if (v === "true") {
6930
- return true;
6931
- } else if (v === "false") {
6932
- return false;
6933
- } else {
6934
- if (field.isOptional && !required) {
6935
- return;
6936
- }
6937
- throw new Error("Invalid boolean");
6938
- }
6939
- }
6940
- case "date":
6941
- return parseLLMFriendlyDate(field, val, required);
6942
- case "datetime":
6943
- return parseLLMFriendlyDateTime(field, val, required);
6944
- case "class":
6945
- const className = val;
6946
- if (field.type.options && !field.type.options.includes(className)) {
6947
- if (field.isOptional) {
6948
- return;
6949
- }
6950
- throw new Error(
6951
- `Invalid class '${val}', expected one of the following: ${field.type.options.join(", ")}`
6952
- );
6953
- }
6954
- return className;
6955
- default:
6956
- return val;
6957
- }
6958
- };
6959
- function* yieldDelta(content, field, s2, e, xstate) {
6960
- const { name: fieldName, isInternal } = field;
6961
- const { isArray: fieldIsArray, name: fieldTypeName } = field.type ?? {};
6962
- if (isInternal || fieldIsArray || fieldTypeName && fieldTypeName !== "string" && fieldTypeName !== "code") {
6963
- return;
6964
- }
6965
- const pos = xstate.streamedIndex[fieldName] ?? 0;
6966
- const isFirstChunk = pos === 0;
6967
- const d1 = content.substring(s2 + pos, e);
6968
- if (d1.length === 0) {
6969
- return;
6970
- }
6971
- let d2 = d1.replace(/\s+$/, "");
6972
- if (xstate.currField?.type?.name === "code") {
6973
- d2 = d2.replace(/\s*```\s*$/, "");
6974
- }
6975
- let d3 = isFirstChunk ? d2.trimStart() : d2;
6976
- if (xstate.currField?.type?.name === "code") {
6977
- d3 = d3.replace(/^[ ]*```[a-zA-Z0-9]*\n\s*/, "");
6978
- }
6979
- if (d3.length > 0) {
6980
- yield { [fieldName]: d3 };
6981
- xstate.streamedIndex[fieldName] = pos + d2.length;
6982
- }
6983
- }
6984
- function* streamValues(sig, content, values, xstate) {
6985
- for (const prevField of xstate.prevFields ?? []) {
6986
- const { field, s: s2, e } = prevField;
6987
- yield* yieldDelta(content, field, s2, e, xstate);
6988
- }
6989
- xstate.prevFields = void 0;
6990
- if (!xstate.currField || xstate.currField.isInternal) {
6991
- return;
6992
- }
6993
- yield* yieldDelta(
6994
- content,
6995
- xstate.currField,
6996
- xstate.s,
6997
- content.length,
6998
- xstate
6999
- );
7000
- const outputFields = sig.getOutputFields();
7001
- for (const key of Object.keys(values)) {
7002
- const field = outputFields.find((f2) => f2.name === key);
7003
- if (!field || field.isInternal) {
7004
- continue;
7005
- }
7006
- const value = values[key];
7007
- if (Array.isArray(value)) {
7008
- const s2 = xstate.streamedIndex?.[key] ?? 0;
7009
- const v = value.slice(s2);
7010
- if (v && v.length > 0) {
7011
- yield { [key]: v };
7012
- xstate.streamedIndex[key] = s2 + v.length;
7013
- }
7014
- continue;
7015
- }
7016
- if (!xstate.streamedIndex[key]) {
7017
- yield { [key]: value };
7018
- xstate.streamedIndex[key] = 1;
7019
- }
7020
- }
7021
- }
7022
- function validateAndParseFieldValue(field, fieldValue) {
7023
- if (!fieldValue || fieldValue === "" || /^(null|undefined)\s*$/i.test(fieldValue)) {
7024
- if (field.isOptional) {
7025
- return;
7026
- }
7027
- throw new ValidationError({
7028
- message: "Required field is missing",
7029
- fields: [field],
7030
- value: fieldValue
7031
- });
7032
- }
7033
- let value;
7034
- if (field.type?.name === "json") {
7035
- try {
7036
- const text = extractBlock(fieldValue);
7037
- value = JSON.parse(text);
7038
- return value;
7039
- } catch (e) {
7040
- throw new ValidationError({
7041
- message: "Invalid JSON: " + e.message,
7042
- fields: [field],
7043
- value: fieldValue
7044
- });
7045
- }
7046
- }
7047
- if (field.type?.isArray) {
7048
- try {
7049
- try {
7050
- value = JSON.parse(fieldValue);
7051
- } catch {
7052
- value = parseMarkdownList(fieldValue);
7053
- }
7054
- if (!Array.isArray(value)) {
7055
- throw new Error("Expected an array");
7056
- }
7057
- } catch (e) {
7058
- throw new ValidationError({
7059
- message: "Invalid Array: " + e.message,
7060
- fields: [field],
7061
- value: fieldValue
7062
- });
7063
- }
7064
- }
7065
- try {
7066
- if (Array.isArray(value)) {
7067
- for (const [index, item] of value.entries()) {
7068
- if (item !== void 0) {
7069
- const v = typeof item === "string" ? item.trim() : item;
7070
- value[index] = convertValueToType(field, v, true);
7071
- }
7072
- }
7073
- } else {
7074
- value = convertValueToType(field, fieldValue);
7075
- }
7076
- } catch (e) {
7077
- throw new ValidationError({
7078
- message: e.message,
7079
- fields: [field],
7080
- value: fieldValue
7081
- });
7082
- }
7083
- if (typeof value === "string" && value === "") {
7084
- return void 0;
7085
- }
7086
- return value;
7087
- }
7088
- var extractBlock = (input) => {
7089
- const markdownBlockPattern = /```([A-Za-z]*)\n([\s\S]*?)\n```/g;
7090
- const match = markdownBlockPattern.exec(input);
7091
- if (!match) {
7092
- return input;
7093
- }
7094
- if (match.length === 3) {
7095
- return match[2];
7096
- }
7097
- if (match.length === 2) {
7098
- return match[1];
7099
- }
7100
- return input;
7101
- };
7102
-
7103
- // dsp/fieldProcessor.ts
7104
- async function processFieldProcessors(fieldProcessors, values, mem, sessionId) {
7105
- for (const processor of fieldProcessors) {
7106
- if (values[processor.field.name] === void 0) {
7107
- continue;
7108
- }
7109
- const processFn = processor.process;
7110
- const result = await processFn(values[processor.field.name], {
7111
- sessionId,
7112
- values,
7113
- done: true
7114
- });
7115
- addToMemory(processor.field, mem, result, sessionId);
7116
- }
7117
- }
7118
- async function processStreamingFieldProcessors(fieldProcessors, content, xstate, mem, values, sessionId, done = false) {
7119
- for (const processor of fieldProcessors) {
7120
- if (xstate.currField?.name !== processor.field.name) {
7121
- continue;
7122
- }
7123
- let value = content.substring(xstate.s);
7124
- if (xstate.currField?.type?.name === "code") {
7125
- value = value.replace(/^[ ]*```[a-zA-Z0-9]*\n\s*/, "");
7126
- value = value.replace(/\s*```\s*$/, "");
7127
- }
7128
- const processFn = processor.process;
7129
- const result = await processFn(value, {
7130
- sessionId,
7131
- values,
7132
- done
7133
- });
7134
- addToMemory(xstate.currField, mem, result, sessionId);
7135
- }
7136
- }
7137
- var addToMemory = (field, mem, result, sessionId) => {
7138
- if (result === void 0 || typeof result === "string" && (result === "" || /^(null|undefined)\s*$/i.test(result))) {
7139
- return;
7140
- }
7141
- let resultText = JSON.stringify(
7142
- result,
7143
- (key, value) => typeof value === "bigint" ? Number(value) : value,
7144
- 2
7145
- );
7146
- const text = getFieldProcessingMessage(field, resultText);
7147
- mem.add({ role: "user", content: [{ type: "text", text }] }, sessionId);
7148
- mem.addTag(`processor`, sessionId);
7305
+ let resultText = JSON.stringify(
7306
+ result,
7307
+ (key, value) => typeof value === "bigint" ? Number(value) : value,
7308
+ 2
7309
+ );
7310
+ const text = getFieldProcessingMessage(field, resultText);
7311
+ mem.addRequest(
7312
+ [{ role: "user", content: [{ type: "text", text }] }],
7313
+ sessionId
7314
+ );
7315
+ mem.addTag(`processor`, sessionId);
7149
7316
  };
7150
7317
  function getFieldProcessingMessage(field, resultText) {
7151
7318
  const isCodeField = field.type?.name === "code";
@@ -7403,10 +7570,10 @@ var AxFunctionProcessor = class {
7403
7570
  } : void 0;
7404
7571
  if (!fnSpec.parameters) {
7405
7572
  const res2 = fnSpec.func.length === 1 ? await fnSpec.func(opt) : await fnSpec.func();
7406
- return typeof res2 === "string" ? res2 : JSON.stringify(res2, null, 2);
7573
+ return typeof res2 === "string" ? res2 : res2 === void 0 || res2 === null ? "" : JSON.stringify(res2, null, 2);
7407
7574
  }
7408
7575
  const res = fnSpec.func.length === 2 ? await fnSpec.func(args, opt) : await fnSpec.func(args);
7409
- return typeof res === "string" ? res : JSON.stringify(res, null, 2);
7576
+ return typeof res === "string" ? res : res === void 0 || res === null ? "" : JSON.stringify(res, null, 2);
7410
7577
  };
7411
7578
  execute = async (func, options) => {
7412
7579
  const fnSpec = this.funcList.find(
@@ -7445,7 +7612,17 @@ var parseFunctions = (newFuncs, existingFuncs) => {
7445
7612
  }
7446
7613
  return [...existingFuncs ?? [], ...functions];
7447
7614
  };
7448
- var processFunctions = async (ai, functionList, functionCalls, mem, sessionId, traceId, span, excludeContentFromTelemetry) => {
7615
+ var processFunctions = async ({
7616
+ ai,
7617
+ functionList,
7618
+ functionCalls,
7619
+ mem,
7620
+ sessionId,
7621
+ traceId,
7622
+ span,
7623
+ excludeContentFromTrace,
7624
+ index
7625
+ }) => {
7449
7626
  const funcProc = new AxFunctionProcessor(functionList);
7450
7627
  const functionsExecuted = /* @__PURE__ */ new Set();
7451
7628
  const promises = functionCalls.map((func) => {
@@ -7458,16 +7635,16 @@ var processFunctions = async (ai, functionList, functionCalls, mem, sessionId, t
7458
7635
  const eventData = {
7459
7636
  name: func.name
7460
7637
  };
7461
- if (!excludeContentFromTelemetry) {
7638
+ if (!excludeContentFromTrace) {
7462
7639
  eventData.args = func.args;
7463
7640
  eventData.result = functionResult ?? "";
7464
7641
  }
7465
7642
  span.addEvent("function.call", eventData);
7466
7643
  }
7467
7644
  return {
7468
- role: "function",
7469
7645
  result: functionResult ?? "",
7470
- functionId: func.id
7646
+ functionId: func.id,
7647
+ index
7471
7648
  };
7472
7649
  }).catch((e) => {
7473
7650
  if (e instanceof FunctionError) {
@@ -7477,22 +7654,22 @@ var processFunctions = async (ai, functionList, functionCalls, mem, sessionId, t
7477
7654
  name: func.name,
7478
7655
  message: e.toString()
7479
7656
  };
7480
- if (!excludeContentFromTelemetry) {
7657
+ if (!excludeContentFromTrace) {
7481
7658
  errorEventData.args = func.args;
7482
7659
  errorEventData.fixing_instructions = result;
7483
7660
  }
7484
7661
  span.addEvent("function.error", errorEventData);
7485
7662
  }
7486
- mem.add(
7663
+ mem.addFunctionResult(
7487
7664
  {
7488
- role: "function",
7489
7665
  functionId: func.id,
7490
7666
  isError: true,
7667
+ index,
7491
7668
  result
7492
7669
  },
7493
7670
  sessionId
7494
7671
  );
7495
- mem.addTag("error");
7672
+ mem.addTag("error", sessionId);
7496
7673
  if (ai.getOptions().debug) {
7497
7674
  const logger = ai.getLogger();
7498
7675
  logger(`\u274C Function Error Correction:
@@ -7509,7 +7686,7 @@ ${result}`, {
7509
7686
  const results = await Promise.all(promises);
7510
7687
  for (const result of results) {
7511
7688
  if (result) {
7512
- mem.add(result, sessionId);
7689
+ mem.addFunctionResult(result, sessionId);
7513
7690
  }
7514
7691
  }
7515
7692
  return functionsExecuted;
@@ -7529,34 +7706,39 @@ function parseFunctionCalls(ai, functionCalls, values, model) {
7529
7706
  return funcs;
7530
7707
  }
7531
7708
 
7532
- // dsp/registry.ts
7533
- var AxInstanceRegistry = class {
7534
- reg;
7535
- // To track keys for iteration
7536
- constructor() {
7537
- this.reg = /* @__PURE__ */ new Set();
7538
- }
7539
- register(instance) {
7540
- this.reg.add(instance);
7541
- }
7542
- *[Symbol.iterator]() {
7543
- const items = Array.from(this.reg);
7544
- for (let i = 0; i < items.length; i++) {
7545
- yield items[i];
7546
- }
7547
- }
7548
- };
7549
-
7550
- // dsp/sig.ts
7551
- var import_crypto3 = require("crypto");
7552
-
7553
- // dsp/globals.ts
7554
- var axGlobals = {
7555
- signatureStrict: true
7556
- // Controls reservedNames enforcement in signature parsing/validation
7557
- };
7709
+ // dsp/processResponse.ts
7710
+ var import_web5 = require("stream/web");
7558
7711
 
7559
- // dsp/parser.ts
7712
+ // ai/util.ts
7713
+ function mergeFunctionCalls(functionCalls, functionCallDeltas) {
7714
+ for (const _fc of functionCallDeltas) {
7715
+ const fc = functionCalls.find((fc2) => fc2.id === _fc.id);
7716
+ if (fc) {
7717
+ if (typeof _fc.function.name == "string" && _fc.function.name.length > 0) {
7718
+ fc.function.name += _fc.function.name;
7719
+ }
7720
+ if (typeof _fc.function.params == "string" && _fc.function.params.length > 0) {
7721
+ fc.function.params += _fc.function.params;
7722
+ }
7723
+ if (typeof _fc.function.params == "object") {
7724
+ fc.function.params = _fc.function.params;
7725
+ }
7726
+ } else {
7727
+ functionCalls.push(_fc);
7728
+ }
7729
+ }
7730
+ }
7731
+
7732
+ // dsp/sig.ts
7733
+ var import_crypto3 = require("crypto");
7734
+
7735
+ // dsp/globals.ts
7736
+ var axGlobals = {
7737
+ signatureStrict: true
7738
+ // Controls reservedNames enforcement in signature parsing/validation
7739
+ };
7740
+
7741
+ // dsp/parser.ts
7560
7742
  var SignatureValidationError = class extends Error {
7561
7743
  constructor(message, position, context3, suggestion) {
7562
7744
  super(message);
@@ -8755,32 +8937,828 @@ function validateFieldType(field, context3) {
8755
8937
  );
8756
8938
  }
8757
8939
  }
8758
- const uniqueOptions = new Set(
8759
- type.options.map((opt) => opt.trim().toLowerCase())
8760
- );
8761
- if (uniqueOptions.size !== type.options.length) {
8762
- throw new AxSignatureValidationError(
8763
- "Duplicate class options found",
8764
- field.name,
8765
- "Each class option must be unique (case-insensitive)"
8766
- );
8940
+ const uniqueOptions = new Set(
8941
+ type.options.map((opt) => opt.trim().toLowerCase())
8942
+ );
8943
+ if (uniqueOptions.size !== type.options.length) {
8944
+ throw new AxSignatureValidationError(
8945
+ "Duplicate class options found",
8946
+ field.name,
8947
+ "Each class option must be unique (case-insensitive)"
8948
+ );
8949
+ }
8950
+ }
8951
+ if (type.name === "code" && type.isArray) {
8952
+ throw new AxSignatureValidationError(
8953
+ "Arrays of code are not commonly supported",
8954
+ field.name,
8955
+ "Consider using a single code field or an array of strings instead"
8956
+ );
8957
+ }
8958
+ if (field.isInternal && context3 === "input") {
8959
+ throw new AxSignatureValidationError(
8960
+ "Internal marker (!) is not allowed on input fields",
8961
+ field.name,
8962
+ "Internal markers are only allowed on output fields"
8963
+ );
8964
+ }
8965
+ }
8966
+
8967
+ // dsp/processResponse.ts
8968
+ async function* processStreamingResponse({
8969
+ res,
8970
+ usage,
8971
+ states,
8972
+ ...args
8973
+ }) {
8974
+ const skipEarlyFail = (args.ai.getFeatures().functionCot ?? false) && args.functions !== void 0 && args.functions.length > 0;
8975
+ for await (const v of res) {
8976
+ if (v.modelUsage) {
8977
+ usage.push(v.modelUsage);
8978
+ }
8979
+ for (const result of v.results) {
8980
+ if (result.content === "" && (!result.functionCalls || result.functionCalls.length === 0)) {
8981
+ continue;
8982
+ }
8983
+ const state = states.find((s2) => s2.index === result.index);
8984
+ if (!state) {
8985
+ throw new Error(`No state found for result (index: ${result.index})`);
8986
+ }
8987
+ yield* _processStreamingResponse({
8988
+ ...args,
8989
+ result,
8990
+ skipEarlyFail,
8991
+ state
8992
+ });
8993
+ }
8994
+ }
8995
+ for (const state of states) {
8996
+ yield* finalizeStreamingResponse({
8997
+ ...args,
8998
+ state
8999
+ });
9000
+ }
9001
+ }
9002
+ async function* _processStreamingResponse({
9003
+ result,
9004
+ mem,
9005
+ sessionId,
9006
+ strictMode,
9007
+ skipEarlyFail,
9008
+ state,
9009
+ signature,
9010
+ streamingFieldProcessors,
9011
+ thoughtFieldName,
9012
+ streamingAsserts,
9013
+ asserts
9014
+ }) {
9015
+ if (result.functionCalls && result.functionCalls.length > 0) {
9016
+ mergeFunctionCalls(state.functionCalls, result.functionCalls);
9017
+ mem.updateResult(
9018
+ {
9019
+ name: result.name,
9020
+ content: result.content,
9021
+ functionCalls: state.functionCalls,
9022
+ delta: result.functionCalls?.[0]?.function?.params,
9023
+ index: result.index
9024
+ },
9025
+ sessionId
9026
+ );
9027
+ } else if (result.content && result.content.length > 0) {
9028
+ if (result.thought && result.thought.length > 0) {
9029
+ yield {
9030
+ index: result.index,
9031
+ delta: { [thoughtFieldName]: result.thought }
9032
+ };
9033
+ }
9034
+ state.content += result.content;
9035
+ mem.updateResult(
9036
+ {
9037
+ name: result.name,
9038
+ content: state.content,
9039
+ delta: result.content,
9040
+ index: result.index
9041
+ },
9042
+ sessionId
9043
+ );
9044
+ const skip = streamingExtractValues(
9045
+ signature,
9046
+ state.values,
9047
+ state.xstate,
9048
+ state.content,
9049
+ { strictMode, skipEarlyFail }
9050
+ );
9051
+ if (skip) {
9052
+ return;
9053
+ }
9054
+ if (streamingAsserts.length !== 0) {
9055
+ await assertStreamingAssertions(
9056
+ streamingAsserts,
9057
+ state.xstate,
9058
+ state.content
9059
+ );
9060
+ }
9061
+ if (streamingFieldProcessors.length !== 0) {
9062
+ await processStreamingFieldProcessors(
9063
+ streamingFieldProcessors,
9064
+ state.content,
9065
+ state.xstate,
9066
+ mem,
9067
+ state.values,
9068
+ sessionId
9069
+ );
9070
+ }
9071
+ yield* streamValues(
9072
+ signature,
9073
+ state.content,
9074
+ state.values,
9075
+ state.xstate,
9076
+ result.index
9077
+ );
9078
+ await assertAssertions(asserts, state.values);
9079
+ } else if (result.thought && result.thought.length > 0) {
9080
+ state.values[thoughtFieldName] = (state.values[thoughtFieldName] ?? "") + result.thought;
9081
+ yield {
9082
+ index: result.index,
9083
+ delta: { [thoughtFieldName]: result.thought }
9084
+ };
9085
+ }
9086
+ if (result.finishReason === "length") {
9087
+ throw new Error(
9088
+ `Max tokens reached before completion
9089
+ Content: ${state.content}`
9090
+ );
9091
+ }
9092
+ }
9093
+ async function* finalizeStreamingResponse({
9094
+ state,
9095
+ signature,
9096
+ ai,
9097
+ model,
9098
+ functions,
9099
+ mem,
9100
+ sessionId,
9101
+ traceId,
9102
+ span,
9103
+ excludeContentFromTrace,
9104
+ streamingAsserts,
9105
+ asserts,
9106
+ fieldProcessors,
9107
+ streamingFieldProcessors
9108
+ }) {
9109
+ const funcs = parseFunctionCalls(ai, state.functionCalls, state.values, model);
9110
+ if (funcs) {
9111
+ if (!functions) {
9112
+ throw new Error("Functions are not defined");
9113
+ }
9114
+ const fx = await processFunctions({
9115
+ ai,
9116
+ functionList: functions,
9117
+ functionCalls: funcs,
9118
+ mem,
9119
+ sessionId,
9120
+ traceId,
9121
+ span,
9122
+ index: state.index,
9123
+ excludeContentFromTrace
9124
+ });
9125
+ state.functionsExecuted = /* @__PURE__ */ new Set([...state.functionsExecuted, ...fx]);
9126
+ } else {
9127
+ streamingExtractFinalValue(
9128
+ signature,
9129
+ state.values,
9130
+ state.xstate,
9131
+ state.content
9132
+ );
9133
+ await assertStreamingAssertions(
9134
+ streamingAsserts,
9135
+ state.xstate,
9136
+ state.content,
9137
+ true
9138
+ );
9139
+ await assertAssertions(asserts, state.values);
9140
+ if (fieldProcessors.length) {
9141
+ await processFieldProcessors(
9142
+ fieldProcessors,
9143
+ state.values,
9144
+ mem,
9145
+ sessionId
9146
+ );
9147
+ }
9148
+ if (streamingFieldProcessors.length !== 0) {
9149
+ await processStreamingFieldProcessors(
9150
+ streamingFieldProcessors,
9151
+ state.content,
9152
+ state.xstate,
9153
+ mem,
9154
+ state.values,
9155
+ sessionId,
9156
+ true
9157
+ );
9158
+ }
9159
+ yield* streamValues(
9160
+ signature,
9161
+ state.content,
9162
+ state.values,
9163
+ state.xstate,
9164
+ state.index
9165
+ );
9166
+ }
9167
+ }
9168
+ async function* processResponse({
9169
+ ai,
9170
+ res,
9171
+ mem,
9172
+ sessionId,
9173
+ traceId,
9174
+ functions,
9175
+ span,
9176
+ strictMode,
9177
+ states,
9178
+ usage,
9179
+ excludeContentFromTrace,
9180
+ asserts,
9181
+ fieldProcessors,
9182
+ thoughtFieldName,
9183
+ signature
9184
+ }) {
9185
+ let results = res.results ?? [];
9186
+ mem.addResponse(results, sessionId);
9187
+ for (const result of results) {
9188
+ const state = states[result.index];
9189
+ if (!state) {
9190
+ throw new Error(`No state found for result (index: ${result.index})`);
9191
+ }
9192
+ if (res.modelUsage) {
9193
+ usage.push(res.modelUsage);
9194
+ }
9195
+ if (result.functionCalls?.length) {
9196
+ const funcs = parseFunctionCalls(ai, result.functionCalls, state.values);
9197
+ if (funcs) {
9198
+ if (!functions) {
9199
+ throw new Error("Functions are not defined");
9200
+ }
9201
+ const fx = await processFunctions({
9202
+ ai,
9203
+ functionList: functions,
9204
+ functionCalls: funcs,
9205
+ mem,
9206
+ sessionId,
9207
+ traceId,
9208
+ span,
9209
+ excludeContentFromTrace,
9210
+ index: result.index
9211
+ });
9212
+ state.functionsExecuted = /* @__PURE__ */ new Set([...state.functionsExecuted, ...fx]);
9213
+ }
9214
+ } else if (result.content) {
9215
+ if (result.thought && result.thought.length > 0) {
9216
+ state.values[thoughtFieldName] = result.thought;
9217
+ }
9218
+ extractValues(signature, state.values, result.content, strictMode);
9219
+ await assertAssertions(asserts, state.values);
9220
+ if (fieldProcessors.length) {
9221
+ await processFieldProcessors(
9222
+ fieldProcessors,
9223
+ state.values,
9224
+ mem,
9225
+ sessionId
9226
+ );
9227
+ }
9228
+ }
9229
+ if (result.finishReason === "length") {
9230
+ throw new Error(
9231
+ `Max tokens reached before completion
9232
+ Content: ${result.content}`
9233
+ );
9234
+ }
9235
+ }
9236
+ const values = states.map((s2) => s2.values);
9237
+ for (const v of values) {
9238
+ for (const field of signature.getOutputFields()) {
9239
+ if (field.isInternal) {
9240
+ delete v[field.name];
9241
+ }
9242
+ }
9243
+ }
9244
+ const outputFields = signature.getOutputFields();
9245
+ const deltas = values.map((v, index) => {
9246
+ const delta = {};
9247
+ for (const field of outputFields) {
9248
+ if (field.isInternal) {
9249
+ continue;
9250
+ }
9251
+ delta[field.name] = v[field.name];
9252
+ }
9253
+ if (v[thoughtFieldName] !== void 0) {
9254
+ delta[thoughtFieldName] = v[thoughtFieldName];
9255
+ }
9256
+ return { index, delta };
9257
+ });
9258
+ for (const delta of deltas) {
9259
+ yield delta;
9260
+ }
9261
+ }
9262
+ function shouldContinueSteps(mem, stopFunction, states, sessionId) {
9263
+ const lastMemItem = mem.getLast(sessionId);
9264
+ if (!lastMemItem) {
9265
+ return true;
9266
+ }
9267
+ for (const [index, state] of states.entries()) {
9268
+ const stopFunctionExecuted = stopFunction && state.functionsExecuted.has(stopFunction);
9269
+ const chat = lastMemItem.chat[index];
9270
+ if (!chat) {
9271
+ throw new Error(`No chat message found for result (index: ${index})`);
9272
+ }
9273
+ const isFunction = lastMemItem.role === "function";
9274
+ const isProcessor = lastMemItem.tags ? lastMemItem.tags.some((tag) => tag === "processor") : false;
9275
+ if (isFunction && stopFunction && stopFunctionExecuted) {
9276
+ return false;
9277
+ }
9278
+ if (!(isFunction || isProcessor)) {
9279
+ return false;
9280
+ }
9281
+ }
9282
+ return true;
9283
+ }
9284
+
9285
+ // dsp/prompt.ts
9286
+ var functionCallInstructions = `
9287
+ ## Function Call Instructions
9288
+ - Complete the task, using the functions defined earlier in this prompt.
9289
+ - Output fields should only be generated after all functions have been called.
9290
+ - Use the function results to generate the output fields.`;
9291
+ var formattingRules = `
9292
+ ## Strict Output Formatting Rules
9293
+ - Output must strictly follow the defined plain-text \`field name: value\` field format.
9294
+ - Output field, values must strictly adhere to the specified output field formatting rules.
9295
+ - No formatting rules should override these **Strict Output Formatting Rules**
9296
+ - Do not add any text before or after the output fields, just the field name and value.
9297
+ - Do not use code blocks.`;
9298
+ var AxPromptTemplate = class {
9299
+ sig;
9300
+ fieldTemplates;
9301
+ task;
9302
+ thoughtFieldName;
9303
+ functions;
9304
+ constructor(sig, options, fieldTemplates) {
9305
+ this.sig = sig;
9306
+ this.fieldTemplates = fieldTemplates;
9307
+ this.thoughtFieldName = options?.thoughtFieldName ?? "thought";
9308
+ this.functions = options?.functions;
9309
+ const task = [];
9310
+ const inArgs = renderDescFields(this.sig.getInputFields());
9311
+ const outArgs = renderDescFields(this.sig.getOutputFields());
9312
+ task.push(
9313
+ `You will be provided with the following fields: ${inArgs}. Your task is to generate new fields: ${outArgs}.`
9314
+ );
9315
+ const funcs = this.functions?.map((f2) => "toFunction" in f2 ? f2.toFunction() : f2)?.flat();
9316
+ const funcList = funcs?.map((fn) => `- \`${fn.name}\`: ${formatDescription(fn.description)}`).join("\n");
9317
+ if (funcList && funcList.length > 0) {
9318
+ task.push(`## Available Functions
9319
+ ${funcList}`);
9320
+ }
9321
+ const inputFields = renderInputFields(this.sig.getInputFields());
9322
+ task.push(`## Input Fields
9323
+ ${inputFields}`);
9324
+ const outputFields = renderOutputFields(this.sig.getOutputFields());
9325
+ task.push(`## Output Fields
9326
+ ${outputFields}`);
9327
+ if (funcList && funcList.length > 0) {
9328
+ task.push(functionCallInstructions.trim());
9329
+ }
9330
+ task.push(formattingRules.trim());
9331
+ const desc = this.sig.getDescription();
9332
+ if (desc) {
9333
+ const text = formatDescription(desc);
9334
+ task.push(text);
9335
+ }
9336
+ this.task = {
9337
+ type: "text",
9338
+ text: task.join("\n\n")
9339
+ };
9340
+ }
9341
+ renderSingleValueUserContent = (values, renderedExamples, renderedDemos, examplesInSystemPrompt) => {
9342
+ const completion = this.renderInputFields(values);
9343
+ const promptList = examplesInSystemPrompt ? completion : [...renderedExamples, ...renderedDemos, ...completion];
9344
+ const prompt = promptList.filter((v) => v !== void 0);
9345
+ return prompt.every((v) => v.type === "text") ? prompt.map((v) => v.text).join("\n") : prompt.reduce(combineConsecutiveStrings("\n"), []);
9346
+ };
9347
+ render = (values, {
9348
+ examples,
9349
+ demos
9350
+ }) => {
9351
+ const renderedExamples = examples ? [
9352
+ { type: "text", text: "\n\n## Examples\n" },
9353
+ ...this.renderExamples(examples)
9354
+ ] : [];
9355
+ const renderedDemos = demos ? this.renderDemos(demos) : [];
9356
+ const allTextExamples = renderedExamples.every((v) => v.type === "text");
9357
+ const allTextDemos = renderedDemos.every((v) => v.type === "text");
9358
+ const examplesInSystemPrompt = allTextExamples && allTextDemos;
9359
+ let systemContent = this.task.text;
9360
+ if (examplesInSystemPrompt) {
9361
+ const combinedItems = [
9362
+ { type: "text", text: systemContent },
9363
+ ...renderedExamples,
9364
+ ...renderedDemos
9365
+ ];
9366
+ combinedItems.reduce(combineConsecutiveStrings(""), []);
9367
+ if (combinedItems && combinedItems[0]) {
9368
+ systemContent = combinedItems[0].text;
9369
+ }
9370
+ }
9371
+ const systemPrompt = {
9372
+ role: "system",
9373
+ content: systemContent
9374
+ };
9375
+ if (Array.isArray(values)) {
9376
+ let messages = [];
9377
+ const history = values;
9378
+ let firstItem = true;
9379
+ for (const message of history) {
9380
+ let content;
9381
+ if (firstItem) {
9382
+ content = this.renderSingleValueUserContent(
9383
+ message.values,
9384
+ renderedExamples,
9385
+ renderedDemos,
9386
+ examplesInSystemPrompt
9387
+ );
9388
+ firstItem = false;
9389
+ } else {
9390
+ content = this.renderSingleValueUserContent(
9391
+ message.values,
9392
+ [],
9393
+ [],
9394
+ false
9395
+ );
9396
+ }
9397
+ if (message.role === "user") {
9398
+ messages.push({ role: "user", content });
9399
+ continue;
9400
+ }
9401
+ if (message.role !== "assistant") {
9402
+ throw new Error("Invalid message role");
9403
+ }
9404
+ if (typeof content !== "string") {
9405
+ throw new Error(
9406
+ "Assistant message cannot contain non-text content like images, files,etc"
9407
+ );
9408
+ }
9409
+ messages.push({ role: "assistant", content });
9410
+ }
9411
+ return [systemPrompt, ...messages];
9412
+ }
9413
+ const userContent = this.renderSingleValueUserContent(
9414
+ values,
9415
+ renderedExamples,
9416
+ renderedDemos,
9417
+ examplesInSystemPrompt
9418
+ );
9419
+ return [systemPrompt, { role: "user", content: userContent }];
9420
+ };
9421
+ renderExtraFields = (extraFields) => {
9422
+ const prompt = [];
9423
+ if (!extraFields || extraFields.length === 0) {
9424
+ return prompt;
9425
+ }
9426
+ const groupedFields = extraFields.reduce(
9427
+ (acc, field) => {
9428
+ const title = field.title;
9429
+ if (!acc[title]) {
9430
+ acc[title] = [];
9431
+ }
9432
+ acc[title].push(field);
9433
+ return acc;
9434
+ },
9435
+ {}
9436
+ );
9437
+ const formattedGroupedFields = Object.entries(groupedFields).map(([title, fields]) => {
9438
+ if (fields.length === 1) {
9439
+ const field = fields[0];
9440
+ return {
9441
+ title,
9442
+ name: field.name,
9443
+ description: field.description
9444
+ };
9445
+ } else if (fields.length > 1) {
9446
+ const valuesList = fields.map((field) => `- ${field.description}`).join("\n");
9447
+ return {
9448
+ title,
9449
+ name: fields[0].name,
9450
+ description: valuesList
9451
+ };
9452
+ }
9453
+ }).filter(Boolean);
9454
+ formattedGroupedFields.forEach((field) => {
9455
+ const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
9456
+ prompt.push(...fn(field, field.description));
9457
+ });
9458
+ return prompt;
9459
+ };
9460
+ renderExamples = (data) => {
9461
+ const list = [];
9462
+ const exampleContext = {
9463
+ isExample: true
9464
+ };
9465
+ for (const [index, item] of data.entries()) {
9466
+ const renderedInputItem = this.sig.getInputFields().map(
9467
+ (field) => this.renderInField(field, item, {
9468
+ ...exampleContext,
9469
+ isInputField: true
9470
+ })
9471
+ ).filter((v) => v !== void 0).flat();
9472
+ const renderedOutputItem = this.sig.getOutputFields().map(
9473
+ (field) => this.renderInField(field, item, {
9474
+ ...exampleContext,
9475
+ isInputField: false
9476
+ })
9477
+ ).filter((v) => v !== void 0).flat();
9478
+ const renderedItem = [...renderedInputItem, ...renderedOutputItem];
9479
+ if (index > 0 && renderedItem.length > 0 && renderedItem[0]?.type === "text") {
9480
+ list.push({ type: "text", text: "---\n\n" });
9481
+ }
9482
+ renderedItem.forEach((v) => {
9483
+ if ("text" in v) {
9484
+ v.text = v.text + "\n";
9485
+ }
9486
+ list.push(v);
9487
+ });
9488
+ }
9489
+ return list;
9490
+ };
9491
+ renderDemos = (data) => {
9492
+ const list = [];
9493
+ const inputFields = this.sig.getInputFields();
9494
+ const outputFields = this.sig.getOutputFields();
9495
+ const demoContext = {
9496
+ isExample: true
9497
+ };
9498
+ for (const item of data) {
9499
+ const inputRenderedItems = inputFields.map(
9500
+ (field) => this.renderInField(field, item, {
9501
+ ...demoContext,
9502
+ isInputField: true
9503
+ })
9504
+ ).filter((v) => v !== void 0).flat();
9505
+ const outputRenderedItems = outputFields.map(
9506
+ (field) => this.renderInField(field, item, {
9507
+ ...demoContext,
9508
+ isInputField: false
9509
+ })
9510
+ ).filter((v) => v !== void 0).flat();
9511
+ const renderedItem = [...inputRenderedItems, ...outputRenderedItems];
9512
+ renderedItem.slice(0, -1).forEach((v) => {
9513
+ if ("text" in v) {
9514
+ v.text = v.text + "\n";
9515
+ }
9516
+ list.push(v);
9517
+ });
9518
+ }
9519
+ return list;
9520
+ };
9521
+ renderInputFields = (values) => {
9522
+ const renderedItems = this.sig.getInputFields().map((field) => this.renderInField(field, values, void 0)).filter((v) => v !== void 0).flat();
9523
+ renderedItems.filter((v) => v.type === "text").forEach((v) => {
9524
+ v.text = v.text + "\n";
9525
+ });
9526
+ return renderedItems;
9527
+ };
9528
+ renderInField = (field, values, context3) => {
9529
+ const value = values[field.name];
9530
+ if (isEmptyValue(field, value, context3)) {
9531
+ return;
9532
+ }
9533
+ if (field.type) {
9534
+ validateValue(field, value);
9535
+ }
9536
+ const processedValue = processValue(field, value);
9537
+ const textFieldFn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
9538
+ return textFieldFn(field, processedValue);
9539
+ };
9540
+ defaultRenderInField = (field, value) => {
9541
+ if (field.type?.name === "image") {
9542
+ const validateImage = (value2) => {
9543
+ if (!value2) {
9544
+ throw new Error("Image field value is required.");
9545
+ }
9546
+ if (typeof value2 !== "object") {
9547
+ throw new Error("Image field value must be an object.");
9548
+ }
9549
+ if (!("mimeType" in value2)) {
9550
+ throw new Error("Image field must have mimeType");
9551
+ }
9552
+ if (!("data" in value2)) {
9553
+ throw new Error("Image field must have data");
9554
+ }
9555
+ return value2;
9556
+ };
9557
+ let result = [
9558
+ { type: "text", text: `${field.title}: ` }
9559
+ ];
9560
+ if (field.type.isArray) {
9561
+ if (!Array.isArray(value)) {
9562
+ throw new Error("Image field value must be an array.");
9563
+ }
9564
+ result = result.concat(
9565
+ value.map((v) => {
9566
+ const validated = validateImage(v);
9567
+ return {
9568
+ type: "image",
9569
+ mimeType: validated.mimeType,
9570
+ image: validated.data
9571
+ };
9572
+ })
9573
+ );
9574
+ } else {
9575
+ const validated = validateImage(value);
9576
+ result.push({
9577
+ type: "image",
9578
+ mimeType: validated.mimeType,
9579
+ image: validated.data
9580
+ });
9581
+ }
9582
+ return result;
9583
+ }
9584
+ if (field.type?.name === "audio") {
9585
+ const validateAudio = (value2) => {
9586
+ if (!value2) {
9587
+ throw new Error("Audio field value is required.");
9588
+ }
9589
+ if (typeof value2 !== "object") {
9590
+ throw new Error("Audio field value must be an object.");
9591
+ }
9592
+ if (!("data" in value2)) {
9593
+ throw new Error("Audio field must have data");
9594
+ }
9595
+ return value2;
9596
+ };
9597
+ let result = [
9598
+ { type: "text", text: `${field.title}: ` }
9599
+ ];
9600
+ if (field.type.isArray) {
9601
+ if (!Array.isArray(value)) {
9602
+ throw new Error("Audio field value must be an array.");
9603
+ }
9604
+ result = result.concat(
9605
+ value.map((v) => {
9606
+ const validated = validateAudio(v);
9607
+ return {
9608
+ type: "audio",
9609
+ format: validated.format ?? "wav",
9610
+ data: validated.data
9611
+ };
9612
+ })
9613
+ );
9614
+ } else {
9615
+ const validated = validateAudio(value);
9616
+ result.push({
9617
+ type: "audio",
9618
+ format: validated.format ?? "wav",
9619
+ data: validated.data
9620
+ });
9621
+ }
9622
+ return result;
9623
+ }
9624
+ const text = [field.title, ": "];
9625
+ if (Array.isArray(value)) {
9626
+ text.push("\n");
9627
+ text.push(value.map((v) => `- ${v}`).join("\n"));
9628
+ } else {
9629
+ text.push(value);
9630
+ }
9631
+ return [{ type: "text", text: text.join("") }];
9632
+ };
9633
+ };
9634
+ var renderDescFields = (list) => list.map((v) => `\`${v.title}\``).join(", ");
9635
+ var renderInputFields = (fields) => {
9636
+ const rows = fields.map((field) => {
9637
+ const name = field.title;
9638
+ const type = field.type?.name ? toFieldType(field.type) : "string";
9639
+ const requiredMsg = field.isOptional ? `This optional ${type} field may be omitted` : `A ${type} field`;
9640
+ const description = field.description ? ` ${formatDescription(field.description)}` : "";
9641
+ return `${name}: (${requiredMsg})${description}`.trim();
9642
+ });
9643
+ return rows.join("\n");
9644
+ };
9645
+ var renderOutputFields = (fields) => {
9646
+ const rows = fields.map((field) => {
9647
+ const name = field.title;
9648
+ const type = field.type?.name ? toFieldType(field.type) : "string";
9649
+ const requiredMsg = field.isOptional ? `Only include this ${type} field if its value is available` : `This ${type} field must be included`;
9650
+ let description = "";
9651
+ if (field.description && field.description.length > 0) {
9652
+ const value = field.type?.name === "class" ? field.description : formatDescription(field.description);
9653
+ description = ` ${value}`;
9654
+ }
9655
+ if (field.type?.options && field.type.options.length > 0) {
9656
+ if (description.length > 0) {
9657
+ description += `. `;
9658
+ }
9659
+ description += `Allowed values: ${field.type.options.join(", ")}`;
9660
+ }
9661
+ return `${name}: (${requiredMsg})${description}`.trim();
9662
+ });
9663
+ return rows.join("\n");
9664
+ };
9665
+ var processValue = (field, value) => {
9666
+ if (field.type?.name === "date" && value instanceof Date) {
9667
+ const v = value.toISOString();
9668
+ return v.slice(0, v.indexOf("T"));
9669
+ }
9670
+ if (field.type?.name === "datetime" && value instanceof Date) {
9671
+ return formatDateWithTimezone(value);
9672
+ }
9673
+ if (field.type?.name === "image" && typeof value === "object") {
9674
+ return value;
9675
+ }
9676
+ if (field.type?.name === "audio" && typeof value === "object") {
9677
+ return value;
9678
+ }
9679
+ if (typeof value === "string") {
9680
+ return value;
9681
+ }
9682
+ return JSON.stringify(value, null, 2);
9683
+ };
9684
+ var toFieldType = (type) => {
9685
+ const baseType = (() => {
9686
+ switch (type?.name) {
9687
+ case "string":
9688
+ return "string";
9689
+ case "number":
9690
+ return "number";
9691
+ case "boolean":
9692
+ return "boolean";
9693
+ case "date":
9694
+ return 'date ("YYYY-MM-DD" format)';
9695
+ case "datetime":
9696
+ return 'date time ("YYYY-MM-DD HH:mm Timezone" format)';
9697
+ case "json":
9698
+ return "JSON object";
9699
+ case "class":
9700
+ return "classification class";
9701
+ case "code":
9702
+ return "code";
9703
+ default:
9704
+ return "string";
9705
+ }
9706
+ })();
9707
+ return type?.isArray ? `json array of ${baseType} items` : baseType;
9708
+ };
9709
+ function combineConsecutiveStrings(separator) {
9710
+ return (acc, current) => {
9711
+ if (current.type === "text") {
9712
+ const previous = acc.length > 0 ? acc[acc.length - 1] : null;
9713
+ if (previous && previous.type === "text") {
9714
+ previous.text += separator + current.text;
9715
+ } else {
9716
+ acc.push(current);
9717
+ }
9718
+ } else {
9719
+ acc.push(current);
9720
+ }
9721
+ return acc;
9722
+ };
9723
+ }
9724
+ var isEmptyValue = (field, value, context3) => {
9725
+ if (typeof value === "boolean") {
9726
+ return false;
9727
+ }
9728
+ if (!value || (Array.isArray(value) || typeof value === "string") && value.length === 0) {
9729
+ if (context3?.isExample) {
9730
+ return true;
8767
9731
  }
9732
+ if (field.isOptional || field.isInternal) {
9733
+ return true;
9734
+ }
9735
+ const fieldType = context3?.isInputField !== false ? "input" : "output";
9736
+ throw new Error(`Value for ${fieldType} field '${field.name}' is required.`);
8768
9737
  }
8769
- if (type.name === "code" && type.isArray) {
8770
- throw new AxSignatureValidationError(
8771
- "Arrays of code are not commonly supported",
8772
- field.name,
8773
- "Consider using a single code field or an array of strings instead"
8774
- );
9738
+ return false;
9739
+ };
9740
+ function formatDescription(str) {
9741
+ const value = str.trim();
9742
+ return value.length > 0 ? `${value.charAt(0).toUpperCase()}${value.slice(1)}${value.endsWith(".") ? "" : "."}` : "";
9743
+ }
9744
+
9745
+ // dsp/registry.ts
9746
+ var AxInstanceRegistry = class {
9747
+ reg;
9748
+ // To track keys for iteration
9749
+ constructor() {
9750
+ this.reg = /* @__PURE__ */ new Set();
8775
9751
  }
8776
- if (field.isInternal && context3 === "input") {
8777
- throw new AxSignatureValidationError(
8778
- "Internal marker (!) is not allowed on input fields",
8779
- field.name,
8780
- "Internal markers are only allowed on output fields"
8781
- );
9752
+ register(instance) {
9753
+ this.reg.add(instance);
8782
9754
  }
8783
- }
9755
+ *[Symbol.iterator]() {
9756
+ const items = Array.from(this.reg);
9757
+ for (let i = 0; i < items.length; i++) {
9758
+ yield items[i];
9759
+ }
9760
+ }
9761
+ };
8784
9762
 
8785
9763
  // dsp/program.ts
8786
9764
  var AxProgramWithSignature = class {
@@ -8983,6 +9961,28 @@ var AxProgram = class {
8983
9961
  }
8984
9962
  };
8985
9963
 
9964
+ // dsp/validate.ts
9965
+ function handleValidationError(mem, errorFields, ai, promptTemplate, sessionId) {
9966
+ mem.addRequest(
9967
+ [
9968
+ {
9969
+ role: "user",
9970
+ content: promptTemplate.renderExtraFields(errorFields)
9971
+ }
9972
+ ],
9973
+ sessionId
9974
+ );
9975
+ mem.addTag("error", sessionId);
9976
+ if (ai.getOptions().debug) {
9977
+ const errors = errorFields.map((field) => `- ${field.title}: ${field.description}`).join("\n");
9978
+ const logger = ai.getLogger();
9979
+ logger(`\u274C Error Correction:
9980
+ ${errors}`, {
9981
+ tags: ["error"]
9982
+ });
9983
+ }
9984
+ }
9985
+
8986
9986
  // dsp/generate.ts
8987
9987
  var AxGen = class extends AxProgramWithSignature {
8988
9988
  promptTemplate;
@@ -8990,10 +9990,8 @@ var AxGen = class extends AxProgramWithSignature {
8990
9990
  streamingAsserts;
8991
9991
  options;
8992
9992
  functions;
8993
- functionsExecuted = /* @__PURE__ */ new Set();
8994
9993
  fieldProcessors = [];
8995
9994
  streamingFieldProcessors = [];
8996
- values = {};
8997
9995
  excludeContentFromTrace = false;
8998
9996
  thoughtFieldName;
8999
9997
  constructor(signature, options) {
@@ -9016,6 +10014,20 @@ var AxGen = class extends AxProgramWithSignature {
9016
10014
  this.functions = parseFunctions(options.functions);
9017
10015
  }
9018
10016
  }
10017
+ createStates(n) {
10018
+ return Array.from({ length: n }, (_, index) => ({
10019
+ index,
10020
+ functionCalls: [],
10021
+ values: {},
10022
+ content: "",
10023
+ functionsExecuted: /* @__PURE__ */ new Set(),
10024
+ xstate: {
10025
+ extractedFields: [],
10026
+ streamedIndex: {},
10027
+ s: -1
10028
+ }
10029
+ }));
10030
+ }
9019
10031
  addAssert = (fn, message) => {
9020
10032
  this.asserts.push({ fn, message });
9021
10033
  };
@@ -9056,7 +10068,6 @@ var AxGen = class extends AxProgramWithSignature {
9056
10068
  const {
9057
10069
  sessionId,
9058
10070
  traceId,
9059
- modelConfig,
9060
10071
  model,
9061
10072
  rateLimiter,
9062
10073
  stream,
@@ -9065,7 +10076,7 @@ var AxGen = class extends AxProgramWithSignature {
9065
10076
  thinkingTokenBudget,
9066
10077
  showThoughts
9067
10078
  } = options ?? {};
9068
- const chatPrompt = mem?.history(sessionId) ?? [];
10079
+ const chatPrompt = mem?.history(0, sessionId) ?? [];
9069
10080
  if (chatPrompt.length === 0) {
9070
10081
  throw new Error("No chat prompt found");
9071
10082
  }
@@ -9074,6 +10085,10 @@ var AxGen = class extends AxProgramWithSignature {
9074
10085
  if (!firstStep && (functionCall === "required" || typeof functionCall === "function")) {
9075
10086
  functionCall = void 0;
9076
10087
  }
10088
+ const modelConfig = {
10089
+ ...options?.modelConfig,
10090
+ ...options?.sampleCount ? { n: options.sampleCount } : {}
10091
+ };
9077
10092
  const res = await ai.chat(
9078
10093
  {
9079
10094
  chatPrompt,
@@ -9106,9 +10121,11 @@ var AxGen = class extends AxProgramWithSignature {
9106
10121
  traceContext
9107
10122
  }) {
9108
10123
  const { sessionId, traceId, functions: _functions } = options ?? {};
9109
- const fastFail = options?.fastFail ?? this.options?.fastFail;
10124
+ const strictMode = options?.strictMode ?? false;
9110
10125
  const model = options.model;
9111
- const functions = _functions?.map((f2) => "toFunction" in f2 ? f2.toFunction() : f2)?.flat();
10126
+ const states = this.createStates(options.sampleCount ?? 1);
10127
+ const usage = this.usage;
10128
+ const functions = _functions?.map((f2) => "toFunction" in f2 ? f2.toFunction() : f2)?.flat() ?? [];
9112
10129
  const res = await this.forwardSendRequest({
9113
10130
  ai,
9114
10131
  mem,
@@ -9116,8 +10133,8 @@ var AxGen = class extends AxProgramWithSignature {
9116
10133
  traceContext,
9117
10134
  firstStep
9118
10135
  });
9119
- if (res instanceof import_web5.ReadableStream) {
9120
- yield* this.processStreamingResponse({
10136
+ if (res instanceof import_web6.ReadableStream) {
10137
+ yield* processStreamingResponse({
9121
10138
  ai,
9122
10139
  model,
9123
10140
  res,
@@ -9125,12 +10142,21 @@ var AxGen = class extends AxProgramWithSignature {
9125
10142
  traceId,
9126
10143
  sessionId,
9127
10144
  functions,
9128
- fastFail,
9129
- span
10145
+ strictMode,
10146
+ span,
10147
+ states,
10148
+ usage,
10149
+ asserts: this.asserts,
10150
+ streamingAsserts: this.streamingAsserts,
10151
+ fieldProcessors: this.fieldProcessors,
10152
+ streamingFieldProcessors: this.streamingFieldProcessors,
10153
+ thoughtFieldName: this.thoughtFieldName,
10154
+ excludeContentFromTrace: this.excludeContentFromTrace,
10155
+ signature: this.signature
9130
10156
  });
9131
10157
  this.getLogger(ai, options)?.("", { tags: ["responseEnd"] });
9132
10158
  } else {
9133
- yield await this.processResponse({
10159
+ yield* processResponse({
9134
10160
  ai,
9135
10161
  model,
9136
10162
  res,
@@ -9138,233 +10164,19 @@ var AxGen = class extends AxProgramWithSignature {
9138
10164
  traceId,
9139
10165
  sessionId,
9140
10166
  functions,
9141
- span
9142
- });
9143
- }
9144
- }
9145
- async *processStreamingResponse({
9146
- ai,
9147
- model,
9148
- res,
9149
- mem,
9150
- sessionId,
9151
- traceId,
9152
- functions,
9153
- fastFail,
9154
- span
9155
- }) {
9156
- const streamingValidation = fastFail ?? ai.getFeatures(model).functionCot !== true;
9157
- const functionCalls = [];
9158
- this.values = {};
9159
- const xstate = {
9160
- extractedFields: [],
9161
- streamedIndex: {},
9162
- s: -1
9163
- };
9164
- let content = "";
9165
- mem.addResult(
9166
- {
9167
- content: "",
9168
- functionCalls: []
9169
- },
9170
- sessionId
9171
- );
9172
- for await (const v of res) {
9173
- const result = v.results[0];
9174
- if (!result) {
9175
- continue;
9176
- }
9177
- if (v.modelUsage) {
9178
- this.usage.push(v.modelUsage);
9179
- }
9180
- if (result.functionCalls && result.functionCalls.length > 0) {
9181
- mergeFunctionCalls(functionCalls, result.functionCalls);
9182
- mem.updateResult(
9183
- {
9184
- name: result.name,
9185
- content,
9186
- functionCalls,
9187
- delta: result.functionCalls?.[0]?.function?.params
9188
- },
9189
- sessionId
9190
- );
9191
- } else if (result.content && result.content.length > 0) {
9192
- if (result.thought && result.thought.length > 0) {
9193
- yield {
9194
- [this.thoughtFieldName]: result.thought
9195
- };
9196
- }
9197
- content += result.content;
9198
- mem.updateResult(
9199
- { name: result.name, content, delta: result.content },
9200
- sessionId
9201
- );
9202
- const skip = streamingExtractValues(
9203
- this.signature,
9204
- this.values,
9205
- xstate,
9206
- content,
9207
- streamingValidation
9208
- );
9209
- if (skip) {
9210
- continue;
9211
- }
9212
- if (this.streamingAsserts.length !== 0) {
9213
- await assertStreamingAssertions(
9214
- this.streamingAsserts,
9215
- xstate,
9216
- content
9217
- );
9218
- }
9219
- if (this.streamingFieldProcessors.length !== 0) {
9220
- await processStreamingFieldProcessors(
9221
- this.streamingFieldProcessors,
9222
- content,
9223
- xstate,
9224
- mem,
9225
- this.values,
9226
- sessionId
9227
- );
9228
- }
9229
- yield* streamValues(
9230
- this.signature,
9231
- content,
9232
- this.values,
9233
- xstate
9234
- );
9235
- await assertAssertions(this.asserts, this.values);
9236
- } else if (result.thought && result.thought.length > 0) {
9237
- this.values[this.thoughtFieldName] = (this.values[this.thoughtFieldName] ?? "") + result.thought;
9238
- yield {
9239
- [this.thoughtFieldName]: result.thought
9240
- };
9241
- }
9242
- if (result.finishReason === "length") {
9243
- throw new Error(
9244
- `Max tokens reached before completion
9245
- Content: ${content}`
9246
- );
9247
- }
9248
- }
9249
- const funcs = parseFunctionCalls(ai, functionCalls, this.values, model);
9250
- if (funcs) {
9251
- if (!functions) {
9252
- throw new Error("Functions are not defined");
9253
- }
9254
- const fx = await processFunctions(
9255
- ai,
9256
- functions,
9257
- funcs,
9258
- mem,
9259
- sessionId,
9260
- traceId,
9261
10167
  span,
9262
- this.excludeContentFromTrace
9263
- );
9264
- this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
9265
- } else {
9266
- streamingExtractFinalValue(this.signature, this.values, xstate, content);
9267
- await assertStreamingAssertions(
9268
- this.streamingAsserts,
9269
- xstate,
9270
- content,
9271
- true
9272
- );
9273
- await assertAssertions(this.asserts, this.values);
9274
- if (this.fieldProcessors.length) {
9275
- await processFieldProcessors(
9276
- this.fieldProcessors,
9277
- this.values,
9278
- mem,
9279
- sessionId
9280
- );
9281
- }
9282
- if (this.streamingFieldProcessors.length !== 0) {
9283
- await processStreamingFieldProcessors(
9284
- this.streamingFieldProcessors,
9285
- content,
9286
- xstate,
9287
- mem,
9288
- this.values,
9289
- sessionId,
9290
- true
9291
- );
9292
- }
9293
- yield* streamValues(
9294
- this.signature,
9295
- content,
9296
- this.values,
9297
- xstate
9298
- );
9299
- }
9300
- }
9301
- async processResponse({
9302
- ai,
9303
- res,
9304
- mem,
9305
- sessionId,
9306
- traceId,
9307
- functions,
9308
- span
9309
- }) {
9310
- this.values = {};
9311
- let results = res.results ?? [];
9312
- if (results.length > 1) {
9313
- results = results.filter((r) => r.functionCalls);
9314
- }
9315
- for (const result of results) {
9316
- if (res.modelUsage) {
9317
- this.usage.push(res.modelUsage);
9318
- }
9319
- mem.addResult(result, sessionId);
9320
- if (result.functionCalls?.length) {
9321
- const funcs = parseFunctionCalls(ai, result.functionCalls, this.values);
9322
- if (funcs) {
9323
- if (!functions) {
9324
- throw new Error("Functions are not defined");
9325
- }
9326
- const fx = await processFunctions(
9327
- ai,
9328
- functions,
9329
- funcs,
9330
- mem,
9331
- sessionId,
9332
- traceId,
9333
- span,
9334
- this.excludeContentFromTrace
9335
- );
9336
- this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
9337
- }
9338
- } else if (result.content) {
9339
- if (result.thought && result.thought.length > 0) {
9340
- this.values[this.thoughtFieldName] = result.thought;
9341
- }
9342
- extractValues(this.signature, this.values, result.content);
9343
- await assertAssertions(this.asserts, this.values);
9344
- if (this.fieldProcessors.length) {
9345
- await processFieldProcessors(
9346
- this.fieldProcessors,
9347
- this.values,
9348
- mem,
9349
- sessionId
9350
- );
9351
- }
9352
- }
9353
- if (result.finishReason === "length") {
9354
- throw new Error(
9355
- `Max tokens reached before completion
9356
- Content: ${result.content}`
9357
- );
9358
- }
9359
- }
9360
- for (const field of this.signature.getOutputFields()) {
9361
- if (field.isInternal) {
9362
- delete this.values[field.name];
9363
- }
10168
+ strictMode,
10169
+ states,
10170
+ usage,
10171
+ asserts: this.asserts,
10172
+ fieldProcessors: this.fieldProcessors,
10173
+ thoughtFieldName: this.thoughtFieldName,
10174
+ excludeContentFromTrace: this.excludeContentFromTrace,
10175
+ signature: this.signature
10176
+ });
9364
10177
  }
9365
- return { ...this.values };
9366
10178
  }
9367
- async *_forward2(ai, values, options, span, traceContext) {
10179
+ async *_forward2(ai, values, states, options, span, traceContext) {
9368
10180
  const stopFunction = (options?.stopFunction ?? this.options?.stopFunction)?.toLowerCase();
9369
10181
  const maxRetries = options.maxRetries ?? this.options?.maxRetries ?? 10;
9370
10182
  const maxSteps = options.maxSteps ?? this.options?.maxSteps ?? 10;
@@ -9373,7 +10185,7 @@ Content: ${result.content}`
9373
10185
  debug: this.isDebug(ai, options),
9374
10186
  debugHideSystemPrompt
9375
10187
  };
9376
- const mem = options.mem ?? this.options?.mem ?? new AxMemory(1e4, memOptions);
10188
+ const mem = options.mem ?? this.options?.mem ?? new AxMemory(memOptions);
9377
10189
  let err;
9378
10190
  if (options?.functions && options.functions.length > 0) {
9379
10191
  const promptTemplateClass = this.options?.promptTemplate ?? AxPromptTemplate;
@@ -9400,7 +10212,7 @@ Content: ${result.content}`
9400
10212
  demos: this.demos
9401
10213
  });
9402
10214
  }
9403
- mem.add(prompt, options?.sessionId);
10215
+ mem.addRequest(prompt, options.sessionId);
9404
10216
  multiStepLoop: for (let n = 0; n < maxSteps; n++) {
9405
10217
  const firstStep = n === 0;
9406
10218
  for (let errCount = 0; errCount < maxRetries; errCount++) {
@@ -9413,15 +10225,20 @@ Content: ${result.content}`
9413
10225
  span,
9414
10226
  traceContext
9415
10227
  });
9416
- for await (const delta of generator) {
9417
- if (delta !== void 0) {
9418
- yield { version: errCount, delta };
10228
+ for await (const result of generator) {
10229
+ if (result !== void 0) {
10230
+ yield {
10231
+ version: errCount,
10232
+ index: result.index,
10233
+ delta: result.delta
10234
+ };
9419
10235
  }
9420
10236
  }
9421
- const lastMemItem = mem.getLast(options?.sessionId);
9422
- const shouldContinue = this.shouldContinueSteps(
9423
- lastMemItem,
9424
- stopFunction
10237
+ const shouldContinue = shouldContinueSteps(
10238
+ mem,
10239
+ stopFunction,
10240
+ states,
10241
+ options?.sessionId
9425
10242
  );
9426
10243
  if (shouldContinue) {
9427
10244
  continue multiStepLoop;
@@ -9477,26 +10294,15 @@ Content: ${result.content}`
9477
10294
  this.signature
9478
10295
  );
9479
10296
  }
9480
- shouldContinueSteps(lastMemItem, stopFunction) {
9481
- const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
9482
- const isFunction = lastMemItem?.chat?.role === "function";
9483
- const isProcessor = lastMemItem?.tags ? lastMemItem.tags.some((tag) => tag === "processor") : false;
9484
- if (isFunction && stopFunction && stopFunctionExecuted) {
9485
- return false;
9486
- }
9487
- if (isFunction || isProcessor) {
9488
- return true;
9489
- }
9490
- return false;
9491
- }
9492
10297
  async *_forward1(ai, values, options) {
10298
+ const states = this.createStates(options.sampleCount ?? 1);
9493
10299
  const tracer = options?.tracer ?? this.options?.tracer ?? ai.getOptions().tracer;
9494
10300
  let functions = this.functions;
9495
10301
  if (options?.functions) {
9496
10302
  functions = parseFunctions(options.functions, this.functions);
9497
10303
  }
9498
10304
  if (!tracer) {
9499
- yield* this._forward2(ai, values, {
10305
+ yield* this._forward2(ai, values, states, {
9500
10306
  ...options,
9501
10307
  functions
9502
10308
  });
@@ -9511,8 +10317,7 @@ Content: ${result.content}`
9511
10317
  ...options?.thinkingTokenBudget ? { thinking_token_budget: options.thinkingTokenBudget } : {},
9512
10318
  ...options?.showThoughts ? { show_thoughts: options.showThoughts } : {},
9513
10319
  ...options?.maxSteps ? { max_steps: options.maxSteps } : {},
9514
- ...options?.maxRetries ? { max_retries: options.maxRetries } : {},
9515
- ...options?.fastFail ? { fast_fail: options.fastFail } : {}
10320
+ ...options?.maxRetries ? { max_retries: options.maxRetries } : {}
9516
10321
  };
9517
10322
  const traceLabel = options.traceLabel ?? this.options?.traceLabel;
9518
10323
  const spanName = traceLabel ? `${traceLabel} (AxGen)` : "AxGen";
@@ -9529,6 +10334,7 @@ Content: ${result.content}`
9529
10334
  yield* this._forward2(
9530
10335
  ai,
9531
10336
  values,
10337
+ states,
9532
10338
  {
9533
10339
  ...options,
9534
10340
  functions
@@ -9537,8 +10343,10 @@ Content: ${result.content}`
9537
10343
  traceContext
9538
10344
  );
9539
10345
  if (!this.excludeContentFromTrace) {
10346
+ const valuesList = states.map((s2) => s2.values);
10347
+ const values2 = valuesList.length === 1 ? valuesList[0] : valuesList;
9540
10348
  span.addEvent("output", {
9541
- content: JSON.stringify(this.values, null, 2)
10349
+ content: JSON.stringify(values2, null, 2)
9542
10350
  });
9543
10351
  }
9544
10352
  } finally {
@@ -9547,17 +10355,18 @@ Content: ${result.content}`
9547
10355
  }
9548
10356
  async forward(ai, values, options) {
9549
10357
  const generator = this._forward1(ai, values, options ?? {});
9550
- let buffer = {};
10358
+ let buffer = [];
9551
10359
  let currentVersion = 0;
9552
- for await (const item of generator) {
9553
- if (item.version !== currentVersion) {
9554
- buffer = {};
10360
+ for await (const delta of generator) {
10361
+ if (delta.version !== currentVersion) {
10362
+ buffer = [];
9555
10363
  }
9556
- currentVersion = item.version;
9557
- buffer = mergeDeltas(buffer, item.delta);
10364
+ currentVersion = delta.version;
10365
+ buffer = mergeDeltas(buffer, delta);
9558
10366
  }
9559
- this.trace = { ...values, ...buffer };
9560
- return buffer;
10367
+ const result = buffer[0]?.delta ?? {};
10368
+ this.trace = { ...values, ...result };
10369
+ return result;
9561
10370
  }
9562
10371
  async *streamingForward(ai, values, options) {
9563
10372
  yield* this._forward1(ai, values, {
@@ -9578,9 +10387,13 @@ Content: ${result.content}`
9578
10387
  var AxGenerateError = class extends Error {
9579
10388
  details;
9580
10389
  constructor(message, details, options) {
9581
- super(message, options);
10390
+ super(message);
9582
10391
  this.name = "AxGenerateError";
9583
10392
  this.details = details;
10393
+ if (options?.cause) {
10394
+ ;
10395
+ this.cause = options.cause;
10396
+ }
9584
10397
  }
9585
10398
  };
9586
10399
  function enhanceError(e, ai, signature) {
@@ -10277,6 +11090,9 @@ var AxBaseOptimizer = class {
10277
11090
  checkpointLoad;
10278
11091
  checkpointInterval;
10279
11092
  resumeFromCheckpoint;
11093
+ // Logging fields
11094
+ logger;
11095
+ verbose;
10280
11096
  // Checkpoint state
10281
11097
  currentRound = 0;
10282
11098
  scoreHistory = [];
@@ -10300,6 +11116,8 @@ var AxBaseOptimizer = class {
10300
11116
  this.checkpointLoad = args.checkpointLoad;
10301
11117
  this.checkpointInterval = args.checkpointInterval ?? 10;
10302
11118
  this.resumeFromCheckpoint = args.resumeFromCheckpoint;
11119
+ this.logger = args.logger;
11120
+ this.verbose = args.verbose;
10303
11121
  const costTracker = new AxDefaultCostTracker({
10304
11122
  maxTokens: 1e6
10305
11123
  });
@@ -10478,8 +11296,14 @@ var AxBaseOptimizer = class {
10478
11296
  async compilePareto(program, metricFn, options) {
10479
11297
  const startTime = Date.now();
10480
11298
  if (options?.verbose) {
10481
- console.log("Starting Pareto optimization using base implementation");
10482
- console.log("This will run multiple single-objective optimizations");
11299
+ this.getLogger(options)?.(
11300
+ "Starting Pareto optimization using base implementation",
11301
+ { tags: ["discovery"] }
11302
+ );
11303
+ this.getLogger(options)?.(
11304
+ "This will run multiple single-objective optimizations",
11305
+ { tags: ["discovery"] }
11306
+ );
10483
11307
  }
10484
11308
  const solutions = await this.generateWeightedSolutions(
10485
11309
  program,
@@ -10493,13 +11317,22 @@ var AxBaseOptimizer = class {
10493
11317
  );
10494
11318
  const allSolutions = [...solutions, ...constraintSolutions];
10495
11319
  if (options?.verbose) {
10496
- console.log(`Generated ${allSolutions.length} candidate solutions`);
11320
+ this.getLogger(options)?.(
11321
+ `Generated ${allSolutions.length} candidate solutions`,
11322
+ { tags: ["discovery"] }
11323
+ );
10497
11324
  }
10498
11325
  const paretoFront = this.findParetoFrontier(allSolutions);
10499
11326
  const hypervolume = this.calculateHypervolume(paretoFront);
10500
11327
  if (options?.verbose) {
10501
- console.log(`Found ${paretoFront.length} non-dominated solutions`);
10502
- console.log(`Hypervolume: ${hypervolume?.toFixed(4) || "N/A"}`);
11328
+ this.getLogger(options)?.(
11329
+ `Found ${paretoFront.length} non-dominated solutions`,
11330
+ { tags: ["discovery"] }
11331
+ );
11332
+ this.getLogger(options)?.(
11333
+ `Hypervolume: ${hypervolume?.toFixed(4) || "N/A"}`,
11334
+ { tags: ["discovery"] }
11335
+ );
10503
11336
  }
10504
11337
  this.updateResourceUsage(startTime);
10505
11338
  this.stats.convergenceInfo.converged = true;
@@ -10537,13 +11370,19 @@ var AxBaseOptimizer = class {
10537
11370
  });
10538
11371
  const objectives = Object.keys(sampleScores);
10539
11372
  if (options?.verbose) {
10540
- console.log(`Detected objectives: ${objectives.join(", ")}`);
11373
+ this.getLogger(options)?.(
11374
+ `Detected objectives: ${objectives.join(", ")}`,
11375
+ { tags: ["discovery"] }
11376
+ );
10541
11377
  }
10542
11378
  const weightCombinations = this.generateWeightCombinations(objectives);
10543
11379
  for (let i = 0; i < weightCombinations.length; i++) {
10544
11380
  const weights = weightCombinations[i];
10545
11381
  if (options?.verbose) {
10546
- console.log(`Optimizing with weights: ${JSON.stringify(weights)}`);
11382
+ this.getLogger(options)?.(
11383
+ `Optimizing with weights: ${JSON.stringify(weights)}`,
11384
+ { tags: ["discovery"] }
11385
+ );
10547
11386
  }
10548
11387
  const weightedMetric = async ({ prediction, example }) => {
10549
11388
  const scores = await metricFn({ prediction, example });
@@ -10575,9 +11414,9 @@ var AxBaseOptimizer = class {
10575
11414
  });
10576
11415
  } catch (error) {
10577
11416
  if (options?.verbose) {
10578
- console.warn(
10579
- `Failed optimization with weights ${JSON.stringify(weights)}:`,
10580
- error
11417
+ this.getLogger(options)?.(
11418
+ `Failed optimization with weights ${JSON.stringify(weights)}: ${error}`,
11419
+ { tags: ["warning"] }
10581
11420
  );
10582
11421
  }
10583
11422
  continue;
@@ -10602,8 +11441,9 @@ var AxBaseOptimizer = class {
10602
11441
  const objectives = Object.keys(sampleScores);
10603
11442
  for (const primaryObjective of objectives) {
10604
11443
  if (options?.verbose) {
10605
- console.log(
10606
- `Optimizing ${primaryObjective} with constraints on other objectives`
11444
+ this.getLogger(options)?.(
11445
+ `Optimizing ${primaryObjective} with constraints on other objectives`,
11446
+ { tags: ["discovery"] }
10607
11447
  );
10608
11448
  }
10609
11449
  const constraintMetric = async ({ prediction, example }) => {
@@ -10640,9 +11480,9 @@ var AxBaseOptimizer = class {
10640
11480
  });
10641
11481
  } catch (error) {
10642
11482
  if (options?.verbose) {
10643
- console.warn(
10644
- `Failed constraint optimization for ${primaryObjective}:`,
10645
- error
11483
+ this.getLogger(options)?.(
11484
+ `Failed constraint optimization for ${primaryObjective}: ${error}`,
11485
+ { tags: ["warning"] }
10646
11486
  );
10647
11487
  }
10648
11488
  continue;
@@ -10877,6 +11717,39 @@ var AxBaseOptimizer = class {
10877
11717
  );
10878
11718
  }
10879
11719
  }
11720
+ /**
11721
+ * Get the logger function with fallback hierarchy:
11722
+ * 1. Explicit logger passed to optimizer
11723
+ * 2. Logger from student AI service
11724
+ * 3. Default optimizer logger
11725
+ * 4. undefined if verbose is false
11726
+ */
11727
+ getLogger(options) {
11728
+ const isVerbose = this.isLoggingEnabled(options);
11729
+ if (!isVerbose) {
11730
+ return void 0;
11731
+ }
11732
+ if (this.logger) {
11733
+ return this.logger;
11734
+ }
11735
+ try {
11736
+ const aiLogger = this.studentAI.getLogger();
11737
+ if (aiLogger) {
11738
+ return aiLogger;
11739
+ }
11740
+ } catch {
11741
+ }
11742
+ return axDefaultOptimizerLogger;
11743
+ }
11744
+ /**
11745
+ * Check if logging is enabled based on verbose settings
11746
+ */
11747
+ isLoggingEnabled(options) {
11748
+ if (options?.verbose !== void 0) {
11749
+ return options.verbose;
11750
+ }
11751
+ return this.verbose ?? true;
11752
+ }
10880
11753
  };
10881
11754
 
10882
11755
  // db/base.ts
@@ -11595,23 +12468,6 @@ var getTopInPercent = (entries, percent = 0.1) => {
11595
12468
  return sortedEntries.slice(0, topTenPercentCount);
11596
12469
  };
11597
12470
 
11598
- // docs/rewriter.ts
11599
- var AxDefaultQueryRewriter = class extends AxGen {
11600
- constructor(options) {
11601
- const signature = `"You are a query rewriter assistant tasked with rewriting a given query to improve its clarity, specificity, and relevance. Your role involves analyzing the query to identify any ambiguities, generalizations, or irrelevant information and then rephrasing it to make it more focused and precise. The rewritten query should be concise, easy to understand, and directly related to the original query. Output only the rewritten query."
11602
- query: string -> rewrittenQuery: string`;
11603
- super(signature, options);
11604
- }
11605
- };
11606
- var AxRewriter = class extends AxGen {
11607
- constructor(options) {
11608
- super(
11609
- '"Rewrite a given text to be clear and concise" original -> rewritten "improved text"',
11610
- options
11611
- );
11612
- }
11613
- };
11614
-
11615
12471
  // funcs/docker.ts
11616
12472
  var AxDockerSession = class {
11617
12473
  apiUrl;
@@ -12459,9 +13315,9 @@ var AxBootstrapFewShot = class extends AxBaseOptimizer {
12459
13315
  this.stats.earlyStopped = true;
12460
13316
  this.stats.earlyStopping.reason = `No improvement for ${this.earlyStoppingPatience} rounds`;
12461
13317
  if (this.verboseMode || this.debugMode) {
12462
- console.log(
12463
- `
12464
- Early stopping triggered after ${roundIndex + 1} rounds. No improvement for ${this.earlyStoppingPatience} rounds.`
13318
+ this.getLogger()?.(
13319
+ `Early stopping after ${roundIndex + 1} rounds (no improvement for ${this.earlyStoppingPatience} rounds)`,
13320
+ { tags: ["optimizer", "warning"] }
12465
13321
  );
12466
13322
  }
12467
13323
  return;
@@ -12472,6 +13328,16 @@ Early stopping triggered after ${roundIndex + 1} rounds. No improvement for ${th
12472
13328
  const maxRounds = options?.maxIterations ?? this.maxRounds;
12473
13329
  this.traces = [];
12474
13330
  this.reset();
13331
+ if (this.verboseMode || this.debugMode) {
13332
+ this.getLogger()?.(
13333
+ `Starting BootstrapFewshot optimization with ${maxRounds} rounds`,
13334
+ { tags: ["optimizer", "start"] }
13335
+ );
13336
+ this.getLogger()?.(
13337
+ `Using ${this.examples.length} examples, max ${this.maxDemos} demos`,
13338
+ { tags: ["optimizer", "config"] }
13339
+ );
13340
+ }
12475
13341
  for (let i = 0; i < maxRounds; i++) {
12476
13342
  await this.compileRound(program, i, metricFn, options);
12477
13343
  if (this.stats.earlyStopped) {
@@ -12488,6 +13354,12 @@ Early stopping triggered after ${roundIndex + 1} rounds. No improvement for ${th
12488
13354
  if (this.traces.length > 0) {
12489
13355
  bestScore = this.stats.successfulDemos / Math.max(1, this.stats.totalCalls);
12490
13356
  }
13357
+ if (this.verboseMode || this.debugMode) {
13358
+ this.getLogger()?.(
13359
+ `Bootstrap complete. Generated ${demos.length} demos with ${bestScore.toFixed(3)} success rate`,
13360
+ { tags: ["optimizer", "complete"] }
13361
+ );
13362
+ }
12491
13363
  return {
12492
13364
  demos,
12493
13365
  stats: this.stats,
@@ -12553,7 +13425,6 @@ var AxMiPRO = class extends AxBaseOptimizer {
12553
13425
  viewDataBatchSize;
12554
13426
  tipAwareProposer;
12555
13427
  fewshotAwareProposer;
12556
- verbose;
12557
13428
  earlyStoppingTrials;
12558
13429
  minImprovementThreshold;
12559
13430
  bayesianOptimization;
@@ -12575,7 +13446,6 @@ var AxMiPRO = class extends AxBaseOptimizer {
12575
13446
  this.viewDataBatchSize = options.viewDataBatchSize ?? 10;
12576
13447
  this.tipAwareProposer = options.tipAwareProposer ?? true;
12577
13448
  this.fewshotAwareProposer = options.fewshotAwareProposer ?? true;
12578
- this.verbose = options.verbose ?? false;
12579
13449
  this.earlyStoppingTrials = options.earlyStoppingTrials ?? 5;
12580
13450
  this.minImprovementThreshold = options.minImprovementThreshold ?? 0.01;
12581
13451
  this.bayesianOptimization = options.bayesianOptimization ?? false;
@@ -12666,8 +13536,10 @@ var AxMiPRO = class extends AxBaseOptimizer {
12666
13536
  * Bootstraps few-shot examples for the program
12667
13537
  */
12668
13538
  async bootstrapFewShotExamples(program, metricFn) {
12669
- if (this.verbose) {
12670
- console.log("Bootstrapping few-shot examples...");
13539
+ if (this.isLoggingEnabled()) {
13540
+ this.getLogger()?.("Bootstrapping few-shot examples...", {
13541
+ tags: ["optimizer", "phase"]
13542
+ });
12671
13543
  }
12672
13544
  const bootstrapper = new AxBootstrapFewShot({
12673
13545
  studentAI: this.studentAI,
@@ -12675,7 +13547,7 @@ var AxMiPRO = class extends AxBaseOptimizer {
12675
13547
  options: {
12676
13548
  maxDemos: this.maxBootstrappedDemos,
12677
13549
  maxRounds: 3,
12678
- verboseMode: this.verbose
13550
+ verboseMode: this.isLoggingEnabled()
12679
13551
  }
12680
13552
  });
12681
13553
  const result = await bootstrapper.compile(program, metricFn, {
@@ -12720,9 +13592,10 @@ var AxMiPRO = class extends AxBaseOptimizer {
12720
13592
  options
12721
13593
  );
12722
13594
  if (checkpoint && checkpoint.optimizerType === "MiPRO") {
12723
- if (this.verbose || options?.verbose) {
12724
- console.log(
12725
- `Resuming from checkpoint at round ${checkpoint.currentRound}`
13595
+ if (this.isLoggingEnabled(options)) {
13596
+ this.getLogger(options)?.(
13597
+ `Resuming from checkpoint at round ${checkpoint.currentRound}`,
13598
+ { tags: ["optimizer", "checkpoint"] }
12726
13599
  );
12727
13600
  }
12728
13601
  this.restoreFromCheckpoint(checkpoint);
@@ -12732,6 +13605,12 @@ var AxMiPRO = class extends AxBaseOptimizer {
12732
13605
  stagnationRounds = checkpoint.stats.convergenceInfo?.stagnationRounds || 0;
12733
13606
  }
12734
13607
  }
13608
+ if (this.isLoggingEnabled(options)) {
13609
+ this.getLogger(options)?.(
13610
+ `Running optimization trials (${this.numTrials} total)`,
13611
+ { tags: ["optimizer", "phase"] }
13612
+ );
13613
+ }
12735
13614
  for (let i = startRound; i < this.numTrials; i++) {
12736
13615
  const config = {
12737
13616
  instruction: instructions[i % instructions.length] || instructions[0] || "",
@@ -12758,6 +13637,12 @@ var AxMiPRO = class extends AxBaseOptimizer {
12758
13637
  bestScore = score;
12759
13638
  bestConfig = config;
12760
13639
  stagnationRounds = 0;
13640
+ if (this.isLoggingEnabled(options)) {
13641
+ this.getLogger(options)?.(
13642
+ `Trial ${i + 1}/${this.numTrials}: New best score ${bestScore.toFixed(3)}`,
13643
+ { tags: ["optimizer", "progress"] }
13644
+ );
13645
+ }
12761
13646
  } else {
12762
13647
  stagnationRounds++;
12763
13648
  }
@@ -12876,38 +13761,53 @@ var AxMiPRO = class extends AxBaseOptimizer {
12876
13761
  this.configureAuto(miproOptions.auto);
12877
13762
  }
12878
13763
  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`
13764
+ if (this.isLoggingEnabled(options)) {
13765
+ this.getLogger(options)?.(
13766
+ `Starting MIPROv2 optimization with ${this.numTrials} trials`,
13767
+ { tags: ["optimizer", "start"] }
13768
+ );
13769
+ this.getLogger(options)?.(
13770
+ `Using ${this.examples.length} examples for training and ${valset.length} for validation`,
13771
+ { tags: ["optimizer", "config"] }
12883
13772
  );
12884
13773
  if (this.teacherAI) {
12885
- console.log("Using separate teacher model for instruction generation");
13774
+ this.getLogger(options)?.(
13775
+ "Using separate teacher model for instruction generation",
13776
+ { tags: ["optimizer", "config"] }
13777
+ );
12886
13778
  }
12887
13779
  }
12888
13780
  let bootstrappedDemos = [];
12889
13781
  if (this.maxBootstrappedDemos > 0) {
12890
13782
  bootstrappedDemos = await this.bootstrapFewShotExamples(program, metricFn);
12891
- if (this.verbose) {
12892
- console.log(
12893
- `Generated ${bootstrappedDemos.length} bootstrapped demonstrations`
13783
+ if (this.isLoggingEnabled(options)) {
13784
+ this.getLogger(options)?.(
13785
+ `Generated ${bootstrappedDemos.length} bootstrapped demonstrations`,
13786
+ { tags: ["optimizer", "result"] }
12894
13787
  );
12895
13788
  }
12896
13789
  }
12897
13790
  let labeledExamples = [];
12898
13791
  if (this.maxLabeledDemos > 0) {
12899
13792
  labeledExamples = this.selectLabeledExamples();
12900
- if (this.verbose) {
12901
- console.log(
12902
- `Selected ${labeledExamples.length} labeled examples from training set`
13793
+ if (this.isLoggingEnabled(options)) {
13794
+ this.getLogger(options)?.(
13795
+ `Selected ${labeledExamples.length} labeled examples from training set`,
13796
+ { tags: ["optimizer", "result"] }
12903
13797
  );
12904
13798
  }
12905
13799
  }
12906
13800
  const instructions = await this.proposeInstructionCandidates(options);
12907
- if (this.verbose) {
12908
- console.log(`Generated ${instructions.length} instruction candidates`);
13801
+ if (this.isLoggingEnabled(options)) {
13802
+ this.getLogger(options)?.(
13803
+ `Generated ${instructions.length} instruction candidates`,
13804
+ { tags: ["optimizer", "result"] }
13805
+ );
12909
13806
  if (this.hasTeacherAI(options)) {
12910
- console.log("Using teacher AI for instruction generation");
13807
+ this.getLogger(options)?.(
13808
+ "Using teacher AI for instruction generation",
13809
+ { tags: ["optimizer", "config"] }
13810
+ );
12911
13811
  }
12912
13812
  }
12913
13813
  const { bestConfig, bestScore } = await this.runOptimization(
@@ -12919,9 +13819,15 @@ var AxMiPRO = class extends AxBaseOptimizer {
12919
13819
  metricFn,
12920
13820
  options
12921
13821
  );
12922
- if (this.verbose || options?.verbose) {
12923
- console.log(`Optimization complete. Best score: ${bestScore}`);
12924
- console.log(`Best configuration: ${JSON.stringify(bestConfig)}`);
13822
+ if (this.isLoggingEnabled(options)) {
13823
+ this.getLogger(options)?.(
13824
+ `Optimization complete. Best score: ${bestScore}`,
13825
+ { tags: ["optimizer", "complete"] }
13826
+ );
13827
+ this.getLogger(options)?.(
13828
+ `Best configuration: ${JSON.stringify(bestConfig)}`,
13829
+ { tags: ["optimizer", "result"] }
13830
+ );
12925
13831
  }
12926
13832
  if (this.checkTargetScore(bestScore)) {
12927
13833
  this.triggerEarlyStopping(
@@ -13048,9 +13954,6 @@ var AxMiPRO = class extends AxBaseOptimizer {
13048
13954
  if (config.minImprovementThreshold !== void 0) {
13049
13955
  this.minImprovementThreshold = config.minImprovementThreshold;
13050
13956
  }
13051
- if (config.verbose !== void 0) {
13052
- this.verbose = config.verbose;
13053
- }
13054
13957
  }
13055
13958
  /**
13056
13959
  * Reset optimizer state for reuse with different programs
@@ -13155,6 +14058,7 @@ var AxMockAIService = class {
13155
14058
  return this.config.chatResponse ?? {
13156
14059
  results: [
13157
14060
  {
14061
+ index: 0,
13158
14062
  content: "Mock response",
13159
14063
  finishReason: "stop"
13160
14064
  }
@@ -15456,7 +16360,6 @@ var AxRAG = class extends AxChainOfThought {
15456
16360
  AxDBPinecone,
15457
16361
  AxDBWeaviate,
15458
16362
  AxDefaultCostTracker,
15459
- AxDefaultQueryRewriter,
15460
16363
  AxDefaultResultReranker,
15461
16364
  AxDockerSession,
15462
16365
  AxEmbeddingAdapter,
@@ -15483,7 +16386,6 @@ var AxRAG = class extends AxChainOfThought {
15483
16386
  AxPromptTemplate,
15484
16387
  AxRAG,
15485
16388
  AxRateLimiterTokenUsage,
15486
- AxRewriter,
15487
16389
  AxSignature,
15488
16390
  AxSimpleClassifier,
15489
16391
  AxSimpleClassifierClass,
@@ -15525,6 +16427,10 @@ var AxRAG = class extends AxChainOfThought {
15525
16427
  axAITogetherDefaultConfig,
15526
16428
  axBaseAIDefaultConfig,
15527
16429
  axBaseAIDefaultCreativeConfig,
16430
+ axCreateDefaultLogger,
16431
+ axCreateDefaultTextLogger,
16432
+ axCreateOptimizerLogger,
16433
+ axDefaultOptimizerLogger,
15528
16434
  axGlobals,
15529
16435
  axModelInfoAnthropic,
15530
16436
  axModelInfoCohere,
@@ -15539,6 +16445,8 @@ var AxRAG = class extends AxChainOfThought {
15539
16445
  axModelInfoTogether,
15540
16446
  axSpanAttributes,
15541
16447
  axSpanEvents,
16448
+ axValidateChatRequestMessage,
16449
+ axValidateChatResponseResult,
15542
16450
  f,
15543
16451
  s
15544
16452
  });