Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use more option about chat history #3

Merged
merged 3 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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__ = '1073853456@qq.com'
__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 = ''

Check warning on line 23 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L23

Added line #L23 was not covered by tests
async for char in chat.async_stream_responses(textonly=True):
print(char, end='', flush=True)
msg += char

Check warning on line 26 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L26

Added line #L26 was not covered by tests
await asyncio.sleep(delay)
return msg

Check warning on line 28 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L28

Added line #L28 was not covered by tests

def ask():
"""Interact with ChatGPT in terminal via chattool"""
Expand All @@ -45,6 +50,14 @@
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 " +\

Check warning on line 57 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L54-L57

Added lines #L54 - L57 were not covered by tests
"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")

Check warning on line 60 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L59-L60

Added lines #L59 - L60 were not covered by tests
## 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 @@
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 @@
print("Created config file at", CONFIG_FILE)
return

# get message, model, and base url
# deal with chat history
call_history = False

Check warning on line 118 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L118

Added line #L118 was not covered by tests
## 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

Check warning on line 124 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L120-L124

Added lines #L120 - L124 were not covered by tests
## 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

Check warning on line 130 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L126-L130

Added lines #L126 - L130 were not covered by tests
## 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)

Check warning on line 136 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L132-L136

Added lines #L132 - L136 were not covered by tests
else:
print("No such file", new_file)
call_history = True

Check warning on line 139 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L138-L139

Added lines #L138 - L139 were not covered by tests
## 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

Check warning on line 147 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L141-L147

Added lines #L141 - L147 were not covered by tests
## 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

Check warning on line 156 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L149-L156

Added lines #L149 - L156 were not covered by tests

# 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

Check warning on line 167 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L163-L167

Added lines #L163 - L167 were not covered by tests

# 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')

Check warning on line 173 in askchat/askchat.py

View check run for this annotation

Codecov / codecov/patch

askchat/askchat.py#L171-L173

Added lines #L171 - L173 were not covered by tests
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
Loading