mirror of
https://github.com/aljazceru/mentor-mcp-server.git
synced 2025-12-17 05:54:26 +01:00
refactor: update Deepseek API implementation
- Switch to OpenAI SDK for Deepseek API calls - Add openai package dependency - Update configuration for Deepseek API - Update environment variable examples - Improve error handling for API responses This change improves reliability and maintainability by using the official SDK with proper typing and error handling.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
# Deepseek API Configuration
|
# Deepseek API Configuration
|
||||||
DEEPSEEK_API_KEY=your_deepseek_api_key_here
|
DEEPSEEK_API_KEY=your_deepseek_api_key_here
|
||||||
DEEPSEEK_API_BASE_URL=https://api.deepseek.com/v1
|
DEEPSEEK_API_BASE_URL=https://api.deepseek.com
|
||||||
DEEPSEEK_MODEL=deepseek-coder
|
DEEPSEEK_MODEL=deepseek-chat
|
||||||
DEEPSEEK_MAX_RETRIES=3
|
DEEPSEEK_MAX_RETRIES=3
|
||||||
DEEPSEEK_TIMEOUT=30000
|
DEEPSEEK_TIMEOUT=30000
|
||||||
|
|
||||||
|
|||||||
193
package-lock.json
generated
193
package-lock.json
generated
@@ -13,6 +13,7 @@
|
|||||||
"@types/node": "^22.10.10",
|
"@types/node": "^22.10.10",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
|
"openai": "^4.80.1",
|
||||||
"typescript": "^5.7.3"
|
"typescript": "^5.7.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -41,6 +42,40 @@
|
|||||||
"undici-types": "~6.20.0"
|
"undici-types": "~6.20.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/node-fetch": {
|
||||||
|
"version": "2.6.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz",
|
||||||
|
"integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*",
|
||||||
|
"form-data": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/abort-controller": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"event-target-shim": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/agentkeepalive": {
|
||||||
|
"version": "4.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
|
||||||
|
"integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"humanize-ms": "^1.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/asynckit": {
|
"node_modules/asynckit": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
@@ -118,6 +153,15 @@
|
|||||||
"url": "https://dotenvx.com"
|
"url": "https://dotenvx.com"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/event-target-shim": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eventsource": {
|
"node_modules/eventsource": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.2.tgz",
|
||||||
@@ -173,6 +217,25 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/form-data-encoder": {
|
||||||
|
"version": "1.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz",
|
||||||
|
"integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/formdata-node": {
|
||||||
|
"version": "4.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz",
|
||||||
|
"integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"node-domexception": "1.0.0",
|
||||||
|
"web-streams-polyfill": "4.0.0-beta.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.20"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/http-errors": {
|
"node_modules/http-errors": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||||
@@ -189,6 +252,15 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/humanize-ms": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/iconv-lite": {
|
"node_modules/iconv-lite": {
|
||||||
"version": "0.6.3",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||||
@@ -228,6 +300,96 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/node-domexception": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/jimmywarting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://paypal.me/jimmywarting"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/node-fetch": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/openai": {
|
||||||
|
"version": "4.80.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/openai/-/openai-4.80.1.tgz",
|
||||||
|
"integrity": "sha512-+6+bbXFwbIE88foZsBEt36bPkgZPdyFN82clAXG61gnHb2gXdZApDyRrcAHqEtpYICywpqaNo57kOm9dtnb7Cw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "^18.11.18",
|
||||||
|
"@types/node-fetch": "^2.6.4",
|
||||||
|
"abort-controller": "^3.0.0",
|
||||||
|
"agentkeepalive": "^4.2.1",
|
||||||
|
"form-data-encoder": "1.7.2",
|
||||||
|
"formdata-node": "^4.3.2",
|
||||||
|
"node-fetch": "^2.6.7"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"openai": "bin/cli"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"ws": "^8.18.0",
|
||||||
|
"zod": "^3.23.8"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"ws": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"zod": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/openai/node_modules/@types/node": {
|
||||||
|
"version": "18.19.74",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.74.tgz",
|
||||||
|
"integrity": "sha512-HMwEkkifei3L605gFdV+/UwtpxP6JSzM+xFk2Ia6DNFSwSVBRh9qp5Tgf4lNFOMfPVuU0WnkcWpXZpgn5ufO4A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~5.26.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/openai/node_modules/undici-types": {
|
||||||
|
"version": "5.26.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
|
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/proxy-from-env": {
|
"node_modules/proxy-from-env": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
@@ -279,6 +441,12 @@
|
|||||||
"node": ">=0.6"
|
"node": ">=0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.7.3",
|
"version": "5.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
|
||||||
@@ -307,6 +475,31 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/web-streams-polyfill": {
|
||||||
|
"version": "4.0.0-beta.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz",
|
||||||
|
"integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
|
||||||
|
"license": "BSD-2-Clause"
|
||||||
|
},
|
||||||
|
"node_modules/whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/zod": {
|
"node_modules/zod": {
|
||||||
"version": "3.24.1",
|
"version": "3.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz",
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz",
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"@types/node": "^22.10.10",
|
"@types/node": "^22.10.10",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"typescript": "^5.7.3"
|
"typescript": "^5.7.3",
|
||||||
|
"openai": "^4.80.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +1,8 @@
|
|||||||
import axios, { AxiosError, AxiosInstance } from 'axios';
|
import OpenAI from 'openai';
|
||||||
import type { LLMResponse } from '../../types/index.js';
|
import type { LLMResponse } from '../../types/index.js';
|
||||||
import { config } from '../../config.js';
|
import { config } from '../../config.js';
|
||||||
import { sanitizeInput } from '../../utils/prompt.js';
|
import { sanitizeInput } from '../../utils/prompt.js';
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for Deepseek API message format
|
|
||||||
*/
|
|
||||||
interface DeepseekMessage {
|
|
||||||
role: 'system' | 'user' | 'assistant';
|
|
||||||
content: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for Deepseek API response format
|
|
||||||
*/
|
|
||||||
interface DeepseekResponse {
|
|
||||||
choices: Array<{
|
|
||||||
message: {
|
|
||||||
content: string;
|
|
||||||
};
|
|
||||||
finish_reason?: string;
|
|
||||||
}>;
|
|
||||||
usage?: {
|
|
||||||
prompt_tokens: number;
|
|
||||||
completion_tokens: number;
|
|
||||||
total_tokens: number;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for API error response
|
|
||||||
*/
|
|
||||||
interface ApiErrorResponse {
|
|
||||||
message?: string;
|
|
||||||
error?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rate limiter implementation using token bucket algorithm
|
* Rate limiter implementation using token bucket algorithm
|
||||||
*/
|
*/
|
||||||
@@ -75,61 +42,24 @@ class RateLimiter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deepseek API client class
|
* Deepseek API client class using OpenAI SDK
|
||||||
*/
|
*/
|
||||||
class DeepseekClient {
|
class DeepseekClient {
|
||||||
private readonly axiosInstance: AxiosInstance;
|
private readonly client: OpenAI;
|
||||||
private readonly rateLimiter: RateLimiter;
|
private readonly rateLimiter: RateLimiter;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.axiosInstance = axios.create({
|
this.client = new OpenAI({
|
||||||
baseURL: config.api.baseUrl,
|
baseURL: config.api.baseUrl || 'https://api.deepseek.com',
|
||||||
timeout: config.api.timeout,
|
apiKey: config.api.apiKey,
|
||||||
headers: {
|
defaultQuery: { model: config.api.model || 'deepseek-chat' },
|
||||||
'Content-Type': 'application/json',
|
defaultHeaders: { 'api-key': config.api.apiKey }
|
||||||
'Authorization': `Bearer ${config.api.apiKey}`,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.rateLimiter = new RateLimiter(
|
this.rateLimiter = new RateLimiter(
|
||||||
50, // max 50 requests
|
50, // max 50 requests
|
||||||
10 // refill 10 tokens per second
|
10 // refill 10 tokens per second
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add response interceptor for error handling
|
|
||||||
this.axiosInstance.interceptors.response.use(
|
|
||||||
response => response,
|
|
||||||
this.handleApiError.bind(this)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles API errors and transforms them into appropriate responses
|
|
||||||
*/
|
|
||||||
private async handleApiError(error: AxiosError<ApiErrorResponse>): Promise<never> {
|
|
||||||
if (error.response) {
|
|
||||||
// The request was made and the server responded with a status code
|
|
||||||
// that falls out of the range of 2xx
|
|
||||||
const status = error.response.status;
|
|
||||||
const message = error.response.data?.message || error.response.data?.error || error.message;
|
|
||||||
|
|
||||||
switch (status) {
|
|
||||||
case 401:
|
|
||||||
throw new Error('Authentication failed: Invalid API key');
|
|
||||||
case 429:
|
|
||||||
throw new Error('Rate limit exceeded. Please try again later.');
|
|
||||||
case 500:
|
|
||||||
throw new Error('Deepseek API server error. Please try again later.');
|
|
||||||
default:
|
|
||||||
throw new Error(`API error: ${message}`);
|
|
||||||
}
|
|
||||||
} else if (error.request) {
|
|
||||||
// The request was made but no response was received
|
|
||||||
throw new Error('No response received from Deepseek API');
|
|
||||||
} else {
|
|
||||||
// Something happened in setting up the request
|
|
||||||
throw new Error(`Error setting up request: ${error.message}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -147,7 +77,7 @@ class DeepseekClient {
|
|||||||
return await operation();
|
return await operation();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
lastError = error as Error;
|
lastError = error as Error;
|
||||||
if (error instanceof AxiosError && error.response?.status === 429) {
|
if (error instanceof OpenAI.APIError && error.status === 429) {
|
||||||
const delay = baseDelay * Math.pow(2, attempt);
|
const delay = baseDelay * Math.pow(2, attempt);
|
||||||
await new Promise(resolve => setTimeout(resolve, delay));
|
await new Promise(resolve => setTimeout(resolve, delay));
|
||||||
continue;
|
continue;
|
||||||
@@ -180,37 +110,38 @@ class DeepseekClient {
|
|||||||
const sanitizedPrompt = sanitizeInput(prompt);
|
const sanitizedPrompt = sanitizeInput(prompt);
|
||||||
const sanitizedSystemPrompt = sanitizeInput(systemPrompt);
|
const sanitizedSystemPrompt = sanitizeInput(systemPrompt);
|
||||||
|
|
||||||
const messages: DeepseekMessage[] = [
|
|
||||||
{
|
|
||||||
role: 'system',
|
|
||||||
content: sanitizedSystemPrompt,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: 'user',
|
|
||||||
content: sanitizedPrompt,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const response = await this.retryWithExponentialBackoff(async () => {
|
const response = await this.retryWithExponentialBackoff(async () => {
|
||||||
const result = await this.axiosInstance.post<DeepseekResponse>('/chat/completions', {
|
const completion = await this.client.chat.completions.create({
|
||||||
model: config.api.model,
|
messages: [
|
||||||
messages,
|
{ role: 'system', content: sanitizedSystemPrompt },
|
||||||
|
{ role: 'user', content: sanitizedPrompt }
|
||||||
|
],
|
||||||
|
model: config.api.model || 'deepseek-chat',
|
||||||
temperature: 0.7,
|
temperature: 0.7,
|
||||||
max_tokens: 2048,
|
max_tokens: 2048
|
||||||
});
|
});
|
||||||
return result;
|
|
||||||
|
return completion;
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
text: response.data.choices[0].message.content,
|
text: response.choices[0]?.message?.content || '',
|
||||||
isError: false,
|
isError: false,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Deepseek API error:', error);
|
console.error('Deepseek API error:', error);
|
||||||
|
let errorMessage = 'Unknown error occurred';
|
||||||
|
|
||||||
|
if (error instanceof OpenAI.APIError) {
|
||||||
|
errorMessage = error.message;
|
||||||
|
} else if (error instanceof Error) {
|
||||||
|
errorMessage = error.message;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
text: '',
|
text: '',
|
||||||
isError: true,
|
isError: true,
|
||||||
errorMessage: error instanceof Error ? error.message : 'Unknown error occurred',
|
errorMessage
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ function requireEnv(name: string): string {
|
|||||||
|
|
||||||
const apiConfig: APIConfig = {
|
const apiConfig: APIConfig = {
|
||||||
apiKey: requireEnv('DEEPSEEK_API_KEY'),
|
apiKey: requireEnv('DEEPSEEK_API_KEY'),
|
||||||
baseUrl: process.env.DEEPSEEK_API_BASE_URL || 'https://api.deepseek.com/v1',
|
baseUrl: process.env.DEEPSEEK_API_BASE_URL || 'https://api.deepseek.com',
|
||||||
model: process.env.DEEPSEEK_MODEL || 'deepseek-coder',
|
model: process.env.DEEPSEEK_MODEL || 'deepseek-chat',
|
||||||
maxRetries: parseInt(process.env.DEEPSEEK_MAX_RETRIES || '3', 10),
|
maxRetries: parseInt(process.env.DEEPSEEK_MAX_RETRIES || '3', 10),
|
||||||
timeout: parseInt(process.env.DEEPSEEK_TIMEOUT || '30000', 10),
|
timeout: parseInt(process.env.DEEPSEEK_TIMEOUT || '30000', 10),
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user