agent-relay 3.2.21 → 4.0.0
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/bin/agent-relay-broker-darwin-arm64 +0 -0
- package/bin/agent-relay-broker-darwin-x64 +0 -0
- package/bin/agent-relay-broker-linux-arm64 +0 -0
- package/bin/agent-relay-broker-linux-x64 +0 -0
- package/dist/index.cjs +5065 -1422
- package/dist/src/cli/bootstrap.d.ts.map +1 -1
- package/dist/src/cli/bootstrap.js +2 -0
- package/dist/src/cli/bootstrap.js.map +1 -1
- package/dist/src/cli/commands/agent-management.d.ts.map +1 -1
- package/dist/src/cli/commands/agent-management.js +14 -4
- package/dist/src/cli/commands/agent-management.js.map +1 -1
- package/dist/src/cli/commands/core.d.ts +2 -6
- package/dist/src/cli/commands/core.d.ts.map +1 -1
- package/dist/src/cli/commands/core.js +30 -12
- package/dist/src/cli/commands/core.js.map +1 -1
- package/dist/src/cli/commands/messaging.d.ts.map +1 -1
- package/dist/src/cli/commands/messaging.js +10 -3
- package/dist/src/cli/commands/messaging.js.map +1 -1
- package/dist/src/cli/commands/monitoring.d.ts +2 -2
- package/dist/src/cli/commands/monitoring.d.ts.map +1 -1
- package/dist/src/cli/commands/monitoring.js +15 -6
- package/dist/src/cli/commands/monitoring.js.map +1 -1
- package/dist/src/cli/commands/on/dotfiles.d.ts +35 -0
- package/dist/src/cli/commands/on/dotfiles.d.ts.map +1 -0
- package/dist/src/cli/commands/on/dotfiles.js +157 -0
- package/dist/src/cli/commands/on/dotfiles.js.map +1 -0
- package/dist/src/cli/commands/on/prereqs.d.ts +15 -0
- package/dist/src/cli/commands/on/prereqs.d.ts.map +1 -0
- package/dist/src/cli/commands/on/prereqs.js +103 -0
- package/dist/src/cli/commands/on/prereqs.js.map +1 -0
- package/dist/src/cli/commands/on/provision.d.ts +22 -0
- package/dist/src/cli/commands/on/provision.d.ts.map +1 -0
- package/dist/src/cli/commands/on/provision.js +157 -0
- package/dist/src/cli/commands/on/provision.js.map +1 -0
- package/dist/src/cli/commands/on/scan.d.ts +8 -0
- package/dist/src/cli/commands/on/scan.d.ts.map +1 -0
- package/dist/src/cli/commands/on/scan.js +59 -0
- package/dist/src/cli/commands/on/scan.js.map +1 -0
- package/dist/src/cli/commands/on/services.d.ts +17 -0
- package/dist/src/cli/commands/on/services.d.ts.map +1 -0
- package/dist/src/cli/commands/on/services.js +328 -0
- package/dist/src/cli/commands/on/services.js.map +1 -0
- package/dist/src/cli/commands/on/start.d.ts +61 -0
- package/dist/src/cli/commands/on/start.d.ts.map +1 -0
- package/dist/src/cli/commands/on/start.js +1071 -0
- package/dist/src/cli/commands/on/start.js.map +1 -0
- package/dist/src/cli/commands/on/stop.d.ts +4 -0
- package/dist/src/cli/commands/on/stop.d.ts.map +1 -0
- package/dist/src/cli/commands/on/stop.js +11 -0
- package/dist/src/cli/commands/on/stop.js.map +1 -0
- package/dist/src/cli/commands/on/token.d.ts +8 -0
- package/dist/src/cli/commands/on/token.d.ts.map +1 -0
- package/dist/src/cli/commands/on/token.js +26 -0
- package/dist/src/cli/commands/on/token.js.map +1 -0
- package/dist/src/cli/commands/on/workspace.d.ts +4 -0
- package/dist/src/cli/commands/on/workspace.d.ts.map +1 -0
- package/dist/src/cli/commands/on/workspace.js +241 -0
- package/dist/src/cli/commands/on/workspace.js.map +1 -0
- package/dist/src/cli/commands/on.d.ts +10 -0
- package/dist/src/cli/commands/on.d.ts.map +1 -0
- package/dist/src/cli/commands/on.js +52 -0
- package/dist/src/cli/commands/on.js.map +1 -0
- package/dist/src/cli/commands/setup.d.ts.map +1 -1
- package/dist/src/cli/commands/setup.js +10 -21
- package/dist/src/cli/commands/setup.js.map +1 -1
- package/dist/src/cli/lib/bridge.js +1 -1
- package/dist/src/cli/lib/bridge.js.map +1 -1
- package/dist/src/cli/lib/broker-lifecycle.d.ts +14 -4
- package/dist/src/cli/lib/broker-lifecycle.d.ts.map +1 -1
- package/dist/src/cli/lib/broker-lifecycle.js +82 -120
- package/dist/src/cli/lib/broker-lifecycle.js.map +1 -1
- package/dist/src/cli/lib/client-factory.d.ts +2 -2
- package/dist/src/cli/lib/client-factory.d.ts.map +1 -1
- package/dist/src/cli/lib/client-factory.js +14 -11
- package/dist/src/cli/lib/client-factory.js.map +1 -1
- package/dist/src/cli/lib/core-maintenance.d.ts.map +1 -1
- package/dist/src/cli/lib/core-maintenance.js +11 -22
- package/dist/src/cli/lib/core-maintenance.js.map +1 -1
- package/package.json +14 -11
- package/packages/acp-bridge/package.json +2 -2
- package/packages/brand/package.json +1 -1
- package/packages/cloud/package.json +2 -2
- package/packages/config/package.json +1 -1
- package/packages/hooks/package.json +4 -4
- package/packages/memory/package.json +2 -2
- package/packages/openclaw/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/sdk/README.md +10 -3
- package/packages/sdk/dist/client.d.ts +108 -196
- package/packages/sdk/dist/client.d.ts.map +1 -1
- package/packages/sdk/dist/client.js +336 -824
- package/packages/sdk/dist/client.js.map +1 -1
- package/packages/sdk/dist/examples/example.js +2 -5
- package/packages/sdk/dist/examples/example.js.map +1 -1
- package/packages/sdk/dist/index.d.ts +3 -1
- package/packages/sdk/dist/index.d.ts.map +1 -1
- package/packages/sdk/dist/index.js +3 -1
- package/packages/sdk/dist/index.js.map +1 -1
- package/packages/sdk/dist/relay-adapter.d.ts +9 -26
- package/packages/sdk/dist/relay-adapter.d.ts.map +1 -1
- package/packages/sdk/dist/relay-adapter.js +75 -47
- package/packages/sdk/dist/relay-adapter.js.map +1 -1
- package/packages/sdk/dist/relay.d.ts +24 -5
- package/packages/sdk/dist/relay.d.ts.map +1 -1
- package/packages/sdk/dist/relay.js +213 -43
- package/packages/sdk/dist/relay.js.map +1 -1
- package/packages/sdk/dist/transport.d.ts +58 -0
- package/packages/sdk/dist/transport.d.ts.map +1 -0
- package/packages/sdk/dist/transport.js +184 -0
- package/packages/sdk/dist/transport.js.map +1 -0
- package/packages/sdk/dist/types.d.ts +69 -0
- package/packages/sdk/dist/types.d.ts.map +1 -0
- package/packages/sdk/dist/types.js +5 -0
- package/packages/sdk/dist/types.js.map +1 -0
- package/packages/sdk/dist/workflows/cli.js +46 -2
- package/packages/sdk/dist/workflows/cli.js.map +1 -1
- package/packages/sdk/dist/workflows/file-db.d.ts +2 -0
- package/packages/sdk/dist/workflows/file-db.d.ts.map +1 -1
- package/packages/sdk/dist/workflows/file-db.js +20 -3
- package/packages/sdk/dist/workflows/file-db.js.map +1 -1
- package/packages/sdk/dist/workflows/runner.d.ts +6 -1
- package/packages/sdk/dist/workflows/runner.d.ts.map +1 -1
- package/packages/sdk/dist/workflows/runner.js +157 -11
- package/packages/sdk/dist/workflows/runner.js.map +1 -1
- package/packages/sdk/dist/workflows/validator.d.ts.map +1 -1
- package/packages/sdk/dist/workflows/validator.js +17 -2
- package/packages/sdk/dist/workflows/validator.js.map +1 -1
- package/packages/sdk/package.json +2 -2
- package/packages/sdk/src/__tests__/resume-fallback.test.ts +415 -0
- package/packages/sdk/src/__tests__/unit.test.ts +100 -1
- package/packages/sdk/src/client.ts +422 -1072
- package/packages/sdk/src/examples/example.ts +2 -5
- package/packages/sdk/src/index.ts +8 -1
- package/packages/sdk/src/relay-adapter.ts +75 -55
- package/packages/sdk/src/relay.ts +260 -57
- package/packages/sdk/src/transport.ts +216 -0
- package/packages/sdk/src/types.ts +75 -0
- package/packages/sdk/src/workflows/cli.ts +53 -2
- package/packages/sdk/src/workflows/file-db.ts +22 -3
- package/packages/sdk/src/workflows/runner.ts +178 -11
- package/packages/sdk/src/workflows/validator.ts +20 -2
- package/packages/sdk-py/pyproject.toml +1 -1
- package/packages/sdk-py/src/agent_relay/__init__.py +0 -8
- package/packages/sdk-py/src/agent_relay/client.py +329 -522
- package/packages/sdk-py/src/agent_relay/protocol.py +2 -96
- package/packages/sdk-py/src/agent_relay/relay.py +1 -4
- package/packages/sdk-py/tests/test_wait_for_api_url.py +92 -0
- package/packages/sdk-py/uv.lock +5388 -0
- package/packages/telemetry/dist/client.d.ts.map +1 -1
- package/packages/telemetry/dist/client.js +1 -1
- package/packages/telemetry/dist/client.js.map +1 -1
- package/packages/telemetry/package.json +1 -1
- package/packages/telemetry/src/client.ts +3 -10
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/package.json +2 -2
- package/scripts/postinstall.js +121 -1
|
@@ -1,110 +1,16 @@
|
|
|
1
|
-
"""Wire protocol types for the Agent Relay broker
|
|
1
|
+
"""Wire protocol types for the Agent Relay broker.
|
|
2
2
|
|
|
3
3
|
Matches the TypeScript definitions in packages/sdk/src/protocol.ts.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from typing import Any, Literal, Optional
|
|
10
|
-
|
|
11
|
-
PROTOCOL_VERSION = 1
|
|
8
|
+
from typing import Any, Literal
|
|
12
9
|
|
|
13
10
|
AgentRuntime = Literal["pty", "headless"]
|
|
14
11
|
HeadlessProvider = Literal["claude", "opencode"]
|
|
15
12
|
MessageInjectionMode = Literal["wait", "steer"]
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
@dataclass
|
|
19
|
-
class RestartPolicy:
|
|
20
|
-
enabled: bool = False
|
|
21
|
-
max_restarts: int = 3
|
|
22
|
-
cooldown_ms: int = 1000
|
|
23
|
-
max_consecutive_failures: int = 3
|
|
24
|
-
|
|
25
|
-
def to_dict(self) -> dict[str, Any]:
|
|
26
|
-
return {
|
|
27
|
-
"enabled": self.enabled,
|
|
28
|
-
"max_restarts": self.max_restarts,
|
|
29
|
-
"cooldown_ms": self.cooldown_ms,
|
|
30
|
-
"max_consecutive_failures": self.max_consecutive_failures,
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
@dataclass
|
|
35
|
-
class AgentSpec:
|
|
36
|
-
"""Specification for spawning an agent."""
|
|
37
|
-
|
|
38
|
-
name: str
|
|
39
|
-
runtime: AgentRuntime = "pty"
|
|
40
|
-
provider: Optional[HeadlessProvider] = None
|
|
41
|
-
cli: Optional[str] = None
|
|
42
|
-
args: list[str] = field(default_factory=list)
|
|
43
|
-
channels: list[str] = field(default_factory=list)
|
|
44
|
-
model: Optional[str] = None
|
|
45
|
-
cwd: Optional[str] = None
|
|
46
|
-
team: Optional[str] = None
|
|
47
|
-
shadow_of: Optional[str] = None
|
|
48
|
-
shadow_mode: Optional[str] = None
|
|
49
|
-
restart_policy: Optional[RestartPolicy] = None
|
|
50
|
-
|
|
51
|
-
def to_dict(self) -> dict[str, Any]:
|
|
52
|
-
d: dict[str, Any] = {
|
|
53
|
-
"name": self.name,
|
|
54
|
-
"runtime": self.runtime,
|
|
55
|
-
}
|
|
56
|
-
if self.provider is not None:
|
|
57
|
-
d["provider"] = self.provider
|
|
58
|
-
if self.cli is not None:
|
|
59
|
-
d["cli"] = self.cli
|
|
60
|
-
if self.args:
|
|
61
|
-
d["args"] = self.args
|
|
62
|
-
if self.channels:
|
|
63
|
-
d["channels"] = self.channels
|
|
64
|
-
if self.model is not None:
|
|
65
|
-
d["model"] = self.model
|
|
66
|
-
if self.cwd is not None:
|
|
67
|
-
d["cwd"] = self.cwd
|
|
68
|
-
if self.team is not None:
|
|
69
|
-
d["team"] = self.team
|
|
70
|
-
if self.shadow_of is not None:
|
|
71
|
-
d["shadow_of"] = self.shadow_of
|
|
72
|
-
if self.shadow_mode is not None:
|
|
73
|
-
d["shadow_mode"] = self.shadow_mode
|
|
74
|
-
if self.restart_policy is not None:
|
|
75
|
-
d["restart_policy"] = self.restart_policy.to_dict()
|
|
76
|
-
return d
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
@dataclass
|
|
80
|
-
class ProtocolEnvelope:
|
|
81
|
-
"""JSON envelope for all broker communication."""
|
|
82
|
-
|
|
83
|
-
v: int
|
|
84
|
-
type: str
|
|
85
|
-
payload: dict[str, Any]
|
|
86
|
-
request_id: Optional[str] = None
|
|
87
|
-
|
|
88
|
-
def to_dict(self) -> dict[str, Any]:
|
|
89
|
-
d: dict[str, Any] = {
|
|
90
|
-
"v": self.v,
|
|
91
|
-
"type": self.type,
|
|
92
|
-
"payload": self.payload,
|
|
93
|
-
}
|
|
94
|
-
if self.request_id is not None:
|
|
95
|
-
d["request_id"] = self.request_id
|
|
96
|
-
return d
|
|
97
|
-
|
|
98
|
-
@classmethod
|
|
99
|
-
def from_dict(cls, data: dict[str, Any]) -> ProtocolEnvelope:
|
|
100
|
-
return cls(
|
|
101
|
-
v=data.get("v", 0),
|
|
102
|
-
type=data.get("type", ""),
|
|
103
|
-
payload=data.get("payload", {}),
|
|
104
|
-
request_id=data.get("request_id"),
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
|
|
108
14
|
# BrokerEvent is a dict with a 'kind' field discriminator.
|
|
109
15
|
# Event kinds: agent_spawned, agent_released, agent_exit, agent_exited,
|
|
110
16
|
# relay_inbound, worker_stream, worker_ready, worker_error,
|
|
@@ -424,8 +424,6 @@ class AgentRelay:
|
|
|
424
424
|
"channels": self._default_channels,
|
|
425
425
|
"cwd": cwd,
|
|
426
426
|
"env": env,
|
|
427
|
-
"request_timeout_ms": request_timeout_ms,
|
|
428
|
-
"shutdown_timeout_ms": shutdown_timeout_ms,
|
|
429
427
|
}
|
|
430
428
|
|
|
431
429
|
self._client: Optional[AgentRelayClient] = None
|
|
@@ -477,8 +475,7 @@ class AgentRelay:
|
|
|
477
475
|
|
|
478
476
|
# Remove None values to use defaults
|
|
479
477
|
kwargs = {k: v for k, v in self._client_kwargs.items() if v is not None}
|
|
480
|
-
client = AgentRelayClient(**kwargs)
|
|
481
|
-
await client.start_client()
|
|
478
|
+
client = await AgentRelayClient.spawn(**kwargs)
|
|
482
479
|
|
|
483
480
|
self._client = client
|
|
484
481
|
if client.workspace_key:
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""Tests for _wait_for_api_url."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from unittest.mock import AsyncMock, PropertyMock
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
from agent_relay.client import AgentRelayProcessError, _wait_for_api_url
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _make_process(lines: list[str], returncode: int | None = 0):
|
|
12
|
+
"""Create a mock asyncio.subprocess.Process with canned stdout lines."""
|
|
13
|
+
remaining = list(lines)
|
|
14
|
+
|
|
15
|
+
async def readline() -> bytes:
|
|
16
|
+
if remaining:
|
|
17
|
+
return (remaining.pop(0) + "\n").encode("utf-8")
|
|
18
|
+
return b""
|
|
19
|
+
|
|
20
|
+
process = AsyncMock()
|
|
21
|
+
process.stdout = AsyncMock()
|
|
22
|
+
process.stdout.readline = readline
|
|
23
|
+
type(process).returncode = PropertyMock(return_value=returncode)
|
|
24
|
+
return process
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class TestWaitForApiUrl:
|
|
28
|
+
async def test_parses_default_loopback(self):
|
|
29
|
+
process = _make_process([
|
|
30
|
+
"[agent-relay] API listening on http://127.0.0.1:3889",
|
|
31
|
+
])
|
|
32
|
+
url = await _wait_for_api_url(process, 5000)
|
|
33
|
+
assert url == "http://127.0.0.1:3889"
|
|
34
|
+
|
|
35
|
+
async def test_parses_wildcard_bind(self):
|
|
36
|
+
process = _make_process([
|
|
37
|
+
"[agent-relay] API listening on http://0.0.0.0:4000",
|
|
38
|
+
])
|
|
39
|
+
url = await _wait_for_api_url(process, 5000)
|
|
40
|
+
assert url == "http://0.0.0.0:4000"
|
|
41
|
+
|
|
42
|
+
async def test_parses_custom_ip(self):
|
|
43
|
+
process = _make_process([
|
|
44
|
+
"[agent-relay] API listening on http://10.0.1.5:8080",
|
|
45
|
+
])
|
|
46
|
+
url = await _wait_for_api_url(process, 5000)
|
|
47
|
+
assert url == "http://10.0.1.5:8080"
|
|
48
|
+
|
|
49
|
+
async def test_parses_https(self):
|
|
50
|
+
process = _make_process([
|
|
51
|
+
"[agent-relay] API listening on https://broker.example.com:443",
|
|
52
|
+
])
|
|
53
|
+
url = await _wait_for_api_url(process, 5000)
|
|
54
|
+
assert url == "https://broker.example.com:443"
|
|
55
|
+
|
|
56
|
+
async def test_skips_non_matching_lines(self):
|
|
57
|
+
process = _make_process([
|
|
58
|
+
"[agent-relay] Starting broker...",
|
|
59
|
+
"[agent-relay] Loading config",
|
|
60
|
+
"[agent-relay] API listening on http://127.0.0.1:5555",
|
|
61
|
+
])
|
|
62
|
+
url = await _wait_for_api_url(process, 5000)
|
|
63
|
+
assert url == "http://127.0.0.1:5555"
|
|
64
|
+
|
|
65
|
+
async def test_raises_on_process_exit_before_ready(self):
|
|
66
|
+
process = _make_process(
|
|
67
|
+
["[agent-relay] Starting broker..."],
|
|
68
|
+
returncode=1,
|
|
69
|
+
)
|
|
70
|
+
with pytest.raises(AgentRelayProcessError, match="exited with code 1"):
|
|
71
|
+
await _wait_for_api_url(process, 5000)
|
|
72
|
+
|
|
73
|
+
async def test_raises_on_timeout(self):
|
|
74
|
+
async def slow_readline() -> bytes:
|
|
75
|
+
await asyncio.sleep(10)
|
|
76
|
+
return b""
|
|
77
|
+
|
|
78
|
+
process = AsyncMock()
|
|
79
|
+
process.stdout = AsyncMock()
|
|
80
|
+
process.stdout.readline = slow_readline
|
|
81
|
+
type(process).returncode = PropertyMock(return_value=None)
|
|
82
|
+
|
|
83
|
+
with pytest.raises(AgentRelayProcessError, match="did not report API URL"):
|
|
84
|
+
await _wait_for_api_url(process, 50)
|
|
85
|
+
|
|
86
|
+
async def test_ignores_lines_with_colon_but_no_url(self):
|
|
87
|
+
process = _make_process([
|
|
88
|
+
"[agent-relay] config: loaded from /etc/relay.conf",
|
|
89
|
+
"[agent-relay] API listening on http://127.0.0.1:9999",
|
|
90
|
+
])
|
|
91
|
+
url = await _wait_for_api_url(process, 5000)
|
|
92
|
+
assert url == "http://127.0.0.1:9999"
|