Skip to content
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Refresh display pricing for the current Command Code model catalog, remove expired Qwen promotional rates, add current free and discounted models, and require review when temporary prices expire.
- Use the host-provided `pi-ai` and `pi-coding-agent` core packages instead of installing private runtime copies, including for local and out-of-store development checkouts.

## 0.4.4 - 2026-08-03
Expand Down
46 changes: 1 addition & 45 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,57 +20,13 @@ import { COMMAND_CODE_CLI_VERSION, createStreamCommandCode, DEFAULT_API_BASE } f
import { calculateCommandCodeCost } from "./src/cost.ts"
import { DEFAULT_MODELS_URL, loadCommandCodeModels } from "./src/models.ts"
import { getApiKey, login, refreshToken } from "./src/oauth.ts"
import { MODEL_COSTS, ZERO_MODEL_COST } from "./src/pricing.ts"

const API_BASE = process.env.COMMANDCODE_API_BASE ?? DEFAULT_API_BASE
const MODELS_URL = process.env.COMMANDCODE_MODELS_URL ?? DEFAULT_MODELS_URL
const MODELS_CACHE_PATH =
process.env.COMMANDCODE_MODELS_CACHE ?? join(getAgentDir(), "commandcode-models.json")

type CommandCodeModelCost = {
input: number
output: number
cacheRead: number
cacheWrite: number
}

const ZERO_MODEL_COST: CommandCodeModelCost = {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
}

// The Provider API supplies the current model list. Keep known display pricing
// here until the Provider API exposes prices directly.
const MODEL_COSTS: Record<string, CommandCodeModelCost> = {
"claude-opus-4-7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
"claude-opus-4-6": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
"claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
"claude-haiku-4-5-20251001": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 },
"gpt-5.5": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 },
"gpt-5.4": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 },
"gpt-5.3-codex": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 },
"gpt-5.4-mini": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 },
"google/gemini-3.5-flash": { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 },
"google/gemini-3.1-flash-lite": { input: 0.25, output: 1.5, cacheRead: 0.03, cacheWrite: 0 },
// 4× usage deal: 75% off (permanent, no expiry)
"deepseek/deepseek-v4-pro": { input: 0.435, output: 0.87, cacheRead: 0.003625, cacheWrite: 0 },
"deepseek/deepseek-v4-flash": { input: 0.14, output: 0.28, cacheRead: 0.028, cacheWrite: 0 },
"moonshotai/Kimi-K2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 },
"moonshotai/Kimi-K2.5": { input: 0.6, output: 3, cacheRead: 0.1, cacheWrite: 0 },
"zai-org/GLM-5.1": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 },
"zai-org/GLM-5": { input: 1, output: 3.2, cacheRead: 0.2, cacheWrite: 0 },
"MiniMaxAI/MiniMax-M2.7": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 },
"MiniMaxAI/MiniMax-M2.5": { input: 0.27, output: 0.95, cacheRead: 0.03, cacheWrite: 0 },
"Qwen/Qwen3.6-Max-Preview": { input: 1.3, output: 7.8, cacheRead: 0.26, cacheWrite: 1.63 },
"Qwen/Qwen3.6-Plus": { input: 0.5, output: 3, cacheRead: 0.1, cacheWrite: 0 },
// 2× usage deal: 50% off through June 22, 2026
"Qwen/Qwen3.7-Max": { input: 1.25, output: 3.75, cacheRead: 0.25, cacheWrite: 1.56 },
"stepfun/Step-3.5-Flash": { input: 0.1, output: 0.3, cacheRead: 0.02, cacheWrite: 0 },
"xiaomi/mimo-v2.5-pro": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
"xiaomi/mimo-v2.5": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
}

