use-computer 0.0.22__tar.gz → 0.0.24__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.
- {use_computer-0.0.22 → use_computer-0.0.24}/PKG-INFO +14 -1
- {use_computer-0.0.22 → use_computer-0.0.24}/README.md +13 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/pyproject.toml +1 -1
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/__init__.py +4 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/client.py +71 -3
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/sandbox.py +111 -3
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/windows/shell.py +11 -7
- use_computer-0.0.22/examples/_1_hello_macos.py +0 -8
- use_computer-0.0.22/examples/_2_hello_ios.py +0 -11
- use_computer-0.0.22/examples/_3_recording.py +0 -10
- use_computer-0.0.22/examples/_4_file_transfer.py +0 -7
- use_computer-0.0.22/examples/_5_keepalive.py +0 -9
- use_computer-0.0.22/examples/_6_hello_tvos.py +0 -11
- use_computer-0.0.22/examples/_7_hello_windows.py +0 -11
- use_computer-0.0.22/examples/go/hello_windows.go +0 -35
- use_computer-0.0.22/examples/javascript/hello_windows.ts +0 -14
- use_computer-0.0.22/go/README.md +0 -46
- use_computer-0.0.22/go/client.go +0 -192
- use_computer-0.0.22/go/go.mod +0 -3
- use_computer-0.0.22/go/sandbox.go +0 -156
- use_computer-0.0.22/javascript/.gitignore +0 -3
- use_computer-0.0.22/javascript/README.md +0 -48
- use_computer-0.0.22/javascript/package-lock.json +0 -51
- use_computer-0.0.22/javascript/package.json +0 -27
- use_computer-0.0.22/javascript/src/client.ts +0 -82
- use_computer-0.0.22/javascript/src/http.ts +0 -96
- use_computer-0.0.22/javascript/src/index.ts +0 -11
- use_computer-0.0.22/javascript/src/sandbox.ts +0 -208
- use_computer-0.0.22/javascript/tsconfig.json +0 -16
- {use_computer-0.0.22 → use_computer-0.0.24}/.env.example +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/.gitignore +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/.pre-commit-config.yaml +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/accessibility.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/ax_transpile.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/display.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/errors.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/ios/__init__.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/ios/apps.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/ios/environment.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/ios/input.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/macos/__init__.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/macos/keyboard.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/macos/mouse.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/models.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/parsers.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/py.typed +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/recording.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/retry.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/screenshot.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/simulators.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/tasks/__init__.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/tasks/templates/pre_command.sh +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/tasks/templates/task.toml +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/tasks/templates/test_ios.sh +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/tasks/templates/test_ios_nograder.sh +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/tasks/templates/test_macos.sh +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/tasks/templates/test_macos_check.sh +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/tasks/templates/test_macos_nograder.sh +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/use_computer/windows/__init__.py +0 -0
- {use_computer-0.0.22 → use_computer-0.0.24}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: use-computer
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.24
|
|
4
4
|
Summary: Python SDK for the use.computer macOS and iOS Computer Use API
|
|
5
5
|
Project-URL: Homepage, https://use.computer
|
|
6
6
|
Project-URL: Documentation, https://api.use.computer/docs
|
|
@@ -60,6 +60,19 @@ recording/file surface as macOS; exec runs in-guest via PowerShell/cmd
|
|
|
60
60
|
(`win.run` / `win.shell`) instead of SSH. `AsyncWindowsSandbox` mirrors it.
|
|
61
61
|
See [docs.use.computer/docs/windows](https://docs.use.computer/docs/windows).
|
|
62
62
|
|
|
63
|
+
### Ubuntu (Beta)
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
with Computer().create(type="ubuntu", version="ubuntu-24.04") as ubuntu:
|
|
67
|
+
print(ubuntu.run("uname -a").stdout) # bash exec (no SSH)
|
|
68
|
+
ubuntu.keyboard.type("hello")
|
|
69
|
+
ubuntu.screenshot.take_full_screen()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Ubuntu sandboxes are **Beta** (admin-only). They use the same KVM/noVNC backend
|
|
73
|
+
as Windows; pass `version="ubuntu-24.04"` to select a specific image. Exec
|
|
74
|
+
defaults to bash and the macOS accessibility tree is not available yet.
|
|
75
|
+
|
|
63
76
|
Full DSL reference (macOS + simulator): [docs.use.computer/docs/sdk](https://docs.use.computer/docs/sdk)
|
|
64
77
|
|
|
65
78
|
Simulator sandboxes use `type=SandboxType.IOS` for the SDK route, but
|
|
@@ -38,6 +38,19 @@ recording/file surface as macOS; exec runs in-guest via PowerShell/cmd
|
|
|
38
38
|
(`win.run` / `win.shell`) instead of SSH. `AsyncWindowsSandbox` mirrors it.
|
|
39
39
|
See [docs.use.computer/docs/windows](https://docs.use.computer/docs/windows).
|
|
40
40
|
|
|
41
|
+
### Ubuntu (Beta)
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
with Computer().create(type="ubuntu", version="ubuntu-24.04") as ubuntu:
|
|
45
|
+
print(ubuntu.run("uname -a").stdout) # bash exec (no SSH)
|
|
46
|
+
ubuntu.keyboard.type("hello")
|
|
47
|
+
ubuntu.screenshot.take_full_screen()
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Ubuntu sandboxes are **Beta** (admin-only). They use the same KVM/noVNC backend
|
|
51
|
+
as Windows; pass `version="ubuntu-24.04"` to select a specific image. Exec
|
|
52
|
+
defaults to bash and the macOS accessibility tree is not available yet.
|
|
53
|
+
|
|
41
54
|
Full DSL reference (macOS + simulator): [docs.use.computer/docs/sdk](https://docs.use.computer/docs/sdk)
|
|
42
55
|
|
|
43
56
|
Simulator sandboxes use `type=SandboxType.IOS` for the SDK route, but
|
|
@@ -15,11 +15,13 @@ from use_computer.sandbox import (
|
|
|
15
15
|
AsyncIOSSandbox,
|
|
16
16
|
AsyncMacOSSandbox,
|
|
17
17
|
AsyncSandbox,
|
|
18
|
+
AsyncUbuntuSandbox,
|
|
18
19
|
AsyncWindowsSandbox,
|
|
19
20
|
IOSSandbox,
|
|
20
21
|
MacOSSandbox,
|
|
21
22
|
Sandbox,
|
|
22
23
|
SandboxType,
|
|
24
|
+
UbuntuSandbox,
|
|
23
25
|
WindowsSandbox,
|
|
24
26
|
)
|
|
25
27
|
from use_computer.simulators import (
|
|
@@ -42,6 +44,7 @@ __all__ = [
|
|
|
42
44
|
"AsyncMacOSSandbox",
|
|
43
45
|
"AsyncComputer",
|
|
44
46
|
"AsyncSandbox",
|
|
47
|
+
"AsyncUbuntuSandbox",
|
|
45
48
|
"AsyncWindowsSandbox",
|
|
46
49
|
"Button",
|
|
47
50
|
"Computer",
|
|
@@ -63,6 +66,7 @@ __all__ = [
|
|
|
63
66
|
"TaskSummary",
|
|
64
67
|
"TasksClient",
|
|
65
68
|
"UseComputerError",
|
|
69
|
+
"UbuntuSandbox",
|
|
66
70
|
"WindowsSandbox",
|
|
67
71
|
"family_for_device",
|
|
68
72
|
"is_usable_device_type",
|
|
@@ -14,11 +14,13 @@ from use_computer.sandbox import (
|
|
|
14
14
|
AsyncIOSSandbox,
|
|
15
15
|
AsyncMacOSSandbox,
|
|
16
16
|
AsyncSandbox,
|
|
17
|
+
AsyncUbuntuSandbox,
|
|
17
18
|
AsyncWindowsSandbox,
|
|
18
19
|
IOSSandbox,
|
|
19
20
|
MacOSSandbox,
|
|
20
21
|
Sandbox,
|
|
21
22
|
SandboxType,
|
|
23
|
+
UbuntuSandbox,
|
|
22
24
|
WindowsSandbox,
|
|
23
25
|
)
|
|
24
26
|
from use_computer.simulators import SimulatorFamily, select_simulator
|
|
@@ -26,7 +28,7 @@ from use_computer.tasks import TasksClient
|
|
|
26
28
|
|
|
27
29
|
DEFAULT_BASE_URL = "https://api.use.computer"
|
|
28
30
|
|
|
29
|
-
SandboxTypeInput = SandboxType | Literal["macos", "ios", "windows"]
|
|
31
|
+
SandboxTypeInput = SandboxType | Literal["macos", "ios", "windows", "ubuntu"]
|
|
30
32
|
|
|
31
33
|
|
|
32
34
|
def _resolve_api_key(api_key: str | None) -> str | None:
|
|
@@ -135,9 +137,19 @@ class Computer:
|
|
|
135
137
|
self,
|
|
136
138
|
*,
|
|
137
139
|
type: Literal["windows", SandboxType.WINDOWS],
|
|
140
|
+
version: str = ...,
|
|
138
141
|
host: str = ...,
|
|
139
142
|
) -> WindowsSandbox: ...
|
|
140
143
|
|
|
144
|
+
@overload
|
|
145
|
+
def create(
|
|
146
|
+
self,
|
|
147
|
+
*,
|
|
148
|
+
type: Literal["ubuntu", SandboxType.UBUNTU],
|
|
149
|
+
version: str = ...,
|
|
150
|
+
host: str = ...,
|
|
151
|
+
) -> UbuntuSandbox: ...
|
|
152
|
+
|
|
141
153
|
def create(
|
|
142
154
|
self,
|
|
143
155
|
*,
|
|
@@ -146,7 +158,8 @@ class Computer:
|
|
|
146
158
|
family: SimulatorFamily | str | None = None,
|
|
147
159
|
device_type: str = "",
|
|
148
160
|
runtime: str = "",
|
|
149
|
-
|
|
161
|
+
version: str = "",
|
|
162
|
+
) -> MacOSSandbox | IOSSandbox | WindowsSandbox | UbuntuSandbox:
|
|
150
163
|
"""Create a new sandbox.
|
|
151
164
|
|
|
152
165
|
Args:
|
|
@@ -155,11 +168,15 @@ class Computer:
|
|
|
155
168
|
family: Simulator family enum/alias, for example SimulatorFamily.TV.
|
|
156
169
|
device_type: Simulator device type identifier, for exact pinning.
|
|
157
170
|
runtime: Simulator runtime identifier, for exact pinning.
|
|
171
|
+
version: KVM desktop image version, for example "windows-11",
|
|
172
|
+
"windows-10", or "ubuntu-24.04".
|
|
158
173
|
"""
|
|
159
174
|
sandbox_type = _normalize_sandbox_type(type)
|
|
160
175
|
body: dict = {"type": sandbox_type.value}
|
|
161
176
|
if host:
|
|
162
177
|
body["host"] = host
|
|
178
|
+
if sandbox_type in (SandboxType.WINDOWS, SandboxType.UBUNTU) and version:
|
|
179
|
+
body["version"] = version
|
|
163
180
|
if sandbox_type == SandboxType.IOS:
|
|
164
181
|
if family and (not device_type or not runtime):
|
|
165
182
|
choice = select_simulator(self.platforms(), family)
|
|
@@ -183,6 +200,15 @@ class Computer:
|
|
|
183
200
|
http=self._http,
|
|
184
201
|
vnc_url=f"{self._base_url}{data.get('vnc_url', '')}",
|
|
185
202
|
host=data.get("host", ""),
|
|
203
|
+
version=data.get("version", ""),
|
|
204
|
+
)
|
|
205
|
+
if sandbox_type == SandboxType.UBUNTU:
|
|
206
|
+
return UbuntuSandbox(
|
|
207
|
+
sandbox_id=sid,
|
|
208
|
+
http=self._http,
|
|
209
|
+
vnc_url=f"{self._base_url}{data.get('vnc_url', '')}",
|
|
210
|
+
host=data.get("host", ""),
|
|
211
|
+
version=data.get("version", ""),
|
|
186
212
|
)
|
|
187
213
|
return MacOSSandbox(
|
|
188
214
|
sandbox_id=sid,
|
|
@@ -207,6 +233,15 @@ class Computer:
|
|
|
207
233
|
http=self._http,
|
|
208
234
|
vnc_url=f"{self._base_url}{data.get('vnc_url', '')}",
|
|
209
235
|
host=data.get("host", ""),
|
|
236
|
+
version=data.get("version", ""),
|
|
237
|
+
)
|
|
238
|
+
if sb_type == SandboxType.UBUNTU:
|
|
239
|
+
return UbuntuSandbox(
|
|
240
|
+
sandbox_id=data["sandbox_id"],
|
|
241
|
+
http=self._http,
|
|
242
|
+
vnc_url=f"{self._base_url}{data.get('vnc_url', '')}",
|
|
243
|
+
host=data.get("host", ""),
|
|
244
|
+
version=data.get("version", ""),
|
|
210
245
|
)
|
|
211
246
|
return MacOSSandbox(
|
|
212
247
|
sandbox_id=data["sandbox_id"],
|
|
@@ -321,9 +356,19 @@ class AsyncComputer:
|
|
|
321
356
|
self,
|
|
322
357
|
*,
|
|
323
358
|
type: Literal["windows", SandboxType.WINDOWS],
|
|
359
|
+
version: str = ...,
|
|
324
360
|
host: str = ...,
|
|
325
361
|
) -> AsyncWindowsSandbox: ...
|
|
326
362
|
|
|
363
|
+
@overload
|
|
364
|
+
async def create(
|
|
365
|
+
self,
|
|
366
|
+
*,
|
|
367
|
+
type: Literal["ubuntu", SandboxType.UBUNTU],
|
|
368
|
+
version: str = ...,
|
|
369
|
+
host: str = ...,
|
|
370
|
+
) -> AsyncUbuntuSandbox: ...
|
|
371
|
+
|
|
327
372
|
async def create(
|
|
328
373
|
self,
|
|
329
374
|
*,
|
|
@@ -332,7 +377,8 @@ class AsyncComputer:
|
|
|
332
377
|
family: SimulatorFamily | str | None = None,
|
|
333
378
|
device_type: str = "",
|
|
334
379
|
runtime: str = "",
|
|
335
|
-
|
|
380
|
+
version: str = "",
|
|
381
|
+
) -> AsyncMacOSSandbox | AsyncIOSSandbox | AsyncWindowsSandbox | AsyncUbuntuSandbox:
|
|
336
382
|
"""Create a new sandbox.
|
|
337
383
|
|
|
338
384
|
Args:
|
|
@@ -341,11 +387,15 @@ class AsyncComputer:
|
|
|
341
387
|
family: Simulator family enum/alias, for example SimulatorFamily.TV.
|
|
342
388
|
device_type: Simulator device type identifier, for exact pinning.
|
|
343
389
|
runtime: Simulator runtime identifier, for exact pinning.
|
|
390
|
+
version: KVM desktop image version, for example "windows-11",
|
|
391
|
+
"windows-10", or "ubuntu-24.04".
|
|
344
392
|
"""
|
|
345
393
|
sandbox_type = _normalize_sandbox_type(type)
|
|
346
394
|
body: dict = {"type": sandbox_type.value}
|
|
347
395
|
if host:
|
|
348
396
|
body["host"] = host
|
|
397
|
+
if sandbox_type in (SandboxType.WINDOWS, SandboxType.UBUNTU) and version:
|
|
398
|
+
body["version"] = version
|
|
349
399
|
if sandbox_type == SandboxType.IOS:
|
|
350
400
|
if family and (not device_type or not runtime):
|
|
351
401
|
choice = select_simulator(await self.platforms(), family)
|
|
@@ -369,6 +419,15 @@ class AsyncComputer:
|
|
|
369
419
|
http=self._http,
|
|
370
420
|
vnc_url=f"{self._base_url}{data.get('vnc_url', '')}",
|
|
371
421
|
host=data.get("host", ""),
|
|
422
|
+
version=data.get("version", ""),
|
|
423
|
+
)
|
|
424
|
+
if sandbox_type == SandboxType.UBUNTU:
|
|
425
|
+
return AsyncUbuntuSandbox(
|
|
426
|
+
sandbox_id=sid,
|
|
427
|
+
http=self._http,
|
|
428
|
+
vnc_url=f"{self._base_url}{data.get('vnc_url', '')}",
|
|
429
|
+
host=data.get("host", ""),
|
|
430
|
+
version=data.get("version", ""),
|
|
372
431
|
)
|
|
373
432
|
return AsyncMacOSSandbox(
|
|
374
433
|
sandbox_id=sid,
|
|
@@ -393,6 +452,15 @@ class AsyncComputer:
|
|
|
393
452
|
http=self._http,
|
|
394
453
|
vnc_url=f"{self._base_url}{data.get('vnc_url', '')}",
|
|
395
454
|
host=data.get("host", ""),
|
|
455
|
+
version=data.get("version", ""),
|
|
456
|
+
)
|
|
457
|
+
if sb_type == SandboxType.UBUNTU:
|
|
458
|
+
return AsyncUbuntuSandbox(
|
|
459
|
+
sandbox_id=data["sandbox_id"],
|
|
460
|
+
http=self._http,
|
|
461
|
+
vnc_url=f"{self._base_url}{data.get('vnc_url', '')}",
|
|
462
|
+
host=data.get("host", ""),
|
|
463
|
+
version=data.get("version", ""),
|
|
396
464
|
)
|
|
397
465
|
return AsyncMacOSSandbox(
|
|
398
466
|
sandbox_id=data["sandbox_id"],
|
|
@@ -27,6 +27,7 @@ class SandboxType(str, Enum):
|
|
|
27
27
|
MACOS = "macos"
|
|
28
28
|
IOS = "ios"
|
|
29
29
|
WINDOWS = "windows"
|
|
30
|
+
UBUNTU = "ubuntu"
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
# ---------------------------------------------------------------------------
|
|
@@ -256,14 +257,17 @@ class IOSSandbox(Sandbox):
|
|
|
256
257
|
|
|
257
258
|
|
|
258
259
|
class _NoAxeAccessibility:
|
|
259
|
-
"""Mixin
|
|
260
|
+
"""Mixin for desktop guests without the macOS axe-schema tree."""
|
|
261
|
+
|
|
262
|
+
_accessibility_sandbox_type = "desktop"
|
|
263
|
+
_accessibility_hint = "accessibility tree is not supported for this sandbox"
|
|
260
264
|
|
|
261
265
|
@property
|
|
262
266
|
def accessibility(self):
|
|
263
267
|
raise PlatformNotSupportedError(
|
|
264
268
|
action="accessibility (macOS axe schema)",
|
|
265
|
-
sandbox_type=
|
|
266
|
-
hint=
|
|
269
|
+
sandbox_type=self._accessibility_sandbox_type,
|
|
270
|
+
hint=self._accessibility_hint,
|
|
267
271
|
)
|
|
268
272
|
|
|
269
273
|
@accessibility.setter
|
|
@@ -279,6 +283,9 @@ class WindowsSandbox(_NoAxeAccessibility, Sandbox):
|
|
|
279
283
|
macOS axe-schema `.accessibility` raises PlatformNotSupportedError here.
|
|
280
284
|
"""
|
|
281
285
|
|
|
286
|
+
_accessibility_sandbox_type = "windows"
|
|
287
|
+
_accessibility_hint = "use .ui_tree() for the native Windows UIAutomation tree"
|
|
288
|
+
|
|
282
289
|
def __init__(
|
|
283
290
|
self,
|
|
284
291
|
sandbox_id: str,
|
|
@@ -286,9 +293,11 @@ class WindowsSandbox(_NoAxeAccessibility, Sandbox):
|
|
|
286
293
|
*,
|
|
287
294
|
vnc_url: str = "",
|
|
288
295
|
host: str = "",
|
|
296
|
+
version: str = "",
|
|
289
297
|
):
|
|
290
298
|
super().__init__(sandbox_id, SandboxType.WINDOWS, http, vnc_url=vnc_url)
|
|
291
299
|
self.host = host
|
|
300
|
+
self.version = version
|
|
292
301
|
# Mouse/keyboard hit the same gateway command path as macOS.
|
|
293
302
|
self.mouse = Mouse(http, self._prefix)
|
|
294
303
|
self.keyboard = Keyboard(http, self._prefix)
|
|
@@ -324,6 +333,52 @@ class WindowsSandbox(_NoAxeAccessibility, Sandbox):
|
|
|
324
333
|
return resp.json()
|
|
325
334
|
|
|
326
335
|
|
|
336
|
+
class UbuntuSandbox(_NoAxeAccessibility, Sandbox):
|
|
337
|
+
"""Ubuntu desktop VM sandbox — mouse, keyboard, bash exec, VNC."""
|
|
338
|
+
|
|
339
|
+
_accessibility_sandbox_type = "ubuntu"
|
|
340
|
+
_accessibility_hint = "Ubuntu accessibility tree is not supported yet"
|
|
341
|
+
|
|
342
|
+
def __init__(
|
|
343
|
+
self,
|
|
344
|
+
sandbox_id: str,
|
|
345
|
+
http: httpx.Client,
|
|
346
|
+
*,
|
|
347
|
+
vnc_url: str = "",
|
|
348
|
+
host: str = "",
|
|
349
|
+
version: str = "",
|
|
350
|
+
):
|
|
351
|
+
super().__init__(sandbox_id, SandboxType.UBUNTU, http, vnc_url=vnc_url)
|
|
352
|
+
self.host = host
|
|
353
|
+
self.version = version
|
|
354
|
+
self.mouse = Mouse(http, self._prefix)
|
|
355
|
+
self.keyboard = Keyboard(http, self._prefix)
|
|
356
|
+
self.shell = Shell(http, self._prefix, default_shell="bash")
|
|
357
|
+
|
|
358
|
+
def act(
|
|
359
|
+
self,
|
|
360
|
+
action: dict,
|
|
361
|
+
screenshot_after: bool = True,
|
|
362
|
+
screenshot_delay_ms: int = 100,
|
|
363
|
+
) -> ActResult:
|
|
364
|
+
resp = self._http.post(
|
|
365
|
+
f"{self._prefix}/act",
|
|
366
|
+
json={
|
|
367
|
+
"action": action,
|
|
368
|
+
"screenshot_after": screenshot_after,
|
|
369
|
+
"screenshot_delay_ms": screenshot_delay_ms,
|
|
370
|
+
},
|
|
371
|
+
)
|
|
372
|
+
resp.raise_for_status()
|
|
373
|
+
if screenshot_after and resp.headers.get("content-type", "").startswith("image/"):
|
|
374
|
+
return ActResult(screenshot=resp.content)
|
|
375
|
+
return ActResult(data=resp.json())
|
|
376
|
+
|
|
377
|
+
def run(self, command: str, shell: ShellKind | None = None, timeout: int = 300) -> ExecResult:
|
|
378
|
+
"""Shorthand for self.shell.run()."""
|
|
379
|
+
return self.shell.run(command, shell, timeout)
|
|
380
|
+
|
|
381
|
+
|
|
327
382
|
# ---------------------------------------------------------------------------
|
|
328
383
|
# Async
|
|
329
384
|
# ---------------------------------------------------------------------------
|
|
@@ -497,6 +552,9 @@ class AsyncIOSSandbox(AsyncSandbox):
|
|
|
497
552
|
class AsyncWindowsSandbox(_NoAxeAccessibility, AsyncSandbox):
|
|
498
553
|
"""Async Windows VM sandbox — see WindowsSandbox."""
|
|
499
554
|
|
|
555
|
+
_accessibility_sandbox_type = "windows"
|
|
556
|
+
_accessibility_hint = "use .ui_tree() for the native Windows UIAutomation tree"
|
|
557
|
+
|
|
500
558
|
def __init__(
|
|
501
559
|
self,
|
|
502
560
|
sandbox_id: str,
|
|
@@ -504,9 +562,11 @@ class AsyncWindowsSandbox(_NoAxeAccessibility, AsyncSandbox):
|
|
|
504
562
|
*,
|
|
505
563
|
vnc_url: str = "",
|
|
506
564
|
host: str = "",
|
|
565
|
+
version: str = "",
|
|
507
566
|
):
|
|
508
567
|
super().__init__(sandbox_id, SandboxType.WINDOWS, http, vnc_url=vnc_url)
|
|
509
568
|
self.host = host
|
|
569
|
+
self.version = version
|
|
510
570
|
self.mouse = AsyncMouse(http, self._prefix)
|
|
511
571
|
self.keyboard = AsyncKeyboard(http, self._prefix)
|
|
512
572
|
self.shell = AsyncShell(http, self._prefix)
|
|
@@ -543,3 +603,51 @@ class AsyncWindowsSandbox(_NoAxeAccessibility, AsyncSandbox):
|
|
|
543
603
|
)
|
|
544
604
|
resp.raise_for_status()
|
|
545
605
|
return resp.json()
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
class AsyncUbuntuSandbox(_NoAxeAccessibility, AsyncSandbox):
|
|
609
|
+
"""Async Ubuntu desktop VM sandbox — see UbuntuSandbox."""
|
|
610
|
+
|
|
611
|
+
_accessibility_sandbox_type = "ubuntu"
|
|
612
|
+
_accessibility_hint = "Ubuntu accessibility tree is not supported yet"
|
|
613
|
+
|
|
614
|
+
def __init__(
|
|
615
|
+
self,
|
|
616
|
+
sandbox_id: str,
|
|
617
|
+
http: httpx.AsyncClient,
|
|
618
|
+
*,
|
|
619
|
+
vnc_url: str = "",
|
|
620
|
+
host: str = "",
|
|
621
|
+
version: str = "",
|
|
622
|
+
):
|
|
623
|
+
super().__init__(sandbox_id, SandboxType.UBUNTU, http, vnc_url=vnc_url)
|
|
624
|
+
self.host = host
|
|
625
|
+
self.version = version
|
|
626
|
+
self.mouse = AsyncMouse(http, self._prefix)
|
|
627
|
+
self.keyboard = AsyncKeyboard(http, self._prefix)
|
|
628
|
+
self.shell = AsyncShell(http, self._prefix, default_shell="bash")
|
|
629
|
+
|
|
630
|
+
async def act(
|
|
631
|
+
self,
|
|
632
|
+
action: dict,
|
|
633
|
+
screenshot_after: bool = True,
|
|
634
|
+
screenshot_delay_ms: int = 100,
|
|
635
|
+
) -> ActResult:
|
|
636
|
+
resp = await self._http.post(
|
|
637
|
+
f"{self._prefix}/act",
|
|
638
|
+
json={
|
|
639
|
+
"action": action,
|
|
640
|
+
"screenshot_after": screenshot_after,
|
|
641
|
+
"screenshot_delay_ms": screenshot_delay_ms,
|
|
642
|
+
},
|
|
643
|
+
)
|
|
644
|
+
resp.raise_for_status()
|
|
645
|
+
if screenshot_after and resp.headers.get("content-type", "").startswith("image/"):
|
|
646
|
+
return ActResult(screenshot=resp.content)
|
|
647
|
+
return ActResult(data=resp.json())
|
|
648
|
+
|
|
649
|
+
async def run(
|
|
650
|
+
self, command: str, shell: ShellKind | None = None, timeout: int = 300
|
|
651
|
+
) -> ExecResult:
|
|
652
|
+
"""Shorthand for self.shell.run()."""
|
|
653
|
+
return await self.shell.run(command, shell, timeout)
|
|
@@ -6,20 +6,21 @@ import httpx
|
|
|
6
6
|
|
|
7
7
|
from use_computer.models import ExecResult
|
|
8
8
|
|
|
9
|
-
ShellKind = Literal["powershell", "cmd"]
|
|
9
|
+
ShellKind = Literal["bash", "sh", "powershell", "cmd"]
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class Shell:
|
|
13
13
|
"""Run commands inside a Windows sandbox via the in-guest agent (no SSH)."""
|
|
14
14
|
|
|
15
|
-
def __init__(self, http: httpx.Client, prefix: str):
|
|
15
|
+
def __init__(self, http: httpx.Client, prefix: str, default_shell: ShellKind = "powershell"):
|
|
16
16
|
self._http = http
|
|
17
17
|
self._prefix = prefix
|
|
18
|
+
self._default_shell = default_shell
|
|
18
19
|
|
|
19
|
-
def run(self, command: str, shell: ShellKind =
|
|
20
|
+
def run(self, command: str, shell: ShellKind | None = None, timeout: int = 300) -> ExecResult:
|
|
20
21
|
resp = self._http.post(
|
|
21
22
|
f"{self._prefix}/exec",
|
|
22
|
-
json={"command": command, "shell": shell},
|
|
23
|
+
json={"command": command, "shell": shell or self._default_shell},
|
|
23
24
|
timeout=timeout,
|
|
24
25
|
)
|
|
25
26
|
resp.raise_for_status()
|
|
@@ -35,16 +36,19 @@ class Shell:
|
|
|
35
36
|
class AsyncShell:
|
|
36
37
|
"""Async variant of Shell."""
|
|
37
38
|
|
|
38
|
-
def __init__(
|
|
39
|
+
def __init__(
|
|
40
|
+
self, http: httpx.AsyncClient, prefix: str, default_shell: ShellKind = "powershell"
|
|
41
|
+
):
|
|
39
42
|
self._http = http
|
|
40
43
|
self._prefix = prefix
|
|
44
|
+
self._default_shell = default_shell
|
|
41
45
|
|
|
42
46
|
async def run(
|
|
43
|
-
self, command: str, shell: ShellKind =
|
|
47
|
+
self, command: str, shell: ShellKind | None = None, timeout: int = 300
|
|
44
48
|
) -> ExecResult:
|
|
45
49
|
resp = await self._http.post(
|
|
46
50
|
f"{self._prefix}/exec",
|
|
47
|
-
json={"command": command, "shell": shell},
|
|
51
|
+
json={"command": command, "shell": shell or self._default_shell},
|
|
48
52
|
timeout=timeout,
|
|
49
53
|
)
|
|
50
54
|
resp.raise_for_status()
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
from use_computer import Computer
|
|
2
|
-
|
|
3
|
-
with Computer().create() as mac:
|
|
4
|
-
mac.exec_ssh("open -a TextEdit")
|
|
5
|
-
mac.keyboard.type("hello from use.computer")
|
|
6
|
-
png = mac.screenshot.take_full_screen()
|
|
7
|
-
open("hello_macos.png", "wb").write(png)
|
|
8
|
-
print(f"saved hello_macos.png ({len(png)} bytes)")
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from use_computer import Computer, SandboxType, SimulatorFamily
|
|
2
|
-
|
|
3
|
-
# iPhone is the default when family= is omitted. Pass family= to target a
|
|
4
|
-
# different simulator family (iPad, Apple Watch, Apple TV, Apple Vision); the
|
|
5
|
-
# SDK picks a compatible installed device_type + runtime pair for you. See
|
|
6
|
-
# _6_hello_tvos.py for an Apple TV walkthrough.
|
|
7
|
-
with Computer().create(type=SandboxType.IOS, family=SimulatorFamily.IPHONE) as ios:
|
|
8
|
-
ios.apps.open_url("https://example.com")
|
|
9
|
-
png = ios.screenshot.take_full_screen()
|
|
10
|
-
open("hello_ios.png", "wb").write(png)
|
|
11
|
-
print(f"saved hello_ios.png ({len(png)} bytes)")
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
from use_computer import Computer
|
|
2
|
-
|
|
3
|
-
with Computer().create() as mac:
|
|
4
|
-
# Seed data files the task needs before handing the sandbox to an agent.
|
|
5
|
-
mac.upload_bytes(b"hello from use.computer\n", "/Users/lume/Desktop/hello.txt")
|
|
6
|
-
mac.download_file("/Users/lume/Desktop/hello.txt", "hello.txt")
|
|
7
|
-
print("saved hello.txt")
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from use_computer import Computer, RemoteButton, SandboxType, SimulatorFamily
|
|
2
|
-
|
|
3
|
-
# tvOS sims have no touch — drive them with the remote (D-pad + select / menu /
|
|
4
|
-
# home). `press_remote` accepts the enum or a string.
|
|
5
|
-
with Computer().create(type=SandboxType.IOS, family=SimulatorFamily.TV) as tv:
|
|
6
|
-
tv.input.press_remote(RemoteButton.DOWN)
|
|
7
|
-
tv.input.press_remote(RemoteButton.DOWN)
|
|
8
|
-
tv.input.press_remote(RemoteButton.SELECT)
|
|
9
|
-
png = tv.screenshot.take_full_screen()
|
|
10
|
-
open("hello_tvos.png", "wb").write(png)
|
|
11
|
-
print(f"saved hello_tvos.png ({len(png)} bytes)")
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from use_computer import Computer
|
|
2
|
-
|
|
3
|
-
# Beta: Windows sandboxes. No SSH — exec runs in-guest via PowerShell/cmd.
|
|
4
|
-
with Computer().create(type="windows") as win:
|
|
5
|
-
win.run("Start-Process notepad") # PowerShell by default
|
|
6
|
-
win.keyboard.type("hello from use.computer")
|
|
7
|
-
print(win.run("$env:COMPUTERNAME", shell="powershell").stdout)
|
|
8
|
-
|
|
9
|
-
png = win.screenshot.take_full_screen()
|
|
10
|
-
open("hello_windows.png", "wb").write(png)
|
|
11
|
-
print(f"saved hello_windows.png ({len(png)} bytes)")
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
// Windows (Beta). Run:
|
|
2
|
-
// export USE_COMPUTER_API_KEY=...
|
|
3
|
-
// go run hello_windows.go
|
|
4
|
-
package main
|
|
5
|
-
|
|
6
|
-
import (
|
|
7
|
-
"context"
|
|
8
|
-
"fmt"
|
|
9
|
-
"os"
|
|
10
|
-
|
|
11
|
-
uc "github.com/josancamon19/use-computer-sdk/go"
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
func main() {
|
|
15
|
-
ctx := context.Background()
|
|
16
|
-
c := uc.New()
|
|
17
|
-
|
|
18
|
-
win, err := c.Create(ctx, uc.CreateOptions{Type: uc.Windows, Version: "windows-11"})
|
|
19
|
-
if err != nil {
|
|
20
|
-
panic(err)
|
|
21
|
-
}
|
|
22
|
-
defer win.Close(ctx)
|
|
23
|
-
|
|
24
|
-
name, _ := win.RunShell(ctx, "$env:COMPUTERNAME", "powershell")
|
|
25
|
-
fmt.Println("computer name:", name.Stdout)
|
|
26
|
-
win.RunShell(ctx, "Start-Process notepad", "powershell")
|
|
27
|
-
win.TypeText(ctx, "hello from use.computer")
|
|
28
|
-
|
|
29
|
-
png, err := win.Screenshot(ctx)
|
|
30
|
-
if err != nil {
|
|
31
|
-
panic(err)
|
|
32
|
-
}
|
|
33
|
-
os.WriteFile("hello_windows.png", png, 0o644)
|
|
34
|
-
fmt.Printf("saved hello_windows.png (%d bytes)\n", len(png))
|
|
35
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
// Windows (Beta) — run: USE_COMPUTER_API_KEY=... npx tsx hello_windows.ts
|
|
2
|
-
import { Computer } from "use-computer";
|
|
3
|
-
|
|
4
|
-
const computer = new Computer();
|
|
5
|
-
await using win = await computer.create({ type: "windows", version: "windows-11" });
|
|
6
|
-
|
|
7
|
-
console.log("computer name:", (await win.run("$env:COMPUTERNAME")).stdout.trim());
|
|
8
|
-
await win.run("Start-Process notepad");
|
|
9
|
-
await win.keyboard.type("hello from use.computer");
|
|
10
|
-
|
|
11
|
-
const png = await win.screenshot.takeFullScreen();
|
|
12
|
-
const { writeFile } = await import("node:fs/promises");
|
|
13
|
-
await writeFile("hello_windows.png", png);
|
|
14
|
-
console.log(`saved hello_windows.png (${png.length} bytes)`);
|
use_computer-0.0.22/go/README.md
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# use-computer — Go SDK
|
|
2
|
-
|
|
3
|
-
Go client for [use.computer](https://use.computer) — rent dedicated VMs (macOS, iOS/visionOS/tvOS simulators, **Windows**, **Ubuntu**) built for computer-use agents. Parity with the [Python](../python) and [TypeScript](../javascript) SDKs.
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
go get github.com/josancamon19/use-computer-sdk/go@latest
|
|
7
|
-
export USE_COMPUTER_API_KEY=mk_live_...
|
|
8
|
-
```
|
|
9
|
-
|
|
10
|
-
```go
|
|
11
|
-
package main
|
|
12
|
-
|
|
13
|
-
import (
|
|
14
|
-
"context"
|
|
15
|
-
"fmt"
|
|
16
|
-
|
|
17
|
-
uc "github.com/josancamon19/use-computer-sdk/go"
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
func main() {
|
|
21
|
-
ctx := context.Background()
|
|
22
|
-
c := uc.New() // base URL + key from env, or uc.WithBaseURL/WithAPIKey
|
|
23
|
-
|
|
24
|
-
// Windows (Beta) — no SSH; runs in-guest via PowerShell/cmd
|
|
25
|
-
win, err := c.Create(ctx, uc.CreateOptions{Type: uc.Windows, Version: "windows-11"})
|
|
26
|
-
if err != nil {
|
|
27
|
-
panic(err)
|
|
28
|
-
}
|
|
29
|
-
defer win.Close(ctx)
|
|
30
|
-
|
|
31
|
-
r, _ := win.RunShell(ctx, "$env:COMPUTERNAME", "powershell")
|
|
32
|
-
fmt.Println(r.Stdout)
|
|
33
|
-
win.Click(ctx, 400, 300)
|
|
34
|
-
win.TypeText(ctx, "hello from use.computer")
|
|
35
|
-
png, _ := win.Screenshot(ctx)
|
|
36
|
-
fmt.Printf("screenshot %d bytes\n", len(png))
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Surface
|
|
41
|
-
|
|
42
|
-
- `New(opts...)` → `*Computer`; `WithBaseURL`, `WithAPIKey`, `WithHTTPClient`.
|
|
43
|
-
- `Create(ctx, CreateOptions{Type, Version, Host, Family, DeviceType, Runtime})` → `*Sandbox`.
|
|
44
|
-
- `Sandbox`: `Exec` (SSH on macOS / in-guest on Ubuntu / PowerShell on Windows), `RunShell(cmd, "powershell"|"cmd")`, `Screenshot`, `Click`, `Move`, `Scroll`, `TypeText`, `PressKey`, `Hotkey`, `UITree`, `Upload`, `Download`, `StartRecording`/`StopRecording`, `Keepalive`, `Close`.
|
|
45
|
-
|
|
46
|
-
Every call takes a `context.Context`. Docs: [docs.use.computer](https://docs.use.computer). Windows is **Beta** (admin-only).
|