@goodandready/dsh-clinebot 0.6.1 → 0.6.3
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 +14 -0
- package/README.md +10 -14
- package/README.ru.md +6 -13
- package/README.zh.md +6 -13
- package/lib/adapter.js +6 -1
- package/lib/budget.js +37 -0
- package/lib/client.js +86 -142
- package/lib/cline-client.js +0 -102
- package/lib/config.js +6 -8
- package/lib/index.js +7 -201
- package/lib/provider-sync.js +2 -141
- package/lib/routes/accounts.js +1 -37
- package/lib/stats-storage.js +15 -0
- package/lib/transport/cline-transport.js +1 -1
- package/lib/tui-settings.js +24 -0
- package/package.json +1 -1
- package/lib/proxy-server.js +0 -138
- package/lib/proxy-token.js +0 -187
- package/lib/routes/proxy.js +0 -578
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@ 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.6.3] - 2026-10-21
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Quota forecast**: each 5-hour, weekly and monthly quota row now shows an estimated burn-down (`~2h 15m left`, `holds until reset`, `no usage yet`) based on the current pace and reset time. Forecasts appear in the sidebar and the center-column panel.
|
|
12
|
+
- **Budget guard**: optional `dailyBudgetUsd` and `monthlyBudgetUsd` limits (0 disables). The adapter rejects new ClineBot requests with `BUDGET_EXCEEDED` once the local estimated spend for the UTC day/month reaches the limit; both fields are available in Settings → ClineBot → Advanced and the TUI.
|
|
13
|
+
- Budget fields are wired through `publicConfig`, and the budget guard is covered by unit/integration tests.
|
|
14
|
+
|
|
15
|
+
## [0.6.2] - 2026-10-21
|
|
16
|
+
|
|
17
|
+
### Removed
|
|
18
|
+
- **Legacy transport removed**: `transport: "pi-ai"`, `proxyMode`, `lib/proxy-server.js`, `lib/proxy-token.js`, `lib/routes/proxy.js`, the `llm/stream` failover hook and `/register` / `/unregister` routes are gone. ClineBot is adapter-only on `ctx.llm`.
|
|
19
|
+
- **Legacy settings surfaces removed**: the transport selector, proxy diagnostics and proxy-mode toggle no longer appear in Settings or the TUI. A one-time cleanup still removes an old `llm-pi-ai.providers.clinebot` entry for users upgrading from 0.6.1.
|
|
20
|
+
- **Legacy tests removed**; the adapter/session-router paths remain covered. Final bundle: 248.9 KB.
|
|
21
|
+
|
|
8
22
|
## [0.6.1] - 2026-10-21
|
|
9
23
|
|
|
10
24
|
### Fixed
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<h3>Native ClineBot / ClinePass Provider Companion for DeepSeek Harness</h3>
|
|
6
6
|
|
|
7
|
-
<p><b>0.6.
|
|
7
|
+
<p><b>0.6.3</b> adds quota burn-down forecasts and optional daily/monthly spend guards on top of the adapter-only line. Chat runs on the native <code>ctx.llm</code> adapter and requires DSH <code>0.2.1-rc.2</code>; the legacy <code>llm-pi-ai</code>, loopback proxy and <code>llm/stream</code> path are removed.</p>
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
10
|
<a href="https://www.npmjs.com/package/@goodandready/dsh-clinebot"><img src="https://img.shields.io/npm/v/@goodandready/dsh-clinebot.svg?style=for-the-badge&color=6366f1&labelColor=1e1b4b" alt="npm version"></a>
|
|
@@ -118,7 +118,7 @@ graph LR
|
|
|
118
118
|
* **`lib/adapter.js`**:
|
|
119
119
|
Registers the `ClineBotAdapter` directly on `ctx.llm`: streaming, model catalogue, reasoning effort, pre-first-token account failover, retry policy, usage accounting and provider metadata.
|
|
120
120
|
* **`lib/transport/cline-transport.js`**:
|
|
121
|
-
OpenAI-compatible SSE transport with connect/idle timeouts, abort handling and upstream error classification.
|
|
121
|
+
OpenAI-compatible SSE transport with connect/idle timeouts, abort handling and upstream error classification.
|
|
122
122
|
* **`lib/models.js`**:
|
|
123
123
|
Dynamic subscription catalogue, curated fallback properties, reasoning efforts, custom models and plan parsing (`parsePlanIncludedModels`, `getAllModels`, `getDynamicModels`).
|
|
124
124
|
* **`lib/model-prices.js`**:
|
|
@@ -128,9 +128,9 @@ graph LR
|
|
|
128
128
|
* **`lib/account-pool.js` / `lib/session-router.js`**:
|
|
129
129
|
Credential discovery, usage-aware least-used and round-robin rotation, sticky sessions and cooldown recovery.
|
|
130
130
|
* **`lib/cline-client.js`**:
|
|
131
|
-
`fetchUsageLimits`, credential save, smoke test
|
|
131
|
+
`fetchUsageLimits`, credential save, smoke test and the model catalogue cache.
|
|
132
132
|
* **`lib/index.js`**:
|
|
133
|
-
Cordis lifecycle: adapter registration, optional HTTP routes, quota warnings, `/cline` command,
|
|
133
|
+
Cordis lifecycle: adapter registration, optional HTTP routes, quota warnings, `/cline` command, one-time cleanup of the old provider entry and TUI section registration.
|
|
134
134
|
* **`lib/tui-settings.js`**:
|
|
135
135
|
`dsh-TUI` section for key, base URL, model filters, active account, context window and output cap.
|
|
136
136
|
* **`lib/client.js`**:
|
|
@@ -144,7 +144,7 @@ graph LR
|
|
|
144
144
|
dsh plugin --profile web add @goodandready/dsh-clinebot
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
-
Requires **DSH `0.2.1-rc.2`** and Node 22+.
|
|
147
|
+
Requires **DSH `0.2.1-rc.2`** and Node 22+. ClineBot registers directly with `ctx.llm`; there is no transport switch or loopback proxy.
|
|
148
148
|
|
|
149
149
|
Restart your DeepSeek Harness instance and refresh the browser.
|
|
150
150
|
|
|
@@ -191,13 +191,14 @@ dsh-clinebot:
|
|
|
191
191
|
baseUrl: https://api.cline.bot/api/v1
|
|
192
192
|
apiKeyEnv: CLINEBOT_API_KEY
|
|
193
193
|
defaultModel: your-default-model
|
|
194
|
-
proxyMode: true
|
|
195
194
|
disabledModels: []
|
|
196
195
|
customModels: []
|
|
197
196
|
modelReasoningDefaults:
|
|
198
197
|
your-reasoning-model: high
|
|
199
198
|
modelContextOverrides: []
|
|
200
199
|
statsPath: ~/.dsh/clinebot-stats.json
|
|
200
|
+
dailyBudgetUsd: 0
|
|
201
|
+
monthlyBudgetUsd: 0
|
|
201
202
|
timeoutMs: 30000
|
|
202
203
|
smokeTimeoutMs: 60000
|
|
203
204
|
streamIdleTimeoutMs: 60000
|
|
@@ -218,8 +219,9 @@ dsh-clinebot:
|
|
|
218
219
|
| `customModels` | `array` | `[]` | User-defined gateway models (`[{ id, name, contextLength, maxTokens, category, isReasoning }]`) |
|
|
219
220
|
| `modelReasoningDefaults` | `object` | `{}` | Configured default reasoning effort per model (`low`, `medium`, `high`, `max`) |
|
|
220
221
|
| `modelContextOverrides` | `array` | `[]` | User-defined model context length and max token overrides |
|
|
221
|
-
| `proxyMode` | `boolean` | `true` | Enable local transparent loopback proxy for sticky sessions and automatic 429 failover |
|
|
222
222
|
| `statsPath` | `string` | `"~/.dsh/clinebot-stats.json"` | Persistent on-disk path for token usage analytics |
|
|
223
|
+
| `dailyBudgetUsd` | `number` | `0` | Optional estimated daily spend guard; 0 disables it |
|
|
224
|
+
| `monthlyBudgetUsd` | `number` | `0` | Optional estimated monthly spend guard; 0 disables it |
|
|
223
225
|
| `accounts` | `array` | `[]` | Additional accounts for multi-account failover and quota rotation (`[{ label, apiKeyEnv }]`) |
|
|
224
226
|
| `activeAccount` | `string` | `""` | Manually pinned active account env name (empty for least-used auto routing) |
|
|
225
227
|
| `timeoutMs` | `number` | `15000` | HTTP probe timeout in milliseconds |
|
|
@@ -232,7 +234,7 @@ dsh-clinebot:
|
|
|
232
234
|
|
|
233
235
|
## 🌐 HTTP API Endpoints
|
|
234
236
|
|
|
235
|
-
All endpoints are registered under `/dsh-clinebot/*` and protected against untrusted cross-site origins (same-origin and loopback allowed). Control endpoints enforce a 256 KiB request payload limit
|
|
237
|
+
All endpoints are registered under `/dsh-clinebot/*` and protected against untrusted cross-site origins (same-origin and loopback allowed). Control endpoints enforce a 256 KiB request payload limit:
|
|
236
238
|
|
|
237
239
|
### Management & Control Endpoints (Max 256 KiB)
|
|
238
240
|
* `GET /dsh-clinebot/status` — Live status report including provider health, active credential, quota, and session metrics.
|
|
@@ -252,12 +254,6 @@ All endpoints are registered under `/dsh-clinebot/*` and protected against untru
|
|
|
252
254
|
* `GET /dsh-clinebot/update/status` — Query available GitHub releases and plugin updates.
|
|
253
255
|
* `POST /dsh-clinebot/update/apply` — Apply version upgrade with process-group cleanup and lockfile sync.
|
|
254
256
|
|
|
255
|
-
### OpenAI-Compatible Loopback Proxy (Max 64 MiB)
|
|
256
|
-
* `POST /dsh-clinebot/v1/chat/completions` — Transparent local proxy supporting streaming SSE and non-streaming responses, Bearer token authentication, sticky session affinity with least-used quota allocation, body read watchdog (`streamIdleTimeoutMs`), and automatic 429 failover.
|
|
257
|
-
* `GET /dsh-clinebot/v1/models` — OpenAI-compatible catalog listing all active plan and custom models.
|
|
258
|
-
|
|
259
|
-
> **DSH Desktop 2.x & Headless Environments**: The loopback proxy binds an isolated loopback HTTP server on `127.0.0.1` (ephemeral port), completely bypassing `DesktopWebServer` renderer fences (`x-dsh-desktop-renderer`). Automated fence detection (`detectHostWebServerFence`) falls back to direct upstream connection if the loopback server is restricted, and proxy mode can be directly toggled via the Diagnostics settings card.
|
|
260
|
-
|
|
261
257
|
---
|
|
262
258
|
|
|
263
259
|
## Visual verification
|
package/README.ru.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<h3>Нативное подключение провайдера ClineBot / ClinePass для DeepSeek Harness</h3>
|
|
6
6
|
|
|
7
|
-
<p><b>0.6.
|
|
7
|
+
<p><b>0.6.3</b> добавляет прогноз расхода квоты и опциональные дневной/месячный лимиты трат. Чат работает через нативный адаптер <code>ctx.llm</code>, требуется DSH <code>0.2.1-rc.2</code>; старые <code>llm-pi-ai</code>, loopback-прокси и <code>llm/stream</code> удалены.</p>
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
10
|
<a href="https://www.npmjs.com/package/@goodandready/dsh-clinebot"><img src="https://img.shields.io/npm/v/@goodandready/dsh-clinebot.svg?style=for-the-badge&color=6366f1&labelColor=1e1b4b" alt="npm version"></a>
|
|
@@ -84,7 +84,6 @@ graph LR
|
|
|
84
84
|
|
|
85
85
|
subgraph DSHCore [Сервисы DSH]
|
|
86
86
|
Credentials["Сервис credentials (~/.dsh/.credentials.yaml)"]
|
|
87
|
-
PiAi["Настройки: llm-pi-ai.providers.clinebot"]
|
|
88
87
|
end
|
|
89
88
|
|
|
90
89
|
subgraph Upstream [Сервер Cline]
|
|
@@ -99,7 +98,6 @@ graph LR
|
|
|
99
98
|
HttpEndpoints --> Credentials
|
|
100
99
|
HttpEndpoints --> ClientCore
|
|
101
100
|
ClientCore --> ModelCatalog
|
|
102
|
-
HttpEndpoints -->|Атомарная мутация| PiAi
|
|
103
101
|
ClientCore -->|Чат| ClinePass
|
|
104
102
|
ClientCore -->|Квоты| ClineQuota
|
|
105
103
|
ClientCore -->|Тарифный план| ClinePlan
|
|
@@ -115,7 +113,6 @@ graph LR
|
|
|
115
113
|
* `sessionStats` / `recordSessionRequest`: счетчики сессии (запросы, токены, задержка, время).
|
|
116
114
|
* `saveCredentialKey`: атомарная запись ключей в `~/.dsh/.credentials.yaml`.
|
|
117
115
|
* `smokeChat`: замер задержки и тестовый пинг с фиксацией статистики.
|
|
118
|
-
* `buildPiAiProvider`: генерация конфигурации провайдера для `llm-pi-ai` (`api: 'openai-completions'`).
|
|
119
116
|
* **`lib/index.js`**: сервис Cordis, регистрация системных маршрутов (включая `/dsh-clinebot/models/sync`), расчет порогов предупреждения квоты и слэш-команды `/cline`.
|
|
120
117
|
* **`lib/client.js`**: страница конфигурации строки плагина (`plugins.row.config`) с предупреждениями, статистикой сессии, синхронизацией моделей и запасной карточкой (`settings.plugin.item`). Пункта `settings.section` в боковом меню нет.
|
|
121
118
|
|
|
@@ -163,13 +160,14 @@ dsh-clinebot:
|
|
|
163
160
|
baseUrl: https://api.cline.bot/api/v1
|
|
164
161
|
apiKeyEnv: CLINEBOT_API_KEY
|
|
165
162
|
defaultModel: your-default-model
|
|
166
|
-
proxyMode: true
|
|
167
163
|
disabledModels: []
|
|
168
164
|
customModels: []
|
|
169
165
|
modelReasoningDefaults:
|
|
170
166
|
your-reasoning-model: high
|
|
171
167
|
modelContextOverrides: []
|
|
172
168
|
statsPath: ~/.dsh/clinebot-stats.json
|
|
169
|
+
dailyBudgetUsd: 0
|
|
170
|
+
monthlyBudgetUsd: 0
|
|
173
171
|
timeoutMs: 30000
|
|
174
172
|
smokeTimeoutMs: 60000
|
|
175
173
|
streamIdleTimeoutMs: 60000
|
|
@@ -190,8 +188,9 @@ dsh-clinebot:
|
|
|
190
188
|
| `customModels` | `array` | `[]` | Пользовательские модели шлюза (`[{ id, name, contextLength, maxTokens, category, isReasoning }]`) |
|
|
191
189
|
| `modelReasoningDefaults` | `object` | `{}` | Значения thinking effort по умолчанию для моделей (`low`, `medium`, `high`, `max`) |
|
|
192
190
|
| `modelContextOverrides` | `array` | `[]` | Пользовательские переопределения размера контекста и лимита токенов |
|
|
193
|
-
| `proxyMode` | `boolean` | `true` | Включение локального прозрачного loopback-прокси с сессионным роутингом и failover |
|
|
194
191
|
| `statsPath` | `string` | `"~/.dsh/clinebot-stats.json"` | Путь к файлу персистентной аналитики использования токенов |
|
|
192
|
+
| `dailyBudgetUsd` | `number` | `0` | Опциональный дневной лимит оценочных трат; 0 отключает |
|
|
193
|
+
| `monthlyBudgetUsd` | `number` | `0` | Опциональный месячный лимит оценочных трат; 0 отключает |
|
|
195
194
|
| `accounts` | `array` | `[]` | Дополнительные аккаунты для ротации квоты и failover (`[{ label, apiKeyEnv }]`) |
|
|
196
195
|
| `activeAccount` | `string` | `""` | Принудительно закреплённый аккаунт (пусто для автоматического выбора least-used) |
|
|
197
196
|
| `timeoutMs` | `number` | `15000` | Таймаут HTTP-запросов (мс) |
|
|
@@ -204,7 +203,7 @@ dsh-clinebot:
|
|
|
204
203
|
|
|
205
204
|
## 🌐 Маршруты HTTP API
|
|
206
205
|
|
|
207
|
-
Все маршруты регистрируются с префиксом `/dsh-clinebot/*` и защищены от межсайтовых запросов (разрешены same-origin и loopback). Управляющие эндпоинты ограничены лимитом 256
|
|
206
|
+
Все маршруты регистрируются с префиксом `/dsh-clinebot/*` и защищены от межсайтовых запросов (разрешены same-origin и loopback). Управляющие эндпоинты ограничены лимитом 256 КиБ:
|
|
208
207
|
|
|
209
208
|
### Управляющие эндпоинты (макс. 256 КиБ)
|
|
210
209
|
* `GET /dsh-clinebot/status` — Текущее состояние провайдера, активный аккаунт, квоты и статистика сессий.
|
|
@@ -224,12 +223,6 @@ dsh-clinebot:
|
|
|
224
223
|
* `GET /dsh-clinebot/update/status` — Проверка наличия обновлений плагина.
|
|
225
224
|
* `POST /dsh-clinebot/update/apply` — Обновление плагина с корректным завершением групп процессов и блокировками профиля.
|
|
226
225
|
|
|
227
|
-
### OpenAI-совместимый loopback-прокси (макс. 64 МиБ)
|
|
228
|
-
* `POST /dsh-clinebot/v1/chat/completions` — Прозрачный локальный прокси с поддержкой SSE и нестриминговых ответов, Bearer-аутентификацией, сессионной липкостью и least-used распределением квот, контролем дедлайнов (`streamIdleTimeoutMs`) и автоматическим 429 failover.
|
|
229
|
-
* `GET /dsh-clinebot/v1/models` — Каталог моделей в стандарте OpenAI API.
|
|
230
|
-
|
|
231
|
-
> **DSH Desktop 2.x и автономные окружения**: Прокси поднимает изолированный выделенный HTTP-сервер на `127.0.0.1` (эфемеридный порт), полностью обходя сетевые экраны `DesktopWebServer` (`x-dsh-desktop-renderer`). Встроенный детектор защитных экранов (`detectHostWebServerFence`) автоматически переключает провайдер на прямое соединение с upstream при ограничении loopback-порта, а режим прокси можно переключать напрямую в карточке «Диагностика» в UI.
|
|
232
|
-
|
|
233
226
|
---
|
|
234
227
|
|
|
235
228
|
## 🧪 Тестирование
|
package/README.zh.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<h3>适用于 DeepSeek Harness 的 ClineBot / ClinePass 原生模型提供商伴侣插件</h3>
|
|
6
6
|
|
|
7
|
-
<p><b>0.6.
|
|
7
|
+
<p><b>0.6.3</b> 添加配额消耗预测和可选的每日/每月花费上限。聊天使用原生 <code>ctx.llm</code> 适配器,需要 DSH <code>0.2.1-rc.2</code>;旧的 <code>llm-pi-ai</code>、回环代理和 <code>llm/stream</code> 已删除。</p>
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
10
|
<a href="https://www.npmjs.com/package/@goodandready/dsh-clinebot"><img src="https://img.shields.io/npm/v/@goodandready/dsh-clinebot.svg?style=for-the-badge&color=6366f1&labelColor=1e1b4b" alt="npm version"></a>
|
|
@@ -84,7 +84,6 @@ graph LR
|
|
|
84
84
|
|
|
85
85
|
subgraph DSHCore [DSH 核心系统服务]
|
|
86
86
|
Credentials["凭据存储服务 (~/.dsh/.credentials.yaml)"]
|
|
87
|
-
PiAi["模型注册: llm-pi-ai.providers.clinebot"]
|
|
88
87
|
end
|
|
89
88
|
|
|
90
89
|
subgraph Upstream [Cline 官方云端]
|
|
@@ -99,7 +98,6 @@ graph LR
|
|
|
99
98
|
HttpEndpoints --> Credentials
|
|
100
99
|
HttpEndpoints --> ClientCore
|
|
101
100
|
ClientCore --> ModelCatalog
|
|
102
|
-
HttpEndpoints -->|原子级写入| PiAi
|
|
103
101
|
ClientCore -->|模型对话| ClinePass
|
|
104
102
|
ClientCore -->|额度查询| ClineQuota
|
|
105
103
|
ClientCore -->|套餐信息| ClinePlan
|
|
@@ -115,7 +113,6 @@ graph LR
|
|
|
115
113
|
* `sessionStats` / `recordSessionRequest`:内存级会话度量记录器(请求次数、Token 估算、延迟、时间戳)。
|
|
116
114
|
* `saveCredentialKey`:将密钥安全写入 `~/.dsh/.credentials.yaml`。
|
|
117
115
|
* `smokeChat`:毫秒级网络探活与非流式延迟测试,并记录会话指标。
|
|
118
|
-
* `buildPiAiProvider`:构建 DSH `llm-pi-ai` 兼容的服务商定义 (`api: 'openai-completions'`)。
|
|
119
116
|
* **`lib/index.js`**:Cordis 插件主生命周期服务,注册后端 REST API 路由(含 `/dsh-clinebot/models/sync`)、额度预警计算与 `/cline` 聊天斜杠指令。
|
|
120
117
|
* **`lib/client.js`**:插件行配置页(`plugins.row.config`),含预警横幅、会话指标、一键模型同步,以及后备插件卡片(`settings.plugin.item`)。没有 `settings.section` 侧边栏项。
|
|
121
118
|
|
|
@@ -165,13 +162,14 @@ dsh-clinebot:
|
|
|
165
162
|
baseUrl: https://api.cline.bot/api/v1
|
|
166
163
|
apiKeyEnv: CLINEBOT_API_KEY
|
|
167
164
|
defaultModel: your-default-model
|
|
168
|
-
proxyMode: true
|
|
169
165
|
disabledModels: []
|
|
170
166
|
customModels: []
|
|
171
167
|
modelReasoningDefaults:
|
|
172
168
|
your-reasoning-model: high
|
|
173
169
|
modelContextOverrides: []
|
|
174
170
|
statsPath: ~/.dsh/clinebot-stats.json
|
|
171
|
+
dailyBudgetUsd: 0
|
|
172
|
+
monthlyBudgetUsd: 0
|
|
175
173
|
timeoutMs: 30000
|
|
176
174
|
smokeTimeoutMs: 60000
|
|
177
175
|
streamIdleTimeoutMs: 60000
|
|
@@ -192,8 +190,9 @@ dsh-clinebot:
|
|
|
192
190
|
| `customModels` | `array` | `[]` | 用户自定义网关模型 (`[{ id, name, contextLength, maxTokens, category, isReasoning }]`) |
|
|
193
191
|
| `modelReasoningDefaults` | `object` | `{}` | 各模型默认思考强度配置 (`low`, `medium`, `high`, `max`) |
|
|
194
192
|
| `modelContextOverrides` | `array` | `[]` | 用户自定义模型上下文窗口与最大 Token 数量覆盖 |
|
|
195
|
-
| `proxyMode` | `boolean` | `true` | 启用透明本地环回代理以支持会话粘性路由与 429 自动故障转移 |
|
|
196
193
|
| `statsPath` | `string` | `"~/.dsh/clinebot-stats.json"` | 本地持久化 Token 用量统计文件路径 |
|
|
194
|
+
| `dailyBudgetUsd` | `number` | `0` | 可选的每日估算花费上限;0 表示关闭 |
|
|
195
|
+
| `monthlyBudgetUsd` | `number` | `0` | 可选的每月估算花费上限;0 表示关闭 |
|
|
197
196
|
| `accounts` | `array` | `[]` | 额外轮转账号池 (`[{ label, apiKeyEnv }]`) |
|
|
198
197
|
| `activeAccount` | `string` | `""` | 手动指定的主账号(为空时自动按最低配额消耗优先路由) |
|
|
199
198
|
| `timeoutMs` | `number` | `15000` | HTTP 请求探测超时时间(毫秒) |
|
|
@@ -206,7 +205,7 @@ dsh-clinebot:
|
|
|
206
205
|
|
|
207
206
|
## 🌐 HTTP API 接口说明
|
|
208
207
|
|
|
209
|
-
所有接口挂载于 `/dsh-clinebot/*` 路径,并受到跨站请求防护(仅放行同源或环回请求)。管理接口限制请求体上限 256 KiB
|
|
208
|
+
所有接口挂载于 `/dsh-clinebot/*` 路径,并受到跨站请求防护(仅放行同源或环回请求)。管理接口限制请求体上限 256 KiB:
|
|
210
209
|
|
|
211
210
|
### 管理与控制接口(上限 256 KiB)
|
|
212
211
|
* `GET /dsh-clinebot/status` — 服务运行状态,包括健康探活、当前凭据名称、配额限制及会话统计。
|
|
@@ -226,12 +225,6 @@ dsh-clinebot:
|
|
|
226
225
|
* `GET /dsh-clinebot/update/status` — 查询插件版本更新状态。
|
|
227
226
|
* `POST /dsh-clinebot/update/apply` — 应用版本更新(支持进程树完全清理与锁文件保护)。
|
|
228
227
|
|
|
229
|
-
### OpenAI 兼容环回代理接口(上限 64 MiB)
|
|
230
|
-
* `POST /dsh-clinebot/v1/chat/completions` — 本地透明代理,支持 SSE 流式与完整响应、会话粘性路由、最低用量负载均衡、响应体超时防护 (`streamIdleTimeoutMs`) 以及 429 自动故障转移。
|
|
231
|
-
* `GET /dsh-clinebot/v1/models` — 符合 OpenAI API 规范的模型列表。
|
|
232
|
-
|
|
233
|
-
> **DSH Desktop 2.x 与无界面环境**:环回代理在 `127.0.0.1` 绑定独立的专用 HTTP 服务(临时端口),彻底绕过桌面端路由防护 (`DesktopWebServer` 的 `x-dsh-desktop-renderer` 限制)。内置防护检测机制 (`detectHostWebServerFence`) 在环回端口受限时自动回退为直连模式,用户亦可在设置页的“诊断”模块中直接切换代理模式。
|
|
234
|
-
|
|
235
228
|
---
|
|
236
229
|
|
|
237
230
|
## 🧪 测试
|
package/lib/adapter.js
CHANGED
|
@@ -12,7 +12,8 @@ import { getAllModels, findModel, formatModelDescription } from './models.js'
|
|
|
12
12
|
import { resolveAccountPool } from './account-pool.js'
|
|
13
13
|
import { resolveSessionAccount, markAccountCooldown } from './session-router.js'
|
|
14
14
|
import { recordSessionRequest } from './telemetry.js'
|
|
15
|
-
import { recordUsage } from './stats-storage.js'
|
|
15
|
+
import { recordUsage, getBudgetSpend } from './stats-storage.js'
|
|
16
|
+
import { budgetStatus, budgetErrorMessage } from './budget.js'
|
|
16
17
|
import { estimateCost } from './model-prices.js'
|
|
17
18
|
import { buildOpenAiPayload } from './adapter-messages.js'
|
|
18
19
|
import { streamJsonCompletion, streamOpenAiChunks } from './adapter-stream.js'
|
|
@@ -244,6 +245,10 @@ export class ClineBotAdapter extends LlmAdapter {
|
|
|
244
245
|
if (!pub.enabled) {
|
|
245
246
|
throw new LlmError('ClineBot provider is disabled', 'PROVIDER_DISABLED')
|
|
246
247
|
}
|
|
248
|
+
const budget = budgetStatus(pub, getBudgetSpend())
|
|
249
|
+
if (budget.blocked) {
|
|
250
|
+
throw new LlmError(budgetErrorMessage(budget), 'BUDGET_EXCEEDED')
|
|
251
|
+
}
|
|
247
252
|
|
|
248
253
|
const signal = options.signal
|
|
249
254
|
const sessionId = options.sessionId ? String(options.sessionId) : ''
|
package/lib/budget.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Estimated-spend budget guard.
|
|
3
|
+
*
|
|
4
|
+
* ClinePass does not expose a per-token invoice; spend comes from the local
|
|
5
|
+
* price table and is therefore explicit about being an estimate. A guard of 0
|
|
6
|
+
* disables the corresponding limit.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {{ dailyBudgetUsd?: number, monthlyBudgetUsd?: number }} config
|
|
11
|
+
* @param {{ dayCost?: number, monthCost?: number }} spend
|
|
12
|
+
* @returns {{ blocked: boolean, scope: 'daily'|'monthly'|null, spent: number, limit: number }}
|
|
13
|
+
*/
|
|
14
|
+
export function budgetStatus(config, spend) {
|
|
15
|
+
const dailyLimit = Math.max(0, Number(config?.dailyBudgetUsd) || 0)
|
|
16
|
+
const monthlyLimit = Math.max(0, Number(config?.monthlyBudgetUsd) || 0)
|
|
17
|
+
const dayCost = Math.max(0, Number(spend?.dayCost) || 0)
|
|
18
|
+
const monthCost = Math.max(0, Number(spend?.monthCost) || 0)
|
|
19
|
+
|
|
20
|
+
if (dailyLimit > 0 && dayCost >= dailyLimit) {
|
|
21
|
+
return { blocked: true, scope: 'daily', spent: dayCost, limit: dailyLimit }
|
|
22
|
+
}
|
|
23
|
+
if (monthlyLimit > 0 && monthCost >= monthlyLimit) {
|
|
24
|
+
return { blocked: true, scope: 'monthly', spent: monthCost, limit: monthlyLimit }
|
|
25
|
+
}
|
|
26
|
+
return { blocked: false, scope: null, spent: 0, limit: 0 }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Human-readable error for an exhausted budget guard.
|
|
31
|
+
* @param {ReturnType<typeof budgetStatus>} status
|
|
32
|
+
*/
|
|
33
|
+
export function budgetErrorMessage(status) {
|
|
34
|
+
if (!status?.blocked) return ''
|
|
35
|
+
const label = status.scope === 'monthly' ? 'Monthly' : 'Daily'
|
|
36
|
+
return `${label} ClineBot budget reached (estimated $${status.spent.toFixed(4)} of $${status.limit.toFixed(2)}). Raise the limit in Settings -> ClineBot -> Advanced.`
|
|
37
|
+
}
|