ngpt 2.2.0__py3-none-any.whl → 2.3.1__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.py CHANGED
@@ -5,6 +5,246 @@ from .client import NGPTClient
5
5
  from .config import load_config, get_config_path, load_configs, add_config_entry, remove_config_entry
6
6
  from . import __version__
7
7
 
8
+ # ANSI color codes for terminal output
9
+ COLORS = {
10
+ "reset": "\033[0m",
11
+ "bold": "\033[1m",
12
+ "cyan": "\033[36m",
13
+ "green": "\033[32m",
14
+ "yellow": "\033[33m",
15
+ "blue": "\033[34m",
16
+ "magenta": "\033[35m",
17
+ "gray": "\033[90m",
18
+ "bg_blue": "\033[44m",
19
+ "bg_cyan": "\033[46m"
20
+ }
21
+
22
+ # Check if ANSI colors are supported
23
+ def supports_ansi_colors():
24
+ """Check if the current terminal supports ANSI colors."""
25
+ import os
26
+ import sys
27
+
28
+ # If not a TTY, probably redirected, so no color
29
+ if not sys.stdout.isatty():
30
+ return False
31
+
32
+ # Windows specific checks
33
+ if sys.platform == "win32":
34
+ try:
35
+ # Windows 10+ supports ANSI colors in cmd/PowerShell
36
+ import ctypes
37
+ kernel32 = ctypes.windll.kernel32
38
+
39
+ # Try to enable ANSI color support
40
+ kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
41
+
42
+ # Check if TERM_PROGRAM is set (WSL/ConEmu/etc.)
43
+ if os.environ.get('TERM_PROGRAM') or os.environ.get('WT_SESSION'):
44
+ return True
45
+
46
+ # Check Windows version - 10+ supports ANSI natively
47
+ winver = sys.getwindowsversion()
48
+ if winver.major >= 10:
49
+ return True
50
+
51
+ return False
52
+ except Exception:
53
+ return False
54
+
55
+ # Most UNIX systems support ANSI colors
56
+ return True
57
+
58
+ # Initialize color support
59
+ HAS_COLOR = supports_ansi_colors()
60
+
61
+ # If we're on Windows, use brighter colors that work better in PowerShell
62
+ if sys.platform == "win32" and HAS_COLOR:
63
+ COLORS["magenta"] = "\033[95m" # Bright magenta for metavars
64
+ COLORS["cyan"] = "\033[96m" # Bright cyan for options
65
+
66
+ # If no color support, use empty color codes
67
+ if not HAS_COLOR:
68
+ for key in COLORS:
69
+ COLORS[key] = ""
70
+
71
+ # Custom help formatter with color support
72
+ class ColoredHelpFormatter(argparse.HelpFormatter):
73
+ """Help formatter that properly handles ANSI color codes without breaking alignment."""
74
+
75
+ def __init__(self, prog):
76
+ # Import modules needed for terminal size detection
77
+ import re
78
+ import textwrap
79
+ import shutil
80
+
81
+ # Get terminal size for dynamic width adjustment
82
+ try:
83
+ self.term_width = shutil.get_terminal_size().columns
84
+ except:
85
+ self.term_width = 80 # Default if we can't detect terminal width
86
+
87
+ # Calculate dynamic layout values based on terminal width
88
+ self.formatter_width = self.term_width - 2 # Leave some margin
89
+
90
+ # For very wide terminals, limit the width to maintain readability
91
+ if self.formatter_width > 120:
92
+ self.formatter_width = 120
93
+
94
+ # Calculate help position based on terminal width (roughly 1/3 of width)
95
+ self.help_position = min(max(20, int(self.term_width * 0.33)), 36)
96
+
97
+ # Initialize the parent class with dynamic values
98
+ super().__init__(prog, max_help_position=self.help_position, width=self.formatter_width)
99
+
100
+ # Calculate wrap width based on remaining space after help position
101
+ self.wrap_width = self.formatter_width - self.help_position - 5
102
+
103
+ # Set up the text wrapper for help text
104
+ self.ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
105
+ self.wrapper = textwrap.TextWrapper(width=self.wrap_width)
106
+
107
+ def _strip_ansi(self, s):
108
+ """Strip ANSI escape sequences for width calculations"""
109
+ return self.ansi_escape.sub('', s)
110
+
111
+ def _colorize(self, text, color, bold=False):
112
+ """Helper to consistently apply color with optional bold"""
113
+ if bold:
114
+ return f"{COLORS['bold']}{COLORS[color]}{text}{COLORS['reset']}"
115
+ return f"{COLORS[color]}{text}{COLORS['reset']}"
116
+
117
+ def _format_action_invocation(self, action):
118
+ if not action.option_strings:
119
+ # For positional arguments
120
+ metavar = self._format_args(action, action.dest.upper())
121
+ return self._colorize(metavar, 'cyan', bold=True)
122
+ else:
123
+ # For optional arguments with different color for metavar
124
+ if action.nargs != argparse.SUPPRESS:
125
+ default = self._get_default_metavar_for_optional(action)
126
+ args_string = self._format_args(action, default)
127
+
128
+ # Color option name and metavar differently
129
+ option_part = ', '.join(action.option_strings)
130
+ colored_option = self._colorize(option_part, 'cyan', bold=True)
131
+
132
+ if args_string:
133
+ # Make metavars more visible with brackets and color
134
+ # If HAS_COLOR is False, brackets will help in PowerShell
135
+ if not HAS_COLOR:
136
+ # Add brackets to make metavars stand out even without color
137
+ formatted_args = f"<{args_string}>"
138
+ else:
139
+ # Use color for metavar
140
+ formatted_args = self._colorize(args_string, 'magenta')
141
+
142
+ return f"{colored_option} {formatted_args}"
143
+ else:
144
+ return colored_option
145
+ else:
146
+ return self._colorize(', '.join(action.option_strings), 'cyan', bold=True)
147
+
148
+ def _format_usage(self, usage, actions, groups, prefix):
149
+ usage_text = super()._format_usage(usage, actions, groups, prefix)
150
+
151
+ # Replace "usage:" with colored version
152
+ colored_usage = self._colorize("usage:", 'green', bold=True)
153
+ usage_text = usage_text.replace("usage:", colored_usage)
154
+
155
+ # We won't color metavars in usage text as it breaks the formatting
156
+ # Just return with the colored usage prefix
157
+ return usage_text
158
+
159
+ def _join_parts(self, part_strings):
160
+ """Override to fix any potential formatting issues with section joins"""
161
+ return '\n'.join([part for part in part_strings if part])
162
+
163
+ def start_section(self, heading):
164
+ # Remove the colon as we'll add it with color
165
+ if heading.endswith(':'):
166
+ heading = heading[:-1]
167
+ heading_text = f"{self._colorize(heading, 'yellow', bold=True)}:"
168
+ super().start_section(heading_text)
169
+
170
+ def _get_help_string(self, action):
171
+ # Add color to help strings
172
+ help_text = action.help
173
+ if help_text:
174
+ return help_text.replace('(default:', f"{COLORS['gray']}(default:") + COLORS['reset']
175
+ return help_text
176
+
177
+ def _wrap_help_text(self, text, initial_indent="", subsequent_indent=" "):
178
+ """Wrap long help text to prevent overflow"""
179
+ if not text:
180
+ return text
181
+
182
+ # Strip ANSI codes for width calculation
183
+ clean_text = self._strip_ansi(text)
184
+
185
+ # If the text is already short enough, return it as is
186
+ if len(clean_text) <= self.wrap_width:
187
+ return text
188
+
189
+ # Handle any existing ANSI codes
190
+ has_ansi = text != clean_text
191
+ wrap_text = clean_text
192
+
193
+ # Wrap the text
194
+ lines = self.wrapper.wrap(wrap_text)
195
+
196
+ # Add indentation to all but the first line
197
+ wrapped = lines[0]
198
+ for line in lines[1:]:
199
+ wrapped += f"\n{subsequent_indent}{line}"
200
+
201
+ # Re-add the ANSI codes if they were present
202
+ if has_ansi and text.endswith(COLORS['reset']):
203
+ wrapped += COLORS['reset']
204
+
205
+ return wrapped
206
+
207
+ def _format_action(self, action):
208
+ # For subparsers, just return the regular formatting
209
+ if isinstance(action, argparse._SubParsersAction):
210
+ return super()._format_action(action)
211
+
212
+ # Get the action header with colored parts (both option names and metavars)
213
+ # The coloring is now done in _format_action_invocation
214
+ action_header = self._format_action_invocation(action)
215
+
216
+ # Format help text
217
+ help_text = self._expand_help(action)
218
+
219
+ # Get the raw lengths without ANSI codes for formatting
220
+ raw_header_len = len(self._strip_ansi(action_header))
221
+
222
+ # Calculate the indent for the help text
223
+ help_position = min(self._action_max_length + 2, self._max_help_position)
224
+ help_indent = ' ' * help_position
225
+
226
+ # If the action header is too long, put help on the next line
227
+ if raw_header_len > help_position:
228
+ # An action header that's too long gets a line break
229
+ # Wrap the help text with proper indentation
230
+ wrapped_help = self._wrap_help_text(help_text, subsequent_indent=help_indent)
231
+ line = f"{action_header}\n{help_indent}{wrapped_help}"
232
+ else:
233
+ # Standard formatting with proper spacing
234
+ padding = ' ' * (help_position - raw_header_len)
235
+ # Wrap the help text with proper indentation
236
+ wrapped_help = self._wrap_help_text(help_text, subsequent_indent=help_indent)
237
+ line = f"{action_header}{padding}{wrapped_help}"
238
+
239
+ # Handle subactions
240
+ if action.help is argparse.SUPPRESS:
241
+ return line
242
+
243
+ if not action.help:
244
+ return line
245
+
246
+ return line
247
+
8
248
  # Optional imports for enhanced UI
