Skip to content

Commit ca0ead7

Browse files
committed
1. RawDog:
- Give consent to script execution - Execute script internally or externally - Choose python interpreter name
1 parent 57e66fa commit ca0ead7

File tree

6 files changed

+160
-37
lines changed

6 files changed

+160
-37
lines changed

docs/CHANGELOG.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ Assume role of the LLM and give your response.*
315315
- Disable g4f version check.
316316
- Partial or full installation options.
317317

318-
## v0.4.0
318+
## v0.4.1
319319

320320
**What's new?**
321321

@@ -336,4 +336,14 @@ For instance:
336336
<img src="https://github.com/Simatwa/python-tgpt/blob/main/assets/Figure_1.png?raw=true" width='60%'>
337337
</p>
338338

339-
</details>
339+
</details>
340+
341+
342+
## v0.4.2
343+
344+
**What's new?**
345+
346+
1. RawDog:
347+
- Give consent to script execution
348+
- Execute script internally or externally
349+
- Choose python interpreter name

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ webchatgpt==0.2.7
88
GoogleBard1==2.1.1
99
colorama==0.4.6
1010
g4f>=0.2.1.0
11-
pyyaml==6.0.1
11+
pyyaml==6.0.1
12+
matplotlib

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
setup(
3838
name="python-tgpt",
39-
version="0.4.1",
39+
version="0.4.2",
4040
license="MIT",
4141
author="Smartwa",
4242
maintainer="Smartwa",

src/pytgpt/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
from .utils import appdir
22
import g4f
33

4-
__version__ = "0.4.1"
4+
__version__ = "0.4.2"
55
__author__ = "Smartwa"
66
__repo__ = "https://github.com/Simatwa/python-tgpt"
77

88
tgpt_providers = [
99
"leo",
1010
"openai",
11-
"fakeopen",
1211
"opengpt",
1312
"koboldai",
1413
"bard",

src/pytgpt/console.py

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,9 @@ def __init__(
332332
chat_completion=False,
333333
ignore_working=False,
334334
rawdog=False,
335+
external_exec=False,
336+
confirm_script=False,
337+
interpreter="python",
335338
*args,
336339
**kwargs,
337340
):
@@ -346,9 +349,16 @@ def __init__(
346349
getOr = lambda option, default: option if option else default
347350

348351
if rawdog:
349-
self.RawDog = RawDog(quiet=quiet)
350-
intro = RawDog.intro_prompt
351-
getpass.getuser = lambda:'RawDog'
352+
353+
self.RawDog = RawDog(
354+
quiet=quiet,
355+
external_exec=external_exec,
356+
confirm_script=confirm_script,
357+
interpreter=interpreter,
358+
prettify=True,
359+
)
360+
intro = self.RawDog.intro_prompt
361+
getpass.getuser = lambda: "RawDog"
352362

353363
if provider == "leo":
354364
import pytgpt.leo as leo
@@ -1131,6 +1141,25 @@ class ChatInteractive:
11311141
is_flag=True,
11321142
help="Generate and auto-execute Python scripts - (experimental)",
11331143
)
1144+
@click.option(
1145+
"-ex",
1146+
"--external-exec",
1147+
is_flag=True,
1148+
help="RawDog : Execute scripts with system's python interpreter",
1149+
)
1150+
@click.option(
1151+
"-cs",
1152+
"--confirm-script",
1153+
is_flag=True,
1154+
help="RawDog : Give consent to generated scripts prior to execution",
1155+
)
1156+
@click.option(
1157+
"-int",
1158+
"--interpreter",
1159+
default="python",
1160+
help="RawDog : Python's interpreter name",
1161+
envvar="python_interpreter",
1162+
)
11341163
@click.help_option("-h", "--help")
11351164
def interactive(
11361165
model,
@@ -1162,6 +1191,9 @@ def interactive(
11621191
chat_completion,
11631192
ignore_working,
11641193
rawdog,
1194+
external_exec,
1195+
confirm_script,
1196+
interpreter,
11651197
):
11661198
"""Chat with AI interactively (Default)"""
11671199
this.clear_history_file(filepath, new)
@@ -1185,6 +1217,9 @@ def interactive(
11851217
chat_completion,
11861218
ignore_working,
11871219
rawdog=rawdog,
1220+
external_exec=external_exec,
1221+
confirm_script=confirm_script,
1222+
interpreter=interpreter,
11881223
)
11891224
busy_bar.spin_index = busy_bar_index
11901225
bot.code_theme = code_theme
@@ -1392,6 +1427,25 @@ class ChatGenerate:
13921427
is_flag=True,
13931428
help="Generate and auto-execute Python scripts - (experimental)",
13941429
)
1430+
@click.option(
1431+
"-ex",
1432+
"--external-exec",
1433+
is_flag=True,
1434+
help="RawDog : Execute scripts with system's python interpreter",
1435+
)
1436+
@click.option(
1437+
"-cs",
1438+
"--confirm-script",
1439+
is_flag=True,
1440+
help="RawDog : Give consent to generated scripts prior to execution",
1441+
)
1442+
@click.option(
1443+
"-int",
1444+
"--interpreter",
1445+
default="python",
1446+
help="RawDog : Python's interpreter name",
1447+
envvar="python_interpreter",
1448+
)
13951449
@click.help_option("-h", "--help")
13961450
def generate(
13971451
model,
@@ -1423,6 +1477,9 @@ def generate(
14231477
with_copied,
14241478
ignore_working,
14251479
rawdog,
1480+
external_exec,
1481+
confirm_script,
1482+
interpreter,
14261483
):
14271484
"""Generate a quick response with AI"""
14281485
bot = Main(
@@ -1444,6 +1501,9 @@ def generate(
14441501
quiet,
14451502
ignore_working=ignore_working,
14461503
rawdog=rawdog,
1504+
external_exec=external_exec,
1505+
confirm_script=confirm_script,
1506+
interpreter=interpreter,
14471507
)
14481508
prompt = prompt if prompt else ""
14491509
copied_placeholder = "{{copied}}"

src/pytgpt/utils.py

Lines changed: 81 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import datetime
88
import re
99
import sys
10+
import click
11+
from rich.markdown import Markdown
12+
from rich.console import Console
1013

1114
appdir = appdirs.AppDirs("pytgpt", "Smartwa")
1215

@@ -424,7 +427,41 @@ class RawDog:
424427

425428
# Idea borrowed from https://github.com/AbanteAI/rawdog
426429

427-
intro_prompt = f"""
430+
def __init__(
431+
self,
432+
quiet: bool = False,
433+
external_exec: bool = False,
434+
confirm_script: bool = False,
435+
interpreter: str = "python",
436+
prettify: bool = True,
437+
):
438+
"""Constructor
439+
440+
Args:
441+
quiet (bool, optional): Flag for control logging. Defaults to False.
442+
external_exec (bool, optional): Execute scripts with system's python executable. Defaults to False.
443+
confirm_script (bool, optional): Give consent to scripts prior to execution. Defaults to False.
444+
interpreter (str, optional): Python's interpreter name. Defaults to Python.
445+
prettify (bool, optional): Prettify the code on stdout. Defaults to True.
446+
"""
447+
if not quiet:
448+
print(
449+
"To get the most out of Rawdog. Ensure the following are installed:\n"
450+
" 1. Python interpreter.\n"
451+
" 2. Dependency:\n"
452+
" - Matplotlib\n"
453+
"Be alerted on the risk posed! (Experimental)\n"
454+
"Use '--quiet' to suppress this message and code/logs stdout.\n"
455+
)
456+
self.external_exec = external_exec
457+
self.confirm_script = confirm_script
458+
self.quiet = quiet
459+
self.interpreter = interpreter
460+
self.prettify = prettify
461+
462+
@property
463+
def intro_prompt(self):
464+
return f"""
428465
You are a command-line coding assistant called Rawdog that generates and auto-executes Python scripts.
429466
430467
A typical interaction goes like this:
@@ -470,22 +507,21 @@ class RawDog:
470507
- ALWAYS Return your SCRIPT inside of a single pair of ``` delimiters. Only the console output of the first such SCRIPT is visible to the user, so make sure that it's complete and don't bother returning anything else.
471508
472509
Current system : {platform.system()}
473-
Python version : {run_system_command("python --version",exit_on_error=True,stdout_error=True)[1].stdout}
510+
Python version : {run_system_command(f"{self.interpreter} --version",exit_on_error=True,stdout_error=True)[1].stdout.split(' ')[1]}
474511
Current directory : {os.getcwd()}
475512
Current Datetime : {datetime.datetime.now()}
476513
"""
477514

478-
def __init__(self, quiet: bool = False):
479-
if not quiet:
480-
print(
481-
"To get the most out of Rawdog. Ensure the following are installed:\n"
482-
" 1. Python interpreter.\n"
483-
" 2. Dependency:\n"
484-
" - Matplotlib\n"
485-
"Be alerted on the risk posed! (Experimental)\n"
486-
"Use '--quiet' to suppress this message and code/logs stdout.\n"
487-
)
488-
self.quiet = quiet
515+
def stdout(self, message: str) -> None:
516+
"""Stdout data
517+
518+
Args:
519+
message (str): Text to be printed
520+
"""
521+
if self.prettify:
522+
Console().print(Markdown(message))
523+
else:
524+
click.secho(message, fg="yellow")
489525

490526
def log(self, message: str, category: str = "info"):
491527
"""RawDog logger
@@ -497,6 +533,7 @@ def log(self, message: str, category: str = "info"):
497533
if self.quiet:
498534
return
499535

536+
message = "[PYTGPT] - " + message
500537
if category == "error":
501538
logging.error(message)
502539
else:
@@ -513,34 +550,50 @@ def main(self, response: str) -> None:
513550
"""
514551
code_blocks = re.findall(r"```python.*?```", response, re.DOTALL)
515552
if len(code_blocks) != 1:
516-
print(response)
553+
self.stdout(response)
554+
517555
else:
518556
raw_code = code_blocks[0]
519-
raw_code_plus = re.sub(r"(```)(python)?", "", raw_code)
520557

521-
if not self.quiet:
522-
print(raw_code_plus)
558+
if self.confirm_script:
559+
self.stdout(raw_code)
560+
if not click.confirm("- Do you wish to execute this"):
561+
return
562+
563+
elif not self.quiet:
564+
self.stdout(raw_code)
565+
566+
raw_code_plus = re.sub(r"(```)(python)?", "", raw_code)
523567

524-
if "CONTINUE" in response:
525-
self.log("Executing script")
568+
if "CONTINUE" in response or self.external_exec:
569+
self.log("Executing script externally")
526570
path_to_script = os.path.join(default_path, "execute_this.py")
527571
with open(path_to_script, "w") as fh:
528572
fh.write(raw_code_plus)
529-
success, proc = run_system_command(
530-
f"python {path_to_script}", exit_on_error=False, stdout_error=False
531-
)
532-
if success:
533-
self.log("Returning success feedback")
534-
return f"LAST SCRIPT OUTPUT:\n{proc.stdout}"
573+
if "CONTINUE" in response:
574+
575+
success, proc = run_system_command(
576+
f"{self.interpreter} {path_to_script}",
577+
exit_on_error=False,
578+
stdout_error=False,
579+
)
580+
581+
if success:
582+
self.log("Returning success feedback")
583+
return f"LAST SCRIPT OUTPUT:\n{proc.stdout}"
584+
else:
585+
self.log("Returning error feedback", "error")
586+
return f"PREVIOUS SCRIPT EXCEPTION:\n{proc.stderr}"
535587
else:
536-
self.log("Returning error feedback", "error")
537-
return f"PREVIOUS SCRIPT EXCEPTION:\n{proc.stderr}"
588+
os.system(f"{self.interpreter} {path_to_script}")
589+
538590
else:
539591
try:
592+
self.log("Executing script internally")
540593
exec(raw_code_plus)
541594
except Exception as e:
542595
self.log(
543596
"Exception occurred while executing script. Responding with error.",
544597
"error",
545598
)
546-
return str(e)
599+
return f"PREVIOUS SCRIPT EXCEPTION:\n{str(e)}"

0 commit comments

Comments
 (0)