@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.cjs +2640 -2052
- package/index.cjs.map +1 -1
- package/index.d.cts +216 -192
- package/index.d.ts +216 -192
- package/index.js +2251 -1663
- package/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
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
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
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
|
-
|
|
1899
|
-
...
|
|
1900
|
-
|
|
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
|
|
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
|
-
{
|
|
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
|
|
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
|
|
2597
|
-
sstate.indexIdMap[
|
|
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[
|
|
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
|
-
|
|
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 (
|
|
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
|
|
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/
|
|
5704
|
-
function
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
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
|
-
|
|
5712
|
-
|
|
5850
|
+
break;
|
|
5851
|
+
case "user":
|
|
5852
|
+
if (!item.content) {
|
|
5853
|
+
throw new Error("User message content cannot be undefined");
|
|
5713
5854
|
}
|
|
5714
|
-
if (typeof
|
|
5715
|
-
|
|
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
|
-
|
|
5718
|
-
|
|
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
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
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
|
-
|
|
5748
|
-
|
|
5749
|
-
if (
|
|
5750
|
-
|
|
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
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
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
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
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
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
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 (
|
|
5786
|
-
|
|
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 (
|
|
5789
|
-
|
|
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 (
|
|
5792
|
-
|
|
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 (
|
|
5795
|
-
if (
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
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
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
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
|
-
|
|
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)
|
|
6177
|
+
return indices.reverse().map((index) => this.data.splice(index, 1).at(0)).filter((item) => item !== void 0).reverse();
|
|
5833
6178
|
}
|
|
5834
|
-
history() {
|
|
5835
|
-
|
|
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
|
-
|
|
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(
|
|
5851
|
-
this.limit = limit;
|
|
6197
|
+
constructor(options) {
|
|
5852
6198
|
this.options = options;
|
|
5853
|
-
this.defaultMemory = new MemoryImpl(
|
|
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.
|
|
6208
|
+
this.memories.set(sessionId, new MemoryImpl(this.options));
|
|
5863
6209
|
}
|
|
5864
6210
|
return this.memories.get(sessionId);
|
|
5865
6211
|
}
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
this.getMemory(sessionId).
|
|
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.
|
|
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,
|
|
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 =
|
|
6657
|
+
const baseValue = target[key];
|
|
6139
6658
|
const deltaValue = delta[key];
|
|
6140
6659
|
if (baseValue === void 0 && Array.isArray(deltaValue)) {
|
|
6141
|
-
|
|
6660
|
+
target[key] = [...deltaValue];
|
|
6142
6661
|
} else if (Array.isArray(baseValue) && Array.isArray(deltaValue)) {
|
|
6143
|
-
|
|
6662
|
+
target[key] = [...baseValue, ...deltaValue];
|
|
6144
6663
|
} else if ((baseValue === void 0 || typeof baseValue === "string") && typeof deltaValue === "string") {
|
|
6145
|
-
|
|
6664
|
+
target[key] = `${baseValue ?? ""}${deltaValue}`;
|
|
6146
6665
|
} else {
|
|
6147
|
-
|
|
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/
|
|
6265
|
-
var
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
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
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
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
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
}
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
|
|
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
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
if (
|
|
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 (
|
|
6378
|
-
|
|
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 (
|
|
6381
|
-
throw new
|
|
6382
|
-
|
|
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
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
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
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
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
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
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
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
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
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6510
|
-
|
|
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
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
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
|
-
|
|
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
|
|
6911
|
+
return v;
|
|
6559
6912
|
}
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
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
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
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
|
-
|
|
6632
|
-
|
|
6633
|
-
|
|
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
|
-
|
|
6636
|
-
|
|
6637
|
-
|
|
6638
|
-
}
|
|
6639
|
-
return rows.join("\n");
|
|
6943
|
+
return className;
|
|
6944
|
+
default:
|
|
6945
|
+
return val;
|
|
6946
|
+
}
|
|
6640
6947
|
};
|
|
6641
|
-
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
|
|
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
|
-
|
|
6647
|
-
|
|
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
|
-
|
|
6650
|
-
|
|
6960
|
+
let d2 = d1.replace(/\s+$/, "");
|
|
6961
|
+
if (xstate.currField?.type?.name === "code") {
|
|
6962
|
+
d2 = d2.replace(/\s*```\s*$/, "");
|
|
6651
6963
|
}
|
|
6652
|
-
|
|
6653
|
-
|
|
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 (
|
|
6656
|
-
|
|
6968
|
+
if (d3.length > 0) {
|
|
6969
|
+
yield { index, delta: { [fieldName]: d3 } };
|
|
6970
|
+
xstate.streamedIndex[fieldName] = pos + d2.length;
|
|
6657
6971
|
}
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
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
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
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
|
-
|
|
6695
|
-
|
|
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
|
-
|
|
6722
|
-
|
|
6723
|
-
|
|
6724
|
-
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
6728
|
-
|
|
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
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
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
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
|
|
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
|
-
|
|
6794
|
-
|
|
6795
|
-
|
|
6796
|
-
|
|
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
|
-
|
|
6799
|
-
throw new ValidationError({
|
|
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
|
-
|
|
6803
|
-
const
|
|
6804
|
-
const match =
|
|
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
|
-
|
|
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
|
-
|
|
6817
|
-
|
|
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
|
-
|
|
6823
|
-
|
|
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
|
|
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/
|
|
6840
|
-
|
|
6841
|
-
const
|
|
6842
|
-
|
|
6843
|
-
|
|
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
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
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
|
-
|
|
6865
|
-
const
|
|
6866
|
-
|
|
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
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
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.
|
|
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 (
|
|
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 (!
|
|
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 (!
|
|
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.
|
|
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.
|
|
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/
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
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
|
-
|
|
8495
|
-
|
|
8496
|
-
|
|
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
|
-
|
|
8500
|
-
|
|
8501
|
-
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
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
|
-
|
|
8511
|
-
|
|
8512
|
-
|
|
8513
|
-
|
|
8514
|
-
|
|
8515
|
-
|
|
8516
|
-
|
|
8517
|
-
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
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
|
-
|
|
8530
|
-
|
|
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
|
-
|
|
8535
|
-
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
|
|
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
|
-
|
|
8560
|
-
const
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
|
|
8564
|
-
|
|
8565
|
-
|
|
8566
|
-
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
|
|
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
|
-
|
|
8572
|
-
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
|
|
8576
|
-
|
|
8577
|
-
|
|
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
|
-
|
|
9408
|
+
return result;
|
|
8581
9409
|
}
|
|
8582
|
-
|
|
8583
|
-
|
|
8584
|
-
|
|
8585
|
-
|
|
8586
|
-
|
|
8587
|
-
|
|
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
|
-
|
|
8592
|
-
|
|
8593
|
-
|
|
8594
|
-
|
|
8595
|
-
|
|
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
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
|
|
8637
|
-
|
|
8638
|
-
|
|
8639
|
-
|
|
8640
|
-
|
|
8641
|
-
|
|
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
|
|
8644
|
-
|
|
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.
|
|
8648
|
-
|
|
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
|
|
8725
|
-
|
|
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
|
|
8732
|
-
|
|
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 (
|
|
8739
|
-
|
|
9505
|
+
if (typeof value === "string") {
|
|
9506
|
+
return value;
|
|
8740
9507
|
}
|
|
8741
|
-
|
|
8742
|
-
|
|
8743
|
-
|
|
8744
|
-
const
|
|
8745
|
-
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
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
|
-
|
|
8754
|
-
|
|
8755
|
-
|
|
8756
|
-
|
|
8757
|
-
|
|
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 (
|
|
8762
|
-
if (context3
|
|
8763
|
-
|
|
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
|
-
|
|
8794
|
-
|
|
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
|
-
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
|
|
8808
|
-
|
|
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
|
-
|
|
8812
|
-
|
|
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
|
|
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
|
|
9155
|
-
yield*
|
|
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
|
|
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 *
|
|
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(
|
|
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.
|
|
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
|
|
9453
|
-
if (
|
|
9454
|
-
yield {
|
|
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
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
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(
|
|
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
|
|
9588
|
-
if (
|
|
9589
|
-
buffer =
|
|
10186
|
+
for await (const delta of generator) {
|
|
10187
|
+
if (delta.version !== currentVersion) {
|
|
10188
|
+
buffer = [];
|
|
9590
10189
|
}
|
|
9591
|
-
currentVersion =
|
|
9592
|
-
buffer = mergeDeltas(buffer,
|
|
10190
|
+
currentVersion = delta.version;
|
|
10191
|
+
buffer = mergeDeltas(buffer, delta);
|
|
9593
10192
|
}
|
|
9594
|
-
|
|
9595
|
-
|
|
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
|
|
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
|
};
|