9
249
  try:
10
250
  from prompt_toolkit import prompt as pt_prompt
@@ -26,81 +266,67 @@ except ImportError:
26
266
 
27
267
  def show_config_help():
28
268
  """Display help information about configuration."""
29
- print("\nConfiguration Help:")
30
- print(" 1. Create a config file at one of these locations:")
269
+ print(f"\n{COLORS['green']}{COLORS['bold']}Configuration Help:{COLORS['reset']}")
270
+ print(f" 1. {COLORS['cyan']}Create a config file at one of these locations:{COLORS['reset']}")
31
271
  if sys.platform == "win32":
32
- print(f" - %APPDATA%\\ngpt\\ngpt.conf")
272
+ print(f" - {COLORS['yellow']}%APPDATA%\\ngpt\\ngpt.conf{COLORS['reset']}")
33
273
  elif sys.platform == "darwin":
34
- print(f" - ~/Library/Application Support/ngpt/ngpt.conf")
274
+ print(f" - {COLORS['yellow']}~/Library/Application Support/ngpt/ngpt.conf{COLORS['reset']}")
35
275
  else:
36
- print(f" - ~/.config/ngpt/ngpt.conf")
276
+ print(f" - {COLORS['yellow']}~/.config/ngpt/ngpt.conf{COLORS['reset']}")
37
277
 
