echoclaw-relay-agent 0.3.3 → 0.4.1

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.
Files changed (2) hide show
  1. package/dist/main.js +43 -9
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -2837,10 +2837,13 @@ var GatewayConnection = class extends import_events.EventEmitter {
2837
2837
  var import_events2 = require("events");
2838
2838
  var MAX_FRAMES_PER_STREAM = 256;
2839
2839
  var MAX_BYTES_PER_STREAM = 1 * 1024 * 1024;
2840
+ var STREAMING_METHODS = /* @__PURE__ */ new Set(["chat.send"]);
2840
2841
  var GatewayRpcProxy = class extends import_events2.EventEmitter {
2841
2842
  gateway;
2842
2843
  streams = /* @__PURE__ */ new Map();
2843
2844
  // rpcId → stream
2845
+ runIdToRpc = /* @__PURE__ */ new Map();
2846
+ // runId → rpcId (for event routing)
2844
2847
  requestToRpc = /* @__PURE__ */ new Map();
2845
2848
  // requestId → rpcId
2846
2849
  constructor(gateway) {
@@ -2870,13 +2873,15 @@ var GatewayRpcProxy = class extends import_events2.EventEmitter {
2870
2873
  return false;
2871
2874
  }
2872
2875
  if (frame.type === "req") {
2876
+ const isStreaming = STREAMING_METHODS.has(frame.method ?? "");
2873
2877
  const stream = {
2874
2878
  requestId: payload.request_id,
2875
2879
  rpcId: frame.id,
2876
2880
  generation: this.gateway.currentGeneration,
2877
2881
  frameCount: 0,
2878
2882
  byteCount: 0,
2879
- createdAt: Date.now()
2883
+ createdAt: Date.now(),
2884
+ streaming: isStreaming
2880
2885
  };
2881
2886
  this.streams.set(frame.id, stream);
2882
2887
  this.requestToRpc.set(payload.request_id, frame.id);
@@ -2924,6 +2929,7 @@ var GatewayRpcProxy = class extends import_events2.EventEmitter {
2924
2929
  }, true);
2925
2930
  }
2926
2931
  this.streams.clear();
2932
+ this.runIdToRpc.clear();
2927
2933
  this.requestToRpc.clear();
2928
2934
  }
2929
2935
  // ── Internal: Gateway frame handling ───────────────────────
@@ -2942,33 +2948,48 @@ var GatewayRpcProxy = class extends import_events2.EventEmitter {
2942
2948
  this.removeStream(frame.id, "stale");
2943
2949
  return;
2944
2950
  }
2945
- this.emitTunnelResponse(stream.requestId, frame, true);
2946
- this.removeStream(frame.id, "complete");
2951
+ if (stream.streaming && frame.ok) {
2952
+ const runId = frame.payload?.runId;
2953
+ if (runId) {
2954
+ stream.runId = runId;
2955
+ this.runIdToRpc.set(runId, frame.id);
2956
+ console.log(`[rpc-proxy] Streaming ACK for ${frame.id} \u2192 runId=${runId}, keeping stream open`);
2957
+ }
2958
+ this.emitTunnelResponse(stream.requestId, frame, false);
2959
+ } else {
2960
+ this.emitTunnelResponse(stream.requestId, frame, true);
2961
+ this.removeStream(frame.id, "complete");
2962
+ }
2947
2963
  }
