clawmatrix 0.1.14 → 0.1.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.
@@ -37,6 +37,18 @@ export function createClusterHandoffTool(): AnyAgentTool {
37
37
  const runtime = getClusterRuntime();
38
38
  const result = await runtime.handoffManager.handoff(target, task, context);
39
39
 
40
+ if (result.inputRequired) {
41
+ return {
42
+ content: [
43
+ {
44
+ type: "text" as const,
45
+ text: `Remote agent needs more information before continuing.\n\nHandoff ID: ${result.handoffId}\nQuestion: ${result.result}\n\nUse cluster_handoff_reply tool to respond.`,
46
+ },
47
+ ],
48
+ details: result,
49
+ };
50
+ }
51
+
40
52
  if (!result.success) {
41
53
  return {
42
54
  content: [
@@ -6,7 +6,7 @@ export function createClusterPeersTool(): AnyAgentTool {
6
6
  name: "cluster_peers",
7
7
  label: "Cluster Peers",
8
8
  description:
9
- "List all reachable peers in the cluster, their agents, available models, and connection status.",
9
+ "List all reachable peers in the cluster, their agents, models, tools, and connection status.",
10
10
  parameters: {
11
11
  type: "object",
12
12
  properties: {},
@@ -26,10 +26,26 @@ export function createClusterPeersTool(): AnyAgentTool {
26
26
  provider: m.provider,
27
27
  })),
28
28
  tags: entry.tags,
29
+ tools: entry.toolProxy?.enabled ? (entry.toolProxy.allow ?? []) : [],
29
30
  status: entry.connection?.isOpen ? "connected" : "unreachable",
30
31
  latencyMs: entry.latencyMs,
31
32
  }));
32
33
 
34
+ // Include satellite nodes
35
+ const satellites = runtime.webHandler?.getSatelliteContexts() ?? runtime.peerManager.satelliteContexts;
36
+ for (const sat of satellites) {
37
+ if (Date.now() - sat.ts >= 600_000) continue;
38
+ peers.push({
39
+ nodeId: sat.nodeId,
40
+ agents: [],
41
+ models: [],
42
+ tags: [],
43
+ tools: sat.tools ?? [],
44
+ status: "satellite",
45
+ latencyMs: undefined,
46
+ });
47
+ }
48
+
33
49
  return {
34
50
  content: [
35
51
  {
@@ -6,9 +6,7 @@ export function createClusterSendTool(): AnyAgentTool {
6
6
  name: "cluster_send",
7
7
  label: "Cluster Send",
8
8
  description:
9
- "Send a one-way message to another agent in the cluster. " +
10
- "The message is injected into the target agent's session as an inbound message. " +
11
- "Does not wait for a response.",
9
+ "Send a one-way message to a remote agent. Does not wait for a response.",
12
10
  parameters: {
13
11
  type: "object",
14
12
  properties: {
@@ -6,10 +6,7 @@ export function createClusterToolTool(): AnyAgentTool {
6
6
  name: "cluster_tool",
7
7
  label: "Cluster Tool",
8
8
  description:
9
- "Invoke any OpenClaw tool on a remote cluster node. " +
10
- "Supports all tools available on the remote node (exec, read, write, edit, " +
11
- "web_search, web_fetch, browser, process, etc.). " +
12
- "Use nodeId or 'tags:<tag>' to specify the target.",
9
+ "Invoke any OpenClaw tool on a remote cluster node. Use nodeId or 'tags:<tag>' to specify the target.",
13
10
  parameters: {
14
11
  type: "object",
15
12
  properties: {
@@ -19,7 +16,7 @@ export function createClusterToolTool(): AnyAgentTool {
19
16
  },
20
17
  tool: {
21
18
  type: "string",
22
- description: "Tool name to invoke (e.g. exec, read, write, edit, web_search, web_fetch, browser, process)",
19
+ description: "Tool name to invoke on the remote node",
23
20
  },
24
21
  args: {
25
22
  type: "object",
package/src/types.ts CHANGED
@@ -23,6 +23,8 @@ export interface AuthRequest extends ClusterFrame {
23
23
  agents?: AgentInfo[];
24
24
  models?: ModelInfo[];
25
25
  tags?: string[];
26
+ deviceInfo?: DeviceInfo;
27
+ toolProxy?: ToolProxyInfo;
26
28
  };
27
29
  }
28
30
 
@@ -33,6 +35,8 @@ export interface AuthOk extends ClusterFrame {
33
35
  agents: AgentInfo[];
34
36
  models: ModelInfo[];
35
37
  tags: string[];
38
+ deviceInfo?: DeviceInfo;
39
+ toolProxy?: ToolProxyInfo;
36
40
  };
37
41
  }
38
42
 
@@ -42,10 +46,27 @@ export interface AuthFail extends ClusterFrame {
42
46
  }
43
47
 
44
48
  // ── Peer discovery ─────────────────────────────────────────────────
49
+ export interface SatelliteContext {
50
+ nodeId: string;
51
+ ssid?: string;
52
+ ip?: string;
53
+ router?: string;
54
+ cellular: boolean;
55
+ country?: string;
56
+ tools?: string[];
57
+ ts: number;
58
+ // Extended context
59
+ battery?: number; // 0-100
60
+ charging?: boolean;
61
+ platform?: string; // "ios" | "macos"
62
+ location?: string; // user-defined location name from WiFi mapping
63
+ }
64
+
45
65
  export interface PeerSync extends ClusterFrame {
46
66
  type: "peer_sync";
47
67
  payload: {
48
68
  peers: PeerInfo[];
69
+ satellites?: SatelliteContext[];
49
70
  };
50
71
  }
51
72
 
@@ -74,6 +95,8 @@ export interface ModelRequest extends ClusterFrame {
74
95
  id: string;
75
96
  payload: {
76
97
  model: string;
98
+ provider?: string;
99
+ api?: string;
77
100
  messages: unknown[];
78
101
  temperature?: number;
79
102
  maxTokens?: number;
@@ -87,6 +110,9 @@ export interface ModelResponse extends ClusterFrame {
87
110
  payload: {
88
111
  success: boolean;
89
112
  content?: string;
113
+ /** Full message object from upstream (choices[0].message or responses output).
114
+ * Carries tool_calls, refusal, etc. that `content` alone cannot represent. */
115
+ message?: unknown;
90
116
  usage?: { inputTokens: number; outputTokens: number };
91
117
  error?: string;
92
118
  };
@@ -97,12 +123,23 @@ export interface ModelStreamChunk extends ClusterFrame {
97
123
  id: string;
98
124
  payload: {
99
125
  delta: string;
126
+ /** Full delta object from upstream (choices[0].delta).
127
+ * Carries tool_calls chunks that `delta` string cannot represent. */
128
+ deltaObj?: unknown;
100
129
  done: boolean;
101
130
  usage?: { inputTokens: number; outputTokens: number };
102
131
  };
103
132
  }
104
133
 
105
134
  // ── Handoff ────────────────────────────────────────────────────────
135
+ export type HandoffStatus = "working" | "input_required" | "completed" | "failed" | "canceled";
136
+
137
+ export interface Artifact {
138
+ name: string;
139
+ mimeType: string;
140
+ data: string; // text content or base64-encoded binary
141
+ }
142
+
106
143
  export interface HandoffRequest extends ClusterFrame {
107
144
  type: "handoff_req";
108
145
  id: string;
@@ -119,6 +156,7 @@ export interface HandoffStreamChunk extends ClusterFrame {
119
156
  payload: {
120
157
  delta: string;
121
158
  done: boolean;
159
+ artifacts?: Artifact[];
122
160
  };
123
161
  }
124
162
 
@@ -131,6 +169,48 @@ export interface HandoffResponse extends ClusterFrame {
131
169
  agent?: string;
132
170
  result?: string;
133
171
  error?: string;
172
+ artifacts?: Artifact[];
173
+ inputRequired?: boolean;
174
+ handoffId?: string;
175
+ };
176
+ }
177
+
178
+ export interface HandoffCancel extends ClusterFrame {
179
+ type: "handoff_cancel";
180
+ id: string;
181
+ payload?: unknown;
182
+ }
183
+
184
+ export interface HandoffStatusQuery extends ClusterFrame {
185
+ type: "handoff_status";
186
+ id: string;
187
+ payload?: unknown;
188
+ }
189
+
190
+ export interface HandoffStatusResponse extends ClusterFrame {
191
+ type: "handoff_status_res";
192
+ id: string;
193
+ payload: {
194
+ status: HandoffStatus;
195
+ nodeId: string;
196
+ agent: string;
197
+ elapsedMs: number;
198
+ };
199
+ }
200
+
201
+ export interface HandoffInputRequired extends ClusterFrame {
202
+ type: "handoff_input_required";
203
+ id: string;
204
+ payload: {
205
+ message: string;
206
+ };
207
+ }
208
+
209
+ export interface HandoffInput extends ClusterFrame {
210
+ type: "handoff_input";
211
+ id: string;
212
+ payload: {
213
+ message: string;
134
214
  };
135
215
  }
136
216
 
@@ -163,6 +243,17 @@ export interface ToolProxyResponse extends ClusterFrame {
163
243
  };
164
244
  }
165
245
 
246
+ // ── Device info ───────────────────────────────────────────────────
247
+ export interface DeviceInfo {
248
+ os: string; // e.g. "Darwin 24.6.0", "Linux 6.1.0"
249
+ arch: string; // e.g. "arm64", "x64"
250
+ cpuModel: string; // e.g. "Apple M1 Pro"
251
+ cpuCores: number; // logical CPU cores
252
+ totalMemoryMB: number; // total system memory in MB
253
+ hostname: string; // machine hostname
254
+ openclawVersion?: string; // e.g. "2026.3.7"
255
+ }
256
+
166
257
  // ── Shared info types ──────────────────────────────────────────────
167
258
  export interface AgentInfo {
168
259
  id: string;
@@ -192,12 +283,21 @@ export interface ModelInfo {
192
283
  compat?: ModelCompatInfo;
193
284
  }
194
285
 
286
+ export interface ToolProxyInfo {
287
+ enabled: boolean;
288
+ allow: string[];
289
+ deny: string[];
290
+ }
291
+
195
292
  export interface PeerInfo {
196
293
  nodeId: string;
197
294
  agents: AgentInfo[];
198
295
  models: ModelInfo[];
199
296
  tags: string[];
200
297
  reachableVia?: string; // nodeId of the relay node
298
+ directPeers?: string[]; // nodeIds this node has direct connections to
299
+ deviceInfo?: DeviceInfo; // system/hardware info
300
+ toolProxy?: ToolProxyInfo;
201
301
  }
202
302
 
203
303
  export interface NodeCapabilities {
@@ -205,6 +305,18 @@ export interface NodeCapabilities {
205
305
  agents: AgentInfo[];
206
306
  models: ModelInfo[];
207
307
  tags: string[];
308
+ deviceInfo?: DeviceInfo;
309
+ toolProxy?: ToolProxyInfo;
310
+ }
311
+
312
+ // ── Ingested events (from Shortcuts automations, etc.) ────────────
313
+ export interface IngestedEvent {
314
+ id: string;
315
+ source: string; // e.g. "shortcuts", "iphone-14", "surge"
316
+ type: string; // e.g. "message_received", "call_missed", "location_changed"
317
+ data: Record<string, unknown>;
318
+ ts: number; // ingestion timestamp
319
+ consumed: boolean; // whether an agent has consumed this event
208
320
  }
209
321
 
210
322
  // ── Union of all frame types ───────────────────────────────────────
@@ -224,6 +336,11 @@ export type AnyClusterFrame =
224
336
  | HandoffRequest
225
337
  | HandoffStreamChunk
226
338
  | HandoffResponse
339
+ | HandoffCancel
340
+ | HandoffStatusQuery
341
+ | HandoffStatusResponse
227
342
  | SendMessage
343
+ | HandoffInputRequired
344
+ | HandoffInput
228
345
  | ToolProxyRequest
229
346
  | ToolProxyResponse;