mirror of
https://github.com/NCBM/plyngent.git
synced 2026-07-23 05:55:16 +08:00
core/tools: soft-confirm shells, REPLs, and python/bash -c one-liners
classify_danger prompts on interactive shell/runtime launches and any -c code (with argv + snippet preview). Confirm deny can attach a user comment for the model. Restores ToolRegistry.execute after WIP breakage.
This commit is contained in:
@@ -11,18 +11,71 @@ def test_classify_delete_and_move() -> None:
|
||||
assert "move" in (classify_danger("move_path", {"src": "a", "dst": "b"}) or "")
|
||||
|
||||
|
||||
def test_classify_copy_overwrite_only() -> None:
|
||||
assert classify_danger("copy_path", {"src": "a", "dst": "b"}) is None
|
||||
assert "overwrite" in (classify_danger("copy_path", {"src": "a", "dst": "b", "overwrite": True}) or "")
|
||||
def test_classify_copy() -> None:
|
||||
assert "copy" in (classify_danger("copy_path", {"src": "a", "dst": "b"}) or "")
|
||||
|
||||
|
||||
def test_classify_write_file_overwrite(workspace: object) -> None:
|
||||
assert isinstance(workspace, Path)
|
||||
_ = (workspace / "x.txt").write_text("old", encoding="utf-8")
|
||||
assert "overwrite" in (classify_danger("write_file", {"path": "x.txt", "content": "n"}) or "")
|
||||
assert classify_danger("write_file", {"path": "new.txt", "content": "n"}) is None
|
||||
def test_classify_write_and_edits(tmp_path: Path) -> None:
|
||||
from plyngent.tools.workspace import clear_workspace_root, set_workspace_root
|
||||
|
||||
set_workspace_root(tmp_path)
|
||||
try:
|
||||
reason = classify_danger("write_file", {"path": "x.txt"})
|
||||
assert reason is not None and "write file" in reason
|
||||
assert "edit" in (classify_danger("edit_replace", {"path": "x.txt"}) or "")
|
||||
assert "lines" in (classify_danger("edit_lineno", {"path": "x.txt", "start_line": 1, "end_line": 2}) or "")
|
||||
finally:
|
||||
clear_workspace_root()
|
||||
|
||||
|
||||
def test_classify_safe_tools() -> None:
|
||||
assert classify_danger("read_file", {"path": "a"}) is None
|
||||
assert classify_danger("listdir", {"path": "."}) is None
|
||||
assert classify_danger("run_command", {"command": ["echo", "hi"]}) is None
|
||||
assert classify_danger("open_pty", {"command": ["true"]}) is None
|
||||
assert classify_danger("run_command", {"command": ["ls", "-la"]}) is None
|
||||
|
||||
|
||||
def test_classify_shell_and_dash_c() -> None:
|
||||
r = classify_danger("run_command", {"command": ["bash", "-c", "rm -rf /"]})
|
||||
assert r is not None
|
||||
assert "bash -c" in r
|
||||
assert "rm -rf" in r
|
||||
|
||||
r2 = classify_danger("run_command", {"command": ["python3", "-c", "print(1)"]})
|
||||
assert r2 is not None
|
||||
assert "python" in r2
|
||||
assert "-c" in r2
|
||||
assert "print(1)" in r2
|
||||
|
||||
r_py = classify_danger("run_command", {"command": ["python", "-c", "import os"]})
|
||||
assert r_py is not None and "python -c" in r_py
|
||||
|
||||
r3 = classify_danger("open_pty", {"command": ["bash"]})
|
||||
assert r3 is not None and "bash" in r3
|
||||
assert "interactive" in r3 or "review" in r3
|
||||
|
||||
r4 = classify_danger("open_pty", {"command": ["python3"]})
|
||||
assert r4 is not None and "python" in r4
|
||||
|
||||
r5 = classify_danger("open_pty", {"command": ["python3", "-c", "x=1"]})
|
||||
assert r5 is not None and "-c" in r5
|
||||
|
||||
|
||||
async def test_confirm_deny_with_comment() -> None:
|
||||
from plyngent.agent.tools import ToolRegistry, tool
|
||||
from plyngent.tools.danger import classify_danger as danger
|
||||
|
||||
@tool
|
||||
def delete_path(path: str) -> str:
|
||||
return f"deleted {path}"
|
||||
|
||||
async def deny_comment(name: str, args: object, reason: str) -> str:
|
||||
del name, args, reason
|
||||
return "too destructive for this session"
|
||||
|
||||
reg = ToolRegistry([delete_path], danger=danger, on_confirm=deny_comment)
|
||||
out = await reg.execute("delete_path", '{"path": "x"}')
|
||||
assert "denied" in out
|
||||
assert "user comment:" in out
|
||||
assert "too destructive" in out
|
||||
|
||||
Reference in New Issue
Block a user