Advertisement
wrightmikea

elisp AI chat with context

Mar 30th, 2023
329
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 4.64 KB | None | 0 0
  1. ;;-*- lexical-binding: t; -*-
  2. ;;
  3. ;; elisp interactive command that chats with gpt-3.5-turbo maintaining a history of interactions provided on
  4. ;; subsequent queries so that there is context and queries can refer to prior responses
  5. ;;
  6. ;; inspired by: https://pastebin.com/mEDv2zVN
  7. ;; refined from long discussion with ChatGPT-4
  8. ;;
  9. ;; comments? reddit: https://www.reddit.com/r/emacs/comments/11wv3fj/50_line_elisp_script_for_querying_chatgpt_35/
  10. ;;
  11. ;; pre-req: M-x package-list-packages install request.el
  12. (defvar openai-response-buffer (get-buffer-create "*openai-response*"))
  13. (defvar openai-api-key (getenv "OPENAI_API_KEY")) ;; sign up at: https://platform.openai.com/overview
  14.  
  15. (defvar openai-messages `((("role" . "system") ("content" . "You are a helpful assistant."))))
  16. ;; to clear history, eval the next line:
  17. ;; (setq openai-messages `((("role" . "system") ("content" . "You are a helpful assistant."))))
  18.  
  19. (defun openai-prepare-params (prompt)
  20.   "Prepare the parameters for the OpenAI API request using the given prompt."
  21.   `(("model" . "gpt-3.5-turbo")
  22.     ("messages" . ,(vconcat (append openai-messages
  23.                                     `((("role" . "user") ("content" . ,prompt))))))))
  24.  
  25. (defun openai-send-request (url params headers)
  26.   "Send a POST request to the given URL with the specified parameters and headers."
  27.   (request
  28.    url
  29.    :timeout 60
  30.    :type "POST"
  31.    :data (json-encode params)
  32.    :headers headers
  33.    :parser 'json-read))
  34.  
  35. (defun openai-handle-response (response prompt)
  36.   "Handle the OpenAI API response by updating the conversation history and displaying the response."
  37.   (let ((response-text (cdr (assoc 'content
  38.                                    (cdr (assoc 'message
  39.                                                (elt
  40.                                                 (cdr (assoc 'choices response)) 0)))))))
  41.     (with-current-buffer openai-response-buffer
  42.       (when (not (get-buffer-window (buffer-name openai-response-buffer)))
  43.         (let ((window (split-window)))
  44.           (set-window-buffer window openai-response-buffer)))
  45.       (goto-char (point-max))
  46.       (insert (format ">>> %s -- Response: %s"
  47.                       (format-time-string "%Y-%m-%d %H:%M:%S")
  48.                       response-text)))
  49.     (setq openai-messages (append openai-messages
  50.                                   `((("role" . "user") ("content" . ,prompt))
  51.                                     (("role" . "assistant") ("content" . ,response-text)))))))
  52.  
  53. (defun openai-api-request (prompt)
  54.   "Send a request to the OpenAI API with the given prompt and return the response."
  55.   (let* ((url "https://api.openai.com/v1/chat/completions")
  56.          (params (openai-prepare-params prompt))
  57.          (headers `(("Content-Type" . "application/json")
  58.                     ("Authorization" . ,(concat "Bearer " openai-api-key)))))
  59.     (with-current-buffer openai-response-buffer
  60.       (goto-char (point-max))
  61.       (insert "\n\n")
  62.       (insert (format ">>> %s -- Prompt: %s\n" (format-time-string "%Y-%m-%d %H:%M:%S") prompt)))
  63.     (openai-send-request
  64.      url params headers)
  65.     (request
  66.      url
  67.      :timeout 60
  68.      :type "POST"
  69.      :data (json-encode params)
  70.      :headers headers
  71.      :parser 'json-read
  72.      :success (cl-function (lambda (&key data &allow-other-keys)
  73.                              (openai-handle-response data prompt)))
  74.      :error (cl-function (lambda (&key error-thrown data &allow-other-keys)
  75.                            (with-current-buffer openai-response-buffer
  76.                              (goto-char (point-max))
  77.                              (insert "\n")
  78.                              (insert (format "Response Error: %S \n %s \n" error-thrown data))))))))
  79.  
  80. (defun ask-gpt (prompt)
  81.   (interactive "sEnter a prompt: ")
  82.   (openai-api-request prompt))
  83.  
  84. ;;;; test retained context
  85. ;;;; *openai-response* buffer:
  86. ;; >>> 2023-03-30 11:16:26 -- Prompt: pick two numbers
  87. ;; >>> 2023-03-30 11:16:28 -- Response: Sure! How about 7 and 13?
  88.  
  89. ;; >>> 2023-03-30 11:16:37 -- Prompt: sum them
  90. ;; >>> 2023-03-30 11:16:38 -- Response: The sum of 7 and 13 is 20.
  91.  
  92. ;; >>> 2023-03-30 11:18:43 -- Prompt: pick two more numbers
  93. ;; >>> 2023-03-30 11:18:45 -- Response: Alright! How about 3 and 8 this time?
  94.  
  95. ;; >>> 2023-03-30 11:18:51 -- Prompt: sum them
  96. ;; >>> 2023-03-30 11:18:52 -- Response: The sum of 3 and 8 is 11.
  97.  
  98. ;; >>> 2023-03-30 11:19:06 -- Prompt: how many questions have I asked so far
  99. ;; >>> 2023-03-30 11:19:07 -- Response: You have asked 4 questions so far.
  100.  
  101. ;; >>> 2023-03-30 11:19:12 -- Prompt: how many questions have I asked so far
  102. ;; >>> 2023-03-30 11:19:13 -- Response: You have asked 5 questions so far.
  103.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement