@buda-ai/connector 0.1.28 → 0.1.29

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/cli.js +49 -19
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -523,7 +523,7 @@ import path2 from "path";
523
523
  // package.json
524
524
  var package_default = {
525
525
  name: "@buda-ai/connector",
526
- version: "0.1.28",
526
+ version: "0.1.29",
527
527
  private: false,
528
528
  type: "module",
529
529
  publishConfig: {
@@ -4704,6 +4704,7 @@ var isAlreadyExists3 = (error) => error instanceof Error && "code" in error && e
4704
4704
  // src/relay.ts
4705
4705
  var RELAY_PING_INTERVAL_MS = 2e4;
4706
4706
  var RELAY_PONG_TIMEOUT_MS = 1e4;
4707
+ var RELAY_ACTIVE_REQUEST_PONG_TIMEOUT_LIMIT = 2;
4707
4708
  var RELAY_HANDSHAKE_TIMEOUT_MS = 1e4;
4708
4709
  var RELAY_RECONNECT_MAX_MS = 3e4;
4709
4710
  var RELAY_RECONNECT_JITTER = 0.2;
@@ -4809,6 +4810,7 @@ function startConnectorRelay(config, bunnyDaemon, relayProtocol, workspaceRegist
4809
4810
  socket = ws;
4810
4811
  const inflight = /* @__PURE__ */ new Map();
4811
4812
  currentInflight = inflight;
4813
+ let consecutivePongTimeouts = 0;
4812
4814
  let detached = false;
4813
4815
  const detach = () => {
4814
4816
  if (detached) return;
@@ -4821,6 +4823,7 @@ function startConnectorRelay(config, bunnyDaemon, relayProtocol, workspaceRegist
4821
4823
  void writeLog("info", `relay connected ${relayUrl}`);
4822
4824
  hadOpenConnection = true;
4823
4825
  reconnectDelayMs = RELAY_RECONNECT_INTERVAL_MS;
4826
+ consecutivePongTimeouts = 0;
4824
4827
  pingTimer = setInterval(() => {
4825
4828
  if (ws.readyState !== WebSocket2.OPEN) return;
4826
4829
  try {
@@ -4832,18 +4835,33 @@ function startConnectorRelay(config, bunnyDaemon, relayProtocol, workspaceRegist
4832
4835
  }
4833
4836
  if (pongTimer) clearTimeout(pongTimer);
4834
4837
  pongTimer = setTimeout(() => {
4838
+ pongTimer = null;
4839
+ consecutivePongTimeouts += 1;
4840
+ if (inflight.size > 0 && consecutivePongTimeouts < RELAY_ACTIVE_REQUEST_PONG_TIMEOUT_LIMIT) {
4841
+ void writeLog(
4842
+ "warn",
4843
+ `relay pong timeout deferred while ${inflight.size} request(s) are active`
4844
+ );
4845
+ return;
4846
+ }
4835
4847
  void writeLog("warn", "relay pong timeout, terminating");
4836
4848
  ws.terminate();
4837
4849
  }, RELAY_PONG_TIMEOUT_MS);
4838
4850
  }, RELAY_PING_INTERVAL_MS);
4839
4851
  });
4840
4852
  ws.on("pong", () => {
4853
+ consecutivePongTimeouts = 0;
4841
4854
  if (pongTimer) {
4842
4855
  clearTimeout(pongTimer);
4843
4856
  pongTimer = null;
4844
4857
  }
4845
4858
  });
4846
4859
  ws.on("message", (raw) => {
4860
+ consecutivePongTimeouts = 0;
4861
+ if (pongTimer) {
4862
+ clearTimeout(pongTimer);
4863
+ pongTimer = null;
4864
+ }
4847
4865
  void handleRelayMessage(
4848
4866
  ws,
4849
4867
  bunnyDaemon,
@@ -5019,7 +5037,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
5019
5037
  });
5020
5038
  executionIdentity = message.executionIdentity;
5021
5039
  } catch (error) {
5022
- sendRelayError(socket, message.requestId, error);
5040
+ await sendRelayError(socket, message.requestId, error).catch(() => void 0);
5023
5041
  return;
5024
5042
  }
5025
5043
  }
@@ -5105,7 +5123,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
5105
5123
  durationMs: Date.now() - codingRunStartedAt
5106
5124
  });
5107
5125
  }
