ngpt 2.3.0__py3-none-any.whl → 2.3.2__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 +299 -58
- {ngpt-2.3.0.dist-info → ngpt-2.3.2.dist-info}/METADATA +1 -1
- ngpt-2.3.2.dist-info/RECORD +9 -0
- ngpt-2.3.0.dist-info/RECORD +0 -9
- {ngpt-2.3.0.dist-info → ngpt-2.3.2.dist-info}/WHEEL +0 -0
- {ngpt-2.3.0.dist-info → ngpt-2.3.2.dist-info}/entry_points.txt +0 -0
- {ngpt-2.3.0.dist-info → ngpt-2.3.2.dist-info}/licenses/LICENSE +0 -0
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("\
|
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
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
|
@@ -300,10 +526,25 @@ def interactive_chat_session(client, web_search=False, no_stream=False, temperat
|
|
300
526
|
log_handle.close()
|
301
527
|
|
302
528
|
def main():
|
303
|
-
|
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()
|
304
545
|
|
305
546
|
# Version flag
|
306
|
-
parser.add_argument('-v', '--version', action=
|
547
|
+
parser.add_argument('-v', '--version', action=ColoredVersionAction, nargs=0, help='Show version information and exit')
|
307
548
|
|
308
549
|
# Config options
|
309
550
|
config_group = parser.add_argument_group('Configuration Options')
|
@@ -582,9 +823,9 @@ def main():
|
|
582
823
|
style="class:input-area",
|
583
824
|
multiline=True,
|
584
825
|
wrap_lines=True,
|
585
|
-
width=term_width -
|
586
|
-
height=min(
|
587
|
-
prompt=HTML("<ansicyan
|
826
|
+
width=term_width - 10,
|
827
|
+
height=min(15, term_height - 10),
|
828
|
+
prompt=HTML("<ansicyan><b>> </b></ansicyan>"),
|
588
829
|
scrollbar=True,
|
589
830
|
focus_on_click=True,
|
590
831
|
lexer=None,
|
@@ -593,7 +834,7 @@ def main():
|
|
593
834
|
|
594
835
|
# Create a title bar
|
595
836
|
title_bar = FormattedTextControl(
|
596
|
-
HTML("<
|
837
|
+
HTML("<ansicyan><b> nGPT Multi-line Editor </b></ansicyan>")
|
597
838
|
)
|
598
839
|
|
599
840
|
# Create a status bar with key bindings info
|
@@ -605,17 +846,17 @@ def main():
|
|
605
846
|
layout = Layout(
|
606
847
|
HSplit([
|
607
848
|
Window(title_bar, height=1),
|
608
|
-
Window(height=1, char="
|
849
|
+
Window(height=1, char="─", style="class:separator"),
|
609
850
|
text_area,
|
610
|
-
Window(height=1, char="
|
851
|
+
Window(height=1, char="─", style="class:separator"),
|
611
852
|
Window(status_bar, height=1),
|
612
853
|
])
|
613
854
|
)
|
614
855
|
|
615
856
|
# Create a style
|
616
857
|
style = Style.from_dict({
|
617
|
-
"separator": "
|
618
|
-
"input-area": "
|
858
|
+
"separator": "ansicyan",
|
859
|
+
"input-area": "fg:ansiwhite",
|
619
860
|
"cursor": "bg:ansiwhite fg:ansiblack",
|
620
861
|
})
|
621
862
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ngpt
|
3
|
-
Version: 2.3.
|
3
|
+
Version: 2.3.2
|
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
|
@@ -0,0 +1,9 @@
|
|
1
|
+
ngpt/__init__.py,sha256=ehInP9w0MZlS1vZ1g6Cm4YE1ftmgF72CnEddQ3Le9n4,368
|
2
|
+
ngpt/cli.py,sha256=Or59XajZRf1Gl4zExygLIeIbwsJTkT_YLK_23ViwW2k,43230
|
3
|
+
ngpt/client.py,sha256=75xmzO7e9wQ7y_LzZCacg3mkZdheewcBxB6moPftqYw,13067
|
4
|
+
ngpt/config.py,sha256=BF0G3QeiPma8l7EQyc37bR7LWZog7FHJQNe7uj9cr4w,6896
|
5
|
+
ngpt-2.3.2.dist-info/METADATA,sha256=PnZr050walUIcVAWQz_xVd_yEK8ZA7UlKHYZEX5k9hI,13535
|
6
|
+
ngpt-2.3.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
7
|
+
ngpt-2.3.2.dist-info/entry_points.txt,sha256=1cnAMujyy34DlOahrJg19lePSnb08bLbkUs_kVerqdk,39
|
8
|
+
ngpt-2.3.2.dist-info/licenses/LICENSE,sha256=mQkpWoADxbHqE0HRefYLJdm7OpdrXBr3vNv5bZ8w72M,1065
|
9
|
+
ngpt-2.3.2.dist-info/RECORD,,
|
ngpt-2.3.0.dist-info/RECORD
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
ngpt/__init__.py,sha256=ehInP9w0MZlS1vZ1g6Cm4YE1ftmgF72CnEddQ3Le9n4,368
|
2
|
-
ngpt/cli.py,sha256=MfZ_QDKdylLvhPwUPRgCCBUD3iRDDh8Gy2Xnzf1MbbY,32511
|
3
|
-
ngpt/client.py,sha256=75xmzO7e9wQ7y_LzZCacg3mkZdheewcBxB6moPftqYw,13067
|
4
|
-
ngpt/config.py,sha256=BF0G3QeiPma8l7EQyc37bR7LWZog7FHJQNe7uj9cr4w,6896
|
5
|
-
ngpt-2.3.0.dist-info/METADATA,sha256=TG0WxgRFDG8oWOE3dtJgqRoyrJUfWB-QlgLkEq34Sqg,13535
|
6
|
-
ngpt-2.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
7
|
-
ngpt-2.3.0.dist-info/entry_points.txt,sha256=1cnAMujyy34DlOahrJg19lePSnb08bLbkUs_kVerqdk,39
|
8
|
-
ngpt-2.3.0.dist-info/licenses/LICENSE,sha256=mQkpWoADxbHqE0HRefYLJdm7OpdrXBr3vNv5bZ8w72M,1065
|
9
|
-
ngpt-2.3.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|