From a2a3d4a3055f217161fb1766182f8b9ed641b0ea Mon Sep 17 00:00:00 2001 From: Maximus Date: Thu, 26 Dec 2024 16:45:48 -0700 Subject: [PATCH] added deepseek --- keys.example.json | 3 ++- profiles/deepseek.json | 7 ++++++ settings.js | 1 + src/agent/prompter.js | 5 ++++ src/models/deepseek.js | 56 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 profiles/deepseek.json create mode 100644 src/models/deepseek.js diff --git a/keys.example.json b/keys.example.json index f6939f0..0e3d7dd 100644 --- a/keys.example.json +++ b/keys.example.json @@ -7,5 +7,6 @@ "GROQCLOUD_API_KEY": "", "HUGGINGFACE_API_KEY": "", "QWEN_API_KEY": "", - "XAI_API_KEY": "" + "XAI_API_KEY": "", + "DEEPSEEK_API_KEY": "" } diff --git a/profiles/deepseek.json b/profiles/deepseek.json new file mode 100644 index 0000000..ddae9bb --- /dev/null +++ b/profiles/deepseek.json @@ -0,0 +1,7 @@ +{ + "name": "deepseek", + + "model": "deepseek-chat", + + "embedding": "openai" +} \ No newline at end of file diff --git a/settings.js b/settings.js index 4895833..e21eb3e 100644 --- a/settings.js +++ b/settings.js @@ -18,6 +18,7 @@ export default // "./profiles/llama.json", // "./profiles/qwen.json", // "./profiles/grok.json", + // "./profiles/deepseek.json", // using more than 1 profile requires you to /msg each bot indivually ], diff --git a/src/agent/prompter.js b/src/agent/prompter.js index 5f07eb4..3679fcf 100644 --- a/src/agent/prompter.js +++ b/src/agent/prompter.js @@ -15,6 +15,7 @@ import { GroqCloudAPI } from '../models/groq.js'; import { HuggingFace } from '../models/huggingface.js'; import { Qwen } from "../models/qwen.js"; import { Grok } from "../models/grok.js"; +import { DeepSeek } from '../models/deepseek.js'; export class Prompter { constructor(agent, fp) { @@ -60,6 +61,8 @@ export class Prompter { chat.api = 'qwen'; else if (chat.model.includes('grok')) chat.api = 'xai'; + else if (chat.model.includes('deepseek')) + chat.api = 'deepseek'; else chat.api = 'ollama'; } @@ -87,6 +90,8 @@ export class Prompter { this.chat_model = new Qwen(chat.model, chat.url); else if (chat.api === 'xai') this.chat_model = new Grok(chat.model, chat.url); + else if (chat.api === 'deepseek') + this.chat_model = new DeepSeek(chat.model, chat.url); else throw new Error('Unknown API:', api); diff --git a/src/models/deepseek.js b/src/models/deepseek.js new file mode 100644 index 0000000..395aa8c --- /dev/null +++ b/src/models/deepseek.js @@ -0,0 +1,56 @@ +import OpenAIApi from 'openai'; +import { getKey, hasKey } from '../utils/keys.js'; +import { strictFormat } from '../utils/text.js'; + +export class DeepSeek { + constructor(model_name, url) { + this.model_name = model_name; + + let config = {}; + + config.baseURL = url || 'https://api.deepseek.com'; + config.apiKey = getKey('DEEPSEEK_API_KEY'); + + this.openai = new OpenAIApi(config); + } + + async sendRequest(turns, systemMessage, stop_seq='***') { + let messages = [{'role': 'system', 'content': systemMessage}].concat(turns); + + messages = strictFormat(messages); + + const pack = { + model: this.model_name || "deepseek-chat", + messages, + stop: stop_seq, + }; + + let res = null; + try { + console.log('Awaiting deepseek api response...') + // console.log('Messages:', messages); + let completion = await this.openai.chat.completions.create(pack); + if (completion.choices[0].finish_reason == 'length') + throw new Error('Context length exceeded'); + console.log('Received.') + res = completion.choices[0].message.content; + } + catch (err) { + if ((err.message == 'Context length exceeded' || err.code == 'context_length_exceeded') && turns.length > 1) { + console.log('Context length exceeded, trying again with shorter context.'); + return await this.sendRequest(turns.slice(1), systemMessage, stop_seq); + } else { + console.log(err); + res = 'My brain disconnected, try again.'; + } + } + return res; + } + + async embed(text) { + throw new Error('Embeddings are not supported by Deepseek.'); + } +} + + +