diff --git a/CHANGELOG.md b/CHANGELOG.md index f8c223e..c062904 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,19 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) - SemVer. ## [Unreleased] +## [1.0.4] - 2026-10-20 + +### Fixed + +- The declared output limit was hardcoded to 16,384 tokens for every model. OpenCode + forwards `limit.output` as `max_completion_tokens`, so every response was capped at + 16k even though the catalog supports far more (the DeepSeek V4.1 Flash 1017 build + declares 393,216). The default is now 32,768, the highest value that is safe across the + whole catalog (the minimum declared output in models.dev's commandcode provider is + exactly 32,768), and `COMMANDCODE_OUTPUT_TOKENS` overrides it per process. +- The static model entries in `opencode.json` carried `output: 16384`, which took + precedence over the plugin. Those limits are now owned by the plugin alone. + ## [1.0.3] - 2026-10-19 ### Added diff --git a/README.es.md b/README.es.md index 526f060..b2fbce1 100644 --- a/README.es.md +++ b/README.es.md @@ -210,6 +210,7 @@ Cada ajuste es una variable de entorno con default seguro. Referencia completa: | `CC_NO_CONNECTION_CLOSE` | `0` | Poner en `1` para dejar de inyectar `Connection: close` | | `COMMANDCODE_STATE_DIR` | `$XDG_STATE_HOME/opencode` | Donde viven los logs y la cache de modelos | | `COMMANDCODE_LIVE_TESTS` | `0` | Poner en `1` para correr la suite de tests con red | +| `COMMANDCODE_OUTPUT_TOKENS` | `32768` | Limite de tokens de salida declarado por modelo (OpenCode lo envia como `max_completion_tokens`). Subilo si un modelo soporta mas | Kill switch en runtime para la higiene de conexion: crea un archivo centinela llamado `.disable-connection-close` dentro del directorio del plugin. diff --git a/README.md b/README.md index 047dbc4..32d462c 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,7 @@ Every setting is an environment variable with a safe default. Full reference: | `CC_NO_CONNECTION_CLOSE` | `0` | Set to `1` to stop injecting `Connection: close` | | `COMMANDCODE_STATE_DIR` | `$XDG_STATE_HOME/opencode` | Where logs and the model cache live | | `COMMANDCODE_LIVE_TESTS` | `0` | Set to `1` to run the network test suite | +| `COMMANDCODE_OUTPUT_TOKENS` | `32768` | Output token limit declared per model (OpenCode sends it as `max_completion_tokens`). Raise it for models that support more | Runtime kill switch for connection hygiene: create a sentinel file named `.disable-connection-close` inside the plugin directory. diff --git a/package.json b/package.json index 14d1b27..c138fef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "opencode-commandcode", - "version": "1.0.3", + "version": "1.0.4", "description": "Production-grade OpenCode plugin for Command Code: dynamic model discovery, stability hooks and quota telemetry", "main": "index.ts", "type": "module", diff --git a/src/index.ts b/src/index.ts index 38f5650..1c7c61f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,6 +18,24 @@ import { describeRetryEvent } from "./telemetry.ts"; import { buildReleaseDate, freeCostEntry } from "./catalog.ts"; export const PROVIDER_ID = "commandcode"; + +/** + * Max completion tokens declared for every Command Code model. + * + * OpenCode forwards `limit.output` as `max_completion_tokens`, so this value caps + * every response. The catalog API only exposes the context window, but every model + * in models.dev's commandcode provider declares an output limit of at least 32,768 + * (the minimum is exactly that, for Qwen3.8-27B and Ling 3.1 Flash), so 32,768 is + * the highest value that is safe across the whole catalog. + * + * Override with COMMANDCODE_OUTPUT_TOKENS when a specific model needs more (the + * DeepSeek V4.1 Flash 1017 build supports 393,216). + */ +function outputLimit(): number { + const raw = Number(process.env.COMMANDCODE_OUTPUT_TOKENS); + if (Number.isFinite(raw) && raw >= 1024) return Math.floor(raw); + return 32768; +} const WATCHDOG_TIMEOUT_MS = 60_000; function logPath(name: string): string { @@ -82,7 +100,7 @@ function applyModelCatalog(editor: any, models: any[]): { registered: number; sk draft.enabled = true; draft.limit = { context: model.context_length || 200000, - output: 16384, + output: outputLimit(), }; draft.capabilities = { tools: true,