38
- print(" 2. Format your config file as JSON:")
39
- print(""" [
40
- {
278
+ print(f" 2. {COLORS['cyan']}Format your config file as JSON:{COLORS['reset']}")
279
+ print(f"""{COLORS['yellow']} [
280
+ {{
41
281
  "api_key": "your-api-key-here",
42
282
  "base_url": "https://api.openai.com/v1/",
43
283
  "provider": "OpenAI",
44
284
  "model": "gpt-3.5-turbo"
45
- },
46
- {
285
+ }},
286
+ {{
47
287
  "api_key": "your-second-api-key",
48
288
  "base_url": "http://localhost:1337/v1/",
49
289
  "provider": "Another Provider",
50
290
  "model": "different-model"
51
- }
52
- ]""")
53
-
54
- print(" 3. Or set environment variables:")
55
- print(" - OPENAI_API_KEY")
56
- print(" - OPENAI_BASE_URL")
57
- print(" - OPENAI_MODEL")
58
-
59
- print(" 4. Or provide command line arguments:")
60
- print(" ngpt --api-key your-key --base-url https://api.example.com --model your-model \"Your prompt\"")
61
-
62
- print(" 5. Use --config-index to specify which configuration to use or edit:")
63
- print(" ngpt --config-index 1 \"Your prompt\"")
64
-
65
- print(" 6. Use --config without arguments to add a new configuration:")
66
- print(" ngpt --config")
67
- print(" Or specify an index to edit an existing configuration:")
68
- print(" ngpt --config --config-index 1")
69
- print(" 7. Remove a configuration at a specific index:")
70
- print(" ngpt --config --remove --config-index 1")
71
- print(" 8. List available models for the current configuration:")
72
- print(" ngpt --list-models")
291
+ }}
292
+ ]{COLORS['reset']}""")
293
+
294
+ print(f" 3. {COLORS['cyan']}Or set environment variables:{COLORS['reset']}")
295
+ print(f" - {COLORS['yellow']}OPENAI_API_KEY{COLORS['reset']}")
296
+ print(f" - {COLORS['yellow']}OPENAI_BASE_URL{COLORS['reset']}")
297
+ print(f" - {COLORS['yellow']}OPENAI_MODEL{COLORS['reset']}")
298
+
299
+ print(f" 4. {COLORS['cyan']}Or provide command line arguments:{COLORS['reset']}")
300
+ print(f" {COLORS['yellow']}ngpt --api-key your-key --base-url https://api.example.com --model your-model \"Your prompt\"{COLORS['reset']}")
301
+
302
+ print(f" 5. {COLORS['cyan']}Use --config-index to specify which configuration to use or edit:{COLORS['reset']}")
303
+ print(f" {COLORS['yellow']}ngpt --config-index 1 \"Your prompt\"{COLORS['reset']}")
304
+
305
+ print(f" 6. {COLORS['cyan']}Use --config without arguments to add a new configuration:{COLORS['reset']}")
306
+ print(f" {COLORS['yellow']}ngpt --config{COLORS['reset']}")
307
+ print(f" Or specify an index to edit an existing configuration:")
308
+ print(f" {COLORS['yellow']}ngpt --config --config-index 1{COLORS['reset']}")
309
+ print(f" 7. {COLORS['cyan']}Remove a configuration at a specific index:{COLORS['reset']}")
310
+ print(f" {COLORS['yellow']}ngpt --config --remove --config-index 1{COLORS['reset']}")
311
+ print(f" 8. {COLORS['cyan']}List available models for the current configuration:{COLORS['reset']}")
312
+ print(f" {COLORS['yellow']}ngpt --list-models{COLORS['reset']}")
73
313
 
74
314
  def check_config(config):
75
315
  """Check config for common issues and provide guidance."""
76
316
  if not config.get("api_key"):
77
- print("Error: API key is not set.")
317
+ print(f"{COLORS['yellow']}{COLORS['bold']}Error: API key is not set.{COLORS['reset']}")
78
318
  show_config_help()
79
319
  return False
80
320
 
81
321
  # Check for common URL mistakes
82
322
  base_url = config.get("base_url", "")
83
323
  if base_url and not (base_url.startswith("http://") or base_url.startswith("https://")):
84
- print(f"Warning: Base URL '{base_url}' doesn't start with http:// or https://")
324
+ print(f"{COLORS['yellow']}Warning: Base URL '{base_url}' doesn't start with http:// or https://{COLORS['reset']}")
85
325
 
86
326
  return True
87
327
 
88
- def interactive_chat_session(client, web_search=False, no_stream=False, temperature=0.7, top_p=1.0, max_length=None, log_file=None):
328
+ def interactive_chat_session(client, web_search=False, no_stream=False, temperature=0.7, top_p=1.0, max_length=None, log_file=None, preprompt=None):
89
329
  """Run an interactive chat session with conversation history."""
90
- # Define ANSI color codes for terminal output
91
- COLORS = {
92
- "reset": "\033[0m",
93
- "bold": "\033[1m",
94
- "cyan": "\033[36m",
95
- "green": "\033[32m",
96
- "yellow": "\033[33m",
97
- "blue": "\033[34m",
98
- "magenta": "\033[35m",
99
- "gray": "\033[90m",
100
- "bg_blue": "\033[44m",
101
- "bg_cyan": "\033[46m"
102
- }
103
-
104
330
  # Get terminal width for better formatting
105
331
  try:
106
332
  term_width = shutil.get_terminal_size().columns
@@ -146,11 +372,16 @@ def interactive_chat_session(client, web_search=False, no_stream=False, temperat
146
372
  print(f"\n{separator}\n")
147
373
 
148
374
  # Initialize conversation history
149
- system_prompt = "You are a helpful assistant."
375
+ system_prompt = preprompt if preprompt else "You are a helpful assistant."
150
376
  conversation = []
151
377
  system_message = {"role": "system", "content": system_prompt}
152
378
  conversation.append(system_message)
153
379
 
380
+ # Log system prompt if logging is enabled
381
+ if log_handle and preprompt:
382
+ log_handle.write(f"System: {system_prompt}\n\n")
383
+ log_handle.flush()
384
+
154
385
  # Initialize prompt_toolkit history
155
386
  prompt_history = InMemoryHistory() if HAS_PROMPT_TOOLKIT else None
156
387
 
@@ -295,10 +526,25 @@ def interactive_chat_session(client, web_search=False, no_stream=False, temperat
295
526
  log_handle.close()
296
527
 
297
528
  def main():
298
- parser = argparse.ArgumentParser(description="nGPT - A CLI tool for interacting with OpenAI-compatible APIs, supporting both official and self-hosted LLM endpoints")
529
+ # Colorize description - use a shorter description to avoid line wrapping issues
530
+ description = f"{COLORS['cyan']}{COLORS['bold']}nGPT{COLORS['reset']} - Interact with AI language models via OpenAI-compatible APIs"
531
+ parser = argparse.ArgumentParser(description=description, formatter_class=ColoredHelpFormatter)
532
+
533
+ # Add custom error method with color
534
+ original_error = parser.error
535
+ def error_with_color(message):
536
+ parser.print_usage(sys.stderr)
537
+ parser.exit(2, f"{COLORS['bold']}{COLORS['yellow']}error: {COLORS['reset']}{message}\n")
538
+ parser.error = error_with_color
539
+
540
+ # Custom version action with color
541
+ class ColoredVersionAction(argparse.Action):
542
+ def __call__(self, parser, namespace, values, option_string=None):
543
+ print(f"{COLORS['green']}{COLORS['bold']}nGPT{COLORS['reset']} version {COLORS['yellow']}{__version__}{COLORS['reset']}")
544
+ parser.exit()
299
545
 
300
546
  # Version flag
301
- parser.add_argument('-v', '--version', action='version', version=f'nGPT {__version__}', help='Show version information and exit')
547
+ parser.add_argument('-v', '--version', action=ColoredVersionAction, nargs=0, help='Show version information and exit')
302
548
 
303
549
  # Config options
304
550
  config_group = parser.add_argument_group('Configuration Options')
@@ -326,6 +572,8 @@ def main():
326
572
  help='Set max response length in tokens')
327
573
  global_group.add_argument('--log', metavar='FILE',
328
574
  help='Set filepath to log conversation to (For interactive modes)')
575
+ global_group.add_argument('--preprompt',
576
+ help='Set preprompt')
329
577
 
330
578
  # Mode flags (mutually exclusive)
331
579
  mode_group = parser.add_argument_group('Modes (mutually exclusive)')
@@ -486,7 +734,7 @@ def main():
486
734
  # Interactive chat mode
487
735
  interactive_chat_session(client, web_search=args.web_search, no_stream=args.no_stream,
488
736
  temperature=args.temperature, top_p=args.top_p,
489
- max_length=args.max_length, log_file=args.log)
737
+ max_length=args.max_length, log_file=args.log, preprompt=args.preprompt)
490
738
  elif args.shell:
491
739
  if args.prompt is None:
492
740
  try:
@@ -543,7 +791,6 @@ def main():
543
791
  print(f"\nGenerated code:\n{generated_code}")
544
792
 
545
793
  elif args.text:
546
- # Multi-line text input mode
547
794
  if args.prompt is not None:
548
795
  prompt = args.prompt
549
796
  else:
@@ -651,9 +898,18 @@ def main():
651
898
  sys.exit(130)
652
899
 
653
900
  print("\nSubmission successful. Waiting for response...")
901
+
902
+ # Create messages array with preprompt if available
903
+ messages = None
904
+ if args.preprompt:
905
+ messages = [
906
+ {"role": "system", "content": args.preprompt},
907
+ {"role": "user", "content": prompt}
908
+ ]
909
+
654
910
  response = client.chat(prompt, stream=not args.no_stream, web_search=args.web_search,
655
911
  temperature=args.temperature, top_p=args.top_p,
656
- max_tokens=args.max_length)
912
+ max_tokens=args.max_length, messages=messages)
657
913
  if args.no_stream and response:
