-
Notifications
You must be signed in to change notification settings - Fork 1
Permalink
Choose a base ref
{{ refName }}
default
Choose a head ref
{{ refName }}
default
Comparing changes
Choose two branches to see what’s changed or to start a new pull request.
If you need to, you can also or
learn more about diff comparisons.
Open a pull request
Create a new pull request by comparing changes across two branches. If you need to, you can also .
Learn more about diff comparisons here.
base repository: thaolaptrinh/commandcode-api-proxy
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.1.4
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
...
head repository: thaolaptrinh/commandcode-api-proxy
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.2.0
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
- 2 commits
- 20 files changed
- 2 contributors
Commits on Jul 20, 2026
-
feat(proxy): expand model catalog, per-model reasoning effort, openco…
…de variants + production hardening (#2) * fix(proxy): tool_choice object form, streaming input_tokens, production hardening Found + verified against the live CC /alpha/generate stream (captured real events + probed the validation schema). The biggest issue — tool_choice — was invisible from code review alone. Functional fixes - tool_choice: was sent as a bare string, which CC rejects with 400 ("expected object, received string at params.tool_choice"). Map both OpenAI and Anthropic tool_choice to CC's object union {type:"auto"|"any"|"tool", name?}. CC has no "required" (use "any") and no "none" (omit). Verified all three shapes return 200 against live CC. - streaming Anthropic input_tokens: CC's `start` event carries no usage, so message_start reported input_tokens=0. Emit input_tokens in message_delta from finish.totalUsage (the Anthropic SDK merges it over message_start). Robustness / ops - Retry retryable upstream failures (5xx/429/timeout/network) up to 2x with backoff, before the stream starts only; client aborts are never retried. (isRetryable was previously computed but unused.) - Request body size limit (10 MiB → 413) to prevent OOM. - Guard all response writes against destroyed/ended sockets (client disconnect mid-request no longer throws). - Top-level unhandledRejection/uncaughtException handlers + bounded graceful shutdown (force-exit after 10s). Config / packaging - Docker: mount ~/.config/commandcode-api-proxy (was ~/.commandcode, so auth.json never loaded); bind host port to 127.0.0.1 only. - CORS_ORIGIN env (default *; empty disables); document the localhost-only security posture. - Drop key-prefix logging (length only). - Remove dead NDJSONParser class (runtime parses via parseCCLine). Tests: 127 pass; added tool_choice (object form) + streaming input_tokens coverage. Co-Authored-By: Claude <noreply@anthropic.com> * feat(models): expand catalog + per-model reasoning effort clipping Researched the model catalog in the command-code CLI (the authoritative source) and the /alpha/generate plan gating by probing each candidate live. Catalog (src/models.json) - Add 12 models reachable on the standard plan (verified 200, not 403): GLM-5.2, GLM-5.2-Fast, MiniMax-M3, Kimi-K2.7-Code (+Highspeed), Kimi-K3, mimo-v2.5-pro, Step-3.7-Flash, grok-4.5, nemotron-3-ultra, inkling, Hy3. - Exclude plan-gated models (gemini-3.5-flash, gemini-3.1-flash-lite, fugu-ultra, muse-spark) — they 403 MODEL_NOT_IN_PLAN on standard. - Add reasoningEfforts map; fix stale contextWindows (Step-3.5-Flash 1M, Kimi K2.5/K2.6 256k); add aliases for all new models. Reasoning effort (the capability gap) - Each CC model accepts a different effort subset (e.g. deepseek-v4-pro is {high,max}; grok-4.5 is {low,medium,high}). CC silently coerces unsupported values, so the proxy previously could send (or drop) the wrong level and could never reach "max"/"xhigh". - models.ts: resolveEffortForModel() clips a request to the nearest valid level for the model; uncatalogued models pass through unchanged. - OpenAI: widen reasoning_effort to low/medium/high/xhigh/max. - Anthropic: extend thinking.budget_tokens mapping through xhigh/max, then clip per model. Verified live: deepseek-v4-pro+low→high, +max→max; grok-4.5+xhigh→high. Tests: 130 pass; added effort-clipping coverage (per-model clip, xhigh/max, grok cap) for both protocols. README aliases + reasoning-effort notes updated. Co-Authored-By: Claude <noreply@anthropic.com> * fix(models): resolve bare model names so OpenCode variant keys work OpenCode's provider config (written by --setup-opencode) keys each model by the bare last path segment with original casing (e.g. "GLM-5.2", "MiniMax-M3", "Kimi-K3") and sends that key as the model id. The proxy's resolveModel only matched lowercase aliases or org-prefixed ids, so mixed-case bare names passed through unchanged and CC rejected them (403 — needs org/model). Only deepseek/grok worked, by lowercase-alias coincidence. resolveModel now: (a) matches aliases case-insensitively, and (b) falls back to the builtin catalog's last path segment. Verified live: GLM-5.2, MiniMax-M3, Kimi-K3, Kimi-K2.7-Code-Highspeed, nemotron-3-ultra-550b-a55b all resolve to canonical ids and return 200. Tests: 131 pass; added bare-name resolution coverage. Co-Authored-By: Claude <noreply@anthropic.com> * feat(opencode): emit reasoning-effort variants so /variants is populated OpenCode's `/variants` picker lists a model's `variants` map. OpenCode only auto-generates reasoning variants from models.dev metadata, which does not cover our custom commandcode model IDs — so the picker was empty. The opencode setup now declares `variants` explicitly for effort-capable models, driven by models.json's reasoningEfforts map: deepseek-v4-pro/flash, GLM-5.2 → {high, max} grok-4.5 → {low, medium, high} Each variant maps to `{ reasoningEffort: <level> }`, which OpenCode forwards to the proxy (and the proxy clips per model — see resolveEffortForModel). Source-of-truth for the mechanism: sst/opencode — provider/provider.ts (config variants are mergeDeep'd in) and provider/transform.ts ({reasoningEffort} variant shape for openai-compatible). Tests: 133 pass; added setup-opencode coverage (variants emitted for effort models, omitted for others). Co-Authored-By: Claude <noreply@anthropic.com> * fix(opencode): disable unsupported effort tiers so /variants matches the model OpenCode auto-adds WIDELY_SUPPORTED_EFFORTS (low/medium/high) to every reasoning-capable openai-compatible model and mergeDeep's them with our config, so deepseek-v4-pro (which CC only supports at {high, max}) showed 4 variants including bogus low/medium (which the proxy would silently clip to high). Declare the full effort universe per model and mark the unsupported tiers `disabled: true`. OpenCode filters disabled variants out of the picker (pickBy !disabled), so each model shows exactly what it supports: deepseek-v4-pro/flash, GLM-5.2 → high, max grok-4.5 → low, medium, high Tests updated to assert the disabled tiers. 133 pass. Co-Authored-By: Claude <noreply@anthropic.com> * fix(models): guard empty effort set in resolveEffortForModel An empty reasoningEfforts array ([] is truthy) bypassed the early return and reached reduce() on an empty array, which throws. No current model triggers it, but adding `reasoningEfforts: []` to models.json would have crashed the request. Added a length guard. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 665a859 - Browse repository at this point
Copy the full SHA 665a859View commit details -
Configuration menu - View commit details
-
Copy full SHA for 748704c - Browse repository at this point
Copy the full SHA 748704cView commit details
Loading
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff v0.1.4...v0.2.0