Skip to content

Commit 0a8f4dd

Browse files
committed
feat: align with CommandCode CLI 1.28.1 and instrument stalled turns
Add Qwen 3.8 27B to the static catalog (56 models), bump the CLI version header, and log warn-level diagnostics when a streaming turn dies mid-way or a non-streaming turn ends in an upstream 502, so intermittent disconnects can be attributed from logs alone.
1 parent 73954f8 commit 0a8f4dd

14 files changed

Lines changed: 113 additions & 32 deletions

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ COMMANDCODE_API_BASE=https://api.commandcode.ai
2323
COMMANDCODE_DEFAULT_MODEL=deepseek/deepseek-v4-pro
2424
COMMANDCODE_ALLOWED_MODELS=deepseek/deepseek-v4-pro,deepseek/deepseek-v4-flash
2525
COMMANDCODE_ALLOW_UNKNOWN_MODELS=false
26-
COMMANDCODE_CLI_VERSION=1.25.0
26+
COMMANDCODE_CLI_VERSION=1.28.1
2727
COMMANDCODE_TIMEOUT_MS=600000
2828
COMMANDCODE_RETRY_MAX_ATTEMPTS=5
2929
COMMANDCODE_RETRY_BACKOFF_MS=250

README.ko.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</p>
99

1010
<p align="center">
11-
<a href="package.json"><img src="https://img.shields.io/badge/version-1.25.0.b-b57920?style=flat-square" alt="Version 1.25.0.b"></a>
11+
<a href="package.json"><img src="https://img.shields.io/badge/version-1.28.1.a-b57920?style=flat-square" alt="Version 1.28.1.a"></a>
1212
<a href="src/model-catalog.ts"><img src="https://img.shields.io/badge/models-52-1f6f78?style=flat-square" alt="52 models"></a>
1313
<a href="package.json"><img src="https://img.shields.io/badge/Node.js-20%2B-9f4d2e?style=flat-square" alt="Node.js 20+"></a>
1414
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-28231f?style=flat-square" alt="MIT License"></a>
@@ -20,7 +20,7 @@
2020

2121
<!-- README-I18N:END -->
2222

23-
CommandCode Bridge는 CommandCode 계정을 위한 신뢰 환경용 HTTP 게이트웨이입니다. 표준 OpenAI-compatible 모델·채팅 endpoint를 제공하고 eligible upstream credential 사이에서 요청을 라우팅하며, CommandCode **1.25.0**에 맞춘 정확한 **55-model** catalog를 게시합니다. Bridge 버전은 항상 현재 CommandCode CLI 버전을 따라가며 그 뒤에 문자 접미사를 붙입니다(예: **1.25.0.b**). 접미사는 bridge 전용 release를 뜻합니다.
23+
CommandCode Bridge는 CommandCode 계정을 위한 신뢰 환경용 HTTP 게이트웨이입니다. 표준 OpenAI-compatible 모델·채팅 endpoint를 제공하고 eligible upstream credential 사이에서 요청을 라우팅하며, CommandCode **1.28.1**에 맞춘 정확한 **56-model** catalog를 게시합니다. Bridge 버전은 항상 현재 CommandCode CLI 버전을 따라가며 그 뒤에 문자 접미사를 붙입니다(예: **1.28.1.a**). 접미사는 bridge 전용 release를 뜻합니다.
2424

