aboutsummaryrefslogtreecommitdiffstats
path: root/elisp/ai-query.el
blob: 3bc621c2c02e071e2b9e0bc1ec197e23a04c3784 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
;;; ai-query.el --- Query an AI over the lakera gandalf game -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2024 Óscar Nájera
;;
;; Author: Óscar Nájera <hi@oscarnajera.com>
;; Maintainer: Óscar Nájera <hi@oscarnajera.com>
;; Created: July 22, 2024
;; Modified: July 22, 2024
;; Version: 0.0.1
;; Package-Requires: ((emacs "27.1"))
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;;  Query an AI over the lakera gandalf game
;;
;;; Code:

(require 'subr-x)
(require 'markdown-mode)

;; Silence byte-compiler.
(defvar url-http-end-of-headers)

(defconst ai-query-api
  "https://gandalf.lakera.ai/api/send-message"
  "AI security endpoint, use it for queries.")

(defun ai-query--request (prompt callback)
  "Async request to API using PROMPT and process with CALLBACK."
  (let ((url-request-method "POST")
        (url-request-extra-headers
         '(("Content-Type" . "application/x-www-form-urlencoded")))
        (url-request-data
         (thread-first
           (list 'prompt prompt)
           (cons '((defender "baseline")))
           (url-build-query-string))))
    (url-retrieve ai-query-api callback)))

(defun ai-query--process-response (_status)
  "Callback function to process response."
  (goto-char url-http-end-of-headers)
  (let ((response (json-parse-buffer)))
    (with-current-buffer (get-buffer-create "*AI reply*")
      (markdown-mode)
      (erase-buffer)
      (insert "# Question\n" (gethash "prompt" response))
      (insert "\n\n# Answer\n\n" (gethash "answer" response))
      (display-buffer (current-buffer)))))

(defun ai-query-request (prompt)
  "Query the API with this PROMPT."
  (thread-first
    (if (use-region-p)
        (buffer-substring-no-properties (region-beginning) (region-end))
      (read-string "What is your question? "))
    (list)
    (interactive))
  (ai-query--request prompt #'ai-query--process-response))

(provide 'ai-query)
;;; ai-query.el ends here