An extensible command-line utility powered by ChatGPT, designed to enhance your productivity.
Gptx is designed to bridge the gap between the ChatGPT API and your shell environment. Seamlessly integrate ChatGPT's natural language processing capabilities with familiar shell functionalities. With Gptx, you can easily script, automate, and elevate your shell tasks with the power of ChatGPT, unlocking a new world of AI-assisted productivity in a terminal environment.
- Chat with ChatGPT from your terminal
- Manage a series of messages as a conversation
- Cache responses from ChatGPT API
- Highly customizable with Hooks and Custom subcommands
Gptx is a single binary command line program. You can download a precompiled binary at the Github releases page.
brew install kohkimakimoto/gptx/gptx
go install github.com/kohkimakimoto/gptx/cmd/gptx@latest
After installing, you can run gptx init
command to initialize the configuration.
gptx init
This command creates a directory ~/.gptx
. It has a configuration file config.toml
.
ℹ️ Note: You can also change the directory path by setting the environment variable
GPTX_HOME
. This directory is used to store the configuration file, along with other files utilized by the gptx command.
Open the configuration file ~/.gptx/config.toml
with your favorite editor, and enter your OpenAI API key in the openai_api_key
field.
# ~/.gptx/config.toml
openai_api_key = "sk-*******"
You can chat with ChatGPT by running the gptx chat
or gptx c
command.
gptx chat "What is the capital city of Japan?"
# -> The capital city of Japan is Tokyo.
Gptx can accept prompt text from STDIN.
echo "What is the most famous landmark in Tokyo?" | gptx chat
# -> The most famous landmark in Tokyo is the Tokyo Tower.
ℹ️ Note: You can use both STDIN and arguments at the same time. They are concatenated with a newline such as
STDIN + "\n" + ARGUMENTS
.
simple_chat_1.mp4
Conversations in Gptx consist of a series of messages. Each conversation has one or more messages. Messages comprise user's message or assistant's message. A user's message is a text that you send to ChatGPT, and a assistant's message is a text that ChatGPT returns to you.
By default, Gptx creates a new conversation for each chat process described above. You can list the created conversations by running the gptx list
or gptx ls
command.
gptx list
ID PROMPT MESSAGES NAME LABEL HOOKS CREATED ELAPSED
1 What is the capital city of Japan? 2 2023-05-03T06:40:24Z 21 seconds ago
2 What is the most famous landmark in Tokyo? 2 2023-05-03T06:40:37Z 8 seconds ago
ℹ️ Note: Conversations are saved to the internal database file
$GPTX_HOME/gptx.db
.
You can display the conversation details by running the gptx inspect
or gptx i
command with conversation ID.
gptx inspect -p 1
ℹ️ Note: The -p option is used for pretty-printing JSON data.
{
"id": 1,
"prompt": "What is the capital city of Japan?",
"created_at": "2023-05-03T06:40:24.465656Z",
"messages": [
{
"role": "user",
"content": "What is the capital city of Japan?"
},
{
"role": "assistant",
"content": "The capital city of Japan is Tokyo."
}
]
}
If you want to send a message in an existing conversation context, you can use the --resume
or -r
option.
gptx chat --resume 1 "What about the USA?"
# -> The capital city of the United States of America (USA) is Washington D.C.
You can assign a unique name to a conversation using the --name
or -n
option. This is helpful if you want to resume the conversation later.
# Create a new conversation with a name.
gptx chat -n city "What is the capital city of Japan?"
# -> The capital city of Japan is Tokyo.
# Resume the conversation by name.
gptx chat -r city "What about the USA?"
# -> The capital city of the United States of America (USA) is Washington D.C.
conversation_1.mp4
By default, Gptx caches the response from ChatGPT API. When you send the exact same message to ChatGPT API, Gptx returns the cached response instead of sending a request to ChatGPT API.
If you don't want to use the cache, you can use the --no-cache
option.
gptx chat --no-cache "What is the capital city of Japan?"
You can also clear the all cache by running the gptx clean
command.
gptx clean
Gptx has an interactive (REPL) mode. You can enter the interactive mode by running the gptx chat
command with --interactive
or -i
option.
gptx chat -i
Welcome to gptx v0.0.1.
Type ".help" for more information.
> What is the capital city of Japan?
The capital city of Japan is Tokyo.
> What about the USA?
The capital city of the United States of America (USA) is Washington D.C.
>
ℹ️ Note: In the interactive mode, your input messages are in the same conversation context.
interactive_mode_1.mp4
The configuration file must be written in TOML.
By default, Gptx loads the configuration file from ~/.gptx/config.toml
.
If you want to change the path, you can set the environment variable GPTX_HOME
and then it will load the configuration file from $GPTX_HOME/config.toml
.
# OpenAI API Key. You can override this value by using the OPENAI_API_KEY environment variable.
openai_api_key = ""
# Default model for Chat API
model = "gpt-3.5-turbo"
# Maximum number of cached responses.
max_cache_length = 100
Gptx hooks offer a powerful mechanism for extending the functionality of your Gptx processes. Designed to inspect and filter the messages, hooks provide the flexibility to execute custom logic both before and after submitting a request to the ChatGPT API. Hooks can generate dynamic prompts, parse outputs, and implement any other custom behavior to tailor your ChatGPT experience to your specific needs.
Gptx has a reference implementation of the hook called Shell Hook. You can use it by running the gptx chat
command with --hook
or -H
option. Try the following command.
gptx chat --hook shell "start http server with python3"
You will see the following output.
python3 -m http.server
Choose an action: Run (r), Copy to clipboard (c), or Nothing (n):
Using the Shell Hook, Gptx is able to generate shell commands based on your input message and then asks for additional action.
shell_hook_1.mp4
Hooks are command line programs that you can write in any programming language. The Gptx chat process goes through a series of steps, with hooks being executed along the way to provide opportunities for modifying the chat process behavior.
The following diagram illustrates the chat process with hooks incorporated.
As you can see in the diagram, there are various points at which hooks are executed: pre-message
, post-message
, and finish
.
These execution points are called Types of hooks.
Hooks specified by the --hook
or -H
option are executed at all of these points.
You can retrieve the hook execution point from the GPTX_HOOK_TYPE
environment variable in the hook programs.
So, the minimum hook written in Bash script is like the following:
#!/usr/bin/env bash
set -e -o pipefail
case "$GPTX_HOOK_TYPE" in
'pre-message')
echo "run pre-message hook"
;;
'post-message')
echo "run post-message hook"
;;
'finish')
echo "run finish hook"
;;
*)
echo "invalid hook kind: $GPTX_HOOK_TYPE" 1>&2
exit 1
;;
esac
Hooks must have a gptx-hook-
prefix in their file name and be executable.
For example, if you want to use the above minimum example hook, you should create a file named gptx-hook-example
and make it executable.
You can place the hooks in the directory indicated by the PATH environment variable, just like general command line programs.
Gptx also provides a libexec
directory under the Gptx home directory (~/.gptx/libexec
by default) for placing executable programs related to Gptx.
The libexec
directory is automatically added to the PATH environment variable while Gptx is running.
It is recommended to place the hook programs in the libexec
directory.
ℹ️ Note: Shell Hook is also placed in the
libexec
directory.
If you run the above example hook, you will see the following output.
gptx chat -H example "Say hello"
# -> run pre-message hook
# -> run post-message hook
# -> Hello! How may I assist you today?
# -> run finish hook
That's it! These are the requirements for implementing the minimum hook. If you want more details, please read the following sections.
Gptx uses environment variables to pass information to hooks. The following environment variables are available to all hooks.
GPTX_HOOK_TYPE
: The type of hook in which the hook is executed. The value is one ofpre-message
,post-message
, orfinish
.GPTX_MESSAGE_INDEX
: The index of the current message within the conversation. The value is an integer starting from0
, with0
representing the first message.GPTX_CONVERSATION_ID
: The ID of the conversation. If the hook processes a new conversation and is in thepre-message
stage, the value is0
. This indicates that the conversation has not been saved and does not have an ID yet.
Hooks are executed at various points during the chat process. You need to implement appropriate logic in the hook programs based on the execution points. If no action is needed at a specific point, you should write programs that ignore it.
The following sections describe the types of hooks in detail.
This hook is executed before sending a message to the ChatGPT API, allowing you to modify the message in advance.
You can read the input prompt text from the file whose path is specified by the GPTX_PROMPT_FILE
environment variable.
The GPTX_PROMPT_FILE
environment variable also indicates the path to the file where the hook should write the modified prompt text.
Example: gptx-hook-translation
#!/usr/bin/env bash
set -e -o pipefail
case "$GPTX_HOOK_TYPE" in
'pre-message')
# read the input prompt text
prompt=$(cat "$GPTX_PROMPT_FILE")
# modify the prompt text and write it to the file
cat << EOF > "$GPTX_PROMPT_FILE"
Translate the following text into Japanese.
Text: $prompt
Japanese:
EOF
;;
'post-message')
# for post-message code...
;;
'finish')
# for post-message code...
;;
*)
echo "invalid hook kind: $GPTX_HOOK_TYPE" 1>&2
exit 1
;;
esac
Output:
gptx chat -H translation hello
# -> こんにちは
This hook is executed after receiving a message from the ChatGPT API, allowing you to modify the AI generated output.
You can read the AI-generated output from the file whose path is specified by the GPTX_COMPLETION_FILE
environment variable.
The GPTX_COMPLETION_FILE
environment variable also indicates the path to the file where the hook should write the modified AI-generated output.
This hook is executed at the last stage of the chat process.
You can read the final output of the chat process from the file whose path is specified by the GPTX_COMPLETION_FILE
environment variable.
You can use this hook to run additional processing with the chat process output.
- You can assign multiple hooks to the
--hook
or-H
option. In this case, the hooks are executed in the order in which they are specified. - You can only assign hooks to the new conversation. Assigned hooks are saved in the conversation object. If you resume the conversation, the saved hooks will be executed.
- The hook can use an exit code
3
as a Cancel signal. If the hook returns an exit code3
, the Gptx process is terminated immediately with no error.
Gptx allows you to add custom subcommands.
Gptx recognizes commands with the gptx-
prefix as these custom subcommands.
For example, if you create a command named gptx-foo
, you can run it as gptx foo
.
As I mentioned in the How do hooks actually work? section, you can place the executable programs in the libexec
directory under the Gptx home directory (~/.gptx/libexec
by default).
The custom subcommands should also be placed in the libexec directory, as it is the recommended location.
Kohki Makimoto kohki.makimoto@gmail.com
The MIT License (MIT)