diff options
Diffstat (limited to 'llm-chat-deepseek.el')
| -rw-r--r-- | llm-chat-deepseek.el | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/llm-chat-deepseek.el b/llm-chat-deepseek.el new file mode 100644 index 0000000..60ff763 --- /dev/null +++ b/llm-chat-deepseek.el @@ -0,0 +1,77 @@ +;;; llm-chat-deepseek.el --- Implements deepseek llm intergration -*- lexical-binding: t; -*- + +;; This file is not part of GNU Emacs. + +;;; License: + +;; llm-chat-deepseek.el is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; llm-chat-deepseek.el is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <https://www.gnu.org/licenses/>. + +;;; Code: + +(require 'llm-chat-api) + +(defvar llm-chat-deepseek-models '("deepseek-chat" "deepseek-coder" "deepseek-reasoner")) + +(cl-defgeneric llm-chat-resolve-model-backend ((backend (eql 'deepseek)) + model) + (if (member model llm-chat-deepseek-models) + t)) + +(defun llm-chat-deepseek-get-model () + (if (member (llm-chat-get-model) llm-chat-deepseek-models) + (llm-chat-get-model) + "deepseek-coder")) + +(defun llm-chat-make-deepseek-backend () + (make-llm-chat-backend + :api-endpoint "https://api.deepseek.com/chat/completions" + :api-key (auth-source-pick-first-password :host "api.deepseek.com") + :headers-fn #'llm-chat-deepseek-headers + :json-fn #'llm-chat-deepseek-json + :filter-fn #'llm-chat-deepseek-filter)) + +(defun llm-chat-deepseek-json () + (let ((json-object `((model . ,(llm-chat-deepseek-get-model)) + (messages . ,(llm-chat-get-history)) + (temperature . ,(llm-chat-get-temperature)) + (stream . ,(llm-chat-get-stream?))))) + (json-encode json-object))) + +(defun llm-chat-deepseek-headers (backend) + (list "-H" (concat "Authorization: " (concat "Bearer " + (llm-chat-backend-api-key backend))))) + +(defun llm-chat-deepseek-filter (proc string) + (llm-chat-data-filter proc string + #'llm-chat-deepseek-finished-p + #'llm-chat-deepseek-parse-content)) + +(defun llm-chat-deepseek-finished-p (match) + (string-equal "[DONE]" match)) + +(defun llm-chat-deepseek-parse-content (string) + (let* ((json-object (json-read-from-string string)) + (choices (alist-get 'choices json-object)) + (first-choice (aref choices 0)) + (delta (alist-get 'delta first-choice)) + (content (alist-get 'content delta nil)) + (reasoning-content (when (assoc 'reasoning_content delta) + (alist-get 'reasoning_content delta nil)))) + (cond + ((and (stringp content) (not (equal content "null"))) content) + ((stringp reasoning-content) reasoning-content)))) + +(provide 'llm-chat-deepseek) + +;;; llm-chat-deepseek.el ends here |