@ax-llm/ax 12.0.9 → 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.js CHANGED
@@ -1212,6 +1212,9 @@ var AxBaseAI = class {
1212
1212
  }
1213
1213
  async _chat1(req, options) {
1214
1214
  const model = this.getModel(req.model) ?? req.model ?? this.defaults.model;
1215
+ if (req.chatPrompt && Array.isArray(req.chatPrompt)) {
1216
+ validateAxMessageArray(req.chatPrompt);
1217
+ }
1215
1218
  const modelConfig = {
1216
1219
  ...this.aiImpl.getModelConfig(),
1217
1220
  ...req.modelConfig
@@ -1283,7 +1286,6 @@ var AxBaseAI = class {
1283
1286
  if (chatReq.functions && chatReq.functions.length > 0) {
1284
1287
  functions = chatReq.functions.map((fn2) => this.cleanupFunctionSchema(fn2));
1285
1288
  }
1286
- validateChatPrompt(chatReq.chatPrompt);
1287
1289
  const req = {
1288
1290
  ...chatReq,
1289
1291
  model,
@@ -1334,11 +1336,14 @@ var AxBaseAI = class {
1334
1336
  const res2 = respFn(resp, state);
1335
1337
  res2.sessionId = options?.sessionId;
1336
1338
  if (!res2.modelUsage) {
1337
- res2.modelUsage = {
1338
- ai: this.name,
1339
- model,
1340
- tokens: this.aiImpl.getTokenUsage()
1341
- };
1339
+ const tokenUsage = this.aiImpl.getTokenUsage();
1340
+ if (tokenUsage) {
1341
+ res2.modelUsage = {
1342
+ ai: this.name,
1343
+ model,
1344
+ tokens: tokenUsage
1345
+ };
1346
+ }
1342
1347
  }
1343
1348
  this.modelUsage = res2.modelUsage;
1344
1349
  if (span?.isRecording()) {
@@ -1472,11 +1477,14 @@ var AxBaseAI = class {
1472
1477
  const res = this.aiImpl.createEmbedResp(resValue);
1473
1478
  res.sessionId = options?.sessionId;
1474
1479
  if (!res.modelUsage) {
1475
- res.modelUsage = {
1476
- ai: this.name,
1477
- model: embedModel,
1478
- tokens: this.aiImpl.getTokenUsage()
1479
- };
1480
+ const tokenUsage = this.aiImpl.getTokenUsage();
1481
+ if (tokenUsage) {
1482
+ res.modelUsage = {
1483
+ ai: this.name,
1484
+ model: embedModel,
1485
+ tokens: tokenUsage
1486
+ };
1487
+ }
1480
1488
  }
1481
1489
  this.embedModelUsage = res.modelUsage;
1482
1490
  if (span?.isRecording() && res.modelUsage?.tokens) {
@@ -1640,26 +1648,6 @@ function validateAxMessageArray(values) {
1640
1648
  }
1641
1649
  }
1642
1650
  }
1643
- function validateChatPrompt(chatPrompt) {
1644
- for (let i = 0; i < chatPrompt.length; i++) {
1645
- const message = chatPrompt[i];
1646
- if (message && "functionCalls" in message && Array.isArray(message.functionCalls) && message.functionCalls.length === 0) {
1647
- throw new Error(
1648
- `Chat prompt validation failed: Message at index ${i} has empty functionCalls`
1649
- );
1650
- }
1651
- if (message && "content" in message && Array.isArray(message.content) && message.content.length === 0) {
1652
- throw new Error(
1653
- `Chat prompt validation failed: Message at index ${i} has empty content`
1654
- );
1655
- }
1656
- if (message && "content" in message && typeof message.content === "string" && message.content.trim() === "") {
1657
- throw new Error(
1658
- `Chat prompt validation failed: Message at index ${i} has empty content`
1659
- );
1660
- }
1661
- }
1662
- }
1663
1651
  function validateModels(models) {
1664
1652
  const keys = /* @__PURE__ */ new Set();
1665
1653
  for (const model of models) {
@@ -1731,14 +1719,18 @@ var axModelInfoAnthropic = [
1731
1719
  currency: "usd",
1732
1720
  promptTokenCostPer1M: 15,
1733
1721
  completionTokenCostPer1M: 75,
1734
- maxTokens: 32e3
1722
+ maxTokens: 32e3,
1723
+ hasThinkingBudget: true,
1724
+ hasShowThoughts: true
1735
1725
  },
1736
1726
  {
1737
1727
  name: "claude-sonnet-4-20250514" /* Claude4Sonnet */,
1738
1728
  currency: "usd",
1739
1729
  promptTokenCostPer1M: 3,
1740
1730
  completionTokenCostPer1M: 15,
1741
- maxTokens: 64e3
1731
+ maxTokens: 64e3,
1732
+ hasThinkingBudget: true,
1733
+ hasShowThoughts: true
1742
1734
  },
1743
1735
  // 3.7
1744
1736
  {
@@ -1746,7 +1738,9 @@ var axModelInfoAnthropic = [
1746
1738
  currency: "usd",
1747
1739
  promptTokenCostPer1M: 3,
1748
1740
  completionTokenCostPer1M: 15,
1749
- maxTokens: 64e3
1741
+ maxTokens: 64e3,
1742
+ hasThinkingBudget: true,
1743
+ hasShowThoughts: true
1750
1744
  },
1751
1745
  // 3.5
1752
1746
  {
@@ -1802,13 +1796,47 @@ var axModelInfoAnthropic = [
1802
1796
  }
1803
1797
  ];
1804
1798
 
1799
+ // dsp/modelinfo.ts
1800
+ function getModelInfo({
1801
+ model,
1802
+ modelInfo,
1803
+ models
1804
+ }) {
1805
+ const modelEntry = models?.find((v) => v.key === model);
1806
+ const mappedModel = modelEntry && "model" in modelEntry ? modelEntry.model : model;
1807
+ const exactMatch = modelInfo.find((v) => v.name === model);
1808
+ if (exactMatch) return exactMatch;
1809
+ 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+$/, "");
1810
+ const normalizedMatch = modelInfo.find((v) => v.name === normalizedName);
1811
+ if (normalizedMatch) return normalizedMatch;
1812
+ return null;
1813
+ }
1814
+
1805
1815
  // ai/anthropic/api.ts
1806
1816
  var axAIAnthropicDefaultConfig = () => structuredClone({
1807
1817
  model: "claude-3-7-sonnet-latest" /* Claude37Sonnet */,
1818
+ maxTokens: 4e4,
1819
+ // Ensure maxTokens is higher than highest thinking budget
1820
+ thinkingTokenBudgetLevels: {
1821
+ minimal: 1024,
1822
+ low: 5e3,
1823
+ medium: 1e4,
1824
+ high: 2e4,
1825
+ highest: 32e3
1826
+ },
1808
1827
  ...axBaseAIDefaultConfig()
1809
1828
  });
1810
1829
  var axAIAnthropicVertexDefaultConfig = () => structuredClone({
1811
1830
  model: "claude-3-7-sonnet" /* Claude37Sonnet */,
1831
+ maxTokens: 4e4,
1832
+ // Ensure maxTokens is higher than highest thinking budget
1833
+ thinkingTokenBudgetLevels: {
1834
+ minimal: 1024,
1835
+ low: 5e3,
1836
+ medium: 1e4,
1837
+ high: 2e4,
1838
+ highest: 32e3
1839
+ },
1812
1840
  ...axBaseAIDefaultConfig()
1813
1841
  });
1814
1842
  var AxAIAnthropicImpl = class {
@@ -1817,6 +1845,7 @@ var AxAIAnthropicImpl = class {
1817
1845
  this.isVertex = isVertex;
1818
1846
  }
1819
1847
  tokensUsed;
1848
+ currentPromptConfig;
1820
1849
  getTokenUsage() {
1821
1850
  return this.tokensUsed;
1822
1851
  }
@@ -1835,7 +1864,8 @@ var AxAIAnthropicImpl = class {
1835
1864
  n: config.n
1836
1865
  };
1837
1866
  }
1838
- createChatReq = (req) => {
1867
+ createChatReq = (req, config) => {
1868
+ this.currentPromptConfig = config;
1839
1869
  const model = req.model;
1840
1870
  const stream = req.modelConfig?.stream ?? this.config.stream;
1841
1871
  let apiConfig;
@@ -1891,17 +1921,67 @@ var AxAIAnthropicImpl = class {
1891
1921
  const temperature = req.modelConfig?.temperature ?? this.config.temperature;
1892
1922
  const topP = req.modelConfig?.topP ?? this.config.topP;
1893
1923
  const topK = req.modelConfig?.topK ?? this.config.topK;
1924
+ const n = req.modelConfig?.n ?? this.config.n;
1925
+ if (n && n > 1) {
1926
+ throw new Error("Anthropic does not support sampling (n > 1)");
1927
+ }
1928
+ let thinkingConfig;
1929
+ if (this.config.thinking?.budget_tokens) {
1930
+ thinkingConfig = this.config.thinking;
1931
+ }
1932
+ if (config?.thinkingTokenBudget) {
1933
+ const levels = this.config.thinkingTokenBudgetLevels;
1934
+ switch (config.thinkingTokenBudget) {
1935
+ case "none":
1936
+ thinkingConfig = void 0;
1937
+ break;
1938
+ case "minimal":
1939
+ thinkingConfig = {
1940
+ type: "enabled",
1941
+ budget_tokens: levels?.minimal ?? 1024
1942
+ };
1943
+ break;
1944
+ case "low":
1945
+ thinkingConfig = {
1946
+ type: "enabled",
1947
+ budget_tokens: levels?.low ?? 5e3
1948
+ };
1949
+ break;
1950
+ case "medium":
1951
+ thinkingConfig = {
1952
+ type: "enabled",
1953
+ budget_tokens: levels?.medium ?? 1e4
1954
+ };
1955
+ break;
1956
+ case "high":
1957
+ thinkingConfig = {
1958
+ type: "enabled",
1959
+ budget_tokens: levels?.high ?? 2e4
1960
+ };
1961
+ break;
1962
+ case "highest":
1963
+ thinkingConfig = {
1964
+ type: "enabled",
1965
+ budget_tokens: levels?.highest ?? 32e3
1966
+ };
1967
+ break;
1968
+ }
1969
+ }
1894
1970
  const reqValue = {
1895
1971
  ...this.isVertex ? { anthropic_version: "vertex-2023-10-16" } : { model },
1896
1972
  ...maxTokens ? { max_tokens: maxTokens } : {},
1897
1973
  ...stopSequences && stopSequences.length > 0 ? { stop_sequences: stopSequences } : {},
1898
- ...temperature ? { temperature } : {},
1899
- ...topP ? { top_p: topP } : {},
1900
- ...topK ? { top_k: topK } : {},
1974
+ // Only include temperature when thinking is not enabled
1975
+ ...temperature && !thinkingConfig ? { temperature } : {},
1976
+ // Only include top_p when thinking is not enabled, or when it's >= 0.95
1977
+ ...topP && (!thinkingConfig || topP >= 0.95) ? { top_p: topP } : {},
1978
+ // Only include top_k when thinking is not enabled
1979
+ ...topK && !thinkingConfig ? { top_k: topK } : {},
1901
1980
  ...toolsChoice,
1902
1981
  ...tools && tools.length > 0 ? { tools } : {},
1903
1982
  ...stream ? { stream: true } : {},
1904
1983
  ...system ? { system } : {},
1984
+ ...thinkingConfig ? { thinking: thinkingConfig } : {},
1905
1985
  messages
1906
1986
  };
1907
1987
  return [apiConfig, reqValue];
@@ -1911,9 +1991,11 @@ var AxAIAnthropicImpl = class {
1911
1991
  throw new Error(`Anthropic Chat API Error: ${resp.error.message}`);
1912
1992
  }
1913
1993
  const finishReason = mapFinishReason(resp.stop_reason);
1914
- const results = resp.content.map((msg) => {
1994
+ const showThoughts = this.currentPromptConfig?.thinkingTokenBudget !== "none" && this.currentPromptConfig?.showThoughts !== false;
1995
+ const results = resp.content.map((msg, index) => {
1915
1996
  if (msg.type === "tool_use") {
1916
1997
  return {
1998
+ index,
1917
1999
  id: msg.id,
1918
2000
  functionCalls: [
1919
2001
  {
@@ -1928,12 +2010,23 @@ var AxAIAnthropicImpl = class {
1928
2010
  finishReason
1929
2011
  };
1930
2012
  }
2013
+ if ((msg.type === "thinking" || msg.type === "redacted_thinking") && showThoughts) {
2014
+ return {
2015
+ index,
2016
+ thought: msg.thinking,
2017
+ id: resp.id,
2018
+ finishReason
2019
+ };
2020
+ }
1931
2021
  return {
2022
+ index,
1932
2023
  content: msg.type === "text" ? msg.text : "",
1933
2024
  id: resp.id,
1934
2025
  finishReason
1935
2026
  };
1936
- });
2027
+ }).filter(
2028
+ (result) => result.content !== "" || result.thought !== void 0 || result.functionCalls !== void 0
2029
+ );
1937
2030
  this.tokensUsed = {
1938
2031
  promptTokens: resp.usage.input_tokens,
1939
2032
  completionTokens: resp.usage.output_tokens,
@@ -1953,9 +2046,10 @@ var AxAIAnthropicImpl = class {
1953
2046
  const { error } = resp;
1954
2047
  throw new Error(error.message);
1955
2048
  }
2049
+ const index = 0;
1956
2050
  if (resp.type === "message_start") {
1957
2051
  const { message } = resp;
1958
- const results = [{ content: "", id: message.id }];
2052
+ const results = [{ index, content: "", id: message.id }];
1959
2053
  this.tokensUsed = {
1960
2054
  promptTokens: message.usage?.input_tokens ?? 0,
1961
2055
  completionTokens: message.usage?.output_tokens ?? 0,
@@ -1967,7 +2061,18 @@ var AxAIAnthropicImpl = class {
1967
2061
  const { content_block: contentBlock } = resp;
1968
2062
  if (contentBlock.type === "text") {
1969
2063
  return {
1970
- results: [{ content: contentBlock.text }]
2064
+ results: [{ index, content: contentBlock.text }]
2065
+ };
2066
+ }
2067
+ if (contentBlock.type === "thinking") {
2068
+ const showThoughts = this.currentPromptConfig?.thinkingTokenBudget !== "none" && this.currentPromptConfig?.showThoughts !== false;
2069
+ if (showThoughts) {
2070
+ return {
2071
+ results: [{ index, thought: contentBlock.thinking }]
2072
+ };
2073
+ }
2074
+ return {
2075
+ results: [{ index, content: "" }]
1971
2076
  };
1972
2077
  }
1973
2078
  if (contentBlock.type === "tool_use") {
@@ -1984,7 +2089,7 @@ var AxAIAnthropicImpl = class {
1984
2089
  }
1985
2090
  ];
1986
2091
  return {
1987
- results: [{ functionCalls }]
2092
+ results: [{ index, functionCalls }]
1988
2093
  };
1989
2094
  }
1990
2095
  }
@@ -1993,7 +2098,23 @@ var AxAIAnthropicImpl = class {
1993
2098
  const { delta } = resp;
1994
2099
  if (delta.type === "text_delta") {
1995
2100
  return {
1996
- results: [{ content: delta.text }]
2101
+ results: [{ index, content: delta.text }]
2102
+ };
2103
+ }
2104
+ if (delta.type === "thinking_delta") {
2105
+ const showThoughts = this.currentPromptConfig?.thinkingTokenBudget !== "none" && this.currentPromptConfig?.showThoughts !== false;
2106
+ if (showThoughts) {
2107
+ return {
2108
+ results: [{ index, thought: delta.thinking }]
2109
+ };
2110
+ }
2111
+ return {
2112
+ results: [{ index, content: "" }]
2113
+ };
2114
+ }
2115
+ if (delta.type === "signature_delta") {
2116
+ return {
2117
+ results: [{ index, content: "" }]
1997
2118
  };
1998
2119
  }
1999
2120
  if (delta.type === "input_json_delta") {
@@ -2012,7 +2133,7 @@ var AxAIAnthropicImpl = class {
2012
2133
  }
2013
2134
  ];
2014
2135
  return {
2015
- results: [{ functionCalls }]
2136
+ results: [{ index, functionCalls }]
2016
2137
  };
2017
2138
  }
2018
2139
  }
@@ -2024,12 +2145,16 @@ var AxAIAnthropicImpl = class {
2024
2145
  totalTokens: usage.output_tokens
2025
2146
  };
2026
2147
  const results = [
2027
- { content: "", finishReason: mapFinishReason(delta.stop_reason) }
2148
+ {
2149
+ index,
2150
+ content: "",
2151
+ finishReason: mapFinishReason(delta.stop_reason)
2152
+ }
2028
2153
  ];
2029
2154
  return { results };
2030
2155
  }
2031
2156
  return {
2032
- results: [{ content: "" }]
2157
+ results: [{ index, content: "" }]
2033
2158
  };
2034
2159
  };
2035
2160
  };
@@ -2071,6 +2196,20 @@ var AxAIAnthropic = class extends AxBaseAI {
2071
2196
  ...config
2072
2197
  };
2073
2198
  const aiImpl = new AxAIAnthropicImpl(_config, isVertex);
2199
+ const supportFor = (model) => {
2200
+ const mi = getModelInfo({
2201
+ model,
2202
+ modelInfo: axModelInfoAnthropic,
2203
+ models
2204
+ });
2205
+ return {
2206
+ functions: true,
2207
+ streaming: true,
2208
+ hasThinkingBudget: mi?.hasThinkingBudget ?? false,
2209
+ hasShowThoughts: mi?.hasShowThoughts ?? false,
2210
+ functionCot: true
2211
+ };
2212
+ };
2074
2213
  super(aiImpl, {
2075
2214
  name: "Anthropic",
2076
2215
  apiURL,
@@ -2078,7 +2217,7 @@ var AxAIAnthropic = class extends AxBaseAI {
2078
2217
  modelInfo: axModelInfoAnthropic,
2079
2218
  defaults: { model: _config.model },
2080
2219
  options,
2081
- supportFor: { functions: true, streaming: true, functionCot: true },
2220
+ supportFor,
2082
2221
  models
2083
2222
  });
2084
2223
  }
@@ -2208,22 +2347,6 @@ function mapFinishReason(stopReason) {
2208
2347
  }
2209
2348
  }
2210
2349
 
2211
- // dsp/modelinfo.ts
2212
- function getModelInfo({
2213
- model,
2214
- modelInfo,
2215
- models
2216
- }) {
2217
- const modelEntry = models?.find((v) => v.key === model);
2218
- const mappedModel = modelEntry && "model" in modelEntry ? modelEntry.model : model;
2219
- const exactMatch = modelInfo.find((v) => v.name === model);
2220
- if (exactMatch) return exactMatch;
2221
- 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+$/, "");
2222
- const normalizedMatch = modelInfo.find((v) => v.name === normalizedName);
2223
- if (normalizedMatch) return normalizedMatch;
2224
- return null;
2225
- }
2226
-
2227
2350
  // ai/openai/chat_types.ts
2228
2351
  var AxAIOpenAIModel = /* @__PURE__ */ ((AxAIOpenAIModel2) => {
2229
2352
  AxAIOpenAIModel2["O1"] = "o1";
@@ -2558,6 +2681,7 @@ var AxAIOpenAIImpl = class {
2558
2681
  })
2559
2682
  );
2560
2683
  return {
2684
+ index: choice.index,
2561
2685
  id: `${choice.index}`,
2562
2686
  content: choice.message.content,
2563
2687
  thought: choice.message.reasoning_content,
@@ -2583,6 +2707,7 @@ var AxAIOpenAIImpl = class {
2583
2707
  }
2584
2708
  const results = choices.map(
2585
2709
  ({
2710
+ index,
2586
2711
  delta: {
2587
2712
  content,
2588
2713
  role,
@@ -2592,11 +2717,11 @@ var AxAIOpenAIImpl = class {
2592
2717
  finish_reason: oaiFinishReason
2593
2718
  }) => {
2594
2719
  const finishReason = mapFinishReason2(oaiFinishReason);
2595
- const functionCalls = toolCalls?.map(({ id: _id, index, function: { name, arguments: params } }) => {
2596
- if (typeof _id === "string" && typeof index === "number" && !sstate.indexIdMap[index]) {
2597
- sstate.indexIdMap[index] = _id;
2720
+ const functionCalls = toolCalls?.map(({ id: _id, index: index2, function: { name, arguments: params } }) => {
2721
+ if (typeof _id === "string" && typeof index2 === "number" && !sstate.indexIdMap[index2]) {
2722
+ sstate.indexIdMap[index2] = _id;
2598
2723
  }
2599
- const id2 = sstate.indexIdMap[index];
2724
+ const id2 = sstate.indexIdMap[index2];
2600
2725
  if (!id2) {
2601
2726
  return null;
2602
2727
  }
@@ -2607,6 +2732,7 @@ var AxAIOpenAIImpl = class {
2607
2732
  };
2608
2733
  }).filter((v) => v !== null);
2609
2734
  return {
2735
+ index,
2610
2736
  content,
2611
2737
  role,
2612
2738
  thought,
@@ -2641,7 +2767,7 @@ var mapFinishReason2 = (finishReason) => {
2641
2767
  }
2642
2768
  };
2643
2769
  function createMessages2(req) {
2644
- return req.chatPrompt.map((msg) => {
2770
+ const openaiReq = req.chatPrompt.map((msg) => {
2645
2771
  switch (msg.role) {
2646
2772
  case "system":
2647
2773
  return { role: "system", content: msg.content };
@@ -2690,7 +2816,7 @@ function createMessages2(req) {
2690
2816
  tool_calls: toolCalls
2691
2817
  };
2692
2818
  }
2693
- if (!msg.content) {
2819
+ if (msg.content === void 0) {
2694
2820
  throw new Error(
2695
2821
  "Assistant content is required when no tool calls are provided"
2696
2822
  );
@@ -2710,6 +2836,7 @@ function createMessages2(req) {
2710
2836
  throw new Error("Invalid role");
2711
2837
  }
2712
2838
  });
2839
+ return openaiReq;
2713
2840
  }
2714
2841
  var AxAIOpenAIBase = class extends AxBaseAI {
2715
2842
  constructor({
@@ -3063,6 +3190,7 @@ var AxAICohereImpl = class {
3063
3190
  }
3064
3191
  const results = [
3065
3192
  {
3193
+ index: 0,
3066
3194
  id: resp.generation_id,
3067
3195
  content: resp.text,
3068
3196
  functionCalls,
@@ -3695,7 +3823,7 @@ var AxAIGoogleGeminiImpl = class {
3695
3823
  createChatResp = (resp) => {
3696
3824
  const results = resp.candidates?.map(
3697
3825
  (candidate) => {
3698
- const result = {};
3826
+ const result = { index: 0 };
3699
3827
  switch (candidate.finishReason) {
3700
3828
  case "MAX_TOKENS":
3701
3829
  result.finishReason = "length";
@@ -4092,6 +4220,7 @@ ${fc}`;
4092
4220
  return {
4093
4221
  results: [
4094
4222
  {
4223
+ index: 0,
4095
4224
  content: resp.generated_text
4096
4225
  }
4097
4226
  ]
@@ -4733,7 +4862,7 @@ var AxAIOpenAIResponsesImpl = class {
4733
4862
  }
4734
4863
  }
4735
4864
  return {
4736
- results: [currentResult],
4865
+ results: [{ ...currentResult, index: 0 }],
4737
4866
  remoteId: id
4738
4867
  };
4739
4868
  }
@@ -4741,6 +4870,7 @@ var AxAIOpenAIResponsesImpl = class {
4741
4870
  createChatStreamResp(streamEvent) {
4742
4871
  const event = streamEvent;
4743
4872
  const baseResult = {
4873
+ index: 0,
4744
4874
  id: "",
4745
4875
  content: "",
4746
4876
  finishReason: "stop"
@@ -5308,7 +5438,7 @@ var AxAIRekaImpl = class {
5308
5438
  completionTokens: usage.output_tokens,
5309
5439
  totalTokens: usage.input_tokens + usage.output_tokens
5310
5440
  } : void 0;
5311
- const results = responses.map((res) => {
5441
+ const results = responses.map((res, index) => {
5312
5442
  const finishReason = mapFinishReason3(res.finish_reason);
5313
5443
  let content;
5314
5444
  if (typeof res.message.content === "string") {
@@ -5317,6 +5447,7 @@ var AxAIRekaImpl = class {
5317
5447
  content = res.message.content.text;
5318
5448
  }
5319
5449
  return {
5450
+ index,
5320
5451
  id: `${id}`,
5321
5452
  content,
5322
5453
  finishReason
@@ -5331,7 +5462,7 @@ var AxAIRekaImpl = class {
5331
5462
  completionTokens: usage.output_tokens,
5332
5463
  totalTokens: usage.input_tokens + usage.output_tokens
5333
5464
  } : void 0;
5334
- const results = responses.map((res) => {
5465
+ const results = responses.map((res, index) => {
5335
5466
  const finishReason = mapFinishReason3(res.finish_reason);
5336
5467
  let content;
5337
5468
  if (typeof res.chunk.content === "string") {
@@ -5340,6 +5471,7 @@ var AxAIRekaImpl = class {
5340
5471
  content = res.chunk.content.text;
5341
5472
  }
5342
5473
  return {
5474
+ index,
5343
5475
  id: `${id}`,
5344
5476
  content,
5345
5477
  finishReason
@@ -5693,116 +5825,330 @@ var AxAIGrok = class extends AxAIOpenAIBase {
5693
5825
  };
5694
5826
 
5695
5827
  // dsp/generate.ts
5696
- import { ReadableStream as ReadableStream2 } from "stream/web";
5828
+ import { ReadableStream as ReadableStream3 } from "stream/web";
5697
5829
  import {
5698
5830
  context as context2,
5699
5831
  SpanKind as SpanKind2,
5700
5832
  trace
5701
5833
  } from "@opentelemetry/api";
5702
5834
 
5703
- // ai/util.ts
5704
- function mergeFunctionCalls(functionCalls, functionCallDeltas) {
5705
- for (const _fc of functionCallDeltas) {
5706
- const fc = functionCalls.find((fc2) => fc2.id === _fc.id);
5707
- if (fc) {
5708
- if (typeof _fc.function.name == "string" && _fc.function.name.length > 0) {
5709
- fc.function.name += _fc.function.name;
5835
+ // ai/validate.ts
5836
+ function axValidateChatRequestMessage(item) {
5837
+ if (!item) {
5838
+ throw new Error("Chat request message item cannot be null or undefined");
5839
+ }
5840
+ if (!item.role) {
5841
+ throw new Error("Chat request message must have a role");
5842
+ }
5843
+ switch (item.role) {
5844
+ case "system":
5845
+ if (!item.content || item.content.trim() === "") {
5846
+ throw new Error(
5847
+ "System message content cannot be empty or whitespace-only"
5848
+ );
5710
5849
  }
5711
- if (typeof _fc.function.params == "string" && _fc.function.params.length > 0) {
5712
- fc.function.params += _fc.function.params;
5850
+ break;
5851
+ case "user":
5852
+ if (!item.content) {
5853
+ throw new Error("User message content cannot be undefined");
5713
5854
  }
5714
- if (typeof _fc.function.params == "object") {
5715
- fc.function.params = _fc.function.params;
5855
+ if (typeof item.content === "string") {
5856
+ if (item.content.trim() === "") {
5857
+ throw new Error(
5858
+ "User message content cannot be empty or whitespace-only"
5859
+ );
5860
+ }
5861
+ } else if (Array.isArray(item.content)) {
5862
+ if (item.content.length === 0) {
5863
+ throw new Error("User message content array cannot be empty");
5864
+ }
5865
+ for (let index = 0; index < item.content.length; index++) {
5866
+ const contentItem = item.content[index];
5867
+ if (!contentItem || typeof contentItem !== "object") {
5868
+ throw new Error(
5869
+ `User message content item at index ${index} must be an object`
5870
+ );
5871
+ }
5872
+ if (!contentItem.type) {
5873
+ throw new Error(
5874
+ `User message content item at index ${index} must have a type`
5875
+ );
5876
+ }
5877
+ switch (contentItem.type) {
5878
+ case "text":
5879
+ if (!contentItem.text || contentItem.text.trim() === "") {
5880
+ throw new Error(
5881
+ `User message text content at index ${index} cannot be empty or whitespace-only`
5882
+ );
5883
+ }
5884
+ break;
5885
+ case "image":
5886
+ if (!contentItem.image || contentItem.image.trim() === "") {
5887
+ throw new Error(
5888
+ `User message image content at index ${index} cannot be empty`
5889
+ );
5890
+ }
5891
+ if (!contentItem.mimeType || contentItem.mimeType.trim() === "") {
5892
+ throw new Error(
5893
+ `User message image content at index ${index} must have a mimeType`
5894
+ );
5895
+ }
5896
+ break;
5897
+ case "audio":
5898
+ if (!contentItem.data || contentItem.data.trim() === "") {
5899
+ throw new Error(
5900
+ `User message audio content at index ${index} cannot be empty`
5901
+ );
5902
+ }
5903
+ break;
5904
+ default:
5905
+ throw new Error(
5906
+ `User message content item at index ${index} has unsupported type: ${contentItem.type}`
5907
+ );
5908
+ }
5909
+ }
5910
+ } else {
5911
+ throw new Error(
5912
+ "User message content must be a string or array of content objects"
5913
+ );
5716
5914
  }
5717
- } else {
5718
- functionCalls.push(_fc);
5719
- }
5915
+ break;
5916
+ case "assistant":
5917
+ if (!item.content && !item.functionCalls) {
5918
+ throw new Error(
5919
+ "Assistant message must have either content or function calls"
5920
+ );
5921
+ }
5922
+ if (item.content && typeof item.content !== "string") {
5923
+ throw new Error("Assistant message content must be a string");
5924
+ }
5925
+ if (item.functionCalls && !Array.isArray(item.functionCalls)) {
5926
+ throw new Error("Assistant message function calls must be an array");
5927
+ }
5928
+ break;
5929
+ case "function":
5930
+ if (!item.functionId || item.functionId.trim() === "") {
5931
+ throw new Error("Function message must have a non-empty functionId");
5932
+ }
5933
+ if (item.result === void 0 || item.result === null) {
5934
+ throw new Error("Function message must have a result");
5935
+ }
5936
+ if (typeof item.result !== "string") {
5937
+ throw new Error("Function message result must be a string");
5938
+ }
5939
+ break;
5940
+ default:
5941
+ throw new Error(
5942
+ `Unsupported message role: ${item.role}`
5943
+ );
5720
5944
  }
5721
5945
  }
5722
-
5723
- // mem/memory.ts
5724
- var defaultLimit = 1e4;
5725
- var MemoryImpl = class {
5726
- constructor(limit = defaultLimit, options) {
5727
- this.limit = limit;
5728
- this.options = options;
5729
- if (limit <= 0) {
5730
- throw Error("argument 'limit' must be greater than 0");
5731
- }
5732
- }
5733
- data = [];
5734
- addMemory(value) {
5735
- if (Array.isArray(value)) {
5736
- this.data.push(...value.map((chat) => ({ chat: structuredClone(chat) })));
5737
- } else {
5738
- this.data.push({
5739
- chat: structuredClone(value)
5740
- });
5741
- }
5742
- if (this.data.length > this.limit) {
5743
- const removeCount = this.data.length - this.limit;
5744
- this.data.splice(0, removeCount);
5745
- }
5946
+ function axValidateChatResponseResult(results) {
5947
+ const resultsArray = Array.isArray(results) ? results : [results];
5948
+ if (resultsArray.length === 0) {
5949
+ throw new Error("Chat response results cannot be empty");
5746
5950
  }
5747
- add(value) {
5748
- this.addMemory(value);
5749
- if (this.options?.debug) {
5750
- debugRequest(value, this.options?.debugHideSystemPrompt);
5951
+ for (let arrayIndex = 0; arrayIndex < resultsArray.length; arrayIndex++) {
5952
+ const result = resultsArray[arrayIndex];
5953
+ if (!result) {
5954
+ throw new Error(
5955
+ `Chat response result at index ${arrayIndex} cannot be null or undefined`
5956
+ );
5751
5957
  }
5752
- }
5753
- addResultMessage({
5754
- content,
5755
- name,
5756
- functionCalls
5757
- }) {
5758
- const isContentEmpty = typeof content === "string" && content.trim() === "";
5759
- if (isContentEmpty) {
5760
- this.addMemory({ name, role: "assistant", functionCalls });
5761
- } else {
5762
- this.addMemory({ content, name, role: "assistant", functionCalls });
5958
+ if (typeof result.index !== "number") {
5959
+ throw new Error(
5960
+ `Chat response result at index ${arrayIndex} must have a numeric index`
5961
+ );
5763
5962
  }
5764
- }
5765
- addResult({
5766
- content,
5767
- name,
5768
- functionCalls
5769
- }) {
5770
- this.addResultMessage({ content, name, functionCalls });
5771
- if (this.options?.debug) {
5772
- debugResponse({ content, name, functionCalls });
5963
+ if (result.index < 0) {
5964
+ throw new Error(
5965
+ `Chat response result at index ${arrayIndex} must have a non-negative index`
5966
+ );
5773
5967
  }
5774
- }
5775
- updateResult({
5776
- content,
5777
- name,
5778
- functionCalls,
5779
- delta
5780
- }) {
5781
- const lastItem = this.data.at(-1);
5782
- if (!lastItem || lastItem.chat.role !== "assistant") {
5783
- throw new Error("No assistant message to update");
5968
+ if (!result.content && !result.thought && !result.functionCalls && !result.finishReason) {
5969
+ throw new Error(
5970
+ `Chat response result at index ${arrayIndex} must have at least one of: content, thought, functionCalls, or finishReason`
5971
+ );
5784
5972
  }
5785
- if (typeof content === "string" && content.trim() !== "") {
5786
- lastItem.chat.content = content;
5973
+ if (result.content !== void 0 && typeof result.content !== "string") {
5974
+ throw new Error(
5975
+ `Chat response result content at index ${arrayIndex} must be a string`
5976
+ );
5787
5977
  }
5788
- if (name && name.trim() !== "") {
5789
- lastItem.chat.name = name;
5978
+ if (result.thought !== void 0 && typeof result.thought !== "string") {
5979
+ throw new Error(
5980
+ `Chat response result thought at index ${arrayIndex} must be a string`
5981
+ );
5790
5982
  }
5791
- if (functionCalls && functionCalls.length > 0) {
5792
- lastItem.chat.functionCalls = functionCalls;
5983
+ if (result.name !== void 0) {
5984
+ if (typeof result.name !== "string") {
5985
+ throw new Error(
5986
+ `Chat response result name at index ${arrayIndex} must be a string`
5987
+ );
5988
+ }
5989
+ if (result.name.trim() === "") {
5990
+ throw new Error(
5991
+ `Chat response result name at index ${arrayIndex} cannot be empty or whitespace-only`
5992
+ );
5993
+ }
5793
5994
  }
5794
- if (this.options?.debug) {
5795
- if (delta && typeof delta === "string") {
5796
- debugResponseDelta(delta);
5797
- } else if (!delta && (content || functionCalls)) {
5798
- debugResponse({ content, name, functionCalls });
5995
+ if (result.id !== void 0) {
5996
+ if (typeof result.id !== "string") {
5997
+ throw new Error(
5998
+ `Chat response result id at index ${arrayIndex} must be a string`
5999
+ );
6000
+ }
6001
+ if (result.id.trim() === "") {
6002
+ throw new Error(
6003
+ `Chat response result id at index ${arrayIndex} cannot be empty or whitespace-only`
6004
+ );
5799
6005
  }
5800
6006
  }
5801
- }
5802
- addTag(name) {
5803
- const lastItem = this.data.at(-1);
5804
- if (!lastItem) {
5805
- return;
6007
+ if (result.functionCalls !== void 0) {
6008
+ if (!Array.isArray(result.functionCalls)) {
6009
+ throw new Error(
6010
+ `Chat response result functionCalls at index ${arrayIndex} must be an array`
6011
+ );
6012
+ }
6013
+ for (let callIndex = 0; callIndex < result.functionCalls.length; callIndex++) {
6014
+ const functionCall = result.functionCalls[callIndex];
6015
+ if (!functionCall) {
6016
+ throw new Error(
6017
+ `Function call at index ${callIndex} in result ${arrayIndex} cannot be null or undefined`
6018
+ );
6019
+ }
6020
+ if (!functionCall.id || typeof functionCall.id !== "string" || functionCall.id.trim() === "") {
6021
+ throw new Error(
6022
+ `Function call at index ${callIndex} in result ${arrayIndex} must have a non-empty string id`
6023
+ );
6024
+ }
6025
+ if (functionCall.type !== "function") {
6026
+ throw new Error(
6027
+ `Function call at index ${callIndex} in result ${arrayIndex} must have type 'function'`
6028
+ );
6029
+ }
6030
+ if (!functionCall.function) {
6031
+ throw new Error(
6032
+ `Function call at index ${callIndex} in result ${arrayIndex} must have a function object`
6033
+ );
6034
+ }
6035
+ if (!functionCall.function.name || typeof functionCall.function.name !== "string" || functionCall.function.name.trim() === "") {
6036
+ throw new Error(
6037
+ `Function call at index ${callIndex} in result ${arrayIndex} must have a non-empty function name`
6038
+ );
6039
+ }
6040
+ if (functionCall.function.params !== void 0) {
6041
+ if (typeof functionCall.function.params !== "string" && typeof functionCall.function.params !== "object") {
6042
+ throw new Error(
6043
+ `Function call params at index ${callIndex} in result ${arrayIndex} must be a string or object`
6044
+ );
6045
+ }
6046
+ }
6047
+ }
6048
+ }
6049
+ if (result.finishReason !== void 0) {
6050
+ const validFinishReasons = [
6051
+ "stop",
6052
+ "length",
6053
+ "function_call",
6054
+ "content_filter",
6055
+ "error"
6056
+ ];
6057
+ if (!validFinishReasons.includes(result.finishReason)) {
6058
+ throw new Error(
6059
+ `Chat response result finishReason at index ${arrayIndex} must be one of: ${validFinishReasons.join(", ")}`
6060
+ );
6061
+ }
6062
+ }
6063
+ }
6064
+ }
6065
+
6066
+ // mem/memory.ts
6067
+ var MemoryImpl = class {
6068
+ constructor(options) {
6069
+ this.options = options;
6070
+ }
6071
+ data = [];
6072
+ addRequest(items, index) {
6073
+ this.data.push(
6074
+ ...items.map((item) => {
6075
+ const value = structuredClone(item);
6076
+ return {
6077
+ role: item.role,
6078
+ chat: [{ index, value }]
6079
+ };
6080
+ })
6081
+ );
6082
+ if (this.options?.debug) {
6083
+ debugRequest(items, this.options?.debugHideSystemPrompt);
6084
+ }
6085
+ }
6086
+ addResponse(results) {
6087
+ const chat = results.map((result) => ({
6088
+ index: result.index,
6089
+ value: structuredClone(result)
6090
+ }));
6091
+ this.data.push({
6092
+ role: "assistant",
6093
+ chat
6094
+ });
6095
+ if (this.options?.debug) {
6096
+ for (const result of results) {
6097
+ debugResponse(result);
6098
+ }
6099
+ }
6100
+ }
6101
+ updateResult({
6102
+ content,
6103
+ name,
6104
+ functionCalls,
6105
+ delta,
6106
+ index
6107
+ }) {
6108
+ const lastItem = this.data.at(-1);
6109
+ const log = () => {
6110
+ if (this.options?.debug) {
6111
+ if (delta && typeof delta === "string") {
6112
+ debugResponseDelta(delta);
6113
+ } else if (!delta && (content || functionCalls)) {
6114
+ debugResponse({ content, name, functionCalls, index });
6115
+ }
6116
+ }
6117
+ };
6118
+ if (!lastItem || lastItem.role !== "assistant") {
6119
+ this.data.push({
6120
+ role: "assistant",
6121
+ chat: [
6122
+ { index, value: structuredClone({ content, name, functionCalls }) }
6123
+ ]
6124
+ });
6125
+ log();
6126
+ return;
6127
+ }
6128
+ const chat = lastItem.chat.find((v) => v.index === index);
6129
+ if (!chat) {
6130
+ lastItem.chat.push({
6131
+ index,
6132
+ value: structuredClone({ content, name, functionCalls })
6133
+ });
6134
+ log();
6135
+ return;
6136
+ }
6137
+ if ("content" in chat.value && typeof content === "string" && content.trim() !== "") {
6138
+ chat.value.content = content;
6139
+ }
6140
+ if ("name" in chat.value && name && name.trim() !== "") {
6141
+ chat.value.name = name;
6142
+ }
6143
+ if ("functionCalls" in chat.value && functionCalls && functionCalls.length > 0) {
6144
+ chat.value.functionCalls = functionCalls;
6145
+ }
6146
+ log();
6147
+ }
6148
+ addTag(name) {
6149
+ const lastItem = this.data.at(-1);
6150
+ if (!lastItem) {
6151
+ return;
5806
6152
  }
5807
6153
  if (!lastItem.tags) {
5808
6154
  lastItem.tags = [];
@@ -5816,8 +6162,7 @@ var MemoryImpl = class {
5816
6162
  if (tagIndex === -1) {
5817
6163
  throw new Error(`Tag "${name}" not found`);
5818
6164
  }
5819
- const removedItems = this.data.splice(tagIndex);
5820
- return removedItems.map((item) => item.chat);
6165
+ return this.data.splice(tagIndex);
5821
6166
  }
5822
6167
  removeByTag(name) {
5823
6168
  const indices = this.data.reduce((acc, item, index) => {
@@ -5829,28 +6174,29 @@ var MemoryImpl = class {
5829
6174
  if (indices.length === 0) {
5830
6175
  throw new Error(`No items found with tag "${name}"`);
5831
6176
  }
5832
- return indices.reverse().map((index) => this.data.splice(index, 1).at(0)?.chat).filter(Boolean).reverse();
6177
+ return indices.reverse().map((index) => this.data.splice(index, 1).at(0)).filter((item) => item !== void 0).reverse();
5833
6178
  }
5834
- history() {
5835
- return this.data.map((item) => item.chat);
6179
+ history(index) {
6180
+ const result = [];
6181
+ for (const { role, chat } of this.data) {
6182
+ const value = chat.find((v) => v.index === index)?.value;
6183
+ if (value) {
6184
+ result.push({ role, ...value });
6185
+ }
6186
+ }
6187
+ return result;
5836
6188
  }
5837
6189
  getLast() {
5838
- const lastItem = this.data.at(-1);
5839
- if (!lastItem) return void 0;
5840
- return {
5841
- chat: lastItem.chat,
5842
- tags: lastItem.tags
5843
- };
6190
+ return this.data.at(-1);
5844
6191
  }
5845
6192
  reset() {
5846
6193
  this.data = [];
5847
6194
  }
5848
6195
  };
5849
6196
  var AxMemory = class {
5850
- constructor(limit = defaultLimit, options) {
5851
- this.limit = limit;
6197
+ constructor(options) {
5852
6198
  this.options = options;
5853
- this.defaultMemory = new MemoryImpl(limit, options);
6199
+ this.defaultMemory = new MemoryImpl(options);
5854
6200
  }
5855
6201
  memories = /* @__PURE__ */ new Map();
5856
6202
  defaultMemory;
@@ -5859,15 +6205,34 @@ var AxMemory = class {
5859
6205
  return this.defaultMemory;
5860
6206
  }
5861
6207
  if (!this.memories.has(sessionId)) {
5862
- this.memories.set(sessionId, new MemoryImpl(this.limit, this.options));
6208
+ this.memories.set(sessionId, new MemoryImpl(this.options));
5863
6209
  }
5864
6210
  return this.memories.get(sessionId);
5865
6211
  }
5866
- add(value, sessionId) {
5867
- this.getMemory(sessionId).add(value);
5868
- }
5869
- addResult(result, sessionId) {
5870
- this.getMemory(sessionId).addResult(result);
6212
+ addRequest(value, sessionId) {
6213
+ for (const item of value) {
6214
+ axValidateChatRequestMessage(item);
6215
+ }
6216
+ this.getMemory(sessionId).addRequest(value, 0);
6217
+ }
6218
+ addResponse(results, sessionId) {
6219
+ axValidateChatResponseResult(results);
6220
+ this.getMemory(sessionId).addResponse(results);
6221
+ }
6222
+ addFunctionResult({
6223
+ functionId,
6224
+ isError,
6225
+ index,
6226
+ result
6227
+ }, sessionId) {
6228
+ const functionMessage = {
6229
+ role: "function",
6230
+ functionId,
6231
+ isError,
6232
+ result
6233
+ };
6234
+ axValidateChatRequestMessage(functionMessage);
6235
+ this.getMemory(sessionId).addRequest([functionMessage], index);
5871
6236
  }
5872
6237
  updateResult(result, sessionId) {
5873
6238
  this.getMemory(sessionId).updateResult(result);
@@ -5878,8 +6243,8 @@ var AxMemory = class {
5878
6243
  rewindToTag(name, sessionId) {
5879
6244
  return this.getMemory(sessionId).rewindToTag(name);
5880
6245
  }
5881
- history(sessionId) {
5882
- return this.getMemory(sessionId).history();
6246
+ history(index, sessionId) {
6247
+ return this.getMemory(sessionId).history(index);
5883
6248
  }
5884
6249
  getLast(sessionId) {
5885
6250
  return this.getMemory(sessionId).getLast();
@@ -5888,7 +6253,7 @@ var AxMemory = class {
5888
6253
  if (!sessionId) {
5889
6254
  this.defaultMemory.reset();
5890
6255
  } else {
5891
- this.memories.set(sessionId, new MemoryImpl(this.limit, this.options));
6256
+ this.memories.set(sessionId, new MemoryImpl(this.options));
5892
6257
  }
5893
6258
  }
5894
6259
  };
@@ -5969,8 +6334,156 @@ var assertStreamingAssertions = async (asserts, xstate, content, final = false)
5969
6334
  }
5970
6335
  };
5971
6336
 
6337
+ // dsp/errors.ts
6338
+ var ValidationError = class extends Error {
6339
+ fields;
6340
+ constructor({
6341
+ message,
6342
+ fields
6343
+ }) {
6344
+ super(message);
6345
+ this.fields = fields;
6346
+ this.name = this.constructor.name;
6347
+ }
6348
+ getFixingInstructions = () => {
6349
+ const toFieldType2 = (type) => {
6350
+ const baseType = (() => {
6351
+ switch (type?.name) {
6352
+ case "string":
6353
+ return "string";
6354
+ case "number":
6355
+ return "number";
6356
+ case "boolean":
6357
+ return "boolean";
6358
+ case "date":
6359
+ return 'date ("YYYY-MM-DD" format)';
6360
+ case "datetime":
6361
+ return 'date time ("YYYY-MM-DD HH:mm Timezone" format)';
6362
+ case "json":
6363
+ return "JSON object";
6364
+ case "class":
6365
+ return "classification class";
6366
+ case "code":
6367
+ return "code";
6368
+ default:
6369
+ return "string";
6370
+ }
6371
+ })();
6372
+ return type?.isArray ? `json array of ${baseType} items` : baseType;
6373
+ };
6374
+ return this.fields.map((field) => ({
6375
+ name: "outputError",
6376
+ title: "Output Correction Required",
6377
+ 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.`
6378
+ }));
6379
+ };
6380
+ toString() {
6381
+ const toFieldType2 = (type) => {
6382
+ const baseType = (() => {
6383
+ switch (type?.name) {
6384
+ case "string":
6385
+ return "string";
6386
+ case "number":
6387
+ return "number";
6388
+ case "boolean":
6389
+ return "boolean";
6390
+ case "date":
6391
+ return 'date ("YYYY-MM-DD" format)';
6392
+ case "datetime":
6393
+ return 'date time ("YYYY-MM-DD HH:mm Timezone" format)';
6394
+ case "json":
6395
+ return "JSON object";
6396
+ case "class":
6397
+ return "classification class";
6398
+ case "code":
6399
+ return "code";
6400
+ default:
6401
+ return "string";
6402
+ }
6403
+ })();
6404
+ return type?.isArray ? `json array of ${baseType} items` : baseType;
6405
+ };
6406
+ return [
6407
+ `${this.name}: ${this.message}`,
6408
+ ...this.fields.map(
6409
+ (field) => ` - ${field.title}: Expected format '${toFieldType2(field.type)}'`
6410
+ )
6411
+ ].join("\n");
6412
+ }
6413
+ [Symbol.for("nodejs.util.inspect.custom")](_depth, _options) {
6414
+ return this.toString();
6415
+ }
6416
+ };
6417
+
5972
6418
  // dsp/datetime.ts
5973
6419
  import moment from "moment-timezone";
6420
+ function parseLLMFriendlyDate(field, dateStr, required = false) {
6421
+ try {
6422
+ return _parseLLMFriendlyDate(dateStr);
6423
+ } catch (err) {
6424
+ if (field.isOptional && !required) {
6425
+ return;
6426
+ }
6427
+ const message = err.message;
6428
+ throw new ValidationError({ fields: [field], message, value: dateStr });
6429
+ }
6430
+ }
6431
+ function _parseLLMFriendlyDate(dateStr) {
6432
+ if (!moment(dateStr, "YYYY-MM-DD", true).isValid()) {
6433
+ throw new Error(
6434
+ 'Invalid date format. Please provide the date in "YYYY-MM-DD" format.'
6435
+ );
6436
+ }
6437
+ const date = moment.utc(dateStr, "YYYY-MM-DD").startOf("day");
6438
+ return date.toDate();
6439
+ }
6440
+ function parseLLMFriendlyDateTime(field, dateStr, required = false) {
6441
+ try {
6442
+ return _parseLLMFriendlyDateTime(dateStr);
6443
+ } catch (err) {
6444
+ if (field.isOptional && !required) {
6445
+ return;
6446
+ }
6447
+ const message = err.message;
6448
+ throw new ValidationError({ fields: [field], message, value: dateStr });
6449
+ }
6450
+ }
6451
+ function _parseLLMFriendlyDateTime(dateTimeStr) {
6452
+ const dateTimeRegex = /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}(?::\d{2})?) (.+)$/;
6453
+ const match = dateTimeStr.match(dateTimeRegex);
6454
+ if (!match) {
6455
+ throw new Error(
6456
+ '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.'
6457
+ );
6458
+ }
6459
+ const [, dateTime, timeZone] = match;
6460
+ if (!dateTime || !timeZone) {
6461
+ throw new Error(
6462
+ '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.'
6463
+ );
6464
+ }
6465
+ const zone = moment.tz.zone(timeZone);
6466
+ if (!zone) {
6467
+ throw new Error(
6468
+ `Unrecognized time zone ${timeZone}. Please provide a valid time zone name, abbreviation, or offset. For example, "America/New_York", or "EST".`
6469
+ );
6470
+ }
6471
+ const date = moment.tz(
6472
+ dateTime,
6473
+ ["YYYY-MM-DD HH:mm", "YYYY-MM-DD HH:mm:ss"],
6474
+ zone.name
6475
+ );
6476
+ if (!date.isValid()) {
6477
+ throw new Error(
6478
+ "Invalid date and time values. Please ensure all components are correct."
6479
+ );
6480
+ }
6481
+ return date.utc().toDate();
6482
+ }
6483
+ var formatDateWithTimezone = (date) => {
6484
+ const momentDate = moment(date).utc();
6485
+ return momentDate.format(`YYYY-MM-DD HH:mm:ss UTC`);
6486
+ };
5974
6487
 
5975
6488
  // dsp/util.ts
5976
6489
  var colorLog3 = new ColorLog();
@@ -6133,18 +6646,24 @@ var parseMarkdownList = (input) => {
6133
6646
  }
6134
6647
  return list;
6135
6648
  };
6136
- function mergeDeltas(base, delta) {
6649
+ function mergeDeltas(base, currentDelta) {
6650
+ const { index, delta, version } = currentDelta;
6651
+ const target = base.find((b) => b.index === index)?.delta;
6652
+ if (!target) {
6653
+ base.push({ index, delta, version });
6654
+ return base;
6655
+ }
6137
6656
  for (const key of Object.keys(delta)) {
6138
- const baseValue = base[key];
6657
+ const baseValue = target[key];
6139
6658
  const deltaValue = delta[key];
6140
6659
  if (baseValue === void 0 && Array.isArray(deltaValue)) {
6141
- base[key] = [...deltaValue];
6660
+ target[key] = [...deltaValue];
6142
6661
  } else if (Array.isArray(baseValue) && Array.isArray(deltaValue)) {
6143
- base[key] = [...baseValue ?? [], ...deltaValue];
6662
+ target[key] = [...baseValue, ...deltaValue];
6144
6663
  } else if ((baseValue === void 0 || typeof baseValue === "string") && typeof deltaValue === "string") {
6145
- base[key] = (baseValue ?? "") + deltaValue;
6664
+ target[key] = `${baseValue ?? ""}${deltaValue}`;
6146
6665
  } else {
6147
- base[key] = deltaValue;
6666
+ target[key] = deltaValue;
6148
6667
  }
6149
6668
  }
6150
6669
  return base;
@@ -6261,904 +6780,340 @@ var updateDetailedProgress = (roundIndex, current, total, elapsedTime, example,
6261
6780
  console.log(output);
6262
6781
  };
6263
6782
 
6264
- // dsp/prompt.ts
6265
- var functionCallInstructions = `
6266
- ## Function Call Instructions
6267
- - Complete the task, using the functions defined earlier in this prompt.
6268
- - Call functions step-by-step, using the output of one function as input to the next.
6269
- - Use the function results to generate the output fields.`;
6270
- var formattingRules = `
6271
- ## Strict Output Formatting Rules
6272
- - Output must strictly follow the defined plain-text \`field name: value\` field format.
6273
- - Output field, values must strictly adhere to the specified output field formatting rules.
6274
- - Do not add any text before or after the output fields, just the field name and value.
6275
- - Do not use code blocks.`;
6276
- var AxPromptTemplate = class {
6277
- sig;
6278
- fieldTemplates;
6279
- task;
6280
- thoughtFieldName;
6281
- functions;
6282
- constructor(sig, options, fieldTemplates) {
6283
- this.sig = sig;
6284
- this.fieldTemplates = fieldTemplates;
6285
- this.thoughtFieldName = options?.thoughtFieldName ?? "thought";
6286
- this.functions = options?.functions;
6287
- const task = [];
6288
- const inArgs = renderDescFields(this.sig.getInputFields());
6289
- const outArgs = renderDescFields(this.sig.getOutputFields());
6290
- task.push(
6291
- `You will be provided with the following fields: ${inArgs}. Your task is to generate new fields: ${outArgs}.`
6292
- );
6293
- const funcs = this.functions?.map((f2) => "toFunction" in f2 ? f2.toFunction() : f2)?.flat();
6294
- const funcList = funcs?.map((fn) => `- \`${fn.name}\`: ${formatDescription(fn.description)}`).join("\n");
6295
- if (funcList && funcList.length > 0) {
6296
- task.push(`## Available Functions
6297
- ${funcList}`);
6298
- }
6299
- const inputFields = renderInputFields(this.sig.getInputFields());
6300
- task.push(`## Input Fields
6301
- ${inputFields}`);
6302
- const outputFields = renderOutputFields(this.sig.getOutputFields());
6303
- task.push(`## Output Fields
6304
- ${outputFields}`);
6305
- if (funcList && funcList.length > 0) {
6306
- task.push(functionCallInstructions.trim());
6783
+ // dsp/extract.ts
6784
+ var extractValues = (sig, values, content, strictMode = false) => {
6785
+ const xstate = { extractedFields: [], streamedIndex: {}, s: -1 };
6786
+ streamingExtractValues(sig, values, xstate, content, { strictMode });
6787
+ streamingExtractFinalValue(sig, values, xstate, content);
6788
+ for (const field of sig.getOutputFields()) {
6789
+ if (field.isInternal) {
6790
+ delete values[field.name];
6307
6791
  }
6308
- task.push(formattingRules.trim());
6309
- const desc = this.sig.getDescription();
6310
- if (desc) {
6311
- const text = formatDescription(desc);
6312
- task.push(text);
6792
+ }
6793
+ };
6794
+ var checkMissingRequiredFields = (xstate, values, outputFields) => {
6795
+ const missingFields = [];
6796
+ for (const field of outputFields) {
6797
+ if (field && !field.isOptional && values[field.name] === void 0) {
6798
+ missingFields.push(field);
6313
6799
  }
6314
- this.task = {
6315
- type: "text",
6316
- text: task.join("\n\n")
6317
- };
6318
6800
  }
6319
- renderSingleValueUserContent = (values, renderedExamples, renderedDemos, examplesInSystemPrompt) => {
6320
- const completion = this.renderInputFields(values);
6321
- const promptList = examplesInSystemPrompt ? completion : [...renderedExamples, ...renderedDemos, ...completion];
6322
- const prompt = promptList.filter((v) => v !== void 0);
6323
- return prompt.every((v) => v.type === "text") ? prompt.map((v) => v.text).join("\n") : prompt.reduce(combineConsecutiveStrings("\n"), []);
6324
- };
6325
- render = (values, {
6326
- examples,
6327
- demos
6328
- }) => {
6329
- const renderedExamples = examples ? [
6330
- { type: "text", text: "\n\n## Examples\n" },
6331
- ...this.renderExamples(examples)
6332
- ] : [];
6333
- const renderedDemos = demos ? this.renderDemos(demos) : [];
6334
- const allTextExamples = renderedExamples.every((v) => v.type === "text");
6335
- const allTextDemos = renderedDemos.every((v) => v.type === "text");
6336
- const examplesInSystemPrompt = allTextExamples && allTextDemos;
6337
- let systemContent = this.task.text;
6338
- if (examplesInSystemPrompt) {
6339
- const combinedItems = [
6340
- { type: "text", text: systemContent },
6341
- ...renderedExamples,
6342
- ...renderedDemos
6343
- ];
6344
- combinedItems.reduce(combineConsecutiveStrings(""), []);
6345
- if (combinedItems && combinedItems[0]) {
6346
- systemContent = combinedItems[0].text;
6347
- }
6801
+ if (missingFields.length > 0) {
6802
+ throw new ValidationError({
6803
+ message: `Required ${missingFields.length === 1 ? "field" : "fields"} not found`,
6804
+ fields: missingFields
6805
+ });
6806
+ }
6807
+ };
6808
+ var streamingExtractValues = (sig, values, xstate, content, { strictMode, skipEarlyFail } = {}) => {
6809
+ const fields = sig.getOutputFields();
6810
+ let expectedField;
6811
+ for (const [index, field] of fields.entries()) {
6812
+ if (index === xstate.currFieldIndex && !xstate.inAssumedField) {
6813
+ continue;
6348
6814
  }
6349
- const systemPrompt = {
6350
- role: "system",
6351
- content: systemContent
6352
- };
6353
- if (Array.isArray(values)) {
6354
- let messages = [];
6355
- const history = values;
6356
- for (const [index, message] of history.entries()) {
6357
- let content;
6358
- if (index === 0) {
6359
- content = this.renderSingleValueUserContent(
6360
- message.values,
6361
- renderedExamples,
6362
- renderedDemos,
6363
- examplesInSystemPrompt
6364
- );
6365
- } else {
6366
- content = this.renderSingleValueUserContent(
6367
- message.values,
6368
- [],
6369
- [],
6370
- false
6371
- );
6372
- }
6373
- if (message.role === "user") {
6374
- messages.push({ role: "user", content });
6815
+ if (field.name in values && !(index === xstate.currFieldIndex && xstate.inAssumedField)) {
6816
+ continue;
6817
+ }
6818
+ const isFirst = xstate.extractedFields.length === 0;
6819
+ const prefix = (isFirst ? "" : "\n") + field.title + ":";
6820
+ let e = matchesContent(content, prefix, xstate.s);
6821
+ let prefixLen = prefix.length;
6822
+ switch (e) {
6823
+ case -1:
6824
+ if (skipEarlyFail) {
6375
6825
  continue;
6376
6826
  }
6377
- if (message.role !== "assistant") {
6378
- throw new Error("Invalid message role");
6827
+ if (!strictMode && fields.length === 1 && xstate.currField === void 0) {
6828
+ xstate.inAssumedField = true;
6829
+ expectedField = field;
6830
+ prefixLen = 0;
6831
+ e = 0;
6832
+ break;
6379
6833
  }
6380
- if (typeof content !== "string") {
6381
- throw new Error(
6382
- "Assistant message cannot contain non-text content like images, files,etc"
6383
- );
6834
+ if (xstate.currField === void 0 && !field.isOptional) {
6835
+ throw new ValidationError({
6836
+ message: "Expected (Required) field not found",
6837
+ fields: [field]
6838
+ });
6384
6839
  }
6385
- messages.push({ role: "assistant", content });
6386
- }
6387
- return [systemPrompt, ...messages];
6840
+ expectedField = field.isOptional ? void 0 : field;
6841
+ continue;
6842
+ // Field is not found, continue to the next field
6843
+ case -2:
6844
+ return true;
6845
+ // Partial match at end, skip and gather more content
6846
+ case -3:
6847
+ return true;
6848
+ // String is only whitespace, skip and gather more content
6849
+ case -4:
6850
+ xstate.inBlock = true;
6851
+ return true;
6388
6852
  }
6389
- const userContent = this.renderSingleValueUserContent(
6390
- values,
6391
- renderedExamples,
6392
- renderedDemos,
6393
- examplesInSystemPrompt
6394
- );
6395
- return [systemPrompt, { role: "user", content: userContent }];
6396
- };
6397
- renderExtraFields = (extraFields) => {
6398
- const prompt = [];
6399
- if (!extraFields || extraFields.length === 0) {
6400
- return prompt;
6853
+ if (expectedField && expectedField.name !== field.name) {
6854
+ throw new ValidationError({
6855
+ message: "Expected (Required) field not found",
6856
+ fields: [expectedField]
6857
+ });
6401
6858
  }
6402
- const groupedFields = extraFields.reduce(
6403
- (acc, field) => {
6404
- const title = field.title;
6405
- if (!acc[title]) {
6406
- acc[title] = [];
6407
- }
6408
- acc[title].push(field);
6409
- return acc;
6410
- },
6411
- {}
6412
- );
6413
- const formattedGroupedFields = Object.entries(groupedFields).map(([title, fields]) => {
6414
- if (fields.length === 1) {
6415
- const field = fields[0];
6416
- return {
6417
- title,
6418
- name: field.name,
6419
- description: field.description
6420
- };
6421
- } else if (fields.length > 1) {
6422
- const valuesList = fields.map((field) => `- ${field.description}`).join("\n");
6423
- return {
6424
- title,
6425
- name: fields[0].name,
6426
- description: valuesList
6427
- };
6859
+ if (xstate.currField !== void 0 && xstate.inAssumedField) {
6860
+ xstate.inAssumedField = false;
6861
+ xstate.streamedIndex[xstate.currField.name] = 0;
6862
+ xstate.currField = void 0;
6863
+ }
6864
+ if (xstate.currField) {
6865
+ const val = content.substring(xstate.s, e).trim();
6866
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
6867
+ if (parsedValue !== void 0) {
6868
+ values[xstate.currField.name] = parsedValue;
6428
6869
  }
6429
- }).filter(Boolean);
6430
- formattedGroupedFields.forEach((field) => {
6431
- const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
6432
- prompt.push(...fn(field, field.description));
6433
- });
6434
- return prompt;
6435
- };
6436
- renderExamples = (data) => {
6437
- const list = [];
6438
- const exampleContext = {
6439
- isExample: true
6440
- };
6441
- for (const [index, item] of data.entries()) {
6442
- const renderedInputItem = this.sig.getInputFields().map(
6443
- (field) => this.renderInField(field, item, {
6444
- ...exampleContext,
6445
- isInputField: true
6446
- })
6447
- ).filter((v) => v !== void 0).flat();
6448
- const renderedOutputItem = this.sig.getOutputFields().map(
6449
- (field) => this.renderInField(field, item, {
6450
- ...exampleContext,
6451
- isInputField: false
6452
- })
6453
- ).filter((v) => v !== void 0).flat();
6454
- const renderedItem = [...renderedInputItem, ...renderedOutputItem];
6455
- if (index > 0 && renderedItem.length > 0 && renderedItem[0]?.type === "text") {
6456
- list.push({ type: "text", text: "---\n\n" });
6870
+ if (xstate.prevFields) {
6871
+ xstate.prevFields?.push({ field: xstate.currField, s: xstate.s, e });
6872
+ } else {
6873
+ xstate.prevFields = [{ field: xstate.currField, s: xstate.s, e }];
6457
6874
  }
6458
- renderedItem.forEach((v) => {
6459
- if ("text" in v) {
6460
- v.text = v.text + "\n";
6461
- }
6462
- list.push(v);
6463
- });
6464
6875
  }
6465
- return list;
6466
- };
6467
- renderDemos = (data) => {
6468
- const list = [];
6469
- const inputFields = this.sig.getInputFields();
6470
- const outputFields = this.sig.getOutputFields();
6471
- const demoContext = {
6472
- isExample: true
6473
- };
6474
- for (const item of data) {
6475
- const inputRenderedItems = inputFields.map(
6476
- (field) => this.renderInField(field, item, {
6477
- ...demoContext,
6478
- isInputField: true
6479
- })
6480
- ).filter((v) => v !== void 0).flat();
6481
- const outputRenderedItems = outputFields.map(
6482
- (field) => this.renderInField(field, item, {
6483
- ...demoContext,
6484
- isInputField: false
6485
- })
6486
- ).filter((v) => v !== void 0).flat();
6487
- const renderedItem = [...inputRenderedItems, ...outputRenderedItems];
6488
- renderedItem.slice(0, -1).forEach((v) => {
6489
- if ("text" in v) {
6490
- v.text = v.text + "\n";
6491
- }
6492
- list.push(v);
6493
- });
6876
+ xstate.s = e + prefixLen;
6877
+ xstate.currField = field;
6878
+ xstate.currFieldIndex = index;
6879
+ if (!xstate.extractedFields.includes(field)) {
6880
+ xstate.extractedFields.push(field);
6494
6881
  }
6495
- return list;
6496
- };
6497
- renderInputFields = (values) => {
6498
- const renderedItems = this.sig.getInputFields().map((field) => this.renderInField(field, values, void 0)).filter((v) => v !== void 0).flat();
6499
- renderedItems.filter((v) => v.type === "text").forEach((v) => {
6500
- v.text = v.text + "\n";
6501
- });
6502
- return renderedItems;
6503
- };
6504
- renderInField = (field, values, context3) => {
6505
- const value = values[field.name];
6506
- if (isEmptyValue(field, value, context3)) {
6507
- return;
6882
+ if (xstate.streamedIndex[field.name] === void 0) {
6883
+ xstate.streamedIndex[field.name] = 0;
6508
6884
  }
6509
- if (field.type) {
6510
- validateValue(field, value);
6885
+ }
6886
+ };
6887
+ var streamingExtractFinalValue = (sig, values, xstate, content) => {
6888
+ if (xstate.currField) {
6889
+ let val = content.substring(xstate.s).trim();
6890
+ const parsedValue = validateAndParseFieldValue(xstate.currField, val);
6891
+ if (parsedValue !== void 0) {
6892
+ values[xstate.currField.name] = parsedValue;
6511
6893
  }
6512
- const processedValue = processValue(field, value);
6513
- const textFieldFn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
6514
- return textFieldFn(field, processedValue);
6515
- };
6516
- defaultRenderInField = (field, value) => {
6517
- if (field.type?.name === "image") {
6518
- const validateImage = (value2) => {
6519
- if (!value2) {
6520
- throw new Error("Image field value is required.");
6521
- }
6522
- if (typeof value2 !== "object") {
6523
- throw new Error("Image field value must be an object.");
6524
- }
6525
- if (!("mimeType" in value2)) {
6526
- throw new Error("Image field must have mimeType");
6527
- }
6528
- if (!("data" in value2)) {
6529
- throw new Error("Image field must have data");
6530
- }
6531
- return value2;
6532
- };
6533
- let result = [
6534
- { type: "text", text: `${field.title}: ` }
6535
- ];
6536
- if (field.type.isArray) {
6537
- if (!Array.isArray(value)) {
6538
- throw new Error("Image field value must be an array.");
6894
+ }
6895
+ checkMissingRequiredFields(xstate, values, sig.getOutputFields());
6896
+ };
6897
+ var convertValueToType = (field, val, required = false) => {
6898
+ switch (field.type?.name) {
6899
+ case "code":
6900
+ return extractBlock(val);
6901
+ case "string":
6902
+ return val;
6903
+ case "number": {
6904
+ const v = Number(val);
6905
+ if (Number.isNaN(v)) {
6906
+ if (field.isOptional && !required) {
6907
+ return;
6539
6908
  }
6540
- result = result.concat(
6541
- value.map((v) => {
6542
- const validated = validateImage(v);
6543
- return {
6544
- type: "image",
6545
- mimeType: validated.mimeType,
6546
- image: validated.data
6547
- };
6548
- })
6549
- );
6550
- } else {
6551
- const validated = validateImage(value);
6552
- result.push({
6553
- type: "image",
6554
- mimeType: validated.mimeType,
6555
- image: validated.data
6556
- });
6909
+ throw new Error("Invalid number");
6557
6910
  }
6558
- return result;
6911
+ return v;
6559
6912
  }
6560
- if (field.type?.name === "audio") {
6561
- const validateAudio = (value2) => {
6562
- if (!value2) {
6563
- throw new Error("Audio field value is required.");
6564
- }
6565
- if (typeof value2 !== "object") {
6566
- throw new Error("Audio field value must be an object.");
6567
- }
6568
- if (!("data" in value2)) {
6569
- throw new Error("Audio field must have data");
6570
- }
6571
- return value2;
6572
- };
6573
- let result = [
6574
- { type: "text", text: `${field.title}: ` }
6575
- ];
6576
- if (field.type.isArray) {
6577
- if (!Array.isArray(value)) {
6578
- throw new Error("Audio field value must be an array.");
6579
- }
6580
- result = result.concat(
6581
- value.map((v) => {
6582
- const validated = validateAudio(v);
6583
- return {
6584
- type: "audio",
6585
- format: validated.format ?? "wav",
6586
- data: validated.data
6587
- };
6588
- })
6589
- );
6913
+ case "boolean": {
6914
+ if (typeof val === "boolean") {
6915
+ return val;
6916
+ }
6917
+ const v = val.toLowerCase();
6918
+ if (v === "true") {
6919
+ return true;
6920
+ } else if (v === "false") {
6921
+ return false;
6590
6922
  } else {
6591
- const validated = validateAudio(value);
6592
- result.push({
6593
- type: "audio",
6594
- format: validated.format ?? "wav",
6595
- data: validated.data
6596
- });
6923
+ if (field.isOptional && !required) {
6924
+ return;
6925
+ }
6926
+ throw new Error("Invalid boolean");
6597
6927
  }
6598
- return result;
6599
- }
6600
- const text = [field.title, ": "];
6601
- if (Array.isArray(value)) {
6602
- text.push("\n");
6603
- text.push(value.map((v) => `- ${v}`).join("\n"));
6604
- } else {
6605
- text.push(value);
6606
- }
6607
- return [{ type: "text", text: text.join("") }];
6608
- };
6609
- };
6610
- var renderDescFields = (list) => list.map((v) => `\`${v.title}\``).join(", ");
6611
- var renderInputFields = (fields) => {
6612
- const rows = fields.map((field) => {
6613
- const name = field.title;
6614
- const type = field.type?.name ? toFieldType(field.type) : "string";
6615
- const requiredMsg = field.isOptional ? `This optional ${type} field may be omitted` : `A ${type} field`;
6616
- const description = field.description ? ` ${formatDescription(field.description)}` : "";
6617
- return `${name}: (${requiredMsg})${description}`.trim();
6618
- });
6619
- return rows.join("\n");
6620
- };
6621
- var renderOutputFields = (fields) => {
6622
- const rows = fields.map((field) => {
6623
- const name = field.title;
6624
- const type = field.type?.name ? toFieldType(field.type) : "string";
6625
- const requiredMsg = field.isOptional ? `Only include this ${type} field if its value is available` : `This ${type} field must be included`;
6626
- let description = "";
6627
- if (field.description && field.description.length > 0) {
6628
- const value = field.type?.name === "class" ? field.description : formatDescription(field.description);
6629
- description = ` ${value}`;
6630
6928
  }
6631
- if (field.type?.options && field.type.options.length > 0) {
6632
- if (description.length > 0) {
6633
- description += `. `;
6929
+ case "date":
6930
+ return parseLLMFriendlyDate(field, val, required);
6931
+ case "datetime":
6932
+ return parseLLMFriendlyDateTime(field, val, required);
6933
+ case "class":
6934
+ const className = val;
6935
+ if (field.type.options && !field.type.options.includes(className)) {
6936
+ if (field.isOptional) {
6937
+ return;
6938
+ }
6939
+ throw new Error(
6940
+ `Invalid class '${val}', expected one of the following: ${field.type.options.join(", ")}`
6941
+ );
6634
6942
  }
6635
- description += `Allowed values: ${field.type.options.join(", ")}`;
6636
- }
6637
- return `${name}: (${requiredMsg})${description}`.trim();
6638
- });
6639
- return rows.join("\n");
6943
+ return className;
6944
+ default:
6945
+ return val;
6946
+ }
6640
6947
  };
6641
- var processValue = (field, value) => {
6642
- if (field.type?.name === "date" && value instanceof Date) {
6643
- const v = value.toISOString();
6644
- return v.slice(0, v.indexOf("T"));
6948
+ function* yieldDelta(content, field, s2, e, xstate, index) {
6949
+ const { name: fieldName, isInternal } = field;
6950
+ const { isArray: fieldIsArray, name: fieldTypeName } = field.type ?? {};
6951
+ if (isInternal || fieldIsArray || fieldTypeName && fieldTypeName !== "string" && fieldTypeName !== "code") {
6952
+ return;
6645
6953
  }
6646
- if (field.type?.name === "datetime" && value instanceof Date) {
6647
- return formatDateWithTimezone(value);
6954
+ const pos = xstate.streamedIndex[fieldName] ?? 0;
6955
+ const isFirstChunk = pos === 0;
6956
+ const d1 = content.substring(s2 + pos, e);
6957
+ if (d1.length === 0) {
6958
+ return;
6648
6959
  }
6649
- if (field.type?.name === "image" && typeof value === "object") {
6650
- return value;
6960
+ let d2 = d1.replace(/\s+$/, "");
6961
+ if (xstate.currField?.type?.name === "code") {
6962
+ d2 = d2.replace(/\s*```\s*$/, "");
6651
6963
  }
6652
- if (field.type?.name === "audio" && typeof value === "object") {
6653
- return value;
6964
+ let d3 = isFirstChunk ? d2.trimStart() : d2;
6965
+ if (xstate.currField?.type?.name === "code") {
6966
+ d3 = d3.replace(/^[ ]*```[a-zA-Z0-9]*\n\s*/, "");
6654
6967
  }
6655
- if (typeof value === "string") {
6656
- return value;
6968
+ if (d3.length > 0) {
6969
+ yield { index, delta: { [fieldName]: d3 } };
6970
+ xstate.streamedIndex[fieldName] = pos + d2.length;
6657
6971
  }
6658
- return JSON.stringify(value, null, 2);
6659
- };
6660
- var toFieldType = (type) => {
6661
- const baseType = (() => {
6662
- switch (type?.name) {
6663
- case "string":
6664
- return "string";
6665
- case "number":
6666
- return "number";
6667
- case "boolean":
6668
- return "boolean";
6669
- case "date":
6670
- return 'date ("YYYY-MM-DD" format)';
6671
- case "datetime":
6672
- return 'date time ("YYYY-MM-DD HH:mm Timezone" format)';
6673
- case "json":
6674
- return "JSON object";
6675
- case "class":
6676
- return "classification class";
6677
- case "code":
6678
- return "code";
6679
- default:
6680
- return "string";
6972
+ }
6973
+ function* streamValues(sig, content, values, xstate, index) {
6974
+ for (const prevField of xstate.prevFields ?? []) {
6975
+ const { field, s: s2, e } = prevField;
6976
+ yield* yieldDelta(content, field, s2, e, xstate, index);
6977
+ }
6978
+ xstate.prevFields = void 0;
6979
+ if (!xstate.currField || xstate.currField.isInternal) {
6980
+ return;
6981
+ }
6982
+ yield* yieldDelta(
6983
+ content,
6984
+ xstate.currField,
6985
+ xstate.s,
6986
+ content.length,
6987
+ xstate,
6988
+ index
6989
+ );
6990
+ const outputFields = sig.getOutputFields();
6991
+ for (const key of Object.keys(values)) {
6992
+ const field = outputFields.find((f2) => f2.name === key);
6993
+ if (!field || field.isInternal) {
6994
+ continue;
6681
6995
  }
6682
- })();
6683
- return type?.isArray ? `json array of ${baseType} items` : baseType;
6684
- };
6685
- function combineConsecutiveStrings(separator) {
6686
- return (acc, current) => {
6687
- if (current.type === "text") {
6688
- const previous = acc.length > 0 ? acc[acc.length - 1] : null;
6689
- if (previous && previous.type === "text") {
6690
- previous.text += separator + current.text;
6691
- } else {
6692
- acc.push(current);
6996
+ const value = values[key];
6997
+ if (Array.isArray(value)) {
6998
+ const s2 = xstate.streamedIndex?.[key] ?? 0;
6999
+ const v = value.slice(s2);
7000
+ if (v && v.length > 0) {
7001
+ yield { index, delta: { [key]: v } };
7002
+ xstate.streamedIndex[key] = s2 + v.length;
6693
7003
  }
6694
- } else {
6695
- acc.push(current);
7004
+ continue;
7005
+ }
7006
+ if (!xstate.streamedIndex[key]) {
7007
+ yield { index, delta: { [key]: value } };
7008
+ xstate.streamedIndex[key] = 1;
6696
7009
  }
6697
- return acc;
6698
- };
6699
- }
6700
- var isEmptyValue = (field, value, context3) => {
6701
- if (typeof value === "boolean") {
6702
- return false;
6703
7010
  }
6704
- if (!value || (Array.isArray(value) || typeof value === "string") && value.length === 0) {
6705
- if (context3?.isExample) {
6706
- return true;
6707
- }
6708
- if (field.isOptional || field.isInternal) {
6709
- return true;
6710
- }
6711
- const fieldType = context3?.isInputField !== false ? "input" : "output";
6712
- throw new Error(`Value for ${fieldType} field '${field.name}' is required.`);
6713
- }
6714
- return false;
6715
- };
6716
- function formatDescription(str) {
6717
- const value = str.trim();
6718
- return value.length > 0 ? `${value.charAt(0).toUpperCase()}${value.slice(1)}${value.endsWith(".") ? "" : "."}` : "";
6719
7011
  }
6720
-
6721
- // dsp/validate.ts
6722
- var ValidationError = class extends Error {
6723
- fields;
6724
- constructor({
6725
- message,
6726
- fields
6727
- }) {
6728
- super(message);
6729
- this.fields = fields;
6730
- this.name = this.constructor.name;
6731
- }
6732
- getFixingInstructions = () => {
6733
- return this.fields.map((field) => ({
6734
- name: "outputError",
6735
- title: "Output Correction Required",
6736
- 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.`
6737
- }));
6738
- };
6739
- toString() {
6740
- return [
6741
- `${this.name}: ${this.message}`,
6742
- ...this.fields.map(
6743
- (field) => ` - ${field.title}: Expected format '${toFieldType(field.type)}'`
6744
- )
6745
- ].join("\n");
6746
- }
6747
- [Symbol.for("nodejs.util.inspect.custom")](_depth, _options) {
6748
- return this.toString();
6749
- }
6750
- };
6751
- function handleValidationError(mem, errorFields, ai, promptTemplate, sessionId) {
6752
- mem.add(
6753
- {
6754
- role: "user",
6755
- content: promptTemplate.renderExtraFields(errorFields)
6756
- },
6757
- sessionId
6758
- );
6759
- mem.addTag("error");
6760
- if (ai.getOptions().debug) {
6761
- const errors = errorFields.map((field) => `- ${field.title}: ${field.description}`).join("\n");
6762
- const logger = ai.getLogger();
6763
- logger(`\u274C Error Correction:
6764
- ${errors}`, {
6765
- tags: ["error"]
7012
+ function validateAndParseFieldValue(field, fieldValue) {
7013
+ if (!fieldValue || fieldValue === "" || /^(null|undefined)\s*$/i.test(fieldValue)) {
7014
+ if (field.isOptional) {
7015
+ return;
7016
+ }
7017
+ throw new ValidationError({
7018
+ message: "Required field is missing",
7019
+ fields: [field],
7020
+ value: fieldValue
6766
7021
  });
6767
7022
  }
6768
- }
6769
-
6770
- // dsp/datetime.ts
6771
- function parseLLMFriendlyDate(field, dateStr, required = false) {
6772
- try {
6773
- return _parseLLMFriendlyDate(dateStr);
6774
- } catch (err) {
6775
- if (field.isOptional && !required) {
6776
- return;
7023
+ let value;
7024
+ if (field.type?.name === "json") {
7025
+ try {
7026
+ const text = extractBlock(fieldValue);
7027
+ value = JSON.parse(text);
7028
+ return value;
7029
+ } catch (e) {
7030
+ throw new ValidationError({
7031
+ message: "Invalid JSON: " + e.message,
7032
+ fields: [field],
7033
+ value: fieldValue
7034
+ });
6777
7035
  }
6778
- const message = err.message;
6779
- throw new ValidationError({ fields: [field], message, value: dateStr });
6780
7036
  }
6781
- }
6782
- function _parseLLMFriendlyDate(dateStr) {
6783
- if (!moment(dateStr, "YYYY-MM-DD", true).isValid()) {
6784
- throw new Error(
6785
- 'Invalid date format. Please provide the date in "YYYY-MM-DD" format.'
6786
- );
7037
+ if (field.type?.isArray) {
7038
+ try {
7039
+ try {
7040
+ value = JSON.parse(fieldValue);
7041
+ } catch {
7042
+ value = parseMarkdownList(fieldValue);
7043
+ }
7044
+ if (!Array.isArray(value)) {
7045
+ throw new Error("Expected an array");
7046
+ }
7047
+ } catch (e) {
7048
+ throw new ValidationError({
7049
+ message: "Invalid Array: " + e.message,
7050
+ fields: [field],
7051
+ value: fieldValue
7052
+ });
7053
+ }
6787
7054
  }
6788
- const date = moment.utc(dateStr, "YYYY-MM-DD").startOf("day");
6789
- return date.toDate();
6790
- }
6791
- function parseLLMFriendlyDateTime(field, dateStr, required = false) {
6792
7055
  try {
6793
- return _parseLLMFriendlyDateTime(dateStr);
6794
- } catch (err) {
6795
- if (field.isOptional && !required) {
6796
- return;
7056
+ if (Array.isArray(value)) {
7057
+ for (const [index, item] of value.entries()) {
7058
+ if (item !== void 0) {
7059
+ const v = typeof item === "string" ? item.trim() : item;
7060
+ value[index] = convertValueToType(field, v, true);
7061
+ }
7062
+ }
7063
+ } else {
7064
+ value = convertValueToType(field, fieldValue);
6797
7065
  }
6798
- const message = err.message;
6799
- throw new ValidationError({ fields: [field], message, value: dateStr });
7066
+ } catch (e) {
7067
+ throw new ValidationError({
7068
+ message: e.message,
7069
+ fields: [field],
7070
+ value: fieldValue
7071
+ });
7072
+ }
7073
+ if (typeof value === "string" && value === "") {
7074
+ return void 0;
6800
7075
  }
7076
+ return value;
6801
7077
  }
6802
- function _parseLLMFriendlyDateTime(dateTimeStr) {
6803
- const dateTimeRegex = /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}(?::\d{2})?) (.+)$/;
6804
- const match = dateTimeStr.match(dateTimeRegex);
7078
+ var extractBlock = (input) => {
7079
+ const markdownBlockPattern = /```([A-Za-z]*)\n([\s\S]*?)\n```/g;
7080
+ const match = markdownBlockPattern.exec(input);
6805
7081
  if (!match) {
6806
- throw new Error(
6807
- '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.'
6808
- );
6809
- }
6810
- const [, dateTime, timeZone] = match;
6811
- if (!dateTime || !timeZone) {
6812
- throw new Error(
6813
- '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.'
6814
- );
7082
+ return input;
6815
7083
  }
6816
- const zone = moment.tz.zone(timeZone);
6817
- if (!zone) {
6818
- throw new Error(
6819
- `Unrecognized time zone ${timeZone}. Please provide a valid time zone name, abbreviation, or offset. For example, "America/New_York", or "EST".`
6820
- );
7084
+ if (match.length === 3) {
7085
+ return match[2];
6821
7086
  }
6822
- const date = moment.tz(
6823
- dateTime,
6824
- ["YYYY-MM-DD HH:mm", "YYYY-MM-DD HH:mm:ss"],
6825
- zone.name
6826
- );
6827
- if (!date.isValid()) {
6828
- throw new Error(
6829
- "Invalid date and time values. Please ensure all components are correct."
6830
- );
7087
+ if (match.length === 2) {
7088
+ return match[1];
6831
7089
  }
6832
- return date.utc().toDate();
6833
- }
6834
- var formatDateWithTimezone = (date) => {
6835
- const momentDate = moment(date).utc();
6836
- return momentDate.format(`YYYY-MM-DD HH:mm:ss UTC`);
7090
+ return input;
6837
7091
  };
6838
7092
 
6839
- // dsp/extract.ts
6840
- var extractValues = (sig, values, content, strictMode = false) => {
6841
- const xstate = { extractedFields: [], streamedIndex: {}, s: -1 };
6842
- streamingExtractValues(sig, values, xstate, content, strictMode);
6843
- streamingExtractFinalValue(sig, values, xstate, content);
6844
- for (const field of sig.getOutputFields()) {
6845
- if (field.isInternal) {
6846
- delete values[field.name];
6847
- }
6848
- }
6849
- };
6850
- var checkMissingRequiredFields = (xstate, values, outputFields) => {
6851
- const missingFields = [];
6852
- for (const field of outputFields) {
6853
- if (field && !field.isOptional && values[field.name] === void 0) {
6854
- missingFields.push(field);
7093
+ // dsp/fieldProcessor.ts
7094
+ async function processFieldProcessors(fieldProcessors, values, mem, sessionId) {
7095
+ for (const processor of fieldProcessors) {
7096
+ if (values[processor.field.name] === void 0) {
7097
+ continue;
6855
7098
  }
6856
- }
6857
- if (missingFields.length > 0) {
6858
- throw new ValidationError({
6859
- message: `Required ${missingFields.length === 1 ? "field" : "fields"} not found`,
6860
- fields: missingFields
7099
+ const processFn = processor.process;
7100
+ const result = await processFn(values[processor.field.name], {
7101
+ sessionId,
7102
+ values,
7103
+ done: true
6861
7104
  });
7105
+ addToMemory(processor.field, mem, result, sessionId);
6862
7106
  }
6863
- };
6864
- var streamingExtractValues = (sig, values, xstate, content, strictMode = false) => {
6865
- const fields = sig.getOutputFields();
6866
- let expectedField;
6867
- for (const [index, field] of fields.entries()) {
6868
- if (index === xstate.currFieldIndex) {
6869
- continue;
6870
- }
6871
- if (field.name in values) {
7107
+ }
7108
+ async function processStreamingFieldProcessors(fieldProcessors, content, xstate, mem, values, sessionId, done = false) {
7109
+ for (const processor of fieldProcessors) {
7110
+ if (xstate.currField?.name !== processor.field.name) {
6872
7111
  continue;
6873
7112
  }
6874
- const isFirst = xstate.extractedFields.length === 0;
6875
- const prefix = (isFirst ? "" : "\n") + field.title + ":";
6876
- let e = matchesContent(content, prefix, xstate.s);
6877
- let prefixLen = prefix.length;
6878
- switch (e) {
6879
- case -1:
6880
- if (!strictMode && fields.length === 1 && xstate.currField === void 0) {
6881
- prefixLen = 0;
6882
- e = 0;
6883
- break;
6884
- }
6885
- if (xstate.currField === void 0 && !field.isOptional) {
6886
- throw new ValidationError({
6887
- message: "Expected (Required) field not found",
6888
- fields: [field]
6889
- });
6890
- }
6891
- expectedField = field.isOptional ? void 0 : field;
6892
- continue;
6893
- // Field is not found, continue to the next field
6894
- case -2:
6895
- return true;
6896
- // Partial match at end, skip and gather more content
6897
- case -3:
6898
- return true;
6899
- // String is only whitespace, skip and gather more content
6900
- case -4:
6901
- xstate.inBlock = true;
6902
- return true;
6903
- }
6904
- if (expectedField && expectedField.name !== field.name) {
6905
- throw new ValidationError({
6906
- message: "Expected (Required) field not found",
6907
- fields: [expectedField]
6908
- });
6909
- }
6910
- if (xstate.currField) {
6911
- const val = content.substring(xstate.s, e).trim();
6912
- const parsedValue = validateAndParseFieldValue(xstate.currField, val);
6913
- if (parsedValue !== void 0) {
6914
- values[xstate.currField.name] = parsedValue;
6915
- }
6916
- if (xstate.prevFields) {
6917
- xstate.prevFields?.push({ field: xstate.currField, s: xstate.s, e });
6918
- } else {
6919
- xstate.prevFields = [{ field: xstate.currField, s: xstate.s, e }];
6920
- }
6921
- }
6922
- xstate.s = e + prefixLen;
6923
- xstate.currField = field;
6924
- xstate.currFieldIndex = index;
6925
- if (!xstate.extractedFields.includes(field)) {
6926
- xstate.extractedFields.push(field);
6927
- }
6928
- if (xstate.streamedIndex[field.name] === void 0) {
6929
- xstate.streamedIndex[field.name] = 0;
6930
- }
6931
- }
6932
- };
6933
- var streamingExtractFinalValue = (sig, values, xstate, content) => {
6934
- if (xstate.currField) {
6935
- let val = content.substring(xstate.s).trim();
6936
- const parsedValue = validateAndParseFieldValue(xstate.currField, val);
6937
- if (parsedValue !== void 0) {
6938
- values[xstate.currField.name] = parsedValue;
6939
- }
6940
- }
6941
- checkMissingRequiredFields(xstate, values, sig.getOutputFields());
6942
- };
6943
- var convertValueToType = (field, val, required = false) => {
6944
- switch (field.type?.name) {
6945
- case "code":
6946
- return extractBlock(val);
6947
- case "string":
6948
- return val;
6949
- case "number": {
6950
- const v = Number(val);
6951
- if (Number.isNaN(v)) {
6952
- if (field.isOptional && !required) {
6953
- return;
6954
- }
6955
- throw new Error("Invalid number");
6956
- }
6957
- return v;
6958
- }
6959
- case "boolean": {
6960
- if (typeof val === "boolean") {
6961
- return val;
6962
- }
6963
- const v = val.toLowerCase();
6964
- if (v === "true") {
6965
- return true;
6966
- } else if (v === "false") {
6967
- return false;
6968
- } else {
6969
- if (field.isOptional && !required) {
6970
- return;
6971
- }
6972
- throw new Error("Invalid boolean");
6973
- }
6974
- }
6975
- case "date":
6976
- return parseLLMFriendlyDate(field, val, required);
6977
- case "datetime":
6978
- return parseLLMFriendlyDateTime(field, val, required);
6979
- case "class":
6980
- const className = val;
6981
- if (field.type.options && !field.type.options.includes(className)) {
6982
- if (field.isOptional) {
6983
- return;
6984
- }
6985
- throw new Error(
6986
- `Invalid class '${val}', expected one of the following: ${field.type.options.join(", ")}`
6987
- );
6988
- }
6989
- return className;
6990
- default:
6991
- return val;
6992
- }
6993
- };
6994
- function* yieldDelta(content, field, s2, e, xstate) {
6995
- const { name: fieldName, isInternal } = field;
6996
- const { isArray: fieldIsArray, name: fieldTypeName } = field.type ?? {};
6997
- if (isInternal || fieldIsArray || fieldTypeName && fieldTypeName !== "string" && fieldTypeName !== "code") {
6998
- return;
6999
- }
7000
- const pos = xstate.streamedIndex[fieldName] ?? 0;
7001
- const isFirstChunk = pos === 0;
7002
- const d1 = content.substring(s2 + pos, e);
7003
- if (d1.length === 0) {
7004
- return;
7005
- }
7006
- let d2 = d1.replace(/\s+$/, "");
7007
- if (xstate.currField?.type?.name === "code") {
7008
- d2 = d2.replace(/\s*```\s*$/, "");
7009
- }
7010
- let d3 = isFirstChunk ? d2.trimStart() : d2;
7011
- if (xstate.currField?.type?.name === "code") {
7012
- d3 = d3.replace(/^[ ]*```[a-zA-Z0-9]*\n\s*/, "");
7013
- }
7014
- if (d3.length > 0) {
7015
- yield { [fieldName]: d3 };
7016
- xstate.streamedIndex[fieldName] = pos + d2.length;
7017
- }
7018
- }
7019
- function* streamValues(sig, content, values, xstate) {
7020
- for (const prevField of xstate.prevFields ?? []) {
7021
- const { field, s: s2, e } = prevField;
7022
- yield* yieldDelta(content, field, s2, e, xstate);
7023
- }
7024
- xstate.prevFields = void 0;
7025
- if (!xstate.currField || xstate.currField.isInternal) {
7026
- return;
7027
- }
7028
- yield* yieldDelta(
7029
- content,
7030
- xstate.currField,
7031
- xstate.s,
7032
- content.length,
7033
- xstate
7034
- );
7035
- const outputFields = sig.getOutputFields();
7036
- for (const key of Object.keys(values)) {
7037
- const field = outputFields.find((f2) => f2.name === key);
7038
- if (!field || field.isInternal) {
7039
- continue;
7040
- }
7041
- const value = values[key];
7042
- if (Array.isArray(value)) {
7043
- const s2 = xstate.streamedIndex?.[key] ?? 0;
7044
- const v = value.slice(s2);
7045
- if (v && v.length > 0) {
7046
- yield { [key]: v };
7047
- xstate.streamedIndex[key] = s2 + v.length;
7048
- }
7049
- continue;
7050
- }
7051
- if (!xstate.streamedIndex[key]) {
7052
- yield { [key]: value };
7053
- xstate.streamedIndex[key] = 1;
7054
- }
7055
- }
7056
- }
7057
- function validateAndParseFieldValue(field, fieldValue) {
7058
- if (!fieldValue || fieldValue === "" || /^(null|undefined)\s*$/i.test(fieldValue)) {
7059
- if (field.isOptional) {
7060
- return;
7061
- }
7062
- throw new ValidationError({
7063
- message: "Required field is missing",
7064
- fields: [field],
7065
- value: fieldValue
7066
- });
7067
- }
7068
- let value;
7069
- if (field.type?.name === "json") {
7070
- try {
7071
- const text = extractBlock(fieldValue);
7072
- value = JSON.parse(text);
7073
- return value;
7074
- } catch (e) {
7075
- throw new ValidationError({
7076
- message: "Invalid JSON: " + e.message,
7077
- fields: [field],
7078
- value: fieldValue
7079
- });
7080
- }
7081
- }
7082
- if (field.type?.isArray) {
7083
- try {
7084
- try {
7085
- value = JSON.parse(fieldValue);
7086
- } catch {
7087
- value = parseMarkdownList(fieldValue);
7088
- }
7089
- if (!Array.isArray(value)) {
7090
- throw new Error("Expected an array");
7091
- }
7092
- } catch (e) {
7093
- throw new ValidationError({
7094
- message: "Invalid Array: " + e.message,
7095
- fields: [field],
7096
- value: fieldValue
7097
- });
7098
- }
7099
- }
7100
- try {
7101
- if (Array.isArray(value)) {
7102
- for (const [index, item] of value.entries()) {
7103
- if (item !== void 0) {
7104
- const v = typeof item === "string" ? item.trim() : item;
7105
- value[index] = convertValueToType(field, v, true);
7106
- }
7107
- }
7108
- } else {
7109
- value = convertValueToType(field, fieldValue);
7110
- }
7111
- } catch (e) {
7112
- throw new ValidationError({
7113
- message: e.message,
7114
- fields: [field],
7115
- value: fieldValue
7116
- });
7117
- }
7118
- if (typeof value === "string" && value === "") {
7119
- return void 0;
7120
- }
7121
- return value;
7122
- }
7123
- var extractBlock = (input) => {
7124
- const markdownBlockPattern = /```([A-Za-z]*)\n([\s\S]*?)\n```/g;
7125
- const match = markdownBlockPattern.exec(input);
7126
- if (!match) {
7127
- return input;
7128
- }
7129
- if (match.length === 3) {
7130
- return match[2];
7131
- }
7132
- if (match.length === 2) {
7133
- return match[1];
7134
- }
7135
- return input;
7136
- };
7137
-
7138
- // dsp/fieldProcessor.ts
7139
- async function processFieldProcessors(fieldProcessors, values, mem, sessionId) {
7140
- for (const processor of fieldProcessors) {
7141
- if (values[processor.field.name] === void 0) {
7142
- continue;
7143
- }
7144
- const processFn = processor.process;
7145
- const result = await processFn(values[processor.field.name], {
7146
- sessionId,
7147
- values,
7148
- done: true
7149
- });
7150
- addToMemory(processor.field, mem, result, sessionId);
7151
- }
7152
- }
7153
- async function processStreamingFieldProcessors(fieldProcessors, content, xstate, mem, values, sessionId, done = false) {
7154
- for (const processor of fieldProcessors) {
7155
- if (xstate.currField?.name !== processor.field.name) {
7156
- continue;
7157
- }
7158
- let value = content.substring(xstate.s);
7159
- if (xstate.currField?.type?.name === "code") {
7160
- value = value.replace(/^[ ]*```[a-zA-Z0-9]*\n\s*/, "");
7161
- value = value.replace(/\s*```\s*$/, "");
7113
+ let value = content.substring(xstate.s);
7114
+ if (xstate.currField?.type?.name === "code") {
7115
+ value = value.replace(/^[ ]*```[a-zA-Z0-9]*\n\s*/, "");
7116
+ value = value.replace(/\s*```\s*$/, "");
7162
7117
  }
7163
7118
  const processFn = processor.process;
7164
7119
  const result = await processFn(value, {
@@ -7179,7 +7134,10 @@ var addToMemory = (field, mem, result, sessionId) => {
7179
7134
  2
7180
7135
  );
7181
7136
  const text = getFieldProcessingMessage(field, resultText);
7182
- mem.add({ role: "user", content: [{ type: "text", text }] }, sessionId);
7137
+ mem.addRequest(
7138
+ [{ role: "user", content: [{ type: "text", text }] }],
7139
+ sessionId
7140
+ );
7183
7141
  mem.addTag(`processor`, sessionId);
7184
7142
  };
7185
7143
  function getFieldProcessingMessage(field, resultText) {
@@ -7438,10 +7396,10 @@ var AxFunctionProcessor = class {
7438
7396
  } : void 0;
7439
7397
  if (!fnSpec.parameters) {
7440
7398
  const res2 = fnSpec.func.length === 1 ? await fnSpec.func(opt) : await fnSpec.func();
7441
- return typeof res2 === "string" ? res2 : JSON.stringify(res2, null, 2);
7399
+ return typeof res2 === "string" ? res2 : res2 === void 0 || res2 === null ? "" : JSON.stringify(res2, null, 2);
7442
7400
  }
7443
7401
  const res = fnSpec.func.length === 2 ? await fnSpec.func(args, opt) : await fnSpec.func(args);
7444
- return typeof res === "string" ? res : JSON.stringify(res, null, 2);
7402
+ return typeof res === "string" ? res : res === void 0 || res === null ? "" : JSON.stringify(res, null, 2);
7445
7403
  };
7446
7404
  execute = async (func, options) => {
7447
7405
  const fnSpec = this.funcList.find(
@@ -7480,7 +7438,17 @@ var parseFunctions = (newFuncs, existingFuncs) => {
7480
7438
  }
7481
7439
  return [...existingFuncs ?? [], ...functions];
7482
7440
  };
7483
- var processFunctions = async (ai, functionList, functionCalls, mem, sessionId, traceId, span, excludeContentFromTelemetry) => {
7441
+ var processFunctions = async ({
7442
+ ai,
7443
+ functionList,
7444
+ functionCalls,
7445
+ mem,
7446
+ sessionId,
7447
+ traceId,
7448
+ span,
7449
+ excludeContentFromTrace,
7450
+ index
7451
+ }) => {
7484
7452
  const funcProc = new AxFunctionProcessor(functionList);
7485
7453
  const functionsExecuted = /* @__PURE__ */ new Set();
7486
7454
  const promises = functionCalls.map((func) => {
@@ -7493,16 +7461,16 @@ var processFunctions = async (ai, functionList, functionCalls, mem, sessionId, t
7493
7461
  const eventData = {
7494
7462
  name: func.name
7495
7463
  };
7496
- if (!excludeContentFromTelemetry) {
7464
+ if (!excludeContentFromTrace) {
7497
7465
  eventData.args = func.args;
7498
7466
  eventData.result = functionResult ?? "";
7499
7467
  }
7500
7468
  span.addEvent("function.call", eventData);
7501
7469
  }
7502
7470
  return {
7503
- role: "function",
7504
7471
  result: functionResult ?? "",
7505
- functionId: func.id
7472
+ functionId: func.id,
7473
+ index
7506
7474
  };
7507
7475
  }).catch((e) => {
7508
7476
  if (e instanceof FunctionError) {
@@ -7512,22 +7480,22 @@ var processFunctions = async (ai, functionList, functionCalls, mem, sessionId, t
7512
7480
  name: func.name,
7513
7481
  message: e.toString()
7514
7482
  };
7515
- if (!excludeContentFromTelemetry) {
7483
+ if (!excludeContentFromTrace) {
7516
7484
  errorEventData.args = func.args;
7517
7485
  errorEventData.fixing_instructions = result;
7518
7486
  }
7519
7487
  span.addEvent("function.error", errorEventData);
7520
7488
  }
7521
- mem.add(
7489
+ mem.addFunctionResult(
7522
7490
  {
7523
- role: "function",
7524
7491
  functionId: func.id,
7525
7492
  isError: true,
7493
+ index,
7526
7494
  result
7527
7495
  },
7528
7496
  sessionId
7529
7497
  );
7530
- mem.addTag("error");
7498
+ mem.addTag("error", sessionId);
7531
7499
  if (ai.getOptions().debug) {
7532
7500
  const logger = ai.getLogger();
7533
7501
  logger(`\u274C Function Error Correction:
@@ -7544,7 +7512,7 @@ ${result}`, {
7544
7512
  const results = await Promise.all(promises);
7545
7513
  for (const result of results) {
7546
7514
  if (result) {
7547
- mem.add(result, sessionId);
7515
+ mem.addFunctionResult(result, sessionId);
7548
7516
  }
7549
7517
  }
7550
7518
  return functionsExecuted;
@@ -7564,23 +7532,28 @@ function parseFunctionCalls(ai, functionCalls, values, model) {
7564
7532
  return funcs;
7565
7533
  }
7566
7534
 
7567
- // dsp/registry.ts
7568
- var AxInstanceRegistry = class {
7569
- reg;
7570
- // To track keys for iteration
7571
- constructor() {
7572
- this.reg = /* @__PURE__ */ new Set();
7573
- }
7574
- register(instance) {
7575
- this.reg.add(instance);
7576
- }
7577
- *[Symbol.iterator]() {
7578
- const items = Array.from(this.reg);
7579
- for (let i = 0; i < items.length; i++) {
7580
- yield items[i];
7535
+ // dsp/processResponse.ts
7536
+ import "stream/web";
7537
+
7538
+ // ai/util.ts
7539
+ function mergeFunctionCalls(functionCalls, functionCallDeltas) {
7540
+ for (const _fc of functionCallDeltas) {
7541
+ const fc = functionCalls.find((fc2) => fc2.id === _fc.id);
7542
+ if (fc) {
7543
+ if (typeof _fc.function.name == "string" && _fc.function.name.length > 0) {
7544
+ fc.function.name += _fc.function.name;
7545
+ }
7546
+ if (typeof _fc.function.params == "string" && _fc.function.params.length > 0) {
7547
+ fc.function.params += _fc.function.params;
7548
+ }
7549
+ if (typeof _fc.function.params == "object") {
7550
+ fc.function.params = _fc.function.params;
7551
+ }
7552
+ } else {
7553
+ functionCalls.push(_fc);
7581
7554
  }
7582
7555
  }
7583
- };
7556
+ }
7584
7557
 
7585
7558
  // dsp/sig.ts
7586
7559
  import { createHash } from "crypto";
@@ -8465,357 +8438,1153 @@ var AxSignature = class _AxSignature {
8465
8438
  );
8466
8439
  }
8467
8440
  };
8468
- getInputFields = () => this.inputFields;
8469
- getOutputFields = () => this.outputFields;
8470
- getDescription = () => this.description;
8471
- invalidateValidationCache = () => {
8472
- this.validatedAtHash = void 0;
8473
- };
8474
- toTitle = (name) => {
8475
- let result = name.replace(/_/g, " ");
8476
- result = result.replace(/([A-Z]|[0-9]+)/g, " $1").trim();
8477
- return result.charAt(0).toUpperCase() + result.slice(1);
8478
- };
8479
- toJSONSchema = () => {
8480
- const properties = {};
8481
- const required = [];
8482
- for (const f2 of this.inputFields) {
8483
- const type = f2.type ? f2.type.name : "string";
8484
- if (f2.type?.isArray) {
8485
- properties[f2.name] = {
8486
- description: f2.description,
8487
- type: "array",
8488
- items: {
8489
- type,
8490
- description: f2.description
8491
- }
8441
+ getInputFields = () => this.inputFields;
8442
+ getOutputFields = () => this.outputFields;
8443
+ getDescription = () => this.description;
8444
+ invalidateValidationCache = () => {
8445
+ this.validatedAtHash = void 0;
8446
+ };
8447
+ toTitle = (name) => {
8448
+ let result = name.replace(/_/g, " ");
8449
+ result = result.replace(/([A-Z]|[0-9]+)/g, " $1").trim();
8450
+ return result.charAt(0).toUpperCase() + result.slice(1);
8451
+ };
8452
+ toJSONSchema = () => {
8453
+ const properties = {};
8454
+ const required = [];
8455
+ for (const f2 of this.inputFields) {
8456
+ const type = f2.type ? f2.type.name : "string";
8457
+ if (f2.type?.isArray) {
8458
+ properties[f2.name] = {
8459
+ description: f2.description,
8460
+ type: "array",
8461
+ items: {
8462
+ type,
8463
+ description: f2.description
8464
+ }
8465
+ };
8466
+ } else {
8467
+ properties[f2.name] = {
8468
+ description: f2.description,
8469
+ type
8470
+ };
8471
+ }
8472
+ if (!f2.isOptional) {
8473
+ required.push(f2.name);
8474
+ }
8475
+ }
8476
+ const schema = {
8477
+ type: "object",
8478
+ properties,
8479
+ required
8480
+ };
8481
+ return schema;
8482
+ };
8483
+ updateHashLight = () => {
8484
+ try {
8485
+ this.getInputFields().forEach((field) => {
8486
+ validateField(field, "input");
8487
+ });
8488
+ this.getOutputFields().forEach((field) => {
8489
+ validateField(field, "output");
8490
+ });
8491
+ this.sigHash = createHash("sha256").update(JSON.stringify(this.inputFields)).update(JSON.stringify(this.outputFields)).digest("hex");
8492
+ this.sigString = renderSignature(
8493
+ this.description,
8494
+ this.inputFields,
8495
+ this.outputFields
8496
+ );
8497
+ return [this.sigHash, this.sigString];
8498
+ } catch (error) {
8499
+ if (error instanceof AxSignatureValidationError) {
8500
+ throw error;
8501
+ }
8502
+ throw new AxSignatureValidationError(
8503
+ `Signature validation failed: ${error instanceof Error ? error.message : "Unknown error"}`
8504
+ );
8505
+ }
8506
+ };
8507
+ updateHash = () => {
8508
+ try {
8509
+ this.getInputFields().forEach((field) => {
8510
+ validateField(field, "input");
8511
+ });
8512
+ this.getOutputFields().forEach((field) => {
8513
+ validateField(field, "output");
8514
+ });
8515
+ this.validateSignatureConsistency();
8516
+ this.sigHash = createHash("sha256").update(this.description ?? "").update(JSON.stringify(this.inputFields)).update(JSON.stringify(this.outputFields)).digest("hex");
8517
+ this.sigString = renderSignature(
8518
+ this.description,
8519
+ this.inputFields,
8520
+ this.outputFields
8521
+ );
8522
+ return [this.sigHash, this.sigString];
8523
+ } catch (error) {
8524
+ if (error instanceof AxSignatureValidationError) {
8525
+ throw error;
8526
+ }
8527
+ throw new AxSignatureValidationError(
8528
+ `Signature validation failed: ${error instanceof Error ? error.message : "Unknown error"}`
8529
+ );
8530
+ }
8531
+ };
8532
+ validateSignatureConsistency() {
8533
+ const inputNames = /* @__PURE__ */ new Set();
8534
+ for (const field of this.inputFields) {
8535
+ if (inputNames.has(field.name)) {
8536
+ throw new AxSignatureValidationError(
8537
+ `Duplicate input field name: "${field.name}"`,
8538
+ field.name,
8539
+ "Each field name must be unique within the signature"
8540
+ );
8541
+ }
8542
+ inputNames.add(field.name);
8543
+ }
8544
+ const outputNames = /* @__PURE__ */ new Set();
8545
+ for (const field of this.outputFields) {
8546
+ if (outputNames.has(field.name)) {
8547
+ throw new AxSignatureValidationError(
8548
+ `Duplicate output field name: "${field.name}"`,
8549
+ field.name,
8550
+ "Each field name must be unique within the signature"
8551
+ );
8552
+ }
8553
+ outputNames.add(field.name);
8554
+ }
8555
+ for (const outputField of this.outputFields) {
8556
+ if (inputNames.has(outputField.name)) {
8557
+ throw new AxSignatureValidationError(
8558
+ `Field name "${outputField.name}" appears in both inputs and outputs`,
8559
+ outputField.name,
8560
+ "Use different names for input and output fields to avoid confusion"
8561
+ );
8562
+ }
8563
+ }
8564
+ if (this.inputFields.length === 0) {
8565
+ throw new AxSignatureValidationError(
8566
+ "Signature must have at least one input field",
8567
+ void 0,
8568
+ 'Add an input field. Example: "userInput:string -> ..."'
8569
+ );
8570
+ }
8571
+ if (this.outputFields.length === 0) {
8572
+ throw new AxSignatureValidationError(
8573
+ "Signature must have at least one output field",
8574
+ void 0,
8575
+ 'Add an output field. Example: "... -> responseText:string"'
8576
+ );
8577
+ }
8578
+ }
8579
+ validate = () => {
8580
+ if (this.validatedAtHash === this.sigHash) {
8581
+ return true;
8582
+ }
8583
+ try {
8584
+ this.updateHash();
8585
+ this.validatedAtHash = this.sigHash;
8586
+ return true;
8587
+ } catch (error) {
8588
+ this.validatedAtHash = void 0;
8589
+ throw error;
8590
+ }
8591
+ };
8592
+ hash = () => this.sigHash;
8593
+ toString = () => this.sigString;
8594
+ toJSON = () => {
8595
+ return {
8596
+ id: this.hash(),
8597
+ description: this.description,
8598
+ inputFields: this.inputFields,
8599
+ outputFields: this.outputFields
8600
+ };
8601
+ };
8602
+ };
8603
+ function renderField(field) {
8604
+ let result = field.name;
8605
+ if (field.isOptional) {
8606
+ result += "?";
8607
+ }
8608
+ if (field.isInternal) {
8609
+ result += "!";
8610
+ }
8611
+ if (field.type) {
8612
+ result += ":" + field.type.name;
8613
+ if (field.type.isArray) {
8614
+ result += "[]";
8615
+ }
8616
+ if (field.type.name === "class" && field.type.options) {
8617
+ result += ` "${field.type.options.join(" | ")}"`;
8618
+ }
8619
+ }
8620
+ if (field.description && field.type?.name !== "class") {
8621
+ result += ` "${field.description}"`;
8622
+ }
8623
+ return result;
8624
+ }
8625
+ function renderSignature(description, inputFields, outputFields) {
8626
+ const descriptionPart = description ? `"${description}" ` : "";
8627
+ const inputFieldsRendered = inputFields.map(renderField).join(", ");
8628
+ const outputFieldsRendered = outputFields.map(renderField).join(", ");
8629
+ return `${descriptionPart}${inputFieldsRendered} -> ${outputFieldsRendered}`;
8630
+ }
8631
+ function isValidCase(inputString) {
8632
+ const camelCaseRegex = /^[a-z][a-zA-Z0-9]*$/;
8633
+ const snakeCaseRegex = /^[a-z]+(_[a-z0-9]+)*$/;
8634
+ return camelCaseRegex.test(inputString) || snakeCaseRegex.test(inputString);
8635
+ }
8636
+ function validateField(field, context3) {
8637
+ if (!field.name || field.name.length === 0) {
8638
+ throw new AxSignatureValidationError(
8639
+ "Field name cannot be blank",
8640
+ field.name,
8641
+ "Every field must have a descriptive name"
8642
+ );
8643
+ }
8644
+ if (!isValidCase(field.name)) {
8645
+ throw new AxSignatureValidationError(
8646
+ `Invalid field name '${field.name}' - must be camelCase or snake_case`,
8647
+ field.name,
8648
+ 'Use camelCase (e.g., "userInput") or snake_case (e.g., "user_input")'
8649
+ );
8650
+ }
8651
+ if (axGlobals.signatureStrict) {
8652
+ const reservedNames = [
8653
+ "text",
8654
+ "object",
8655
+ "image",
8656
+ "string",
8657
+ "number",
8658
+ "boolean",
8659
+ "json",
8660
+ "array",
8661
+ "datetime",
8662
+ "date",
8663
+ "time",
8664
+ "type",
8665
+ "class",
8666
+ "input",
8667
+ "output",
8668
+ "data",
8669
+ "value",
8670
+ "result",
8671
+ "response",
8672
+ "request",
8673
+ "item",
8674
+ "element"
8675
+ ];
8676
+ if (reservedNames.includes(field.name.toLowerCase())) {
8677
+ const suggestions = context3 === "input" ? [
8678
+ "userInput",
8679
+ "questionText",
8680
+ "documentContent",
8681
+ "messageText",
8682
+ "queryString"
8683
+ ] : [
8684
+ "responseText",
8685
+ "analysisResult",
8686
+ "categoryType",
8687
+ "summaryText",
8688
+ "outputData"
8689
+ ];
8690
+ throw new AxSignatureValidationError(
8691
+ `Field name '${field.name}' is too generic`,
8692
+ field.name,
8693
+ `Use a more descriptive name. Examples for ${context3} fields: ${suggestions.join(", ")}`
8694
+ );
8695
+ }
8696
+ }
8697
+ if (field.name.length < 2) {
8698
+ throw new AxSignatureValidationError(
8699
+ `Field name '${field.name}' is too short`,
8700
+ field.name,
8701
+ "Field names must be at least 2 characters long"
8702
+ );
8703
+ }
8704
+ if (field.name.length > 50) {
8705
+ throw new AxSignatureValidationError(
8706
+ `Field name '${field.name}' is too long (${field.name.length} characters)`,
8707
+ field.name,
8708
+ "Field names should be 50 characters or less"
8709
+ );
8710
+ }
8711
+ if (field.type) {
8712
+ validateFieldType(field, context3);
8713
+ }
8714
+ }
8715
+ function validateFieldType(field, context3) {
8716
+ if (!field.type) return;
8717
+ const { type } = field;
8718
+ if (type.name === "image" || type.name === "audio") {
8719
+ if (context3 === "output") {
8720
+ throw new AxSignatureValidationError(
8721
+ `${type.name} type is not supported in output fields`,
8722
+ field.name,
8723
+ `${type.name} types can only be used in input fields`
8724
+ );
8725
+ }
8726
+ if (type.isArray) {
8727
+ throw new AxSignatureValidationError(
8728
+ `Arrays of ${type.name} are not supported`,
8729
+ field.name,
8730
+ `Use a single ${type.name} type instead`
8731
+ );
8732
+ }
8733
+ }
8734
+ if (type.name === "class") {
8735
+ if (context3 === "input") {
8736
+ throw new AxSignatureValidationError(
8737
+ "Class type is not supported in input fields",
8738
+ field.name,
8739
+ 'Class types are only allowed on output fields. Use "string" type for input classifications'
8740
+ );
8741
+ }
8742
+ if (!type.options || type.options.length === 0) {
8743
+ throw new AxSignatureValidationError(
8744
+ "Class type requires options",
8745
+ field.name,
8746
+ 'Provide class options. Example: class "positive, negative, neutral"'
8747
+ );
8748
+ }
8749
+ for (const option of type.options) {
8750
+ if (!option || option.trim().length === 0) {
8751
+ throw new AxSignatureValidationError(
8752
+ "Empty class option found",
8753
+ field.name,
8754
+ "All class options must be non-empty strings"
8755
+ );
8756
+ }
8757
+ const trimmedOption = option.trim();
8758
+ if (trimmedOption.includes(",") || trimmedOption.includes("|")) {
8759
+ throw new AxSignatureValidationError(
8760
+ `Invalid class option "${trimmedOption}"`,
8761
+ field.name,
8762
+ "Class options cannot contain commas (,) or pipes (|) as they are used to separate options"
8763
+ );
8764
+ }
8765
+ }
8766
+ const uniqueOptions = new Set(
8767
+ type.options.map((opt) => opt.trim().toLowerCase())
8768
+ );
8769
+ if (uniqueOptions.size !== type.options.length) {
8770
+ throw new AxSignatureValidationError(
8771
+ "Duplicate class options found",
8772
+ field.name,
8773
+ "Each class option must be unique (case-insensitive)"
8774
+ );
8775
+ }
8776
+ }
8777
+ if (type.name === "code" && type.isArray) {
8778
+ throw new AxSignatureValidationError(
8779
+ "Arrays of code are not commonly supported",
8780
+ field.name,
8781
+ "Consider using a single code field or an array of strings instead"
8782
+ );
8783
+ }
8784
+ if (field.isInternal && context3 === "input") {
8785
+ throw new AxSignatureValidationError(
8786
+ "Internal marker (!) is not allowed on input fields",
8787
+ field.name,
8788
+ "Internal markers are only allowed on output fields"
8789
+ );
8790
+ }
8791
+ }
8792
+
8793
+ // dsp/processResponse.ts
8794
+ async function* processStreamingResponse({
8795
+ res,
8796
+ usage,
8797
+ states,
8798
+ ...args
8799
+ }) {
8800
+ const skipEarlyFail = (args.ai.getFeatures().functionCot ?? false) && args.functions !== void 0 && args.functions.length > 0;
8801
+ for await (const v of res) {
8802
+ if (v.modelUsage) {
8803
+ usage.push(v.modelUsage);
8804
+ }
8805
+ for (const result of v.results) {
8806
+ if (result.content === "" && (!result.functionCalls || result.functionCalls.length === 0)) {
8807
+ continue;
8808
+ }
8809
+ const state = states.find((s2) => s2.index === result.index);
8810
+ if (!state) {
8811
+ throw new Error(`No state found for result (index: ${result.index})`);
8812
+ }
8813
+ yield* _processStreamingResponse({
8814
+ ...args,
8815
+ result,
8816
+ skipEarlyFail,
8817
+ state
8818
+ });
8819
+ }
8820
+ }
8821
+ for (const state of states) {
8822
+ yield* finalizeStreamingResponse({
8823
+ ...args,
8824
+ state
8825
+ });
8826
+ }
8827
+ }
8828
+ async function* _processStreamingResponse({
8829
+ result,
8830
+ mem,
8831
+ sessionId,
8832
+ strictMode,
8833
+ skipEarlyFail,
8834
+ state,
8835
+ signature,
8836
+ streamingFieldProcessors,
8837
+ thoughtFieldName,
8838
+ streamingAsserts,
8839
+ asserts
8840
+ }) {
8841
+ if (result.functionCalls && result.functionCalls.length > 0) {
8842
+ mergeFunctionCalls(state.functionCalls, result.functionCalls);
8843
+ mem.updateResult(
8844
+ {
8845
+ name: result.name,
8846
+ content: result.content,
8847
+ functionCalls: state.functionCalls,
8848
+ delta: result.functionCalls?.[0]?.function?.params,
8849
+ index: result.index
8850
+ },
8851
+ sessionId
8852
+ );
8853
+ } else if (result.content && result.content.length > 0) {
8854
+ if (result.thought && result.thought.length > 0) {
8855
+ yield {
8856
+ index: result.index,
8857
+ delta: { [thoughtFieldName]: result.thought }
8858
+ };
8859
+ }
8860
+ state.content += result.content;
8861
+ mem.updateResult(
8862
+ {
8863
+ name: result.name,
8864
+ content: state.content,
8865
+ delta: result.content,
8866
+ index: result.index
8867
+ },
8868
+ sessionId
8869
+ );
8870
+ const skip = streamingExtractValues(
8871
+ signature,
8872
+ state.values,
8873
+ state.xstate,
8874
+ state.content,
8875
+ { strictMode, skipEarlyFail }
8876
+ );
8877
+ if (skip) {
8878
+ return;
8879
+ }
8880
+ if (streamingAsserts.length !== 0) {
8881
+ await assertStreamingAssertions(
8882
+ streamingAsserts,
8883
+ state.xstate,
8884
+ state.content
8885
+ );
8886
+ }
8887
+ if (streamingFieldProcessors.length !== 0) {
8888
+ await processStreamingFieldProcessors(
8889
+ streamingFieldProcessors,
8890
+ state.content,
8891
+ state.xstate,
8892
+ mem,
8893
+ state.values,
8894
+ sessionId
8895
+ );
8896
+ }
8897
+ yield* streamValues(
8898
+ signature,
8899
+ state.content,
8900
+ state.values,
8901
+ state.xstate,
8902
+ result.index
8903
+ );
8904
+ await assertAssertions(asserts, state.values);
8905
+ } else if (result.thought && result.thought.length > 0) {
8906
+ state.values[thoughtFieldName] = (state.values[thoughtFieldName] ?? "") + result.thought;
8907
+ yield {
8908
+ index: result.index,
8909
+ delta: { [thoughtFieldName]: result.thought }
8910
+ };
8911
+ }
8912
+ if (result.finishReason === "length") {
8913
+ throw new Error(
8914
+ `Max tokens reached before completion
8915
+ Content: ${state.content}`
8916
+ );
8917
+ }
8918
+ }
8919
+ async function* finalizeStreamingResponse({
8920
+ state,
8921
+ signature,
8922
+ ai,
8923
+ model,
8924
+ functions,
8925
+ mem,
8926
+ sessionId,
8927
+ traceId,
8928
+ span,
8929
+ excludeContentFromTrace,
8930
+ streamingAsserts,
8931
+ asserts,
8932
+ fieldProcessors,
8933
+ streamingFieldProcessors
8934
+ }) {
8935
+ const funcs = parseFunctionCalls(ai, state.functionCalls, state.values, model);
8936
+ if (funcs) {
8937
+ if (!functions) {
8938
+ throw new Error("Functions are not defined");
8939
+ }
8940
+ const fx = await processFunctions({
8941
+ ai,
8942
+ functionList: functions,
8943
+ functionCalls: funcs,
8944
+ mem,
8945
+ sessionId,
8946
+ traceId,
8947
+ span,
8948
+ index: state.index,
8949
+ excludeContentFromTrace
8950
+ });
8951
+ state.functionsExecuted = /* @__PURE__ */ new Set([...state.functionsExecuted, ...fx]);
8952
+ } else {
8953
+ streamingExtractFinalValue(
8954
+ signature,
8955
+ state.values,
8956
+ state.xstate,
8957
+ state.content
8958
+ );
8959
+ await assertStreamingAssertions(
8960
+ streamingAsserts,
8961
+ state.xstate,
8962
+ state.content,
8963
+ true
8964
+ );
8965
+ await assertAssertions(asserts, state.values);
8966
+ if (fieldProcessors.length) {
8967
+ await processFieldProcessors(
8968
+ fieldProcessors,
8969
+ state.values,
8970
+ mem,
8971
+ sessionId
8972
+ );
8973
+ }
8974
+ if (streamingFieldProcessors.length !== 0) {
8975
+ await processStreamingFieldProcessors(
8976
+ streamingFieldProcessors,
8977
+ state.content,
8978
+ state.xstate,
8979
+ mem,
8980
+ state.values,
8981
+ sessionId,
8982
+ true
8983
+ );
8984
+ }
8985
+ yield* streamValues(
8986
+ signature,
8987
+ state.content,
8988
+ state.values,
8989
+ state.xstate,
8990
+ state.index
8991
+ );
8992
+ }
8993
+ }
8994
+ async function* processResponse({
8995
+ ai,
8996
+ res,
8997
+ mem,
8998
+ sessionId,
8999
+ traceId,
9000
+ functions,
9001
+ span,
9002
+ strictMode,
9003
+ states,
9004
+ usage,
9005
+ excludeContentFromTrace,
9006
+ asserts,
9007
+ fieldProcessors,
9008
+ thoughtFieldName,
9009
+ signature
9010
+ }) {
9011
+ let results = res.results ?? [];
9012
+ mem.addResponse(results, sessionId);
9013
+ for (const result of results) {
9014
+ const state = states[result.index];
9015
+ if (!state) {
9016
+ throw new Error(`No state found for result (index: ${result.index})`);
9017
+ }
9018
+ if (res.modelUsage) {
9019
+ usage.push(res.modelUsage);
9020
+ }
9021
+ if (result.functionCalls?.length) {
9022
+ const funcs = parseFunctionCalls(ai, result.functionCalls, state.values);
9023
+ if (funcs) {
9024
+ if (!functions) {
9025
+ throw new Error("Functions are not defined");
9026
+ }
9027
+ const fx = await processFunctions({
9028
+ ai,
9029
+ functionList: functions,
9030
+ functionCalls: funcs,
9031
+ mem,
9032
+ sessionId,
9033
+ traceId,
9034
+ span,
9035
+ excludeContentFromTrace,
9036
+ index: result.index
9037
+ });
9038
+ state.functionsExecuted = /* @__PURE__ */ new Set([...state.functionsExecuted, ...fx]);
9039
+ }
9040
+ } else if (result.content) {
9041
+ if (result.thought && result.thought.length > 0) {
9042
+ state.values[thoughtFieldName] = result.thought;
9043
+ }
9044
+ extractValues(signature, state.values, result.content, strictMode);
9045
+ await assertAssertions(asserts, state.values);
9046
+ if (fieldProcessors.length) {
9047
+ await processFieldProcessors(
9048
+ fieldProcessors,
9049
+ state.values,
9050
+ mem,
9051
+ sessionId
9052
+ );
9053
+ }
9054
+ }
9055
+ if (result.finishReason === "length") {
9056
+ throw new Error(
9057
+ `Max tokens reached before completion
9058
+ Content: ${result.content}`
9059
+ );
9060
+ }
9061
+ }
9062
+ const values = states.map((s2) => s2.values);
9063
+ for (const v of values) {
9064
+ for (const field of signature.getOutputFields()) {
9065
+ if (field.isInternal) {
9066
+ delete v[field.name];
9067
+ }
9068
+ }
9069
+ }
9070
+ const outputFields = signature.getOutputFields();
9071
+ const deltas = values.map((v, index) => {
9072
+ const delta = {};
9073
+ for (const field of outputFields) {
9074
+ if (field.isInternal) {
9075
+ continue;
9076
+ }
9077
+ delta[field.name] = v[field.name];
9078
+ }
9079
+ if (v[thoughtFieldName] !== void 0) {
9080
+ delta[thoughtFieldName] = v[thoughtFieldName];
9081
+ }
9082
+ return { index, delta };
9083
+ });
9084
+ for (const delta of deltas) {
9085
+ yield delta;
9086
+ }
9087
+ }
9088
+ function shouldContinueSteps(mem, stopFunction, states, sessionId) {
9089
+ const lastMemItem = mem.getLast(sessionId);
9090
+ if (!lastMemItem) {
9091
+ return true;
9092
+ }
9093
+ for (const [index, state] of states.entries()) {
9094
+ const stopFunctionExecuted = stopFunction && state.functionsExecuted.has(stopFunction);
9095
+ const chat = lastMemItem.chat[index];
9096
+ if (!chat) {
9097
+ throw new Error(`No chat message found for result (index: ${index})`);
9098
+ }
9099
+ const isFunction = lastMemItem.role === "function";
9100
+ const isProcessor = lastMemItem.tags ? lastMemItem.tags.some((tag) => tag === "processor") : false;
9101
+ if (isFunction && stopFunction && stopFunctionExecuted) {
9102
+ return false;
9103
+ }
9104
+ if (!(isFunction || isProcessor)) {
9105
+ return false;
9106
+ }
9107
+ }
9108
+ return true;
9109
+ }
9110
+
9111
+ // dsp/prompt.ts
9112
+ var functionCallInstructions = `
9113
+ ## Function Call Instructions
9114
+ - Complete the task, using the functions defined earlier in this prompt.
9115
+ - Output fields should only be generated after all functions have been called.
9116
+ - Use the function results to generate the output fields.`;
9117
+ var formattingRules = `
9118
+ ## Strict Output Formatting Rules
9119
+ - Output must strictly follow the defined plain-text \`field name: value\` field format.
9120
+ - Output field, values must strictly adhere to the specified output field formatting rules.
9121
+ - No formatting rules should override these **Strict Output Formatting Rules**
9122
+ - Do not add any text before or after the output fields, just the field name and value.
9123
+ - Do not use code blocks.`;
9124
+ var AxPromptTemplate = class {
9125
+ sig;
9126
+ fieldTemplates;
9127
+ task;
9128
+ thoughtFieldName;
9129
+ functions;
9130
+ constructor(sig, options, fieldTemplates) {
9131
+ this.sig = sig;
9132
+ this.fieldTemplates = fieldTemplates;
9133
+ this.thoughtFieldName = options?.thoughtFieldName ?? "thought";
9134
+ this.functions = options?.functions;
9135
+ const task = [];
9136
+ const inArgs = renderDescFields(this.sig.getInputFields());
9137
+ const outArgs = renderDescFields(this.sig.getOutputFields());
9138
+ task.push(
9139
+ `You will be provided with the following fields: ${inArgs}. Your task is to generate new fields: ${outArgs}.`
9140
+ );
9141
+ const funcs = this.functions?.map((f2) => "toFunction" in f2 ? f2.toFunction() : f2)?.flat();
9142
+ const funcList = funcs?.map((fn) => `- \`${fn.name}\`: ${formatDescription(fn.description)}`).join("\n");
9143
+ if (funcList && funcList.length > 0) {
9144
+ task.push(`## Available Functions
9145
+ ${funcList}`);
9146
+ }
9147
+ const inputFields = renderInputFields(this.sig.getInputFields());
9148
+ task.push(`## Input Fields
9149
+ ${inputFields}`);
9150
+ const outputFields = renderOutputFields(this.sig.getOutputFields());
9151
+ task.push(`## Output Fields
9152
+ ${outputFields}`);
9153
+ if (funcList && funcList.length > 0) {
9154
+ task.push(functionCallInstructions.trim());
9155
+ }
9156
+ task.push(formattingRules.trim());
9157
+ const desc = this.sig.getDescription();
9158
+ if (desc) {
9159
+ const text = formatDescription(desc);
9160
+ task.push(text);
9161
+ }
9162
+ this.task = {
9163
+ type: "text",
9164
+ text: task.join("\n\n")
9165
+ };
9166
+ }
9167
+ renderSingleValueUserContent = (values, renderedExamples, renderedDemos, examplesInSystemPrompt) => {
9168
+ const completion = this.renderInputFields(values);
9169
+ const promptList = examplesInSystemPrompt ? completion : [...renderedExamples, ...renderedDemos, ...completion];
9170
+ const prompt = promptList.filter((v) => v !== void 0);
9171
+ return prompt.every((v) => v.type === "text") ? prompt.map((v) => v.text).join("\n") : prompt.reduce(combineConsecutiveStrings("\n"), []);
9172
+ };
9173
+ render = (values, {
9174
+ examples,
9175
+ demos
9176
+ }) => {
9177
+ const renderedExamples = examples ? [
9178
+ { type: "text", text: "\n\n## Examples\n" },
9179
+ ...this.renderExamples(examples)
9180
+ ] : [];
9181
+ const renderedDemos = demos ? this.renderDemos(demos) : [];
9182
+ const allTextExamples = renderedExamples.every((v) => v.type === "text");
9183
+ const allTextDemos = renderedDemos.every((v) => v.type === "text");
9184
+ const examplesInSystemPrompt = allTextExamples && allTextDemos;
9185
+ let systemContent = this.task.text;
9186
+ if (examplesInSystemPrompt) {
9187
+ const combinedItems = [
9188
+ { type: "text", text: systemContent },
9189
+ ...renderedExamples,
9190
+ ...renderedDemos
9191
+ ];
9192
+ combinedItems.reduce(combineConsecutiveStrings(""), []);
9193
+ if (combinedItems && combinedItems[0]) {
9194
+ systemContent = combinedItems[0].text;
9195
+ }
9196
+ }
9197
+ const systemPrompt = {
9198
+ role: "system",
9199
+ content: systemContent
9200
+ };
9201
+ if (Array.isArray(values)) {
9202
+ let messages = [];
9203
+ const history = values;
9204
+ let firstItem = true;
9205
+ for (const message of history) {
9206
+ let content;
9207
+ if (firstItem) {
9208
+ content = this.renderSingleValueUserContent(
9209
+ message.values,
9210
+ renderedExamples,
9211
+ renderedDemos,
9212
+ examplesInSystemPrompt
9213
+ );
9214
+ firstItem = false;
9215
+ } else {
9216
+ content = this.renderSingleValueUserContent(
9217
+ message.values,
9218
+ [],
9219
+ [],
9220
+ false
9221
+ );
9222
+ }
9223
+ if (message.role === "user") {
9224
+ messages.push({ role: "user", content });
9225
+ continue;
9226
+ }
9227
+ if (message.role !== "assistant") {
9228
+ throw new Error("Invalid message role");
9229
+ }
9230
+ if (typeof content !== "string") {
9231
+ throw new Error(
9232
+ "Assistant message cannot contain non-text content like images, files,etc"
9233
+ );
9234
+ }
9235
+ messages.push({ role: "assistant", content });
9236
+ }
9237
+ return [systemPrompt, ...messages];
9238
+ }
9239
+ const userContent = this.renderSingleValueUserContent(
9240
+ values,
9241
+ renderedExamples,
9242
+ renderedDemos,
9243
+ examplesInSystemPrompt
9244
+ );
9245
+ return [systemPrompt, { role: "user", content: userContent }];
9246
+ };
9247
+ renderExtraFields = (extraFields) => {
9248
+ const prompt = [];
9249
+ if (!extraFields || extraFields.length === 0) {
9250
+ return prompt;
9251
+ }
9252
+ const groupedFields = extraFields.reduce(
9253
+ (acc, field) => {
9254
+ const title = field.title;
9255
+ if (!acc[title]) {
9256
+ acc[title] = [];
9257
+ }
9258
+ acc[title].push(field);
9259
+ return acc;
9260
+ },
9261
+ {}
9262
+ );
9263
+ const formattedGroupedFields = Object.entries(groupedFields).map(([title, fields]) => {
9264
+ if (fields.length === 1) {
9265
+ const field = fields[0];
9266
+ return {
9267
+ title,
9268
+ name: field.name,
9269
+ description: field.description
8492
9270
  };
8493
- } else {
8494
- properties[f2.name] = {
8495
- description: f2.description,
8496
- type
9271
+ } else if (fields.length > 1) {
9272
+ const valuesList = fields.map((field) => `- ${field.description}`).join("\n");
9273
+ return {
9274
+ title,
9275
+ name: fields[0].name,
9276
+ description: valuesList
8497
9277
  };
8498
9278
  }
8499
- if (!f2.isOptional) {
8500
- required.push(f2.name);
8501
- }
8502
- }
8503
- const schema = {
8504
- type: "object",
8505
- properties,
8506
- required
8507
- };
8508
- return schema;
9279
+ }).filter(Boolean);
9280
+ formattedGroupedFields.forEach((field) => {
9281
+ const fn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
9282
+ prompt.push(...fn(field, field.description));
9283
+ });
9284
+ return prompt;
8509
9285
  };
8510
- updateHashLight = () => {
8511
- try {
8512
- this.getInputFields().forEach((field) => {
8513
- validateField(field, "input");
8514
- });
8515
- this.getOutputFields().forEach((field) => {
8516
- validateField(field, "output");
8517
- });
8518
- this.sigHash = createHash("sha256").update(JSON.stringify(this.inputFields)).update(JSON.stringify(this.outputFields)).digest("hex");
8519
- this.sigString = renderSignature(
8520
- this.description,
8521
- this.inputFields,
8522
- this.outputFields
8523
- );
8524
- return [this.sigHash, this.sigString];
8525
- } catch (error) {
8526
- if (error instanceof AxSignatureValidationError) {
8527
- throw error;
9286
+ renderExamples = (data) => {
9287
+ const list = [];
9288
+ const exampleContext = {
9289
+ isExample: true
9290
+ };
9291
+ for (const [index, item] of data.entries()) {
9292
+ const renderedInputItem = this.sig.getInputFields().map(
9293
+ (field) => this.renderInField(field, item, {
9294
+ ...exampleContext,
9295
+ isInputField: true
9296
+ })
9297
+ ).filter((v) => v !== void 0).flat();
9298
+ const renderedOutputItem = this.sig.getOutputFields().map(
9299
+ (field) => this.renderInField(field, item, {
9300
+ ...exampleContext,
9301
+ isInputField: false
9302
+ })
9303
+ ).filter((v) => v !== void 0).flat();
9304
+ const renderedItem = [...renderedInputItem, ...renderedOutputItem];
9305
+ if (index > 0 && renderedItem.length > 0 && renderedItem[0]?.type === "text") {
9306
+ list.push({ type: "text", text: "---\n\n" });
8528
9307
  }
8529
- throw new AxSignatureValidationError(
8530
- `Signature validation failed: ${error instanceof Error ? error.message : "Unknown error"}`
8531
- );
9308
+ renderedItem.forEach((v) => {
9309
+ if ("text" in v) {
9310
+ v.text = v.text + "\n";
9311
+ }
9312
+ list.push(v);
9313
+ });
8532
9314
  }
9315
+ return list;
8533
9316
  };
8534
- updateHash = () => {
8535
- try {
8536
- this.getInputFields().forEach((field) => {
8537
- validateField(field, "input");
8538
- });
8539
- this.getOutputFields().forEach((field) => {
8540
- validateField(field, "output");
9317
+ renderDemos = (data) => {
9318
+ const list = [];
9319
+ const inputFields = this.sig.getInputFields();
9320
+ const outputFields = this.sig.getOutputFields();
9321
+ const demoContext = {
9322
+ isExample: true
9323
+ };
9324
+ for (const item of data) {
9325
+ const inputRenderedItems = inputFields.map(
9326
+ (field) => this.renderInField(field, item, {
9327
+ ...demoContext,
9328
+ isInputField: true
9329
+ })
9330
+ ).filter((v) => v !== void 0).flat();
9331
+ const outputRenderedItems = outputFields.map(
9332
+ (field) => this.renderInField(field, item, {
9333
+ ...demoContext,
9334
+ isInputField: false
9335
+ })
9336
+ ).filter((v) => v !== void 0).flat();
9337
+ const renderedItem = [...inputRenderedItems, ...outputRenderedItems];
9338
+ renderedItem.slice(0, -1).forEach((v) => {
9339
+ if ("text" in v) {
9340
+ v.text = v.text + "\n";
9341
+ }
9342
+ list.push(v);
8541
9343
  });
8542
- this.validateSignatureConsistency();
8543
- this.sigHash = createHash("sha256").update(this.description ?? "").update(JSON.stringify(this.inputFields)).update(JSON.stringify(this.outputFields)).digest("hex");
8544
- this.sigString = renderSignature(
8545
- this.description,
8546
- this.inputFields,
8547
- this.outputFields
8548
- );
8549
- return [this.sigHash, this.sigString];
8550
- } catch (error) {
8551
- if (error instanceof AxSignatureValidationError) {
8552
- throw error;
8553
- }
8554
- throw new AxSignatureValidationError(
8555
- `Signature validation failed: ${error instanceof Error ? error.message : "Unknown error"}`
8556
- );
8557
9344
  }
9345
+ return list;
8558
9346
  };
8559
- validateSignatureConsistency() {
8560
- const inputNames = /* @__PURE__ */ new Set();
8561
- for (const field of this.inputFields) {
8562
- if (inputNames.has(field.name)) {
8563
- throw new AxSignatureValidationError(
8564
- `Duplicate input field name: "${field.name}"`,
8565
- field.name,
8566
- "Each field name must be unique within the signature"
8567
- );
8568
- }
8569
- inputNames.add(field.name);
9347
+ renderInputFields = (values) => {
9348
+ const renderedItems = this.sig.getInputFields().map((field) => this.renderInField(field, values, void 0)).filter((v) => v !== void 0).flat();
9349
+ renderedItems.filter((v) => v.type === "text").forEach((v) => {
9350
+ v.text = v.text + "\n";
9351
+ });
9352
+ return renderedItems;
9353
+ };
9354
+ renderInField = (field, values, context3) => {
9355
+ const value = values[field.name];
9356
+ if (isEmptyValue(field, value, context3)) {
9357
+ return;
8570
9358
  }
8571
- const outputNames = /* @__PURE__ */ new Set();
8572
- for (const field of this.outputFields) {
8573
- if (outputNames.has(field.name)) {
8574
- throw new AxSignatureValidationError(
8575
- `Duplicate output field name: "${field.name}"`,
8576
- field.name,
8577
- "Each field name must be unique within the signature"
9359
+ if (field.type) {
9360
+ validateValue(field, value);
9361
+ }
9362
+ const processedValue = processValue(field, value);
9363
+ const textFieldFn = this.fieldTemplates?.[field.name] ?? this.defaultRenderInField;
9364
+ return textFieldFn(field, processedValue);
9365
+ };
9366
+ defaultRenderInField = (field, value) => {
9367
+ if (field.type?.name === "image") {
9368
+ const validateImage = (value2) => {
9369
+ if (!value2) {
9370
+ throw new Error("Image field value is required.");
9371
+ }
9372
+ if (typeof value2 !== "object") {
9373
+ throw new Error("Image field value must be an object.");
9374
+ }
9375
+ if (!("mimeType" in value2)) {
9376
+ throw new Error("Image field must have mimeType");
9377
+ }
9378
+ if (!("data" in value2)) {
9379
+ throw new Error("Image field must have data");
9380
+ }
9381
+ return value2;
9382
+ };
9383
+ let result = [
9384
+ { type: "text", text: `${field.title}: ` }
9385
+ ];
9386
+ if (field.type.isArray) {
9387
+ if (!Array.isArray(value)) {
9388
+ throw new Error("Image field value must be an array.");
9389
+ }
9390
+ result = result.concat(
9391
+ value.map((v) => {
9392
+ const validated = validateImage(v);
9393
+ return {
9394
+ type: "image",
9395
+ mimeType: validated.mimeType,
9396
+ image: validated.data
9397
+ };
9398
+ })
8578
9399
  );
9400
+ } else {
9401
+ const validated = validateImage(value);
9402
+ result.push({
9403
+ type: "image",
9404
+ mimeType: validated.mimeType,
9405
+ image: validated.data
9406
+ });
8579
9407
  }
8580
- outputNames.add(field.name);
9408
+ return result;
8581
9409
  }
8582
- for (const outputField of this.outputFields) {
8583
- if (inputNames.has(outputField.name)) {
8584
- throw new AxSignatureValidationError(
8585
- `Field name "${outputField.name}" appears in both inputs and outputs`,
8586
- outputField.name,
8587
- "Use different names for input and output fields to avoid confusion"
9410
+ if (field.type?.name === "audio") {
9411
+ const validateAudio = (value2) => {
9412
+ if (!value2) {
9413
+ throw new Error("Audio field value is required.");
9414
+ }
9415
+ if (typeof value2 !== "object") {
9416
+ throw new Error("Audio field value must be an object.");
9417
+ }
9418
+ if (!("data" in value2)) {
9419
+ throw new Error("Audio field must have data");
9420
+ }
9421
+ return value2;
9422
+ };
9423
+ let result = [
9424
+ { type: "text", text: `${field.title}: ` }
9425
+ ];
9426
+ if (field.type.isArray) {
9427
+ if (!Array.isArray(value)) {
9428
+ throw new Error("Audio field value must be an array.");
9429
+ }
9430
+ result = result.concat(
9431
+ value.map((v) => {
9432
+ const validated = validateAudio(v);
9433
+ return {
9434
+ type: "audio",
9435
+ format: validated.format ?? "wav",
9436
+ data: validated.data
9437
+ };
9438
+ })
8588
9439
  );
9440
+ } else {
9441
+ const validated = validateAudio(value);
9442
+ result.push({
9443
+ type: "audio",
9444
+ format: validated.format ?? "wav",
9445
+ data: validated.data
9446
+ });
8589
9447
  }
9448
+ return result;
8590
9449
  }
8591
- if (this.inputFields.length === 0) {
8592
- throw new AxSignatureValidationError(
8593
- "Signature must have at least one input field",
8594
- void 0,
8595
- 'Add an input field. Example: "userInput:string -> ..."'
8596
- );
8597
- }
8598
- if (this.outputFields.length === 0) {
8599
- throw new AxSignatureValidationError(
8600
- "Signature must have at least one output field",
8601
- void 0,
8602
- 'Add an output field. Example: "... -> responseText:string"'
8603
- );
8604
- }
8605
- }
8606
- validate = () => {
8607
- if (this.validatedAtHash === this.sigHash) {
8608
- return true;
8609
- }
8610
- try {
8611
- this.updateHash();
8612
- this.validatedAtHash = this.sigHash;
8613
- return true;
8614
- } catch (error) {
8615
- this.validatedAtHash = void 0;
8616
- throw error;
9450
+ const text = [field.title, ": "];
9451
+ if (Array.isArray(value)) {
9452
+ text.push("\n");
9453
+ text.push(value.map((v) => `- ${v}`).join("\n"));
9454
+ } else {
9455
+ text.push(value);
8617
9456
  }
8618
- };
8619
- hash = () => this.sigHash;
8620
- toString = () => this.sigString;
8621
- toJSON = () => {
8622
- return {
8623
- id: this.hash(),
8624
- description: this.description,
8625
- inputFields: this.inputFields,
8626
- outputFields: this.outputFields
8627
- };
9457
+ return [{ type: "text", text: text.join("") }];
8628
9458
  };
8629
9459
  };
8630
- function renderField(field) {
8631
- let result = field.name;
8632
- if (field.isOptional) {
8633
- result += "?";
8634
- }
8635
- if (field.isInternal) {
8636
- result += "!";
8637
- }
8638
- if (field.type) {
8639
- result += ":" + field.type.name;
8640
- if (field.type.isArray) {
8641
- result += "[]";
9460
+ var renderDescFields = (list) => list.map((v) => `\`${v.title}\``).join(", ");
9461
+ var renderInputFields = (fields) => {
9462
+ const rows = fields.map((field) => {
9463
+ const name = field.title;
9464
+ const type = field.type?.name ? toFieldType(field.type) : "string";
9465
+ const requiredMsg = field.isOptional ? `This optional ${type} field may be omitted` : `A ${type} field`;
9466
+ const description = field.description ? ` ${formatDescription(field.description)}` : "";
9467
+ return `${name}: (${requiredMsg})${description}`.trim();
9468
+ });
9469
+ return rows.join("\n");
9470
+ };
9471
+ var renderOutputFields = (fields) => {
9472
+ const rows = fields.map((field) => {
9473
+ const name = field.title;
9474
+ const type = field.type?.name ? toFieldType(field.type) : "string";
9475
+ const requiredMsg = field.isOptional ? `Only include this ${type} field if its value is available` : `This ${type} field must be included`;
9476
+ let description = "";
9477
+ if (field.description && field.description.length > 0) {
9478
+ const value = field.type?.name === "class" ? field.description : formatDescription(field.description);
9479
+ description = ` ${value}`;
8642
9480
  }
8643
- if (field.type.name === "class" && field.type.options) {
8644
- result += ` "${field.type.options.join(" | ")}"`;
9481
+ if (field.type?.options && field.type.options.length > 0) {
9482
+ if (description.length > 0) {
9483
+ description += `. `;
9484
+ }
9485
+ description += `Allowed values: ${field.type.options.join(", ")}`;
8645
9486
  }
9487
+ return `${name}: (${requiredMsg})${description}`.trim();
9488
+ });
9489
+ return rows.join("\n");
9490
+ };
9491
+ var processValue = (field, value) => {
9492
+ if (field.type?.name === "date" && value instanceof Date) {
9493
+ const v = value.toISOString();
9494
+ return v.slice(0, v.indexOf("T"));
8646
9495
  }
8647
- if (field.description && field.type?.name !== "class") {
8648
- result += ` "${field.description}"`;
8649
- }
8650
- return result;
8651
- }
8652
- function renderSignature(description, inputFields, outputFields) {
8653
- const descriptionPart = description ? `"${description}" ` : "";
8654
- const inputFieldsRendered = inputFields.map(renderField).join(", ");
8655
- const outputFieldsRendered = outputFields.map(renderField).join(", ");
8656
- return `${descriptionPart}${inputFieldsRendered} -> ${outputFieldsRendered}`;
8657
- }
8658
- function isValidCase(inputString) {
8659
- const camelCaseRegex = /^[a-z][a-zA-Z0-9]*$/;
8660
- const snakeCaseRegex = /^[a-z]+(_[a-z0-9]+)*$/;
8661
- return camelCaseRegex.test(inputString) || snakeCaseRegex.test(inputString);
8662
- }
8663
- function validateField(field, context3) {
8664
- if (!field.name || field.name.length === 0) {
8665
- throw new AxSignatureValidationError(
8666
- "Field name cannot be blank",
8667
- field.name,
8668
- "Every field must have a descriptive name"
8669
- );
8670
- }
8671
- if (!isValidCase(field.name)) {
8672
- throw new AxSignatureValidationError(
8673
- `Invalid field name '${field.name}' - must be camelCase or snake_case`,
8674
- field.name,
8675
- 'Use camelCase (e.g., "userInput") or snake_case (e.g., "user_input")'
8676
- );
8677
- }
8678
- if (axGlobals.signatureStrict) {
8679
- const reservedNames = [
8680
- "text",
8681
- "object",
8682
- "image",
8683
- "string",
8684
- "number",
8685
- "boolean",
8686
- "json",
8687
- "array",
8688
- "datetime",
8689
- "date",
8690
- "time",
8691
- "type",
8692
- "class",
8693
- "input",
8694
- "output",
8695
- "data",
8696
- "value",
8697
- "result",
8698
- "response",
8699
- "request",
8700
- "item",
8701
- "element"
8702
- ];
8703
- if (reservedNames.includes(field.name.toLowerCase())) {
8704
- const suggestions = context3 === "input" ? [
8705
- "userInput",
8706
- "questionText",
8707
- "documentContent",
8708
- "messageText",
8709
- "queryString"
8710
- ] : [
8711
- "responseText",
8712
- "analysisResult",
8713
- "categoryType",
8714
- "summaryText",
8715
- "outputData"
8716
- ];
8717
- throw new AxSignatureValidationError(
8718
- `Field name '${field.name}' is too generic`,
8719
- field.name,
8720
- `Use a more descriptive name. Examples for ${context3} fields: ${suggestions.join(", ")}`
8721
- );
8722
- }
9496
+ if (field.type?.name === "datetime" && value instanceof Date) {
9497
+ return formatDateWithTimezone(value);
8723
9498
  }
8724
- if (field.name.length < 2) {
8725
- throw new AxSignatureValidationError(
8726
- `Field name '${field.name}' is too short`,
8727
- field.name,
8728
- "Field names must be at least 2 characters long"
8729
- );
9499
+ if (field.type?.name === "image" && typeof value === "object") {
9500
+ return value;
8730
9501
  }
8731
- if (field.name.length > 50) {
8732
- throw new AxSignatureValidationError(
8733
- `Field name '${field.name}' is too long (${field.name.length} characters)`,
8734
- field.name,
8735
- "Field names should be 50 characters or less"
8736
- );
9502
+ if (field.type?.name === "audio" && typeof value === "object") {
9503
+ return value;
8737
9504
  }
8738
- if (field.type) {
8739
- validateFieldType(field, context3);
9505
+ if (typeof value === "string") {
9506
+ return value;
8740
9507
  }
8741
- }
8742
- function validateFieldType(field, context3) {
8743
- if (!field.type) return;
8744
- const { type } = field;
8745
- if (type.name === "image" || type.name === "audio") {
8746
- if (context3 === "output") {
8747
- throw new AxSignatureValidationError(
8748
- `${type.name} type is not supported in output fields`,
8749
- field.name,
8750
- `${type.name} types can only be used in input fields`
8751
- );
9508
+ return JSON.stringify(value, null, 2);
9509
+ };
9510
+ var toFieldType = (type) => {
9511
+ const baseType = (() => {
9512
+ switch (type?.name) {
9513
+ case "string":
9514
+ return "string";
9515
+ case "number":
9516
+ return "number";
9517
+ case "boolean":
9518
+ return "boolean";
9519
+ case "date":
9520
+ return 'date ("YYYY-MM-DD" format)';
9521
+ case "datetime":
9522
+ return 'date time ("YYYY-MM-DD HH:mm Timezone" format)';
9523
+ case "json":
9524
+ return "JSON object";
9525
+ case "class":
9526
+ return "classification class";
9527
+ case "code":
9528
+ return "code";
9529
+ default:
9530
+ return "string";
8752
9531
  }
8753
- if (type.isArray) {
8754
- throw new AxSignatureValidationError(
8755
- `Arrays of ${type.name} are not supported`,
8756
- field.name,
8757
- `Use a single ${type.name} type instead`
8758
- );
9532
+ })();
9533
+ return type?.isArray ? `json array of ${baseType} items` : baseType;
9534
+ };
9535
+ function combineConsecutiveStrings(separator) {
9536
+ return (acc, current) => {
9537
+ if (current.type === "text") {
9538
+ const previous = acc.length > 0 ? acc[acc.length - 1] : null;
9539
+ if (previous && previous.type === "text") {
9540
+ previous.text += separator + current.text;
9541
+ } else {
9542
+ acc.push(current);
9543
+ }
9544
+ } else {
9545
+ acc.push(current);
8759
9546
  }
9547
+ return acc;
9548
+ };
9549
+ }
9550
+ var isEmptyValue = (field, value, context3) => {
9551
+ if (typeof value === "boolean") {
9552
+ return false;
8760
9553
  }
8761
- if (type.name === "class") {
8762
- if (context3 === "input") {
8763
- throw new AxSignatureValidationError(
8764
- "Class type is not supported in input fields",
8765
- field.name,
8766
- 'Class types are only allowed on output fields. Use "string" type for input classifications'
8767
- );
8768
- }
8769
- if (!type.options || type.options.length === 0) {
8770
- throw new AxSignatureValidationError(
8771
- "Class type requires options",
8772
- field.name,
8773
- 'Provide class options. Example: class "positive, negative, neutral"'
8774
- );
8775
- }
8776
- for (const option of type.options) {
8777
- if (!option || option.trim().length === 0) {
8778
- throw new AxSignatureValidationError(
8779
- "Empty class option found",
8780
- field.name,
8781
- "All class options must be non-empty strings"
8782
- );
8783
- }
8784
- const trimmedOption = option.trim();
8785
- if (trimmedOption.includes(",") || trimmedOption.includes("|")) {
8786
- throw new AxSignatureValidationError(
8787
- `Invalid class option "${trimmedOption}"`,
8788
- field.name,
8789
- "Class options cannot contain commas (,) or pipes (|) as they are used to separate options"
8790
- );
8791
- }
9554
+ if (!value || (Array.isArray(value) || typeof value === "string") && value.length === 0) {
9555
+ if (context3?.isExample) {
9556
+ return true;
8792
9557
  }
8793
- const uniqueOptions = new Set(
8794
- type.options.map((opt) => opt.trim().toLowerCase())
8795
- );
8796
- if (uniqueOptions.size !== type.options.length) {
8797
- throw new AxSignatureValidationError(
8798
- "Duplicate class options found",
8799
- field.name,
8800
- "Each class option must be unique (case-insensitive)"
8801
- );
9558
+ if (field.isOptional || field.isInternal) {
9559
+ return true;
8802
9560
  }
9561
+ const fieldType = context3?.isInputField !== false ? "input" : "output";
9562
+ throw new Error(`Value for ${fieldType} field '${field.name}' is required.`);
8803
9563
  }
8804
- if (type.name === "code" && type.isArray) {
8805
- throw new AxSignatureValidationError(
8806
- "Arrays of code are not commonly supported",
8807
- field.name,
8808
- "Consider using a single code field or an array of strings instead"
8809
- );
9564
+ return false;
9565
+ };
9566
+ function formatDescription(str) {
9567
+ const value = str.trim();
9568
+ return value.length > 0 ? `${value.charAt(0).toUpperCase()}${value.slice(1)}${value.endsWith(".") ? "" : "."}` : "";
9569
+ }
9570
+
9571
+ // dsp/registry.ts
9572
+ var AxInstanceRegistry = class {
9573
+ reg;
9574
+ // To track keys for iteration
9575
+ constructor() {
9576
+ this.reg = /* @__PURE__ */ new Set();
8810
9577
  }
8811
- if (field.isInternal && context3 === "input") {
8812
- throw new AxSignatureValidationError(
8813
- "Internal marker (!) is not allowed on input fields",
8814
- field.name,
8815
- "Internal markers are only allowed on output fields"
8816
- );
9578
+ register(instance) {
9579
+ this.reg.add(instance);
8817
9580
  }
8818
- }
9581
+ *[Symbol.iterator]() {
9582
+ const items = Array.from(this.reg);
9583
+ for (let i = 0; i < items.length; i++) {
9584
+ yield items[i];
9585
+ }
9586
+ }
9587
+ };
8819
9588
 
8820
9589
  // dsp/program.ts
8821
9590
  var AxProgramWithSignature = class {
@@ -9018,6 +9787,28 @@ var AxProgram = class {
9018
9787
  }
9019
9788
  };
9020
9789
 
9790
+ // dsp/validate.ts
9791
+ function handleValidationError(mem, errorFields, ai, promptTemplate, sessionId) {
9792
+ mem.addRequest(
9793
+ [
9794
+ {
9795
+ role: "user",
9796
+ content: promptTemplate.renderExtraFields(errorFields)
9797
+ }
9798
+ ],
9799
+ sessionId
9800
+ );
9801
+ mem.addTag("error", sessionId);
9802
+ if (ai.getOptions().debug) {
9803
+ const errors = errorFields.map((field) => `- ${field.title}: ${field.description}`).join("\n");
9804
+ const logger = ai.getLogger();
9805
+ logger(`\u274C Error Correction:
9806
+ ${errors}`, {
9807
+ tags: ["error"]
9808
+ });
9809
+ }
9810
+ }
9811
+
9021
9812
  // dsp/generate.ts
9022
9813
  var AxGen = class extends AxProgramWithSignature {
9023
9814
  promptTemplate;
@@ -9025,10 +9816,8 @@ var AxGen = class extends AxProgramWithSignature {
9025
9816
  streamingAsserts;
9026
9817
  options;
9027
9818
  functions;
9028
- functionsExecuted = /* @__PURE__ */ new Set();
9029
9819
  fieldProcessors = [];
9030
9820
  streamingFieldProcessors = [];
9031
- values = {};
9032
9821
  excludeContentFromTrace = false;
9033
9822
  thoughtFieldName;
9034
9823
  constructor(signature, options) {
@@ -9051,6 +9840,20 @@ var AxGen = class extends AxProgramWithSignature {
9051
9840
  this.functions = parseFunctions(options.functions);
9052
9841
  }
9053
9842
  }
9843
+ createStates(n) {
9844
+ return Array.from({ length: n }, (_, index) => ({
9845
+ index,
9846
+ functionCalls: [],
9847
+ values: {},
9848
+ content: "",
9849
+ functionsExecuted: /* @__PURE__ */ new Set(),
9850
+ xstate: {
9851
+ extractedFields: [],
9852
+ streamedIndex: {},
9853
+ s: -1
9854
+ }
9855
+ }));
9856
+ }
9054
9857
  addAssert = (fn, message) => {
9055
9858
  this.asserts.push({ fn, message });
9056
9859
  };
@@ -9091,7 +9894,6 @@ var AxGen = class extends AxProgramWithSignature {
9091
9894
  const {
9092
9895
  sessionId,
9093
9896
  traceId,
9094
- modelConfig,
9095
9897
  model,
9096
9898
  rateLimiter,
9097
9899
  stream,
@@ -9100,7 +9902,7 @@ var AxGen = class extends AxProgramWithSignature {
9100
9902
  thinkingTokenBudget,
9101
9903
  showThoughts
9102
9904
  } = options ?? {};
9103
- const chatPrompt = mem?.history(sessionId) ?? [];
9905
+ const chatPrompt = mem?.history(0, sessionId) ?? [];
9104
9906
  if (chatPrompt.length === 0) {
9105
9907
  throw new Error("No chat prompt found");
9106
9908
  }
@@ -9109,6 +9911,10 @@ var AxGen = class extends AxProgramWithSignature {
9109
9911
  if (!firstStep && (functionCall === "required" || typeof functionCall === "function")) {
9110
9912
  functionCall = void 0;
9111
9913
  }
9914
+ const modelConfig = {
9915
+ ...options?.modelConfig,
9916
+ ...options?.sampleCount ? { n: options.sampleCount } : {}
9917
+ };
9112
9918
  const res = await ai.chat(
9113
9919
  {
9114
9920
  chatPrompt,
@@ -9143,7 +9949,9 @@ var AxGen = class extends AxProgramWithSignature {
9143
9949
  const { sessionId, traceId, functions: _functions } = options ?? {};
9144
9950
  const strictMode = options?.strictMode ?? false;
9145
9951
  const model = options.model;
9146
- const functions = _functions?.map((f2) => "toFunction" in f2 ? f2.toFunction() : f2)?.flat();
9952
+ const states = this.createStates(options.sampleCount ?? 1);
9953
+ const usage = this.usage;
9954
+ const functions = _functions?.map((f2) => "toFunction" in f2 ? f2.toFunction() : f2)?.flat() ?? [];
9147
9955
  const res = await this.forwardSendRequest({
9148
9956
  ai,
9149
9957
  mem,
@@ -9151,8 +9959,8 @@ var AxGen = class extends AxProgramWithSignature {
9151
9959
  traceContext,
9152
9960
  firstStep
9153
9961
  });
9154
- if (res instanceof ReadableStream2) {
9155
- yield* this.processStreamingResponse({
9962
+ if (res instanceof ReadableStream3) {
9963
+ yield* processStreamingResponse({
9156
9964
  ai,
9157
9965
  model,
9158
9966
  res,
@@ -9161,11 +9969,20 @@ var AxGen = class extends AxProgramWithSignature {
9161
9969
  sessionId,
9162
9970
  functions,
9163
9971
  strictMode,
9164
- span
9972
+ span,
9973
+ states,
9974
+ usage,
9975
+ asserts: this.asserts,
9976
+ streamingAsserts: this.streamingAsserts,
9977
+ fieldProcessors: this.fieldProcessors,
9978
+ streamingFieldProcessors: this.streamingFieldProcessors,
9979
+ thoughtFieldName: this.thoughtFieldName,
9980
+ excludeContentFromTrace: this.excludeContentFromTrace,
9981
+ signature: this.signature
9165
9982
  });
9166
9983
  this.getLogger(ai, options)?.("", { tags: ["responseEnd"] });
9167
9984
  } else {
9168
- yield await this.processResponse({
9985
+ yield* processResponse({
9169
9986
  ai,
9170
9987
  model,
9171
9988
  res,
@@ -9174,233 +9991,18 @@ var AxGen = class extends AxProgramWithSignature {
9174
9991
  sessionId,
9175
9992
  functions,
9176
9993
  span,
9177
- strictMode
9994
+ strictMode,
9995
+ states,
9996
+ usage,
9997
+ asserts: this.asserts,
9998
+ fieldProcessors: this.fieldProcessors,
9999
+ thoughtFieldName: this.thoughtFieldName,
10000
+ excludeContentFromTrace: this.excludeContentFromTrace,
10001
+ signature: this.signature
9178
10002
  });
9179
10003
  }
9180
10004
  }
9181
- async *processStreamingResponse({
9182
- ai,
9183
- model,
9184
- res,
9185
- mem,
9186
- sessionId,
9187
- traceId,
9188
- functions,
9189
- strictMode,
9190
- span
9191
- }) {
9192
- const functionCalls = [];
9193
- this.values = {};
9194
- const xstate = {
9195
- extractedFields: [],
9196
- streamedIndex: {},
9197
- s: -1
9198
- };
9199
- let content = "";
9200
- mem.addResult(
9201
- {
9202
- content: "",
9203
- functionCalls: []
9204
- },
9205
- sessionId
9206
- );
9207
- for await (const v of res) {
9208
- const result = v.results[0];
9209
- if (!result) {
9210
- continue;
9211
- }
9212
- if (v.modelUsage) {
9213
- this.usage.push(v.modelUsage);
9214
- }
9215
- if (result.functionCalls && result.functionCalls.length > 0) {
9216
- mergeFunctionCalls(functionCalls, result.functionCalls);
9217
- mem.updateResult(
9218
- {
9219
- name: result.name,
9220
- content,
9221
- functionCalls,
9222
- delta: result.functionCalls?.[0]?.function?.params
9223
- },
9224
- sessionId
9225
- );
9226
- } else if (result.content && result.content.length > 0) {
9227
- if (result.thought && result.thought.length > 0) {
9228
- yield {
9229
- [this.thoughtFieldName]: result.thought
9230
- };
9231
- }
9232
- content += result.content;
9233
- mem.updateResult(
9234
- { name: result.name, content, delta: result.content },
9235
- sessionId
9236
- );
9237
- const skip = streamingExtractValues(
9238
- this.signature,
9239
- this.values,
9240
- xstate,
9241
- content,
9242
- strictMode
9243
- );
9244
- if (skip) {
9245
- continue;
9246
- }
9247
- if (this.streamingAsserts.length !== 0) {
9248
- await assertStreamingAssertions(
9249
- this.streamingAsserts,
9250
- xstate,
9251
- content
9252
- );
9253
- }
9254
- if (this.streamingFieldProcessors.length !== 0) {
9255
- await processStreamingFieldProcessors(
9256
- this.streamingFieldProcessors,
9257
- content,
9258
- xstate,
9259
- mem,
9260
- this.values,
9261
- sessionId
9262
- );
9263
- }
9264
- yield* streamValues(
9265
- this.signature,
9266
- content,
9267
- this.values,
9268
- xstate
9269
- );
9270
- await assertAssertions(this.asserts, this.values);
9271
- } else if (result.thought && result.thought.length > 0) {
9272
- this.values[this.thoughtFieldName] = (this.values[this.thoughtFieldName] ?? "") + result.thought;
9273
- yield {
9274
- [this.thoughtFieldName]: result.thought
9275
- };
9276
- }
9277
- if (result.finishReason === "length") {
9278
- throw new Error(
9279
- `Max tokens reached before completion
9280
- Content: ${content}`
9281
- );
9282
- }
9283
- }
9284
- const funcs = parseFunctionCalls(ai, functionCalls, this.values, model);
9285
- if (funcs) {
9286
- if (!functions) {
9287
- throw new Error("Functions are not defined");
9288
- }
9289
- const fx = await processFunctions(
9290
- ai,
9291
- functions,
9292
- funcs,
9293
- mem,
9294
- sessionId,
9295
- traceId,
9296
- span,
9297
- this.excludeContentFromTrace
9298
- );
9299
- this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
9300
- } else {
9301
- streamingExtractFinalValue(this.signature, this.values, xstate, content);
9302
- await assertStreamingAssertions(
9303
- this.streamingAsserts,
9304
- xstate,
9305
- content,
9306
- true
9307
- );
9308
- await assertAssertions(this.asserts, this.values);
9309
- if (this.fieldProcessors.length) {
9310
- await processFieldProcessors(
9311
- this.fieldProcessors,
9312
- this.values,
9313
- mem,
9314
- sessionId
9315
- );
9316
- }
9317
- if (this.streamingFieldProcessors.length !== 0) {
9318
- await processStreamingFieldProcessors(
9319
- this.streamingFieldProcessors,
9320
- content,
9321
- xstate,
9322
- mem,
9323
- this.values,
9324
- sessionId,
9325
- true
9326
- );
9327
- }
9328
- yield* streamValues(
9329
- this.signature,
9330
- content,
9331
- this.values,
9332
- xstate
9333
- );
9334
- }
9335
- }
9336
- async processResponse({
9337
- ai,
9338
- res,
9339
- mem,
9340
- sessionId,
9341
- traceId,
9342
- functions,
9343
- span,
9344
- strictMode
9345
- }) {
9346
- this.values = {};
9347
- let results = res.results ?? [];
9348
- if (results.length > 1) {
9349
- results = results.filter((r) => r.functionCalls);
9350
- }
9351
- for (const result of results) {
9352
- if (res.modelUsage) {
9353
- this.usage.push(res.modelUsage);
9354
- }
9355
- mem.addResult(result, sessionId);
9356
- if (result.functionCalls?.length) {
9357
- const funcs = parseFunctionCalls(ai, result.functionCalls, this.values);
9358
- if (funcs) {
9359
- if (!functions) {
9360
- throw new Error("Functions are not defined");
9361
- }
9362
- const fx = await processFunctions(
9363
- ai,
9364
- functions,
9365
- funcs,
9366
- mem,
9367
- sessionId,
9368
- traceId,
9369
- span,
9370
- this.excludeContentFromTrace
9371
- );
9372
- this.functionsExecuted = /* @__PURE__ */ new Set([...this.functionsExecuted, ...fx]);
9373
- }
9374
- } else if (result.content) {
9375
- if (result.thought && result.thought.length > 0) {
9376
- this.values[this.thoughtFieldName] = result.thought;
9377
- }
9378
- extractValues(this.signature, this.values, result.content, strictMode);
9379
- await assertAssertions(this.asserts, this.values);
9380
- if (this.fieldProcessors.length) {
9381
- await processFieldProcessors(
9382
- this.fieldProcessors,
9383
- this.values,
9384
- mem,
9385
- sessionId
9386
- );
9387
- }
9388
- }
9389
- if (result.finishReason === "length") {
9390
- throw new Error(
9391
- `Max tokens reached before completion
9392
- Content: ${result.content}`
9393
- );
9394
- }
9395
- }
9396
- for (const field of this.signature.getOutputFields()) {
9397
- if (field.isInternal) {
9398
- delete this.values[field.name];
9399
- }
9400
- }
9401
- return { ...this.values };
9402
- }
9403
- async *_forward2(ai, values, options, span, traceContext) {
10005
+ async *_forward2(ai, values, states, options, span, traceContext) {
9404
10006
  const stopFunction = (options?.stopFunction ?? this.options?.stopFunction)?.toLowerCase();
9405
10007
  const maxRetries = options.maxRetries ?? this.options?.maxRetries ?? 10;
9406
10008
  const maxSteps = options.maxSteps ?? this.options?.maxSteps ?? 10;
@@ -9409,7 +10011,7 @@ Content: ${result.content}`
9409
10011
  debug: this.isDebug(ai, options),
9410
10012
  debugHideSystemPrompt
9411
10013
  };
9412
- const mem = options.mem ?? this.options?.mem ?? new AxMemory(1e4, memOptions);
10014
+ const mem = options.mem ?? this.options?.mem ?? new AxMemory(memOptions);
9413
10015
  let err;
9414
10016
  if (options?.functions && options.functions.length > 0) {
9415
10017
  const promptTemplateClass = this.options?.promptTemplate ?? AxPromptTemplate;
@@ -9436,7 +10038,7 @@ Content: ${result.content}`
9436
10038
  demos: this.demos
9437
10039
  });
9438
10040
  }
9439
- mem.add(prompt, options?.sessionId);
10041
+ mem.addRequest(prompt, options.sessionId);
9440
10042
  multiStepLoop: for (let n = 0; n < maxSteps; n++) {
9441
10043
  const firstStep = n === 0;
9442
10044
  for (let errCount = 0; errCount < maxRetries; errCount++) {
@@ -9449,15 +10051,20 @@ Content: ${result.content}`
9449
10051
  span,
9450
10052
  traceContext
9451
10053
  });
9452
- for await (const delta of generator) {
9453
- if (delta !== void 0) {
9454
- yield { version: errCount, delta };
10054
+ for await (const result of generator) {
10055
+ if (result !== void 0) {
10056
+ yield {
10057
+ version: errCount,
10058
+ index: result.index,
10059
+ delta: result.delta
10060
+ };
9455
10061
  }
9456
10062
  }
9457
- const lastMemItem = mem.getLast(options?.sessionId);
9458
- const shouldContinue = this.shouldContinueSteps(
9459
- lastMemItem,
9460
- stopFunction
10063
+ const shouldContinue = shouldContinueSteps(
10064
+ mem,
10065
+ stopFunction,
10066
+ states,
10067
+ options?.sessionId
9461
10068
  );
9462
10069
  if (shouldContinue) {
9463
10070
  continue multiStepLoop;
@@ -9513,26 +10120,15 @@ Content: ${result.content}`
9513
10120
  this.signature
9514
10121
  );
9515
10122
  }
9516
- shouldContinueSteps(lastMemItem, stopFunction) {
9517
- const stopFunctionExecuted = stopFunction && this.functionsExecuted.has(stopFunction);
9518
- const isFunction = lastMemItem?.chat?.role === "function";
9519
- const isProcessor = lastMemItem?.tags ? lastMemItem.tags.some((tag) => tag === "processor") : false;
9520
- if (isFunction && stopFunction && stopFunctionExecuted) {
9521
- return false;
9522
- }
9523
- if (isFunction || isProcessor) {
9524
- return true;
9525
- }
9526
- return false;
9527
- }
9528
10123
  async *_forward1(ai, values, options) {
10124
+ const states = this.createStates(options.sampleCount ?? 1);
9529
10125
  const tracer = options?.tracer ?? this.options?.tracer ?? ai.getOptions().tracer;
9530
10126
  let functions = this.functions;
9531
10127
  if (options?.functions) {
9532
10128
  functions = parseFunctions(options.functions, this.functions);
9533
10129
  }
9534
10130
  if (!tracer) {
9535
- yield* this._forward2(ai, values, {
10131
+ yield* this._forward2(ai, values, states, {
9536
10132
  ...options,
9537
10133
  functions
9538
10134
  });
@@ -9564,6 +10160,7 @@ Content: ${result.content}`
9564
10160
  yield* this._forward2(
9565
10161
  ai,
9566
10162
  values,
10163
+ states,
9567
10164
  {
9568
10165
  ...options,
9569
10166
  functions
@@ -9572,8 +10169,10 @@ Content: ${result.content}`
9572
10169
  traceContext
9573
10170
  );
9574
10171
  if (!this.excludeContentFromTrace) {
10172
+ const valuesList = states.map((s2) => s2.values);
10173
+ const values2 = valuesList.length === 1 ? valuesList[0] : valuesList;
9575
10174
  span.addEvent("output", {
9576
- content: JSON.stringify(this.values, null, 2)
10175
+ content: JSON.stringify(values2, null, 2)
9577
10176
  });
9578
10177
  }
9579
10178
  } finally {
@@ -9582,17 +10181,18 @@ Content: ${result.content}`
9582
10181
  }
9583
10182
  async forward(ai, values, options) {
9584
10183
  const generator = this._forward1(ai, values, options ?? {});
9585
- let buffer = {};
10184
+ let buffer = [];
9586
10185
  let currentVersion = 0;
9587
- for await (const item of generator) {
9588
- if (item.version !== currentVersion) {
9589
- buffer = {};
10186
+ for await (const delta of generator) {
10187
+ if (delta.version !== currentVersion) {
10188
+ buffer = [];
9590
10189
  }
9591
- currentVersion = item.version;
9592
- buffer = mergeDeltas(buffer, item.delta);
10190
+ currentVersion = delta.version;
10191
+ buffer = mergeDeltas(buffer, delta);
9593
10192
  }
9594
- this.trace = { ...values, ...buffer };
9595
- return buffer;
10193
+ const result = buffer[0]?.delta ?? {};
10194
+ this.trace = { ...values, ...result };
10195
+ return result;
9596
10196
  }
9597
10197
  async *streamingForward(ai, values, options) {
9598
10198
  yield* this._forward1(ai, values, {
@@ -9613,9 +10213,13 @@ Content: ${result.content}`
9613
10213
  var AxGenerateError = class extends Error {
9614
10214
  details;
9615
10215
  constructor(message, details, options) {
9616
- super(message, options);
10216
+ super(message);
9617
10217
  this.name = "AxGenerateError";
9618
10218
  this.details = details;
10219
+ if (options?.cause) {
10220
+ ;
10221
+ this.cause = options.cause;
10222
+ }
9619
10223
  }
9620
10224
  };
9621
10225
  function enhanceError(e, ai, signature) {
@@ -11690,23 +12294,6 @@ var getTopInPercent = (entries, percent = 0.1) => {
11690
12294
  return sortedEntries.slice(0, topTenPercentCount);
11691
12295
  };
11692
12296
 
11693
- // docs/rewriter.ts
11694
- var AxDefaultQueryRewriter = class extends AxGen {
11695
- constructor(options) {
11696
- 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."
11697
- query: string -> rewrittenQuery: string`;
11698
- super(signature, options);
11699
- }
11700
- };
11701
- var AxRewriter = class extends AxGen {
11702
- constructor(options) {
11703
- super(
11704
- '"Rewrite a given text to be clear and concise" original -> rewritten "improved text"',
11705
- options
11706
- );
11707
- }
11708
- };
11709
-
11710
12297
  // funcs/docker.ts
11711
12298
  var AxDockerSession = class {
11712
12299
  apiUrl;
@@ -13297,6 +13884,7 @@ var AxMockAIService = class {
13297
13884
  return this.config.chatResponse ?? {
13298
13885
  results: [
13299
13886
  {
13887
+ index: 0,
13300
13888
  content: "Mock response",
13301
13889
  finishReason: "stop"
13302
13890
  }
@@ -15597,7 +16185,6 @@ export {
15597
16185
  AxDBPinecone,
15598
16186
  AxDBWeaviate,
15599
16187
  AxDefaultCostTracker,
15600
- AxDefaultQueryRewriter,
15601
16188
  AxDefaultResultReranker,
15602
16189
  AxDockerSession,
15603
16190
  AxEmbeddingAdapter,
@@ -15624,7 +16211,6 @@ export {
15624
16211
  AxPromptTemplate,
15625
16212
  AxRAG,
15626
16213
  AxRateLimiterTokenUsage,
15627
- AxRewriter,
15628
16214
  AxSignature,
15629
16215
  AxSimpleClassifier,
15630
16216
  AxSimpleClassifierClass,
@@ -15684,6 +16270,8 @@ export {
15684
16270
  axModelInfoTogether,
15685
16271
  axSpanAttributes,
15686
16272
  axSpanEvents,
16273
+ axValidateChatRequestMessage,
16274
+ axValidateChatResponseResult,
15687
16275
  f,
15688
16276
  s
15689
16277
  };