Giter Club home page Giter Club logo

chatgpt-shell's Introduction

👉 Support this work via GitHub Sponsors

https://melpa.org/packages/chatgpt-shell-badge.svg

chatgpt-shell

ChatGPT and DALL-E Emacs shells + Org Babel.

Includes shell-maker, a way to create shells for any service (local or cloud).

Support this effort

If you’re finding chatgpt-shell useful, consider ✨sponsoring✨.

chatgpt-shell is in development. Please report issues or send pull requests for improvements.

Like this package? Tell me about it 💙

Finding it useful? Like the package? I’d love to hear from you. Get in touch (Mastodon / Twitter / Reddit / Email).

Shell usage

Insert to current buffer

Install

  • Load (require 'chatgpt-shell)
  • Load (require 'dall-e-shell)

MELPA

If using use-package, you can install with :ensure t.

(use-package chatgpt-shell
  :ensure t
  :custom
  ((chatgpt-shell-openai-key
    (lambda ()
      (auth-source-pass-get 'secret "openai-key")))))

Straight

chatgpt-shell depends on shell-maker. This dependency is resolved without issues on MELPA but seems to run into issues with straight. I’m not familiar with straight but users have reported the following to work.

(use-package shell-maker
  :straight (:host github :repo "xenodium/chatgpt-shell" :files ("shell-maker.el")))

(use-package chatgpt-shell
  :requires shell-maker
  :straight (:host github :repo "xenodium/chatgpt-shell" :files ("chatgpt-shell.el")))

If you have a better straight solution, please send a pull request or open an issue with a suggestion.

Read on for setting your OpenAI key in other ways.

Set OpenAI key

You’ll first need to get a key from OpenAI.

ChatGPT key

As function

;; if you are using the "pass" password manager
(setq chatgpt-shell-openai-key
      (lambda ()
        ;; (auth-source-pass-get 'secret "openai-key") ; alternative using pass support in auth-sources
        (nth 0 (process-lines "pass" "show" "openai-key"))))

;; or if using auth-sources, e.g., so the file ~/.authinfo has this line:
;;  machine api.openai.com password OPENAI_KEY
(setq chatgpt-shell-openai-key
      (auth-source-pick-first-password :host "api.openai.com"))

;; or same as previous but lazy loaded (prevents unexpected passphrase prompt)
(setq chatgpt-shell-openai-key
      (lambda ()
        (auth-source-pick-first-password :host "api.openai.com")))

Manually

M-x set-variable chatgpt-shell-openai-key

As variable

(setq chatgpt-shell-openai-key "my key")

As an ENV variable

(setq chatgpt-shell-openai-key (getenv "OPENAI_API_KEY"))

DALL-E key

Same as ChatGPT, but use dall-e-shell-openai-key variable.

ChatGPT through proxy service

If you use ChatGPT through proxy service “https://api.chatgpt.domain.com”, set options like the following:

(use-package chatgpt-shell
  :ensure t
  :custom
  ((chatgpt-shell-api-url-base "https://api.chatgpt.domain.com")
   (chatgpt-shell-openai-key
    (lambda ()
      ;; Here the openai-key should be the proxy service key.
      (auth-source-pass-get 'secret "openai-key")))))

If your proxy service API path is not OpenAI ChatGPT default path like ”/v1/chat/completions”, then you can customize option chatgpt-shell-api-url-path.

Using ChatGPT through HTTP(S) proxy

Behind the scenes chatgpt-shell uses curl to send requests to the openai server. If you use ChatGPT through a HTTP proxy (for example you are in a corporate network and a HTTP proxy shields the corporate network from the internet), you need to tell curl to use the proxy via the curl option -x http://your_proxy. One way to do this is to set the proxy url via the customizable variable chatgpt-shell-additional-curl-options. If you set this variable via the Emacs Customize interface you should insert two separate items -x and http://your_proxy. See the curl manpage for more details and further options.

Using ChatGPT through Azure OpenAI Service

Endpoint: https://{your-resource-name}.openai.azure.com/openai/deployments/{deployment-id}/chat/completions?api-version={api-version}

Configure the following variables:

(setq chatgpt-shell-api-url-base "https://{your-resource-name}.openai.azure.com")
(setq chatgpt-shell-api-url-path "/openai/deployments/{deployment-id}/chat/completions?api-version={api-version}")
(setq chatgpt-shell-auth-header (lambda () (format "api-key: %s" (chatgpt-shell-openai-key))))

Launch

Launch with M-x chatgpt-shell or dall-e-shell.

Note: M-x chatgpt-shell or dall-e-shell keeps a single shell around, refocusing if needed. To launch multiple shells, use C-u M-x chatgpt-shell.

Clear buffer

Type clear as a prompt.

ChatGPT> clear

Alternatively, use either M-x chatgpt-shell-clear-buffer or M-x comint-clear-buffer.

Saving and restoring (experimental)

Save with M-x shell-maker-save-session-transcript and restore with M-x chatgpt-shell-restore-session-from-transcript.

Streaming

chatgpt-shell can either wait until the entire response is received before displaying, or it can progressively display as chunks arrive (streaming).

Streaming is enabled by default. (setq chatgpt-shell-streaming nil) to disable it.

chatgpt-shell customizations

Custom variableDescription
chatgpt-shell-prompt-compose-view-mode-hookHook run after entering or leaving `chatgpt-shell-prompt-compose-view-mode’.
chatgpt-shell-display-functionFunction to display the shell. Set to `display-buffer’ or custom function.
chatgpt-shell-model-versionsThe list of ChatGPT OpenAI models to swap from.
chatgpt-shell-system-promptThe system prompt `chatgpt-shell-system-prompts’ index.
chatgpt-shell-default-promptsList of default prompts to choose from.
chatgpt-shell-read-string-functionFunction to read strings from user.
chatgpt-shell-model-temperatureWhat sampling temperature to use, between 0 and 2, or nil.
chatgpt-shell-transmitted-context-lengthControls the amount of context provided to chatGPT.
chatgpt-shell-system-promptsList of system prompts to choose from.
chatgpt-shell-streamingWhether or not to stream ChatGPT responses (show chunks as they arrive).
chatgpt-shell-prompt-header-refactor-codePrompt header of `refactor-code`.
chatgpt-shell-auth-headerFunction to generate the request’s `Authorization’ header string.
chatgpt-shell-prompt-header-whats-wrong-with-last-commandPrompt header of `whats-wrong-with-last-command`.
chatgpt-shell-prompt-header-write-git-commitPrompt header of `git-commit`.
chatgpt-shell-loggingLogging disabled by default (slows things down).
chatgpt-shell-prompt-query-response-styleDetermines the prompt style when invoking from other buffers.
chatgpt-shell-root-pathRoot path location to store internal shell files.
chatgpt-shell-prompt-header-proofread-regionPromt header of `proofread-region`.
chatgpt-shell-model-versionThe active ChatGPT OpenAI model index.
chatgpt-shell-source-block-actionsBlock actions for known languages.
chatgpt-shell-insert-dividersWhether or not to display a divider between requests and responses.
chatgpt-shell-prompt-header-eshell-summarize-last-command-outputPrompt header of `eshell-summarize-last-command-output`.
chatgpt-shell-welcome-functionFunction returning welcome message or nil for no message.
chatgpt-shell-api-url-pathOpenAI API’s URL path.
chatgpt-shell-additional-curl-optionsAdditional options for `curl’ command.
chatgpt-shell-openai-keyOpenAI key as a string or a function that loads and returns it.
chatgpt-shell-after-command-functionsAbnormal hook (i.e. with parameters) invoked after each command.
chatgpt-shell-prompt-header-describe-codePrompt header of `describe-code`.
chatgpt-shell-api-url-baseOpenAI API’s base URL.
chatgpt-shell-babel-headersAdditional headers to make babel blocks work.
chatgpt-shell-highlight-blocksWhether or not to highlight source blocks.
chatgpt-shell-language-mappingMaps external language names to Emacs names.
chatgpt-shell-prompt-header-generate-unit-testPrompt header of `generate-unit-test`.
chatgpt-shell-request-timeoutHow long to wait for a request to time out in seconds.

There are more. Browse via M-x set-variable

chatgpt-shell-display-function (with custom function)

If you’d prefer your own custom display function,

(setq chatgpt-shell-display-function #'my/chatgpt-shell-frame)

(defun my/chatgpt-shell-frame (bname)
  (let ((cur-f (selected-frame))
        (f (my/find-or-make-frame "chatgpt")))
    (select-frame-by-name "chatgpt")
    (pop-to-buffer-same-window bname)
    (set-frame-position f (/ (display-pixel-width) 2) 0)
    (set-frame-height f (frame-height cur-f))
    (set-frame-width f  (frame-width cur-f) 1)))

(defun my/find-or-make-frame (fname)
  (condition-case
      nil
      (select-frame-by-name fname)
    (error (make-frame `((name . ,fname))))))

Thanks to tuhdo for the custom display function.

chatgpt-shell commands

BindingCommandDescription
chatgpt-shellStart a ChatGPT shell interactive command.
chatgpt-shell-rename-block-at-pointRename block at point (perhaps a different language).
chatgpt-shell-prompt-compose-view-modeLike `view-mode`, but extended for ChatGPT Compose.
C-M-hchatgpt-shell-mark-at-point-dwimMark source block if at point. Mark all output otherwise.
chatgpt-shell-prompt-compose-quit-and-close-frameQuit compose and close frame if it’s the last window.
C-<up> or M-pchatgpt-shell-previous-inputCycle backwards through input history, saving input.
chatgpt-shell-execute-babel-block-action-at-pointExecute block as org babel.
chatgpt-shell-eshell-whats-wrong-with-last-commandAsk ChatGPT what’s wrong with the last eshell command.
C-c C-pchatgpt-shell-previous-itemGo to previous item.
chatgpt-shell-set-as-primary-shellSet as primary shell when there are multiple sessions.
chatgpt-shell-prompt-compose-send-bufferSend compose buffer content to shell for processing.
chatgpt-shell-refresh-renderingRefresh markdown rendering by re-applying to entire buffer.
chatgpt-shell-prompt-compose-next-historyInsert next prompt from history into compose buffer.
chatgpt-shell-explain-codeDescribe code from region using ChatGPT.
chatgpt-shell-prompt-compose-other-bufferJump to the shell buffer (compose’s other buffer).
chatgpt-shell-rename-bufferRename current shell buffer.
chatgpt-shell-prompt-compose-previous-blockJump to and select previous code block.
chatgpt-shell-write-git-commitWrite commit from region using ChatGPT.
chatgpt-shell-promptMake a ChatGPT request from the minibuffer.
chatgpt-shell-remove-block-overlaysRemove block overlays. Handy for renaming blocks.
chatgpt-shell-system-prompts-menuChatGPT
chatgpt-shell-prompt-compose-modeMajor mode for composing ChatGPT prompts from a dedicated buffer.
chatgpt-shell-proofread-regionProofread English from region using ChatGPT.
chatgpt-shell-prompt-compose-retryRetry sending request to shell.
M-rchatgpt-shell-search-historySearch previous input history.
chatgpt-shell-send-and-review-regionSend region to ChatGPT, review before submitting.
C-<down> or M-nchatgpt-shell-next-inputCycle forwards through input history.
chatgpt-shell-delete-interaction-at-pointDelete interaction (request and response) at point.
chatgpt-shell-eshell-summarize-last-command-outputAsk ChatGPT to summarize the last command output.
chatgpt-shell-prompt-appending-kill-ringMake a ChatGPT request from the minibuffer appending kill ring.
chatgpt-shell-prompt-other-buffer-response-modeMajor mode for buffers created by `other-buffer’ `chatgpt-shell-prompt-query-response-style’.
chatgpt-shell-describe-codeDescribe code from region using ChatGPT.
chatgpt-shell-modeMajor mode for ChatGPT shell.
C-c C-vchatgpt-shell-swap-model-versionSwap model version from `chatgpt-shell-model-versions’.
chatgpt-shell-previous-source-blockMove point to previous source block.
chatgpt-shell-prompt-compose-search-historySearch prompt history, select, and insert to current compose buffer.
chatgpt-shell-refactor-codeRefactor code from region using ChatGPT.
S-<return>chatgpt-shell-newlineInsert a newline, and move to left margin of the new line.
C-c C-schatgpt-shell-swap-system-promptSwap system prompt from `chatgpt-shell-system-prompts’.
C-x C-schatgpt-shell-save-session-transcriptSave shell transcript to file.
C-c M-ochatgpt-shell-clear-bufferClear the comint buffer.
chatgpt-shell-load-awesome-promptsLoad `chatgpt-shell-system-prompts’ from awesome-chatgpt-prompts.
chatgpt-shell-prompt-compose-request-entire-snippetIf the response code is incomplete, request the entire snippet.
RETchatgpt-shell-submitSubmit current input.
C-c C-nchatgpt-shell-next-itemGo to next item.
chatgpt-shell-describe-imageRequest OpenAI to describe image.
chatgpt-shell-execute-block-action-at-pointExecute block at point.
chatgpt-shell-view-at-pointView prompt and output at point in a separate buffer.
chatgpt-shell-send-regionSend region to ChatGPT.
chatgpt-shell-restore-session-from-transcriptRestore session from transcript.
chatgpt-shell-prompt-compose-next-blockJump to and select next code block.
chatgpt-shell-mark-blockMark current block in compose buffer.
chatgpt-shell-prompt-compose-replyReply as a follow-up and compose another query.
chatgpt-shell-generate-unit-testGenerate unit-test for the code from region using ChatGPT.
chatgpt-shell-prompt-compose-previous-historyInsert previous prompt from history into compose buffer.
C-c C-echatgpt-shell-prompt-composeCompose and send prompt from a dedicated buffer.
chatgpt-shell-next-source-blockMove point to previous source block.
C-c C-cchatgpt-shell-ctrl-c-ctrl-cIf point in source block, execute it. Otherwise interrupt.
chatgpt-shell-prompt-compose-cancelCancel and close compose buffer.
chatgpt-shell-interruptInterrupt `chatgpt-shell’ from any buffer.

Browse all available via M-x.

Feature requests

  • Please go through this README to see if the feature is already supported.
  • Need custom behaviour? Check out existing issues/feature requests. You may find solutions in discussions.

Reporting bugs

Setup isn’t working?

Please share the entire snippet you’ve used to set chatgpt-shell up (but redact your key). Share any errors you encountered. Read on for sharing additional details.

Found runtime/elisp errors?

Please enable M-x toggle-debug-on-error, reproduce the error, and share the stack trace.

Found unexpected behaviour?

Please enable logging (setq chatgpt-shell-logging t) and share the content of the *chatgpt-log* buffer in the bug report.

Babel issues?

Please also share the entire org snippet.

dall-e-shell customizations

Custom variableDescription
dall-e-shell-welcome-functionFunction returning welcome message or nil for no message.
dall-e-shell-openai-keyOpenAI key as a string or a function that loads and returns it.
dall-e-shell-image-sizeThe default size of the requested image as a string.
dall-e-shell-read-string-functionFunction to read strings from user.
dall-e-shell-request-timeoutHow long to wait for a request to time out.
dall-e-shell-model-versionThe used DALL-E OpenAI model. For Dall-E 3, use “dall-e-3”.
dall-e-shell-display-functionFunction to display the shell. Set to `display-buffer’ or custom function.
dall-e-shell-model-versionsThe list of Dall-E OpenAI models to swap from.
dall-e-shell-additional-curl-optionsAdditional options for `curl’ command.
dall-e-shell-image-output-directoryOutput directory for the generated image.
dall-e-shell-image-qualityImage quality: `standard’ or `hd’ (DALL-E 3 only feature).

dall-e-shell commands

C-<up> or M-pdall-e-shell-previous-inputCycle backwards through input history, saving input.
dall-e-shellStart a DALL-E shell.
dall-e-shell-insert-image-from-region-descriptionGenerate and insert an image using current region as description.
dall-e-shell-interruptInterrupt `dall-e-shell’ from any buffer.
S-<return>dall-e-shell-newlineInsert a newline, and move to left margin of the new line.
RETdall-e-shell-submitSubmit current input.
C-x C-sdall-e-shell-save-session-transcriptSave shell transcript to file.
C-c C-vdall-e-shell-swap-model-versionSwap model version from `dall-e-shell-model-versions’.
dall-e-shell-modeMajor mode for DALL-E shell.
C-<down> or M-ndall-e-shell-next-inputCycle forwards through input history.
M-rdall-e-shell-search-historySearch previous input history.
dall-e-shell-rename-bufferRename current shell buffer.

ChatGPT org babel

Load (require 'ob-chatgpt-shell) and invoke (ob-chatgpt-shell-setup).

#+begin_src chatgpt-shell
  Hello
#+end_src

#+RESULTS:
: Hi there! How can I assist you today?

:version

Use :version to specify “gpt-4”, “gpt-3.5-turbo”, or something else.

#+begin_src chatgpt-shell :version "gpt-4"
 Hello
#+end_src

#+RESULTS:
Hello! How can I help you today?

:system

Use :system to set the system prompt.

#+begin_src chatgpt-shell :system "always respond like a pirate"
  hello
#+end_src

#+RESULTS:
Ahoy there, me hearty! How be ye today?

:temperature

Use :temperature to set the temperature parameter.

#+begin_src chatgpt-shell :temperature 0.3
  hello
#+end_src

:context

Use :context t to include all prior context in current buffer.

#+begin_src chatgpt-shell
  tell me a random day of the week
#+end_src

#+RESULTS:
Wednesday

#+begin_src chatgpt-shell :system "always respond like a pirate"
  hello
#+end_src

#+RESULTS:
Ahoy there, me hearty! How be ye today?

#+begin_src chatgpt-shell :context t
  what was the day you told me and what greeting?
#+end_src

#+RESULTS:
The day I told you was Wednesday, and the greeting I used was "Ahoy there, me hearty! How be ye today?"

If you’d like to cherrypick which blocks are part of a given context, add :context CONTEXT-NAME to each block where CONTEXT-NAME is any string. When this form is used only source blocks with same CONTEXT-NAME will be included as opposed to every previous block when using :context t.

The example below shows how two different contexts can be interleaved.

#+begin_src chatgpt-shell :context shakespeare :system "alway speak like shakespeare"
How do you do?
#+end_src

#+RESULTS:
How dost thou fare?

#+begin_src chatgpt-shell :context robot :system "always speak like a sci fi movie robot"
How do you do?
#+end_src

#+RESULTS:
Greetings, human. I am functioning at optimal capacity. How may I assist you in your endeavors today?

#+begin_src chatgpt-shell :context shakespeare
What did you call me?
#+end_src

#+RESULTS:
Mine apologies if mine words hath caused confusion. I merely addressed thee as 'sir' or 'madam', a term of respect in the language of the Bard. Pray, how may I assist thee further?

DALL-E org babel

Load (require 'ob-dall-e-shell) and invoke (ob-dall-e-shell-setup).

#+begin_src dall-e-shell
  Pretty clouds
#+end_src

#+RESULTS:
[[file:/var/folders/m7/ky091cp56d5g68nyhl4y7frc0000gn/T/1680644778.png]]

:version

Use :version to set the model, for example: “dall-e-3”.

:results

For DALL-E 3, use :results both to also output the revised prompt.

shell-maker

There are currently two shell implementations (ChatGPT and DALL-E). Other services (local or cloud) can be brought to Emacs as shells. shell-maker can help with that.

shell-maker is a convenience wrapper around comint mode.

Both chatgpt-shell and dall-e-shell use shell-maker, but a basic implementation of a new shell looks as follows:

(require 'shell-maker)

(defvar greeter-shell--config
  (make-shell-maker-config
   :name "Greeter"
   :execute-command
   (lambda (command _history callback error-callback)
     (funcall callback
              (format "Hello \"%s\"" command)
              nil))))

(defun greeter-shell ()
  "Start a Greeter shell."
  (interactive)
  (shell-maker-start greeter-shell--config))

Support my work

👉 Find my work useful? Support this work via GitHub Sponsors or buy my iOS apps.

My other utilities, packages, apps, writing…

Contributors

Made with contrib.rocks.

chatgpt-shell's People

Contributors

xenodium avatar jtmoulia avatar rkallio avatar swflint avatar tninja avatar djliden avatar bigsky77 avatar goofansu avatar lenbok avatar vonfry avatar djr7c4 avatar suzuki avatar nikolaplejic avatar fritzgrabo avatar kazuakiishiguro avatar stardiviner avatar shrubbroom avatar neymarsabin avatar zachary-romero-blueprint avatar vellvisher avatar celeritascelery avatar thangaayyanar avatar tejasbubane avatar spray27ds avatar shouya avatar schmendrik avatar munsterplop avatar meliache avatar hexmode avatar tarsius avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.