@tianshu-ai/local-bridge 0.7.0 → 0.7.2
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/connection.js +112 -7
- package/dist/connection.js.map +1 -1
- package/package.json +1 -1
package/dist/connection.js
CHANGED
|
@@ -6,7 +6,23 @@
|
|
|
6
6
|
import WebSocket from "ws";
|
|
7
7
|
import { MSG, textResult } from "./protocol.js";
|
|
8
8
|
const RECONNECT_BASE_MS = 1000;
|
|
9
|
-
|
|
9
|
+
// Capped low so a server restart (down for a few seconds) reconnects
|
|
10
|
+
// promptly instead of getting stuck on a long backoff. The first
|
|
11
|
+
// retry after a drop is immediate (see the close handler).
|
|
12
|
+
const RECONNECT_MAX_MS = 10_000;
|
|
13
|
+
// Heartbeat: proactively detect "half-open" / silently-dead sockets
|
|
14
|
+
// that never fire a `close` event (Wi-Fi switch, laptop sleep, NAT
|
|
15
|
+
// timeout, server process vanished without a TCP FIN). We send a WS
|
|
16
|
+
// ping every HEARTBEAT_MS; the server auto-replies with pong (RFC
|
|
17
|
+
// default in the `ws` lib). If we go DEAD_AFTER_MS without ANY sign of
|
|
18
|
+
// life (no pong, no message, nothing buffered to send, no tool call in
|
|
19
|
+
// flight) we consider the socket dead and terminate it — that fires
|
|
20
|
+
// `close`, which runs the normal reconnect-with-backoff path.
|
|
21
|
+
const HEARTBEAT_MS = 25_000;
|
|
22
|
+
// A socket is declared dead after ~2.5 missed heartbeats of total
|
|
23
|
+
// silence. Kept comfortably above HEARTBEAT_MS so one slow round-trip
|
|
24
|
+
// doesn't nuke a healthy link.
|
|
25
|
+
const DEAD_AFTER_MS = 65_000;
|
|
10
26
|
export class BridgeConnection {
|
|
11
27
|
opts;
|
|
12
28
|
ws = null;
|
|
@@ -14,6 +30,13 @@ export class BridgeConnection {
|
|
|
14
30
|
attempt = 0;
|
|
15
31
|
toolsByName = new Map();
|
|
16
32
|
log;
|
|
33
|
+
// Liveness tracking. `lastActivityAt` bumps on any inbound frame,
|
|
34
|
+
// pong, or successful send. `inFlight` counts tool calls currently
|
|
35
|
+
// executing — a busy connection is by definition alive + must not be
|
|
36
|
+
// torn down mid-task.
|
|
37
|
+
lastActivityAt = 0;
|
|
38
|
+
inFlight = 0;
|
|
39
|
+
heartbeatTimer = null;
|
|
17
40
|
constructor(opts) {
|
|
18
41
|
this.opts = opts;
|
|
19
42
|
this.log = opts.log ?? ((m) => console.log(m));
|
|
@@ -26,6 +49,7 @@ export class BridgeConnection {
|
|
|
26
49
|
}
|
|
27
50
|
stop() {
|
|
28
51
|
this.closed = true;
|
|
52
|
+
this.stopHeartbeat();
|
|
29
53
|
try {
|
|
30
54
|
this.ws?.send(JSON.stringify({ type: MSG.unregister }));
|
|
31
55
|
}
|
|
@@ -35,6 +59,60 @@ export class BridgeConnection {
|
|
|
35
59
|
this.ws?.close();
|
|
36
60
|
this.ws = null;
|
|
37
61
|
}
|
|
62
|
+
/** Is this connection currently doing work? True while one or more
|
|
63
|
+
* tool calls are executing, or while there are bytes still queued
|
|
64
|
+
* to send (e.g. a large tool result mid-flight). Used by the
|
|
65
|
+
* heartbeat so we never tear down a busy socket. */
|
|
66
|
+
isBusy() {
|
|
67
|
+
return this.inFlight > 0 || (this.ws?.bufferedAmount ?? 0) > 0;
|
|
68
|
+
}
|
|
69
|
+
// ── heartbeat ────────────────────────────────────────────────
|
|
70
|
+
startHeartbeat(ws) {
|
|
71
|
+
this.stopHeartbeat();
|
|
72
|
+
this.heartbeatTimer = setInterval(() => {
|
|
73
|
+
if (this.ws !== ws || ws.readyState !== WebSocket.OPEN)
|
|
74
|
+
return;
|
|
75
|
+
// A busy or recently-active socket is alive by definition —
|
|
76
|
+
// don't judge it dead, just keep pinging.
|
|
77
|
+
const silentFor = Date.now() - this.lastActivityAt;
|
|
78
|
+
if (silentFor >= DEAD_AFTER_MS && !this.isBusy()) {
|
|
79
|
+
this.log(`no response for ${Math.round(silentFor / 1000)}s — assuming dead link, forcing reconnect`);
|
|
80
|
+
// terminate() (not close()) drops a half-open socket
|
|
81
|
+
// immediately; the 'close' handler then runs reconnect.
|
|
82
|
+
try {
|
|
83
|
+
ws.terminate();
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
/* ignore */
|
|
87
|
+
}
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
// Otherwise probe: server auto-pongs, bumping lastActivityAt.
|
|
91
|
+
try {
|
|
92
|
+
ws.ping();
|
|
93
|
+
this.log(`heartbeat: ping (silent ${Math.round(silentFor / 1000)}s, busy=${this.isBusy()})`);
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
// A failed ping means the socket is already broken; force it
|
|
97
|
+
// through the close/reconnect path rather than waiting.
|
|
98
|
+
this.log(`heartbeat: ping failed (${err instanceof Error ? err.message : String(err)}), terminating`);
|
|
99
|
+
try {
|
|
100
|
+
ws.terminate();
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
/* ignore */
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}, HEARTBEAT_MS);
|
|
107
|
+
// Don't let the heartbeat keep the process alive on its own.
|
|
108
|
+
this.heartbeatTimer.unref?.();
|
|
109
|
+
}
|
|
110
|
+
stopHeartbeat() {
|
|
111
|
+
if (this.heartbeatTimer) {
|
|
112
|
+
clearInterval(this.heartbeatTimer);
|
|
113
|
+
this.heartbeatTimer = null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
38
116
|
connect() {
|
|
39
117
|
const headers = {};
|
|
40
118
|
if (this.opts.token)
|
|
@@ -43,7 +121,8 @@ export class BridgeConnection {
|
|
|
43
121
|
this.ws = ws;
|
|
44
122
|
ws.on("open", () => {
|
|
45
123
|
this.attempt = 0;
|
|
46
|
-
this.
|
|
124
|
+
this.lastActivityAt = Date.now();
|
|
125
|
+
this.log(`connected to ${this.opts.server} (heartbeat ${HEARTBEAT_MS / 1000}s, dead-after ${DEAD_AFTER_MS / 1000}s)`);
|
|
47
126
|
const reg = {
|
|
48
127
|
type: MSG.register,
|
|
49
128
|
deviceId: this.opts.deviceId,
|
|
@@ -51,8 +130,15 @@ export class BridgeConnection {
|
|
|
51
130
|
tools: this.opts.tools.map((t) => t.descriptor),
|
|
52
131
|
};
|
|
53
132
|
ws.send(JSON.stringify(reg));
|
|
133
|
+
this.startHeartbeat(ws);
|
|
134
|
+
});
|
|
135
|
+
// Any pong is a sign of life. (Server auto-pongs our pings.)
|
|
136
|
+
ws.on("pong", () => {
|
|
137
|
+
this.lastActivityAt = Date.now();
|
|
138
|
+
this.log("heartbeat: pong");
|
|
54
139
|
});
|
|
55
140
|
ws.on("message", (raw) => {
|
|
141
|
+
this.lastActivityAt = Date.now();
|
|
56
142
|
let msg;
|
|
57
143
|
try {
|
|
58
144
|
msg = JSON.parse(raw.toString());
|
|
@@ -77,13 +163,24 @@ export class BridgeConnection {
|
|
|
77
163
|
break;
|
|
78
164
|
}
|
|
79
165
|
});
|
|
80
|
-
ws.on("close", () => {
|
|
166
|
+
ws.on("close", (code, reason) => {
|
|
167
|
+
this.stopHeartbeat();
|
|
81
168
|
this.ws = null;
|
|
82
|
-
|
|
169
|
+
const why = `code=${code}${reason?.length ? ` reason=${reason.toString()}` : ""}`;
|
|
170
|
+
if (this.closed) {
|
|
171
|
+
this.log(`socket closed after stop (${why})`);
|
|
83
172
|
return;
|
|
84
|
-
|
|
173
|
+
}
|
|
174
|
+
// First retry after a drop is immediate — a server restart is
|
|
175
|
+
// usually back within a second, and waiting a full backoff step
|
|
176
|
+
// feels like "it didn't reconnect". Subsequent retries back off.
|
|
177
|
+
const delay = this.attempt === 0
|
|
178
|
+
? 0
|
|
179
|
+
: Math.min(RECONNECT_BASE_MS * 2 ** this.attempt, RECONNECT_MAX_MS);
|
|
85
180
|
this.attempt++;
|
|
86
|
-
this.log(
|
|
181
|
+
this.log(delay === 0
|
|
182
|
+
? `disconnected (${why}); reconnecting now`
|
|
183
|
+
: `disconnected (${why}); reconnecting in ${Math.round(delay / 1000)}s`);
|
|
87
184
|
setTimeout(() => {
|
|
88
185
|
if (!this.closed)
|
|
89
186
|
this.connect();
|
|
@@ -93,7 +190,7 @@ export class BridgeConnection {
|
|
|
93
190
|
const e = err;
|
|
94
191
|
const detail = [e.code, e.message].filter(Boolean).join(" ") ||
|
|
95
192
|
(err ? String(err) : "unknown (connection refused / handshake rejected?)");
|
|
96
|
-
this.log(`socket error
|
|
193
|
+
this.log(`socket error: ${detail}`);
|
|
97
194
|
});
|
|
98
195
|
// Surface non-101 handshake responses (auth/path problems), which
|
|
99
196
|
// otherwise arrive as an opaque error.
|
|
@@ -121,6 +218,10 @@ export class BridgeConnection {
|
|
|
121
218
|
this.send({ type: MSG.response, id: req.id, error: { code: -32602, message: `unknown tool: ${params.name}` } });
|
|
122
219
|
return;
|
|
123
220
|
}
|
|
221
|
+
// Mark the connection busy for the duration of the tool call so
|
|
222
|
+
// the heartbeat never tears it down mid-task (a slow tool =
|
|
223
|
+
// silence on the wire, but the link is fine).
|
|
224
|
+
this.inFlight += 1;
|
|
124
225
|
try {
|
|
125
226
|
const result = await tool.run(params.arguments ?? {});
|
|
126
227
|
this.send({ type: MSG.response, id: req.id, result });
|
|
@@ -132,6 +233,10 @@ export class BridgeConnection {
|
|
|
132
233
|
result: textResult(`tool "${params.name}" failed: ${err instanceof Error ? err.message : String(err)}`, true),
|
|
133
234
|
});
|
|
134
235
|
}
|
|
236
|
+
finally {
|
|
237
|
+
this.inFlight = Math.max(0, this.inFlight - 1);
|
|
238
|
+
this.lastActivityAt = Date.now();
|
|
239
|
+
}
|
|
135
240
|
}
|
|
136
241
|
}
|
|
137
242
|
//# sourceMappingURL=connection.js.map
|
package/dist/connection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,EAAE;AACF,0EAA0E;AAC1E,mEAAmE;AACnE,2DAA2D;AAE3D,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EAAE,GAAG,EAAE,UAAU,EAAuE,MAAM,eAAe,CAAC;AAWrH,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC,MAAM,OAAO,gBAAgB;
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tianshu-ai/local-bridge",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"description": "Local bridge for tianshu — dial into a tianshu server over WebSocket and expose your machine's tools (browser, files, shell) to the agent via reverse-MCP.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|