@levelcode/sdk 0.0.1 → 0.0.3
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/index.cjs +1644 -186
- package/dist/index.cjs.map +26 -13
- package/dist/index.mjs +1644 -186
- package/dist/index.mjs.map +26 -13
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -13093,15 +13093,15 @@ import path17 from "path";
|
|
|
13093
13093
|
// ../common/src/env-schema.ts
|
|
13094
13094
|
import z from "zod/v4";
|
|
13095
13095
|
var clientEnvSchema = z.object({
|
|
13096
|
-
NEXT_PUBLIC_CB_ENVIRONMENT: z.enum(["dev", "test", "prod"]),
|
|
13097
|
-
NEXT_PUBLIC_LEVELCODE_APP_URL: z.
|
|
13098
|
-
NEXT_PUBLIC_SUPPORT_EMAIL: z.
|
|
13099
|
-
NEXT_PUBLIC_POSTHOG_API_KEY: z.string().
|
|
13100
|
-
NEXT_PUBLIC_POSTHOG_HOST_URL: z.
|
|
13101
|
-
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: z.string().
|
|
13102
|
-
NEXT_PUBLIC_STRIPE_CUSTOMER_PORTAL: z.
|
|
13096
|
+
NEXT_PUBLIC_CB_ENVIRONMENT: z.enum(["dev", "test", "prod"]).default("prod"),
|
|
13097
|
+
NEXT_PUBLIC_LEVELCODE_APP_URL: z.string().default(""),
|
|
13098
|
+
NEXT_PUBLIC_SUPPORT_EMAIL: z.string().default("support@levelcode.ai"),
|
|
13099
|
+
NEXT_PUBLIC_POSTHOG_API_KEY: z.string().default(""),
|
|
13100
|
+
NEXT_PUBLIC_POSTHOG_HOST_URL: z.string().default("https://app.posthog.com"),
|
|
13101
|
+
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: z.string().default(""),
|
|
13102
|
+
NEXT_PUBLIC_STRIPE_CUSTOMER_PORTAL: z.string().default("https://billing.stripe.com"),
|
|
13103
13103
|
NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION_ID: z.string().optional(),
|
|
13104
|
-
NEXT_PUBLIC_WEB_PORT: z.coerce.number().
|
|
13104
|
+
NEXT_PUBLIC_WEB_PORT: z.coerce.number().default(3000)
|
|
13105
13105
|
});
|
|
13106
13106
|
var clientEnvVars = clientEnvSchema.keyof().options;
|
|
13107
13107
|
var clientProcessEnv = {
|
|
@@ -13118,10 +13118,18 @@ var clientProcessEnv = {
|
|
|
13118
13118
|
|
|
13119
13119
|
// ../common/src/env.ts
|
|
13120
13120
|
var parsedEnv = clientEnvSchema.safeParse(clientProcessEnv);
|
|
13121
|
-
|
|
13122
|
-
|
|
13123
|
-
|
|
13124
|
-
|
|
13121
|
+
var fallbackEnv = {
|
|
13122
|
+
NEXT_PUBLIC_CB_ENVIRONMENT: "prod",
|
|
13123
|
+
NEXT_PUBLIC_LEVELCODE_APP_URL: "",
|
|
13124
|
+
NEXT_PUBLIC_SUPPORT_EMAIL: "support@levelcode.ai",
|
|
13125
|
+
NEXT_PUBLIC_POSTHOG_API_KEY: "",
|
|
13126
|
+
NEXT_PUBLIC_POSTHOG_HOST_URL: "https://app.posthog.com",
|
|
13127
|
+
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: "",
|
|
13128
|
+
NEXT_PUBLIC_STRIPE_CUSTOMER_PORTAL: "https://billing.stripe.com",
|
|
13129
|
+
NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION_ID: undefined,
|
|
13130
|
+
NEXT_PUBLIC_WEB_PORT: 3000
|
|
13131
|
+
};
|
|
13132
|
+
var env = parsedEnv.success ? parsedEnv.data : fallbackEnv;
|
|
13125
13133
|
if (env.NEXT_PUBLIC_CB_ENVIRONMENT !== "prod") {
|
|
13126
13134
|
console.log("Using environment:", env.NEXT_PUBLIC_CB_ENVIRONMENT);
|
|
13127
13135
|
}
|
|
@@ -35154,7 +35162,152 @@ import z66 from "zod/v4";
|
|
|
35154
35162
|
|
|
35155
35163
|
// src/constants.ts
|
|
35156
35164
|
var LEVELCODE_BINARY = "levelcode";
|
|
35157
|
-
var WEBSITE_URL = env.NEXT_PUBLIC_LEVELCODE_APP_URL;
|
|
35165
|
+
var WEBSITE_URL = env.NEXT_PUBLIC_LEVELCODE_APP_URL || "";
|
|
35166
|
+
|
|
35167
|
+
// ../common/src/constants/byok.ts
|
|
35168
|
+
var BYOK_OPENROUTER_HEADER = "x-openrouter-api-key";
|
|
35169
|
+
var BYOK_OPENROUTER_ENV_VAR = "LEVELCODE_BYOK_OPENROUTER";
|
|
35170
|
+
|
|
35171
|
+
// ../common/src/constants/claude-oauth.ts
|
|
35172
|
+
var CLAUDE_OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
35173
|
+
var CLAUDE_OAUTH_TOKEN_ENV_VAR = "LEVELCODE_CLAUDE_OAUTH_TOKEN";
|
|
35174
|
+
var CLAUDE_OAUTH_BETA_HEADERS = [
|
|
35175
|
+
"oauth-2025-04-20",
|
|
35176
|
+
"claude-code-20250219",
|
|
35177
|
+
"interleaved-thinking-2025-05-14",
|
|
35178
|
+
"fine-grained-tool-streaming-2025-05-14"
|
|
35179
|
+
];
|
|
35180
|
+
var CLAUDE_CODE_SYSTEM_PROMPT_PREFIX = "You are Claude Code, Anthropic's official CLI for Claude.";
|
|
35181
|
+
var OPENROUTER_TO_ANTHROPIC_MODEL_MAP = {
|
|
35182
|
+
"anthropic/claude-3.5-haiku-20241022": "claude-3-5-haiku-20241022",
|
|
35183
|
+
"anthropic/claude-3.5-haiku": "claude-3-5-haiku-20241022",
|
|
35184
|
+
"anthropic/claude-3-5-haiku": "claude-3-5-haiku-20241022",
|
|
35185
|
+
"anthropic/claude-3-5-haiku-20241022": "claude-3-5-haiku-20241022",
|
|
35186
|
+
"anthropic/claude-3-haiku": "claude-3-haiku-20240307",
|
|
35187
|
+
"anthropic/claude-3.5-sonnet": "claude-3-5-sonnet-20241022",
|
|
35188
|
+
"anthropic/claude-3-5-sonnet": "claude-3-5-sonnet-20241022",
|
|
35189
|
+
"anthropic/claude-3-5-sonnet-20241022": "claude-3-5-sonnet-20241022",
|
|
35190
|
+
"anthropic/claude-3-5-sonnet-20240620": "claude-3-5-sonnet-20240620",
|
|
35191
|
+
"anthropic/claude-3-sonnet": "claude-3-sonnet-20240229",
|
|
35192
|
+
"anthropic/claude-3-opus": "claude-3-opus-20240229",
|
|
35193
|
+
"anthropic/claude-3-opus-20240229": "claude-3-opus-20240229",
|
|
35194
|
+
"anthropic/claude-haiku-4.5": "claude-haiku-4-5-20251001",
|
|
35195
|
+
"anthropic/claude-haiku-4": "claude-haiku-4-20250514",
|
|
35196
|
+
"anthropic/claude-sonnet-4.5": "claude-sonnet-4-5-20250929",
|
|
35197
|
+
"anthropic/claude-sonnet-4": "claude-sonnet-4-20250514",
|
|
35198
|
+
"anthropic/claude-4-sonnet-20250522": "claude-sonnet-4-20250514",
|
|
35199
|
+
"anthropic/claude-4-sonnet": "claude-sonnet-4-20250514",
|
|
35200
|
+
"anthropic/claude-opus-4.5": "claude-opus-4-5-20251101",
|
|
35201
|
+
"anthropic/claude-opus-4.1": "claude-opus-4-1-20250805",
|
|
35202
|
+
"anthropic/claude-opus-4": "claude-opus-4-1-20250805"
|
|
35203
|
+
};
|
|
35204
|
+
function isClaudeModel(model) {
|
|
35205
|
+
return model.startsWith("anthropic/") || model.startsWith("claude-");
|
|
35206
|
+
}
|
|
35207
|
+
function toAnthropicModelId(openrouterModel) {
|
|
35208
|
+
if (!openrouterModel.includes("/")) {
|
|
35209
|
+
return openrouterModel;
|
|
35210
|
+
}
|
|
35211
|
+
if (!openrouterModel.startsWith("anthropic/")) {
|
|
35212
|
+
throw new Error(`Cannot convert non-Anthropic model to Anthropic model ID: ${openrouterModel}`);
|
|
35213
|
+
}
|
|
35214
|
+
const mapped = OPENROUTER_TO_ANTHROPIC_MODEL_MAP[openrouterModel];
|
|
35215
|
+
if (mapped) {
|
|
35216
|
+
return mapped;
|
|
35217
|
+
}
|
|
35218
|
+
return openrouterModel.replace("anthropic/", "");
|
|
35219
|
+
}
|
|
35220
|
+
|
|
35221
|
+
// src/env.ts
|
|
35222
|
+
init_paths();
|
|
35223
|
+
|
|
35224
|
+
// ../common/src/env-process.ts
|
|
35225
|
+
var getBaseEnv = () => ({
|
|
35226
|
+
SHELL: process.env.SHELL,
|
|
35227
|
+
COMSPEC: process.env.COMSPEC,
|
|
35228
|
+
HOME: process.env.HOME,
|
|
35229
|
+
USERPROFILE: process.env.USERPROFILE,
|
|
35230
|
+
APPDATA: process.env.APPDATA,
|
|
35231
|
+
XDG_CONFIG_HOME: process.env.XDG_CONFIG_HOME,
|
|
35232
|
+
TERM: process.env.TERM,
|
|
35233
|
+
TERM_PROGRAM: process.env.TERM_PROGRAM,
|
|
35234
|
+
TERM_BACKGROUND: process.env.TERM_BACKGROUND,
|
|
35235
|
+
TERMINAL_EMULATOR: process.env.TERMINAL_EMULATOR,
|
|
35236
|
+
COLORFGBG: process.env.COLORFGBG,
|
|
35237
|
+
NODE_ENV: "development",
|
|
35238
|
+
NODE_PATH: process.env.NODE_PATH,
|
|
35239
|
+
PATH: process.env.PATH
|
|
35240
|
+
});
|
|
35241
|
+
var getProcessEnv = () => ({
|
|
35242
|
+
...getBaseEnv(),
|
|
35243
|
+
KITTY_WINDOW_ID: process.env.KITTY_WINDOW_ID,
|
|
35244
|
+
SIXEL_SUPPORT: process.env.SIXEL_SUPPORT,
|
|
35245
|
+
ZED_NODE_ENV: process.env.ZED_NODE_ENV,
|
|
35246
|
+
VSCODE_THEME_KIND: process.env.VSCODE_THEME_KIND,
|
|
35247
|
+
VSCODE_COLOR_THEME_KIND: process.env.VSCODE_COLOR_THEME_KIND,
|
|
35248
|
+
VSCODE_GIT_IPC_HANDLE: process.env.VSCODE_GIT_IPC_HANDLE,
|
|
35249
|
+
VSCODE_PID: process.env.VSCODE_PID,
|
|
35250
|
+
VSCODE_CWD: process.env.VSCODE_CWD,
|
|
35251
|
+
VSCODE_NLS_CONFIG: process.env.VSCODE_NLS_CONFIG,
|
|
35252
|
+
CURSOR_PORT: process.env.CURSOR_PORT,
|
|
35253
|
+
CURSOR: process.env.CURSOR,
|
|
35254
|
+
JETBRAINS_REMOTE_RUN: process.env.JETBRAINS_REMOTE_RUN,
|
|
35255
|
+
IDEA_INITIAL_DIRECTORY: process.env.IDEA_INITIAL_DIRECTORY,
|
|
35256
|
+
IDE_CONFIG_DIR: process.env.IDE_CONFIG_DIR,
|
|
35257
|
+
JB_IDE_CONFIG_DIR: process.env.JB_IDE_CONFIG_DIR,
|
|
35258
|
+
VISUAL: process.env.VISUAL,
|
|
35259
|
+
EDITOR: process.env.EDITOR,
|
|
35260
|
+
LEVELCODE_CLI_EDITOR: process.env.LEVELCODE_CLI_EDITOR,
|
|
35261
|
+
LEVELCODE_EDITOR: process.env.LEVELCODE_EDITOR,
|
|
35262
|
+
OPEN_TUI_THEME: process.env.OPEN_TUI_THEME,
|
|
35263
|
+
OPENTUI_THEME: process.env.OPENTUI_THEME,
|
|
35264
|
+
LEVELCODE_IS_BINARY: process.env.LEVELCODE_IS_BINARY,
|
|
35265
|
+
LEVELCODE_CLI_VERSION: process.env.LEVELCODE_CLI_VERSION,
|
|
35266
|
+
LEVELCODE_CLI_TARGET: process.env.LEVELCODE_CLI_TARGET,
|
|
35267
|
+
LEVELCODE_RG_PATH: process.env.LEVELCODE_RG_PATH,
|
|
35268
|
+
LEVELCODE_WASM_DIR: process.env.LEVELCODE_WASM_DIR,
|
|
35269
|
+
VERBOSE: process.env.VERBOSE,
|
|
35270
|
+
OVERRIDE_TARGET: process.env.OVERRIDE_TARGET,
|
|
35271
|
+
OVERRIDE_PLATFORM: process.env.OVERRIDE_PLATFORM,
|
|
35272
|
+
OVERRIDE_ARCH: process.env.OVERRIDE_ARCH
|
|
35273
|
+
});
|
|
35274
|
+
var processEnv = getProcessEnv();
|
|
35275
|
+
|
|
35276
|
+
// src/env.ts
|
|
35277
|
+
var getSdkEnv = () => ({
|
|
35278
|
+
...getBaseEnv(),
|
|
35279
|
+
LEVELCODE_RG_PATH: process.env.LEVELCODE_RG_PATH,
|
|
35280
|
+
LEVELCODE_WASM_DIR: process.env.LEVELCODE_WASM_DIR,
|
|
35281
|
+
VERBOSE: process.env.VERBOSE,
|
|
35282
|
+
OVERRIDE_TARGET: process.env.OVERRIDE_TARGET,
|
|
35283
|
+
OVERRIDE_PLATFORM: process.env.OVERRIDE_PLATFORM,
|
|
35284
|
+
OVERRIDE_ARCH: process.env.OVERRIDE_ARCH
|
|
35285
|
+
});
|
|
35286
|
+
var getLevelCodeApiKeyFromEnv = () => {
|
|
35287
|
+
return process.env[API_KEY_ENV_VAR];
|
|
35288
|
+
};
|
|
35289
|
+
var getSystemProcessEnv = () => {
|
|
35290
|
+
return process.env;
|
|
35291
|
+
};
|
|
35292
|
+
var getByokOpenrouterApiKeyFromEnv = () => {
|
|
35293
|
+
return process.env[BYOK_OPENROUTER_ENV_VAR];
|
|
35294
|
+
};
|
|
35295
|
+
var getClaudeOAuthTokenFromEnv = () => {
|
|
35296
|
+
return process.env[CLAUDE_OAUTH_TOKEN_ENV_VAR];
|
|
35297
|
+
};
|
|
35298
|
+
var getOpenRouterApiKeyFromEnv = () => {
|
|
35299
|
+
return process.env.OPENROUTER_API_KEY;
|
|
35300
|
+
};
|
|
35301
|
+
var getAnthropicApiKeyFromEnv = () => {
|
|
35302
|
+
return process.env.ANTHROPIC_API_KEY;
|
|
35303
|
+
};
|
|
35304
|
+
var isStandaloneMode = () => {
|
|
35305
|
+
const appUrl = process.env.NEXT_PUBLIC_LEVELCODE_APP_URL;
|
|
35306
|
+
if (!appUrl)
|
|
35307
|
+
return true;
|
|
35308
|
+
const hasDirectKey = !!getOpenRouterApiKeyFromEnv() || !!getAnthropicApiKeyFromEnv();
|
|
35309
|
+
return hasDirectKey && !getLevelCodeApiKeyFromEnv();
|
|
35310
|
+
};
|
|
35158
35311
|
|
|
35159
35312
|
// src/retry-config.ts
|
|
35160
35313
|
var MAX_RETRIES_PER_MESSAGE = 3;
|
|
@@ -35197,6 +35350,10 @@ async function fetchWithRetry(url, options, logger2) {
|
|
|
35197
35350
|
throw lastError ?? new Error("Request failed after retries");
|
|
35198
35351
|
}
|
|
35199
35352
|
async function getUserInfoFromApiKey(params2) {
|
|
35353
|
+
if (isStandaloneMode()) {
|
|
35354
|
+
const standaloneUser = { id: "standalone-user", email: "standalone@local" };
|
|
35355
|
+
return Object.fromEntries(params2.fields.map((field) => [field, standaloneUser[field] ?? null]));
|
|
35356
|
+
}
|
|
35200
35357
|
const { apiKey, fields, logger: logger2 } = params2;
|
|
35201
35358
|
const cached = userInfoCache[apiKey];
|
|
35202
35359
|
if (cached === null) {
|
|
@@ -35259,6 +35416,9 @@ async function getUserInfoFromApiKey(params2) {
|
|
|
35259
35416
|
return Object.fromEntries(fields.map((field) => [field, userInfo[field]]));
|
|
35260
35417
|
}
|
|
35261
35418
|
async function fetchAgentFromDatabase(params2) {
|
|
35419
|
+
if (isStandaloneMode()) {
|
|
35420
|
+
return null;
|
|
35421
|
+
}
|
|
35262
35422
|
const { apiKey, parsedAgentId, logger: logger2 } = params2;
|
|
35263
35423
|
const { publisherId, agentId, version: version2 } = parsedAgentId;
|
|
35264
35424
|
const url = new URL(`/api/v1/agents/${publisherId}/${agentId}/${version2 ? version2 : "latest"}`, WEBSITE_URL);
|
|
@@ -35312,6 +35472,9 @@ async function fetchAgentFromDatabase(params2) {
|
|
|
35312
35472
|
}
|
|
35313
35473
|
}
|
|
35314
35474
|
async function startAgentRun(params2) {
|
|
35475
|
+
if (isStandaloneMode()) {
|
|
35476
|
+
return crypto.randomUUID();
|
|
35477
|
+
}
|
|
35315
35478
|
const { apiKey, agentId, ancestorRunIds, logger: logger2 } = params2;
|
|
35316
35479
|
const url = new URL(`/api/v1/agent-runs`, WEBSITE_URL);
|
|
35317
35480
|
try {
|
|
@@ -35341,6 +35504,9 @@ async function startAgentRun(params2) {
|
|
|
35341
35504
|
}
|
|
35342
35505
|
}
|
|
35343
35506
|
async function finishAgentRun(params2) {
|
|
35507
|
+
if (isStandaloneMode()) {
|
|
35508
|
+
return;
|
|
35509
|
+
}
|
|
35344
35510
|
const {
|
|
35345
35511
|
apiKey,
|
|
35346
35512
|
runId,
|
|
@@ -35375,6 +35541,9 @@ async function finishAgentRun(params2) {
|
|
|
35375
35541
|
}
|
|
35376
35542
|
}
|
|
35377
35543
|
async function addAgentStep2(params2) {
|
|
35544
|
+
if (isStandaloneMode()) {
|
|
35545
|
+
return crypto.randomUUID();
|
|
35546
|
+
}
|
|
35378
35547
|
const {
|
|
35379
35548
|
apiKey,
|
|
35380
35549
|
agentRunId,
|
|
@@ -35496,60 +35665,6 @@ import {
|
|
|
35496
35665
|
import path5 from "path";
|
|
35497
35666
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
35498
35667
|
|
|
35499
|
-
// ../common/src/constants/byok.ts
|
|
35500
|
-
var BYOK_OPENROUTER_HEADER = "x-openrouter-api-key";
|
|
35501
|
-
var BYOK_OPENROUTER_ENV_VAR = "LEVELCODE_BYOK_OPENROUTER";
|
|
35502
|
-
|
|
35503
|
-
// ../common/src/constants/claude-oauth.ts
|
|
35504
|
-
var CLAUDE_OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
35505
|
-
var CLAUDE_OAUTH_TOKEN_ENV_VAR = "LEVELCODE_CLAUDE_OAUTH_TOKEN";
|
|
35506
|
-
var CLAUDE_OAUTH_BETA_HEADERS = [
|
|
35507
|
-
"oauth-2025-04-20",
|
|
35508
|
-
"claude-code-20250219",
|
|
35509
|
-
"interleaved-thinking-2025-05-14",
|
|
35510
|
-
"fine-grained-tool-streaming-2025-05-14"
|
|
35511
|
-
];
|
|
35512
|
-
var CLAUDE_CODE_SYSTEM_PROMPT_PREFIX = "You are Claude Code, Anthropic's official CLI for Claude.";
|
|
35513
|
-
var OPENROUTER_TO_ANTHROPIC_MODEL_MAP = {
|
|
35514
|
-
"anthropic/claude-3.5-haiku-20241022": "claude-3-5-haiku-20241022",
|
|
35515
|
-
"anthropic/claude-3.5-haiku": "claude-3-5-haiku-20241022",
|
|
35516
|
-
"anthropic/claude-3-5-haiku": "claude-3-5-haiku-20241022",
|
|
35517
|
-
"anthropic/claude-3-5-haiku-20241022": "claude-3-5-haiku-20241022",
|
|
35518
|
-
"anthropic/claude-3-haiku": "claude-3-haiku-20240307",
|
|
35519
|
-
"anthropic/claude-3.5-sonnet": "claude-3-5-sonnet-20241022",
|
|
35520
|
-
"anthropic/claude-3-5-sonnet": "claude-3-5-sonnet-20241022",
|
|
35521
|
-
"anthropic/claude-3-5-sonnet-20241022": "claude-3-5-sonnet-20241022",
|
|
35522
|
-
"anthropic/claude-3-5-sonnet-20240620": "claude-3-5-sonnet-20240620",
|
|
35523
|
-
"anthropic/claude-3-sonnet": "claude-3-sonnet-20240229",
|
|
35524
|
-
"anthropic/claude-3-opus": "claude-3-opus-20240229",
|
|
35525
|
-
"anthropic/claude-3-opus-20240229": "claude-3-opus-20240229",
|
|
35526
|
-
"anthropic/claude-haiku-4.5": "claude-haiku-4-5-20251001",
|
|
35527
|
-
"anthropic/claude-haiku-4": "claude-haiku-4-20250514",
|
|
35528
|
-
"anthropic/claude-sonnet-4.5": "claude-sonnet-4-5-20250929",
|
|
35529
|
-
"anthropic/claude-sonnet-4": "claude-sonnet-4-20250514",
|
|
35530
|
-
"anthropic/claude-4-sonnet-20250522": "claude-sonnet-4-20250514",
|
|
35531
|
-
"anthropic/claude-4-sonnet": "claude-sonnet-4-20250514",
|
|
35532
|
-
"anthropic/claude-opus-4.5": "claude-opus-4-5-20251101",
|
|
35533
|
-
"anthropic/claude-opus-4.1": "claude-opus-4-1-20250805",
|
|
35534
|
-
"anthropic/claude-opus-4": "claude-opus-4-1-20250805"
|
|
35535
|
-
};
|
|
35536
|
-
function isClaudeModel(model) {
|
|
35537
|
-
return model.startsWith("anthropic/") || model.startsWith("claude-");
|
|
35538
|
-
}
|
|
35539
|
-
function toAnthropicModelId(openrouterModel) {
|
|
35540
|
-
if (!openrouterModel.includes("/")) {
|
|
35541
|
-
return openrouterModel;
|
|
35542
|
-
}
|
|
35543
|
-
if (!openrouterModel.startsWith("anthropic/")) {
|
|
35544
|
-
throw new Error(`Cannot convert non-Anthropic model to Anthropic model ID: ${openrouterModel}`);
|
|
35545
|
-
}
|
|
35546
|
-
const mapped = OPENROUTER_TO_ANTHROPIC_MODEL_MAP[openrouterModel];
|
|
35547
|
-
if (mapped) {
|
|
35548
|
-
return mapped;
|
|
35549
|
-
}
|
|
35550
|
-
return openrouterModel.replace("anthropic/", "");
|
|
35551
|
-
}
|
|
35552
|
-
|
|
35553
35668
|
// ../node_modules/@ai-sdk/provider/dist/index.mjs
|
|
35554
35669
|
var marker = "vercel.ai.error";
|
|
35555
35670
|
var symbol = Symbol.for(marker);
|
|
@@ -35950,6 +36065,38 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
|
|
|
35950
36065
|
return Object.fromEntries(normalizedHeaders.entries());
|
|
35951
36066
|
}
|
|
35952
36067
|
var VERSION = "3.0.20";
|
|
36068
|
+
function loadApiKey({
|
|
36069
|
+
apiKey,
|
|
36070
|
+
environmentVariableName,
|
|
36071
|
+
apiKeyParameterName = "apiKey",
|
|
36072
|
+
description: description31
|
|
36073
|
+
}) {
|
|
36074
|
+
if (typeof apiKey === "string") {
|
|
36075
|
+
return apiKey;
|
|
36076
|
+
}
|
|
36077
|
+
if (apiKey != null) {
|
|
36078
|
+
throw new LoadAPIKeyError({
|
|
36079
|
+
message: `${description31} API key must be a string.`
|
|
36080
|
+
});
|
|
36081
|
+
}
|
|
36082
|
+
if (typeof process === "undefined") {
|
|
36083
|
+
throw new LoadAPIKeyError({
|
|
36084
|
+
message: `${description31} API key is missing. Pass it using the '${apiKeyParameterName}' parameter. Environment variables is not supported in this environment.`
|
|
36085
|
+
});
|
|
36086
|
+
}
|
|
36087
|
+
apiKey = process.env[environmentVariableName];
|
|
36088
|
+
if (apiKey == null) {
|
|
36089
|
+
throw new LoadAPIKeyError({
|
|
36090
|
+
message: `${description31} API key is missing. Pass it using the '${apiKeyParameterName}' parameter or the ${environmentVariableName} environment variable.`
|
|
36091
|
+
});
|
|
36092
|
+
}
|
|
36093
|
+
if (typeof apiKey !== "string") {
|
|
36094
|
+
throw new LoadAPIKeyError({
|
|
36095
|
+
message: `${description31} API key must be a string. The value of the ${environmentVariableName} environment variable is not a string.`
|
|
36096
|
+
});
|
|
36097
|
+
}
|
|
36098
|
+
return apiKey;
|
|
36099
|
+
}
|
|
35953
36100
|
var suspectProtoRx = /"__proto__"\s*:/;
|
|
35954
36101
|
var suspectConstructorRx = /"constructor"\s*:/;
|
|
35955
36102
|
function _parse(text) {
|
|
@@ -36326,6 +36473,9 @@ function convertUint8ArrayToBase64(array) {
|
|
|
36326
36473
|
function convertToBase64(value) {
|
|
36327
36474
|
return value instanceof Uint8Array ? convertUint8ArrayToBase64(value) : value;
|
|
36328
36475
|
}
|
|
36476
|
+
function withoutTrailingSlash(url) {
|
|
36477
|
+
return url == null ? undefined : url.replace(/\/$/, "");
|
|
36478
|
+
}
|
|
36329
36479
|
|
|
36330
36480
|
// ../packages/internal/src/openai-compatible/chat/openai-compatible-chat-language-model.ts
|
|
36331
36481
|
import { z as z69 } from "zod/v4";
|
|
@@ -37034,111 +37184,1395 @@ var createOpenAICompatibleChatChunkSchema = (errorSchema) => z69.union([
|
|
|
37034
37184
|
]);
|
|
37035
37185
|
// ../packages/internal/src/openai-compatible/version.ts
|
|
37036
37186
|
var VERSION2 = typeof __PACKAGE_VERSION__ !== "undefined" ? __PACKAGE_VERSION__ : "0.0.0-test";
|
|
37037
|
-
// src/
|
|
37038
|
-
|
|
37039
|
-
|
|
37040
|
-
|
|
37187
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/is-url.ts
|
|
37188
|
+
function isUrl({
|
|
37189
|
+
url,
|
|
37190
|
+
protocols
|
|
37191
|
+
}) {
|
|
37192
|
+
try {
|
|
37193
|
+
const urlObj = new URL(url);
|
|
37194
|
+
return protocols.has(urlObj.protocol);
|
|
37195
|
+
} catch (_) {
|
|
37196
|
+
return false;
|
|
37197
|
+
}
|
|
37198
|
+
}
|
|
37041
37199
|
|
|
37042
|
-
// ../
|
|
37200
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/file-url-utils.ts
|
|
37201
|
+
function getFileUrl({
|
|
37202
|
+
part,
|
|
37203
|
+
defaultMediaType
|
|
37204
|
+
}) {
|
|
37205
|
+
if (part.data instanceof Uint8Array) {
|
|
37206
|
+
const base64 = convertUint8ArrayToBase64(part.data);
|
|
37207
|
+
return `data:${part.mediaType ?? defaultMediaType};base64,${base64}`;
|
|
37208
|
+
}
|
|
37209
|
+
const stringUrl = part.data.toString();
|
|
37210
|
+
if (isUrl({
|
|
37211
|
+
url: stringUrl,
|
|
37212
|
+
protocols: new Set(["http:", "https:"])
|
|
37213
|
+
})) {
|
|
37214
|
+
return stringUrl;
|
|
37215
|
+
}
|
|
37216
|
+
return stringUrl.startsWith("data:") ? stringUrl : `data:${part.mediaType ?? defaultMediaType};base64,${stringUrl}`;
|
|
37217
|
+
}
|
|
37218
|
+
|
|
37219
|
+
// ../packages/internal/src/openrouter-ai-sdk/schemas/reasoning-details.ts
|
|
37043
37220
|
import { z as z70 } from "zod/v4";
|
|
37044
|
-
var
|
|
37045
|
-
|
|
37046
|
-
|
|
37047
|
-
name: z70.string().nullable(),
|
|
37048
|
-
authToken: z70.string(),
|
|
37049
|
-
fingerprintId: z70.string(),
|
|
37050
|
-
fingerprintHash: z70.string()
|
|
37221
|
+
var ReasoningDetailSummarySchema = z70.object({
|
|
37222
|
+
type: z70.literal("reasoning.summary" /* Summary */),
|
|
37223
|
+
summary: z70.string()
|
|
37051
37224
|
});
|
|
37052
|
-
|
|
37053
|
-
|
|
37054
|
-
|
|
37055
|
-
|
|
37056
|
-
// src/env.ts
|
|
37057
|
-
init_paths();
|
|
37058
|
-
|
|
37059
|
-
// ../common/src/env-process.ts
|
|
37060
|
-
var getBaseEnv = () => ({
|
|
37061
|
-
SHELL: process.env.SHELL,
|
|
37062
|
-
COMSPEC: process.env.COMSPEC,
|
|
37063
|
-
HOME: process.env.HOME,
|
|
37064
|
-
USERPROFILE: process.env.USERPROFILE,
|
|
37065
|
-
APPDATA: process.env.APPDATA,
|
|
37066
|
-
XDG_CONFIG_HOME: process.env.XDG_CONFIG_HOME,
|
|
37067
|
-
TERM: process.env.TERM,
|
|
37068
|
-
TERM_PROGRAM: process.env.TERM_PROGRAM,
|
|
37069
|
-
TERM_BACKGROUND: process.env.TERM_BACKGROUND,
|
|
37070
|
-
TERMINAL_EMULATOR: process.env.TERMINAL_EMULATOR,
|
|
37071
|
-
COLORFGBG: process.env.COLORFGBG,
|
|
37072
|
-
NODE_ENV: "development",
|
|
37073
|
-
NODE_PATH: process.env.NODE_PATH,
|
|
37074
|
-
PATH: process.env.PATH
|
|
37225
|
+
var ReasoningDetailEncryptedSchema = z70.object({
|
|
37226
|
+
type: z70.literal("reasoning.encrypted" /* Encrypted */),
|
|
37227
|
+
data: z70.string()
|
|
37075
37228
|
});
|
|
37076
|
-
var
|
|
37077
|
-
|
|
37078
|
-
|
|
37079
|
-
|
|
37080
|
-
|
|
37081
|
-
|
|
37082
|
-
|
|
37083
|
-
|
|
37084
|
-
|
|
37085
|
-
|
|
37086
|
-
|
|
37087
|
-
|
|
37088
|
-
|
|
37089
|
-
|
|
37090
|
-
|
|
37091
|
-
|
|
37092
|
-
|
|
37093
|
-
|
|
37094
|
-
|
|
37095
|
-
|
|
37096
|
-
|
|
37097
|
-
|
|
37098
|
-
|
|
37099
|
-
|
|
37100
|
-
|
|
37101
|
-
|
|
37102
|
-
|
|
37103
|
-
|
|
37104
|
-
|
|
37105
|
-
|
|
37106
|
-
|
|
37107
|
-
|
|
37229
|
+
var ReasoningDetailTextSchema = z70.object({
|
|
37230
|
+
type: z70.literal("reasoning.text" /* Text */),
|
|
37231
|
+
text: z70.string().nullish(),
|
|
37232
|
+
signature: z70.string().nullish()
|
|
37233
|
+
});
|
|
37234
|
+
var ReasoningDetailUnionSchema = z70.union([
|
|
37235
|
+
ReasoningDetailSummarySchema,
|
|
37236
|
+
ReasoningDetailEncryptedSchema,
|
|
37237
|
+
ReasoningDetailTextSchema
|
|
37238
|
+
]);
|
|
37239
|
+
var ReasoningDetailsWithUnknownSchema = z70.union([
|
|
37240
|
+
ReasoningDetailUnionSchema,
|
|
37241
|
+
z70.unknown().transform(() => null)
|
|
37242
|
+
]);
|
|
37243
|
+
var ReasoningDetailArraySchema = z70.array(ReasoningDetailsWithUnknownSchema).transform((d) => d.filter((d2) => !!d2));
|
|
37244
|
+
|
|
37245
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/convert-to-openrouter-chat-messages.ts
|
|
37246
|
+
function getCacheControl(providerMetadata) {
|
|
37247
|
+
const anthropic = providerMetadata?.anthropic;
|
|
37248
|
+
const openrouter = providerMetadata?.openrouter;
|
|
37249
|
+
return openrouter?.cacheControl ?? openrouter?.cache_control ?? anthropic?.cacheControl ?? anthropic?.cache_control;
|
|
37250
|
+
}
|
|
37251
|
+
function convertToOpenRouterChatMessages(prompt2) {
|
|
37252
|
+
const messages = [];
|
|
37253
|
+
for (const { role, content, providerOptions } of prompt2) {
|
|
37254
|
+
switch (role) {
|
|
37255
|
+
case "system": {
|
|
37256
|
+
messages.push({
|
|
37257
|
+
role: "system",
|
|
37258
|
+
content,
|
|
37259
|
+
cache_control: getCacheControl(providerOptions)
|
|
37260
|
+
});
|
|
37261
|
+
break;
|
|
37262
|
+
}
|
|
37263
|
+
case "user": {
|
|
37264
|
+
const messageCacheControl = getCacheControl(providerOptions);
|
|
37265
|
+
const contentParts = content.map((part) => {
|
|
37266
|
+
const cacheControl = getCacheControl(part.providerOptions) ?? messageCacheControl;
|
|
37267
|
+
switch (part.type) {
|
|
37268
|
+
case "text":
|
|
37269
|
+
return {
|
|
37270
|
+
type: "text",
|
|
37271
|
+
text: part.text,
|
|
37272
|
+
cache_control: cacheControl
|
|
37273
|
+
};
|
|
37274
|
+
case "file": {
|
|
37275
|
+
if (part.mediaType?.startsWith("image/")) {
|
|
37276
|
+
const url = getFileUrl({
|
|
37277
|
+
part,
|
|
37278
|
+
defaultMediaType: "image/jpeg"
|
|
37279
|
+
});
|
|
37280
|
+
return {
|
|
37281
|
+
type: "image_url",
|
|
37282
|
+
image_url: {
|
|
37283
|
+
url
|
|
37284
|
+
},
|
|
37285
|
+
cache_control: cacheControl
|
|
37286
|
+
};
|
|
37287
|
+
}
|
|
37288
|
+
const fileName = String(part.providerOptions?.openrouter?.filename ?? part.filename ?? "");
|
|
37289
|
+
const fileData = getFileUrl({
|
|
37290
|
+
part,
|
|
37291
|
+
defaultMediaType: "application/pdf"
|
|
37292
|
+
});
|
|
37293
|
+
if (isUrl({
|
|
37294
|
+
url: fileData,
|
|
37295
|
+
protocols: new Set(["http:", "https:"])
|
|
37296
|
+
})) {
|
|
37297
|
+
return {
|
|
37298
|
+
type: "file",
|
|
37299
|
+
file: {
|
|
37300
|
+
filename: fileName,
|
|
37301
|
+
file_data: fileData
|
|
37302
|
+
}
|
|
37303
|
+
};
|
|
37304
|
+
}
|
|
37305
|
+
return {
|
|
37306
|
+
type: "file",
|
|
37307
|
+
file: {
|
|
37308
|
+
filename: fileName,
|
|
37309
|
+
file_data: fileData
|
|
37310
|
+
},
|
|
37311
|
+
cache_control: cacheControl
|
|
37312
|
+
};
|
|
37313
|
+
}
|
|
37314
|
+
default: {
|
|
37315
|
+
return {
|
|
37316
|
+
type: "text",
|
|
37317
|
+
text: "",
|
|
37318
|
+
cache_control: cacheControl
|
|
37319
|
+
};
|
|
37320
|
+
}
|
|
37321
|
+
}
|
|
37322
|
+
});
|
|
37323
|
+
messages.push({
|
|
37324
|
+
role: "user",
|
|
37325
|
+
content: contentParts
|
|
37326
|
+
});
|
|
37327
|
+
break;
|
|
37328
|
+
}
|
|
37329
|
+
case "assistant": {
|
|
37330
|
+
let text = "";
|
|
37331
|
+
let reasoning = "";
|
|
37332
|
+
const reasoningDetails = [];
|
|
37333
|
+
const toolCalls2 = [];
|
|
37334
|
+
for (const part of content) {
|
|
37335
|
+
switch (part.type) {
|
|
37336
|
+
case "text": {
|
|
37337
|
+
text += part.text;
|
|
37338
|
+
break;
|
|
37339
|
+
}
|
|
37340
|
+
case "tool-call": {
|
|
37341
|
+
toolCalls2.push({
|
|
37342
|
+
id: part.toolCallId,
|
|
37343
|
+
type: "function",
|
|
37344
|
+
function: {
|
|
37345
|
+
name: part.toolName,
|
|
37346
|
+
arguments: JSON.stringify(part.input)
|
|
37347
|
+
}
|
|
37348
|
+
});
|
|
37349
|
+
break;
|
|
37350
|
+
}
|
|
37351
|
+
case "reasoning": {
|
|
37352
|
+
reasoning += part.text;
|
|
37353
|
+
reasoningDetails.push({
|
|
37354
|
+
type: "reasoning.text" /* Text */,
|
|
37355
|
+
text: part.text
|
|
37356
|
+
});
|
|
37357
|
+
break;
|
|
37358
|
+
}
|
|
37359
|
+
case "file":
|
|
37360
|
+
break;
|
|
37361
|
+
default: {
|
|
37362
|
+
break;
|
|
37363
|
+
}
|
|
37364
|
+
}
|
|
37365
|
+
}
|
|
37366
|
+
messages.push({
|
|
37367
|
+
role: "assistant",
|
|
37368
|
+
content: text,
|
|
37369
|
+
tool_calls: toolCalls2.length > 0 ? toolCalls2 : undefined,
|
|
37370
|
+
reasoning: reasoning || undefined,
|
|
37371
|
+
reasoning_details: reasoningDetails.length > 0 ? reasoningDetails : undefined,
|
|
37372
|
+
cache_control: getCacheControl(providerOptions)
|
|
37373
|
+
});
|
|
37374
|
+
break;
|
|
37375
|
+
}
|
|
37376
|
+
case "tool": {
|
|
37377
|
+
for (const toolResponse of content) {
|
|
37378
|
+
const content2 = getToolResultContent(toolResponse);
|
|
37379
|
+
messages.push({
|
|
37380
|
+
role: "tool",
|
|
37381
|
+
tool_call_id: toolResponse.toolCallId,
|
|
37382
|
+
content: content2,
|
|
37383
|
+
cache_control: getCacheControl(providerOptions) ?? getCacheControl(toolResponse.providerOptions)
|
|
37384
|
+
});
|
|
37385
|
+
}
|
|
37386
|
+
break;
|
|
37387
|
+
}
|
|
37388
|
+
default: {
|
|
37389
|
+
break;
|
|
37390
|
+
}
|
|
37391
|
+
}
|
|
37392
|
+
}
|
|
37393
|
+
return messages;
|
|
37394
|
+
}
|
|
37395
|
+
function getToolResultContent(input) {
|
|
37396
|
+
return input.output.type === "text" ? input.output.value : JSON.stringify(input.output.value);
|
|
37397
|
+
}
|
|
37398
|
+
|
|
37399
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/get-tool-choice.ts
|
|
37400
|
+
import { z as z71 } from "zod/v4";
|
|
37401
|
+
var ChatCompletionToolChoiceSchema = z71.union([
|
|
37402
|
+
z71.literal("auto"),
|
|
37403
|
+
z71.literal("none"),
|
|
37404
|
+
z71.literal("required"),
|
|
37405
|
+
z71.object({
|
|
37406
|
+
type: z71.literal("function"),
|
|
37407
|
+
function: z71.object({
|
|
37408
|
+
name: z71.string()
|
|
37409
|
+
})
|
|
37410
|
+
})
|
|
37411
|
+
]);
|
|
37412
|
+
function getChatCompletionToolChoice(toolChoice) {
|
|
37413
|
+
switch (toolChoice.type) {
|
|
37414
|
+
case "auto":
|
|
37415
|
+
case "none":
|
|
37416
|
+
case "required":
|
|
37417
|
+
return toolChoice.type;
|
|
37418
|
+
case "tool": {
|
|
37419
|
+
return {
|
|
37420
|
+
type: "function",
|
|
37421
|
+
function: { name: toolChoice.toolName }
|
|
37422
|
+
};
|
|
37423
|
+
}
|
|
37424
|
+
default: {
|
|
37425
|
+
throw new Error(`Invalid tool choice type: ${toolChoice}`);
|
|
37426
|
+
}
|
|
37427
|
+
}
|
|
37428
|
+
}
|
|
37429
|
+
|
|
37430
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/schemas.ts
|
|
37431
|
+
import { z as z73 } from "zod/v4";
|
|
37432
|
+
|
|
37433
|
+
// ../packages/internal/src/openrouter-ai-sdk/schemas/error-response.ts
|
|
37434
|
+
import { z as z72 } from "zod/v4";
|
|
37435
|
+
var OpenRouterErrorResponseSchema = z72.object({
|
|
37436
|
+
error: z72.object({
|
|
37437
|
+
code: z72.union([z72.string(), z72.number()]).nullable().optional().default(null),
|
|
37438
|
+
message: z72.string(),
|
|
37439
|
+
type: z72.string().nullable().optional().default(null),
|
|
37440
|
+
param: z72.any().nullable().optional().default(null)
|
|
37441
|
+
})
|
|
37442
|
+
});
|
|
37443
|
+
var openrouterFailedResponseHandler = createJsonErrorResponseHandler({
|
|
37444
|
+
errorSchema: OpenRouterErrorResponseSchema,
|
|
37445
|
+
errorToMessage: (data) => data.error.message
|
|
37446
|
+
});
|
|
37447
|
+
|
|
37448
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/schemas.ts
|
|
37449
|
+
var OpenRouterChatCompletionBaseResponseSchema = z73.object({
|
|
37450
|
+
id: z73.string().optional(),
|
|
37451
|
+
model: z73.string().optional(),
|
|
37452
|
+
provider: z73.string().optional(),
|
|
37453
|
+
usage: z73.object({
|
|
37454
|
+
prompt_tokens: z73.number(),
|
|
37455
|
+
prompt_tokens_details: z73.object({
|
|
37456
|
+
cached_tokens: z73.number()
|
|
37457
|
+
}).nullish(),
|
|
37458
|
+
completion_tokens: z73.number(),
|
|
37459
|
+
completion_tokens_details: z73.object({
|
|
37460
|
+
reasoning_tokens: z73.number()
|
|
37461
|
+
}).nullish(),
|
|
37462
|
+
total_tokens: z73.number(),
|
|
37463
|
+
cost: z73.number().optional(),
|
|
37464
|
+
cost_details: z73.object({
|
|
37465
|
+
upstream_inference_cost: z73.number().nullish()
|
|
37466
|
+
}).nullish()
|
|
37467
|
+
}).nullish()
|
|
37468
|
+
});
|
|
37469
|
+
var OpenRouterNonStreamChatCompletionResponseSchema = OpenRouterChatCompletionBaseResponseSchema.extend({
|
|
37470
|
+
choices: z73.array(z73.object({
|
|
37471
|
+
message: z73.object({
|
|
37472
|
+
role: z73.literal("assistant"),
|
|
37473
|
+
content: z73.string().nullable().optional(),
|
|
37474
|
+
reasoning: z73.string().nullable().optional(),
|
|
37475
|
+
reasoning_details: ReasoningDetailArraySchema.nullish(),
|
|
37476
|
+
tool_calls: z73.array(z73.object({
|
|
37477
|
+
id: z73.string().optional().nullable(),
|
|
37478
|
+
type: z73.literal("function"),
|
|
37479
|
+
function: z73.object({
|
|
37480
|
+
name: z73.string(),
|
|
37481
|
+
arguments: z73.string()
|
|
37482
|
+
})
|
|
37483
|
+
})).optional(),
|
|
37484
|
+
annotations: z73.array(z73.object({
|
|
37485
|
+
type: z73.enum(["url_citation"]),
|
|
37486
|
+
url_citation: z73.object({
|
|
37487
|
+
end_index: z73.number(),
|
|
37488
|
+
start_index: z73.number(),
|
|
37489
|
+
title: z73.string(),
|
|
37490
|
+
url: z73.string(),
|
|
37491
|
+
content: z73.string().optional()
|
|
37492
|
+
})
|
|
37493
|
+
})).nullish()
|
|
37494
|
+
}),
|
|
37495
|
+
index: z73.number().nullish(),
|
|
37496
|
+
logprobs: z73.object({
|
|
37497
|
+
content: z73.array(z73.object({
|
|
37498
|
+
token: z73.string(),
|
|
37499
|
+
logprob: z73.number(),
|
|
37500
|
+
top_logprobs: z73.array(z73.object({
|
|
37501
|
+
token: z73.string(),
|
|
37502
|
+
logprob: z73.number()
|
|
37503
|
+
}))
|
|
37504
|
+
})).nullable()
|
|
37505
|
+
}).nullable().optional(),
|
|
37506
|
+
finish_reason: z73.string().optional().nullable()
|
|
37507
|
+
}))
|
|
37508
|
+
});
|
|
37509
|
+
var OpenRouterStreamChatCompletionChunkSchema = z73.union([
|
|
37510
|
+
OpenRouterChatCompletionBaseResponseSchema.extend({
|
|
37511
|
+
choices: z73.array(z73.object({
|
|
37512
|
+
delta: z73.object({
|
|
37513
|
+
role: z73.enum(["assistant"]).optional(),
|
|
37514
|
+
content: z73.string().nullish(),
|
|
37515
|
+
reasoning: z73.string().nullish().optional(),
|
|
37516
|
+
reasoning_details: ReasoningDetailArraySchema.nullish(),
|
|
37517
|
+
tool_calls: z73.array(z73.object({
|
|
37518
|
+
index: z73.number().nullish(),
|
|
37519
|
+
id: z73.string().nullish(),
|
|
37520
|
+
type: z73.literal("function").optional(),
|
|
37521
|
+
function: z73.object({
|
|
37522
|
+
name: z73.string().nullish(),
|
|
37523
|
+
arguments: z73.string().nullish()
|
|
37524
|
+
})
|
|
37525
|
+
})).nullish(),
|
|
37526
|
+
annotations: z73.array(z73.object({
|
|
37527
|
+
type: z73.enum(["url_citation"]),
|
|
37528
|
+
url_citation: z73.object({
|
|
37529
|
+
end_index: z73.number(),
|
|
37530
|
+
start_index: z73.number(),
|
|
37531
|
+
title: z73.string(),
|
|
37532
|
+
url: z73.string(),
|
|
37533
|
+
content: z73.string().optional()
|
|
37534
|
+
})
|
|
37535
|
+
})).nullish()
|
|
37536
|
+
}).nullish(),
|
|
37537
|
+
logprobs: z73.object({
|
|
37538
|
+
content: z73.array(z73.object({
|
|
37539
|
+
token: z73.string(),
|
|
37540
|
+
logprob: z73.number(),
|
|
37541
|
+
top_logprobs: z73.array(z73.object({
|
|
37542
|
+
token: z73.string(),
|
|
37543
|
+
logprob: z73.number()
|
|
37544
|
+
}))
|
|
37545
|
+
})).nullable()
|
|
37546
|
+
}).nullish(),
|
|
37547
|
+
finish_reason: z73.string().nullable().optional(),
|
|
37548
|
+
index: z73.number().nullish()
|
|
37549
|
+
}))
|
|
37550
|
+
}),
|
|
37551
|
+
OpenRouterErrorResponseSchema
|
|
37552
|
+
]);
|
|
37553
|
+
|
|
37554
|
+
// ../packages/internal/src/openrouter-ai-sdk/utils/map-finish-reason.ts
|
|
37555
|
+
function mapOpenRouterFinishReason(finishReason) {
|
|
37556
|
+
switch (finishReason) {
|
|
37557
|
+
case "stop":
|
|
37558
|
+
return "stop";
|
|
37559
|
+
case "length":
|
|
37560
|
+
return "length";
|
|
37561
|
+
case "content_filter":
|
|
37562
|
+
return "content-filter";
|
|
37563
|
+
case "function_call":
|
|
37564
|
+
case "tool_calls":
|
|
37565
|
+
return "tool-calls";
|
|
37566
|
+
default:
|
|
37567
|
+
return "unknown";
|
|
37568
|
+
}
|
|
37569
|
+
}
|
|
37570
|
+
|
|
37571
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/index.ts
|
|
37572
|
+
class OpenRouterChatLanguageModel {
|
|
37573
|
+
specificationVersion = "v2";
|
|
37574
|
+
provider = "openrouter";
|
|
37575
|
+
defaultObjectGenerationMode = "tool";
|
|
37576
|
+
modelId;
|
|
37577
|
+
supportedUrls = {
|
|
37578
|
+
"image/*": [
|
|
37579
|
+
/^data:image\/[a-zA-Z]+;base64,/,
|
|
37580
|
+
/^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)$/i
|
|
37581
|
+
],
|
|
37582
|
+
"application/*": [/^data:application\//, /^https?:\/\/.+$/]
|
|
37583
|
+
};
|
|
37584
|
+
settings;
|
|
37585
|
+
config;
|
|
37586
|
+
constructor(modelId, settings, config) {
|
|
37587
|
+
this.modelId = modelId;
|
|
37588
|
+
this.settings = settings;
|
|
37589
|
+
this.config = config;
|
|
37590
|
+
}
|
|
37591
|
+
getArgs({
|
|
37592
|
+
prompt: prompt2,
|
|
37593
|
+
maxOutputTokens,
|
|
37594
|
+
temperature,
|
|
37595
|
+
topP,
|
|
37596
|
+
frequencyPenalty,
|
|
37597
|
+
presencePenalty,
|
|
37598
|
+
seed,
|
|
37599
|
+
stopSequences,
|
|
37600
|
+
responseFormat,
|
|
37601
|
+
topK,
|
|
37602
|
+
tools,
|
|
37603
|
+
toolChoice
|
|
37604
|
+
}) {
|
|
37605
|
+
const baseArgs = {
|
|
37606
|
+
model: this.modelId,
|
|
37607
|
+
models: this.settings.models,
|
|
37608
|
+
logit_bias: this.settings.logitBias,
|
|
37609
|
+
logprobs: this.settings.logprobs === true || typeof this.settings.logprobs === "number" ? true : undefined,
|
|
37610
|
+
top_logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : undefined : undefined,
|
|
37611
|
+
user: this.settings.user,
|
|
37612
|
+
parallel_tool_calls: this.settings.parallelToolCalls,
|
|
37613
|
+
max_tokens: maxOutputTokens,
|
|
37614
|
+
temperature,
|
|
37615
|
+
top_p: topP,
|
|
37616
|
+
frequency_penalty: frequencyPenalty,
|
|
37617
|
+
presence_penalty: presencePenalty,
|
|
37618
|
+
seed,
|
|
37619
|
+
...this.modelId === "x-ai/grok-code-fast-1" ? {} : { stop: stopSequences },
|
|
37620
|
+
response_format: responseFormat,
|
|
37621
|
+
top_k: topK,
|
|
37622
|
+
messages: convertToOpenRouterChatMessages(prompt2),
|
|
37623
|
+
include_reasoning: this.settings.includeReasoning,
|
|
37624
|
+
reasoning: this.settings.reasoning,
|
|
37625
|
+
usage: this.settings.usage,
|
|
37626
|
+
plugins: this.settings.plugins,
|
|
37627
|
+
web_search_options: this.settings.web_search_options,
|
|
37628
|
+
provider: this.settings.provider,
|
|
37629
|
+
...this.config.extraBody,
|
|
37630
|
+
...this.settings.extraBody
|
|
37631
|
+
};
|
|
37632
|
+
if (responseFormat?.type === "json" && responseFormat.schema != null) {
|
|
37633
|
+
return {
|
|
37634
|
+
...baseArgs,
|
|
37635
|
+
response_format: {
|
|
37636
|
+
type: "json_schema",
|
|
37637
|
+
json_schema: {
|
|
37638
|
+
schema: responseFormat.schema,
|
|
37639
|
+
strict: true,
|
|
37640
|
+
name: responseFormat.name ?? "response",
|
|
37641
|
+
...responseFormat.description && {
|
|
37642
|
+
description: responseFormat.description
|
|
37643
|
+
}
|
|
37644
|
+
}
|
|
37645
|
+
}
|
|
37646
|
+
};
|
|
37647
|
+
}
|
|
37648
|
+
if (tools && tools.length > 0) {
|
|
37649
|
+
const mappedTools = tools.filter((tool) => tool.type === "function").map((tool) => ({
|
|
37650
|
+
type: "function",
|
|
37651
|
+
function: {
|
|
37652
|
+
name: tool.name,
|
|
37653
|
+
description: tool.description,
|
|
37654
|
+
parameters: tool.inputSchema
|
|
37655
|
+
}
|
|
37656
|
+
}));
|
|
37657
|
+
return {
|
|
37658
|
+
...baseArgs,
|
|
37659
|
+
tools: mappedTools,
|
|
37660
|
+
tool_choice: toolChoice ? getChatCompletionToolChoice(toolChoice) : undefined
|
|
37661
|
+
};
|
|
37662
|
+
}
|
|
37663
|
+
return baseArgs;
|
|
37664
|
+
}
|
|
37665
|
+
async doGenerate(options) {
|
|
37666
|
+
const providerOptions = options.providerOptions || {};
|
|
37667
|
+
const openrouterOptions = providerOptions.openrouter || {};
|
|
37668
|
+
const args = {
|
|
37669
|
+
...this.getArgs(options),
|
|
37670
|
+
...openrouterOptions
|
|
37671
|
+
};
|
|
37672
|
+
const { value: response, responseHeaders } = await postJsonToApi({
|
|
37673
|
+
url: this.config.url({
|
|
37674
|
+
path: "/chat/completions",
|
|
37675
|
+
modelId: this.modelId
|
|
37676
|
+
}),
|
|
37677
|
+
headers: combineHeaders(this.config.headers(), options.headers),
|
|
37678
|
+
body: args,
|
|
37679
|
+
failedResponseHandler: openrouterFailedResponseHandler,
|
|
37680
|
+
successfulResponseHandler: createJsonResponseHandler(OpenRouterNonStreamChatCompletionResponseSchema),
|
|
37681
|
+
abortSignal: options.abortSignal,
|
|
37682
|
+
fetch: this.config.fetch
|
|
37683
|
+
});
|
|
37684
|
+
const choice = response.choices[0];
|
|
37685
|
+
if (!choice) {
|
|
37686
|
+
throw new Error("No choice in response");
|
|
37687
|
+
}
|
|
37688
|
+
const usageInfo = response.usage ? {
|
|
37689
|
+
inputTokens: response.usage.prompt_tokens ?? 0,
|
|
37690
|
+
outputTokens: response.usage.completion_tokens ?? 0,
|
|
37691
|
+
totalTokens: (response.usage.prompt_tokens ?? 0) + (response.usage.completion_tokens ?? 0),
|
|
37692
|
+
reasoningTokens: response.usage.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
37693
|
+
cachedInputTokens: response.usage.prompt_tokens_details?.cached_tokens ?? 0
|
|
37694
|
+
} : {
|
|
37695
|
+
inputTokens: 0,
|
|
37696
|
+
outputTokens: 0,
|
|
37697
|
+
totalTokens: 0,
|
|
37698
|
+
reasoningTokens: 0,
|
|
37699
|
+
cachedInputTokens: 0
|
|
37700
|
+
};
|
|
37701
|
+
const reasoningDetails = choice.message.reasoning_details ?? [];
|
|
37702
|
+
const reasoning = reasoningDetails.length > 0 ? reasoningDetails.map((detail) => {
|
|
37703
|
+
switch (detail.type) {
|
|
37704
|
+
case "reasoning.text" /* Text */: {
|
|
37705
|
+
if (detail.text) {
|
|
37706
|
+
return {
|
|
37707
|
+
type: "reasoning",
|
|
37708
|
+
text: detail.text
|
|
37709
|
+
};
|
|
37710
|
+
}
|
|
37711
|
+
break;
|
|
37712
|
+
}
|
|
37713
|
+
case "reasoning.summary" /* Summary */: {
|
|
37714
|
+
if (detail.summary) {
|
|
37715
|
+
return {
|
|
37716
|
+
type: "reasoning",
|
|
37717
|
+
text: detail.summary
|
|
37718
|
+
};
|
|
37719
|
+
}
|
|
37720
|
+
break;
|
|
37721
|
+
}
|
|
37722
|
+
case "reasoning.encrypted" /* Encrypted */: {
|
|
37723
|
+
if (detail.data) {
|
|
37724
|
+
return {
|
|
37725
|
+
type: "reasoning",
|
|
37726
|
+
text: "[REDACTED]"
|
|
37727
|
+
};
|
|
37728
|
+
}
|
|
37729
|
+
break;
|
|
37730
|
+
}
|
|
37731
|
+
default: {}
|
|
37732
|
+
}
|
|
37733
|
+
return null;
|
|
37734
|
+
}).filter((p) => p !== null) : choice.message.reasoning ? [
|
|
37735
|
+
{
|
|
37736
|
+
type: "reasoning",
|
|
37737
|
+
text: choice.message.reasoning
|
|
37738
|
+
}
|
|
37739
|
+
] : [];
|
|
37740
|
+
const content = [];
|
|
37741
|
+
content.push(...reasoning);
|
|
37742
|
+
if (choice.message.content) {
|
|
37743
|
+
content.push({
|
|
37744
|
+
type: "text",
|
|
37745
|
+
text: choice.message.content
|
|
37746
|
+
});
|
|
37747
|
+
}
|
|
37748
|
+
if (choice.message.tool_calls) {
|
|
37749
|
+
for (const toolCall of choice.message.tool_calls) {
|
|
37750
|
+
content.push({
|
|
37751
|
+
type: "tool-call",
|
|
37752
|
+
toolCallId: toolCall.id ?? generateId(),
|
|
37753
|
+
toolName: toolCall.function.name,
|
|
37754
|
+
input: toolCall.function.arguments
|
|
37755
|
+
});
|
|
37756
|
+
}
|
|
37757
|
+
}
|
|
37758
|
+
if (choice.message.annotations) {
|
|
37759
|
+
for (const annotation of choice.message.annotations) {
|
|
37760
|
+
if (annotation.type === "url_citation") {
|
|
37761
|
+
content.push({
|
|
37762
|
+
type: "source",
|
|
37763
|
+
sourceType: "url",
|
|
37764
|
+
id: annotation.url_citation.url,
|
|
37765
|
+
url: annotation.url_citation.url,
|
|
37766
|
+
title: annotation.url_citation.title,
|
|
37767
|
+
providerMetadata: {
|
|
37768
|
+
openrouter: {
|
|
37769
|
+
content: annotation.url_citation.content || ""
|
|
37770
|
+
}
|
|
37771
|
+
}
|
|
37772
|
+
});
|
|
37773
|
+
}
|
|
37774
|
+
}
|
|
37775
|
+
}
|
|
37776
|
+
return {
|
|
37777
|
+
content,
|
|
37778
|
+
finishReason: mapOpenRouterFinishReason(choice.finish_reason),
|
|
37779
|
+
usage: usageInfo,
|
|
37780
|
+
warnings: [],
|
|
37781
|
+
providerMetadata: {
|
|
37782
|
+
openrouter: {
|
|
37783
|
+
provider: response.provider ?? "",
|
|
37784
|
+
usage: {
|
|
37785
|
+
promptTokens: usageInfo.inputTokens ?? 0,
|
|
37786
|
+
completionTokens: usageInfo.outputTokens ?? 0,
|
|
37787
|
+
totalTokens: usageInfo.totalTokens ?? 0,
|
|
37788
|
+
cost: response.usage?.cost,
|
|
37789
|
+
promptTokensDetails: {
|
|
37790
|
+
cachedTokens: response.usage?.prompt_tokens_details?.cached_tokens ?? 0
|
|
37791
|
+
},
|
|
37792
|
+
completionTokensDetails: {
|
|
37793
|
+
reasoningTokens: response.usage?.completion_tokens_details?.reasoning_tokens ?? 0
|
|
37794
|
+
},
|
|
37795
|
+
costDetails: {
|
|
37796
|
+
upstreamInferenceCost: response.usage?.cost_details?.upstream_inference_cost ?? 0
|
|
37797
|
+
}
|
|
37798
|
+
}
|
|
37799
|
+
}
|
|
37800
|
+
},
|
|
37801
|
+
request: { body: args },
|
|
37802
|
+
response: {
|
|
37803
|
+
id: response.id,
|
|
37804
|
+
modelId: response.model,
|
|
37805
|
+
headers: responseHeaders
|
|
37806
|
+
}
|
|
37807
|
+
};
|
|
37808
|
+
}
|
|
37809
|
+
async doStream(options) {
|
|
37810
|
+
const providerOptions = options.providerOptions || {};
|
|
37811
|
+
const openrouterOptions = providerOptions.openrouter || {};
|
|
37812
|
+
const args = {
|
|
37813
|
+
...this.getArgs(options),
|
|
37814
|
+
...openrouterOptions
|
|
37815
|
+
};
|
|
37816
|
+
const { value: response, responseHeaders } = await postJsonToApi({
|
|
37817
|
+
url: this.config.url({
|
|
37818
|
+
path: "/chat/completions",
|
|
37819
|
+
modelId: this.modelId
|
|
37820
|
+
}),
|
|
37821
|
+
headers: combineHeaders(this.config.headers(), options.headers),
|
|
37822
|
+
body: {
|
|
37823
|
+
...args,
|
|
37824
|
+
stream: true,
|
|
37825
|
+
stream_options: this.config.compatibility === "strict" ? {
|
|
37826
|
+
include_usage: true,
|
|
37827
|
+
...this.settings.usage?.include ? { include_usage: true } : {}
|
|
37828
|
+
} : undefined
|
|
37829
|
+
},
|
|
37830
|
+
failedResponseHandler: openrouterFailedResponseHandler,
|
|
37831
|
+
successfulResponseHandler: createEventSourceResponseHandler(OpenRouterStreamChatCompletionChunkSchema),
|
|
37832
|
+
abortSignal: options.abortSignal,
|
|
37833
|
+
fetch: this.config.fetch
|
|
37834
|
+
});
|
|
37835
|
+
const toolCalls2 = [];
|
|
37836
|
+
let finishReason = "other";
|
|
37837
|
+
const usage = {
|
|
37838
|
+
inputTokens: Number.NaN,
|
|
37839
|
+
outputTokens: Number.NaN,
|
|
37840
|
+
totalTokens: Number.NaN,
|
|
37841
|
+
reasoningTokens: Number.NaN,
|
|
37842
|
+
cachedInputTokens: Number.NaN
|
|
37843
|
+
};
|
|
37844
|
+
const openrouterUsage = {};
|
|
37845
|
+
let textStarted = false;
|
|
37846
|
+
let reasoningStarted = false;
|
|
37847
|
+
let textId;
|
|
37848
|
+
let reasoningId;
|
|
37849
|
+
let openrouterResponseId;
|
|
37850
|
+
let provider;
|
|
37851
|
+
return {
|
|
37852
|
+
stream: response.pipeThrough(new TransformStream({
|
|
37853
|
+
transform(chunk, controller) {
|
|
37854
|
+
if (!chunk.success) {
|
|
37855
|
+
finishReason = "error";
|
|
37856
|
+
controller.enqueue({ type: "error", error: chunk.error });
|
|
37857
|
+
return;
|
|
37858
|
+
}
|
|
37859
|
+
const value = chunk.value;
|
|
37860
|
+
if ("error" in value) {
|
|
37861
|
+
finishReason = "error";
|
|
37862
|
+
controller.enqueue({ type: "error", error: value.error });
|
|
37863
|
+
return;
|
|
37864
|
+
}
|
|
37865
|
+
if (value.provider) {
|
|
37866
|
+
provider = value.provider;
|
|
37867
|
+
}
|
|
37868
|
+
if (value.id) {
|
|
37869
|
+
openrouterResponseId = value.id;
|
|
37870
|
+
controller.enqueue({
|
|
37871
|
+
type: "response-metadata",
|
|
37872
|
+
id: value.id
|
|
37873
|
+
});
|
|
37874
|
+
}
|
|
37875
|
+
if (value.model) {
|
|
37876
|
+
controller.enqueue({
|
|
37877
|
+
type: "response-metadata",
|
|
37878
|
+
modelId: value.model
|
|
37879
|
+
});
|
|
37880
|
+
}
|
|
37881
|
+
if (value.usage != null) {
|
|
37882
|
+
usage.inputTokens = value.usage.prompt_tokens;
|
|
37883
|
+
usage.outputTokens = value.usage.completion_tokens;
|
|
37884
|
+
usage.totalTokens = value.usage.prompt_tokens + value.usage.completion_tokens;
|
|
37885
|
+
openrouterUsage.promptTokens = value.usage.prompt_tokens;
|
|
37886
|
+
if (value.usage.prompt_tokens_details) {
|
|
37887
|
+
const cachedInputTokens = value.usage.prompt_tokens_details.cached_tokens ?? 0;
|
|
37888
|
+
usage.cachedInputTokens = cachedInputTokens;
|
|
37889
|
+
openrouterUsage.promptTokensDetails = {
|
|
37890
|
+
cachedTokens: cachedInputTokens
|
|
37891
|
+
};
|
|
37892
|
+
}
|
|
37893
|
+
openrouterUsage.completionTokens = value.usage.completion_tokens;
|
|
37894
|
+
if (value.usage.completion_tokens_details) {
|
|
37895
|
+
const reasoningTokens = value.usage.completion_tokens_details.reasoning_tokens ?? 0;
|
|
37896
|
+
usage.reasoningTokens = reasoningTokens;
|
|
37897
|
+
openrouterUsage.completionTokensDetails = {
|
|
37898
|
+
reasoningTokens
|
|
37899
|
+
};
|
|
37900
|
+
}
|
|
37901
|
+
const upstreamInferenceCost = value.usage.cost_details?.upstream_inference_cost;
|
|
37902
|
+
if (upstreamInferenceCost != null && upstreamInferenceCost !== undefined) {
|
|
37903
|
+
openrouterUsage.costDetails = {
|
|
37904
|
+
upstreamInferenceCost
|
|
37905
|
+
};
|
|
37906
|
+
}
|
|
37907
|
+
if (value.usage.cost !== undefined) {
|
|
37908
|
+
openrouterUsage.cost = value.usage.cost;
|
|
37909
|
+
}
|
|
37910
|
+
openrouterUsage.totalTokens = value.usage.total_tokens;
|
|
37911
|
+
}
|
|
37912
|
+
const choice = value.choices[0];
|
|
37913
|
+
if (choice?.finish_reason != null) {
|
|
37914
|
+
finishReason = mapOpenRouterFinishReason(choice.finish_reason);
|
|
37915
|
+
}
|
|
37916
|
+
if (choice?.delta == null) {
|
|
37917
|
+
return;
|
|
37918
|
+
}
|
|
37919
|
+
const delta = choice.delta;
|
|
37920
|
+
const emitReasoningChunk = (chunkText) => {
|
|
37921
|
+
if (!reasoningStarted) {
|
|
37922
|
+
reasoningId = openrouterResponseId || generateId();
|
|
37923
|
+
controller.enqueue({
|
|
37924
|
+
type: "reasoning-start",
|
|
37925
|
+
id: reasoningId
|
|
37926
|
+
});
|
|
37927
|
+
reasoningStarted = true;
|
|
37928
|
+
}
|
|
37929
|
+
controller.enqueue({
|
|
37930
|
+
type: "reasoning-delta",
|
|
37931
|
+
delta: chunkText,
|
|
37932
|
+
id: reasoningId || generateId()
|
|
37933
|
+
});
|
|
37934
|
+
};
|
|
37935
|
+
if (delta.reasoning_details && delta.reasoning_details.length > 0) {
|
|
37936
|
+
for (const detail of delta.reasoning_details) {
|
|
37937
|
+
switch (detail.type) {
|
|
37938
|
+
case "reasoning.text" /* Text */: {
|
|
37939
|
+
if (detail.text) {
|
|
37940
|
+
emitReasoningChunk(detail.text);
|
|
37941
|
+
}
|
|
37942
|
+
break;
|
|
37943
|
+
}
|
|
37944
|
+
case "reasoning.encrypted" /* Encrypted */: {
|
|
37945
|
+
if (detail.data) {
|
|
37946
|
+
emitReasoningChunk("[REDACTED]");
|
|
37947
|
+
}
|
|
37948
|
+
break;
|
|
37949
|
+
}
|
|
37950
|
+
case "reasoning.summary" /* Summary */: {
|
|
37951
|
+
if (detail.summary) {
|
|
37952
|
+
emitReasoningChunk(detail.summary);
|
|
37953
|
+
}
|
|
37954
|
+
break;
|
|
37955
|
+
}
|
|
37956
|
+
default: {
|
|
37957
|
+
break;
|
|
37958
|
+
}
|
|
37959
|
+
}
|
|
37960
|
+
}
|
|
37961
|
+
} else if (delta.reasoning) {
|
|
37962
|
+
emitReasoningChunk(delta.reasoning);
|
|
37963
|
+
}
|
|
37964
|
+
if (delta.content) {
|
|
37965
|
+
if (reasoningStarted && !textStarted) {
|
|
37966
|
+
controller.enqueue({
|
|
37967
|
+
type: "reasoning-end",
|
|
37968
|
+
id: reasoningId || generateId()
|
|
37969
|
+
});
|
|
37970
|
+
reasoningStarted = false;
|
|
37971
|
+
}
|
|
37972
|
+
if (!textStarted) {
|
|
37973
|
+
textId = openrouterResponseId || generateId();
|
|
37974
|
+
controller.enqueue({
|
|
37975
|
+
type: "text-start",
|
|
37976
|
+
id: textId
|
|
37977
|
+
});
|
|
37978
|
+
textStarted = true;
|
|
37979
|
+
}
|
|
37980
|
+
controller.enqueue({
|
|
37981
|
+
type: "text-delta",
|
|
37982
|
+
delta: delta.content,
|
|
37983
|
+
id: textId || generateId()
|
|
37984
|
+
});
|
|
37985
|
+
}
|
|
37986
|
+
if (delta.annotations) {
|
|
37987
|
+
for (const annotation of delta.annotations) {
|
|
37988
|
+
if (annotation.type === "url_citation") {
|
|
37989
|
+
controller.enqueue({
|
|
37990
|
+
type: "source",
|
|
37991
|
+
sourceType: "url",
|
|
37992
|
+
id: annotation.url_citation.url,
|
|
37993
|
+
url: annotation.url_citation.url,
|
|
37994
|
+
title: annotation.url_citation.title,
|
|
37995
|
+
providerMetadata: {
|
|
37996
|
+
openrouter: {
|
|
37997
|
+
content: annotation.url_citation.content || ""
|
|
37998
|
+
}
|
|
37999
|
+
}
|
|
38000
|
+
});
|
|
38001
|
+
}
|
|
38002
|
+
}
|
|
38003
|
+
}
|
|
38004
|
+
if (delta.tool_calls != null) {
|
|
38005
|
+
for (const toolCallDelta of delta.tool_calls) {
|
|
38006
|
+
const index = toolCallDelta.index ?? toolCalls2.length - 1;
|
|
38007
|
+
if (toolCalls2[index] == null) {
|
|
38008
|
+
if (toolCallDelta.type !== "function") {
|
|
38009
|
+
throw new InvalidResponseDataError({
|
|
38010
|
+
data: toolCallDelta,
|
|
38011
|
+
message: `Expected 'function' type.`
|
|
38012
|
+
});
|
|
38013
|
+
}
|
|
38014
|
+
if (toolCallDelta.id == null) {
|
|
38015
|
+
throw new InvalidResponseDataError({
|
|
38016
|
+
data: toolCallDelta,
|
|
38017
|
+
message: `Expected 'id' to be a string.`
|
|
38018
|
+
});
|
|
38019
|
+
}
|
|
38020
|
+
if (toolCallDelta.function?.name == null) {
|
|
38021
|
+
throw new InvalidResponseDataError({
|
|
38022
|
+
data: toolCallDelta,
|
|
38023
|
+
message: `Expected 'function.name' to be a string.`
|
|
38024
|
+
});
|
|
38025
|
+
}
|
|
38026
|
+
toolCalls2[index] = {
|
|
38027
|
+
id: toolCallDelta.id,
|
|
38028
|
+
type: "function",
|
|
38029
|
+
function: {
|
|
38030
|
+
name: toolCallDelta.function.name,
|
|
38031
|
+
arguments: toolCallDelta.function.arguments ?? ""
|
|
38032
|
+
},
|
|
38033
|
+
inputStarted: false,
|
|
38034
|
+
sent: false
|
|
38035
|
+
};
|
|
38036
|
+
const toolCall2 = toolCalls2[index];
|
|
38037
|
+
if (toolCall2 == null) {
|
|
38038
|
+
throw new Error("Tool call is missing");
|
|
38039
|
+
}
|
|
38040
|
+
if (toolCall2.function?.name != null && toolCall2.function?.arguments != null && isParsableJson(toolCall2.function.arguments)) {
|
|
38041
|
+
toolCall2.inputStarted = true;
|
|
38042
|
+
controller.enqueue({
|
|
38043
|
+
type: "tool-input-start",
|
|
38044
|
+
id: toolCall2.id,
|
|
38045
|
+
toolName: toolCall2.function.name
|
|
38046
|
+
});
|
|
38047
|
+
controller.enqueue({
|
|
38048
|
+
type: "tool-input-delta",
|
|
38049
|
+
id: toolCall2.id,
|
|
38050
|
+
delta: toolCall2.function.arguments
|
|
38051
|
+
});
|
|
38052
|
+
controller.enqueue({
|
|
38053
|
+
type: "tool-input-end",
|
|
38054
|
+
id: toolCall2.id
|
|
38055
|
+
});
|
|
38056
|
+
controller.enqueue({
|
|
38057
|
+
type: "tool-call",
|
|
38058
|
+
toolCallId: toolCall2.id,
|
|
38059
|
+
toolName: toolCall2.function.name,
|
|
38060
|
+
input: toolCall2.function.arguments
|
|
38061
|
+
});
|
|
38062
|
+
toolCall2.sent = true;
|
|
38063
|
+
}
|
|
38064
|
+
continue;
|
|
38065
|
+
}
|
|
38066
|
+
const toolCall = toolCalls2[index];
|
|
38067
|
+
if (toolCall == null) {
|
|
38068
|
+
throw new Error("Tool call is missing");
|
|
38069
|
+
}
|
|
38070
|
+
if (!toolCall.inputStarted) {
|
|
38071
|
+
toolCall.inputStarted = true;
|
|
38072
|
+
controller.enqueue({
|
|
38073
|
+
type: "tool-input-start",
|
|
38074
|
+
id: toolCall.id,
|
|
38075
|
+
toolName: toolCall.function.name
|
|
38076
|
+
});
|
|
38077
|
+
}
|
|
38078
|
+
if (toolCallDelta.function?.arguments != null) {
|
|
38079
|
+
toolCall.function.arguments += toolCallDelta.function?.arguments ?? "";
|
|
38080
|
+
}
|
|
38081
|
+
controller.enqueue({
|
|
38082
|
+
type: "tool-input-delta",
|
|
38083
|
+
id: toolCall.id,
|
|
38084
|
+
delta: toolCallDelta.function.arguments ?? ""
|
|
38085
|
+
});
|
|
38086
|
+
if (toolCall.function?.name != null && toolCall.function?.arguments != null && isParsableJson(toolCall.function.arguments)) {
|
|
38087
|
+
controller.enqueue({
|
|
38088
|
+
type: "tool-call",
|
|
38089
|
+
toolCallId: toolCall.id ?? generateId(),
|
|
38090
|
+
toolName: toolCall.function.name,
|
|
38091
|
+
input: toolCall.function.arguments
|
|
38092
|
+
});
|
|
38093
|
+
toolCall.sent = true;
|
|
38094
|
+
}
|
|
38095
|
+
}
|
|
38096
|
+
}
|
|
38097
|
+
},
|
|
38098
|
+
flush(controller) {
|
|
38099
|
+
if (finishReason === "tool-calls") {
|
|
38100
|
+
for (const toolCall of toolCalls2) {
|
|
38101
|
+
if (toolCall && !toolCall.sent) {
|
|
38102
|
+
controller.enqueue({
|
|
38103
|
+
type: "tool-call",
|
|
38104
|
+
toolCallId: toolCall.id ?? generateId(),
|
|
38105
|
+
toolName: toolCall.function.name,
|
|
38106
|
+
input: isParsableJson(toolCall.function.arguments) ? toolCall.function.arguments : "{}"
|
|
38107
|
+
});
|
|
38108
|
+
toolCall.sent = true;
|
|
38109
|
+
}
|
|
38110
|
+
}
|
|
38111
|
+
}
|
|
38112
|
+
if (reasoningStarted) {
|
|
38113
|
+
controller.enqueue({
|
|
38114
|
+
type: "reasoning-end",
|
|
38115
|
+
id: reasoningId || generateId()
|
|
38116
|
+
});
|
|
38117
|
+
}
|
|
38118
|
+
if (textStarted) {
|
|
38119
|
+
controller.enqueue({
|
|
38120
|
+
type: "text-end",
|
|
38121
|
+
id: textId || generateId()
|
|
38122
|
+
});
|
|
38123
|
+
}
|
|
38124
|
+
const openrouterMetadata = {
|
|
38125
|
+
usage: openrouterUsage
|
|
38126
|
+
};
|
|
38127
|
+
if (provider !== undefined) {
|
|
38128
|
+
openrouterMetadata.provider = provider;
|
|
38129
|
+
}
|
|
38130
|
+
controller.enqueue({
|
|
38131
|
+
type: "finish",
|
|
38132
|
+
finishReason,
|
|
38133
|
+
usage,
|
|
38134
|
+
providerMetadata: {
|
|
38135
|
+
openrouter: openrouterMetadata
|
|
38136
|
+
}
|
|
38137
|
+
});
|
|
38138
|
+
}
|
|
38139
|
+
})),
|
|
38140
|
+
warnings: [],
|
|
38141
|
+
request: { body: args },
|
|
38142
|
+
response: { headers: responseHeaders }
|
|
38143
|
+
};
|
|
38144
|
+
}
|
|
38145
|
+
}
|
|
38146
|
+
|
|
38147
|
+
// ../packages/internal/src/openrouter-ai-sdk/completion/convert-to-openrouter-completion-prompt.ts
|
|
38148
|
+
function convertToOpenRouterCompletionPrompt({
|
|
38149
|
+
prompt: prompt2,
|
|
38150
|
+
inputFormat,
|
|
38151
|
+
user = "user",
|
|
38152
|
+
assistant = "assistant"
|
|
38153
|
+
}) {
|
|
38154
|
+
if (inputFormat === "prompt" && prompt2.length === 1 && prompt2[0] && prompt2[0].role === "user" && prompt2[0].content.length === 1 && prompt2[0].content[0] && prompt2[0].content[0].type === "text") {
|
|
38155
|
+
return { prompt: prompt2[0].content[0].text };
|
|
38156
|
+
}
|
|
38157
|
+
let text = "";
|
|
38158
|
+
if (prompt2[0] && prompt2[0].role === "system") {
|
|
38159
|
+
text += `${prompt2[0].content}
|
|
38160
|
+
|
|
38161
|
+
`;
|
|
38162
|
+
prompt2 = prompt2.slice(1);
|
|
38163
|
+
}
|
|
38164
|
+
for (const { role, content } of prompt2) {
|
|
38165
|
+
switch (role) {
|
|
38166
|
+
case "system": {
|
|
38167
|
+
throw new InvalidPromptError({
|
|
38168
|
+
message: `Unexpected system message in prompt: ${content}`,
|
|
38169
|
+
prompt: prompt2
|
|
38170
|
+
});
|
|
38171
|
+
}
|
|
38172
|
+
case "user": {
|
|
38173
|
+
const userMessage2 = content.map((part) => {
|
|
38174
|
+
switch (part.type) {
|
|
38175
|
+
case "text": {
|
|
38176
|
+
return part.text;
|
|
38177
|
+
}
|
|
38178
|
+
case "file": {
|
|
38179
|
+
throw new UnsupportedFunctionalityError({
|
|
38180
|
+
functionality: "file attachments"
|
|
38181
|
+
});
|
|
38182
|
+
}
|
|
38183
|
+
default: {
|
|
38184
|
+
return "";
|
|
38185
|
+
}
|
|
38186
|
+
}
|
|
38187
|
+
}).join("");
|
|
38188
|
+
text += `${user}:
|
|
38189
|
+
${userMessage2}
|
|
38190
|
+
|
|
38191
|
+
`;
|
|
38192
|
+
break;
|
|
38193
|
+
}
|
|
38194
|
+
case "assistant": {
|
|
38195
|
+
const assistantMessage2 = content.map((part) => {
|
|
38196
|
+
switch (part.type) {
|
|
38197
|
+
case "text": {
|
|
38198
|
+
return part.text;
|
|
38199
|
+
}
|
|
38200
|
+
case "tool-call": {
|
|
38201
|
+
throw new UnsupportedFunctionalityError({
|
|
38202
|
+
functionality: "tool-call messages"
|
|
38203
|
+
});
|
|
38204
|
+
}
|
|
38205
|
+
case "tool-result": {
|
|
38206
|
+
throw new UnsupportedFunctionalityError({
|
|
38207
|
+
functionality: "tool-result messages"
|
|
38208
|
+
});
|
|
38209
|
+
}
|
|
38210
|
+
case "reasoning": {
|
|
38211
|
+
throw new UnsupportedFunctionalityError({
|
|
38212
|
+
functionality: "reasoning messages"
|
|
38213
|
+
});
|
|
38214
|
+
}
|
|
38215
|
+
case "file": {
|
|
38216
|
+
throw new UnsupportedFunctionalityError({
|
|
38217
|
+
functionality: "file attachments"
|
|
38218
|
+
});
|
|
38219
|
+
}
|
|
38220
|
+
default: {
|
|
38221
|
+
return "";
|
|
38222
|
+
}
|
|
38223
|
+
}
|
|
38224
|
+
}).join("");
|
|
38225
|
+
text += `${assistant}:
|
|
38226
|
+
${assistantMessage2}
|
|
38227
|
+
|
|
38228
|
+
`;
|
|
38229
|
+
break;
|
|
38230
|
+
}
|
|
38231
|
+
case "tool": {
|
|
38232
|
+
throw new UnsupportedFunctionalityError({
|
|
38233
|
+
functionality: "tool messages"
|
|
38234
|
+
});
|
|
38235
|
+
}
|
|
38236
|
+
default: {
|
|
38237
|
+
break;
|
|
38238
|
+
}
|
|
38239
|
+
}
|
|
38240
|
+
}
|
|
38241
|
+
text += `${assistant}:
|
|
38242
|
+
`;
|
|
38243
|
+
return {
|
|
38244
|
+
prompt: text
|
|
38245
|
+
};
|
|
38246
|
+
}
|
|
38247
|
+
|
|
38248
|
+
// ../packages/internal/src/openrouter-ai-sdk/completion/schemas.ts
|
|
38249
|
+
import { z as z74 } from "zod/v4";
|
|
38250
|
+
var OpenRouterCompletionChunkSchema = z74.union([
|
|
38251
|
+
z74.object({
|
|
38252
|
+
id: z74.string().optional(),
|
|
38253
|
+
model: z74.string().optional(),
|
|
38254
|
+
choices: z74.array(z74.object({
|
|
38255
|
+
text: z74.string(),
|
|
38256
|
+
reasoning: z74.string().nullish().optional(),
|
|
38257
|
+
reasoning_details: ReasoningDetailArraySchema.nullish(),
|
|
38258
|
+
finish_reason: z74.string().nullish(),
|
|
38259
|
+
index: z74.number().nullish(),
|
|
38260
|
+
logprobs: z74.object({
|
|
38261
|
+
tokens: z74.array(z74.string()),
|
|
38262
|
+
token_logprobs: z74.array(z74.number()),
|
|
38263
|
+
top_logprobs: z74.array(z74.record(z74.string(), z74.number())).nullable()
|
|
38264
|
+
}).nullable().optional()
|
|
38265
|
+
})),
|
|
38266
|
+
usage: z74.object({
|
|
38267
|
+
prompt_tokens: z74.number(),
|
|
38268
|
+
prompt_tokens_details: z74.object({
|
|
38269
|
+
cached_tokens: z74.number()
|
|
38270
|
+
}).nullish(),
|
|
38271
|
+
completion_tokens: z74.number(),
|
|
38272
|
+
completion_tokens_details: z74.object({
|
|
38273
|
+
reasoning_tokens: z74.number()
|
|
38274
|
+
}).nullish(),
|
|
38275
|
+
total_tokens: z74.number(),
|
|
38276
|
+
cost: z74.number().optional()
|
|
38277
|
+
}).nullish()
|
|
38278
|
+
}),
|
|
38279
|
+
OpenRouterErrorResponseSchema
|
|
38280
|
+
]);
|
|
38281
|
+
|
|
38282
|
+
// ../packages/internal/src/openrouter-ai-sdk/completion/index.ts
|
|
38283
|
+
class OpenRouterCompletionLanguageModel {
|
|
38284
|
+
specificationVersion = "v2";
|
|
38285
|
+
provider = "openrouter";
|
|
38286
|
+
modelId;
|
|
38287
|
+
supportedUrls = {
|
|
38288
|
+
"image/*": [
|
|
38289
|
+
/^data:image\/[a-zA-Z]+;base64,/,
|
|
38290
|
+
/^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)$/i
|
|
38291
|
+
],
|
|
38292
|
+
"text/*": [/^data:text\//, /^https?:\/\/.+$/],
|
|
38293
|
+
"application/*": [/^data:application\//, /^https?:\/\/.+$/]
|
|
38294
|
+
};
|
|
38295
|
+
defaultObjectGenerationMode = undefined;
|
|
38296
|
+
settings;
|
|
38297
|
+
config;
|
|
38298
|
+
constructor(modelId, settings, config) {
|
|
38299
|
+
this.modelId = modelId;
|
|
38300
|
+
this.settings = settings;
|
|
38301
|
+
this.config = config;
|
|
38302
|
+
}
|
|
38303
|
+
getArgs({
|
|
38304
|
+
prompt: prompt2,
|
|
38305
|
+
maxOutputTokens,
|
|
38306
|
+
temperature,
|
|
38307
|
+
topP,
|
|
38308
|
+
frequencyPenalty,
|
|
38309
|
+
presencePenalty,
|
|
38310
|
+
seed,
|
|
38311
|
+
responseFormat,
|
|
38312
|
+
topK,
|
|
38313
|
+
stopSequences,
|
|
38314
|
+
tools,
|
|
38315
|
+
toolChoice
|
|
38316
|
+
}) {
|
|
38317
|
+
const { prompt: completionPrompt } = convertToOpenRouterCompletionPrompt({
|
|
38318
|
+
prompt: prompt2,
|
|
38319
|
+
inputFormat: "prompt"
|
|
38320
|
+
});
|
|
38321
|
+
if (tools?.length) {
|
|
38322
|
+
throw new UnsupportedFunctionalityError({
|
|
38323
|
+
functionality: "tools"
|
|
38324
|
+
});
|
|
38325
|
+
}
|
|
38326
|
+
if (toolChoice) {
|
|
38327
|
+
throw new UnsupportedFunctionalityError({
|
|
38328
|
+
functionality: "toolChoice"
|
|
38329
|
+
});
|
|
38330
|
+
}
|
|
38331
|
+
return {
|
|
38332
|
+
model: this.modelId,
|
|
38333
|
+
models: this.settings.models,
|
|
38334
|
+
logit_bias: this.settings.logitBias,
|
|
38335
|
+
logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : undefined : undefined,
|
|
38336
|
+
suffix: this.settings.suffix,
|
|
38337
|
+
user: this.settings.user,
|
|
38338
|
+
max_tokens: maxOutputTokens,
|
|
38339
|
+
temperature,
|
|
38340
|
+
top_p: topP,
|
|
38341
|
+
frequency_penalty: frequencyPenalty,
|
|
38342
|
+
presence_penalty: presencePenalty,
|
|
38343
|
+
seed,
|
|
38344
|
+
...this.modelId === "x-ai/grok-code-fast-1" ? {} : { stop: stopSequences },
|
|
38345
|
+
response_format: responseFormat,
|
|
38346
|
+
top_k: topK,
|
|
38347
|
+
prompt: completionPrompt,
|
|
38348
|
+
include_reasoning: this.settings.includeReasoning,
|
|
38349
|
+
reasoning: this.settings.reasoning,
|
|
38350
|
+
...this.config.extraBody,
|
|
38351
|
+
...this.settings.extraBody
|
|
38352
|
+
};
|
|
38353
|
+
}
|
|
38354
|
+
async doGenerate(options) {
|
|
38355
|
+
const providerOptions = options.providerOptions || {};
|
|
38356
|
+
const openrouterOptions = providerOptions.openrouter || {};
|
|
38357
|
+
const args = {
|
|
38358
|
+
...this.getArgs(options),
|
|
38359
|
+
...openrouterOptions
|
|
38360
|
+
};
|
|
38361
|
+
const { value: response, responseHeaders } = await postJsonToApi({
|
|
38362
|
+
url: this.config.url({
|
|
38363
|
+
path: "/completions",
|
|
38364
|
+
modelId: this.modelId
|
|
38365
|
+
}),
|
|
38366
|
+
headers: combineHeaders(this.config.headers(), options.headers),
|
|
38367
|
+
body: args,
|
|
38368
|
+
failedResponseHandler: openrouterFailedResponseHandler,
|
|
38369
|
+
successfulResponseHandler: createJsonResponseHandler(OpenRouterCompletionChunkSchema),
|
|
38370
|
+
abortSignal: options.abortSignal,
|
|
38371
|
+
fetch: this.config.fetch
|
|
38372
|
+
});
|
|
38373
|
+
if ("error" in response) {
|
|
38374
|
+
throw new Error(`${response.error.message}`);
|
|
38375
|
+
}
|
|
38376
|
+
const choice = response.choices[0];
|
|
38377
|
+
if (!choice) {
|
|
38378
|
+
throw new Error("No choice in OpenRouter completion response");
|
|
38379
|
+
}
|
|
38380
|
+
return {
|
|
38381
|
+
content: [
|
|
38382
|
+
{
|
|
38383
|
+
type: "text",
|
|
38384
|
+
text: choice.text ?? ""
|
|
38385
|
+
}
|
|
38386
|
+
],
|
|
38387
|
+
finishReason: mapOpenRouterFinishReason(choice.finish_reason),
|
|
38388
|
+
usage: {
|
|
38389
|
+
inputTokens: response.usage?.prompt_tokens ?? 0,
|
|
38390
|
+
outputTokens: response.usage?.completion_tokens ?? 0,
|
|
38391
|
+
totalTokens: (response.usage?.prompt_tokens ?? 0) + (response.usage?.completion_tokens ?? 0),
|
|
38392
|
+
reasoningTokens: response.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
38393
|
+
cachedInputTokens: response.usage?.prompt_tokens_details?.cached_tokens ?? 0
|
|
38394
|
+
},
|
|
38395
|
+
warnings: [],
|
|
38396
|
+
response: {
|
|
38397
|
+
headers: responseHeaders
|
|
38398
|
+
}
|
|
38399
|
+
};
|
|
38400
|
+
}
|
|
38401
|
+
async doStream(options) {
|
|
38402
|
+
const providerOptions = options.providerOptions || {};
|
|
38403
|
+
const openrouterOptions = providerOptions.openrouter || {};
|
|
38404
|
+
const args = {
|
|
38405
|
+
...this.getArgs(options),
|
|
38406
|
+
...openrouterOptions
|
|
38407
|
+
};
|
|
38408
|
+
const { value: response, responseHeaders } = await postJsonToApi({
|
|
38409
|
+
url: this.config.url({
|
|
38410
|
+
path: "/completions",
|
|
38411
|
+
modelId: this.modelId
|
|
38412
|
+
}),
|
|
38413
|
+
headers: combineHeaders(this.config.headers(), options.headers),
|
|
38414
|
+
body: {
|
|
38415
|
+
...args,
|
|
38416
|
+
stream: true,
|
|
38417
|
+
stream_options: this.config.compatibility === "strict" ? { include_usage: true } : undefined
|
|
38418
|
+
},
|
|
38419
|
+
failedResponseHandler: openrouterFailedResponseHandler,
|
|
38420
|
+
successfulResponseHandler: createEventSourceResponseHandler(OpenRouterCompletionChunkSchema),
|
|
38421
|
+
abortSignal: options.abortSignal,
|
|
38422
|
+
fetch: this.config.fetch
|
|
38423
|
+
});
|
|
38424
|
+
let finishReason = "other";
|
|
38425
|
+
const usage = {
|
|
38426
|
+
inputTokens: Number.NaN,
|
|
38427
|
+
outputTokens: Number.NaN,
|
|
38428
|
+
totalTokens: Number.NaN,
|
|
38429
|
+
reasoningTokens: Number.NaN,
|
|
38430
|
+
cachedInputTokens: Number.NaN
|
|
38431
|
+
};
|
|
38432
|
+
const openrouterUsage = {};
|
|
38433
|
+
return {
|
|
38434
|
+
stream: response.pipeThrough(new TransformStream({
|
|
38435
|
+
transform(chunk, controller) {
|
|
38436
|
+
if (!chunk.success) {
|
|
38437
|
+
finishReason = "error";
|
|
38438
|
+
controller.enqueue({ type: "error", error: chunk.error });
|
|
38439
|
+
return;
|
|
38440
|
+
}
|
|
38441
|
+
const value = chunk.value;
|
|
38442
|
+
if ("error" in value) {
|
|
38443
|
+
finishReason = "error";
|
|
38444
|
+
controller.enqueue({ type: "error", error: value.error });
|
|
38445
|
+
return;
|
|
38446
|
+
}
|
|
38447
|
+
if (value.usage != null) {
|
|
38448
|
+
usage.inputTokens = value.usage.prompt_tokens;
|
|
38449
|
+
usage.outputTokens = value.usage.completion_tokens;
|
|
38450
|
+
usage.totalTokens = value.usage.prompt_tokens + value.usage.completion_tokens;
|
|
38451
|
+
openrouterUsage.promptTokens = value.usage.prompt_tokens;
|
|
38452
|
+
if (value.usage.prompt_tokens_details) {
|
|
38453
|
+
const cachedInputTokens = value.usage.prompt_tokens_details.cached_tokens ?? 0;
|
|
38454
|
+
usage.cachedInputTokens = cachedInputTokens;
|
|
38455
|
+
openrouterUsage.promptTokensDetails = {
|
|
38456
|
+
cachedTokens: cachedInputTokens
|
|
38457
|
+
};
|
|
38458
|
+
}
|
|
38459
|
+
openrouterUsage.completionTokens = value.usage.completion_tokens;
|
|
38460
|
+
if (value.usage.completion_tokens_details) {
|
|
38461
|
+
const reasoningTokens = value.usage.completion_tokens_details.reasoning_tokens ?? 0;
|
|
38462
|
+
usage.reasoningTokens = reasoningTokens;
|
|
38463
|
+
openrouterUsage.completionTokensDetails = {
|
|
38464
|
+
reasoningTokens
|
|
38465
|
+
};
|
|
38466
|
+
}
|
|
38467
|
+
if (value.usage.cost !== undefined) {
|
|
38468
|
+
openrouterUsage.cost = value.usage.cost;
|
|
38469
|
+
}
|
|
38470
|
+
openrouterUsage.totalTokens = value.usage.total_tokens;
|
|
38471
|
+
}
|
|
38472
|
+
const choice = value.choices[0];
|
|
38473
|
+
if (choice?.finish_reason != null) {
|
|
38474
|
+
finishReason = mapOpenRouterFinishReason(choice.finish_reason);
|
|
38475
|
+
}
|
|
38476
|
+
if (choice?.text != null) {
|
|
38477
|
+
controller.enqueue({
|
|
38478
|
+
type: "text-delta",
|
|
38479
|
+
delta: choice.text,
|
|
38480
|
+
id: generateId()
|
|
38481
|
+
});
|
|
38482
|
+
}
|
|
38483
|
+
},
|
|
38484
|
+
flush(controller) {
|
|
38485
|
+
controller.enqueue({
|
|
38486
|
+
type: "finish",
|
|
38487
|
+
finishReason,
|
|
38488
|
+
usage,
|
|
38489
|
+
providerMetadata: {
|
|
38490
|
+
openrouter: {
|
|
38491
|
+
usage: openrouterUsage
|
|
38492
|
+
}
|
|
38493
|
+
}
|
|
38494
|
+
});
|
|
38495
|
+
}
|
|
38496
|
+
})),
|
|
38497
|
+
response: {
|
|
38498
|
+
headers: responseHeaders
|
|
38499
|
+
}
|
|
38500
|
+
};
|
|
38501
|
+
}
|
|
38502
|
+
}
|
|
38503
|
+
|
|
38504
|
+
// ../packages/internal/src/openrouter-ai-sdk/provider.ts
|
|
38505
|
+
function createOpenRouter(options = {}) {
|
|
38506
|
+
const baseURL = withoutTrailingSlash(options.baseURL ?? options.baseUrl) ?? "https://openrouter.ai/api/v1";
|
|
38507
|
+
const compatibility = options.compatibility ?? "compatible";
|
|
38508
|
+
const getHeaders = () => ({
|
|
38509
|
+
Authorization: `Bearer ${loadApiKey({
|
|
38510
|
+
apiKey: options.apiKey,
|
|
38511
|
+
environmentVariableName: "OPENROUTER_API_KEY",
|
|
38512
|
+
description: "OpenRouter"
|
|
38513
|
+
})}`,
|
|
38514
|
+
...options.headers
|
|
38515
|
+
});
|
|
38516
|
+
const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
|
|
38517
|
+
provider: "openrouter.chat",
|
|
38518
|
+
url: ({ path: path4 }) => `${baseURL}${path4}`,
|
|
38519
|
+
headers: getHeaders,
|
|
38520
|
+
compatibility,
|
|
38521
|
+
fetch: options.fetch,
|
|
38522
|
+
extraBody: options.extraBody
|
|
38523
|
+
});
|
|
38524
|
+
const createCompletionModel = (modelId, settings = {}) => new OpenRouterCompletionLanguageModel(modelId, settings, {
|
|
38525
|
+
provider: "openrouter.completion",
|
|
38526
|
+
url: ({ path: path4 }) => `${baseURL}${path4}`,
|
|
38527
|
+
headers: getHeaders,
|
|
38528
|
+
compatibility,
|
|
38529
|
+
fetch: options.fetch,
|
|
38530
|
+
extraBody: options.extraBody
|
|
38531
|
+
});
|
|
38532
|
+
const createLanguageModel = (modelId, settings) => {
|
|
38533
|
+
if (new.target) {
|
|
38534
|
+
throw new Error("The OpenRouter model function cannot be called with the new keyword.");
|
|
38535
|
+
}
|
|
38536
|
+
if (modelId === "openai/gpt-3.5-turbo-instruct") {
|
|
38537
|
+
return createCompletionModel(modelId, settings);
|
|
38538
|
+
}
|
|
38539
|
+
return createChatModel(modelId, settings);
|
|
38540
|
+
};
|
|
38541
|
+
const provider = (modelId, settings) => createLanguageModel(modelId, settings);
|
|
38542
|
+
provider.languageModel = createLanguageModel;
|
|
38543
|
+
provider.chat = createChatModel;
|
|
38544
|
+
provider.completion = createCompletionModel;
|
|
38545
|
+
return provider;
|
|
38546
|
+
}
|
|
38547
|
+
var openrouter = createOpenRouter({
|
|
38548
|
+
compatibility: "strict"
|
|
37108
38549
|
});
|
|
37109
|
-
var processEnv = getProcessEnv();
|
|
37110
38550
|
|
|
37111
|
-
// src/
|
|
37112
|
-
|
|
37113
|
-
|
|
37114
|
-
|
|
37115
|
-
|
|
37116
|
-
|
|
37117
|
-
|
|
37118
|
-
|
|
37119
|
-
|
|
38551
|
+
// src/credentials.ts
|
|
38552
|
+
import fs from "fs";
|
|
38553
|
+
import path4 from "node:path";
|
|
38554
|
+
import os2 from "os";
|
|
38555
|
+
|
|
38556
|
+
// ../common/src/util/credentials.ts
|
|
38557
|
+
import { z as z75 } from "zod/v4";
|
|
38558
|
+
var userSchema = z75.object({
|
|
38559
|
+
id: z75.string(),
|
|
38560
|
+
email: z75.string(),
|
|
38561
|
+
name: z75.string().nullable(),
|
|
38562
|
+
authToken: z75.string(),
|
|
38563
|
+
fingerprintId: z75.string(),
|
|
38564
|
+
fingerprintHash: z75.string()
|
|
37120
38565
|
});
|
|
37121
|
-
var getLevelCodeApiKeyFromEnv = () => {
|
|
37122
|
-
return process.env[API_KEY_ENV_VAR];
|
|
37123
|
-
};
|
|
37124
|
-
var getSystemProcessEnv = () => {
|
|
37125
|
-
return process.env;
|
|
37126
|
-
};
|
|
37127
|
-
var getByokOpenrouterApiKeyFromEnv = () => {
|
|
37128
|
-
return process.env[BYOK_OPENROUTER_ENV_VAR];
|
|
37129
|
-
};
|
|
37130
|
-
var getClaudeOAuthTokenFromEnv = () => {
|
|
37131
|
-
return process.env[CLAUDE_OAUTH_TOKEN_ENV_VAR];
|
|
37132
|
-
};
|
|
37133
38566
|
|
|
37134
38567
|
// src/credentials.ts
|
|
37135
|
-
|
|
37136
|
-
|
|
37137
|
-
|
|
37138
|
-
|
|
37139
|
-
|
|
38568
|
+
import { z as z76 } from "zod/v4";
|
|
38569
|
+
var claudeOAuthSchema = z76.object({
|
|
38570
|
+
accessToken: z76.string(),
|
|
38571
|
+
refreshToken: z76.string(),
|
|
38572
|
+
expiresAt: z76.number(),
|
|
38573
|
+
connectedAt: z76.number()
|
|
37140
38574
|
});
|
|
37141
|
-
var credentialsFileSchema =
|
|
38575
|
+
var credentialsFileSchema = z76.object({
|
|
37142
38576
|
default: userSchema.optional(),
|
|
37143
38577
|
claudeOAuth: claudeOAuthSchema.optional()
|
|
37144
38578
|
});
|
|
@@ -37346,6 +38780,15 @@ async function fetchClaudeOAuthResetTime(accessToken) {
|
|
|
37346
38780
|
return null;
|
|
37347
38781
|
}
|
|
37348
38782
|
}
|
|
38783
|
+
function createDirectOpenRouterModel(openRouterApiKey, model) {
|
|
38784
|
+
const provider = createOpenRouter({ apiKey: openRouterApiKey, compatibility: "strict" });
|
|
38785
|
+
return provider.chat(model);
|
|
38786
|
+
}
|
|
38787
|
+
function createDirectAnthropicModel(anthropicApiKey, model) {
|
|
38788
|
+
const anthropicModelId = toAnthropicModelId(model);
|
|
38789
|
+
const anthropic = createAnthropic({ apiKey: anthropicApiKey });
|
|
38790
|
+
return anthropic(anthropicModelId);
|
|
38791
|
+
}
|
|
37349
38792
|
async function getModelForRequest(params2) {
|
|
37350
38793
|
const { apiKey, model, skipClaudeOAuth } = params2;
|
|
37351
38794
|
if (!skipClaudeOAuth && !isClaudeOAuthRateLimited() && isClaudeModel(model)) {
|
|
@@ -37357,6 +38800,16 @@ async function getModelForRequest(params2) {
|
|
|
37357
38800
|
};
|
|
37358
38801
|
}
|
|
37359
38802
|
}
|
|
38803
|
+
if (isStandaloneMode()) {
|
|
38804
|
+
const openRouterKey = getOpenRouterApiKeyFromEnv();
|
|
38805
|
+
if (openRouterKey) {
|
|
38806
|
+
return { model: createDirectOpenRouterModel(openRouterKey, model), isClaudeOAuth: false };
|
|
38807
|
+
}
|
|
38808
|
+
const anthropicKey = getAnthropicApiKeyFromEnv();
|
|
38809
|
+
if (anthropicKey) {
|
|
38810
|
+
return { model: createDirectAnthropicModel(anthropicKey, model), isClaudeOAuth: false };
|
|
38811
|
+
}
|
|
38812
|
+
}
|
|
37360
38813
|
return {
|
|
37361
38814
|
model: createLevelCodeBackendModel(apiKey, model),
|
|
37362
38815
|
isClaudeOAuth: false
|
|
@@ -38547,7 +40000,7 @@ function parseFile(parser, query, sourceCode) {
|
|
|
38547
40000
|
|
|
38548
40001
|
// src/run-state.ts
|
|
38549
40002
|
var import_lodash17 = __toESM(require_lodash(), 1);
|
|
38550
|
-
import
|
|
40003
|
+
import z78 from "zod/v4";
|
|
38551
40004
|
|
|
38552
40005
|
// src/agents/load-agents.ts
|
|
38553
40006
|
import fs5 from "fs";
|
|
@@ -38789,21 +40242,21 @@ function isValidSkillName(name14) {
|
|
|
38789
40242
|
}
|
|
38790
40243
|
|
|
38791
40244
|
// ../common/src/types/skill.ts
|
|
38792
|
-
import { z as
|
|
38793
|
-
var SkillMetadataSchema =
|
|
38794
|
-
var SkillFrontmatterSchema =
|
|
38795
|
-
name:
|
|
38796
|
-
description:
|
|
38797
|
-
license:
|
|
40245
|
+
import { z as z77 } from "zod/v4";
|
|
40246
|
+
var SkillMetadataSchema = z77.record(z77.string(), z77.string());
|
|
40247
|
+
var SkillFrontmatterSchema = z77.object({
|
|
40248
|
+
name: z77.string().min(1).max(SKILL_NAME_MAX_LENGTH).regex(SKILL_NAME_REGEX, "Name must be lowercase alphanumeric with single hyphen separators"),
|
|
40249
|
+
description: z77.string().min(1).max(SKILL_DESCRIPTION_MAX_LENGTH),
|
|
40250
|
+
license: z77.string().optional(),
|
|
38798
40251
|
metadata: SkillMetadataSchema.optional()
|
|
38799
40252
|
});
|
|
38800
|
-
var SkillDefinitionSchema =
|
|
38801
|
-
name:
|
|
38802
|
-
description:
|
|
38803
|
-
license:
|
|
40253
|
+
var SkillDefinitionSchema = z77.object({
|
|
40254
|
+
name: z77.string(),
|
|
40255
|
+
description: z77.string(),
|
|
40256
|
+
license: z77.string().optional(),
|
|
38804
40257
|
metadata: SkillMetadataSchema.optional(),
|
|
38805
|
-
content:
|
|
38806
|
-
filePath:
|
|
40258
|
+
content: z77.string(),
|
|
40259
|
+
filePath: z77.string()
|
|
38807
40260
|
});
|
|
38808
40261
|
|
|
38809
40262
|
// src/skills/load-skills.ts
|
|
@@ -38943,7 +40396,7 @@ function processAgentDefinitions(agentDefinitions) {
|
|
|
38943
40396
|
}
|
|
38944
40397
|
function processCustomToolDefinitions(customToolDefinitions) {
|
|
38945
40398
|
return Object.fromEntries(customToolDefinitions.map((toolDefinition) => {
|
|
38946
|
-
const jsonSchema =
|
|
40399
|
+
const jsonSchema = z78.toJSONSchema(toolDefinition.inputSchema, {
|
|
38947
40400
|
io: "input"
|
|
38948
40401
|
});
|
|
38949
40402
|
delete jsonSchema["$schema"];
|
|
@@ -39341,11 +40794,11 @@ function buildFileTree(filePaths) {
|
|
|
39341
40794
|
// src/tools/change-file.ts
|
|
39342
40795
|
import path12 from "path";
|
|
39343
40796
|
import { applyPatch } from "diff";
|
|
39344
|
-
import
|
|
39345
|
-
var FileChangeSchema2 =
|
|
39346
|
-
type:
|
|
39347
|
-
path:
|
|
39348
|
-
content:
|
|
40797
|
+
import z79 from "zod/v4";
|
|
40798
|
+
var FileChangeSchema2 = z79.object({
|
|
40799
|
+
type: z79.enum(["patch", "file"]),
|
|
40800
|
+
path: z79.string(),
|
|
40801
|
+
content: z79.string()
|
|
39349
40802
|
});
|
|
39350
40803
|
function containsUpwardTraversal(dirPath) {
|
|
39351
40804
|
const normalized = path12.normalize(dirPath);
|
|
@@ -40738,7 +42191,7 @@ init_paths();
|
|
|
40738
42191
|
class LevelCodeClient {
|
|
40739
42192
|
options;
|
|
40740
42193
|
constructor(options) {
|
|
40741
|
-
const foundApiKey = options.apiKey ?? getLevelCodeApiKeyFromEnv();
|
|
42194
|
+
const foundApiKey = options.apiKey ?? getLevelCodeApiKeyFromEnv() ?? (isStandaloneMode() ? "standalone-mode" : undefined);
|
|
40742
42195
|
if (!foundApiKey) {
|
|
40743
42196
|
throw new Error(`LevelCode API key not found. Please provide an apiKey in the constructor of LevelCodeClient or set the ${API_KEY_ENV_VAR} environment variable.`);
|
|
40744
42197
|
}
|
|
@@ -40759,6 +42212,9 @@ Provide a handleEvent function to handle this error.`);
|
|
|
40759
42212
|
return run({ ...this.options, ...options });
|
|
40760
42213
|
}
|
|
40761
42214
|
async checkConnection() {
|
|
42215
|
+
if (isStandaloneMode()) {
|
|
42216
|
+
return true;
|
|
42217
|
+
}
|
|
40762
42218
|
try {
|
|
40763
42219
|
const response = await fetch(`${WEBSITE_URL}/api/healthz`, {
|
|
40764
42220
|
method: "GET",
|
|
@@ -40824,9 +42280,9 @@ import fs9 from "fs";
|
|
|
40824
42280
|
import fsPromises from "fs/promises";
|
|
40825
42281
|
import os7 from "os";
|
|
40826
42282
|
import path18 from "path";
|
|
40827
|
-
import { z as
|
|
40828
|
-
var mcpFileSchema =
|
|
40829
|
-
mcpServers:
|
|
42283
|
+
import { z as z80 } from "zod/v4";
|
|
42284
|
+
var mcpFileSchema = z80.object({
|
|
42285
|
+
mcpServers: z80.record(z80.string(), mcpConfigSchema).default(() => ({}))
|
|
40830
42286
|
});
|
|
40831
42287
|
var envKey = "env";
|
|
40832
42288
|
var processEnv2 = process[envKey];
|
|
@@ -40976,6 +42432,7 @@ export {
|
|
|
40976
42432
|
loadMCPConfigSync,
|
|
40977
42433
|
loadMCPConfig,
|
|
40978
42434
|
loadLocalAgents,
|
|
42435
|
+
isStandaloneMode,
|
|
40979
42436
|
isRetryableStatusCode,
|
|
40980
42437
|
isKnowledgeFile,
|
|
40981
42438
|
isClaudeOAuthValid,
|
|
@@ -40983,6 +42440,7 @@ export {
|
|
|
40983
42440
|
getValidClaudeOAuthCredentials,
|
|
40984
42441
|
getUserInfoFromApiKey,
|
|
40985
42442
|
getUserCredentials,
|
|
42443
|
+
getOpenRouterApiKeyFromEnv,
|
|
40986
42444
|
getFiles,
|
|
40987
42445
|
getFileTokenScores,
|
|
40988
42446
|
getErrorStatusCode,
|
|
@@ -41019,5 +42477,5 @@ export {
|
|
|
41019
42477
|
IS_DEV
|
|
41020
42478
|
};
|
|
41021
42479
|
|
|
41022
|
-
//# debugId=
|
|
42480
|
+
//# debugId=E2ADC0F32EFD708C64756E2164756E21
|
|
41023
42481
|
//# sourceMappingURL=index.mjs.map
|