gemini-computer-use 0.4.2 → 0.4.4

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.
package/core/policies.py DELETED
@@ -1,132 +0,0 @@
1
- import os
2
- import re
3
- from typing import List, Optional, Callable, Any, Awaitable
4
- from google.antigravity import types
5
- from google.antigravity.hooks import policy
6
- from google.antigravity.hooks.policy import Policy, Decision
7
-
8
- def _platform_root(posix_root: str) -> str:
9
- """Express a documented deployment root for the host running this node.
10
-
11
- ``/root/...`` is an absolute path on Linux but only drive-relative on Windows,
12
- where the SDK refuses it outright ("app_data_dir must be an absolute path") and
13
- ``os.makedirs`` would scatter a ``\\root\\...`` tree beside the drive root. The
14
- POSIX path is kept unchanged on POSIX hosts, so deployed services do not move.
15
- """
16
- if os.name != "nt":
17
- return posix_root
18
- leaf = posix_root.rstrip("/").rsplit("/", 1)[-1]
19
- return os.path.join(os.path.expanduser("~"), leaf)
20
-
21
-
22
- # Workspace roots are read from the environment ONLY -- never hardcode a personal
23
- # home directory. Point MESH_COORDINATOR_WORKSPACE / MESH_WORKSPACE at the real
24
- # deployment paths in the service environment. The documented defaults are the
25
- # Linux deployment paths; on Windows the same roots live under the user profile.
26
- ALLOWED_WORKSPACES = [
27
- os.environ.get("MESH_COORDINATOR_WORKSPACE") or _platform_root("/root/agy-gdrive-runner"),
28
- os.environ.get("MESH_WORKSPACE") or _platform_root("/root/antigravity-mesh"),
29
- ]
30
-
31
- SAFE_COMMAND_PREFIXES = [
32
- "git status",
33
- "git log",
34
- "git diff",
35
- "systemctl status",
36
- "uptime",
37
- "ls",
38
- "ps",
39
- "cat",
40
- "echo",
41
- "whoami",
42
- "uname",
43
- "df",
44
- "free",
45
- ]
46
-
47
- DESTRUCTIVE_COMMAND_PATTERNS = [
48
- re.compile(r"\breboot\b"),
49
- re.compile(r"\bshutdown\b"),
50
- re.compile(r"\bsystemctl\s+(stop|disable|mask|restart)\b"),
51
- re.compile(r"\brm\s+"),
52
- re.compile(r"\bpkill\b"),
53
- re.compile(r"\bkill\s+-9\b"),
54
- re.compile(r"\bmkfs\b"),
55
- re.compile(r"\bdd\s+"),
56
- ]
57
-
58
- def _is_within(path: str, root: str) -> bool:
59
- """True when *path* is *root* itself or lives inside it.
60
-
61
- The comparison has to use the platform separator: ``root + "/"`` never
62
- matches a normpath'ed Windows path, so every file inside an allowed workspace
63
- was rejected there and the policy could not be satisfied at all.
64
- """
65
- if path == root:
66
- return True
67
- root = root.rstrip("/\\")
68
- for sep in {os.sep, "/", "\\"}:
69
- if path.startswith(root + sep):
70
- return True
71
- return False
72
-
73
-
74
- def validate_workspace_path(path: str, allowed_workspaces: Optional[List[str]] = None) -> bool:
75
- workspaces = allowed_workspaces or ALLOWED_WORKSPACES
76
- abs_path = os.path.abspath(path)
77
- for ws in workspaces:
78
- if _is_within(abs_path, os.path.abspath(ws)):
79
- return True
80
- return False
81
-
82
- def _extract_command(args: dict) -> str:
83
- if not isinstance(args, dict):
84
- return ""
85
- return str(args.get("command") or args.get("CommandLine") or "").strip()
86
-
87
- def is_safe_command(args: dict) -> bool:
88
- cmd = _extract_command(args)
89
- if not cmd:
90
- return False
91
- return any(cmd.startswith(prefix) for prefix in SAFE_COMMAND_PREFIXES)
92
-
93
- def is_destructive_command(args: dict) -> bool:
94
- cmd = _extract_command(args)
95
- if not cmd:
96
- return False
97
- return any(pat.search(cmd) for pat in DESTRUCTIVE_COMMAND_PATTERNS)
98
-
99
- async def default_deny_handler(tool_call: types.ToolCall) -> bool:
100
- return False
101
-
102
- def get_mesh_policies(
103
- allowed_workspaces: Optional[List[str]] = None,
104
- ask_user_handler: Optional[Callable[[types.ToolCall], Awaitable[bool]]] = None,
105
- ) -> List[Policy]:
106
- handler = ask_user_handler or default_deny_handler
107
- policies: List[Policy] = []
108
-
109
- # 1. Ask user for destructive commands
110
- policies.append(
111
- policy.ask_user(
112
- "run_command",
113
- when=is_destructive_command,
114
- handler=handler,
115
- name="confirm_destructive",
116
- )
117
- )
118
-
119
- # 2. Allow safe commands without confirmation
120
- policies.append(
121
- policy.allow(
122
- "run_command",
123
- when=is_safe_command,
124
- name="allow_safe_commands",
125
- )
126
- )
127
-
128
- return policies
129
-
130
- async def evaluate_policies(policies: List[Policy], tool_call: types.ToolCall) -> types.HookResult:
131
- hook = policy._PolicyDecideHook(policies)
132
- return await hook.run(None, tool_call)
package/core/schemas.py DELETED
@@ -1,49 +0,0 @@
1
- from datetime import datetime, timezone
2
- from typing import List, Optional
3
- from pydantic import BaseModel, Field, field_validator
4
-
5
- class NodeVitals(BaseModel):
6
- hostname: str
7
- ip: str
8
- is_online: bool
9
- cpu_load_1m: float
10
- ram_used_mb: int
11
- ram_total_mb: int
12
- ram_usage_pct: float
13
- disk_free_gb: float
14
- disk_total_gb: float
15
- uptime: str
16
- timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
17
-
18
- @field_validator("ram_usage_pct")
19
- @classmethod
20
- def validate_ram_usage_pct(cls, v: float) -> float:
21
- if not (0.0 <= v <= 100.0):
22
- raise ValueError(f"ram_usage_pct must be between 0.0 and 100.0, got {v}")
23
- return v
24
-
25
- class ToolExecutionResult(BaseModel):
26
- command: str
27
- target_node: str
28
- exit_code: int
29
- duration_seconds: float
30
- stdout: str
31
- stderr: Optional[str] = None
32
- is_error: bool
33
- error_summary: Optional[str] = None
34
-
35
- class MeshHealthSnapshot(BaseModel):
36
- overall_healthy: bool
37
- healthy_node_count: int
38
- total_node_count: int
39
- nodes: List[NodeVitals]
40
- warnings: List[str] = Field(default_factory=list)
41
- timestamp: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
42
-
43
- class TaskDispatchPlan(BaseModel):
44
- task_id: str
45
- title: str
46
- target_nodes: List[str]
47
- ordered_steps: List[str]
48
- rollback_steps: List[str]
49
- dry_run_verified: bool = False