@alfe.ai/openclaw 0.4.10 → 0.4.11

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/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 { EventEmitter } from "events";
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.readyPromise = new Promise((resolve, reject) => {
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
- this.doConnect();
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
- const ws = this.ws;
3843
- if (ws) ws.send(JSON.stringify({
3844
- type: "req",
3845
- id,
3846
- method,
3847
- params
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
- this.ws = new wrapper_default(this.opts.url, { maxPayload: this.opts.maxPayload ?? 10 * 1024 * 1024 });
3882
- this.ws.on("open", () => {
3883
- this.log.info(`[agent-client] Connected to ${this.opts.url}`);
3884
- this.initiateHandshake();
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
- this.ws.on("message", (data) => {
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
- this.ws.on("close", (code, reason) => {
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.onDisconnected();
3896
- this.scheduleReconnect();
3938
+ if (!this.closed) {
3939
+ this.onDisconnected();
3940
+ if (this.readySettled) this.resetReady();
3941
+ this.scheduleReconnect();
3942
+ }
3897
3943
  });
3898
- this.ws.on("error", (err) => {
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.readyReject(err);
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
- this.ws?.close(1008, "handshake failed");
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 ("event" in parsed) {
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 ("id" in parsed && "ok" in parsed) {
3925
- const rpc = parsed;
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?.status === "accepted") return;
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 pending.reject(new Error(rpc.error?.message ?? "Gateway request failed"));
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.readyPromise = new Promise((resolve, reject) => {
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 ?? "0.1.0",
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((p) => p.text).filter(Boolean).join("\n\n");
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 };