clawmatrix 0.1.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/README.md +15 -0
- package/llms.txt +191 -0
- package/openclaw.plugin.json +76 -0
- package/package.json +43 -0
- package/src/auth.ts +38 -0
- package/src/cli.ts +84 -0
- package/src/cluster-service.ts +160 -0
- package/src/config.ts +50 -0
- package/src/connection.ts +261 -0
- package/src/handoff.ts +201 -0
- package/src/index.ts +119 -0
- package/src/model-proxy.ts +441 -0
- package/src/peer-manager.ts +333 -0
- package/src/router.ts +275 -0
- package/src/tool-proxy.ts +324 -0
- package/src/tools/cluster-exec.ts +66 -0
- package/src/tools/cluster-handoff.ts +82 -0
- package/src/tools/cluster-ls.ts +51 -0
- package/src/tools/cluster-peers.ts +55 -0
- package/src/tools/cluster-read.ts +48 -0
- package/src/tools/cluster-send.ts +79 -0
- package/src/tools/cluster-write.ts +61 -0
- package/src/types.ts +197 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { AnyAgentTool } from "openclaw/plugin-sdk";
|
|
2
|
+
import { getClusterRuntime } from "../cluster-service.ts";
|
|
3
|
+
|
|
4
|
+
export function createClusterWriteTool(): AnyAgentTool {
|
|
5
|
+
return {
|
|
6
|
+
name: "cluster_write",
|
|
7
|
+
label: "Cluster Write",
|
|
8
|
+
description: "Write content to a file on a remote cluster node.",
|
|
9
|
+
parameters: {
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: {
|
|
12
|
+
node: {
|
|
13
|
+
type: "string",
|
|
14
|
+
description: 'Target nodeId or "tags:<tag>"',
|
|
15
|
+
},
|
|
16
|
+
path: {
|
|
17
|
+
type: "string",
|
|
18
|
+
description: "Absolute file path to write",
|
|
19
|
+
},
|
|
20
|
+
content: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "Content to write to the file",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
required: ["node", "path", "content"],
|
|
26
|
+
},
|
|
27
|
+
async execute(_toolCallId, params) {
|
|
28
|
+
const { node, path, content } = params as {
|
|
29
|
+
node: string;
|
|
30
|
+
path: string;
|
|
31
|
+
content: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
const runtime = getClusterRuntime();
|
|
36
|
+
const result = await runtime.toolProxy.write(node, path, content);
|
|
37
|
+
return {
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
type: "text" as const,
|
|
41
|
+
text: result.success
|
|
42
|
+
? `Successfully wrote to ${path} on ${node}`
|
|
43
|
+
: `Write failed on ${node}`,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
details: result,
|
|
47
|
+
};
|
|
48
|
+
} catch (err) {
|
|
49
|
+
return {
|
|
50
|
+
content: [
|
|
51
|
+
{
|
|
52
|
+
type: "text" as const,
|
|
53
|
+
text: `Write error: ${err instanceof Error ? err.message : String(err)}`,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
details: { error: true },
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
// ── Cluster Frame (message envelope) ────────────────────────────────
|
|
2
|
+
export interface ClusterFrame {
|
|
3
|
+
type: string;
|
|
4
|
+
id?: string;
|
|
5
|
+
from: string;
|
|
6
|
+
to?: string;
|
|
7
|
+
ttl?: number;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
payload?: unknown;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// ── Auth messages ──────────────────────────────────────────────────
|
|
13
|
+
export interface AuthChallenge extends ClusterFrame {
|
|
14
|
+
type: "auth_challenge";
|
|
15
|
+
payload: { nonce: string };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AuthRequest extends ClusterFrame {
|
|
19
|
+
type: "auth";
|
|
20
|
+
payload: { nodeId: string; sig: string };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface AuthOk extends ClusterFrame {
|
|
24
|
+
type: "auth_ok";
|
|
25
|
+
payload: {
|
|
26
|
+
nodeId: string;
|
|
27
|
+
agents: AgentInfo[];
|
|
28
|
+
models: ModelInfo[];
|
|
29
|
+
tags: string[];
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface AuthFail extends ClusterFrame {
|
|
34
|
+
type: "auth_fail";
|
|
35
|
+
payload: { reason: string };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ── Peer discovery ─────────────────────────────────────────────────
|
|
39
|
+
export interface PeerSync extends ClusterFrame {
|
|
40
|
+
type: "peer_sync";
|
|
41
|
+
payload: {
|
|
42
|
+
peers: PeerInfo[];
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface PeerJoin extends ClusterFrame {
|
|
47
|
+
type: "peer_join";
|
|
48
|
+
payload: PeerInfo;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface PeerLeave extends ClusterFrame {
|
|
52
|
+
type: "peer_leave";
|
|
53
|
+
payload: { nodeId: string };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ── Heartbeat ──────────────────────────────────────────────────────
|
|
57
|
+
export interface Ping extends ClusterFrame {
|
|
58
|
+
type: "ping";
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface Pong extends ClusterFrame {
|
|
62
|
+
type: "pong";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ── Model proxy ────────────────────────────────────────────────────
|
|
66
|
+
export interface ModelRequest extends ClusterFrame {
|
|
67
|
+
type: "model_req";
|
|
68
|
+
id: string;
|
|
69
|
+
payload: {
|
|
70
|
+
model: string;
|
|
71
|
+
messages: unknown[];
|
|
72
|
+
temperature?: number;
|
|
73
|
+
maxTokens?: number;
|
|
74
|
+
stream: boolean;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface ModelResponse extends ClusterFrame {
|
|
79
|
+
type: "model_res";
|
|
80
|
+
id: string;
|
|
81
|
+
payload: {
|
|
82
|
+
success: boolean;
|
|
83
|
+
content?: string;
|
|
84
|
+
usage?: { inputTokens: number; outputTokens: number };
|
|
85
|
+
error?: string;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface ModelStreamChunk extends ClusterFrame {
|
|
90
|
+
type: "model_stream";
|
|
91
|
+
id: string;
|
|
92
|
+
payload: {
|
|
93
|
+
delta: string;
|
|
94
|
+
done: boolean;
|
|
95
|
+
usage?: { inputTokens: number; outputTokens: number };
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ── Handoff ────────────────────────────────────────────────────────
|
|
100
|
+
export interface HandoffRequest extends ClusterFrame {
|
|
101
|
+
type: "handoff_req";
|
|
102
|
+
id: string;
|
|
103
|
+
payload: {
|
|
104
|
+
target: string;
|
|
105
|
+
task: string;
|
|
106
|
+
context?: string;
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface HandoffResponse extends ClusterFrame {
|
|
111
|
+
type: "handoff_res";
|
|
112
|
+
id: string;
|
|
113
|
+
payload: {
|
|
114
|
+
success: boolean;
|
|
115
|
+
nodeId?: string;
|
|
116
|
+
agent?: string;
|
|
117
|
+
result?: string;
|
|
118
|
+
error?: string;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ── Send (one-way) ─────────────────────────────────────────────────
|
|
123
|
+
export interface SendMessage extends ClusterFrame {
|
|
124
|
+
type: "send";
|
|
125
|
+
payload: {
|
|
126
|
+
target: string;
|
|
127
|
+
message: string;
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ── Tool proxy ─────────────────────────────────────────────────────
|
|
132
|
+
export interface ToolProxyRequest extends ClusterFrame {
|
|
133
|
+
type: "tool_req";
|
|
134
|
+
id: string;
|
|
135
|
+
payload: {
|
|
136
|
+
tool: "exec" | "read" | "write" | "ls";
|
|
137
|
+
params: Record<string, unknown>;
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface ToolProxyResponse extends ClusterFrame {
|
|
142
|
+
type: "tool_res";
|
|
143
|
+
id: string;
|
|
144
|
+
payload: {
|
|
145
|
+
success: boolean;
|
|
146
|
+
result?: Record<string, unknown>;
|
|
147
|
+
error?: string;
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ── Shared info types ──────────────────────────────────────────────
|
|
152
|
+
export interface AgentInfo {
|
|
153
|
+
id: string;
|
|
154
|
+
description: string;
|
|
155
|
+
tags: string[];
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface ModelInfo {
|
|
159
|
+
id: string;
|
|
160
|
+
provider: string;
|
|
161
|
+
description?: string;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface PeerInfo {
|
|
165
|
+
nodeId: string;
|
|
166
|
+
agents: AgentInfo[];
|
|
167
|
+
models: ModelInfo[];
|
|
168
|
+
tags: string[];
|
|
169
|
+
reachableVia?: string; // nodeId of the relay node
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export interface NodeCapabilities {
|
|
173
|
+
nodeId: string;
|
|
174
|
+
agents: AgentInfo[];
|
|
175
|
+
models: ModelInfo[];
|
|
176
|
+
tags: string[];
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// ── Union of all frame types ───────────────────────────────────────
|
|
180
|
+
export type AnyClusterFrame =
|
|
181
|
+
| AuthChallenge
|
|
182
|
+
| AuthRequest
|
|
183
|
+
| AuthOk
|
|
184
|
+
| AuthFail
|
|
185
|
+
| PeerSync
|
|
186
|
+
| PeerJoin
|
|
187
|
+
| PeerLeave
|
|
188
|
+
| Ping
|
|
189
|
+
| Pong
|
|
190
|
+
| ModelRequest
|
|
191
|
+
| ModelResponse
|
|
192
|
+
| ModelStreamChunk
|
|
193
|
+
| HandoffRequest
|
|
194
|
+
| HandoffResponse
|
|
195
|
+
| SendMessage
|
|
196
|
+
| ToolProxyRequest
|
|
197
|
+
| ToolProxyResponse;
|