anywhere-cli 0.1.0__tar.gz → 0.1.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.
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/PKG-INFO +2 -1
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/cli.py +83 -12
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/pyproject.toml +2 -1
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/tests/test_claude_sdk_adapter.py +0 -1
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/tests/test_connector_cli.py +74 -8
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/uv.lock +12 -1
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/.gitignore +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/README.md +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/__init__.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/adapter.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/attachments.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/capabilities.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/claude/__init__.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/claude/history_adapter.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/claude/normalized.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/claude/normalizers.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/claude/path_utils.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/claude/preferences.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/claude/sdk_adapter.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/claude/timeline_identity.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/claude/timeline_reducer.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/claude/trust.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/codex/__init__.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/codex/adapter.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/codex/history.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/codex/reducer.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/codex/rpc.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/launch.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/local/__init__.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/local/common.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/local/file_ops.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/local/ops.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/local/shell.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/local/terminal.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/local_ops.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/protocol.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/runtime.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/sync_state.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/connector/time.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/run.sh +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/tests/test_claude_history_adapter.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/tests/test_claude_preferences.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/tests/test_claude_timeline_parity.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/tests/test_claude_trust.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/tests/test_codex_adapter.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/tests/test_connector_capabilities.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/tests/test_connector_runtime.py +0 -0
- {anywhere_cli-0.1.0 → anywhere_cli-0.1.2}/tests/test_terminal_backend.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: anywhere-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Local runtime connector for Agents Anywhere
|
|
5
5
|
Requires-Python: >=3.12
|
|
6
6
|
Requires-Dist: claude-agent-sdk
|
|
@@ -10,6 +10,7 @@ Requires-Dist: pexpect>=4.9.0; sys_platform != 'win32'
|
|
|
10
10
|
Requires-Dist: ptyprocess>=0.7.0; sys_platform != 'win32'
|
|
11
11
|
Requires-Dist: pydantic>=2.0.0
|
|
12
12
|
Requires-Dist: pyte>=0.8.2
|
|
13
|
+
Requires-Dist: python-socks>=2.8.1
|
|
13
14
|
Requires-Dist: pywinpty>=2.0.13; sys_platform == 'win32'
|
|
14
15
|
Requires-Dist: websockets>=16.0
|
|
15
16
|
Description-Content-Type: text/markdown
|
|
@@ -6,6 +6,7 @@ import os
|
|
|
6
6
|
import sys
|
|
7
7
|
import time
|
|
8
8
|
from pathlib import Path
|
|
9
|
+
from urllib.parse import urlparse
|
|
9
10
|
|
|
10
11
|
import httpx
|
|
11
12
|
|
|
@@ -16,21 +17,41 @@ def main(argv: list[str] | None = None) -> None:
|
|
|
16
17
|
parser = _build_parser()
|
|
17
18
|
args = parser.parse_args(argv)
|
|
18
19
|
try:
|
|
19
|
-
if args.command
|
|
20
|
-
asyncio.run(
|
|
20
|
+
if args.command in {"pair", "login"}:
|
|
21
|
+
asyncio.run(_pair(args))
|
|
21
22
|
elif args.command == "configure":
|
|
22
23
|
_configure(args)
|
|
23
24
|
elif args.command == "start":
|
|
24
25
|
asyncio.run(_start(args))
|
|
25
26
|
else:
|
|
26
27
|
parser.print_help()
|
|
28
|
+
except CliError as exc:
|
|
29
|
+
print(f"error: {exc}", file=sys.stderr)
|
|
30
|
+
raise SystemExit(2) from None
|
|
31
|
+
except httpx.TimeoutException as exc:
|
|
32
|
+
print(f"error: request timed out: {exc.request.url if exc.request else exc}", file=sys.stderr)
|
|
33
|
+
raise SystemExit(2) from None
|
|
34
|
+
except httpx.HTTPStatusError as exc:
|
|
35
|
+
detail = _response_detail(exc.response)
|
|
36
|
+
print(f"error: server returned HTTP {exc.response.status_code}: {detail}", file=sys.stderr)
|
|
37
|
+
raise SystemExit(2) from None
|
|
38
|
+
except httpx.RequestError as exc:
|
|
39
|
+
print(f"error: cannot reach server: {exc}", file=sys.stderr)
|
|
40
|
+
raise SystemExit(2) from None
|
|
41
|
+
except (TimeoutError, RuntimeError, ValueError) as exc:
|
|
42
|
+
print(f"error: {exc}", file=sys.stderr)
|
|
43
|
+
raise SystemExit(2) from None
|
|
27
44
|
except KeyboardInterrupt:
|
|
28
45
|
raise SystemExit(130) from None
|
|
29
46
|
|
|
30
47
|
|
|
48
|
+
class CliError(RuntimeError):
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
|
|
31
52
|
def _build_parser() -> argparse.ArgumentParser:
|
|
32
53
|
parser = argparse.ArgumentParser(prog="anywhere-cli", description="Agent Server Codex connector CLI")
|
|
33
|
-
subparsers = parser.add_subparsers(dest="command")
|
|
54
|
+
subparsers = parser.add_subparsers(dest="command", metavar="{start,pair,configure}")
|
|
34
55
|
|
|
35
56
|
start = subparsers.add_parser("start", help="start the connector")
|
|
36
57
|
_add_config_args(start)
|
|
@@ -38,12 +59,12 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
38
59
|
start.add_argument("--connector-id", help="connector id")
|
|
39
60
|
start.add_argument("--connector-token", help="connector token")
|
|
40
61
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
62
|
+
pair = subparsers.add_parser(
|
|
63
|
+
"pair",
|
|
64
|
+
aliases=["login"],
|
|
65
|
+
help="pair with a backend, save credentials, and start the connector",
|
|
66
|
+
)
|
|
67
|
+
_add_pair_args(pair)
|
|
47
68
|
|
|
48
69
|
configure = subparsers.add_parser("configure", help="save connector credentials to local JSON")
|
|
49
70
|
_add_config_args(configure)
|
|
@@ -61,13 +82,22 @@ def _add_config_args(parser: argparse.ArgumentParser) -> None:
|
|
|
61
82
|
)
|
|
62
83
|
|
|
63
84
|
|
|
85
|
+
def _add_pair_args(parser: argparse.ArgumentParser) -> None:
|
|
86
|
+
_add_config_args(parser)
|
|
87
|
+
parser.add_argument("server", nargs="?", help="backend server URL, for example anywhere.com or https://api.anywhere.com")
|
|
88
|
+
parser.add_argument("--server-url", help="backend server URL (deprecated; use positional server)")
|
|
89
|
+
parser.add_argument("--poll-interval", type=float, default=2, help="seconds between pairing polls")
|
|
90
|
+
parser.add_argument("--timeout", type=float, default=600, help="pairing timeout in seconds")
|
|
91
|
+
parser.add_argument("--no-start", action="store_true", help="save credentials without starting the connector")
|
|
92
|
+
|
|
93
|
+
|
|
64
94
|
async def _start(args: argparse.Namespace) -> None:
|
|
65
95
|
config = _resolve_config(args)
|
|
66
96
|
await BackendRpcClient(config).run_forever()
|
|
67
97
|
|
|
68
98
|
|
|
69
|
-
async def
|
|
70
|
-
server_url = args.server_url
|
|
99
|
+
async def _pair(args: argparse.Namespace) -> None:
|
|
100
|
+
server_url = await _resolve_server_url_for_pair(args.server or args.server_url, timeout=10)
|
|
71
101
|
async with httpx.AsyncClient(timeout=30) as client:
|
|
72
102
|
start_response = await client.post(
|
|
73
103
|
f"{server_url}/pairing/start",
|
|
@@ -109,6 +139,35 @@ async def _login(args: argparse.Namespace) -> None:
|
|
|
109
139
|
raise TimeoutError("pairing timed out")
|
|
110
140
|
|
|
111
141
|
|
|
142
|
+
async def _resolve_server_url_for_pair(value: str | None, *, timeout: float = 10) -> str:
|
|
143
|
+
if not value:
|
|
144
|
+
raise CliError("missing server address. Usage: anywhere-cli pair <server>")
|
|
145
|
+
normalized = value.strip().rstrip("/")
|
|
146
|
+
if not normalized:
|
|
147
|
+
raise CliError("missing server address. Usage: anywhere-cli pair <server>")
|
|
148
|
+
|
|
149
|
+
parsed = urlparse(normalized)
|
|
150
|
+
if parsed.scheme:
|
|
151
|
+
if parsed.scheme in {"http", "https"}:
|
|
152
|
+
return normalized
|
|
153
|
+
if "://" in normalized:
|
|
154
|
+
raise CliError("server URL must use http or https")
|
|
155
|
+
|
|
156
|
+
candidates = [f"https://{normalized}", f"http://{normalized}"]
|
|
157
|
+
errors: list[str] = []
|
|
158
|
+
for candidate in candidates:
|
|
159
|
+
try:
|
|
160
|
+
async with httpx.AsyncClient(timeout=timeout) as client:
|
|
161
|
+
response = await client.get(f"{candidate}/health")
|
|
162
|
+
if response.status_code < 500:
|
|
163
|
+
return candidate
|
|
164
|
+
errors.append(f"{candidate}: HTTP {response.status_code}")
|
|
165
|
+
except httpx.RequestError as exc:
|
|
166
|
+
errors.append(f"{candidate}: {exc}")
|
|
167
|
+
joined = "; ".join(errors)
|
|
168
|
+
raise CliError(f"could not reach server over https or http ({joined})")
|
|
169
|
+
|
|
170
|
+
|
|
112
171
|
def _configure(args: argparse.Namespace) -> None:
|
|
113
172
|
config = ConnectorConfig(
|
|
114
173
|
server_url=args.server_url.rstrip("/"),
|
|
@@ -142,7 +201,19 @@ def _resolve_config(args: argparse.Namespace) -> ConnectorConfig:
|
|
|
142
201
|
if not connector_token:
|
|
143
202
|
missing.append("--connector-token")
|
|
144
203
|
missing.append(f"or config file {config_path}")
|
|
145
|
-
raise
|
|
204
|
+
raise CliError("missing connector credentials: " + ", ".join(missing))
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _response_detail(response: httpx.Response) -> str:
|
|
208
|
+
try:
|
|
209
|
+
payload = response.json()
|
|
210
|
+
except ValueError:
|
|
211
|
+
text = response.text.strip()
|
|
212
|
+
return text[:300] if text else response.reason_phrase
|
|
213
|
+
if isinstance(payload, dict):
|
|
214
|
+
detail = payload.get("detail") or payload.get("message") or payload
|
|
215
|
+
return str(detail)
|
|
216
|
+
return str(payload)
|
|
146
217
|
|
|
147
218
|
|
|
148
219
|
if __name__ == "__main__":
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "anywhere-cli"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.2"
|
|
4
4
|
description = "Local runtime connector for Agents Anywhere"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -12,6 +12,7 @@ dependencies = [
|
|
|
12
12
|
"ptyprocess>=0.7.0; sys_platform != 'win32'",
|
|
13
13
|
"pydantic>=2.0.0",
|
|
14
14
|
"pyte>=0.8.2",
|
|
15
|
+
"python-socks>=2.8.1",
|
|
15
16
|
"pywinpty>=2.0.13; sys_platform == 'win32'",
|
|
16
17
|
"websockets>=16.0",
|
|
17
18
|
]
|
|
@@ -414,7 +414,6 @@ async def test_claude_sdk_adapter_streams_timeline_and_updates_external_session(
|
|
|
414
414
|
"mediaType": "text/plain",
|
|
415
415
|
"size": 12,
|
|
416
416
|
"sha256": "abc",
|
|
417
|
-
"downloadUrl": "/sessions/sess_1/attachments/file_1",
|
|
418
417
|
}
|
|
419
418
|
]
|
|
420
419
|
assert timeline[2]["id"].startswith("claude_msg_")
|
|
@@ -46,6 +46,30 @@ class FakeHttpClient:
|
|
|
46
46
|
raise AssertionError(f"unexpected url: {url}")
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
class FakeProbeResponse:
|
|
50
|
+
def __init__(self, status_code: int) -> None:
|
|
51
|
+
self.status_code = status_code
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class FakeFallbackHttpClient:
|
|
55
|
+
calls: list[str] = []
|
|
56
|
+
|
|
57
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
async def __aenter__(self) -> FakeFallbackHttpClient:
|
|
61
|
+
return self
|
|
62
|
+
|
|
63
|
+
async def __aexit__(self, *args: Any) -> None:
|
|
64
|
+
return None
|
|
65
|
+
|
|
66
|
+
async def get(self, url: str) -> FakeProbeResponse:
|
|
67
|
+
self.calls.append(url)
|
|
68
|
+
if url.startswith("https://"):
|
|
69
|
+
raise cli_module.httpx.ConnectError("tls failed")
|
|
70
|
+
return FakeProbeResponse(200)
|
|
71
|
+
|
|
72
|
+
|
|
49
73
|
class FakeBackendRpcClient:
|
|
50
74
|
started_configs: list[ConnectorConfig] = []
|
|
51
75
|
|
|
@@ -56,7 +80,7 @@ class FakeBackendRpcClient:
|
|
|
56
80
|
self.started_configs.append(self.config)
|
|
57
81
|
|
|
58
82
|
|
|
59
|
-
def
|
|
83
|
+
def test_pair_starts_connector_after_saving_credentials(monkeypatch, tmp_path) -> None:
|
|
60
84
|
config_path = tmp_path / "connector.json"
|
|
61
85
|
FakeBackendRpcClient.started_configs = []
|
|
62
86
|
monkeypatch.setattr(cli_module.httpx, "AsyncClient", FakeHttpClient)
|
|
@@ -64,8 +88,7 @@ def test_login_starts_connector_after_saving_credentials(monkeypatch, tmp_path)
|
|
|
64
88
|
|
|
65
89
|
args = cli_module._build_parser().parse_args(
|
|
66
90
|
[
|
|
67
|
-
"
|
|
68
|
-
"--server-url",
|
|
91
|
+
"pair",
|
|
69
92
|
"http://127.0.0.1:8000",
|
|
70
93
|
"--config",
|
|
71
94
|
str(config_path),
|
|
@@ -73,14 +96,14 @@ def test_login_starts_connector_after_saving_credentials(monkeypatch, tmp_path)
|
|
|
73
96
|
"0",
|
|
74
97
|
]
|
|
75
98
|
)
|
|
76
|
-
asyncio.run(cli_module.
|
|
99
|
+
asyncio.run(cli_module._pair(args))
|
|
77
100
|
|
|
78
101
|
loaded = ConnectorConfig.load(config_path)
|
|
79
102
|
assert loaded.connector_id == "conn_1"
|
|
80
103
|
assert [config.connector_id for config in FakeBackendRpcClient.started_configs] == ["conn_1"]
|
|
81
104
|
|
|
82
105
|
|
|
83
|
-
def
|
|
106
|
+
def test_pair_no_start_only_saves_credentials(monkeypatch, tmp_path) -> None:
|
|
84
107
|
config_path = tmp_path / "connector.json"
|
|
85
108
|
FakeBackendRpcClient.started_configs = []
|
|
86
109
|
monkeypatch.setattr(cli_module.httpx, "AsyncClient", FakeHttpClient)
|
|
@@ -88,8 +111,7 @@ def test_login_no_start_only_saves_credentials(monkeypatch, tmp_path) -> None:
|
|
|
88
111
|
|
|
89
112
|
args = cli_module._build_parser().parse_args(
|
|
90
113
|
[
|
|
91
|
-
"
|
|
92
|
-
"--server-url",
|
|
114
|
+
"pair",
|
|
93
115
|
"http://127.0.0.1:8000",
|
|
94
116
|
"--config",
|
|
95
117
|
str(config_path),
|
|
@@ -98,7 +120,51 @@ def test_login_no_start_only_saves_credentials(monkeypatch, tmp_path) -> None:
|
|
|
98
120
|
"--no-start",
|
|
99
121
|
]
|
|
100
122
|
)
|
|
101
|
-
asyncio.run(cli_module.
|
|
123
|
+
asyncio.run(cli_module._pair(args))
|
|
102
124
|
|
|
103
125
|
assert ConnectorConfig.load(config_path).connector_token == "cxt_secret"
|
|
104
126
|
assert FakeBackendRpcClient.started_configs == []
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def test_pair_accepts_legacy_server_url_flag(monkeypatch, tmp_path) -> None:
|
|
130
|
+
config_path = tmp_path / "connector.json"
|
|
131
|
+
FakeBackendRpcClient.started_configs = []
|
|
132
|
+
monkeypatch.setattr(cli_module.httpx, "AsyncClient", FakeHttpClient)
|
|
133
|
+
monkeypatch.setattr(cli_module, "BackendRpcClient", FakeBackendRpcClient)
|
|
134
|
+
|
|
135
|
+
args = cli_module._build_parser().parse_args(
|
|
136
|
+
[
|
|
137
|
+
"pair",
|
|
138
|
+
"--server-url",
|
|
139
|
+
"http://127.0.0.1:8000",
|
|
140
|
+
"--config",
|
|
141
|
+
str(config_path),
|
|
142
|
+
"--poll-interval",
|
|
143
|
+
"0",
|
|
144
|
+
"--no-start",
|
|
145
|
+
]
|
|
146
|
+
)
|
|
147
|
+
asyncio.run(cli_module._pair(args))
|
|
148
|
+
|
|
149
|
+
assert ConnectorConfig.load(config_path).connector_id == "conn_1"
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def test_login_alias_is_still_accepted() -> None:
|
|
153
|
+
args = cli_module._build_parser().parse_args(["login", "http://127.0.0.1:8000", "--no-start"])
|
|
154
|
+
|
|
155
|
+
assert args.command == "login"
|
|
156
|
+
assert args.server == "http://127.0.0.1:8000"
|
|
157
|
+
assert args.no_start is True
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def test_pair_server_without_scheme_falls_back_to_http(monkeypatch) -> None:
|
|
161
|
+
FakeFallbackHttpClient.calls = []
|
|
162
|
+
monkeypatch.setattr(cli_module.httpx, "AsyncClient", FakeFallbackHttpClient)
|
|
163
|
+
|
|
164
|
+
resolved = asyncio.run(cli_module._resolve_server_url_for_pair("anywhere.test:6664", timeout=0.1))
|
|
165
|
+
|
|
166
|
+
assert resolved == "http://anywhere.test:6664"
|
|
167
|
+
assert FakeFallbackHttpClient.calls == [
|
|
168
|
+
"https://anywhere.test:6664/health",
|
|
169
|
+
"http://anywhere.test:6664/health",
|
|
170
|
+
]
|
|
@@ -26,7 +26,7 @@ wheels = [
|
|
|
26
26
|
|
|
27
27
|
[[package]]
|
|
28
28
|
name = "anywhere-cli"
|
|
29
|
-
version = "0.1.
|
|
29
|
+
version = "0.1.2"
|
|
30
30
|
source = { editable = "." }
|
|
31
31
|
dependencies = [
|
|
32
32
|
{ name = "claude-agent-sdk" },
|
|
@@ -36,6 +36,7 @@ dependencies = [
|
|
|
36
36
|
{ name = "ptyprocess", marker = "sys_platform != 'win32'" },
|
|
37
37
|
{ name = "pydantic" },
|
|
38
38
|
{ name = "pyte" },
|
|
39
|
+
{ name = "python-socks" },
|
|
39
40
|
{ name = "pywinpty", marker = "sys_platform == 'win32'" },
|
|
40
41
|
{ name = "websockets" },
|
|
41
42
|
]
|
|
@@ -55,6 +56,7 @@ requires-dist = [
|
|
|
55
56
|
{ name = "ptyprocess", marker = "sys_platform != 'win32'", specifier = ">=0.7.0" },
|
|
56
57
|
{ name = "pydantic", specifier = ">=2.0.0" },
|
|
57
58
|
{ name = "pyte", specifier = ">=0.8.2" },
|
|
59
|
+
{ name = "python-socks", specifier = ">=2.8.1" },
|
|
58
60
|
{ name = "pywinpty", marker = "sys_platform == 'win32'", specifier = ">=2.0.13" },
|
|
59
61
|
{ name = "websockets", specifier = ">=16.0" },
|
|
60
62
|
]
|
|
@@ -582,6 +584,15 @@ wheels = [
|
|
|
582
584
|
{ url = "https://files.pythonhosted.org/packages/e1/04/e8135ebd1ad02c56ec633277529b2602ff99ff634be76cdba5744cf554fd/python_multipart-0.0.32-py3-none-any.whl", hash = "sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23", size = 30042, upload-time = "2026-06-04T16:18:57.319Z" },
|
|
583
585
|
]
|
|
584
586
|
|
|
587
|
+
[[package]]
|
|
588
|
+
name = "python-socks"
|
|
589
|
+
version = "2.8.1"
|
|
590
|
+
source = { registry = "https://pypi.org/simple" }
|
|
591
|
+
sdist = { url = "https://files.pythonhosted.org/packages/36/0b/cd77011c1bc01b76404f7aba07fca18aca02a19c7626e329b40201217624/python_socks-2.8.1.tar.gz", hash = "sha256:698daa9616d46dddaffe65b87db222f2902177a2d2b2c0b9a9361df607ab3687", size = 38909, upload-time = "2026-02-16T05:24:00.745Z" }
|
|
592
|
+
wheels = [
|
|
593
|
+
{ url = "https://files.pythonhosted.org/packages/15/fe/9a58cb6eec633ff6afae150ca53c16f8cc8b65862ccb3d088051efdfceb7/python_socks-2.8.1-py3-none-any.whl", hash = "sha256:28232739c4988064e725cdbcd15be194743dd23f1c910f784163365b9d7be035", size = 55087, upload-time = "2026-02-16T05:23:59.147Z" },
|
|
594
|
+
]
|
|
595
|
+
|
|
585
596
|
[[package]]
|
|
586
597
|
name = "pywin32"
|
|
587
598
|
version = "312"
|
|
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
|