@absolutejs/ai 0.0.23 → 0.0.25
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/dist/ai/index.js +102 -21
- package/dist/ai/index.js.map +9 -9
- package/dist/ai/providers/anthropic.js +56 -19
- package/dist/ai/providers/anthropic.js.map +4 -4
- package/dist/ai/providers/gemini.js.map +2 -2
- package/dist/ai/providers/ollama.js.map +2 -2
- package/dist/ai/providers/openai.js +2 -7
- package/dist/ai/providers/openai.js.map +3 -3
- package/dist/ai/providers/openaiCompatible.js +2 -7
- package/dist/ai/providers/openaiCompatible.js.map +3 -3
- package/dist/ai/providers/openaiResponses.js +2 -7
- package/dist/ai/providers/openaiResponses.js.map +4 -4
- package/dist/ai/tools/index.js +8 -3
- package/dist/ai/tools/index.js.map +4 -4
- package/dist/types/ai.d.ts +14 -0
- package/dist/types/anthropic.d.ts +9 -0
- package/package.json +172 -172
package/dist/ai/index.js
CHANGED
|
@@ -292,12 +292,7 @@ var EFFORT_ORDER = [
|
|
|
292
292
|
"high",
|
|
293
293
|
"max"
|
|
294
294
|
];
|
|
295
|
-
var ANTHROPIC_EFFORT = [
|
|
296
|
-
/opus-4-[5-8]/,
|
|
297
|
-
/sonnet-4-6/,
|
|
298
|
-
/fable-5/,
|
|
299
|
-
/mythos-5/
|
|
300
|
-
];
|
|
295
|
+
var ANTHROPIC_EFFORT = [/opus-4-[5-8]/, /sonnet-4-6/, /fable-5/, /mythos-5/];
|
|
301
296
|
var ANTHROPIC_ADAPTIVE_ONLY = [];
|
|
302
297
|
var ANTHROPIC_LEGACY_THINKING = [
|
|
303
298
|
/sonnet-4-5/,
|
|
@@ -1526,7 +1521,7 @@ var gemini = (config2) => {
|
|
|
1526
1521
|
var h2IfHttps4 = (url) => url.startsWith("https://") ? { protocol: "http2" } : {};
|
|
1527
1522
|
var DEFAULT_BASE_URL4 = "https://api.anthropic.com";
|
|
1528
1523
|
var API_VERSION = "2023-06-01";
|
|
1529
|
-
var
|
|
1524
|
+
var DEFAULT_MAX_TOKENS = 32000;
|
|
1530
1525
|
var EVENT_PREFIX_LENGTH2 = 7;
|
|
1531
1526
|
var DATA_PREFIX_LENGTH2 = 6;
|
|
1532
1527
|
var EMPTY_CHUNKS = [];
|
|
@@ -1577,16 +1572,42 @@ var mapToolDefinition2 = (tool) => ({
|
|
|
1577
1572
|
input_schema: tool.input_schema,
|
|
1578
1573
|
name: tool.name
|
|
1579
1574
|
});
|
|
1580
|
-
var
|
|
1575
|
+
var cacheLastContentBlock = (msg) => {
|
|
1576
|
+
const cacheControl = { type: "ephemeral" };
|
|
1577
|
+
if (typeof msg.content === "string") {
|
|
1578
|
+
return {
|
|
1579
|
+
content: [
|
|
1580
|
+
{ cache_control: cacheControl, text: msg.content, type: "text" }
|
|
1581
|
+
],
|
|
1582
|
+
role: msg.role
|
|
1583
|
+
};
|
|
1584
|
+
}
|
|
1585
|
+
if (msg.content.length === 0)
|
|
1586
|
+
return msg;
|
|
1587
|
+
const blocks = [...msg.content];
|
|
1588
|
+
blocks[blocks.length - 1] = {
|
|
1589
|
+
...blocks[blocks.length - 1],
|
|
1590
|
+
cache_control: cacheControl
|
|
1591
|
+
};
|
|
1592
|
+
return { content: blocks, role: msg.role };
|
|
1593
|
+
};
|
|
1594
|
+
var buildRequestBody4 = (params, configuredMax, promptCaching) => {
|
|
1581
1595
|
const messages = params.messages.filter((msg) => msg.role !== "system").map(mapMessage);
|
|
1596
|
+
if (promptCaching && messages.length > 1) {
|
|
1597
|
+
const last = messages[messages.length - 1];
|
|
1598
|
+
if (last) {
|
|
1599
|
+
messages[messages.length - 1] = cacheLastContentBlock(last);
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
const max = typeof params.maxTokens === "number" ? params.maxTokens : configuredMax;
|
|
1582
1603
|
const body = {
|
|
1583
|
-
max_tokens:
|
|
1604
|
+
max_tokens: max,
|
|
1584
1605
|
messages,
|
|
1585
1606
|
model: params.model,
|
|
1586
1607
|
stream: true
|
|
1587
1608
|
};
|
|
1588
1609
|
if (params.systemPrompt) {
|
|
1589
|
-
body.system = params.cacheSystemPrompt ? [
|
|
1610
|
+
body.system = promptCaching || params.cacheSystemPrompt ? [
|
|
1590
1611
|
{
|
|
1591
1612
|
cache_control: { type: "ephemeral" },
|
|
1592
1613
|
text: params.systemPrompt,
|
|
@@ -1595,7 +1616,14 @@ var buildRequestBody4 = (params) => {
|
|
|
1595
1616
|
] : params.systemPrompt;
|
|
1596
1617
|
}
|
|
1597
1618
|
if (params.tools && params.tools.length > 0) {
|
|
1598
|
-
|
|
1619
|
+
const tools = params.tools.map(mapToolDefinition2);
|
|
1620
|
+
if (promptCaching) {
|
|
1621
|
+
tools[tools.length - 1] = {
|
|
1622
|
+
...tools[tools.length - 1],
|
|
1623
|
+
cache_control: { type: "ephemeral" }
|
|
1624
|
+
};
|
|
1625
|
+
}
|
|
1626
|
+
body.tools = tools;
|
|
1599
1627
|
if (params.toolChoice === "auto" || params.toolChoice === "none") {
|
|
1600
1628
|
body.tool_choice = { type: params.toolChoice };
|
|
1601
1629
|
} else if (params.toolChoice === "required") {
|
|
@@ -1604,8 +1632,6 @@ var buildRequestBody4 = (params) => {
|
|
|
1604
1632
|
body.tool_choice = { name: params.toolChoice.name, type: "tool" };
|
|
1605
1633
|
}
|
|
1606
1634
|
}
|
|
1607
|
-
if (typeof params.maxTokens === "number")
|
|
1608
|
-
body.max_tokens = params.maxTokens;
|
|
1609
1635
|
if (params.stopSequences && params.stopSequences.length > 0) {
|
|
1610
1636
|
body.stop_sequences = params.stopSequences;
|
|
1611
1637
|
}
|
|
@@ -1629,7 +1655,7 @@ var buildRequestBody4 = (params) => {
|
|
|
1629
1655
|
const budget = resolveBudgetTokens(params.reasoning);
|
|
1630
1656
|
if (budget) {
|
|
1631
1657
|
body.thinking = { budget_tokens: budget, type: "enabled" };
|
|
1632
|
-
body.max_tokens = Math.max(
|
|
1658
|
+
body.max_tokens = Math.max(max, budget + max);
|
|
1633
1659
|
}
|
|
1634
1660
|
}
|
|
1635
1661
|
return body;
|
|
@@ -1778,6 +1804,10 @@ var extractUsage4 = (usageRecord, existingUsage) => {
|
|
|
1778
1804
|
var handleMessageDelta = (parsed, state) => {
|
|
1779
1805
|
const deltaUsage = getRecord(parsed, "usage");
|
|
1780
1806
|
state.usage = extractUsage4(deltaUsage, state.usage);
|
|
1807
|
+
const delta = getRecord(parsed, "delta");
|
|
1808
|
+
const stopReason = delta ? getString(delta, "stop_reason") : "";
|
|
1809
|
+
if (stopReason)
|
|
1810
|
+
state.stopReason = stopReason;
|
|
1781
1811
|
};
|
|
1782
1812
|
var handleMessageStart = (parsed, state) => {
|
|
1783
1813
|
const message = getRecord(parsed, "message");
|
|
@@ -1820,7 +1850,11 @@ var processEvent = (eventType, parsed, state) => {
|
|
|
1820
1850
|
return;
|
|
1821
1851
|
}
|
|
1822
1852
|
case "message_stop": {
|
|
1823
|
-
return {
|
|
1853
|
+
return {
|
|
1854
|
+
stopReason: state.stopReason,
|
|
1855
|
+
type: "done",
|
|
1856
|
+
usage: state.usage
|
|
1857
|
+
};
|
|
1824
1858
|
}
|
|
1825
1859
|
case "error": {
|
|
1826
1860
|
handleError(parsed);
|
|
@@ -1896,6 +1930,7 @@ async function* parseSSEStream4(body, signal) {
|
|
|
1896
1930
|
currentToolId: "",
|
|
1897
1931
|
currentToolName: "",
|
|
1898
1932
|
isThinkingBlock: false,
|
|
1933
|
+
stopReason: "",
|
|
1899
1934
|
thinkingSignature: "",
|
|
1900
1935
|
toolInputJson: "",
|
|
1901
1936
|
usage: undefined
|
|
@@ -1906,8 +1941,8 @@ async function* parseSSEStream4(body, signal) {
|
|
|
1906
1941
|
reader.releaseLock();
|
|
1907
1942
|
}
|
|
1908
1943
|
}
|
|
1909
|
-
var fetchAndStream = async function* (baseUrl, config2, params) {
|
|
1910
|
-
const body = buildRequestBody4(params);
|
|
1944
|
+
var fetchAndStream = async function* (baseUrl, config2, params, configuredMax, promptCaching) {
|
|
1945
|
+
const body = buildRequestBody4(params, configuredMax, promptCaching);
|
|
1911
1946
|
const target = `${baseUrl}/v1/messages`;
|
|
1912
1947
|
const response = await fetch(target, {
|
|
1913
1948
|
...h2IfHttps4(target),
|
|
@@ -1935,8 +1970,10 @@ var fetchAndStream = async function* (baseUrl, config2, params) {
|
|
|
1935
1970
|
};
|
|
1936
1971
|
var anthropic = (config2) => {
|
|
1937
1972
|
const baseUrl = config2.baseUrl ?? DEFAULT_BASE_URL4;
|
|
1973
|
+
const configuredMax = config2.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
1974
|
+
const promptCaching = config2.promptCaching ?? true;
|
|
1938
1975
|
return instrumentAIProvider({
|
|
1939
|
-
stream: (params) => fetchAndStream(baseUrl, config2, params)
|
|
1976
|
+
stream: (params) => fetchAndStream(baseUrl, config2, params, configuredMax, promptCaching)
|
|
1940
1977
|
}, "anthropic");
|
|
1941
1978
|
};
|
|
1942
1979
|
|
|
@@ -2790,9 +2827,21 @@ var processChunk2 = function* (chunk, chunkState, renderers, options, fullRespon
|
|
|
2790
2827
|
case "done":
|
|
2791
2828
|
maybeFlushThinking(chunkState);
|
|
2792
2829
|
chunkState.usage = chunk.usage;
|
|
2830
|
+
chunkState.stopReason = chunk.stopReason;
|
|
2793
2831
|
break;
|
|
2794
2832
|
}
|
|
2795
2833
|
};
|
|
2834
|
+
var truncateToolResult = (result, max) => {
|
|
2835
|
+
if (result.length <= max)
|
|
2836
|
+
return result;
|
|
2837
|
+
const omitted = result.length - max;
|
|
2838
|
+
const headLen = Math.ceil(max / 2);
|
|
2839
|
+
const tailLen = max - headLen;
|
|
2840
|
+
const marker = `
|
|
2841
|
+
<result truncated to ${max} chars; ${omitted} omitted \u2014 re-read a narrower slice if needed>
|
|
2842
|
+
`;
|
|
2843
|
+
return result.slice(0, headLen) + marker + result.slice(result.length - tailLen);
|
|
2844
|
+
};
|
|
2796
2845
|
var executeToolCalls = async function* (pendingToolCalls, options, renderers, turnState) {
|
|
2797
2846
|
const toolResultBlocks = [];
|
|
2798
2847
|
for (const toolCall of pendingToolCalls) {
|
|
@@ -2802,8 +2851,9 @@ var executeToolCalls = async function* (pendingToolCalls, options, renderers, tu
|
|
|
2802
2851
|
turnState.allToolsHtml = turnState.allToolsHtml.replace(renderers.toolRunning(toolCall.name, toolCall.input), renderers.toolComplete(toolCall.name, result));
|
|
2803
2852
|
yield { data: turnState.allToolsHtml, event: "tools" };
|
|
2804
2853
|
options.onToolUse?.(toolCall.name, toolCall.input, result);
|
|
2854
|
+
const resultContent = options.maxToolResultChars !== undefined ? truncateToolResult(result, options.maxToolResultChars) : result;
|
|
2805
2855
|
toolResultBlocks.push({
|
|
2806
|
-
content:
|
|
2856
|
+
content: resultContent,
|
|
2807
2857
|
tool_use_id: toolCall.id,
|
|
2808
2858
|
type: "tool_result"
|
|
2809
2859
|
});
|
|
@@ -2848,14 +2898,17 @@ var streamTurns = async function* (options, renderers, messages, signal, startTi
|
|
|
2848
2898
|
turn: 0
|
|
2849
2899
|
};
|
|
2850
2900
|
const toolDefs = options.tools ? buildToolDefinitions2(options.tools) : undefined;
|
|
2901
|
+
let runningTotalTokens = 0;
|
|
2851
2902
|
for (;turnState.turn <= maxTurns && !signal.aborted; turnState.turn++) {
|
|
2852
2903
|
const chunkState = {
|
|
2853
2904
|
contentBlocks: [],
|
|
2854
2905
|
currentThinking: null,
|
|
2855
2906
|
pendingToolCalls: [],
|
|
2907
|
+
stopReason: undefined,
|
|
2856
2908
|
usage: undefined
|
|
2857
2909
|
};
|
|
2858
2910
|
const stream = options.provider.stream({
|
|
2911
|
+
maxTokens: options.maxTokens,
|
|
2859
2912
|
messages: turnState.currentMessages,
|
|
2860
2913
|
model: options.model,
|
|
2861
2914
|
reasoning: options.reasoning,
|
|
@@ -2864,6 +2917,29 @@ var streamTurns = async function* (options, renderers, messages, signal, startTi
|
|
|
2864
2917
|
tools: toolDefs
|
|
2865
2918
|
});
|
|
2866
2919
|
yield* consumeStream2(stream, chunkState, renderers, options, turnState, signal);
|
|
2920
|
+
options.onTurn?.(turnState.turn, chunkState.usage);
|
|
2921
|
+
runningTotalTokens += (chunkState.usage?.inputTokens ?? 0) + (chunkState.usage?.outputTokens ?? 0);
|
|
2922
|
+
if (chunkState.stopReason === "max_tokens") {
|
|
2923
|
+
yield {
|
|
2924
|
+
data: renderers.error(`Response truncated at max_tokens (output=${chunkState.usage?.outputTokens ?? "?"}). ` + `Raise maxTokens on the provider/options, split the request, or reduce upstream context.`),
|
|
2925
|
+
event: "status"
|
|
2926
|
+
};
|
|
2927
|
+
return;
|
|
2928
|
+
}
|
|
2929
|
+
if (options.maxTotalTokens && runningTotalTokens >= options.maxTotalTokens) {
|
|
2930
|
+
yield {
|
|
2931
|
+
data: renderers.error(`Stopped: token budget reached (${runningTotalTokens}/${options.maxTotalTokens} tokens over ` + `${turnState.turn} turns). Narrow the request or raise maxTotalTokens.`),
|
|
2932
|
+
event: "status"
|
|
2933
|
+
};
|
|
2934
|
+
return;
|
|
2935
|
+
}
|
|
2936
|
+
if (options.maxDurationMs && Date.now() - startTime >= options.maxDurationMs) {
|
|
2937
|
+
yield {
|
|
2938
|
+
data: renderers.error(`Stopped: time budget reached (${Math.round((Date.now() - startTime) / 1000)}s over ` + `${turnState.turn} turns). Narrow the request or raise maxDurationMs.`),
|
|
2939
|
+
event: "status"
|
|
2940
|
+
};
|
|
2941
|
+
return;
|
|
2942
|
+
}
|
|
2867
2943
|
if (shouldStopToolLoop(chunkState, turnState, signal)) {
|
|
2868
2944
|
return void (yield yieldCompletion(renderers, options, turnState.fullResponse, chunkState.usage, startTime));
|
|
2869
2945
|
}
|
|
@@ -3253,7 +3329,12 @@ var toProviderTools = (tools) => Object.entries(tools).map(([name, definition])
|
|
|
3253
3329
|
name
|
|
3254
3330
|
}));
|
|
3255
3331
|
var generateAIWithTools = async (options) => {
|
|
3256
|
-
const {
|
|
3332
|
+
const {
|
|
3333
|
+
maxTurns = DEFAULT_TOOL_MAX_TURNS,
|
|
3334
|
+
onToolUse,
|
|
3335
|
+
tools,
|
|
3336
|
+
...base
|
|
3337
|
+
} = options;
|
|
3257
3338
|
const providerTools = toProviderTools(tools);
|
|
3258
3339
|
const toolCalls = [];
|
|
3259
3340
|
let usage;
|
|
@@ -4283,5 +4364,5 @@ export {
|
|
|
4283
4364
|
PROVIDER_STATUS_PAGES
|
|
4284
4365
|
};
|
|
4285
4366
|
|
|
4286
|
-
//# debugId=
|
|
4367
|
+
//# debugId=A76D544D382AA89A64756E2164756E21
|
|
4287
4368
|
//# sourceMappingURL=index.js.map
|