const streamCommandCode = createStreamCommandCode({
createStream: () => new AssistantMessageEventStream(),
calculateCost: calculateCommandCodeCost,
Expand Down
20 changes: 16 additions & 4 deletions src/cost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,22 @@
import type { ModelLike, Usage } from "./types.ts"

export function calculateCommandCodeCost(model: ModelLike, usage: Usage): void {
usage.cost.input = (model.cost.input / 1_000_000) * usage.input
usage.cost.output = (model.cost.output / 1_000_000) * usage.output
usage.cost.cacheRead = (model.cost.cacheRead / 1_000_000) * usage.cacheRead
usage.cost.cacheWrite = (model.cost.cacheWrite * usage.cacheWrite) / 1_000_000
const inputTokens = usage.input + usage.cacheRead + usage.cacheWrite
let rates = model.cost
let matchedThreshold = -1
for (const tier of model.cost.tiers ?? []) {
if (inputTokens > tier.inputTokensAbove && tier.inputTokensAbove > matchedThreshold) {
rates = tier
matchedThreshold = tier.inputTokensAbove
}
}

const longWrite = usage.cacheWrite1h ?? 0
const shortWrite = usage.cacheWrite - longWrite
usage.cost.input = (rates.input / 1_000_000) * usage.input
usage.cost.output = (rates.output / 1_000_000) * usage.output
usage.cost.cacheRead = (rates.cacheRead / 1_000_000) * usage.cacheRead
usage.cost.cacheWrite = (rates.cacheWrite * shortWrite + rates.input * 2 * longWrite) / 1_000_000
usage.cost.total =
usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite
}
226 changes: 226 additions & 0 deletions src/pricing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
export interface CommandCodeModelCostRates {
input: number
output: number
cacheRead: number
cacheWrite: number
}

export interface CommandCodeModelCostTier extends CommandCodeModelCostRates {
inputTokensAbove: number
}

export interface CommandCodeModelCost extends CommandCodeModelCostRates {
tiers?: readonly CommandCodeModelCostTier[]
}

export interface TemporaryPricing {
models: readonly string[]
expiresOn: string
description: string
}

export const PRICING_SOURCE_URL = "https://commandcode.ai/docs/resources/pricing-limits"
export const PRICING_LAST_VERIFIED = "2026-08-04"

export const ZERO_MODEL_COST: CommandCodeModelCost = {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
}

/**
* Display prices in USD per million tokens.
*
* Context-dependent rates use pi's request-wide input pricing tiers. The
* highest threshold exceeded by input + cache reads + cache writes applies to
* the full request. The Command Code usage page remains authoritative for the
* amount billed for an individual request.
*/
export const MODEL_COSTS: Readonly<Record<string, CommandCodeModelCost>> = {
// Free models
"poolside/laguna-s-2.1-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
"inclusionai/ling-3.0-flash-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },

// Open and open-weight models
"tencent/hy3-paid": { input: 0.14, output: 0.58, cacheRead: 0.035, cacheWrite: 0 },
"moonshotai/Kimi-K3": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 },
"moonshotai/Kimi-K2.7-Code": { input: 0.95, output: 4, cacheRead: 0.19, cacheWrite: 0 },
"moonshotai/Kimi-K2.7-Code-Highspeed": {
input: 1.9,
output: 8,
cacheRead: 0.38,
cacheWrite: 0,
},
"moonshotai/Kimi-K2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 },
"moonshotai/Kimi-K2.5": { input: 0.6, output: 3, cacheRead: 0.1, cacheWrite: 0 },
"zai-org/GLM-5.2": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 },
"zai-org/GLM-5.2-Fast": { input: 3, output: 10.25, cacheRead: 0.5, cacheWrite: 0 },
"zai-org/GLM-5.1": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 },
"zai-org/GLM-5": { input: 1, output: 3.2, cacheRead: 0.2, cacheWrite: 0 },
"MiniMaxAI/MiniMax-M3": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 },
"MiniMaxAI/MiniMax-M2.7": { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0 },
"MiniMaxAI/MiniMax-M2.5": { input: 0.3, output: 1.2, cacheRead: 0.03, cacheWrite: 0 },
// Permanent 75% discount.
"deepseek/deepseek-v4-pro": {
input: 0.435,
output: 0.87,
cacheRead: 0.003625,
cacheWrite: 0,
},
"deepseek/deepseek-v4-flash": {
input: 0.14,
output: 0.28,
cacheRead: 0.0028,
cacheWrite: 0,
},
"Qwen/Qwen3.8-Max": { input: 2, output: 6, cacheRead: 0.25, cacheWrite: 2.5 },
"Qwen/Qwen3.7-Max": { input: 2.5, output: 7.5, cacheRead: 0.5, cacheWrite: 3.13 },
"Qwen/Qwen3.7-Plus": {
input: 0.4,
output: 1.6,
cacheRead: 0.08,
cacheWrite: 0.5,
tiers: [
{
inputTokensAbove: 256_000,
input: 1.2,
output: 4.8,
cacheRead: 0.24,
cacheWrite: 1.5,
},
],
},
"Qwen/Qwen3.7-Flash": {
input: 0.03,
output: 0.13,
cacheRead: 0.006,
cacheWrite: 0.038,
tiers: [
{
inputTokensAbove: 32_000,
input: 0.1,
output: 0.4,
cacheRead: 0.02,
cacheWrite: 0.125,
},
{
inputTokensAbove: 256_000,
input: 0.2,
output: 0.8,
cacheRead: 0.04,
cacheWrite: 0.25,
},
],
},
"Qwen/Qwen3.6-Max-Preview": {
input: 1.3,
output: 7.8,
cacheRead: 0.26,
cacheWrite: 1.63,
},
"Qwen/Qwen3.6-Plus": { input: 0.5, output: 3, cacheRead: 0.1, cacheWrite: 0 },
"stepfun/Step-3.7-Flash": { input: 0.2, output: 1.15, cacheRead: 0.04, cacheWrite: 0 },
"stepfun/Step-3.5-Flash": { input: 0.1, output: 0.3, cacheRead: 0.02, cacheWrite: 0 },
// Permanent discounted rates.
"xiaomi/mimo-v2.5-pro": { input: 0.435, output: 0.87, cacheRead: 0.0036, cacheWrite: 0 },
"xiaomi/mimo-v2.5": { input: 0.14, output: 0.28, cacheRead: 0.0028, cacheWrite: 0 },
"nvidia/nemotron-3-ultra-550b-a55b": {
input: 0.6,
output: 2.4,
cacheRead: 0.12,
cacheWrite: 0,
},
"sakana/fugu-ultra": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 },
"thinkingmachines/inkling": { input: 1, output: 4.05, cacheRead: 0.17, cacheWrite: 0 },
"thinkingmachines/inkling-small": {
input: 0.5,
output: 1.2,
cacheRead: 0.1,
cacheWrite: 0,
},
"meta/muse-spark-1.1": { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite: 0 },

