@arikusi/deepseek-mcp-server 1.2.0 → 1.3.0
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 +25 -1
- package/README.md +79 -8
- package/dist/circuit-breaker.d.ts +37 -0
- package/dist/circuit-breaker.d.ts.map +1 -0
- package/dist/circuit-breaker.js +101 -0
- package/dist/circuit-breaker.js.map +1 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -0
- package/dist/config.js.map +1 -1
- package/dist/deepseek-client.d.ts +23 -5
- package/dist/deepseek-client.d.ts.map +1 -1
- package/dist/deepseek-client.js +221 -119
- package/dist/deepseek-client.js.map +1 -1
- package/dist/errors.d.ts +13 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +18 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/resources/config.d.ts +7 -0
- package/dist/resources/config.d.ts.map +1 -0
- package/dist/resources/config.js +44 -0
- package/dist/resources/config.js.map +1 -0
- package/dist/resources/index.d.ts +7 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +13 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/models.d.ts +7 -0
- package/dist/resources/models.d.ts.map +1 -0
- package/dist/resources/models.js +62 -0
- package/dist/resources/models.js.map +1 -0
- package/dist/resources/usage.d.ts +7 -0
- package/dist/resources/usage.d.ts.map +1 -0
- package/dist/resources/usage.js +31 -0
- package/dist/resources/usage.js.map +1 -0
- package/dist/schemas.d.ts +13 -0
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +6 -0
- package/dist/schemas.js.map +1 -1
- package/dist/session.d.ts +68 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +184 -0
- package/dist/session.js.map +1 -0
- package/dist/tools/deepseek-chat.d.ts +1 -0
- package/dist/tools/deepseek-chat.d.ts.map +1 -1
- package/dist/tools/deepseek-chat.js +50 -7
- package/dist/tools/deepseek-chat.js.map +1 -1
- package/dist/tools/deepseek-sessions.d.ts +7 -0
- package/dist/tools/deepseek-sessions.d.ts.map +1 -0
- package/dist/tools/deepseek-sessions.js +101 -0
- package/dist/tools/deepseek-sessions.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/types.d.ts +55 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/usage-tracker.d.ts +40 -0
- package/dist/usage-tracker.d.ts.map +1 -0
- package/dist/usage-tracker.js +76 -0
- package/dist/usage-tracker.js.map +1 -0
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
16
16
|
### Fixed
|
|
17
17
|
- Nothing yet
|
|
18
18
|
|
|
19
|
+
## [1.3.0] - 2026-03-04
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- **Multi-Turn Sessions**: `session_id` parameter on `deepseek_chat` for multi-turn conversations. Session history is stored in memory and automatically prepended to requests. Sessions have configurable TTL and max count.
|
|
23
|
+
- **Session Management Tool**: `deepseek_sessions` tool with `list`, `delete`, and `clear` actions for managing active sessions.
|
|
24
|
+
- **Circuit Breaker**: Protects against cascading API failures. After 5 consecutive failures, fast-fails for 30 seconds, then probes for recovery.
|
|
25
|
+
- **Model Fallback**: Automatic fallback between `deepseek-chat` and `deepseek-reasoner` on retryable errors (429, 503, timeout). Configurable via `FALLBACK_ENABLED`.
|
|
26
|
+
- **MCP Resources**: 3 read-only resources following MCP Resources spec:
|
|
27
|
+
- `deepseek://models`: Model list with capabilities, context limits, and pricing
|
|
28
|
+
- `deepseek://config`: Current server configuration (API key masked)
|
|
29
|
+
- `deepseek://usage`: Real-time usage statistics (requests, tokens, costs, sessions)
|
|
30
|
+
- **Usage Tracker**: Global usage statistics tracking across all requests.
|
|
31
|
+
- **New Error Classes**: `FallbackExhaustedError`, `CircuitBreakerOpenError` for resilience error handling.
|
|
32
|
+
- **New Config**: `SESSION_TTL_MINUTES` (default: 30), `MAX_SESSIONS` (default: 100), `FALLBACK_ENABLED` (default: true).
|
|
33
|
+
- **198 Tests**: Up from 150, covering sessions, circuit breaker, fallback, and MCP resources.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
- `deepseek-client.ts` now wraps API calls in circuit breaker and supports automatic model fallback.
|
|
37
|
+
- `deepseek_chat` tool description updated to mention sessions, fallback, and circuit breaker.
|
|
38
|
+
- `tools/index.ts` now registers both `deepseek_chat` and `deepseek_sessions` tools.
|
|
39
|
+
- `index.ts` now registers MCP resources via `registerAllResources()`.
|
|
40
|
+
|
|
19
41
|
## [1.2.0] - 2026-02-26
|
|
20
42
|
|
|
21
43
|
### Added
|
|
@@ -171,6 +193,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
171
193
|
|
|
172
194
|
## Version History
|
|
173
195
|
|
|
196
|
+
- **1.3.0** (2026-03-04): Sessions, circuit breaker, model fallback, MCP resources, 198 tests
|
|
174
197
|
- **1.2.0** (2026-02-26): DeepSeek V3.2 support — thinking mode, JSON mode, cache-aware pricing, 150 tests
|
|
175
198
|
- **1.1.1** (2026-02-11): Modular architecture, type safety, security fixes, 126 tests
|
|
176
199
|
- **1.1.0** (2026-02-10): Function calling, config system, test suite
|
|
@@ -184,7 +207,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
184
207
|
- [GitHub repository](https://github.com/arikusi/deepseek-mcp-server)
|
|
185
208
|
- [Issue tracker](https://github.com/arikusi/deepseek-mcp-server/issues)
|
|
186
209
|
|
|
187
|
-
[Unreleased]: https://github.com/arikusi/deepseek-mcp-server/compare/v1.
|
|
210
|
+
[Unreleased]: https://github.com/arikusi/deepseek-mcp-server/compare/v1.3.0...HEAD
|
|
211
|
+
[1.3.0]: https://github.com/arikusi/deepseek-mcp-server/compare/v1.2.0...v1.3.0
|
|
188
212
|
[1.2.0]: https://github.com/arikusi/deepseek-mcp-server/compare/v1.1.1...v1.2.0
|
|
189
213
|
[1.1.1]: https://github.com/arikusi/deepseek-mcp-server/compare/v1.1.0...v1.1.1
|
|
190
214
|
[1.1.0]: https://github.com/arikusi/deepseek-mcp-server/compare/v1.0.3...v1.1.0
|
package/README.md
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
[](https://www.typescriptlang.org/)
|
|
8
8
|
[](https://github.com/arikusi/deepseek-mcp-server/actions)
|
|
9
9
|
|
|
10
|
-
A Model Context Protocol (MCP) server that integrates DeepSeek AI models with MCP-compatible clients. Access DeepSeek's powerful chat and reasoning models directly from your development environment.
|
|
10
|
+
A Model Context Protocol (MCP) server that integrates DeepSeek AI models with MCP-compatible clients. Access DeepSeek's powerful chat and reasoning models with multi-turn sessions, automatic model fallback, and MCP Resources directly from your development environment.
|
|
11
11
|
|
|
12
12
|
**Compatible with:**
|
|
13
13
|
- Claude Code CLI
|
|
14
|
-
- Gemini CLI
|
|
15
|
-
- Any MCP-compatible client
|
|
14
|
+
- Gemini CLI
|
|
15
|
+
- Any MCP-compatible client (Cursor, Windsurf, etc.)
|
|
16
16
|
|
|
17
17
|
> **Note**: This is an unofficial community project and is not affiliated with DeepSeek.
|
|
18
18
|
|
|
@@ -49,14 +49,18 @@ That's it! Your MCP client can now use DeepSeek models!
|
|
|
49
49
|
## Features
|
|
50
50
|
|
|
51
51
|
- **DeepSeek V3.2**: Both models now run DeepSeek-V3.2 (since Sept 2025)
|
|
52
|
+
- **Multi-Turn Sessions**: Conversation context preserved across requests via `session_id` parameter
|
|
53
|
+
- **Model Fallback & Circuit Breaker**: Automatic fallback between models with circuit breaker protection against cascading failures
|
|
54
|
+
- **MCP Resources**: `deepseek://models`, `deepseek://config`, `deepseek://usage` — query model info, config, and usage stats
|
|
52
55
|
- **Thinking Mode**: Enable enhanced reasoning on deepseek-chat with `thinking: {type: "enabled"}`
|
|
53
56
|
- **JSON Output Mode**: Structured JSON responses with `json_mode: true`
|
|
54
57
|
- **Function Calling**: OpenAI-compatible tool use with up to 128 tool definitions
|
|
55
58
|
- **Cache-Aware Cost Tracking**: Automatic cost calculation with cache hit/miss breakdown
|
|
59
|
+
- **Session Management Tool**: List, delete, and clear sessions via `deepseek_sessions` tool
|
|
56
60
|
- **Configurable**: Environment-based configuration with validation
|
|
57
61
|
- **12 Prompt Templates**: Pre-built templates for debugging, code review, function calling, and more
|
|
58
62
|
- **Streaming Support**: Real-time response generation
|
|
59
|
-
- **Tested**:
|
|
63
|
+
- **Tested**: 198 tests with 90%+ code coverage
|
|
60
64
|
- **Type-Safe**: Full TypeScript implementation
|
|
61
65
|
- **MCP Compatible**: Works with any MCP-compatible CLI (Claude Code, Gemini CLI, etc.)
|
|
62
66
|
|
|
@@ -98,7 +102,7 @@ npm run build
|
|
|
98
102
|
|
|
99
103
|
## Usage
|
|
100
104
|
|
|
101
|
-
Once configured, your MCP client will have access to
|
|
105
|
+
Once configured, your MCP client will have access to `deepseek_chat` and `deepseek_sessions` tools, plus 3 MCP resources.
|
|
102
106
|
|
|
103
107
|
**Example prompts:**
|
|
104
108
|
```
|
|
@@ -150,6 +154,7 @@ Chat with DeepSeek AI models with automatic cost tracking and function calling s
|
|
|
150
154
|
- `tool_choice` (optional): "auto" | "none" | "required" | `{type: "function", function: {name: "..."}}`
|
|
151
155
|
- `thinking` (optional): Enable thinking mode `{type: "enabled"}` for enhanced reasoning
|
|
152
156
|
- `json_mode` (optional): Enable JSON output mode (supported by both models)
|
|
157
|
+
- `session_id` (optional): Session ID for multi-turn conversations. Previous context is automatically prepended.
|
|
153
158
|
|
|
154
159
|
**Response includes:**
|
|
155
160
|
- Content with formatting
|
|
@@ -258,6 +263,60 @@ When thinking mode is enabled, `temperature`, `top_p`, `frequency_penalty`, and
|
|
|
258
263
|
|
|
259
264
|
JSON mode ensures the model outputs valid JSON. Include the word "json" in your prompt for best results. Supported by both `deepseek-chat` and `deepseek-reasoner`.
|
|
260
265
|
|
|
266
|
+
**Multi-Turn Session Example:**
|
|
267
|
+
|
|
268
|
+
```json
|
|
269
|
+
{
|
|
270
|
+
"messages": [
|
|
271
|
+
{
|
|
272
|
+
"role": "user",
|
|
273
|
+
"content": "What is the capital of France?"
|
|
274
|
+
}
|
|
275
|
+
],
|
|
276
|
+
"session_id": "my-session-1"
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Use the same `session_id` across requests to maintain conversation context. The server stores messages in memory and automatically prepends history to each request.
|
|
281
|
+
|
|
282
|
+
### `deepseek_sessions`
|
|
283
|
+
|
|
284
|
+
Manage conversation sessions.
|
|
285
|
+
|
|
286
|
+
**Parameters:**
|
|
287
|
+
- `action` (required): "list" | "clear" | "delete"
|
|
288
|
+
- `session_id` (optional): Required when action is "delete"
|
|
289
|
+
|
|
290
|
+
**Examples:**
|
|
291
|
+
```json
|
|
292
|
+
{"action": "list"}
|
|
293
|
+
{"action": "delete", "session_id": "my-session-1"}
|
|
294
|
+
{"action": "clear"}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Available Resources
|
|
298
|
+
|
|
299
|
+
MCP Resources provide read-only data about the server:
|
|
300
|
+
|
|
301
|
+
| Resource URI | Description |
|
|
302
|
+
|-------------|-------------|
|
|
303
|
+
| `deepseek://models` | Available models with capabilities, context limits, and pricing |
|
|
304
|
+
| `deepseek://config` | Current server configuration (API key masked) |
|
|
305
|
+
| `deepseek://usage` | Real-time usage statistics (requests, tokens, costs, sessions) |
|
|
306
|
+
|
|
307
|
+
## Model Fallback & Circuit Breaker
|
|
308
|
+
|
|
309
|
+
When a model fails with a retryable error (429, 503, timeout), the server automatically falls back to the other model:
|
|
310
|
+
- `deepseek-chat` fails → tries `deepseek-reasoner`
|
|
311
|
+
- `deepseek-reasoner` fails → tries `deepseek-chat`
|
|
312
|
+
|
|
313
|
+
The circuit breaker protects against cascading failures:
|
|
314
|
+
- After 5 consecutive failures, the circuit **opens** (fast-fail mode)
|
|
315
|
+
- After 30 seconds, it enters **half-open** state and sends a probe request
|
|
316
|
+
- If the probe succeeds, the circuit **closes** and normal operation resumes
|
|
317
|
+
|
|
318
|
+
Fallback can be disabled with `FALLBACK_ENABLED=false`.
|
|
319
|
+
|
|
261
320
|
## Available Prompts
|
|
262
321
|
|
|
263
322
|
Pre-built prompt templates for common tasks (12 total):
|
|
@@ -320,6 +379,9 @@ The server is configured via environment variables. All settings except `DEEPSEE
|
|
|
320
379
|
| `MAX_RETRIES` | `2` | Maximum retry count for failed requests |
|
|
321
380
|
| `SKIP_CONNECTION_TEST` | `false` | Skip startup API connection test |
|
|
322
381
|
| `MAX_MESSAGE_LENGTH` | `100000` | Maximum message content length (characters) |
|
|
382
|
+
| `SESSION_TTL_MINUTES` | `30` | Session time-to-live in minutes |
|
|
383
|
+
| `MAX_SESSIONS` | `100` | Maximum number of concurrent sessions |
|
|
384
|
+
| `FALLBACK_ENABLED` | `true` | Enable automatic model fallback on errors |
|
|
323
385
|
|
|
324
386
|
**Example with custom config:**
|
|
325
387
|
```bash
|
|
@@ -336,17 +398,26 @@ claude mcp add -s user deepseek npx @arikusi/deepseek-mcp-server \
|
|
|
336
398
|
```
|
|
337
399
|
deepseek-mcp-server/
|
|
338
400
|
├── src/
|
|
339
|
-
│ ├── index.ts # Entry point, bootstrap
|
|
401
|
+
│ ├── index.ts # Entry point, bootstrap
|
|
340
402
|
│ ├── server.ts # McpServer factory (auto-version)
|
|
341
|
-
│ ├── deepseek-client.ts # DeepSeek API wrapper (
|
|
403
|
+
│ ├── deepseek-client.ts # DeepSeek API wrapper (circuit breaker + fallback)
|
|
342
404
|
│ ├── config.ts # Centralized config with Zod validation
|
|
343
405
|
│ ├── cost.ts # Cost calculation and formatting
|
|
344
406
|
│ ├── schemas.ts # Zod input validation schemas
|
|
345
407
|
│ ├── types.ts # TypeScript types + type guards
|
|
346
408
|
│ ├── errors.ts # Custom error classes
|
|
409
|
+
│ ├── session.ts # In-memory session store (multi-turn)
|
|
410
|
+
│ ├── circuit-breaker.ts # Circuit breaker pattern
|
|
411
|
+
│ ├── usage-tracker.ts # Usage statistics tracker
|
|
347
412
|
│ ├── tools/
|
|
348
|
-
│ │ ├── deepseek-chat.ts # deepseek_chat tool
|
|
413
|
+
│ │ ├── deepseek-chat.ts # deepseek_chat tool (sessions + fallback)
|
|
414
|
+
│ │ ├── deepseek-sessions.ts # deepseek_sessions tool
|
|
349
415
|
│ │ └── index.ts # Tool registration aggregator
|
|
416
|
+
│ ├── resources/
|
|
417
|
+
│ │ ├── models.ts # deepseek://models resource
|
|
418
|
+
│ │ ├── config.ts # deepseek://config resource
|
|
419
|
+
│ │ ├── usage.ts # deepseek://usage resource
|
|
420
|
+
│ │ └── index.ts # Resource registration aggregator
|
|
350
421
|
│ └── prompts/
|
|
351
422
|
│ ├── core.ts # 5 core reasoning prompts
|
|
352
423
|
│ ├── advanced.ts # 5 advanced prompts
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Circuit Breaker Pattern
|
|
3
|
+
* Prevents cascading failures by fast-failing when the API is unhealthy
|
|
4
|
+
*
|
|
5
|
+
* States:
|
|
6
|
+
* CLOSED → normal operation, requests pass through
|
|
7
|
+
* OPEN → API is unhealthy, requests are immediately rejected
|
|
8
|
+
* HALF_OPEN → testing if API has recovered with a single probe request
|
|
9
|
+
*/
|
|
10
|
+
import type { CircuitBreakerStatus } from './types.js';
|
|
11
|
+
export declare class CircuitBreaker {
|
|
12
|
+
private readonly threshold;
|
|
13
|
+
private readonly openTimeout;
|
|
14
|
+
private state;
|
|
15
|
+
private failureCount;
|
|
16
|
+
private lastFailureTime;
|
|
17
|
+
private halfOpenInProgress;
|
|
18
|
+
constructor(threshold?: number, openTimeout?: number);
|
|
19
|
+
/**
|
|
20
|
+
* Execute a function through the circuit breaker.
|
|
21
|
+
* - CLOSED: pass through, track failures
|
|
22
|
+
* - OPEN: reject immediately (fast-fail) unless timeout elapsed → HALF_OPEN
|
|
23
|
+
* - HALF_OPEN: allow one probe request
|
|
24
|
+
*/
|
|
25
|
+
execute<T>(fn: () => Promise<T>): Promise<T>;
|
|
26
|
+
/**
|
|
27
|
+
* Get current circuit breaker status
|
|
28
|
+
*/
|
|
29
|
+
getStatus(): CircuitBreakerStatus;
|
|
30
|
+
/**
|
|
31
|
+
* Manually reset the circuit breaker to CLOSED state
|
|
32
|
+
*/
|
|
33
|
+
reset(): void;
|
|
34
|
+
private onSuccess;
|
|
35
|
+
private onFailure;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=circuit-breaker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAuB,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAE5E,qBAAa,cAAc;IAOvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAP9B,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,kBAAkB,CAAS;gBAGhB,SAAS,GAAE,MAAU,EACrB,WAAW,GAAE,MAAc;IAG9C;;;;;OAKG;IACG,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IA+BlD;;OAEG;IACH,SAAS,IAAI,oBAAoB;IAiBjC;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,SAAS;CAYlB"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Circuit Breaker Pattern
|
|
3
|
+
* Prevents cascading failures by fast-failing when the API is unhealthy
|
|
4
|
+
*
|
|
5
|
+
* States:
|
|
6
|
+
* CLOSED → normal operation, requests pass through
|
|
7
|
+
* OPEN → API is unhealthy, requests are immediately rejected
|
|
8
|
+
* HALF_OPEN → testing if API has recovered with a single probe request
|
|
9
|
+
*/
|
|
10
|
+
import { CircuitBreakerOpenError } from './errors.js';
|
|
11
|
+
export class CircuitBreaker {
|
|
12
|
+
threshold;
|
|
13
|
+
openTimeout;
|
|
14
|
+
state = 'CLOSED';
|
|
15
|
+
failureCount = 0;
|
|
16
|
+
lastFailureTime = 0;
|
|
17
|
+
halfOpenInProgress = false;
|
|
18
|
+
constructor(threshold = 5, openTimeout = 30000) {
|
|
19
|
+
this.threshold = threshold;
|
|
20
|
+
this.openTimeout = openTimeout;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Execute a function through the circuit breaker.
|
|
24
|
+
* - CLOSED: pass through, track failures
|
|
25
|
+
* - OPEN: reject immediately (fast-fail) unless timeout elapsed → HALF_OPEN
|
|
26
|
+
* - HALF_OPEN: allow one probe request
|
|
27
|
+
*/
|
|
28
|
+
async execute(fn) {
|
|
29
|
+
if (this.state === 'OPEN') {
|
|
30
|
+
// Check if enough time has elapsed to try half-open
|
|
31
|
+
if (Date.now() - this.lastFailureTime >= this.openTimeout) {
|
|
32
|
+
this.state = 'HALF_OPEN';
|
|
33
|
+
this.halfOpenInProgress = false;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
throw new CircuitBreakerOpenError();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (this.state === 'HALF_OPEN' && this.halfOpenInProgress) {
|
|
40
|
+
throw new CircuitBreakerOpenError('Circuit breaker is half-open — probe request in progress');
|
|
41
|
+
}
|
|
42
|
+
if (this.state === 'HALF_OPEN') {
|
|
43
|
+
this.halfOpenInProgress = true;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const result = await fn();
|
|
47
|
+
this.onSuccess();
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
this.onFailure();
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get current circuit breaker status
|
|
57
|
+
*/
|
|
58
|
+
getStatus() {
|
|
59
|
+
// Auto-transition from OPEN to HALF_OPEN if timeout elapsed
|
|
60
|
+
if (this.state === 'OPEN' &&
|
|
61
|
+
Date.now() - this.lastFailureTime >= this.openTimeout) {
|
|
62
|
+
this.state = 'HALF_OPEN';
|
|
63
|
+
this.halfOpenInProgress = false;
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
state: this.state,
|
|
67
|
+
failureCount: this.failureCount,
|
|
68
|
+
lastFailureTime: this.lastFailureTime,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Manually reset the circuit breaker to CLOSED state
|
|
73
|
+
*/
|
|
74
|
+
reset() {
|
|
75
|
+
this.state = 'CLOSED';
|
|
76
|
+
this.failureCount = 0;
|
|
77
|
+
this.lastFailureTime = 0;
|
|
78
|
+
this.halfOpenInProgress = false;
|
|
79
|
+
}
|
|
80
|
+
onSuccess() {
|
|
81
|
+
if (this.state === 'HALF_OPEN') {
|
|
82
|
+
// Probe succeeded → close circuit
|
|
83
|
+
this.state = 'CLOSED';
|
|
84
|
+
this.halfOpenInProgress = false;
|
|
85
|
+
}
|
|
86
|
+
this.failureCount = 0;
|
|
87
|
+
}
|
|
88
|
+
onFailure() {
|
|
89
|
+
this.failureCount++;
|
|
90
|
+
this.lastFailureTime = Date.now();
|
|
91
|
+
if (this.state === 'HALF_OPEN') {
|
|
92
|
+
// Probe failed → re-open
|
|
93
|
+
this.state = 'OPEN';
|
|
94
|
+
this.halfOpenInProgress = false;
|
|
95
|
+
}
|
|
96
|
+
else if (this.failureCount >= this.threshold) {
|
|
97
|
+
this.state = 'OPEN';
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=circuit-breaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -11,6 +11,9 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
11
11
|
maxRetries: z.ZodDefault<z.ZodNumber>;
|
|
12
12
|
skipConnectionTest: z.ZodDefault<z.ZodBoolean>;
|
|
13
13
|
maxMessageLength: z.ZodDefault<z.ZodNumber>;
|
|
14
|
+
sessionTtlMinutes: z.ZodDefault<z.ZodNumber>;
|
|
15
|
+
maxSessions: z.ZodDefault<z.ZodNumber>;
|
|
16
|
+
fallbackEnabled: z.ZodDefault<z.ZodBoolean>;
|
|
14
17
|
}, "strip", z.ZodTypeAny, {
|
|
15
18
|
apiKey: string;
|
|
16
19
|
baseUrl: string;
|
|
@@ -19,6 +22,9 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
19
22
|
maxRetries: number;
|
|
20
23
|
skipConnectionTest: boolean;
|
|
21
24
|
maxMessageLength: number;
|
|
25
|
+
sessionTtlMinutes: number;
|
|
26
|
+
maxSessions: number;
|
|
27
|
+
fallbackEnabled: boolean;
|
|
22
28
|
}, {
|
|
23
29
|
apiKey: string;
|
|
24
30
|
baseUrl?: string | undefined;
|
|
@@ -27,6 +33,9 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
27
33
|
maxRetries?: number | undefined;
|
|
28
34
|
skipConnectionTest?: boolean | undefined;
|
|
29
35
|
maxMessageLength?: number | undefined;
|
|
36
|
+
sessionTtlMinutes?: number | undefined;
|
|
37
|
+
maxSessions?: number | undefined;
|
|
38
|
+
fallbackEnabled?: boolean | undefined;
|
|
30
39
|
}>;
|
|
31
40
|
export type Config = z.infer<typeof ConfigSchema>;
|
|
32
41
|
/**
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,QAAA,MAAM,YAAY
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWhB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAIlD;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,MAAM,CA4CnC;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAKlC;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC"}
|
package/dist/config.js
CHANGED
|
@@ -12,6 +12,9 @@ const ConfigSchema = z.object({
|
|
|
12
12
|
maxRetries: z.number().min(0).max(10).default(2),
|
|
13
13
|
skipConnectionTest: z.boolean().default(false),
|
|
14
14
|
maxMessageLength: z.number().positive().default(100_000),
|
|
15
|
+
sessionTtlMinutes: z.number().positive().default(30),
|
|
16
|
+
maxSessions: z.number().positive().default(100),
|
|
17
|
+
fallbackEnabled: z.boolean().default(true),
|
|
15
18
|
});
|
|
16
19
|
let cachedConfig = null;
|
|
17
20
|
/**
|
|
@@ -34,6 +37,13 @@ export function loadConfig() {
|
|
|
34
37
|
maxMessageLength: process.env.MAX_MESSAGE_LENGTH
|
|
35
38
|
? parseInt(process.env.MAX_MESSAGE_LENGTH, 10)
|
|
36
39
|
: 100_000,
|
|
40
|
+
sessionTtlMinutes: process.env.SESSION_TTL_MINUTES
|
|
41
|
+
? parseInt(process.env.SESSION_TTL_MINUTES, 10)
|
|
42
|
+
: 30,
|
|
43
|
+
maxSessions: process.env.MAX_SESSIONS
|
|
44
|
+
? parseInt(process.env.MAX_SESSIONS, 10)
|
|
45
|
+
: 100,
|
|
46
|
+
fallbackEnabled: process.env.FALLBACK_ENABLED !== 'false',
|
|
37
47
|
};
|
|
38
48
|
const result = ConfigSchema.safeParse(raw);
|
|
39
49
|
if (!result.success) {
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,8BAA8B,CAAC;IACzD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,0BAA0B,CAAC;IAC7D,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACvC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACpD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IAChD,kBAAkB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC9C,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* DeepSeek API Client
|
|
3
3
|
* Wrapper around OpenAI SDK for DeepSeek API
|
|
4
|
+
* Features: circuit breaker protection, automatic model fallback
|
|
4
5
|
*/
|
|
5
|
-
import type { ChatCompletionParams, ChatCompletionResponse } from './types.js';
|
|
6
|
+
import type { ChatCompletionParams, ChatCompletionResponse, FallbackInfo } from './types.js';
|
|
7
|
+
/** Extended response with optional fallback info */
|
|
8
|
+
export interface ChatCompletionResponseWithFallback extends ChatCompletionResponse {
|
|
9
|
+
fallback?: FallbackInfo;
|
|
10
|
+
}
|
|
6
11
|
export declare class DeepSeekClient {
|
|
7
12
|
private client;
|
|
13
|
+
private circuitBreaker;
|
|
8
14
|
constructor();
|
|
15
|
+
/**
|
|
16
|
+
* Get circuit breaker status
|
|
17
|
+
*/
|
|
18
|
+
getCircuitBreakerStatus(): import("./types.js").CircuitBreakerStatus;
|
|
9
19
|
/**
|
|
10
20
|
* Build request params shared between streaming and non-streaming
|
|
11
21
|
*/
|
|
@@ -15,14 +25,22 @@ export declare class DeepSeekClient {
|
|
|
15
25
|
*/
|
|
16
26
|
private wrapError;
|
|
17
27
|
/**
|
|
18
|
-
*
|
|
28
|
+
* Parse raw API response into ChatCompletionResponse
|
|
19
29
|
*/
|
|
20
|
-
|
|
30
|
+
private parseResponse;
|
|
21
31
|
/**
|
|
22
|
-
* Create a streaming
|
|
32
|
+
* Create a chat completion (non-streaming) with circuit breaker and fallback
|
|
33
|
+
*/
|
|
34
|
+
createChatCompletion(params: ChatCompletionParams): Promise<ChatCompletionResponseWithFallback>;
|
|
35
|
+
/**
|
|
36
|
+
* Create a streaming chat completion with circuit breaker and fallback
|
|
23
37
|
* Returns the full text after streaming completes (buffered)
|
|
24
38
|
*/
|
|
25
|
-
createStreamingChatCompletion(params: ChatCompletionParams): Promise<
|
|
39
|
+
createStreamingChatCompletion(params: ChatCompletionParams): Promise<ChatCompletionResponseWithFallback>;
|
|
40
|
+
/**
|
|
41
|
+
* Internal streaming implementation
|
|
42
|
+
*/
|
|
43
|
+
private streamInternal;
|
|
26
44
|
/**
|
|
27
45
|
* Test API connection
|
|
28
46
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deepseek-client.d.ts","sourceRoot":"","sources":["../src/deepseek-client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"deepseek-client.d.ts","sourceRoot":"","sources":["../src/deepseek-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EAItB,YAAY,EAEb,MAAM,YAAY,CAAC;AAiBpB,oDAAoD;AACpD,MAAM,WAAW,kCAAmC,SAAQ,sBAAsB;IAChF,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAwBD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,cAAc,CAAiB;;IAevC;;OAEG;IACH,uBAAuB;IAIvB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyD1B;;OAEG;IACH,OAAO,CAAC,SAAS;IASjB;;OAEG;IACH,OAAO,CAAC,aAAa;IAoCrB;;OAEG;IACG,oBAAoB,CACxB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,kCAAkC,CAAC;IAoD9C;;;OAGG;IACG,6BAA6B,CACjC,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,kCAAkC,CAAC;IAwC9C;;OAEG;YACW,cAAc;IA4F5B;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;CAazC"}
|