From df40984ba546fa038e9465a324c788e786c774e5 Mon Sep 17 00:00:00 2001 From: Yash Dewasthale Date: Sun, 19 Jul 2026 11:56:26 +0530 Subject: [PATCH] feat: update supercode-cli version to 0.1.75 and enhance ConcentrateAI key management: - Bumped version in package.json to 0.1.75. - Refactored API key retrieval for ConcentrateAI to support multiple environment variables. - Updated error handling for missing API keys to provide clearer instructions. - Cleaned up old persisted ConcentrateAI keys, transitioning to session-only BYOK variables. --- apps/supercode-cli/server/package.json | 2 +- .../server/src/cli/ai/concentrate-service.ts | 17 ++++++++++++----- .../server/src/cli/ai/provider.ts | 4 ++-- .../src/cli/commands/slashCommands/connect.ts | 6 ++++-- .../server/src/lib/cli-config.ts | 19 +++++++++++++++++++ 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/apps/supercode-cli/server/package.json b/apps/supercode-cli/server/package.json index d697c04..ce296ca 100644 --- a/apps/supercode-cli/server/package.json +++ b/apps/supercode-cli/server/package.json @@ -1,6 +1,6 @@ { "name": "supercode-cli", - "version": "0.1.74", + "version": "0.1.75", "description": "AI-powered coding agent CLI", "main": "dist/main.js", "bin": { diff --git a/apps/supercode-cli/server/src/cli/ai/concentrate-service.ts b/apps/supercode-cli/server/src/cli/ai/concentrate-service.ts index 5bdb689..776916e 100644 --- a/apps/supercode-cli/server/src/cli/ai/concentrate-service.ts +++ b/apps/supercode-cli/server/src/cli/ai/concentrate-service.ts @@ -10,7 +10,13 @@ const HIGH_VALUE_MODELS = ["anthropic/claude-fable-5", "anthropic/claude-opus-4- const OPUS_MODELS = ["anthropic/claude-opus-4-8", "anthropic/claude-opus-4-7"] const OPUS_MODEL = "anthropic/claude-opus-4-8" -const CONCENTRATE_API_KEY = process.env.CONCENTRATEAI_API_KEY || "" +function getConcentrateApiKey(): string { + return process.env.CONCENTRATE_BYOK_PROD_KEY + || process.env.CONCENTRATE_BYOK_DEV_KEY + || process.env.CONCENTRATEAI_API_KEY + || "" +} + const BASE_URL = "https://api.concentrate.ai/v1" const MAX_RETRIES = 3 @@ -45,7 +51,7 @@ async function nonStreamingRequest(modelName: string, system: string, messages: } const res = await fetchWithRetry(`${BASE_URL}/chat/completions`, { method: "POST", - headers: { Authorization: `Bearer ${CONCENTRATE_API_KEY}`, "Content-Type": "application/json" }, + headers: { Authorization: `Bearer ${getConcentrateApiKey()}`, "Content-Type": "application/json" }, body: JSON.stringify(body), signal: AbortSignal.timeout(60_000), }) @@ -68,8 +74,9 @@ export class ConcentrateService { readonly modelName: string constructor(modelName?: string) { - if (!CONCENTRATE_API_KEY) { - throw new Error("ConcentrateAI is not configured.\n\n Set CONCENTRATEAI_API_KEY in your environment:\n export CONCENTRATEAI_API_KEY=\n\n Get a key at: https://concentrate.ai") + const apiKey = getConcentrateApiKey() + if (!apiKey) { + throw new Error("ConcentrateAI is not configured.\n\n Set CONCENTRATE_BYOK_PROD_KEY or CONCENTRATE_BYOK_DEV_KEY in your\n environment, or run /connect to provide your API key.\n\n Get a key at: https://concentrate.ai") } this.modelName = modelName || "deepseek-v4-flash" @@ -78,7 +85,7 @@ export class ConcentrateService { name: "concentrate", baseURL: BASE_URL, headers: { - Authorization: `Bearer ${CONCENTRATE_API_KEY}`, + Authorization: `Bearer ${apiKey}`, }, fetch: fetchWithRetry as typeof fetch, }) diff --git a/apps/supercode-cli/server/src/cli/ai/provider.ts b/apps/supercode-cli/server/src/cli/ai/provider.ts index f12fd93..05a967a 100644 --- a/apps/supercode-cli/server/src/cli/ai/provider.ts +++ b/apps/supercode-cli/server/src/cli/ai/provider.ts @@ -45,7 +45,7 @@ export const providerMeta: Record string> = { minimax: () => minimaxConfig.apiKey, openrouter: () => openRouterConfig.apiKey, nvidia: () => nvidiaConfig.apiKey, - concentrateai: () => process.env.CONCENTRATEAI_API_KEY || "", + concentrateai: () => process.env.CONCENTRATE_BYOK_PROD_KEY || process.env.CONCENTRATE_BYOK_DEV_KEY || process.env.CONCENTRATEAI_API_KEY || "", mergedev: () => mergedevConfig.apiKey, } diff --git a/apps/supercode-cli/server/src/cli/commands/slashCommands/connect.ts b/apps/supercode-cli/server/src/cli/commands/slashCommands/connect.ts index 30da806..db5c535 100644 --- a/apps/supercode-cli/server/src/cli/commands/slashCommands/connect.ts +++ b/apps/supercode-cli/server/src/cli/commands/slashCommands/connect.ts @@ -36,10 +36,12 @@ export async function connectProvider(): Promise<{ type: "connect"; provider?: M const provider = PROVIDERS.find((p) => p.value === providerChoice)! - // Check if user already has a key saved for this provider + // Check if user already has a BYOK key for this session (for concentrateai, don't count the proxy key) const config = await getCliConfig() const envKeys = getProviderApiKeys() - const existingKey = config?.apiKeys?.[provider.value] || envKeys[provider.value] + const byokSessionKey = process.env.CONCENTRATE_BYOK_PROD_KEY || process.env.CONCENTRATE_BYOK_DEV_KEY + const existingKey = config?.apiKeys?.[provider.value] + || (provider.value === "concentrateai" ? byokSessionKey : envKeys[provider.value]) if (existingKey) { console.log(` ${chalk.hex(theme.green)("✓")} ${chalk.hex(theme.green)(`Already have a key for ${provider.label} — switching to direct mode (🔑)`)}`) diff --git a/apps/supercode-cli/server/src/lib/cli-config.ts b/apps/supercode-cli/server/src/lib/cli-config.ts index 27494e9..a323d08 100644 --- a/apps/supercode-cli/server/src/lib/cli-config.ts +++ b/apps/supercode-cli/server/src/lib/cli-config.ts @@ -86,12 +86,31 @@ export async function applyStoredApiKeys(): Promise { } } } + // Clean up old persisted concentrateai key — now session-only via BYOK vars + if (config.apiKeys?.["concentrateai"]) { + const cleaned = { ...config.apiKeys } + delete cleaned.concentrateai + await saveCliConfig({ apiKeys: cleaned } as any) + } } catch { // no stored keys — fine } } +function getConcentrateByokVar(): string { + const serverUrl = process.env.SUPERCODE_SERVER_URL + if (serverUrl && (serverUrl.includes("localhost") || serverUrl.includes("127.0.0.1"))) { + return "CONCENTRATE_BYOK_DEV_KEY" + } + return "CONCENTRATE_BYOK_PROD_KEY" +} + export async function saveProviderApiKey(provider: ModelProvider, apiKey: string): Promise { + if (provider === "concentrateai") { + const byokVar = getConcentrateByokVar() + process.env[byokVar] = apiKey + return + } const config = await getCliConfig() const existingConfig = config || {} const currentKeys = (existingConfig as any)?.apiKeys || {}