agent-relay 3.2.15 → 3.2.16

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.
Files changed (133) hide show
  1. package/bin/agent-relay-broker-darwin-arm64 +0 -0
  2. package/bin/agent-relay-broker-darwin-x64 +0 -0
  3. package/bin/agent-relay-broker-linux-arm64 +0 -0
  4. package/bin/agent-relay-broker-linux-x64 +0 -0
  5. package/dist/index.cjs +3853 -17163
  6. package/package.json +8 -8
  7. package/packages/acp-bridge/package.json +2 -2
  8. package/packages/config/package.json +1 -1
  9. package/packages/hooks/package.json +4 -4
  10. package/packages/memory/package.json +2 -2
  11. package/packages/openclaw/package.json +2 -2
  12. package/packages/policy/package.json +2 -2
  13. package/packages/sdk/dist/broker-path.d.ts +19 -0
  14. package/packages/sdk/dist/broker-path.d.ts.map +1 -0
  15. package/packages/sdk/dist/broker-path.js +71 -0
  16. package/packages/sdk/dist/broker-path.js.map +1 -0
  17. package/packages/sdk/dist/cli-registry.d.ts.map +1 -1
  18. package/packages/sdk/dist/cli-registry.js +4 -0
  19. package/packages/sdk/dist/cli-registry.js.map +1 -1
  20. package/packages/sdk/dist/client.d.ts +6 -1
  21. package/packages/sdk/dist/client.d.ts.map +1 -1
  22. package/packages/sdk/dist/client.js +18 -0
  23. package/packages/sdk/dist/client.js.map +1 -1
  24. package/packages/sdk/dist/communicate/adapters/index.d.ts +0 -5
  25. package/packages/sdk/dist/communicate/adapters/index.d.ts.map +1 -1
  26. package/packages/sdk/dist/communicate/adapters/index.js +0 -5
  27. package/packages/sdk/dist/communicate/adapters/index.js.map +1 -1
  28. package/packages/sdk/dist/communicate/adapters/pi.d.ts +0 -1
  29. package/packages/sdk/dist/communicate/adapters/pi.d.ts.map +1 -1
  30. package/packages/sdk/dist/communicate/adapters/pi.js +0 -4
  31. package/packages/sdk/dist/communicate/adapters/pi.js.map +1 -1
  32. package/packages/sdk/dist/communicate/core.d.ts.map +1 -1
  33. package/packages/sdk/dist/communicate/core.js +2 -3
  34. package/packages/sdk/dist/communicate/core.js.map +1 -1
  35. package/packages/sdk/dist/communicate/index.d.ts +17 -1
  36. package/packages/sdk/dist/communicate/index.d.ts.map +1 -1
  37. package/packages/sdk/dist/communicate/index.js +40 -1
  38. package/packages/sdk/dist/communicate/index.js.map +1 -1
  39. package/packages/sdk/dist/communicate/transport.d.ts +0 -1
  40. package/packages/sdk/dist/communicate/transport.d.ts.map +1 -1
  41. package/packages/sdk/dist/communicate/transport.js +42 -134
  42. package/packages/sdk/dist/communicate/transport.js.map +1 -1
  43. package/packages/sdk/dist/http.d.ts +38 -0
  44. package/packages/sdk/dist/http.d.ts.map +1 -0
  45. package/packages/sdk/dist/http.js +60 -0
  46. package/packages/sdk/dist/http.js.map +1 -0
  47. package/packages/sdk/dist/protocol.d.ts +25 -0
  48. package/packages/sdk/dist/protocol.d.ts.map +1 -1
  49. package/packages/sdk/dist/relay.d.ts +26 -3
  50. package/packages/sdk/dist/relay.d.ts.map +1 -1
  51. package/packages/sdk/dist/relay.js +62 -4
  52. package/packages/sdk/dist/relay.js.map +1 -1
  53. package/packages/sdk/dist/workflows/api-executor.d.ts +16 -0
  54. package/packages/sdk/dist/workflows/api-executor.d.ts.map +1 -0
  55. package/packages/sdk/dist/workflows/api-executor.js +94 -0
  56. package/packages/sdk/dist/workflows/api-executor.js.map +1 -0
  57. package/packages/sdk/dist/workflows/builder.d.ts +14 -0
  58. package/packages/sdk/dist/workflows/builder.d.ts.map +1 -1
  59. package/packages/sdk/dist/workflows/builder.js +26 -0
  60. package/packages/sdk/dist/workflows/builder.js.map +1 -1
  61. package/packages/sdk/dist/workflows/cloud-runner.d.ts +15 -0
  62. package/packages/sdk/dist/workflows/cloud-runner.d.ts.map +1 -0
  63. package/packages/sdk/dist/workflows/cloud-runner.js +41 -0
  64. package/packages/sdk/dist/workflows/cloud-runner.js.map +1 -0
  65. package/packages/sdk/dist/workflows/index.d.ts +2 -0
  66. package/packages/sdk/dist/workflows/index.d.ts.map +1 -1
  67. package/packages/sdk/dist/workflows/index.js +1 -0
  68. package/packages/sdk/dist/workflows/index.js.map +1 -1
  69. package/packages/sdk/dist/workflows/run.d.ts.map +1 -1
  70. package/packages/sdk/dist/workflows/run.js +4 -0
  71. package/packages/sdk/dist/workflows/run.js.map +1 -1
  72. package/packages/sdk/dist/workflows/runner.d.ts +14 -0
  73. package/packages/sdk/dist/workflows/runner.d.ts.map +1 -1
  74. package/packages/sdk/dist/workflows/runner.js +154 -10
  75. package/packages/sdk/dist/workflows/runner.js.map +1 -1
  76. package/packages/sdk/dist/workflows/types.d.ts +13 -3
  77. package/packages/sdk/dist/workflows/types.d.ts.map +1 -1
  78. package/packages/sdk/dist/workflows/types.js +5 -1
  79. package/packages/sdk/dist/workflows/types.js.map +1 -1
  80. package/packages/sdk/dist/workflows/validator.d.ts.map +1 -1
  81. package/packages/sdk/dist/workflows/validator.js +12 -0
  82. package/packages/sdk/dist/workflows/validator.js.map +1 -1
  83. package/packages/sdk/package.json +13 -3
  84. package/packages/sdk/src/__tests__/channel-management.test.ts +131 -0
  85. package/packages/sdk/src/__tests__/communicate/core.test.ts +36 -88
  86. package/packages/sdk/src/__tests__/communicate/transport.test.ts +41 -80
  87. package/packages/sdk/src/__tests__/orchestration-upgrades.test.ts +120 -0
  88. package/packages/sdk/src/__tests__/relay-channel-ops.test.ts +121 -0
  89. package/packages/sdk/src/broker-path.ts +74 -0
  90. package/packages/sdk/src/cli-registry.ts +4 -0
  91. package/packages/sdk/src/client.ts +28 -0
  92. package/packages/sdk/src/communicate/adapters/index.ts +0 -5
  93. package/packages/sdk/src/communicate/adapters/pi.ts +1 -5
  94. package/packages/sdk/src/communicate/core.ts +6 -10
  95. package/packages/sdk/src/communicate/index.ts +57 -1
  96. package/packages/sdk/src/communicate/transport.ts +46 -177
  97. package/packages/sdk/src/http.ts +96 -0
  98. package/packages/sdk/src/protocol.ts +24 -0
  99. package/packages/sdk/src/relay.ts +93 -8
  100. package/packages/sdk/src/workflows/README.md +5 -2
  101. package/packages/sdk/src/workflows/api-executor.ts +108 -0
  102. package/packages/sdk/src/workflows/builder.ts +40 -0
  103. package/packages/sdk/src/workflows/cloud-runner.ts +56 -0
  104. package/packages/sdk/src/workflows/index.ts +2 -0
  105. package/packages/sdk/src/workflows/run.ts +5 -0
  106. package/packages/sdk/src/workflows/runner.ts +181 -11
  107. package/packages/sdk/src/workflows/types.ts +19 -4
  108. package/packages/sdk/src/workflows/validator.ts +15 -0
  109. package/packages/sdk-py/README.md +7 -0
  110. package/packages/sdk-py/pyproject.toml +1 -1
  111. package/packages/sdk-py/src/agent_relay/__init__.py +2 -0
  112. package/packages/sdk-py/src/agent_relay/client.py +4 -0
  113. package/packages/sdk-py/src/agent_relay/communicate/adapters/__init__.py +0 -9
  114. package/packages/sdk-py/src/agent_relay/communicate/adapters/agno.py +5 -9
  115. package/packages/sdk-py/src/agent_relay/communicate/adapters/claude_sdk.py +5 -7
  116. package/packages/sdk-py/src/agent_relay/communicate/adapters/crewai.py +3 -13
  117. package/packages/sdk-py/src/agent_relay/communicate/adapters/google_adk.py +5 -2
  118. package/packages/sdk-py/src/agent_relay/communicate/adapters/openai_agents.py +5 -9
  119. package/packages/sdk-py/src/agent_relay/communicate/core.py +7 -24
  120. package/packages/sdk-py/src/agent_relay/communicate/transport.py +35 -212
  121. package/packages/sdk-py/src/agent_relay/communicate/types.py +1 -1
  122. package/packages/sdk-py/src/agent_relay/protocol.py +1 -0
  123. package/packages/sdk-py/src/agent_relay/relay.py +9 -1
  124. package/packages/sdk-py/tests/communicate/adapters/test_claude_sdk.py +6 -6
  125. package/packages/sdk-py/tests/communicate/conftest.py +86 -233
  126. package/packages/sdk-py/tests/communicate/integration/test_cross_framework.py +2 -2
  127. package/packages/sdk-py/tests/communicate/integration/test_end_to_end.py +14 -24
  128. package/packages/sdk-py/tests/communicate/test_transport.py +65 -54
  129. package/packages/sdk-py/tests/test_send_message_mode.py +91 -0
  130. package/packages/telemetry/package.json +1 -1
  131. package/packages/trajectory/package.json +2 -2
  132. package/packages/user-directory/package.json +2 -2
  133. package/packages/utils/package.json +2 -2