5108
- sendRelayMessage(socket, {
5126
+ await sendRelayMessage(socket, {
5109
5127
  type: "start",
5110
5128
  requestId: message.requestId,
5111
5129
  status: response.status,
@@ -5125,7 +5143,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
5125
5143
  while (true) {
5126
5144
  const { value, done } = await reader.read();
5127
5145
  if (done) break;
5128
- sendRelayMessage(socket, {
5146
+ await sendRelayMessage(socket, {
5129
5147
  type: "chunk",
5130
5148
  requestId: message.requestId,
5131
5149
  data: binaryResponse ? Buffer.from(value).toString("base64") : decoder?.decode(value, { stream: true }) ?? "",
@@ -5134,7 +5152,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
5134
5152
  }
5135
5153
  const tail = decoder?.decode() ?? "";
5136
5154
  if (tail) {
5137
- sendRelayMessage(socket, {
5155
+ await sendRelayMessage(socket, {
5138
5156
  type: "chunk",
5139
5157
  requestId: message.requestId,
5140
5158
  data: tail
@@ -5145,7 +5163,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
5145
5163
  reader.releaseLock();
5146
5164
  }
5147
5165
  }
5148
- sendRelayMessage(socket, {
5166
+ await sendRelayMessage(socket, {
5149
5167
  type: "end",
5150
5168
  requestId: message.requestId
5151
5169
  });
@@ -5157,14 +5175,16 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
5157
5175
  });
5158
5176
  }
5159
5177
  } catch (error) {
5178
+ controller.abort();
5160
5179
  if (codingRunTrace && codingRunStartedAt !== void 0) {
5161
5180
  await writeLog("error", "relay request coding run error", {
5162
5181
  ...codingRunTrace,
5163
5182
  status: codingRunStatus,
5164
- durationMs: Date.now() - codingRunStartedAt
5183
+ durationMs: Date.now() - codingRunStartedAt,
5184
+ error: formatConnectorRelayError(error)
5165
5185
  });
5166
5186
  }
5167
- sendRelayError(socket, message.requestId, error);
5187
+ await sendRelayError(socket, message.requestId, error).catch(() => void 0);
5168
5188
  } finally {
5169
5189
  inflight.delete(message.requestId);
5170
5190
  }
@@ -5218,17 +5238,20 @@ var normalizeWorkspaceRequest = (request, mounts) => {
5218
5238
  if (!mount || relative === void 0) {
5219
5239
  throw new ConnectorRelayProtocolError("WORKSPACE_MISMATCH");
5220
5240
  }
5221
- const env = body.env && typeof body.env === "object" && !Array.isArray(body.env) ? body.env : {};
5241
+ const systemEnv = body.systemEnv && typeof body.systemEnv === "object" && !Array.isArray(body.systemEnv) ? body.systemEnv : {};
5242
+ const workspaceEnv = {
5243
+ BUDA_AGENT_ROOT: mounts.agent,
5244
+ BUDA_SPACE_ROOT: mounts.space,
5245
+ BUDA_SYSTEM_ROOT: mounts.system
5246
+ };
5222
5247
  return {
5223
5248
  ...request,
5224
5249
  body: {
5225
5250
  ...body,
5226
5251
  cwd: path12.join(mount, relative),
5227
- env: {
5228
- ...env,
5229
- BUDA_AGENT_ROOT: mounts.agent,
5230
- BUDA_SPACE_ROOT: mounts.space,
5231
- BUDA_SYSTEM_ROOT: mounts.system
5252
+ systemEnv: {
5253
+ ...systemEnv,
5254
+ ...workspaceEnv
5232
5255
  }
5233
5256
  }
5234
5257
  };
@@ -5260,17 +5283,24 @@ var normalizeConnectorFilesystemRequest = (request, mounts) => {
5260
5283
  }
5261
5284
  return request;
5262
5285
  };
5263
- function sendRelayError(socket, requestId, error) {
5264
- sendRelayMessage(socket, {
5286
+ async function sendRelayError(socket, requestId, error) {
5287
+ await sendRelayMessage(socket, {
5265
5288
  type: "error",
5266
5289
  requestId,
5267
5290
  error: error instanceof Error ? error.message : String(error),
5268
5291
  ...error instanceof ConnectorRelayProtocolError ? { code: error.code } : {}
5269
5292
  });
5270
5293
  }
5271
- function sendRelayMessage(socket, message) {
5272
- if (socket.readyState !== WebSocket2.OPEN) return;
5273
- socket.send(JSON.stringify(message));
5294
+ async function sendRelayMessage(socket, message) {
5295
+ if (socket.readyState !== WebSocket2.OPEN) {
5296
+ throw new Error(`Connector relay socket closed before ${message.type} could be sent.`);
5297
+ }
5298
+ await new Promise((resolve, reject) => {
5299
+ socket.send(JSON.stringify(message), (error) => {
5300
+ if (error) reject(error);
5301
+ else resolve();
5302
+ });
5303
+ });
5274
5304
  }
5275
5305
  function headersToRecord(headers) {
5276
5306
  const result = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buda-ai/connector",
3
- "version": "0.1.28",
3
+ "version": "0.1.29",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "publishConfig": {