ngpt 4.0.2__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.
@@ -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
- print(separator)
54
-
55
- # Group commands into categories with better formatting
56
- print(f"\n{COLORS['cyan']}Navigation:{COLORS['reset']}")
57
- print(f" {COLORS['yellow']}↑/↓{COLORS['reset']} : Browse input history")
58
-
59
- print(f"\n{COLORS['cyan']}Session Commands:{COLORS['reset']}")
60
- print(f" {COLORS['yellow']}history{COLORS['reset']} : Show conversation history")
61
- print(f" {COLORS['yellow']}clear{COLORS['reset']} : Reset conversation")
62
- print(f" {COLORS['yellow']}exit{COLORS['reset']} : End session")
63
-
64
- if multiline_enabled:
65
- print(f" {COLORS['yellow']}ml{COLORS['reset']} : Open multiline editor")
66
-
67
- print(f"\n{separator}\n")
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.2
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"
@@ -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=kBs1TIaMOYR6SBWXhgK-etXxI0zYF1-g3_25zwI2DtQ,19072
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.2.dist-info/METADATA,sha256=W31q71Mv3Fp_EvvfDlAHGK3oEjvExu97GulrYsap0qM,31619
27
- ngpt-4.0.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
28
- ngpt-4.0.2.dist-info/entry_points.txt,sha256=SqAAvLhMrsEpkIr4YFRdUeyuXQ9o0IBCeYgE6AVojoI,44
29
- ngpt-4.0.2.dist-info/licenses/LICENSE,sha256=mQkpWoADxbHqE0HRefYLJdm7OpdrXBr3vNv5bZ8w72M,1065
30
- ngpt-4.0.2.dist-info/RECORD,,
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