org-assistant provides support for accessing chat APIs such as ChatGPT in the context of an org notebook.
Org-assistant is available on MELPA
M-x package-install
[RET] org-assistant
[RET]
It provides a function named org-assistant that serves as entrypoint for displaying an org assistant buffer. Also, it can be used in any org file by using a src block like #+BEGIN_SRC assistant or #+BEGIN_SRC ?.
The API Key is looked up via org-assistant-auth-function, which has meen tested using the MacOS Keychain. Alternatively, org-assistant-auth-function can be a string and directly set to your API key.
(setq org-assistant-auth-function "<YOUR_API_KEY>")
Calling org-assistant
interactively will generate an org-assistant buffer for you.
It can be set to a keybinding for quick use like below:
(global-set-key (kbd "C-x C-o") #'org-assistant)
- The org tree is traversed up in order to generate the message list when sending information to the chat endpoint.
- It will only use messages from the branch of the tree that the block that initiated the request is in.
- It does not include example blocks or source blocks that appear later in the org buffer than the initiating block.
- noweb support is enabled for all blocks in the conversation based on the initiating block having the :noweb flag set.
- Example blocks are treated as being responses from the assistant by default if they occur after user messages.
- If the example block is before any user source block, they are treated as system messages to the assistant instead.
See org-babel-execute:assistant for more details.
* Chat User Question
#+BEGIN_SRC ?
Hi
#+END_SRC
AI Response
#+BEGIN_SRC assistant :sender assistant
Hello! How can I assist you today?
#+END_SRC
When the output is set to png file, the image generation APIs are called instead.
* Image Generation User Question
#+BEGIN_SRC ? :file sphere.png
Generate a sphere
#+END_SRC
AI Response
#+RESULTS:
file:sphere.png
You can introspect the sent conversation using the :echo flag.
* Branching Echo
#+BEGIN_SRC ?
This is the user. Repeat verbatim only: "This is the system"
#+END_SRC
#+RESULTS:
#+BEGIN_SRC assistant :sender assistant
"This is the system"
#+END_SRC
** Branch A
#+BEGIN_SRC ? :echo
Response A
#+END_SRC
#+RESULTS:
#+BEGIN_SRC assistant :sender assistant
(user . "This is the user. Repeat verbatim only: \"This is the system\"")
(assistant . "\"This is the system\"")
(user . "Response A")
#+END_SRC
** Branch B
#+BEGIN_SRC ? :echo
Response B
#+END_SRC
#+RESULTS:
#+BEGIN_SRC assistant :sender assistant
(user . "This is the user. Repeat verbatim only: \"This is the system\"")
(assistant . "\"This is the system\"")
(user . "Response B")
#+END_SRC
- org-ai.el is focused more on runtime interaction with AI
- org-assistant.el is focused more on reproducible sessions via org babel
- org-assistant.el supports branching conversations
- org-assistant.el is not meant to be used downstream as a library for AI endpoint interactions.
- In org-assistant.el, all interaction is async using org-babel, which allows for notebook style prompt development
- In org-ai.el, interaction is synchronous and inline, which is better for in-editor use cases
- org-ai.el supports a lot of other AI use cases like text to speech
- Most of the same differences and similarities apply from org-assistant.el and org-ai.el
Set up optional libraries like ‘markdown-mode’ to work with ‘org-assistant’.
If ‘markdown-mode’ is available, it will be used.
Prompt the user for an initial prompt for the assistant.
Then display a window with the buffer containing the response.
Execute a curl shell command for ‘org-assistant’. URL is the endpoint called from ‘org-assistant’. METHOD is the Http method used in the request. REQUEST-ID is the request id, used for debugging purposes. BUFFER is the buffer that the process should output to HEADERS are the headers to send in the request BODY is a JSON object encoded as a string.
(fn &key URL METHOD REQUEST-ID BUFFER HEADERS BODY)
Execute an ‘org-assistant’ in an org-babel context.
PARAMS is used to enable noweb mode. If :echo is set, return the conversation that would be sent to the endpoint instead of evaluating.
If :list-models is set, the ‘org-assistant-models-endpoint’ will be called instead.
:params can be set to a list like ’((max_tokens . 1) (stop . "stop")).
See https://platform.openai.com/docs/api-reference/chat/create for parameters.
TEXT must be empty if :list-models is set.
This is intended to be called via org babel in a src block with Ctrl-C Ctrl-C like:
#+BEGIN_SRC assistant
Hi
#+END_SRC
The response from the assistant will be in the example block following:
#+BEGIN_SRC assistant :sender assistant
Response
#+END_SRC
All of the messages that are in the same branch of the org tree are included in the request to the assistant.
* Question
#+BEGIN_SRC assistant
Hi
#+END_SRC
#+BEGIN_SRC assistant :sender assistant
Response
#+END_SRC
#+BEGIN_SRC assistant
What’s up?
#+END_SRC
Running babel on the second assistant block will send the conversation:
User: Hi
Assistant: Response
User: What’s up?
Running babel on the first assistant block will only include the messages before it:
User: Hi
Only messages in the same branch will be included:
* Question
#+BEGIN_SRC assistant
Hi
#+END_SRC
#+BEGIN_SRC assistant :sender assistant
Response
#+END_SRC
** Branch A
#+BEGIN_SRC assistant
Branch A
#+END_SRC
#+BEGIN_SRC assistant :sender assistant
Branch A Response
#+END_SRC
** Branch B
#+BEGIN_SRC assistant
Branch B
#+END_SRC
#+BEGIN_SRC assistant :sender assistant
Branch B Response
#+END_SRC
If you ran Ctrl-C Ctrl-C on Branch B’s src block the conversation sent to the endpoint would be:
User: Hi
Assistant: Response
User: Branch B
Assistant: Branch B Response
‘org-assistant’ also supports image generation. If the :file attribute is set, the image API will be used.
The following is an example of using the image endpoint:
#+BEGIN_SRC assistant :file output.png
An image of the GNU mascot
#+END_SRC
See ‘org-babel-execute:assistant’.
ARGS is routed as is.
Ask the assistant to explain the function at point.
Ask the assistant to generate a docstring for the function at point.
-
org-assistant-auth-function: Function used to get the secret key. Optionally can be set directly to a string, in which case it will be used as the OpenAI key.
-
org-assistant-mode-visual-line-enabled: When non-nil,
visual-line-mode
is enabled withorg-assistant-mode
. -
org-assistant-buffer-name: The buffer name used for the
org-assistant
buffer. -
org-assistant-mode-line-format: The
mode-line-format
used by theorg-assistant
buffer. Set to nil to usemode-line-format
instead. -
org-assistant-model: The model used for the assistant.
-
org-assistant-curl-command: The path to the curl command used to run requests.
-
org-assistant-endpoint: The endpoint used for the assistant.
org-assistant-endpoint-path-chat
andorg-assistant-endpoint-path-image
contain the paths for the respective APIs. -
org-assistant-endpoint-path-chat: The path used for the chat API. See
org-assistant-endpoint
for the domain. -
org-assistant-endpoint-path-models: The path used for the list models API. See
org-assistant-endpoint
for the domain. -
org-assistant-endpoint-path-image: The endpoint used for the assistant.
-
org-assistant-response-completed-hook: The hook called whenever a
org-assistant
request finishes executing. Called with the arguments: Stream-Id and Message Where: Stream-Id is the stream-id of the request Message is the full contents of the response from the endpoint. The buffer and point are set to the the end of the response. -
org-assistant-parallelism: The max inflight requests to send with
org-assistant
at once. -
org-assistant-chat-extra-parameters-alist: Extra parameters to be sent with a chat request.
Known keys are: temperature top_p n stream stop max-tokens presence-penalty frequency-penalty logit-bias user Should be a alist like '((max_tokens . 10) (user . "emacs")).
This can be overriden on a per-src block basis by specifying the :params argument.
See https://platform.openai.com/docs/api-reference/chat/create for reference.
#+BEGIN_SRC assistant :params '((max_tokens . 10) (user . "emacs"))
Hi
#+END_SRC
- org-assistant-image-extra-parameters-alist: Extra parameters to be sent with an image request.
Known allowed keys are: size user Should be a alist like '((size . "1024x1024") (user . "emacs")).
This can be overriden on a per-src block basis by specifying the :params argument.
See https://platform.openai.com/docs/api-reference/chat/create for reference.
#+BEGIN_SRC assistant :params '((max_tokens . 10) (user . "emacs"))
Hi
#+END_SRC
- org-assistant-execute-curl-process-function:
Function used to execute the shell command for
org-assistant
. Seeorg-assistant--execute-curl-shell-command-request
for expected arguments.
Contributions welcome, but forking preferred. I plan to actively maintain this, but I will be prioritizing features that impact me first.
I'll look at most pull requests eventually, but there is no SLA on those being accepted.
Also, I will only respond to pull requests on a case by case basis. I have no obligation to comment on, justify not accepting, or accept any given pull request. Feel free to start a fork that has more support in that area.
If there's a great pull request that I'm slow on accepting, feel free to fork and rename the project.