@levelcode/sdk 0.0.2 → 0.0.4
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/CHANGELOG.md +1 -1
- package/README.md +4 -4
- package/dist/index.cjs +1658 -192
- package/dist/index.cjs.map +30 -17
- package/dist/index.d.ts +3443 -0
- package/dist/index.mjs +1658 -192
- package/dist/index.mjs.map +30 -17
- package/dist/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/dist/vendor/ripgrep/arm64-linux/rg +0 -0
- package/dist/vendor/ripgrep/x64-darwin/rg +0 -0
- package/dist/vendor/ripgrep/x64-linux/rg +0 -0
- package/dist/vendor/ripgrep/x64-win32/rg.exe +0 -0
- package/dist/wasm/tree-sitter-c-sharp.wasm +0 -0
- package/dist/wasm/tree-sitter-cpp.wasm +0 -0
- package/dist/wasm/tree-sitter-go.wasm +0 -0
- package/dist/wasm/tree-sitter-java.wasm +0 -0
- package/dist/wasm/tree-sitter-javascript.wasm +0 -0
- package/dist/wasm/tree-sitter-python.wasm +0 -0
- package/dist/wasm/tree-sitter-ruby.wasm +0 -0
- package/dist/wasm/tree-sitter-rust.wasm +0 -0
- package/dist/wasm/tree-sitter-tsx.wasm +0 -0
- package/dist/wasm/tree-sitter-typescript.wasm +0 -0
- package/dist/wasm/tree-sitter.wasm +0 -0
- 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("https://levelcode.vercel.app"),
|
|
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: "https://levelcode.vercel.app",
|
|
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
|
}
|
|
@@ -19611,7 +19619,7 @@ When the user requests a new git commit, please follow these steps closely:
|
|
|
19611
19619
|
4. **Create the commit, ending with this specific footer:**
|
|
19612
19620
|
\`\`\`
|
|
19613
19621
|
Generated with LevelCode \uD83E\uDD16
|
|
19614
|
-
Co-Authored-By: LevelCode <noreply@levelcode.
|
|
19622
|
+
Co-Authored-By: LevelCode <noreply@levelcode.vercel.app>
|
|
19615
19623
|
\`\`\`
|
|
19616
19624
|
To maintain proper formatting, use cross-platform compatible commit messages:
|
|
19617
19625
|
|
|
@@ -19621,7 +19629,7 @@ When the user requests a new git commit, please follow these steps closely:
|
|
|
19621
19629
|
Your commit message here.
|
|
19622
19630
|
|
|
19623
19631
|
\uD83E\uDD16 Generated with LevelCode
|
|
19624
|
-
Co-Authored-By: LevelCode <noreply@levelcode.
|
|
19632
|
+
Co-Authored-By: LevelCode <noreply@levelcode.vercel.app>
|
|
19625
19633
|
EOF
|
|
19626
19634
|
)"
|
|
19627
19635
|
\`\`\`
|
|
@@ -19631,7 +19639,7 @@ When the user requests a new git commit, please follow these steps closely:
|
|
|
19631
19639
|
git commit -m "Your commit message here.
|
|
19632
19640
|
|
|
19633
19641
|
\uD83E\uDD16 Generated with LevelCode
|
|
19634
|
-
Co-Authored-By: LevelCode <noreply@levelcode.
|
|
19642
|
+
Co-Authored-By: LevelCode <noreply@levelcode.vercel.app>"
|
|
19635
19643
|
\`\`\`
|
|
19636
19644
|
|
|
19637
19645
|
Always detect the platform and use the appropriate syntax. HEREDOC syntax (\`<<'EOF'\`) only works in bash/Unix shells and will fail on Windows Command Prompt.
|
|
@@ -19698,7 +19706,7 @@ ${$getNativeToolCallExampleString({
|
|
|
19698
19706
|
command: `git commit -m "Your commit message here.
|
|
19699
19707
|
|
|
19700
19708
|
\uD83E\uDD16 Generated with LevelCode
|
|
19701
|
-
Co-Authored-By: LevelCode <noreply@levelcode.
|
|
19709
|
+
Co-Authored-By: LevelCode <noreply@levelcode.vercel.app>"`
|
|
19702
19710
|
},
|
|
19703
19711
|
endsAgentStep: endsAgentStep18
|
|
19704
19712
|
})}
|
|
@@ -35154,7 +35162,158 @@ 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 getOpenRouterBaseUrlFromEnv = () => {
|
|
35302
|
+
return process.env.OPENROUTER_BASE_URL;
|
|
35303
|
+
};
|
|
35304
|
+
var getAnthropicApiKeyFromEnv = () => {
|
|
35305
|
+
return process.env.ANTHROPIC_API_KEY;
|
|
35306
|
+
};
|
|
35307
|
+
var getAnthropicBaseUrlFromEnv = () => {
|
|
35308
|
+
return process.env.ANTHROPIC_BASE_URL;
|
|
35309
|
+
};
|
|
35310
|
+
var isStandaloneMode = () => {
|
|
35311
|
+
const appUrl = process.env.NEXT_PUBLIC_LEVELCODE_APP_URL;
|
|
35312
|
+
if (!appUrl)
|
|
35313
|
+
return true;
|
|
35314
|
+
const hasDirectKey = !!getOpenRouterApiKeyFromEnv() || !!getAnthropicApiKeyFromEnv();
|
|
35315
|
+
return hasDirectKey && !getLevelCodeApiKeyFromEnv();
|
|
35316
|
+
};
|
|
35158
35317
|
|
|
35159
35318
|
// src/retry-config.ts
|
|
35160
35319
|
var MAX_RETRIES_PER_MESSAGE = 3;
|
|
@@ -35197,6 +35356,10 @@ async function fetchWithRetry(url, options, logger2) {
|
|
|
35197
35356
|
throw lastError ?? new Error("Request failed after retries");
|
|
35198
35357
|
}
|
|
35199
35358
|
async function getUserInfoFromApiKey(params2) {
|
|
35359
|
+
if (isStandaloneMode()) {
|
|
35360
|
+
const standaloneUser = { id: "standalone-user", email: "standalone@local" };
|
|
35361
|
+
return Object.fromEntries(params2.fields.map((field) => [field, standaloneUser[field] ?? null]));
|
|
35362
|
+
}
|
|
35200
35363
|
const { apiKey, fields, logger: logger2 } = params2;
|
|
35201
35364
|
const cached = userInfoCache[apiKey];
|
|
35202
35365
|
if (cached === null) {
|
|
@@ -35259,6 +35422,9 @@ async function getUserInfoFromApiKey(params2) {
|
|
|
35259
35422
|
return Object.fromEntries(fields.map((field) => [field, userInfo[field]]));
|
|
35260
35423
|
}
|
|
35261
35424
|
async function fetchAgentFromDatabase(params2) {
|
|
35425
|
+
if (isStandaloneMode()) {
|
|
35426
|
+
return null;
|
|
35427
|
+
}
|
|
35262
35428
|
const { apiKey, parsedAgentId, logger: logger2 } = params2;
|
|
35263
35429
|
const { publisherId, agentId, version: version2 } = parsedAgentId;
|
|
35264
35430
|
const url = new URL(`/api/v1/agents/${publisherId}/${agentId}/${version2 ? version2 : "latest"}`, WEBSITE_URL);
|
|
@@ -35312,6 +35478,9 @@ async function fetchAgentFromDatabase(params2) {
|
|
|
35312
35478
|
}
|
|
35313
35479
|
}
|
|
35314
35480
|
async function startAgentRun(params2) {
|
|
35481
|
+
if (isStandaloneMode()) {
|
|
35482
|
+
return crypto.randomUUID();
|
|
35483
|
+
}
|
|
35315
35484
|
const { apiKey, agentId, ancestorRunIds, logger: logger2 } = params2;
|
|
35316
35485
|
const url = new URL(`/api/v1/agent-runs`, WEBSITE_URL);
|
|
35317
35486
|
try {
|
|
@@ -35341,6 +35510,9 @@ async function startAgentRun(params2) {
|
|
|
35341
35510
|
}
|
|
35342
35511
|
}
|
|
35343
35512
|
async function finishAgentRun(params2) {
|
|
35513
|
+
if (isStandaloneMode()) {
|
|
35514
|
+
return;
|
|
35515
|
+
}
|
|
35344
35516
|
const {
|
|
35345
35517
|
apiKey,
|
|
35346
35518
|
runId,
|
|
@@ -35375,6 +35547,9 @@ async function finishAgentRun(params2) {
|
|
|
35375
35547
|
}
|
|
35376
35548
|
}
|
|
35377
35549
|
async function addAgentStep2(params2) {
|
|
35550
|
+
if (isStandaloneMode()) {
|
|
35551
|
+
return crypto.randomUUID();
|
|
35552
|
+
}
|
|
35378
35553
|
const {
|
|
35379
35554
|
apiKey,
|
|
35380
35555
|
agentRunId,
|
|
@@ -35496,60 +35671,6 @@ import {
|
|
|
35496
35671
|
import path5 from "path";
|
|
35497
35672
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
35498
35673
|
|
|
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
35674
|
// ../node_modules/@ai-sdk/provider/dist/index.mjs
|
|
35554
35675
|
var marker = "vercel.ai.error";
|
|
35555
35676
|
var symbol = Symbol.for(marker);
|
|
@@ -35950,6 +36071,38 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
|
|
|
35950
36071
|
return Object.fromEntries(normalizedHeaders.entries());
|
|
35951
36072
|
}
|
|
35952
36073
|
var VERSION = "3.0.20";
|
|
36074
|
+
function loadApiKey({
|
|
36075
|
+
apiKey,
|
|
36076
|
+
environmentVariableName,
|
|
36077
|
+
apiKeyParameterName = "apiKey",
|
|
36078
|
+
description: description31
|
|
36079
|
+
}) {
|
|
36080
|
+
if (typeof apiKey === "string") {
|
|
36081
|
+
return apiKey;
|
|
36082
|
+
}
|
|
36083
|
+
if (apiKey != null) {
|
|
36084
|
+
throw new LoadAPIKeyError({
|
|
36085
|
+
message: `${description31} API key must be a string.`
|
|
36086
|
+
});
|
|
36087
|
+
}
|
|
36088
|
+
if (typeof process === "undefined") {
|
|
36089
|
+
throw new LoadAPIKeyError({
|
|
36090
|
+
message: `${description31} API key is missing. Pass it using the '${apiKeyParameterName}' parameter. Environment variables is not supported in this environment.`
|
|
36091
|
+
});
|
|
36092
|
+
}
|
|
36093
|
+
apiKey = process.env[environmentVariableName];
|
|
36094
|
+
if (apiKey == null) {
|
|
36095
|
+
throw new LoadAPIKeyError({
|
|
36096
|
+
message: `${description31} API key is missing. Pass it using the '${apiKeyParameterName}' parameter or the ${environmentVariableName} environment variable.`
|
|
36097
|
+
});
|
|
36098
|
+
}
|
|
36099
|
+
if (typeof apiKey !== "string") {
|
|
36100
|
+
throw new LoadAPIKeyError({
|
|
36101
|
+
message: `${description31} API key must be a string. The value of the ${environmentVariableName} environment variable is not a string.`
|
|
36102
|
+
});
|
|
36103
|
+
}
|
|
36104
|
+
return apiKey;
|
|
36105
|
+
}
|
|
35953
36106
|
var suspectProtoRx = /"__proto__"\s*:/;
|
|
35954
36107
|
var suspectConstructorRx = /"constructor"\s*:/;
|
|
35955
36108
|
function _parse(text) {
|
|
@@ -36326,6 +36479,9 @@ function convertUint8ArrayToBase64(array) {
|
|
|
36326
36479
|
function convertToBase64(value) {
|
|
36327
36480
|
return value instanceof Uint8Array ? convertUint8ArrayToBase64(value) : value;
|
|
36328
36481
|
}
|
|
36482
|
+
function withoutTrailingSlash(url) {
|
|
36483
|
+
return url == null ? undefined : url.replace(/\/$/, "");
|
|
36484
|
+
}
|
|
36329
36485
|
|
|
36330
36486
|
// ../packages/internal/src/openai-compatible/chat/openai-compatible-chat-language-model.ts
|
|
36331
36487
|
import { z as z69 } from "zod/v4";
|
|
@@ -37034,111 +37190,1395 @@ var createOpenAICompatibleChatChunkSchema = (errorSchema) => z69.union([
|
|
|
37034
37190
|
]);
|
|
37035
37191
|
// ../packages/internal/src/openai-compatible/version.ts
|
|
37036
37192
|
var VERSION2 = typeof __PACKAGE_VERSION__ !== "undefined" ? __PACKAGE_VERSION__ : "0.0.0-test";
|
|
37037
|
-
// src/
|
|
37038
|
-
|
|
37039
|
-
|
|
37040
|
-
|
|
37193
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/is-url.ts
|
|
37194
|
+
function isUrl({
|
|
37195
|
+
url,
|
|
37196
|
+
protocols
|
|
37197
|
+
}) {
|
|
37198
|
+
try {
|
|
37199
|
+
const urlObj = new URL(url);
|
|
37200
|
+
return protocols.has(urlObj.protocol);
|
|
37201
|
+
} catch (_) {
|
|
37202
|
+
return false;
|
|
37203
|
+
}
|
|
37204
|
+
}
|
|
37041
37205
|
|
|
37042
|
-
// ../
|
|
37206
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/file-url-utils.ts
|
|
37207
|
+
function getFileUrl({
|
|
37208
|
+
part,
|
|
37209
|
+
defaultMediaType
|
|
37210
|
+
}) {
|
|
37211
|
+
if (part.data instanceof Uint8Array) {
|
|
37212
|
+
const base64 = convertUint8ArrayToBase64(part.data);
|
|
37213
|
+
return `data:${part.mediaType ?? defaultMediaType};base64,${base64}`;
|
|
37214
|
+
}
|
|
37215
|
+
const stringUrl = part.data.toString();
|
|
37216
|
+
if (isUrl({
|
|
37217
|
+
url: stringUrl,
|
|
37218
|
+
protocols: new Set(["http:", "https:"])
|
|
37219
|
+
})) {
|
|
37220
|
+
return stringUrl;
|
|
37221
|
+
}
|
|
37222
|
+
return stringUrl.startsWith("data:") ? stringUrl : `data:${part.mediaType ?? defaultMediaType};base64,${stringUrl}`;
|
|
37223
|
+
}
|
|
37224
|
+
|
|
37225
|
+
// ../packages/internal/src/openrouter-ai-sdk/schemas/reasoning-details.ts
|
|
37043
37226
|
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()
|
|
37227
|
+
var ReasoningDetailSummarySchema = z70.object({
|
|
37228
|
+
type: z70.literal("reasoning.summary" /* Summary */),
|
|
37229
|
+
summary: z70.string()
|
|
37051
37230
|
});
|
|
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
|
|
37231
|
+
var ReasoningDetailEncryptedSchema = z70.object({
|
|
37232
|
+
type: z70.literal("reasoning.encrypted" /* Encrypted */),
|
|
37233
|
+
data: z70.string()
|
|
37075
37234
|
});
|
|
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
|
-
|
|
37235
|
+
var ReasoningDetailTextSchema = z70.object({
|
|
37236
|
+
type: z70.literal("reasoning.text" /* Text */),
|
|
37237
|
+
text: z70.string().nullish(),
|
|
37238
|
+
signature: z70.string().nullish()
|
|
37239
|
+
});
|
|
37240
|
+
var ReasoningDetailUnionSchema = z70.union([
|
|
37241
|
+
ReasoningDetailSummarySchema,
|
|
37242
|
+
ReasoningDetailEncryptedSchema,
|
|
37243
|
+
ReasoningDetailTextSchema
|
|
37244
|
+
]);
|
|
37245
|
+
var ReasoningDetailsWithUnknownSchema = z70.union([
|
|
37246
|
+
ReasoningDetailUnionSchema,
|
|
37247
|
+
z70.unknown().transform(() => null)
|
|
37248
|
+
]);
|
|
37249
|
+
var ReasoningDetailArraySchema = z70.array(ReasoningDetailsWithUnknownSchema).transform((d) => d.filter((d2) => !!d2));
|
|
37250
|
+
|
|
37251
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/convert-to-openrouter-chat-messages.ts
|
|
37252
|
+
function getCacheControl(providerMetadata) {
|
|
37253
|
+
const anthropic = providerMetadata?.anthropic;
|
|
37254
|
+
const openrouter = providerMetadata?.openrouter;
|
|
37255
|
+
return openrouter?.cacheControl ?? openrouter?.cache_control ?? anthropic?.cacheControl ?? anthropic?.cache_control;
|
|
37256
|
+
}
|
|
37257
|
+
function convertToOpenRouterChatMessages(prompt2) {
|
|
37258
|
+
const messages = [];
|
|
37259
|
+
for (const { role, content, providerOptions } of prompt2) {
|
|
37260
|
+
switch (role) {
|
|
37261
|
+
case "system": {
|
|
37262
|
+
messages.push({
|
|
37263
|
+
role: "system",
|
|
37264
|
+
content,
|
|
37265
|
+
cache_control: getCacheControl(providerOptions)
|
|
37266
|
+
});
|
|
37267
|
+
break;
|
|
37268
|
+
}
|
|
37269
|
+
case "user": {
|
|
37270
|
+
const messageCacheControl = getCacheControl(providerOptions);
|
|
37271
|
+
const contentParts = content.map((part) => {
|
|
37272
|
+
const cacheControl = getCacheControl(part.providerOptions) ?? messageCacheControl;
|
|
37273
|
+
switch (part.type) {
|
|
37274
|
+
case "text":
|
|
37275
|
+
return {
|
|
37276
|
+
type: "text",
|
|
37277
|
+
text: part.text,
|
|
37278
|
+
cache_control: cacheControl
|
|
37279
|
+
};
|
|
37280
|
+
case "file": {
|
|
37281
|
+
if (part.mediaType?.startsWith("image/")) {
|
|
37282
|
+
const url = getFileUrl({
|
|
37283
|
+
part,
|
|
37284
|
+
defaultMediaType: "image/jpeg"
|
|
37285
|
+
});
|
|
37286
|
+
return {
|
|
37287
|
+
type: "image_url",
|
|
37288
|
+
image_url: {
|
|
37289
|
+
url
|
|
37290
|
+
},
|
|
37291
|
+
cache_control: cacheControl
|
|
37292
|
+
};
|
|
37293
|
+
}
|
|
37294
|
+
const fileName = String(part.providerOptions?.openrouter?.filename ?? part.filename ?? "");
|
|
37295
|
+
const fileData = getFileUrl({
|
|
37296
|
+
part,
|
|
37297
|
+
defaultMediaType: "application/pdf"
|
|
37298
|
+
});
|
|
37299
|
+
if (isUrl({
|
|
37300
|
+
url: fileData,
|
|
37301
|
+
protocols: new Set(["http:", "https:"])
|
|
37302
|
+
})) {
|
|
37303
|
+
return {
|
|
37304
|
+
type: "file",
|
|
37305
|
+
file: {
|
|
37306
|
+
filename: fileName,
|
|
37307
|
+
file_data: fileData
|
|
37308
|
+
}
|
|
37309
|
+
};
|
|
37310
|
+
}
|
|
37311
|
+
return {
|
|
37312
|
+
type: "file",
|
|
37313
|
+
file: {
|
|
37314
|
+
filename: fileName,
|
|
37315
|
+
file_data: fileData
|
|
37316
|
+
},
|
|
37317
|
+
cache_control: cacheControl
|
|
37318
|
+
};
|
|
37319
|
+
}
|
|
37320
|
+
default: {
|
|
37321
|
+
return {
|
|
37322
|
+
type: "text",
|
|
37323
|
+
text: "",
|
|
37324
|
+
cache_control: cacheControl
|
|
37325
|
+
};
|
|
37326
|
+
}
|
|
37327
|
+
}
|
|
37328
|
+
});
|
|
37329
|
+
messages.push({
|
|
37330
|
+
role: "user",
|
|
37331
|
+
content: contentParts
|
|
37332
|
+
});
|
|
37333
|
+
break;
|
|
37334
|
+
}
|
|
37335
|
+
case "assistant": {
|
|
37336
|
+
let text = "";
|
|
37337
|
+
let reasoning = "";
|
|
37338
|
+
const reasoningDetails = [];
|
|
37339
|
+
const toolCalls2 = [];
|
|
37340
|
+
for (const part of content) {
|
|
37341
|
+
switch (part.type) {
|
|
37342
|
+
case "text": {
|
|
37343
|
+
text += part.text;
|
|
37344
|
+
break;
|
|
37345
|
+
}
|
|
37346
|
+
case "tool-call": {
|
|
37347
|
+
toolCalls2.push({
|
|
37348
|
+
id: part.toolCallId,
|
|
37349
|
+
type: "function",
|
|
37350
|
+
function: {
|
|
37351
|
+
name: part.toolName,
|
|
37352
|
+
arguments: JSON.stringify(part.input)
|
|
37353
|
+
}
|
|
37354
|
+
});
|
|
37355
|
+
break;
|
|
37356
|
+
}
|
|
37357
|
+
case "reasoning": {
|
|
37358
|
+
reasoning += part.text;
|
|
37359
|
+
reasoningDetails.push({
|
|
37360
|
+
type: "reasoning.text" /* Text */,
|
|
37361
|
+
text: part.text
|
|
37362
|
+
});
|
|
37363
|
+
break;
|
|
37364
|
+
}
|
|
37365
|
+
case "file":
|
|
37366
|
+
break;
|
|
37367
|
+
default: {
|
|
37368
|
+
break;
|
|
37369
|
+
}
|
|
37370
|
+
}
|
|
37371
|
+
}
|
|
37372
|
+
messages.push({
|
|
37373
|
+
role: "assistant",
|
|
37374
|
+
content: text,
|
|
37375
|
+
tool_calls: toolCalls2.length > 0 ? toolCalls2 : undefined,
|
|
37376
|
+
reasoning: reasoning || undefined,
|
|
37377
|
+
reasoning_details: reasoningDetails.length > 0 ? reasoningDetails : undefined,
|
|
37378
|
+
cache_control: getCacheControl(providerOptions)
|
|
37379
|
+
});
|
|
37380
|
+
break;
|
|
37381
|
+
}
|
|
37382
|
+
case "tool": {
|
|
37383
|
+
for (const toolResponse of content) {
|
|
37384
|
+
const content2 = getToolResultContent(toolResponse);
|
|
37385
|
+
messages.push({
|
|
37386
|
+
role: "tool",
|
|
37387
|
+
tool_call_id: toolResponse.toolCallId,
|
|
37388
|
+
content: content2,
|
|
37389
|
+
cache_control: getCacheControl(providerOptions) ?? getCacheControl(toolResponse.providerOptions)
|
|
37390
|
+
});
|
|
37391
|
+
}
|
|
37392
|
+
break;
|
|
37393
|
+
}
|
|
37394
|
+
default: {
|
|
37395
|
+
break;
|
|
37396
|
+
}
|
|
37397
|
+
}
|
|
37398
|
+
}
|
|
37399
|
+
return messages;
|
|
37400
|
+
}
|
|
37401
|
+
function getToolResultContent(input) {
|
|
37402
|
+
return input.output.type === "text" ? input.output.value : JSON.stringify(input.output.value);
|
|
37403
|
+
}
|
|
37404
|
+
|
|
37405
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/get-tool-choice.ts
|
|
37406
|
+
import { z as z71 } from "zod/v4";
|
|
37407
|
+
var ChatCompletionToolChoiceSchema = z71.union([
|
|
37408
|
+
z71.literal("auto"),
|
|
37409
|
+
z71.literal("none"),
|
|
37410
|
+
z71.literal("required"),
|
|
37411
|
+
z71.object({
|
|
37412
|
+
type: z71.literal("function"),
|
|
37413
|
+
function: z71.object({
|
|
37414
|
+
name: z71.string()
|
|
37415
|
+
})
|
|
37416
|
+
})
|
|
37417
|
+
]);
|
|
37418
|
+
function getChatCompletionToolChoice(toolChoice) {
|
|
37419
|
+
switch (toolChoice.type) {
|
|
37420
|
+
case "auto":
|
|
37421
|
+
case "none":
|
|
37422
|
+
case "required":
|
|
37423
|
+
return toolChoice.type;
|
|
37424
|
+
case "tool": {
|
|
37425
|
+
return {
|
|
37426
|
+
type: "function",
|
|
37427
|
+
function: { name: toolChoice.toolName }
|
|
37428
|
+
};
|
|
37429
|
+
}
|
|
37430
|
+
default: {
|
|
37431
|
+
throw new Error(`Invalid tool choice type: ${toolChoice}`);
|
|
37432
|
+
}
|
|
37433
|
+
}
|
|
37434
|
+
}
|
|
37435
|
+
|
|
37436
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/schemas.ts
|
|
37437
|
+
import { z as z73 } from "zod/v4";
|
|
37438
|
+
|
|
37439
|
+
// ../packages/internal/src/openrouter-ai-sdk/schemas/error-response.ts
|
|
37440
|
+
import { z as z72 } from "zod/v4";
|
|
37441
|
+
var OpenRouterErrorResponseSchema = z72.object({
|
|
37442
|
+
error: z72.object({
|
|
37443
|
+
code: z72.union([z72.string(), z72.number()]).nullable().optional().default(null),
|
|
37444
|
+
message: z72.string(),
|
|
37445
|
+
type: z72.string().nullable().optional().default(null),
|
|
37446
|
+
param: z72.any().nullable().optional().default(null)
|
|
37447
|
+
})
|
|
37448
|
+
});
|
|
37449
|
+
var openrouterFailedResponseHandler = createJsonErrorResponseHandler({
|
|
37450
|
+
errorSchema: OpenRouterErrorResponseSchema,
|
|
37451
|
+
errorToMessage: (data) => data.error.message
|
|
37452
|
+
});
|
|
37453
|
+
|
|
37454
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/schemas.ts
|
|
37455
|
+
var OpenRouterChatCompletionBaseResponseSchema = z73.object({
|
|
37456
|
+
id: z73.string().optional(),
|
|
37457
|
+
model: z73.string().optional(),
|
|
37458
|
+
provider: z73.string().optional(),
|
|
37459
|
+
usage: z73.object({
|
|
37460
|
+
prompt_tokens: z73.number(),
|
|
37461
|
+
prompt_tokens_details: z73.object({
|
|
37462
|
+
cached_tokens: z73.number()
|
|
37463
|
+
}).nullish(),
|
|
37464
|
+
completion_tokens: z73.number(),
|
|
37465
|
+
completion_tokens_details: z73.object({
|
|
37466
|
+
reasoning_tokens: z73.number()
|
|
37467
|
+
}).nullish(),
|
|
37468
|
+
total_tokens: z73.number(),
|
|
37469
|
+
cost: z73.number().optional(),
|
|
37470
|
+
cost_details: z73.object({
|
|
37471
|
+
upstream_inference_cost: z73.number().nullish()
|
|
37472
|
+
}).nullish()
|
|
37473
|
+
}).nullish()
|
|
37474
|
+
});
|
|
37475
|
+
var OpenRouterNonStreamChatCompletionResponseSchema = OpenRouterChatCompletionBaseResponseSchema.extend({
|
|
37476
|
+
choices: z73.array(z73.object({
|
|
37477
|
+
message: z73.object({
|
|
37478
|
+
role: z73.literal("assistant"),
|
|
37479
|
+
content: z73.string().nullable().optional(),
|
|
37480
|
+
reasoning: z73.string().nullable().optional(),
|
|
37481
|
+
reasoning_details: ReasoningDetailArraySchema.nullish(),
|
|
37482
|
+
tool_calls: z73.array(z73.object({
|
|
37483
|
+
id: z73.string().optional().nullable(),
|
|
37484
|
+
type: z73.literal("function"),
|
|
37485
|
+
function: z73.object({
|
|
37486
|
+
name: z73.string(),
|
|
37487
|
+
arguments: z73.string()
|
|
37488
|
+
})
|
|
37489
|
+
})).optional(),
|
|
37490
|
+
annotations: z73.array(z73.object({
|
|
37491
|
+
type: z73.enum(["url_citation"]),
|
|
37492
|
+
url_citation: z73.object({
|
|
37493
|
+
end_index: z73.number(),
|
|
37494
|
+
start_index: z73.number(),
|
|
37495
|
+
title: z73.string(),
|
|
37496
|
+
url: z73.string(),
|
|
37497
|
+
content: z73.string().optional()
|
|
37498
|
+
})
|
|
37499
|
+
})).nullish()
|
|
37500
|
+
}),
|
|
37501
|
+
index: z73.number().nullish(),
|
|
37502
|
+
logprobs: z73.object({
|
|
37503
|
+
content: z73.array(z73.object({
|
|
37504
|
+
token: z73.string(),
|
|
37505
|
+
logprob: z73.number(),
|
|
37506
|
+
top_logprobs: z73.array(z73.object({
|
|
37507
|
+
token: z73.string(),
|
|
37508
|
+
logprob: z73.number()
|
|
37509
|
+
}))
|
|
37510
|
+
})).nullable()
|
|
37511
|
+
}).nullable().optional(),
|
|
37512
|
+
finish_reason: z73.string().optional().nullable()
|
|
37513
|
+
}))
|
|
37514
|
+
});
|
|
37515
|
+
var OpenRouterStreamChatCompletionChunkSchema = z73.union([
|
|
37516
|
+
OpenRouterChatCompletionBaseResponseSchema.extend({
|
|
37517
|
+
choices: z73.array(z73.object({
|
|
37518
|
+
delta: z73.object({
|
|
37519
|
+
role: z73.enum(["assistant"]).optional(),
|
|
37520
|
+
content: z73.string().nullish(),
|
|
37521
|
+
reasoning: z73.string().nullish().optional(),
|
|
37522
|
+
reasoning_details: ReasoningDetailArraySchema.nullish(),
|
|
37523
|
+
tool_calls: z73.array(z73.object({
|
|
37524
|
+
index: z73.number().nullish(),
|
|
37525
|
+
id: z73.string().nullish(),
|
|
37526
|
+
type: z73.literal("function").optional(),
|
|
37527
|
+
function: z73.object({
|
|
37528
|
+
name: z73.string().nullish(),
|
|
37529
|
+
arguments: z73.string().nullish()
|
|
37530
|
+
})
|
|
37531
|
+
})).nullish(),
|
|
37532
|
+
annotations: z73.array(z73.object({
|
|
37533
|
+
type: z73.enum(["url_citation"]),
|
|
37534
|
+
url_citation: z73.object({
|
|
37535
|
+
end_index: z73.number(),
|
|
37536
|
+
start_index: z73.number(),
|
|
37537
|
+
title: z73.string(),
|
|
37538
|
+
url: z73.string(),
|
|
37539
|
+
content: z73.string().optional()
|
|
37540
|
+
})
|
|
37541
|
+
})).nullish()
|
|
37542
|
+
}).nullish(),
|
|
37543
|
+
logprobs: z73.object({
|
|
37544
|
+
content: z73.array(z73.object({
|
|
37545
|
+
token: z73.string(),
|
|
37546
|
+
logprob: z73.number(),
|
|
37547
|
+
top_logprobs: z73.array(z73.object({
|
|
37548
|
+
token: z73.string(),
|
|
37549
|
+
logprob: z73.number()
|
|
37550
|
+
}))
|
|
37551
|
+
})).nullable()
|
|
37552
|
+
}).nullish(),
|
|
37553
|
+
finish_reason: z73.string().nullable().optional(),
|
|
37554
|
+
index: z73.number().nullish()
|
|
37555
|
+
}))
|
|
37556
|
+
}),
|
|
37557
|
+
OpenRouterErrorResponseSchema
|
|
37558
|
+
]);
|
|
37559
|
+
|
|
37560
|
+
// ../packages/internal/src/openrouter-ai-sdk/utils/map-finish-reason.ts
|
|
37561
|
+
function mapOpenRouterFinishReason(finishReason) {
|
|
37562
|
+
switch (finishReason) {
|
|
37563
|
+
case "stop":
|
|
37564
|
+
return "stop";
|
|
37565
|
+
case "length":
|
|
37566
|
+
return "length";
|
|
37567
|
+
case "content_filter":
|
|
37568
|
+
return "content-filter";
|
|
37569
|
+
case "function_call":
|
|
37570
|
+
case "tool_calls":
|
|
37571
|
+
return "tool-calls";
|
|
37572
|
+
default:
|
|
37573
|
+
return "unknown";
|
|
37574
|
+
}
|
|
37575
|
+
}
|
|
37576
|
+
|
|
37577
|
+
// ../packages/internal/src/openrouter-ai-sdk/chat/index.ts
|
|
37578
|
+
class OpenRouterChatLanguageModel {
|
|
37579
|
+
specificationVersion = "v2";
|
|
37580
|
+
provider = "openrouter";
|
|
37581
|
+
defaultObjectGenerationMode = "tool";
|
|
37582
|
+
modelId;
|
|
37583
|
+
supportedUrls = {
|
|
37584
|
+
"image/*": [
|
|
37585
|
+
/^data:image\/[a-zA-Z]+;base64,/,
|
|
37586
|
+
/^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)$/i
|
|
37587
|
+
],
|
|
37588
|
+
"application/*": [/^data:application\//, /^https?:\/\/.+$/]
|
|
37589
|
+
};
|
|
37590
|
+
settings;
|
|
37591
|
+
config;
|
|
37592
|
+
constructor(modelId, settings, config) {
|
|
37593
|
+
this.modelId = modelId;
|
|
37594
|
+
this.settings = settings;
|
|
37595
|
+
this.config = config;
|
|
37596
|
+
}
|
|
37597
|
+
getArgs({
|
|
37598
|
+
prompt: prompt2,
|
|
37599
|
+
maxOutputTokens,
|
|
37600
|
+
temperature,
|
|
37601
|
+
topP,
|
|
37602
|
+
frequencyPenalty,
|
|
37603
|
+
presencePenalty,
|
|
37604
|
+
seed,
|
|
37605
|
+
stopSequences,
|
|
37606
|
+
responseFormat,
|
|
37607
|
+
topK,
|
|
37608
|
+
tools,
|
|
37609
|
+
toolChoice
|
|
37610
|
+
}) {
|
|
37611
|
+
const baseArgs = {
|
|
37612
|
+
model: this.modelId,
|
|
37613
|
+
models: this.settings.models,
|
|
37614
|
+
logit_bias: this.settings.logitBias,
|
|
37615
|
+
logprobs: this.settings.logprobs === true || typeof this.settings.logprobs === "number" ? true : undefined,
|
|
37616
|
+
top_logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : undefined : undefined,
|
|
37617
|
+
user: this.settings.user,
|
|
37618
|
+
parallel_tool_calls: this.settings.parallelToolCalls,
|
|
37619
|
+
max_tokens: maxOutputTokens,
|
|
37620
|
+
temperature,
|
|
37621
|
+
top_p: topP,
|
|
37622
|
+
frequency_penalty: frequencyPenalty,
|
|
37623
|
+
presence_penalty: presencePenalty,
|
|
37624
|
+
seed,
|
|
37625
|
+
...this.modelId === "x-ai/grok-code-fast-1" ? {} : { stop: stopSequences },
|
|
37626
|
+
response_format: responseFormat,
|
|
37627
|
+
top_k: topK,
|
|
37628
|
+
messages: convertToOpenRouterChatMessages(prompt2),
|
|
37629
|
+
include_reasoning: this.settings.includeReasoning,
|
|
37630
|
+
reasoning: this.settings.reasoning,
|
|
37631
|
+
usage: this.settings.usage,
|
|
37632
|
+
plugins: this.settings.plugins,
|
|
37633
|
+
web_search_options: this.settings.web_search_options,
|
|
37634
|
+
provider: this.settings.provider,
|
|
37635
|
+
...this.config.extraBody,
|
|
37636
|
+
...this.settings.extraBody
|
|
37637
|
+
};
|
|
37638
|
+
if (responseFormat?.type === "json" && responseFormat.schema != null) {
|
|
37639
|
+
return {
|
|
37640
|
+
...baseArgs,
|
|
37641
|
+
response_format: {
|
|
37642
|
+
type: "json_schema",
|
|
37643
|
+
json_schema: {
|
|
37644
|
+
schema: responseFormat.schema,
|
|
37645
|
+
strict: true,
|
|
37646
|
+
name: responseFormat.name ?? "response",
|
|
37647
|
+
...responseFormat.description && {
|
|
37648
|
+
description: responseFormat.description
|
|
37649
|
+
}
|
|
37650
|
+
}
|
|
37651
|
+
}
|
|
37652
|
+
};
|
|
37653
|
+
}
|
|
37654
|
+
if (tools && tools.length > 0) {
|
|
37655
|
+
const mappedTools = tools.filter((tool) => tool.type === "function").map((tool) => ({
|
|
37656
|
+
type: "function",
|
|
37657
|
+
function: {
|
|
37658
|
+
name: tool.name,
|
|
37659
|
+
description: tool.description,
|
|
37660
|
+
parameters: tool.inputSchema
|
|
37661
|
+
}
|
|
37662
|
+
}));
|
|
37663
|
+
return {
|
|
37664
|
+
...baseArgs,
|
|
37665
|
+
tools: mappedTools,
|
|
37666
|
+
tool_choice: toolChoice ? getChatCompletionToolChoice(toolChoice) : undefined
|
|
37667
|
+
};
|
|
37668
|
+
}
|
|
37669
|
+
return baseArgs;
|
|
37670
|
+
}
|
|
37671
|
+
async doGenerate(options) {
|
|
37672
|
+
const providerOptions = options.providerOptions || {};
|
|
37673
|
+
const openrouterOptions = providerOptions.openrouter || {};
|
|
37674
|
+
const args = {
|
|
37675
|
+
...this.getArgs(options),
|
|
37676
|
+
...openrouterOptions
|
|
37677
|
+
};
|
|
37678
|
+
const { value: response, responseHeaders } = await postJsonToApi({
|
|
37679
|
+
url: this.config.url({
|
|
37680
|
+
path: "/chat/completions",
|
|
37681
|
+
modelId: this.modelId
|
|
37682
|
+
}),
|
|
37683
|
+
headers: combineHeaders(this.config.headers(), options.headers),
|
|
37684
|
+
body: args,
|
|
37685
|
+
failedResponseHandler: openrouterFailedResponseHandler,
|
|
37686
|
+
successfulResponseHandler: createJsonResponseHandler(OpenRouterNonStreamChatCompletionResponseSchema),
|
|
37687
|
+
abortSignal: options.abortSignal,
|
|
37688
|
+
fetch: this.config.fetch
|
|
37689
|
+
});
|
|
37690
|
+
const choice = response.choices[0];
|
|
37691
|
+
if (!choice) {
|
|
37692
|
+
throw new Error("No choice in response");
|
|
37693
|
+
}
|
|
37694
|
+
const usageInfo = response.usage ? {
|
|
37695
|
+
inputTokens: response.usage.prompt_tokens ?? 0,
|
|
37696
|
+
outputTokens: response.usage.completion_tokens ?? 0,
|
|
37697
|
+
totalTokens: (response.usage.prompt_tokens ?? 0) + (response.usage.completion_tokens ?? 0),
|
|
37698
|
+
reasoningTokens: response.usage.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
37699
|
+
cachedInputTokens: response.usage.prompt_tokens_details?.cached_tokens ?? 0
|
|
37700
|
+
} : {
|
|
37701
|
+
inputTokens: 0,
|
|
37702
|
+
outputTokens: 0,
|
|
37703
|
+
totalTokens: 0,
|
|
37704
|
+
reasoningTokens: 0,
|
|
37705
|
+
cachedInputTokens: 0
|
|
37706
|
+
};
|
|
37707
|
+
const reasoningDetails = choice.message.reasoning_details ?? [];
|
|
37708
|
+
const reasoning = reasoningDetails.length > 0 ? reasoningDetails.map((detail) => {
|
|
37709
|
+
switch (detail.type) {
|
|
37710
|
+
case "reasoning.text" /* Text */: {
|
|
37711
|
+
if (detail.text) {
|
|
37712
|
+
return {
|
|
37713
|
+
type: "reasoning",
|
|
37714
|
+
text: detail.text
|
|
37715
|
+
};
|
|
37716
|
+
}
|
|
37717
|
+
break;
|
|
37718
|
+
}
|
|
37719
|
+
case "reasoning.summary" /* Summary */: {
|
|
37720
|
+
if (detail.summary) {
|
|
37721
|
+
return {
|
|
37722
|
+
type: "reasoning",
|
|
37723
|
+
text: detail.summary
|
|
37724
|
+
};
|
|
37725
|
+
}
|
|
37726
|
+
break;
|
|
37727
|
+
}
|
|
37728
|
+
case "reasoning.encrypted" /* Encrypted */: {
|
|
37729
|
+
if (detail.data) {
|
|
37730
|
+
return {
|
|
37731
|
+
type: "reasoning",
|
|
37732
|
+
text: "[REDACTED]"
|
|
37733
|
+
};
|
|
37734
|
+
}
|
|
37735
|
+
break;
|
|
37736
|
+
}
|
|
37737
|
+
default: {}
|
|
37738
|
+
}
|
|
37739
|
+
return null;
|
|
37740
|
+
}).filter((p) => p !== null) : choice.message.reasoning ? [
|
|
37741
|
+
{
|
|
37742
|
+
type: "reasoning",
|
|
37743
|
+
text: choice.message.reasoning
|
|
37744
|
+
}
|
|
37745
|
+
] : [];
|
|
37746
|
+
const content = [];
|
|
37747
|
+
content.push(...reasoning);
|
|
37748
|
+
if (choice.message.content) {
|
|
37749
|
+
content.push({
|
|
37750
|
+
type: "text",
|
|
37751
|
+
text: choice.message.content
|
|
37752
|
+
});
|
|
37753
|
+
}
|
|
37754
|
+
if (choice.message.tool_calls) {
|
|
37755
|
+
for (const toolCall of choice.message.tool_calls) {
|
|
37756
|
+
content.push({
|
|
37757
|
+
type: "tool-call",
|
|
37758
|
+
toolCallId: toolCall.id ?? generateId(),
|
|
37759
|
+
toolName: toolCall.function.name,
|
|
37760
|
+
input: toolCall.function.arguments
|
|
37761
|
+
});
|
|
37762
|
+
}
|
|
37763
|
+
}
|
|
37764
|
+
if (choice.message.annotations) {
|
|
37765
|
+
for (const annotation of choice.message.annotations) {
|
|
37766
|
+
if (annotation.type === "url_citation") {
|
|
37767
|
+
content.push({
|
|
37768
|
+
type: "source",
|
|
37769
|
+
sourceType: "url",
|
|
37770
|
+
id: annotation.url_citation.url,
|
|
37771
|
+
url: annotation.url_citation.url,
|
|
37772
|
+
title: annotation.url_citation.title,
|
|
37773
|
+
providerMetadata: {
|
|
37774
|
+
openrouter: {
|
|
37775
|
+
content: annotation.url_citation.content || ""
|
|
37776
|
+
}
|
|
37777
|
+
}
|
|
37778
|
+
});
|
|
37779
|
+
}
|
|
37780
|
+
}
|
|
37781
|
+
}
|
|
37782
|
+
return {
|
|
37783
|
+
content,
|
|
37784
|
+
finishReason: mapOpenRouterFinishReason(choice.finish_reason),
|
|
37785
|
+
usage: usageInfo,
|
|
37786
|
+
warnings: [],
|
|
37787
|
+
providerMetadata: {
|
|
37788
|
+
openrouter: {
|
|
37789
|
+
provider: response.provider ?? "",
|
|
37790
|
+
usage: {
|
|
37791
|
+
promptTokens: usageInfo.inputTokens ?? 0,
|
|
37792
|
+
completionTokens: usageInfo.outputTokens ?? 0,
|
|
37793
|
+
totalTokens: usageInfo.totalTokens ?? 0,
|
|
37794
|
+
cost: response.usage?.cost,
|
|
37795
|
+
promptTokensDetails: {
|
|
37796
|
+
cachedTokens: response.usage?.prompt_tokens_details?.cached_tokens ?? 0
|
|
37797
|
+
},
|
|
37798
|
+
completionTokensDetails: {
|
|
37799
|
+
reasoningTokens: response.usage?.completion_tokens_details?.reasoning_tokens ?? 0
|
|
37800
|
+
},
|
|
37801
|
+
costDetails: {
|
|
37802
|
+
upstreamInferenceCost: response.usage?.cost_details?.upstream_inference_cost ?? 0
|
|
37803
|
+
}
|
|
37804
|
+
}
|
|
37805
|
+
}
|
|
37806
|
+
},
|
|
37807
|
+
request: { body: args },
|
|
37808
|
+
response: {
|
|
37809
|
+
id: response.id,
|
|
37810
|
+
modelId: response.model,
|
|
37811
|
+
headers: responseHeaders
|
|
37812
|
+
}
|
|
37813
|
+
};
|
|
37814
|
+
}
|
|
37815
|
+
async doStream(options) {
|
|
37816
|
+
const providerOptions = options.providerOptions || {};
|
|
37817
|
+
const openrouterOptions = providerOptions.openrouter || {};
|
|
37818
|
+
const args = {
|
|
37819
|
+
...this.getArgs(options),
|
|
37820
|
+
...openrouterOptions
|
|
37821
|
+
};
|
|
37822
|
+
const { value: response, responseHeaders } = await postJsonToApi({
|
|
37823
|
+
url: this.config.url({
|
|
37824
|
+
path: "/chat/completions",
|
|
37825
|
+
modelId: this.modelId
|
|
37826
|
+
}),
|
|
37827
|
+
headers: combineHeaders(this.config.headers(), options.headers),
|
|
37828
|
+
body: {
|
|
37829
|
+
...args,
|
|
37830
|
+
stream: true,
|
|
37831
|
+
stream_options: this.config.compatibility === "strict" ? {
|
|
37832
|
+
include_usage: true,
|
|
37833
|
+
...this.settings.usage?.include ? { include_usage: true } : {}
|
|
37834
|
+
} : undefined
|
|
37835
|
+
},
|
|
37836
|
+
failedResponseHandler: openrouterFailedResponseHandler,
|
|
37837
|
+
successfulResponseHandler: createEventSourceResponseHandler(OpenRouterStreamChatCompletionChunkSchema),
|
|
37838
|
+
abortSignal: options.abortSignal,
|
|
37839
|
+
fetch: this.config.fetch
|
|
37840
|
+
});
|
|
37841
|
+
const toolCalls2 = [];
|
|
37842
|
+
let finishReason = "other";
|
|
37843
|
+
const usage = {
|
|
37844
|
+
inputTokens: Number.NaN,
|
|
37845
|
+
outputTokens: Number.NaN,
|
|
37846
|
+
totalTokens: Number.NaN,
|
|
37847
|
+
reasoningTokens: Number.NaN,
|
|
37848
|
+
cachedInputTokens: Number.NaN
|
|
37849
|
+
};
|
|
37850
|
+
const openrouterUsage = {};
|
|
37851
|
+
let textStarted = false;
|
|
37852
|
+
let reasoningStarted = false;
|
|
37853
|
+
let textId;
|
|
37854
|
+
let reasoningId;
|
|
37855
|
+
let openrouterResponseId;
|
|
37856
|
+
let provider;
|
|
37857
|
+
return {
|
|
37858
|
+
stream: response.pipeThrough(new TransformStream({
|
|
37859
|
+
transform(chunk, controller) {
|
|
37860
|
+
if (!chunk.success) {
|
|
37861
|
+
finishReason = "error";
|
|
37862
|
+
controller.enqueue({ type: "error", error: chunk.error });
|
|
37863
|
+
return;
|
|
37864
|
+
}
|
|
37865
|
+
const value = chunk.value;
|
|
37866
|
+
if ("error" in value) {
|
|
37867
|
+
finishReason = "error";
|
|
37868
|
+
controller.enqueue({ type: "error", error: value.error });
|
|
37869
|
+
return;
|
|
37870
|
+
}
|
|
37871
|
+
if (value.provider) {
|
|
37872
|
+
provider = value.provider;
|
|
37873
|
+
}
|
|
37874
|
+
if (value.id) {
|
|
37875
|
+
openrouterResponseId = value.id;
|
|
37876
|
+
controller.enqueue({
|
|
37877
|
+
type: "response-metadata",
|
|
37878
|
+
id: value.id
|
|
37879
|
+
});
|
|
37880
|
+
}
|
|
37881
|
+
if (value.model) {
|
|
37882
|
+
controller.enqueue({
|
|
37883
|
+
type: "response-metadata",
|
|
37884
|
+
modelId: value.model
|
|
37885
|
+
});
|
|
37886
|
+
}
|
|
37887
|
+
if (value.usage != null) {
|
|
37888
|
+
usage.inputTokens = value.usage.prompt_tokens;
|
|
37889
|
+
usage.outputTokens = value.usage.completion_tokens;
|
|
37890
|
+
usage.totalTokens = value.usage.prompt_tokens + value.usage.completion_tokens;
|
|
37891
|
+
openrouterUsage.promptTokens = value.usage.prompt_tokens;
|
|
37892
|
+
if (value.usage.prompt_tokens_details) {
|
|
37893
|
+
const cachedInputTokens = value.usage.prompt_tokens_details.cached_tokens ?? 0;
|
|
37894
|
+
usage.cachedInputTokens = cachedInputTokens;
|
|
37895
|
+
openrouterUsage.promptTokensDetails = {
|
|
37896
|
+
cachedTokens: cachedInputTokens
|
|
37897
|
+
};
|
|
37898
|
+
}
|
|
37899
|
+
openrouterUsage.completionTokens = value.usage.completion_tokens;
|
|
37900
|
+
if (value.usage.completion_tokens_details) {
|
|
37901
|
+
const reasoningTokens = value.usage.completion_tokens_details.reasoning_tokens ?? 0;
|
|
37902
|
+
usage.reasoningTokens = reasoningTokens;
|
|
37903
|
+
openrouterUsage.completionTokensDetails = {
|
|
37904
|
+
reasoningTokens
|
|
37905
|
+
};
|
|
37906
|
+
}
|
|
37907
|
+
const upstreamInferenceCost = value.usage.cost_details?.upstream_inference_cost;
|
|
37908
|
+
if (upstreamInferenceCost != null && upstreamInferenceCost !== undefined) {
|
|
37909
|
+
openrouterUsage.costDetails = {
|
|
37910
|
+
upstreamInferenceCost
|
|
37911
|
+
};
|
|
37912
|
+
}
|
|
37913
|
+
if (value.usage.cost !== undefined) {
|
|
37914
|
+
openrouterUsage.cost = value.usage.cost;
|
|
37915
|
+
}
|
|
37916
|
+
openrouterUsage.totalTokens = value.usage.total_tokens;
|
|
37917
|
+
}
|
|
37918
|
+
const choice = value.choices[0];
|
|
37919
|
+
if (choice?.finish_reason != null) {
|
|
37920
|
+
finishReason = mapOpenRouterFinishReason(choice.finish_reason);
|
|
37921
|
+
}
|
|
37922
|
+
if (choice?.delta == null) {
|
|
37923
|
+
return;
|
|
37924
|
+
}
|
|
37925
|
+
const delta = choice.delta;
|
|
37926
|
+
const emitReasoningChunk = (chunkText) => {
|
|
37927
|
+
if (!reasoningStarted) {
|
|
37928
|
+
reasoningId = openrouterResponseId || generateId();
|
|
37929
|
+
controller.enqueue({
|
|
37930
|
+
type: "reasoning-start",
|
|
37931
|
+
id: reasoningId
|
|
37932
|
+
});
|
|
37933
|
+
reasoningStarted = true;
|
|
37934
|
+
}
|
|
37935
|
+
controller.enqueue({
|
|
37936
|
+
type: "reasoning-delta",
|
|
37937
|
+
delta: chunkText,
|
|
37938
|
+
id: reasoningId || generateId()
|
|
37939
|
+
});
|
|
37940
|
+
};
|
|
37941
|
+
if (delta.reasoning_details && delta.reasoning_details.length > 0) {
|
|
37942
|
+
for (const detail of delta.reasoning_details) {
|
|
37943
|
+
switch (detail.type) {
|
|
37944
|
+
case "reasoning.text" /* Text */: {
|
|
37945
|
+
if (detail.text) {
|
|
37946
|
+
emitReasoningChunk(detail.text);
|
|
37947
|
+
}
|
|
37948
|
+
break;
|
|
37949
|
+
}
|
|
37950
|
+
case "reasoning.encrypted" /* Encrypted */: {
|
|
37951
|
+
if (detail.data) {
|
|
37952
|
+
emitReasoningChunk("[REDACTED]");
|
|
37953
|
+
}
|
|
37954
|
+
break;
|
|
37955
|
+
}
|
|
37956
|
+
case "reasoning.summary" /* Summary */: {
|
|
37957
|
+
if (detail.summary) {
|
|
37958
|
+
emitReasoningChunk(detail.summary);
|
|
37959
|
+
}
|
|
37960
|
+
break;
|
|
37961
|
+
}
|
|
37962
|
+
default: {
|
|
37963
|
+
break;
|
|
37964
|
+
}
|
|
37965
|
+
}
|
|
37966
|
+
}
|
|
37967
|
+
} else if (delta.reasoning) {
|
|
37968
|
+
emitReasoningChunk(delta.reasoning);
|
|
37969
|
+
}
|
|
37970
|
+
if (delta.content) {
|
|
37971
|
+
if (reasoningStarted && !textStarted) {
|
|
37972
|
+
controller.enqueue({
|
|
37973
|
+
type: "reasoning-end",
|
|
37974
|
+
id: reasoningId || generateId()
|
|
37975
|
+
});
|
|
37976
|
+
reasoningStarted = false;
|
|
37977
|
+
}
|
|
37978
|
+
if (!textStarted) {
|
|
37979
|
+
textId = openrouterResponseId || generateId();
|
|
37980
|
+
controller.enqueue({
|
|
37981
|
+
type: "text-start",
|
|
37982
|
+
id: textId
|
|
37983
|
+
});
|
|
37984
|
+
textStarted = true;
|
|
37985
|
+
}
|
|
37986
|
+
controller.enqueue({
|
|
37987
|
+
type: "text-delta",
|
|
37988
|
+
delta: delta.content,
|
|
37989
|
+
id: textId || generateId()
|
|
37990
|
+
});
|
|
37991
|
+
}
|
|
37992
|
+
if (delta.annotations) {
|
|
37993
|
+
for (const annotation of delta.annotations) {
|
|
37994
|
+
if (annotation.type === "url_citation") {
|
|
37995
|
+
controller.enqueue({
|
|
37996
|
+
type: "source",
|
|
37997
|
+
sourceType: "url",
|
|
37998
|
+
id: annotation.url_citation.url,
|
|
37999
|
+
url: annotation.url_citation.url,
|
|
38000
|
+
title: annotation.url_citation.title,
|
|
38001
|
+
providerMetadata: {
|
|
38002
|
+
openrouter: {
|
|
38003
|
+
content: annotation.url_citation.content || ""
|
|
38004
|
+
}
|
|
38005
|
+
}
|
|
38006
|
+
});
|
|
38007
|
+
}
|
|
38008
|
+
}
|
|
38009
|
+
}
|
|
38010
|
+
if (delta.tool_calls != null) {
|
|
38011
|
+
for (const toolCallDelta of delta.tool_calls) {
|
|
38012
|
+
const index = toolCallDelta.index ?? toolCalls2.length - 1;
|
|
38013
|
+
if (toolCalls2[index] == null) {
|
|
38014
|
+
if (toolCallDelta.type !== "function") {
|
|
38015
|
+
throw new InvalidResponseDataError({
|
|
38016
|
+
data: toolCallDelta,
|
|
38017
|
+
message: `Expected 'function' type.`
|
|
38018
|
+
});
|
|
38019
|
+
}
|
|
38020
|
+
if (toolCallDelta.id == null) {
|
|
38021
|
+
throw new InvalidResponseDataError({
|
|
38022
|
+
data: toolCallDelta,
|
|
38023
|
+
message: `Expected 'id' to be a string.`
|
|
38024
|
+
});
|
|
38025
|
+
}
|
|
38026
|
+
if (toolCallDelta.function?.name == null) {
|
|
38027
|
+
throw new InvalidResponseDataError({
|
|
38028
|
+
data: toolCallDelta,
|
|
38029
|
+
message: `Expected 'function.name' to be a string.`
|
|
38030
|
+
});
|
|
38031
|
+
}
|
|
38032
|
+
toolCalls2[index] = {
|
|
38033
|
+
id: toolCallDelta.id,
|
|
38034
|
+
type: "function",
|
|
38035
|
+
function: {
|
|
38036
|
+
name: toolCallDelta.function.name,
|
|
38037
|
+
arguments: toolCallDelta.function.arguments ?? ""
|
|
38038
|
+
},
|
|
38039
|
+
inputStarted: false,
|
|
38040
|
+
sent: false
|
|
38041
|
+
};
|
|
38042
|
+
const toolCall2 = toolCalls2[index];
|
|
38043
|
+
if (toolCall2 == null) {
|
|
38044
|
+
throw new Error("Tool call is missing");
|
|
38045
|
+
}
|
|
38046
|
+
if (toolCall2.function?.name != null && toolCall2.function?.arguments != null && isParsableJson(toolCall2.function.arguments)) {
|
|
38047
|
+
toolCall2.inputStarted = true;
|
|
38048
|
+
controller.enqueue({
|
|
38049
|
+
type: "tool-input-start",
|
|
38050
|
+
id: toolCall2.id,
|
|
38051
|
+
toolName: toolCall2.function.name
|
|
38052
|
+
});
|
|
38053
|
+
controller.enqueue({
|
|
38054
|
+
type: "tool-input-delta",
|
|
38055
|
+
id: toolCall2.id,
|
|
38056
|
+
delta: toolCall2.function.arguments
|
|
38057
|
+
});
|
|
38058
|
+
controller.enqueue({
|
|
38059
|
+
type: "tool-input-end",
|
|
38060
|
+
id: toolCall2.id
|
|
38061
|
+
});
|
|
38062
|
+
controller.enqueue({
|
|
38063
|
+
type: "tool-call",
|
|
38064
|
+
toolCallId: toolCall2.id,
|
|
38065
|
+
toolName: toolCall2.function.name,
|
|
38066
|
+
input: toolCall2.function.arguments
|
|
38067
|
+
});
|
|
38068
|
+
toolCall2.sent = true;
|
|
38069
|
+
}
|
|
38070
|
+
continue;
|
|
38071
|
+
}
|
|
38072
|
+
const toolCall = toolCalls2[index];
|
|
38073
|
+
if (toolCall == null) {
|
|
38074
|
+
throw new Error("Tool call is missing");
|
|
38075
|
+
}
|
|
38076
|
+
if (!toolCall.inputStarted) {
|
|
38077
|
+
toolCall.inputStarted = true;
|
|
38078
|
+
controller.enqueue({
|
|
38079
|
+
type: "tool-input-start",
|
|
38080
|
+
id: toolCall.id,
|
|
38081
|
+
toolName: toolCall.function.name
|
|
38082
|
+
});
|
|
38083
|
+
}
|
|
38084
|
+
if (toolCallDelta.function?.arguments != null) {
|
|
38085
|
+
toolCall.function.arguments += toolCallDelta.function?.arguments ?? "";
|
|
38086
|
+
}
|
|
38087
|
+
controller.enqueue({
|
|
38088
|
+
type: "tool-input-delta",
|
|
38089
|
+
id: toolCall.id,
|
|
38090
|
+
delta: toolCallDelta.function.arguments ?? ""
|
|
38091
|
+
});
|
|
38092
|
+
if (toolCall.function?.name != null && toolCall.function?.arguments != null && isParsableJson(toolCall.function.arguments)) {
|
|
38093
|
+
controller.enqueue({
|
|
38094
|
+
type: "tool-call",
|
|
38095
|
+
toolCallId: toolCall.id ?? generateId(),
|
|
38096
|
+
toolName: toolCall.function.name,
|
|
38097
|
+
input: toolCall.function.arguments
|
|
38098
|
+
});
|
|
38099
|
+
toolCall.sent = true;
|
|
38100
|
+
}
|
|
38101
|
+
}
|
|
38102
|
+
}
|
|
38103
|
+
},
|
|
38104
|
+
flush(controller) {
|
|
38105
|
+
if (finishReason === "tool-calls") {
|
|
38106
|
+
for (const toolCall of toolCalls2) {
|
|
38107
|
+
if (toolCall && !toolCall.sent) {
|
|
38108
|
+
controller.enqueue({
|
|
38109
|
+
type: "tool-call",
|
|
38110
|
+
toolCallId: toolCall.id ?? generateId(),
|
|
38111
|
+
toolName: toolCall.function.name,
|
|
38112
|
+
input: isParsableJson(toolCall.function.arguments) ? toolCall.function.arguments : "{}"
|
|
38113
|
+
});
|
|
38114
|
+
toolCall.sent = true;
|
|
38115
|
+
}
|
|
38116
|
+
}
|
|
38117
|
+
}
|
|
38118
|
+
if (reasoningStarted) {
|
|
38119
|
+
controller.enqueue({
|
|
38120
|
+
type: "reasoning-end",
|
|
38121
|
+
id: reasoningId || generateId()
|
|
38122
|
+
});
|
|
38123
|
+
}
|
|
38124
|
+
if (textStarted) {
|
|
38125
|
+
controller.enqueue({
|
|
38126
|
+
type: "text-end",
|
|
38127
|
+
id: textId || generateId()
|
|
38128
|
+
});
|
|
38129
|
+
}
|
|
38130
|
+
const openrouterMetadata = {
|
|
38131
|
+
usage: openrouterUsage
|
|
38132
|
+
};
|
|
38133
|
+
if (provider !== undefined) {
|
|
38134
|
+
openrouterMetadata.provider = provider;
|
|
38135
|
+
}
|
|
38136
|
+
controller.enqueue({
|
|
38137
|
+
type: "finish",
|
|
38138
|
+
finishReason,
|
|
38139
|
+
usage,
|
|
38140
|
+
providerMetadata: {
|
|
38141
|
+
openrouter: openrouterMetadata
|
|
38142
|
+
}
|
|
38143
|
+
});
|
|
38144
|
+
}
|
|
38145
|
+
})),
|
|
38146
|
+
warnings: [],
|
|
38147
|
+
request: { body: args },
|
|
38148
|
+
response: { headers: responseHeaders }
|
|
38149
|
+
};
|
|
38150
|
+
}
|
|
38151
|
+
}
|
|
38152
|
+
|
|
38153
|
+
// ../packages/internal/src/openrouter-ai-sdk/completion/convert-to-openrouter-completion-prompt.ts
|
|
38154
|
+
function convertToOpenRouterCompletionPrompt({
|
|
38155
|
+
prompt: prompt2,
|
|
38156
|
+
inputFormat,
|
|
38157
|
+
user = "user",
|
|
38158
|
+
assistant = "assistant"
|
|
38159
|
+
}) {
|
|
38160
|
+
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") {
|
|
38161
|
+
return { prompt: prompt2[0].content[0].text };
|
|
38162
|
+
}
|
|
38163
|
+
let text = "";
|
|
38164
|
+
if (prompt2[0] && prompt2[0].role === "system") {
|
|
38165
|
+
text += `${prompt2[0].content}
|
|
38166
|
+
|
|
38167
|
+
`;
|
|
38168
|
+
prompt2 = prompt2.slice(1);
|
|
38169
|
+
}
|
|
38170
|
+
for (const { role, content } of prompt2) {
|
|
38171
|
+
switch (role) {
|
|
38172
|
+
case "system": {
|
|
38173
|
+
throw new InvalidPromptError({
|
|
38174
|
+
message: `Unexpected system message in prompt: ${content}`,
|
|
38175
|
+
prompt: prompt2
|
|
38176
|
+
});
|
|
38177
|
+
}
|
|
38178
|
+
case "user": {
|
|
38179
|
+
const userMessage2 = content.map((part) => {
|
|
38180
|
+
switch (part.type) {
|
|
38181
|
+
case "text": {
|
|
38182
|
+
return part.text;
|
|
38183
|
+
}
|
|
38184
|
+
case "file": {
|
|
38185
|
+
throw new UnsupportedFunctionalityError({
|
|
38186
|
+
functionality: "file attachments"
|
|
38187
|
+
});
|
|
38188
|
+
}
|
|
38189
|
+
default: {
|
|
38190
|
+
return "";
|
|
38191
|
+
}
|
|
38192
|
+
}
|
|
38193
|
+
}).join("");
|
|
38194
|
+
text += `${user}:
|
|
38195
|
+
${userMessage2}
|
|
38196
|
+
|
|
38197
|
+
`;
|
|
38198
|
+
break;
|
|
38199
|
+
}
|
|
38200
|
+
case "assistant": {
|
|
38201
|
+
const assistantMessage2 = content.map((part) => {
|
|
38202
|
+
switch (part.type) {
|
|
38203
|
+
case "text": {
|
|
38204
|
+
return part.text;
|
|
38205
|
+
}
|
|
38206
|
+
case "tool-call": {
|
|
38207
|
+
throw new UnsupportedFunctionalityError({
|
|
38208
|
+
functionality: "tool-call messages"
|
|
38209
|
+
});
|
|
38210
|
+
}
|
|
38211
|
+
case "tool-result": {
|
|
38212
|
+
throw new UnsupportedFunctionalityError({
|
|
38213
|
+
functionality: "tool-result messages"
|
|
38214
|
+
});
|
|
38215
|
+
}
|
|
38216
|
+
case "reasoning": {
|
|
38217
|
+
throw new UnsupportedFunctionalityError({
|
|
38218
|
+
functionality: "reasoning messages"
|
|
38219
|
+
});
|
|
38220
|
+
}
|
|
38221
|
+
case "file": {
|
|
38222
|
+
throw new UnsupportedFunctionalityError({
|
|
38223
|
+
functionality: "file attachments"
|
|
38224
|
+
});
|
|
38225
|
+
}
|
|
38226
|
+
default: {
|
|
38227
|
+
return "";
|
|
38228
|
+
}
|
|
38229
|
+
}
|
|
38230
|
+
}).join("");
|
|
38231
|
+
text += `${assistant}:
|
|
38232
|
+
${assistantMessage2}
|
|
38233
|
+
|
|
38234
|
+
`;
|
|
38235
|
+
break;
|
|
38236
|
+
}
|
|
38237
|
+
case "tool": {
|
|
38238
|
+
throw new UnsupportedFunctionalityError({
|
|
38239
|
+
functionality: "tool messages"
|
|
38240
|
+
});
|
|
38241
|
+
}
|
|
38242
|
+
default: {
|
|
38243
|
+
break;
|
|
38244
|
+
}
|
|
38245
|
+
}
|
|
38246
|
+
}
|
|
38247
|
+
text += `${assistant}:
|
|
38248
|
+
`;
|
|
38249
|
+
return {
|
|
38250
|
+
prompt: text
|
|
38251
|
+
};
|
|
38252
|
+
}
|
|
38253
|
+
|
|
38254
|
+
// ../packages/internal/src/openrouter-ai-sdk/completion/schemas.ts
|
|
38255
|
+
import { z as z74 } from "zod/v4";
|
|
38256
|
+
var OpenRouterCompletionChunkSchema = z74.union([
|
|
38257
|
+
z74.object({
|
|
38258
|
+
id: z74.string().optional(),
|
|
38259
|
+
model: z74.string().optional(),
|
|
38260
|
+
choices: z74.array(z74.object({
|
|
38261
|
+
text: z74.string(),
|
|
38262
|
+
reasoning: z74.string().nullish().optional(),
|
|
38263
|
+
reasoning_details: ReasoningDetailArraySchema.nullish(),
|
|
38264
|
+
finish_reason: z74.string().nullish(),
|
|
38265
|
+
index: z74.number().nullish(),
|
|
38266
|
+
logprobs: z74.object({
|
|
38267
|
+
tokens: z74.array(z74.string()),
|
|
38268
|
+
token_logprobs: z74.array(z74.number()),
|
|
38269
|
+
top_logprobs: z74.array(z74.record(z74.string(), z74.number())).nullable()
|
|
38270
|
+
}).nullable().optional()
|
|
38271
|
+
})),
|
|
38272
|
+
usage: z74.object({
|
|
38273
|
+
prompt_tokens: z74.number(),
|
|
38274
|
+
prompt_tokens_details: z74.object({
|
|
38275
|
+
cached_tokens: z74.number()
|
|
38276
|
+
}).nullish(),
|
|
38277
|
+
completion_tokens: z74.number(),
|
|
38278
|
+
completion_tokens_details: z74.object({
|
|
38279
|
+
reasoning_tokens: z74.number()
|
|
38280
|
+
}).nullish(),
|
|
38281
|
+
total_tokens: z74.number(),
|
|
38282
|
+
cost: z74.number().optional()
|
|
38283
|
+
}).nullish()
|
|
38284
|
+
}),
|
|
38285
|
+
OpenRouterErrorResponseSchema
|
|
38286
|
+
]);
|
|
38287
|
+
|
|
38288
|
+
// ../packages/internal/src/openrouter-ai-sdk/completion/index.ts
|
|
38289
|
+
class OpenRouterCompletionLanguageModel {
|
|
38290
|
+
specificationVersion = "v2";
|
|
38291
|
+
provider = "openrouter";
|
|
38292
|
+
modelId;
|
|
38293
|
+
supportedUrls = {
|
|
38294
|
+
"image/*": [
|
|
38295
|
+
/^data:image\/[a-zA-Z]+;base64,/,
|
|
38296
|
+
/^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)$/i
|
|
38297
|
+
],
|
|
38298
|
+
"text/*": [/^data:text\//, /^https?:\/\/.+$/],
|
|
38299
|
+
"application/*": [/^data:application\//, /^https?:\/\/.+$/]
|
|
38300
|
+
};
|
|
38301
|
+
defaultObjectGenerationMode = undefined;
|
|
38302
|
+
settings;
|
|
38303
|
+
config;
|
|
38304
|
+
constructor(modelId, settings, config) {
|
|
38305
|
+
this.modelId = modelId;
|
|
38306
|
+
this.settings = settings;
|
|
38307
|
+
this.config = config;
|
|
38308
|
+
}
|
|
38309
|
+
getArgs({
|
|
38310
|
+
prompt: prompt2,
|
|
38311
|
+
maxOutputTokens,
|
|
38312
|
+
temperature,
|
|
38313
|
+
topP,
|
|
38314
|
+
frequencyPenalty,
|
|
38315
|
+
presencePenalty,
|
|
38316
|
+
seed,
|
|
38317
|
+
responseFormat,
|
|
38318
|
+
topK,
|
|
38319
|
+
stopSequences,
|
|
38320
|
+
tools,
|
|
38321
|
+
toolChoice
|
|
38322
|
+
}) {
|
|
38323
|
+
const { prompt: completionPrompt } = convertToOpenRouterCompletionPrompt({
|
|
38324
|
+
prompt: prompt2,
|
|
38325
|
+
inputFormat: "prompt"
|
|
38326
|
+
});
|
|
38327
|
+
if (tools?.length) {
|
|
38328
|
+
throw new UnsupportedFunctionalityError({
|
|
38329
|
+
functionality: "tools"
|
|
38330
|
+
});
|
|
38331
|
+
}
|
|
38332
|
+
if (toolChoice) {
|
|
38333
|
+
throw new UnsupportedFunctionalityError({
|
|
38334
|
+
functionality: "toolChoice"
|
|
38335
|
+
});
|
|
38336
|
+
}
|
|
38337
|
+
return {
|
|
38338
|
+
model: this.modelId,
|
|
38339
|
+
models: this.settings.models,
|
|
38340
|
+
logit_bias: this.settings.logitBias,
|
|
38341
|
+
logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : undefined : undefined,
|
|
38342
|
+
suffix: this.settings.suffix,
|
|
38343
|
+
user: this.settings.user,
|
|
38344
|
+
max_tokens: maxOutputTokens,
|
|
38345
|
+
temperature,
|
|
38346
|
+
top_p: topP,
|
|
38347
|
+
frequency_penalty: frequencyPenalty,
|
|
38348
|
+
presence_penalty: presencePenalty,
|
|
38349
|
+
seed,
|
|
38350
|
+
...this.modelId === "x-ai/grok-code-fast-1" ? {} : { stop: stopSequences },
|
|
38351
|
+
response_format: responseFormat,
|
|
38352
|
+
top_k: topK,
|
|
38353
|
+
prompt: completionPrompt,
|
|
38354
|
+
include_reasoning: this.settings.includeReasoning,
|
|
38355
|
+
reasoning: this.settings.reasoning,
|
|
38356
|
+
...this.config.extraBody,
|
|
38357
|
+
...this.settings.extraBody
|
|
38358
|
+
};
|
|
38359
|
+
}
|
|
38360
|
+
async doGenerate(options) {
|
|
38361
|
+
const providerOptions = options.providerOptions || {};
|
|
38362
|
+
const openrouterOptions = providerOptions.openrouter || {};
|
|
38363
|
+
const args = {
|
|
38364
|
+
...this.getArgs(options),
|
|
38365
|
+
...openrouterOptions
|
|
38366
|
+
};
|
|
38367
|
+
const { value: response, responseHeaders } = await postJsonToApi({
|
|
38368
|
+
url: this.config.url({
|
|
38369
|
+
path: "/completions",
|
|
38370
|
+
modelId: this.modelId
|
|
38371
|
+
}),
|
|
38372
|
+
headers: combineHeaders(this.config.headers(), options.headers),
|
|
38373
|
+
body: args,
|
|
38374
|
+
failedResponseHandler: openrouterFailedResponseHandler,
|
|
38375
|
+
successfulResponseHandler: createJsonResponseHandler(OpenRouterCompletionChunkSchema),
|
|
38376
|
+
abortSignal: options.abortSignal,
|
|
38377
|
+
fetch: this.config.fetch
|
|
38378
|
+
});
|
|
38379
|
+
if ("error" in response) {
|
|
38380
|
+
throw new Error(`${response.error.message}`);
|
|
38381
|
+
}
|
|
38382
|
+
const choice = response.choices[0];
|
|
38383
|
+
if (!choice) {
|
|
38384
|
+
throw new Error("No choice in OpenRouter completion response");
|
|
38385
|
+
}
|
|
38386
|
+
return {
|
|
38387
|
+
content: [
|
|
38388
|
+
{
|
|
38389
|
+
type: "text",
|
|
38390
|
+
text: choice.text ?? ""
|
|
38391
|
+
}
|
|
38392
|
+
],
|
|
38393
|
+
finishReason: mapOpenRouterFinishReason(choice.finish_reason),
|
|
38394
|
+
usage: {
|
|
38395
|
+
inputTokens: response.usage?.prompt_tokens ?? 0,
|
|
38396
|
+
outputTokens: response.usage?.completion_tokens ?? 0,
|
|
38397
|
+
totalTokens: (response.usage?.prompt_tokens ?? 0) + (response.usage?.completion_tokens ?? 0),
|
|
38398
|
+
reasoningTokens: response.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
|
|
38399
|
+
cachedInputTokens: response.usage?.prompt_tokens_details?.cached_tokens ?? 0
|
|
38400
|
+
},
|
|
38401
|
+
warnings: [],
|
|
38402
|
+
response: {
|
|
38403
|
+
headers: responseHeaders
|
|
38404
|
+
}
|
|
38405
|
+
};
|
|
38406
|
+
}
|
|
38407
|
+
async doStream(options) {
|
|
38408
|
+
const providerOptions = options.providerOptions || {};
|
|
38409
|
+
const openrouterOptions = providerOptions.openrouter || {};
|
|
38410
|
+
const args = {
|
|
38411
|
+
...this.getArgs(options),
|
|
38412
|
+
...openrouterOptions
|
|
38413
|
+
};
|
|
38414
|
+
const { value: response, responseHeaders } = await postJsonToApi({
|
|
38415
|
+
url: this.config.url({
|
|
38416
|
+
path: "/completions",
|
|
38417
|
+
modelId: this.modelId
|
|
38418
|
+
}),
|
|
38419
|
+
headers: combineHeaders(this.config.headers(), options.headers),
|
|
38420
|
+
body: {
|
|
38421
|
+
...args,
|
|
38422
|
+
stream: true,
|
|
38423
|
+
stream_options: this.config.compatibility === "strict" ? { include_usage: true } : undefined
|
|
38424
|
+
},
|
|
38425
|
+
failedResponseHandler: openrouterFailedResponseHandler,
|
|
38426
|
+
successfulResponseHandler: createEventSourceResponseHandler(OpenRouterCompletionChunkSchema),
|
|
38427
|
+
abortSignal: options.abortSignal,
|
|
38428
|
+
fetch: this.config.fetch
|
|
38429
|
+
});
|
|
38430
|
+
let finishReason = "other";
|
|
38431
|
+
const usage = {
|
|
38432
|
+
inputTokens: Number.NaN,
|
|
38433
|
+
outputTokens: Number.NaN,
|
|
38434
|
+
totalTokens: Number.NaN,
|
|
38435
|
+
reasoningTokens: Number.NaN,
|
|
38436
|
+
cachedInputTokens: Number.NaN
|
|
38437
|
+
};
|
|
38438
|
+
const openrouterUsage = {};
|
|
38439
|
+
return {
|
|
38440
|
+
stream: response.pipeThrough(new TransformStream({
|
|
38441
|
+
transform(chunk, controller) {
|
|
38442
|
+
if (!chunk.success) {
|
|
38443
|
+
finishReason = "error";
|
|
38444
|
+
controller.enqueue({ type: "error", error: chunk.error });
|
|
38445
|
+
return;
|
|
38446
|
+
}
|
|
38447
|
+
const value = chunk.value;
|
|
38448
|
+
if ("error" in value) {
|
|
38449
|
+
finishReason = "error";
|
|
38450
|
+
controller.enqueue({ type: "error", error: value.error });
|
|
38451
|
+
return;
|
|
38452
|
+
}
|
|
38453
|
+
if (value.usage != null) {
|
|
38454
|
+
usage.inputTokens = value.usage.prompt_tokens;
|
|
38455
|
+
usage.outputTokens = value.usage.completion_tokens;
|
|
38456
|
+
usage.totalTokens = value.usage.prompt_tokens + value.usage.completion_tokens;
|
|
38457
|
+
openrouterUsage.promptTokens = value.usage.prompt_tokens;
|
|
38458
|
+
if (value.usage.prompt_tokens_details) {
|
|
38459
|
+
const cachedInputTokens = value.usage.prompt_tokens_details.cached_tokens ?? 0;
|
|
38460
|
+
usage.cachedInputTokens = cachedInputTokens;
|
|
38461
|
+
openrouterUsage.promptTokensDetails = {
|
|
38462
|
+
cachedTokens: cachedInputTokens
|
|
38463
|
+
};
|
|
38464
|
+
}
|
|
38465
|
+
openrouterUsage.completionTokens = value.usage.completion_tokens;
|
|
38466
|
+
if (value.usage.completion_tokens_details) {
|
|
38467
|
+
const reasoningTokens = value.usage.completion_tokens_details.reasoning_tokens ?? 0;
|
|
38468
|
+
usage.reasoningTokens = reasoningTokens;
|
|
38469
|
+
openrouterUsage.completionTokensDetails = {
|
|
38470
|
+
reasoningTokens
|
|
38471
|
+
};
|
|
38472
|
+
}
|
|
38473
|
+
if (value.usage.cost !== undefined) {
|
|
38474
|
+
openrouterUsage.cost = value.usage.cost;
|
|
38475
|
+
}
|
|
38476
|
+
openrouterUsage.totalTokens = value.usage.total_tokens;
|
|
38477
|
+
}
|
|
38478
|
+
const choice = value.choices[0];
|
|
38479
|
+
if (choice?.finish_reason != null) {
|
|
38480
|
+
finishReason = mapOpenRouterFinishReason(choice.finish_reason);
|
|
38481
|
+
}
|
|
38482
|
+
if (choice?.text != null) {
|
|
38483
|
+
controller.enqueue({
|
|
38484
|
+
type: "text-delta",
|
|
38485
|
+
delta: choice.text,
|
|
38486
|
+
id: generateId()
|
|
38487
|
+
});
|
|
38488
|
+
}
|
|
38489
|
+
},
|
|
38490
|
+
flush(controller) {
|
|
38491
|
+
controller.enqueue({
|
|
38492
|
+
type: "finish",
|
|
38493
|
+
finishReason,
|
|
38494
|
+
usage,
|
|
38495
|
+
providerMetadata: {
|
|
38496
|
+
openrouter: {
|
|
38497
|
+
usage: openrouterUsage
|
|
38498
|
+
}
|
|
38499
|
+
}
|
|
38500
|
+
});
|
|
38501
|
+
}
|
|
38502
|
+
})),
|
|
38503
|
+
response: {
|
|
38504
|
+
headers: responseHeaders
|
|
38505
|
+
}
|
|
38506
|
+
};
|
|
38507
|
+
}
|
|
38508
|
+
}
|
|
38509
|
+
|
|
38510
|
+
// ../packages/internal/src/openrouter-ai-sdk/provider.ts
|
|
38511
|
+
function createOpenRouter(options = {}) {
|
|
38512
|
+
const baseURL = withoutTrailingSlash(options.baseURL ?? options.baseUrl) ?? "https://openrouter.ai/api/v1";
|
|
38513
|
+
const compatibility = options.compatibility ?? "compatible";
|
|
38514
|
+
const getHeaders = () => ({
|
|
38515
|
+
Authorization: `Bearer ${loadApiKey({
|
|
38516
|
+
apiKey: options.apiKey,
|
|
38517
|
+
environmentVariableName: "OPENROUTER_API_KEY",
|
|
38518
|
+
description: "OpenRouter"
|
|
38519
|
+
})}`,
|
|
38520
|
+
...options.headers
|
|
38521
|
+
});
|
|
38522
|
+
const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
|
|
38523
|
+
provider: "openrouter.chat",
|
|
38524
|
+
url: ({ path: path4 }) => `${baseURL}${path4}`,
|
|
38525
|
+
headers: getHeaders,
|
|
38526
|
+
compatibility,
|
|
38527
|
+
fetch: options.fetch,
|
|
38528
|
+
extraBody: options.extraBody
|
|
38529
|
+
});
|
|
38530
|
+
const createCompletionModel = (modelId, settings = {}) => new OpenRouterCompletionLanguageModel(modelId, settings, {
|
|
38531
|
+
provider: "openrouter.completion",
|
|
38532
|
+
url: ({ path: path4 }) => `${baseURL}${path4}`,
|
|
38533
|
+
headers: getHeaders,
|
|
38534
|
+
compatibility,
|
|
38535
|
+
fetch: options.fetch,
|
|
38536
|
+
extraBody: options.extraBody
|
|
38537
|
+
});
|
|
38538
|
+
const createLanguageModel = (modelId, settings) => {
|
|
38539
|
+
if (new.target) {
|
|
38540
|
+
throw new Error("The OpenRouter model function cannot be called with the new keyword.");
|
|
38541
|
+
}
|
|
38542
|
+
if (modelId === "openai/gpt-3.5-turbo-instruct") {
|
|
38543
|
+
return createCompletionModel(modelId, settings);
|
|
38544
|
+
}
|
|
38545
|
+
return createChatModel(modelId, settings);
|
|
38546
|
+
};
|
|
38547
|
+
const provider = (modelId, settings) => createLanguageModel(modelId, settings);
|
|
38548
|
+
provider.languageModel = createLanguageModel;
|
|
38549
|
+
provider.chat = createChatModel;
|
|
38550
|
+
provider.completion = createCompletionModel;
|
|
38551
|
+
return provider;
|
|
38552
|
+
}
|
|
38553
|
+
var openrouter = createOpenRouter({
|
|
38554
|
+
compatibility: "strict"
|
|
37108
38555
|
});
|
|
37109
|
-
var processEnv = getProcessEnv();
|
|
37110
38556
|
|
|
37111
|
-
// src/
|
|
37112
|
-
|
|
37113
|
-
|
|
37114
|
-
|
|
37115
|
-
|
|
37116
|
-
|
|
37117
|
-
|
|
37118
|
-
|
|
37119
|
-
|
|
38557
|
+
// src/credentials.ts
|
|
38558
|
+
import fs from "fs";
|
|
38559
|
+
import path4 from "node:path";
|
|
38560
|
+
import os2 from "os";
|
|
38561
|
+
|
|
38562
|
+
// ../common/src/util/credentials.ts
|
|
38563
|
+
import { z as z75 } from "zod/v4";
|
|
38564
|
+
var userSchema = z75.object({
|
|
38565
|
+
id: z75.string(),
|
|
38566
|
+
email: z75.string(),
|
|
38567
|
+
name: z75.string().nullable(),
|
|
38568
|
+
authToken: z75.string(),
|
|
38569
|
+
fingerprintId: z75.string(),
|
|
38570
|
+
fingerprintHash: z75.string()
|
|
37120
38571
|
});
|
|
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
38572
|
|
|
37134
38573
|
// src/credentials.ts
|
|
37135
|
-
|
|
37136
|
-
|
|
37137
|
-
|
|
37138
|
-
|
|
37139
|
-
|
|
38574
|
+
import { z as z76 } from "zod/v4";
|
|
38575
|
+
var claudeOAuthSchema = z76.object({
|
|
38576
|
+
accessToken: z76.string(),
|
|
38577
|
+
refreshToken: z76.string(),
|
|
38578
|
+
expiresAt: z76.number(),
|
|
38579
|
+
connectedAt: z76.number()
|
|
37140
38580
|
});
|
|
37141
|
-
var credentialsFileSchema =
|
|
38581
|
+
var credentialsFileSchema = z76.object({
|
|
37142
38582
|
default: userSchema.optional(),
|
|
37143
38583
|
claudeOAuth: claudeOAuthSchema.optional()
|
|
37144
38584
|
});
|
|
@@ -37157,7 +38597,7 @@ var userFromJson = (json) => {
|
|
|
37157
38597
|
};
|
|
37158
38598
|
var getConfigDir = (clientEnv = env) => {
|
|
37159
38599
|
const envSuffix = clientEnv.NEXT_PUBLIC_CB_ENVIRONMENT && clientEnv.NEXT_PUBLIC_CB_ENVIRONMENT !== "prod" ? `-${clientEnv.NEXT_PUBLIC_CB_ENVIRONMENT}` : "";
|
|
37160
|
-
return path4.join(os2.homedir(), ".config", `
|
|
38600
|
+
return path4.join(os2.homedir(), ".config", `levelcode${envSuffix}`);
|
|
37161
38601
|
};
|
|
37162
38602
|
var getCredentialsPath = (clientEnv = env) => {
|
|
37163
38603
|
return path4.join(getConfigDir(clientEnv), "credentials.json");
|
|
@@ -37346,6 +38786,17 @@ async function fetchClaudeOAuthResetTime(accessToken) {
|
|
|
37346
38786
|
return null;
|
|
37347
38787
|
}
|
|
37348
38788
|
}
|
|
38789
|
+
function createDirectOpenRouterModel(openRouterApiKey, model) {
|
|
38790
|
+
const baseURL = getOpenRouterBaseUrlFromEnv();
|
|
38791
|
+
const provider = createOpenRouter({ apiKey: openRouterApiKey, compatibility: "strict", ...baseURL && { baseURL } });
|
|
38792
|
+
return provider.chat(model);
|
|
38793
|
+
}
|
|
38794
|
+
function createDirectAnthropicModel(anthropicApiKey, model) {
|
|
38795
|
+
const anthropicModelId = toAnthropicModelId(model);
|
|
38796
|
+
const baseURL = getAnthropicBaseUrlFromEnv();
|
|
38797
|
+
const anthropic = createAnthropic({ apiKey: anthropicApiKey, ...baseURL && { baseURL } });
|
|
38798
|
+
return anthropic(anthropicModelId);
|
|
38799
|
+
}
|
|
37349
38800
|
async function getModelForRequest(params2) {
|
|
37350
38801
|
const { apiKey, model, skipClaudeOAuth } = params2;
|
|
37351
38802
|
if (!skipClaudeOAuth && !isClaudeOAuthRateLimited() && isClaudeModel(model)) {
|
|
@@ -37357,6 +38808,16 @@ async function getModelForRequest(params2) {
|
|
|
37357
38808
|
};
|
|
37358
38809
|
}
|
|
37359
38810
|
}
|
|
38811
|
+
if (isStandaloneMode()) {
|
|
38812
|
+
const openRouterKey = getOpenRouterApiKeyFromEnv();
|
|
38813
|
+
if (openRouterKey) {
|
|
38814
|
+
return { model: createDirectOpenRouterModel(openRouterKey, model), isClaudeOAuth: false };
|
|
38815
|
+
}
|
|
38816
|
+
const anthropicKey = getAnthropicApiKeyFromEnv();
|
|
38817
|
+
if (anthropicKey) {
|
|
38818
|
+
return { model: createDirectAnthropicModel(anthropicKey, model), isClaudeOAuth: false };
|
|
38819
|
+
}
|
|
38820
|
+
}
|
|
37360
38821
|
return {
|
|
37361
38822
|
model: createLevelCodeBackendModel(apiKey, model),
|
|
37362
38823
|
isClaudeOAuth: false
|
|
@@ -38547,7 +40008,7 @@ function parseFile(parser, query, sourceCode) {
|
|
|
38547
40008
|
|
|
38548
40009
|
// src/run-state.ts
|
|
38549
40010
|
var import_lodash17 = __toESM(require_lodash(), 1);
|
|
38550
|
-
import
|
|
40011
|
+
import z78 from "zod/v4";
|
|
38551
40012
|
|
|
38552
40013
|
// src/agents/load-agents.ts
|
|
38553
40014
|
import fs5 from "fs";
|
|
@@ -38789,21 +40250,21 @@ function isValidSkillName(name14) {
|
|
|
38789
40250
|
}
|
|
38790
40251
|
|
|
38791
40252
|
// ../common/src/types/skill.ts
|
|
38792
|
-
import { z as
|
|
38793
|
-
var SkillMetadataSchema =
|
|
38794
|
-
var SkillFrontmatterSchema =
|
|
38795
|
-
name:
|
|
38796
|
-
description:
|
|
38797
|
-
license:
|
|
40253
|
+
import { z as z77 } from "zod/v4";
|
|
40254
|
+
var SkillMetadataSchema = z77.record(z77.string(), z77.string());
|
|
40255
|
+
var SkillFrontmatterSchema = z77.object({
|
|
40256
|
+
name: z77.string().min(1).max(SKILL_NAME_MAX_LENGTH).regex(SKILL_NAME_REGEX, "Name must be lowercase alphanumeric with single hyphen separators"),
|
|
40257
|
+
description: z77.string().min(1).max(SKILL_DESCRIPTION_MAX_LENGTH),
|
|
40258
|
+
license: z77.string().optional(),
|
|
38798
40259
|
metadata: SkillMetadataSchema.optional()
|
|
38799
40260
|
});
|
|
38800
|
-
var SkillDefinitionSchema =
|
|
38801
|
-
name:
|
|
38802
|
-
description:
|
|
38803
|
-
license:
|
|
40261
|
+
var SkillDefinitionSchema = z77.object({
|
|
40262
|
+
name: z77.string(),
|
|
40263
|
+
description: z77.string(),
|
|
40264
|
+
license: z77.string().optional(),
|
|
38804
40265
|
metadata: SkillMetadataSchema.optional(),
|
|
38805
|
-
content:
|
|
38806
|
-
filePath:
|
|
40266
|
+
content: z77.string(),
|
|
40267
|
+
filePath: z77.string()
|
|
38807
40268
|
});
|
|
38808
40269
|
|
|
38809
40270
|
// src/skills/load-skills.ts
|
|
@@ -38943,7 +40404,7 @@ function processAgentDefinitions(agentDefinitions) {
|
|
|
38943
40404
|
}
|
|
38944
40405
|
function processCustomToolDefinitions(customToolDefinitions) {
|
|
38945
40406
|
return Object.fromEntries(customToolDefinitions.map((toolDefinition) => {
|
|
38946
|
-
const jsonSchema =
|
|
40407
|
+
const jsonSchema = z78.toJSONSchema(toolDefinition.inputSchema, {
|
|
38947
40408
|
io: "input"
|
|
38948
40409
|
});
|
|
38949
40410
|
delete jsonSchema["$schema"];
|
|
@@ -39341,11 +40802,11 @@ function buildFileTree(filePaths) {
|
|
|
39341
40802
|
// src/tools/change-file.ts
|
|
39342
40803
|
import path12 from "path";
|
|
39343
40804
|
import { applyPatch } from "diff";
|
|
39344
|
-
import
|
|
39345
|
-
var FileChangeSchema2 =
|
|
39346
|
-
type:
|
|
39347
|
-
path:
|
|
39348
|
-
content:
|
|
40805
|
+
import z79 from "zod/v4";
|
|
40806
|
+
var FileChangeSchema2 = z79.object({
|
|
40807
|
+
type: z79.enum(["patch", "file"]),
|
|
40808
|
+
path: z79.string(),
|
|
40809
|
+
content: z79.string()
|
|
39349
40810
|
});
|
|
39350
40811
|
function containsUpwardTraversal(dirPath) {
|
|
39351
40812
|
const normalized = path12.normalize(dirPath);
|
|
@@ -40694,7 +42155,7 @@ async function handlePromptResponse({
|
|
|
40694
42155
|
const message = [
|
|
40695
42156
|
"Received invalid prompt response from server:",
|
|
40696
42157
|
JSON.stringify(parsedOutput.error.issues),
|
|
40697
|
-
"If this issues persists, please contact support@levelcode.
|
|
42158
|
+
"If this issues persists, please contact support@levelcode.vercel.app"
|
|
40698
42159
|
].join(`
|
|
40699
42160
|
`);
|
|
40700
42161
|
onError({ message });
|
|
@@ -40738,7 +42199,7 @@ init_paths();
|
|
|
40738
42199
|
class LevelCodeClient {
|
|
40739
42200
|
options;
|
|
40740
42201
|
constructor(options) {
|
|
40741
|
-
const foundApiKey = options.apiKey ?? getLevelCodeApiKeyFromEnv();
|
|
42202
|
+
const foundApiKey = options.apiKey ?? getLevelCodeApiKeyFromEnv() ?? (isStandaloneMode() ? "standalone-mode" : undefined);
|
|
40742
42203
|
if (!foundApiKey) {
|
|
40743
42204
|
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
42205
|
}
|
|
@@ -40759,6 +42220,9 @@ Provide a handleEvent function to handle this error.`);
|
|
|
40759
42220
|
return run({ ...this.options, ...options });
|
|
40760
42221
|
}
|
|
40761
42222
|
async checkConnection() {
|
|
42223
|
+
if (isStandaloneMode()) {
|
|
42224
|
+
return true;
|
|
42225
|
+
}
|
|
40762
42226
|
try {
|
|
40763
42227
|
const response = await fetch(`${WEBSITE_URL}/api/healthz`, {
|
|
40764
42228
|
method: "GET",
|
|
@@ -40824,9 +42288,9 @@ import fs9 from "fs";
|
|
|
40824
42288
|
import fsPromises from "fs/promises";
|
|
40825
42289
|
import os7 from "os";
|
|
40826
42290
|
import path18 from "path";
|
|
40827
|
-
import { z as
|
|
40828
|
-
var mcpFileSchema =
|
|
40829
|
-
mcpServers:
|
|
42291
|
+
import { z as z80 } from "zod/v4";
|
|
42292
|
+
var mcpFileSchema = z80.object({
|
|
42293
|
+
mcpServers: z80.record(z80.string(), mcpConfigSchema).default(() => ({}))
|
|
40830
42294
|
});
|
|
40831
42295
|
var envKey = "env";
|
|
40832
42296
|
var processEnv2 = process[envKey];
|
|
@@ -40976,6 +42440,7 @@ export {
|
|
|
40976
42440
|
loadMCPConfigSync,
|
|
40977
42441
|
loadMCPConfig,
|
|
40978
42442
|
loadLocalAgents,
|
|
42443
|
+
isStandaloneMode,
|
|
40979
42444
|
isRetryableStatusCode,
|
|
40980
42445
|
isKnowledgeFile,
|
|
40981
42446
|
isClaudeOAuthValid,
|
|
@@ -40983,6 +42448,7 @@ export {
|
|
|
40983
42448
|
getValidClaudeOAuthCredentials,
|
|
40984
42449
|
getUserInfoFromApiKey,
|
|
40985
42450
|
getUserCredentials,
|
|
42451
|
+
getOpenRouterApiKeyFromEnv,
|
|
40986
42452
|
getFiles,
|
|
40987
42453
|
getFileTokenScores,
|
|
40988
42454
|
getErrorStatusCode,
|
|
@@ -41019,5 +42485,5 @@ export {
|
|
|
41019
42485
|
IS_DEV
|
|
41020
42486
|
};
|
|
41021
42487
|
|
|
41022
|
-
//# debugId=
|
|
42488
|
+
//# debugId=E5A8E91746F38B8964756E2164756E21
|
|
41023
42489
|
//# sourceMappingURL=index.mjs.map
|