@agentrux/agentrux-openclaw-plugin 0.3.6 → 0.3.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.
Files changed (2) hide show
  1. package/dist/index.js +53 -59
  2. 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
- // Prevent multiple ingress starts (plugin loaded multiple times by OpenClaw)
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
- // Skip ingress if not configured
296
+ const ingressMode = pluginConfig.ingressMode || "webhook";
300
297
  if (!commandTopicId || !resultTopicId || !agentId) {
301
- logger.info?.("[agentrux] Ingress not configured (missing commandTopicId/resultTopicId/agentId). Tools-only mode.");
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
- // Initialize components
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(() => { }); // aborted/truncated request → empty body → 400 below
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
- // --- Webhook endpoint (only when ingressMode=webhook) ---
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 Dispatcher anyway");
457
+ logger.warn("[agentrux] Gateway readiness timeout — starting anyway");
464
458
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentrux/agentrux-openclaw-plugin",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "description": "OpenClaw plugin for AgenTrux — Agent-to-Agent authenticated Pub/Sub",
5
5
  "keywords": [
6
6
  "openclaw",