ngpt 4.0.1__py3-none-any.whl → 4.1.0__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/args.py +4 -0
- ngpt/cli/modes/interactive.py +107 -15
- {ngpt-4.0.1.dist-info → ngpt-4.1.0.dist-info}/METADATA +9 -1
- {ngpt-4.0.1.dist-info → ngpt-4.1.0.dist-info}/RECORD +7 -7
- {ngpt-4.0.1.dist-info → ngpt-4.1.0.dist-info}/WHEEL +0 -0
- {ngpt-4.0.1.dist-info → ngpt-4.1.0.dist-info}/entry_points.txt +0 -0
- {ngpt-4.0.1.dist-info → ngpt-4.1.0.dist-info}/licenses/LICENSE +0 -0
ngpt/cli/args.py
CHANGED
@@ -144,6 +144,10 @@ def setup_argument_parser():
|
|
144
144
|
mode_exclusive_group.add_argument('-g', '--gitcommsg', action='store_true',
|
145
145
|
help='Generate AI-powered git commit messages from staged changes or diff file')
|
146
146
|
|
147
|
+
# Add positional argument for the prompt (optional)
|
148
|
+
parser.add_argument('prompt', nargs='?', default=None,
|
149
|
+
help='The prompt to send to the language model')
|
150
|
+
|
147
151
|
return parser
|
148
152
|
|
149
153
|
def parse_args():
|
ngpt/cli/modes/interactive.py
CHANGED
@@ -4,6 +4,9 @@ import traceback
|
|
4
4
|
import threading
|
5
5
|
import sys
|
6
6
|
import time
|
7
|
+
import json
|
8
|
+
from datetime import datetime
|
9
|
+
from ...utils.config import get_config_dir
|
7
10
|
from ..formatters import COLORS
|
8
11
|
from ..renderers import prettify_markdown, prettify_streaming_markdown, TERMINAL_RENDER_LOCK
|
9
12
|
from ..ui import spinner, get_multiline_input
|
@@ -50,21 +53,29 @@ def interactive_chat_session(client, web_search=False, no_stream=False, temperat
|
|
50
53
|
# Create a separator line - use a consistent separator length for all lines
|
51
54
|
separator_length = min(40, term_width - 10)
|
52
55
|
separator = f"{COLORS['gray']}{'─' * separator_length}{COLORS['reset']}"
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
print(f" {COLORS['yellow']}
|
66
|
-
|
67
|
-
|
56
|
+
|
57
|
+
def show_help():
|
58
|
+
"""Displays the help menu."""
|
59
|
+
print(separator)
|
60
|
+
# Group commands into categories with better formatting
|
61
|
+
print(f"\n{COLORS['cyan']}Navigation:{COLORS['reset']}")
|
62
|
+
print(f" {COLORS['yellow']}↑/↓{COLORS['reset']} : Browse input history")
|
63
|
+
|
64
|
+
print(f"\n{COLORS['cyan']}Session Commands:{COLORS['reset']}")
|
65
|
+
print(f" {COLORS['yellow']}history{COLORS['reset']} : Show conversation history")
|
66
|
+
print(f" {COLORS['yellow']}clear{COLORS['reset']} : Reset conversation")
|
67
|
+
print(f" {COLORS['yellow']}exit{COLORS['reset']} : End session")
|
68
|
+
print(f" {COLORS['yellow']}save{COLORS['reset']} : Save current session")
|
69
|
+
print(f" {COLORS['yellow']}load{COLORS['reset']} : Load a previous session")
|
70
|
+
print(f" {COLORS['yellow']}sessions{COLORS['reset']}: List saved sessions")
|
71
|
+
print(f" {COLORS['yellow']}help{COLORS['reset']} : Show this help message")
|
72
|
+
|
73
|
+
if multiline_enabled:
|
74
|
+
print(f" {COLORS['yellow']}ml{COLORS['reset']} : Open multiline editor")
|
75
|
+
|
76
|
+
print(f"\n{separator}\n")
|
77
|
+
|
78
|
+
show_help()
|
68
79
|
|
69
80
|
# Show logging info if logger is available
|
70
81
|
if logger:
|
@@ -148,6 +159,71 @@ def interactive_chat_session(client, web_search=False, no_stream=False, temperat
|
|
148
159
|
print(f"\n{COLORS['yellow']}Conversation history cleared.{COLORS['reset']}")
|
149
160
|
print(separator) # Add separator for consistency
|
150
161
|
|
162
|
+
# --- Session Management Functions ---
|
163
|
+
|
164
|
+
def get_history_dir():
|
165
|
+
"""Get the history directory, creating it if it doesn't exist."""
|
166
|
+
history_dir = get_config_dir() / "history"
|
167
|
+
history_dir.mkdir(parents=True, exist_ok=True)
|
168
|
+
return history_dir
|
169
|
+
|
170
|
+
def save_session():
|
171
|
+
"""Save the current conversation to a JSON file."""
|
172
|
+
history_dir = get_history_dir()
|
173
|
+
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
174
|
+
filename = history_dir / f"session_{timestamp}.json"
|
175
|
+
|
176
|
+
with open(filename, "w") as f:
|
177
|
+
json.dump(conversation, f, indent=2)
|
178
|
+
|
179
|
+
print(f"\n{COLORS['green']}Session saved to {filename}{COLORS['reset']}")
|
180
|
+
|
181
|
+
def list_sessions():
|
182
|
+
"""List all saved sessions."""
|
183
|
+
history_dir = get_history_dir()
|
184
|
+
sessions = sorted(history_dir.glob("session_*.json"), reverse=True)
|
185
|
+
|
186
|
+
if not sessions:
|
187
|
+
print(f"\n{COLORS['yellow']}No saved sessions found.{COLORS['reset']}")
|
188
|
+
return
|
189
|
+
|
190
|
+
print(f"\n{COLORS['cyan']}{COLORS['bold']}Saved Sessions:{COLORS['reset']}")
|
191
|
+
for i, session_file in enumerate(sessions):
|
192
|
+
print(f" [{i}] {session_file.name}")
|
193
|
+
|
194
|
+
def load_session():
|
195
|
+
"""Load a conversation from a saved session file."""
|
196
|
+
nonlocal conversation
|
197
|
+
history_dir = get_history_dir()
|
198
|
+
sessions = sorted(history_dir.glob("session_*.json"), reverse=True)
|
199
|
+
|
200
|
+
if not sessions:
|
201
|
+
print(f"\n{COLORS['yellow']}No saved sessions to load.{COLORS['reset']}")
|
202
|
+
return
|
203
|
+
|
204
|
+
list_sessions()
|
205
|
+
|
206
|
+
try:
|
207
|
+
choice = input("Enter the number of the session to load: ")
|
208
|
+
choice_index = int(choice)
|
209
|
+
|
210
|
+
if 0 <= choice_index < len(sessions):
|
211
|
+
session_file = sessions[choice_index]
|
212
|
+
with open(session_file, "r") as f:
|
213
|
+
loaded_conversation = json.load(f)
|
214
|
+
|
215
|
+
# Basic validation
|
216
|
+
if isinstance(loaded_conversation, list) and all(isinstance(item, dict) for item in loaded_conversation):
|
217
|
+
conversation = loaded_conversation
|
218
|
+
print(f"\n{COLORS['green']}Session loaded from {session_file.name}{COLORS['reset']}")
|
219
|
+
display_history()
|
220
|
+
else:
|
221
|
+
print(f"\n{COLORS['red']}Error: Invalid session file format.{COLORS['reset']}")
|
222
|
+
else:
|
223
|
+
print(f"\n{COLORS['red']}Error: Invalid selection.{COLORS['reset']}")
|
224
|
+
except (ValueError, IndexError):
|
225
|
+
print(f"\n{COLORS['red']}Error: Invalid input. Please enter a number from the list.{COLORS['reset']}")
|
226
|
+
|
151
227
|
try:
|
152
228
|
while True:
|
153
229
|
# Get user input
|
@@ -188,6 +264,22 @@ def interactive_chat_session(client, web_search=False, no_stream=False, temperat
|
|
188
264
|
if user_input.lower() == 'clear':
|
189
265
|
clear_history()
|
190
266
|
continue
|
267
|
+
|
268
|
+
if user_input.lower() == 'save':
|
269
|
+
save_session()
|
270
|
+
continue
|
271
|
+
|
272
|
+
if user_input.lower() == 'sessions':
|
273
|
+
list_sessions()
|
274
|
+
continue
|
275
|
+
|
276
|
+
if user_input.lower() == 'load':
|
277
|
+
load_session()
|
278
|
+
continue
|
279
|
+
|
280
|
+
if user_input.lower() == 'help':
|
281
|
+
show_help()
|
282
|
+
continue
|
191
283
|
|
192
284
|
if multiline_enabled and user_input.lower() == 'ml':
|
193
285
|
print(f"{COLORS['cyan']}Opening multiline editor. Press Ctrl+D to submit.{COLORS['reset']}")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ngpt
|
3
|
-
Version: 4.0
|
3
|
+
Version: 4.1.0
|
4
4
|
Summary: A Swiss army knife for LLMs: A fast, lightweight CLI and interactive chat tool that brings the power of any OpenAI-compatible LLM (OpenAI, Ollama, Groq, Claude, Gemini, etc.) straight to your terminal. rewrite texts or refine code, craft git commit messages, generate and run OS-aware shell commands.
|
5
5
|
Project-URL: Homepage, https://github.com/nazdridoy/ngpt
|
6
6
|
Project-URL: Repository, https://github.com/nazdridoy/ngpt
|
@@ -81,6 +81,7 @@ Description-Content-Type: text/markdown
|
|
81
81
|
- 🎭 **System Prompts**: Customize model behavior with custom system prompts
|
82
82
|
- 🤖 **Custom Roles**: Create and use reusable AI roles for specialized tasks
|
83
83
|
- 📃 **Conversation Logging**: Save your conversations to text files for later reference
|
84
|
+
- 💾 **Session Management**: Save, load, and list interactive chat sessions.
|
84
85
|
- 🔌 **Modular Architecture**: Well-structured codebase with clean separation of concerns
|
85
86
|
- 🔄 **Provider Switching**: Easily switch between different LLM providers with a single parameter
|
86
87
|
- 🚀 **Performance Optimized**: Fast response times and minimal resource usage
|
@@ -138,6 +139,13 @@ python -m ngpt "Tell me about quantum computing"
|
|
138
139
|
|
139
140
|
# Start an interactive chat session with conversation memory
|
140
141
|
ngpt -i
|
142
|
+
# Inside interactive mode, you can use commands like:
|
143
|
+
# help - Show help menu
|
144
|
+
# save - Save the current session
|
145
|
+
# load - Load a previous session
|
146
|
+
# sessions - List saved sessions
|
147
|
+
# clear - Clear the conversation
|
148
|
+
# exit - Exit the session
|
141
149
|
|
142
150
|
# Return response without streaming
|
143
151
|
ngpt --no-stream "Tell me about quantum computing"
|
@@ -2,7 +2,7 @@ ngpt/__init__.py,sha256=kpKhViLakwMdHZkuLht2vWcjt0uD_5gR33gvMhfXr6w,664
|
|
2
2
|
ngpt/__main__.py,sha256=j3eFYPOtCCFBOGh7NK5IWEnADnTMMSEB9GLyIDoW724,66
|
3
3
|
ngpt/client.py,sha256=XjpA2UnvrRvzk6_DzVEddUTzoPlF8koQ-cZURpHoT7c,9041
|
4
4
|
ngpt/cli/__init__.py,sha256=hebbDSMGiOd43YNnQP67uzr67Ue6rZPwm2czynr5iZY,43
|
5
|
-
ngpt/cli/args.py,sha256=
|
5
|
+
ngpt/cli/args.py,sha256=F3ra7MJYqf0ULBR3C05jZwm9hiTIMpDd5DUC1tg1Fjs,15509
|
6
6
|
ngpt/cli/config_manager.py,sha256=NQQcWnjUppAAd0s0p9YAf8EyKS1ex5-0EB4DvKdB4dk,3662
|
7
7
|
ngpt/cli/formatters.py,sha256=HBYGlx_7eoAKyzfy0Vq5L0yn8yVKjngqYBukMmXCcz0,9401
|
8
8
|
ngpt/cli/main.py,sha256=SERPyiniRDbqcEcyAmAcP1Uo1E4VFXpdaM_1r9cRCiA,31129
|
@@ -13,7 +13,7 @@ ngpt/cli/modes/__init__.py,sha256=KP7VR6Xw9k1p5Jcu0F38RDxSFvFIzH3j1ThDLNwznUI,36
|
|
13
13
|
ngpt/cli/modes/chat.py,sha256=x1leClKq7UupA_CdW4tym0AivY2o_II123-I5IcAkxQ,7091
|
14
14
|
ngpt/cli/modes/code.py,sha256=Qj59xq6fZqgUDw7SbvmPKX_gdpc7DHJhNkn1sB5qgUU,12932
|
15
15
|
ngpt/cli/modes/gitcommsg.py,sha256=qFOrll333ebFOkzLP_WD1Qw0VfpphYqeiuHumkP6OB4,54833
|
16
|
-
ngpt/cli/modes/interactive.py,sha256=
|
16
|
+
ngpt/cli/modes/interactive.py,sha256=ybJ1MFigW_-NBQKe7AOfuWz_XjW3x_9cYzjBvCiVkbs,22790
|
17
17
|
ngpt/cli/modes/rewrite.py,sha256=RaN4NOItKrGy5ilRrTa2amK4zmNo59j6K7plUf5SJPM,20290
|
18
18
|
ngpt/cli/modes/shell.py,sha256=it1Brq1-LGeNfPKYBeVAwF-a78g9UP-KscofBZQkbr4,41589
|
19
19
|
ngpt/cli/modes/text.py,sha256=NOikaU9YVCBgyaCl6pwy9EVt-YY5Q4jBx0l47izpVTA,6986
|
@@ -23,8 +23,8 @@ ngpt/utils/config.py,sha256=wsArA4osnh8fKqOvtsPqqBxAz3DpdjtaWUFaRtnUdyc,10452
|
|
23
23
|
ngpt/utils/log.py,sha256=f1jg2iFo35PAmsarH8FVL_62plq4VXH0Mu2QiP6RJGw,15934
|
24
24
|
ngpt/utils/pipe.py,sha256=qRHF-Ma7bbU0cOcb1Yhe4S-kBavivtnnvLA3EYS4FY4,2162
|
25
25
|
ngpt/utils/web_search.py,sha256=w5ke4KJMRxq7r5jtbUXvspja6XhjoPZloVkZ0IvBXIE,30731
|
26
|
-
ngpt-4.0.
|
27
|
-
ngpt-4.0.
|
28
|
-
ngpt-4.0.
|
29
|
-
ngpt-4.0.
|
30
|
-
ngpt-4.0.
|
26
|
+
ngpt-4.1.0.dist-info/METADATA,sha256=5Zl4EPZPe8Kjm2K24fPeXAat340IsEGMFSZ4VZqnVTc,31954
|
27
|
+
ngpt-4.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
28
|
+
ngpt-4.1.0.dist-info/entry_points.txt,sha256=SqAAvLhMrsEpkIr4YFRdUeyuXQ9o0IBCeYgE6AVojoI,44
|
29
|
+
ngpt-4.1.0.dist-info/licenses/LICENSE,sha256=mQkpWoADxbHqE0HRefYLJdm7OpdrXBr3vNv5bZ8w72M,1065
|
30
|
+
ngpt-4.1.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|