@@ -1,4 +1,4 @@
1
- """Tests for the RelayTransport HTTP/WS client against real Relaycast API surface."""
1
+ """Wave 1.2 tests for the RelayTransport HTTP/WS client."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
@@ -44,8 +44,10 @@ async def test_register_agent_and_unregister_agent_manage_identity(relay_server)
44
44
 
45
45
  assert transport.agent_id in relay_server.registered_agents
46
46
  assert transport.token == relay_server.registered_agents[transport.agent_id]["token"]
47
- register_payload = relay_server.requests["register_agent"][-1]["json"]
48
- assert register_payload["name"] == "TransportTester"
47
+ assert relay_server.requests["register_agent"][-1]["json"] == {
48
+ "name": "TransportTester",
49
+ "workspace": relay_server.workspace,
50
+ }
49
51
 
50
52
  agent_id = transport.agent_id
51
53
  await transport.unregister_agent()
@@ -75,55 +77,47 @@ async def test_connect_and_disconnect_manage_registration_and_websocket(relay_se
75
77
 
76
78
 
77
79
  @pytest.mark.asyncio
78
- async def test_send_dm_posts_to_correct_endpoint(relay_server):
79
- RelayTransport = _transport_class()
80
- transport = RelayTransport("TransportTester", relay_server.make_config())
81
- await transport.connect()
82
-
83
- try:
84
- message_id = await transport.send_dm("Review-Core", "hello")
85
- finally:
86
- await transport.disconnect()
87
-
88
- assert message_id.startswith("message-")
89
- dm_req = relay_server.requests["send_dm"][-1]
90
- assert dm_req["json"]["to"] == "Review-Core"
91
- assert dm_req["json"]["text"] == "hello"
92
- assert dm_req["path"] == "/v1/dm"
93
-
94
-
95
- @pytest.mark.asyncio
96
- async def test_post_message_posts_to_channel_endpoint(relay_server):
97
- RelayTransport = _transport_class()
98
- transport = RelayTransport("TransportTester", relay_server.make_config())
99
- await transport.connect()
100
-
101
- try:
102
- message_id = await transport.post_message("core-py", "status update")
103
- finally:
104
- await transport.disconnect()
105
-
106
- assert message_id.startswith("message-")
107
- ch_req = relay_server.requests["post_message"][-1]
108
- assert ch_req["json"]["text"] == "status update"
109
- assert "/v1/channels/core-py/messages" in ch_req["path"]
110
-
111
-
112
- @pytest.mark.asyncio
113
- async def test_reply_posts_to_replies_endpoint(relay_server):
80
+ @pytest.mark.parametrize(
81
+ ("method_name", "args", "operation", "expected_payload"),
82
+ [
83
+ (
84
+ "send_dm",
85
+ ("Review-Core", "hello"),
86
+ "send_dm",
87
+ {"to": "Review-Core", "text": "hello", "from": "TransportTester"},
88
+ ),
89
+ (
90
+ "post_message",
91
+ ("core-py", "status update"),
92
+ "post_message",
93
+ {"channel": "core-py", "text": "status update", "from": "TransportTester"},
94
+ ),
95
+ (
96
+ "reply",
97
+ ("message-123", "thread reply"),
98
+ "reply",
99
+ {"message_id": "message-123", "text": "thread reply", "from": "TransportTester"},
100
+ ),
101
+ ],
102
+ )
103
+ async def test_send_methods_use_expected_http_payload(
104
+ relay_server,
105
+ method_name,
106
+ args,
107
+ operation,
108
+ expected_payload,
109
+ ):
114
110
  RelayTransport = _transport_class()
115
111
  transport = RelayTransport("TransportTester", relay_server.make_config())
116
112
  await transport.connect()
117
113
 
118
114
  try:
119
- message_id = await transport.reply("message-123", "thread reply")
115
+ message_id = await getattr(transport, method_name)(*args)
120
116
  finally:
121
117
  await transport.disconnect()
122
118
 
123
119
  assert message_id.startswith("message-")
124
- reply_req = relay_server.requests["reply"][-1]
125
- assert reply_req["json"]["text"] == "thread reply"
126
- assert "/v1/messages/message-123/replies" in reply_req["path"]
120
+ assert relay_server.requests[operation][-1]["json"] == expected_payload
127
121
 
128
122
 
129
123
  @pytest.mark.asyncio
@@ -148,10 +142,16 @@ async def test_check_inbox_returns_message_objects_and_drains_server_inbox(relay
148
142
  finally:
149
143
  await transport.disconnect()
150
144
 
151
- assert len(messages) == 1
152
- assert messages[0].sender == "Impl-Core"
153
- assert messages[0].text == "transport ready"
154
- assert messages[0].message_id == "message-inbox-1"
145
+ assert messages == [
146
+ Message(
147
+ sender=queued["sender"],
148
+ text=queued["text"],
149
+ channel=queued["channel"],
150
+ thread_id=queued["thread_id"],
151
+ timestamp=queued["timestamp"],
152
+ message_id=queued["message_id"],
153
+ )
154
+ ]
155
155
  assert empty == []
156
156
 
157
157
 
@@ -197,11 +197,16 @@ async def test_websocket_messages_are_decoded_and_delivered_to_callback(relay_se
197
197
  finally:
198
198
  await transport.disconnect()
199
199
 
200
- assert len(received) == 1
201
- assert received[0].sender == "Review-Core"
202
- assert received[0].text == "looks good"
203
- assert received[0].channel == "core-py"
204
- assert received[0].message_id == "message-ws-1"
200
+ assert received == [
201
+ Message(
202
+ sender="Review-Core",
203
+ text="looks good",
204
+ channel="core-py",
205
+ thread_id=None,
206
+ timestamp=None,
207
+ message_id="message-ws-1",
208
+ )
209
+ ]
205
210
 
206
211
 
207
212
  @pytest.mark.asyncio
@@ -242,8 +247,14 @@ async def test_transport_reconnects_after_websocket_disconnect(relay_server, mon
242
247
  finally:
243
248
  await transport.disconnect()
244
249
 
245
- assert received[-1].sender == "Impl-Core"
246
- assert received[-1].text == "reconnected"
250
+ assert received[-1] == Message(
251
+ sender="Impl-Core",
252
+ text="reconnected",
253
+ channel=None,
254
+ thread_id=None,
255
+ timestamp=None,
256
+ message_id="message-reconnect-1",
257
+ )
247
258
  assert [delay for delay in sleep_calls if delay >= 1][:1] == [1]
248
259
 
249
260
 
@@ -0,0 +1,91 @@
1
+ from __future__ import annotations
2
+
3
+ from unittest.mock import AsyncMock
4
+
5
+ import pytest
6
+
7
+ from agent_relay.client import AgentRelayClient
8
+ from agent_relay.relay import AgentRelay, HumanHandle
9
+
10
+
11
+ @pytest.mark.asyncio
12
+ async def test_client_send_message_includes_mode_in_payload():
13
+ client = AgentRelayClient(binary_path="agent-relay-broker")
14
+ client.start_client = AsyncMock()
15
+
16
+ payloads: list[dict] = []
17
+
18
+ async def fake_request_ok(type_: str, payload: dict):
19
+ assert type_ == "send_message"
20
+ payloads.append(payload)
21
+ return {"event_id": "evt-1", "targets": ["Worker"]}
22
+
23
+ client._request_ok = fake_request_ok # type: ignore[method-assign]
24
+
25
+ result = await client.send_message(
26
+ to="Worker",
27
+ text="hello",
28
+ from_="system",
29
+ thread_id="thread-1",
30
+ priority=5,
31
+ data={"k": "v"},
32
+ mode="steer",
33
+ )
34
+
35
+ assert result["event_id"] == "evt-1"
36
+ assert payloads == [
37
+ {
38
+ "to": "Worker",
39
+ "text": "hello",
40
+ "from": "system",
41
+ "thread_id": "thread-1",
42
+ "priority": 5,
43
+ "data": {"k": "v"},
44
+ "mode": "steer",
45
+ }
46
+ ]
47
+
48
+
49
+ @pytest.mark.asyncio
50
+ async def test_human_send_message_passes_mode_and_sets_message_mode():
51
+ relay = AgentRelay()
52
+ client = AsyncMock()
53
+ client.send_message = AsyncMock(return_value={"event_id": "evt-2"})
54
+ relay._ensure_started = AsyncMock(return_value=client)
55
+
56
+ human = HumanHandle("system", relay)
57
+ msg = await human.send_message(to="Worker", text="status?", mode="wait")
58
+
59
+ assert msg.mode == "wait"
60
+ client.send_message.assert_awaited_once_with(
61
+ to="Worker",
62
+ text="status?",
63
+ from_="system",
64
+ thread_id=None,
65
+ priority=None,
66
+ data=None,
67
+ mode="wait",
68
+ )
69
+
70
+
71
+ @pytest.mark.asyncio
72
+ async def test_agent_send_message_passes_mode_and_sets_message_mode():
73
+ relay = AgentRelay()
74
+ client = AsyncMock()
75
+ client.spawn_pty = AsyncMock(return_value={"name": "Worker", "runtime": "pty"})
76
+ client.send_message = AsyncMock(return_value={"event_id": "evt-3"})
77
+ relay._ensure_started = AsyncMock(return_value=client)
78
+
79
+ agent = await relay.spawn("Worker", "claude")
80
+ msg = await agent.send_message(to="Reviewer", text="ready", mode="steer")
81
+
82
+ assert msg.mode == "steer"
83
+ client.send_message.assert_awaited_with(
84
+ to="Reviewer",
85
+ text="ready",
86
+ from_="Worker",
87
+ thread_id=None,
88
+ priority=None,
89
+ data=None,
90
+ mode="steer",
91
+ )
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/telemetry",
3
- "version": "3.2.15",
3
+ "version": "3.2.16",
4
4
  "description": "Anonymous telemetry for Agent Relay usage analytics",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/trajectory",
3
- "version": "3.2.15",
3
+ "version": "3.2.16",
4
4
  "description": "Trajectory integration utilities (trail/PDERO) for Relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,7 +22,7 @@
22
22
  "test:watch": "vitest"
23
23
  },
24
24
  "dependencies": {
25
- "@agent-relay/config": "3.2.15"
25
+ "@agent-relay/config": "3.2.16"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^22.19.3",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/user-directory",
3
- "version": "3.2.15",
3
+ "version": "3.2.16",
4
4
  "description": "User directory service for agent-relay (per-user credential storage)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,7 +22,7 @@
22
22
  "test:watch": "vitest"
23
23
  },
24
24
  "dependencies": {
25
- "@agent-relay/utils": "3.2.15"
25
+ "@agent-relay/utils": "3.2.16"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^22.19.3",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/utils",
3
- "version": "3.2.15",
3
+ "version": "3.2.16",
4
4
  "description": "Shared utilities for agent-relay: logging, name generation, command resolution, update checking",
5
5
  "type": "module",
6
6
  "main": "dist/cjs/index.js",
@@ -112,7 +112,7 @@
112
112
  "vitest": "^3.2.4"
113
113
  },
114
114
  "dependencies": {
115
- "@agent-relay/config": "3.2.15",
115
+ "@agent-relay/config": "3.2.16",
116
116
  "compare-versions": "^6.1.1"
117
117
  },
118
118
  "publishConfig": {