@remcp/remcp 0.2.48 → 0.2.50
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/package.json +1 -1
- package/src/agent.mjs +27 -0
package/package.json
CHANGED
package/src/agent.mjs
CHANGED
|
@@ -36,6 +36,8 @@ const RUNTIME_STDIO_BUFFER_BYTES = 24 * 1024 * 1024;
|
|
|
36
36
|
const RECONNECT_MAX_MS = 60_000;
|
|
37
37
|
const RUNTIME_RESTART_BASE_MS = 1_000;
|
|
38
38
|
const RUNTIME_RESTART_MAX_MS = 30_000;
|
|
39
|
+
const RUNTIME_TOOLS_RETRY_BASE_MS = 1_000;
|
|
40
|
+
const RUNTIME_TOOLS_RETRY_MAX_MS = 30_000;
|
|
39
41
|
// Below the relay's RPC timeout so the model gets a real error instead of a client-side
|
|
40
42
|
// timeout while the device keeps working invisibly.
|
|
41
43
|
const CALL_TIMEOUT_MARGIN_MS = 10_000;
|
|
@@ -109,6 +111,8 @@ export async function runAgent(options) {
|
|
|
109
111
|
let transport = null;
|
|
110
112
|
let runtimeRestartDelay = RUNTIME_RESTART_BASE_MS;
|
|
111
113
|
let runtimeRestartTimer = null;
|
|
114
|
+
let runtimeToolsRetryDelay = RUNTIME_TOOLS_RETRY_BASE_MS;
|
|
115
|
+
let runtimeToolsRetryTimer = null;
|
|
112
116
|
let stopPromise = null;
|
|
113
117
|
|
|
114
118
|
function runtimeEnv() {
|
|
@@ -125,16 +129,31 @@ export async function runAgent(options) {
|
|
|
125
129
|
return [...new Set(tools.map(tool => String(tool?.name || '').trim().slice(0, 128)).filter(Boolean))].slice(0, 256);
|
|
126
130
|
}
|
|
127
131
|
|
|
132
|
+
function scheduleRuntimeToolsRetry(client) {
|
|
133
|
+
if (stopping || runtimeDown || mcp !== client || runtimeToolsRetryTimer) return;
|
|
134
|
+
const delay = jitter(runtimeToolsRetryDelay);
|
|
135
|
+
runtimeToolsRetryDelay = Math.min(RUNTIME_TOOLS_RETRY_MAX_MS, runtimeToolsRetryDelay * 2);
|
|
136
|
+
runtimeToolsRetryTimer = setTimeout(() => {
|
|
137
|
+
runtimeToolsRetryTimer = null;
|
|
138
|
+
void refreshRuntimeTools(client);
|
|
139
|
+
}, delay);
|
|
140
|
+
runtimeToolsRetryTimer.unref?.();
|
|
141
|
+
}
|
|
142
|
+
|
|
128
143
|
async function refreshRuntimeTools(client = mcp, { announce = true } = {}) {
|
|
129
144
|
if (!client || runtimeDown) return runtimeTools;
|
|
130
145
|
try {
|
|
131
146
|
const listed = await client.listTools(undefined, { timeout: 3000 });
|
|
147
|
+
if (runtimeToolsRetryTimer) clearTimeout(runtimeToolsRetryTimer);
|
|
148
|
+
runtimeToolsRetryTimer = null;
|
|
149
|
+
runtimeToolsRetryDelay = RUNTIME_TOOLS_RETRY_BASE_MS;
|
|
132
150
|
const next = toolNames(listed);
|
|
133
151
|
if (next.length === runtimeTools.length && next.every((name, index) => name === runtimeTools[index])) return runtimeTools;
|
|
134
152
|
runtimeTools = next;
|
|
135
153
|
if (announce) send({ type: 'capabilities', runtimeTools });
|
|
136
154
|
} catch (error) {
|
|
137
155
|
console.error(`ReMCP could not refresh runtime capabilities: ${error instanceof Error ? error.message : String(error)}`);
|
|
156
|
+
scheduleRuntimeToolsRetry(client);
|
|
138
157
|
}
|
|
139
158
|
return runtimeTools;
|
|
140
159
|
}
|
|
@@ -143,6 +162,9 @@ export async function runAgent(options) {
|
|
|
143
162
|
if (stopping) return;
|
|
144
163
|
clearTimeout(runtimeRestartTimer);
|
|
145
164
|
runtimeRestartTimer = null;
|
|
165
|
+
if (runtimeToolsRetryTimer) clearTimeout(runtimeToolsRetryTimer);
|
|
166
|
+
runtimeToolsRetryTimer = null;
|
|
167
|
+
runtimeToolsRetryDelay = RUNTIME_TOOLS_RETRY_BASE_MS;
|
|
146
168
|
runtimeDown = true;
|
|
147
169
|
const previous = mcp;
|
|
148
170
|
mcp = null;
|
|
@@ -197,6 +219,9 @@ export async function runAgent(options) {
|
|
|
197
219
|
|
|
198
220
|
function handleRuntimeExit(reason) {
|
|
199
221
|
if (stopping || runtimeRestartTimer) return;
|
|
222
|
+
if (runtimeToolsRetryTimer) clearTimeout(runtimeToolsRetryTimer);
|
|
223
|
+
runtimeToolsRetryTimer = null;
|
|
224
|
+
runtimeToolsRetryDelay = RUNTIME_TOOLS_RETRY_BASE_MS;
|
|
200
225
|
runtimeDown = true;
|
|
201
226
|
runtimeTools = [];
|
|
202
227
|
send({ type: 'capabilities', runtimeTools });
|
|
@@ -520,6 +545,8 @@ export async function runAgent(options) {
|
|
|
520
545
|
if (stopPromise) return stopPromise;
|
|
521
546
|
stopping = true;
|
|
522
547
|
clearTimeout(runtimeRestartTimer);
|
|
548
|
+
clearTimeout(runtimeToolsRetryTimer);
|
|
549
|
+
runtimeToolsRetryTimer = null;
|
|
523
550
|
clearTimeout(reconnectTimer);
|
|
524
551
|
reconnectTimer = null;
|
|
525
552
|
if (telemetryTimer) clearInterval(telemetryTimer);
|