Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/supercode-cli/server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "supercode-cli",
"version": "0.1.90",
"version": "0.1.91",
"description": "AI-powered coding agent CLI",
"main": "dist/main.js",
"bin": {
Expand Down
52 changes: 45 additions & 7 deletions apps/supercode-cli/server/src/cli/commands/slashCommands/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ const SECTION_MINIMAX = "__section_minimax__"
const SECTION_NVIDIA = "__section_nvidia__"
const SECTION_OPENROUTER = "__section_openrouter__"
const SECTION_ORCAROUTER = "__section_orcarouter__"
const SECTION_CLOUD_PREMIUM = "__section_cloud_premium__"

export const ALL_SECTIONS = new Set([
SECTION_CLOUD, SECTION_BYOK,
SECTION_CONCENTRATEAI, SECTION_MERGEDEV,
SECTION_GOOGLE, SECTION_MINIMAX,
SECTION_NVIDIA, SECTION_OPENROUTER,
SECTION_ORCAROUTER,
SECTION_CLOUD_PREMIUM,
])

const SECTION_LABELS: Record<string, string> = {
Expand All @@ -41,18 +43,21 @@ const SECTION_LABELS: Record<string, string> = {
[SECTION_NVIDIA]: "NVIDIA NIM",
[SECTION_OPENROUTER]: "OpenRouter",
[SECTION_ORCAROUTER]: "OrcaRouter",
[SECTION_CLOUD_PREMIUM]: "Supercode Cloud Premium",
}

const isMainSection = (v: string) => v === SECTION_CLOUD || v === SECTION_BYOK
const isMainSection = (v: string) => v === SECTION_CLOUD || v === SECTION_BYOK || v === SECTION_CLOUD_PREMIUM

// Models available through the Supercode cloud proxy (no API key needed)
export const CLOUD_MODELS: ModelEntry[] = [
{ value: "deepseek-v4-flash", label: "DeepSeek V4 Flash", provider: "supercode", cost: "free", desc: "Fast & capable" },
{ value: "glm-5.2", label: "GLM 5.2", provider: "supercode", cost: "free", desc: "Latest GLM" },
{ value: "glm-5.1", label: "GLM 5.1", provider: "supercode", cost: "free", desc: "Stable & reliable" },
{ value: "kimi-k2-6", label: "Kimi K2.6", provider: "supercode", cost: "free", desc: "Long context" },
{ value: "minimax-m3", label: "MiniMax M3", provider: "supercode", cost: "free", desc: "Fast & smart" },
// { value: "glm-5.2", label: "GLM 5.2", provider: "supercode", cost: "free", desc: "Latest GLM" },
// { value: "glm-5.1", label: "GLM 5.1", provider: "supercode", cost: "free", desc: "Stable & reliable" },
// { value: "kimi-k2-6", label: "Kimi K2.6", provider: "supercode", cost: "free", desc: "Long context" },
// { value: "minimax-m3", label: "MiniMax M3", provider: "supercode", cost: "free", desc: "Fast & smart" },
{ value: "hy3", label: "Hunyuan Hy3", provider: "supercode", cost: "free", desc: "Tencent flagship" },
{ value: "mimo-v2.5", label: "Mimo v2.5", provider: "supercode", cost: "free", desc: "Novita" },
// { value: "fireworks/nemotron-3-ultra-nvfp4", label: "Nemotron 3 Ultra NVFP4", provider: "supercode", cost: "free", desc: "Fireworks" },
Comment on lines 53 to +60

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Expose Nemotron in the model picker.

Line 60 leaves fireworks/nemotron-3-ultra-nvfp4 commented out, so users cannot select a model that this PR allowlists and prices. Add it to CLOUD_MODELS (or PREMIUM_CLOUD_MODELS, if intended).

Proposed fix
-  // { value: "fireworks/nemotron-3-ultra-nvfp4", label: "Nemotron 3 Ultra NVFP4", provider: "supercode", cost: "free", desc: "Fireworks" },
+  { value: "fireworks/nemotron-3-ultra-nvfp4", label: "Nemotron 3 Ultra NVFP4", provider: "supercode", cost: "free", desc: "Fireworks" },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{ value: "deepseek-v4-flash", label: "DeepSeek V4 Flash", provider: "supercode", cost: "free", desc: "Fast & capable" },
{ value: "glm-5.2", label: "GLM 5.2", provider: "supercode", cost: "free", desc: "Latest GLM" },
{ value: "glm-5.1", label: "GLM 5.1", provider: "supercode", cost: "free", desc: "Stable & reliable" },
{ value: "kimi-k2-6", label: "Kimi K2.6", provider: "supercode", cost: "free", desc: "Long context" },
{ value: "minimax-m3", label: "MiniMax M3", provider: "supercode", cost: "free", desc: "Fast & smart" },
// { value: "glm-5.2", label: "GLM 5.2", provider: "supercode", cost: "free", desc: "Latest GLM" },
// { value: "glm-5.1", label: "GLM 5.1", provider: "supercode", cost: "free", desc: "Stable & reliable" },
// { value: "kimi-k2-6", label: "Kimi K2.6", provider: "supercode", cost: "free", desc: "Long context" },
// { value: "minimax-m3", label: "MiniMax M3", provider: "supercode", cost: "free", desc: "Fast & smart" },
{ value: "hy3", label: "Hunyuan Hy3", provider: "supercode", cost: "free", desc: "Tencent flagship" },
{ value: "mimo-v2.5", label: "Mimo v2.5", provider: "supercode", cost: "free", desc: "Novita" },
// { value: "fireworks/nemotron-3-ultra-nvfp4", label: "Nemotron 3 Ultra NVFP4", provider: "supercode", cost: "free", desc: "Fireworks" },
{ value: "deepseek-v4-flash", label: "DeepSeek V4 Flash", provider: "supercode", cost: "free", desc: "Fast & capable" },
// { value: "glm-5.2", label: "GLM 5.2", provider: "supercode", cost: "free", desc: "Latest GLM" },
// { value: "glm-5.1", label: "GLM 5.1", provider: "supercode", cost: "free", desc: "Stable & reliable" },
// { value: "kimi-k2-6", label: "Kimi K2.6", provider: "supercode", cost: "free", desc: "Long context" },
// { value: "minimax-m3", label: "MiniMax M3", provider: "supercode", cost: "free", desc: "Fast & smart" },
{ value: "hy3", label: "Hunyuan Hy3", provider: "supercode", cost: "free", desc: "Tencent flagship" },
{ value: "mimo-v2.5", label: "Mimo v2.5", provider: "supercode", cost: "free", desc: "Novita" },
{ value: "fireworks/nemotron-3-ultra-nvfp4", label: "Nemotron 3 Ultra NVFP4", provider: "supercode", cost: "free", desc: "Fireworks" },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/supercode-cli/server/src/cli/commands/slashCommands/model.ts` around
lines 53 - 60, Uncomment and expose the `fireworks/nemotron-3-ultra-nvfp4` entry
in the model picker’s `CLOUD_MODELS` collection, or place it in
`PREMIUM_CLOUD_MODELS` if that is the intended pricing tier, so users can select
the allowlisted model.

]

// Models available when you bring your own API key (BYOK)
Expand Down Expand Up @@ -199,9 +204,22 @@ export const BYOK_MODELS: ModelEntry[] = [
{ value: "orcarouter/auto", label: "OrcaRouter Auto", provider: "orcarouter", cost: "0x", desc: "Auto-pick cheapest" },
]

// Set of premium cloud models that require Supercode Cloud Premium
export const PREMIUM_CLOUD_MODELS = new Set([
"glm-5.2",
"kimi-k2-7-code",
"kimi-k3",
"minimax-m3",
])

export const MODELS: ModelEntry[] = [
{ value: SECTION_CLOUD, label: "Supercode Cloud", provider: "supercode", cost: "", desc: "" },
...CLOUD_MODELS,
{ value: SECTION_CLOUD_PREMIUM, label: "Supercode Cloud Premium", provider: "supercode", cost: "", desc: "" },
{ value: "glm-5.2", label: "GLM 5.2", provider: "supercode", cost: "", desc: "Latest GLM" },
{ value: "kimi-k2-7-code", label: "Kimi K2.7 Code", provider: "supercode", cost: "", desc: "Code specialist" },
{ value: "kimi-k3", label: "Kimi K3", provider: "supercode", cost: "", desc: "Moonshot latest" },
{ value: "minimax-m3", label: "MiniMax M3", provider: "supercode", cost: "", desc: "Fast & smart" },
{ value: SECTION_BYOK, label: "Bring Your Own Key", provider: "supercode", cost: "", desc: "" },
...BYOK_MODELS,
]
Expand Down Expand Up @@ -366,16 +384,21 @@ export class ModelPicker {
const marker = isCurrent
? ` ${chalk.bgHex(theme.amber).hex(theme.black).bold(" current ")}`
: ""
const isPremium = PREMIUM_CLOUD_MODELS.has(m.value)
const cloudTag =
m.provider === "supercode" && !isCurrent
m.provider === "supercode" && !isCurrent && !isPremium
? ` ${chalk.bgHex(theme.green).hex(theme.black).bold(" CLOUD ")}`
: ""
const premiumTag =
isPremium && !isCurrent
? ` ${chalk.bgHex(theme.amber).hex(theme.black).bold(" PREMIUM ")}`
: ""
const freeTag =
!isCurrent && m.cost === "free" && m.provider !== "supercode"
? ` ${chalk.bgHex(theme.green).hex(theme.black).bold(" FREE ")}`
: ""

const label = `${prefix} ${name} ${cost}${desc}${marker}${cloudTag}${freeTag}`
const label = `${prefix} ${name} ${cost}${desc}${marker}${cloudTag}${premiumTag}${freeTag}`

if (isSelected) {
const bg = chalk.bgHex(theme.greenDeep)
Expand Down Expand Up @@ -585,6 +608,21 @@ export async function pickModel(
return { provider: selected.provider, model: trimmed }
}

// Premium cloud models require Supercode Cloud Premium
if (PREMIUM_CLOUD_MODELS.has(selected.value)) {
process.stdout.write("\n")
process.stdout.write(
` ${chalk.hex(theme.amber)("◆")} ${chalk.hex(theme.green).bold("Supercode Cloud Premium")}

${chalk.hex(theme.muted)("This model is available on Supercode Cloud Premium.")}
${chalk.hex(theme.muted)("Upgrade your plan to access premium models.")}
${chalk.hex(theme.muted)("→ https://supercode.ai/pricing")}

`
)
return { provider: currentProvider as ModelProvider, model: currentModel }
}

// For BYOK providers, check if an API key is configured
if (selected.provider !== "supercode") {
const config = await getCliConfig()
Expand Down
4 changes: 4 additions & 0 deletions apps/supercode-cli/server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ const CLOUD_ALLOWED_MODELS = new Set([
"kimi-k2-6",
"minimax-m3",
"hy3",
"mimo-v2.5",
"fireworks/nemotron-3-ultra-nvfp4",
"kimi-k2-7-code",
"kimi-k3",
Comment on lines +69 to +72

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Enforce Premium entitlement on the server.

The picker denies every premium selection without checking a plan, while the Supercode structured-generation endpoint accepts these newly allowlisted models based only on CLOUD_ALLOWED_MODELS. A caller can bypass the CLI notice with a direct request, and subscribed users cannot select these models through the picker.

  • apps/supercode-cli/server/src/index.ts#L69-L72: require a verified Cloud Premium entitlement before serving premium model IDs.
  • apps/supercode-cli/server/src/cli/commands/slashCommands/model.ts#L611-L624: show the upgrade notice only when the authenticated user lacks that entitlement.
📍 Affects 2 files
  • apps/supercode-cli/server/src/index.ts#L69-L72 (this comment)
  • apps/supercode-cli/server/src/cli/commands/slashCommands/model.ts#L611-L624
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/supercode-cli/server/src/index.ts` around lines 69 - 72, Enforce the
verified Cloud Premium entitlement consistently: in
apps/supercode-cli/server/src/index.ts lines 69-72, gate the newly allowlisted
premium model IDs behind the authenticated user’s entitlement instead of relying
only on CLOUD_ALLOWED_MODELS; in
apps/supercode-cli/server/src/cli/commands/slashCommands/model.ts lines 611-624,
display the upgrade notice only when the authenticated user lacks that
entitlement, allowing subscribed users to select these models.

])
const JSON_BODY_LIMIT = process.env.SUPERCODE_JSON_BODY_LIMIT || "10mb"
const app = express()
Expand Down
4 changes: 4 additions & 0 deletions apps/supercode-cli/server/src/lib/pricing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export const MODEL_PRICING: Record<string, ModelPricing> = {
"deepseek/deepseek-reasoner": { inputPrice: 0.50, outputPrice: 2.00, cachedPrice: 0 },
"grok/grok-4-fast-reasoning": { inputPrice: 1.00, outputPrice: 5.00, cachedPrice: 0 },
"orcarouter/auto": { inputPrice: 0, outputPrice: 0, cachedPrice: 0 },
"mimo-v2.5": { inputPrice: 0.15, outputPrice: 0.60, cachedPrice: 0 },
"fireworks/nemotron-3-ultra-nvfp4": { inputPrice: 0.60, outputPrice: 2.40, cachedPrice: 0.12 },
"kimi-k2-7-code": { inputPrice: 0.25, outputPrice: 1.00, cachedPrice: 0 },
"kimi-k3": { inputPrice: 0.50, outputPrice: 2.00, cachedPrice: 0 },
}

export function computeCost(model: string, inputTokens: number, outputTokens: number, cachedInputTokens: number): number {
Expand Down
Loading