@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/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.url().min(1),
13098
- NEXT_PUBLIC_SUPPORT_EMAIL: z.email().min(1),
13099
- NEXT_PUBLIC_POSTHOG_API_KEY: z.string().min(1),
13100
- NEXT_PUBLIC_POSTHOG_HOST_URL: z.url().min(1),
13101
- NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: z.string().min(1),
13102
- NEXT_PUBLIC_STRIPE_CUSTOMER_PORTAL: z.url().min(1),
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().min(1000)
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
- if (!parsedEnv.success) {
13122
- throw parsedEnv.error;
13123
- }
13124
- var env = parsedEnv.data;
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.com>
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.com>
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.com>"
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.com>"`
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/credentials.ts
37038
- import fs from "fs";
37039
- import path4 from "node:path";
37040
- import os2 from "os";
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
- // ../common/src/util/credentials.ts
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 userSchema = z70.object({
37045
- id: z70.string(),
37046
- email: z70.string(),
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
- // src/credentials.ts
37054
- import { z as z71 } from "zod/v4";
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 getProcessEnv = () => ({
37077
- ...getBaseEnv(),
37078
- KITTY_WINDOW_ID: process.env.KITTY_WINDOW_ID,
37079
- SIXEL_SUPPORT: process.env.SIXEL_SUPPORT,
37080
- ZED_NODE_ENV: process.env.ZED_NODE_ENV,
37081
- VSCODE_THEME_KIND: process.env.VSCODE_THEME_KIND,
37082
- VSCODE_COLOR_THEME_KIND: process.env.VSCODE_COLOR_THEME_KIND,
37083
- VSCODE_GIT_IPC_HANDLE: process.env.VSCODE_GIT_IPC_HANDLE,
37084
- VSCODE_PID: process.env.VSCODE_PID,
37085
- VSCODE_CWD: process.env.VSCODE_CWD,
37086
- VSCODE_NLS_CONFIG: process.env.VSCODE_NLS_CONFIG,
37087
- CURSOR_PORT: process.env.CURSOR_PORT,
37088
- CURSOR: process.env.CURSOR,
37089
- JETBRAINS_REMOTE_RUN: process.env.JETBRAINS_REMOTE_RUN,
37090
- IDEA_INITIAL_DIRECTORY: process.env.IDEA_INITIAL_DIRECTORY,
37091
- IDE_CONFIG_DIR: process.env.IDE_CONFIG_DIR,
37092
- JB_IDE_CONFIG_DIR: process.env.JB_IDE_CONFIG_DIR,
37093
- VISUAL: process.env.VISUAL,
37094
- EDITOR: process.env.EDITOR,
37095
- LEVELCODE_CLI_EDITOR: process.env.LEVELCODE_CLI_EDITOR,
37096
- LEVELCODE_EDITOR: process.env.LEVELCODE_EDITOR,
37097
- OPEN_TUI_THEME: process.env.OPEN_TUI_THEME,
37098
- OPENTUI_THEME: process.env.OPENTUI_THEME,
37099
- LEVELCODE_IS_BINARY: process.env.LEVELCODE_IS_BINARY,
37100
- LEVELCODE_CLI_VERSION: process.env.LEVELCODE_CLI_VERSION,
37101
- LEVELCODE_CLI_TARGET: process.env.LEVELCODE_CLI_TARGET,
37102
- LEVELCODE_RG_PATH: process.env.LEVELCODE_RG_PATH,
37103
- LEVELCODE_WASM_DIR: process.env.LEVELCODE_WASM_DIR,
37104
- VERBOSE: process.env.VERBOSE,
37105
- OVERRIDE_TARGET: process.env.OVERRIDE_TARGET,
37106
- OVERRIDE_PLATFORM: process.env.OVERRIDE_PLATFORM,
37107
- OVERRIDE_ARCH: process.env.OVERRIDE_ARCH
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/env.ts
37112
- var getSdkEnv = () => ({
37113
- ...getBaseEnv(),
37114
- LEVELCODE_RG_PATH: process.env.LEVELCODE_RG_PATH,
37115
- LEVELCODE_WASM_DIR: process.env.LEVELCODE_WASM_DIR,
37116
- VERBOSE: process.env.VERBOSE,
37117
- OVERRIDE_TARGET: process.env.OVERRIDE_TARGET,
37118
- OVERRIDE_PLATFORM: process.env.OVERRIDE_PLATFORM,
37119
- OVERRIDE_ARCH: process.env.OVERRIDE_ARCH
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
- var claudeOAuthSchema = z71.object({
37136
- accessToken: z71.string(),
37137
- refreshToken: z71.string(),
37138
- expiresAt: z71.number(),
37139
- connectedAt: z71.number()
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 = z71.object({
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", `manicode${envSuffix}`);
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 z73 from "zod/v4";
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 z72 } from "zod/v4";
38793
- var SkillMetadataSchema = z72.record(z72.string(), z72.string());
38794
- var SkillFrontmatterSchema = z72.object({
38795
- name: z72.string().min(1).max(SKILL_NAME_MAX_LENGTH).regex(SKILL_NAME_REGEX, "Name must be lowercase alphanumeric with single hyphen separators"),
38796
- description: z72.string().min(1).max(SKILL_DESCRIPTION_MAX_LENGTH),
38797
- license: z72.string().optional(),
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 = z72.object({
38801
- name: z72.string(),
38802
- description: z72.string(),
38803
- license: z72.string().optional(),
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: z72.string(),
38806
- filePath: z72.string()
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 = z73.toJSONSchema(toolDefinition.inputSchema, {
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 z74 from "zod/v4";
39345
- var FileChangeSchema2 = z74.object({
39346
- type: z74.enum(["patch", "file"]),
39347
- path: z74.string(),
39348
- content: z74.string()
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.com"
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 z75 } from "zod/v4";
40828
- var mcpFileSchema = z75.object({
40829
- mcpServers: z75.record(z75.string(), mcpConfigSchema).default(() => ({}))
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=635305F5A012B85F64756E2164756E21
42488
+ //# debugId=E5A8E91746F38B8964756E2164756E21
41023
42489
  //# sourceMappingURL=index.mjs.map