From 03eeeed7871800cf704e8bff60aac297c97aae4e Mon Sep 17 00:00:00 2001 From: rex <1073853456@qq.com> Date: Wed, 22 Nov 2023 14:51:29 +0800 Subject: [PATCH 1/3] use more option about chat history --- askchat/askchat.py | 68 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/askchat/askchat.py b/askchat/askchat.py index c4e9351..2a02a5b 100644 --- a/askchat/askchat.py +++ b/askchat/askchat.py @@ -3,12 +3,14 @@ from argparse import ArgumentParser from pprint import pprint from dotenv import load_dotenv, set_key -import asyncio, os, uuid +import asyncio, os, uuid, json, shutil import askchat VERSION = askchat.__version__ CONFIG_PATH = os.path.expanduser("~/.askchat") CONFIG_FILE = os.path.expanduser("~/.askchat/.env") +LAST_CHAT_FILE = os.path.expanduser("~/.askchat/_last_chat.json") +os.makedirs(CONFIG_PATH, exist_ok=True) ## read para from config file if os.path.exists(CONFIG_FILE): load_dotenv(CONFIG_FILE, override=True) @@ -18,9 +20,12 @@ # print the response in a typewriter way async def show_resp(chat, delay=0.01): + msg = '' async for char in chat.async_stream_responses(textonly=True): print(char, end='', flush=True) + msg += char await asyncio.sleep(delay) + return msg def ask(): """Interact with ChatGPT in terminal via chattool""" @@ -45,6 +50,14 @@ def main(): parser.add_argument('-m', '--model', default=None, help='Model name') parser.add_argument('--base-url', default=None, help='base url of the api(without suffix `/v1`)') parser.add_argument("--api-key", default=None, help="API key") + ## Chat with history + parser.add_argument('-c', action='store_true', help='Continue the last conversation') + parser.add_argument('-s', "--save", default=None, help="Save the conversation to a file") + parser.add_argument("-l", "--load", default=None, help="Load the conversation from a file") + parser.add_argument("-p", "--print", default=None, nargs='*', help="Print the conversation from " +\ + "a file or the last conversation if no file is specified") + parser.add_argument("-d", "--delete", default=None, help="Delete the conversation from a file") + parser.add_argument("--list", action="store_true", help="List all the conversation files") ## other options parser.add_argument('--debug', action='store_true', help='Print debug log') parser.add_argument('--valid-models', action='store_true', help='Print valid models that contain "gpt" in their names') @@ -82,7 +95,6 @@ def main(): os.rename(CONFIG_FILE, tmp_file) print(f"Moved old config file to {tmp_file}") # save the config file - os.makedirs(CONFIG_PATH, exist_ok=True) with open(CONFIG_FILE, "w") as f: # description for the config file f.write("#!/bin/bash\n" +\ @@ -102,12 +114,60 @@ def main(): print("Created config file at", CONFIG_FILE) return - # get message, model, and base url + # deal with chat history + call_history = False + ## load chat + if args.load is not None: + new_file = os.path.join(CONFIG_PATH, args.load) + ".json" + shutil.copyfile(new_file, LAST_CHAT_FILE) + print("Loaded conversation from", new_file) + call_history = True + ## save chat + if args.save is not None: + new_file = os.path.join(CONFIG_PATH, args.save) + ".json" + shutil.copyfile(LAST_CHAT_FILE, new_file) + print("Saved conversation to", new_file) + call_history = True + ## delete chat + if args.delete is not None: + new_file = os.path.join(CONFIG_PATH, args.delete) + ".json" + if os.path.exists(new_file): + os.remove(new_file) + print("Deleted conversation at", new_file) + else: + print("No such file", new_file) + call_history = True + ## list chat + if args.list: + print("All conversation files:") + for file in os.listdir(CONFIG_PATH): + if not file.startswith("_") and file.endswith(".json"): + print(" -", file[:-5]) + call_history = True + if call_history: return + ## print chat + if args.print is not None: + names = args.print + assert len(names) <= 1, "Only one file can be specified" + new_file = os.path.join(CONFIG_PATH, names[0]) + ".json" if len(names) else LAST_CHAT_FILE + with open(new_file, "r") as f: + chatlog = json.load(f) + Chat(chatlog).print_log() + call_history = True + + # Initial message msg = args.message if isinstance(msg, list): msg = ' '.join(msg) assert len(msg.strip()), 'Please specify message' + if args.c and os.path.exists(LAST_CHAT_FILE): + with open(LAST_CHAT_FILE, "r") as f: + chatlog = json.load(f) + chatlog.append({"role":"user", "content":msg}) + msg = chatlog # call the function chat = Chat(msg, model=args.model, base_url=args.base_url, api_key=args.api_key) - asyncio.run(show_resp(chat)) \ No newline at end of file + msg = asyncio.run(show_resp(chat)) + chat.assistant(msg) + chat.save(LAST_CHAT_FILE, mode='w') \ No newline at end of file From 3c478390bae990bb3c860d2d514526e6876dcccc Mon Sep 17 00:00:00 2001 From: rex <1073853456@qq.com> Date: Wed, 22 Nov 2023 15:32:32 +0800 Subject: [PATCH 2/3] update documentation --- README-ZH.md | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 30 ++++++++++++++++++++--- 2 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 README-ZH.md diff --git a/README-ZH.md b/README-ZH.md new file mode 100644 index 0000000..aa8c674 --- /dev/null +++ b/README-ZH.md @@ -0,0 +1,67 @@ +# askchat + +[![PyPI版本](https://img.shields.io/pypi/v/askchat.svg)](https://pypi.python.org/pypi/askchat) +[![测试](https://github.com/rexwzh/askchat/actions/workflows/test.yml/badge.svg)](https://github.com/rexwzh/askchat/actions/workflows/test.yml/) +[![文档状态](https://img.shields.io/badge/docs-github_pages-blue.svg)](https://rexwzh.github.io/askchat/) +[![覆盖率](https://codecov.io/gh/rexwzh/askchat/branch/main/graph/badge.svg)](https://codecov.io/gh/rexwzh/askchat) + +终端使用 ChatGPT API 的小工具。 + +## 安装 + +```bash +pip install askchat +``` + +## 使用方法 + +简单运行方式,参数使用默认的环境变量: +```bash +ask hello +``` + +通过 `askchat` 指定其他选项: +```bash +# 使用特定模型提问 +askchat hello -m "baichuan2" --base_url "localhost:8000" +``` + +生成默认选项的配置文件,您可以在 `~/.askchat/.env` 中编辑配置 +```bash +askchat --generate-config +``` + + +其他选项: +```bash +# 当前版本 +askchat -v +# 打印调试日志 +askchat --debug +# 获取包含"gpt"的有效模型 +askchat --valid-models +# 获取所有有效模型 +askchat --all-valid-models +``` + +## 高级用法 + +您可以使用 `askchat` 管理您的对话: + +```bash +askchat hello +# 继续上一次对话:-c +askchat -c 请给我讲个笑话 +# 保存对话:-s/--save +askchat -s joke +# 加载对话:-l/--load +askchat -l joke +# 删除对话:-d/--delete +askchat -d joke +# 列出所有保存的对话:--list +askchat --list +# 打印最后一次对话:-p/--print +askchat -p +# 打印指定的对话:-p/--print +askchat -p joke +``` \ No newline at end of file diff --git a/README.md b/README.md index c7bce4a..f891777 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Coverage](https://codecov.io/gh/rexwzh/askchat/branch/main/graph/badge.svg)](https://codecov.io/gh/rexwzh/askchat) -Interact with ChatGPT in terminal via chattool +Interact with ChatGPT in terminal via chattool. ## Installation @@ -31,14 +31,38 @@ Generate config file for default options: askchat --generate-config ``` +You might edit the config at `~/.askchat/.env`. + Other options: ```bash # current version askchat -v -# Get debug log +# print the debug log askchat --debug # get valid models that contains "gpt" askchat --valid-models # get all valid models askchat --all-valid-models -``` \ No newline at end of file +``` + +## Advance usage + +You can manage your chats with `askchat`: + +```bash +askchat hello +# continue the last chat: -c +askchat -c tell me a joke please +# save the chat: -s/--save +askchat -s joke +# load the chat: -l/--load +askchat -l joke +# delete the chat: -d/--delete +askchat -d joke +# list all saved chats: --list +askchat --list +# print the last chat: -p/--print +askchat -p +# print the given chat: -p/--print +askchat -p joke +``` From e3a11237cda4bf6328e595a69330bd444521f3ef Mon Sep 17 00:00:00 2001 From: rex <1073853456@qq.com> Date: Wed, 22 Nov 2023 15:33:26 +0800 Subject: [PATCH 3/3] update version --- askchat/__init__.py | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/askchat/__init__.py b/askchat/__init__.py index 3c283ca..edf07ca 100644 --- a/askchat/__init__.py +++ b/askchat/__init__.py @@ -2,6 +2,6 @@ __author__ = """Rex Wang""" __email__ = '1073853456@qq.com' -__version__ = '0.2.0' +__version__ = '0.3.0' from .askchat import ask \ No newline at end of file diff --git a/setup.py b/setup.py index 6b348c2..88016c3 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ from setuptools import setup, find_packages -VERSION = '0.2.0' +VERSION = '0.3.0' with open('README.md') as readme_file: readme = readme_file.read()