robot-resources 1.7.5 → 1.7.7
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/lib/tool-config.js +38 -17
- package/lib/wizard.js +11 -13
- package/package.json +1 -1
package/lib/tool-config.js
CHANGED
|
@@ -221,27 +221,48 @@ export function configureToolRouting() {
|
|
|
221
221
|
return results;
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Run a command with a heartbeat to keep agent sessions alive.
|
|
226
|
+
* OC kills processes after 5s of no output (noOutputTimeoutMs = 5000).
|
|
227
|
+
* Prints immediately, then every 4s (safely under the 5s threshold).
|
|
228
|
+
*/
|
|
229
|
+
function spawnWithHeartbeat(cmd, args, { label, timeout = 30_000 } = {}) {
|
|
230
|
+
return new Promise((resolve, reject) => {
|
|
231
|
+
const proc = spawn(cmd, args, {
|
|
232
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
233
|
+
timeout,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
process.stdout.write(` ${label}...\n`);
|
|
237
|
+
let seconds = 0;
|
|
238
|
+
const heartbeat = setInterval(() => {
|
|
239
|
+
seconds += 4;
|
|
240
|
+
process.stdout.write(` ${label}... ${seconds}s\n`);
|
|
241
|
+
}, 4000);
|
|
242
|
+
|
|
243
|
+
proc.on('close', (code) => {
|
|
244
|
+
clearInterval(heartbeat);
|
|
245
|
+
if (code === 0) resolve();
|
|
246
|
+
else reject(new Error(`${cmd} ${args.join(' ')} exited with code ${code}`));
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
proc.on('error', (err) => {
|
|
250
|
+
clearInterval(heartbeat);
|
|
251
|
+
reject(err);
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
224
256
|
/**
|
|
225
257
|
* Restart the OpenClaw gateway so it picks up new plugin + config.
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
* follow-up before the gateway dies.
|
|
229
|
-
*
|
|
230
|
-
* Why deferred: a synchronous restart kills the OC session before the
|
|
231
|
-
* install report is captured. The 30s window gives the agent time to
|
|
232
|
-
* respond and handle a follow-up message. After the restart, the next
|
|
233
|
-
* conversation loads the plugin and routing is active.
|
|
234
|
-
*
|
|
235
|
-
* History: PR #89 used synchronous await (worked but required user to
|
|
236
|
-
* ask for updates). Session #26 used 5s delay (too short — killed
|
|
237
|
-
* session mid-conversation). 30s balances report delivery with restart.
|
|
258
|
+
* Uses heartbeat to keep OC sessions alive during the restart.
|
|
259
|
+
* Telegram survives this restart — tested end-to-end (PR #89).
|
|
238
260
|
*/
|
|
239
261
|
async function restartOpenClawGateway() {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
})
|
|
244
|
-
process.stdout.write(' Gateway restart scheduled (30s)...\n');
|
|
262
|
+
await spawnWithHeartbeat('openclaw', ['gateway', 'restart'], {
|
|
263
|
+
label: 'Restarting gateway',
|
|
264
|
+
timeout: 15_000,
|
|
265
|
+
});
|
|
245
266
|
}
|
|
246
267
|
|
|
247
268
|
// Exported for testing and direct use
|
package/lib/wizard.js
CHANGED
|
@@ -382,21 +382,19 @@ export async function runWizard({ nonInteractive = false } = {}) {
|
|
|
382
382
|
}
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
-
// ── Best-effort:
|
|
385
|
+
// ── Best-effort: Single gateway restart (MUST be last) ─────────────────
|
|
386
386
|
//
|
|
387
|
-
//
|
|
388
|
-
//
|
|
389
|
-
//
|
|
390
|
-
//
|
|
391
|
-
// exit and return output to OC before the gateway dies. Silent catch —
|
|
392
|
-
// the plugin's install message already tells the user to start a new
|
|
393
|
-
// conversation. No warn/success needed.
|
|
394
|
-
//
|
|
395
|
-
// History: PR #89 (Manuel) had this right — restart last, silent catch.
|
|
396
|
-
// Session #25 moved it earlier with 3x retries, which killed OC Telegram
|
|
397
|
-
// sessions. Reverted to deferred spawn, positioned last.
|
|
387
|
+
// Everything is already installed, configured, and reported above.
|
|
388
|
+
// The restart loads the plugin + scraper MCP into the running gateway.
|
|
389
|
+
// Telegram survives this restart. If the session dies here, the agent
|
|
390
|
+
// picks up on the next message with all tools loaded.
|
|
398
391
|
|
|
399
392
|
if (isOpenClawInstalled() && (results.tools?.some(r => r.action === 'installed') || scraperRegistered)) {
|
|
400
|
-
try {
|
|
393
|
+
try {
|
|
394
|
+
await restartOpenClawGateway();
|
|
395
|
+
success('OpenClaw gateway restarted');
|
|
396
|
+
} catch {
|
|
397
|
+
// Best-effort — gateway picks up changes on next restart
|
|
398
|
+
}
|
|
401
399
|
}
|
|
402
400
|
}
|