2948
2964
  handleEvent(frame, generation) {
2965
+ const runId = frame.payload?.runId;
2966
+ const state = frame.payload?.state;
2949
2967
  const streamId = frame.payload?.streamId || frame.payload?.id;
2950
- const stream = streamId ? this.streams.get(streamId) : null;
2968
+ console.log(`[rpc-proxy] Event received: event=${frame.event}, state=${state}, runId=${runId?.slice(0, 8) ?? "none"}, streams=${this.streams.size}, runIdMap=${this.runIdToRpc.size}`);
2969
+ let rpcId = runId ? this.runIdToRpc.get(runId) : void 0;
2970
+ if (!rpcId && streamId) rpcId = streamId;
2971
+ const stream = rpcId ? this.streams.get(rpcId) : null;
2951
2972
  if (!stream) {
2973
+ console.log(`[rpc-proxy] No matching stream for runId=${runId?.slice(0, 8) ?? "none"}, forwarding as unmatched event`);
2952
2974
  this.emit("gateway_event", frame);
2953
2975
  return;
2954
2976
  }
2955
2977
  if (stream.generation !== generation) {
2956
- console.warn(`[rpc-proxy] Dropping stale event for ${streamId}`);
2978
+ console.warn(`[rpc-proxy] Dropping stale event for ${rpcId}`);
2957
2979
  return;
2958
2980
  }
2959
2981
  const frameSize = JSON.stringify(frame).length;
2960
2982
  stream.frameCount++;
2961
2983
  stream.byteCount += frameSize;
2962
2984
  if (stream.frameCount > MAX_FRAMES_PER_STREAM || stream.byteCount > MAX_BYTES_PER_STREAM) {
2963
- console.warn(`[rpc-proxy] Stream ${streamId} exceeded limits (frames=${stream.frameCount}, bytes=${stream.byteCount})`);
2985
+ console.warn(`[rpc-proxy] Stream ${rpcId} exceeded limits (frames=${stream.frameCount}, bytes=${stream.byteCount})`);
2964
2986
  this.cancelStream(stream.requestId);
2965
2987
  return;
2966
2988
  }
2967
- const state = frame.payload?.state;
2968
2989
  const isFinal = state === "final" || state === "aborted" || state === "error";
2969
2990
  this.emitTunnelResponse(stream.requestId, frame, isFinal);
2970
2991
  if (isFinal) {
2971
- this.removeStream(streamId, state);
2992
+ this.removeStream(rpcId, state);
2972
2993
  }
2973
2994
  }
2974
2995
  // ── Internal: emit tunnel response ─────────────────────────
@@ -2988,6 +3009,9 @@ var GatewayRpcProxy = class extends import_events2.EventEmitter {
2988
3009
  if (!stream) return;
2989
3010
  this.streams.delete(rpcId);
2990
3011
  this.requestToRpc.delete(stream.requestId);
3012
+ if (stream.runId) {
3013
+ this.runIdToRpc.delete(stream.runId);
3014
+ }
2991
3015
  }
2992
3016
  };
2993
3017
 
@@ -3049,6 +3073,16 @@ function startGateway(gwConfig) {
3049
3073
  rpcProxy.on("response", (response) => {
3050
3074
  sendEncryptedPayload(response);
3051
3075
  });
3076
+ rpcProxy.on("gateway_event", (frame) => {
3077
+ console.log(`[relay-agent] Forwarding unmatched gateway event: ${frame.event ?? frame.type}`);
3078
+ sendEncryptedPayload({
3079
+ request_id: `evt-${Date.now().toString(36)}`,
3080
+ direction: "response",
3081
+ type: "ws-rpc",
3082
+ frame,
3083
+ final: false
3084
+ });
3085
+ });
3052
3086
  gatewayConn.on("state", (newState, oldState) => {
3053
3087
  console.log(`[relay-agent] Gateway: ${oldState} \u2192 ${newState}`);
3054
3088
  broadcastControlState();
@@ -3866,7 +3900,7 @@ async function discoverGatewayToken() {
3866
3900
  }
3867
3901
 
3868
3902
  // src/main.ts
3869
- var VERSION = "0.3.3";
3903
+ var VERSION = "0.4.1";
3870
3904
  function parseArgs() {
3871
3905
  const args = process.argv.slice(2);
3872
3906
  const opts = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "echoclaw-relay-agent",
3
- "version": "0.3.3",
3
+ "version": "0.4.1",
4
4
  "description": "EchoClaw Relay Agent — connects OpenClaw bridge to the EchoClaw Relay Server with E2E encryption",
5
5
  "main": "./dist/main.js",
6
6
  "bin": {