ngpt 2.16.4__py3-none-any.whl → 2.16.6__py3-none-any.whl
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.
- ngpt/cli/interactive.py +46 -6
- ngpt/cli/modes/chat.py +1 -1
- ngpt/cli/modes/code.py +1 -1
- ngpt/cli/modes/rewrite.py +1 -3
- ngpt/cli/modes/shell.py +1 -1
- ngpt/cli/modes/text.py +1 -3
- ngpt/cli/renderers.py +11 -5
- ngpt/cli/ui.py +8 -2
- {ngpt-2.16.4.dist-info → ngpt-2.16.6.dist-info}/METADATA +1 -1
- {ngpt-2.16.4.dist-info → ngpt-2.16.6.dist-info}/RECORD +13 -13
- {ngpt-2.16.4.dist-info → ngpt-2.16.6.dist-info}/WHEEL +0 -0
- {ngpt-2.16.4.dist-info → ngpt-2.16.6.dist-info}/entry_points.txt +0 -0
- {ngpt-2.16.4.dist-info → ngpt-2.16.6.dist-info}/licenses/LICENSE +0 -0
ngpt/cli/interactive.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
import os
|
2
2
|
import shutil
|
3
3
|
import traceback
|
4
|
+
import threading
|
5
|
+
import sys
|
4
6
|
from .formatters import COLORS
|
5
7
|
from .renderers import prettify_markdown, prettify_streaming_markdown
|
6
8
|
|
@@ -197,21 +199,53 @@ def interactive_chat_session(client, web_search=False, no_stream=False, temperat
|
|
197
199
|
# Setup for stream-prettify
|
198
200
|
stream_callback = None
|
199
201
|
live_display = None
|
202
|
+
stop_spinner_func = None
|
203
|
+
stop_spinner_event = None
|
204
|
+
first_content_received = False
|
200
205
|
|
201
206
|
if stream_prettify and should_stream:
|
202
207
|
# Get the correct header for interactive mode
|
203
208
|
header = ngpt_header()
|
204
|
-
live_display, stream_callback = prettify_streaming_markdown(renderer, is_interactive=True, header_text=header)
|
209
|
+
live_display, stream_callback, setup_spinner = prettify_streaming_markdown(renderer, is_interactive=True, header_text=header)
|
205
210
|
if not live_display:
|
206
211
|
# Fallback to normal prettify if live display setup failed
|
207
212
|
prettify = True
|
208
213
|
stream_prettify = False
|
209
214
|
should_stream = False
|
210
215
|
print(f"{COLORS['yellow']}Falling back to regular prettify mode.{COLORS['reset']}")
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
216
|
+
else:
|
217
|
+
# Create a wrapper for the stream callback that handles spinner and live display
|
218
|
+
original_callback = stream_callback
|
219
|
+
|
220
|
+
def spinner_handling_callback(content):
|
221
|
+
nonlocal first_content_received
|
222
|
+
|
223
|
+
# On first content, stop the spinner and start the live display
|
224
|
+
if not first_content_received:
|
225
|
+
first_content_received = True
|
226
|
+
|
227
|
+
# Stop the spinner if it's running
|
228
|
+
if stop_spinner_func:
|
229
|
+
stop_spinner_func()
|
230
|
+
|
231
|
+
# Clear the spinner line completely
|
232
|
+
sys.stdout.write("\r" + " " * 100 + "\r")
|
233
|
+
sys.stdout.flush()
|
234
|
+
|
235
|
+
# Now start the live display
|
236
|
+
if live_display:
|
237
|
+
live_display.start()
|
238
|
+
|
239
|
+
# Call the original callback to update content
|
240
|
+
if original_callback:
|
241
|
+
original_callback(content)
|
242
|
+
|
243
|
+
# Use our wrapper callback
|
244
|
+
stream_callback = spinner_handling_callback
|
245
|
+
|
246
|
+
# Set up and start the spinner
|
247
|
+
stop_spinner_event = threading.Event()
|
248
|
+
stop_spinner_func = setup_spinner(stop_spinner_event, "Waiting for response...", color=COLORS['green'])
|
215
249
|
|
216
250
|
# Get AI response with conversation history
|
217
251
|
response = client.chat(
|
@@ -226,8 +260,14 @@ def interactive_chat_session(client, web_search=False, no_stream=False, temperat
|
|
226
260
|
stream_callback=stream_callback
|
227
261
|
)
|
228
262
|
|
263
|
+
# Ensure spinner is stopped if no content was received
|
264
|
+
if stop_spinner_event and not first_content_received:
|
265
|
+
stop_spinner_event.set()
|
266
|
+
sys.stdout.write("\r" + " " * 100 + "\r")
|
267
|
+
sys.stdout.flush()
|
268
|
+
|
229
269
|
# Stop live display if using stream-prettify
|
230
|
-
if stream_prettify and live_display:
|
270
|
+
if stream_prettify and live_display and first_content_received:
|
231
271
|
live_display.stop()
|
232
272
|
|
233
273
|
# Add AI response to conversation history
|
ngpt/cli/modes/chat.py
CHANGED
@@ -97,7 +97,7 @@ def chat_mode(client, args, logger=None):
|
|
97
97
|
stop_spinner_event = None
|
98
98
|
if args.stream_prettify and live_display:
|
99
99
|
stop_spinner_event = threading.Event()
|
100
|
-
stop_spinner_func = setup_spinner(stop_spinner_event)
|
100
|
+
stop_spinner_func = setup_spinner(stop_spinner_event, color=COLORS['cyan'])
|
101
101
|
|
102
102
|
# Create a wrapper for the stream callback that will stop the spinner on first content
|
103
103
|
original_callback = stream_callback
|
ngpt/cli/modes/code.py
CHANGED
@@ -82,7 +82,7 @@ def code_mode(client, args, logger=None):
|
|
82
82
|
stop_spinner_event = None
|
83
83
|
if use_stream_prettify and live_display:
|
84
84
|
stop_spinner_event = threading.Event()
|
85
|
-
stop_spinner_func = setup_spinner(stop_spinner_event)
|
85
|
+
stop_spinner_func = setup_spinner(stop_spinner_event, color=COLORS['cyan'])
|
86
86
|
|
87
87
|
# Create a wrapper for the stream callback that will stop the spinner on first content
|
88
88
|
original_callback = stream_callback
|
ngpt/cli/modes/rewrite.py
CHANGED
@@ -131,8 +131,6 @@ def rewrite_mode(client, args, logger=None):
|
|
131
131
|
{"role": "user", "content": input_text}
|
132
132
|
]
|
133
133
|
|
134
|
-
print("\nSubmission successful. Waiting for response...")
|
135
|
-
|
136
134
|
# Log the messages if logging is enabled
|
137
135
|
if logger:
|
138
136
|
logger.log("system", REWRITE_SYSTEM_PROMPT)
|
@@ -168,7 +166,7 @@ def rewrite_mode(client, args, logger=None):
|
|
168
166
|
stop_spinner_event = None
|
169
167
|
if args.stream_prettify and live_display:
|
170
168
|
stop_spinner_event = threading.Event()
|
171
|
-
stop_spinner_func = setup_spinner(stop_spinner_event)
|
169
|
+
stop_spinner_func = setup_spinner(stop_spinner_event, color=COLORS['cyan'])
|
172
170
|
|
173
171
|
# Create a wrapper for the stream callback that will stop the spinner on first content
|
174
172
|
original_callback = stream_callback
|
ngpt/cli/modes/shell.py
CHANGED
@@ -31,7 +31,7 @@ def shell_mode(client, args, logger=None):
|
|
31
31
|
spinner_thread = threading.Thread(
|
32
32
|
target=spinner,
|
33
33
|
args=("Generating command...",),
|
34
|
-
kwargs={"stop_event": stop_spinner}
|
34
|
+
kwargs={"stop_event": stop_spinner, "color": COLORS['cyan']}
|
35
35
|
)
|
36
36
|
spinner_thread.daemon = True
|
37
37
|
spinner_thread.start()
|
ngpt/cli/modes/text.py
CHANGED
@@ -21,8 +21,6 @@ def text_mode(client, args, logger=None):
|
|
21
21
|
print("Exiting.")
|
22
22
|
return
|
23
23
|
|
24
|
-
print("\nSubmission successful. Waiting for response...")
|
25
|
-
|
26
24
|
# Log the user message if logging is enabled
|
27
25
|
if logger:
|
28
26
|
logger.log("user", prompt)
|
@@ -70,7 +68,7 @@ def text_mode(client, args, logger=None):
|
|
70
68
|
stop_spinner_event = None
|
71
69
|
if args.stream_prettify and live_display:
|
72
70
|
stop_spinner_event = threading.Event()
|
73
|
-
stop_spinner_func = setup_spinner(stop_spinner_event)
|
71
|
+
stop_spinner_func = setup_spinner(stop_spinner_event, color=COLORS['cyan'])
|
74
72
|
|
75
73
|
# Create a wrapper for the stream callback that will stop the spinner on first content
|
76
74
|
original_callback = stream_callback
|
ngpt/cli/renderers.py
CHANGED
@@ -239,8 +239,14 @@ def prettify_streaming_markdown(renderer='rich', is_interactive=False, header_te
|
|
239
239
|
else:
|
240
240
|
md_obj = Markdown("")
|
241
241
|
|
242
|
-
# Initialize the Live display with
|
243
|
-
live = Live(
|
242
|
+
# Initialize the Live display with vertical overflow handling
|
243
|
+
live = Live(
|
244
|
+
md_obj,
|
245
|
+
console=console,
|
246
|
+
refresh_per_second=10,
|
247
|
+
auto_refresh=False,
|
248
|
+
vertical_overflow="visible" # Attempt to make overflow visible
|
249
|
+
)
|
244
250
|
|
245
251
|
# Track if this is the first content update
|
246
252
|
first_update = True
|
@@ -259,7 +265,7 @@ def prettify_streaming_markdown(renderer='rich', is_interactive=False, header_te
|
|
259
265
|
sys.stdout.flush()
|
260
266
|
live.start()
|
261
267
|
|
262
|
-
# Update content
|
268
|
+
# Update content in live display
|
263
269
|
if is_interactive and header_text:
|
264
270
|
# Update the panel content
|
265
271
|
md_obj.renderable = Markdown(content)
|
@@ -272,7 +278,7 @@ def prettify_streaming_markdown(renderer='rich', is_interactive=False, header_te
|
|
272
278
|
live.refresh()
|
273
279
|
|
274
280
|
# Define a function to set up and start the spinner
|
275
|
-
def setup_spinner(stop_event, message="Waiting for AI response..."):
|
281
|
+
def setup_spinner(stop_event, message="Waiting for AI response...", color=COLORS['cyan']):
|
276
282
|
nonlocal stop_spinner_event, spinner_thread
|
277
283
|
from .ui import spinner
|
278
284
|
import threading
|
@@ -284,7 +290,7 @@ def prettify_streaming_markdown(renderer='rich', is_interactive=False, header_te
|
|
284
290
|
spinner_thread = threading.Thread(
|
285
291
|
target=spinner,
|
286
292
|
args=(message,),
|
287
|
-
kwargs={"stop_event": stop_event}
|
293
|
+
kwargs={"stop_event": stop_event, "color": color}
|
288
294
|
)
|
289
295
|
spinner_thread.daemon = True
|
290
296
|
spinner_thread.start()
|
ngpt/cli/ui.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import sys
|
2
2
|
import time
|
3
3
|
import shutil
|
4
|
+
from .formatters import COLORS
|
4
5
|
|
5
6
|
# Optional imports for enhanced UI
|
6
7
|
try:
|
@@ -167,18 +168,23 @@ def spinner(message, duration=5, spinner_chars="⣾⣽⣻⢿⡿⣟⣯⣷", color
|
|
167
168
|
"""
|
168
169
|
char_duration = 0.2
|
169
170
|
|
171
|
+
# Apply color to message if provided
|
172
|
+
colored_message = message
|
173
|
+
if color:
|
174
|
+
colored_message = f"{color}{message}{COLORS['reset']}"
|
175
|
+
|
170
176
|
if stop_event:
|
171
177
|
i = 0
|
172
178
|
while not stop_event.is_set():
|
173
179
|
char = spinner_chars[i % len(spinner_chars)]
|
174
|
-
print(f"\r{
|
180
|
+
print(f"\r{colored_message} {char}", end="", flush=True)
|
175
181
|
i += 1
|
176
182
|
time.sleep(char_duration)
|
177
183
|
else:
|
178
184
|
total_chars = int(duration / char_duration)
|
179
185
|
for i in range(total_chars):
|
180
186
|
char = spinner_chars[i % len(spinner_chars)]
|
181
|
-
print(f"\r{
|
187
|
+
print(f"\r{colored_message} {char}", end="", flush=True)
|
182
188
|
time.sleep(char_duration)
|
183
189
|
|
184
190
|
# Clear the line when done
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ngpt
|
3
|
-
Version: 2.16.
|
3
|
+
Version: 2.16.6
|
4
4
|
Summary: Swiss army knife for LLMs: powerful CLI, interactive chatbot, and flexible Python library. Works with OpenAI, Ollama, Groq, Claude, and any OpenAI-compatible API.
|
5
5
|
Project-URL: Homepage, https://github.com/nazdridoy/ngpt
|
6
6
|
Project-URL: Repository, https://github.com/nazdridoy/ngpt
|
@@ -5,23 +5,23 @@ ngpt/cli/__init__.py,sha256=hebbDSMGiOd43YNnQP67uzr67Ue6rZPwm2czynr5iZY,43
|
|
5
5
|
ngpt/cli/args.py,sha256=VJM6ySMnVrXgKaGb7Qb3AQPYxcQCv3FfCI4x8YkAsLQ,11534
|
6
6
|
ngpt/cli/config_manager.py,sha256=NQQcWnjUppAAd0s0p9YAf8EyKS1ex5-0EB4DvKdB4dk,3662
|
7
7
|
ngpt/cli/formatters.py,sha256=HBYGlx_7eoAKyzfy0Vq5L0yn8yVKjngqYBukMmXCcz0,9401
|
8
|
-
ngpt/cli/interactive.py,sha256=
|
8
|
+
ngpt/cli/interactive.py,sha256=oLflfYVSX_NdYb5D8BsEeYr2m_6yWw06Rw-BS5tLqkI,12923
|
9
9
|
ngpt/cli/main.py,sha256=6GO4r9e9su7FFukj9JeVmJt1bJsqPOJBj6xo3iyMZXU,28911
|
10
|
-
ngpt/cli/renderers.py,sha256=
|
11
|
-
ngpt/cli/ui.py,sha256=
|
10
|
+
ngpt/cli/renderers.py,sha256=yYt3b_cWUYckfgLQ1wkEiQCnq5v5m7hfn5PWxHJzR9Y,12422
|
11
|
+
ngpt/cli/ui.py,sha256=m8qtd4cCSHBGHPUlHVdBEfun1G1Se4vLKTSgnS7QOKE,6775
|
12
12
|
ngpt/cli/modes/__init__.py,sha256=R3aO662RIzWEOvr3moTrEI8Tpg0zDDyMGGh1-OxiRgM,285
|
13
|
-
ngpt/cli/modes/chat.py,sha256
|
14
|
-
ngpt/cli/modes/code.py,sha256=
|
13
|
+
ngpt/cli/modes/chat.py,sha256=-g8hMHkn9Dv3iGFZvbXXFQwG8KsXEgngr6Si9AUdQXE,5701
|
14
|
+
ngpt/cli/modes/code.py,sha256=1EeiooyNe1jvTyNu6r0J9xY34QXb2uBQKPeNca-DrRI,5734
|
15
15
|
ngpt/cli/modes/gitcommsg.py,sha256=Bhgg9UArrfRUwosgVlNLUB7i1B8j-1ngpkmCm5iZBkM,46786
|
16
|
-
ngpt/cli/modes/rewrite.py,sha256=
|
17
|
-
ngpt/cli/modes/shell.py,sha256
|
18
|
-
ngpt/cli/modes/text.py,sha256=
|
16
|
+
ngpt/cli/modes/rewrite.py,sha256=iEMn6i6cuaxOiKq886Lsh961riCmPj5K1mXVQeT2Z7k,10112
|
17
|
+
ngpt/cli/modes/shell.py,sha256=QkprnOxMMTg2v5DIwcofDnnr3JPNfuk-YgSQaae5Xps,3311
|
18
|
+
ngpt/cli/modes/text.py,sha256=z08xaW2r0XzyunUzBhwZKqnwPjyRol_CSazjLygmLRs,4514
|
19
19
|
ngpt/utils/__init__.py,sha256=E46suk2-QgYBI0Qrs6WXOajOUOebF3ETAFY7ah8DTWs,942
|
20
20
|
ngpt/utils/cli_config.py,sha256=tQxR3a2iXyc5TfRBPQHSUXPInO2dv_zTPGn04eWfmoo,11285
|
21
21
|
ngpt/utils/config.py,sha256=WYOk_b1eiYjo6hpV3pfXr2RjqhOnmKqwZwKid1T41I4,10363
|
22
22
|
ngpt/utils/log.py,sha256=f1jg2iFo35PAmsarH8FVL_62plq4VXH0Mu2QiP6RJGw,15934
|
23
|
-
ngpt-2.16.
|
24
|
-
ngpt-2.16.
|
25
|
-
ngpt-2.16.
|
26
|
-
ngpt-2.16.
|
27
|
-
ngpt-2.16.
|
23
|
+
ngpt-2.16.6.dist-info/METADATA,sha256=DayL8rMlMWdplumfhcy9agLbWwXVQxGQv0kjOhGu14k,24938
|
24
|
+
ngpt-2.16.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
25
|
+
ngpt-2.16.6.dist-info/entry_points.txt,sha256=SqAAvLhMrsEpkIr4YFRdUeyuXQ9o0IBCeYgE6AVojoI,44
|
26
|
+
ngpt-2.16.6.dist-info/licenses/LICENSE,sha256=mQkpWoADxbHqE0HRefYLJdm7OpdrXBr3vNv5bZ8w72M,1065
|
27
|
+
ngpt-2.16.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|