From 48df80e4a567d3c0b3b2ec719fc26d1528579684 Mon Sep 17 00:00:00 2001 From: Xiangzhe <32761048+xz-dev@users.noreply.github.com> Date: Sat, 11 Jul 2026 05:05:46 +0800 Subject: [PATCH] fix(providers): update SenseNova Token Plan support (#6330) Reconstructed onto release/v3.8.47 to drop unrelated main-drift (deps/electron/proxy files belong to #6620, not this PR); the author's constants/registry/snapshot deltas were re-applied cleanly onto the release tip. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --- .../fixes/6330-sensenova-token-plan.md | 1 + open-sse/config/constants.ts | 1 + .../providers/registry/sensenova/index.ts | 44 ++++++++++++------- tests/snapshots/provider/translate-path.json | 4 +- tests/unit/sensenova-provider.test.ts | 25 +++++++++++ 5 files changed, 58 insertions(+), 17 deletions(-) create mode 100644 changelog.d/fixes/6330-sensenova-token-plan.md create mode 100644 tests/unit/sensenova-provider.test.ts diff --git a/changelog.d/fixes/6330-sensenova-token-plan.md b/changelog.d/fixes/6330-sensenova-token-plan.md new file mode 100644 index 0000000000..3ef26dea2b --- /dev/null +++ b/changelog.d/fixes/6330-sensenova-token-plan.md @@ -0,0 +1 @@ +- **fix(providers):** update SenseNova Token Plan support — register the token-plan model ids/constants and adjust the SenseNova registry so token-plan accounts route correctly (#6330 — thanks @xz-dev). diff --git a/open-sse/config/constants.ts b/open-sse/config/constants.ts index 881ce9fbd2..381dd9fe9b 100644 --- a/open-sse/config/constants.ts +++ b/open-sse/config/constants.ts @@ -108,6 +108,7 @@ export const PROVIDER_MAX_TOKENS: Record = { openai: 16384, // GPT-4/4o standard anthropic: 65536, // Claude models gemini: 65536, // Gemini Studio + sensenova: 65536, // SenseNova Token Plan rejects MaxTokens outside [1, 65536] }; export const DEFAULT_PROVIDER_MAX_TOKENS = 32000; diff --git a/open-sse/config/providers/registry/sensenova/index.ts b/open-sse/config/providers/registry/sensenova/index.ts index 9407e4ef29..37e95acc32 100644 --- a/open-sse/config/providers/registry/sensenova/index.ts +++ b/open-sse/config/providers/registry/sensenova/index.ts @@ -5,23 +5,37 @@ export const sensenovaProvider: RegistryEntry = { alias: "sensenova", format: "openai", executor: "default", - baseUrl: "https://api.sensenova.cn/v1/chat/completions", + baseUrl: "https://token.sensenova.cn/v1/chat/completions", authType: "apikey", authHeader: "bearer", - // Sweep 2026-06-19: refreshed against the official SenseCore compatible-mode catalog. - // V6.5-Pro is the heavyweight flagship; the 6.7 generation so far ships only flash-lite. - // Note the casing split: V6.5 models are PascalCase-dotted, 6.7 is lowercase-dotted. + // SenseNova Token Plan (validated 2026-07-06): the Token Plan endpoint is + // OpenAI-compatible but enforces max_tokens in [1, 65536]. Its /models list + // also currently advertises sensenova-u1-fast, but chat completions return + // 404 "model is not found" for that model; U1 Fast belongs to image flows. models: [ - { id: "SenseNova-V6.5-Pro", name: "SenseNova V6.5 Pro", contextLength: 131072 }, - { id: "SenseNova-V6.5-Turbo", name: "SenseNova V6.5 Turbo", contextLength: 131072 }, - { id: "sensenova-6.7-flash-lite", name: "SenseNova 6.7 Flash-Lite" }, - // DeepSeek V4 Flash is served on SenseNova's free Token Plan (9router#2233). - { id: "deepseek-v4-flash", name: "DeepSeek V4 Flash" }, - { id: "SenseChat-5", name: "SenseChat 5", contextLength: 131072 }, - { id: "SenseChat-5-Cantonese", name: "SenseChat 5 Cantonese", contextLength: 32768 }, - { id: "SenseChat-Turbo", name: "SenseChat Turbo", contextLength: 4096 }, - { id: "SenseChat-Vision", name: "SenseChat Vision", contextLength: 4096 }, - { id: "SenseChat-Character", name: "SenseChat Character", contextLength: 8192 }, - { id: "sensechat", name: "SenseChat" }, + { + id: "sensenova-6.7-flash-lite", + name: "SenseNova 6.7 Flash-Lite", + contextLength: 262144, + maxOutputTokens: 65536, + supportsVision: true, + toolCalling: true, + }, + { + id: "deepseek-v4-flash", + name: "DeepSeek V4 Flash", + contextLength: 1048576, + maxOutputTokens: 65536, + supportsReasoning: true, + interleavedField: "reasoning_content", + }, + { + id: "glm-5.2", + name: "GLM 5.2", + contextLength: 1048576, + maxOutputTokens: 65536, + supportsReasoning: true, + interleavedField: "reasoning_content", + }, ], }; diff --git a/tests/snapshots/provider/translate-path.json b/tests/snapshots/provider/translate-path.json index 46e7afe185..5c5ec76a89 100644 --- a/tests/snapshots/provider/translate-path.json +++ b/tests/snapshots/provider/translate-path.json @@ -3706,8 +3706,8 @@ } }, "url": { - "nonStream": "https://api.sensenova.cn/v1/chat/completions", - "stream": "https://api.sensenova.cn/v1/chat/completions" + "nonStream": "https://token.sensenova.cn/v1/chat/completions", + "stream": "https://token.sensenova.cn/v1/chat/completions" } }, "siliconflow": { diff --git a/tests/unit/sensenova-provider.test.ts b/tests/unit/sensenova-provider.test.ts new file mode 100644 index 0000000000..b376ec7394 --- /dev/null +++ b/tests/unit/sensenova-provider.test.ts @@ -0,0 +1,25 @@ +import test from "node:test"; +import assert from "node:assert/strict"; + +import { PROVIDER_MAX_TOKENS } from "../../open-sse/config/constants.ts"; +import { getModelsByProviderId } from "../../open-sse/config/providerModels.ts"; + +test("SenseNova Token Plan catalog exposes only supported chat models with 64K output", () => { + const models = getModelsByProviderId("sensenova"); + const ids = new Set(models.map((model) => model.id)); + + assert.ok(ids.has("sensenova-6.7-flash-lite")); + assert.ok(ids.has("deepseek-v4-flash")); + assert.ok(ids.has("glm-5.2")); + assert.equal(ids.has("sensenova-u1-fast"), false, "U1 Fast is not a chat-completions model"); + + for (const model of models) { + assert.equal( + model.maxOutputTokens, + 65536, + `${model.id} should use Token Plan's 64K output cap` + ); + } + + assert.equal(PROVIDER_MAX_TOKENS.sensenova, 65536); +});