ngpt 1.2.0__py3-none-any.whl → 1.3.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.py +131 -1
- {ngpt-1.2.0.dist-info → ngpt-1.3.0.dist-info}/METADATA +11 -1
- ngpt-1.3.0.dist-info/RECORD +9 -0
- ngpt-1.2.0.dist-info/RECORD +0 -9
- {ngpt-1.2.0.dist-info → ngpt-1.3.0.dist-info}/WHEEL +0 -0
- {ngpt-1.2.0.dist-info → ngpt-1.3.0.dist-info}/entry_points.txt +0 -0
- {ngpt-1.2.0.dist-info → ngpt-1.3.0.dist-info}/licenses/LICENSE +0 -0
ngpt/cli.py
CHANGED
@@ -5,6 +5,24 @@ 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
|
+
# Optional imports for enhanced UI
|
9
|
+
try:
|
10
|
+
from prompt_toolkit import prompt as pt_prompt
|
11
|
+
from prompt_toolkit.styles import Style
|
12
|
+
from prompt_toolkit.key_binding import KeyBindings
|
13
|
+
from prompt_toolkit.formatted_text import HTML
|
14
|
+
from prompt_toolkit.layout.containers import HSplit, Window
|
15
|
+
from prompt_toolkit.layout.layout import Layout
|
16
|
+
from prompt_toolkit.layout.controls import FormattedTextControl
|
17
|
+
from prompt_toolkit.application import Application
|
18
|
+
from prompt_toolkit.widgets import TextArea
|
19
|
+
from prompt_toolkit.layout.margins import ScrollbarMargin
|
20
|
+
from prompt_toolkit.filters import to_filter
|
21
|
+
import shutil
|
22
|
+
HAS_PROMPT_TOOLKIT = True
|
23
|
+
except ImportError:
|
24
|
+
HAS_PROMPT_TOOLKIT = False
|
25
|
+
|
8
26
|
def show_config_help():
|
9
27
|
"""Display help information about configuration."""
|
10
28
|
print("\nConfiguration Help:")
|
@@ -91,6 +109,7 @@ def main():
|
|
91
109
|
mode_exclusive_group = mode_group.add_mutually_exclusive_group()
|
92
110
|
mode_exclusive_group.add_argument('-s', '--shell', action='store_true', help='Generate and execute shell commands')
|
93
111
|
mode_exclusive_group.add_argument('-c', '--code', action='store_true', help='Generate code')
|
112
|
+
mode_exclusive_group.add_argument('-t', '--text', action='store_true', help='Enter multi-line text input (submit with Ctrl+D)')
|
94
113
|
# Note: --show-config is handled separately and implicitly acts as a mode
|
95
114
|
|
96
115
|
# Language option for code mode
|
@@ -209,7 +228,7 @@ def main():
|
|
209
228
|
return
|
210
229
|
|
211
230
|
# Check if prompt is required but not provided
|
212
|
-
if not args.prompt and not (args.shell or args.code):
|
231
|
+
if not args.prompt and not (args.shell or args.code or args.text):
|
213
232
|
parser.print_help()
|
214
233
|
return
|
215
234
|
|
@@ -273,6 +292,117 @@ def main():
|
|
273
292
|
if generated_code:
|
274
293
|
print(f"\nGenerated code:\n{generated_code}")
|
275
294
|
|
295
|
+
elif args.text:
|
296
|
+
# Multi-line text input mode
|
297
|
+
if args.prompt is not None:
|
298
|
+
prompt = args.prompt
|
299
|
+
else:
|
300
|
+
try:
|
301
|
+
if HAS_PROMPT_TOOLKIT:
|
302
|
+
print("\033[94m\033[1m" + "Multi-line Input Mode" + "\033[0m")
|
303
|
+
print("Press Ctrl+D to submit, Ctrl+C to exit")
|
304
|
+
print("Use arrow keys to navigate, Enter for new line")
|
305
|
+
|
306
|
+
# Create key bindings
|
307
|
+
kb = KeyBindings()
|
308
|
+
|
309
|
+
# Explicitly bind Ctrl+D to exit
|
310
|
+
@kb.add('c-d')
|
311
|
+
def _(event):
|
312
|
+
event.app.exit(result=event.app.current_buffer.text)
|
313
|
+
|
314
|
+
# Explicitly bind Ctrl+C to exit
|
315
|
+
@kb.add('c-c')
|
316
|
+
def _(event):
|
317
|
+
event.app.exit(result=None)
|
318
|
+
print("\nInput cancelled by user. Exiting gracefully.")
|
319
|
+
sys.exit(130)
|
320
|
+
|
321
|
+
# Get terminal dimensions
|
322
|
+
term_width, term_height = shutil.get_terminal_size()
|
323
|
+
|
324
|
+
# Create a styled TextArea
|
325
|
+
text_area = TextArea(
|
326
|
+
style="class:input-area",
|
327
|
+
multiline=True,
|
328
|
+
wrap_lines=True,
|
329
|
+
width=term_width - 4,
|
330
|
+
height=min(20, term_height - 8),
|
331
|
+
prompt=HTML("<ansicyan>>>> </ansicyan>"),
|
332
|
+
scrollbar=True,
|
333
|
+
focus_on_click=True,
|
334
|
+
lexer=None,
|
335
|
+
)
|
336
|
+
text_area.window.right_margins = [ScrollbarMargin(display_arrows=True)]
|
337
|
+
|
338
|
+
# Create a title bar
|
339
|
+
title_bar = FormattedTextControl(
|
340
|
+
HTML("<style bg='ansicyan' fg='ansiblack'><b> NGPT Multi-line Editor </b></style>")
|
341
|
+
)
|
342
|
+
|
343
|
+
# Create a status bar with key bindings info
|
344
|
+
status_bar = FormattedTextControl(
|
345
|
+
HTML("<ansiblue><b>Ctrl+D</b></ansiblue>: Submit | <ansiblue><b>Ctrl+C</b></ansiblue>: Cancel | <ansiblue><b>↑↓←→</b></ansiblue>: Navigate")
|
346
|
+
)
|
347
|
+
|
348
|
+
# Create the layout
|
349
|
+
layout = Layout(
|
350
|
+
HSplit([
|
351
|
+
Window(title_bar, height=1),
|
352
|
+
Window(height=1, char="-", style="class:separator"),
|
353
|
+
text_area,
|
354
|
+
Window(height=1, char="-", style="class:separator"),
|
355
|
+
Window(status_bar, height=1),
|
356
|
+
])
|
357
|
+
)
|
358
|
+
|
359
|
+
# Create a style
|
360
|
+
style = Style.from_dict({
|
361
|
+
"separator": "ansigray",
|
362
|
+
"input-area": "bg:ansiblack fg:ansiwhite",
|
363
|
+
"cursor": "bg:ansiwhite fg:ansiblack",
|
364
|
+
})
|
365
|
+
|
366
|
+
# Create and run the application
|
367
|
+
app = Application(
|
368
|
+
layout=layout,
|
369
|
+
full_screen=False,
|
370
|
+
key_bindings=kb,
|
371
|
+
style=style,
|
372
|
+
mouse_support=True,
|
373
|
+
)
|
374
|
+
|
375
|
+
prompt = app.run()
|
376
|
+
|
377
|
+
if not prompt or not prompt.strip():
|
378
|
+
print("Empty prompt. Exiting.")
|
379
|
+
return
|
380
|
+
else:
|
381
|
+
# Fallback to standard input with a better implementation
|
382
|
+
print("Enter your multi-line prompt (press Ctrl+D to submit):")
|
383
|
+
print("Note: Install 'prompt_toolkit' package for an enhanced input experience")
|
384
|
+
|
385
|
+
# Use a more robust approach for multiline input without prompt_toolkit
|
386
|
+
lines = []
|
387
|
+
while True:
|
388
|
+
try:
|
389
|
+
line = input()
|
390
|
+
lines.append(line)
|
391
|
+
except EOFError: # Ctrl+D was pressed
|
392
|
+
break
|
393
|
+
|
394
|
+
prompt = "\n".join(lines)
|
395
|
+
if not prompt.strip():
|
396
|
+
print("Empty prompt. Exiting.")
|
397
|
+
return
|
398
|
+
|
399
|
+
except KeyboardInterrupt:
|
400
|
+
print("\nInput cancelled by user. Exiting gracefully.")
|
401
|
+
sys.exit(130)
|
402
|
+
|
403
|
+
print("\nSubmission successful. Waiting for response...")
|
404
|
+
client.chat(prompt, web_search=args.web_search)
|
405
|
+
|
276
406
|
else:
|
277
407
|
# Default to chat mode
|
278
408
|
if args.prompt is None:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ngpt
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.3.0
|
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
|
@@ -28,6 +28,7 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
28
28
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
29
29
|
Classifier: Topic :: Utilities
|
30
30
|
Requires-Python: >=3.8
|
31
|
+
Requires-Dist: prompt-toolkit>=3.0.0
|
31
32
|
Requires-Dist: requests>=2.31.0
|
32
33
|
Description-Content-Type: text/markdown
|
33
34
|
|
@@ -68,6 +69,9 @@ ngpt --code "function to calculate the Fibonacci sequence"
|
|
68
69
|
|
69
70
|
# Generate and execute shell commands
|
70
71
|
ngpt --shell "list all files in the current directory"
|
72
|
+
|
73
|
+
# Use multiline editor for complex prompts
|
74
|
+
ngpt --text
|
71
75
|
```
|
72
76
|
|
73
77
|
## Features
|
@@ -80,6 +84,7 @@ ngpt --shell "list all files in the current directory"
|
|
80
84
|
- ⚙️ **Multiple Configurations**: Cross-platform config system supporting different profiles
|
81
85
|
- 💻 **Shell Command Generation**: OS-aware command execution
|
82
86
|
- 🧩 **Clean Code Generation**: Output code without markdown or explanations
|
87
|
+
- 📝 **Rich Multiline Editor**: Interactive multiline text input with syntax highlighting and intuitive controls
|
83
88
|
|
84
89
|
## Installation
|
85
90
|
|
@@ -121,6 +126,10 @@ ngpt -s "list all files in current directory"
|
|
121
126
|
# Generate clean code (using -c or --code flag)
|
122
127
|
# Returns only code without markdown formatting or explanations
|
123
128
|
ngpt -c "create a python function that calculates fibonacci numbers"
|
129
|
+
|
130
|
+
# Use multiline text editor for complex prompts (using -t or --text flag)
|
131
|
+
# Opens an interactive editor with syntax highlighting and intuitive controls
|
132
|
+
ngpt -t
|
124
133
|
```
|
125
134
|
|
126
135
|
### As a Library
|
@@ -200,6 +209,7 @@ You can configure the client using the following options:
|
|
200
209
|
| `--all` | Used with `--show-config` to display all configurations |
|
201
210
|
| `-s, --shell` | Generate and execute shell commands |
|
202
211
|
| `-c, --code` | Generate clean code output |
|
212
|
+
| `-t, --text` | Open interactive multiline editor for complex prompts |
|
203
213
|
| `-v, --version` | Show version information |
|
204
214
|
|
205
215
|
### Interactive Configuration
|
@@ -0,0 +1,9 @@
|
|
1
|
+
ngpt/__init__.py,sha256=ehInP9w0MZlS1vZ1g6Cm4YE1ftmgF72CnEddQ3Le9n4,368
|
2
|
+
ngpt/cli.py,sha256=U8A9JKOpp-GorBk9yMs2nPThSdUwm83P_e3sDgfqCYo,19880
|
3
|
+
ngpt/client.py,sha256=O0dPYeQCJlpWZWBBsroo-5UxeyBVwqC6o3Pm8lRnDiY,10329
|
4
|
+
ngpt/config.py,sha256=BF0G3QeiPma8l7EQyc37bR7LWZog7FHJQNe7uj9cr4w,6896
|
5
|
+
ngpt-1.3.0.dist-info/METADATA,sha256=mGKNDQa1ppPnBp8lXILcSGYsS_40J0TQRQWLgpF_ewQ,9939
|
6
|
+
ngpt-1.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
7
|
+
ngpt-1.3.0.dist-info/entry_points.txt,sha256=1cnAMujyy34DlOahrJg19lePSnb08bLbkUs_kVerqdk,39
|
8
|
+
ngpt-1.3.0.dist-info/licenses/LICENSE,sha256=mQkpWoADxbHqE0HRefYLJdm7OpdrXBr3vNv5bZ8w72M,1065
|
9
|
+
ngpt-1.3.0.dist-info/RECORD,,
|
ngpt-1.2.0.dist-info/RECORD
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
ngpt/__init__.py,sha256=ehInP9w0MZlS1vZ1g6Cm4YE1ftmgF72CnEddQ3Le9n4,368
|
2
|
-
ngpt/cli.py,sha256=tIKXjKfh4K19UcZ0uG8JqTVz-9Lxg-p16dkYTiOmp7o,13582
|
3
|
-
ngpt/client.py,sha256=O0dPYeQCJlpWZWBBsroo-5UxeyBVwqC6o3Pm8lRnDiY,10329
|
4
|
-
ngpt/config.py,sha256=BF0G3QeiPma8l7EQyc37bR7LWZog7FHJQNe7uj9cr4w,6896
|
5
|
-
ngpt-1.2.0.dist-info/METADATA,sha256=o8iptGfiLJbibZZLKYFrg584Ppw6BMLkZuZQfvOzAFk,9497
|
6
|
-
ngpt-1.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
7
|
-
ngpt-1.2.0.dist-info/entry_points.txt,sha256=1cnAMujyy34DlOahrJg19lePSnb08bLbkUs_kVerqdk,39
|
8
|
-
ngpt-1.2.0.dist-info/licenses/LICENSE,sha256=mQkpWoADxbHqE0HRefYLJdm7OpdrXBr3vNv5bZ8w72M,1065
|
9
|
-
ngpt-1.2.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|