;;; 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 . ;;; 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