-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
712 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Distribution / packaging | ||
.Python | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
wheels/ | ||
pip-wheel-metadata/ | ||
share/python-wheels/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
MANIFEST | ||
|
||
# PyInstaller | ||
# Usually these files are written by a python script from a template | ||
# before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
*.manifest | ||
|
||
# Installer logs | ||
pip-log.txt | ||
pip-delete-this-directory.txt | ||
|
||
# Unit test / coverage reports | ||
htmlcov/ | ||
.tox/ | ||
.nox/ | ||
.coverage | ||
.coverage.* | ||
.cache | ||
nosetests.xml | ||
coverage.xml | ||
*.cover | ||
*.py,cover | ||
.hypothesis/ | ||
.pytest_cache/ | ||
|
||
# Translations | ||
*.mo | ||
*.pot | ||
|
||
# Django stuff: | ||
*.log | ||
local_settings.py | ||
db.sqlite3 | ||
db.sqlite3-journal | ||
|
||
# Flask stuff: | ||
instance/ | ||
.webassets-cache | ||
|
||
# Scrapy stuff: | ||
.scrapy | ||
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# PyBuilder | ||
target/ | ||
|
||
# Jupyter Notebook | ||
.ipynb_checkpoints | ||
|
||
# IPython | ||
profile_default/ | ||
ipython_config.py | ||
|
||
# pyenv | ||
.python-version | ||
|
||
# pipenv | ||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. | ||
# However, in case of collaboration, if having platform-specific dependencies or dependencies | ||
# having no cross-platform support, pipenv may install dependencies that don't work, or not | ||
# install all needed dependencies. | ||
#Pipfile.lock | ||
|
||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow | ||
__pypackages__/ | ||
|
||
# Celery stuff | ||
celerybeat-schedule | ||
celerybeat.pid | ||
|
||
# SageMath parsed files | ||
*.sage.py | ||
|
||
# Environments | ||
.env | ||
.venv | ||
env/ | ||
venv/ | ||
ENV/ | ||
env.bak/ | ||
venv.bak/ | ||
|
||
# Spyder project settings | ||
.spyderproject | ||
.spyproject | ||
|
||
# Rope project settings | ||
.ropeproject | ||
|
||
# mkdocs documentation | ||
/site | ||
|
||
# mypy | ||
.mypy_cache/ | ||
.dmypy.json | ||
dmypy.json | ||
|
||
# Pyre type checker | ||
.pyre/ | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
Build your ChatGPT app. | ||
|
||
![GPT-UI](doc/1.jpg) | ||
|
||
|
||
# Run | ||
- 1.clone this repo | ||
- 2.edit your config.json | ||
```json | ||
{ | ||
"key": "your api key", //create at https://platform.openai.com/account/api-keys | ||
"api_base": "", | ||
"model": "gpt-3.5-turbo", //support: gpt-3.5-turbo/gpt-4/gpt-4-32k | ||
"stream": true, | ||
"response": true, | ||
"folder": "/Users/Qincji/Desktop/gptfileout/", //directory where chat logs are saved | ||
"repeat": true, //if false: all chats in one file. if true: each chat is in a new file | ||
"proxy": "socks5://127.0.0.1:7890" //support proxy: HTTP/HTTPS/SOCKS4A/SOCKS5 | ||
} | ||
|
||
``` | ||
- 3.run main.py | ||
|
||
|
||
# Build App | ||
- 4.install pyinstaller | ||
- 5.cd `GPT-UI` | ||
- 6.run `pyinstaller --windowed --name GPT-UI --add-data "config.ini:." --icon logo.ico main.py gpt.py utils.py` | ||
|
||
|
||
# Feature | ||
- [x] Support model: gpt-3.5-turbo/gpt-4/gpt-4-32k | ||
- [x] Support for exporting chat logs to files | ||
- [x] Support proxy: HTTP/HTTPS/SOCKS4A/SOCKS5 | ||
- [x] Build MacOS App | ||
- [x] Build Window exe | ||
- [ ] Support for generating images | ||
|
||
# Link | ||
- API key generated: [https://platform.openai.com/account/api-keys](https://platform.openai.com/account/api-keys) | ||
- [https://github.com/evilpan/gptcli](https://github.com/evilpan/gptcli) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[common] | ||
expired_time=2025/12/15 23:59:59 | ||
|
||
title=GPT-UI | ||
|
||
version_name=v1.0.1--github/xhunmon | ||
|
||
version_code=1010 | ||
|
||
email[email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"key": "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", | ||
"api_base": "", | ||
"model": "gpt-3.5-turbo", | ||
"stream": true, | ||
"response": true, | ||
"folder": "", | ||
"repeat": true, | ||
"proxy": "socks5://127.0.0.1:7890" | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"api_base": "", | ||
"key": "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", | ||
"model": "gpt-3.5-turbo", | ||
"stream": true, | ||
"response": true, | ||
"folder": "/Users/Qincji/Desktop/develop/py/opengpt/gptcli/doc/", | ||
"repeat": true, | ||
"proxy": "socks5://127.0.0.1:7890" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/bin/bash | ||
|
||
|
||
pyinstaller --windowed --name GPT-UI --add-data "config.ini:." --icon logo.ico main.py gpt.py utils.py | ||
|
||
#if use --onefile, the build file is small, but star very slow. | ||
#pyinstaller --onefile --windowed --name GPT-UI --add-data "config.ini:." --icon logo.ico main.py gpt.py utils.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
#!/usr/bin/env python | ||
# -*- encoding: utf-8 -*- | ||
""" | ||
@Description:gpt.py | ||
@Date :2023/03/31 | ||
@Author :xhunmon | ||
@Mail :[email protected] | ||
""" | ||
|
||
import time | ||
from datetime import datetime | ||
|
||
from utils import * | ||
|
||
|
||
class Gpt(object): | ||
func_ui_print = None | ||
|
||
def __init__(self, config: Config): | ||
self.session = [] | ||
self.api_prompt = [] | ||
self.update_config(config) | ||
self.content = "" | ||
self.is_change = False | ||
self.is_finish = True | ||
gpt_t = threading.Thread(target=self.start) | ||
gpt_t.setDaemon(True) | ||
gpt_t.start() | ||
|
||
def update_config(self, config: Config): | ||
self.cfg = config | ||
self.api_key = self.cfg.api_key | ||
self.api_base = self.cfg.api_base | ||
self.api_model = self.cfg.model | ||
self.api_stream = self.cfg.stream | ||
self.api_response = self.cfg.response | ||
self.proxy = self.cfg.proxy | ||
openai.api_key = self.api_key | ||
if self.api_base: | ||
openai.api_base = self.api_base | ||
openai.proxy = self.proxy | ||
|
||
def start(self): | ||
while True: | ||
if self.is_finish: | ||
while not self.is_change: | ||
time.sleep(0.3) | ||
self.print("\nMY:\n{}".format(self.content)) | ||
self.print("\nGPT:\n") | ||
self.is_change = False | ||
self.is_finish = False | ||
self.handle_input(self.content) | ||
time.sleep(1) | ||
|
||
def print(self, content): | ||
Gpt.func_ui_print(content) | ||
|
||
def query_openai_stream(self, data: dict) -> str: | ||
messages = [] | ||
messages.extend(self.api_prompt) | ||
messages.extend(data) | ||
answer = "" | ||
try: | ||
response = openai.ChatCompletion.create( | ||
model=self.api_model, | ||
messages=messages, | ||
stream=True) | ||
for part in response: | ||
finish_reason = part["choices"][0]["finish_reason"] | ||
if "content" in part["choices"][0]["delta"]: | ||
content = part["choices"][0]["delta"]["content"] | ||
answer += content | ||
self.print(content) | ||
elif finish_reason: | ||
pass | ||
|
||
except KeyboardInterrupt: | ||
self.print("Canceled") | ||
except openai.error.OpenAIError as e: | ||
self.print("OpenAIError:{}".format(e)) | ||
answer = "" | ||
return answer | ||
|
||
def content_change(self, content: str): | ||
if not content: | ||
return | ||
if self.content != content: | ||
self.content = content | ||
self.is_change = True | ||
|
||
def handle_input(self, content: str): | ||
if not content: | ||
return | ||
self.is_finish = False | ||
self.session.append({"role": "user", "content": content}) | ||
if self.api_stream: | ||
answer = self.query_openai_stream(self.session) | ||
else: | ||
answer = self.query_openai(self.session) | ||
if not answer: | ||
self.session.pop() | ||
elif self.api_response: | ||
self.session.append({"role": "assistant", "content": answer}) | ||
if answer: | ||
try: | ||
if self.cfg.folder and not os.path.exists(self.cfg.folder): | ||
os.makedirs(self.cfg.folder) | ||
wfile = os.path.join(self.cfg.folder, "gpt.md" if self.cfg.repeat else "gpt_{}.md".format( | ||
datetime.now().strftime("%Y%m%d%H%M:%S"))) | ||
if self.cfg.repeat: | ||
with open(wfile, mode='a', encoding="utf-8") as f: | ||
f.write("MY:\n{}\n".format(content)) | ||
f.write("\nGPT:\n{}\n\n".format(answer)) | ||
f.close() | ||
else: | ||
with open(wfile, mode='w', encoding="utf-8") as f: | ||
f.write("MY:\n{}\n".format(content)) | ||
f.write("\nGPT:{}".format(answer)) | ||
f.close() | ||
except Exception as e: | ||
self.print("Write error: {} ".format(e)) | ||
self.is_finish = True | ||
|
||
def query_openai(self, data: dict) -> str: | ||
messages = [] | ||
messages.extend(self.api_prompt) | ||
messages.extend(data) | ||
try: | ||
response = openai.ChatCompletion.create( | ||
model=self.api_model, | ||
messages=messages | ||
) | ||
content = response["choices"][0]["message"]["content"] | ||
self.print(content) | ||
return content | ||
except openai.error.OpenAIError as e: | ||
self.print("OpenAI error: {} ".format(e)) | ||
return "" |
Binary file not shown.
Oops, something went wrong.