@mariozechner/pi-ai 0.49.3 → 0.50.0
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/README.md +32 -22
- package/dist/api-registry.d.ts +20 -0
- package/dist/api-registry.d.ts.map +1 -0
- package/dist/api-registry.js +44 -0
- package/dist/api-registry.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +22 -67
- package/dist/cli.js.map +1 -1
- package/dist/env-api-keys.d.ts +9 -0
- package/dist/env-api-keys.d.ts.map +1 -0
- package/dist/env-api-keys.js +91 -0
- package/dist/env-api-keys.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/models.generated.d.ts +599 -70
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +619 -90
- package/dist/models.generated.js.map +1 -1
- package/dist/providers/amazon-bedrock.d.ts +3 -2
- package/dist/providers/amazon-bedrock.d.ts.map +1 -1
- package/dist/providers/amazon-bedrock.js +52 -5
- package/dist/providers/amazon-bedrock.js.map +1 -1
- package/dist/providers/anthropic.d.ts +3 -2
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +20 -2
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/azure-openai-responses.d.ts +15 -0
- package/dist/providers/azure-openai-responses.d.ts.map +1 -0
- package/dist/providers/azure-openai-responses.js +184 -0
- package/dist/providers/azure-openai-responses.js.map +1 -0
- package/dist/providers/google-gemini-cli.d.ts +3 -2
- package/dist/providers/google-gemini-cli.d.ts.map +1 -1
- package/dist/providers/google-gemini-cli.js +68 -1
- package/dist/providers/google-gemini-cli.js.map +1 -1
- package/dist/providers/google-vertex.d.ts +3 -2
- package/dist/providers/google-vertex.d.ts.map +1 -1
- package/dist/providers/google-vertex.js +81 -1
- package/dist/providers/google-vertex.js.map +1 -1
- package/dist/providers/google.d.ts +3 -2
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +84 -3
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/openai-codex-responses.d.ts +3 -2
- package/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/dist/providers/openai-codex-responses.js +57 -307
- package/dist/providers/openai-codex-responses.js.map +1 -1
- package/dist/providers/openai-completions.d.ts +5 -2
- package/dist/providers/openai-completions.d.ts.map +1 -1
- package/dist/providers/openai-completions.js +78 -41
- package/dist/providers/openai-completions.js.map +1 -1
- package/dist/providers/openai-responses-shared.d.ts +17 -0
- package/dist/providers/openai-responses-shared.d.ts.map +1 -0
- package/dist/providers/openai-responses-shared.js +424 -0
- package/dist/providers/openai-responses-shared.js.map +1 -0
- package/dist/providers/openai-responses.d.ts +3 -2
- package/dist/providers/openai-responses.d.ts.map +1 -1
- package/dist/providers/openai-responses.js +25 -415
- package/dist/providers/openai-responses.js.map +1 -1
- package/dist/providers/register-builtins.d.ts +3 -0
- package/dist/providers/register-builtins.d.ts.map +1 -0
- package/dist/providers/register-builtins.js +63 -0
- package/dist/providers/register-builtins.js.map +1 -0
- package/dist/providers/simple-options.d.ts +8 -0
- package/dist/providers/simple-options.d.ts.map +1 -0
- package/dist/providers/simple-options.js +32 -0
- package/dist/providers/simple-options.js.map +1 -0
- package/dist/stream.d.ts +5 -10
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +17 -420
- package/dist/stream.js.map +1 -1
- package/dist/types.d.ts +18 -22
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/event-stream.d.ts +2 -0
- package/dist/utils/event-stream.d.ts.map +1 -1
- package/dist/utils/event-stream.js +4 -0
- package/dist/utils/event-stream.js.map +1 -1
- package/dist/utils/oauth/anthropic.d.ts +2 -1
- package/dist/utils/oauth/anthropic.d.ts.map +1 -1
- package/dist/utils/oauth/anthropic.js +13 -0
- package/dist/utils/oauth/anthropic.js.map +1 -1
- package/dist/utils/oauth/github-copilot.d.ts +2 -1
- package/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/dist/utils/oauth/github-copilot.js +25 -0
- package/dist/utils/oauth/github-copilot.js.map +1 -1
- package/dist/utils/oauth/google-antigravity.d.ts +2 -1
- package/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
- package/dist/utils/oauth/google-antigravity.js +19 -0
- package/dist/utils/oauth/google-antigravity.js.map +1 -1
- package/dist/utils/oauth/google-gemini-cli.d.ts +2 -1
- package/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
- package/dist/utils/oauth/google-gemini-cli.js +19 -0
- package/dist/utils/oauth/google-gemini-cli.js.map +1 -1
- package/dist/utils/oauth/index.d.ts +26 -16
- package/dist/utils/oauth/index.d.ts.map +1 -1
- package/dist/utils/oauth/index.js +65 -84
- package/dist/utils/oauth/index.js.map +1 -1
- package/dist/utils/oauth/openai-codex.d.ts +2 -1
- package/dist/utils/oauth/openai-codex.d.ts.map +1 -1
- package/dist/utils/oauth/openai-codex.js +20 -1
- package/dist/utils/oauth/openai-codex.js.map +1 -1
- package/dist/utils/oauth/types.d.ts +28 -6
- package/dist/utils/oauth/types.d.ts.map +1 -1
- package/dist/utils/oauth/types.js.map +1 -1
- package/package.json +3 -1
package/dist/stream.js
CHANGED
|
@@ -1,438 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
//
|
|
1
|
+
import "./providers/register-builtins.js";
|
|
2
|
+
import { getApiProvider } from "./api-registry.js";
|
|
3
|
+
export { getEnvApiKey } from "./env-api-keys.js";
|
|
4
|
+
// Set up http proxy according to env variables for `fetch` based SDKs in Node.js.
|
|
5
|
+
// Bun has builtin support for this.
|
|
6
6
|
if (typeof process !== "undefined" && process.versions?.node) {
|
|
7
|
-
import("
|
|
8
|
-
|
|
7
|
+
import("undici").then((m) => {
|
|
8
|
+
const { EnvHttpProxyAgent, setGlobalDispatcher } = m;
|
|
9
|
+
setGlobalDispatcher(new EnvHttpProxyAgent());
|
|
9
10
|
});
|
|
10
|
-
import("node:os").then((m) => {
|
|
11
|
-
_homedir = m.homedir;
|
|
12
|
-
});
|
|
13
|
-
import("node:path").then((m) => {
|
|
14
|
-
_join = m.join;
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
import { supportsXhigh } from "./models.js";
|
|
18
|
-
import { streamBedrock } from "./providers/amazon-bedrock.js";
|
|
19
|
-
import { streamAnthropic } from "./providers/anthropic.js";
|
|
20
|
-
import { streamGoogle } from "./providers/google.js";
|
|
21
|
-
import { streamGoogleGeminiCli, } from "./providers/google-gemini-cli.js";
|
|
22
|
-
import { streamGoogleVertex } from "./providers/google-vertex.js";
|
|
23
|
-
import { streamOpenAICodexResponses } from "./providers/openai-codex-responses.js";
|
|
24
|
-
import { streamOpenAICompletions } from "./providers/openai-completions.js";
|
|
25
|
-
import { streamOpenAIResponses } from "./providers/openai-responses.js";
|
|
26
|
-
let cachedVertexAdcCredentialsExists = null;
|
|
27
|
-
function hasVertexAdcCredentials() {
|
|
28
|
-
if (cachedVertexAdcCredentialsExists === null) {
|
|
29
|
-
// In browser or if node modules not loaded yet, return false
|
|
30
|
-
if (!_existsSync || !_homedir || !_join) {
|
|
31
|
-
cachedVertexAdcCredentialsExists = false;
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
// Check GOOGLE_APPLICATION_CREDENTIALS env var first (standard way)
|
|
35
|
-
const gacPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
36
|
-
if (gacPath) {
|
|
37
|
-
cachedVertexAdcCredentialsExists = _existsSync(gacPath);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
// Fall back to default ADC path (lazy evaluation)
|
|
41
|
-
cachedVertexAdcCredentialsExists = _existsSync(_join(_homedir(), ".config", "gcloud", "application_default_credentials.json"));
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return cachedVertexAdcCredentialsExists;
|
|
45
11
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (provider
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
// ANTHROPIC_OAUTH_TOKEN takes precedence over ANTHROPIC_API_KEY
|
|
52
|
-
if (provider === "anthropic") {
|
|
53
|
-
return process.env.ANTHROPIC_OAUTH_TOKEN || process.env.ANTHROPIC_API_KEY;
|
|
54
|
-
}
|
|
55
|
-
// Vertex AI uses Application Default Credentials, not API keys.
|
|
56
|
-
// Auth is configured via `gcloud auth application-default login`.
|
|
57
|
-
if (provider === "google-vertex") {
|
|
58
|
-
const hasCredentials = hasVertexAdcCredentials();
|
|
59
|
-
const hasProject = !!(process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT);
|
|
60
|
-
const hasLocation = !!process.env.GOOGLE_CLOUD_LOCATION;
|
|
61
|
-
if (hasCredentials && hasProject && hasLocation) {
|
|
62
|
-
return "<authenticated>";
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (provider === "amazon-bedrock") {
|
|
66
|
-
// Amazon Bedrock supports multiple credential sources:
|
|
67
|
-
// 1. AWS_PROFILE - named profile from ~/.aws/credentials
|
|
68
|
-
// 2. AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY - standard IAM keys
|
|
69
|
-
// 3. AWS_BEARER_TOKEN_BEDROCK - Bedrock API keys (bearer token)
|
|
70
|
-
// 4. AWS_CONTAINER_CREDENTIALS_RELATIVE_URI - ECS task roles
|
|
71
|
-
// 5. AWS_CONTAINER_CREDENTIALS_FULL_URI - ECS task roles (full URI)
|
|
72
|
-
// 6. AWS_WEB_IDENTITY_TOKEN_FILE - IRSA (IAM Roles for Service Accounts)
|
|
73
|
-
if (process.env.AWS_PROFILE ||
|
|
74
|
-
(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ||
|
|
75
|
-
process.env.AWS_BEARER_TOKEN_BEDROCK ||
|
|
76
|
-
process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI ||
|
|
77
|
-
process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI ||
|
|
78
|
-
process.env.AWS_WEB_IDENTITY_TOKEN_FILE) {
|
|
79
|
-
return "<authenticated>";
|
|
80
|
-
}
|
|
12
|
+
function resolveApiProvider(api) {
|
|
13
|
+
const provider = getApiProvider(api);
|
|
14
|
+
if (!provider) {
|
|
15
|
+
throw new Error(`No API provider registered for api: ${api}`);
|
|
81
16
|
}
|
|
82
|
-
|
|
83
|
-
openai: "OPENAI_API_KEY",
|
|
84
|
-
google: "GEMINI_API_KEY",
|
|
85
|
-
groq: "GROQ_API_KEY",
|
|
86
|
-
cerebras: "CEREBRAS_API_KEY",
|
|
87
|
-
xai: "XAI_API_KEY",
|
|
88
|
-
openrouter: "OPENROUTER_API_KEY",
|
|
89
|
-
"vercel-ai-gateway": "AI_GATEWAY_API_KEY",
|
|
90
|
-
zai: "ZAI_API_KEY",
|
|
91
|
-
mistral: "MISTRAL_API_KEY",
|
|
92
|
-
minimax: "MINIMAX_API_KEY",
|
|
93
|
-
"minimax-cn": "MINIMAX_CN_API_KEY",
|
|
94
|
-
opencode: "OPENCODE_API_KEY",
|
|
95
|
-
};
|
|
96
|
-
const envVar = envMap[provider];
|
|
97
|
-
return envVar ? process.env[envVar] : undefined;
|
|
17
|
+
return provider;
|
|
98
18
|
}
|
|
99
19
|
export function stream(model, context, options) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return streamGoogleVertex(model, context, options);
|
|
103
|
-
}
|
|
104
|
-
else if (model.api === "bedrock-converse-stream") {
|
|
105
|
-
// Bedrock doesn't have any API keys instead it sources credentials from standard AWS env variables or from given AWS profile.
|
|
106
|
-
return streamBedrock(model, context, (options || {}));
|
|
107
|
-
}
|
|
108
|
-
const apiKey = options?.apiKey || getEnvApiKey(model.provider);
|
|
109
|
-
if (!apiKey) {
|
|
110
|
-
throw new Error(`No API key for provider: ${model.provider}`);
|
|
111
|
-
}
|
|
112
|
-
const providerOptions = { ...options, apiKey };
|
|
113
|
-
const api = model.api;
|
|
114
|
-
switch (api) {
|
|
115
|
-
case "anthropic-messages":
|
|
116
|
-
return streamAnthropic(model, context, providerOptions);
|
|
117
|
-
case "openai-completions":
|
|
118
|
-
return streamOpenAICompletions(model, context, providerOptions);
|
|
119
|
-
case "openai-responses":
|
|
120
|
-
return streamOpenAIResponses(model, context, providerOptions);
|
|
121
|
-
case "openai-codex-responses":
|
|
122
|
-
return streamOpenAICodexResponses(model, context, providerOptions);
|
|
123
|
-
case "google-generative-ai":
|
|
124
|
-
return streamGoogle(model, context, providerOptions);
|
|
125
|
-
case "google-gemini-cli":
|
|
126
|
-
return streamGoogleGeminiCli(model, context, providerOptions);
|
|
127
|
-
default: {
|
|
128
|
-
// This should never be reached if all Api cases are handled
|
|
129
|
-
const _exhaustive = api;
|
|
130
|
-
throw new Error(`Unhandled API: ${_exhaustive}`);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
20
|
+
const provider = resolveApiProvider(model.api);
|
|
21
|
+
return provider.stream(model, context, options);
|
|
133
22
|
}
|
|
134
23
|
export async function complete(model, context, options) {
|
|
135
24
|
const s = stream(model, context, options);
|
|
136
25
|
return s.result();
|
|
137
26
|
}
|
|
138
27
|
export function streamSimple(model, context, options) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const providerOptions = mapOptionsForApi(model, options, undefined);
|
|
142
|
-
return stream(model, context, providerOptions);
|
|
143
|
-
}
|
|
144
|
-
else if (model.api === "bedrock-converse-stream") {
|
|
145
|
-
// Bedrock doesn't have any API keys instead it sources credentials from standard AWS env variables or from given AWS profile.
|
|
146
|
-
const providerOptions = mapOptionsForApi(model, options, undefined);
|
|
147
|
-
return stream(model, context, providerOptions);
|
|
148
|
-
}
|
|
149
|
-
const apiKey = options?.apiKey || getEnvApiKey(model.provider);
|
|
150
|
-
if (!apiKey) {
|
|
151
|
-
throw new Error(`No API key for provider: ${model.provider}`);
|
|
152
|
-
}
|
|
153
|
-
const providerOptions = mapOptionsForApi(model, options, apiKey);
|
|
154
|
-
return stream(model, context, providerOptions);
|
|
28
|
+
const provider = resolveApiProvider(model.api);
|
|
29
|
+
return provider.streamSimple(model, context, options);
|
|
155
30
|
}
|
|
156
31
|
export async function completeSimple(model, context, options) {
|
|
157
32
|
const s = streamSimple(model, context, options);
|
|
158
33
|
return s.result();
|
|
159
34
|
}
|
|
160
|
-
function mapOptionsForApi(model, options, apiKey) {
|
|
161
|
-
const base = {
|
|
162
|
-
temperature: options?.temperature,
|
|
163
|
-
maxTokens: options?.maxTokens || Math.min(model.maxTokens, 32000),
|
|
164
|
-
signal: options?.signal,
|
|
165
|
-
apiKey: apiKey || options?.apiKey,
|
|
166
|
-
sessionId: options?.sessionId,
|
|
167
|
-
headers: options?.headers,
|
|
168
|
-
onPayload: options?.onPayload,
|
|
169
|
-
};
|
|
170
|
-
// Helper to clamp xhigh to high for providers that don't support it
|
|
171
|
-
const clampReasoning = (effort) => (effort === "xhigh" ? "high" : effort);
|
|
172
|
-
/**
|
|
173
|
-
* Adjust maxTokens to account for thinking budget.
|
|
174
|
-
* APIs like Anthropic and Bedrock require max_tokens > thinking.budget_tokens.
|
|
175
|
-
* Returns { adjustedMaxTokens, adjustedThinkingBudget }
|
|
176
|
-
*/
|
|
177
|
-
const adjustMaxTokensForThinking = (baseMaxTokens, modelMaxTokens, reasoningLevel, customBudgets) => {
|
|
178
|
-
const defaultBudgets = {
|
|
179
|
-
minimal: 1024,
|
|
180
|
-
low: 2048,
|
|
181
|
-
medium: 8192,
|
|
182
|
-
high: 16384,
|
|
183
|
-
};
|
|
184
|
-
const budgets = { ...defaultBudgets, ...customBudgets };
|
|
185
|
-
const minOutputTokens = 1024;
|
|
186
|
-
const level = clampReasoning(reasoningLevel);
|
|
187
|
-
let thinkingBudget = budgets[level];
|
|
188
|
-
// Caller's maxTokens is the desired output; add thinking budget on top, capped at model limit
|
|
189
|
-
const maxTokens = Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);
|
|
190
|
-
// If not enough room for thinking + output, reduce thinking budget
|
|
191
|
-
if (maxTokens <= thinkingBudget) {
|
|
192
|
-
thinkingBudget = Math.max(0, maxTokens - minOutputTokens);
|
|
193
|
-
}
|
|
194
|
-
return { maxTokens, thinkingBudget };
|
|
195
|
-
};
|
|
196
|
-
switch (model.api) {
|
|
197
|
-
case "anthropic-messages": {
|
|
198
|
-
// Explicitly disable thinking when reasoning is not specified
|
|
199
|
-
if (!options?.reasoning) {
|
|
200
|
-
return { ...base, thinkingEnabled: false };
|
|
201
|
-
}
|
|
202
|
-
// Claude requires max_tokens > thinking.budget_tokens
|
|
203
|
-
// So we need to ensure maxTokens accounts for both thinking and output
|
|
204
|
-
const adjusted = adjustMaxTokensForThinking(base.maxTokens || 0, model.maxTokens, options.reasoning, options?.thinkingBudgets);
|
|
205
|
-
return {
|
|
206
|
-
...base,
|
|
207
|
-
maxTokens: adjusted.maxTokens,
|
|
208
|
-
thinkingEnabled: true,
|
|
209
|
-
thinkingBudgetTokens: adjusted.thinkingBudget,
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
case "bedrock-converse-stream": {
|
|
213
|
-
// Explicitly disable thinking when reasoning is not specified
|
|
214
|
-
if (!options?.reasoning) {
|
|
215
|
-
return { ...base, reasoning: undefined };
|
|
216
|
-
}
|
|
217
|
-
// Claude requires max_tokens > thinking.budget_tokens (same as Anthropic direct API)
|
|
218
|
-
// So we need to ensure maxTokens accounts for both thinking and output
|
|
219
|
-
if (model.id.includes("anthropic.claude") || model.id.includes("anthropic/claude")) {
|
|
220
|
-
const adjusted = adjustMaxTokensForThinking(base.maxTokens || 0, model.maxTokens, options.reasoning, options?.thinkingBudgets);
|
|
221
|
-
return {
|
|
222
|
-
...base,
|
|
223
|
-
maxTokens: adjusted.maxTokens,
|
|
224
|
-
reasoning: options.reasoning,
|
|
225
|
-
thinkingBudgets: {
|
|
226
|
-
...(options?.thinkingBudgets || {}),
|
|
227
|
-
[clampReasoning(options.reasoning)]: adjusted.thinkingBudget,
|
|
228
|
-
},
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
// Non-Claude models - pass through
|
|
232
|
-
return {
|
|
233
|
-
...base,
|
|
234
|
-
reasoning: options?.reasoning,
|
|
235
|
-
thinkingBudgets: options?.thinkingBudgets,
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
case "openai-completions":
|
|
239
|
-
return {
|
|
240
|
-
...base,
|
|
241
|
-
reasoningEffort: supportsXhigh(model) ? options?.reasoning : clampReasoning(options?.reasoning),
|
|
242
|
-
};
|
|
243
|
-
case "openai-responses":
|
|
244
|
-
return {
|
|
245
|
-
...base,
|
|
246
|
-
reasoningEffort: supportsXhigh(model) ? options?.reasoning : clampReasoning(options?.reasoning),
|
|
247
|
-
};
|
|
248
|
-
case "openai-codex-responses":
|
|
249
|
-
return {
|
|
250
|
-
...base,
|
|
251
|
-
reasoningEffort: supportsXhigh(model) ? options?.reasoning : clampReasoning(options?.reasoning),
|
|
252
|
-
};
|
|
253
|
-
case "google-generative-ai": {
|
|
254
|
-
// Explicitly disable thinking when reasoning is not specified
|
|
255
|
-
// This is needed because Gemini has "dynamic thinking" enabled by default
|
|
256
|
-
if (!options?.reasoning) {
|
|
257
|
-
return { ...base, thinking: { enabled: false } };
|
|
258
|
-
}
|
|
259
|
-
const googleModel = model;
|
|
260
|
-
const effort = clampReasoning(options.reasoning);
|
|
261
|
-
// Gemini 3 models use thinkingLevel exclusively instead of thinkingBudget.
|
|
262
|
-
// https://ai.google.dev/gemini-api/docs/thinking#set-budget
|
|
263
|
-
if (isGemini3ProModel(googleModel) || isGemini3FlashModel(googleModel)) {
|
|
264
|
-
return {
|
|
265
|
-
...base,
|
|
266
|
-
thinking: {
|
|
267
|
-
enabled: true,
|
|
268
|
-
level: getGemini3ThinkingLevel(effort, googleModel),
|
|
269
|
-
},
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
return {
|
|
273
|
-
...base,
|
|
274
|
-
thinking: {
|
|
275
|
-
enabled: true,
|
|
276
|
-
budgetTokens: getGoogleBudget(googleModel, effort, options?.thinkingBudgets),
|
|
277
|
-
},
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
case "google-gemini-cli": {
|
|
281
|
-
if (!options?.reasoning) {
|
|
282
|
-
return { ...base, thinking: { enabled: false } };
|
|
283
|
-
}
|
|
284
|
-
const effort = clampReasoning(options.reasoning);
|
|
285
|
-
// Gemini 3 models use thinkingLevel instead of thinkingBudget
|
|
286
|
-
if (model.id.includes("3-pro") || model.id.includes("3-flash")) {
|
|
287
|
-
return {
|
|
288
|
-
...base,
|
|
289
|
-
thinking: {
|
|
290
|
-
enabled: true,
|
|
291
|
-
level: getGeminiCliThinkingLevel(effort, model.id),
|
|
292
|
-
},
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
// Models using thinkingBudget (Gemini 2.x, Claude via Antigravity)
|
|
296
|
-
// Claude requires max_tokens > thinking.budget_tokens
|
|
297
|
-
// So we need to ensure maxTokens accounts for both thinking and output
|
|
298
|
-
const defaultBudgets = {
|
|
299
|
-
minimal: 1024,
|
|
300
|
-
low: 2048,
|
|
301
|
-
medium: 8192,
|
|
302
|
-
high: 16384,
|
|
303
|
-
};
|
|
304
|
-
const budgets = { ...defaultBudgets, ...options?.thinkingBudgets };
|
|
305
|
-
const minOutputTokens = 1024;
|
|
306
|
-
let thinkingBudget = budgets[effort];
|
|
307
|
-
// Caller's maxTokens is the desired output; add thinking budget on top, capped at model limit
|
|
308
|
-
const maxTokens = Math.min((base.maxTokens || 0) + thinkingBudget, model.maxTokens);
|
|
309
|
-
// If not enough room for thinking + output, reduce thinking budget
|
|
310
|
-
if (maxTokens <= thinkingBudget) {
|
|
311
|
-
thinkingBudget = Math.max(0, maxTokens - minOutputTokens);
|
|
312
|
-
}
|
|
313
|
-
return {
|
|
314
|
-
...base,
|
|
315
|
-
maxTokens,
|
|
316
|
-
thinking: {
|
|
317
|
-
enabled: true,
|
|
318
|
-
budgetTokens: thinkingBudget,
|
|
319
|
-
},
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
case "google-vertex": {
|
|
323
|
-
// Explicitly disable thinking when reasoning is not specified
|
|
324
|
-
if (!options?.reasoning) {
|
|
325
|
-
return { ...base, thinking: { enabled: false } };
|
|
326
|
-
}
|
|
327
|
-
const vertexModel = model;
|
|
328
|
-
const effort = clampReasoning(options.reasoning);
|
|
329
|
-
const geminiModel = vertexModel;
|
|
330
|
-
if (isGemini3ProModel(geminiModel) || isGemini3FlashModel(geminiModel)) {
|
|
331
|
-
return {
|
|
332
|
-
...base,
|
|
333
|
-
thinking: {
|
|
334
|
-
enabled: true,
|
|
335
|
-
level: getGemini3ThinkingLevel(effort, geminiModel),
|
|
336
|
-
},
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
return {
|
|
340
|
-
...base,
|
|
341
|
-
thinking: {
|
|
342
|
-
enabled: true,
|
|
343
|
-
budgetTokens: getGoogleBudget(geminiModel, effort, options?.thinkingBudgets),
|
|
344
|
-
},
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
default: {
|
|
348
|
-
// Exhaustiveness check
|
|
349
|
-
const _exhaustive = model.api;
|
|
350
|
-
throw new Error(`Unhandled API in mapOptionsForApi: ${_exhaustive}`);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
function isGemini3ProModel(model) {
|
|
355
|
-
// Covers gemini-3-pro, gemini-3-pro-preview, and possible other prefixed ids in the future
|
|
356
|
-
return model.id.includes("3-pro");
|
|
357
|
-
}
|
|
358
|
-
function isGemini3FlashModel(model) {
|
|
359
|
-
// Covers gemini-3-flash, gemini-3-flash-preview, and possible other prefixed ids in the future
|
|
360
|
-
return model.id.includes("3-flash");
|
|
361
|
-
}
|
|
362
|
-
function getGemini3ThinkingLevel(effort, model) {
|
|
363
|
-
if (isGemini3ProModel(model)) {
|
|
364
|
-
// Gemini 3 Pro only supports LOW/HIGH (for now)
|
|
365
|
-
switch (effort) {
|
|
366
|
-
case "minimal":
|
|
367
|
-
case "low":
|
|
368
|
-
return "LOW";
|
|
369
|
-
case "medium":
|
|
370
|
-
case "high":
|
|
371
|
-
return "HIGH";
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
// Gemini 3 Flash supports all four levels
|
|
375
|
-
switch (effort) {
|
|
376
|
-
case "minimal":
|
|
377
|
-
return "MINIMAL";
|
|
378
|
-
case "low":
|
|
379
|
-
return "LOW";
|
|
380
|
-
case "medium":
|
|
381
|
-
return "MEDIUM";
|
|
382
|
-
case "high":
|
|
383
|
-
return "HIGH";
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
function getGeminiCliThinkingLevel(effort, modelId) {
|
|
387
|
-
if (modelId.includes("3-pro")) {
|
|
388
|
-
// Gemini 3 Pro only supports LOW/HIGH (for now)
|
|
389
|
-
switch (effort) {
|
|
390
|
-
case "minimal":
|
|
391
|
-
case "low":
|
|
392
|
-
return "LOW";
|
|
393
|
-
case "medium":
|
|
394
|
-
case "high":
|
|
395
|
-
return "HIGH";
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
// Gemini 3 Flash supports all four levels
|
|
399
|
-
switch (effort) {
|
|
400
|
-
case "minimal":
|
|
401
|
-
return "MINIMAL";
|
|
402
|
-
case "low":
|
|
403
|
-
return "LOW";
|
|
404
|
-
case "medium":
|
|
405
|
-
return "MEDIUM";
|
|
406
|
-
case "high":
|
|
407
|
-
return "HIGH";
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
function getGoogleBudget(model, effort, customBudgets) {
|
|
411
|
-
// Custom budgets take precedence if provided for this level
|
|
412
|
-
if (customBudgets?.[effort] !== undefined) {
|
|
413
|
-
return customBudgets[effort];
|
|
414
|
-
}
|
|
415
|
-
// See https://ai.google.dev/gemini-api/docs/thinking#set-budget
|
|
416
|
-
if (model.id.includes("2.5-pro")) {
|
|
417
|
-
const budgets = {
|
|
418
|
-
minimal: 128,
|
|
419
|
-
low: 2048,
|
|
420
|
-
medium: 8192,
|
|
421
|
-
high: 32768,
|
|
422
|
-
};
|
|
423
|
-
return budgets[effort];
|
|
424
|
-
}
|
|
425
|
-
if (model.id.includes("2.5-flash")) {
|
|
426
|
-
// Covers 2.5-flash-lite as well
|
|
427
|
-
const budgets = {
|
|
428
|
-
minimal: 128,
|
|
429
|
-
low: 2048,
|
|
430
|
-
medium: 8192,
|
|
431
|
-
high: 24576,
|
|
432
|
-
};
|
|
433
|
-
return budgets[effort];
|
|
434
|
-
}
|
|
435
|
-
// Unknown model - use dynamic
|
|
436
|
-
return -1;
|
|
437
|
-
}
|
|
438
35
|
//# sourceMappingURL=stream.js.map
|
package/dist/stream.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"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","sourcesContent":["// NEVER convert to top-level imports - breaks browser/Vite builds (web-ui)\nlet _existsSync: typeof import(\"node:fs\").existsSync | null = null;\nlet _homedir: typeof import(\"node:os\").homedir | null = null;\nlet _join: typeof import(\"node:path\").join | null = null;\n\n// Eagerly load in Node.js environment only\nif (typeof process !== \"undefined\" && process.versions?.node) {\n\timport(\"node:fs\").then((m) => {\n\t\t_existsSync = m.existsSync;\n\t});\n\timport(\"node:os\").then((m) => {\n\t\t_homedir = m.homedir;\n\t});\n\timport(\"node:path\").then((m) => {\n\t\t_join = m.join;\n\t});\n}\n\nimport { supportsXhigh } from \"./models.js\";\nimport { type BedrockOptions, streamBedrock } from \"./providers/amazon-bedrock.js\";\nimport { type AnthropicOptions, streamAnthropic } from \"./providers/anthropic.js\";\nimport { type GoogleOptions, streamGoogle } from \"./providers/google.js\";\nimport {\n\ttype GoogleGeminiCliOptions,\n\ttype GoogleThinkingLevel,\n\tstreamGoogleGeminiCli,\n} from \"./providers/google-gemini-cli.js\";\nimport { type GoogleVertexOptions, streamGoogleVertex } from \"./providers/google-vertex.js\";\nimport { type OpenAICodexResponsesOptions, streamOpenAICodexResponses } from \"./providers/openai-codex-responses.js\";\nimport { type OpenAICompletionsOptions, streamOpenAICompletions } from \"./providers/openai-completions.js\";\nimport { type OpenAIResponsesOptions, streamOpenAIResponses } from \"./providers/openai-responses.js\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tAssistantMessageEventStream,\n\tContext,\n\tKnownProvider,\n\tModel,\n\tOptionsForApi,\n\tSimpleStreamOptions,\n\tThinkingBudgets,\n\tThinkingLevel,\n} from \"./types.js\";\n\nlet cachedVertexAdcCredentialsExists: boolean | null = null;\n\nfunction hasVertexAdcCredentials(): boolean {\n\tif (cachedVertexAdcCredentialsExists === null) {\n\t\t// In browser or if node modules not loaded yet, return false\n\t\tif (!_existsSync || !_homedir || !_join) {\n\t\t\tcachedVertexAdcCredentialsExists = false;\n\t\t\treturn false;\n\t\t}\n\n\t\t// Check GOOGLE_APPLICATION_CREDENTIALS env var first (standard way)\n\t\tconst gacPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;\n\t\tif (gacPath) {\n\t\t\tcachedVertexAdcCredentialsExists = _existsSync(gacPath);\n\t\t} else {\n\t\t\t// Fall back to default ADC path (lazy evaluation)\n\t\t\tcachedVertexAdcCredentialsExists = _existsSync(\n\t\t\t\t_join(_homedir(), \".config\", \"gcloud\", \"application_default_credentials.json\"),\n\t\t\t);\n\t\t}\n\t}\n\treturn cachedVertexAdcCredentialsExists;\n}\n\n/**\n * Get API key for provider from known environment variables, e.g. OPENAI_API_KEY.\n *\n * Will not return API keys for providers that require OAuth tokens.\n */\nexport function getEnvApiKey(provider: KnownProvider): string | undefined;\nexport function getEnvApiKey(provider: string): string | undefined;\nexport function getEnvApiKey(provider: any): string | undefined {\n\t// Fall back to environment variables\n\tif (provider === \"github-copilot\") {\n\t\treturn process.env.COPILOT_GITHUB_TOKEN || process.env.GH_TOKEN || process.env.GITHUB_TOKEN;\n\t}\n\n\t// ANTHROPIC_OAUTH_TOKEN takes precedence over ANTHROPIC_API_KEY\n\tif (provider === \"anthropic\") {\n\t\treturn process.env.ANTHROPIC_OAUTH_TOKEN || process.env.ANTHROPIC_API_KEY;\n\t}\n\n\t// Vertex AI uses Application Default Credentials, not API keys.\n\t// Auth is configured via `gcloud auth application-default login`.\n\tif (provider === \"google-vertex\") {\n\t\tconst hasCredentials = hasVertexAdcCredentials();\n\t\tconst hasProject = !!(process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT);\n\t\tconst hasLocation = !!process.env.GOOGLE_CLOUD_LOCATION;\n\n\t\tif (hasCredentials && hasProject && hasLocation) {\n\t\t\treturn \"<authenticated>\";\n\t\t}\n\t}\n\n\tif (provider === \"amazon-bedrock\") {\n\t\t// Amazon Bedrock supports multiple credential sources:\n\t\t// 1. AWS_PROFILE - named profile from ~/.aws/credentials\n\t\t// 2. AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY - standard IAM keys\n\t\t// 3. AWS_BEARER_TOKEN_BEDROCK - Bedrock API keys (bearer token)\n\t\t// 4. AWS_CONTAINER_CREDENTIALS_RELATIVE_URI - ECS task roles\n\t\t// 5. AWS_CONTAINER_CREDENTIALS_FULL_URI - ECS task roles (full URI)\n\t\t// 6. AWS_WEB_IDENTITY_TOKEN_FILE - IRSA (IAM Roles for Service Accounts)\n\t\tif (\n\t\t\tprocess.env.AWS_PROFILE ||\n\t\t\t(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ||\n\t\t\tprocess.env.AWS_BEARER_TOKEN_BEDROCK ||\n\t\t\tprocess.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI ||\n\t\t\tprocess.env.AWS_CONTAINER_CREDENTIALS_FULL_URI ||\n\t\t\tprocess.env.AWS_WEB_IDENTITY_TOKEN_FILE\n\t\t) {\n\t\t\treturn \"<authenticated>\";\n\t\t}\n\t}\n\n\tconst envMap: Record<string, string> = {\n\t\topenai: \"OPENAI_API_KEY\",\n\t\tgoogle: \"GEMINI_API_KEY\",\n\t\tgroq: \"GROQ_API_KEY\",\n\t\tcerebras: \"CEREBRAS_API_KEY\",\n\t\txai: \"XAI_API_KEY\",\n\t\topenrouter: \"OPENROUTER_API_KEY\",\n\t\t\"vercel-ai-gateway\": \"AI_GATEWAY_API_KEY\",\n\t\tzai: \"ZAI_API_KEY\",\n\t\tmistral: \"MISTRAL_API_KEY\",\n\t\tminimax: \"MINIMAX_API_KEY\",\n\t\t\"minimax-cn\": \"MINIMAX_CN_API_KEY\",\n\t\topencode: \"OPENCODE_API_KEY\",\n\t};\n\n\tconst envVar = envMap[provider];\n\treturn envVar ? process.env[envVar] : undefined;\n}\n\nexport function stream<TApi extends Api>(\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions?: OptionsForApi<TApi>,\n): AssistantMessageEventStream {\n\t// Vertex AI uses Application Default Credentials, not API keys\n\tif (model.api === \"google-vertex\") {\n\t\treturn streamGoogleVertex(model as Model<\"google-vertex\">, context, options as GoogleVertexOptions);\n\t} else if (model.api === \"bedrock-converse-stream\") {\n\t\t// Bedrock doesn't have any API keys instead it sources credentials from standard AWS env variables or from given AWS profile.\n\t\treturn streamBedrock(model as Model<\"bedrock-converse-stream\">, context, (options || {}) as BedrockOptions);\n\t}\n\n\tconst apiKey = options?.apiKey || getEnvApiKey(model.provider);\n\tif (!apiKey) {\n\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t}\n\tconst providerOptions = { ...options, apiKey };\n\n\tconst api: Api = model.api;\n\tswitch (api) {\n\t\tcase \"anthropic-messages\":\n\t\t\treturn streamAnthropic(model as Model<\"anthropic-messages\">, context, providerOptions);\n\n\t\tcase \"openai-completions\":\n\t\t\treturn streamOpenAICompletions(model as Model<\"openai-completions\">, context, providerOptions as any);\n\n\t\tcase \"openai-responses\":\n\t\t\treturn streamOpenAIResponses(model as Model<\"openai-responses\">, context, providerOptions as any);\n\n\t\tcase \"openai-codex-responses\":\n\t\t\treturn streamOpenAICodexResponses(model as Model<\"openai-codex-responses\">, context, providerOptions as any);\n\n\t\tcase \"google-generative-ai\":\n\t\t\treturn streamGoogle(model as Model<\"google-generative-ai\">, context, providerOptions);\n\n\t\tcase \"google-gemini-cli\":\n\t\t\treturn streamGoogleGeminiCli(\n\t\t\t\tmodel as Model<\"google-gemini-cli\">,\n\t\t\t\tcontext,\n\t\t\t\tproviderOptions as GoogleGeminiCliOptions,\n\t\t\t);\n\n\t\tdefault: {\n\t\t\t// This should never be reached if all Api cases are handled\n\t\t\tconst _exhaustive: never = api;\n\t\t\tthrow new Error(`Unhandled API: ${_exhaustive}`);\n\t\t}\n\t}\n}\n\nexport async function complete<TApi extends Api>(\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions?: OptionsForApi<TApi>,\n): Promise<AssistantMessage> {\n\tconst s = stream(model, context, options);\n\treturn s.result();\n}\n\nexport function streamSimple<TApi extends Api>(\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream {\n\t// Vertex AI uses Application Default Credentials, not API keys\n\tif (model.api === \"google-vertex\") {\n\t\tconst providerOptions = mapOptionsForApi(model, options, undefined);\n\t\treturn stream(model, context, providerOptions);\n\t} else if (model.api === \"bedrock-converse-stream\") {\n\t\t// Bedrock doesn't have any API keys instead it sources credentials from standard AWS env variables or from given AWS profile.\n\t\tconst providerOptions = mapOptionsForApi(model, options, undefined);\n\t\treturn stream(model, context, providerOptions);\n\t}\n\n\tconst apiKey = options?.apiKey || getEnvApiKey(model.provider);\n\tif (!apiKey) {\n\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t}\n\n\tconst providerOptions = mapOptionsForApi(model, options, apiKey);\n\treturn stream(model, context, providerOptions);\n}\n\nexport async function completeSimple<TApi extends Api>(\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): Promise<AssistantMessage> {\n\tconst s = streamSimple(model, context, options);\n\treturn s.result();\n}\n\nfunction mapOptionsForApi<TApi extends Api>(\n\tmodel: Model<TApi>,\n\toptions?: SimpleStreamOptions,\n\tapiKey?: string,\n): OptionsForApi<TApi> {\n\tconst base = {\n\t\ttemperature: options?.temperature,\n\t\tmaxTokens: options?.maxTokens || Math.min(model.maxTokens, 32000),\n\t\tsignal: options?.signal,\n\t\tapiKey: apiKey || options?.apiKey,\n\t\tsessionId: options?.sessionId,\n\t\theaders: options?.headers,\n\t\tonPayload: options?.onPayload,\n\t};\n\n\t// Helper to clamp xhigh to high for providers that don't support it\n\tconst clampReasoning = (effort: ThinkingLevel | undefined) => (effort === \"xhigh\" ? \"high\" : effort);\n\n\t/**\n\t * Adjust maxTokens to account for thinking budget.\n\t * APIs like Anthropic and Bedrock require max_tokens > thinking.budget_tokens.\n\t * Returns { adjustedMaxTokens, adjustedThinkingBudget }\n\t */\n\tconst adjustMaxTokensForThinking = (\n\t\tbaseMaxTokens: number,\n\t\tmodelMaxTokens: number,\n\t\treasoningLevel: ThinkingLevel,\n\t\tcustomBudgets?: ThinkingBudgets,\n\t): { maxTokens: number; thinkingBudget: number } => {\n\t\tconst defaultBudgets: ThinkingBudgets = {\n\t\t\tminimal: 1024,\n\t\t\tlow: 2048,\n\t\t\tmedium: 8192,\n\t\t\thigh: 16384,\n\t\t};\n\t\tconst budgets = { ...defaultBudgets, ...customBudgets };\n\n\t\tconst minOutputTokens = 1024;\n\t\tconst level = clampReasoning(reasoningLevel)!;\n\t\tlet thinkingBudget = budgets[level]!;\n\t\t// Caller's maxTokens is the desired output; add thinking budget on top, capped at model limit\n\t\tconst maxTokens = Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);\n\n\t\t// If not enough room for thinking + output, reduce thinking budget\n\t\tif (maxTokens <= thinkingBudget) {\n\t\t\tthinkingBudget = Math.max(0, maxTokens - minOutputTokens);\n\t\t}\n\n\t\treturn { maxTokens, thinkingBudget };\n\t};\n\n\tswitch (model.api) {\n\t\tcase \"anthropic-messages\": {\n\t\t\t// Explicitly disable thinking when reasoning is not specified\n\t\t\tif (!options?.reasoning) {\n\t\t\t\treturn { ...base, thinkingEnabled: false } satisfies AnthropicOptions;\n\t\t\t}\n\n\t\t\t// Claude requires max_tokens > thinking.budget_tokens\n\t\t\t// So we need to ensure maxTokens accounts for both thinking and output\n\t\t\tconst adjusted = adjustMaxTokensForThinking(\n\t\t\t\tbase.maxTokens || 0,\n\t\t\t\tmodel.maxTokens,\n\t\t\t\toptions.reasoning,\n\t\t\t\toptions?.thinkingBudgets,\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tmaxTokens: adjusted.maxTokens,\n\t\t\t\tthinkingEnabled: true,\n\t\t\t\tthinkingBudgetTokens: adjusted.thinkingBudget,\n\t\t\t} satisfies AnthropicOptions;\n\t\t}\n\n\t\tcase \"bedrock-converse-stream\": {\n\t\t\t// Explicitly disable thinking when reasoning is not specified\n\t\t\tif (!options?.reasoning) {\n\t\t\t\treturn { ...base, reasoning: undefined } satisfies BedrockOptions;\n\t\t\t}\n\n\t\t\t// Claude requires max_tokens > thinking.budget_tokens (same as Anthropic direct API)\n\t\t\t// So we need to ensure maxTokens accounts for both thinking and output\n\t\t\tif (model.id.includes(\"anthropic.claude\") || model.id.includes(\"anthropic/claude\")) {\n\t\t\t\tconst adjusted = adjustMaxTokensForThinking(\n\t\t\t\t\tbase.maxTokens || 0,\n\t\t\t\t\tmodel.maxTokens,\n\t\t\t\t\toptions.reasoning,\n\t\t\t\t\toptions?.thinkingBudgets,\n\t\t\t\t);\n\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\tmaxTokens: adjusted.maxTokens,\n\t\t\t\t\treasoning: options.reasoning,\n\t\t\t\t\tthinkingBudgets: {\n\t\t\t\t\t\t...(options?.thinkingBudgets || {}),\n\t\t\t\t\t\t[clampReasoning(options.reasoning)!]: adjusted.thinkingBudget,\n\t\t\t\t\t},\n\t\t\t\t} satisfies BedrockOptions;\n\t\t\t}\n\n\t\t\t// Non-Claude models - pass through\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\treasoning: options?.reasoning,\n\t\t\t\tthinkingBudgets: options?.thinkingBudgets,\n\t\t\t} satisfies BedrockOptions;\n\t\t}\n\n\t\tcase \"openai-completions\":\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\treasoningEffort: supportsXhigh(model) ? options?.reasoning : clampReasoning(options?.reasoning),\n\t\t\t} satisfies OpenAICompletionsOptions;\n\n\t\tcase \"openai-responses\":\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\treasoningEffort: supportsXhigh(model) ? options?.reasoning : clampReasoning(options?.reasoning),\n\t\t\t} satisfies OpenAIResponsesOptions;\n\n\t\tcase \"openai-codex-responses\":\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\treasoningEffort: supportsXhigh(model) ? options?.reasoning : clampReasoning(options?.reasoning),\n\t\t\t} satisfies OpenAICodexResponsesOptions;\n\n\t\tcase \"google-generative-ai\": {\n\t\t\t// Explicitly disable thinking when reasoning is not specified\n\t\t\t// This is needed because Gemini has \"dynamic thinking\" enabled by default\n\t\t\tif (!options?.reasoning) {\n\t\t\t\treturn { ...base, thinking: { enabled: false } } satisfies GoogleOptions;\n\t\t\t}\n\n\t\t\tconst googleModel = model as Model<\"google-generative-ai\">;\n\t\t\tconst effort = clampReasoning(options.reasoning)!;\n\n\t\t\t// Gemini 3 models use thinkingLevel exclusively instead of thinkingBudget.\n\t\t\t// https://ai.google.dev/gemini-api/docs/thinking#set-budget\n\t\t\tif (isGemini3ProModel(googleModel) || isGemini3FlashModel(googleModel)) {\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\tthinking: {\n\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\tlevel: getGemini3ThinkingLevel(effort, googleModel),\n\t\t\t\t\t},\n\t\t\t\t} satisfies GoogleOptions;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tthinking: {\n\t\t\t\t\tenabled: true,\n\t\t\t\t\tbudgetTokens: getGoogleBudget(googleModel, effort, options?.thinkingBudgets),\n\t\t\t\t},\n\t\t\t} satisfies GoogleOptions;\n\t\t}\n\n\t\tcase \"google-gemini-cli\": {\n\t\t\tif (!options?.reasoning) {\n\t\t\t\treturn { ...base, thinking: { enabled: false } } satisfies GoogleGeminiCliOptions;\n\t\t\t}\n\n\t\t\tconst effort = clampReasoning(options.reasoning)!;\n\n\t\t\t// Gemini 3 models use thinkingLevel instead of thinkingBudget\n\t\t\tif (model.id.includes(\"3-pro\") || model.id.includes(\"3-flash\")) {\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\tthinking: {\n\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\tlevel: getGeminiCliThinkingLevel(effort, model.id),\n\t\t\t\t\t},\n\t\t\t\t} satisfies GoogleGeminiCliOptions;\n\t\t\t}\n\n\t\t\t// Models using thinkingBudget (Gemini 2.x, Claude via Antigravity)\n\t\t\t// Claude requires max_tokens > thinking.budget_tokens\n\t\t\t// So we need to ensure maxTokens accounts for both thinking and output\n\t\t\tconst defaultBudgets: ThinkingBudgets = {\n\t\t\t\tminimal: 1024,\n\t\t\t\tlow: 2048,\n\t\t\t\tmedium: 8192,\n\t\t\t\thigh: 16384,\n\t\t\t};\n\t\t\tconst budgets = { ...defaultBudgets, ...options?.thinkingBudgets };\n\n\t\t\tconst minOutputTokens = 1024;\n\t\t\tlet thinkingBudget = budgets[effort]!;\n\t\t\t// Caller's maxTokens is the desired output; add thinking budget on top, capped at model limit\n\t\t\tconst maxTokens = Math.min((base.maxTokens || 0) + thinkingBudget, model.maxTokens);\n\n\t\t\t// If not enough room for thinking + output, reduce thinking budget\n\t\t\tif (maxTokens <= thinkingBudget) {\n\t\t\t\tthinkingBudget = Math.max(0, maxTokens - minOutputTokens);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tmaxTokens,\n\t\t\t\tthinking: {\n\t\t\t\t\tenabled: true,\n\t\t\t\t\tbudgetTokens: thinkingBudget,\n\t\t\t\t},\n\t\t\t} satisfies GoogleGeminiCliOptions;\n\t\t}\n\n\t\tcase \"google-vertex\": {\n\t\t\t// Explicitly disable thinking when reasoning is not specified\n\t\t\tif (!options?.reasoning) {\n\t\t\t\treturn { ...base, thinking: { enabled: false } } satisfies GoogleVertexOptions;\n\t\t\t}\n\n\t\t\tconst vertexModel = model as Model<\"google-vertex\">;\n\t\t\tconst effort = clampReasoning(options.reasoning)!;\n\t\t\tconst geminiModel = vertexModel as unknown as Model<\"google-generative-ai\">;\n\n\t\t\tif (isGemini3ProModel(geminiModel) || isGemini3FlashModel(geminiModel)) {\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\tthinking: {\n\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\tlevel: getGemini3ThinkingLevel(effort, geminiModel),\n\t\t\t\t\t},\n\t\t\t\t} satisfies GoogleVertexOptions;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tthinking: {\n\t\t\t\t\tenabled: true,\n\t\t\t\t\tbudgetTokens: getGoogleBudget(geminiModel, effort, options?.thinkingBudgets),\n\t\t\t\t},\n\t\t\t} satisfies GoogleVertexOptions;\n\t\t}\n\n\t\tdefault: {\n\t\t\t// Exhaustiveness check\n\t\t\tconst _exhaustive: never = model.api;\n\t\t\tthrow new Error(`Unhandled API in mapOptionsForApi: ${_exhaustive}`);\n\t\t}\n\t}\n}\n\ntype ClampedThinkingLevel = Exclude<ThinkingLevel, \"xhigh\">;\n\nfunction isGemini3ProModel(model: Model<\"google-generative-ai\">): boolean {\n\t// Covers gemini-3-pro, gemini-3-pro-preview, and possible other prefixed ids in the future\n\treturn model.id.includes(\"3-pro\");\n}\n\nfunction isGemini3FlashModel(model: Model<\"google-generative-ai\">): boolean {\n\t// Covers gemini-3-flash, gemini-3-flash-preview, and possible other prefixed ids in the future\n\treturn model.id.includes(\"3-flash\");\n}\n\nfunction getGemini3ThinkingLevel(\n\teffort: ClampedThinkingLevel,\n\tmodel: Model<\"google-generative-ai\">,\n): GoogleThinkingLevel {\n\tif (isGemini3ProModel(model)) {\n\t\t// Gemini 3 Pro only supports LOW/HIGH (for now)\n\t\tswitch (effort) {\n\t\t\tcase \"minimal\":\n\t\t\tcase \"low\":\n\t\t\t\treturn \"LOW\";\n\t\t\tcase \"medium\":\n\t\t\tcase \"high\":\n\t\t\t\treturn \"HIGH\";\n\t\t}\n\t}\n\t// Gemini 3 Flash supports all four levels\n\tswitch (effort) {\n\t\tcase \"minimal\":\n\t\t\treturn \"MINIMAL\";\n\t\tcase \"low\":\n\t\t\treturn \"LOW\";\n\t\tcase \"medium\":\n\t\t\treturn \"MEDIUM\";\n\t\tcase \"high\":\n\t\t\treturn \"HIGH\";\n\t}\n}\n\nfunction getGeminiCliThinkingLevel(effort: ClampedThinkingLevel, modelId: string): GoogleThinkingLevel {\n\tif (modelId.includes(\"3-pro\")) {\n\t\t// Gemini 3 Pro only supports LOW/HIGH (for now)\n\t\tswitch (effort) {\n\t\t\tcase \"minimal\":\n\t\t\tcase \"low\":\n\t\t\t\treturn \"LOW\";\n\t\t\tcase \"medium\":\n\t\t\tcase \"high\":\n\t\t\t\treturn \"HIGH\";\n\t\t}\n\t}\n\t// Gemini 3 Flash supports all four levels\n\tswitch (effort) {\n\t\tcase \"minimal\":\n\t\t\treturn \"MINIMAL\";\n\t\tcase \"low\":\n\t\t\treturn \"LOW\";\n\t\tcase \"medium\":\n\t\t\treturn \"MEDIUM\";\n\t\tcase \"high\":\n\t\t\treturn \"HIGH\";\n\t}\n}\n\nfunction getGoogleBudget(\n\tmodel: Model<\"google-generative-ai\">,\n\teffort: ClampedThinkingLevel,\n\tcustomBudgets?: ThinkingBudgets,\n): number {\n\t// Custom budgets take precedence if provided for this level\n\tif (customBudgets?.[effort] !== undefined) {\n\t\treturn customBudgets[effort]!;\n\t}\n\n\t// See https://ai.google.dev/gemini-api/docs/thinking#set-budget\n\tif (model.id.includes(\"2.5-pro\")) {\n\t\tconst budgets: Record<ClampedThinkingLevel, number> = {\n\t\t\tminimal: 128,\n\t\t\tlow: 2048,\n\t\t\tmedium: 8192,\n\t\t\thigh: 32768,\n\t\t};\n\t\treturn budgets[effort];\n\t}\n\n\tif (model.id.includes(\"2.5-flash\")) {\n\t\t// Covers 2.5-flash-lite as well\n\t\tconst budgets: Record<ClampedThinkingLevel, number> = {\n\t\t\tminimal: 128,\n\t\t\tlow: 2048,\n\t\t\tmedium: 8192,\n\t\t\thigh: 24576,\n\t\t};\n\t\treturn budgets[effort];\n\t}\n\n\t// Unknown model - use dynamic\n\treturn -1;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,kCAAkC,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAYnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,kFAAkF;AAClF,oCAAoC;AACpC,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC9D,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,GAAG,CAAC,CAAC;QACrD,mBAAmB,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAC;IAAA,CAC7C,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAQ,EAAE;IACrC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,uCAAuC,GAAG,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,QAAQ,CAAC;AAAA,CAChB;AAED,MAAM,UAAU,MAAM,CACrB,KAAkB,EAClB,OAAgB,EAChB,OAA+B,EACD;IAC9B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/C,OAAO,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAwB,CAAC,CAAC;AAAA,CACjE;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC7B,KAAkB,EAClB,OAAgB,EAChB,OAA+B,EACH;IAC5B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;AAAA,CAClB;AAED,MAAM,UAAU,YAAY,CAC3B,KAAkB,EAClB,OAAgB,EAChB,OAA6B,EACC;IAC9B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/C,OAAO,QAAQ,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAAA,CACtD;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,KAAkB,EAClB,OAAgB,EAChB,OAA6B,EACD;IAC5B,MAAM,CAAC,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;AAAA,CAClB","sourcesContent":["import \"./providers/register-builtins.js\";\n\nimport { getApiProvider } from \"./api-registry.js\";\nimport type {\n\tApi,\n\tAssistantMessage,\n\tAssistantMessageEventStream,\n\tContext,\n\tModel,\n\tProviderStreamOptions,\n\tSimpleStreamOptions,\n\tStreamOptions,\n} from \"./types.js\";\n\nexport { getEnvApiKey } from \"./env-api-keys.js\";\n\n// Set up http proxy according to env variables for `fetch` based SDKs in Node.js.\n// Bun has builtin support for this.\nif (typeof process !== \"undefined\" && process.versions?.node) {\n\timport(\"undici\").then((m) => {\n\t\tconst { EnvHttpProxyAgent, setGlobalDispatcher } = m;\n\t\tsetGlobalDispatcher(new EnvHttpProxyAgent());\n\t});\n}\n\nfunction resolveApiProvider(api: Api) {\n\tconst provider = getApiProvider(api);\n\tif (!provider) {\n\t\tthrow new Error(`No API provider registered for api: ${api}`);\n\t}\n\treturn provider;\n}\n\nexport function stream<TApi extends Api>(\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions?: ProviderStreamOptions,\n): AssistantMessageEventStream {\n\tconst provider = resolveApiProvider(model.api);\n\treturn provider.stream(model, context, options as StreamOptions);\n}\n\nexport async function complete<TApi extends Api>(\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions?: ProviderStreamOptions,\n): Promise<AssistantMessage> {\n\tconst s = stream(model, context, options);\n\treturn s.result();\n}\n\nexport function streamSimple<TApi extends Api>(\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream {\n\tconst provider = resolveApiProvider(model.api);\n\treturn provider.streamSimple(model, context, options);\n}\n\nexport async function completeSimple<TApi extends Api>(\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): Promise<AssistantMessage> {\n\tconst s = streamSimple(model, context, options);\n\treturn s.result();\n}\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,26 +1,8 @@
|
|
|
1
|
-
import type { BedrockOptions } from "./providers/amazon-bedrock.js";
|
|
2
|
-
import type { AnthropicOptions } from "./providers/anthropic.js";
|
|
3
|
-
import type { GoogleOptions } from "./providers/google.js";
|
|
4
|
-
import type { GoogleGeminiCliOptions } from "./providers/google-gemini-cli.js";
|
|
5
|
-
import type { GoogleVertexOptions } from "./providers/google-vertex.js";
|
|
6
|
-
import type { OpenAICodexResponsesOptions } from "./providers/openai-codex-responses.js";
|
|
7
|
-
import type { OpenAICompletionsOptions } from "./providers/openai-completions.js";
|
|
8
|
-
import type { OpenAIResponsesOptions } from "./providers/openai-responses.js";
|
|
9
1
|
import type { AssistantMessageEventStream } from "./utils/event-stream.js";
|
|
10
2
|
export type { AssistantMessageEventStream } from "./utils/event-stream.js";
|
|
11
|
-
export type
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
"bedrock-converse-stream": BedrockOptions;
|
|
15
|
-
"openai-completions": OpenAICompletionsOptions;
|
|
16
|
-
"openai-responses": OpenAIResponsesOptions;
|
|
17
|
-
"openai-codex-responses": OpenAICodexResponsesOptions;
|
|
18
|
-
"google-generative-ai": GoogleOptions;
|
|
19
|
-
"google-gemini-cli": GoogleGeminiCliOptions;
|
|
20
|
-
"google-vertex": GoogleVertexOptions;
|
|
21
|
-
}
|
|
22
|
-
export type OptionsForApi<TApi extends Api> = ApiOptionsMap[TApi];
|
|
23
|
-
export type KnownProvider = "amazon-bedrock" | "anthropic" | "google" | "google-gemini-cli" | "google-antigravity" | "google-vertex" | "openai" | "openai-codex" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "opencode";
|
|
3
|
+
export type KnownApi = "openai-completions" | "openai-responses" | "azure-openai-responses" | "openai-codex-responses" | "anthropic-messages" | "bedrock-converse-stream" | "google-generative-ai" | "google-gemini-cli" | "google-vertex";
|
|
4
|
+
export type Api = KnownApi | (string & {});
|
|
5
|
+
export type KnownProvider = "amazon-bedrock" | "anthropic" | "google" | "google-gemini-cli" | "google-antigravity" | "google-vertex" | "openai" | "azure-openai-responses" | "openai-codex" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "mistral" | "minimax" | "minimax-cn" | "opencode";
|
|
24
6
|
export type Provider = KnownProvider | string;
|
|
25
7
|
export type ThinkingLevel = "minimal" | "low" | "medium" | "high" | "xhigh";
|
|
26
8
|
/** Token budgets for each thinking level (token-based providers only) */
|
|
@@ -52,12 +34,13 @@ export interface StreamOptions {
|
|
|
52
34
|
*/
|
|
53
35
|
headers?: Record<string, string>;
|
|
54
36
|
}
|
|
37
|
+
export type ProviderStreamOptions = StreamOptions & Record<string, unknown>;
|
|
55
38
|
export interface SimpleStreamOptions extends StreamOptions {
|
|
56
39
|
reasoning?: ThinkingLevel;
|
|
57
40
|
/** Custom token budgets for thinking levels (token-based providers only) */
|
|
58
41
|
thinkingBudgets?: ThinkingBudgets;
|
|
59
42
|
}
|
|
60
|
-
export type StreamFunction<TApi extends Api> = (model: Model<TApi>, context: Context, options
|
|
43
|
+
export type StreamFunction<TApi extends Api = Api, TOptions extends StreamOptions = StreamOptions> = (model: Model<TApi>, context: Context, options?: TOptions) => AssistantMessageEventStream;
|
|
61
44
|
export interface TextContent {
|
|
62
45
|
type: "text";
|
|
63
46
|
text: string;
|
|
@@ -211,10 +194,23 @@ export interface OpenAICompletionsCompat {
|
|
|
211
194
|
requiresMistralToolIds?: boolean;
|
|
212
195
|
/** Format for reasoning/thinking parameter. "openai" uses reasoning_effort, "zai" uses thinking: { type: "enabled" }. Default: "openai". */
|
|
213
196
|
thinkingFormat?: "openai" | "zai";
|
|
197
|
+
/** OpenRouter-specific routing preferences. Only used when baseUrl points to OpenRouter. */
|
|
198
|
+
openRouterRouting?: OpenRouterRouting;
|
|
214
199
|
}
|
|
215
200
|
/** Compatibility settings for OpenAI Responses APIs. */
|
|
216
201
|
export interface OpenAIResponsesCompat {
|
|
217
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* OpenRouter provider routing preferences.
|
|
205
|
+
* Controls which upstream providers OpenRouter routes requests to.
|
|
206
|
+
* @see https://openrouter.ai/docs/provider-routing
|
|
207
|
+
*/
|
|
208
|
+
export interface OpenRouterRouting {
|
|
209
|
+
/** List of provider slugs to exclusively use for this request (e.g., ["amazon-bedrock", "anthropic"]). */
|
|
210
|
+
only?: string[];
|
|
211
|
+
/** List of provider slugs to try in order (e.g., ["anthropic", "openai"]). */
|
|
212
|
+
order?: string[];
|
|
213
|
+
}
|
|
218
214
|
export interface Model<TApi extends Api> {
|
|
219
215
|
id: string;
|
|
220
216
|
name: string;
|