Skip to content

Commit

Permalink
Merge pull request #3 from RexWzh/rex/continue_chat
Browse files Browse the repository at this point in the history
use more option about chat history
  • Loading branch information
RexWzh authored Nov 22, 2023
2 parents d38b9b3 + e3a1123 commit 6445cce
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 9 deletions.
67 changes: 67 additions & 0 deletions README-ZH.md
Original file line number Diff line number Diff line change
@@ -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
```
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
```
```

## 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
```
2 changes: 1 addition & 1 deletion askchat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

__author__ = """Rex Wang"""
__email__ = '[email protected]'
__version__ = '0.2.0'
__version__ = '0.3.0'

from .askchat import ask
68 changes: 64 additions & 4 deletions askchat/askchat.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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"""
Expand All @@ -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')
Expand Down Expand Up @@ -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" +\
Expand All @@ -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))
msg = asyncio.run(show_resp(chat))
chat.assistant(msg)
chat.save(LAST_CHAT_FILE, mode='w')
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit 6445cce

Please sign in to comment.