diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d1cb9d7..79a85c1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,9 +14,9 @@ jobs: strategy: matrix: include: - - python-version: "3.9" + - python-version: "3.10" os: ubuntu-latest - - python-version: "3.9" + - python-version: "3.10" os: macos-latest # - python-version: "3.9" # os: window diff --git a/README-en.md b/README-en.md index f67f546..f132179 100644 --- a/README-en.md +++ b/README-en.md @@ -46,6 +46,10 @@ pip install askchat --upgrade Configure environment variables: ```bash +# Initialize configuration (interactive) +chatenv init -i + +# Or manually set environment variables export OPENAI_API_KEY="your-api-key" export OPENAI_API_BASE="https://api.openai.com/v1" export OPENAI_API_BASE_URL="https://api.openai.com" @@ -56,13 +60,13 @@ Note: The `OPENAI_API_BASE` variable takes precedence over the `OPENAI_API_BASE_ ## How to Use -Use environment variables for simple question and answer: +After configuration, use environment variables for simple question and answer: ```bash ask hello world ``` -In addition, you can use `askchat` for more flexible dialogue and `askenv` to manage environment configurations. +In addition, you can use `askchat` for more flexible dialogue. ## AskChat @@ -126,7 +130,6 @@ Default parameters for `askchat`, these are used for direct interaction with Cha | `--api-base` | `--api-base https://api.example.com/v1` | Set the Base URL | | `--api-key` | `-a sk-xxxxxxx` | Provide the OpenAI API key | | `--option` | `-o top_p 1 temperature 0.5` | Set request parameters | -| `--use-env` | `-u prod` | Load environment variables from a specified config, see [AskEnv](#askenv) | Note: Some model APIs, such as Zhishu, use `/v4` as the API base path, in which case use the `--api-base` parameter. @@ -136,7 +139,6 @@ Auxiliary features, such as generating configuration files, debugging logs, prin | Parameter | Example | Explanation | |--------------------------|----------------------------------|---------------------------------------| -| `--generate-config` | `askchat --generate-config` | Generate a configuration file, saved in `~/.askchat/.env` | | `--print-curl` | `askchat hello --print-curl` | Print the actual request URL | | `--debug` | `askchat --debug` | Print debugging logs | | `--valid-models` | `askchat --valid-models` | Print a list of models containing "gpt" in their names | @@ -145,77 +147,6 @@ Auxiliary features, such as generating configuration files, debugging logs, prin Note: `--all-valid-models` will print all available models, including Embedding, dalle-3, tts, etc., use `--valid-models` to filter these out. -## AskEnv - -`askenv` is used to manage different environment configurations, including creating, activating, deleting, etc., making it easy to switch between different channels. - -### Examples - -
-
-
1. Create channel
- askenv -
-
- -
-
-
2. Edit channel
- editenv -
-
- -### Basic Usage - -1. Create a new environment configuration using the `new` command. - - ```bash - askenv new [-a API_KEY] [-b BASE_URL] [--api-base API_BASE] [-m MODEL] - ``` - - Or generate a default config from environment variables using `askchat --generate-config`: - - ```bash - askchat --generate-config - ``` - -2. Activate a certain environment, setting it as the currently used configuration. - - ```bash - askenv use - ``` - -3. Delete a specified environment configuration file. - - ```bash - askenv delete - askenv delete --default - ``` - -4. List all currently available environments. - - ```bash - askenv list - ``` - -5. Show configuration info of a specified environment, or the default environment if no name is specified. - - ```bash - askenv show [name] - ``` - -6. Save the currently activated environment configuration as a specified name's configuration file. - - ```bash - askenv save - ``` - -7. Update one or more settings of a specified or default environment configuration. - - ```bash - askenv config [name] [-a API_KEY] [-b BASE_URL] [--api-base API_BASE] [-m MODEL] - ``` - ## Issues and Feedback If you encounter any problems or have suggestions, feel free to submit an [Issue](https://github.com/cubenlp/askchat/issues). \ No newline at end of file diff --git a/README.md b/README.md index 144dc38..23ce2c6 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,10 @@ pip install askchat --upgrade 配置环境变量: ```bash +# 初始化配置(交互式) +chatenv init -i + +# 或者手动设置环境变量 export OPENAI_API_KEY="your-api-key" export OPENAI_API_BASE="https://api.openai.com/v1" export OPENAI_API_BASE_URL="https://api.openai.com" @@ -52,13 +56,13 @@ export OPENAI_API_MODEL="gpt-3.5-turbo" ## 使用方法 -使用环境变量,进行简单的问答: +配置完成后,进行简单的问答: ```bash ask hello world ``` -除此之外,可使用 `askchat` 进行更灵活的对话,使用 `askenv` 管理环境配置。 +除此之外,可使用 `askchat` 进行更灵活的对话。 ## AskChat @@ -114,7 +118,6 @@ ask hello world | `--api-base` | `--api-base https://api.example.com/v1` | 设置 Base URL | | `--api-key` | `-a sk-xxxxxxx` | 提供 OpenAI API 密钥 | | `--option` | `-o top_p 1 temperature 0.5` | 设置请求参数 | -| `--use-env` | `-u prod` | 使用指定配置文件加载环境变量,详见 [AskEnv](#askenv) | 注:一些模型 API,比如智谱,使用 `/v4` 作为 API 的基础路径,这时得用 `--api-base` 参数。 @@ -124,7 +127,6 @@ ask hello world | 参数 | 示例 | 解释 | |---------------------------|----------------------|--------------------------------------------| -| `--generate-config` | `askchat --generate-config` | 生成配置文件,保存在 `~/.askchat/.env` 中 | | `--print-url` | `askchat hello --print-url` | 打印实际请求的 URL | | `--debug` | `askchat --debug` | 打印调试日志 | | `--valid-models` | `askchat --valid-models` | 打印包含 "gpt" 名称的模型列表 | @@ -133,73 +135,6 @@ ask hello world 注:`--all-valid-models` 会打印所有可用模型,包括 Embedding, dalle-3, tts 等,使用 `--valid-models` 可以过滤掉这些。 -## AskEnv - -`askenv` 用于管理不同的环境配置,包括创建、激活、删除等操作,便于在不同的渠道间切换。 - -### 示例 - -
-
1. 创建渠道
- askenv -
- -
-
2. 编辑渠道
- editenv -
- -### 基本用法 - -1. 创建一个新的环境配置,使用 `new` 命令。 - - ```bash - askenv new [-a API_KEY] [-b BASE_URL] [--api-base API_BASE] [-m MODEL] - ``` - - 或者用 `askchat --generate-config` 从环境变量生成默认配置: - - ```bash - askchat --generate-config - ``` - -2. 激活某个环境,将其设置为当前使用的配置。 - - ```bash - askenv use - ``` - -3. 删除指定的环境配置文件。 - - ```bash - askenv delete - askenv delete --default - ``` - -4. 列出当前所有可用环境。 - - ```bash - askenv list - ``` - -5. 显示指定环境的配置信息,如果没有指定环境名称,则显示默认环境的配置。 - - ```bash - askenv show [name] - ``` - -6. 将当前激活的环境配置保存为指定名称的配置文件。 - - ```bash - askenv save - ``` - -7. 更新指定或默认环境配置的一项或多项设置。 - - ```bash - askenv config [name] [-a API_KEY] [-b BASE_URL] [--api-base API_BASE] [-m MODEL] - ``` - ## 问题和反馈 使用过程中有任何问题或建议,欢迎提交 [Issue](https://github.com/cubenlp/askchat/issues)。 \ No newline at end of file diff --git a/docs/assets/svgs/askenv.svg b/docs/assets/svgs/askenv.svg deleted file mode 100644 index e2f167e..0000000 --- a/docs/assets/svgs/askenv.svg +++ /dev/null @@ -1,391 +0,0 @@ - - - - - - - - - - - - - - - - - ~ ~ e ~ ex ~ exp ~ expo ~ expor ~ export ~ export ~  base  system ~ ex  base  system ~ expor  base  system ~ export  base  system ~ export  base  system ~ export OPENAI_API_MODEL='deepseek-chat'  base  system ~ export OPENAI_API_MODEL='deepseek-chat'  base  system ~ export OPENAI_API_MODEL='deepseek-chat'  base  system export OPENAI_API_MODEL='deepseek-chat' ~ e  base  system ~ export OPENAI_API_MODEL='deepseek-chat'  base  system ~ export OPENAI_API_MODEL='deepseek-chat'  base  system ~ export OPENAI_API_MODEL='deepseek-chat'  base  system ~ export OPENAI_API_MODEL='deepseek-chat'  base  system ~ export OPENAI_API_MODEL='deepseek-chat'  base  system ~ export OPENAI_API_MODEL='deepseek-chat'  base  system ~ export OPENAI_API_KEY=sk-testkey  base  system ~ export OPENAI_API_BASE=https://api.deepseek.com  base  system ~ export OPENAI_API_BASE=https://api.deepseek.com  base  system export OPENAI_API_BASE=https://api.deepseek.com ~ export OPENAI_API_BASE=https://api.deepseek.com  base  system ~ export OPENAI_API_BASE=https://api.deepseek.com  base  system ~ export OPENAI_API_BASE=https://api.deepseek.com  base  system ~ export OPENAI_API_BASE=https://api.deepseek.com  base  system ~ export OPENAI_API_BASE=https://api.deepseek.com  base  system ~ export OPENAI_API_BASE=https://api.deepseek.com  base  system ~ export OPENAI_API_BASE=https://api.deepseek.com  base  system ~ export OPENAI_API_KEY=sk-testkey  base  system export OPENAI_API_KEY=sk-testkey ~ a  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system ~ askchat --  base  system ~ askchat --help  base  system ~ askchat --g  base  system ~ askchat --generate-config  base  system ~ askchat --generate-config  base  system ~ askchat --generate-config  base  system ~ askchat --generate-config  base  system askchat --generate-config Overwrite the existing configuration file /Users/wangzhihong/.askchat/.env? [y/N]: ]: y ]: yCreated config file at /Users/wangzhihong/.askchat/.env~ askchat --generate-config  base  system ~ askchat --generate-config  base  system ~ askchat --generate-config  base  system ~ aske  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv s  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show  base  system ~ askenv show  base  system askenv show "# Description: Env file for askchat.# Current version: 1.1.4# The base url of the API (with suffix /v1)# This will override OPENAI_API_BASE_URL if both are set.OPENAI_API_BASE='https://api.deepseek.com'# The base url of the API (without suffix /v1)OPENAI_API_BASE_URL=''# Your API keyOPENAI_API_KEY='sk-testkey'# The default model name# You can use `askchat --all-valid-models` to see supported modelsOPENAI_API_MODEL='deepseek-chat'~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv sa  base  system ~ askenv save deepseek  base  system ~ askenv save deepseek  base  system ~ askenv save deepseek  base  system ~ askenv save deepseek  base  system ~ askenv save deepseek  base  system ~ askenv save deepseek  base  system askenv save deepseek Warning: Overwriting existing environment 'deepseek'.Do you want to continue? [y/N]: Do you want to continue? [y/N]: y Do you want to continue? [y/N]: yEnvironment 'deepseek' saved.~ askenv save deepseek  base  system ~ askenv save deepseek  base  system ~ askenv save deepseek  base  system ~ askenv save deepseek  base  system ~ askenv save deepseek  base  system ~ askenv save deepseek  base  system ~ askenv save deepseek  base  system ~ askenv l  base  system ~ askenv list  base  system ~ askenv list  base  system ~ askenv list  base  system ~ askenv list  base  system ~ askenv list  base  system askenv list Available environments:- chatgpt- wokaai- ollama- chatanywhere- litellm- one-api- deepseek~ askenv list  base  system ~ askenv list  base  system ~ askenv list  base  system ~ askenv list  base  system ~ askenv list  base  system ~ askenv list  base  system ~ askenv list  base  system ~ askenv save deepseek  base  system ~ askenv sh  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system askenv show ollama #Description: Env file for askchat.#Current version: 1.1.2OPENAI_API_BASE="http://172.23.148.83:11434/v1"OPENAI_API_BASE_URL="http://172.23.148.83:11434"OPENAI_API_KEY=""# The model nameOPENAI_API_MODEL="qwen:0.5b"~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv u  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system askenv use one-api Environment 'one-api' activated.~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askc  base  system ~ askchat --generate-config  base  system ~ askchat --generate-config  base  system ~ askchat --generate-config  base  system ~ askchat --generate-config  base  system ~ askchat --generate-config  base  system ~ askchat --generate-config  base  system ~ askchat -u  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system ~ askchat -u one-api hello world  base  system askchat -u one-api hello world Hello Hello! Hello! How Hello! How can Hello! How can I Hello! How can I assist Hello! How can I assist you Hello! How can I assist you today Hello! How can I assist you today? Hello! How can I assist you today? If Hello! How can I assist you today? If you Hello! How can I assist you today? If you have Hello! How can I assist you today? If you have any Hello! How can I assist you today? If you have any questions Hello! How can I assist you today? If you have any questions or Hello! How can I assist you today? If you have any questions or need Hello! How can I assist you today? If you have any questions or need information n on n on a specific n on a specific topic n on a specific topic, n on a specific topic, feel n on a specific topic, feel free n on a specific topic, feel free to n on a specific topic, feel free to ask n on a specific topic, feel free to ask. n on a specific topic, feel free to ask.~ askenv d  base  system ~ askenv delete test  base  system ~ askenv delete test  base  system ~ askenv delete test  base  system ~ askenv delete test  base  system ~ askenv delete test  base  system ~ askenv delete test  base  system ~ askenv delete test  base  system ~ askenv delete d  base  system ~ askenv delete de  base  system ~ askenv delete dee  base  system ~ askenv delete deep  base  system ~ askenv delete deeps  base  system ~ askenv delete deepse  base  system ~ askenv delete deepse  base  system ~ askenv delete deepsee  base  system ~ askenv delete deepseek  base  system ~ askenv delete deepseek  base  system askenv delete deepseek Environment 'deepseek' deleted.~ export OPENAI_API_KEY=sk-testkey  base  system ~  base  system - \ No newline at end of file diff --git a/docs/assets/svgs/editenv.svg b/docs/assets/svgs/editenv.svg deleted file mode 100644 index c010320..0000000 --- a/docs/assets/svgs/editenv.svg +++ /dev/null @@ -1,206 +0,0 @@ - - - - - - - - - - - - - - - - - ~ ~ a ~ as ~ ask ~ aske ~ asken ~ askenv ~ askenv ~ askenv c ~ askenv co ~ askenv con ~ askenv conf ~  base  system ~ as  base  system ~ aske  base  system ~ askenv  base  system ~ askenv co  base  system ~ askenv con  base  system ~ askenv conf  base  system ~ askenv config -b http://recall:3021 -a sk-123 -m test-model  base  system ~ askenv config -b http://recall:3021 -a sk-123 -m test-model  base  system ~ askenv config -b http://recall:3021 -a sk-123 -m test-model  base  system ~ askenv config -b http://recall:3021 -a sk-123 -m test-model  base  system ~ askenv config -b http://recall:3021 -a sk-123 -m test-model  base  system ~ askenv config -b http://recall:3021 -a sk-123 -m test-model  base  system askenv config -b http://recall:3021 -a sk-123 -m test-model Environment /Users/wangzhihong/.askchat/.env updated.~ a  base  system ~ askenv config -b http://recall:3021 -a sk-123 -m test-model  base  system ~ askenv config -b http://recall:3021 -a sk-123 -m test-model  base  system ~ askenv config -b http://recall:3021 -a sk-123 -m test-model  base  system ~ askenv config -b http://recall:3021 -a sk-123 -m test-model  base  system ~ askenv config -b http://recall:3021 -a sk-123 -m test-model  base  system ~ askenv config -b http://recall:3021 -a sk-123 -m test-model  base  system ~ askenv config -b http://recall:3021 -a sk-123 -m test-model  base  system ~ askenv s  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show ollama  base  system ~ askenv show  base  system ~ askenv show  base  system askenv show #Description: Env file for askchat.#Current version: 1.0.2# The base url of the API (with suffix /v1)# This will override OPENAI_API_BASE_URL if both are set.OPENAI_API_BASE='https://one-api.cubenlp.com/v1'# The base url of the API (without suffix /v1)OPENAI_API_BASE_URL='http://recall:3021'# Your API keyOPENAI_API_KEY='sk-123'# The model name# You can use `askchat --all-valid-models` to see supported modelsOPENAI_API_MODEL='test-model'~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv n  base  system ~ askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 ~ askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 ~ askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 ~ askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 ~ askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 ~ askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 Environment 'test' created.~ askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 ~ askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 ~ askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 ~ askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 ~ askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 ~ askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 ~ askenv new test -a "sk-xxx" -b https://api.example.com -m gpt-4 ~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv show  base  system ~ askenv show ollama  base  system ~ askenv show t  base  system ~ askenv show test  base  system ~ askenv show test  base  system ~ askenv show test  base  system ~ askenv show test  base  system ~ askenv show test  base  system askenv show test "# Description: Env file for askchat.# Current version: 1.1.4OPENAI_API_BASE=''OPENAI_API_BASE_URL='https://api.example.com'OPENAI_API_KEY='sk-xxx'# The default model nameOPENAI_API_MODEL='gpt-4'~ askenv show test  base  system ~ askenv show test  base  system ~ askenv show test  base  system ~ askenv show test  base  system ~ askenv show test  base  system ~ askenv show test  base  system ~ askenv show test  base  system ~ askenv u  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use one-api  base  system ~ askenv use t  base  system ~ askenv use test  base  system ~ askenv use test  base  system ~ askenv use test  base  system ~ askenv use test  base  system ~ askenv use test  base  system askenv use test Environment 'test' activated.~  base  system - \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 825af69..761ed8b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ ] requires-python = ">=3.6" dependencies = [ - "chattool>=4.1.0", + "chattool>=5.0.0", "python-dotenv>=0.17.0", "Click>=8.0", "platformdirs>=2.0.0" @@ -38,7 +38,6 @@ Repository = "https://github.com/cubenlp/askchat" [project.scripts] ask = "askchat.ask:main" askchat = "askchat.cli:main" -askenv = "askchat.askenv:cli" [project.optional-dependencies] dev = [ diff --git a/src/askchat/__init__.py b/src/askchat/__init__.py index ec40eb4..d0830d3 100644 --- a/src/askchat/__init__.py +++ b/src/askchat/__init__.py @@ -2,16 +2,12 @@ __author__ = """Rex Wang""" __email__ = '1073853456@qq.com' -__version__ = '2.0.1' +__version__ = '2.1.0' -from .elements import ChatFileCompletionType, EnvNameCompletionType -from .utils import show_resp, set_keys, initialize_config, write_config +from .elements import ChatFileCompletionType +from .utils import show_resp __all__ = [ "ChatFileCompletionType", - "EnvNameCompletionType", "show_resp", - "set_keys", - "initialize_config", - "write_config", ] \ No newline at end of file diff --git a/src/askchat/askenv.py b/src/askchat/askenv.py deleted file mode 100644 index 70d07b2..0000000 --- a/src/askchat/askenv.py +++ /dev/null @@ -1,136 +0,0 @@ -import click -from askchat import write_config, EnvNameCompletionType -from chattool.const import CHATTOOL_ENV_DIR, CHATTOOL_ENV_FILE -from dotenv import set_key - -help_message = """Manage askchat environments. - -To enable autocompletion, add the following line to your shell configuration file (e.g., .bashrc, .zshrc): - -For zsh users: eval "$(_ASKENV_COMPLETE=zsh_source askenv)" - -For bash users: eval "$(_ASKENV_COMPLETE=bash_source askenv)\"""" - -@click.group(help=help_message) -def cli(): - """askenv CLI for managing askchat environments.""" - if not CHATTOOL_ENV_DIR.exists(): - CHATTOOL_ENV_DIR.mkdir(parents=True) - -@cli.command() -def list(): - """List all environment configurations.""" - configs = [env for env in CHATTOOL_ENV_DIR.glob('*.env')] - if configs: - click.echo("Available environments:") - for config in configs: - click.echo(f"- {config.stem}") - else: - click.echo("No environments found in ~/.askchat/envs.") - -@cli.command() -@click.argument('name') -@click.option('-a', '--api-key', default=None, help='API key') -@click.option('-b', '--base-url', default=None, help='Base URL of the API (without suffix `/v1`)') -@click.option('--api-base', default=None, help='Base URL of the API (with suffix `/v1`)') -@click.option('-m', '--model', default=None, help='Model name') -@click.option('--interactive', '-i', is_flag=True, default=False, help='Enable interactive mode for inputting options') -def new(name, api_key, base_url, api_base, model, interactive): - """Create a new environment configuration.""" - config_path = CHATTOOL_ENV_DIR / f'{name}.env' - if config_path.exists(): - click.echo(f"Warning: Overwriting existing environment '{name}'.") - click.confirm("Do you want to continue?", abort=True) - if interactive: - api_key = click.prompt('API key', default=api_key, hide_input=True) - base_url = click.prompt('Base URL of the API (without suffix `/v1`)', default=base_url) - default_api_base = f"{base_url}/v1" if base_url else api_base - api_base = click.prompt('Base URL of the API (with suffix `/v1`)', default=default_api_base) - model = click.prompt('Default model name', default=model) - write_config(config_path, api_key, model, base_url, api_base, overwrite=True) - -@cli.command() -@click.argument('name', required=False, type=EnvNameCompletionType()) -@click.option('--default', is_flag=True, help='Delete the default environment configuration') -def delete(name, default): - """Delete an environment configuration.""" - if default: - default_config_path = CHATTOOL_ENV_DIR / 'default.env' - if default_config_path.exists(): - default_config_path.unlink() - click.echo("Default environment configuration deleted.") - else: - click.echo("No default environment configuration found.") - else: - if not name: - click.echo("Please specify an environment name or use --default to delete the default configuration.") - return - config_path = CHATTOOL_ENV_DIR / f'{name}.env' - if config_path.exists(): - config_path.unlink() - click.echo(f"Environment '{name}' deleted.") - else: - click.echo(f"Environment '{name}' not found.") - -@cli.command() -@click.argument('name', required=False, type=EnvNameCompletionType()) -def show(name): - """Print environment variables. Show default if no name is provided.""" - config_path = CHATTOOL_ENV_DIR / f'{name}.env' if name else CHATTOOL_ENV_FILE - if config_path.exists(): - with config_path.open() as f: - click.echo(f.read()) - else: - if name: - click.echo(f"Environment '{name}' not found.") - else: - click.echo("No active environment. You can use `askenv new` to new one.") - -@cli.command() -@click.argument('name') -def save(name): - """Save the current environment variables to a file.""" - if CHATTOOL_ENV_FILE.exists(): - content = CHATTOOL_ENV_FILE.read_text() - config_path = CHATTOOL_ENV_DIR / f'{name}.env' - if config_path.exists(): - click.echo(f"Warning: Overwriting existing environment '{name}'.") - click.confirm("Do you want to continue?", abort=True) - config_path.write_text(content) - click.echo(f"Environment '{name}' saved.") - else: - click.echo("No active environment to save.") - -@cli.command() -@click.argument('name', type=EnvNameCompletionType()) -def use(name): - """Activate an environment by replacing the .env file.""" - config_path = CHATTOOL_ENV_DIR / f'{name}.env' - if config_path.exists(): - content = config_path.read_text() - CHATTOOL_ENV_FILE.write_text(content) - click.echo(f"Environment '{name}' activated.") - else: - click.echo(f"Environment '{name}' not found.") - -@cli.command() -@click.option('-a', '--api-key', help='API key') -@click.option('-b', '--base-url', help='Base URL of the API (without suffix `/v1`)') -@click.option('--api-base', help='Base URL of the API (with suffix `/v1`)') -@click.option('-m', '--model', help='Model name') -@click.argument('name', required=False, type=EnvNameCompletionType()) -def config(name, api_key, base_url, api_base, model): - """Update default .env values.""" - if not any([api_key, base_url, api_base, model]): - click.echo("No updates made. Provide at least one option to update.") - return - config_path = CHATTOOL_ENV_DIR / f'{name}.env' if name else CHATTOOL_ENV_FILE - if not config_path.exists(): - click.echo(f"Environment '{config_path}' not found.\n" +\ - "Use `askenv new` to create a new environment." ) - return - write_config(config_path, api_key, model, base_url, api_base) - click.echo(f"Environment {config_path} updated.") - -if __name__ == '__main__': - cli() diff --git a/src/askchat/cli.py b/src/askchat/cli.py index 6a67afe..71d487b 100644 --- a/src/askchat/cli.py +++ b/src/askchat/cli.py @@ -8,8 +8,8 @@ from chattool.const import ( CHATTOOL_CACHE_DIR, CHATTOOL_ENV_DIR, CHATTOOL_ENV_FILE ) -from .elements import EnvNameCompletionType, ChatFileCompletionType -from .utils import show_resp, write_config, initialize_config +from .elements import ChatFileCompletionType +from .utils import show_resp # Version and Config Path VERSION = askchat.__version__ @@ -28,17 +28,6 @@ def setup(): os.makedirs(CHATTOOL_ENV_DIR, exist_ok=True) chattool.load_envs(CHATTOOL_ENV_FILE) -# callback functions for general options -def generate_config_callback(ctx, param, value): - """Generate a configuration file by environment table.""" - if not value: return - # save the config file - if os.path.exists(CHATTOOL_ENV_FILE): - click.confirm(f"Overwrite the existing configuration file {CHATTOOL_ENV_FILE}?", abort=True) - initialize_config(CHATTOOL_ENV_FILE) - print("Created config file at", CHATTOOL_ENV_FILE) - ctx.exit() - def debug_log_callback(ctx, param, value): if not value: return setup() @@ -104,19 +93,6 @@ def load_chat_callback(ctx, param, value): click.echo(f"The specified conversation {CHATTOOL_CACHE_DIR}/{value}.json does not exist." +\ "Please check the chat list with `--list` option.") ctx.exit() -# callback function for --use-env option -def use_env_callback(ctx, param, value): - if not value: - return - env_file = CHATTOOL_ENV_DIR / f"{value}.env" - if env_file.exists(): - content = env_file.read_text() - CHATTOOL_ENV_FILE.write_text(content) - setup() - click.echo(f"Environment '{value}' activated.") - else: - raise click.BadParameter(f"Environment file {env_file} does not exist.") - return value @click.group() def cli(): @@ -129,7 +105,6 @@ def cli(): @click.option('-b', '--base-url', default=None, help='Base URL of the API (without suffix `/v1`)') @click.option('--api-base', default=None, help='Base URL of the API (with suffix `/v1`)') @click.option('-a', '--api-key', default=None, help='OpenAI API key') -@click.option('-u', '--use-env', type=EnvNameCompletionType(), help='Use environment variables from the `~/.askchat/envs`', callback=use_env_callback, expose_value=True) # Chat with history @click.option('-c', is_flag=True, help='Continue the last conversation') @click.option('-r', '--regenerate', is_flag=True, help='Regenerate the last conversation') @@ -140,19 +115,17 @@ def cli(): @click.option('-d', '--delete', type=ChatFileCompletionType(), callback=delete_chat_callback, expose_value=False, help='Delete the conversation from a file') @click.option('--list', is_flag=True, callback=list_chats_callback, expose_value=False, help='List all the conversation files') # Other options -@click.option('--generate-config', is_flag=True, callback=generate_config_callback, expose_value=False, help='Generate a configuration file by environment table') @click.option('--debug', is_flag=True, callback=debug_log_callback, expose_value=False, help='Print debug log') @click.option('--valid-models', is_flag=True, callback=valid_models_callback, expose_value=False, help='Print valid models that contain "gpt" in their names') @click.option('--all-valid-models', is_flag=True, callback=all_valid_models_callback, expose_value=False, help='Print all valid models') @click.option('--print-curl', is_flag=True, help='Print the curl command for the request') @click.option('-v', '--version', is_flag=True, callback=version_callback, expose_value=False, help='Print the version') @click.option('-o', '--option', multiple=True, type=(str, str), help='Additional options for show_resp in the form of key=value') -def main( message, model, base_url, api_base, api_key, use_env +def main( message, model, base_url, api_base, api_key , c, regenerate, p, option, print_curl): """Interact with ChatGPT in terminal via chattool""" setup() message_text = ' '.join(message).strip() - if use_env and not message_text: return # set values for the environment variables if api_key: chattool.const.OPENAI_API_KEY = api_key diff --git a/src/askchat/elements.py b/src/askchat/elements.py index 6ca7bd8..5060e98 100644 --- a/src/askchat/elements.py +++ b/src/askchat/elements.py @@ -1,15 +1,8 @@ import click import click.shell_completion -from chattool.const import CHATTOOL_CONFIG_DIR, CHATTOOL_ENV_DIR +from chattool.const import CHATTOOL_CONFIG_DIR # Autocompletion -# environment name completion -class EnvNameCompletionType(click.ParamType): - name = "envname" - def shell_complete(self, ctx, param, incomplete): - return [ - click.shell_completion.CompletionItem(path.stem) for path in CHATTOOL_ENV_DIR.glob(f"{incomplete}*.env") - ] # chat file completion class ChatFileCompletionType(click.ParamType): name = "chatfile" diff --git a/src/askchat/utils.py b/src/askchat/utils.py index d9b8b72..52896e0 100644 --- a/src/askchat/utils.py +++ b/src/askchat/utils.py @@ -1,6 +1,5 @@ import os -from dotenv import set_key -from chattool import create_env_file, Chat +from chattool import Chat # common functions async def show_resp(chat:Chat, **options): @@ -11,31 +10,4 @@ async def show_resp(chat:Chat, **options): # await asyncio.sleep(0.01) if not msg.endswith('\n'): print() # add a newline if the message doesn't end with one - return msg - -def set_keys(config_file, keys): - """Set multiple keys in the config file.""" - for key, value in keys.items(): - if value: - set_key(config_file, key, value) - -def initialize_config(config_file:str): - """Initialize the config file with the current environment variables.""" - create_env_file(config_file) - set_keys(config_file, { - "OPENAI_API_KEY": os.getenv("OPENAI_API_KEY"), - "OPENAI_API_MODEL": os.getenv("OPENAI_API_MODEL"), - "OPENAI_API_BASE_URL": os.getenv("OPENAI_API_BASE_URL"), - "OPENAI_API_BASE": os.getenv("OPENAI_API_BASE"), - }) - -def write_config(config_file, api_key, model, base_url, api_base, overwrite=False): - """Write the environment variables to a config file.""" - if overwrite or not config_file.exists(): - create_env_file(config_file) - set_keys(config_file, { - "OPENAI_API_KEY": api_key, - "OPENAI_API_MODEL": model, - "OPENAI_API_BASE_URL": base_url, - "OPENAI_API_BASE": api_base, - }) \ No newline at end of file + return msg \ No newline at end of file diff --git a/tests/test_askenv.py b/tests/test_askenv.py deleted file mode 100644 index 26e9879..0000000 --- a/tests/test_askenv.py +++ /dev/null @@ -1,64 +0,0 @@ -import pytest -from click.testing import CliRunner -from askchat.askenv import cli, CHATTOOL_ENV_DIR, CHATTOOL_ENV_FILE -from pathlib import Path - -@pytest.fixture -def runner(): - """Fixture providing a CliRunner for invoking command-line interfaces.""" - return CliRunner() - -@pytest.fixture -def setup_env(): - """Fixture to set up and tear down an environment configuration.""" - env_name = "pytest_env" - config_path = CHATTOOL_ENV_DIR / f"{env_name}.env" - # Setup code before yield - yield env_name, config_path - # Teardown code after yield - if config_path.exists(): - config_path.unlink() - -def test_overwrite_environment_confirm(runner, setup_env): - """Test overwriting an existing environment configuration with user confirmation.""" - env_name, config_path = setup_env - # Create an initial environment - runner.invoke(cli, ["new", env_name, "--api-key", "123"], input="y\n") - - # Attempt to overwrite the environment, confirming the action - result = runner.invoke(cli, ["new", env_name, "--api-key", "456"], input="y\n") - assert "Warning: Overwriting existing environment" in result.output - assert "Do you want to continue?" in result.output - # Verify the environment was overwritten by checking if the new API key is in the file - with open(config_path) as f: - assert "OPENAI_API_KEY='456'" in f.read() - -def test_list_initially_empty(runner, setup_env): - """Ensure no environments are listed when none have been created.""" - env_name, config_path = setup_env - runner.invoke(cli, ["new", env_name, "--api-key", "123"], input="y\n") - result = runner.invoke(cli, ["list"]) - assert env_name in result.output - -def test_delete_environment(runner, setup_env): - """Test deleting an environment configuration.""" - env_name, config_path = setup_env - # First, create an environment to delete - runner.invoke(cli, ["new", env_name, "--api-key", "123"]) - assert config_path.exists() # Ensure the environment was created - # Now, delete it - result = runner.invoke(cli, ["delete", env_name]) - assert result.exit_code == 0 - assert f"Environment '{env_name}' deleted." in result.output - assert not config_path.exists() - -# Example test for the `show` command -def test_show_environment(runner, setup_env): - """Test showing the details of a specific environment configuration.""" - env_name, config_path = setup_env - # Create an environment to show - runner.invoke(cli, ["new", env_name, "--api-key", "abc123"]) - result = runner.invoke(cli, ["show", env_name]) - assert "abc123" in result.output # Checking if the API key is shown - -# Continue writing tests for the remaining commands (save, use, config) following similar patterns.