2525
[기능](#기능) · [설치](#설치) · [사용법](#사용법) · [동작 방식](#동작-방식) · [저장소 구성](#저장소-구성) · [현재 제한](#현재-제한) · [라이선스](#라이선스)
2626

@@ -48,7 +48,7 @@ CommandCode Bridge는 CommandCode 계정을 위한 신뢰 환경용 HTTP 게이
4848

4949
### Linux rootless installer
5050

51-
installer는 Linux user systemd용이며 CommandCode CLI 1.25.0 때문에 Node.js 22+를 요구합니다. 가능한 경우 CLI auth를 가져오고 private state는 `~/.config/commandcode-bridge`, 설치본은 `~/.local/share/commandcode-bridge`에 두며 안전한 기본값은 `127.0.0.1:9992`입니다. `0.0.0.0``BRIDGE_API_KEY`를 켠 신뢰 LAN/VPN/tailnet/firewall/reverse proxy 뒤에서만 사용하십시오. 로그인 전 시작에는 `sudo loginctl enable-linger "$USER"`, 제거에는 `./uninstall.sh` 또는 `./uninstall.sh --purge-config`를 사용합니다.
51+
installer는 Linux user systemd용이며 CommandCode CLI 1.28.1 때문에 Node.js 22+를 요구합니다. 가능한 경우 CLI auth를 가져오고 private state는 `~/.config/commandcode-bridge`, 설치본은 `~/.local/share/commandcode-bridge`에 두며 안전한 기본값은 `127.0.0.1:9992`입니다. `0.0.0.0``BRIDGE_API_KEY`를 켠 신뢰 LAN/VPN/tailnet/firewall/reverse proxy 뒤에서만 사용하십시오. 로그인 전 시작에는 `sudo loginctl enable-linger "$USER"`, 제거에는 `./uninstall.sh` 또는 `./uninstall.sh --purge-config`를 사용합니다.
5252

5353
```bash
5454
./install.sh

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</p>
99

1010
<p align="center">
11-
<a href="package.json"><img src="https://img.shields.io/badge/version-1.25.0.b-b57920?style=flat-square" alt="Version 1.25.0.b"></a>
11+
<a href="package.json"><img src="https://img.shields.io/badge/version-1.28.1.a-b57920?style=flat-square" alt="Version 1.28.1.a"></a>
1212
<a href="src/model-catalog.ts"><img src="https://img.shields.io/badge/models-52-1f6f78?style=flat-square" alt="52 models"></a>
1313
<a href="package.json"><img src="https://img.shields.io/badge/Node.js-20%2B-9f4d2e?style=flat-square" alt="Node.js 20+"></a>
1414
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-28231f?style=flat-square" alt="MIT License"></a>
@@ -20,7 +20,7 @@
2020

2121
<!-- README-I18N:END -->
2222

23-
CommandCode Bridge is a trusted-environment HTTP gateway for a CommandCode account. It presents standard OpenAI-compatible model and chat endpoints, routes work across eligible upstream credentials, and publishes an exact **55-model** catalog aligned with CommandCode **1.25.0**. The bridge version always tracks the current CommandCode CLI version with a letter suffix (for example **1.25.0.b**); the suffix marks bridge-only releases.
23+
CommandCode Bridge is a trusted-environment HTTP gateway for a CommandCode account. It presents standard OpenAI-compatible model and chat endpoints, routes work across eligible upstream credentials, and publishes an exact **56-model** catalog aligned with CommandCode **1.28.1**. The bridge version always tracks the current CommandCode CLI version with a letter suffix (for example **1.28.1.a**); the suffix marks bridge-only releases.
2424

2525
[What it does](#what-it-does) · [Install](#install) · [Usage](#usage) · [How it works](#how-it-works) · [Repository layout](#repository-layout) · [Current limitations](#current-limitations) · [License](#license)
2626

@@ -48,7 +48,7 @@ CommandCode Bridge is a trusted-environment HTTP gateway for a CommandCode accou
4848

4949
### Linux rootless installer
5050

51-
The installer targets Linux user systemd, requires Node.js 22+ for CommandCode CLI 1.25.0, imports CLI auth when available, writes private state under `~/.config/commandcode-bridge`, installs under `~/.local/share/commandcode-bridge`, and safely defaults to `127.0.0.1:9992`. Use `0.0.0.0` only behind a trusted LAN/VPN/tailnet/firewall/reverse proxy with `BRIDGE_API_KEY`. Use `sudo loginctl enable-linger "$USER"` for pre-login startup; uninstall with `./uninstall.sh` or `./uninstall.sh --purge-config`.
51+
The installer targets Linux user systemd, requires Node.js 22+ for CommandCode CLI 1.28.1, imports CLI auth when available, writes private state under `~/.config/commandcode-bridge`, installs under `~/.local/share/commandcode-bridge`, and safely defaults to `127.0.0.1:9992`. Use `0.0.0.0` only behind a trusted LAN/VPN/tailnet/firewall/reverse proxy with `BRIDGE_API_KEY`. Use `sudo loginctl enable-linger "$USER"` for pre-login startup; uninstall with `./uninstall.sh` or `./uninstall.sh --purge-config`.
5252

5353
```bash
5454
./install.sh

README.zh.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</p>
99

1010
<p align="center">
11-
<a href="package.json"><img src="https://img.shields.io/badge/version-1.25.0.b-b57920?style=flat-square" alt="Version 1.25.0.b"></a>
11+
<a href="package.json"><img src="https://img.shields.io/badge/version-1.28.1.a-b57920?style=flat-square" alt="Version 1.28.1.a"></a>
1212
<a href="src/model-catalog.ts"><img src="https://img.shields.io/badge/models-52-1f6f78?style=flat-square" alt="52 models"></a>
1313
<a href="package.json"><img src="https://img.shields.io/badge/Node.js-20%2B-9f4d2e?style=flat-square" alt="Node.js 20+"></a>
1414
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-28231f?style=flat-square" alt="MIT License"></a>
@@ -20,7 +20,7 @@
2020

2121
<!-- README-I18N:END -->
2222

23-
CommandCode Bridge 是面向 CommandCode 账号的可信环境 HTTP 网关。它提供标准 OpenAI-compatible 模型与聊天端点,在符合条件的上游凭据之间路由请求,并发布与 CommandCode **1.25.0** 对齐的准确 **55-model** catalog。Bridge 版本始终跟随当前 CommandCode CLI 版本并在其后附加字母后缀(例如 **1.25.0.b**);后缀表示仅限 Bridge 的发布。
23+
CommandCode Bridge 是面向 CommandCode 账号的可信环境 HTTP 网关。它提供标准 OpenAI-compatible 模型与聊天端点,在符合条件的上游凭据之间路由请求,并发布与 CommandCode **1.28.1** 对齐的准确 **56-model** catalog。Bridge 版本始终跟随当前 CommandCode CLI 版本并在其后附加字母后缀(例如 **1.28.1.a**);后缀表示仅限 Bridge 的发布。
2424

2525
[功能](#功能) · [安装](#安装) · [用法](#用法) · [工作原理](#工作原理) · [仓库布局](#仓库布局) · [当前限制](#当前限制) · [许可证](#许可证)
2626

@@ -48,7 +48,7 @@ CommandCode Bridge 是面向 CommandCode 账号的可信环境 HTTP 网关。它
4848

4949
### Linux rootless installer
5050

51-
installer 面向 Linux user systemd;由于 CommandCode CLI 1.25.0,需要 Node.js 22+。它会在可用时导入 CLI auth,把 private state 写入 `~/.config/commandcode-bridge`,安装到 `~/.local/share/commandcode-bridge`,安全默认值为 `127.0.0.1:9992`。只有在启用 `BRIDGE_API_KEY` 的可信 LAN/VPN/tailnet/firewall/reverse proxy 后才使用 `0.0.0.0`。登录前启动使用 `sudo loginctl enable-linger "$USER"`;卸载使用 `./uninstall.sh``./uninstall.sh --purge-config`
51+
installer 面向 Linux user systemd;由于 CommandCode CLI 1.28.1,需要 Node.js 22+。它会在可用时导入 CLI auth,把 private state 写入 `~/.config/commandcode-bridge`,安装到 `~/.local/share/commandcode-bridge`,安全默认值为 `127.0.0.1:9992`。只有在启用 `BRIDGE_API_KEY` 的可信 LAN/VPN/tailnet/firewall/reverse proxy 后才使用 `0.0.0.0`。登录前启动使用 `sudo loginctl enable-linger "$USER"`;卸载使用 `./uninstall.sh``./uninstall.sh --purge-config`
5252

5353
```bash
5454
./install.sh

docs/PROCESS_LOG.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,17 @@
8686
- Released bridge version `1.25.0.b`.
8787
- Added dashboard enable-all / disable-all controls beside the models heading.
8888

89-
## Current status — 2026-08-15
89+
## 2026-08-19
90+
91+
- Released bridge version `1.28.1.a` aligned with CommandCode CLI `1.28.1`.
92+
- Added `Qwen/Qwen3.8-27B` to the static catalog (56 models). GPT-5.6 Sol advertised price stays $5/$30 after the 1.27.1 standard-pricing note.
93+
94+
## Current status — 2026-08-19
9095

9196
- Branch: `main`, synchronized with `origin/main` when this status audit began.
92-
- Package: `commandcode-bridge` `1.25.0.b`, Node.js `>=20`, with `commandcode-bridge` and `commandcode-router` executables.
97+
- Package: `commandcode-bridge` `1.28.1.a`, Node.js `>=20`, with `commandcode-bridge` and `commandcode-router` executables.
9398
- API surface: authenticated OpenAI-compatible `/v1/models` and `/v1/chat/completions`, health endpoint, and same-origin dashboard configuration.
94-
- Model surface: 55 statically aligned models with live Provider API refresh when available.
99+
- Model surface: 56 statically aligned models with live Provider API refresh when available.
95100
- Routing surface: `daily_burn_priority`, `balance_priority`, `round_robin`, and `drain_first`, with per-key model scope, concurrency, cooldown, failover, and retry controls.
96101
- Deployment surface: Docker/Compose, Linux install/uninstall scripts, nginx and systemd release assets, and GitHub/GitLab CI definitions.
97102
- Verification: `npm run typecheck`, `npm run lint`, all 199 Vitest tests in 14 files, and `npm run build` pass on this workstation.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "commandcode-bridge",
3-
"version": "1.25.0.b",
3+
"version": "1.28.1.a",
44
"description": "OpenAI-compatible HTTP bridge for CommandCode's DeepSeek V4 Pro API path.",
55
"type": "module",
66
"license": "MIT",

src/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ export function loadBridgeConfig(options: LoadBridgeConfigOptions = {}): BridgeC
194194
host: serverFromFile.host,
195195
port: serverFromFile.port,
196196
apiBase: (env.COMMANDCODE_API_BASE?.trim() || "https://api.commandcode.ai").replace(/\/+$/, ""),
197-
cliVersion: env.COMMANDCODE_CLI_VERSION?.trim() || "1.25.0",
197+
cliVersion: env.COMMANDCODE_CLI_VERSION?.trim() || "1.28.1",
198198
upstreamMode: parseUpstreamMode(env.COMMANDCODE_UPSTREAM_MODE),
199199
zdr: parseBoolean(env.COMMANDCODE_ZDR, false),
200200
defaultModel,

src/model-catalog.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,16 @@ export const COMMANDCODE_MODEL_DEFINITIONS: CommandCodeModelDefinition[] = [
314314
enabledByDefault: false,
315315
notes: "$2/M in · $6/M out",
316316
},
317+
{
318+
id: "Qwen/Qwen3.8-27B",
319+
label: "Qwen 3.8 27B",
320+
provider: "Qwen",
321+
family: "qwen",
322+
aliases: ["qwen3.8-27b", "Qwen3.8-27B", "alibaba/qwen3.8-27b"],
323+
contextWindow: 262_000,
324+
enabledByDefault: false,
325+
notes: "$0.4/M in · $3/M out",
326+
},
317327
{
318328
id: "Qwen/Qwen3.7-Max",
319329
label: "Qwen 3.7 Max",

src/openai.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ export class CommandCodeEmptyVisibleResponseError extends Error {
6666

6767
export interface StreamOpenAIChunksOptions extends CollectOpenAICompletionOptions {
6868
includeUsage?: boolean;
69+
requestId?: string;
70+
log?: { warn(payload: Record<string, unknown>, message: string): void };
6971
}
7072

7173
export function mapUsageToOpenAI(usage: CommandCodeUsage | undefined): OpenAIUsage {
@@ -499,6 +501,20 @@ export async function* streamOpenAIChunks(
499501
}
500502
}
501503
} catch (error: unknown) {
504+
options.log?.warn(
505+
{
506+
code: "commandcode_stream_error",
507+
model: options.model,
508+
request_id: options.requestId,
509+
stream: true,
510+
visible_content_length: visibleContentLength,
511+
tool_call_count: toolCallCount,
512+
saw_completion_signal: sawCompletionSignal,
513+
finish_reason: finishReason ?? null,
514+
error: error instanceof Error ? error.message : String(error),
515+
},
516+
"upstream stream failed mid-turn",
517+
);
502518
yield sse(streamExceptionPayload(error));
503519
yield "data: [DONE]\n\n";
504520
return;

src/server.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
publicModelList,
1717
publicModelObject,
1818
resolveModel,
19+
type ResolvedModel,
1920
} from "./config.js";
2021
import {
2122
defaultModelCatalog,
@@ -654,13 +655,15 @@ export async function createApp(options: CreateAppOptions = {}): Promise<Fastify
654655
});
655656

656657
app.post("/v1/chat/completions", async (request, reply) => {
658+
let resolvedModel: ResolvedModel | undefined;
657659
try {
658660
const parsed = chatCompletionRequestSchema.parse(request.body);
659661
const openAIRequest = asOpenAIRequest(parsed);
660-
const resolvedModel = resolveModel(openAIRequest.model, config);
662+
resolvedModel = resolveModel(openAIRequest.model, config);
663+
const resolved = resolvedModel;
661664
const useProviderChat =
662665
!eventPipelineAll &&
663-
!isClaudeModelId(resolvedModel.upstreamModel) &&
666+
!isClaudeModelId(resolved.upstreamModel) &&
664667
(config.upstreamMode === "provider" ||
665668
(config.upstreamMode === "auto" && providerAccessAvailable));
666669
const id = `chatcmpl_${randomUUID().replace(/-/g, "")}`;
@@ -704,6 +707,8 @@ export async function createApp(options: CreateAppOptions = {}): Promise<Fastify
704707
includeReasoning: config.includeReasoning,
705708
emptyVisibleResponsePolicy: config.emptyVisibleResponsePolicy,
706709
includeUsage: openAIRequest.stream_options?.include_usage ?? false,
710+
requestId: request.id,
711+
log: request.log,
707712
}),
708713
);
709714
}
@@ -766,18 +771,31 @@ export async function createApp(options: CreateAppOptions = {}): Promise<Fastify
766771
: error instanceof CommandCodeEventError
767772
? error.upstreamBody
768773
: undefined;
774+
const errorCode =
775+
error instanceof CommandCodeHttpError
776+
? "commandcode_http_error"
777+
: error instanceof CommandCodeEventError
778+
? "commandcode_event_error"
779+
: error instanceof CommandCodeEmptyVisibleResponseError
780+
? "commandcode_empty_visible_response"
781+
: "commandcode_empty_response";
782+
if (!(error instanceof CommandCodeEmptyVisibleResponseError)) {
783+
request.log.warn(
784+
{
785+
code: errorCode,
786+
upstream_status: upstreamStatus,
787+
request_id: request.id,
788+
model: resolvedModel?.publicModel,
789+
error: error.message,
790+
},
791+
"non-streaming chat failed with an upstream error",
792+
);
793+
}
769794
return reply.code(502).send({
770795
error: {
771796
message: error.message,
772797
type: "upstream_error",
773-
code:
774-
error instanceof CommandCodeHttpError
775-
? "commandcode_http_error"
776-
: error instanceof CommandCodeEventError
777-
? "commandcode_event_error"
778-
: error instanceof CommandCodeEmptyVisibleResponseError
779-
? "commandcode_empty_visible_response"
780-
: "commandcode_empty_response",
798+
code: errorCode,
781799
upstream_status: upstreamStatus,
782800
upstream_body: upstreamBody,
783801
},

0 commit comments

Comments
 (0)