openclaw-client 1.1.0 → 2.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/README.md +183 -6
- package/dist/client.d.ts +46 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +86 -14
- package/dist/types.d.ts +170 -7
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +115 -14
- package/src/protocol.schema.json +801 -79
- package/src/types.ts +198 -17
package/src/client.ts
CHANGED
|
@@ -2,6 +2,10 @@ import type {
|
|
|
2
2
|
AgentIdentityParams,
|
|
3
3
|
AgentIdentityResult,
|
|
4
4
|
AgentParams,
|
|
5
|
+
AgentsCreateParams,
|
|
6
|
+
AgentsCreateResult,
|
|
7
|
+
AgentsDeleteParams,
|
|
8
|
+
AgentsDeleteResult,
|
|
5
9
|
AgentsFilesGetParams,
|
|
6
10
|
AgentsFilesGetResult,
|
|
7
11
|
AgentsFilesListParams,
|
|
@@ -10,6 +14,8 @@ import type {
|
|
|
10
14
|
AgentsFilesSetResult,
|
|
11
15
|
AgentsListParams,
|
|
12
16
|
AgentsListResult,
|
|
17
|
+
AgentsUpdateParams,
|
|
18
|
+
AgentsUpdateResult,
|
|
13
19
|
AgentWaitParams,
|
|
14
20
|
ChannelsLogoutParams,
|
|
15
21
|
ChannelsStatusParams,
|
|
@@ -37,6 +43,7 @@ import type {
|
|
|
37
43
|
DevicePairApproveParams,
|
|
38
44
|
DevicePairListParams,
|
|
39
45
|
DevicePairRejectParams,
|
|
46
|
+
DevicePairRemoveParams,
|
|
40
47
|
DeviceTokenRevokeParams,
|
|
41
48
|
DeviceTokenRotateParams,
|
|
42
49
|
EventFrame,
|
|
@@ -62,6 +69,8 @@ import type {
|
|
|
62
69
|
NodePairVerifyParams,
|
|
63
70
|
NodeRenameParams,
|
|
64
71
|
PollParams,
|
|
72
|
+
PushTestParams,
|
|
73
|
+
PushTestResult,
|
|
65
74
|
RequestFrame,
|
|
66
75
|
ResponseFrame,
|
|
67
76
|
SendParams,
|
|
@@ -72,11 +81,14 @@ import type {
|
|
|
72
81
|
SessionsPreviewParams,
|
|
73
82
|
SessionsResetParams,
|
|
74
83
|
SessionsResolveParams,
|
|
84
|
+
SessionsUsageParams,
|
|
75
85
|
SkillsBinsParams,
|
|
76
86
|
SkillsBinsResult,
|
|
77
87
|
SkillsInstallParams,
|
|
78
88
|
SkillsStatusParams,
|
|
79
89
|
SkillsUpdateParams,
|
|
90
|
+
TalkConfigParams,
|
|
91
|
+
TalkConfigResult,
|
|
80
92
|
TalkModeParams,
|
|
81
93
|
UpdateRunParams,
|
|
82
94
|
WakeParams,
|
|
@@ -98,6 +110,14 @@ export interface OpenClawClientConfig {
|
|
|
98
110
|
clientVersion?: string;
|
|
99
111
|
platform?: string;
|
|
100
112
|
mode?: ConnectParams['client']['mode'];
|
|
113
|
+
/** Timeout in ms for the connect handshake (default: 120000).
|
|
114
|
+
* Set this higher if device approval may take a while. */
|
|
115
|
+
connectTimeoutMs?: number;
|
|
116
|
+
/** Timeout in ms for regular RPC requests (default: 30000). */
|
|
117
|
+
requestTimeoutMs?: number;
|
|
118
|
+
/** Additional ConnectParams fields to merge into the handshake request
|
|
119
|
+
* (e.g. `device` for device identity, `caps`, `commands`). */
|
|
120
|
+
connectParams?: Partial<ConnectParams>;
|
|
101
121
|
}
|
|
102
122
|
|
|
103
123
|
export type EventListener = (event: EventFrame) => void;
|
|
@@ -130,7 +150,13 @@ export class OpenClawClient {
|
|
|
130
150
|
}
|
|
131
151
|
|
|
132
152
|
/**
|
|
133
|
-
* Connect to the OpenClaw Gateway and perform handshake
|
|
153
|
+
* Connect to the OpenClaw Gateway and perform handshake.
|
|
154
|
+
*
|
|
155
|
+
* The protocol flow is:
|
|
156
|
+
* 1. Open WebSocket connection
|
|
157
|
+
* 2. Gateway sends a `connect.challenge` event with a nonce
|
|
158
|
+
* 3. Client responds with a `connect` request (including auth token)
|
|
159
|
+
* 4. Gateway replies with `hello-ok` containing server info and snapshot
|
|
134
160
|
*/
|
|
135
161
|
async connect(): Promise<HelloOk> {
|
|
136
162
|
if (this.connected && this.ws?.readyState === WebSocket.OPEN) {
|
|
@@ -141,26 +167,49 @@ export class OpenClawClient {
|
|
|
141
167
|
const WS = getWebSocketConstructor();
|
|
142
168
|
this.ws = new WS(this.config.gatewayUrl);
|
|
143
169
|
|
|
144
|
-
// Wait for connection to open
|
|
145
|
-
await new Promise<
|
|
170
|
+
// Wait for connection to open and receive the challenge event
|
|
171
|
+
const challenge = await new Promise<{ nonce: string; ts: number }>((resolve, reject) => {
|
|
146
172
|
if (!this.ws) {
|
|
147
173
|
reject(new Error('WebSocket not initialized'));
|
|
148
174
|
return;
|
|
149
175
|
}
|
|
150
176
|
|
|
151
|
-
|
|
152
|
-
|
|
177
|
+
const timeout = setTimeout(() => {
|
|
178
|
+
reject(new Error('Connection timeout: no challenge received'));
|
|
179
|
+
}, 15000);
|
|
180
|
+
|
|
181
|
+
this.ws.onerror = (error) => {
|
|
182
|
+
clearTimeout(timeout);
|
|
183
|
+
reject(error);
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
this.ws.onmessage = (event) => {
|
|
187
|
+
try {
|
|
188
|
+
const frame = JSON.parse(event.data);
|
|
189
|
+
if (frame.type === 'event' && frame.event === 'connect.challenge') {
|
|
190
|
+
clearTimeout(timeout);
|
|
191
|
+
resolve(frame.payload);
|
|
192
|
+
}
|
|
193
|
+
} catch (error) {
|
|
194
|
+
clearTimeout(timeout);
|
|
195
|
+
reject(new Error('Failed to parse challenge frame'));
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
this.ws.onopen = () => {
|
|
200
|
+
// Wait for the challenge event after connection opens
|
|
201
|
+
};
|
|
153
202
|
});
|
|
154
203
|
|
|
155
|
-
// Set up message handler
|
|
204
|
+
// Set up message handler for subsequent messages
|
|
156
205
|
if (this.ws) {
|
|
157
206
|
this.ws.onmessage = (event) => this.handleMessage(event);
|
|
158
207
|
this.ws.onclose = () => this.handleClose();
|
|
159
208
|
this.ws.onerror = (error) => this.handleError(error);
|
|
160
209
|
}
|
|
161
210
|
|
|
162
|
-
// Perform handshake
|
|
163
|
-
const result = await this.handshake();
|
|
211
|
+
// Perform handshake (send connect request after receiving challenge)
|
|
212
|
+
const result = await this.handshake(challenge);
|
|
164
213
|
this.connected = true;
|
|
165
214
|
this.connectionId = result.server.connId;
|
|
166
215
|
return result;
|
|
@@ -212,9 +261,10 @@ export class OpenClawClient {
|
|
|
212
261
|
}
|
|
213
262
|
|
|
214
263
|
/**
|
|
215
|
-
* Perform the connection handshake
|
|
264
|
+
* Perform the connection handshake after receiving the challenge.
|
|
265
|
+
* Uses connectTimeoutMs (default 120s) since device approval may take a while.
|
|
216
266
|
*/
|
|
217
|
-
private async handshake(): Promise<HelloOk> {
|
|
267
|
+
private async handshake(_challenge: { nonce: string; ts: number }): Promise<HelloOk> {
|
|
218
268
|
const params: ConnectParams = {
|
|
219
269
|
minProtocol: 3,
|
|
220
270
|
maxProtocol: 3,
|
|
@@ -229,15 +279,17 @@ export class OpenClawClient {
|
|
|
229
279
|
auth: {
|
|
230
280
|
token: this.config.token,
|
|
231
281
|
},
|
|
282
|
+
...this.config.connectParams,
|
|
232
283
|
};
|
|
233
284
|
|
|
234
|
-
|
|
285
|
+
const connectTimeout = this.config.connectTimeoutMs ?? 120000;
|
|
286
|
+
return this.request<HelloOk>('connect', params, connectTimeout);
|
|
235
287
|
}
|
|
236
288
|
|
|
237
289
|
/**
|
|
238
290
|
* Send a request and wait for response
|
|
239
291
|
*/
|
|
240
|
-
private async request<T = any>(method: string, params?: any): Promise<T> {
|
|
292
|
+
private async request<T = any>(method: string, params?: any, timeoutMs?: number): Promise<T> {
|
|
241
293
|
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
242
294
|
throw new Error('Not connected');
|
|
243
295
|
}
|
|
@@ -253,11 +305,11 @@ export class OpenClawClient {
|
|
|
253
305
|
return new Promise((resolve, reject) => {
|
|
254
306
|
this.pending.set(id, { resolve, reject });
|
|
255
307
|
|
|
256
|
-
|
|
308
|
+
const effectiveTimeout = timeoutMs ?? this.config.requestTimeoutMs ?? 30000;
|
|
257
309
|
const timeout = setTimeout(() => {
|
|
258
310
|
this.pending.delete(id);
|
|
259
311
|
reject(new Error(`Request timeout: ${method}`));
|
|
260
|
-
},
|
|
312
|
+
}, effectiveTimeout);
|
|
261
313
|
|
|
262
314
|
// Clear timeout when promise settles
|
|
263
315
|
const originalResolve = resolve;
|
|
@@ -413,6 +465,27 @@ export class OpenClawClient {
|
|
|
413
465
|
return this.request<AgentsListResult>('agents.list', params);
|
|
414
466
|
}
|
|
415
467
|
|
|
468
|
+
/**
|
|
469
|
+
* Create agent
|
|
470
|
+
*/
|
|
471
|
+
async createAgent(params: AgentsCreateParams): Promise<AgentsCreateResult> {
|
|
472
|
+
return this.request<AgentsCreateResult>('agents.create', params);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Update agent
|
|
477
|
+
*/
|
|
478
|
+
async updateAgent(params: AgentsUpdateParams): Promise<AgentsUpdateResult> {
|
|
479
|
+
return this.request<AgentsUpdateResult>('agents.update', params);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Delete agent
|
|
484
|
+
*/
|
|
485
|
+
async deleteAgent(params: AgentsDeleteParams): Promise<AgentsDeleteResult> {
|
|
486
|
+
return this.request<AgentsDeleteResult>('agents.delete', params);
|
|
487
|
+
}
|
|
488
|
+
|
|
416
489
|
/**
|
|
417
490
|
* Get agent identity
|
|
418
491
|
*/
|
|
@@ -483,6 +556,13 @@ export class OpenClawClient {
|
|
|
483
556
|
return this.request('sessions.compact', params);
|
|
484
557
|
}
|
|
485
558
|
|
|
559
|
+
/**
|
|
560
|
+
* Get session usage
|
|
561
|
+
*/
|
|
562
|
+
async getSessionsUsage(params: SessionsUsageParams = {}): Promise<any> {
|
|
563
|
+
return this.request('sessions.usage', params);
|
|
564
|
+
}
|
|
565
|
+
|
|
486
566
|
/**
|
|
487
567
|
* Send a message to agent
|
|
488
568
|
*/
|
|
@@ -553,6 +633,13 @@ export class OpenClawClient {
|
|
|
553
633
|
return this.request('talk.mode', params);
|
|
554
634
|
}
|
|
555
635
|
|
|
636
|
+
/**
|
|
637
|
+
* Get talk config
|
|
638
|
+
*/
|
|
639
|
+
async getTalkConfig(params: TalkConfigParams = {}): Promise<TalkConfigResult> {
|
|
640
|
+
return this.request<TalkConfigResult>('talk.config', params);
|
|
641
|
+
}
|
|
642
|
+
|
|
556
643
|
/**
|
|
557
644
|
* Get channels status
|
|
558
645
|
*/
|
|
@@ -721,6 +808,13 @@ export class OpenClawClient {
|
|
|
721
808
|
return this.request('device.pair.reject', params);
|
|
722
809
|
}
|
|
723
810
|
|
|
811
|
+
/**
|
|
812
|
+
* Remove paired device
|
|
813
|
+
*/
|
|
814
|
+
async removeDevicePairing(params: DevicePairRemoveParams): Promise<any> {
|
|
815
|
+
return this.request('device.pair.remove', params);
|
|
816
|
+
}
|
|
817
|
+
|
|
724
818
|
/**
|
|
725
819
|
* Rotate device token
|
|
726
820
|
*/
|
|
@@ -826,6 +920,13 @@ export class OpenClawClient {
|
|
|
826
920
|
return this.request('node.invoke', params);
|
|
827
921
|
}
|
|
828
922
|
|
|
923
|
+
/**
|
|
924
|
+
* Test push notification to node
|
|
925
|
+
*/
|
|
926
|
+
async testPush(params: PushTestParams): Promise<PushTestResult> {
|
|
927
|
+
return this.request<PushTestResult>('push.test', params);
|
|
928
|
+
}
|
|
929
|
+
|
|
829
930
|
/**
|
|
830
931
|
* Update and run
|
|
831
932
|
*/
|