npcsh 0.1.2__py3-none-any.whl → 1.1.13__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.
- npcsh/_state.py +3508 -0
- npcsh/alicanto.py +65 -0
- npcsh/build.py +291 -0
- npcsh/completion.py +206 -0
- npcsh/config.py +163 -0
- npcsh/corca.py +50 -0
- npcsh/execution.py +185 -0
- npcsh/guac.py +46 -0
- npcsh/mcp_helpers.py +357 -0
- npcsh/mcp_server.py +299 -0
- npcsh/npc.py +323 -0
- npcsh/npc_team/alicanto.npc +2 -0
- npcsh/npc_team/alicanto.png +0 -0
- npcsh/npc_team/corca.npc +12 -0
- npcsh/npc_team/corca.png +0 -0
- npcsh/npc_team/corca_example.png +0 -0
- npcsh/npc_team/foreman.npc +7 -0
- npcsh/npc_team/frederic.npc +6 -0
- npcsh/npc_team/frederic4.png +0 -0
- npcsh/npc_team/guac.png +0 -0
- npcsh/npc_team/jinxs/code/python.jinx +11 -0
- npcsh/npc_team/jinxs/code/sh.jinx +34 -0
- npcsh/npc_team/jinxs/code/sql.jinx +16 -0
- npcsh/npc_team/jinxs/modes/alicanto.jinx +194 -0
- npcsh/npc_team/jinxs/modes/corca.jinx +249 -0
- npcsh/npc_team/jinxs/modes/guac.jinx +317 -0
- npcsh/npc_team/jinxs/modes/plonk.jinx +214 -0
- npcsh/npc_team/jinxs/modes/pti.jinx +170 -0
- npcsh/npc_team/jinxs/modes/spool.jinx +161 -0
- npcsh/npc_team/jinxs/modes/wander.jinx +186 -0
- npcsh/npc_team/jinxs/modes/yap.jinx +262 -0
- npcsh/npc_team/jinxs/npc_studio/npc-studio.jinx +77 -0
- npcsh/npc_team/jinxs/utils/agent.jinx +17 -0
- npcsh/npc_team/jinxs/utils/chat.jinx +44 -0
- npcsh/npc_team/jinxs/utils/cmd.jinx +44 -0
- npcsh/npc_team/jinxs/utils/compress.jinx +140 -0
- npcsh/npc_team/jinxs/utils/core/build.jinx +65 -0
- npcsh/npc_team/jinxs/utils/core/compile.jinx +50 -0
- npcsh/npc_team/jinxs/utils/core/help.jinx +52 -0
- npcsh/npc_team/jinxs/utils/core/init.jinx +41 -0
- npcsh/npc_team/jinxs/utils/core/jinxs.jinx +32 -0
- npcsh/npc_team/jinxs/utils/core/set.jinx +40 -0
- npcsh/npc_team/jinxs/utils/edit_file.jinx +94 -0
- npcsh/npc_team/jinxs/utils/load_file.jinx +35 -0
- npcsh/npc_team/jinxs/utils/ots.jinx +61 -0
- npcsh/npc_team/jinxs/utils/roll.jinx +68 -0
- npcsh/npc_team/jinxs/utils/sample.jinx +56 -0
- npcsh/npc_team/jinxs/utils/search.jinx +130 -0
- npcsh/npc_team/jinxs/utils/serve.jinx +26 -0
- npcsh/npc_team/jinxs/utils/sleep.jinx +116 -0
- npcsh/npc_team/jinxs/utils/trigger.jinx +61 -0
- npcsh/npc_team/jinxs/utils/usage.jinx +33 -0
- npcsh/npc_team/jinxs/utils/vixynt.jinx +144 -0
- npcsh/npc_team/kadiefa.npc +3 -0
- npcsh/npc_team/kadiefa.png +0 -0
- npcsh/npc_team/npcsh.ctx +18 -0
- npcsh/npc_team/npcsh_sibiji.png +0 -0
- npcsh/npc_team/plonk.npc +2 -0
- npcsh/npc_team/plonk.png +0 -0
- npcsh/npc_team/plonkjr.npc +2 -0
- npcsh/npc_team/plonkjr.png +0 -0
- npcsh/npc_team/sibiji.npc +3 -0
- npcsh/npc_team/sibiji.png +0 -0
- npcsh/npc_team/spool.png +0 -0
- npcsh/npc_team/yap.png +0 -0
- npcsh/npcsh.py +296 -112
- npcsh/parsing.py +118 -0
- npcsh/plonk.py +54 -0
- npcsh/pti.py +54 -0
- npcsh/routes.py +139 -0
- npcsh/spool.py +48 -0
- npcsh/ui.py +199 -0
- npcsh/wander.py +62 -0
- npcsh/yap.py +50 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/agent.jinx +17 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/alicanto.jinx +194 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/alicanto.npc +2 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/alicanto.png +0 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/build.jinx +65 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/chat.jinx +44 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/cmd.jinx +44 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/compile.jinx +50 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/compress.jinx +140 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/corca.jinx +249 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/corca.npc +12 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/corca.png +0 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/corca_example.png +0 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/edit_file.jinx +94 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/foreman.npc +7 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/frederic.npc +6 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/frederic4.png +0 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/guac.jinx +317 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/guac.png +0 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/help.jinx +52 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/init.jinx +41 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/jinxs.jinx +32 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/kadiefa.npc +3 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/kadiefa.png +0 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/load_file.jinx +35 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/npc-studio.jinx +77 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/npcsh.ctx +18 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/npcsh_sibiji.png +0 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/ots.jinx +61 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/plonk.jinx +214 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/plonk.npc +2 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/plonk.png +0 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/plonkjr.npc +2 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/plonkjr.png +0 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/pti.jinx +170 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/python.jinx +11 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/roll.jinx +68 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/sample.jinx +56 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/search.jinx +130 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/serve.jinx +26 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/set.jinx +40 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/sh.jinx +34 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/sibiji.npc +3 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/sibiji.png +0 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/sleep.jinx +116 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/spool.jinx +161 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/spool.png +0 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/sql.jinx +16 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/trigger.jinx +61 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/usage.jinx +33 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/vixynt.jinx +144 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/wander.jinx +186 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/yap.jinx +262 -0
- npcsh-1.1.13.data/data/npcsh/npc_team/yap.png +0 -0
- npcsh-1.1.13.dist-info/METADATA +522 -0
- npcsh-1.1.13.dist-info/RECORD +135 -0
- {npcsh-0.1.2.dist-info → npcsh-1.1.13.dist-info}/WHEEL +1 -1
- npcsh-1.1.13.dist-info/entry_points.txt +9 -0
- {npcsh-0.1.2.dist-info → npcsh-1.1.13.dist-info/licenses}/LICENSE +1 -1
- npcsh/command_history.py +0 -81
- npcsh/helpers.py +0 -36
- npcsh/llm_funcs.py +0 -295
- npcsh/main.py +0 -5
- npcsh/modes.py +0 -343
- npcsh/npc_compiler.py +0 -124
- npcsh-0.1.2.dist-info/METADATA +0 -99
- npcsh-0.1.2.dist-info/RECORD +0 -14
- npcsh-0.1.2.dist-info/entry_points.txt +0 -2
- {npcsh-0.1.2.dist-info → npcsh-1.1.13.dist-info}/top_level.txt +0 -0
npcsh/command_history.py
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import sqlite3
|
|
3
|
-
import json
|
|
4
|
-
from datetime import datetime
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def show_history(command_history, args):
|
|
8
|
-
if args:
|
|
9
|
-
search_results = command_history.search(args[0])
|
|
10
|
-
if search_results:
|
|
11
|
-
return "\n".join(
|
|
12
|
-
[f"{item[0]}. [{item[1]}] {item[2]}" for item in search_results]
|
|
13
|
-
)
|
|
14
|
-
else:
|
|
15
|
-
return f"No commands found matching '{args[0]}'"
|
|
16
|
-
else:
|
|
17
|
-
all_history = command_history.get_all()
|
|
18
|
-
return "\n".join([f"{item[0]}. [{item[1]}] {item[2]}" for item in all_history])
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def query_history_for_llm(command_history, query):
|
|
22
|
-
results = command_history.search(query)
|
|
23
|
-
formatted_results = [
|
|
24
|
-
f"Command: {r[2]}\nOutput: {r[4]}\nLocation: {r[5]}" for r in results
|
|
25
|
-
]
|
|
26
|
-
return "\n\n".join(formatted_results)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class CommandHistory:
|
|
30
|
-
def __init__(self, path="~/npcsh_history.db"):
|
|
31
|
-
self.db_path = os.path.expanduser(path)
|
|
32
|
-
self.conn = sqlite3.connect(self.db_path)
|
|
33
|
-
self.cursor = self.conn.cursor()
|
|
34
|
-
self.create_table()
|
|
35
|
-
|
|
36
|
-
def create_table(self):
|
|
37
|
-
self.cursor.execute(
|
|
38
|
-
"""
|
|
39
|
-
CREATE TABLE IF NOT EXISTS command_history (
|
|
40
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
41
|
-
timestamp TEXT,
|
|
42
|
-
command TEXT,
|
|
43
|
-
subcommands TEXT,
|
|
44
|
-
output TEXT,
|
|
45
|
-
location TEXT
|
|
46
|
-
)
|
|
47
|
-
"""
|
|
48
|
-
)
|
|
49
|
-
self.conn.commit()
|
|
50
|
-
|
|
51
|
-
def add(self, command, subcommands, output, location):
|
|
52
|
-
timestamp = datetime.now().isoformat()
|
|
53
|
-
self.cursor.execute(
|
|
54
|
-
"""
|
|
55
|
-
INSERT INTO command_history (timestamp, command, subcommands, output, location)
|
|
56
|
-
VALUES (?, ?, ?, ?, ?)
|
|
57
|
-
""",
|
|
58
|
-
(timestamp, command, json.dumps(subcommands), output, location),
|
|
59
|
-
)
|
|
60
|
-
self.conn.commit()
|
|
61
|
-
|
|
62
|
-
def search(self, term):
|
|
63
|
-
self.cursor.execute(
|
|
64
|
-
"""
|
|
65
|
-
SELECT * FROM command_history WHERE command LIKE ?
|
|
66
|
-
""",
|
|
67
|
-
(f"%{term}%",),
|
|
68
|
-
)
|
|
69
|
-
return self.cursor.fetchall()
|
|
70
|
-
|
|
71
|
-
def get_all(self, limit=100):
|
|
72
|
-
self.cursor.execute(
|
|
73
|
-
"""
|
|
74
|
-
SELECT * FROM command_history ORDER BY id DESC LIMIT ?
|
|
75
|
-
""",
|
|
76
|
-
(limit,),
|
|
77
|
-
)
|
|
78
|
-
return self.cursor.fetchall()
|
|
79
|
-
|
|
80
|
-
def close(self):
|
|
81
|
-
self.conn.close()
|
npcsh/helpers.py
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# helpers.py
|
|
2
|
-
import logging
|
|
3
|
-
|
|
4
|
-
logging.basicConfig(
|
|
5
|
-
filename=".npcsh.log",
|
|
6
|
-
level=logging.INFO,
|
|
7
|
-
format="%(asctime)s - %(levelname)s - %(message)s",
|
|
8
|
-
)
|
|
9
|
-
import os
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def list_directory(args):
|
|
13
|
-
directory = args[0] if args else "."
|
|
14
|
-
try:
|
|
15
|
-
files = os.listdir(directory)
|
|
16
|
-
for f in files:
|
|
17
|
-
print(f)
|
|
18
|
-
except Exception as e:
|
|
19
|
-
print(f"Error listing directory: {e}")
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def read_file(args):
|
|
23
|
-
if not args:
|
|
24
|
-
print("Usage: /read <filename>")
|
|
25
|
-
return
|
|
26
|
-
filename = args[0]
|
|
27
|
-
try:
|
|
28
|
-
with open(filename, "r") as file:
|
|
29
|
-
content = file.read()
|
|
30
|
-
print(content)
|
|
31
|
-
except Exception as e:
|
|
32
|
-
print(f"Error reading file: {e}")
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def log_action(action, detail=""):
|
|
36
|
-
logging.info(f"{action}: {detail}")
|
npcsh/llm_funcs.py
DELETED
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
import subprocess
|
|
2
|
-
import requests
|
|
3
|
-
import os
|
|
4
|
-
import json
|
|
5
|
-
import ollama
|
|
6
|
-
import sqlite3
|
|
7
|
-
|
|
8
|
-
npcsh_model = os.environ.get("NPCSH_MODEL", "phi3")
|
|
9
|
-
npcsh_provider = os.environ.get("NPCSH_PROVIDER", "ollama")
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def get_ollama_conversation(messages, model):
|
|
13
|
-
response = ollama.chat(model=model, messages=messages)
|
|
14
|
-
messages.append(response)
|
|
15
|
-
# print(response["message"])
|
|
16
|
-
return messages
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"""
|
|
20
|
-
test_messages = [
|
|
21
|
-
{"role": "user", "content": "hows it going"}]
|
|
22
|
-
model = "llama3.1"
|
|
23
|
-
ea = get_ollama_conversion(ea, model)
|
|
24
|
-
|
|
25
|
-
ea.append({"role": "user", "content": "then can you help me design something really spectacular?"})
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"""
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def get_ollama_response(prompt, model, format=None, **kwargs):
|
|
32
|
-
try:
|
|
33
|
-
url = "http://localhost:11434/api/generate"
|
|
34
|
-
data = {
|
|
35
|
-
"model": model,
|
|
36
|
-
"prompt": prompt,
|
|
37
|
-
"stream": False,
|
|
38
|
-
}
|
|
39
|
-
if format is not None:
|
|
40
|
-
data["format"] = format
|
|
41
|
-
|
|
42
|
-
# print(f"Requesting LLM response for prompt: {prompt}")
|
|
43
|
-
response = requests.post(url, json=data)
|
|
44
|
-
response.raise_for_status()
|
|
45
|
-
llm_response = json.loads(response.text)["response"]
|
|
46
|
-
|
|
47
|
-
# If format is JSON, try to parse the response as JSON
|
|
48
|
-
if format == "json":
|
|
49
|
-
try:
|
|
50
|
-
return json.loads(llm_response)
|
|
51
|
-
except json.JSONDecodeError:
|
|
52
|
-
print(f"Warning: Expected JSON response, but received: {llm_response}")
|
|
53
|
-
return {"error": "Invalid JSON response"}
|
|
54
|
-
else:
|
|
55
|
-
return llm_response
|
|
56
|
-
except Exception as e:
|
|
57
|
-
return f"Error interacting with LLM: {e}"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def get_openai_response(prompt, model, functional_requirements=None):
|
|
61
|
-
pass
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def get_claude_response(prompt, model, format=None):
|
|
65
|
-
pass
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def get_llm_response(prompt, provider=npcsh_provider, model=npcsh_model, **kwargs):
|
|
69
|
-
if provider == "ollama":
|
|
70
|
-
return get_ollama_response(prompt, model, **kwargs)
|
|
71
|
-
elif provider == "openai":
|
|
72
|
-
return get_openai_response(prompt, model, **kwargs)
|
|
73
|
-
elif provider == "claude":
|
|
74
|
-
return get_claude_response(prompt, model, **kwargs)
|
|
75
|
-
else:
|
|
76
|
-
return "Error: Invalid provider specified."
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def execute_data_operations(query, command_history):
|
|
80
|
-
location = os.getcwd()
|
|
81
|
-
prompt = f"""
|
|
82
|
-
A user submitted this query: {query}
|
|
83
|
-
You need to generate a script using python, R, or SQL that will accomplish the user's intent.
|
|
84
|
-
|
|
85
|
-
Respond ONLY with the procedure that should be executed.
|
|
86
|
-
|
|
87
|
-
Here are some examples:
|
|
88
|
-
{{"data_operation": "<sql query>", 'engine': 'SQL'}}
|
|
89
|
-
{{'data_operation': '<python script>', 'engine': 'PYTHON'}}
|
|
90
|
-
{{'data_operation': '<r script>', 'engine': 'R'}}
|
|
91
|
-
|
|
92
|
-
You must reply with only ONE output.
|
|
93
|
-
"""
|
|
94
|
-
|
|
95
|
-
response = get_llm_response(prompt, format="json")
|
|
96
|
-
output = response
|
|
97
|
-
command_history.add(query, [], json.dumps(output), location)
|
|
98
|
-
print(response)
|
|
99
|
-
|
|
100
|
-
if response["engine"] == "SQL":
|
|
101
|
-
db_path = os.path.expanduser("~/.npcsh_history.db")
|
|
102
|
-
query = response["data_operation"]
|
|
103
|
-
try:
|
|
104
|
-
print(f"Executing query in SQLite database: {query}")
|
|
105
|
-
with sqlite3.connect(db_path) as conn:
|
|
106
|
-
cursor = conn.cursor()
|
|
107
|
-
cursor.execute(query)
|
|
108
|
-
result = cursor.fetchall()
|
|
109
|
-
for row in result:
|
|
110
|
-
print(row)
|
|
111
|
-
except sqlite3.Error as e:
|
|
112
|
-
print(f"SQLite error: {e}")
|
|
113
|
-
except Exception as e:
|
|
114
|
-
print(f"Error executing query: {e}")
|
|
115
|
-
elif response["engine"] == "PYTHON":
|
|
116
|
-
engine = "python"
|
|
117
|
-
script = response["data_operation"]
|
|
118
|
-
try:
|
|
119
|
-
result = subprocess.run(
|
|
120
|
-
f"echo '{script}' | {engine}",
|
|
121
|
-
shell=True,
|
|
122
|
-
text=True,
|
|
123
|
-
capture_output=True,
|
|
124
|
-
)
|
|
125
|
-
if result.returncode == 0:
|
|
126
|
-
print(result.stdout)
|
|
127
|
-
else:
|
|
128
|
-
print(f"Error executing script: {result.stderr}")
|
|
129
|
-
except Exception as e:
|
|
130
|
-
print(f"Error executing script: {e}")
|
|
131
|
-
elif response["engine"] == "R":
|
|
132
|
-
engine = "Rscript"
|
|
133
|
-
script = response["data_operation"]
|
|
134
|
-
try:
|
|
135
|
-
result = subprocess.run(
|
|
136
|
-
f"echo '{script}' | {engine}",
|
|
137
|
-
shell=True,
|
|
138
|
-
text=True,
|
|
139
|
-
capture_output=True,
|
|
140
|
-
)
|
|
141
|
-
if result.returncode == 0:
|
|
142
|
-
print(result.stdout)
|
|
143
|
-
else:
|
|
144
|
-
print(f"Error executing script: {result.stderr}")
|
|
145
|
-
except Exception as e:
|
|
146
|
-
print(f"Error executing script: {e}")
|
|
147
|
-
else:
|
|
148
|
-
print("Error: Invalid engine specified.")
|
|
149
|
-
|
|
150
|
-
return response
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
def execute_llm_command(command, command_history):
|
|
154
|
-
max_attempts = 5
|
|
155
|
-
attempt = 0
|
|
156
|
-
subcommands = []
|
|
157
|
-
|
|
158
|
-
location = os.getcwd()
|
|
159
|
-
while attempt < max_attempts:
|
|
160
|
-
prompt = f"""
|
|
161
|
-
A user submitted this query: {command}.
|
|
162
|
-
You need to generate a bash command that will accomplish the user's intent.
|
|
163
|
-
Respond ONLY with the command that should be executed.
|
|
164
|
-
in the json key "bash_command".
|
|
165
|
-
You must reply with valid json and nothing else.
|
|
166
|
-
"""
|
|
167
|
-
|
|
168
|
-
response = get_llm_response(prompt, format="json")
|
|
169
|
-
print(f"LLM suggests: {response}")
|
|
170
|
-
|
|
171
|
-
if isinstance(response, dict) and "bash_command" in response:
|
|
172
|
-
bash_command = response["bash_command"]
|
|
173
|
-
else:
|
|
174
|
-
print("Error: Invalid response format from LLM")
|
|
175
|
-
attempt += 1
|
|
176
|
-
continue
|
|
177
|
-
|
|
178
|
-
try:
|
|
179
|
-
subcommands.append(bash_command)
|
|
180
|
-
result = subprocess.run(
|
|
181
|
-
bash_command, shell=True, text=True, capture_output=True
|
|
182
|
-
)
|
|
183
|
-
if result.returncode == 0:
|
|
184
|
-
# simplify the output
|
|
185
|
-
prompt = f"""
|
|
186
|
-
Here was the output of the result for the {command} inquiry
|
|
187
|
-
which ran this bash command {bash_command}:
|
|
188
|
-
|
|
189
|
-
{result.stdout}
|
|
190
|
-
|
|
191
|
-
Provide a simple short description that provides the most
|
|
192
|
-
useful information about the command's result.
|
|
193
|
-
|
|
194
|
-
"""
|
|
195
|
-
response = get_llm_response(prompt)
|
|
196
|
-
print(response)
|
|
197
|
-
output = response
|
|
198
|
-
command_history.add(command, subcommands, output, location)
|
|
199
|
-
|
|
200
|
-
return response
|
|
201
|
-
else:
|
|
202
|
-
print(f"Command failed with error:")
|
|
203
|
-
print(result.stderr)
|
|
204
|
-
|
|
205
|
-
error_prompt = f"""
|
|
206
|
-
The command '{bash_command}' failed with the following error:
|
|
207
|
-
{result.stderr}
|
|
208
|
-
Please suggest a fix or an alternative command.
|
|
209
|
-
Respond with a JSON object containing the key "bash_command" with the suggested command.
|
|
210
|
-
"""
|
|
211
|
-
fix_suggestion = get_llm_response(error_prompt, format="json")
|
|
212
|
-
if isinstance(fix_suggestion, dict) and "bash_command" in fix_suggestion:
|
|
213
|
-
print(f"LLM suggests fix: {fix_suggestion['bash_command']}")
|
|
214
|
-
command = fix_suggestion["bash_command"]
|
|
215
|
-
else:
|
|
216
|
-
print("Error: Invalid response format from LLM for fix suggestion")
|
|
217
|
-
except Exception as e:
|
|
218
|
-
print(f"Error executing command: {e}")
|
|
219
|
-
|
|
220
|
-
attempt += 1
|
|
221
|
-
command_history.add(command, subcommands, "Execution failed", location)
|
|
222
|
-
|
|
223
|
-
print("Max attempts reached. Unable to execute the command successfully.")
|
|
224
|
-
return "Max attempts reached. Unable to execute the command successfully."
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
def execute_llm_question(command, command_history):
|
|
228
|
-
location = os.getcwd()
|
|
229
|
-
|
|
230
|
-
prompt = f"""
|
|
231
|
-
A user submitted this query: {command}
|
|
232
|
-
You need to generate a response to the user's inquiry.
|
|
233
|
-
Respond ONLY with the response that should be given.
|
|
234
|
-
in the json key "response".
|
|
235
|
-
You must reply with valid json and nothing else.
|
|
236
|
-
"""
|
|
237
|
-
response = get_llm_response(prompt, format="json")
|
|
238
|
-
print(f"LLM suggests: {response}")
|
|
239
|
-
output = response["response"]
|
|
240
|
-
command_history.add(command, [], output, location)
|
|
241
|
-
return response["response"]
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
def execute_llm_thought(command, command_history):
|
|
245
|
-
location = os.getcwd()
|
|
246
|
-
prompt = f"""
|
|
247
|
-
A user submitted this query: {command} .
|
|
248
|
-
Please generate a response to the user's inquiry.
|
|
249
|
-
Respond ONLY with the response that should be given.
|
|
250
|
-
in the json key "response".
|
|
251
|
-
You must reply with valid json and nothing else.
|
|
252
|
-
"""
|
|
253
|
-
response = get_llm_response(prompt, format="json")
|
|
254
|
-
print(f"LLM suggests: {response}")
|
|
255
|
-
output = response["response"]
|
|
256
|
-
command_history.add(command, [], output, location)
|
|
257
|
-
return response["response"]
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
def check_llm_command(command, command_history):
|
|
261
|
-
# check what kind of request the command is
|
|
262
|
-
prompt = f"""
|
|
263
|
-
A user submitted this query: {command}
|
|
264
|
-
What kind of request is this?
|
|
265
|
-
[Command, Thought]
|
|
266
|
-
Thoughts are simply musings or ideas.
|
|
267
|
-
Commands are requests for a specific action to be performed.
|
|
268
|
-
|
|
269
|
-
Most requests are likely to be commands so only use the other options if
|
|
270
|
-
the request is clearly not a command.
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
Return your response in valid json key "request_type".
|
|
274
|
-
|
|
275
|
-
Provide an explanation in key "explanation".
|
|
276
|
-
Your answer must be like
|
|
277
|
-
|
|
278
|
-
{{"request_type": "Command",
|
|
279
|
-
"explanation": "This is a command because..."}}
|
|
280
|
-
or
|
|
281
|
-
{{"request_type": "Thought",
|
|
282
|
-
"explanation": "This is a thought because..."}}
|
|
283
|
-
"""
|
|
284
|
-
|
|
285
|
-
response = get_llm_response(prompt, format="json")
|
|
286
|
-
correct_request_type = response["request_type"]
|
|
287
|
-
print(f"LLM initially suggests: {response}")
|
|
288
|
-
# does the user agree with the request type? y/n
|
|
289
|
-
|
|
290
|
-
if correct_request_type == "Command":
|
|
291
|
-
return execute_llm_command(command, command_history)
|
|
292
|
-
elif correct_request_type == "Question":
|
|
293
|
-
return execute_llm_question(command, command_history)
|
|
294
|
-
elif correct_request_type == "Thought":
|
|
295
|
-
return execute_llm_thought(command, command_history)
|