@levelcode/sdk 0.0.1 → 0.0.3

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