-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathpowershell.py
More file actions
99 lines (85 loc) · 3.5 KB
/
Copy pathpowershell.py
File metadata and controls
99 lines (85 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
"""PowerShell command execution tool."""
from __future__ import annotations
from pathlib import Path
from pydantic import BaseModel
from koder_agent.harness.permissions.powershell_classifier import classify_powershell_command
from koder_agent.harness.sandbox_settings import is_excluded_command, resolve_sandbox_settings
from koder_agent.harness.tools.shell_executor import (
capture_unsandboxed_fallback_requirement,
execute_powershell_command,
unsandboxed_fallback_requirement_mismatch,
)
from .compat import function_tool
from .permission_context import approve_sandbox_degradation
class PowerShellModel(BaseModel):
command: str
timeout: int = 120
run_in_background: bool = False
@function_tool
async def run_powershell(command: str, timeout: int = 120, run_in_background: bool = False) -> str:
"""Execute a PowerShell command with Koder permission and background support.
Args:
command: The PowerShell command to execute.
timeout: Timeout in seconds for foreground commands. The value is clamped to 1-600.
run_in_background: Set true for long-running commands. Use shell_output to monitor.
Returns:
Command output, or a shell_id if run_in_background=True.
"""
decision = classify_powershell_command(command)
if not decision.allowed:
return decision.reason
cwd = Path.cwd()
sandbox_state = resolve_sandbox_settings(cwd)
degraded = sandbox_state.enabled and not is_excluded_command(command, cwd=cwd)
if degraded:
fallback_trigger = "PowerShell sandbox execution is unsupported"
fallback_requirement = capture_unsandboxed_fallback_requirement(
sandbox_state,
command=command,
trigger=fallback_trigger,
)
if fallback_requirement is None:
return (
"sandboxed: false\ncreated: false\nexecuted: false\n"
"reason: unable to capture exact PowerShell sandbox fallback state; "
"host execution was blocked"
)
approved = await approve_sandbox_degradation(
"run_powershell",
{
"command": command,
"timeout": timeout,
"run_in_background": run_in_background,
},
fallback_requirement.reason,
)
if not approved:
return (
"sandboxed: false\ncreated: false\nexecuted: false\n"
"reason: exact PowerShell unsandboxed fallback approval was not granted; "
f"{fallback_requirement.reason}"
)
refreshed_state = resolve_sandbox_settings(Path.cwd())
mismatch_reason = unsandboxed_fallback_requirement_mismatch(
fallback_requirement,
refreshed_state,
command=command,
trigger=fallback_trigger,
)
if mismatch_reason is not None:
return (
"sandboxed: false\ncreated: false\nexecuted: false\n"
"reason: sandbox state changed after exact PowerShell fallback approval; "
f"{mismatch_reason}; a new exact approval is required before execution"
)
result = await execute_powershell_command(
command,
timeout=timeout,
run_in_background=run_in_background,
)
if degraded:
return (
"warning: PowerShell sandbox execution is unsupported; running UNSANDBOXED "
f"with exact state-bound approval\n{result.output}"
)
return result.output