// Anthropic
// Introductory pricing through 2026-08-31.
"claude-sonnet-5": { input: 2, output: 10, cacheRead: 0.2, cacheWrite: 2.5 },
"claude-sonnet-4-6": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
"claude-fable-5": { input: 10, output: 50, cacheRead: 1, cacheWrite: 12.5 },
"claude-opus-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
"claude-opus-4-8": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
"claude-opus-4-7": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
"claude-haiku-4-5-20251001": {
input: 1,
output: 5,
cacheRead: 0.1,
cacheWrite: 1.25,
},

// OpenAI
"gpt-5.6-sol": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 6.25 },
// Discounted rates through 2026-08-14.
"gpt-5.6-terra": {
input: 1,
output: 6,
cacheRead: 0.1,
cacheWrite: 1.25,
tiers: [
{
inputTokensAbove: 272_000,
input: 2,
output: 9,
cacheRead: 0.2,
cacheWrite: 2.5,
},
],
},
"gpt-5.6-luna": {
input: 0.1,
output: 0.6,
cacheRead: 0.01,
cacheWrite: 0.125,
tiers: [
{
inputTokensAbove: 272_000,
input: 0.2,
output: 0.9,
cacheRead: 0.02,
cacheWrite: 0.25,
},
],
},
"gpt-5.5": { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 },
"gpt-5.4": { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 },
"gpt-5.3-codex": { input: 2, output: 8, cacheRead: 0.5, cacheWrite: 0 },
"gpt-5.4-mini": { input: 0.75, output: 4.5, cacheRead: 0.075, cacheWrite: 0 },

// Google and xAI
"google/gemini-3.6-flash": { input: 1.5, output: 7.5, cacheRead: 0.15, cacheWrite: 0 },
"google/gemini-3.5-flash": { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 },
"google/gemini-3.5-flash-lite": {
input: 0.3,
output: 2.5,
cacheRead: 0.03,
cacheWrite: 0,
},
"google/gemini-3.1-flash-lite": {
input: 0.25,
output: 1.5,
cacheRead: 0.03,
cacheWrite: 0,
},
"xai/grok-4.5": { input: 2, output: 6, cacheRead: 0.5, cacheWrite: 0 },
}

export const TEMPORARY_PRICING: readonly TemporaryPricing[] = [
{
models: ["gpt-5.6-terra", "gpt-5.6-luna"],
expiresOn: "2026-08-14",
description: "50% promotional rates",
},
{
models: ["claude-sonnet-5"],
expiresOn: "2026-08-31",
description: "introductory pricing",
},
]
11 changes: 10 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface Usage {
output: number
cacheRead: number
cacheWrite: number
cacheWrite1h?: number
totalTokens: number
cost: UsageCost
}
Expand Down Expand Up @@ -50,13 +51,21 @@ export interface AssistantMessageLike {
timestamp: number
}

export interface ModelCost {
export interface ModelCostRates {
input: number
output: number
cacheRead: number
cacheWrite: number
}

export interface ModelCostTier extends ModelCostRates {
inputTokensAbove: number
}

export interface ModelCost extends ModelCostRates {
tiers?: readonly ModelCostTier[]
}

export interface ModelLike {
id: string
api: unknown
Expand Down
Loading
Loading