Merge remote-tracking branch 'origin/main' into review/pr-52

# Conflicts:
#	CHANGELOG.md
This commit is contained in:
Patrick Wozniak
2026-08-25 13:33:55 +02:00
11 changed files with 29 additions and 19 deletions
+3 -4
View File
@@ -2,10 +2,8 @@
## Unreleased ## Unreleased
- Reformat `/commandcode-quota` output into a dashboard layout: credits remaining/used with a percentage, monthly/purchased/free sources, plan, month-to-date cost/requests/tokens, and API key name, while keeping the 5-hour/weekly usage windows and full-detail link. - Add `/commandcode-quota` with live credits, plan, usage totals, and rolling-limit diagnostics from Command Code's alpha usage endpoints.
- Optionally show an aggregate token count and API key name when the usage endpoints report them. - Add `zai-org/GLM-5.3` with its verified reasoning efforts and display pricing.
- Fix `/commandcode-quota` on Oh My Pi: OMP surfaces an unresolved `$COMMANDCODE_API_KEY` placeholder through the model registry, which previously caused a 401 on the quota endpoints. The command now filters placeholders and falls back to the env/auth-file key resolver, matching the stream path.
- Fix `/commandcode-quota` usage windows so the 5-hour and weekly limits actually render: the API reports `windowLimits` as a top-level sibling of `credits` (not nested inside it), and its `resetAt` is in milliseconds, not seconds. Both are now parsed correctly, giving real "resets in …" countdowns instead of omitting the section or showing a huge day count.
- Prefer Command Code's Provider API (`/provider/v1/chat/completions` and `/provider/v1/messages`) and automatically fall back to the existing `/alpha/generate` transport only when the Provider API returns `403 upgrade_required` for a Go-plan account. - Prefer Command Code's Provider API (`/provider/v1/chat/completions` and `/provider/v1/messages`) and automatically fall back to the existing `/alpha/generate` transport only when the Provider API returns `403 upgrade_required` for a Go-plan account.
- Remember the detected transport for the running process, re-detect it when credentials change, prevent stale in-flight requests from overwriting the new credential's transport, and never fall back for unrelated authentication, permission, rate-limit, network, or server failures. - Remember the detected transport for the running process, re-detect it when credentials change, prevent stale in-flight requests from overwriting the new credential's transport, and never fall back for unrelated authentication, permission, rate-limit, network, or server failures.
- Use Pi's native OpenAI- and Anthropic-compatible providers for Provider API streaming, including adaptive thinking for current reasoning-capable Claude models, while preserving the existing hardened generate transport, dynamic model discovery, offline cache, refresh/status commands, pricing, and OAuth credentials. - Use Pi's native OpenAI- and Anthropic-compatible providers for Provider API streaming, including adaptive thinking for current reasoning-capable Claude models, while preserving the existing hardened generate transport, dynamic model discovery, offline cache, refresh/status commands, pricing, and OAuth credentials.
@@ -13,6 +11,7 @@
- Add optional zero-data-retention headers through `COMMANDCODE_ZDR=1`. - Add optional zero-data-retention headers through `COMMANDCODE_ZDR=1`.
- Refresh GPT-5.6 Terra and Luna display prices after their temporary 50% promotion ended, and display the current DeepSeek V4 off-peak rates for its time-dependent pricing. - Refresh GPT-5.6 Terra and Luna display prices after their temporary 50% promotion ended, and display the current DeepSeek V4 off-peak rates for its time-dependent pricing.
- Add isolated live E2E profiles for separate Go-plan and Provider-API credentials, including an explicit selected-transport assertion and packed-package validation. - Add isolated live E2E profiles for separate Go-plan and Provider-API credentials, including an explicit selected-transport assertion and packed-package validation.
- Fix extension load failure on newer pi hosts that reject registering a custom API under a built-in name (`openai-completions`); register under `commandcode-custom` instead and restore the real wire API before native compat dispatch.
## 0.5.1 - 2026-08-11 ## 0.5.1 - 2026-08-11
+1 -1
View File
@@ -144,7 +144,7 @@ The following environment variables are intended for tests, local mocks, and com
## Image input ## Image input
The provider advertises image input only for models marked with the `image` input modality in the official Command Code CLI model catalog. The capability snapshot currently follows `command-code@1.15.1`; unknown models default to text-only until their upstream metadata is reviewed. The provider advertises image input only for models marked with the `image` input modality in the official Command Code CLI model catalog. The capability snapshot currently follows `command-code@1.32.1`; unknown models default to text-only until their upstream metadata is reviewed.
For vision-capable models, Pi's native provider adapters forward image blocks from user messages and tool results using the documented OpenAI or Anthropic message schema. Unknown and text-only models remain marked text-only in Pi. For vision-capable models, Pi's native provider adapters forward image blocks from user messages and tool results using the documented OpenAI or Anthropic message schema. Unknown and text-only models remain marked text-only in Pi.
+9 -3
View File
@@ -20,6 +20,7 @@ import { createStreamCommandCode } from "./src/core.ts"
import { calculateCommandCodeCost } from "./src/cost.ts" import { calculateCommandCodeCost } from "./src/cost.ts"
import { pickCommandCodeApiKey } from "./src/converters.ts" import { pickCommandCodeApiKey } from "./src/converters.ts"
import { import {
apiForModelId,
baseUrlForModel, baseUrlForModel,
DEFAULT_MODELS_URL, DEFAULT_MODELS_URL,
DEFAULT_PROVIDER_API_BASE, DEFAULT_PROVIDER_API_BASE,
@@ -63,7 +64,7 @@ function createProviderConfig(
name: "Command Code", name: "Command Code",
baseUrl: apiBase, baseUrl: apiBase,
apiKey: getConfiguredApiKey() ?? "$COMMANDCODE_API_KEY", apiKey: getConfiguredApiKey() ?? "$COMMANDCODE_API_KEY",
api: "openai-completions", api: "commandcode-custom",
streamSimple: streamCommandCode, streamSimple: streamCommandCode,
headers, headers,
oauth: { oauth: {
@@ -75,7 +76,7 @@ function createProviderConfig(
models: models.map((model) => ({ models: models.map((model) => ({
id: model.id, id: model.id,
name: model.name, name: model.name,
api: model.api, api: "commandcode-custom",
baseUrl: baseUrlForModel(apiBase, model.api), baseUrl: baseUrlForModel(apiBase, model.api),
reasoning: model.reasoning, reasoning: model.reasoning,
...(thinkingMetadataForModel(model.id) ?? {}), ...(thinkingMetadataForModel(model.id) ?? {}),
@@ -120,7 +121,12 @@ export default async function (pi: ExtensionAPI) {
}) })
const transport = createCommandCodeTransportRouter({ const transport = createCommandCodeTransportRouter({
createStream: () => new AssistantMessageEventStream(), createStream: () => new AssistantMessageEventStream(),
streamProvider: streamNativeProvider, streamProvider: (model, context, options) =>
streamNativeProvider(
{ ...model, api: apiForModelId(model.id), compat: model.compatConfig ?? model.compat },
context,
options,
),
streamGenerate, streamGenerate,
}) })
+1 -1
View File
@@ -43,7 +43,7 @@ export * from "./overflow.ts"
export * from "./types.ts" export * from "./types.ts"
export const DEFAULT_API_BASE = "https://api.commandcode.ai" export const DEFAULT_API_BASE = "https://api.commandcode.ai"
export const COMMAND_CODE_CLI_VERSION = "1.15.1" export const COMMAND_CODE_CLI_VERSION = "1.32.1"
const DEFAULT_GENERATE_MAX_TOKENS = 64_000 const DEFAULT_GENERATE_MAX_TOKENS = 64_000
const DEFAULT_MAX_RETRIES = 0 const DEFAULT_MAX_RETRIES = 0
+3 -2
View File
@@ -12,7 +12,7 @@ export type CommandCodeApi = "openai-completions" | "anthropic-messages"
export type CommandCodeInputType = "text" | "image" export type CommandCodeInputType = "text" | "image"
/** /**
* Model input modalities from the command-code@1.15.1 bundled catalog. * Model input modalities from the command-code@1.32.1 bundled catalog.
* Models omitted here remain text-only so newly discovered IDs never claim * Models omitted here remain text-only so newly discovered IDs never claim
* image support without upstream evidence. * image support without upstream evidence.
*/ */
@@ -74,7 +74,7 @@ type CommandCodeReasoningEffort = Exclude<PiThinkingLevel, "off">
* Per-model reasoning efforts supported by Command Code's generate endpoint. * Per-model reasoning efforts supported by Command Code's generate endpoint.
* *
* The Provider API does not expose reasoning metadata. This is an exact * The Provider API does not expose reasoning metadata. This is an exact
* snapshot of `reasoningEfforts` from the command-code@1.15.1 model catalog * snapshot of `reasoningEfforts` from the command-code@1.32.1 model catalog
* (`packages/shared/src/model-catalog.ts`, also published in the generated * (`packages/shared/src/model-catalog.ts`, also published in the generated
* `dist/bundled/command-code-knowledge/reference/models.md`). Models omitted * `dist/bundled/command-code-knowledge/reference/models.md`). Models omitted
* here let Command Code choose their reasoning depth, matching the CLI. * here let Command Code choose their reasoning depth, matching the CLI.
@@ -103,6 +103,7 @@ export const MODEL_EFFORTS: Readonly<Record<string, readonly CommandCodeReasonin
"sakana/fugu-ultra": ["high", "xhigh"], "sakana/fugu-ultra": ["high", "xhigh"],
"xai/grok-4.5": ["low", "medium", "high"], "xai/grok-4.5": ["low", "medium", "high"],
"zai-org/GLM-5.2": ["high", "max"], "zai-org/GLM-5.2": ["high", "max"],
"zai-org/GLM-5.3": ["low", "high", "max"],
} }
const PI_THINKING_LEVELS: readonly PiThinkingLevel[] = [ const PI_THINKING_LEVELS: readonly PiThinkingLevel[] = [
+2 -1
View File
@@ -20,7 +20,7 @@ export interface TemporaryPricing {
} }
export const PRICING_SOURCE_URL = "https://commandcode.ai/docs/resources/pricing-limits" export const PRICING_SOURCE_URL = "https://commandcode.ai/docs/resources/pricing-limits"
export const PRICING_LAST_VERIFIED = "2026-08-20" export const PRICING_LAST_VERIFIED = "2026-08-22"
export const ZERO_MODEL_COST: CommandCodeModelCost = { export const ZERO_MODEL_COST: CommandCodeModelCost = {
input: 0, input: 0,
@@ -54,6 +54,7 @@ export const MODEL_COSTS: Readonly<Record<string, CommandCodeModelCost>> = {
}, },
"moonshotai/Kimi-K2.6": { input: 0.95, output: 4, cacheRead: 0.16, 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 }, "moonshotai/Kimi-K2.5": { input: 0.6, output: 3, cacheRead: 0.1, cacheWrite: 0 },
"zai-org/GLM-5.3": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 },
"zai-org/GLM-5.2": { input: 1.4, output: 4.4, cacheRead: 0.26, 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.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.1": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 0 },
+2 -1
View File
@@ -1,5 +1,5 @@
{ {
"fetchedAt": "2026-08-04T10:12:57.953Z", "fetchedAt": "2026-08-22T21:19:37.782Z",
"source": "https://api.commandcode.ai/provider/v1/models", "source": "https://api.commandcode.ai/provider/v1/models",
"modelIds": [ "modelIds": [
"claude-sonnet-5", "claude-sonnet-5",
@@ -23,6 +23,7 @@
"moonshotai/Kimi-K2.7-Code-Highspeed", "moonshotai/Kimi-K2.7-Code-Highspeed",
"moonshotai/Kimi-K2.6", "moonshotai/Kimi-K2.6",
"moonshotai/Kimi-K2.5", "moonshotai/Kimi-K2.5",
"zai-org/GLM-5.3",
"zai-org/GLM-5.2", "zai-org/GLM-5.2",
"zai-org/GLM-5.2-Fast", "zai-org/GLM-5.2-Fast",
"zai-org/GLM-5.1", "zai-org/GLM-5.1",
+2 -1
View File
@@ -1,5 +1,5 @@
{ {
"verifiedAt": "2026-08-20", "verifiedAt": "2026-08-22",
"source": "https://commandcode.ai/docs/resources/pricing-limits", "source": "https://commandcode.ai/docs/resources/pricing-limits",
"tierPolicy": "Use request-wide input tiers; the highest threshold exceeded by input plus cache tokens applies to the full request.", "tierPolicy": "Use request-wide input tiers; the highest threshold exceeded by input plus cache tokens applies to the full request.",
"tiers": { "tiers": {
@@ -18,6 +18,7 @@
"moonshotai/Kimi-K2.7-Code-Highspeed": [1.9, 8, 0.38, 0], "moonshotai/Kimi-K2.7-Code-Highspeed": [1.9, 8, 0.38, 0],
"moonshotai/Kimi-K2.6": [0.95, 4, 0.16, 0], "moonshotai/Kimi-K2.6": [0.95, 4, 0.16, 0],
"moonshotai/Kimi-K2.5": [0.6, 3, 0.1, 0], "moonshotai/Kimi-K2.5": [0.6, 3, 0.1, 0],
"zai-org/GLM-5.3": [1.4, 4.4, 0.26, 0],
"zai-org/GLM-5.2": [1.4, 4.4, 0.26, 0], "zai-org/GLM-5.2": [1.4, 4.4, 0.26, 0],
"zai-org/GLM-5.2-Fast": [3, 10.25, 0.5, 0], "zai-org/GLM-5.2-Fast": [3, 10.25, 0.5, 0],
"zai-org/GLM-5.1": [1.4, 4.4, 0.26, 0], "zai-org/GLM-5.1": [1.4, 4.4, 0.26, 0],
+3 -2
View File
@@ -100,7 +100,7 @@ describe("commandCodeModelsFromApiResponse()", () => {
) )
}) })
it("matches command-code@1.15.1 image input capabilities", () => { it("matches command-code@1.32.1 image input capabilities", () => {
assert.deepEqual(inputModalitiesForModel("gpt-5.6-luna"), ["text", "image"]) assert.deepEqual(inputModalitiesForModel("gpt-5.6-luna"), ["text", "image"])
assert.deepEqual(inputModalitiesForModel("meta/muse-spark-1.2"), ["text", "image"]) assert.deepEqual(inputModalitiesForModel("meta/muse-spark-1.2"), ["text", "image"])
assert.deepEqual(inputModalitiesForModel("deepseek/deepseek-v4-pro"), ["text"]) assert.deepEqual(inputModalitiesForModel("deepseek/deepseek-v4-pro"), ["text"])
@@ -123,7 +123,7 @@ describe("commandCodeModelsFromApiResponse()", () => {
assert.equal(models[1]?.reasoning, false) assert.equal(models[1]?.reasoning, false)
}) })
it("matches the exact command-code@1.15.1 reasoning effort catalog", () => { it("matches the exact command-code@1.32.1 reasoning effort catalog", () => {
assert.deepEqual(MODEL_EFFORTS, { assert.deepEqual(MODEL_EFFORTS, {
"Qwen/Qwen3.8-Max": ["low", "medium", "xhigh"], "Qwen/Qwen3.8-Max": ["low", "medium", "xhigh"],
"claude-fable-5": ["low", "medium", "high", "xhigh", "max"], "claude-fable-5": ["low", "medium", "high", "xhigh", "max"],
@@ -147,6 +147,7 @@ describe("commandCodeModelsFromApiResponse()", () => {
"google/gemini-3.6-flash": ["low", "medium", "high"], "google/gemini-3.6-flash": ["low", "medium", "high"],
"sakana/fugu-ultra": ["high", "xhigh"], "sakana/fugu-ultra": ["high", "xhigh"],
"xai/grok-4.5": ["low", "medium", "high"], "xai/grok-4.5": ["low", "medium", "high"],
"zai-org/GLM-5.3": ["low", "high", "max"],
"zai-org/GLM-5.2": ["high", "max"], "zai-org/GLM-5.2": ["high", "max"],
}) })
}) })
+2 -2
View File
@@ -50,7 +50,7 @@ function assertCost(
describe("MODEL_COSTS pricing overlay", () => { describe("MODEL_COSTS pricing overlay", () => {
it("covers the current Command Code model catalog snapshot", () => { it("covers the current Command Code model catalog snapshot", () => {
assert.equal(fixture.source, "https://api.commandcode.ai/provider/v1/models") assert.equal(fixture.source, "https://api.commandcode.ai/provider/v1/models")
assert.match(fixture.fetchedAt, /^2026-08-04T/) assert.match(fixture.fetchedAt, /^2026-08-22T/)
const catalogIds = [...fixture.modelIds].sort() const catalogIds = [...fixture.modelIds].sort()
const pricedIds = Object.keys(MODEL_COSTS).sort() const pricedIds = Object.keys(MODEL_COSTS).sort()
@@ -169,7 +169,7 @@ describe("MODEL_COSTS pricing overlay", () => {
it("tracks pricing provenance", () => { it("tracks pricing provenance", () => {
assert.equal(PRICING_SOURCE_URL, "https://commandcode.ai/docs/resources/pricing-limits") assert.equal(PRICING_SOURCE_URL, "https://commandcode.ai/docs/resources/pricing-limits")
assert.equal(PRICING_LAST_VERIFIED, "2026-08-20") assert.equal(PRICING_LAST_VERIFIED, "2026-08-22")
}) })
it("fails once temporary pricing needs review", () => { it("fails once temporary pricing needs review", () => {
+1 -1
View File
@@ -488,7 +488,7 @@ describe("streamCommandCode — request serialization", () => {
const headers = server.lastRequestHeaders() const headers = server.lastRequestHeaders()
assert.equal(headers.authorization, "Bearer mock-key") assert.equal(headers.authorization, "Bearer mock-key")
assert.equal(headers["x-command-code-version"], "1.15.1") assert.equal(headers["x-command-code-version"], "1.32.1")
assert.equal(headers["x-project-slug"], "repo") assert.equal(headers["x-project-slug"], "repo")
assert.equal(headers["x-taste-learning"], "true") assert.equal(headers["x-taste-learning"], "true")
assert.equal(headers["x-co-flag"], "false") assert.equal(headers["x-co-flag"], "false")