forked from xenodium/chatgpt-shell
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathob-chatgpt-shell.el
129 lines (113 loc) · 4.74 KB
/
ob-chatgpt-shell.el
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
;;; ob-chatgpt-shell.el --- Org babel functions for ChatGPT evaluation -*- lexical-binding: t; -*-
;; Copyright (C) Alvaro Ramirez
;; Author: Alvaro Ramirez
;; URL: https://github.com/xenodium/chatgpt-shell
;; Version: 0.20.1
;; Package-Requires: ((emacs "27.1") (chatgpt-shell "0.39.1"))
;;; License:
;; This program 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, or (at your option)
;; any later version.
;;
;; This program 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 GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;; Commentary:
;; Run and get responses from ChatGPT blocks using org babel.
;;
;; Install with:
;;
;; (require 'ob-chatgpt-shell)
;; (ob-chatgpt-shell-setup)
;;
;; Usage:
;;
;; #+begin_src chatgpt-shell
;; Hello
;; #+end_src
;;; Requirements:
;;; Code:
(require 'chatgpt-shell)
(require 'map)
(require 'ob)
(require 'org-element)
(defvar org-babel-default-header-args:chatgpt-shell '((:results . "raw")
(:version . nil)
(:system . nil)
(:context . nil)
(:temperature . nil)))
(defun org-babel-execute:chatgpt-shell(body params)
"Execute a block of ChatGPT prompt in BODY with org-babel header PARAMS.
This function is called by `org-babel-execute-src-block'"
(message "executing ChatGPT source code block")
(chatgpt-shell-post-messages
(vconcat ;; Vector for json
(when (map-elt params :system)
(list
(list
(cons 'role "system")
(cons 'content (map-elt params :system)))))
(when (map-elt params :context)
(ob-chatgpt-shell--context))
`(((role . "user")
(content . ,body))))
(map-elt params :version)
nil nil
(map-elt params :temperature)))
(defun ob-chatgpt-shell--context ()
"Return the context (what was asked and responded) in all previous blocks."
(let ((context '()))
(mapc
(lambda (src-block)
(add-to-list
'context
(list
(cons 'role "user")
(cons 'content (map-elt src-block 'body))))
(add-to-list
'context
(list
(cons 'role "assistant")
(cons 'content (map-elt src-block 'result)))))
(ob-chatgpt--relevant-source-blocks-before-current))
(nreverse context)))
(defun ob-chatgpt-shell-setup ()
"Set up babel ChatGPT support."
(org-babel-do-load-languages 'org-babel-load-languages
(append org-babel-load-languages
'((chatgpt-shell . t))))
(add-to-list 'org-src-lang-modes '("chatgpt-shell" . text)))
(defun ob-chatgpt--relevant-source-blocks-before-current ()
"Return all previous source blocks from current one."
(when-let ((current-block-pos (let ((element (org-element-context)))
(when (eq (org-element-type element) 'src-block)
(org-element-property :begin element)))))
(seq-filter (lambda (src)
(and (string-equal (map-elt src 'language)
"chatgpt-shell")
(< (map-elt src 'start) current-block-pos)))
(ob-chatgpt--all-source-blocks))))
(defun ob-chatgpt--all-source-blocks ()
"Return all source blocks in buffer."
(org-element-map (org-element-parse-buffer) '(src-block fixed-width)
(lambda (element)
(cond ((eq (org-element-type element) 'src-block)
(list 'start (org-element-property :begin element)
'body (when (org-element-property :value element)
(string-trim (org-element-property :value element)))
'language (when (org-element-property :language element)
(string-trim (org-element-property :language element)))
'result (save-restriction
(goto-char (org-element-property :begin element))
(when (org-babel-where-is-src-block-result)
(goto-char (org-babel-where-is-src-block-result))
(org-babel-read-result)))))))))
(provide 'ob-chatgpt-shell)
;;; ob-chatgpt-shell.el ends here