@absolutejs/ai 0.0.16 → 0.0.18
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 +173 -41
- package/dist/ai/index.js.map +11 -10
- package/dist/ai/providers/anthropic.js +137 -9
- package/dist/ai/providers/anthropic.js.map +5 -4
- package/dist/ai/providers/openai.js +124 -7
- package/dist/ai/providers/openai.js.map +5 -4
- package/dist/ai/providers/openaiCompatible.js +124 -7
- package/dist/ai/providers/openaiCompatible.js.map +5 -4
- package/dist/ai/providers/openaiResponses.js +114 -6
- package/dist/ai/providers/openaiResponses.js.map +5 -4
- package/dist/src/ai/generateAI.d.ts +9 -1
- package/dist/src/ai/providers/reasoning.d.ts +14 -0
- package/dist/types/ai.d.ts +46 -13
- package/package.json +2 -2
package/dist/ai/index.js
CHANGED
|
@@ -43,6 +43,111 @@ async function* tapStream(source, params, providerName) {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
// src/ai/providers/reasoning.ts
|
|
47
|
+
var EFFORT_ORDER = [
|
|
48
|
+
"minimal",
|
|
49
|
+
"low",
|
|
50
|
+
"medium",
|
|
51
|
+
"high",
|
|
52
|
+
"max"
|
|
53
|
+
];
|
|
54
|
+
var ANTHROPIC_EFFORT = [
|
|
55
|
+
/opus-4-[5-8]/,
|
|
56
|
+
/sonnet-4-6/,
|
|
57
|
+
/fable-5/,
|
|
58
|
+
/mythos-5/
|
|
59
|
+
];
|
|
60
|
+
var ANTHROPIC_ADAPTIVE_ONLY = [];
|
|
61
|
+
var ANTHROPIC_LEGACY_THINKING = [
|
|
62
|
+
/sonnet-4-5/,
|
|
63
|
+
/sonnet-4-0/,
|
|
64
|
+
/sonnet-4-2025/,
|
|
65
|
+
/opus-4-0/,
|
|
66
|
+
/opus-4-1/,
|
|
67
|
+
/opus-4-2025/,
|
|
68
|
+
/3-7-sonnet/
|
|
69
|
+
];
|
|
70
|
+
var ANTHROPIC_NO_SAMPLING = [/opus-4-[78]/, /fable-5/, /mythos-5/];
|
|
71
|
+
var ANTHROPIC_MAX_EFFORT = [
|
|
72
|
+
/opus-4-[678]/,
|
|
73
|
+
/sonnet-4-6/,
|
|
74
|
+
/fable-5/,
|
|
75
|
+
/mythos-5/
|
|
76
|
+
];
|
|
77
|
+
var OPENAI_REASONING = [/(^|[^a-z])o[1345](-|$)/, /gpt-5/];
|
|
78
|
+
var OPENAI_MINIMAL_EFFORT = [/gpt-5/];
|
|
79
|
+
var matches = (model, patterns) => patterns.some((pattern) => pattern.test(model));
|
|
80
|
+
var anthropicReasoningMode = (model) => {
|
|
81
|
+
if (matches(model, ANTHROPIC_EFFORT))
|
|
82
|
+
return "effort";
|
|
83
|
+
if (matches(model, ANTHROPIC_ADAPTIVE_ONLY))
|
|
84
|
+
return "adaptive";
|
|
85
|
+
if (matches(model, ANTHROPIC_LEGACY_THINKING))
|
|
86
|
+
return "legacy";
|
|
87
|
+
return "none";
|
|
88
|
+
};
|
|
89
|
+
var anthropicSupportsSampling = (model) => !matches(model, ANTHROPIC_NO_SAMPLING);
|
|
90
|
+
var isOpenAIReasoningModel = (model) => matches(model, OPENAI_REASONING);
|
|
91
|
+
var EFFORT_BUDGET = {
|
|
92
|
+
high: 16384,
|
|
93
|
+
low: 2048,
|
|
94
|
+
max: 32768,
|
|
95
|
+
medium: 8192,
|
|
96
|
+
minimal: 1024
|
|
97
|
+
};
|
|
98
|
+
var budgetToEffort = (budget) => {
|
|
99
|
+
if (budget <= 2048)
|
|
100
|
+
return "low";
|
|
101
|
+
if (budget <= 8192)
|
|
102
|
+
return "medium";
|
|
103
|
+
if (budget <= 16384)
|
|
104
|
+
return "high";
|
|
105
|
+
return "max";
|
|
106
|
+
};
|
|
107
|
+
var resolveEffort = (reasoning) => {
|
|
108
|
+
if (reasoning.effort)
|
|
109
|
+
return reasoning.effort;
|
|
110
|
+
if (typeof reasoning.budgetTokens === "number") {
|
|
111
|
+
return budgetToEffort(reasoning.budgetTokens);
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
};
|
|
115
|
+
var resolveBudgetTokens = (reasoning) => {
|
|
116
|
+
if (typeof reasoning.budgetTokens === "number")
|
|
117
|
+
return reasoning.budgetTokens;
|
|
118
|
+
if (reasoning.effort)
|
|
119
|
+
return EFFORT_BUDGET[reasoning.effort];
|
|
120
|
+
return null;
|
|
121
|
+
};
|
|
122
|
+
var clampEffort = (effort, allowed) => {
|
|
123
|
+
if (allowed.includes(effort))
|
|
124
|
+
return effort;
|
|
125
|
+
const idx = EFFORT_ORDER.indexOf(effort);
|
|
126
|
+
for (let lower = idx - 1;lower >= 0; lower -= 1) {
|
|
127
|
+
const candidate = EFFORT_ORDER[lower];
|
|
128
|
+
if (candidate && allowed.includes(candidate))
|
|
129
|
+
return candidate;
|
|
130
|
+
}
|
|
131
|
+
return allowed[0] ?? effort;
|
|
132
|
+
};
|
|
133
|
+
var anthropicEffortValue = (model, reasoning) => {
|
|
134
|
+
const effort = resolveEffort(reasoning);
|
|
135
|
+
if (!effort)
|
|
136
|
+
return null;
|
|
137
|
+
const allowed = matches(model, ANTHROPIC_MAX_EFFORT) ? ["low", "medium", "high", "max"] : ["low", "medium", "high"];
|
|
138
|
+
return clampEffort(effort, allowed);
|
|
139
|
+
};
|
|
140
|
+
var openaiEffortValue = (model, reasoning) => {
|
|
141
|
+
if (!isOpenAIReasoningModel(model))
|
|
142
|
+
return null;
|
|
143
|
+
const effort = resolveEffort(reasoning);
|
|
144
|
+
if (!effort)
|
|
145
|
+
return null;
|
|
146
|
+
const allowed = matches(model, OPENAI_MINIMAL_EFFORT) ? ["minimal", "low", "medium", "high"] : ["low", "medium", "high"];
|
|
147
|
+
const requested = effort === "max" ? "high" : effort;
|
|
148
|
+
return clampEffort(requested, allowed);
|
|
149
|
+
};
|
|
150
|
+
|
|
46
151
|
// src/ai/providers/openai.ts
|
|
47
152
|
var h2IfHttps = (url) => url.startsWith("https://") ? { protocol: "http2" } : {};
|
|
48
153
|
var DEFAULT_BASE_URL = "https://api.openai.com";
|
|
@@ -169,12 +274,24 @@ var buildRequestBody = (params) => {
|
|
|
169
274
|
body.parallel_tool_calls = params.parallelToolCalls;
|
|
170
275
|
}
|
|
171
276
|
}
|
|
172
|
-
if (
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
277
|
+
if (isOpenAIReasoningModel(params.model)) {
|
|
278
|
+
if (typeof params.maxTokens === "number") {
|
|
279
|
+
body.max_completion_tokens = params.maxTokens;
|
|
280
|
+
}
|
|
281
|
+
if (params.reasoning) {
|
|
282
|
+
const effort = openaiEffortValue(params.model, params.reasoning);
|
|
283
|
+
if (effort)
|
|
284
|
+
body.reasoning_effort = effort;
|
|
285
|
+
}
|
|
286
|
+
} else {
|
|
287
|
+
if (typeof params.temperature === "number") {
|
|
288
|
+
body.temperature = params.temperature;
|
|
289
|
+
}
|
|
290
|
+
if (typeof params.topP === "number")
|
|
291
|
+
body.top_p = params.topP;
|
|
292
|
+
if (typeof params.maxTokens === "number")
|
|
293
|
+
body.max_tokens = params.maxTokens;
|
|
294
|
+
}
|
|
178
295
|
if (params.stopSequences && params.stopSequences.length > 0)
|
|
179
296
|
body.stop = params.stopSequences;
|
|
180
297
|
if (typeof params.seed === "number")
|
|
@@ -591,11 +708,14 @@ var buildRequestBody2 = (params, isImageModel) => {
|
|
|
591
708
|
};
|
|
592
709
|
}
|
|
593
710
|
}
|
|
594
|
-
if (params.
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
711
|
+
if (params.reasoning && isOpenAIReasoningModel(params.model)) {
|
|
712
|
+
const effort = openaiEffortValue(params.model, params.reasoning);
|
|
713
|
+
if (effort) {
|
|
714
|
+
body.reasoning = {
|
|
715
|
+
effort,
|
|
716
|
+
summary: "auto"
|
|
717
|
+
};
|
|
718
|
+
}
|
|
599
719
|
}
|
|
600
720
|
return body;
|
|
601
721
|
};
|
|
@@ -1221,7 +1341,13 @@ var buildRequestBody4 = (params) => {
|
|
|
1221
1341
|
stream: true
|
|
1222
1342
|
};
|
|
1223
1343
|
if (params.systemPrompt) {
|
|
1224
|
-
body.system = params.
|
|
1344
|
+
body.system = params.cacheSystemPrompt ? [
|
|
1345
|
+
{
|
|
1346
|
+
cache_control: { type: "ephemeral" },
|
|
1347
|
+
text: params.systemPrompt,
|
|
1348
|
+
type: "text"
|
|
1349
|
+
}
|
|
1350
|
+
] : params.systemPrompt;
|
|
1225
1351
|
}
|
|
1226
1352
|
if (params.tools && params.tools.length > 0) {
|
|
1227
1353
|
body.tools = params.tools.map(mapToolDefinition2);
|
|
@@ -1233,18 +1359,33 @@ var buildRequestBody4 = (params) => {
|
|
|
1233
1359
|
body.tool_choice = { name: params.toolChoice.name, type: "tool" };
|
|
1234
1360
|
}
|
|
1235
1361
|
}
|
|
1236
|
-
if (typeof params.temperature === "number")
|
|
1237
|
-
body.temperature = params.temperature;
|
|
1238
|
-
if (typeof params.topP === "number")
|
|
1239
|
-
body.top_p = params.topP;
|
|
1240
1362
|
if (typeof params.maxTokens === "number")
|
|
1241
1363
|
body.max_tokens = params.maxTokens;
|
|
1242
1364
|
if (params.stopSequences && params.stopSequences.length > 0) {
|
|
1243
1365
|
body.stop_sequences = params.stopSequences;
|
|
1244
1366
|
}
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1367
|
+
const mode = params.reasoning ? anthropicReasoningMode(params.model) : "none";
|
|
1368
|
+
const thinkingActive = mode !== "none";
|
|
1369
|
+
if (!thinkingActive && anthropicSupportsSampling(params.model)) {
|
|
1370
|
+
if (typeof params.temperature === "number") {
|
|
1371
|
+
body.temperature = params.temperature;
|
|
1372
|
+
}
|
|
1373
|
+
if (typeof params.topP === "number")
|
|
1374
|
+
body.top_p = params.topP;
|
|
1375
|
+
}
|
|
1376
|
+
if (mode === "effort" || mode === "adaptive") {
|
|
1377
|
+
body.thinking = { type: "adaptive" };
|
|
1378
|
+
if (mode === "effort" && params.reasoning) {
|
|
1379
|
+
const effort = anthropicEffortValue(params.model, params.reasoning);
|
|
1380
|
+
if (effort)
|
|
1381
|
+
body.output_config = { effort };
|
|
1382
|
+
}
|
|
1383
|
+
} else if (mode === "legacy" && params.reasoning) {
|
|
1384
|
+
const budget = resolveBudgetTokens(params.reasoning);
|
|
1385
|
+
if (budget) {
|
|
1386
|
+
body.thinking = { budget_tokens: budget, type: "enabled" };
|
|
1387
|
+
body.max_tokens = Math.max(typeof body.max_tokens === "number" ? body.max_tokens : MAX_TOKENS, budget + MAX_TOKENS);
|
|
1388
|
+
}
|
|
1248
1389
|
}
|
|
1249
1390
|
return body;
|
|
1250
1391
|
};
|
|
@@ -1383,6 +1524,8 @@ var extractUsage4 = (usageRecord, existingUsage) => {
|
|
|
1383
1524
|
return existingUsage;
|
|
1384
1525
|
}
|
|
1385
1526
|
return {
|
|
1527
|
+
cacheReadInputTokens: getNumber(usageRecord, "cache_read_input_tokens") || existingUsage?.cacheReadInputTokens || 0,
|
|
1528
|
+
cacheWriteInputTokens: getNumber(usageRecord, "cache_creation_input_tokens") || existingUsage?.cacheWriteInputTokens || 0,
|
|
1386
1529
|
inputTokens: getNumber(usageRecord, "input_tokens") || existingUsage?.inputTokens || 0,
|
|
1387
1530
|
outputTokens: getNumber(usageRecord, "output_tokens") || existingUsage?.outputTokens || 0
|
|
1388
1531
|
};
|
|
@@ -1893,7 +2036,6 @@ var WS_OPEN = 1;
|
|
|
1893
2036
|
var BACKPRESSURE_THRESHOLD = 1048576;
|
|
1894
2037
|
var BACKPRESSURE_DELAY = 10;
|
|
1895
2038
|
var DEFAULT_MAX_TURNS = 10;
|
|
1896
|
-
var DEFAULT_THINKING_BUDGET = 1e4;
|
|
1897
2039
|
var INITIAL_TURN = 0;
|
|
1898
2040
|
var delay = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
1899
2041
|
var checkBackpressure = async (socket) => {
|
|
@@ -2075,16 +2217,12 @@ var processToolTurn = async (socket, options, state, messageId, conversationId,
|
|
|
2075
2217
|
role: "user"
|
|
2076
2218
|
});
|
|
2077
2219
|
const toolDefs = options.tools ? buildToolDefinitions(options.tools) : undefined;
|
|
2078
|
-
const thinkingConfig = options.thinking ? {
|
|
2079
|
-
budget_tokens: typeof options.thinking === "object" ? options.thinking.budgetTokens : DEFAULT_THINKING_BUDGET,
|
|
2080
|
-
type: "enabled"
|
|
2081
|
-
} : undefined;
|
|
2082
2220
|
const stream = options.provider.stream({
|
|
2083
2221
|
messages: state.currentMessages,
|
|
2084
2222
|
model: options.model,
|
|
2223
|
+
reasoning: options.reasoning,
|
|
2085
2224
|
signal,
|
|
2086
2225
|
systemPrompt: options.systemPrompt,
|
|
2087
|
-
thinking: thinkingConfig,
|
|
2088
2226
|
tools: toolDefs
|
|
2089
2227
|
});
|
|
2090
2228
|
await consumeToolStream(stream, state, options, socket, messageId, conversationId, signal);
|
|
@@ -2163,16 +2301,12 @@ var processStreamTextChunk = async (chunk, options, socket, messageId, conversat
|
|
|
2163
2301
|
};
|
|
2164
2302
|
var processStream = async (socket, options, messages, messageId, conversationId, signal, startTime) => {
|
|
2165
2303
|
const toolDefs = options.tools ? buildToolDefinitions(options.tools) : undefined;
|
|
2166
|
-
const thinkingConfig = options.thinking ? {
|
|
2167
|
-
budget_tokens: typeof options.thinking === "object" ? options.thinking.budgetTokens : DEFAULT_THINKING_BUDGET,
|
|
2168
|
-
type: "enabled"
|
|
2169
|
-
} : undefined;
|
|
2170
2304
|
const stream = options.provider.stream({
|
|
2171
2305
|
messages,
|
|
2172
2306
|
model: options.model,
|
|
2307
|
+
reasoning: options.reasoning,
|
|
2173
2308
|
signal,
|
|
2174
2309
|
systemPrompt: options.systemPrompt,
|
|
2175
|
-
thinking: thinkingConfig,
|
|
2176
2310
|
tools: toolDefs
|
|
2177
2311
|
});
|
|
2178
2312
|
const result = await consumeStream(stream, options, socket, messages, messageId, conversationId, signal);
|
|
@@ -2282,7 +2416,6 @@ var handleStreamError = async (socket, err, messageId, conversationId, signal, s
|
|
|
2282
2416
|
|
|
2283
2417
|
// src/ai/streamAIToSSE.ts
|
|
2284
2418
|
var DEFAULT_MAX_TURNS2 = 10;
|
|
2285
|
-
var DEFAULT_THINKING_BUDGET2 = 1e4;
|
|
2286
2419
|
var buildToolDefinitions2 = (tools) => Object.entries(tools).map(([name, def]) => ({
|
|
2287
2420
|
description: def.description,
|
|
2288
2421
|
input_schema: def.input,
|
|
@@ -2299,10 +2432,6 @@ var executeTool2 = async (options, toolName, toolInput) => {
|
|
|
2299
2432
|
return `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
2300
2433
|
}
|
|
2301
2434
|
};
|
|
2302
|
-
var buildThinkingConfig = (options) => options.thinking ? {
|
|
2303
|
-
budget_tokens: typeof options.thinking === "object" ? options.thinking.budgetTokens : DEFAULT_THINKING_BUDGET2,
|
|
2304
|
-
type: "enabled"
|
|
2305
|
-
} : undefined;
|
|
2306
2435
|
var serializeToolCall2 = (name, input) => `${name}:${JSON.stringify(input)}`;
|
|
2307
2436
|
var streamAIToSSE = async function* (conversationId, messageId, options, renderers) {
|
|
2308
2437
|
const signal = options.signal ?? new AbortController().signal;
|
|
@@ -2463,7 +2592,6 @@ var streamTurns = async function* (options, renderers, messages, signal, startTi
|
|
|
2463
2592
|
turn: 0
|
|
2464
2593
|
};
|
|
2465
2594
|
const toolDefs = options.tools ? buildToolDefinitions2(options.tools) : undefined;
|
|
2466
|
-
const thinkingConfig = buildThinkingConfig(options);
|
|
2467
2595
|
for (;turnState.turn <= maxTurns && !signal.aborted; turnState.turn++) {
|
|
2468
2596
|
const chunkState = {
|
|
2469
2597
|
contentBlocks: [],
|
|
@@ -2474,9 +2602,9 @@ var streamTurns = async function* (options, renderers, messages, signal, startTi
|
|
|
2474
2602
|
const stream = options.provider.stream({
|
|
2475
2603
|
messages: turnState.currentMessages,
|
|
2476
2604
|
model: options.model,
|
|
2605
|
+
reasoning: options.reasoning,
|
|
2477
2606
|
signal,
|
|
2478
2607
|
systemPrompt: options.systemPrompt,
|
|
2479
|
-
thinking: thinkingConfig,
|
|
2480
2608
|
tools: toolDefs
|
|
2481
2609
|
});
|
|
2482
2610
|
yield* consumeStream2(stream, chunkState, renderers, options, turnState, signal);
|
|
@@ -2632,7 +2760,7 @@ var resolveModel = (config, parsed) => {
|
|
|
2632
2760
|
return parsed.providerName;
|
|
2633
2761
|
};
|
|
2634
2762
|
var resolveTools = (config, providerName, model) => typeof config.tools === "function" ? config.tools(providerName, model) : config.tools;
|
|
2635
|
-
var
|
|
2763
|
+
var resolveReasoning = (config, providerName, model) => typeof config.reasoning === "function" ? config.reasoning(providerName, model) : config.reasoning;
|
|
2636
2764
|
var aiChat = (config) => {
|
|
2637
2765
|
const path = config.path ?? DEFAULT_PATH;
|
|
2638
2766
|
const store = config.store ?? createMemoryStore();
|
|
@@ -2683,7 +2811,7 @@ var aiChat = (config) => {
|
|
|
2683
2811
|
provider: config.provider(providerName),
|
|
2684
2812
|
signal: controller.signal,
|
|
2685
2813
|
systemPrompt: config.systemPrompt,
|
|
2686
|
-
|
|
2814
|
+
reasoning: resolveReasoning(config, providerName, model),
|
|
2687
2815
|
tools: resolveTools(config, providerName, model),
|
|
2688
2816
|
onComplete: async (fullResponse, usage) => {
|
|
2689
2817
|
const conv = await store.get(conversationId);
|
|
@@ -2757,7 +2885,7 @@ var aiChat = (config) => {
|
|
|
2757
2885
|
provider: config.provider(providerName),
|
|
2758
2886
|
signal: controller.signal,
|
|
2759
2887
|
systemPrompt: config.systemPrompt,
|
|
2760
|
-
|
|
2888
|
+
reasoning: resolveReasoning(config, providerName, model),
|
|
2761
2889
|
tools: resolveTools(config, providerName, model)
|
|
2762
2890
|
}, renderers);
|
|
2763
2891
|
for await (const event of sseStream) {
|
|
@@ -2821,9 +2949,11 @@ var aiChat = (config) => {
|
|
|
2821
2949
|
var DEFAULT_OBJECT_TOOL_NAME = "respond";
|
|
2822
2950
|
var generateAI = async (options) => {
|
|
2823
2951
|
const stream = options.provider.stream({
|
|
2952
|
+
cacheSystemPrompt: options.cacheSystemPrompt,
|
|
2824
2953
|
maxTokens: options.maxTokens,
|
|
2825
2954
|
messages: options.messages,
|
|
2826
2955
|
model: options.model,
|
|
2956
|
+
reasoning: options.reasoning,
|
|
2827
2957
|
responseFormat: options.responseFormat,
|
|
2828
2958
|
signal: options.signal,
|
|
2829
2959
|
stopSequences: options.stopSequences,
|
|
@@ -2855,10 +2985,12 @@ var generateObjectAI = async (options) => {
|
|
|
2855
2985
|
name: toolName
|
|
2856
2986
|
};
|
|
2857
2987
|
const { toolCalls, usage } = await generateAI({
|
|
2988
|
+
cacheSystemPrompt: options.cacheSystemPrompt,
|
|
2858
2989
|
maxTokens: options.maxTokens,
|
|
2859
2990
|
messages: options.messages,
|
|
2860
2991
|
model: options.model,
|
|
2861
2992
|
provider: options.provider,
|
|
2993
|
+
reasoning: options.reasoning,
|
|
2862
2994
|
signal: options.signal,
|
|
2863
2995
|
systemPrompt: options.systemPrompt,
|
|
2864
2996
|
temperature: options.temperature,
|
|
@@ -3725,5 +3857,5 @@ export {
|
|
|
3725
3857
|
aiChat
|
|
3726
3858
|
};
|
|
3727
3859
|
|
|
3728
|
-
//# debugId=
|
|
3860
|
+
//# debugId=F448AA17322C183164756E2164756E21
|
|
3729
3861
|
//# sourceMappingURL=index.js.map
|