@buda-ai/connector 0.1.28 → 0.1.30
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/cli.js +70 -26
- 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.
|
|
526
|
+
version: "0.1.30",
|
|
527
527
|
private: false,
|
|
528
528
|
type: "module",
|
|
529
529
|
publishConfig: {
|
|
@@ -2790,6 +2790,25 @@ var stopLiveDaemon = async (config, status, configRoot = getConfigRoot(), comman
|
|
|
2790
2790
|
await stopUnresponsiveDaemonProcess(status.pid);
|
|
2791
2791
|
return true;
|
|
2792
2792
|
};
|
|
2793
|
+
var matchesDaemonIdentity = (config, status) => status.connectorId === config.connectorId && normalizeServerOrigin(status.serverUrl) === normalizeServerOrigin(config.serverUrl) && Number.isSafeInteger(status.pid) && status.pid > 0 && typeof status.instanceId === "string" && status.instanceId.length > 0;
|
|
2794
|
+
var readMatchingPersistedDaemonStatus = async (config, configRoot = getConfigRoot()) => {
|
|
2795
|
+
const status = await readPersistedDaemonStatus(config, configRoot).catch(() => null);
|
|
2796
|
+
return status && matchesDaemonIdentity(config, status) ? status : null;
|
|
2797
|
+
};
|
|
2798
|
+
var stopDaemonForIdentity = async (config, configRoot = getConfigRoot()) => {
|
|
2799
|
+
const liveStatus = await readLiveStatus(config, configRoot);
|
|
2800
|
+
if (liveStatus) {
|
|
2801
|
+
await stopLiveDaemon(config, liveStatus, configRoot);
|
|
2802
|
+
return;
|
|
2803
|
+
}
|
|
2804
|
+
const persistedStatus = await readMatchingPersistedDaemonStatus(config, configRoot);
|
|
2805
|
+
if (!persistedStatus || !isProcessAlive2(persistedStatus.pid)) return;
|
|
2806
|
+
const currentStatus = await readMatchingPersistedDaemonStatus(config, configRoot);
|
|
2807
|
+
if (!currentStatus || currentStatus.pid !== persistedStatus.pid || currentStatus.instanceId !== persistedStatus.instanceId || !isProcessAlive2(currentStatus.pid)) {
|
|
2808
|
+
return;
|
|
2809
|
+
}
|
|
2810
|
+
await stopUnresponsiveDaemonProcess(currentStatus.pid);
|
|
2811
|
+
};
|
|
2793
2812
|
var shouldRestartUnhealthyDaemonForEnrollment = (status, explicitEnrollment) => explicitEnrollment && status.idle && status.heartbeatHealthy === false;
|
|
2794
2813
|
var readDaemonLockOwnerPid = async (config) => {
|
|
2795
2814
|
const lockPath = `${getConnectorDaemonLockTarget(
|
|
@@ -2978,9 +2997,7 @@ async function stopLocalConnectorDaemon(connectorId, serverUrl, configRoot = get
|
|
|
2978
2997
|
(candidate) => candidate.connectorId === connectorId && normalizeServerOrigin(candidate.serverUrl) === serverOrigin
|
|
2979
2998
|
);
|
|
2980
2999
|
if (!config) throw new Error(`Local Connector ${connectorId} was not found`);
|
|
2981
|
-
|
|
2982
|
-
if (!status) return;
|
|
2983
|
-
await stopLiveDaemon(config, status, configRoot);
|
|
3000
|
+
await stopDaemonForIdentity(config, configRoot);
|
|
2984
3001
|
}
|
|
2985
3002
|
async function stopAllLocalConnectorDaemons(configRoot = getConfigRoot()) {
|
|
2986
3003
|
const configs = await listDeviceConfigs(configRoot);
|
|
@@ -2991,10 +3008,7 @@ async function stopAllLocalConnectorDaemons(configRoot = getConfigRoot()) {
|
|
|
2991
3008
|
${config.connectorId}`, config);
|
|
2992
3009
|
}
|
|
2993
3010
|
const results = await Promise.allSettled(
|
|
2994
|
-
[...identities.values()].map(
|
|
2995
|
-
const status = await readLiveStatus(config, configRoot);
|
|
2996
|
-
if (status) await stopLiveDaemon(config, status, configRoot);
|
|
2997
|
-
})
|
|
3011
|
+
[...identities.values()].map((config) => stopDaemonForIdentity(config, configRoot))
|
|
2998
3012
|
);
|
|
2999
3013
|
const failures = results.filter((result) => result.status === "rejected");
|
|
3000
3014
|
if (failures.length) {
|
|
@@ -4704,6 +4718,7 @@ var isAlreadyExists3 = (error) => error instanceof Error && "code" in error && e
|
|
|
4704
4718
|
// src/relay.ts
|
|
4705
4719
|
var RELAY_PING_INTERVAL_MS = 2e4;
|
|
4706
4720
|
var RELAY_PONG_TIMEOUT_MS = 1e4;
|
|
4721
|
+
var RELAY_ACTIVE_REQUEST_PONG_TIMEOUT_LIMIT = 2;
|
|
4707
4722
|
var RELAY_HANDSHAKE_TIMEOUT_MS = 1e4;
|
|
4708
4723
|
var RELAY_RECONNECT_MAX_MS = 3e4;
|
|
4709
4724
|
var RELAY_RECONNECT_JITTER = 0.2;
|
|
@@ -4809,6 +4824,7 @@ function startConnectorRelay(config, bunnyDaemon, relayProtocol, workspaceRegist
|
|
|
4809
4824
|
socket = ws;
|
|
4810
4825
|
const inflight = /* @__PURE__ */ new Map();
|
|
4811
4826
|
currentInflight = inflight;
|
|
4827
|
+
let consecutivePongTimeouts = 0;
|
|
4812
4828
|
let detached = false;
|
|
4813
4829
|
const detach = () => {
|
|
4814
4830
|
if (detached) return;
|
|
@@ -4821,6 +4837,7 @@ function startConnectorRelay(config, bunnyDaemon, relayProtocol, workspaceRegist
|
|
|
4821
4837
|
void writeLog("info", `relay connected ${relayUrl}`);
|
|
4822
4838
|
hadOpenConnection = true;
|
|
4823
4839
|
reconnectDelayMs = RELAY_RECONNECT_INTERVAL_MS;
|
|
4840
|
+
consecutivePongTimeouts = 0;
|
|
4824
4841
|
pingTimer = setInterval(() => {
|
|
4825
4842
|
if (ws.readyState !== WebSocket2.OPEN) return;
|
|
4826
4843
|
try {
|
|
@@ -4832,18 +4849,33 @@ function startConnectorRelay(config, bunnyDaemon, relayProtocol, workspaceRegist
|
|
|
4832
4849
|
}
|
|
4833
4850
|
if (pongTimer) clearTimeout(pongTimer);
|
|
4834
4851
|
pongTimer = setTimeout(() => {
|
|
4852
|
+
pongTimer = null;
|
|
4853
|
+
consecutivePongTimeouts += 1;
|
|
4854
|
+
if (inflight.size > 0 && consecutivePongTimeouts < RELAY_ACTIVE_REQUEST_PONG_TIMEOUT_LIMIT) {
|
|
4855
|
+
void writeLog(
|
|
4856
|
+
"warn",
|
|
4857
|
+
`relay pong timeout deferred while ${inflight.size} request(s) are active`
|
|
4858
|
+
);
|
|
4859
|
+
return;
|
|
4860
|
+
}
|
|
4835
4861
|
void writeLog("warn", "relay pong timeout, terminating");
|
|
4836
4862
|
ws.terminate();
|
|
4837
4863
|
}, RELAY_PONG_TIMEOUT_MS);
|
|
4838
4864
|
}, RELAY_PING_INTERVAL_MS);
|
|
4839
4865
|
});
|
|
4840
4866
|
ws.on("pong", () => {
|
|
4867
|
+
consecutivePongTimeouts = 0;
|
|
4841
4868
|
if (pongTimer) {
|
|
4842
4869
|
clearTimeout(pongTimer);
|
|
4843
4870
|
pongTimer = null;
|
|
4844
4871
|
}
|
|
4845
4872
|
});
|
|
4846
4873
|
ws.on("message", (raw) => {
|
|
4874
|
+
consecutivePongTimeouts = 0;
|
|
4875
|
+
if (pongTimer) {
|
|
4876
|
+
clearTimeout(pongTimer);
|
|
4877
|
+
pongTimer = null;
|
|
4878
|
+
}
|
|
4847
4879
|
void handleRelayMessage(
|
|
4848
4880
|
ws,
|
|
4849
4881
|
bunnyDaemon,
|
|
@@ -5019,7 +5051,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
|
|
|
5019
5051
|
});
|
|
5020
5052
|
executionIdentity = message.executionIdentity;
|
|
5021
5053
|
} catch (error) {
|
|
5022
|
-
sendRelayError(socket, message.requestId, error);
|
|
5054
|
+
await sendRelayError(socket, message.requestId, error).catch(() => void 0);
|
|
5023
5055
|
return;
|
|
5024
5056
|
}
|
|
5025
5057
|
}
|
|
@@ -5105,7 +5137,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
|
|
|
5105
5137
|
durationMs: Date.now() - codingRunStartedAt
|
|
5106
5138
|
});
|
|
5107
5139
|
}
|
|
5108
|
-
sendRelayMessage(socket, {
|
|
5140
|
+
await sendRelayMessage(socket, {
|
|
5109
5141
|
type: "start",
|
|
5110
5142
|
requestId: message.requestId,
|
|
5111
5143
|
status: response.status,
|
|
@@ -5125,7 +5157,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
|
|
|
5125
5157
|
while (true) {
|
|
5126
5158
|
const { value, done } = await reader.read();
|
|
5127
5159
|
if (done) break;
|
|
5128
|
-
sendRelayMessage(socket, {
|
|
5160
|
+
await sendRelayMessage(socket, {
|
|
5129
5161
|
type: "chunk",
|
|
5130
5162
|
requestId: message.requestId,
|
|
5131
5163
|
data: binaryResponse ? Buffer.from(value).toString("base64") : decoder?.decode(value, { stream: true }) ?? "",
|
|
@@ -5134,7 +5166,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
|
|
|
5134
5166
|
}
|
|
5135
5167
|
const tail = decoder?.decode() ?? "";
|
|
5136
5168
|
if (tail) {
|
|
5137
|
-
sendRelayMessage(socket, {
|
|
5169
|
+
await sendRelayMessage(socket, {
|
|
5138
5170
|
type: "chunk",
|
|
5139
5171
|
requestId: message.requestId,
|
|
5140
5172
|
data: tail
|
|
@@ -5145,7 +5177,7 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
|
|
|
5145
5177
|
reader.releaseLock();
|
|
5146
5178
|
}
|
|
5147
5179
|
}
|
|
5148
|
-
sendRelayMessage(socket, {
|
|
5180
|
+
await sendRelayMessage(socket, {
|
|
5149
5181
|
type: "end",
|
|
5150
5182
|
requestId: message.requestId
|
|
5151
5183
|
});
|
|
@@ -5157,14 +5189,16 @@ async function handleRelayMessage(socket, bunnyDaemon, raw, inflight, expectedCo
|
|
|
5157
5189
|
});
|
|
5158
5190
|
}
|
|
5159
5191
|
} catch (error) {
|
|
5192
|
+
controller.abort();
|
|
5160
5193
|
if (codingRunTrace && codingRunStartedAt !== void 0) {
|
|
5161
5194
|
await writeLog("error", "relay request coding run error", {
|
|
5162
5195
|
...codingRunTrace,
|
|
5163
5196
|
status: codingRunStatus,
|
|
5164
|
-
durationMs: Date.now() - codingRunStartedAt
|
|
5197
|
+
durationMs: Date.now() - codingRunStartedAt,
|
|
5198
|
+
error: formatConnectorRelayError(error)
|
|
5165
5199
|
});
|
|
5166
5200
|
}
|
|
5167
|
-
sendRelayError(socket, message.requestId, error);
|
|
5201
|
+
await sendRelayError(socket, message.requestId, error).catch(() => void 0);
|
|
5168
5202
|
} finally {
|
|
5169
5203
|
inflight.delete(message.requestId);
|
|
5170
5204
|
}
|
|
@@ -5218,17 +5252,20 @@ var normalizeWorkspaceRequest = (request, mounts) => {
|
|
|
5218
5252
|
if (!mount || relative === void 0) {
|
|
5219
5253
|
throw new ConnectorRelayProtocolError("WORKSPACE_MISMATCH");
|
|
5220
5254
|
}
|
|
5221
|
-
const
|
|
5255
|
+
const systemEnv = body.systemEnv && typeof body.systemEnv === "object" && !Array.isArray(body.systemEnv) ? body.systemEnv : {};
|
|
5256
|
+
const workspaceEnv = {
|
|
5257
|
+
BUDA_AGENT_ROOT: mounts.agent,
|
|
5258
|
+
BUDA_SPACE_ROOT: mounts.space,
|
|
5259
|
+
BUDA_SYSTEM_ROOT: mounts.system
|
|
5260
|
+
};
|
|
5222
5261
|
return {
|
|
5223
5262
|
...request,
|
|
5224
5263
|
body: {
|
|
5225
5264
|
...body,
|
|
5226
5265
|
cwd: path12.join(mount, relative),
|
|
5227
|
-
|
|
5228
|
-
...
|
|
5229
|
-
|
|
5230
|
-
BUDA_SPACE_ROOT: mounts.space,
|
|
5231
|
-
BUDA_SYSTEM_ROOT: mounts.system
|
|
5266
|
+
systemEnv: {
|
|
5267
|
+
...systemEnv,
|
|
5268
|
+
...workspaceEnv
|
|
5232
5269
|
}
|
|
5233
5270
|
}
|
|
5234
5271
|
};
|
|
@@ -5260,17 +5297,24 @@ var normalizeConnectorFilesystemRequest = (request, mounts) => {
|
|
|
5260
5297
|
}
|
|
5261
5298
|
return request;
|
|
5262
5299
|
};
|
|
5263
|
-
function sendRelayError(socket, requestId, error) {
|
|
5264
|
-
sendRelayMessage(socket, {
|
|
5300
|
+
async function sendRelayError(socket, requestId, error) {
|
|
5301
|
+
await sendRelayMessage(socket, {
|
|
5265
5302
|
type: "error",
|
|
5266
5303
|
requestId,
|
|
5267
5304
|
error: error instanceof Error ? error.message : String(error),
|
|
5268
5305
|
...error instanceof ConnectorRelayProtocolError ? { code: error.code } : {}
|
|
5269
5306
|
});
|
|
5270
5307
|
}
|
|
5271
|
-
function sendRelayMessage(socket, message) {
|
|
5272
|
-
if (socket.readyState !== WebSocket2.OPEN)
|
|
5273
|
-
|
|
5308
|
+
async function sendRelayMessage(socket, message) {
|
|
5309
|
+
if (socket.readyState !== WebSocket2.OPEN) {
|
|
5310
|
+
throw new Error(`Connector relay socket closed before ${message.type} could be sent.`);
|
|
5311
|
+
}
|
|
5312
|
+
await new Promise((resolve, reject) => {
|
|
5313
|
+
socket.send(JSON.stringify(message), (error) => {
|
|
5314
|
+
if (error) reject(error);
|
|
5315
|
+
else resolve();
|
|
5316
|
+
});
|
|
5317
|
+
});
|
|
5274
5318
|
}
|
|
5275
5319
|
function headersToRecord(headers) {
|
|
5276
5320
|
const result = {};
|