@levelcode/sdk 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -13109,6 +13109,7 @@ __export(exports_src, {
13109
13109
  loadMCPConfigSync: () => loadMCPConfigSync,
13110
13110
  loadMCPConfig: () => loadMCPConfig,
13111
13111
  loadLocalAgents: () => loadLocalAgents,
13112
+ isStandaloneMode: () => isStandaloneMode,
13112
13113
  isRetryableStatusCode: () => isRetryableStatusCode,
13113
13114
  isKnowledgeFile: () => isKnowledgeFile,
13114
13115
  isClaudeOAuthValid: () => isClaudeOAuthValid,
@@ -13116,6 +13117,7 @@ __export(exports_src, {
13116
13117
  getValidClaudeOAuthCredentials: () => getValidClaudeOAuthCredentials,
13117
13118
  getUserInfoFromApiKey: () => getUserInfoFromApiKey,
13118
13119
  getUserCredentials: () => getUserCredentials,
13120
+ getOpenRouterApiKeyFromEnv: () => getOpenRouterApiKeyFromEnv,
13119
13121
  getFiles: () => getFiles,
13120
13122
  getFileTokenScores: () => getFileTokenScores,
13121
13123
  getErrorStatusCode: () => getErrorStatusCode,
@@ -13159,15 +13161,15 @@ var import_path12 = __toESM(require("path"));
13159
13161
  // ../common/src/env-schema.ts
13160
13162
  var import_v4 = __toESM(require("zod/v4"));
13161
13163
  var clientEnvSchema = import_v4.default.object({
13162
- NEXT_PUBLIC_CB_ENVIRONMENT: import_v4.default.enum(["dev", "test", "prod"]),
13163
- NEXT_PUBLIC_LEVELCODE_APP_URL: import_v4.default.url().min(1),
13164
- NEXT_PUBLIC_SUPPORT_EMAIL: import_v4.default.email().min(1),
13165
- NEXT_PUBLIC_POSTHOG_API_KEY: import_v4.default.string().min(1),
13166
- NEXT_PUBLIC_POSTHOG_HOST_URL: import_v4.default.url().min(1),
13167
- NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: import_v4.default.string().min(1),
13168
- NEXT_PUBLIC_STRIPE_CUSTOMER_PORTAL: import_v4.default.url().min(1),
13164
+ NEXT_PUBLIC_CB_ENVIRONMENT: import_v4.default.enum(["dev", "test", "prod"]).default("prod"),
13165
+ NEXT_PUBLIC_LEVELCODE_APP_URL: import_v4.default.string().default(""),
13166
+ NEXT_PUBLIC_SUPPORT_EMAIL: import_v4.default.string().default("support@levelcode.ai"),
13167
+ NEXT_PUBLIC_POSTHOG_API_KEY: import_v4.default.string().default(""),
13168
+ NEXT_PUBLIC_POSTHOG_HOST_URL: import_v4.default.string().default("https://app.posthog.com"),
13169
+ NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: import_v4.default.string().default(""),
13170
+ NEXT_PUBLIC_STRIPE_CUSTOMER_PORTAL: import_v4.default.string().default("https://billing.stripe.com"),
13169
13171
  NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION_ID: import_v4.default.string().optional(),
13170
- NEXT_PUBLIC_WEB_PORT: import_v4.default.coerce.number().min(1000)
13172
+ NEXT_PUBLIC_WEB_PORT: import_v4.default.coerce.number().default(3000)
13171
13173
  });
13172
13174
  var clientEnvVars = clientEnvSchema.keyof().options;
13173
13175
  var clientProcessEnv = {
@@ -13184,10 +13186,18 @@ var clientProcessEnv = {
13184
13186
 
13185
13187
  // ../common/src/env.ts
13186
13188
  var parsedEnv = clientEnvSchema.safeParse(clientProcessEnv);
13187
- if (!parsedEnv.success) {
13188
- throw parsedEnv.error;
13189
- }
13190
- var env = parsedEnv.data;
13189
+ var fallbackEnv = {
13190
+ NEXT_PUBLIC_CB_ENVIRONMENT: "prod",
13191
+ NEXT_PUBLIC_LEVELCODE_APP_URL: "",
13192
+ NEXT_PUBLIC_SUPPORT_EMAIL: "support@levelcode.ai",
13193
+ NEXT_PUBLIC_POSTHOG_API_KEY: "",
13194
+ NEXT_PUBLIC_POSTHOG_HOST_URL: "https://app.posthog.com",
13195
+ NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: "",
13196
+ NEXT_PUBLIC_STRIPE_CUSTOMER_PORTAL: "https://billing.stripe.com",
13197
+ NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION_ID: undefined,
13198
+ NEXT_PUBLIC_WEB_PORT: 3000
13199
+ };
13200
+ var env = parsedEnv.success ? parsedEnv.data : fallbackEnv;
13191
13201
  if (env.NEXT_PUBLIC_CB_ENVIRONMENT !== "prod") {
13192
13202
  console.log("Using environment:", env.NEXT_PUBLIC_CB_ENVIRONMENT);
13193
13203
  }
@@ -35220,7 +35230,152 @@ var import_v461 = __toESM(require("zod/v4"));
35220
35230
 
35221
35231
  // src/constants.ts
35222
35232
  var LEVELCODE_BINARY = "levelcode";
35223
- var WEBSITE_URL = env.NEXT_PUBLIC_LEVELCODE_APP_URL;
35233
+ var WEBSITE_URL = env.NEXT_PUBLIC_LEVELCODE_APP_URL || "";
35234
+
35235
+ // ../common/src/constants/byok.ts
35236
+ var BYOK_OPENROUTER_HEADER = "x-openrouter-api-key";
35237
+ var BYOK_OPENROUTER_ENV_VAR = "LEVELCODE_BYOK_OPENROUTER";
35238
+
35239
+ // ../common/src/constants/claude-oauth.ts
35240
+ var CLAUDE_OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
35241
+ var CLAUDE_OAUTH_TOKEN_ENV_VAR = "LEVELCODE_CLAUDE_OAUTH_TOKEN";
35242
+ var CLAUDE_OAUTH_BETA_HEADERS = [
35243
+ "oauth-2025-04-20",
35244
+ "claude-code-20250219",
35245
+ "interleaved-thinking-2025-05-14",
35246
+ "fine-grained-tool-streaming-2025-05-14"
35247
+ ];
35248
+ var CLAUDE_CODE_SYSTEM_PROMPT_PREFIX = "You are Claude Code, Anthropic's official CLI for Claude.";
35249
+ var OPENROUTER_TO_ANTHROPIC_MODEL_MAP = {
35250
+ "anthropic/claude-3.5-haiku-20241022": "claude-3-5-haiku-20241022",
35251
+ "anthropic/claude-3.5-haiku": "claude-3-5-haiku-20241022",
35252
+ "anthropic/claude-3-5-haiku": "claude-3-5-haiku-20241022",
35253
+ "anthropic/claude-3-5-haiku-20241022": "claude-3-5-haiku-20241022",
35254
+ "anthropic/claude-3-haiku": "claude-3-haiku-20240307",
35255
+ "anthropic/claude-3.5-sonnet": "claude-3-5-sonnet-20241022",
35256
+ "anthropic/claude-3-5-sonnet": "claude-3-5-sonnet-20241022",
35257
+ "anthropic/claude-3-5-sonnet-20241022": "claude-3-5-sonnet-20241022",
35258
+ "anthropic/claude-3-5-sonnet-20240620": "claude-3-5-sonnet-20240620",
35259
+ "anthropic/claude-3-sonnet": "claude-3-sonnet-20240229",
35260
+ "anthropic/claude-3-opus": "claude-3-opus-20240229",
35261
+ "anthropic/claude-3-opus-20240229": "claude-3-opus-20240229",
35262
+ "anthropic/claude-haiku-4.5": "claude-haiku-4-5-20251001",
35263
+ "anthropic/claude-haiku-4": "claude-haiku-4-20250514",
35264
+ "anthropic/claude-sonnet-4.5": "claude-sonnet-4-5-20250929",
35265
+ "anthropic/claude-sonnet-4": "claude-sonnet-4-20250514",
35266
+ "anthropic/claude-4-sonnet-20250522": "claude-sonnet-4-20250514",
35267
+ "anthropic/claude-4-sonnet": "claude-sonnet-4-20250514",
35268
+ "anthropic/claude-opus-4.5": "claude-opus-4-5-20251101",
35269
+ "anthropic/claude-opus-4.1": "claude-opus-4-1-20250805",
35270
+ "anthropic/claude-opus-4": "claude-opus-4-1-20250805"
35271
+ };
35272
+ function isClaudeModel(model) {
35273
+ return model.startsWith("anthropic/") || model.startsWith("claude-");
35274
+ }
35275
+ function toAnthropicModelId(openrouterModel) {
35276
+ if (!openrouterModel.includes("/")) {
35277
+ return openrouterModel;
35278
+ }
35279
+ if (!openrouterModel.startsWith("anthropic/")) {
35280
+ throw new Error(`Cannot convert non-Anthropic model to Anthropic model ID: ${openrouterModel}`);
35281
+ }
35282
+ const mapped = OPENROUTER_TO_ANTHROPIC_MODEL_MAP[openrouterModel];
35283
+ if (mapped) {
35284
+ return mapped;
35285
+ }
35286
+ return openrouterModel.replace("anthropic/", "");
35287
+ }
35288
+
35289
+ // src/env.ts
35290
+ init_paths();
35291
+
35292
+ // ../common/src/env-process.ts
35293
+ var getBaseEnv = () => ({
35294
+ SHELL: process.env.SHELL,
35295
+ COMSPEC: process.env.COMSPEC,
35296
+ HOME: process.env.HOME,
35297
+ USERPROFILE: process.env.USERPROFILE,
35298
+ APPDATA: process.env.APPDATA,
35299
+ XDG_CONFIG_HOME: process.env.XDG_CONFIG_HOME,
35300
+ TERM: process.env.TERM,
35301
+ TERM_PROGRAM: process.env.TERM_PROGRAM,
35302
+ TERM_BACKGROUND: process.env.TERM_BACKGROUND,
35303
+ TERMINAL_EMULATOR: process.env.TERMINAL_EMULATOR,
35304
+ COLORFGBG: process.env.COLORFGBG,
35305
+ NODE_ENV: "development",
35306
+ NODE_PATH: process.env.NODE_PATH,
35307
+ PATH: process.env.PATH
35308
+ });
35309
+ var getProcessEnv = () => ({
35310
+ ...getBaseEnv(),
35311
+ KITTY_WINDOW_ID: process.env.KITTY_WINDOW_ID,
35312
+ SIXEL_SUPPORT: process.env.SIXEL_SUPPORT,
35313
+ ZED_NODE_ENV: process.env.ZED_NODE_ENV,
35314
+ VSCODE_THEME_KIND: process.env.VSCODE_THEME_KIND,
35315
+ VSCODE_COLOR_THEME_KIND: process.env.VSCODE_COLOR_THEME_KIND,
35316
+ VSCODE_GIT_IPC_HANDLE: process.env.VSCODE_GIT_IPC_HANDLE,
35317
+ VSCODE_PID: process.env.VSCODE_PID,
35318
+ VSCODE_CWD: process.env.VSCODE_CWD,
35319
+ VSCODE_NLS_CONFIG: process.env.VSCODE_NLS_CONFIG,
35320
+ CURSOR_PORT: process.env.CURSOR_PORT,
35321
+ CURSOR: process.env.CURSOR,
35322
+ JETBRAINS_REMOTE_RUN: process.env.JETBRAINS_REMOTE_RUN,
35323
+ IDEA_INITIAL_DIRECTORY: process.env.IDEA_INITIAL_DIRECTORY,
35324
+ IDE_CONFIG_DIR: process.env.IDE_CONFIG_DIR,
35325
+ JB_IDE_CONFIG_DIR: process.env.JB_IDE_CONFIG_DIR,
35326
+ VISUAL: process.env.VISUAL,
35327
+ EDITOR: process.env.EDITOR,
35328
+ LEVELCODE_CLI_EDITOR: process.env.LEVELCODE_CLI_EDITOR,
35329
+ LEVELCODE_EDITOR: process.env.LEVELCODE_EDITOR,
35330
+ OPEN_TUI_THEME: process.env.OPEN_TUI_THEME,
35331
+ OPENTUI_THEME: process.env.OPENTUI_THEME,
35332
+ LEVELCODE_IS_BINARY: process.env.LEVELCODE_IS_BINARY,
35333
+ LEVELCODE_CLI_VERSION: process.env.LEVELCODE_CLI_VERSION,
35334
+ LEVELCODE_CLI_TARGET: process.env.LEVELCODE_CLI_TARGET,
35335
+ LEVELCODE_RG_PATH: process.env.LEVELCODE_RG_PATH,
35336
+ LEVELCODE_WASM_DIR: process.env.LEVELCODE_WASM_DIR,
35337
+ VERBOSE: process.env.VERBOSE,
35338
+ OVERRIDE_TARGET: process.env.OVERRIDE_TARGET,
35339
+ OVERRIDE_PLATFORM: process.env.OVERRIDE_PLATFORM,
35340
+ OVERRIDE_ARCH: process.env.OVERRIDE_ARCH
35341
+ });
35342
+ var processEnv = getProcessEnv();
35343
+
35344
+ // src/env.ts
35345
+ var getSdkEnv = () => ({
35346
+ ...getBaseEnv(),
35347
+ LEVELCODE_RG_PATH: process.env.LEVELCODE_RG_PATH,
35348
+ LEVELCODE_WASM_DIR: process.env.LEVELCODE_WASM_DIR,
35349
+ VERBOSE: process.env.VERBOSE,
35350
+ OVERRIDE_TARGET: process.env.OVERRIDE_TARGET,
35351
+ OVERRIDE_PLATFORM: process.env.OVERRIDE_PLATFORM,
35352
+ OVERRIDE_ARCH: process.env.OVERRIDE_ARCH
35353
+ });
35354
+ var getLevelCodeApiKeyFromEnv = () => {
35355
+ return process.env[API_KEY_ENV_VAR];
35356
+ };
35357
+ var getSystemProcessEnv = () => {
35358
+ return process.env;
35359
+ };
35360
+ var getByokOpenrouterApiKeyFromEnv = () => {
35361
+ return process.env[BYOK_OPENROUTER_ENV_VAR];
35362
+ };
35363
+ var getClaudeOAuthTokenFromEnv = () => {
35364
+ return process.env[CLAUDE_OAUTH_TOKEN_ENV_VAR];
35365
+ };
35366
+ var getOpenRouterApiKeyFromEnv = () => {
35367
+ return process.env.OPENROUTER_API_KEY;
35368
+ };
35369
+ var getAnthropicApiKeyFromEnv = () => {
35370
+ return process.env.ANTHROPIC_API_KEY;
35371
+ };
35372
+ var isStandaloneMode = () => {
35373
+ const appUrl = process.env.NEXT_PUBLIC_LEVELCODE_APP_URL;
35374
+ if (!appUrl)
35375
+ return true;
35376
+ const hasDirectKey = !!getOpenRouterApiKeyFromEnv() || !!getAnthropicApiKeyFromEnv();
35377
+ return hasDirectKey && !getLevelCodeApiKeyFromEnv();
35378
+ };
35224
35379
 
35225
35380
  // src/retry-config.ts
35226
35381
  var MAX_RETRIES_PER_MESSAGE = 3;
@@ -35263,6 +35418,10 @@ async function fetchWithRetry(url, options, logger2) {
35263
35418
  throw lastError ?? new Error("Request failed after retries");
35264
35419
  }
35265
35420
  async function getUserInfoFromApiKey(params2) {
35421
+ if (isStandaloneMode()) {
35422
+ const standaloneUser = { id: "standalone-user", email: "standalone@local" };
35423
+ return Object.fromEntries(params2.fields.map((field) => [field, standaloneUser[field] ?? null]));
35424
+ }
35266
35425
  const { apiKey, fields, logger: logger2 } = params2;
35267
35426
  const cached = userInfoCache[apiKey];
35268
35427
  if (cached === null) {
@@ -35325,6 +35484,9 @@ async function getUserInfoFromApiKey(params2) {
35325
35484
  return Object.fromEntries(fields.map((field) => [field, userInfo[field]]));
35326
35485
  }
35327
35486
  async function fetchAgentFromDatabase(params2) {
35487
+ if (isStandaloneMode()) {
35488
+ return null;
35489
+ }
35328
35490
  const { apiKey, parsedAgentId, logger: logger2 } = params2;
35329
35491
  const { publisherId, agentId, version: version2 } = parsedAgentId;
35330
35492
  const url = new URL(`/api/v1/agents/${publisherId}/${agentId}/${version2 ? version2 : "latest"}`, WEBSITE_URL);
@@ -35378,6 +35540,9 @@ async function fetchAgentFromDatabase(params2) {
35378
35540
  }
35379
35541
  }
35380
35542
  async function startAgentRun(params2) {
35543
+ if (isStandaloneMode()) {
35544
+ return crypto.randomUUID();
35545
+ }
35381
35546
  const { apiKey, agentId, ancestorRunIds, logger: logger2 } = params2;
35382
35547
  const url = new URL(`/api/v1/agent-runs`, WEBSITE_URL);
35383
35548
  try {
@@ -35407,6 +35572,9 @@ async function startAgentRun(params2) {
35407
35572
  }
35408
35573
  }
35409
35574
  async function finishAgentRun(params2) {
35575
+ if (isStandaloneMode()) {
35576
+ return;
35577
+ }
35410
35578
  const {
35411
35579
  apiKey,
35412
35580
  runId,
@@ -35441,6 +35609,9 @@ async function finishAgentRun(params2) {
35441
35609
  }
35442
35610
  }
35443
35611
  async function addAgentStep2(params2) {
35612
+ if (isStandaloneMode()) {
35613
+ return crypto.randomUUID();
35614
+ }
35444
35615
  const {
35445
35616
  apiKey,
35446
35617
  agentRunId,
@@ -35553,60 +35724,6 @@ var import_ai3 = require("ai");
35553
35724
  var import_path5 = __toESM(require("path"));
35554
35725
  var import_anthropic = require("@ai-sdk/anthropic");
35555
35726
 
35556
- // ../common/src/constants/byok.ts
35557
- var BYOK_OPENROUTER_HEADER = "x-openrouter-api-key";
35558
- var BYOK_OPENROUTER_ENV_VAR = "LEVELCODE_BYOK_OPENROUTER";
35559
-
35560
- // ../common/src/constants/claude-oauth.ts
35561
- var CLAUDE_OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
35562
- var CLAUDE_OAUTH_TOKEN_ENV_VAR = "LEVELCODE_CLAUDE_OAUTH_TOKEN";
35563
- var CLAUDE_OAUTH_BETA_HEADERS = [
35564
- "oauth-2025-04-20",
35565
- "claude-code-20250219",
35566
- "interleaved-thinking-2025-05-14",
35567
- "fine-grained-tool-streaming-2025-05-14"
35568
- ];
35569
- var CLAUDE_CODE_SYSTEM_PROMPT_PREFIX = "You are Claude Code, Anthropic's official CLI for Claude.";
35570
- var OPENROUTER_TO_ANTHROPIC_MODEL_MAP = {
35571
- "anthropic/claude-3.5-haiku-20241022": "claude-3-5-haiku-20241022",
35572
- "anthropic/claude-3.5-haiku": "claude-3-5-haiku-20241022",
35573
- "anthropic/claude-3-5-haiku": "claude-3-5-haiku-20241022",
35574
- "anthropic/claude-3-5-haiku-20241022": "claude-3-5-haiku-20241022",
35575
- "anthropic/claude-3-haiku": "claude-3-haiku-20240307",
35576
- "anthropic/claude-3.5-sonnet": "claude-3-5-sonnet-20241022",
35577
- "anthropic/claude-3-5-sonnet": "claude-3-5-sonnet-20241022",
35578
- "anthropic/claude-3-5-sonnet-20241022": "claude-3-5-sonnet-20241022",
35579
- "anthropic/claude-3-5-sonnet-20240620": "claude-3-5-sonnet-20240620",
35580
- "anthropic/claude-3-sonnet": "claude-3-sonnet-20240229",
35581
- "anthropic/claude-3-opus": "claude-3-opus-20240229",
35582
- "anthropic/claude-3-opus-20240229": "claude-3-opus-20240229",
35583
- "anthropic/claude-haiku-4.5": "claude-haiku-4-5-20251001",
35584
- "anthropic/claude-haiku-4": "claude-haiku-4-20250514",
35585
- "anthropic/claude-sonnet-4.5": "claude-sonnet-4-5-20250929",
35586
- "anthropic/claude-sonnet-4": "claude-sonnet-4-20250514",
35587
- "anthropic/claude-4-sonnet-20250522": "claude-sonnet-4-20250514",
35588
- "anthropic/claude-4-sonnet": "claude-sonnet-4-20250514",
35589
- "anthropic/claude-opus-4.5": "claude-opus-4-5-20251101",
35590
- "anthropic/claude-opus-4.1": "claude-opus-4-1-20250805",
35591
- "anthropic/claude-opus-4": "claude-opus-4-1-20250805"
35592
- };
35593
- function isClaudeModel(model) {
35594
- return model.startsWith("anthropic/") || model.startsWith("claude-");
35595
- }
35596
- function toAnthropicModelId(openrouterModel) {
35597
- if (!openrouterModel.includes("/")) {
35598
- return openrouterModel;
35599
- }
35600
- if (!openrouterModel.startsWith("anthropic/")) {
35601
- throw new Error(`Cannot convert non-Anthropic model to Anthropic model ID: ${openrouterModel}`);
35602
- }
35603
- const mapped = OPENROUTER_TO_ANTHROPIC_MODEL_MAP[openrouterModel];
35604
- if (mapped) {
35605
- return mapped;
35606
- }
35607
- return openrouterModel.replace("anthropic/", "");
35608
- }
35609
-
35610
35727
  // ../node_modules/@ai-sdk/provider/dist/index.mjs
35611
35728
  var marker = "vercel.ai.error";
35612
35729
  var symbol = Symbol.for(marker);
@@ -36005,6 +36122,38 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
36005
36122
  return Object.fromEntries(normalizedHeaders.entries());
36006
36123
  }
36007
36124
  var VERSION = "3.0.20";
36125
+ function loadApiKey({
36126
+ apiKey,
36127
+ environmentVariableName,
36128
+ apiKeyParameterName = "apiKey",
36129
+ description: description31
36130
+ }) {
36131
+ if (typeof apiKey === "string") {
36132
+ return apiKey;
36133
+ }
36134
+ if (apiKey != null) {
36135
+ throw new LoadAPIKeyError({
36136
+ message: `${description31} API key must be a string.`
36137
+ });
36138
+ }
36139
+ if (typeof process === "undefined") {
36140
+ throw new LoadAPIKeyError({
36141
+ message: `${description31} API key is missing. Pass it using the '${apiKeyParameterName}' parameter. Environment variables is not supported in this environment.`
36142
+ });
36143
+ }
36144
+ apiKey = process.env[environmentVariableName];
36145
+ if (apiKey == null) {
36146
+ throw new LoadAPIKeyError({
36147
+ message: `${description31} API key is missing. Pass it using the '${apiKeyParameterName}' parameter or the ${environmentVariableName} environment variable.`
36148
+ });
36149
+ }
36150
+ if (typeof apiKey !== "string") {
36151
+ throw new LoadAPIKeyError({
36152
+ message: `${description31} API key must be a string. The value of the ${environmentVariableName} environment variable is not a string.`
36153
+ });
36154
+ }
36155
+ return apiKey;
36156
+ }
36008
36157
  var suspectProtoRx = /"__proto__"\s*:/;
36009
36158
  var suspectConstructorRx = /"constructor"\s*:/;
36010
36159
  function _parse(text) {
@@ -36381,6 +36530,9 @@ function convertUint8ArrayToBase64(array) {
36381
36530
  function convertToBase64(value) {
36382
36531
  return value instanceof Uint8Array ? convertUint8ArrayToBase64(value) : value;
36383
36532
  }
36533
+ function withoutTrailingSlash(url) {
36534
+ return url == null ? undefined : url.replace(/\/$/, "");
36535
+ }
36384
36536
 
36385
36537
  // ../packages/internal/src/openai-compatible/chat/openai-compatible-chat-language-model.ts
36386
36538
  var import_v464 = require("zod/v4");
@@ -37089,111 +37241,1395 @@ var createOpenAICompatibleChatChunkSchema = (errorSchema) => import_v464.z.union
37089
37241
  ]);
37090
37242
  // ../packages/internal/src/openai-compatible/version.ts
37091
37243
  var VERSION2 = typeof __PACKAGE_VERSION__ !== "undefined" ? __PACKAGE_VERSION__ : "0.0.0-test";
37092
- // src/credentials.ts
37093
- var import_fs = __toESM(require("fs"));
37094
- var import_node_path = __toESM(require("node:path"));
37095
- var import_os = __toESM(require("os"));
37244
+ // ../packages/internal/src/openrouter-ai-sdk/chat/is-url.ts
37245
+ function isUrl({
37246
+ url,
37247
+ protocols
37248
+ }) {
37249
+ try {
37250
+ const urlObj = new URL(url);
37251
+ return protocols.has(urlObj.protocol);
37252
+ } catch (_) {
37253
+ return false;
37254
+ }
37255
+ }
37096
37256
 
37097
- // ../common/src/util/credentials.ts
37257
+ // ../packages/internal/src/openrouter-ai-sdk/chat/file-url-utils.ts
37258
+ function getFileUrl({
37259
+ part,
37260
+ defaultMediaType
37261
+ }) {
37262
+ if (part.data instanceof Uint8Array) {
37263
+ const base64 = convertUint8ArrayToBase64(part.data);
37264
+ return `data:${part.mediaType ?? defaultMediaType};base64,${base64}`;
37265
+ }
37266
+ const stringUrl = part.data.toString();
37267
+ if (isUrl({
37268
+ url: stringUrl,
37269
+ protocols: new Set(["http:", "https:"])
37270
+ })) {
37271
+ return stringUrl;
37272
+ }
37273
+ return stringUrl.startsWith("data:") ? stringUrl : `data:${part.mediaType ?? defaultMediaType};base64,${stringUrl}`;
37274
+ }
37275
+
37276
+ // ../packages/internal/src/openrouter-ai-sdk/schemas/reasoning-details.ts
37098
37277
  var import_v465 = require("zod/v4");
37099
- var userSchema = import_v465.z.object({
37100
- id: import_v465.z.string(),
37101
- email: import_v465.z.string(),
37102
- name: import_v465.z.string().nullable(),
37103
- authToken: import_v465.z.string(),
37104
- fingerprintId: import_v465.z.string(),
37105
- fingerprintHash: import_v465.z.string()
37278
+ var ReasoningDetailSummarySchema = import_v465.z.object({
37279
+ type: import_v465.z.literal("reasoning.summary" /* Summary */),
37280
+ summary: import_v465.z.string()
37106
37281
  });
37107
-
37108
- // src/credentials.ts
37109
- var import_v466 = require("zod/v4");
37110
-
37111
- // src/env.ts
37112
- init_paths();
37113
-
37114
- // ../common/src/env-process.ts
37115
- var getBaseEnv = () => ({
37116
- SHELL: process.env.SHELL,
37117
- COMSPEC: process.env.COMSPEC,
37118
- HOME: process.env.HOME,
37119
- USERPROFILE: process.env.USERPROFILE,
37120
- APPDATA: process.env.APPDATA,
37121
- XDG_CONFIG_HOME: process.env.XDG_CONFIG_HOME,
37122
- TERM: process.env.TERM,
37123
- TERM_PROGRAM: process.env.TERM_PROGRAM,
37124
- TERM_BACKGROUND: process.env.TERM_BACKGROUND,
37125
- TERMINAL_EMULATOR: process.env.TERMINAL_EMULATOR,
37126
- COLORFGBG: process.env.COLORFGBG,
37127
- NODE_ENV: "development",
37128
- NODE_PATH: process.env.NODE_PATH,
37129
- PATH: process.env.PATH
37282
+ var ReasoningDetailEncryptedSchema = import_v465.z.object({
37283
+ type: import_v465.z.literal("reasoning.encrypted" /* Encrypted */),
37284
+ data: import_v465.z.string()
37130
37285
  });
37131
- var getProcessEnv = () => ({
37132
- ...getBaseEnv(),
37133
- KITTY_WINDOW_ID: process.env.KITTY_WINDOW_ID,
37134
- SIXEL_SUPPORT: process.env.SIXEL_SUPPORT,
37135
- ZED_NODE_ENV: process.env.ZED_NODE_ENV,
37136
- VSCODE_THEME_KIND: process.env.VSCODE_THEME_KIND,
37137
- VSCODE_COLOR_THEME_KIND: process.env.VSCODE_COLOR_THEME_KIND,
37138
- VSCODE_GIT_IPC_HANDLE: process.env.VSCODE_GIT_IPC_HANDLE,
37139
- VSCODE_PID: process.env.VSCODE_PID,
37140
- VSCODE_CWD: process.env.VSCODE_CWD,
37141
- VSCODE_NLS_CONFIG: process.env.VSCODE_NLS_CONFIG,
37142
- CURSOR_PORT: process.env.CURSOR_PORT,
37143
- CURSOR: process.env.CURSOR,
37144
- JETBRAINS_REMOTE_RUN: process.env.JETBRAINS_REMOTE_RUN,
37145
- IDEA_INITIAL_DIRECTORY: process.env.IDEA_INITIAL_DIRECTORY,
37146
- IDE_CONFIG_DIR: process.env.IDE_CONFIG_DIR,
37147
- JB_IDE_CONFIG_DIR: process.env.JB_IDE_CONFIG_DIR,
37148
- VISUAL: process.env.VISUAL,
37149
- EDITOR: process.env.EDITOR,
37150
- LEVELCODE_CLI_EDITOR: process.env.LEVELCODE_CLI_EDITOR,
37151
- LEVELCODE_EDITOR: process.env.LEVELCODE_EDITOR,
37152
- OPEN_TUI_THEME: process.env.OPEN_TUI_THEME,
37153
- OPENTUI_THEME: process.env.OPENTUI_THEME,
37154
- LEVELCODE_IS_BINARY: process.env.LEVELCODE_IS_BINARY,
37155
- LEVELCODE_CLI_VERSION: process.env.LEVELCODE_CLI_VERSION,
37156
- LEVELCODE_CLI_TARGET: process.env.LEVELCODE_CLI_TARGET,
37157
- LEVELCODE_RG_PATH: process.env.LEVELCODE_RG_PATH,
37158
- LEVELCODE_WASM_DIR: process.env.LEVELCODE_WASM_DIR,
37159
- VERBOSE: process.env.VERBOSE,
37160
- OVERRIDE_TARGET: process.env.OVERRIDE_TARGET,
37161
- OVERRIDE_PLATFORM: process.env.OVERRIDE_PLATFORM,
37162
- OVERRIDE_ARCH: process.env.OVERRIDE_ARCH
37286
+ var ReasoningDetailTextSchema = import_v465.z.object({
37287
+ type: import_v465.z.literal("reasoning.text" /* Text */),
37288
+ text: import_v465.z.string().nullish(),
37289
+ signature: import_v465.z.string().nullish()
37290
+ });
37291
+ var ReasoningDetailUnionSchema = import_v465.z.union([
37292
+ ReasoningDetailSummarySchema,
37293
+ ReasoningDetailEncryptedSchema,
37294
+ ReasoningDetailTextSchema
37295
+ ]);
37296
+ var ReasoningDetailsWithUnknownSchema = import_v465.z.union([
37297
+ ReasoningDetailUnionSchema,
37298
+ import_v465.z.unknown().transform(() => null)
37299
+ ]);
37300
+ var ReasoningDetailArraySchema = import_v465.z.array(ReasoningDetailsWithUnknownSchema).transform((d) => d.filter((d2) => !!d2));
37301
+
37302
+ // ../packages/internal/src/openrouter-ai-sdk/chat/convert-to-openrouter-chat-messages.ts
37303
+ function getCacheControl(providerMetadata) {
37304
+ const anthropic = providerMetadata?.anthropic;
37305
+ const openrouter = providerMetadata?.openrouter;
37306
+ return openrouter?.cacheControl ?? openrouter?.cache_control ?? anthropic?.cacheControl ?? anthropic?.cache_control;
37307
+ }
37308
+ function convertToOpenRouterChatMessages(prompt2) {
37309
+ const messages = [];
37310
+ for (const { role, content, providerOptions } of prompt2) {
37311
+ switch (role) {
37312
+ case "system": {
37313
+ messages.push({
37314
+ role: "system",
37315
+ content,
37316
+ cache_control: getCacheControl(providerOptions)
37317
+ });
37318
+ break;
37319
+ }
37320
+ case "user": {
37321
+ const messageCacheControl = getCacheControl(providerOptions);
37322
+ const contentParts = content.map((part) => {
37323
+ const cacheControl = getCacheControl(part.providerOptions) ?? messageCacheControl;
37324
+ switch (part.type) {
37325
+ case "text":
37326
+ return {
37327
+ type: "text",
37328
+ text: part.text,
37329
+ cache_control: cacheControl
37330
+ };
37331
+ case "file": {
37332
+ if (part.mediaType?.startsWith("image/")) {
37333
+ const url = getFileUrl({
37334
+ part,
37335
+ defaultMediaType: "image/jpeg"
37336
+ });
37337
+ return {
37338
+ type: "image_url",
37339
+ image_url: {
37340
+ url
37341
+ },
37342
+ cache_control: cacheControl
37343
+ };
37344
+ }
37345
+ const fileName = String(part.providerOptions?.openrouter?.filename ?? part.filename ?? "");
37346
+ const fileData = getFileUrl({
37347
+ part,
37348
+ defaultMediaType: "application/pdf"
37349
+ });
37350
+ if (isUrl({
37351
+ url: fileData,
37352
+ protocols: new Set(["http:", "https:"])
37353
+ })) {
37354
+ return {
37355
+ type: "file",
37356
+ file: {
37357
+ filename: fileName,
37358
+ file_data: fileData
37359
+ }
37360
+ };
37361
+ }
37362
+ return {
37363
+ type: "file",
37364
+ file: {
37365
+ filename: fileName,
37366
+ file_data: fileData
37367
+ },
37368
+ cache_control: cacheControl
37369
+ };
37370
+ }
37371
+ default: {
37372
+ return {
37373
+ type: "text",
37374
+ text: "",
37375
+ cache_control: cacheControl
37376
+ };
37377
+ }
37378
+ }
37379
+ });
37380
+ messages.push({
37381
+ role: "user",
37382
+ content: contentParts
37383
+ });
37384
+ break;
37385
+ }
37386
+ case "assistant": {
37387
+ let text = "";
37388
+ let reasoning = "";
37389
+ const reasoningDetails = [];
37390
+ const toolCalls2 = [];
37391
+ for (const part of content) {
37392
+ switch (part.type) {
37393
+ case "text": {
37394
+ text += part.text;
37395
+ break;
37396
+ }
37397
+ case "tool-call": {
37398
+ toolCalls2.push({
37399
+ id: part.toolCallId,
37400
+ type: "function",
37401
+ function: {
37402
+ name: part.toolName,
37403
+ arguments: JSON.stringify(part.input)
37404
+ }
37405
+ });
37406
+ break;
37407
+ }
37408
+ case "reasoning": {
37409
+ reasoning += part.text;
37410
+ reasoningDetails.push({
37411
+ type: "reasoning.text" /* Text */,
37412
+ text: part.text
37413
+ });
37414
+ break;
37415
+ }
37416
+ case "file":
37417
+ break;
37418
+ default: {
37419
+ break;
37420
+ }
37421
+ }
37422
+ }
37423
+ messages.push({
37424
+ role: "assistant",
37425
+ content: text,
37426
+ tool_calls: toolCalls2.length > 0 ? toolCalls2 : undefined,
37427
+ reasoning: reasoning || undefined,
37428
+ reasoning_details: reasoningDetails.length > 0 ? reasoningDetails : undefined,
37429
+ cache_control: getCacheControl(providerOptions)
37430
+ });
37431
+ break;
37432
+ }
37433
+ case "tool": {
37434
+ for (const toolResponse of content) {
37435
+ const content2 = getToolResultContent(toolResponse);
37436
+ messages.push({
37437
+ role: "tool",
37438
+ tool_call_id: toolResponse.toolCallId,
37439
+ content: content2,
37440
+ cache_control: getCacheControl(providerOptions) ?? getCacheControl(toolResponse.providerOptions)
37441
+ });
37442
+ }
37443
+ break;
37444
+ }
37445
+ default: {
37446
+ break;
37447
+ }
37448
+ }
37449
+ }
37450
+ return messages;
37451
+ }
37452
+ function getToolResultContent(input) {
37453
+ return input.output.type === "text" ? input.output.value : JSON.stringify(input.output.value);
37454
+ }
37455
+
37456
+ // ../packages/internal/src/openrouter-ai-sdk/chat/get-tool-choice.ts
37457
+ var import_v466 = require("zod/v4");
37458
+ var ChatCompletionToolChoiceSchema = import_v466.z.union([
37459
+ import_v466.z.literal("auto"),
37460
+ import_v466.z.literal("none"),
37461
+ import_v466.z.literal("required"),
37462
+ import_v466.z.object({
37463
+ type: import_v466.z.literal("function"),
37464
+ function: import_v466.z.object({
37465
+ name: import_v466.z.string()
37466
+ })
37467
+ })
37468
+ ]);
37469
+ function getChatCompletionToolChoice(toolChoice) {
37470
+ switch (toolChoice.type) {
37471
+ case "auto":
37472
+ case "none":
37473
+ case "required":
37474
+ return toolChoice.type;
37475
+ case "tool": {
37476
+ return {
37477
+ type: "function",
37478
+ function: { name: toolChoice.toolName }
37479
+ };
37480
+ }
37481
+ default: {
37482
+ throw new Error(`Invalid tool choice type: ${toolChoice}`);
37483
+ }
37484
+ }
37485
+ }
37486
+
37487
+ // ../packages/internal/src/openrouter-ai-sdk/chat/schemas.ts
37488
+ var import_v468 = require("zod/v4");
37489
+
37490
+ // ../packages/internal/src/openrouter-ai-sdk/schemas/error-response.ts
37491
+ var import_v467 = require("zod/v4");
37492
+ var OpenRouterErrorResponseSchema = import_v467.z.object({
37493
+ error: import_v467.z.object({
37494
+ code: import_v467.z.union([import_v467.z.string(), import_v467.z.number()]).nullable().optional().default(null),
37495
+ message: import_v467.z.string(),
37496
+ type: import_v467.z.string().nullable().optional().default(null),
37497
+ param: import_v467.z.any().nullable().optional().default(null)
37498
+ })
37499
+ });
37500
+ var openrouterFailedResponseHandler = createJsonErrorResponseHandler({
37501
+ errorSchema: OpenRouterErrorResponseSchema,
37502
+ errorToMessage: (data) => data.error.message
37503
+ });
37504
+
37505
+ // ../packages/internal/src/openrouter-ai-sdk/chat/schemas.ts
37506
+ var OpenRouterChatCompletionBaseResponseSchema = import_v468.z.object({
37507
+ id: import_v468.z.string().optional(),
37508
+ model: import_v468.z.string().optional(),
37509
+ provider: import_v468.z.string().optional(),
37510
+ usage: import_v468.z.object({
37511
+ prompt_tokens: import_v468.z.number(),
37512
+ prompt_tokens_details: import_v468.z.object({
37513
+ cached_tokens: import_v468.z.number()
37514
+ }).nullish(),
37515
+ completion_tokens: import_v468.z.number(),
37516
+ completion_tokens_details: import_v468.z.object({
37517
+ reasoning_tokens: import_v468.z.number()
37518
+ }).nullish(),
37519
+ total_tokens: import_v468.z.number(),
37520
+ cost: import_v468.z.number().optional(),
37521
+ cost_details: import_v468.z.object({
37522
+ upstream_inference_cost: import_v468.z.number().nullish()
37523
+ }).nullish()
37524
+ }).nullish()
37525
+ });
37526
+ var OpenRouterNonStreamChatCompletionResponseSchema = OpenRouterChatCompletionBaseResponseSchema.extend({
37527
+ choices: import_v468.z.array(import_v468.z.object({
37528
+ message: import_v468.z.object({
37529
+ role: import_v468.z.literal("assistant"),
37530
+ content: import_v468.z.string().nullable().optional(),
37531
+ reasoning: import_v468.z.string().nullable().optional(),
37532
+ reasoning_details: ReasoningDetailArraySchema.nullish(),
37533
+ tool_calls: import_v468.z.array(import_v468.z.object({
37534
+ id: import_v468.z.string().optional().nullable(),
37535
+ type: import_v468.z.literal("function"),
37536
+ function: import_v468.z.object({
37537
+ name: import_v468.z.string(),
37538
+ arguments: import_v468.z.string()
37539
+ })
37540
+ })).optional(),
37541
+ annotations: import_v468.z.array(import_v468.z.object({
37542
+ type: import_v468.z.enum(["url_citation"]),
37543
+ url_citation: import_v468.z.object({
37544
+ end_index: import_v468.z.number(),
37545
+ start_index: import_v468.z.number(),
37546
+ title: import_v468.z.string(),
37547
+ url: import_v468.z.string(),
37548
+ content: import_v468.z.string().optional()
37549
+ })
37550
+ })).nullish()
37551
+ }),
37552
+ index: import_v468.z.number().nullish(),
37553
+ logprobs: import_v468.z.object({
37554
+ content: import_v468.z.array(import_v468.z.object({
37555
+ token: import_v468.z.string(),
37556
+ logprob: import_v468.z.number(),
37557
+ top_logprobs: import_v468.z.array(import_v468.z.object({
37558
+ token: import_v468.z.string(),
37559
+ logprob: import_v468.z.number()
37560
+ }))
37561
+ })).nullable()
37562
+ }).nullable().optional(),
37563
+ finish_reason: import_v468.z.string().optional().nullable()
37564
+ }))
37565
+ });
37566
+ var OpenRouterStreamChatCompletionChunkSchema = import_v468.z.union([
37567
+ OpenRouterChatCompletionBaseResponseSchema.extend({
37568
+ choices: import_v468.z.array(import_v468.z.object({
37569
+ delta: import_v468.z.object({
37570
+ role: import_v468.z.enum(["assistant"]).optional(),
37571
+ content: import_v468.z.string().nullish(),
37572
+ reasoning: import_v468.z.string().nullish().optional(),
37573
+ reasoning_details: ReasoningDetailArraySchema.nullish(),
37574
+ tool_calls: import_v468.z.array(import_v468.z.object({
37575
+ index: import_v468.z.number().nullish(),
37576
+ id: import_v468.z.string().nullish(),
37577
+ type: import_v468.z.literal("function").optional(),
37578
+ function: import_v468.z.object({
37579
+ name: import_v468.z.string().nullish(),
37580
+ arguments: import_v468.z.string().nullish()
37581
+ })
37582
+ })).nullish(),
37583
+ annotations: import_v468.z.array(import_v468.z.object({
37584
+ type: import_v468.z.enum(["url_citation"]),
37585
+ url_citation: import_v468.z.object({
37586
+ end_index: import_v468.z.number(),
37587
+ start_index: import_v468.z.number(),
37588
+ title: import_v468.z.string(),
37589
+ url: import_v468.z.string(),
37590
+ content: import_v468.z.string().optional()
37591
+ })
37592
+ })).nullish()
37593
+ }).nullish(),
37594
+ logprobs: import_v468.z.object({
37595
+ content: import_v468.z.array(import_v468.z.object({
37596
+ token: import_v468.z.string(),
37597
+ logprob: import_v468.z.number(),
37598
+ top_logprobs: import_v468.z.array(import_v468.z.object({
37599
+ token: import_v468.z.string(),
37600
+ logprob: import_v468.z.number()
37601
+ }))
37602
+ })).nullable()
37603
+ }).nullish(),
37604
+ finish_reason: import_v468.z.string().nullable().optional(),
37605
+ index: import_v468.z.number().nullish()
37606
+ }))
37607
+ }),
37608
+ OpenRouterErrorResponseSchema
37609
+ ]);
37610
+
37611
+ // ../packages/internal/src/openrouter-ai-sdk/utils/map-finish-reason.ts
37612
+ function mapOpenRouterFinishReason(finishReason) {
37613
+ switch (finishReason) {
37614
+ case "stop":
37615
+ return "stop";
37616
+ case "length":
37617
+ return "length";
37618
+ case "content_filter":
37619
+ return "content-filter";
37620
+ case "function_call":
37621
+ case "tool_calls":
37622
+ return "tool-calls";
37623
+ default:
37624
+ return "unknown";
37625
+ }
37626
+ }
37627
+
37628
+ // ../packages/internal/src/openrouter-ai-sdk/chat/index.ts
37629
+ class OpenRouterChatLanguageModel {
37630
+ specificationVersion = "v2";
37631
+ provider = "openrouter";
37632
+ defaultObjectGenerationMode = "tool";
37633
+ modelId;
37634
+ supportedUrls = {
37635
+ "image/*": [
37636
+ /^data:image\/[a-zA-Z]+;base64,/,
37637
+ /^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)$/i
37638
+ ],
37639
+ "application/*": [/^data:application\//, /^https?:\/\/.+$/]
37640
+ };
37641
+ settings;
37642
+ config;
37643
+ constructor(modelId, settings, config) {
37644
+ this.modelId = modelId;
37645
+ this.settings = settings;
37646
+ this.config = config;
37647
+ }
37648
+ getArgs({
37649
+ prompt: prompt2,
37650
+ maxOutputTokens,
37651
+ temperature,
37652
+ topP,
37653
+ frequencyPenalty,
37654
+ presencePenalty,
37655
+ seed,
37656
+ stopSequences,
37657
+ responseFormat,
37658
+ topK,
37659
+ tools,
37660
+ toolChoice
37661
+ }) {
37662
+ const baseArgs = {
37663
+ model: this.modelId,
37664
+ models: this.settings.models,
37665
+ logit_bias: this.settings.logitBias,
37666
+ logprobs: this.settings.logprobs === true || typeof this.settings.logprobs === "number" ? true : undefined,
37667
+ top_logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : undefined : undefined,
37668
+ user: this.settings.user,
37669
+ parallel_tool_calls: this.settings.parallelToolCalls,
37670
+ max_tokens: maxOutputTokens,
37671
+ temperature,
37672
+ top_p: topP,
37673
+ frequency_penalty: frequencyPenalty,
37674
+ presence_penalty: presencePenalty,
37675
+ seed,
37676
+ ...this.modelId === "x-ai/grok-code-fast-1" ? {} : { stop: stopSequences },
37677
+ response_format: responseFormat,
37678
+ top_k: topK,
37679
+ messages: convertToOpenRouterChatMessages(prompt2),
37680
+ include_reasoning: this.settings.includeReasoning,
37681
+ reasoning: this.settings.reasoning,
37682
+ usage: this.settings.usage,
37683
+ plugins: this.settings.plugins,
37684
+ web_search_options: this.settings.web_search_options,
37685
+ provider: this.settings.provider,
37686
+ ...this.config.extraBody,
37687
+ ...this.settings.extraBody
37688
+ };
37689
+ if (responseFormat?.type === "json" && responseFormat.schema != null) {
37690
+ return {
37691
+ ...baseArgs,
37692
+ response_format: {
37693
+ type: "json_schema",
37694
+ json_schema: {
37695
+ schema: responseFormat.schema,
37696
+ strict: true,
37697
+ name: responseFormat.name ?? "response",
37698
+ ...responseFormat.description && {
37699
+ description: responseFormat.description
37700
+ }
37701
+ }
37702
+ }
37703
+ };
37704
+ }
37705
+ if (tools && tools.length > 0) {
37706
+ const mappedTools = tools.filter((tool) => tool.type === "function").map((tool) => ({
37707
+ type: "function",
37708
+ function: {
37709
+ name: tool.name,
37710
+ description: tool.description,
37711
+ parameters: tool.inputSchema
37712
+ }
37713
+ }));
37714
+ return {
37715
+ ...baseArgs,
37716
+ tools: mappedTools,
37717
+ tool_choice: toolChoice ? getChatCompletionToolChoice(toolChoice) : undefined
37718
+ };
37719
+ }
37720
+ return baseArgs;
37721
+ }
37722
+ async doGenerate(options) {
37723
+ const providerOptions = options.providerOptions || {};
37724
+ const openrouterOptions = providerOptions.openrouter || {};
37725
+ const args = {
37726
+ ...this.getArgs(options),
37727
+ ...openrouterOptions
37728
+ };
37729
+ const { value: response, responseHeaders } = await postJsonToApi({
37730
+ url: this.config.url({
37731
+ path: "/chat/completions",
37732
+ modelId: this.modelId
37733
+ }),
37734
+ headers: combineHeaders(this.config.headers(), options.headers),
37735
+ body: args,
37736
+ failedResponseHandler: openrouterFailedResponseHandler,
37737
+ successfulResponseHandler: createJsonResponseHandler(OpenRouterNonStreamChatCompletionResponseSchema),
37738
+ abortSignal: options.abortSignal,
37739
+ fetch: this.config.fetch
37740
+ });
37741
+ const choice = response.choices[0];
37742
+ if (!choice) {
37743
+ throw new Error("No choice in response");
37744
+ }
37745
+ const usageInfo = response.usage ? {
37746
+ inputTokens: response.usage.prompt_tokens ?? 0,
37747
+ outputTokens: response.usage.completion_tokens ?? 0,
37748
+ totalTokens: (response.usage.prompt_tokens ?? 0) + (response.usage.completion_tokens ?? 0),
37749
+ reasoningTokens: response.usage.completion_tokens_details?.reasoning_tokens ?? 0,
37750
+ cachedInputTokens: response.usage.prompt_tokens_details?.cached_tokens ?? 0
37751
+ } : {
37752
+ inputTokens: 0,
37753
+ outputTokens: 0,
37754
+ totalTokens: 0,
37755
+ reasoningTokens: 0,
37756
+ cachedInputTokens: 0
37757
+ };
37758
+ const reasoningDetails = choice.message.reasoning_details ?? [];
37759
+ const reasoning = reasoningDetails.length > 0 ? reasoningDetails.map((detail) => {
37760
+ switch (detail.type) {
37761
+ case "reasoning.text" /* Text */: {
37762
+ if (detail.text) {
37763
+ return {
37764
+ type: "reasoning",
37765
+ text: detail.text
37766
+ };
37767
+ }
37768
+ break;
37769
+ }
37770
+ case "reasoning.summary" /* Summary */: {
37771
+ if (detail.summary) {
37772
+ return {
37773
+ type: "reasoning",
37774
+ text: detail.summary
37775
+ };
37776
+ }
37777
+ break;
37778
+ }
37779
+ case "reasoning.encrypted" /* Encrypted */: {
37780
+ if (detail.data) {
37781
+ return {
37782
+ type: "reasoning",
37783
+ text: "[REDACTED]"
37784
+ };
37785
+ }
37786
+ break;
37787
+ }
37788
+ default: {}
37789
+ }
37790
+ return null;
37791
+ }).filter((p) => p !== null) : choice.message.reasoning ? [
37792
+ {
37793
+ type: "reasoning",
37794
+ text: choice.message.reasoning
37795
+ }
37796
+ ] : [];
37797
+ const content = [];
37798
+ content.push(...reasoning);
37799
+ if (choice.message.content) {
37800
+ content.push({
37801
+ type: "text",
37802
+ text: choice.message.content
37803
+ });
37804
+ }
37805
+ if (choice.message.tool_calls) {
37806
+ for (const toolCall of choice.message.tool_calls) {
37807
+ content.push({
37808
+ type: "tool-call",
37809
+ toolCallId: toolCall.id ?? generateId(),
37810
+ toolName: toolCall.function.name,
37811
+ input: toolCall.function.arguments
37812
+ });
37813
+ }
37814
+ }
37815
+ if (choice.message.annotations) {
37816
+ for (const annotation of choice.message.annotations) {
37817
+ if (annotation.type === "url_citation") {
37818
+ content.push({
37819
+ type: "source",
37820
+ sourceType: "url",
37821
+ id: annotation.url_citation.url,
37822
+ url: annotation.url_citation.url,
37823
+ title: annotation.url_citation.title,
37824
+ providerMetadata: {
37825
+ openrouter: {
37826
+ content: annotation.url_citation.content || ""
37827
+ }
37828
+ }
37829
+ });
37830
+ }
37831
+ }
37832
+ }
37833
+ return {
37834
+ content,
37835
+ finishReason: mapOpenRouterFinishReason(choice.finish_reason),
37836
+ usage: usageInfo,
37837
+ warnings: [],
37838
+ providerMetadata: {
37839
+ openrouter: {
37840
+ provider: response.provider ?? "",
37841
+ usage: {
37842
+ promptTokens: usageInfo.inputTokens ?? 0,
37843
+ completionTokens: usageInfo.outputTokens ?? 0,
37844
+ totalTokens: usageInfo.totalTokens ?? 0,
37845
+ cost: response.usage?.cost,
37846
+ promptTokensDetails: {
37847
+ cachedTokens: response.usage?.prompt_tokens_details?.cached_tokens ?? 0
37848
+ },
37849
+ completionTokensDetails: {
37850
+ reasoningTokens: response.usage?.completion_tokens_details?.reasoning_tokens ?? 0
37851
+ },
37852
+ costDetails: {
37853
+ upstreamInferenceCost: response.usage?.cost_details?.upstream_inference_cost ?? 0
37854
+ }
37855
+ }
37856
+ }
37857
+ },
37858
+ request: { body: args },
37859
+ response: {
37860
+ id: response.id,
37861
+ modelId: response.model,
37862
+ headers: responseHeaders
37863
+ }
37864
+ };
37865
+ }
37866
+ async doStream(options) {
37867
+ const providerOptions = options.providerOptions || {};
37868
+ const openrouterOptions = providerOptions.openrouter || {};
37869
+ const args = {
37870
+ ...this.getArgs(options),
37871
+ ...openrouterOptions
37872
+ };
37873
+ const { value: response, responseHeaders } = await postJsonToApi({
37874
+ url: this.config.url({
37875
+ path: "/chat/completions",
37876
+ modelId: this.modelId
37877
+ }),
37878
+ headers: combineHeaders(this.config.headers(), options.headers),
37879
+ body: {
37880
+ ...args,
37881
+ stream: true,
37882
+ stream_options: this.config.compatibility === "strict" ? {
37883
+ include_usage: true,
37884
+ ...this.settings.usage?.include ? { include_usage: true } : {}
37885
+ } : undefined
37886
+ },
37887
+ failedResponseHandler: openrouterFailedResponseHandler,
37888
+ successfulResponseHandler: createEventSourceResponseHandler(OpenRouterStreamChatCompletionChunkSchema),
37889
+ abortSignal: options.abortSignal,
37890
+ fetch: this.config.fetch
37891
+ });
37892
+ const toolCalls2 = [];
37893
+ let finishReason = "other";
37894
+ const usage = {
37895
+ inputTokens: Number.NaN,
37896
+ outputTokens: Number.NaN,
37897
+ totalTokens: Number.NaN,
37898
+ reasoningTokens: Number.NaN,
37899
+ cachedInputTokens: Number.NaN
37900
+ };
37901
+ const openrouterUsage = {};
37902
+ let textStarted = false;
37903
+ let reasoningStarted = false;
37904
+ let textId;
37905
+ let reasoningId;
37906
+ let openrouterResponseId;
37907
+ let provider;
37908
+ return {
37909
+ stream: response.pipeThrough(new TransformStream({
37910
+ transform(chunk, controller) {
37911
+ if (!chunk.success) {
37912
+ finishReason = "error";
37913
+ controller.enqueue({ type: "error", error: chunk.error });
37914
+ return;
37915
+ }
37916
+ const value = chunk.value;
37917
+ if ("error" in value) {
37918
+ finishReason = "error";
37919
+ controller.enqueue({ type: "error", error: value.error });
37920
+ return;
37921
+ }
37922
+ if (value.provider) {
37923
+ provider = value.provider;
37924
+ }
37925
+ if (value.id) {
37926
+ openrouterResponseId = value.id;
37927
+ controller.enqueue({
37928
+ type: "response-metadata",
37929
+ id: value.id
37930
+ });
37931
+ }
37932
+ if (value.model) {
37933
+ controller.enqueue({
37934
+ type: "response-metadata",
37935
+ modelId: value.model
37936
+ });
37937
+ }
37938
+ if (value.usage != null) {
37939
+ usage.inputTokens = value.usage.prompt_tokens;
37940
+ usage.outputTokens = value.usage.completion_tokens;
37941
+ usage.totalTokens = value.usage.prompt_tokens + value.usage.completion_tokens;
37942
+ openrouterUsage.promptTokens = value.usage.prompt_tokens;
37943
+ if (value.usage.prompt_tokens_details) {
37944
+ const cachedInputTokens = value.usage.prompt_tokens_details.cached_tokens ?? 0;
37945
+ usage.cachedInputTokens = cachedInputTokens;
37946
+ openrouterUsage.promptTokensDetails = {
37947
+ cachedTokens: cachedInputTokens
37948
+ };
37949
+ }
37950
+ openrouterUsage.completionTokens = value.usage.completion_tokens;
37951
+ if (value.usage.completion_tokens_details) {
37952
+ const reasoningTokens = value.usage.completion_tokens_details.reasoning_tokens ?? 0;
37953
+ usage.reasoningTokens = reasoningTokens;
37954
+ openrouterUsage.completionTokensDetails = {
37955
+ reasoningTokens
37956
+ };
37957
+ }
37958
+ const upstreamInferenceCost = value.usage.cost_details?.upstream_inference_cost;
37959
+ if (upstreamInferenceCost != null && upstreamInferenceCost !== undefined) {
37960
+ openrouterUsage.costDetails = {
37961
+ upstreamInferenceCost
37962
+ };
37963
+ }
37964
+ if (value.usage.cost !== undefined) {
37965
+ openrouterUsage.cost = value.usage.cost;
37966
+ }
37967
+ openrouterUsage.totalTokens = value.usage.total_tokens;
37968
+ }
37969
+ const choice = value.choices[0];
37970
+ if (choice?.finish_reason != null) {
37971
+ finishReason = mapOpenRouterFinishReason(choice.finish_reason);
37972
+ }
37973
+ if (choice?.delta == null) {
37974
+ return;
37975
+ }
37976
+ const delta = choice.delta;
37977
+ const emitReasoningChunk = (chunkText) => {
37978
+ if (!reasoningStarted) {
37979
+ reasoningId = openrouterResponseId || generateId();
37980
+ controller.enqueue({
37981
+ type: "reasoning-start",
37982
+ id: reasoningId
37983
+ });
37984
+ reasoningStarted = true;
37985
+ }
37986
+ controller.enqueue({
37987
+ type: "reasoning-delta",
37988
+ delta: chunkText,
37989
+ id: reasoningId || generateId()
37990
+ });
37991
+ };
37992
+ if (delta.reasoning_details && delta.reasoning_details.length > 0) {
37993
+ for (const detail of delta.reasoning_details) {
37994
+ switch (detail.type) {
37995
+ case "reasoning.text" /* Text */: {
37996
+ if (detail.text) {
37997
+ emitReasoningChunk(detail.text);
37998
+ }
37999
+ break;
38000
+ }
38001
+ case "reasoning.encrypted" /* Encrypted */: {
38002
+ if (detail.data) {
38003
+ emitReasoningChunk("[REDACTED]");
38004
+ }
38005
+ break;
38006
+ }
38007
+ case "reasoning.summary" /* Summary */: {
38008
+ if (detail.summary) {
38009
+ emitReasoningChunk(detail.summary);
38010
+ }
38011
+ break;
38012
+ }
38013
+ default: {
38014
+ break;
38015
+ }
38016
+ }
38017
+ }
38018
+ } else if (delta.reasoning) {
38019
+ emitReasoningChunk(delta.reasoning);
38020
+ }
38021
+ if (delta.content) {
38022
+ if (reasoningStarted && !textStarted) {
38023
+ controller.enqueue({
38024
+ type: "reasoning-end",
38025
+ id: reasoningId || generateId()
38026
+ });
38027
+ reasoningStarted = false;
38028
+ }
38029
+ if (!textStarted) {
38030
+ textId = openrouterResponseId || generateId();
38031
+ controller.enqueue({
38032
+ type: "text-start",
38033
+ id: textId
38034
+ });
38035
+ textStarted = true;
38036
+ }
38037
+ controller.enqueue({
38038
+ type: "text-delta",
38039
+ delta: delta.content,
38040
+ id: textId || generateId()
38041
+ });
38042
+ }
38043
+ if (delta.annotations) {
38044
+ for (const annotation of delta.annotations) {
38045
+ if (annotation.type === "url_citation") {
38046
+ controller.enqueue({
38047
+ type: "source",
38048
+ sourceType: "url",
38049
+ id: annotation.url_citation.url,
38050
+ url: annotation.url_citation.url,
38051
+ title: annotation.url_citation.title,
38052
+ providerMetadata: {
38053
+ openrouter: {
38054
+ content: annotation.url_citation.content || ""
38055
+ }
38056
+ }
38057
+ });
38058
+ }
38059
+ }
38060
+ }
38061
+ if (delta.tool_calls != null) {
38062
+ for (const toolCallDelta of delta.tool_calls) {
38063
+ const index = toolCallDelta.index ?? toolCalls2.length - 1;
38064
+ if (toolCalls2[index] == null) {
38065
+ if (toolCallDelta.type !== "function") {
38066
+ throw new InvalidResponseDataError({
38067
+ data: toolCallDelta,
38068
+ message: `Expected 'function' type.`
38069
+ });
38070
+ }
38071
+ if (toolCallDelta.id == null) {
38072
+ throw new InvalidResponseDataError({
38073
+ data: toolCallDelta,
38074
+ message: `Expected 'id' to be a string.`
38075
+ });
38076
+ }
38077
+ if (toolCallDelta.function?.name == null) {
38078
+ throw new InvalidResponseDataError({
38079
+ data: toolCallDelta,
38080
+ message: `Expected 'function.name' to be a string.`
38081
+ });
38082
+ }
38083
+ toolCalls2[index] = {
38084
+ id: toolCallDelta.id,
38085
+ type: "function",
38086
+ function: {
38087
+ name: toolCallDelta.function.name,
38088
+ arguments: toolCallDelta.function.arguments ?? ""
38089
+ },
38090
+ inputStarted: false,
38091
+ sent: false
38092
+ };
38093
+ const toolCall2 = toolCalls2[index];
38094
+ if (toolCall2 == null) {
38095
+ throw new Error("Tool call is missing");
38096
+ }
38097
+ if (toolCall2.function?.name != null && toolCall2.function?.arguments != null && isParsableJson(toolCall2.function.arguments)) {
38098
+ toolCall2.inputStarted = true;
38099
+ controller.enqueue({
38100
+ type: "tool-input-start",
38101
+ id: toolCall2.id,
38102
+ toolName: toolCall2.function.name
38103
+ });
38104
+ controller.enqueue({
38105
+ type: "tool-input-delta",
38106
+ id: toolCall2.id,
38107
+ delta: toolCall2.function.arguments
38108
+ });
38109
+ controller.enqueue({
38110
+ type: "tool-input-end",
38111
+ id: toolCall2.id
38112
+ });
38113
+ controller.enqueue({
38114
+ type: "tool-call",
38115
+ toolCallId: toolCall2.id,
38116
+ toolName: toolCall2.function.name,
38117
+ input: toolCall2.function.arguments
38118
+ });
38119
+ toolCall2.sent = true;
38120
+ }
38121
+ continue;
38122
+ }
38123
+ const toolCall = toolCalls2[index];
38124
+ if (toolCall == null) {
38125
+ throw new Error("Tool call is missing");
38126
+ }
38127
+ if (!toolCall.inputStarted) {
38128
+ toolCall.inputStarted = true;
38129
+ controller.enqueue({
38130
+ type: "tool-input-start",
38131
+ id: toolCall.id,
38132
+ toolName: toolCall.function.name
38133
+ });
38134
+ }
38135
+ if (toolCallDelta.function?.arguments != null) {
38136
+ toolCall.function.arguments += toolCallDelta.function?.arguments ?? "";
38137
+ }
38138
+ controller.enqueue({
38139
+ type: "tool-input-delta",
38140
+ id: toolCall.id,
38141
+ delta: toolCallDelta.function.arguments ?? ""
38142
+ });
38143
+ if (toolCall.function?.name != null && toolCall.function?.arguments != null && isParsableJson(toolCall.function.arguments)) {
38144
+ controller.enqueue({
38145
+ type: "tool-call",
38146
+ toolCallId: toolCall.id ?? generateId(),
38147
+ toolName: toolCall.function.name,
38148
+ input: toolCall.function.arguments
38149
+ });
38150
+ toolCall.sent = true;
38151
+ }
38152
+ }
38153
+ }
38154
+ },
38155
+ flush(controller) {
38156
+ if (finishReason === "tool-calls") {
38157
+ for (const toolCall of toolCalls2) {
38158
+ if (toolCall && !toolCall.sent) {
38159
+ controller.enqueue({
38160
+ type: "tool-call",
38161
+ toolCallId: toolCall.id ?? generateId(),
38162
+ toolName: toolCall.function.name,
38163
+ input: isParsableJson(toolCall.function.arguments) ? toolCall.function.arguments : "{}"
38164
+ });
38165
+ toolCall.sent = true;
38166
+ }
38167
+ }
38168
+ }
38169
+ if (reasoningStarted) {
38170
+ controller.enqueue({
38171
+ type: "reasoning-end",
38172
+ id: reasoningId || generateId()
38173
+ });
38174
+ }
38175
+ if (textStarted) {
38176
+ controller.enqueue({
38177
+ type: "text-end",
38178
+ id: textId || generateId()
38179
+ });
38180
+ }
38181
+ const openrouterMetadata = {
38182
+ usage: openrouterUsage
38183
+ };
38184
+ if (provider !== undefined) {
38185
+ openrouterMetadata.provider = provider;
38186
+ }
38187
+ controller.enqueue({
38188
+ type: "finish",
38189
+ finishReason,
38190
+ usage,
38191
+ providerMetadata: {
38192
+ openrouter: openrouterMetadata
38193
+ }
38194
+ });
38195
+ }
38196
+ })),
38197
+ warnings: [],
38198
+ request: { body: args },
38199
+ response: { headers: responseHeaders }
38200
+ };
38201
+ }
38202
+ }
38203
+
38204
+ // ../packages/internal/src/openrouter-ai-sdk/completion/convert-to-openrouter-completion-prompt.ts
38205
+ function convertToOpenRouterCompletionPrompt({
38206
+ prompt: prompt2,
38207
+ inputFormat,
38208
+ user = "user",
38209
+ assistant = "assistant"
38210
+ }) {
38211
+ 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") {
38212
+ return { prompt: prompt2[0].content[0].text };
38213
+ }
38214
+ let text = "";
38215
+ if (prompt2[0] && prompt2[0].role === "system") {
38216
+ text += `${prompt2[0].content}
38217
+
38218
+ `;
38219
+ prompt2 = prompt2.slice(1);
38220
+ }
38221
+ for (const { role, content } of prompt2) {
38222
+ switch (role) {
38223
+ case "system": {
38224
+ throw new InvalidPromptError({
38225
+ message: `Unexpected system message in prompt: ${content}`,
38226
+ prompt: prompt2
38227
+ });
38228
+ }
38229
+ case "user": {
38230
+ const userMessage2 = content.map((part) => {
38231
+ switch (part.type) {
38232
+ case "text": {
38233
+ return part.text;
38234
+ }
38235
+ case "file": {
38236
+ throw new UnsupportedFunctionalityError({
38237
+ functionality: "file attachments"
38238
+ });
38239
+ }
38240
+ default: {
38241
+ return "";
38242
+ }
38243
+ }
38244
+ }).join("");
38245
+ text += `${user}:
38246
+ ${userMessage2}
38247
+
38248
+ `;
38249
+ break;
38250
+ }
38251
+ case "assistant": {
38252
+ const assistantMessage2 = content.map((part) => {
38253
+ switch (part.type) {
38254
+ case "text": {
38255
+ return part.text;
38256
+ }
38257
+ case "tool-call": {
38258
+ throw new UnsupportedFunctionalityError({
38259
+ functionality: "tool-call messages"
38260
+ });
38261
+ }
38262
+ case "tool-result": {
38263
+ throw new UnsupportedFunctionalityError({
38264
+ functionality: "tool-result messages"
38265
+ });
38266
+ }
38267
+ case "reasoning": {
38268
+ throw new UnsupportedFunctionalityError({
38269
+ functionality: "reasoning messages"
38270
+ });
38271
+ }
38272
+ case "file": {
38273
+ throw new UnsupportedFunctionalityError({
38274
+ functionality: "file attachments"
38275
+ });
38276
+ }
38277
+ default: {
38278
+ return "";
38279
+ }
38280
+ }
38281
+ }).join("");
38282
+ text += `${assistant}:
38283
+ ${assistantMessage2}
38284
+
38285
+ `;
38286
+ break;
38287
+ }
38288
+ case "tool": {
38289
+ throw new UnsupportedFunctionalityError({
38290
+ functionality: "tool messages"
38291
+ });
38292
+ }
38293
+ default: {
38294
+ break;
38295
+ }
38296
+ }
38297
+ }
38298
+ text += `${assistant}:
38299
+ `;
38300
+ return {
38301
+ prompt: text
38302
+ };
38303
+ }
38304
+
38305
+ // ../packages/internal/src/openrouter-ai-sdk/completion/schemas.ts
38306
+ var import_v469 = require("zod/v4");
38307
+ var OpenRouterCompletionChunkSchema = import_v469.z.union([
38308
+ import_v469.z.object({
38309
+ id: import_v469.z.string().optional(),
38310
+ model: import_v469.z.string().optional(),
38311
+ choices: import_v469.z.array(import_v469.z.object({
38312
+ text: import_v469.z.string(),
38313
+ reasoning: import_v469.z.string().nullish().optional(),
38314
+ reasoning_details: ReasoningDetailArraySchema.nullish(),
38315
+ finish_reason: import_v469.z.string().nullish(),
38316
+ index: import_v469.z.number().nullish(),
38317
+ logprobs: import_v469.z.object({
38318
+ tokens: import_v469.z.array(import_v469.z.string()),
38319
+ token_logprobs: import_v469.z.array(import_v469.z.number()),
38320
+ top_logprobs: import_v469.z.array(import_v469.z.record(import_v469.z.string(), import_v469.z.number())).nullable()
38321
+ }).nullable().optional()
38322
+ })),
38323
+ usage: import_v469.z.object({
38324
+ prompt_tokens: import_v469.z.number(),
38325
+ prompt_tokens_details: import_v469.z.object({
38326
+ cached_tokens: import_v469.z.number()
38327
+ }).nullish(),
38328
+ completion_tokens: import_v469.z.number(),
38329
+ completion_tokens_details: import_v469.z.object({
38330
+ reasoning_tokens: import_v469.z.number()
38331
+ }).nullish(),
38332
+ total_tokens: import_v469.z.number(),
38333
+ cost: import_v469.z.number().optional()
38334
+ }).nullish()
38335
+ }),
38336
+ OpenRouterErrorResponseSchema
38337
+ ]);
38338
+
38339
+ // ../packages/internal/src/openrouter-ai-sdk/completion/index.ts
38340
+ class OpenRouterCompletionLanguageModel {
38341
+ specificationVersion = "v2";
38342
+ provider = "openrouter";
38343
+ modelId;
38344
+ supportedUrls = {
38345
+ "image/*": [
38346
+ /^data:image\/[a-zA-Z]+;base64,/,
38347
+ /^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)$/i
38348
+ ],
38349
+ "text/*": [/^data:text\//, /^https?:\/\/.+$/],
38350
+ "application/*": [/^data:application\//, /^https?:\/\/.+$/]
38351
+ };
38352
+ defaultObjectGenerationMode = undefined;
38353
+ settings;
38354
+ config;
38355
+ constructor(modelId, settings, config) {
38356
+ this.modelId = modelId;
38357
+ this.settings = settings;
38358
+ this.config = config;
38359
+ }
38360
+ getArgs({
38361
+ prompt: prompt2,
38362
+ maxOutputTokens,
38363
+ temperature,
38364
+ topP,
38365
+ frequencyPenalty,
38366
+ presencePenalty,
38367
+ seed,
38368
+ responseFormat,
38369
+ topK,
38370
+ stopSequences,
38371
+ tools,
38372
+ toolChoice
38373
+ }) {
38374
+ const { prompt: completionPrompt } = convertToOpenRouterCompletionPrompt({
38375
+ prompt: prompt2,
38376
+ inputFormat: "prompt"
38377
+ });
38378
+ if (tools?.length) {
38379
+ throw new UnsupportedFunctionalityError({
38380
+ functionality: "tools"
38381
+ });
38382
+ }
38383
+ if (toolChoice) {
38384
+ throw new UnsupportedFunctionalityError({
38385
+ functionality: "toolChoice"
38386
+ });
38387
+ }
38388
+ return {
38389
+ model: this.modelId,
38390
+ models: this.settings.models,
38391
+ logit_bias: this.settings.logitBias,
38392
+ logprobs: typeof this.settings.logprobs === "number" ? this.settings.logprobs : typeof this.settings.logprobs === "boolean" ? this.settings.logprobs ? 0 : undefined : undefined,
38393
+ suffix: this.settings.suffix,
38394
+ user: this.settings.user,
38395
+ max_tokens: maxOutputTokens,
38396
+ temperature,
38397
+ top_p: topP,
38398
+ frequency_penalty: frequencyPenalty,
38399
+ presence_penalty: presencePenalty,
38400
+ seed,
38401
+ ...this.modelId === "x-ai/grok-code-fast-1" ? {} : { stop: stopSequences },
38402
+ response_format: responseFormat,
38403
+ top_k: topK,
38404
+ prompt: completionPrompt,
38405
+ include_reasoning: this.settings.includeReasoning,
38406
+ reasoning: this.settings.reasoning,
38407
+ ...this.config.extraBody,
38408
+ ...this.settings.extraBody
38409
+ };
38410
+ }
38411
+ async doGenerate(options) {
38412
+ const providerOptions = options.providerOptions || {};
38413
+ const openrouterOptions = providerOptions.openrouter || {};
38414
+ const args = {
38415
+ ...this.getArgs(options),
38416
+ ...openrouterOptions
38417
+ };
38418
+ const { value: response, responseHeaders } = await postJsonToApi({
38419
+ url: this.config.url({
38420
+ path: "/completions",
38421
+ modelId: this.modelId
38422
+ }),
38423
+ headers: combineHeaders(this.config.headers(), options.headers),
38424
+ body: args,
38425
+ failedResponseHandler: openrouterFailedResponseHandler,
38426
+ successfulResponseHandler: createJsonResponseHandler(OpenRouterCompletionChunkSchema),
38427
+ abortSignal: options.abortSignal,
38428
+ fetch: this.config.fetch
38429
+ });
38430
+ if ("error" in response) {
38431
+ throw new Error(`${response.error.message}`);
38432
+ }
38433
+ const choice = response.choices[0];
38434
+ if (!choice) {
38435
+ throw new Error("No choice in OpenRouter completion response");
38436
+ }
38437
+ return {
38438
+ content: [
38439
+ {
38440
+ type: "text",
38441
+ text: choice.text ?? ""
38442
+ }
38443
+ ],
38444
+ finishReason: mapOpenRouterFinishReason(choice.finish_reason),
38445
+ usage: {
38446
+ inputTokens: response.usage?.prompt_tokens ?? 0,
38447
+ outputTokens: response.usage?.completion_tokens ?? 0,
38448
+ totalTokens: (response.usage?.prompt_tokens ?? 0) + (response.usage?.completion_tokens ?? 0),
38449
+ reasoningTokens: response.usage?.completion_tokens_details?.reasoning_tokens ?? 0,
38450
+ cachedInputTokens: response.usage?.prompt_tokens_details?.cached_tokens ?? 0
38451
+ },
38452
+ warnings: [],
38453
+ response: {
38454
+ headers: responseHeaders
38455
+ }
38456
+ };
38457
+ }
38458
+ async doStream(options) {
38459
+ const providerOptions = options.providerOptions || {};
38460
+ const openrouterOptions = providerOptions.openrouter || {};
38461
+ const args = {
38462
+ ...this.getArgs(options),
38463
+ ...openrouterOptions
38464
+ };
38465
+ const { value: response, responseHeaders } = await postJsonToApi({
38466
+ url: this.config.url({
38467
+ path: "/completions",
38468
+ modelId: this.modelId
38469
+ }),
38470
+ headers: combineHeaders(this.config.headers(), options.headers),
38471
+ body: {
38472
+ ...args,
38473
+ stream: true,
38474
+ stream_options: this.config.compatibility === "strict" ? { include_usage: true } : undefined
38475
+ },
38476
+ failedResponseHandler: openrouterFailedResponseHandler,
38477
+ successfulResponseHandler: createEventSourceResponseHandler(OpenRouterCompletionChunkSchema),
38478
+ abortSignal: options.abortSignal,
38479
+ fetch: this.config.fetch
38480
+ });
38481
+ let finishReason = "other";
38482
+ const usage = {
38483
+ inputTokens: Number.NaN,
38484
+ outputTokens: Number.NaN,
38485
+ totalTokens: Number.NaN,
38486
+ reasoningTokens: Number.NaN,
38487
+ cachedInputTokens: Number.NaN
38488
+ };
38489
+ const openrouterUsage = {};
38490
+ return {
38491
+ stream: response.pipeThrough(new TransformStream({
38492
+ transform(chunk, controller) {
38493
+ if (!chunk.success) {
38494
+ finishReason = "error";
38495
+ controller.enqueue({ type: "error", error: chunk.error });
38496
+ return;
38497
+ }
38498
+ const value = chunk.value;
38499
+ if ("error" in value) {
38500
+ finishReason = "error";
38501
+ controller.enqueue({ type: "error", error: value.error });
38502
+ return;
38503
+ }
38504
+ if (value.usage != null) {
38505
+ usage.inputTokens = value.usage.prompt_tokens;
38506
+ usage.outputTokens = value.usage.completion_tokens;
38507
+ usage.totalTokens = value.usage.prompt_tokens + value.usage.completion_tokens;
38508
+ openrouterUsage.promptTokens = value.usage.prompt_tokens;
38509
+ if (value.usage.prompt_tokens_details) {
38510
+ const cachedInputTokens = value.usage.prompt_tokens_details.cached_tokens ?? 0;
38511
+ usage.cachedInputTokens = cachedInputTokens;
38512
+ openrouterUsage.promptTokensDetails = {
38513
+ cachedTokens: cachedInputTokens
38514
+ };
38515
+ }
38516
+ openrouterUsage.completionTokens = value.usage.completion_tokens;
38517
+ if (value.usage.completion_tokens_details) {
38518
+ const reasoningTokens = value.usage.completion_tokens_details.reasoning_tokens ?? 0;
38519
+ usage.reasoningTokens = reasoningTokens;
38520
+ openrouterUsage.completionTokensDetails = {
38521
+ reasoningTokens
38522
+ };
38523
+ }
38524
+ if (value.usage.cost !== undefined) {
38525
+ openrouterUsage.cost = value.usage.cost;
38526
+ }
38527
+ openrouterUsage.totalTokens = value.usage.total_tokens;
38528
+ }
38529
+ const choice = value.choices[0];
38530
+ if (choice?.finish_reason != null) {
38531
+ finishReason = mapOpenRouterFinishReason(choice.finish_reason);
38532
+ }
38533
+ if (choice?.text != null) {
38534
+ controller.enqueue({
38535
+ type: "text-delta",
38536
+ delta: choice.text,
38537
+ id: generateId()
38538
+ });
38539
+ }
38540
+ },
38541
+ flush(controller) {
38542
+ controller.enqueue({
38543
+ type: "finish",
38544
+ finishReason,
38545
+ usage,
38546
+ providerMetadata: {
38547
+ openrouter: {
38548
+ usage: openrouterUsage
38549
+ }
38550
+ }
38551
+ });
38552
+ }
38553
+ })),
38554
+ response: {
38555
+ headers: responseHeaders
38556
+ }
38557
+ };
38558
+ }
38559
+ }
38560
+
38561
+ // ../packages/internal/src/openrouter-ai-sdk/provider.ts
38562
+ function createOpenRouter(options = {}) {
38563
+ const baseURL = withoutTrailingSlash(options.baseURL ?? options.baseUrl) ?? "https://openrouter.ai/api/v1";
38564
+ const compatibility = options.compatibility ?? "compatible";
38565
+ const getHeaders = () => ({
38566
+ Authorization: `Bearer ${loadApiKey({
38567
+ apiKey: options.apiKey,
38568
+ environmentVariableName: "OPENROUTER_API_KEY",
38569
+ description: "OpenRouter"
38570
+ })}`,
38571
+ ...options.headers
38572
+ });
38573
+ const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
38574
+ provider: "openrouter.chat",
38575
+ url: ({ path: path4 }) => `${baseURL}${path4}`,
38576
+ headers: getHeaders,
38577
+ compatibility,
38578
+ fetch: options.fetch,
38579
+ extraBody: options.extraBody
38580
+ });
38581
+ const createCompletionModel = (modelId, settings = {}) => new OpenRouterCompletionLanguageModel(modelId, settings, {
38582
+ provider: "openrouter.completion",
38583
+ url: ({ path: path4 }) => `${baseURL}${path4}`,
38584
+ headers: getHeaders,
38585
+ compatibility,
38586
+ fetch: options.fetch,
38587
+ extraBody: options.extraBody
38588
+ });
38589
+ const createLanguageModel = (modelId, settings) => {
38590
+ if (new.target) {
38591
+ throw new Error("The OpenRouter model function cannot be called with the new keyword.");
38592
+ }
38593
+ if (modelId === "openai/gpt-3.5-turbo-instruct") {
38594
+ return createCompletionModel(modelId, settings);
38595
+ }
38596
+ return createChatModel(modelId, settings);
38597
+ };
38598
+ const provider = (modelId, settings) => createLanguageModel(modelId, settings);
38599
+ provider.languageModel = createLanguageModel;
38600
+ provider.chat = createChatModel;
38601
+ provider.completion = createCompletionModel;
38602
+ return provider;
38603
+ }
38604
+ var openrouter = createOpenRouter({
38605
+ compatibility: "strict"
37163
38606
  });
37164
- var processEnv = getProcessEnv();
37165
38607
 
37166
- // src/env.ts
37167
- var getSdkEnv = () => ({
37168
- ...getBaseEnv(),
37169
- LEVELCODE_RG_PATH: process.env.LEVELCODE_RG_PATH,
37170
- LEVELCODE_WASM_DIR: process.env.LEVELCODE_WASM_DIR,
37171
- VERBOSE: process.env.VERBOSE,
37172
- OVERRIDE_TARGET: process.env.OVERRIDE_TARGET,
37173
- OVERRIDE_PLATFORM: process.env.OVERRIDE_PLATFORM,
37174
- OVERRIDE_ARCH: process.env.OVERRIDE_ARCH
38608
+ // src/credentials.ts
38609
+ var import_fs = __toESM(require("fs"));
38610
+ var import_node_path = __toESM(require("node:path"));
38611
+ var import_os = __toESM(require("os"));
38612
+
38613
+ // ../common/src/util/credentials.ts
38614
+ var import_v470 = require("zod/v4");
38615
+ var userSchema = import_v470.z.object({
38616
+ id: import_v470.z.string(),
38617
+ email: import_v470.z.string(),
38618
+ name: import_v470.z.string().nullable(),
38619
+ authToken: import_v470.z.string(),
38620
+ fingerprintId: import_v470.z.string(),
38621
+ fingerprintHash: import_v470.z.string()
37175
38622
  });
37176
- var getLevelCodeApiKeyFromEnv = () => {
37177
- return process.env[API_KEY_ENV_VAR];
37178
- };
37179
- var getSystemProcessEnv = () => {
37180
- return process.env;
37181
- };
37182
- var getByokOpenrouterApiKeyFromEnv = () => {
37183
- return process.env[BYOK_OPENROUTER_ENV_VAR];
37184
- };
37185
- var getClaudeOAuthTokenFromEnv = () => {
37186
- return process.env[CLAUDE_OAUTH_TOKEN_ENV_VAR];
37187
- };
37188
38623
 
37189
38624
  // src/credentials.ts
37190
- var claudeOAuthSchema = import_v466.z.object({
37191
- accessToken: import_v466.z.string(),
37192
- refreshToken: import_v466.z.string(),
37193
- expiresAt: import_v466.z.number(),
37194
- connectedAt: import_v466.z.number()
38625
+ var import_v471 = require("zod/v4");
38626
+ var claudeOAuthSchema = import_v471.z.object({
38627
+ accessToken: import_v471.z.string(),
38628
+ refreshToken: import_v471.z.string(),
38629
+ expiresAt: import_v471.z.number(),
38630
+ connectedAt: import_v471.z.number()
37195
38631
  });
37196
- var credentialsFileSchema = import_v466.z.object({
38632
+ var credentialsFileSchema = import_v471.z.object({
37197
38633
  default: userSchema.optional(),
37198
38634
  claudeOAuth: claudeOAuthSchema.optional()
37199
38635
  });
@@ -37401,6 +38837,15 @@ async function fetchClaudeOAuthResetTime(accessToken) {
37401
38837
  return null;
37402
38838
  }
37403
38839
  }
38840
+ function createDirectOpenRouterModel(openRouterApiKey, model) {
38841
+ const provider = createOpenRouter({ apiKey: openRouterApiKey, compatibility: "strict" });
38842
+ return provider.chat(model);
38843
+ }
38844
+ function createDirectAnthropicModel(anthropicApiKey, model) {
38845
+ const anthropicModelId = toAnthropicModelId(model);
38846
+ const anthropic = import_anthropic.createAnthropic({ apiKey: anthropicApiKey });
38847
+ return anthropic(anthropicModelId);
38848
+ }
37404
38849
  async function getModelForRequest(params2) {
37405
38850
  const { apiKey, model, skipClaudeOAuth } = params2;
37406
38851
  if (!skipClaudeOAuth && !isClaudeOAuthRateLimited() && isClaudeModel(model)) {
@@ -37412,6 +38857,16 @@ async function getModelForRequest(params2) {
37412
38857
  };
37413
38858
  }
37414
38859
  }
38860
+ if (isStandaloneMode()) {
38861
+ const openRouterKey = getOpenRouterApiKeyFromEnv();
38862
+ if (openRouterKey) {
38863
+ return { model: createDirectOpenRouterModel(openRouterKey, model), isClaudeOAuth: false };
38864
+ }
38865
+ const anthropicKey = getAnthropicApiKeyFromEnv();
38866
+ if (anthropicKey) {
38867
+ return { model: createDirectAnthropicModel(anthropicKey, model), isClaudeOAuth: false };
38868
+ }
38869
+ }
37415
38870
  return {
37416
38871
  model: createLevelCodeBackendModel(apiKey, model),
37417
38872
  isClaudeOAuth: false
@@ -38602,7 +40057,7 @@ function parseFile(parser, query, sourceCode) {
38602
40057
 
38603
40058
  // src/run-state.ts
38604
40059
  var import_lodash17 = __toESM(require_lodash());
38605
- var import_v468 = __toESM(require("zod/v4"));
40060
+ var import_v473 = __toESM(require("zod/v4"));
38606
40061
 
38607
40062
  // src/agents/load-agents.ts
38608
40063
  var import_fs2 = __toESM(require("fs"));
@@ -38844,21 +40299,21 @@ function isValidSkillName(name14) {
38844
40299
  }
38845
40300
 
38846
40301
  // ../common/src/types/skill.ts
38847
- var import_v467 = require("zod/v4");
38848
- var SkillMetadataSchema = import_v467.z.record(import_v467.z.string(), import_v467.z.string());
38849
- var SkillFrontmatterSchema = import_v467.z.object({
38850
- name: import_v467.z.string().min(1).max(SKILL_NAME_MAX_LENGTH).regex(SKILL_NAME_REGEX, "Name must be lowercase alphanumeric with single hyphen separators"),
38851
- description: import_v467.z.string().min(1).max(SKILL_DESCRIPTION_MAX_LENGTH),
38852
- license: import_v467.z.string().optional(),
40302
+ var import_v472 = require("zod/v4");
40303
+ var SkillMetadataSchema = import_v472.z.record(import_v472.z.string(), import_v472.z.string());
40304
+ var SkillFrontmatterSchema = import_v472.z.object({
40305
+ name: import_v472.z.string().min(1).max(SKILL_NAME_MAX_LENGTH).regex(SKILL_NAME_REGEX, "Name must be lowercase alphanumeric with single hyphen separators"),
40306
+ description: import_v472.z.string().min(1).max(SKILL_DESCRIPTION_MAX_LENGTH),
40307
+ license: import_v472.z.string().optional(),
38853
40308
  metadata: SkillMetadataSchema.optional()
38854
40309
  });
38855
- var SkillDefinitionSchema = import_v467.z.object({
38856
- name: import_v467.z.string(),
38857
- description: import_v467.z.string(),
38858
- license: import_v467.z.string().optional(),
40310
+ var SkillDefinitionSchema = import_v472.z.object({
40311
+ name: import_v472.z.string(),
40312
+ description: import_v472.z.string(),
40313
+ license: import_v472.z.string().optional(),
38859
40314
  metadata: SkillMetadataSchema.optional(),
38860
- content: import_v467.z.string(),
38861
- filePath: import_v467.z.string()
40315
+ content: import_v472.z.string(),
40316
+ filePath: import_v472.z.string()
38862
40317
  });
38863
40318
 
38864
40319
  // src/skills/load-skills.ts
@@ -38998,7 +40453,7 @@ function processAgentDefinitions(agentDefinitions) {
38998
40453
  }
38999
40454
  function processCustomToolDefinitions(customToolDefinitions) {
39000
40455
  return Object.fromEntries(customToolDefinitions.map((toolDefinition) => {
39001
- const jsonSchema = import_v468.default.toJSONSchema(toolDefinition.inputSchema, {
40456
+ const jsonSchema = import_v473.default.toJSONSchema(toolDefinition.inputSchema, {
39002
40457
  io: "input"
39003
40458
  });
39004
40459
  delete jsonSchema["$schema"];
@@ -39396,11 +40851,11 @@ function buildFileTree(filePaths) {
39396
40851
  // src/tools/change-file.ts
39397
40852
  var import_path9 = __toESM(require("path"));
39398
40853
  var import_diff4 = require("diff");
39399
- var import_v469 = __toESM(require("zod/v4"));
39400
- var FileChangeSchema2 = import_v469.default.object({
39401
- type: import_v469.default.enum(["patch", "file"]),
39402
- path: import_v469.default.string(),
39403
- content: import_v469.default.string()
40854
+ var import_v474 = __toESM(require("zod/v4"));
40855
+ var FileChangeSchema2 = import_v474.default.object({
40856
+ type: import_v474.default.enum(["patch", "file"]),
40857
+ path: import_v474.default.string(),
40858
+ content: import_v474.default.string()
39404
40859
  });
39405
40860
  function containsUpwardTraversal(dirPath) {
39406
40861
  const normalized = import_path9.default.normalize(dirPath);
@@ -40793,7 +42248,7 @@ init_paths();
40793
42248
  class LevelCodeClient {
40794
42249
  options;
40795
42250
  constructor(options) {
40796
- const foundApiKey = options.apiKey ?? getLevelCodeApiKeyFromEnv();
42251
+ const foundApiKey = options.apiKey ?? getLevelCodeApiKeyFromEnv() ?? (isStandaloneMode() ? "standalone-mode" : undefined);
40797
42252
  if (!foundApiKey) {
40798
42253
  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.`);
40799
42254
  }
@@ -40814,6 +42269,9 @@ Provide a handleEvent function to handle this error.`);
40814
42269
  return run({ ...this.options, ...options });
40815
42270
  }
40816
42271
  async checkConnection() {
42272
+ if (isStandaloneMode()) {
42273
+ return true;
42274
+ }
40817
42275
  try {
40818
42276
  const response = await fetch(`${WEBSITE_URL}/api/healthz`, {
40819
42277
  method: "GET",
@@ -40879,9 +42337,9 @@ var import_fs5 = __toESM(require("fs"));
40879
42337
  var import_promises = __toESM(require("fs/promises"));
40880
42338
  var import_os4 = __toESM(require("os"));
40881
42339
  var import_path13 = __toESM(require("path"));
40882
- var import_v470 = require("zod/v4");
40883
- var mcpFileSchema = import_v470.z.object({
40884
- mcpServers: import_v470.z.record(import_v470.z.string(), mcpConfigSchema).default(() => ({}))
42340
+ var import_v475 = require("zod/v4");
42341
+ var mcpFileSchema = import_v475.z.object({
42342
+ mcpServers: import_v475.z.record(import_v475.z.string(), mcpConfigSchema).default(() => ({}))
40885
42343
  });
40886
42344
  var envKey = "env";
40887
42345
  var processEnv2 = process[envKey];
@@ -41010,5 +42468,5 @@ function loadMCPConfigSync(options) {
41010
42468
  return mergedConfig;
41011
42469
  }
41012
42470
 
41013
- //# debugId=CD9F200A7524114264756E2164756E21
42471
+ //# debugId=3A02774EE46048ED64756E2164756E21
41014
42472
  //# sourceMappingURL=index.cjs.map