658
914
  print(response)
659
915
 
@@ -668,9 +924,18 @@ def main():
668
924
  sys.exit(130)
669
925
  else:
670
926
  prompt = args.prompt
927
+
928
+ # Create messages array with preprompt if available
929
+ messages = None
930
+ if args.preprompt:
931
+ messages = [
932
+ {"role": "system", "content": args.preprompt},
933
+ {"role": "user", "content": prompt}
934
+ ]
935
+
671
936
  response = client.chat(prompt, stream=not args.no_stream, web_search=args.web_search,
672
937
  temperature=args.temperature, top_p=args.top_p,
673
- max_tokens=args.max_length)
938
+ max_tokens=args.max_length, messages=messages)
674
939
  if args.no_stream and response:
675
940
  print(response)
676
941
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ngpt
3
- Version: 2.2.0
3
+ Version: 2.3.1
4
4
  Summary: A lightweight Python CLI and library for interacting with OpenAI-compatible APIs, supporting both official and self-hosted LLM endpoints.
5
5
  Project-URL: Homepage, https://github.com/nazdridoy/ngpt
6
6
  Project-URL: Repository, https://github.com/nazdridoy/ngpt
@@ -81,8 +81,16 @@ ngpt --shell "list all files in the current directory"
81
81
 
82
82
  # Use multiline editor for complex prompts
