diff --git a/README.md b/README.md index bd6c6b4..06b1d99 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ cd gpt-cli pip install -r requirements.txt ``` -Add the OpenAI API token to your `.bashrc` file (in the root of your home folder). +Add the OpenAI API key to your `.bashrc` file (in the root of your home folder). In this example we use nano, you can use any text editor. ``` @@ -42,11 +42,23 @@ Run the tool ./gpt.py ``` -You can also use a `.gptrc` file for configuration. See the [Configuration](README.md#Configuration) section below. +If you want to start the program from anywhere, you might want to create an alias in your `.bashrc`. + +``` +alias gpt="/path/to/gpt-cli/gpt.py" +``` + +Alternatively, you can create a symbolic link to the executable in a directory that is in your path, like in the following example. + +``` +ln -s /path/to/gpt-cli/gpt.py /usr/bin/gpt +``` + +You can also use a `gpt.yml` file for configuration. See the [Configuration](README.md#Configuration) section below. ## Usage -Make sure to set the `OPENAI_API_KEY` environment variable to your OpenAI API key (or put it in the `~/.gptrc` file as described below). +Make sure to set the `OPENAI_API_KEY` environment variable to your OpenAI API key (or put it in the `~/.config/gpt-cli/gpt.yml` file as described below). ``` usage: gpt.py [-h] [--no_markdown] [--model MODEL] [--temperature TEMPERATURE] [--top_p TOP_P] @@ -61,7 +73,7 @@ positional arguments: The name of assistant to use. `general` (default) is a generally helpful assistant, `dev` is a software development assistant with shorter responses. You can specify your own assistants in the config file - ~/.gptrc. See the README for more information. + ~/.config/gpt-cli/gpt.yml. See the README for more information. optional arguments: -h, --help show this help message and exit @@ -117,7 +129,7 @@ This will prompt you to edit the command in your `$EDITOR` it before executing i ## Configuration -You can configure the assistants in the config file `~/.gptrc`. The file is a YAML file with the following structure (see also [config.py](./gptcli/config.py)) +You can configure the assistants in the config file `~/.config/gpt-cli/gpt.yml`. The file is a YAML file with the following structure (see also [config.py](./gptcli/config.py)) ```yaml default_assistant: @@ -164,17 +176,21 @@ Ahoy, matey! What be bringing ye to these here waters? Be it treasure or adventu ``` ## Anthropic Claude support + To use Claude, you should have an API key from [Anthropic](https://console.anthropic.com/) (currently there is a waitlist for API access). After getting the API key, you can add an environment variable + ```bash export ANTHROPIC_API_KEY= ``` -or a config line in `~/.gptrc`: + +or a config line in `~/.config/gpt-cli/gpt.yml`: + ```yaml anthropic_api_key: ``` Now you should be able to run `gpt.py` with `--model claude-v1` or `--model claude-instant-v1`: + ```bash ./gpt.py --model claude-v1 ``` - diff --git a/gpt.py b/gpt.py index 4151878..926cd43 100755 --- a/gpt.py +++ b/gpt.py @@ -1,7 +1,6 @@ #!/usr/bin/env python from typing import cast import openai -import os import argparse import sys import logging @@ -18,7 +17,12 @@ CLIUserInputProvider, ) from gptcli.composite import CompositeChatListener -from gptcli.config import GptCliConfig, read_yaml_config +from gptcli.config import ( + CONFIG_FILE_PATHS, + GptCliConfig, + choose_config_file, + read_yaml_config, +) from gptcli.logging import LoggingChatListener from gptcli.cost import PriceChatListener from gptcli.session import ChatSession @@ -50,7 +54,7 @@ def parse_args(config: GptCliConfig): default=config.default_assistant, nargs="?", choices=list(set([*DEFAULT_ASSISTANTS.keys(), *config.assistants.keys()])), - help="The name of assistant to use. `general` (default) is a generally helpful assistant, `dev` is a software development assistant with shorter responses. You can specify your own assistants in the config file ~/.gptrc. See the README for more information.", + help="The name of assistant to use. `general` (default) is a generally helpful assistant, `dev` is a software development assistant with shorter responses. You can specify your own assistants in the config file ~/.config/gpt-cli/gpt.yml. See the README for more information.", ) parser.add_argument( "--no_markdown", @@ -131,10 +135,11 @@ def validate_args(args): def main(): - config_path = os.path.expanduser("~/.gptrc") - config = ( - read_yaml_config(config_path) if os.path.isfile(config_path) else GptCliConfig() - ) + config_file_path = choose_config_file(CONFIG_FILE_PATHS) + if config_file_path: + config = read_yaml_config(config_file_path) + else: + config = GptCliConfig() args = parse_args(config) if args.log_file is not None: @@ -152,7 +157,7 @@ def main(): openai.api_key = config.openai_api_key else: print( - "No API key found. Please set the OPENAI_API_KEY environment variable or `api_key: ` value in ~/.gptrc" + "No API key found. Please set the OPENAI_API_KEY environment variable or `api_key: ` value in ~/.config/gpt-cli/gpt.yml" ) sys.exit(1) @@ -172,6 +177,8 @@ def main(): def run_execute(args, assistant): logger.info( "Starting a non-interactive execution session with prompt '%s'. Assistant config: %s", + args.prompt, + assistant.config, ) if args.execute == "-": args.execute = "".join(sys.stdin.readlines()) diff --git a/gptcli/config.py b/gptcli/config.py index 0cc1100..399c49f 100644 --- a/gptcli/config.py +++ b/gptcli/config.py @@ -1,10 +1,15 @@ import os -from typing import Dict, Optional +from typing import Dict, List, Optional from attr import dataclass import yaml from gptcli.assistant import AssistantConfig +CONFIG_FILE_PATHS = [ + os.path.join(os.path.expanduser("~"), ".config", "gpt-cli", "gpt.yml"), + os.path.join(os.path.expanduser("~"), ".gptrc"), +] + @dataclass class GptCliConfig: @@ -20,6 +25,13 @@ class GptCliConfig: interactive: Optional[bool] = None +def choose_config_file(paths: List[str]) -> str: + for path in paths: + if os.path.isfile(path): + return path + return "" + + def read_yaml_config(file_path: str) -> GptCliConfig: with open(file_path, "r") as file: config = yaml.safe_load(file)