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.
Files changed (26) hide show
  1. {commandchat-0.0.7 → commandchat-0.0.9}/PKG-INFO +3 -1
  2. {commandchat-0.0.7 → commandchat-0.0.9}/commandchat.egg-info/PKG-INFO +3 -1
  3. commandchat-0.0.9/commandchat.egg-info/requires.txt +5 -0
  4. {commandchat-0.0.7 → commandchat-0.0.9}/occ/CommandChat.py +48 -29
  5. commandchat-0.0.9/occ/command/__main__.py +115 -0
  6. {commandchat-0.0.7 → commandchat-0.0.9}/pyproject.toml +4 -2
  7. commandchat-0.0.7/commandchat.egg-info/requires.txt +0 -3
  8. commandchat-0.0.7/occ/command/__main__.py +0 -75
  9. {commandchat-0.0.7 → commandchat-0.0.9}/LICENSE +0 -0
  10. {commandchat-0.0.7 → commandchat-0.0.9}/README.md +0 -0
  11. {commandchat-0.0.7 → commandchat-0.0.9}/commandchat.egg-info/SOURCES.txt +0 -0
  12. {commandchat-0.0.7 → commandchat-0.0.9}/commandchat.egg-info/dependency_links.txt +0 -0
  13. {commandchat-0.0.7 → commandchat-0.0.9}/commandchat.egg-info/entry_points.txt +0 -0
  14. {commandchat-0.0.7 → commandchat-0.0.9}/commandchat.egg-info/top_level.txt +0 -0
  15. {commandchat-0.0.7 → commandchat-0.0.9}/occ/ConvertLogToMarkDown.py +0 -0
  16. {commandchat-0.0.7 → commandchat-0.0.9}/occ/__init__.py +0 -0
  17. {commandchat-0.0.7 → commandchat-0.0.9}/occ/command/__init__.py +0 -0
  18. {commandchat-0.0.7 → commandchat-0.0.9}/occ/commons/__init__.py +0 -0
  19. {commandchat-0.0.7 → commandchat-0.0.9}/occ/commons/config.py +0 -0
  20. {commandchat-0.0.7 → commandchat-0.0.9}/occ/configuration/__init__.py +0 -0
  21. {commandchat-0.0.7 → commandchat-0.0.9}/occ/configuration/profile_config.py +0 -0
  22. {commandchat-0.0.7 → commandchat-0.0.9}/occ/utils/CommonUtil.py +0 -0
  23. {commandchat-0.0.7 → commandchat-0.0.9}/occ/utils/__init__.py +0 -0
  24. {commandchat-0.0.7 → commandchat-0.0.9}/occ/utils/logger.py +0 -0
  25. {commandchat-0.0.7 → commandchat-0.0.9}/setup.cfg +0 -0
  26. {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.7
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.7
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
@@ -0,0 +1,5 @@
1
+ click
2
+ Image
3
+ openai
4
+ prompt_toolkit
5
+ rich
@@ -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
- waiting_stop()
83
- for completion in stream:
84
- for choice in completion.choices:
85
- print(choice.text, end="")
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
- for chunk in response:
113
- if chunk.choices is None or len(chunk.choices) == 0:
114
- continue
115
- choice = chunk.choices[0]
116
- delta = choice.delta
117
-
118
- if choice.finish_reason == "stop":
119
- break
120
-
121
- if role is None and delta.role:
122
- role = delta.role
123
-
124
- if delta.content:
125
- completion_text += delta.content
126
- print(delta.content, end="")
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"
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,3 +0,0 @@
1
- click
2
- Image
3
- openai
@@ -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