83
83
  ngpt --text
84
+
85
+ # Use custom system prompt
86
+ ngpt --preprompt "You are a Linux expert" "How do I find large files?"
87
+
88
+ # Log your conversation to a file
89
+ ngpt --interactive --log conversation.log
84
90
  ```
85
91
 
92
+ For more examples and detailed usage, visit the [CLI Usage Guide](https://nazdridoy.github.io/ngpt/usage/cli_usage.html).
93
+
86
94
  ## Features
87
95
 
88
96
  - ✅ **Dual Mode**: Use as a CLI tool or import as a Python library
@@ -95,6 +103,10 @@ ngpt --text
95
103
  - 💻 **Shell Command Generation**: OS-aware command execution
96
104
  - 🧩 **Clean Code Generation**: Output code without markdown or explanations
97
105
  - 📝 **Rich Multiline Editor**: Interactive multiline text input with syntax highlighting and intuitive controls
106
+ - 🎭 **System Prompts**: Customize model behavior with custom system prompts
107
+ - 📃 **Conversation Logging**: Save your conversations to text files for later reference
108
+
109
+ See the [Feature Overview](https://nazdridoy.github.io/ngpt/overview.html) for more details.
98
110
 
99
111
  ## Documentation
100
112
 
@@ -102,6 +114,13 @@ Comprehensive documentation, including API reference, usage guides, and examples
102
114
 
103
115
  **[https://nazdridoy.github.io/ngpt/](https://nazdridoy.github.io/ngpt/)**
104
116
 
117
+ Key documentation sections:
118
+ - [Installation Guide](https://nazdridoy.github.io/ngpt/installation.html)
119
+ - [CLI Usage Guide](https://nazdridoy.github.io/ngpt/usage/cli_usage.html)
120
+ - [Library Usage Guide](https://nazdridoy.github.io/ngpt/usage/library_usage.html)
121
+ - [Configuration Guide](https://nazdridoy.github.io/ngpt/configuration.html)
122
+ - [Examples & Tutorials](https://nazdridoy.github.io/ngpt/examples/basic.html)
123
+
105
124
  ## Installation
106
125
 
107
126
  ```bash
