Skip to content

Commit 6e00213

Browse files
authored
feat(chat): Add support for chat request (#8)
* feat(chat): Add support for chat request * Impls example * Update changelog
1 parent ff4a7eb commit 6e00213

File tree

4 files changed

+136
-2
lines changed

4 files changed

+136
-2
lines changed

CHANGELOG.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ All notable changes to this project will be documented in this file.
55
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
66

77

8-
## 0.1.0 (Unreleased)
8+
## 0.2.0 (Unreleased)
9+
> Released N/A
10+
11+
* N/A
12+
13+
## 0.1.0
914
> Released N/A
1015
1116
* Initial release

openai-chat.el

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
;;; openai-chat.el --- -*- lexical-binding: t; -*-
2+
3+
;; Copyright (C) 2023 Shen, Jen-Chieh
4+
5+
;; This file is not part of GNU Emacs.
6+
7+
;; This program is free software: you can redistribute it and/or modify
8+
;; it under the terms of the GNU General Public License as published by
9+
;; the Free Software Foundation, either version 3 of the License, or
10+
;; (at your option) any later version.
11+
12+
;; This program is distributed in the hope that it will be useful,
13+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
;; GNU General Public License for more details.
16+
17+
;; You should have received a copy of the GNU General Public License
18+
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
20+
;;; Commentary:
21+
;;
22+
;; Create chat with OpenAI API.
23+
;;
24+
;; See https://platform.openai.com/docs/api-reference/chat
25+
;;
26+
27+
;;; Code:
28+
29+
(require 'openai)
30+
31+
;;
32+
;;; API
33+
34+
;;;###autoload
35+
(cl-defun openai-chat ( messages callback
36+
&key
37+
(key openai-key)
38+
(model "gpt-3.5-turbo")
39+
temperature
40+
top-p
41+
n
42+
stream
43+
stop
44+
max-tokens
45+
presence-penalty
46+
frequency-penalty
47+
logit-bias
48+
(user openai-user))
49+
"Send chat request.
50+
51+
Arguments MESSAGES and CALLBACK are required for this type of request. MESSAGES
52+
is the conversation data. CALLBACK is the execuation after request is made.
53+
54+
Arguments KEY and USER are global options; however, you can overwrite the value
55+
by passing it in.
56+
57+
The rest of the arugments are optional, please see OpenAI API reference page
58+
for more information. Arguments here refer to MODEL, TEMPERATURE, TOP-P, N,
59+
STREAM, STOP, MAX-TOKENS, PRESENCE-PENALTY, FREQUENCY-PENALTY, and LOGIT-BIAS."
60+
(openai-request "https://api.openai.com/v1/chat/completions"
61+
:type "POST"
62+
:headers `(("Content-Type" . "application/json")
63+
("Authorization" . ,(concat "Bearer " key)))
64+
:data (openai--json-encode
65+
`(("model" . ,model)
66+
("messages" . ,messages)
67+
("temperature" . ,temperature)
68+
("top-p" . ,top-p)
69+
("n" . ,n)
70+
("stream" . ,stream)
71+
("stop" . ,stop)
72+
("max_tokens" . ,max-tokens)
73+
("presence_penalty" . ,presence-penalty)
74+
("frequency_penalty" . ,frequency-penalty)
75+
("logit_bias" . ,logit-bias)
76+
("user" . ,user)))
77+
:parser 'json-read
78+
:success (cl-function
79+
(lambda (&key data &allow-other-keys)
80+
(funcall callback data)))))
81+
82+
;;
83+
;;; Application
84+
85+
(defcustom openai-chat-max-tokens 4000
86+
"The maximum number of tokens to generate in the completion."
87+
:type 'integer
88+
:group 'openai)
89+
90+
(defcustom openai-chat-temperature 1.0
91+
"What sampling temperature to use."
92+
:type 'number
93+
:group 'openai)
94+
95+
;;;###autoload
96+
(defun openai-chat-say ()
97+
"Start making a conversation to OpenAI.
98+
99+
This is a ping pong message, so you will only get one response."
100+
(interactive)
101+
(if-let* ((user (read-string "What is your name? " "user"))
102+
(say (read-string "Start the conversation: ")))
103+
(openai-chat `[(("role" . ,user)
104+
("content" . ,say))]
105+
(lambda (data)
106+
(let ((choices (let-alist data .choices)))
107+
(mapc (lambda (choice)
108+
(let-alist choice
109+
(let-alist .message
110+
(message "%s: %s" .role (string-trim .content)))))
111+
choices)))
112+
:max-tokens openai-chat-max-tokens
113+
:temperature openai-chat-temperature
114+
:user (unless (string= user "user") user))
115+
(user-error "Abort, canecel chat operation")))
116+
117+
(provide 'openai-chat)
118+
;;; openai-chat.el ends here

openai-completion.el

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
(user openai-user))
5353
"Send completion request.
5454
55-
Arguments PROMPT and CALLBACK are required for this type of request. PROMPT is
55+
Arguments PROMPT and CALLBACK are required for this type of request. PROMPT is
5656
either the question or instruction to OpenAI. CALLBACK is the execuation after
5757
request is made.
5858

openai.el

+11
Original file line numberDiff line numberDiff line change
@@ -173,5 +173,16 @@ Argument OPTIONS ia an alist use to calculate the frame offset."
173173
(t
174174
(completing-read "Response: " choices nil t))))
175175

176+
;;
177+
;;; Testing
178+
179+
;; The module here is for users to test to see some result.
180+
181+
(defun openai-print-json-encode (object)
182+
"Encode OBJECT to JSON format then print out the result."
183+
(let ((encoded (openai--json-encode object)))
184+
(message "%s" encoded) ; don't pretty it, show the raw!
185+
encoded))
186+
176187
(provide 'openai)
177188
;;; openai.el ends here

0 commit comments

Comments
 (0)