@goodandready/dsh-clinebot 0.5.24 → 0.5.25
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/CHANGELOG.md +5 -0
- package/README.md +3 -3
- package/README.ru.md +3 -3
- package/README.zh.md +3 -3
- package/lib/config.js +4 -3
- package/lib/models.js +26 -15
- package/lib/proxy-token.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,11 @@ All notable changes to `@goodandready/dsh-clinebot` will be documented in this f
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.5.25] - 2026-10-16
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **Subscription Plan Model Synchronization & Default Model Migration (Issue #224, GH #14)**: Updated canonical default model identifier and baseline catalog entry to `cline-pass/deepseek-v4.1-flash` (`DeepSeek V4.1 Flash`), matching upstream ClinePass plan changes. Added automatic silent migration for legacy `cline-pass/deepseek-v4-flash` in `OBSOLETE_MODEL_ID_MAP` and `publicConfig` (`defaultModel`, `disabledModels`, `enabledModels`), eliminating false-positive `Configured default model ... is not available in your active plan` warning banners. Updated `parsePlanIncludedModels` to resolve both legacy and modern plan model feature strings with model deduplication.
|
|
12
|
+
|
|
8
13
|
## [0.5.24] - 2026-10-13
|
|
9
14
|
|
|
10
15
|
### Security
|
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
|
|
43
43
|
Integrating ClinePass into DeepSeek Harness (DSH) natively poses key challenges:
|
|
44
44
|
1. **No `/v1/models` Discovery**: `GET /v1/models` on `api.cline.bot` returns `404 Not Found`. Dynamic discovery fails silently or leaves the provider with 0 models.
|
|
45
|
-
2. **Model Identifier Formats**: Models require the specific prefix `cline-pass/` (e.g. `cline-pass/deepseek-v4-flash`, `cline-pass/kimi-k3`).
|
|
45
|
+
2. **Model Identifier Formats**: Models require the specific prefix `cline-pass/` (e.g. `cline-pass/deepseek-v4.1-flash`, `cline-pass/kimi-k3`).
|
|
46
46
|
3. **Quota Tracking**: Rolling 5-hour and weekly limits need clear in-browser visualization.
|
|
47
47
|
4. **Credential Security**: Storing API keys directly in plain settings is insecure.
|
|
48
48
|
|
|
@@ -140,7 +140,7 @@ From any DSH chat session, type `/cline` to inspect quota, warning alerts, and s
|
|
|
140
140
|
### 🤖 ClinePass Status (ClinePass)
|
|
141
141
|
* Latency: ✅ 210 ms
|
|
142
142
|
* Active Key: CLINEBOT_API_KEY (credentials)
|
|
143
|
-
* Default Model: `cline-pass/deepseek-v4-flash`
|
|
143
|
+
* Default Model: `cline-pass/deepseek-v4.1-flash`
|
|
144
144
|
|
|
145
145
|
⏱ 5-Hour Window: [████░░░░░░] 42% (resets: 18:00)
|
|
146
146
|
📅 Weekly Window: [██████░░░░] 60% (resets: Sep 8)
|
|
@@ -186,7 +186,7 @@ dsh-clinebot:
|
|
|
186
186
|
| `enabled` | `boolean` | `true` | Enable or disable the ClineBot provider bridge in DSH |
|
|
187
187
|
| `baseUrl` | `string` | `"https://api.cline.bot/api/v1"` | ClinePass OpenAI-compatible base URL |
|
|
188
188
|
| `apiKeyEnv` | `string` | `"CLINEBOT_API_KEY"` | Environment variable / credentials key name |
|
|
189
|
-
| `defaultModel` | `string` | `"cline-pass/deepseek-v4-flash"` | Default selected model ID for chat and smoke tests |
|
|
189
|
+
| `defaultModel` | `string` | `"cline-pass/deepseek-v4.1-flash"` | Default selected model ID for chat and smoke tests |
|
|
190
190
|
| `disabledModels` | `array` | `[]` | List of model IDs hidden from the DSH chat picker (new subscription models are auto-enabled) |
|
|
191
191
|
| `customModels` | `array` | `[]` | User-defined gateway models (`[{ id, name, contextLength, maxTokens, category, isReasoning }]`) |
|
|
192
192
|
| `modelReasoningDefaults` | `object` | `{}` | Configured default reasoning effort per model (`low`, `medium`, `high`, `max`) |
|
package/README.ru.md
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
|
|
43
43
|
Интеграция ClinePass в DeepSeek Harness (DSH) напрямую сопряжена со следующими сложностями:
|
|
44
44
|
1. **Отсутствие эндпоинта `/v1/models`**: запрос `GET /v1/models` к `api.cline.bot` возвращает `404 Not Found`, из-за чего динамический поиск моделей в DSH падает или оставляет список пустым.
|
|
45
|
-
2. **Специфический формат идентификаторов**: моделям требуется обязательный префикс `cline-pass/` (например, `cline-pass/deepseek-v4-flash`, `cline-pass/kimi-k3`).
|
|
45
|
+
2. **Специфический формат идентификаторов**: моделям требуется обязательный префикс `cline-pass/` (например, `cline-pass/deepseek-v4.1-flash`, `cline-pass/kimi-k3`).
|
|
46
46
|
3. **Отслеживание лимитов**: 5-часовые и недельные скользящие окна расхода токенов требуют прозрачной визуализации в интерфейсе.
|
|
47
47
|
4. **Безопасность ключей**: хранение API-токенов в открытых конфигурациях небезопасно.
|
|
48
48
|
|
|
@@ -137,7 +137,7 @@ dsh plugin --profile web add @goodandready/dsh-clinebot
|
|
|
137
137
|
### 🤖 ClinePass Status (ClinePass)
|
|
138
138
|
* Пинг хоста: ✅ 210 мс
|
|
139
139
|
* Активный ключ: CLINEBOT_API_KEY (credentials)
|
|
140
|
-
* Модель по умолчанию: `cline-pass/deepseek-v4-flash`
|
|
140
|
+
* Модель по умолчанию: `cline-pass/deepseek-v4.1-flash`
|
|
141
141
|
|
|
142
142
|
⏱ 5-часовое окно: [████░░░░░░] 42% (сброс: 18:00)
|
|
143
143
|
📅 Недельное окно: [██████░░░░] 60% (сброс: 08.09)
|
|
@@ -183,7 +183,7 @@ dsh-clinebot:
|
|
|
183
183
|
| `enabled` | `boolean` | `true` | Включение моста провайдера ClineBot в DSH |
|
|
184
184
|
| `baseUrl` | `string` | `"https://api.cline.bot/api/v1"` | Базовый URL OpenAI-совместимого API ClinePass |
|
|
185
185
|
| `apiKeyEnv` | `string` | `"CLINEBOT_API_KEY"` | Имя переменной / ключа в хранилище credentials |
|
|
186
|
-
| `defaultModel` | `string` | `"cline-pass/deepseek-v4-flash"` | Модель, выбираемая по умолчанию для чата и smoke-тестов |
|
|
186
|
+
| `defaultModel` | `string` | `"cline-pass/deepseek-v4.1-flash"` | Модель, выбираемая по умолчанию для чата и smoke-тестов |
|
|
187
187
|
| `disabledModels` | `array` | `[]` | Список отключённых моделей (новые модели подписки включаются автоматически) |
|
|
188
188
|
| `customModels` | `array` | `[]` | Пользовательские модели шлюза (`[{ id, name, contextLength, maxTokens, category, isReasoning }]`) |
|
|
189
189
|
| `modelReasoningDefaults` | `object` | `{}` | Значения thinking effort по умолчанию для моделей (`low`, `medium`, `high`, `max`) |
|
package/README.zh.md
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
|
|
43
43
|
在将 ClinePass 接入 DeepSeek Harness (DSH) 时存在以下挑战:
|
|
44
44
|
1. **缺失 `/v1/models` 接口**:`api.cline.bot` 的 `GET /v1/models` 会直接返回 `404 Not Found`,导致动态模型同步失败或模型列表为空。
|
|
45
|
-
2. **专属模型前缀**:所有模型 ID 均需前缀 `cline-pass/`(如 `cline-pass/deepseek-v4-flash`, `cline-pass/kimi-k3`)。
|
|
45
|
+
2. **专属模型前缀**:所有模型 ID 均需前缀 `cline-pass/`(如 `cline-pass/deepseek-v4.1-flash`, `cline-pass/kimi-k3`)。
|
|
46
46
|
3. **用量额度监控**:5 小时滑动窗口与每周限额需要清晰直观的可视化进度监控。
|
|
47
47
|
4. **安全凭据隔离**:禁止在明文配置中直接填写密钥。
|
|
48
48
|
|
|
@@ -139,7 +139,7 @@ dsh plugin --profile web add @goodandready/dsh-clinebot
|
|
|
139
139
|
### 🤖 ClinePass Status (ClinePass)
|
|
140
140
|
* 响应延迟: ✅ 210 ms
|
|
141
141
|
* 活跃密钥: CLINEBOT_API_KEY (credentials)
|
|
142
|
-
* 默认模型: `cline-pass/deepseek-v4-flash`
|
|
142
|
+
* 默认模型: `cline-pass/deepseek-v4.1-flash`
|
|
143
143
|
|
|
144
144
|
⏱ 5 小时窗口: [████░░░░░░] 42% (重置时间: 18:00)
|
|
145
145
|
📅 每周窗口: [██████░░░░] 60% (重置时间: 09月08日)
|
|
@@ -185,7 +185,7 @@ dsh-clinebot:
|
|
|
185
185
|
| `enabled` | `boolean` | `true` | 是否在 DSH 中启用 ClineBot 桥接插件 |
|
|
186
186
|
| `baseUrl` | `string` | `"https://api.cline.bot/api/v1"` | ClinePass OpenAI 兼容接口地址 |
|
|
187
187
|
| `apiKeyEnv` | `string` | `"CLINEBOT_API_KEY"` | 凭据管理系统中的密钥名称 |
|
|
188
|
-
| `defaultModel` | `string` | `"cline-pass/deepseek-v4-flash"` | 默认选中的模型 ID(用于对话及探活) |
|
|
188
|
+
| `defaultModel` | `string` | `"cline-pass/deepseek-v4.1-flash"` | 默认选中的模型 ID(用于对话及探活) |
|
|
189
189
|
| `disabledModels` | `array` | `[]` | 在选择器中隐藏的模型 ID 列表(新订阅模型默认自动启用) |
|
|
190
190
|
| `customModels` | `array` | `[]` | 用户自定义网关模型 (`[{ id, name, contextLength, maxTokens, category, isReasoning }]`) |
|
|
191
191
|
| `modelReasoningDefaults` | `object` | `{}` | 各模型默认思考强度配置 (`low`, `medium`, `high`, `max`) |
|
package/lib/config.js
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
DEFAULT_MODEL_ID,
|
|
12
12
|
getAllModels,
|
|
13
13
|
getActiveModelIds,
|
|
14
|
+
migrateModelId,
|
|
14
15
|
} from './models.js'
|
|
15
16
|
|
|
16
17
|
// DSH settings.describe only publishes fields marked volatile. Without them the
|
|
@@ -137,9 +138,9 @@ export function publicConfig(cfg) {
|
|
|
137
138
|
const allModels = getAllModels(dynamic, modelContextOverrides, custom)
|
|
138
139
|
const allDefaultIds = allModels.map((m) => m.id)
|
|
139
140
|
|
|
140
|
-
let disabledList = Array.isArray(cfg?.disabledModels) ? cfg.disabledModels : []
|
|
141
|
+
let disabledList = Array.isArray(cfg?.disabledModels) ? cfg.disabledModels.map(migrateModelId) : []
|
|
141
142
|
if (cfg?.disabledModels === undefined && Array.isArray(cfg?.enabledModels) && cfg.enabledModels.length > 0) {
|
|
142
|
-
const enabledSet = new Set(cfg.enabledModels)
|
|
143
|
+
const enabledSet = new Set(cfg.enabledModels.map(migrateModelId))
|
|
143
144
|
disabledList = allDefaultIds.filter((id) => !enabledSet.has(id))
|
|
144
145
|
}
|
|
145
146
|
|
|
@@ -148,7 +149,7 @@ export function publicConfig(cfg) {
|
|
|
148
149
|
activeIds = [allDefaultIds[0]]
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
let defaultModel = cfg?.defaultModel || DEFAULT_MODEL_ID
|
|
152
|
+
let defaultModel = migrateModelId(cfg?.defaultModel || DEFAULT_MODEL_ID)
|
|
152
153
|
let defaultModelWarning = null
|
|
153
154
|
|
|
154
155
|
if (allDefaultIds.length > 0 && !allDefaultIds.includes(defaultModel)) {
|
package/lib/models.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
export const PROVIDER_ID = 'clinebot'
|
|
14
14
|
|
|
15
15
|
export const OBSOLETE_MODEL_ID_MAP = Object.freeze({
|
|
16
|
+
'cline-pass/deepseek-v4-flash': 'cline-pass/deepseek-v4.1-flash',
|
|
16
17
|
'cline-pass/deepseek-v41-flash': 'cline-pass/deepseek-v4.1-flash',
|
|
17
18
|
'cline-pass/qwen38-max': 'cline-pass/qwen3.8-max',
|
|
18
19
|
'cline-pass/glm-53': 'cline-pass/glm-5.3',
|
|
@@ -20,7 +21,7 @@ export const OBSOLETE_MODEL_ID_MAP = Object.freeze({
|
|
|
20
21
|
'cline-pass/muse-spark-13-contributor': 'cline-pass/muse-spark-1.3-contributor',
|
|
21
22
|
})
|
|
22
23
|
|
|
23
|
-
function migrateModelId(id) {
|
|
24
|
+
export function migrateModelId(id) {
|
|
24
25
|
if (typeof id !== 'string') return id
|
|
25
26
|
return OBSOLETE_MODEL_ID_MAP[id] || id
|
|
26
27
|
}
|
|
@@ -35,7 +36,7 @@ export function migrateModelEntry(model) {
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
export const PROVIDER_DISPLAY_NAME = 'ClineBot (ClinePass)'
|
|
38
|
-
export const DEFAULT_MODEL_ID = 'cline-pass/deepseek-v4-flash'
|
|
39
|
+
export const DEFAULT_MODEL_ID = 'cline-pass/deepseek-v4.1-flash'
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
42
|
* Authentic original model specifications from original creators:
|
|
@@ -104,8 +105,8 @@ function createCuratedModel({
|
|
|
104
105
|
|
|
105
106
|
export const CLINE_MODELS = Object.freeze([
|
|
106
107
|
createCuratedModel({
|
|
107
|
-
id: 'cline-pass/deepseek-v4-flash',
|
|
108
|
-
name: 'DeepSeek V4 Flash',
|
|
108
|
+
id: 'cline-pass/deepseek-v4.1-flash',
|
|
109
|
+
name: 'DeepSeek V4.1 Flash',
|
|
109
110
|
description: 'High-speed reasoning & code completion model optimized for agentic loops.',
|
|
110
111
|
ctx: 128000, maxTokens: 8192, input: ['text', 'image'], category: 'coding', recommended: true,
|
|
111
112
|
reasoningEfforts: ['low', 'medium', 'high'],
|
|
@@ -216,32 +217,38 @@ export function parsePlanIncludedModels(includedInput) {
|
|
|
216
217
|
.replace(/[\s._-]+/g, '')
|
|
217
218
|
|
|
218
219
|
const matched = []
|
|
220
|
+
const seenIds = new Set()
|
|
219
221
|
for (const name of parts) {
|
|
220
222
|
const targetNorm = normalize(name)
|
|
223
|
+
const idPart = name
|
|
224
|
+
.toLowerCase()
|
|
225
|
+
.trim()
|
|
226
|
+
.replace(/^cline-pass\//, '')
|
|
227
|
+
.replace(/qwen\s+([0-9])/i, 'qwen$1')
|
|
228
|
+
.replace(/glm\s+([0-9])/i, 'glm-$1')
|
|
229
|
+
.replace(/[\s_]+/g, '-')
|
|
230
|
+
.replace(/-+/g, '-')
|
|
231
|
+
const candidateId = migrateModelId(`cline-pass/${idPart}`)
|
|
221
232
|
const found = CLINE_MODELS.find(
|
|
222
233
|
(m) =>
|
|
234
|
+
m.id === candidateId ||
|
|
223
235
|
normalize(m.name) === targetNorm ||
|
|
224
236
|
normalize(m.id.replace(/^cline-pass\//, '')) === targetNorm
|
|
225
237
|
)
|
|
226
238
|
if (found) {
|
|
227
|
-
|
|
239
|
+
if (!seenIds.has(found.id)) {
|
|
240
|
+
seenIds.add(found.id)
|
|
241
|
+
matched.push(found)
|
|
242
|
+
}
|
|
228
243
|
} else {
|
|
229
244
|
// Dynamic fallback for newly introduced models mentioned in plan
|
|
230
|
-
const idPart = name
|
|
231
|
-
.toLowerCase()
|
|
232
|
-
.trim()
|
|
233
|
-
.replace(/^cline-pass\//, '')
|
|
234
|
-
.replace(/qwen\s+([0-9])/i, 'qwen$1')
|
|
235
|
-
.replace(/glm\s+([0-9])/i, 'glm-$1')
|
|
236
|
-
.replace(/[\s_]+/g, '-')
|
|
237
|
-
.replace(/-+/g, '-')
|
|
238
245
|
const isVision = /(vision|vl|multimodal|omni|image)/i.test(name)
|
|
239
246
|
const hasReasoning = /(reason|think|r1|pro|flash|max|plus|k3|m3|glm|qwen|mimo)/i.test(name)
|
|
240
247
|
const origCtx = getOriginalModelContext(name)
|
|
241
248
|
const origMax = getOriginalModelMaxTokens(name)
|
|
242
249
|
const origProv = getOriginalModelProvider(name)
|
|
243
|
-
|
|
244
|
-
id:
|
|
250
|
+
const dynamicModel = migrateModelEntry({
|
|
251
|
+
id: candidateId,
|
|
245
252
|
name,
|
|
246
253
|
description: `Official ClinePass subscription model: ${name}`,
|
|
247
254
|
clineContextLength: 200000,
|
|
@@ -258,6 +265,10 @@ export function parsePlanIncludedModels(includedInput) {
|
|
|
258
265
|
isCustom: false,
|
|
259
266
|
...(hasReasoning ? { reasoningEfforts: ['low', 'medium', 'high', 'max'] } : {}),
|
|
260
267
|
})
|
|
268
|
+
if (!seenIds.has(dynamicModel.id)) {
|
|
269
|
+
seenIds.add(dynamicModel.id)
|
|
270
|
+
matched.push(dynamicModel)
|
|
271
|
+
}
|
|
261
272
|
}
|
|
262
273
|
}
|
|
263
274
|
|
package/lib/proxy-token.js
CHANGED
|
@@ -14,9 +14,9 @@ export const LOCAL_PROXY_KEY_ENV = 'CLINEBOT_LOCAL_PROXY_TOKEN'
|
|
|
14
14
|
let cachedToken = null
|
|
15
15
|
|
|
16
16
|
const require = createRequire(import.meta.url)
|
|
17
|
-
let packageVersion = '0.5.
|
|
17
|
+
let packageVersion = '0.5.25'
|
|
18
18
|
try {
|
|
19
|
-
packageVersion = require('../package.json').version || '0.5.
|
|
19
|
+
packageVersion = require('../package.json').version || '0.5.25'
|
|
20
20
|
} catch (err) {
|
|
21
21
|
/* fallback to default version if manifest is unreadable */
|
|
22
22
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-clinebot",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.25",
|
|
4
4
|
"description": "DeepSeek Harness companion for ClineBot / ClinePass: dynamic subscription models sync, quota exhaustion warnings, session metrics, dedicated settings page, live usage limits, and /cline slash-command.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|