diff --git a/connpy/_version.py b/connpy/_version.py
index 2d6a1e5..f27f650 100644
--- a/connpy/_version.py
+++ b/connpy/_version.py
@@ -1,2 +1,2 @@
-__version__ = "5.0b1"
+__version__ = "5.0b2"
diff --git a/docs/connpy/index.html b/docs/connpy/index.html
index 227b950..c3dd081 100644
--- a/docs/connpy/index.html
+++ b/docs/connpy/index.html
@@ -3,7 +3,7 @@
-
+
connpy API documentation
@@ -551,6 +551,13 @@ class Preload:
@@ -623,8 +630,8 @@ class Preload:
if not (isinstance(node.test, ast.Compare) and
isinstance(node.test.left, ast.Name) and
node.test.left.id == '__name__' and
- isinstance(node.test.comparators[0], ast.Str) and
- node.test.comparators[0].s == '__main__'):
+ ((hasattr(ast, 'Str') and isinstance(node.test.comparators[0], getattr(ast, 'Str')) and node.test.comparators[0].s == '__main__') or
+ (hasattr(ast, 'Constant') and isinstance(node.test.comparators[0], getattr(ast, 'Constant')) and node.test.comparators[0].value == '__main__'))):
return "Only __name__ == __main__ If is allowed"
elif not isinstance(node, (ast.FunctionDef, ast.ClassDef, ast.Import, ast.ImportFrom, ast.Pass)):
@@ -758,8 +765,8 @@ class Preload:
if not (isinstance(node.test, ast.Compare) and
isinstance(node.test.left, ast.Name) and
node.test.left.id == '__name__' and
- isinstance(node.test.comparators[0], ast.Str) and
- node.test.comparators[0].s == '__main__'):
+ ((hasattr(ast, 'Str') and isinstance(node.test.comparators[0], getattr(ast, 'Str')) and node.test.comparators[0].s == '__main__') or
+ (hasattr(ast, 'Constant') and isinstance(node.test.comparators[0], getattr(ast, 'Constant')) and node.test.comparators[0].value == '__main__'))):
return "Only __name__ == __main__ If is allowed"
elif not isinstance(node, (ast.FunctionDef, ast.ClassDef, ast.Import, ast.ImportFrom, ast.Pass)):
@@ -1217,7 +1224,7 @@ class ai:
if isinstance(commands, str):
try:
commands = json.loads(commands)
- except:
+ except ValueError:
commands = [c.strip() for c in commands.split('\n') if c.strip()]
# Expand multi-line commands within a list (in case the AI packs them)
@@ -1616,9 +1623,10 @@ class ai:
response = completion(model=model, messages=safe_messages, tools=[], api_key=key)
resp_msg = response.choices[0].message
messages.append(resp_msg.model_dump(exclude_none=True))
- except:
- pass
-
+ except Exception as e:
+ if status:
+ status.update(f"[bold red]Error fetching summary: {e}[/bold red]")
+ printer.warning(f"Failed to fetch final summary from LLM: {e}")
except KeyboardInterrupt:
if status: status.update("[bold red]Interrupted! Closing pending tasks...")
last_msg = messages[-1]
@@ -1631,7 +1639,7 @@ class ai:
response = completion(model=model, messages=safe_messages, tools=tools, api_key=key)
resp_msg = response.choices[0].message
messages.append(resp_msg.model_dump(exclude_none=True))
- except: pass
+ except Exception: pass
finally:
try:
log_dir = self.config.defaultdir
@@ -1641,7 +1649,7 @@ class ai:
if os.path.exists(log_path):
try:
with open(log_path, "r") as f: hist = json.load(f)
- except: hist = []
+ except (IOError, json.JSONDecodeError): hist = []
hist.append({"timestamp": datetime.datetime.now().isoformat(), "roles": {"strategic_engine": self.architect_model, "execution_engine": self.engineer_model}, "session": messages})
with open(log_path, "w") as f: json.dump(hist[-10:], f, indent=4)
except Exception as e:
@@ -1664,7 +1672,7 @@ class ai:
var SAFE_COMMANDS
-
-
+
The type of the None singleton.
Instance variables
@@ -1925,9 +1933,10 @@ def ask(self, user_input, dryrun=False, chat_history=None, status=None, debug=Fa
response = completion(model=model, messages=safe_messages, tools=[], api_key=key)
resp_msg = response.choices[0].message
messages.append(resp_msg.model_dump(exclude_none=True))
- except:
- pass
-
+ except Exception as e:
+ if status:
+ status.update(f"[bold red]Error fetching summary: {e}[/bold red]")
+ printer.warning(f"Failed to fetch final summary from LLM: {e}")
except KeyboardInterrupt:
if status: status.update("[bold red]Interrupted! Closing pending tasks...")
last_msg = messages[-1]
@@ -1940,7 +1949,7 @@ def ask(self, user_input, dryrun=False, chat_history=None, status=None, debug=Fa
response = completion(model=model, messages=safe_messages, tools=tools, api_key=key)
resp_msg = response.choices[0].message
messages.append(resp_msg.model_dump(exclude_none=True))
- except: pass
+ except Exception: pass
finally:
try:
log_dir = self.config.defaultdir
@@ -1950,7 +1959,7 @@ def ask(self, user_input, dryrun=False, chat_history=None, status=None, debug=Fa
if os.path.exists(log_path):
try:
with open(log_path, "r") as f: hist = json.load(f)
- except: hist = []
+ except (IOError, json.JSONDecodeError): hist = []
hist.append({"timestamp": datetime.datetime.now().isoformat(), "roles": {"strategic_engine": self.architect_model, "execution_engine": self.engineer_model}, "session": messages})
with open(log_path, "w") as f: json.dump(hist[-10:], f, indent=4)
except Exception as e:
@@ -2123,7 +2132,7 @@ def confirm(self, user_input): return True
if isinstance(commands, str):
try:
commands = json.loads(commands)
- except:
+ except ValueError:
commands = [c.strip() for c in commands.split('\n') if c.strip()]
# Expand multi-line commands within a list (in case the AI packs them)
@@ -2246,7 +2255,7 @@ class configfile:
try:
with open(pathfile, "r") as f:
configdir = f.read().strip()
- except:
+ except (FileNotFoundError, IOError):
with open(pathfile, "w") as f:
f.write(str(defaultdir))
configdir = defaultdir
@@ -2306,7 +2315,8 @@ class configfile:
with open(conf, "w") as f:
json.dump(newconfig, f, indent = 4)
f.close()
- except:
+ except (IOError, OSError) as e:
+ printer.error(f"Failed to save config: {e}")
return 1
return 0
@@ -2391,12 +2401,12 @@ class configfile:
if profile:
try:
newfolder[node_name][key] = self.profiles[profile.group(1)][key]
- except:
+ except KeyError:
newfolder[node_name][key] = ""
elif value == '' and key == "protocol":
try:
newfolder[node_name][key] = self.profiles["default"][key]
- except:
+ except KeyError:
newfolder[node_name][key] = "ssh"
newfolder = {"{}{}".format(k,unique):v for k,v in newfolder.items()}
@@ -2417,12 +2427,12 @@ class configfile:
if profile:
try:
newnode[key] = self.profiles[profile.group(1)][key]
- except:
+ except KeyError:
newnode[key] = ""
elif value == '' and key == "protocol":
try:
newnode[key] = self.profiles["default"][key]
- except:
+ except KeyError:
newnode[key] = "ssh"
return newnode
@@ -2577,12 +2587,12 @@ class configfile:
if profile:
try:
nodes[node][key] = self.profiles[profile.group(1)][key]
- except:
+ except KeyError:
nodes[node][key] = ""
elif value == '' and key == "protocol":
try:
nodes[node][key] = self.profiles["default"][key]
- except:
+ except KeyError:
nodes[node][key] = "ssh"
return nodes
@@ -2780,12 +2790,12 @@ def getitem(self, unique, keys = None, extract = False):
if profile:
try:
newfolder[node_name][key] = self.profiles[profile.group(1)][key]
- except:
+ except KeyError:
newfolder[node_name][key] = ""
elif value == '' and key == "protocol":
try:
newfolder[node_name][key] = self.profiles["default"][key]
- except:
+ except KeyError:
newfolder[node_name][key] = "ssh"
newfolder = {"{}{}".format(k,unique):v for k,v in newfolder.items()}
@@ -2806,12 +2816,12 @@ def getitem(self, unique, keys = None, extract = False):
if profile:
try:
newnode[key] = self.profiles[profile.group(1)][key]
- except:
+ except KeyError:
newnode[key] = ""
elif value == '' and key == "protocol":
try:
newnode[key] = self.profiles["default"][key]
- except:
+ except KeyError:
newnode[key] = "ssh"
return newnode
@@ -2979,12 +2989,12 @@ class node:
if profile and config != '':
try:
setattr(self,key,config.profiles[profile.group(1)][key])
- except:
+ except KeyError:
setattr(self,key,"")
elif attr[key] == '' and key == "protocol":
try:
setattr(self,key,config.profiles["default"][key])
- except:
+ except (KeyError, AttributeError):
setattr(self,key,"ssh")
else:
setattr(self,key,attr[key])
@@ -3003,12 +3013,12 @@ class node:
if profile:
try:
self.jumphost[key] = config.profiles[profile.group(1)][key]
- except:
+ except KeyError:
self.jumphost[key] = ""
elif self.jumphost[key] == '' and key == "protocol":
try:
self.jumphost[key] = config.profiles["default"][key]
- except:
+ except KeyError:
self.jumphost[key] = "ssh"
if isinstance(self.jumphost["password"],list):
jumphost_password = []
@@ -3053,7 +3063,7 @@ class node:
try:
decrypted = decryptor.decrypt(ast.literal_eval(passwd)).decode("utf-8")
dpass.append(decrypted)
- except:
+ except Exception:
raise ValueError("Missing or corrupted key")
return dpass
@@ -4579,6 +4589,11 @@ def test(self, commands, expected, vars = None,*, prompt = None, parallel = 10,
+-
+
+
-
-
@@ -4631,7 +4646,7 @@ def test(self, commands, expected, vars = None,*, prompt = None, parallel = 10,