aboutsummaryrefslogtreecommitdiff
path: root/actions.py
diff options
context:
space:
mode:
authorJoel Kronqvist <joel.kronqvist@iki.fi>2026-10-10 23:17:46 +0300
committerJoel Kronqvist <joel.kronqvist@iki.fi>2026-10-10 23:47:22 +0300
commit7a00701c535877a22f8a5ae0dfea260459407f05 (patch)
tree4bfaa85a30225a93968001d9939c0253186ead47 /actions.py
parentcf186f82c6acf8faac6e99999442173145c43227 (diff)
downloadagent-7a00701c535877a22f8a5ae0dfea260459407f05.tar.gz
agent-7a00701c535877a22f8a5ae0dfea260459407f05.zip
develop on the agentic features
Diffstat (limited to 'actions.py')
-rw-r--r--actions.py64
1 files changed, 64 insertions, 0 deletions
diff --git a/actions.py b/actions.py
new file mode 100644
index 0000000..9146e53
--- /dev/null
+++ b/actions.py
@@ -0,0 +1,64 @@
+from pathlib import Path
+from typing import Optional
+import subprocess
+
+def _path_checked(path: Path, cwd=Path.cwd()) -> Optional[Path]:
+ """Resolves `path`, returning `None` if it's not a subdirectory of `cwd`."""
+ path = path.resolve()
+ cwd = cwd.resolve()
+ return path if path.is_relative_to(cwd) else None
+
+def _path_helper(path_str: str, callback):
+ path = _path_checked(Path(path_str))
+ if path is None:
+ return {"status": "error", "reason": f"Permission denied: {path_str}"}
+ else:
+ try:
+ return {"status": "success", **callback(path)}
+ except Exception as e:
+ return {"status": "error", "reason": f"Failure: {e}"}
+
+def ls(args):
+ '{"action": "ls", "path": PATH} - list files at PATH'
+ def inner(path: Path):
+ return {"content": list(map(lambda s: str(s), path.iterdir()))}
+ match args:
+ case {"action": "ls", "path": path_str}:
+ return _path_helper(path_str, inner)
+
+def read(args):
+ '{"action": "read", "path": PATH} - read file at PATH'
+ def inner(path: Path):
+ contents = path.read_text(encoding="utf-8")
+ return {"content": contents}
+ match args:
+ case {"action": "read", "path": path_str}:
+ return _path_helper(path_str, inner)
+
+def write(args):
+ '{"action": "write", "path": PATH, "content": CONTENT} - write CONTENT into file at PATH'
+ def inner(path: Path, text: str):
+ n_bytes = path.write_text(text)
+ return {"bytes": n_bytes}
+ match args:
+ case {"action": "write", "path": path_str, "content": content}:
+ return _path_helper(path_str, lambda path: inner(path, content))
+
+def tldr(args):
+ '{"action": "tldr", "program": PROGRAM} - read tldr docs for PROGRAM'
+ match args:
+ case {"action": "tldr", "program": program_str}:
+ try:
+ result = subprocess.run(
+ ["tldr", program_str],
+ capture_output=True,
+ text=True,
+ check=True
+ )
+ return {"status": "success", "content": result.stdout}
+ except subprocess.CalledProcessError:
+ return {"status": "error", "reason": f"Tldr for '{program_str}' not found."}
+ except Exception as e:
+ return {"status": "error", "reason": f"An unexpected error occurred: {e}"}
+
+ALL_ACTIONS = [ls, read, write, tldr]