commandchat 0.0.7__tar.gz → 0.0.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {commandchat-0.0.7 → commandchat-0.0.9}/PKG-INFO +3 -1
- {commandchat-0.0.7 → commandchat-0.0.9}/commandchat.egg-info/PKG-INFO +3 -1
- commandchat-0.0.9/commandchat.egg-info/requires.txt +5 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/occ/CommandChat.py +48 -29
- commandchat-0.0.9/occ/command/__main__.py +115 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/pyproject.toml +4 -2
- commandchat-0.0.7/commandchat.egg-info/requires.txt +0 -3
- commandchat-0.0.7/occ/command/__main__.py +0 -75
- {commandchat-0.0.7 → commandchat-0.0.9}/LICENSE +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/README.md +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/commandchat.egg-info/SOURCES.txt +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/commandchat.egg-info/dependency_links.txt +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/commandchat.egg-info/entry_points.txt +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/commandchat.egg-info/top_level.txt +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/occ/ConvertLogToMarkDown.py +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/occ/__init__.py +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/occ/command/__init__.py +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/occ/commons/__init__.py +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/occ/commons/config.py +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/occ/configuration/__init__.py +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/occ/configuration/profile_config.py +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/occ/utils/CommonUtil.py +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/occ/utils/__init__.py +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/occ/utils/logger.py +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/setup.cfg +0 -0
- {commandchat-0.0.7 → commandchat-0.0.9}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: commandchat
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.9
|
|
4
4
|
Summary: use command to chat with openai models
|
|
5
5
|
Home-page: https://github.com/
|
|
6
6
|
Author: xoto
|
|
@@ -16,6 +16,8 @@ License-File: LICENSE
|
|
|
16
16
|
Requires-Dist: click
|
|
17
17
|
Requires-Dist: Image
|
|
18
18
|
Requires-Dist: openai
|
|
19
|
+
Requires-Dist: prompt_toolkit
|
|
20
|
+
Requires-Dist: rich
|
|
19
21
|
Dynamic: author
|
|
20
22
|
Dynamic: home-page
|
|
21
23
|
Dynamic: license-file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: commandchat
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.9
|
|
4
4
|
Summary: use command to chat with openai models
|
|
5
5
|
Home-page: https://github.com/
|
|
6
6
|
Author: xoto
|
|
@@ -16,6 +16,8 @@ License-File: LICENSE
|
|
|
16
16
|
Requires-Dist: click
|
|
17
17
|
Requires-Dist: Image
|
|
18
18
|
Requires-Dist: openai
|
|
19
|
+
Requires-Dist: prompt_toolkit
|
|
20
|
+
Requires-Dist: rich
|
|
19
21
|
Dynamic: author
|
|
20
22
|
Dynamic: home-page
|
|
21
23
|
Dynamic: license-file
|
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
import json
|
|
2
|
+
import sys
|
|
3
|
+
import time
|
|
4
|
+
|
|
2
5
|
import openai
|
|
3
6
|
from openai import OpenAI
|
|
4
7
|
from openai import AzureOpenAI
|
|
5
8
|
import os
|
|
6
9
|
|
|
10
|
+
from prompt_toolkit import print_formatted_text, HTML
|
|
11
|
+
from rich.console import Console
|
|
12
|
+
from rich.markdown import Markdown
|
|
13
|
+
from rich.live import Live
|
|
14
|
+
|
|
7
15
|
from occ.commons.config import get_env
|
|
8
16
|
from occ.utils.CommonUtil import save_and_copy_image, waiting_start, waiting_stop
|
|
9
17
|
|
|
10
18
|
DEFAULT_CHAT_LOG_ID = "chat-1"
|
|
11
19
|
DEFAULT_PROFILE = "default"
|
|
20
|
+
USER_COLOR = "ansiyellow"
|
|
21
|
+
ASSISTANT_COLOR = "ansicyan"
|
|
22
|
+
TYPING_DELAY = 0.01 # 打字速度(秒/字符)
|
|
23
|
+
SEPARATOR = "─" * 30
|
|
12
24
|
|
|
13
25
|
|
|
14
26
|
def get_home_path():
|
|
@@ -17,6 +29,13 @@ def get_home_path():
|
|
|
17
29
|
homedir = os.path.expanduser('~')
|
|
18
30
|
return homedir
|
|
19
31
|
|
|
32
|
+
console = Console()
|
|
33
|
+
|
|
34
|
+
def print_formatted(content: str, live: Live):
|
|
35
|
+
md = Markdown(content)
|
|
36
|
+
live.update(md)
|
|
37
|
+
sys.stdout.flush()
|
|
38
|
+
|
|
20
39
|
|
|
21
40
|
class CommandChat:
|
|
22
41
|
|
|
@@ -70,8 +89,14 @@ class CommandChat:
|
|
|
70
89
|
print(e.http_status)
|
|
71
90
|
print(e.error)
|
|
72
91
|
|
|
92
|
+
def chat(self, message, model):
|
|
93
|
+
print_formatted_text(HTML(f"<{ASSISTANT_COLOR}>🤖 Assistant: </{ASSISTANT_COLOR}>"))
|
|
94
|
+
if model == "gpt-35-turbo-instruct":
|
|
95
|
+
self.completions(message, model)
|
|
96
|
+
else:
|
|
97
|
+
self.chat_completions(message, model)
|
|
98
|
+
|
|
73
99
|
def completions(self, message, model):
|
|
74
|
-
waiting_start()
|
|
75
100
|
stream = self.client.completions.create(
|
|
76
101
|
model=model,
|
|
77
102
|
prompt=message,
|
|
@@ -79,25 +104,19 @@ class CommandChat:
|
|
|
79
104
|
temperature=0.1,
|
|
80
105
|
stream=True
|
|
81
106
|
)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
for
|
|
85
|
-
|
|
86
|
-
|
|
107
|
+
completion_text = ''
|
|
108
|
+
with Live(console=console, refresh_per_second=8) as live:
|
|
109
|
+
for completion in stream:
|
|
110
|
+
for choice in completion.choices:
|
|
111
|
+
completion_text += choice.text
|
|
112
|
+
print_formatted(completion_text, live)
|
|
87
113
|
print("\n")
|
|
88
114
|
|
|
89
|
-
def chat(self, message, model):
|
|
90
|
-
if model == "gpt-35-turbo-instruct":
|
|
91
|
-
self.completions(message, model)
|
|
92
|
-
else:
|
|
93
|
-
self.chat_completions(message, model)
|
|
94
|
-
|
|
95
115
|
def chat_completions(self, message, model):
|
|
96
116
|
openai.api_key = self.api_key
|
|
97
117
|
openai.api_base = self.api_base
|
|
98
118
|
message = {"role": "user", "content": message}
|
|
99
119
|
self.messages.append(message)
|
|
100
|
-
waiting_start()
|
|
101
120
|
response = self.client.chat.completions.create(
|
|
102
121
|
model=model,
|
|
103
122
|
messages=self.messages,
|
|
@@ -106,24 +125,24 @@ class CommandChat:
|
|
|
106
125
|
frequency_penalty=0.0,
|
|
107
126
|
stream=True
|
|
108
127
|
)
|
|
109
|
-
waiting_stop()
|
|
110
128
|
completion_text = ''
|
|
111
129
|
role = None
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
role
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
130
|
+
with Live(console=console, refresh_per_second=8) as live:
|
|
131
|
+
for chunk in response:
|
|
132
|
+
if chunk.choices is None or len(chunk.choices) == 0:
|
|
133
|
+
continue
|
|
134
|
+
choice = chunk.choices[0]
|
|
135
|
+
delta = choice.delta
|
|
136
|
+
|
|
137
|
+
if choice.finish_reason == "stop":
|
|
138
|
+
break
|
|
139
|
+
|
|
140
|
+
if role is None and delta.role:
|
|
141
|
+
role = delta.role
|
|
142
|
+
|
|
143
|
+
if delta.content:
|
|
144
|
+
completion_text += delta.content
|
|
145
|
+
print_formatted(completion_text, live)
|
|
127
146
|
print("\n")
|
|
128
147
|
self.record_chat_logs(message, {"role": role, "content": completion_text.replace("\n\n", "")})
|
|
129
148
|
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
from __future__ import absolute_import
|
|
2
|
+
|
|
3
|
+
import importlib.metadata
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
from prompt_toolkit import PromptSession, print_formatted_text, HTML
|
|
8
|
+
from prompt_toolkit.cursor_shapes import ModalCursorShapeConfig
|
|
9
|
+
from prompt_toolkit.styles import style_from_pygments_cls
|
|
10
|
+
from pygments.lexers.markup import MarkdownLexer
|
|
11
|
+
from pygments.styles.tango import TangoStyle
|
|
12
|
+
|
|
13
|
+
import occ.utils.logger as logger
|
|
14
|
+
from occ.CommandChat import CommandChat
|
|
15
|
+
from occ.configuration.profile_config import add_profile, add_default_profile
|
|
16
|
+
from occ.utils.CommonUtil import waiting_stop
|
|
17
|
+
|
|
18
|
+
VERSION = importlib.metadata.version("commandchat")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@click.group()
|
|
22
|
+
@click.version_option(version=VERSION, prog_name='openai-commandchat')
|
|
23
|
+
def commandchat_operator():
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@click.command()
|
|
28
|
+
@click.option('--profile', '-p', help='Enable profile name')
|
|
29
|
+
def configure(profile):
|
|
30
|
+
if profile is not None:
|
|
31
|
+
add_profile(profile)
|
|
32
|
+
else:
|
|
33
|
+
add_default_profile()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@click.command()
|
|
37
|
+
@click.argument('message', required=False)
|
|
38
|
+
@click.option('-id', help=' enter chat id, something like context')
|
|
39
|
+
@click.option('--profile', '-p', envvar="OCC_PROFILE", help='Enable profile name')
|
|
40
|
+
@click.option("--model", "-m", envvar="OCC_MODEL", default="o1-mini",
|
|
41
|
+
help="Specify the model to use for this chat session")
|
|
42
|
+
@click.option('--file', '-f', type=click.Path(exists=True), help='the prompt or message is from a file')
|
|
43
|
+
def chat(message, id, profile, model, file):
|
|
44
|
+
try:
|
|
45
|
+
if file:
|
|
46
|
+
with open(file, 'r') as f:
|
|
47
|
+
message = f.read()
|
|
48
|
+
elif not message and not sys.stdin.isatty():
|
|
49
|
+
message = sys.stdin.read()
|
|
50
|
+
elif not message:
|
|
51
|
+
session = PromptSession(
|
|
52
|
+
show_frame=True,
|
|
53
|
+
style=style_from_pygments_cls(TangoStyle), multiline=True, wrap_lines=True,
|
|
54
|
+
cursor=ModalCursorShapeConfig(),
|
|
55
|
+
)
|
|
56
|
+
print_formatted_text(HTML("<ansibrightwhite>AI model Terminal</ansibrightwhite>\n"))
|
|
57
|
+
while True:
|
|
58
|
+
try:
|
|
59
|
+
message = session.prompt("👤 You: \n")
|
|
60
|
+
if not message:
|
|
61
|
+
continue
|
|
62
|
+
if message.lower() in {"/help", "/Help"}:
|
|
63
|
+
print_formatted_text(HTML(
|
|
64
|
+
"<b>Help Info: \n</b><ansigreen>Type your message and press ESC+Enter or OPT+Enter to send.\n"
|
|
65
|
+
"Use /exit or /quit to leave the chat.\n"
|
|
66
|
+
"Use /help to show this message again.</ansigreen>\n"))
|
|
67
|
+
continue
|
|
68
|
+
if message.lower() in {"/exit", "/quit"}:
|
|
69
|
+
print_formatted_text(HTML("<ansired>Bye 👋</ansired>"))
|
|
70
|
+
exit(0)
|
|
71
|
+
CommandChat(profile=profile, chat_log_id=id).chat(message, model)
|
|
72
|
+
print()
|
|
73
|
+
except KeyboardInterrupt:
|
|
74
|
+
print_formatted_text(HTML("<ansired>\n(Interrupted)</ansired>"))
|
|
75
|
+
exit(0)
|
|
76
|
+
CommandChat(profile=profile, chat_log_id=id).chat(message, model)
|
|
77
|
+
except Exception as e:
|
|
78
|
+
logger.log_g(str(e))
|
|
79
|
+
waiting_stop()
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
size_map = {
|
|
83
|
+
"s": "256x256",
|
|
84
|
+
"S": "256x256",
|
|
85
|
+
"m": "512x512",
|
|
86
|
+
"M": "512x512",
|
|
87
|
+
"l": "1024x1024",
|
|
88
|
+
"L": "1024x1024"
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@click.command()
|
|
93
|
+
@click.option('-desc', help=' Enter the description of the images you want')
|
|
94
|
+
@click.option('-size',
|
|
95
|
+
help=' Enter the size(S/s,M/m,L/l): \n small - 256x256 \n middle - 512x512 \n large - 1024x1024')
|
|
96
|
+
@click.option('-num', count=True, help=' Enter the number to generate the specified number of images')
|
|
97
|
+
@click.option('-profile', help='Enable profile name')
|
|
98
|
+
def image(desc, size, num, profile):
|
|
99
|
+
number = num if num > 0 else 1
|
|
100
|
+
size = size_map.get(size)
|
|
101
|
+
size_value = size if size is not None else "512x512"
|
|
102
|
+
CommandChat(profile=profile).image_create(desc, size_value, number if number < 5 else 4)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
commandchat_operator.add_command(configure)
|
|
106
|
+
commandchat_operator.add_command(chat)
|
|
107
|
+
commandchat_operator.add_command(image)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def main():
|
|
111
|
+
commandchat_operator()
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
if __name__ == '__main__':
|
|
115
|
+
main()
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "commandchat"
|
|
7
|
-
version = "0.0.
|
|
7
|
+
version = "0.0.9"
|
|
8
8
|
description = "use command to chat with openai models"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -15,7 +15,9 @@ authors = [
|
|
|
15
15
|
dependencies = [
|
|
16
16
|
"click",
|
|
17
17
|
"Image",
|
|
18
|
-
"openai"
|
|
18
|
+
"openai",
|
|
19
|
+
"prompt_toolkit",
|
|
20
|
+
"rich",
|
|
19
21
|
]
|
|
20
22
|
|
|
21
23
|
classifiers = [
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
from __future__ import absolute_import
|
|
2
|
-
|
|
3
|
-
import click
|
|
4
|
-
import importlib.metadata
|
|
5
|
-
|
|
6
|
-
import occ.utils.logger as logger
|
|
7
|
-
from occ.configuration.profile_config import add_profile, add_default_profile
|
|
8
|
-
from occ.CommandChat import CommandChat
|
|
9
|
-
from occ.utils.CommonUtil import waiting_stop
|
|
10
|
-
|
|
11
|
-
VERSION = importlib.metadata.version("commandchat")
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@click.group()
|
|
15
|
-
@click.version_option(version=VERSION, prog_name='openai-commandchat')
|
|
16
|
-
def commandchat_operator():
|
|
17
|
-
pass
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@click.command()
|
|
21
|
-
@click.option('--profile', '-p', help='Enable profile name')
|
|
22
|
-
def configure(profile):
|
|
23
|
-
if profile is not None:
|
|
24
|
-
add_profile(profile)
|
|
25
|
-
else:
|
|
26
|
-
add_default_profile()
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@click.command()
|
|
30
|
-
@click.argument('message')
|
|
31
|
-
@click.option('-id', help=' enter chat id, something like context')
|
|
32
|
-
@click.option('--profile', '-p', help='Enable profile name')
|
|
33
|
-
@click.option("--model", "-m", envvar="OCC_MODEL", default="o1-mini", help="Specify the model to use for this chat session")
|
|
34
|
-
def chat(message, id, profile, model):
|
|
35
|
-
try:
|
|
36
|
-
CommandChat(profile=profile, chat_log_id=id).chat(message, model)
|
|
37
|
-
except Exception as e:
|
|
38
|
-
logger.log_g(str(e))
|
|
39
|
-
waiting_stop()
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
size_map = {
|
|
43
|
-
"s": "256x256",
|
|
44
|
-
"S": "256x256",
|
|
45
|
-
"m": "512x512",
|
|
46
|
-
"M": "512x512",
|
|
47
|
-
"l": "1024x1024",
|
|
48
|
-
"L": "1024x1024"
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
@click.command()
|
|
53
|
-
@click.option('-desc', help=' Enter the description of the images you want')
|
|
54
|
-
@click.option('-size',
|
|
55
|
-
help=' Enter the size(S/s,M/m,L/l): \n small - 256x256 \n middle - 512x512 \n large - 1024x1024')
|
|
56
|
-
@click.option('-num', count=True, help=' Enter the number to generate the specified number of images')
|
|
57
|
-
@click.option('-profile', help='Enable profile name')
|
|
58
|
-
def image(desc, size, num, profile):
|
|
59
|
-
number = num if num > 0 else 1
|
|
60
|
-
size = size_map.get(size)
|
|
61
|
-
size_value = size if size is not None else "512x512"
|
|
62
|
-
CommandChat(profile=profile).image_create(desc, size_value, number if number < 5 else 4)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
commandchat_operator.add_command(configure)
|
|
66
|
-
commandchat_operator.add_command(chat)
|
|
67
|
-
commandchat_operator.add_command(image)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def main():
|
|
71
|
-
commandchat_operator()
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if __name__ == '__main__':
|
|
75
|
-
main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|