From 451b23804f9124253918b768cfd18cd82ef26a84 Mon Sep 17 00:00:00 2001 From: jcs09018 Date: Thu, 9 Feb 2023 14:57:43 -0800 Subject: [PATCH 1/3] feat(edit): Add Edits module --- openai-edit.el | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 openai-edit.el diff --git a/openai-edit.el b/openai-edit.el new file mode 100644 index 0000000..4bd90ea --- /dev/null +++ b/openai-edit.el @@ -0,0 +1,94 @@ +;;; openai-edit.el --- Edit presented documents with OpenAI API -*- lexical-binding: t; -*- + +;; Copyright (C) 2023 Shen, Jen-Chieh + +;; This file is not part of GNU Emacs. + +;; 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 of the License, 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 this program. If not, see . + +;;; Commentary: +;; +;; Given a prompt and an instruction, the model will return an edited version of +;; the prompt. +;; +;; See https://platform.openai.com/docs/api-reference/edits +;; + +;;; Code: + +(require 'openai) + +(defcustom openai-edit-model "text-davinci-edit-001" + "ID of the model to use. + +You can use the `text-davinci-edit-001' or `code-davinci-edit-001' model with +this endpoint." + :type 'string + :group 'openai) + +(defcustom openai-edit-n 1 + "How many edits to generate for the input and instruction." + :type 'integer + :group 'openai) + +(defcustom openai-edit-temperature 1 + "What sampling temperature to use, between 0 and 2. Higher values like 0.8 +will make the output more random, while lower values like 0.2 will make it more +focused and deterministic. + +We generally recommend altering this or `top_p' but not both." + :type 'integer + :group 'openai) + +(defcustom openai-edit-top-p 1.0 + "An alternative to sampling with temperature, called nucleus sampling, where +the model considers the results of the tokens with top_p probability mass. +So 0.1 means only the tokens comprising the top 10% probability mass are +considered. + +We generally recommend altering this or `temperature' but not both." + :type 'number + :group 'openai) + +;; +;;; API + +(defun openai-edit-create (input instruction callback) + "Creates a new edit for the provided input, instruction, and parameters. + +The INPUT is text to use as a starting point for the edit. The INSTRUCTION that +tells the model how to edit the prompt. + +The argument CALLBACK is execuated after request is made." + (openai-request "https://api.openai.com/v1/edits" + :type "POST" + :headers `(("Content-Type" . "application/json") + ("Authorization" . ,(concat "Bearer " openai-key))) + :data (json-encode + `(("model" . ,openai-edit-model) + ("input" . ,input) + ("instruction" . ,instruction) + ("temperature" . ,openai-edit-temperature) + ("top_p" . ,openai-edit-top-p) + ("n" . ,openai-edit-n))) + :parser 'json-read + :success (cl-function + (lambda (&key data &allow-other-keys) + (funcall callback data))))) + +;; +;;; Application + +(provide 'openai-edit) +;;; openai-edit.el ends here From 438f5de9a44b193db72bfc33c61def90a9f01eea Mon Sep 17 00:00:00 2001 From: jcs090218 Date: Thu, 9 Feb 2023 16:37:25 -0800 Subject: [PATCH 2/3] wip --- openai-completion.el | 26 ++------------------------ openai-edit.el | 41 +++++++++++++++++++++++++++-------------- openai.el | 28 ++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 38 deletions(-) diff --git a/openai-completion.el b/openai-completion.el index 4da3e25..5f5f21b 100644 --- a/openai-completion.el +++ b/openai-completion.el @@ -166,28 +166,6 @@ Argument CALLBACK is a function received one argument which is the JSON data." (lambda (&key data &allow-other-keys) (funcall callback data))))) -;; -;;; Util - -(defun openai-completion--data-choices (data) - "Extract choices from DATA request." - (let ((choices (let-alist data .choices)) ; choices if vector - (texts)) - (mapc (lambda (choice) - (let-alist choice - (push .text texts))) ; text is the only important data in there - choices) - texts)) - -(defun openai-completion--get-choice (choices) - "Return choice from CHOICES." - (cond ((zerop (length choices)) - (user-error "No response, please try again")) - ((= 1 (length choices)) - (car choices)) - (t - (completing-read "Response: " choices nil t)))) - ;; ;;; Application @@ -203,8 +181,8 @@ START and END are selected region boundaries." (lambda (data) (openai--with-buffer initial-buffer (openai--pop-to-buffer initial-buffer) ; make sure to stay in that buffer - (let* ((choices (openai-completion--data-choices data)) - (result (openai-completion--get-choice choices)) + (let* ((choices (openai--data-choices data)) + (result (openai--get-choice choices)) original-point) (when (string-empty-p result) (user-error "No response, please try again")) diff --git a/openai-edit.el b/openai-edit.el index 4bd90ea..fa692f5 100644 --- a/openai-edit.el +++ b/openai-edit.el @@ -72,23 +72,36 @@ tells the model how to edit the prompt. The argument CALLBACK is execuated after request is made." (openai-request "https://api.openai.com/v1/edits" - :type "POST" - :headers `(("Content-Type" . "application/json") - ("Authorization" . ,(concat "Bearer " openai-key))) - :data (json-encode - `(("model" . ,openai-edit-model) - ("input" . ,input) - ("instruction" . ,instruction) - ("temperature" . ,openai-edit-temperature) - ("top_p" . ,openai-edit-top-p) - ("n" . ,openai-edit-n))) - :parser 'json-read - :success (cl-function - (lambda (&key data &allow-other-keys) - (funcall callback data))))) + :type "POST" + :headers `(("Content-Type" . "application/json") + ("Authorization" . ,(concat "Bearer " openai-key))) + :data (json-encode + `(("model" . ,openai-edit-model) + ("input" . ,input) + ("instruction" . ,instruction) + ("temperature" . ,openai-edit-temperature) + ("top_p" . ,openai-edit-top-p) + ("n" . ,openai-edit-n))) + :parser 'json-read + :success (cl-function + (lambda (&key data &allow-other-keys) + (funcall callback data))))) ;; ;;; Application +;;;###autoload +(defun openai-edit-prompt () + "Prompt to ask for edited version." + (interactive) + (let ((input (read-string "Input: ")) + (instruction (read-string "Instruction: "))) + (openai-edit-create input instruction + (lambda (data) + (when-let* ((choices (openai--data-choices data)) + (result (openai--get-choice choices))) + + ))))) + (provide 'openai-edit) ;;; openai-edit.el ends here diff --git a/openai.el b/openai.el index a5302b8..574131f 100644 --- a/openai.el +++ b/openai.el @@ -89,6 +89,9 @@ The URL is the url for `request' function; then BODY is the arguments for rest." :type 'float :group 'openai) +;; +;;; General + (defun openai--2str (obj) "Convert OBJ to string." (format "%s" obj)) @@ -106,6 +109,9 @@ Argument OPTIONS ia an alist use to calculate the frame offset." (max (openai--seq-str-max (mapcar #'cdr options)) (/ (frame-width) openai-annotation-ratio))) +;; +;;; Buffer + (defmacro openai--with-buffer (buffer-or-name &rest body) "Execute BODY ensure the BUFFER-OR-NAME is alive." (declare (indent 1)) @@ -118,5 +124,27 @@ Argument OPTIONS ia an alist use to calculate the frame offset." `((display-buffer-in-direction) (dedicated . t)))) +;; +;;; Choices + +(defun openai--data-choices (data) + "Extract choices from DATA request." + (let ((choices (let-alist data .choices)) ; choices if vector + (texts)) + (mapc (lambda (choice) + (let-alist choice + (push .text texts))) ; text is the only important data in there + choices) + texts)) + +(defun openai--get-choice (choices) + "Return choice from CHOICES." + (cond ((zerop (length choices)) + (user-error "No response, please try again")) + ((= 1 (length choices)) + (car choices)) + (t + (completing-read "Response: " choices nil t)))) + (provide 'openai) ;;; openai.el ends here From 563f0056dbdb285c01f2a51e0cbe376e90bfa290 Mon Sep 17 00:00:00 2001 From: jcs090218 Date: Thu, 9 Feb 2023 16:52:20 -0800 Subject: [PATCH 3/3] Add application layer --- openai-edit.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openai-edit.el b/openai-edit.el index fa692f5..1a4dc81 100644 --- a/openai-edit.el +++ b/openai-edit.el @@ -100,8 +100,8 @@ The argument CALLBACK is execuated after request is made." (lambda (data) (when-let* ((choices (openai--data-choices data)) (result (openai--get-choice choices))) - - ))))) + (kill-new result) + (message "The result is pasted into kill ring")))))) (provide 'openai-edit) ;;; openai-edit.el ends here