@@ -110,6 +129,8 @@ pip install ngpt
110
129
 
111
130
  Requires Python 3.8 or newer.
112
131
 
132
+ For detailed installation instructions, see the [Installation Guide](https://nazdridoy.github.io/ngpt/installation.html).
133
+
113
134
  ## Usage
114
135
 
115
136
  ### As a CLI Tool
@@ -121,6 +142,12 @@ ngpt "Hello, how are you?"
121
142
  # Interactive chat session with conversation history
122
143
  ngpt -i
123
144
 
145
+ # Log conversation to a file
146
+ ngpt --interactive --log conversation.log
147
+
148
+ # Use custom system prompt to guide AI behavior
149
+ ngpt --preprompt "You are a Python programming tutor" "Explain decorators"
150
+
124
151
  # Show version information
125
152
  ngpt -v
126
153
 
@@ -157,6 +184,8 @@ ngpt -c "create a python function that calculates fibonacci numbers"
157
184
  ngpt -t
158
185
  ```
159
186
 
187
+ For more CLI examples and detailed usage information, see the [CLI Usage Guide](https://nazdridoy.github.io/ngpt/usage/cli_usage.html).
188
+
160
189
  ### As a Library
161
190
 
162
191
  ```python
@@ -189,6 +218,8 @@ command = client.generate_shell_command("list all files")
189
218
  code = client.generate_code("create a python function that calculates fibonacci numbers")
190
219
  ```
191
220
 
221
+ For more library examples and advanced usage, see the [Library Usage Guide](https://nazdridoy.github.io/ngpt/usage/library_usage.html).
222
+
192
223
  #### Advanced Library Usage
193
224
 
194
225
  ```python
@@ -215,6 +246,8 @@ code = client.generate_code("function that converts Celsius to Fahrenheit")
215
246
  print(code)
216
247
  ```
217
248
 
249
+ For advanced usage patterns and integrations, check out the [Advanced Examples](https://nazdridoy.github.io/ngpt/examples/advanced.html).
250
+
218
251
  ## Configuration
219
252
 
220
253
  ### Command Line Options
@@ -232,6 +265,8 @@ You can configure the client using the following options:
232
265
  | `--temperature` | Set temperature (controls randomness, default: 0.7) |
233
266
  | `--top_p` | Set top_p (controls diversity, default: 1.0) |
234
267
  | `--max_length` | Set maximum response length in tokens |
268
+ | `--preprompt` | Set custom system prompt to control AI behavior |
269
+ | `--log` | Set filepath to log conversation to (for interactive modes) |
235
270
  | `--config` | Path to a custom configuration file or, when used without a value, enters interactive configuration mode |
236
271
  | `--config-index` | Index of the configuration to use (default: 0) |
237
272
  | `--remove` | Remove the configuration at the specified index (requires --config and --config-index) |
@@ -243,6 +278,8 @@ You can configure the client using the following options:
243
278
  | `-t, --text` | Open interactive multiline editor for complex prompts |
244
279
  | `-v, --version` | Show version information |
245
280
 
281
+ For a complete reference of all available options, see the [CLI Usage Guide](https://nazdridoy.github.io/ngpt/usage/cli_usage.html).
282
+
246
283
  ### Interactive Configuration
247
284
 
248
285
  The `--config` option without arguments enters interactive configuration mode, allowing you to add or edit configurations:
@@ -264,6 +301,8 @@ In interactive mode:
264
301
  - For security, your API key is not displayed when editing configurations
265
302
  - When removing a configuration, you'll be asked to confirm before deletion
266
303
 
304
+ For more details on configuring nGPT, see the [Configuration Guide](https://nazdridoy.github.io/ngpt/configuration.html).
305
+
267
306
  ### Configuration File
268
307
 
269
308
  nGPT uses a configuration file stored in the standard user config directory for your operating system:
@@ -298,6 +337,8 @@ The configuration file uses a JSON list format, allowing you to store multiple c
298
337
  ]
299
338
  ```
300
339
 
340
+ For details on the configuration file format and structure, see the [Configuration Guide](https://nazdridoy.github.io/ngpt/configuration.html).
341
+
301
342
  ### Configuration Priority
302
343
 
303
344
  nGPT determines configuration values in the following order (highest priority first):
@@ -0,0 +1,9 @@
1
+ ngpt/__init__.py,sha256=ehInP9w0MZlS1vZ1g6Cm4YE1ftmgF72CnEddQ3Le9n4,368
2
+ ngpt/cli.py,sha256=y3LzVYJnlAt570dFniUchPa3oUuD4MaDbGl6fGfH_ac,43255
3
+ ngpt/client.py,sha256=75xmzO7e9wQ7y_LzZCacg3mkZdheewcBxB6moPftqYw,13067
4
+ ngpt/config.py,sha256=BF0G3QeiPma8l7EQyc37bR7LWZog7FHJQNe7uj9cr4w,6896
5
+ ngpt-2.3.1.dist-info/METADATA,sha256=M7YPXzIzpSJRfHI8QKt4VvDmgoDaT2WY3P6tk_DRrtg,13535
6
+ ngpt-2.3.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
+ ngpt-2.3.1.dist-info/entry_points.txt,sha256=1cnAMujyy34DlOahrJg19lePSnb08bLbkUs_kVerqdk,39
8
+ ngpt-2.3.1.dist-info/licenses/LICENSE,sha256=mQkpWoADxbHqE0HRefYLJdm7OpdrXBr3vNv5bZ8w72M,1065
9
+ ngpt-2.3.1.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- ngpt/__init__.py,sha256=ehInP9w0MZlS1vZ1g6Cm4YE1ftmgF72CnEddQ3Le9n4,368
2
- ngpt/cli.py,sha256=H_EIwZr-mSpw5JdlSD-CT6zWGWLldCJ4G-BKyWGIoOE,31536
3
- ngpt/client.py,sha256=75xmzO7e9wQ7y_LzZCacg3mkZdheewcBxB6moPftqYw,13067
4
- ngpt/config.py,sha256=BF0G3QeiPma8l7EQyc37bR7LWZog7FHJQNe7uj9cr4w,6896
5
- ngpt-2.2.0.dist-info/METADATA,sha256=seHeG-0SZyJcCN_SXpfpzI3jfwLBs9XrPkcdXt1mMhI,11278
6
- ngpt-2.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
- ngpt-2.2.0.dist-info/entry_points.txt,sha256=1cnAMujyy34DlOahrJg19lePSnb08bLbkUs_kVerqdk,39
8
- ngpt-2.2.0.dist-info/licenses/LICENSE,sha256=mQkpWoADxbHqE0HRefYLJdm7OpdrXBr3vNv5bZ8w72M,1065
9
- ngpt-2.2.0.dist-info/RECORD,,
File without changes