glmproxy 2.6.0 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/lib/core.js +35 -3
- package/lib/fallback-models.json +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -158,8 +158,8 @@ AutoClaw handles authentication automatically. When the cloud path fails, reques
|
|
|
158
158
|
|
|
159
159
|
| ID | Name | Context | Max Output | Notes |
|
|
160
160
|
|----|------|---------|------------|-------|
|
|
161
|
-
| `zai_auto` | Auto | 1M |
|
|
162
|
-
| `zaicoding_glm-5.3` | GLM-5.3 | 1M |
|
|
161
|
+
| `zai_auto` | Auto | 1M | 131K | Routes to AutoClaw's optimal model (GLM-5.3-Flash today) |
|
|
162
|
+
| `zaicoding_glm-5.3` | GLM-5.3 | 1M | 131K | Latest GLM coding model |
|
|
163
163
|
| `zai_glm-5-turbo` | GLM-5-Turbo | 200K | 131K | Zhipu AI GLM-5 Turbo |
|
|
164
164
|
| `zai_glm-5.3-flash` | GLM-5.3-Flash ("OX-alpha") | 1M | 131K | Now a regular catalog model, served straight through the cloud path |
|
|
165
165
|
| `tdpsk_deepseek-v4-flash-202605` | Deepseek-V4-Flash | 1M | 393K | Fast DeepSeek model |
|
|
@@ -386,6 +386,7 @@ TRUSTED_PROXIES=127.0.0.1 glmproxy --host 0.0.0.0
|
|
|
386
386
|
- On a 401, the proxy invalidates its cached token and you can retry immediately
|
|
387
387
|
- Upstream 400 `"invalid request"` gets one retry after a 2s delay (a known upstream hiccup). Quota/plan errors are never retried
|
|
388
388
|
- The cloud upstream requires AutoClaw's app system-prompt banner in every request. The proxy injects it automatically and never duplicates it. In practice it doesn't change much since your harness's own system prompt overrides it anyway
|
|
389
|
+
- Max output is clamped to each model's real upstream cap (131K for every GLM model, 393K for DeepSeek). AutoClaw's runtime catalog overstates GLM-5.3's cap (307K), and asking the cloud for more than a model's real cap makes it **silently run a DeepSeek model instead and bill DeepSeek credits** — the proxy clamps so your `zai_glm-5.3` stays GLM-5.3
|
|
389
390
|
- The token file is watched for changes, so AutoClaw can rotate auth mid-session without a restart
|
|
390
391
|
- AutoClaw's client identity (app version, platform, channel) loads dynamically from its runtime file, same as the model catalog, so an AutoClaw app update is picked up without editing or restarting the proxy
|
|
391
392
|
- The fallback model catalog lives in `lib/fallback-models.json` (override with `FALLBACK_MODELS_PATH`). The built-in list is only a last resort when AutoClaw's runtime file is unreadable
|
package/lib/core.js
CHANGED
|
@@ -192,7 +192,9 @@ export function readRuntimeModels(config) {
|
|
|
192
192
|
id: m.id,
|
|
193
193
|
name: m.name || m.id,
|
|
194
194
|
contextWindow: m.contextWindow || 1_048_576,
|
|
195
|
-
|
|
195
|
+
// The runtime file overstates GLM-5.3's output cap (307200 vs the
|
|
196
|
+
// cloud's real 131072); never advertise more than the verified cap.
|
|
197
|
+
maxTokens: Math.min(m.maxTokens || 131_072, OUTPUT_CAPS[m.id] ?? Infinity),
|
|
196
198
|
}));
|
|
197
199
|
|
|
198
200
|
if (models.length > 0) return { models, source: candidate };
|
|
@@ -227,6 +229,32 @@ export function loadModelCatalog(config) {
|
|
|
227
229
|
return { MODELS: loadModelsFromRuntime(config) };
|
|
228
230
|
}
|
|
229
231
|
|
|
232
|
+
// ============================================================================
|
|
233
|
+
// Real upstream output caps (probe-verified 2026-09-02)
|
|
234
|
+
// ============================================================================
|
|
235
|
+
// AutoClaw's runtime catalog OVERSTATES GLM-5.3's max output (307200) — the
|
|
236
|
+
// cloud's real cap for every GLM model is 131072. Sending max_completion_tokens
|
|
237
|
+
// above the cap makes the upstream silently substitute a deepseek model
|
|
238
|
+
// (glm-5.3 → deepseek-v4-pro, flash/turbo/auto → deepseek-v4-flash) and bill
|
|
239
|
+
// deepseek credits. Verified to the exact token: 131072 ok, 131073 flips.
|
|
240
|
+
export const OUTPUT_CAPS = Object.freeze({
|
|
241
|
+
"zaicoding_glm-5.3": 131_072,
|
|
242
|
+
"zai_glm-5.3-flash": 131_072,
|
|
243
|
+
"zai_glm-5-turbo": 131_072,
|
|
244
|
+
"zai_auto": 131_072,
|
|
245
|
+
"tdpsk_deepseek-v4-flash-202605": 393_216,
|
|
246
|
+
"tdpsk_deepseek-v4-pro-202606": 393_216,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// Clamp a requested max output to the model's real upstream cap. Unknown
|
|
250
|
+
// models (not in OUTPUT_CAPS) pass through untouched.
|
|
251
|
+
export function clampMaxOutput(modelId, value) {
|
|
252
|
+
if (!Number.isFinite(value)) return value;
|
|
253
|
+
const cap = OUTPUT_CAPS[modelId];
|
|
254
|
+
if (!cap) return value;
|
|
255
|
+
return Math.min(value, cap);
|
|
256
|
+
}
|
|
257
|
+
|
|
230
258
|
// ============================================================================
|
|
231
259
|
// Logger
|
|
232
260
|
// ============================================================================
|
|
@@ -1177,8 +1205,12 @@ function buildSanitizedBody(openAIBody, upstreamModelId) {
|
|
|
1177
1205
|
};
|
|
1178
1206
|
if (typeof openAIBody.temperature === "number") sanitized.temperature = openAIBody.temperature;
|
|
1179
1207
|
if (typeof openAIBody.top_p === "number") sanitized.top_p = openAIBody.top_p;
|
|
1180
|
-
|
|
1181
|
-
|
|
1208
|
+
// Clamp max output to the model's REAL upstream cap. Exceeding it makes the
|
|
1209
|
+
// cloud silently swap in a deepseek model (probe-verified 2026-09-02) and
|
|
1210
|
+
// bill deepseek credits — the harness sends 393216 for everything, which
|
|
1211
|
+
// every GLM model (real cap 131072) trips.
|
|
1212
|
+
if (typeof openAIBody.max_tokens === "number") sanitized.max_tokens = clampMaxOutput(upstreamModelId, openAIBody.max_tokens);
|
|
1213
|
+
if (typeof openAIBody.max_completion_tokens === "number") sanitized.max_tokens = clampMaxOutput(upstreamModelId, openAIBody.max_completion_tokens);
|
|
1182
1214
|
if (openAIBody.stop !== undefined) sanitized.stop = openAIBody.stop;
|
|
1183
1215
|
if (Array.isArray(openAIBody.tools) && openAIBody.tools.length > 0) sanitized.tools = openAIBody.tools;
|
|
1184
1216
|
if (openAIBody.tool_choice !== undefined) sanitized.tool_choice = openAIBody.tool_choice;
|
package/lib/fallback-models.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"models": [
|
|
3
|
-
{ "id": "zai_auto", "name": "Auto", "contextWindow": 1048576, "maxTokens":
|
|
4
|
-
{ "id": "zaicoding_glm-5.3", "name": "GLM-5.3", "contextWindow": 1048576, "maxTokens":
|
|
3
|
+
{ "id": "zai_auto", "name": "Auto", "contextWindow": 1048576, "maxTokens": 131072 },
|
|
4
|
+
{ "id": "zaicoding_glm-5.3", "name": "GLM-5.3", "contextWindow": 1048576, "maxTokens": 131072 },
|
|
5
5
|
{ "id": "zai_glm-5-turbo", "name": "GLM-5-Turbo", "contextWindow": 204800, "maxTokens": 131072 },
|
|
6
6
|
{ "id": "zai_glm-5.3-flash", "name": "GLM-5.3-Flash", "contextWindow": 1048576, "maxTokens": 131072 },
|
|
7
7
|
{ "id": "tdpsk_deepseek-v4-flash-202605", "name": "Deepseek-V4-Flash", "contextWindow": 1048576, "maxTokens": 393216 },
|