gothos 0.2.0__tar.gz → 0.2.2__tar.gz
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.
- {gothos-0.2.0 → gothos-0.2.2}/PKG-INFO +1 -1
- {gothos-0.2.0 → gothos-0.2.2}/gothos/__init__.py +1 -1
- {gothos-0.2.0 → gothos-0.2.2}/gothos/cli.py +29 -16
- {gothos-0.2.0 → gothos-0.2.2}/gothos/core/agent.py +1 -1
- {gothos-0.2.0 → gothos-0.2.2}/gothos/mcp/tools.py +6 -6
- {gothos-0.2.0 → gothos-0.2.2}/pyproject.toml +1 -1
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_mcp.py +3 -1
- {gothos-0.2.0 → gothos-0.2.2}/.dockerignore +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/.github/workflows/gothos-ci.yml +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/.github/workflows/publish.yml +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/.gitignore +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/.pre-commit-config.yaml +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/CONTRIBUTING.md +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/Dockerfile +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/LICENSE +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/Makefile +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/README.md +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/examples/agent_loop.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/examples/gothos_agent.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/examples/grounding_cascade.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/__main__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/benchmark/__init__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/benchmark/harness.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/benchmark/suites.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/console/__init__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/console/server.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/console/session_manager.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/console/static/index.html +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/core/__init__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/core/cache.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/core/compactor.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/core/config.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/core/retry.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/core/state.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/core/strategy.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/core/telemetry.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/device/__init__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/device/actions.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/device/adb.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/device/screenshot.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/extract/__init__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/extract/a11y_parser.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/extract/extractor.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/extract/mcp_tool.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/grounding/__init__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/grounding/a11y_navigator.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/grounding/ocr_fallback.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/grounding/provider_agnostic.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/llm/__init__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/llm/factory.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/mcp/__init__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/mcp/models.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/mcp/server.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/memory/__init__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/memory/action_recorder.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/memory/app_navigator.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/memory/models.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/memory/retriever.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/memory/store.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/planner/__init__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/planner/planner.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/planner/prompts.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/py.typed +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/safety/__init__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/safety/action_classifier.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/safety/confirmation.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/safety/dialog_handler.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/safety/policies.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/screen/__init__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/screen/analyzer.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/gothos/screen/models.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/start.bat +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/start.sh +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/__init__.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_benchmark.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_cli.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_compactor.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_console.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_core.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_device.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_extract.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_grounding.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_llm.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_memory.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_planner.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_production.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_safety.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_screen.py +0 -0
- {gothos-0.2.0 → gothos-0.2.2}/tests/test_strategy.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: gothos
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Provider-agnostic Android AI agent — automates any device using any LLM with safety gates, memory, planning and visual grounding
|
|
5
5
|
Project-URL: Homepage, https://github.com/GouthamRajam/GothOS
|
|
6
6
|
Project-URL: Repository, https://github.com/GouthamRajam/GothOS
|
|
@@ -179,7 +179,7 @@ async def _cmd_run(args: argparse.Namespace) -> int:
|
|
|
179
179
|
print(f"Max steps: {args.max_steps}")
|
|
180
180
|
print("-" * 50)
|
|
181
181
|
|
|
182
|
-
result = await agent.run(args.goal)
|
|
182
|
+
result = await agent.run(args.goal, app_package="")
|
|
183
183
|
|
|
184
184
|
print("-" * 50)
|
|
185
185
|
print(f"Success: {result.success}")
|
|
@@ -192,25 +192,38 @@ async def _cmd_run(args: argparse.Namespace) -> int:
|
|
|
192
192
|
|
|
193
193
|
|
|
194
194
|
async def _cmd_devices(_args: argparse.Namespace) -> int:
|
|
195
|
-
from gothos.device.adb import DeviceBridge
|
|
195
|
+
from gothos.device.adb import AdbError, DeviceBridge
|
|
196
196
|
|
|
197
197
|
bridge = DeviceBridge()
|
|
198
|
+
|
|
199
|
+
# List all connected device serials via adb
|
|
198
200
|
try:
|
|
199
|
-
await bridge.
|
|
201
|
+
raw = await bridge.adb("devices")
|
|
202
|
+
assert isinstance(raw, str)
|
|
200
203
|
except Exception as exc:
|
|
201
204
|
print(f"ADB connection failed: {exc}", file=sys.stderr)
|
|
202
205
|
return 1
|
|
203
206
|
|
|
204
|
-
|
|
205
|
-
|
|
207
|
+
serials: list[str] = []
|
|
208
|
+
for line in raw.strip().splitlines()[1:]:
|
|
209
|
+
parts = line.split()
|
|
210
|
+
if len(parts) >= 2 and parts[1] == "device":
|
|
211
|
+
serials.append(parts[0])
|
|
212
|
+
|
|
213
|
+
if not serials:
|
|
206
214
|
print("No devices connected.")
|
|
207
215
|
return 0
|
|
208
216
|
|
|
209
217
|
print(f"{'Serial':<25} {'Model':<20} {'SDK':<6} {'Screen'}")
|
|
210
218
|
print("-" * 70)
|
|
211
|
-
for
|
|
212
|
-
|
|
213
|
-
|
|
219
|
+
for serial in serials:
|
|
220
|
+
try:
|
|
221
|
+
b = DeviceBridge()
|
|
222
|
+
info = await b.connect(device_serial=serial)
|
|
223
|
+
screen = f"{info.screen_width}x{info.screen_height}" if info.screen_width else "unknown"
|
|
224
|
+
print(f"{info.serial:<25} {info.model:<20} {info.sdk_version or '?':<6} {screen}")
|
|
225
|
+
except AdbError:
|
|
226
|
+
print(f"{serial:<25} {'error':<20} {'?':<6} unknown")
|
|
214
227
|
|
|
215
228
|
return 0
|
|
216
229
|
|
|
@@ -219,8 +232,8 @@ async def _cmd_screenshot(args: argparse.Namespace) -> int:
|
|
|
219
232
|
from gothos.device.adb import DeviceBridge
|
|
220
233
|
from gothos.device.screenshot import capture_screenshot
|
|
221
234
|
|
|
222
|
-
bridge = DeviceBridge(
|
|
223
|
-
await bridge.connect()
|
|
235
|
+
bridge = DeviceBridge()
|
|
236
|
+
await bridge.connect(device_serial=args.device)
|
|
224
237
|
|
|
225
238
|
data = await capture_screenshot(bridge)
|
|
226
239
|
output = Path(args.output)
|
|
@@ -233,8 +246,8 @@ async def _cmd_hierarchy(args: argparse.Namespace) -> int:
|
|
|
233
246
|
from gothos.device.adb import DeviceBridge
|
|
234
247
|
from gothos.device.screenshot import dump_ui_hierarchy
|
|
235
248
|
|
|
236
|
-
bridge = DeviceBridge(
|
|
237
|
-
await bridge.connect()
|
|
249
|
+
bridge = DeviceBridge()
|
|
250
|
+
await bridge.connect(device_serial=args.device)
|
|
238
251
|
|
|
239
252
|
xml_str = await dump_ui_hierarchy(bridge)
|
|
240
253
|
|
|
@@ -259,11 +272,11 @@ async def _cmd_plan(args: argparse.Namespace) -> int:
|
|
|
259
272
|
model = args.model or _DEFAULT_MODELS.get(args.provider, "")
|
|
260
273
|
llm = build_llm(provider=args.provider, model=model)
|
|
261
274
|
|
|
262
|
-
bridge = DeviceBridge(
|
|
263
|
-
await bridge.connect()
|
|
275
|
+
bridge = DeviceBridge()
|
|
276
|
+
await bridge.connect(device_serial=args.device)
|
|
264
277
|
|
|
265
278
|
xml_str = await dump_ui_hierarchy(bridge)
|
|
266
|
-
screen_state = get_screen_state(
|
|
279
|
+
screen_state = await get_screen_state(bridge)
|
|
267
280
|
analyzer = ScreenAnalyzer()
|
|
268
281
|
analysis = analyzer.analyze(xml_str) # type: ignore[call-arg]
|
|
269
282
|
|
|
@@ -274,7 +287,7 @@ async def _cmd_plan(args: argparse.Namespace) -> int:
|
|
|
274
287
|
{
|
|
275
288
|
"interactive_elements": len(analysis.interactive_elements),
|
|
276
289
|
"visible_text": analysis.visible_text[:500], # type: ignore[attr-defined]
|
|
277
|
-
"current_package": screen_state.
|
|
290
|
+
"current_package": screen_state.app_package if screen_state else "unknown",
|
|
278
291
|
}
|
|
279
292
|
),
|
|
280
293
|
)
|
|
@@ -156,7 +156,7 @@ class GothOSAgent:
|
|
|
156
156
|
# Public API
|
|
157
157
|
# ------------------------------------------------------------------
|
|
158
158
|
|
|
159
|
-
async def run(self, goal: str, app_package: str) -> RunResult:
|
|
159
|
+
async def run(self, goal: str, app_package: str = "") -> RunResult:
|
|
160
160
|
"""Execute *goal* on *app_package* and return the outcome."""
|
|
161
161
|
if self._graph is None:
|
|
162
162
|
raise RuntimeError("Agent not initialised — call initialize() first")
|
|
@@ -181,8 +181,8 @@ async def capture_state(inp: CaptureStateInput) -> DeviceSnapshot:
|
|
|
181
181
|
)
|
|
182
182
|
from gothos.screen.analyzer import ScreenAnalyzer
|
|
183
183
|
|
|
184
|
-
bridge = DeviceBridge(
|
|
185
|
-
await bridge.connect()
|
|
184
|
+
bridge = DeviceBridge()
|
|
185
|
+
await bridge.connect(device_serial=inp.device_serial)
|
|
186
186
|
device_info = await bridge.get_device_info()
|
|
187
187
|
|
|
188
188
|
snapshot = DeviceSnapshot(
|
|
@@ -215,9 +215,9 @@ async def capture_state(inp: CaptureStateInput) -> DeviceSnapshot:
|
|
|
215
215
|
snapshot.interactive_count = len(analysis.interactive_elements)
|
|
216
216
|
snapshot.has_keyboard = analysis.has_keyboard
|
|
217
217
|
|
|
218
|
-
screen_state = get_screen_state(
|
|
218
|
+
screen_state = await get_screen_state(bridge)
|
|
219
219
|
if screen_state:
|
|
220
|
-
snapshot.current_package = screen_state.
|
|
220
|
+
snapshot.current_package = screen_state.app_package or ""
|
|
221
221
|
|
|
222
222
|
if inp.include_device_info:
|
|
223
223
|
current_pkg = await bridge.shell("dumpsys window | grep mCurrentFocus")
|
|
@@ -279,8 +279,8 @@ async def health_check(inp: HealthCheckInput) -> HealthReport:
|
|
|
279
279
|
try:
|
|
280
280
|
from gothos.device.adb import DeviceBridge
|
|
281
281
|
|
|
282
|
-
bridge = DeviceBridge(
|
|
283
|
-
await bridge.connect()
|
|
282
|
+
bridge = DeviceBridge()
|
|
283
|
+
await bridge.connect(device_serial=inp.device_serial)
|
|
284
284
|
report.adb_connected = True
|
|
285
285
|
|
|
286
286
|
device_info = await bridge.get_device_info()
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "gothos"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "Provider-agnostic Android AI agent — automates any device using any LLM with safety gates, memory, planning and visual grounding"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -8,6 +8,8 @@ from unittest.mock import patch
|
|
|
8
8
|
|
|
9
9
|
import pytest
|
|
10
10
|
|
|
11
|
+
import gothos
|
|
12
|
+
|
|
11
13
|
from gothos.mcp.models import (
|
|
12
14
|
ActionEntry,
|
|
13
15
|
CaptureStateInput,
|
|
@@ -431,7 +433,7 @@ class TestHealthCheck:
|
|
|
431
433
|
):
|
|
432
434
|
result = await health_check(HealthCheckInput(check_llm=False))
|
|
433
435
|
|
|
434
|
-
assert result.gothos_version ==
|
|
436
|
+
assert result.gothos_version == gothos.__version__
|
|
435
437
|
|
|
436
438
|
|
|
437
439
|
# ---------------------------------------------------------------------------
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|