merge main (0.6.0) into fix/omp-developer-messages

Align the developer-message fix with the Provider API transport router.
The fix stays scoped to the legacy /alpha/generate converter, and the
OMP advisory compat test now forces the upgrade_required fallback so the
advisory is asserted on the generate request body.
This commit is contained in:
warc0s
2026-08-25 22:52:02 +02:00
48 changed files with 4325 additions and 490 deletions
+10 -3
View File
@@ -1,5 +1,5 @@
{
"fetchedAt": "2026-08-04T10:12:57.953Z",
"fetchedAt": "2026-08-25T13:32:11.631Z",
"source": "https://api.commandcode.ai/provider/v1/models",
"modelIds": [
"claude-sonnet-5",
@@ -18,11 +18,13 @@
"gpt-5.4-mini",
"deepseek/deepseek-v4-pro",
"deepseek/deepseek-v4-flash",
"deepseek/deepseek-v4-flash-vision-exp",
"moonshotai/Kimi-K3",
"moonshotai/Kimi-K2.7-Code",
"moonshotai/Kimi-K2.7-Code-Highspeed",
"moonshotai/Kimi-K2.6",
"moonshotai/Kimi-K2.5",
"zai-org/GLM-5.3",
"zai-org/GLM-5.2",
"zai-org/GLM-5.2-Fast",
"zai-org/GLM-5.1",
@@ -33,6 +35,7 @@
"xiaomi/mimo-v2.5-pro",
"xiaomi/mimo-v2.5",
"Qwen/Qwen3.8-Max",
"Qwen/Qwen3.8-27B",
"Qwen/Qwen3.7-Max",
"Qwen/Qwen3.7-Plus",
"Qwen/Qwen3.7-Flash",
@@ -41,6 +44,7 @@
"stepfun/Step-3.7-Flash",
"stepfun/Step-3.5-Flash",
"tencent/hy3-paid",
"google/gemini-3.7-flash",
"google/gemini-3.6-flash",
"google/gemini-3.5-flash",
"google/gemini-3.5-flash-lite",
@@ -49,9 +53,12 @@
"nvidia/nemotron-3-ultra-550b-a55b",
"thinkingmachines/inkling",
"thinkingmachines/inkling-small",
"stealth/ox-alpha",
"poolside/laguna-s-2.1-free",
"inclusionai/ling-3.0-flash-free",
"meta/muse-spark-1.1",
"xai/grok-4.5"
"meta/muse-spark-1.2",
"meta/muse-spark-1.2-contributor",
"xai/grok-4.5",
"xai/grok-4.6"
]
}
+21 -15
View File
@@ -1,5 +1,5 @@
{
"verifiedAt": "2026-08-04",
"verifiedAt": "2026-08-25",
"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.",
"tiers": {
@@ -8,18 +8,18 @@
[32000, 0.1, 0.4, 0.02, 0.125],
[256000, 0.2, 0.8, 0.04, 0.25]
],
"gpt-5.6-terra": [[272000, 2, 9, 0.2, 2.5]],
"gpt-5.6-luna": [[272000, 0.2, 0.9, 0.02, 0.25]]
"xai/grok-4.6": [[200000, 4, 12, 1, 0]]
},
"costs": {
"poolside/laguna-s-2.1-free": [0, 0, 0, 0],
"inclusionai/ling-3.0-flash-free": [0, 0, 0, 0],
"tencent/hy3-paid": [0.14, 0.58, 0.035, 0],
"deepseek/deepseek-v4-pro": [0.66, 1.98, 0.022, 0],
"deepseek/deepseek-v4-flash": [0.22, 0.66, 0.007, 0],
"deepseek/deepseek-v4-flash-vision-exp": [0.22, 0.66, 0.007, 0],
"moonshotai/Kimi-K3": [3, 15, 0.3, 0],
"moonshotai/Kimi-K2.7-Code": [0.95, 4, 0.19, 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.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-Fast": [3, 10.25, 0.5, 0],
"zai-org/GLM-5.1": [1.4, 4.4, 0.26, 0],
@@ -27,9 +27,10 @@
"MiniMaxAI/MiniMax-M3": [0.3, 1.2, 0.06, 0],
"MiniMaxAI/MiniMax-M2.7": [0.3, 1.2, 0.06, 0],
"MiniMaxAI/MiniMax-M2.5": [0.3, 1.2, 0.03, 0],
"deepseek/deepseek-v4-pro": [0.435, 0.87, 0.003625, 0],
"deepseek/deepseek-v4-flash": [0.14, 0.28, 0.0028, 0],
"xiaomi/mimo-v2.5-pro": [0.435, 0.87, 0.0036, 0],
"xiaomi/mimo-v2.5": [0.14, 0.28, 0.0028, 0],
"Qwen/Qwen3.8-Max": [2, 6, 0.25, 2.5],
"Qwen/Qwen3.8-27B": [0.4, 3, 0.04, 0],
"Qwen/Qwen3.7-Max": [2.5, 7.5, 0.5, 3.13],
"Qwen/Qwen3.7-Plus": [0.4, 1.6, 0.08, 0.5],
"Qwen/Qwen3.7-Flash": [0.03, 0.13, 0.006, 0.038],
@@ -37,13 +38,12 @@
"Qwen/Qwen3.6-Plus": [0.5, 3, 0.1, 0],
"stepfun/Step-3.7-Flash": [0.2, 1.15, 0.04, 0],
"stepfun/Step-3.5-Flash": [0.1, 0.3, 0.02, 0],
"xiaomi/mimo-v2.5-pro": [0.435, 0.87, 0.0036, 0],
"xiaomi/mimo-v2.5": [0.14, 0.28, 0.0028, 0],
"tencent/hy3-paid": [0.14, 0.58, 0.035, 0],
"nvidia/nemotron-3-ultra-550b-a55b": [0.6, 2.4, 0.12, 0],
"sakana/fugu-ultra": [5, 30, 0.5, 0],
"thinkingmachines/inkling": [1, 4.05, 0.17, 0],
"thinkingmachines/inkling-small": [0.5, 1.2, 0.1, 0],
"meta/muse-spark-1.1": [1.25, 4.25, 0.15, 0],
"poolside/laguna-s-2.1-free": [0, 0, 0, 0],
"stealth/ox-alpha": [0, 0, 0, 0],
"claude-sonnet-5": [2, 10, 0.2, 2.5],
"claude-sonnet-4-6": [3, 15, 0.3, 3.75],
"claude-fable-5": [10, 50, 1, 12.5],
@@ -52,16 +52,22 @@
"claude-opus-4-7": [5, 25, 0.5, 6.25],
"claude-haiku-4-5-20251001": [1, 5, 0.1, 1.25],
"gpt-5.6-sol": [5, 30, 0.5, 6.25],
"gpt-5.6-terra": [1, 6, 0.1, 1.25],
"gpt-5.6-luna": [0.1, 0.6, 0.01, 0.125],
"gpt-5.6-terra": [2, 12, 0.2, 2.5],
"gpt-5.6-luna": [0.2, 1.2, 0.02, 0.25],
"gpt-5.5": [5, 30, 0.5, 0],
"gpt-5.4": [2.5, 15, 0.25, 0],
"gpt-5.3-codex": [2, 8, 0.5, 0],
"gpt-5.4-mini": [0.75, 4.5, 0.075, 0],
"google/gemini-3.7-flash": [0.75, 3.75, 0.075, 0.04167],
"google/gemini-3.6-flash": [1.5, 7.5, 0.15, 0],
"google/gemini-3.5-flash": [1.5, 9, 0.15, 0],
"google/gemini-3.5-flash-lite": [0.3, 2.5, 0.03, 0],
"google/gemini-3.1-flash-lite": [0.25, 1.5, 0.03, 0],
"xai/grok-4.5": [2, 6, 0.5, 0]
"sakana/fugu-ultra": [5, 30, 0.5, 0],
"meta/muse-spark-1.1": [1.25, 4.25, 0.15, 0],
"meta/muse-spark-1.2": [1.25, 4.25, 0.15, 0],
"meta/muse-spark-1.2-contributor": [0.1, 0.2, 0.002, 0],
"xai/grok-4.5": [2, 6, 0.5, 0],
"xai/grok-4.6": [2, 6, 0.5, 0]
}
}
+66
View File
@@ -0,0 +1,66 @@
import assert from "node:assert/strict"
import { mkdtemp, rm, writeFile } from "node:fs/promises"
import { tmpdir } from "node:os"
import { join } from "node:path"
import { describe, it } from "node:test"
import { getConfiguredApiKey } from "../src/api-key.ts"
async function withAuthFile(
value: unknown,
run: (authPath: string) => Promise<void>,
): Promise<void> {
const directory = await mkdtemp(join(tmpdir(), "pi-commandcode-auth-"))
const authPath = join(directory, "auth.json")
try {
await writeFile(authPath, JSON.stringify(value), "utf-8")
await run(authPath)
} finally {
await rm(directory, { recursive: true, force: true })
}
}
describe("getConfiguredApiKey()", () => {
it("prefers the official environment variable and keeps the legacy alias", () => {
assert.equal(
getConfiguredApiKey({
env: { COMMAND_CODE_API_KEY: "official-key", COMMANDCODE_API_KEY: "legacy-key" },
authPaths: [],
}),
"official-key",
)
assert.equal(
getConfiguredApiKey({ env: { COMMANDCODE_API_KEY: "legacy-key" }, authPaths: [] }),
"legacy-key",
)
})
it("reads pi OAuth and API credentials", async () => {
const cases: readonly { credential: unknown; expected: string }[] = [
{
credential: { commandcode: { type: "oauth", access: "oauth-key" } },
expected: "oauth-key",
},
{ credential: { commandcode: { type: "api", key: "api-key" } }, expected: "api-key" },
{ credential: { "command-code": { type: "api", key: "cli-key" } }, expected: "cli-key" },
{ credential: { apiKey: "legacy-key" }, expected: "legacy-key" },
]
for (const testCase of cases) {
await withAuthFile(testCase.credential, async (authPath) => {
assert.equal(getConfiguredApiKey({ env: {}, authPaths: [authPath] }), testCase.expected)
})
}
})
it("ignores malformed files", async () => {
const directory = await mkdtemp(join(tmpdir(), "pi-commandcode-auth-"))
const authPath = join(directory, "auth.json")
try {
await writeFile(authPath, "not json", "utf-8")
assert.equal(getConfiguredApiKey({ env: {}, authPaths: [authPath] }), undefined)
} finally {
await rm(directory, { recursive: true, force: true })
}
})
})
+174 -32
View File
@@ -25,6 +25,22 @@ import { fileURLToPath } from "node:url"
const projectDir = resolve(dirname(fileURLToPath(import.meta.url)), "..")
const extensionPath = join(projectDir, "index.ts")
const testModel = process.env.COMMANDCODE_E2E_MODEL ?? "deepseek/deepseek-v4-flash"
const testProfile = process.env.COMMANDCODE_E2E_PROFILE
const expectedTransport =
testProfile === "go"
? "generate"
: testProfile === "goat" || testProfile === "provider"
? "provider"
: undefined
const expectedPlan =
testProfile === "go"
? "go"
: testProfile === "goat"
? "goat"
: testProfile === "provider"
? "provider"
: undefined
const goatVisionModel = process.env.COMMANDCODE_E2E_GOAT_VISION_MODEL ?? "google/gemini-3.7-flash"
const marker = "commandcode-live-e2e-ok"
function findPiBinary() {
@@ -45,6 +61,7 @@ function findPiBinary() {
function hasAuthMetadata() {
return (
Boolean(process.env.COMMAND_CODE_API_KEY) ||
Boolean(process.env.COMMANDCODE_API_KEY) ||
existsSync(join(homedir(), ".commandcode", "auth.json")) ||
existsSync(join(homedir(), ".pi", "agent", "auth.json"))
@@ -57,9 +74,19 @@ if (!piBin || !hasAuthMetadata()) {
process.exit(0)
}
const profileAgentDir = testProfile
? mkdtempSync(join(tmpdir(), `pi-commandcode-live-${testProfile}-agent-`))
: undefined
function safeEnv(overrides = {}) {
const env = { ...process.env, PI_SKIP_VERSION_CHECK: "1", ...overrides }
delete env.COMMANDCODE_API_KEY
if (testProfile && profileAgentDir) {
env.PI_CODING_AGENT_DIR = profileAgentDir
env.COMMANDCODE_MODELS_CACHE = join(profileAgentDir, "commandcode-models.json")
} else {
delete env.COMMAND_CODE_API_KEY
delete env.COMMANDCODE_API_KEY
}
return env
}
@@ -90,7 +117,7 @@ function run(command, args, options = {}) {
})
}
async function runRpc(extension, action, timeoutMs = 120_000) {
async function runRpc(extension, action, timeoutMs = 120_000, model = testModel) {
const child = spawn(
piBin,
[
@@ -102,7 +129,9 @@ async function runRpc(extension, action, timeoutMs = 120_000) {
"--provider",
"commandcode",
"--model",
testModel,
model,
"--thinking",
"high",
],
{ cwd: projectDir, env: safeEnv(), stdio: ["pipe", "pipe", "pipe"] },
)
@@ -210,8 +239,19 @@ try {
await waitFor(
(event) => event.type === "response" && event.id === "reasoning-turn-1" && event.success,
)
await waitFor((event) => event.type === "agent_settled")
const firstThinkingDeltas = countThinkingDeltas(firstStart)
const firstSettled = await waitFor(
(event) => event.type === "agent_settled" && events.indexOf(event) >= firstStart,
)
const firstSettledIndex = events.indexOf(firstSettled)
const firstThinkingDeltas = events
.slice(firstStart, firstSettledIndex + 1)
.filter(
(event) =>
event.type === "message_update" &&
event.assistantMessageEvent?.type === "thinking_delta" &&
typeof event.assistantMessageEvent.delta === "string" &&
event.assistantMessageEvent.delta.length > 0,
).length
const secondStart = events.length
send({
@@ -223,8 +263,11 @@ try {
await waitFor(
(event) => event.type === "response" && event.id === "reasoning-turn-2" && event.success,
)
await waitFor((event) => event.type === "agent_settled" && events.indexOf(event) >= secondStart)
const secondSettled = await waitFor(
(event) => event.type === "agent_settled" && events.indexOf(event) >= secondStart,
)
const secondThinkingDeltas = countThinkingDeltas(secondStart)
assert.ok(events.indexOf(secondSettled) >= secondStart)
return { firstThinkingDeltas, secondThinkingDeltas, stderr: getStderr() }
})
@@ -234,6 +277,14 @@ try {
console.log("[live-e2e] live runtime refresh/status commands")
const runtime = await runRpc(extensionPath, async ({ send, waitFor, getStderr }) => {
if (expectedTransport) {
send({ id: "transport-probe", type: "prompt", message: `Reply exactly: ${marker}` })
await waitFor(
(event) => event.type === "response" && event.id === "transport-probe" && event.success,
)
await waitFor((event) => event.type === "agent_settled")
}
send({ id: "commands", type: "get_commands" })
const commands = await waitFor(
(event) => event.type === "response" && event.id === "commands" && event.success,
@@ -259,14 +310,66 @@ try {
typeof event.message === "string" &&
event.message.includes("source:"),
)
return { names, refresh: refresh.message, status: status.message, stderr: getStderr() }
send({ id: "quota", type: "prompt", message: "/commandcode-quota" })
await waitFor((event) => event.type === "response" && event.id === "quota" && event.success)
const quota = await waitFor(
(event) =>
event.type === "extension_ui_request" &&
event.method === "notify" &&
typeof event.message === "string" &&
event.message.includes("Plan:"),
)
return {
names,
refresh: refresh.message,
status: status.message,
quota: quota.message,
stderr: getStderr(),
}
})
assert.ok(runtime.names.includes("commandcode-refresh"))
assert.ok(runtime.names.includes("commandcode-status"))
assert.ok(runtime.names.includes("commandcode-quota"))
assert.match(runtime.refresh, /model catalog (?:refreshed|unchanged)/)
if (expectedTransport) assert.match(runtime.status, new RegExp(`transport: ${expectedTransport}`))
assert.match(runtime.status, /source: (?:live|cache)/)
assert.match(runtime.status, /model count: [1-9][0-9]*/)
assert.doesNotMatch(`${runtime.refresh}\n${runtime.status}\n${runtime.stderr}`, /Bearer\s+\S+/i)
if (expectedPlan) assert.match(runtime.quota, new RegExp(`Plan:.*\\b${expectedPlan}\\b`, "i"))
assert.doesNotMatch(
`${runtime.refresh}\n${runtime.status}\n${runtime.quota}\n${runtime.stderr}`,
/Bearer\s+\S+/i,
)
console.log("[live-e2e] live abort through real RPC host")
const abortResult = await runRpc(extensionPath, async ({ send, waitFor, events, getStderr }) => {
const startIndex = events.length
send({
id: "abort-turn",
type: "prompt",
message: "Write a very long detailed explanation of every integer from 1 to 10000.",
})
await waitFor(
(event) => event.type === "response" && event.id === "abort-turn" && event.success,
)
await waitFor((event) => event.type === "message_update" && events.indexOf(event) >= startIndex)
send({ id: "abort", type: "abort" })
await waitFor((event) => event.type === "response" && event.id === "abort" && event.success)
await waitFor((event) => event.type === "agent_settled" && events.indexOf(event) >= startIndex)
return {
aborted: events
.slice(startIndex)
.some(
(event) =>
event.type === "message_end" &&
event.message?.role === "assistant" &&
event.message?.stopReason === "aborted",
),
stderr: getStderr(),
}
})
assert.equal(abortResult.aborted, true)
assert.doesNotMatch(abortResult.stderr, /Bearer\s+\S+/i)
console.log("[live-e2e] live tool-call round trip")
const toolRoot = join(tempRoot, "tool-roundtrip")
@@ -294,32 +397,70 @@ try {
)
assert.equal(toolResult.code, 0, toolResult.stderr)
assert.match(toolResult.stdout, new RegExp(marker))
assert.equal(readFileSync(targetPath, "utf-8"), marker)
assert.equal(readFileSync(targetPath, "utf-8").trimEnd(), marker)
console.log("[live-e2e] image rejection through real RPC host")
const image = await runRpc(extensionPath, async ({ send, waitFor, events }) => {
send({
id: "image",
type: "prompt",
message: "Describe this image",
images: [{ type: "image", data: "iVBORw0KGgo=", mimeType: "image/png" }],
})
await waitFor((event) => event.type === "response" && event.id === "image")
await waitFor(
(event) =>
event.type === "message_end" &&
event.message?.role === "assistant" &&
event.message?.stopReason === "error",
if (testProfile === "goat") {
console.log("[live-e2e] live vision request through Provider API")
const vision = await runRpc(
extensionPath,
async ({ send, waitFor, events, getStderr }) => {
const startIndex = events.length
send({
id: "vision",
type: "prompt",
message: "Describe the attached image briefly.",
images: [
{
type: "image",
data: "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=",
mimeType: "image/png",
},
],
})
await waitFor(
(event) => event.type === "response" && event.id === "vision" && event.success,
)
await waitFor(
(event) => event.type === "agent_settled" && events.indexOf(event) >= startIndex,
)
const messageEnd = events
.slice(startIndex)
.find((event) => event.type === "message_end" && event.message?.role === "assistant")
return { messageEnd, stderr: getStderr() }
},
180_000,
goatVisionModel,
)
return events
})
assert.ok(
image.some(
(event) =>
event.type === "message_end" &&
/does not support image content/i.test(event.message?.errorMessage ?? ""),
),
)
assert.notEqual(vision.messageEnd?.message?.stopReason, "error")
assert.doesNotMatch(vision.stderr, /Bearer\s+\S+/i)
}
if (testProfile === "go") {
console.log("[live-e2e] image rejection through real RPC host")
const image = await runRpc(extensionPath, async ({ send, waitFor, events }) => {
send({
id: "image",
type: "prompt",
message: "Describe this image",
images: [{ type: "image", data: "iVBORw0KGgo=", mimeType: "image/png" }],
})
await waitFor((event) => event.type === "response" && event.id === "image")
await waitFor(
(event) =>
event.type === "message_end" &&
event.message?.role === "assistant" &&
event.message?.stopReason === "error",
)
return events
})
assert.ok(
image.some(
(event) =>
event.type === "message_end" &&
/does not support image content/i.test(event.message?.errorMessage ?? ""),
),
)
}
console.log("[live-e2e] packed artifact with existing authentication")
const packDir = join(tempRoot, "pack")
@@ -361,4 +502,5 @@ try {
console.log("[live-e2e] PASS")
} finally {
rmSync(tempRoot, { recursive: true, force: true })
if (profileAgentDir) rmSync(profileAgentDir, { recursive: true, force: true })
}
+170
View File
@@ -0,0 +1,170 @@
import assert from "node:assert/strict"
import { describe, it } from "node:test"
import {
commandCodeModelMetadataFromContents,
diffModelMetadata,
hasModelMetadataDiff,
parseBundleModelCapabilities,
parseKnownTextOnlyModelIds,
parseModelsReference,
parsePackageVersion,
renderCommandCodeCatalog,
updateReadmeCatalogVersion,
type CommandCodeModelMetadata,
} from "../.github/scripts/check-commandcode-model-metadata.ts"
const MODELS_REFERENCE = `
| Id (use EXACTLY this) | Name | Context | Efforts | $/1M in/out · cache read | Min plan | Best for |
|---|---|---|---|---|---|---|
| \`vision-model\` | Vision | 1M | low, high | $1/$2 | Go | images |
| \`text-model\` | Text | 200K | — | $1/$2 | Go | text |
`
const CLI_BUNDLE =
'const V={id:"vision-model",inputModalities:["text","image"],reasoning:!0,reasoningEfforts:["low","high"],maxOutputTokens:32768},T={id:"text-model",inputModalities:["text"]},catalog=new Set(["text-model"]),__name(isKnownTextOnlyModel,"isKnownTextOnlyModel")'
describe("Command Code model metadata checker", () => {
it("parses model ids and reasoning efforts from the generated reference", () => {
assert.deepEqual(parseModelsReference(MODELS_REFERENCE), {
modelIds: ["text-model", "vision-model"],
reasoningEfforts: { "vision-model": ["low", "high"] },
})
})
it("extracts the text-only set from the bundled CLI catalog", () => {
assert.deepEqual(parseKnownTextOnlyModelIds(CLI_BUNDLE), ["text-model"])
})
it("accepts one exact npm registry version and rejects stale-looking output shapes", () => {
assert.equal(parsePackageVersion("1.32.2"), "1.32.2")
assert.equal(parsePackageVersion("2.0.0-beta.1"), "2.0.0-beta.1")
assert.throws(() => parsePackageVersion(["1.32.1", "1.32.2"]), /one semantic version/)
assert.throws(() => parsePackageVersion("latest"), /one semantic version/)
})
it("derives image, reasoning, effort, and output-limit metadata", () => {
assert.deepEqual(parseBundleModelCapabilities(CLI_BUNDLE, ["text-model", "vision-model"]), {
reasoningModelIds: ["vision-model"],
maxOutputTokens: { "vision-model": 32_768 },
})
assert.deepEqual(commandCodeModelMetadataFromContents(MODELS_REFERENCE, CLI_BUNDLE), {
imageModelIds: ["vision-model"],
reasoningModelIds: ["vision-model"],
reasoningEfforts: { "vision-model": ["low", "high"] },
maxOutputTokens: { "vision-model": 32_768 },
})
})
it("reports additions, removals, and changed reasoning efforts", () => {
const current: CommandCodeModelMetadata = {
imageModelIds: ["removed-image", "stable-image"],
reasoningModelIds: ["removed-reasoning", "stable-reasoning"],
reasoningEfforts: {
"changed-effort": ["low"],
"removed-effort": ["high"],
"stable-effort": ["low", "high"],
},
maxOutputTokens: { "changed-output": 1, "removed-output": 2, "stable-output": 3 },
}
const upstream: CommandCodeModelMetadata = {
imageModelIds: ["added-image", "stable-image"],
reasoningModelIds: ["added-reasoning", "stable-reasoning"],
reasoningEfforts: {
"added-effort": ["max"],
"changed-effort": ["low", "high"],
"stable-effort": ["low", "high"],
},
maxOutputTokens: { "added-output": 4, "changed-output": 5, "stable-output": 3 },
}
const diff = diffModelMetadata(current, upstream)
assert.deepEqual(diff, {
versionChanged: false,
addedImageModelIds: ["added-image"],
removedImageModelIds: ["removed-image"],
addedReasoningModelIds: ["added-reasoning"],
removedReasoningModelIds: ["removed-reasoning"],
addedEffortModelIds: ["added-effort"],
removedEffortModelIds: ["removed-effort"],
changedEffortModelIds: ["changed-effort"],
addedMaxOutputModelIds: ["added-output"],
removedMaxOutputModelIds: ["removed-output"],
changedMaxOutputModelIds: ["changed-output"],
})
assert.equal(hasModelMetadataDiff(diff), true)
})
it("reports CLI version drift even when model metadata is unchanged", () => {
const metadata: CommandCodeModelMetadata = {
imageModelIds: ["vision-model"],
reasoningModelIds: ["vision-model"],
reasoningEfforts: { "vision-model": ["low"] },
maxOutputTokens: { "vision-model": 32_768 },
}
const diff = diffModelMetadata(metadata, metadata, "1.32.2", "1.33.0")
assert.equal(diff.versionChanged, true)
assert.equal(hasModelMetadataDiff(diff), true)
})
it("renders a deterministic generated catalog and updates the README version", () => {
assert.equal(
renderCommandCodeCatalog("1.33.0", {
imageModelIds: ["b-model", "a-model"],
reasoningModelIds: ["c-model", "a-model"],
reasoningEfforts: {
"b-model": ["high", "max"],
"a-model": ["low"],
},
maxOutputTokens: { "b-model": 32_768 },
}),
`export const COMMAND_CODE_CLI_VERSION = "1.33.0"
export type CommandCodeInputType = "text" | "image"
export type CommandCodeReasoningEffort = "minimal" | "low" | "medium" | "high" | "xhigh" | "max"
/**
* Generated from command-code@1.33.0 by \`npm run sync:commandcode-catalog\`.
* Do not edit manually.
*/
export const MODEL_INPUT_MODALITIES: Readonly<Record<string, readonly CommandCodeInputType[]>> = {
"a-model": ["text", "image"],
"b-model": ["text", "image"],
}
export const MODEL_REASONING: Readonly<Record<string, true>> = {
"a-model": true,
"c-model": true,
}
export const MODEL_EFFORTS: Readonly<Record<string, readonly CommandCodeReasoningEffort[]>> = {
"a-model": ["low"],
"b-model": ["high", "max"],
}
export const MODEL_MAX_OUTPUT_TOKENS: Readonly<Record<string, number>> = {
"b-model": 32_768,
}
`,
)
assert.equal(
updateReadmeCatalogVersion(
"The capability snapshot currently follows `command-code@1.32.2`.",
"1.33.0",
),
"The capability snapshot currently follows `command-code@1.33.0`.",
)
})
it("rejects unexpected upstream structures instead of silently passing", () => {
assert.throws(() => parseModelsReference("# no catalog"), /No model rows/)
assert.throws(
() => parseModelsReference(MODELS_REFERENCE.replace("low, high", "low, turbo")),
/Unexpected reasoning efforts/,
)
assert.throws(() => parseKnownTextOnlyModelIds("const unrelated = true"), /Could not find/)
})
})
+89 -36
View File
@@ -4,7 +4,10 @@ import { tmpdir } from "node:os"
import { join } from "node:path"
import { describe, it } from "node:test"
import { COMMAND_CODE_CLI_VERSION } from "../src/commandcode-catalog.ts"
import {
apiForModelId,
baseUrlForModel,
commandCodeModelsFromApiResponse,
commandCodeModelsFromCache,
DEFAULT_MODELS_TIMEOUT_MS,
@@ -13,6 +16,8 @@ import {
loadCommandCodeModels,
MODEL_EFFORTS,
MODEL_INPUT_MODALITIES,
MODEL_MAX_OUTPUT_TOKENS,
MODEL_REASONING,
modelSupportsImageInput,
thinkingLevelMapForEfforts,
thinkingMetadataForModel,
@@ -37,7 +42,8 @@ const EXPECTED_MODELS: readonly CommandCodeModel[] = [
{
id: "Qwen/Qwen3.7-Max",
name: "Qwen 3.7 Max (CC)",
reasoning: false,
api: "openai-completions",
reasoning: true,
contextWindow: 1_000_000,
maxTokens: 65_536,
},
@@ -84,61 +90,108 @@ describe("commandCodeModelsFromApiResponse()", () => {
assert.deepEqual(commandCodeModelsFromApiResponse(API_RESPONSE), EXPECTED_MODELS)
})
it("matches command-code@1.15.1 image input capabilities", () => {
assert.deepEqual(inputModalitiesForModel("gpt-5.6-luna"), ["text", "image"])
assert.deepEqual(inputModalitiesForModel("meta/muse-spark-1.2"), ["text", "image"])
assert.deepEqual(inputModalitiesForModel("deepseek/deepseek-v4-pro"), ["text"])
assert.deepEqual(inputModalitiesForModel("unknown-new-model"), ["text"])
assert.equal(modelSupportsImageInput("gpt-5.6-luna"), true)
assert.equal(modelSupportsImageInput("deepseek/deepseek-v4-pro"), false)
assert.equal(Object.keys(MODEL_INPUT_MODALITIES).length, 37)
it("routes Claude models to Anthropic Messages and all others to Chat Completions", () => {
assert.equal(apiForModelId("claude-sonnet-4-6"), "anthropic-messages")
assert.equal(apiForModelId("gpt-5.6-sol"), "openai-completions")
assert.equal(
baseUrlForModel("https://api.commandcode.ai/provider/v1/", "openai-completions"),
"https://api.commandcode.ai/provider/v1",
)
assert.equal(
baseUrlForModel("https://api.commandcode.ai/provider/v1/", "anthropic-messages"),
"https://api.commandcode.ai/provider",
)
})
it("marks only known reasoning models as reasoning-capable", () => {
it(`uses the command-code@${COMMAND_CODE_CLI_VERSION} image capability catalog`, () => {
assert.deepEqual(inputModalitiesForModel("gpt-5.6-luna"), ["text", "image"])
assert.deepEqual(inputModalitiesForModel("meta/muse-spark-1.2"), ["text", "image"])
assert.deepEqual(inputModalitiesForModel("deepseek/deepseek-v4-flash-vision-exp"), [
"text",
"image",
])
assert.deepEqual(inputModalitiesForModel("Qwen/Qwen3.8-27B"), ["text", "image"])
assert.deepEqual(inputModalitiesForModel("google/gemini-3.7-flash"), ["text", "image"])
assert.deepEqual(inputModalitiesForModel("stealth/ox-alpha"), ["text", "image"])
assert.deepEqual(inputModalitiesForModel("deepseek/deepseek-v4-pro"), ["text"])
assert.deepEqual(inputModalitiesForModel("zai-org/GLM-5.3"), ["text"])
assert.deepEqual(inputModalitiesForModel("unknown-new-model"), ["text"])
assert.equal(modelSupportsImageInput("gpt-5.6-luna"), true)
assert.equal(modelSupportsImageInput("deepseek/deepseek-v4-flash-vision-exp"), true)
assert.equal(modelSupportsImageInput("stealth/ox-alpha"), true)
assert.equal(modelSupportsImageInput("deepseek/deepseek-v4-pro"), false)
assert.ok(Object.keys(MODEL_INPUT_MODALITIES).length > 0)
for (const modalities of Object.values(MODEL_INPUT_MODALITIES)) {
assert.deepEqual(modalities, ["text", "image"])
}
})
it("tracks reasoning independently from selectable effort levels", () => {
const models = commandCodeModelsFromApiResponse({
object: "list",
data: [
{ ...API_RESPONSE.data[0], id: "deepseek/deepseek-v4-flash" },
{ ...API_RESPONSE.data[0], id: "moonshotai/Kimi-K3" },
{ ...API_RESPONSE.data[0], id: "new-model-without-metadata" },
],
})
assert.equal(models[0]?.reasoning, true)
assert.equal(models[1]?.reasoning, false)
assert.equal(models[1]?.reasoning, true)
assert.deepEqual(thinkingMetadataForModel("moonshotai/Kimi-K3"), {
thinkingLevelMap: {
minimal: null,
low: null,
medium: null,
high: null,
xhigh: null,
max: null,
},
})
assert.equal(models[2]?.reasoning, false)
assert.equal(Object.keys(MODEL_REASONING).length, 48)
})
it("matches the exact command-code@1.15.1 reasoning effort catalog", () => {
assert.deepEqual(MODEL_EFFORTS, {
"Qwen/Qwen3.8-Max": ["low", "medium", "xhigh"],
"claude-fable-5": ["low", "medium", "high", "xhigh", "max"],
"claude-opus-4-7": ["low", "medium", "high", "xhigh", "max"],
"claude-opus-4-8": ["low", "medium", "high", "xhigh", "max"],
"claude-opus-5": ["low", "medium", "high", "xhigh", "max"],
"claude-sonnet-4-6": ["low", "medium", "high", "xhigh", "max"],
"claude-sonnet-5": ["low", "medium", "high", "xhigh", "max"],
"deepseek/deepseek-v4-flash": ["high", "max"],
"deepseek/deepseek-v4-pro": ["high", "max"],
"gpt-5.3-codex": ["low", "medium", "high", "xhigh"],
"gpt-5.4": ["low", "medium", "high", "xhigh"],
"gpt-5.4-mini": ["low", "medium", "high"],
"gpt-5.5": ["low", "medium", "high", "xhigh"],
"gpt-5.6-luna": ["low", "medium", "high", "xhigh", "max"],
"gpt-5.6-sol": ["low", "medium", "high", "xhigh", "max"],
"gpt-5.6-terra": ["low", "medium", "high", "xhigh", "max"],
"google/gemini-3.1-flash-lite": ["low", "medium", "high"],
"google/gemini-3.5-flash": ["low", "medium", "high"],
"google/gemini-3.5-flash-lite": ["low", "medium", "high"],
"google/gemini-3.6-flash": ["low", "medium", "high"],
"sakana/fugu-ultra": ["high", "xhigh"],
"xai/grok-4.5": ["low", "medium", "high"],
"zai-org/GLM-5.2": ["high", "max"],
it("uses model-specific output limits from the CLI catalog", () => {
const models = commandCodeModelsFromApiResponse({
object: "list",
data: [
{ ...API_RESPONSE.data[0], id: "Qwen/Qwen3.8-27B", context_length: 262_144 },
{ ...API_RESPONSE.data[0], id: "stealth/ox-alpha", context_length: 1_048_576 },
{
...API_RESPONSE.data[0],
id: "poolside/laguna-s-2.1-free",
context_length: 256_000,
},
],
})
assert.deepEqual(
models.map(({ id, maxTokens }) => ({ id, maxTokens })),
[
{ id: "Qwen/Qwen3.8-27B", maxTokens: 32_768 },
{ id: "stealth/ox-alpha", maxTokens: 131_072 },
{ id: "poolside/laguna-s-2.1-free", maxTokens: 32_768 },
],
)
assert.equal(Object.keys(MODEL_MAX_OUTPUT_TOKENS).length, 3)
})
it(`uses the command-code@${COMMAND_CODE_CLI_VERSION} reasoning effort catalog`, () => {
const validEfforts = new Set(["minimal", "low", "medium", "high", "xhigh", "max"])
assert.ok(Object.keys(MODEL_EFFORTS).length > 0)
for (const efforts of Object.values(MODEL_EFFORTS)) {
assert.ok(efforts.length > 0)
assert.equal(new Set(efforts).size, efforts.length)
assert.ok(efforts.every((effort) => validEfforts.has(effort)))
}
})
it("builds separate canonical pi and OMP metadata", () => {
for (const [modelId, efforts] of Object.entries(MODEL_EFFORTS)) {
const metadata = thinkingMetadataForModel(modelId)
assert.ok(metadata, `${modelId} should have reasoning metadata`)
assert.ok(metadata.thinking)
assert.equal(metadata.thinking.mode, "effort")
assert.deepEqual(metadata.thinking.efforts, efforts)
assert.deepEqual(
+137 -26
View File
@@ -9,7 +9,7 @@ import assert from "node:assert/strict"
import { describe, it } from "node:test"
import { startAuthServer, type AuthCallback } from "../src/auth-server.ts"
import { getApiKey, login, refreshToken, sanitizeApiKey } from "../src/oauth.ts"
import { getApiKey, login, refreshToken, sanitizeApiKey, validateApiKey } from "../src/oauth.ts"
/**
* Helper: wait for an HTTP server to close, or resolve immediately if already closed.
@@ -24,9 +24,27 @@ function waitForClose(server: {
})
}
async function withValidApiKeyFetch<T>(run: () => Promise<T>): Promise<T> {
const originalFetch = globalThis.fetch
globalThis.fetch = (input, init) => {
if (String(input).endsWith("/alpha/whoami")) {
return Promise.resolve(new Response(JSON.stringify({ user: {} }), { status: 200 }))
}
return originalFetch(input, init)
}
try {
return await run()
} finally {
globalThis.fetch = originalFetch
}
}
describe("startAuthServer()", () => {
it("starts on a localhost port and accepts a valid callback POST", async () => {
const { server, port, waitForCallback } = await startAuthServer({ startPort: 0 })
const { server, port, waitForCallback } = await startAuthServer({
startPort: 0,
expectedState: "test-state-token",
})
const callbackData: AuthCallback = {
apiKey: "user_testKey123",
@@ -57,6 +75,42 @@ describe("startAuthServer()", () => {
await waitForClose(server)
})
it("rejects a mismatched state without closing the callback server", async () => {
const { server, port, waitForCallback } = await startAuthServer({
startPort: 0,
expectedState: "correct-state",
})
const invalidResponse = await fetch(`http://127.0.0.1:${port}/callback`, {
method: "POST",
headers: { "Content-Type": "application/json", Origin: "https://commandcode.ai" },
body: JSON.stringify({
apiKey: "user_badState",
state: "wrong-state",
userId: "user_789",
userName: "Attacker",
keyName: "evil-key",
}),
})
assert.equal(invalidResponse.status, 403)
assert.equal(server.listening, true)
const validResponse = await fetch(`http://127.0.0.1:${port}/callback`, {
method: "POST",
headers: { "Content-Type": "application/json", Origin: "https://commandcode.ai" },
body: JSON.stringify({
apiKey: "user_valid",
state: "correct-state",
userId: "user_123",
userName: "Valid User",
keyName: "valid-key",
}),
})
assert.equal(validResponse.status, 200)
assert.equal((await waitForCallback).apiKey, "user_valid")
await waitForClose(server)
})
it("rejects when the callback indicates access_denied", async () => {
const { server, port, waitForCallback } = await startAuthServer({ startPort: 0 })
@@ -176,6 +230,18 @@ describe("OAuth functions", () => {
it("sanitizeApiKey removes paste markers, control chars, and whitespace", () => {
assert.equal(sanitizeApiKey("\u001b[200~ user_manualKey\n\u001b[201~"), "user_manualKey")
})
it("validates manual API keys through whoami", async () => {
await validateApiKey("valid-key", {
fetchImpl: () => Promise.resolve(new Response(JSON.stringify({ user: {} }), { status: 200 })),
})
await assert.rejects(
validateApiKey("invalid-key", {
fetchImpl: () => Promise.resolve(new Response("unauthorized", { status: 401 })),
}),
/Invalid Command Code API key/,
)
})
})
describe("login()", () => {
@@ -186,7 +252,7 @@ describe("login()", () => {
authUrl = params.url
},
onPrompt(_params: { message: string }): Promise<string> {
throw new Error("onPrompt should not be called in browser flow")
return Promise.resolve("")
},
}
@@ -239,21 +305,23 @@ describe("login()", () => {
process.env.COMMANDCODE_AUTH_TIMEOUT_MS = "1"
let authUrl = ""
let promptMessage = ""
const promptMessages: string[] = []
try {
const result = await login({
onAuth(params: { url: string }) {
authUrl = params.url
},
async onPrompt(params: { message: string }): Promise<string> {
promptMessage = params.message
return "\u001b[200~ user_manualApiKey\n\u001b[201~"
},
})
const result = await withValidApiKeyFetch(() =>
login({
onAuth(params: { url: string }) {
authUrl = params.url
},
async onPrompt(params: { message: string }): Promise<string> {
promptMessages.push(params.message)
return promptMessages.length === 1 ? "" : "\u001b[200~ user_manualApiKey\n\u001b[201~"
},
}),
)
assert.match(authUrl, /^https:\/\/commandcode\.ai\/studio\/auth\/cli\?/)
assert.match(promptMessage, /Paste your Command Code API key/)
assert.match(promptMessages[1] ?? "", /Paste your Command Code API key/)
assert.equal(result.access, "user_manualApiKey")
assert.equal(result.refresh, "user_manualApiKey")
assert.ok(result.expires > Date.now(), "expiry should be far in the future")
@@ -263,23 +331,53 @@ describe("login()", () => {
}
})
it("rejects on state token mismatch", async () => {
it("accepts a directly pasted API key", async () => {
let authOpened = false
const result = await withValidApiKeyFetch(() =>
login({
onAuth() {
authOpened = true
},
onPrompt(): Promise<string> {
return Promise.resolve("user_directApiKey")
},
}),
)
assert.equal(authOpened, false)
assert.equal(result.access, "user_directApiKey")
})
it("offers an explicit API key prompt", async () => {
let promptCount = 0
const result = await withValidApiKeyFetch(() =>
login({
onAuth() {
throw new Error("browser should not open")
},
onPrompt(): Promise<string> {
promptCount += 1
return Promise.resolve(promptCount === 1 ? "key" : "user_promptedApiKey")
},
}),
)
assert.equal(result.access, "user_promptedApiKey")
assert.equal(promptCount, 2)
})
it("keeps waiting after a state mismatch and accepts the legitimate callback", async () => {
let authUrl = ""
const callbacks = {
onAuth(params: { url: string }) {
authUrl = params.url
},
onPrompt(_params: { message: string }): Promise<string> {
throw new Error("should not prompt")
return Promise.resolve("")
},
}
const loginPromise: Promise<string> = login(callbacks).then(
() => {
throw new Error("Expected login to reject")
},
(e: Error) => e.message,
)
const loginPromise = login(callbacks)
// Wait for onAuth to be called asynchronously
while (!authUrl) await new Promise((resolve) => setTimeout(resolve, 10))
@@ -287,8 +385,8 @@ describe("login()", () => {
const url = new URL(authUrl)
const port = parseInt(url.searchParams.get("callback")?.match(/localhost:(\d+)/)?.[1] ?? "0")
// Post back with a wrong state token
await fetch(`http://127.0.0.1:${port}/callback`, {
// Post back with a wrong state token.
const invalidResponse = await fetch(`http://127.0.0.1:${port}/callback`, {
method: "POST",
headers: { "Content-Type": "application/json", Origin: "https://commandcode.ai" },
body: JSON.stringify({
@@ -300,7 +398,20 @@ describe("login()", () => {
}),
})
const errorMsg = await loginPromise
assert.match(errorMsg, /State token mismatch/)
assert.equal(invalidResponse.status, 403)
const validResponse = await fetch(`http://127.0.0.1:${port}/callback`, {
method: "POST",
headers: { "Content-Type": "application/json", Origin: "https://commandcode.ai" },
body: JSON.stringify({
apiKey: "user_goodState",
state: url.searchParams.get("state"),
userId: "user_123",
userName: "Real User",
keyName: "real-key",
}),
})
assert.equal(validResponse.status, 200)
assert.equal((await loginPromise).access, "user_goodState")
})
})
+75 -33
View File
@@ -50,6 +50,9 @@ let modelListRequestCount = 0
let lastRequestBody
let requestBodies = []
let lastRequestHeaders = {}
// When true the mock Provider API answers 403 upgrade_required so the
// transport router falls back to the legacy /alpha/generate transport.
let providerUpgradeRequired = false
const server = createServer((req, res) => {
if (req.method === "GET" && req.url === "/provider/v1/models") {
@@ -81,6 +84,51 @@ const server = createServer((req, res) => {
return
}
if (req.method === "POST" && req.url === "/provider/v1/chat/completions") {
requestCount += 1
lastRequestHeaders = Object.fromEntries(
Object.entries(req.headers).map(([key, value]) => [
key,
Array.isArray(value) ? value.join(", ") : (value ?? ""),
]),
)
let body = ""
req.on("data", (chunk) => {
body += chunk.toString("utf-8")
})
req.on("end", () => {
try {
lastRequestBody = JSON.parse(body)
requestBodies.push(lastRequestBody)
} catch {
lastRequestBody = undefined
}
if (providerUpgradeRequired) {
res.writeHead(403, { "Content-Type": "application/json; charset=utf-8" })
res.end(JSON.stringify({ error: { code: "upgrade_required" } }))
return
}
res.writeHead(200, {
"Content-Type": "text/event-stream; charset=utf-8",
"Transfer-Encoding": "chunked",
})
res.write(
`data: ${JSON.stringify({ id: "mock", object: "chat.completion.chunk", choices: [{ index: 0, delta: { role: "assistant", content: "mock-omp-ok" }, finish_reason: null }] })}\n\n`,
)
res.write(
`data: ${JSON.stringify({ id: "mock", object: "chat.completion.chunk", choices: [{ index: 0, delta: {}, finish_reason: "stop" }] })}\n\n`,
)
res.write(
`data: ${JSON.stringify({ id: "mock", object: "chat.completion.chunk", choices: [], usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 } })}\n\n`,
)
res.end("data: [DONE]\n\n")
})
return
}
if (req.method !== "POST" || req.url !== "/alpha/generate") {
res.writeHead(404)
res.end("Not found")
@@ -95,13 +143,13 @@ const server = createServer((req, res) => {
]),
)
let body = ""
let generateBody = ""
req.on("data", (chunk) => {
body += chunk.toString("utf-8")
generateBody += chunk.toString("utf-8")
})
req.on("end", () => {
try {
lastRequestBody = JSON.parse(body)
lastRequestBody = JSON.parse(generateBody)
requestBodies.push(lastRequestBody)
} catch {
lastRequestBody = undefined
@@ -133,8 +181,8 @@ function runOmp(args, timeoutMs = 30_000) {
HOME: tempHome,
USERPROFILE: tempHome,
PI_CODING_AGENT_DIR: join(tempHome, ".omp", "agent"),
COMMANDCODE_API_KEY: "mock-key",
COMMANDCODE_API_BASE: apiBase,
COMMAND_CODE_API_KEY: "mock-key",
COMMANDCODE_API_BASE: `${apiBase}/provider/v1`,
COMMANDCODE_MODELS_URL: `${apiBase}/provider/v1/models`,
},
stdio: ["ignore", "pipe", "pipe"],
@@ -165,29 +213,25 @@ function runOmp(args, timeoutMs = 30_000) {
try {
console.log("[omp-compat] list models through real extension")
modelListRequestCount = 0
const list = await runOmp(["models", "--json", "-e", EXT_PATH, "--no-extensions"])
if (list.code !== 0 && /unknown|unrecognized/i.test(list.stderr + list.stdout)) {
console.log("[omp-compat] SKIP models phase - omp models subcommand unavailable")
} else {
assert.equal(list.code, 0, list.stderr)
let listed = null
try {
listed = JSON.parse(list.stdout)
} catch {
listed = null
}
const models = Array.isArray(listed?.models) ? listed.models : []
assert.ok(
models.some((model) => model.provider === "commandcode"),
"commandcode provider should be listed",
)
assert.ok(
models.some((model) => model.id === TEST_MODEL),
"mock catalog model should be listed",
)
assert.ok(modelListRequestCount >= 1)
assert.doesNotMatch(list.stdout + list.stderr, /Failed to load extension/)
// Prefer the flag form `omp -e EXT --list-models`; Homebrew's `omp`
// distribution only exposes the `omp models` subcommand, so fall back to
// that form when the flag invocation is not recognized.
let result = await runOmp(["-e", EXT_PATH, "--list-models"])
if (result.code !== 0) {
result = await runOmp(["models", "-e", EXT_PATH])
}
assert.equal(result.code, 0, result.stderr)
const listOutput = result.stdout || result.stderr
assert.match(listOutput, /commandcode/)
assert.match(listOutput, /deepseek\/deepseek-v4-flash/)
// The failed flag attempt may already load the extension and fetch the
// catalog once before the subcommand fallback runs, so only assert that
// the mock catalog was actually consulted.
assert.ok(modelListRequestCount >= 1)
assert.doesNotThrow(() =>
accessSync(join(tempHome, ".omp", "agent", "commandcode-models.json"), constants.R_OK),
)
assert.doesNotMatch(result.stdout + result.stderr, /Failed to load extension/)
console.log("[omp-compat] print mode through real extension and mock API")
requestCount = 0
@@ -204,15 +248,13 @@ try {
"Bearer mock-key",
"should send the resolved env-var value, not the literal var name",
)
assert.equal(lastRequestBody?.params?.model, TEST_MODEL)
assert.equal(typeof lastRequestBody?.params?.system, "string")
assert.doesNotThrow(() =>
accessSync(join(tempHome, ".omp", "agent", "commandcode-models.json"), constants.R_OK),
)
assert.equal(lastRequestBody?.model, TEST_MODEL)
assert.ok(Array.isArray(lastRequestBody?.messages))
console.log("[omp-compat] developer advisory reaches the provider request body")
console.log("[omp-compat] developer advisory reaches the legacy generate request body")
requestCount = 0
requestBodies = []
providerUpgradeRequired = true
const advisoryRun = await runOmp(
[
"-e",
+3 -2
View File
@@ -22,7 +22,7 @@ const { writeFileSync } = require("node:fs")
writeFileSync(process.env.FAKE_PI_LOG, JSON.stringify({
args: process.argv.slice(2),
agentDir: process.env.PI_CODING_AGENT_DIR ?? null,
apiKey: process.env.COMMANDCODE_API_KEY ?? null,
apiKey: process.env.COMMAND_CODE_API_KEY ?? process.env.COMMANDCODE_API_KEY ?? null,
skipVersionCheck: process.env.PI_SKIP_VERSION_CHECK,
}))
NODE
@@ -38,7 +38,8 @@ NODE
PATH: `${fakeBin}${delimiter}${process.env.PATH ?? ""}`,
FAKE_PI_LOG: logPath,
PI_CODING_AGENT_DIR: "/existing/pi-agent",
COMMANDCODE_API_KEY: "existing-key",
COMMAND_CODE_API_KEY: "official-existing-key",
COMMANDCODE_API_KEY: "legacy-existing-key",
},
encoding: "utf8",
})
+4 -2
View File
@@ -26,7 +26,8 @@ appendFileSync(process.env.FAKE_PI_LOG, JSON.stringify({
skipVersionCheck: process.env.PI_SKIP_VERSION_CHECK,
home: process.env.HOME,
userProfile: process.env.USERPROFILE,
inheritedApiKey: process.env.COMMANDCODE_API_KEY ?? null,
inheritedApiKey:
process.env.COMMAND_CODE_API_KEY ?? process.env.COMMANDCODE_API_KEY ?? null,
}) + "\\n")
NODE
if [ "$1" = "install" ]; then exit 0; fi
@@ -42,7 +43,8 @@ exit ${exitStatus}
...process.env,
PATH: `${fakeBin}${delimiter}${process.env.PATH ?? ""}`,
FAKE_PI_LOG: logPath,
COMMANDCODE_API_KEY: "must-not-leak",
COMMAND_CODE_API_KEY: "must-not-leak-official",
COMMANDCODE_API_KEY: "must-not-leak-legacy",
},
encoding: "utf8",
})
+109 -36
View File
@@ -15,7 +15,8 @@ import { fileURLToPath } from "node:url"
const __dirname = dirname(fileURLToPath(import.meta.url))
const PROJECT_DIR = resolve(__dirname, "..")
const EXT_PATH = resolve(PROJECT_DIR, "index.ts")
const TEST_MODEL = "deepseek/deepseek-v4-flash"
const TEST_MODEL = "gpt-5.4"
const CLAUDE_TEST_MODEL = "claude-sonnet-4-6"
function findPiBinary() {
if (process.env.PI_BIN) return process.env.PI_BIN
@@ -63,9 +64,17 @@ function modelCatalog() {
object: "model",
created: 1779824324,
owned_by: "command-code",
name: "DeepSeek V4 Flash",
name: "GPT 5.4",
context_length: 1_000_000,
},
{
id: CLAUDE_TEST_MODEL,
object: "model",
created: 1779824324,
owned_by: "command-code",
name: "Claude Sonnet 4.6",
context_length: 200_000,
},
{
id: "cc-second-model",
object: "model",
@@ -101,7 +110,9 @@ const server = createServer((req, res) => {
return
}
if (req.method !== "POST" || req.url !== "/alpha/generate") {
const isOpenAIRequest = req.method === "POST" && req.url === "/provider/v1/chat/completions"
const isAnthropicRequest = req.method === "POST" && req.url === "/provider/v1/messages"
if (!isOpenAIRequest && !isAnthropicRequest) {
res.writeHead(404)
res.end("Not found")
return
@@ -129,12 +140,20 @@ const server = createServer((req, res) => {
if (overflowMode && overflowRequestCount === 2) {
res.writeHead(400, { "Content-Type": "application/json; charset=utf-8" })
res.end(JSON.stringify({ error: { message: "Input exceeds context limit" } }))
res.end(
JSON.stringify({
error: {
message: "Input exceeds context limit",
type: "invalid_request_error",
code: "context_length_exceeded",
},
}),
)
return
}
res.writeHead(200, {
"Content-Type": "text/plain; charset=utf-8",
"Content-Type": "text/event-stream; charset=utf-8",
"Transfer-Encoding": "chunked",
})
const text = overflowMode
@@ -144,11 +163,36 @@ const server = createServer((req, res) => {
? "compaction-summary"
: "overflow-recovered"
: "mock-pi-ok"
res.write(`${JSON.stringify({ type: "text-delta", text })}\n`)
if (isAnthropicRequest) {
res.write(
`event: message_start\ndata: ${JSON.stringify({ type: "message_start", message: { id: "mock", type: "message", role: "assistant", content: [], model: CLAUDE_TEST_MODEL, stop_reason: null, stop_sequence: null, usage: { input_tokens: 1, output_tokens: 0 } } })}\n\n`,
)
res.write(
`event: content_block_start\ndata: ${JSON.stringify({ type: "content_block_start", index: 0, content_block: { type: "text", text: "" } })}\n\n`,
)
res.write(
`event: content_block_delta\ndata: ${JSON.stringify({ type: "content_block_delta", index: 0, delta: { type: "text_delta", text } })}\n\n`,
)
res.write(
`event: content_block_stop\ndata: ${JSON.stringify({ type: "content_block_stop", index: 0 })}\n\n`,
)
res.write(
`event: message_delta\ndata: ${JSON.stringify({ type: "message_delta", delta: { stop_reason: "end_turn", stop_sequence: null }, usage: { output_tokens: 1 } })}\n\n`,
)
res.end(`event: message_stop\ndata: ${JSON.stringify({ type: "message_stop" })}\n\n`)
return
}
res.write(
`${JSON.stringify({ type: "finish", finishReason: "stop", totalUsage: { inputTokens: 1, outputTokens: 1 } })}\n`,
`data: ${JSON.stringify({ id: "mock", object: "chat.completion.chunk", choices: [{ index: 0, delta: { role: "assistant", content: text }, finish_reason: null }] })}\n\n`,
)
res.end()
res.write(
`data: ${JSON.stringify({ id: "mock", object: "chat.completion.chunk", choices: [{ index: 0, delta: {}, finish_reason: "stop" }] })}\n\n`,
)
res.write(
`data: ${JSON.stringify({ id: "mock", object: "chat.completion.chunk", choices: [], usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 } })}\n\n`,
)
res.end("data: [DONE]\n\n")
})
})
@@ -170,8 +214,9 @@ const env = {
USERPROFILE: tempHome,
PI_CODING_AGENT_DIR: agentDir,
PI_CODING_AGENT_SESSION_DIR: join(tempHome, "sessions"),
COMMANDCODE_API_BASE: apiBase,
COMMANDCODE_API_KEY: "mock-key",
COMMANDCODE_API_BASE: `${apiBase}/provider/v1`,
COMMAND_CODE_API_KEY: "mock-key",
CMD_ZDR: "1",
COMMANDCODE_MODELS_URL: `${apiBase}/provider/v1/models`,
}
@@ -403,7 +448,7 @@ async function runRpcExtensionCommands(timeoutMs = 30_000) {
event.type === "extension_ui_request" &&
event.method === "notify" &&
typeof event.message === "string" &&
event.message.includes("model count: 2"),
event.message.includes("model count: 3"),
)
includeRefreshedModel = true
@@ -414,7 +459,7 @@ async function runRpcExtensionCommands(timeoutMs = 30_000) {
event.type === "extension_ui_request" &&
event.method === "notify" &&
typeof event.message === "string" &&
event.message.includes("3 models from live"),
event.message.includes("4 models from live"),
)
send({ id: "status-after", type: "prompt", message: "/commandcode-status" })
@@ -426,7 +471,7 @@ async function runRpcExtensionCommands(timeoutMs = 30_000) {
event.type === "extension_ui_request" &&
event.method === "notify" &&
typeof event.message === "string" &&
event.message.includes("model count: 3"),
event.message.includes("model count: 4"),
)
return {
@@ -565,7 +610,7 @@ try {
)
assert.equal(recoveryList.code, 0, recoveryList.stderr)
const recoveryOutput = recoveryList.stdout || recoveryList.stderr
assert.match(recoveryOutput, /deepseek\/deepseek-v4-flash/)
assert.match(recoveryOutput, /gpt-5\.4/)
assert.match(recoveryOutput, /cc-second-model/)
assert.doesNotMatch(recoveryList.stderr, /no valid cached catalog/)
assert.doesNotMatch(recoveryList.stderr, /Failed to load extension/)
@@ -578,7 +623,7 @@ try {
assert.equal(list.code, 0, list.stderr)
const listOutput = list.stdout || list.stderr
assert.match(listOutput, /commandcode/)
assert.match(listOutput, /deepseek\/deepseek-v4-flash/)
assert.match(listOutput, /gpt-5\.4/)
assert.match(listOutput, /cc-second-model/)
assert.equal(modelListRequestCount, 1)
assert.doesNotThrow(() => accessSync(modelsCachePath, constants.R_OK))
@@ -591,7 +636,7 @@ try {
)
assert.equal(offlineList.code, 0, offlineList.stderr)
const offlineListOutput = offlineList.stdout || offlineList.stderr
assert.match(offlineListOutput, /deepseek\/deepseek-v4-flash/)
assert.match(offlineListOutput, /gpt-5\.4/)
assert.match(offlineListOutput, /cc-second-model/)
assert.match(offlineList.stderr, /Using the cached catalog/)
@@ -659,27 +704,55 @@ try {
lastRequestHeaders.authorization.startsWith("Bearer "),
"should send a bearer Authorization header",
)
assert.equal(lastRequestBody?.params?.model, TEST_MODEL)
assert.equal(lastRequestBody?.params?.reasoning_effort, "high")
const sentTools = lastRequestBody?.params?.tools
assert.equal(lastRequestHeaders["x-cmd-zdr"], "1")
assert.equal(lastRequestBody?.model, TEST_MODEL)
assert.equal(lastRequestBody?.reasoning_effort, "high")
const sentTools = lastRequestBody?.tools
assert.ok(Array.isArray(sentTools) && sentTools.length > 0)
const editTool = sentTools.find((tool) => tool.name === "edit")
assert.equal(editTool?.input_schema?.type, "object")
assert.equal(editTool?.input_schema?.properties?.edits?.type, "array")
assert.equal(editTool?.input_schema?.properties?.edits?.items?.type, "object")
const editTool = sentTools.find((tool) => tool.function?.name === "edit")
assert.equal(editTool?.function?.parameters?.type, "object")
assert.equal(editTool?.function?.parameters?.properties?.edits?.type, "array")
assert.equal(editTool?.function?.parameters?.properties?.edits?.items?.type, "object")
assert.equal(
editTool?.input_schema?.properties?.edits?.items?.properties?.oldText?.type,
editTool?.function?.parameters?.properties?.edits?.items?.properties?.oldText?.type,
"string",
)
console.log("[pi-local] Claude request through Anthropic Messages endpoint")
requestCount = 0
const claudePrint = await runPi(
[
"--no-extensions",
"-e",
EXT_PATH,
"-p",
"say mock token",
"--provider",
"commandcode",
"--model",
CLAUDE_TEST_MODEL,
"--thinking",
"high",
],
30_000,
)
assert.equal(claudePrint.code, 0, claudePrint.stderr)
assert.match(claudePrint.stdout, /mock-pi-ok/)
assert.equal(requestCount, 1)
assert.equal(lastRequestBody?.model, CLAUDE_TEST_MODEL)
assert.equal(lastRequestBody?.thinking?.type, "adaptive")
assert.deepEqual(lastRequestBody?.output_config, { effort: "high" })
assert.equal(lastRequestHeaders["x-api-key"], "mock-key")
assert.equal(lastRequestHeaders["x-cmd-zdr"], "1")
console.log("[pi-local] runtime commands through real RPC extension lifecycle")
includeRefreshedModel = false
const runtimeCommands = await runRpcExtensionCommands()
assert.ok(runtimeCommands.commandNames.includes("commandcode-refresh"))
assert.ok(runtimeCommands.commandNames.includes("commandcode-status"))
assert.match(runtimeCommands.statusBefore, /source: live/)
assert.match(runtimeCommands.refreshNotification, /3 models from live/)
assert.match(runtimeCommands.statusAfter, /model count: 3/)
assert.match(runtimeCommands.refreshNotification, /4 models from live/)
assert.match(runtimeCommands.statusAfter, /model count: 4/)
assert.doesNotMatch(
`${runtimeCommands.statusBefore}\n${runtimeCommands.statusAfter}\n${runtimeCommands.stderr}`,
/mock-key/,
@@ -702,7 +775,7 @@ try {
assert.equal(rpc.sawTextDelta, true)
assert.equal(requestCount, 1)
console.log("[pi-local] reject image input through real RPC preflight/provider path")
console.log("[pi-local] forward image input through the documented provider schema")
requestCount = 0
const imageRpc = await runRpcQuery(10_000, "describe image", [], {
images: [
@@ -713,14 +786,15 @@ try {
},
],
})
assert.equal(requestCount, 0)
assert.equal(imageRpc.ok, true, imageRpc.stderr)
assert.equal(requestCount, 1)
const imageContent = lastRequestBody?.messages?.find(
(message) => message.role === "user",
)?.content
assert.ok(Array.isArray(imageContent), JSON.stringify(lastRequestBody?.messages))
assert.ok(
imageRpc.events.some(
(event) =>
event.type === "message_end" &&
event.message?.role === "assistant" &&
event.message?.stopReason === "error",
) || imageRpc.stderr.includes("does not support image"),
imageContent.some((part) => part.type === "image_url"),
JSON.stringify(imageContent),
)
console.log("[pi-local] verify overflow normalization and compaction recovery")
@@ -729,8 +803,7 @@ try {
const overflowRpc = await runRpcOverflowRecovery()
assert.equal(overflowRpc.ok, true)
assert.ok(overflowRpc.requests >= 4)
assert.equal(overflowRpc.sawNormalizedOverflow, true)
assert.equal(overflowRpc.sawCompactionRetry, true)
assert.equal(overflowRpc.sawCompactionRetry, true, JSON.stringify(overflowRpc))
assert.equal(overflowRpc.stderrHasSecrets, false)
overflowMode = false
+49 -10
View File
@@ -27,7 +27,7 @@ const fixtureUrl = new URL("./fixtures/commandcode-model-ids.json", import.meta.
const fixture = JSON.parse(await readFile(fixtureUrl, "utf-8")) as ModelCatalogSnapshot
const pricingFixtureUrl = new URL("./fixtures/commandcode-pricing.json", import.meta.url)
const pricingFixture = JSON.parse(await readFile(pricingFixtureUrl, "utf-8")) as PricingSnapshot
const freeModels = new Set(["poolside/laguna-s-2.1-free", "inclusionai/ling-3.0-flash-free"])
const freeModels = new Set(["poolside/laguna-s-2.1-free", "stealth/ox-alpha"])
function assertCost(
modelId: string,
@@ -50,7 +50,7 @@ function assertCost(
describe("MODEL_COSTS pricing overlay", () => {
it("covers the current Command Code model catalog snapshot", () => {
assert.equal(fixture.source, "https://api.commandcode.ai/provider/v1/models")
assert.match(fixture.fetchedAt, /^2026-08-04T/)
assert.match(fixture.fetchedAt, /^2026-08-25T/)
const catalogIds = [...fixture.modelIds].sort()
const pricedIds = Object.keys(MODEL_COSTS).sort()
@@ -108,10 +108,16 @@ describe("MODEL_COSTS pricing overlay", () => {
})
it("matches corrected official rates", () => {
assertCost("deepseek/deepseek-v4-pro", {
input: 0.66,
output: 1.98,
cacheRead: 0.022,
cacheWrite: 0,
})
assertCost("deepseek/deepseek-v4-flash", {
input: 0.14,
output: 0.28,
cacheRead: 0.0028,
input: 0.22,
output: 0.66,
cacheRead: 0.007,
cacheWrite: 0,
})
assertCost("Qwen/Qwen3.7-Max", {
@@ -132,6 +138,24 @@ describe("MODEL_COSTS pricing overlay", () => {
cacheRead: 0.03,
cacheWrite: 0,
})
assertCost("Qwen/Qwen3.8-27B", {
input: 0.4,
output: 3,
cacheRead: 0.04,
cacheWrite: 0,
})
assertCost("google/gemini-3.7-flash", {
input: 0.75,
output: 3.75,
cacheRead: 0.075,
cacheWrite: 0.04167,
})
assertCost("meta/muse-spark-1.2-contributor", {
input: 0.1,
output: 0.2,
cacheRead: 0.002,
cacheWrite: 0,
})
})
it("uses the documented base rates for context-dependent models", () => {
@@ -148,16 +172,31 @@ describe("MODEL_COSTS pricing overlay", () => {
cacheWrite: 0.038,
})
assertCost("gpt-5.6-terra", {
input: 1,
output: 6,
cacheRead: 0.1,
cacheWrite: 1.25,
input: 2,
output: 12,
cacheRead: 0.2,
cacheWrite: 2.5,
})
assertCost("gpt-5.6-luna", {
input: 0.2,
output: 1.2,
cacheRead: 0.02,
cacheWrite: 0.25,
})
assert.deepEqual(MODEL_COSTS["xai/grok-4.6"]?.tiers, [
{
inputTokensAbove: 200_000,
input: 4,
output: 12,
cacheRead: 1,
cacheWrite: 0,
},
])
})
it("tracks pricing provenance", () => {
assert.equal(PRICING_SOURCE_URL, "https://commandcode.ai/docs/resources/pricing-limits")
assert.equal(PRICING_LAST_VERIFIED, "2026-08-04")
assert.equal(PRICING_LAST_VERIFIED, "2026-08-25")
})
it("fails once temporary pricing needs review", () => {
+131 -16
View File
@@ -16,6 +16,7 @@ import {
mapFinishReason,
messagesToCC,
parseStreamEventLine,
pickCommandCodeApiKey,
projectSlugFromPath,
textContent,
toJsonSchema,
@@ -26,8 +27,18 @@ import { redactCommandCodeErrorText } from "../src/overflow.ts"
import { objectAt } from "./helpers.ts"
describe("getApiKey()", () => {
it("uses COMMANDCODE_API_KEY from provided env", () => {
assert.equal(getApiKey({ env: { COMMANDCODE_API_KEY: "env-key" }, authPaths: [] }), "env-key")
it("uses the official API key env var before the legacy alias", () => {
assert.equal(
getApiKey({
env: { COMMAND_CODE_API_KEY: "official-key", COMMANDCODE_API_KEY: "legacy-key" },
authPaths: [],
}),
"official-key",
)
assert.equal(
getApiKey({ env: { COMMANDCODE_API_KEY: "legacy-key" }, authPaths: [] }),
"legacy-key",
)
})
it("reads apiKey, commandcode, pi OAuth, and official CLI credential fields", () => {
@@ -106,6 +117,39 @@ describe("error redaction", () => {
})
})
describe("pickCommandCodeApiKey()", () => {
it("falls back to the host key for a placeholder registry value", () => {
assert.equal(pickCommandCodeApiKey("$COMMAND_CODE_API_KEY", "file-key"), "file-key")
assert.equal(pickCommandCodeApiKey("COMMAND_CODE_API_KEY", "file-key"), "file-key")
assert.equal(pickCommandCodeApiKey("$COMMANDCODE_API_KEY", "file-key"), "file-key")
assert.equal(pickCommandCodeApiKey("COMMANDCODE_API_KEY", "file-key"), "file-key")
})
it("returns undefined when only a placeholder is provided (no fallback)", () => {
assert.equal(pickCommandCodeApiKey("$COMMAND_CODE_API_KEY", undefined), undefined)
assert.equal(pickCommandCodeApiKey("$COMMANDCODE_API_KEY", undefined), undefined)
})
it("prefers a real registry key over the host fallback", () => {
assert.equal(pickCommandCodeApiKey("real-registry-key", "file-key"), "real-registry-key")
})
it("falls back to the host key when the registry has none", () => {
assert.equal(pickCommandCodeApiKey(undefined, "file-key"), "file-key")
assert.equal(pickCommandCodeApiKey(undefined, undefined), undefined)
})
it("falls back to the host key for empty or whitespace registry values", () => {
assert.equal(pickCommandCodeApiKey("", "file-key"), "file-key")
assert.equal(pickCommandCodeApiKey(" ", "file-key"), "file-key")
assert.equal(pickCommandCodeApiKey(" ", undefined), undefined)
})
it("trims a real registry key", () => {
assert.equal(pickCommandCodeApiKey(" real-registry-key ", "file-key"), "real-registry-key")
})
})
describe("projectSlugFromPath()", () => {
it("matches the official CLI-style slug from an absolute working directory", () => {
assert.equal(
@@ -117,7 +161,7 @@ describe("projectSlugFromPath()", () => {
})
describe("text-only image handling", () => {
it("rejects image content for models without image support", () => {
it("rejects direct image input for models without image support", () => {
assert.throws(
() =>
assertTextOnlyMessages([
@@ -128,16 +172,17 @@ describe("text-only image handling", () => {
]),
/does not support image content/i,
)
assert.throws(
() =>
assertTextOnlyMessages([
{
role: "toolResult",
toolCallId: "c1",
content: [{ type: "image", data: "base64-data", mimeType: "image/png" }],
},
]),
/does not support image content/i,
})
it("allows historical tool-result images to be omitted for text-only models", () => {
assert.doesNotThrow(() =>
assertTextOnlyMessages([
{
role: "toolResult",
toolCallId: "c1",
content: [{ type: "image", data: "base64-data", mimeType: "image/png" }],
},
]),
)
})
})
@@ -168,6 +213,12 @@ describe("textContent()", () => {
)
})
it("normalizes malformed string and object content", () => {
assert.equal(textContent({ content: "raw result" }), "raw result")
assert.equal(textContent({ content: { ok: true } }), '{"ok":true}')
assert.equal(textContent({ content: null }), "")
})
it("handles empty or missing content", () => {
assert.equal(textContent({ content: [] }), "")
assert.equal(textContent({}), "")
@@ -359,7 +410,7 @@ describe("toJsonSchema()", () => {
if (!outputProperties || typeof outputProperties !== "object") {
throw new Error("expected object properties")
}
assert.ok(Object.prototype.hasOwnProperty.call(outputProperties, "__proto__"))
assert.ok(Object.hasOwn(outputProperties, "__proto__"))
assert.deepEqual(Object.getOwnPropertyDescriptor(outputProperties, "__proto__")?.value, {
type: "string",
})
@@ -500,6 +551,23 @@ describe("messagesToCC()", () => {
assert.equal(objectAt(result, ["2", "content", "0", "output", "value"]), "hello\nworld")
})
it("preserves malformed string tool results instead of sending empty output", () => {
const result = messagesToCC([
{
role: "assistant",
content: [{ type: "toolCall", id: "c1", name: "read", arguments: {} }],
},
{
role: "toolResult",
toolCallId: "c1",
toolName: "read",
content: "raw result",
},
])
assert.equal(objectAt(result, ["1", "content", "0", "output", "value"]), "raw result")
})
it("serializes image inputs in the current Command Code wire format", () => {
assert.deepEqual(
messagesToCC(
@@ -530,6 +598,48 @@ describe("messagesToCC()", () => {
)
})
it("omits tool-result images for text-only models while preserving their text", () => {
const result = messagesToCC([
{ role: "user", content: "read image" },
{
role: "assistant",
content: [{ type: "toolCall", id: "c1", name: "read", arguments: {} }],
},
{
role: "toolResult",
toolCallId: "c1",
toolName: "read",
content: [
{ type: "text", text: "image attached" },
{ type: "image", data: "aGVsbG8=", mimeType: "image/jpeg" },
],
},
])
assert.equal(objectAt(result, ["2", "content", "0", "output", "value"]), "image attached")
assert.equal(objectAt(result, ["3"]), undefined)
})
it("describes an omitted image-only tool result for text-only models", () => {
const result = messagesToCC([
{
role: "assistant",
content: [{ type: "toolCall", id: "c1", name: "read", arguments: {} }],
},
{
role: "toolResult",
toolCallId: "c1",
toolName: "read",
content: [{ type: "image", data: "aGVsbG8=", mimeType: "image/jpeg" }],
},
])
assert.equal(
objectAt(result, ["1", "content", "0", "output", "value"]),
"[Image omitted: model does not support images]",
)
})
it("preserves tool-result images as a following user image message", () => {
const result = messagesToCC(
[
@@ -601,7 +711,7 @@ describe("messagesToCC()", () => {
])
})
it("drops orphaned tool calls that have no matching tool result", () => {
it("synthesizes missing results for orphaned tool calls", () => {
const result = messagesToCC([
{ role: "user", content: "edit a file" },
{
@@ -620,7 +730,12 @@ describe("messagesToCC()", () => {
assert.equal(objectAt(result, ["1", "role"]), "assistant")
assert.equal(objectAt(result, ["1", "content", "0", "type"]), "text")
assert.equal(objectAt(result, ["1", "content", "1"]), undefined)
assert.equal(objectAt(result, ["1", "content", "1", "type"]), "tool-call")
assert.equal(objectAt(result, ["2", "role"]), "tool")
assert.match(
String(objectAt(result, ["2", "content", "0", "output", "value"])),
/did not complete/,
)
})
it("handles empty conversations", () => {
+117
View File
@@ -0,0 +1,117 @@
import assert from "node:assert/strict"
import { describe, it } from "node:test"
import { registerCommandCodeQuota, type QuotaCommandContext } from "../src/quota-command.ts"
import type { CommandCodeQuotaResult } from "../src/quota-types.ts"
class CommandApiDouble {
handler?: (args: string, ctx: QuotaCommandContext) => Promise<void>
registerCommand(
name: string,
options: {
description: string
handler: (args: string, ctx: QuotaCommandContext) => Promise<void>
},
): void {
assert.equal(name, "commandcode-quota")
assert.match(options.description, /usage and quota/)
this.handler = options.handler
}
}
function context(registryKey: string | undefined) {
const notifications: Array<{ message: string; type?: "info" | "warning" | "error" }> = []
let waited = false
const value = {
async waitForIdle() {
waited = true
},
modelRegistry: {
async getApiKeyForProvider(provider: string) {
assert.equal(provider, "commandcode")
return registryKey
},
},
ui: {
notify(message: string, type?: "info" | "warning" | "error") {
notifications.push({ message, type })
},
},
} satisfies QuotaCommandContext
return { value, notifications, waited: () => waited }
}
const quotaResult: CommandCodeQuotaResult = {
ok: true,
quota: {
account: { login: "alice", orgId: null },
credits: null,
subscription: null,
summary: { totalCost: 1, totalCount: 2 },
},
}
describe("commandcode-quota command", () => {
it("registers the command and resolves OMP placeholders through the fallback key", async () => {
const pi = new CommandApiDouble()
let requestKey = ""
let requestBase = ""
registerCommandCodeQuota(pi, {
apiBase: "https://api.commandcode.ai",
getConfiguredKey: () => "fallback-key",
fetchQuota: async (options) => {
requestKey = options.apiKey
requestBase = options.baseUrl ?? ""
return quotaResult
},
})
assert.ok(pi.handler)
const ctx = context("$COMMAND_CODE_API_KEY")
await pi.handler("", ctx.value)
assert.equal(ctx.waited(), true)
assert.equal(requestKey, "fallback-key")
assert.equal(requestBase, "https://api.commandcode.ai")
assert.equal(ctx.notifications.at(-1)?.type, "info")
assert.match(ctx.notifications.at(-1)?.message ?? "", /Requests: 2/)
})
it("warns without calling the endpoint when no API key is available", async () => {
const pi = new CommandApiDouble()
let called = false
registerCommandCodeQuota(pi, {
apiBase: "https://api.commandcode.ai",
getConfiguredKey: () => undefined,
fetchQuota: async () => {
called = true
return quotaResult
},
})
assert.ok(pi.handler)
const ctx = context(undefined)
await pi.handler("", ctx.value)
assert.equal(called, false)
assert.equal(ctx.notifications.at(-1)?.type, "warning")
assert.match(ctx.notifications.at(-1)?.message ?? "", /requires an API key/)
})
it("redacts endpoint failures before notifying the host", async () => {
const pi = new CommandApiDouble()
registerCommandCodeQuota(pi, {
apiBase: "https://api.commandcode.ai",
getConfiguredKey: () => "real-key",
fetchQuota: async () => ({
ok: false,
error: { kind: "http", message: "api_key=supersecretvalue123456 failed" },
}),
})
assert.ok(pi.handler)
const ctx = context("real-key")
await pi.handler("", ctx.value)
assert.equal(ctx.notifications.at(-1)?.type, "error")
assert.doesNotMatch(ctx.notifications.at(-1)?.message ?? "", /supersecret/)
})
})
+417
View File
@@ -0,0 +1,417 @@
/**
* Unit tests for the Command Code quota layer (src/quota.ts).
*
* These are hermetic: no pi runtime and no network. Fetching is exercised with
* a mocked `fetchImpl`, while parsing and formatting are pure function checks.
*/
import assert from "node:assert/strict"
import { describe, it } from "node:test"
import { formatQuota, formatWindowLimits } from "../src/quota-format.ts"
import {
DEFAULT_API_BASE,
fetchCommandCodeQuota,
redactValue,
windowLimitsFromCredits,
} from "../src/quota.ts"
import type {
CommandCodeCredits,
CommandCodeQuota,
CommandCodeWindowLimit,
} from "../src/quota-types.ts"
function jsonResponse(body: unknown, status = 200): Response {
return new Response(JSON.stringify(body), {
status,
headers: { "content-type": "application/json" },
})
}
function okFetch(handlers: Record<string, unknown>) {
const urls: string[] = []
const fetchImpl = async (input: RequestInfo | URL): Promise<Response> => {
const url = String(input)
urls.push(url)
for (const [needle, body] of Object.entries(handlers)) {
if (url.includes(needle)) return jsonResponse(body)
}
throw new Error(`Unexpected URL: ${url}`)
}
return { fetchImpl, urls: () => urls }
}
describe("Command Code quota", () => {
it("parses window limits from the credits windowLimits object", () => {
const limits = windowLimitsFromCredits({
limited: true,
// resetAt as reported by the live API: milliseconds since epoch.
fiveHour: { used: 8, cap: 14, resetAt: 1_700_000_000_000 },
weekly: { used: 30, cap: 35, resetAt: 1_700_000_000_000 },
})
assert.deepEqual(limits, [
{ window: "fiveHour", used: 8, cap: 14, resetAt: 1_700_000_000 },
{ window: "weekly", used: 30, cap: 35, resetAt: 1_700_000_000 },
])
})
it("skips empty window limit entries", () => {
const limits = windowLimitsFromCredits({
limited: false,
fiveHour: { used: 0, cap: 0, resetAt: null },
weekly: { used: 0, cap: 0, resetAt: null },
})
assert.deepEqual(limits, [])
})
it("parses resetAt as numeric string or ISO timestamp string", () => {
const limits = windowLimitsFromCredits({
fiveHour: { used: 1, cap: 2, resetAt: "1700000000000" },
weekly: { used: 1, cap: 2, resetAt: "2023-11-14T22:13:20.000Z" },
})
// numeric ms string -> epoch seconds; ISO string -> epoch seconds
assert.equal(limits[0]?.resetAt, 1_700_000_000)
assert.equal(limits[1]?.resetAt, 1_700_000_000)
})
it("renders valid zero usage without claiming an unknown billing period", () => {
const quota: CommandCodeQuota = {
account: { login: "alice", orgId: null },
credits: null,
subscription: null,
summary: { totalCost: 0, totalCount: 0 },
}
const output = formatQuota(quota, () => 1_700_000_000_000)
assert.match(output, /Usage\n/)
assert.doesNotMatch(output, /billing period/)
assert.match(output, /Requests: 0/)
})
it("formats window limits with percentage and reset clock", () => {
const limits: CommandCodeWindowLimit[] = [
{ window: "fiveHour", used: 7, cap: 14, resetAt: 1_700_000_000 },
{ window: "weekly", used: 0, cap: 35, resetAt: null },
]
const lines = formatWindowLimits(limits)
assert.match(lines[0] ?? "", /^5-hour: 7\.00 \/ 14\.00 credits \(50% used\) \(resets/)
assert.match(lines[1] ?? "", /^Weekly: 0\.00 \/ 35\.00 credits \(0% used\)/)
})
it("uses the injected clock for the reset countdown", () => {
const limit: CommandCodeWindowLimit = {
window: "fiveHour",
used: 7,
cap: 14,
resetAt: 1_700_000_000, // seconds since epoch
}
// now() shortly before reset -> a short "in Nm" countdown
const soon = formatWindowLimits([limit], () => 1_699_999_000 * 1000)[0]
assert.match(soon ?? "", /\(resets in \d+m\)/)
// already past reset -> "soon"
const past = formatWindowLimits([limit], () => 1_700_100_000 * 1000)[0]
assert.match(past ?? "", /\(resets soon\)/)
})
it("fetches and normalizes the full quota snapshot", async () => {
const { fetchImpl, urls } = okFetch({
whoami: { user: { userName: "alice" }, org: { id: "org_1", login: "alice-inc" } },
credits: {
credits: {
monthlyCredits: 40,
purchasedCredits: 10,
freeCredits: 5,
planId: "pro",
},
windowLimits: {
fiveHour: { used: 8, cap: 16, resetAt: 1_700_000_000_000 },
weekly: { used: 20, cap: 40, resetAt: null },
},
},
subscriptions: {
data: {
planId: "pro",
status: "active",
currentPeriodStart: "2026-01-01T00:00:00Z",
currentPeriodEnd: "2026-02-01T00:00:00Z",
},
},
summary: { totalCost: 12.34, totalCount: 1500 },
})
const result = await fetchCommandCodeQuota({ apiKey: "cc_test_key", fetchImpl })
assert.equal(result.ok, true)
if (!result.ok) return
assert.equal(result.quota.account.login, "alice-inc")
assert.equal(result.quota.account.orgId, "org_1")
assert.deepEqual(result.quota.credits?.remainingCredits, 55)
assert.equal(result.quota.credits?.windowLimits.length, 2)
assert.equal(result.quota.subscription?.planId, "pro")
assert.equal(result.quota.summary?.totalCost, 12.34)
// Regression: requested URLs must carry the base exactly once (no
// double prefix), and all hit the alpha usage endpoints.
const fetched = urls()
assert.equal(fetched.length, 4)
for (const url of fetched) {
assert.ok(
/^https:\/\/api\.commandcode\.ai\/alpha\//.test(url),
`expected base-prefixed alpha URL, got: ${url}`,
)
assert.equal((url.match(/https:\/\//g) ?? []).length, 1)
assert.equal(url.includes(`${DEFAULT_API_BASE}${DEFAULT_API_BASE}`), false)
}
})
it("rejects unrecognized successful endpoint schemas instead of displaying zero usage", async () => {
const fetchImpl = async (input: RequestInfo | URL): Promise<Response> => {
const url = String(input)
if (url.includes("whoami")) return jsonResponse({ user: { userName: "alice" }, org: null })
return jsonResponse({ changed: "schema" })
}
const result = await fetchCommandCodeQuota({ apiKey: "cc_test_key", fetchImpl })
assert.equal(result.ok, false)
if (result.ok) return
assert.equal(result.error.kind, "http")
assert.match(result.error.message, /no recognized usage data/i)
})
it("degrades gracefully when individual billing endpoints fail", async () => {
const fetchImpl = async (input: RequestInfo | URL): Promise<Response> => {
const url = String(input)
if (url.includes("whoami")) return jsonResponse({ user: { userName: "alice" }, org: null })
if (url.includes("summary")) return jsonResponse({ totalCost: 3.0, totalCount: 10 })
if (url.includes("credits") || url.includes("subscriptions")) {
return jsonResponse({ error: "boom" }, 500)
}
throw new Error(`Unexpected URL: ${url}`)
}
const result = await fetchCommandCodeQuota({ apiKey: "cc_test_key", fetchImpl })
assert.equal(result.ok, true)
if (!result.ok) return
assert.equal(result.quota.credits, null)
assert.equal(result.quota.summary?.totalCost, 3.0)
assert.deepEqual(result.quota.unavailable, ["credits", "subscription"])
assert.match(formatQuota(result.quota), /Unavailable: credits, subscription/)
// Optional aggregate tokens are parsed when the summary reports them.
assert.equal(result.quota.summary?.totalTokens, undefined)
})
it("degrades on thrown network failures from optional endpoints, not just HTTP 5xx", async () => {
const fetchImpl = async (input: RequestInfo | URL): Promise<Response> => {
const url = String(input)
if (url.includes("whoami")) return jsonResponse({ user: { userName: "alice" }, org: null })
if (url.includes("summary")) return jsonResponse({ totalCost: 3.0, totalCount: 10 })
if (url.includes("credits")) throw new Error("network down")
if (url.includes("subscriptions")) return jsonResponse({ data: { planId: "pro" } })
throw new Error(`Unexpected URL: ${url}`)
}
const result = await fetchCommandCodeQuota({ apiKey: "cc_test_key", fetchImpl })
assert.equal(result.ok, true)
if (!result.ok) return
assert.equal(result.quota.credits, null)
assert.equal(result.quota.subscription?.planId, "pro")
assert.equal(result.quota.summary?.totalCost, 3.0)
assert.deepEqual(result.quota.unavailable, ["credits"])
})
it("fails the command when the summary endpoint rejects auth/permission", async () => {
const fetchImpl = async (input: RequestInfo | URL): Promise<Response> => {
const url = String(input)
if (url.includes("whoami")) return jsonResponse({ user: { userName: "alice" }, org: null })
if (url.includes("credits")) return jsonResponse({ credits: { monthlyCredits: 5 } })
if (url.includes("subscriptions")) return jsonResponse({ data: { planId: "pro" } })
if (url.includes("summary")) return jsonResponse({ error: "nope" }, 403)
throw new Error(`Unexpected URL: ${url}`)
}
const result = await fetchCommandCodeQuota({ apiKey: "cc_test_key", fetchImpl })
assert.equal(result.ok, false)
if (result.ok) return
assert.equal(result.error.kind, "http")
assert.match(result.error.message, /summary/)
})
it("does not treat 429 on billing endpoints as fatal", async () => {
const fetchImpl = async (input: RequestInfo | URL): Promise<Response> => {
const url = String(input)
if (url.includes("whoami")) return jsonResponse({ user: { userName: "alice" }, org: null })
if (url.includes("summary")) return jsonResponse({ totalCost: 3.0, totalCount: 10 })
if (url.includes("credits") || url.includes("subscriptions")) {
return jsonResponse({ error: "rate limited" }, 429)
}
throw new Error(`Unexpected URL: ${url}`)
}
const result = await fetchCommandCodeQuota({ apiKey: "cc_test_key", fetchImpl })
assert.equal(result.ok, true)
if (!result.ok) return
assert.equal(result.quota.credits, null)
assert.equal(result.quota.summary?.totalCost, 3.0)
})
it("sends extra headers (ZDR) on quota requests", async () => {
let sent: Headers | undefined
const fetchImpl = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {
sent = (init?.headers as Headers) ?? undefined
const url = String(input)
if (url.includes("whoami")) return jsonResponse({ user: { userName: "alice" }, org: null })
if (url.includes("credits")) return jsonResponse({ credits: { monthlyCredits: 5 } })
if (url.includes("subscriptions")) return jsonResponse({ data: { planId: "pro" } })
if (url.includes("summary")) return jsonResponse({ totalCost: 1, totalCount: 1 })
throw new Error(`Unexpected URL: ${url}`)
}
const result = await fetchCommandCodeQuota({
apiKey: "cc_test_key",
fetchImpl,
extraHeaders: { "x-cmd-zdr": "1" },
})
assert.equal(result.ok, true)
const headers = new Headers(sent)
assert.equal(headers.get("x-cmd-zdr"), "1")
})
it("parses optional token count and key name when present", async () => {
const { fetchImpl } = okFetch({
whoami: { user: { userName: "alice", keyName: "Pi Agent" }, org: null },
credits: { credits: { monthlyCredits: 5, purchasedCredits: 0, freeCredits: 0 } },
subscriptions: { data: { planId: "pro", status: "active" } },
summary: { totalCost: 1.06, totalCount: 654, totalTokens: 74_200_000 },
})
const result = await fetchCommandCodeQuota({ apiKey: "cc_test_key", fetchImpl })
assert.equal(result.ok, true)
if (!result.ok) return
assert.equal(result.quota.summary?.totalTokens, 74_200_000)
assert.equal(result.quota.account.keyName, "Pi Agent")
})
it("rejects missing API keys as a config error", async () => {
const result = await fetchCommandCodeQuota({ apiKey: "" })
assert.equal(result.ok, false)
if (result.ok) return
assert.equal(result.error.kind, "config")
})
it("fails with a config-style error when the API key is rejected", async () => {
const fetchImpl = async (input: RequestInfo | URL): Promise<Response> => {
if (String(input).includes("whoami")) return jsonResponse({ error: "unauthorized" }, 401)
throw new Error(`Unexpected URL: ${input}`)
}
const result = await fetchCommandCodeQuota({ apiKey: "cc_bad_key", fetchImpl })
assert.equal(result.ok, false)
if (result.ok) return
assert.equal(result.error.kind, "http")
assert.match(result.error.message, /401/)
})
it("formats a complete quota snapshot into readable output", () => {
const quota: CommandCodeQuota = {
account: { login: "alice-inc", orgId: "org_1" },
credits: {
monthlyCredits: 40,
purchasedCredits: 10,
freeCredits: 5,
remainingCredits: 55,
windowLimits: [
{ window: "fiveHour", used: 8, cap: 16, resetAt: null },
{ window: "weekly", used: 20, cap: 40, resetAt: null },
],
} satisfies CommandCodeCredits,
subscription: {
planId: "pro",
status: "active",
currentPeriodStart: "2026-01-01T00:00:00Z",
currentPeriodEnd: "2026-02-01T00:00:00Z",
},
summary: { totalCost: 12.34, totalCount: 1500 },
}
const output = formatQuota(quota, () => 1_700_000_000_000)
assert.doesNotMatch(output, /Command Code quota —/)
assert.match(output, /Credits/)
assert.match(output, /Remaining: \$55\.00 of \$67\.34/)
assert.match(output, /Used: \$12\.34/)
assert.match(output, /Sources: monthly \$40\.00 \/ purchased \$10\.00 \/ free \$5\.00/)
assert.match(output, /Plan: pro \(active\)/)
assert.match(output, /Usage \(billing period\)/)
assert.match(output, /Cost: \$12\.34/)
assert.match(output, /Requests: 1,500/)
assert.match(output, /Account/)
assert.match(output, /alice-inc/)
assert.match(output, /5-hour: 8\.00 \/ 16\.00 credits/)
assert.match(output, /Weekly: 20\.00 \/ 40\.00 credits/)
assert.match(output, /https:\/\/commandcode\.ai\/usage/)
})
it("redacts token-like values from error messages", () => {
// 16+ char run after a credential key is redacted by the shared redactor.
assert.equal(redactValue("api_key=abcdefghijklmnop123456"), "api_key=[redacted]")
assert.equal(redactValue("Bearer user_12345678901234 failed"), "Bearer [redacted] failed")
})
it("redacts named credential fields and short tokens from error bodies", () => {
// Credential key-value forms (with = or : separator) are redacted.
assert.equal(redactValue("api_key=abc123"), "api_key=[redacted]")
assert.equal(
redactValue("authorization=Basic abc:def failed"),
"authorization=[redacted] abc:def failed",
)
assert.equal(redactValue("user_123456789 failed"), "[redacted] failed")
assert.equal(redactValue("cc_abcdefghijkl failed"), "[redacted] failed")
assert.equal(
redactValue("token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.secret"),
"token=[redacted]",
)
})
it("redacts JSON-quoted credential fields in error bodies", () => {
assert.equal(
redactValue('{"apiKey":"sk-abcdefghijklmnop123456","ok":true}'),
'{"apiKey":"[redacted]","ok":true}',
)
assert.equal(
redactValue('{"error":"bad","access_token":"opaque-internal-token-12345"}'),
'{"error":"bad","access_token":"[redacted]"}',
)
assert.equal(
redactValue('{"authorization":"Bearer user_1234"}'),
'{"authorization":"[redacted]"}',
)
})
it("redacts thrown network errors from the outer catch path", async () => {
const fetchImpl = async (_input: RequestInfo | URL): Promise<Response> => {
throw new Error("connection reset by proxy api_key=supersecretvalue123456")
}
const result = await fetchCommandCodeQuota({ apiKey: "cc_test_key", fetchImpl })
assert.equal(result.ok, false)
if (result.ok) return
assert.doesNotMatch(result.error.message, /supersecretvalue123456/)
assert.match(result.error.kind, /network/)
})
it("honors the overall deadline once it has already fired (no phase starts after abort)", async () => {
const start = Date.now()
const fetchImpl = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {
const url = String(input)
if (url.includes("whoami")) {
// Never resolve; let the per-request controller abort it at timeoutMs.
return new Promise<Response>((_resolve, reject) => {
init?.signal?.addEventListener("abort", () =>
reject(Object.assign(new Error("aborted"), { name: "AbortError" })),
)
})
}
throw new Error(`Unexpected URL: ${url}`)
}
const result = await fetchCommandCodeQuota({ apiKey: "cc_test_key", fetchImpl, timeoutMs: 30 })
const elapsed = Date.now() - start
assert.equal(result.ok, false)
if (result.ok) return
assert.equal(result.error.kind, "timeout")
// The overall deadline governs the whole command; no phase may add ~30ms on top.
assert.ok(elapsed < 200, `elapsed ${elapsed}ms exceeded overall deadline`)
})
})
+4
View File
@@ -49,6 +49,7 @@ class CommandContext implements CommandCodeCommandContext {
const FIRST_MODEL: CommandCodeModel = {
id: "first-model",
name: "First Model",
api: "openai-completions",
reasoning: true,
contextWindow: 128_000,
maxTokens: 16_384,
@@ -57,6 +58,7 @@ const FIRST_MODEL: CommandCodeModel = {
const SECOND_MODEL: CommandCodeModel = {
id: "second-model",
name: "Second Model",
api: "openai-completions",
reasoning: true,
contextWindow: 256_000,
maxTokens: 32_768,
@@ -96,6 +98,7 @@ describe("Command Code runtime", () => {
cachePath: "/tmp/commandcode-models.json",
loadModels: () => firstLoad.promise,
createProviderConfig: (models) => ({ models }),
getTransport: () => "provider",
now: () => now,
logWarning: () => {},
})
@@ -113,6 +116,7 @@ describe("Command Code runtime", () => {
assert.ok(statusCommand)
await statusCommand("", context)
const statusMessage = context.notifications.at(-1)?.message ?? ""
assert.match(statusMessage, /transport: provider/)
assert.match(statusMessage, /source: live/)
assert.match(statusMessage, /model count: 1/)
assert.match(statusMessage, /last success:/)
+2 -1
View File
@@ -7,7 +7,7 @@
* 3. Can complete a simple prompt (requires Command Code auth)
*
* Run with: node tests/test-smoke.mjs
* Requires: pi on PATH plus COMMANDCODE_API_KEY or live pi auth files.
* Requires: pi on PATH plus COMMAND_CODE_API_KEY (or legacy COMMANDCODE_API_KEY) or live pi auth files.
*/
import { spawn } from "node:child_process"
@@ -48,6 +48,7 @@ const RPC_QUERY_TIMEOUT = 60_000
function hasCommandCodeAuth() {
return (
!!process.env.COMMAND_CODE_API_KEY ||
!!process.env.COMMANDCODE_API_KEY ||
existsSync(join(homedir(), ".commandcode", "auth.json")) ||
existsSync(join(homedir(), ".pi", "agent", "auth.json"))
+314 -3
View File
@@ -6,6 +6,7 @@
import assert from "node:assert/strict"
import { after, before, beforeEach, describe, it } from "node:test"
import { COMMAND_CODE_CLI_VERSION } from "../src/commandcode-catalog.ts"
import type { AssistantMessageEvent } from "../src/core.ts"
import { MODEL_EFFORTS, thinkingLevelMapForEfforts } from "../src/models.ts"
import {
@@ -76,6 +77,23 @@ describe("streamCommandCode — auth", () => {
)
})
it("accepts the official CLI API key environment variable", async () => {
server.mockResponse({
type: "success",
events: [JSON.stringify({ type: "finish", finishReason: "stop" })],
})
const { streamCommandCode } = createTestDeps({
apiBase: server.baseUrl(),
env: { COMMAND_CODE_API_KEY: "official-env-key" },
})
await collectEvents(
streamCommandCode(makeModel(), makeContext(), { apiKey: "$COMMAND_CODE_API_KEY" }),
)
assert.equal(server.lastRequestHeaders().authorization, "Bearer official-env-key")
})
it("uses options.apiKey in the Authorization header", async () => {
server.mockResponse({
type: "success",
@@ -173,6 +191,101 @@ describe("streamCommandCode — successful streams", () => {
)
})
it("forwards a tool-result image as a following user image for vision-capable models", async () => {
server.mockResponse({
type: "success",
events: [JSON.stringify({ type: "finish", finishReason: "stop" })],
})
const { streamCommandCode } = createTestDeps({ apiBase: server.baseUrl() })
const events = await collectEvents(
streamCommandCode(
makeModel({ id: "deepseek/deepseek-v4-flash-vision-exp" }),
makeContext({
messages: [
{ role: "user", content: "read the image" },
{
role: "assistant",
content: [{ type: "toolCall", id: "c1", name: "read", arguments: {} }],
},
{
role: "toolResult",
toolCallId: "c1",
toolName: "read",
content: [
{ type: "text", text: "image attached" },
{ type: "image", data: "aGVsbG8=", mimeType: "image/png" },
],
},
],
}),
{ apiKey: "mock-key" },
),
)
// No error: the tool-result image must not be rejected for this model.
assert.equal(events.at(-1)?.type, "done")
const body = server.lastRequestBody()
// The tool-result text is forwarded on the tool message at index 2.
assert.equal(
objectAt(body, ["params", "messages", "2", "content", "0", "output", "value"]),
"image attached",
)
// The tool-result image is forwarded as a following user image message at index 3.
assert.equal(objectAt(body, ["params", "messages", "3", "role"]), "user")
assert.equal(
objectAt(body, ["params", "messages", "3", "content", "0", "image"]),
"data:image/png;base64,aGVsbG8=",
)
})
it("omits a historical tool-result image after switching to a text-only model", async () => {
server.mockResponse({
type: "success",
events: [JSON.stringify({ type: "finish", finishReason: "stop" })],
})
const { streamCommandCode } = createTestDeps({ apiBase: server.baseUrl() })
const events = await collectEvents(
streamCommandCode(
makeModel({ id: "deepseek/deepseek-v4-flash" }),
makeContext({
messages: [
{ role: "user", content: "read the image" },
{
role: "assistant",
content: [{ type: "toolCall", id: "c1", name: "read", arguments: {} }],
},
{
role: "toolResult",
toolCallId: "c1",
toolName: "read",
content: [
{ type: "text", text: "image attached" },
{ type: "image", data: "aGVsbG8=", mimeType: "image/png" },
],
},
{ role: "user", content: "continue without the image" },
],
}),
{ apiKey: "mock-key" },
),
)
assert.equal(events.at(-1)?.type, "done")
assert.equal(server.requestCount(), 1)
const body = server.lastRequestBody()
assert.equal(
objectAt(body, ["params", "messages", "2", "content", "0", "output", "value"]),
"image attached",
)
assert.equal(
objectAt(body, ["params", "messages", "3", "content"]),
"continue without the image",
)
})
it("rejects images before network access for text-only models", async () => {
const { streamCommandCode } = createTestDeps({ apiBase: server.baseUrl() })
@@ -326,6 +439,104 @@ describe("streamCommandCode — successful streams", () => {
assert.equal(toolCall?.type === "toolCall" ? toolCall.name : "", "read_file")
})
it("streams incremental tool-call arguments from generate events", async () => {
server.mockResponse({
type: "success",
events: [
JSON.stringify({
type: "tool-input-start",
id: "call_1",
toolName: "read_file",
}),
JSON.stringify({ type: "tool-input-delta", id: "call_1", delta: '{"path":"' }),
JSON.stringify({ type: "tool-input-delta", id: "call_1", delta: '/tmp/x"}' }),
JSON.stringify({ type: "tool-input-end", id: "call_1" }),
JSON.stringify({
type: "tool-call",
toolCallId: "call_1",
toolName: "read_file",
input: { path: "/tmp/x" },
}),
JSON.stringify({ type: "finish", finishReason: "tool-calls" }),
],
})
const { streamCommandCode } = createTestDeps({ apiBase: server.baseUrl() })
const events = await collectEvents(
streamCommandCode(makeModel(), makeContext(), { apiKey: "mock-key" }),
)
assert.deepEqual(eventTypes(events), [
"start",
"toolcall_start",
"toolcall_delta",
"toolcall_delta",
"toolcall_end",
"done",
])
const deltas = events.flatMap((event) => (event.type === "toolcall_delta" ? [event.delta] : []))
assert.deepEqual(deltas, ['{"path":"', '/tmp/x"}'])
const done = events.at(-1)
if (done?.type !== "done") throw new Error("expected done")
assert.equal(done.reason, "toolUse")
const toolCall = done.message.content[0]
assert.equal(toolCall?.type, "toolCall")
if (toolCall?.type !== "toolCall") throw new Error("expected tool call")
assert.equal(toolCall.id, "call_1")
assert.equal(toolCall.name, "read_file")
assert.deepEqual(toolCall.arguments, { path: "/tmp/x" })
})
it("keeps concurrent incremental tool calls separate", async () => {
server.mockResponse({
type: "success",
events: [
JSON.stringify({ type: "tool-input-start", id: "call_1", toolName: "read_file" }),
JSON.stringify({ type: "tool-input-start", id: "call_2", toolName: "read_file" }),
JSON.stringify({ type: "tool-input-delta", id: "call_1", delta: '{"path":"/a"}' }),
JSON.stringify({ type: "tool-input-delta", id: "call_2", delta: '{"path":"/b"}' }),
JSON.stringify({
type: "tool-call",
toolCallId: "call_2",
toolName: "read_file",
input: { path: "/b" },
}),
JSON.stringify({
type: "tool-call",
toolCallId: "call_1",
toolName: "read_file",
input: { path: "/a" },
}),
JSON.stringify({ type: "finish", finishReason: "tool-calls" }),
],
})
const { streamCommandCode } = createTestDeps({ apiBase: server.baseUrl() })
const events = await collectEvents(
streamCommandCode(makeModel(), makeContext(), { apiKey: "mock-key" }),
)
const starts = events.flatMap((event) =>
event.type === "toolcall_start" ? [event.contentIndex] : [],
)
const deltas = events.flatMap((event) =>
event.type === "toolcall_delta" ? [[event.contentIndex, event.delta] as const] : [],
)
const ends = events.flatMap((event) =>
event.type === "toolcall_end" ? [[event.contentIndex, event.toolCall.id] as const] : [],
)
assert.deepEqual(starts, [0, 1])
assert.deepEqual(deltas, [
[0, '{"path":"/a"}'],
[1, '{"path":"/b"}'],
])
assert.deepEqual(ends, [
[1, "call_2"],
[0, "call_1"],
])
})
it("flushes reasoning if finish arrives without reasoning-end", async () => {
server.mockResponse({
type: "success",
@@ -473,7 +684,7 @@ describe("streamCommandCode — request serialization", () => {
assert.equal(objectAt(body, ["params", "stream"]), true)
assert.equal(objectAt(body, ["params", "max_tokens"]), 500)
assert.equal(objectAt(body, ["params", "reasoning_effort"]), undefined)
assert.equal(objectAt(body, ["params", "temperature"]), 0.3)
assert.equal(objectAt(body, ["params", "temperature"]), undefined)
assert.equal(objectAt(body, ["params", "system"]), "You are a test assistant.")
assert.equal(objectAt(body, ["memory"]), null)
assert.equal(objectAt(body, ["taste"]), null)
@@ -488,10 +699,11 @@ describe("streamCommandCode — request serialization", () => {
const headers = server.lastRequestHeaders()
assert.equal(headers.authorization, "Bearer mock-key")
assert.equal(headers["x-command-code-version"], "1.15.1")
assert.equal(headers["x-command-code-version"], COMMAND_CODE_CLI_VERSION)
assert.equal(headers["x-project-slug"], "repo")
assert.equal(headers["x-taste-learning"], "true")
assert.equal(headers["x-co-flag"], "false")
assert.equal(headers["user-agent"], "cli")
assert.equal(headers["x-co-flag"], undefined)
assert.equal(headers["x-session-id"], undefined)
})
@@ -545,6 +757,48 @@ describe("streamCommandCode — request serialization", () => {
assert.doesNotMatch(String(objectAt(body, ["params", "system"])), /advisory/)
})
it("forwards explicit temperature and stable session metadata", async () => {
server.mockResponse({
type: "success",
events: [JSON.stringify({ type: "finish", finishReason: "stop" })],
})
const { streamCommandCode } = createTestDeps({ apiBase: server.baseUrl() })
await collectEvents(
streamCommandCode(makeModel(), makeContext(), {
apiKey: "mock-key",
temperature: 0.7,
sessionId: "11111111-1111-4111-8111-111111111111",
}),
)
const body = server.lastRequestBody()
assert.equal(objectAt(body, ["params", "temperature"]), 0.7)
assert.equal(objectAt(body, ["threadId"]), "11111111-1111-4111-8111-111111111111")
assert.equal(
server.lastRequestHeaders()["x-session-id"],
"11111111-1111-4111-8111-111111111111",
)
})
it("omits non-UUID session ids from the generate thread id", async () => {
server.mockResponse({
type: "success",
events: [JSON.stringify({ type: "finish", finishReason: "stop" })],
})
const { streamCommandCode } = createTestDeps({ apiBase: server.baseUrl() })
await collectEvents(
streamCommandCode(makeModel(), makeContext(), {
apiKey: "mock-key",
sessionId: "human-readable-session",
}),
)
assert.equal(objectAt(server.lastRequestBody(), ["threadId"]), undefined)
assert.equal(server.lastRequestHeaders()["x-session-id"], "human-readable-session")
})
it("accepts the legacy OMP nested reasoning map", async () => {
server.mockResponse({
type: "success",
@@ -787,6 +1041,63 @@ describe("streamCommandCode — upstream errors and malformed streams", () => {
assert.equal(error.error.errorMessage, "provider failed")
})
it("rejects a truncated stream without a finish event", async () => {
server.mockResponse({
type: "success",
events: [JSON.stringify({ type: "text-delta", text: "truncated" })],
})
const { streamCommandCode } = createTestDeps({ apiBase: server.baseUrl() })
const events = await collectEvents(
streamCommandCode(makeModel(), makeContext(), { apiKey: "mock-key" }),
)
const error = events.at(-1)
assert.equal(error?.type, "error")
if (error?.type !== "error") throw new Error("expected error")
assert.match(error.error.errorMessage ?? "", /no finish event/i)
})
it("maps an upstream abort event to an aborted request", async () => {
server.mockResponse({
type: "success",
events: [JSON.stringify({ type: "abort" })],
})
const { streamCommandCode } = createTestDeps({ apiBase: server.baseUrl() })
const events = await collectEvents(
streamCommandCode(makeModel(), makeContext(), { apiKey: "mock-key" }),
)
const error = events.at(-1)
assert.equal(error?.type, "error")
if (error?.type !== "error") throw new Error("expected error")
assert.equal(error.reason, "aborted")
})
it("rejects terminal upstream network failure reasons", async () => {
server.mockResponse({
type: "success",
events: [
JSON.stringify({
type: "finish",
finishReason: "stop",
rawFinishReason: "upstream_error",
}),
],
})
const { streamCommandCode } = createTestDeps({ apiBase: server.baseUrl() })
const events = await collectEvents(
streamCommandCode(makeModel(), makeContext(), { apiKey: "mock-key" }),
)
const error = events.at(-1)
assert.equal(error?.type, "error")
if (error?.type !== "error") throw new Error("expected error")
assert.match(error.error.errorMessage ?? "", /upstream connection failed/i)
})
it("handles SSE lines, malformed lines, split chunks, and final line without newline", async () => {
const textEvent = `data: ${JSON.stringify({ type: "text-delta", text: "split" })}\n`
const finishEvent = JSON.stringify({
+247
View File
@@ -0,0 +1,247 @@
import assert from "node:assert/strict"
import { describe, it } from "node:test"
import { createCommandCodeTransportRouter } from "../src/transport.ts"
import type {
AssistantMessageEvent,
AssistantMessageEventStreamLike,
StreamOptions,
} from "../src/types.ts"
import { collectEvents, createTestEventStream, makeContext, makeModel } from "./helpers.ts"
function completedStream(text: string): AssistantMessageEventStreamLike {
const stream = createTestEventStream()
const model = makeModel()
const message = {
role: "assistant" as const,
content: [{ type: "text" as const, text }],
api: model.api,
provider: model.provider,
model: model.id,
usage: {
input: 1,
output: 1,
cacheRead: 0,
cacheWrite: 0,
totalTokens: 2,
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
},
stopReason: "stop" as const,
timestamp: Date.now(),
}
const events: AssistantMessageEvent[] = [
{ type: "start", partial: message },
{ type: "text_start", contentIndex: 0, partial: message },
{ type: "text_delta", contentIndex: 0, delta: text, partial: message },
{ type: "text_end", contentIndex: 0, content: text, partial: message },
{ type: "done", reason: "stop", message },
]
for (const event of events) stream.push(event)
stream.end()
return stream
}
function providerStream(
response: Response,
text: string,
options?: StreamOptions,
): AssistantMessageEventStreamLike {
const stream = createTestEventStream()
const run = async () => {
const received = await (options?.fetch ?? fetch)("https://provider.test", {})
await options?.onResponse?.(
{ status: received.status, headers: {} },
makeModel({ api: "openai-completions" }),
)
const source = completedStream(text)
for await (const event of source) stream.push(event)
stream.end()
}
run().catch(() => stream.end())
return stream
}
describe("Command Code transport router", () => {
it("keeps using the Provider API after a successful request", async () => {
let providerCalls = 0
let generateCalls = 0
const router = createCommandCodeTransportRouter({
createStream: createTestEventStream,
streamProvider: (_model, _context, options) => {
providerCalls += 1
return providerStream(new Response("ok", { status: 200 }), "provider", options)
},
streamGenerate: () => {
generateCalls += 1
return completedStream("generate")
},
})
const options: StreamOptions = {
fetch: () => Promise.resolve(new Response("ok", { status: 200 })),
}
const first = await collectEvents(router.stream(makeModel(), makeContext(), options))
const second = await collectEvents(router.stream(makeModel(), makeContext(), options))
assert.equal(first.at(-1)?.type, "done")
assert.equal(second.at(-1)?.type, "done")
assert.equal(router.getTransport(), "provider")
assert.equal(providerCalls, 2)
assert.equal(generateCalls, 0)
})
it("falls back only for 403 upgrade_required and remembers generate", async () => {
let providerCalls = 0
let generateCalls = 0
const responseBody = JSON.stringify({
error: { code: "upgrade_required", type: "permission_error" },
})
const router = createCommandCodeTransportRouter({
createStream: createTestEventStream,
streamProvider: (_model, _context, options) => {
providerCalls += 1
return providerStream(new Response(responseBody, { status: 403 }), "blocked", options)
},
streamGenerate: () => {
generateCalls += 1
return completedStream("generate")
},
})
const options: StreamOptions = {
fetch: () => Promise.resolve(new Response(responseBody, { status: 403 })),
}
const first = await collectEvents(router.stream(makeModel(), makeContext(), options))
const second = await collectEvents(router.stream(makeModel(), makeContext(), options))
assert.equal(first.at(-1)?.type, "done")
assert.equal(second.at(-1)?.type, "done")
assert.equal(router.getTransport(), "generate")
assert.equal(providerCalls, 1)
assert.equal(generateCalls, 2)
})
it("re-detects the transport after the API key changes", async () => {
let providerCalls = 0
let generateCalls = 0
const upgradeBody = JSON.stringify({ error: { code: "upgrade_required" } })
const router = createCommandCodeTransportRouter({
createStream: createTestEventStream,
streamProvider: (_model, _context, options) => {
providerCalls += 1
const response =
options?.apiKey === "go-key"
? new Response(upgradeBody, { status: 403 })
: new Response("ok", { status: 200 })
return providerStream(response, "provider", options)
},
streamGenerate: () => {
generateCalls += 1
return completedStream("generate")
},
})
await collectEvents(
router.stream(makeModel(), makeContext(), {
apiKey: "go-key",
fetch: () => Promise.resolve(new Response(upgradeBody, { status: 403 })),
}),
)
await collectEvents(
router.stream(makeModel(), makeContext(), {
apiKey: "provider-key",
fetch: () => Promise.resolve(new Response("ok", { status: 200 })),
}),
)
assert.equal(router.getTransport(), "provider")
assert.equal(providerCalls, 2)
assert.equal(generateCalls, 1)
})
it("does not let a stale request overwrite the transport for a new API key", async () => {
let releaseGoRequest: (() => void) | undefined
const goRequestGate = new Promise<void>((resolve) => {
releaseGoRequest = resolve
})
let providerCalls = 0
let generateCalls = 0
const upgradeBody = JSON.stringify({ error: { code: "upgrade_required" } })
const router = createCommandCodeTransportRouter({
createStream: createTestEventStream,
streamProvider: (_model, _context, options) => {
providerCalls += 1
const response =
options?.apiKey === "go-key"
? new Response(upgradeBody, { status: 403 })
: new Response("ok", { status: 200 })
const stream = createTestEventStream()
const run = async () => {
if (options?.apiKey === "go-key") await goRequestGate
const received = await (options?.fetch ?? fetch)("https://provider.test", {})
await options?.onResponse?.(
{ status: received.status, headers: {} },
makeModel({ api: "openai-completions" }),
)
if (response.ok) {
for await (const event of completedStream("provider")) stream.push(event)
}
stream.end()
}
run().catch(() => stream.end())
return stream
},
streamGenerate: () => {
generateCalls += 1
return completedStream("generate")
},
})
const staleGoRequest = collectEvents(
router.stream(makeModel(), makeContext(), {
apiKey: "go-key",
fetch: () => Promise.resolve(new Response(upgradeBody, { status: 403 })),
}),
)
await collectEvents(
router.stream(makeModel(), makeContext(), {
apiKey: "provider-key",
fetch: () => Promise.resolve(new Response("ok", { status: 200 })),
}),
)
releaseGoRequest?.()
await staleGoRequest
await collectEvents(
router.stream(makeModel(), makeContext(), {
apiKey: "provider-key",
fetch: () => Promise.resolve(new Response("ok", { status: 200 })),
}),
)
assert.equal(router.getTransport(), "provider")
assert.equal(providerCalls, 3)
assert.equal(generateCalls, 1)
})
it("does not fall back for other 403 errors", async () => {
let generateCalls = 0
const responseBody = JSON.stringify({ error: { code: "permission_denied" } })
const router = createCommandCodeTransportRouter({
createStream: createTestEventStream,
streamProvider: (_model, _context, options) =>
providerStream(new Response(responseBody, { status: 403 }), "blocked", options),
streamGenerate: () => {
generateCalls += 1
return completedStream("generate")
},
})
const options: StreamOptions = {
fetch: () => Promise.resolve(new Response(responseBody, { status: 403 })),
}
await collectEvents(router.stream(makeModel(), makeContext(), options))
assert.equal(router.getTransport(), "provider")
assert.equal(generateCalls, 0)
})
})