;;; llm-chat-claude.el --- Implements claude llm intergration -*- lexical-binding: t; -*- ;; This file is not part of GNU Emacs. ;;; License: ;; llm-chat-claude.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-claude.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-claude-models '("claude-3-7-sonnet-latest" "claude-3-5-haiku-latest" "claude-3-5-sonnet-latest" "claude-3-sonnet-20240229" "claude-3-haiku-20240307")) (cl-defgeneric llm-chat-resolve-model-backend ((backend (eql 'claude)) model) (if (member model llm-chat-claude-models) t)) (defun llm-chat-claude-get-model () (if (member (llm-chat-get-model) llm-chat-claude-models) (llm-chat-get-model) "claude-3-haiku-20240307")) (defun llm-chat-make-claude-backend () (make-llm-chat-backend :api-endpoint "https://api.anthropic.com/v1/messages" :api-key (auth-source-pick-first-password :host "api.anthropic.com") :headers-fn #'llm-chat-claude-headers :json-fn #'llm-chat-claude-json :filter-fn #'llm-chat-claude-filter)) (defun llm-chat-claude-json () (let ((json-object `((model . ,(llm-chat-claude-get-model)) (system . ,(llm-chat-get-system-prompt)) (messages . ,(cdr (llm-chat-get-history))) (temperature . ,(llm-chat-get-temperature)) (max_tokens . 4096) (stream . ,(llm-chat-get-stream?))))) (json-encode json-object))) (defun llm-chat-claude-headers (backend) (list "-H" "anthropic-version: 2023-06-01" "-H" (concat "x-api-key: " (llm-chat-backend-api-key backend)))) (defun llm-chat-claude-filter (proc string) (llm-chat-data-filter proc string #'llm-chat-claude-finished-p #'llm-chat-claude-parse-content)) (defun llm-chat-claude-finished-p (string) (let* ((json-object (json-read-from-string string)) (type (alist-get 'type json-object))) (string-equal type "message_stop"))) (defun llm-chat-claude-parse-content (string) (when-let* ((json-object (json-read-from-string string)) (type (alist-get 'type json-object)) (delta (alist-get 'delta json-object)) (text (alist-get 'text delta))) (when (string-equal type "content_block_delta") text))) (provide 'llm-chat-claude) ;;; llm-chat-claude.el ends here