@agentrux/agentrux-openclaw-plugin 0.3.6 → 0.3.8
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/index.js +53 -59
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -286,51 +286,24 @@ function default_1(api) {
|
|
|
286
286
|
// =======================================================================
|
|
287
287
|
if (api.registrationMode !== "full")
|
|
288
288
|
return;
|
|
289
|
-
//
|
|
289
|
+
// Guard: prevent duplicate startup. Set to true only after successful start.
|
|
290
290
|
if (globalThis.__agentruxIngressStarted)
|
|
291
291
|
return;
|
|
292
|
-
globalThis.__agentruxIngressStarted = true;
|
|
293
|
-
// Clear token cache on startup to pick up latest grant scopes
|
|
294
|
-
(0, http_client_1.invalidateToken)();
|
|
295
292
|
const commandTopicId = pluginConfig.commandTopicId;
|
|
296
293
|
const resultTopicId = pluginConfig.resultTopicId;
|
|
297
294
|
const webhookSecret = pluginConfig.webhookSecret;
|
|
298
295
|
const agentId = pluginConfig.agentId;
|
|
299
|
-
|
|
296
|
+
const ingressMode = pluginConfig.ingressMode || "webhook";
|
|
300
297
|
if (!commandTopicId || !resultTopicId || !agentId) {
|
|
301
|
-
logger.info?.("[agentrux] Ingress not configured
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
const creds = (0, credentials_1.loadCredentials)();
|
|
305
|
-
if (!creds) {
|
|
306
|
-
logger.warn?.("[agentrux] No credentials found. Run agentrux_activate first. Ingress disabled.");
|
|
298
|
+
logger.info?.("[agentrux] Ingress not configured. Tools-only mode.");
|
|
307
299
|
return;
|
|
308
300
|
}
|
|
309
|
-
//
|
|
310
|
-
const cursor = (0, cursor_1.loadCursor)();
|
|
311
|
-
const queue = new queue_1.BoundedQueue(100);
|
|
312
|
-
const dispatcher = new dispatcher_1.Dispatcher({
|
|
313
|
-
commandTopicId,
|
|
314
|
-
resultTopicId,
|
|
315
|
-
agentId,
|
|
316
|
-
maxConcurrency: pluginConfig.maxConcurrency || 3,
|
|
317
|
-
subagentTimeoutMs: pluginConfig.subagentTimeoutMs || 120_000,
|
|
318
|
-
gatewayPort: 18789, // OpenClaw default gateway port
|
|
319
|
-
}, creds, cursor, queue, logger);
|
|
320
|
-
const ingressMode = pluginConfig.ingressMode || "webhook";
|
|
321
|
-
const poller = new poller_1.SafetyPoller(creds, commandTopicId, cursor, queue, pluginConfig.pollIntervalMs || 60_000, // default 60s
|
|
322
|
-
logger);
|
|
323
|
-
// SSE listener (only when ingressMode=sse)
|
|
324
|
-
const sseListener = ingressMode === "sse"
|
|
325
|
-
? new sse_listener_1.SSEListener(creds, commandTopicId, queue, logger)
|
|
326
|
-
: null;
|
|
327
|
-
// --- Internal dispatch endpoint (subagent.run() in Gateway request context) ---
|
|
301
|
+
// --- /agentrux/dispatch (called by Dispatcher via localhost) ---
|
|
328
302
|
api.registerHttpRoute({
|
|
329
303
|
path: "/agentrux/dispatch",
|
|
330
304
|
auth: "plugin",
|
|
331
305
|
match: "exact",
|
|
332
306
|
handler: async (req, res) => {
|
|
333
|
-
// Reject non-POST (e.g. HEAD from readiness probe)
|
|
334
307
|
if (req.method !== "POST") {
|
|
335
308
|
res.statusCode = 405;
|
|
336
309
|
res.setHeader("Allow", "POST");
|
|
@@ -343,7 +316,7 @@ function default_1(api) {
|
|
|
343
316
|
req.on("data", (c) => chunks.push(c));
|
|
344
317
|
req.on("end", resolve);
|
|
345
318
|
req.on("error", reject);
|
|
346
|
-
}).catch(() => { });
|
|
319
|
+
}).catch(() => { });
|
|
347
320
|
const raw = Buffer.concat(chunks).toString();
|
|
348
321
|
if (!raw) {
|
|
349
322
|
res.statusCode = 400;
|
|
@@ -362,10 +335,7 @@ function default_1(api) {
|
|
|
362
335
|
return true;
|
|
363
336
|
}
|
|
364
337
|
try {
|
|
365
|
-
// Track active session for attachment registry
|
|
366
338
|
activeSessionKey = params.sessionKey;
|
|
367
|
-
// OpenClaw 2026.3.24+: provider/model override is not authorized
|
|
368
|
-
// for plugin subagent runs. The agent's configured model is used.
|
|
369
339
|
const { runId } = await api.runtime.subagent.run({
|
|
370
340
|
sessionKey: params.sessionKey,
|
|
371
341
|
message: params.message,
|
|
@@ -374,8 +344,7 @@ function default_1(api) {
|
|
|
374
344
|
...(params.extraSystemPrompt ? { extraSystemPrompt: params.extraSystemPrompt } : {}),
|
|
375
345
|
});
|
|
376
346
|
const waitResult = await api.runtime.subagent.waitForRun({
|
|
377
|
-
runId,
|
|
378
|
-
timeoutMs: params.timeoutMs || 60_000,
|
|
347
|
+
runId, timeoutMs: params.timeoutMs || 60_000,
|
|
379
348
|
});
|
|
380
349
|
let responseText = "";
|
|
381
350
|
if (waitResult.status === "ok") {
|
|
@@ -391,10 +360,8 @@ function default_1(api) {
|
|
|
391
360
|
}
|
|
392
361
|
}
|
|
393
362
|
else {
|
|
394
|
-
// Subagent failed (rate limit, timeout, etc.) — include reason in response
|
|
395
363
|
responseText = waitResult.error || waitResult.message || `Agent failed: ${waitResult.status}`;
|
|
396
364
|
}
|
|
397
|
-
// Collect attachments uploaded during this run
|
|
398
365
|
const attachments = consumeAttachments(params.sessionKey);
|
|
399
366
|
activeSessionKey = null;
|
|
400
367
|
res.statusCode = 200;
|
|
@@ -411,31 +378,58 @@ function default_1(api) {
|
|
|
411
378
|
return true;
|
|
412
379
|
},
|
|
413
380
|
});
|
|
414
|
-
// ---
|
|
415
|
-
if (ingressMode === "webhook" && webhookSecret) {
|
|
416
|
-
api.registerHttpRoute({
|
|
417
|
-
path: "/agentrux/webhook",
|
|
418
|
-
auth: "plugin",
|
|
419
|
-
match: "exact",
|
|
420
|
-
handler: (0, webhook_handler_1.createWebhookHandler)(queue, webhookSecret, commandTopicId),
|
|
421
|
-
});
|
|
422
|
-
logger.info?.("[agentrux] Webhook endpoint registered: /agentrux/webhook");
|
|
423
|
-
}
|
|
424
|
-
else if (ingressMode === "webhook" && !webhookSecret) {
|
|
425
|
-
logger.warn?.("[agentrux] ingressMode=webhook but webhookSecret not set. Falling back to poll-only.");
|
|
426
|
-
}
|
|
427
|
-
// --- Start Dispatcher + (Webhook|SSE) + Poller ---
|
|
428
|
-
// Gateway readiness probe: wait until /health responds.
|
|
429
|
-
// Even if /health comes up before plugin routes, the transport retry
|
|
430
|
-
// in callDispatchEndpoint (3 attempts, 2s/4s backoff) covers the gap.
|
|
381
|
+
// --- Async startup: credentials → construct → start ---
|
|
431
382
|
(async () => {
|
|
432
383
|
try {
|
|
384
|
+
// 1. Credentials: load or auto-activate
|
|
385
|
+
(0, http_client_1.invalidateToken)();
|
|
386
|
+
let creds = (0, credentials_1.loadCredentials)();
|
|
387
|
+
if (!creds) {
|
|
388
|
+
const activationCode = pluginConfig.activationCode;
|
|
389
|
+
if (!activationCode) {
|
|
390
|
+
logger.warn?.("[agentrux] No credentials and no activationCode. Ingress disabled.");
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
logger.info?.("[agentrux] Auto-activating...");
|
|
394
|
+
const baseUrl = pluginConfig.baseUrl || "https://api.agentrux.com";
|
|
395
|
+
const r = await (0, http_client_1.httpJson)("POST", `${baseUrl}/auth/activate`, { activation_code: activationCode });
|
|
396
|
+
if (r.status !== 200 || !r.data.script_id) {
|
|
397
|
+
logger.error?.(`[agentrux] Auto-activation failed (HTTP ${r.status}): ${JSON.stringify(r.data)}`);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
creds = { base_url: baseUrl, script_id: r.data.script_id, clientSecret: r.data.client_secret };
|
|
401
|
+
(0, credentials_1.saveCredentials)(creds);
|
|
402
|
+
credentials = creds;
|
|
403
|
+
logger.info?.(`[agentrux] Activated: script_id=${r.data.script_id}`);
|
|
404
|
+
}
|
|
405
|
+
// 2. Construct
|
|
406
|
+
const cursor = (0, cursor_1.loadCursor)();
|
|
407
|
+
const queue = new queue_1.BoundedQueue(100);
|
|
408
|
+
const dispatcher = new dispatcher_1.Dispatcher({
|
|
409
|
+
commandTopicId, resultTopicId, agentId,
|
|
410
|
+
maxConcurrency: pluginConfig.maxConcurrency || 3,
|
|
411
|
+
subagentTimeoutMs: pluginConfig.subagentTimeoutMs || 120_000,
|
|
412
|
+
gatewayPort: 18789,
|
|
413
|
+
publishProcessingStatus: !!pluginConfig.publishProcessingStatus,
|
|
414
|
+
}, creds, cursor, queue, logger);
|
|
415
|
+
const poller = new poller_1.SafetyPoller(creds, commandTopicId, cursor, queue, pluginConfig.pollIntervalMs || 60_000, logger);
|
|
416
|
+
const sseListener = ingressMode === "sse"
|
|
417
|
+
? new sse_listener_1.SSEListener(creds, commandTopicId, queue, logger) : null;
|
|
418
|
+
// Webhook (only if configured)
|
|
419
|
+
if (ingressMode === "webhook" && webhookSecret) {
|
|
420
|
+
api.registerHttpRoute({
|
|
421
|
+
path: "/agentrux/webhook", auth: "plugin", match: "exact",
|
|
422
|
+
handler: (0, webhook_handler_1.createWebhookHandler)(queue, webhookSecret, commandTopicId),
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
// 3. Wait for Gateway
|
|
433
426
|
await waitForGateway(18789, 30_000, logger);
|
|
427
|
+
// 4. Start
|
|
434
428
|
dispatcher.start().catch((e) => logger.error("[agentrux] Dispatcher failed:", e));
|
|
435
|
-
if (sseListener)
|
|
429
|
+
if (sseListener)
|
|
436
430
|
sseListener.start().catch((e) => logger.error("[agentrux] SSE failed:", e));
|
|
437
|
-
}
|
|
438
431
|
poller.start().catch((e) => logger.error("[agentrux] Poller failed:", e));
|
|
432
|
+
globalThis.__agentruxIngressStarted = true;
|
|
439
433
|
logger.info(`[agentrux] Ingress started: mode=${ingressMode} topic=${commandTopicId} agent=${agentId} poll@${pluginConfig.pollIntervalMs || 60000}ms`);
|
|
440
434
|
}
|
|
441
435
|
catch (e) {
|
|
@@ -460,5 +454,5 @@ async function waitForGateway(port, timeoutMs, logger) {
|
|
|
460
454
|
await new Promise((r) => setTimeout(r, 2000));
|
|
461
455
|
}
|
|
462
456
|
}
|
|
463
|
-
logger.warn("[agentrux] Gateway readiness timeout — starting
|
|
457
|
+
logger.warn("[agentrux] Gateway readiness timeout — starting anyway");
|
|
464
458
|
}
|