@alfe.ai/openclaw 0.4.10 → 0.4.12
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 +10 -0
- package/dist/index.cjs +129 -50
- package/dist/index.d.cts +26 -22
- package/dist/index.d.ts +26 -22
- package/dist/index.js +128 -49
- package/dist/plugin2.cjs +622 -252
- package/dist/plugin2.js +623 -253
- package/openclaw.plugin.json +2 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { a as isIPCEvent, c as __commonJSMin, i as PROTOCOL_VERSION, l as __require, n as registerWithDaemon, o as isIPCRequest, r as IPCClient, s as isIPCResponse, t as plugin, u as __toESM } from "./plugin2.js";
|
|
2
|
-
import {
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { EventEmitter } from "node:events";
|
|
3
4
|
import { randomUUID } from "crypto";
|
|
4
5
|
//#region ../../node_modules/.pnpm/ws@8.19.0_bufferutil@4.1.0_utf-8-validate@6.0.6/node_modules/ws/lib/constants.js
|
|
5
6
|
var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -3767,14 +3768,14 @@ const chatEventBus = new ChatEventBus();
|
|
|
3767
3768
|
//#endregion
|
|
3768
3769
|
//#region ../../packages-internal/agent-client/dist/base-client.js
|
|
3769
3770
|
const defaultLogger = {
|
|
3770
|
-
info: (msg) => {
|
|
3771
|
-
console.log(msg);
|
|
3771
|
+
info: (msg, ...args) => {
|
|
3772
|
+
console.log(msg, ...args);
|
|
3772
3773
|
},
|
|
3773
|
-
warn: (msg) => {
|
|
3774
|
-
console.warn(msg);
|
|
3774
|
+
warn: (msg, ...args) => {
|
|
3775
|
+
console.warn(msg, ...args);
|
|
3775
3776
|
},
|
|
3776
|
-
error: (msg) => {
|
|
3777
|
-
console.error(msg);
|
|
3777
|
+
error: (msg, ...args) => {
|
|
3778
|
+
console.error(msg, ...args);
|
|
3778
3779
|
},
|
|
3779
3780
|
debug: () => {}
|
|
3780
3781
|
};
|
|
@@ -3784,9 +3785,11 @@ var BaseAgentClient = class {
|
|
|
3784
3785
|
closed = false;
|
|
3785
3786
|
backoffMs = 1e3;
|
|
3786
3787
|
pending = /* @__PURE__ */ new Map();
|
|
3788
|
+
reconnectTimer = null;
|
|
3787
3789
|
readyResolve = () => {};
|
|
3788
3790
|
readyReject = () => {};
|
|
3789
3791
|
readyPromise;
|
|
3792
|
+
readySettled = false;
|
|
3790
3793
|
log;
|
|
3791
3794
|
opts;
|
|
3792
3795
|
instanceId;
|
|
@@ -3794,10 +3797,7 @@ var BaseAgentClient = class {
|
|
|
3794
3797
|
this.opts = opts;
|
|
3795
3798
|
this.log = opts.logger ?? defaultLogger;
|
|
3796
3799
|
this.instanceId = opts.instanceId ?? randomUUID().slice(0, 8);
|
|
3797
|
-
this.
|
|
3798
|
-
this.readyResolve = resolve;
|
|
3799
|
-
this.readyReject = reject;
|
|
3800
|
-
});
|
|
3800
|
+
this.resetReady();
|
|
3801
3801
|
}
|
|
3802
3802
|
get isConnected() {
|
|
3803
3803
|
return this.connected && this.ws?.readyState === wrapper_default.OPEN;
|
|
@@ -3807,13 +3807,26 @@ var BaseAgentClient = class {
|
|
|
3807
3807
|
this.log.info("[agent-client] URL not set — skipping");
|
|
3808
3808
|
return;
|
|
3809
3809
|
}
|
|
3810
|
+
if (this.isConnected) return;
|
|
3811
|
+
if (this.ws || this.reconnectTimer) return this.readyPromise;
|
|
3812
|
+
if (this.readySettled) this.resetReady();
|
|
3810
3813
|
this.closed = false;
|
|
3811
|
-
|
|
3814
|
+
try {
|
|
3815
|
+
this.doConnect();
|
|
3816
|
+
} catch (err) {
|
|
3817
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
3818
|
+
this.rejectReady(error);
|
|
3819
|
+
}
|
|
3812
3820
|
return this.readyPromise;
|
|
3813
3821
|
}
|
|
3814
3822
|
stop() {
|
|
3815
3823
|
this.closed = true;
|
|
3816
3824
|
this.connected = false;
|
|
3825
|
+
if (this.reconnectTimer) {
|
|
3826
|
+
clearTimeout(this.reconnectTimer);
|
|
3827
|
+
this.reconnectTimer = null;
|
|
3828
|
+
}
|
|
3829
|
+
this.rejectReady(/* @__PURE__ */ new Error("Client stopped"));
|
|
3817
3830
|
this.onDisconnected();
|
|
3818
3831
|
this.ws?.close();
|
|
3819
3832
|
this.ws = null;
|
|
@@ -3821,8 +3834,11 @@ var BaseAgentClient = class {
|
|
|
3821
3834
|
}
|
|
3822
3835
|
request(method, params, opts) {
|
|
3823
3836
|
if (this.ws?.readyState !== wrapper_default.OPEN) return Promise.reject(/* @__PURE__ */ new Error("Gateway WS not connected"));
|
|
3837
|
+
if (method.trim().length === 0) return Promise.reject(/* @__PURE__ */ new TypeError("Gateway method must not be empty"));
|
|
3824
3838
|
const id = randomUUID();
|
|
3825
3839
|
const timeoutMs = opts?.timeoutMs ?? 3e4;
|
|
3840
|
+
if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647) return Promise.reject(/* @__PURE__ */ new RangeError("Gateway timeoutMs must be a positive integer no greater than 2147483647"));
|
|
3841
|
+
const ws = this.ws;
|
|
3826
3842
|
return new Promise((resolve, reject) => {
|
|
3827
3843
|
const timer = setTimeout(() => {
|
|
3828
3844
|
this.pending.delete(id);
|
|
@@ -3839,13 +3855,29 @@ var BaseAgentClient = class {
|
|
|
3839
3855
|
},
|
|
3840
3856
|
expectFinal: opts?.expectFinal === true
|
|
3841
3857
|
});
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3858
|
+
try {
|
|
3859
|
+
ws.send(JSON.stringify({
|
|
3860
|
+
type: "req",
|
|
3861
|
+
id,
|
|
3862
|
+
method,
|
|
3863
|
+
params
|
|
3864
|
+
}), (err) => {
|
|
3865
|
+
if (!err) return;
|
|
3866
|
+
const pending = this.pending.get(id);
|
|
3867
|
+
if (!pending) return;
|
|
3868
|
+
this.pending.delete(id);
|
|
3869
|
+
pending.reject(err);
|
|
3870
|
+
});
|
|
3871
|
+
} catch (err) {
|
|
3872
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
3873
|
+
const pending = this.pending.get(id);
|
|
3874
|
+
this.pending.delete(id);
|
|
3875
|
+
if (pending) pending.reject(error);
|
|
3876
|
+
else {
|
|
3877
|
+
clearTimeout(timer);
|
|
3878
|
+
reject(error);
|
|
3879
|
+
}
|
|
3880
|
+
}
|
|
3849
3881
|
});
|
|
3850
3882
|
}
|
|
3851
3883
|
/**
|
|
@@ -3870,88 +3902,131 @@ var BaseAgentClient = class {
|
|
|
3870
3902
|
}
|
|
3871
3903
|
/** Resolve the ready promise (call after handshake + onConnected). */
|
|
3872
3904
|
resolveReady() {
|
|
3905
|
+
if (this.readySettled) return;
|
|
3906
|
+
this.readySettled = true;
|
|
3873
3907
|
this.readyResolve();
|
|
3874
3908
|
}
|
|
3875
3909
|
/** Reject the ready promise (call on handshake failure). */
|
|
3876
3910
|
rejectReady(err) {
|
|
3911
|
+
if (this.readySettled) return;
|
|
3912
|
+
this.readySettled = true;
|
|
3877
3913
|
this.readyReject(err);
|
|
3878
3914
|
}
|
|
3879
3915
|
doConnect() {
|
|
3880
3916
|
if (this.closed) return;
|
|
3881
|
-
|
|
3882
|
-
this.ws
|
|
3883
|
-
|
|
3884
|
-
this.
|
|
3917
|
+
const ws = new wrapper_default(this.opts.url, { maxPayload: this.opts.maxPayload ?? 10 * 1024 * 1024 });
|
|
3918
|
+
this.ws = ws;
|
|
3919
|
+
ws.on("open", () => {
|
|
3920
|
+
if (this.ws !== ws || this.closed) {
|
|
3921
|
+
ws.close();
|
|
3922
|
+
return;
|
|
3923
|
+
}
|
|
3924
|
+
this.log.info("[agent-client] WebSocket connected");
|
|
3925
|
+
this.initiateHandshake(ws);
|
|
3885
3926
|
});
|
|
3886
|
-
|
|
3927
|
+
ws.on("message", (data) => {
|
|
3928
|
+
if (this.ws !== ws || this.closed) return;
|
|
3887
3929
|
const raw = Buffer.isBuffer(data) ? data.toString("utf-8") : data instanceof ArrayBuffer ? Buffer.from(data).toString("utf-8") : Buffer.concat(data).toString("utf-8");
|
|
3888
3930
|
this.handleMessage(raw);
|
|
3889
3931
|
});
|
|
3890
|
-
|
|
3932
|
+
ws.on("close", (code, reason) => {
|
|
3933
|
+
if (this.ws !== ws) return;
|
|
3891
3934
|
this.log.warn(`[agent-client] Closed (${String(code)}): ${reason.toString()}`);
|
|
3892
3935
|
this.ws = null;
|
|
3893
3936
|
this.connected = false;
|
|
3894
3937
|
this.flushPending(/* @__PURE__ */ new Error(`Gateway closed (${String(code)})`));
|
|
3895
|
-
this.
|
|
3896
|
-
|
|
3938
|
+
if (!this.closed) {
|
|
3939
|
+
this.onDisconnected();
|
|
3940
|
+
if (this.readySettled) this.resetReady();
|
|
3941
|
+
this.scheduleReconnect();
|
|
3942
|
+
}
|
|
3897
3943
|
});
|
|
3898
|
-
|
|
3944
|
+
ws.on("error", (err) => {
|
|
3945
|
+
if (this.ws !== ws || this.closed) return;
|
|
3899
3946
|
this.log.error(`[agent-client] Error: ${err.message}`);
|
|
3900
|
-
if (!this.connected) this.
|
|
3947
|
+
if (!this.connected) this.rejectReady(err);
|
|
3901
3948
|
});
|
|
3902
3949
|
}
|
|
3903
|
-
async initiateHandshake() {
|
|
3950
|
+
async initiateHandshake(ws) {
|
|
3904
3951
|
try {
|
|
3905
3952
|
await this.performHandshake();
|
|
3953
|
+
if (!this.isCurrentConnection(ws)) return;
|
|
3906
3954
|
this.setConnected();
|
|
3907
3955
|
this.log.info("[agent-client] Handshake complete");
|
|
3908
3956
|
await this.onConnected();
|
|
3957
|
+
if (!this.isCurrentConnection(ws)) return;
|
|
3909
3958
|
this.resolveReady();
|
|
3910
3959
|
} catch (err) {
|
|
3960
|
+
if (!this.isCurrentConnection(ws)) return;
|
|
3911
3961
|
const message = err instanceof Error ? err.message : String(err);
|
|
3912
3962
|
this.log.error(`[agent-client] Handshake failed: ${message}`);
|
|
3913
3963
|
this.rejectReady(err instanceof Error ? err : new Error(message));
|
|
3914
|
-
|
|
3964
|
+
ws.close(1008, "handshake failed");
|
|
3915
3965
|
}
|
|
3916
3966
|
}
|
|
3967
|
+
isCurrentConnection(ws) {
|
|
3968
|
+
return this.ws === ws && !this.closed;
|
|
3969
|
+
}
|
|
3917
3970
|
handleMessage(raw) {
|
|
3918
3971
|
try {
|
|
3919
3972
|
const parsed = JSON.parse(raw);
|
|
3920
|
-
if (
|
|
3973
|
+
if (!isRecord$1(parsed)) {
|
|
3974
|
+
this.log.warn("[agent-client] Ignoring malformed message");
|
|
3975
|
+
return;
|
|
3976
|
+
}
|
|
3977
|
+
if (typeof parsed.event === "string") {
|
|
3921
3978
|
this.handleEvent(parsed.event, parsed.payload);
|
|
3922
3979
|
return;
|
|
3923
3980
|
}
|
|
3924
|
-
if (
|
|
3925
|
-
const rpc =
|
|
3981
|
+
if (typeof parsed.id === "string" && typeof parsed.ok === "boolean") {
|
|
3982
|
+
const rpc = {
|
|
3983
|
+
id: parsed.id,
|
|
3984
|
+
ok: parsed.ok,
|
|
3985
|
+
payload: parsed.payload,
|
|
3986
|
+
error: parsed.error
|
|
3987
|
+
};
|
|
3926
3988
|
const pending = this.pending.get(rpc.id);
|
|
3927
3989
|
if (!pending) return;
|
|
3928
|
-
if (pending.expectFinal && rpc.payload
|
|
3990
|
+
if (pending.expectFinal && rpc.ok && isRecord$1(rpc.payload) && rpc.payload.status === "accepted") return;
|
|
3929
3991
|
this.pending.delete(rpc.id);
|
|
3930
3992
|
if (rpc.ok) pending.resolve(rpc.payload);
|
|
3931
|
-
else
|
|
3993
|
+
else {
|
|
3994
|
+
const message = isRecord$1(rpc.error) && typeof rpc.error.message === "string" ? rpc.error.message : "Gateway request failed";
|
|
3995
|
+
pending.reject(new Error(message));
|
|
3996
|
+
}
|
|
3997
|
+
return;
|
|
3932
3998
|
}
|
|
3999
|
+
this.log.warn("[agent-client] Ignoring malformed message");
|
|
3933
4000
|
} catch (err) {
|
|
3934
4001
|
this.log.error(`[agent-client] Parse error: ${String(err)}`);
|
|
3935
4002
|
}
|
|
3936
4003
|
}
|
|
3937
4004
|
scheduleReconnect() {
|
|
3938
|
-
if (this.closed) return;
|
|
4005
|
+
if (this.closed || this.reconnectTimer) return;
|
|
3939
4006
|
const delay = this.backoffMs;
|
|
3940
4007
|
this.backoffMs = Math.min(this.backoffMs * 2, 3e4);
|
|
3941
4008
|
this.log.info(`[agent-client] Reconnecting in ${String(delay)}ms...`);
|
|
3942
|
-
setTimeout(() => {
|
|
3943
|
-
this.
|
|
3944
|
-
this.readyResolve = resolve;
|
|
3945
|
-
this.readyReject = reject;
|
|
3946
|
-
});
|
|
4009
|
+
this.reconnectTimer = setTimeout(() => {
|
|
4010
|
+
this.reconnectTimer = null;
|
|
3947
4011
|
this.doConnect();
|
|
3948
4012
|
}, delay);
|
|
3949
4013
|
}
|
|
4014
|
+
resetReady() {
|
|
4015
|
+
this.readySettled = false;
|
|
4016
|
+
this.readyPromise = new Promise((resolve, reject) => {
|
|
4017
|
+
this.readyResolve = resolve;
|
|
4018
|
+
this.readyReject = reject;
|
|
4019
|
+
});
|
|
4020
|
+
this.readyPromise.catch(() => void 0);
|
|
4021
|
+
}
|
|
3950
4022
|
flushPending(err) {
|
|
3951
4023
|
for (const [, p] of this.pending) p.reject(err);
|
|
3952
4024
|
this.pending.clear();
|
|
3953
4025
|
}
|
|
3954
4026
|
};
|
|
4027
|
+
function isRecord$1(value) {
|
|
4028
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4029
|
+
}
|
|
3955
4030
|
//#endregion
|
|
3956
4031
|
//#region src/ws-client.ts
|
|
3957
4032
|
/**
|
|
@@ -3964,6 +4039,7 @@ var BaseAgentClient = class {
|
|
|
3964
4039
|
* - Agent response parsing (multi-format)
|
|
3965
4040
|
* - Session key formatting
|
|
3966
4041
|
*/
|
|
4042
|
+
const pkg = createRequire(import.meta.url)("../package.json");
|
|
3967
4043
|
var OpenClawGatewayAdapter = class extends BaseAgentClient {
|
|
3968
4044
|
tickTimer = null;
|
|
3969
4045
|
lastTick = 0;
|
|
@@ -3983,7 +4059,7 @@ var OpenClawGatewayAdapter = class extends BaseAgentClient {
|
|
|
3983
4059
|
client: {
|
|
3984
4060
|
id: this.opts.clientId,
|
|
3985
4061
|
displayName: this.opts.displayName,
|
|
3986
|
-
version: this.opts.version ??
|
|
4062
|
+
version: this.opts.version ?? pkg.version,
|
|
3987
4063
|
platform: process.platform,
|
|
3988
4064
|
mode: "backend",
|
|
3989
4065
|
instanceId: this.instanceId
|
|
@@ -4030,13 +4106,13 @@ var OpenClawGatewayAdapter = class extends BaseAgentClient {
|
|
|
4030
4106
|
}
|
|
4031
4107
|
/** Parse the standard agent response format into plain text. */
|
|
4032
4108
|
static parseAgentResponse(response) {
|
|
4033
|
-
if (typeof response !== "object" || response === null) return "";
|
|
4109
|
+
if (typeof response !== "object" || response === null || Array.isArray(response)) return "";
|
|
4034
4110
|
const r = response;
|
|
4035
|
-
const result = r.result;
|
|
4036
|
-
if (result?.payloads) return result.payloads.map((
|
|
4037
|
-
if (typeof r.text === "string") return r.text;
|
|
4038
|
-
if (typeof r.content === "string") return r.content;
|
|
4039
|
-
if (typeof r.message === "string") return r.message;
|
|
4111
|
+
const result = isRecord(r.result) ? r.result : void 0;
|
|
4112
|
+
if (Array.isArray(result?.payloads)) return result.payloads.slice(0, 1e3).filter(isRecord).map((payload) => payload.text).filter((text) => typeof text === "string").join("\n\n").slice(0, 1024 * 1024);
|
|
4113
|
+
if (typeof r.text === "string") return r.text.slice(0, 1024 * 1024);
|
|
4114
|
+
if (typeof r.content === "string") return r.content.slice(0, 1024 * 1024);
|
|
4115
|
+
if (typeof r.message === "string") return r.message.slice(0, 1024 * 1024);
|
|
4040
4116
|
return "";
|
|
4041
4117
|
}
|
|
4042
4118
|
/** Format a session key with the standard agent prefix. */
|
|
@@ -4044,5 +4120,8 @@ var OpenClawGatewayAdapter = class extends BaseAgentClient {
|
|
|
4044
4120
|
return `agent:${agentId}:${sessionKey}`;
|
|
4045
4121
|
}
|
|
4046
4122
|
};
|
|
4123
|
+
function isRecord(value) {
|
|
4124
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4125
|
+
}
|
|
4047
4126
|
//#endregion
|
|
4048
4127
|
export { IPCClient, OpenClawGatewayAdapter, PROTOCOL_VERSION, isIPCEvent, isIPCRequest, isIPCResponse, plugin, registerWithDaemon };
|