aamp-openclaw-plugin 0.1.14 → 0.1.16

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.
@@ -175,6 +175,28 @@ function restartGateway() {
175
175
  }
176
176
  }
177
177
 
178
+ async function fetchJson(url, init, stepLabel) {
179
+ let res
180
+ try {
181
+ res = await fetch(url, init)
182
+ } catch (error) {
183
+ const message = error instanceof Error ? error.message : String(error)
184
+ throw new Error(`${stepLabel} failed for ${url}: ${message}`)
185
+ }
186
+
187
+ if (!res.ok) {
188
+ const text = await res.text().catch(() => '')
189
+ throw new Error(`${stepLabel} failed (${res.status}) for ${url}: ${text || res.statusText}`)
190
+ }
191
+
192
+ try {
193
+ return await res.json()
194
+ } catch (error) {
195
+ const message = error instanceof Error ? error.message : String(error)
196
+ throw new Error(`${stepLabel} returned invalid JSON for ${url}: ${message}`)
197
+ }
198
+ }
199
+
178
200
  async function ensureMailboxIdentity({ aampHost, slug, credentialsFile }) {
179
201
  const resolvedCreds = expandHome(credentialsFile)
180
202
  if (existsSync(resolvedCreds)) {
@@ -182,33 +204,30 @@ async function ensureMailboxIdentity({ aampHost, slug, credentialsFile }) {
182
204
  }
183
205
 
184
206
  const base = normalizeBaseUrl(aampHost)
185
- const registerRes = await fetch(`${base}/api/nodes/self-register`, {
186
- method: 'POST',
187
- headers: { 'Content-Type': 'application/json' },
188
- body: JSON.stringify({
189
- slug,
190
- description: 'OpenClaw AAMP agent node',
191
- }),
192
- })
193
-
194
- if (!registerRes.ok) {
195
- const text = await registerRes.text().catch(() => '')
196
- throw new Error(`AAMP self-register failed (${registerRes.status}): ${text || registerRes.statusText}`)
197
- }
198
-
199
- const registerData = await registerRes.json()
207
+ const registerUrl = `${base}/api/nodes/self-register`
208
+ const registerData = await fetchJson(
209
+ registerUrl,
210
+ {
211
+ method: 'POST',
212
+ headers: { 'Content-Type': 'application/json' },
213
+ body: JSON.stringify({
214
+ slug,
215
+ description: 'OpenClaw AAMP agent node',
216
+ }),
217
+ },
218
+ 'AAMP self-register',
219
+ )
200
220
  const code = registerData?.registrationCode
201
221
  if (!code) {
202
222
  throw new Error('AAMP self-register succeeded but no registrationCode was returned')
203
223
  }
204
224
 
205
- const credRes = await fetch(`${base}/api/nodes/credentials?code=${encodeURIComponent(code)}`)
206
- if (!credRes.ok) {
207
- const text = await credRes.text().catch(() => '')
208
- throw new Error(`AAMP credential exchange failed (${credRes.status}): ${text || credRes.statusText}`)
209
- }
210
-
211
- const credData = await credRes.json()
225
+ const credUrl = `${base}/api/nodes/credentials?code=${encodeURIComponent(code)}`
226
+ const credData = await fetchJson(
227
+ credUrl,
228
+ undefined,
229
+ 'AAMP credential exchange',
230
+ )
212
231
  const identity = {
213
232
  email: credData?.email,
214
233
  jmapToken: credData?.jmap?.token,
package/dist/index.js CHANGED
@@ -16222,6 +16222,9 @@ var transportMonitorTimer = null;
16222
16222
  var currentSessionKey = "agent:main:main";
16223
16223
  var channelRuntime = null;
16224
16224
  var channelCfg = null;
16225
+ function dispatchSessionKey() {
16226
+ return currentSessionKey || "agent:main:main";
16227
+ }
16225
16228
  function logTransportState(api, mode, email, previousMode) {
16226
16229
  if (mode === previousMode)
16227
16230
  return;
@@ -16352,10 +16355,11 @@ var src_default = {
16352
16355
  }
16353
16356
  }
16354
16357
  function wakeAgentForPendingTask(task) {
16355
- const fallback = () => triggerHeartbeatWake(currentSessionKey, `task ${task.taskId}`);
16358
+ const sessionKey = dispatchSessionKey();
16359
+ const fallback = () => triggerHeartbeatWake(sessionKey, `task ${task.taskId}`);
16356
16360
  const dispatcher = channelRuntime?.reply?.dispatchReplyWithBufferedBlockDispatcher;
16357
16361
  api.logger.info(
16358
- `[AAMP] Wake requested for task ${task.taskId} \u2014 channelRuntime=${channelRuntime ? "yes" : "no"} channelCfg=${channelCfg ? "yes" : "no"} dispatcher=${typeof dispatcher === "function" ? "yes" : "no"} session=${currentSessionKey}`
16362
+ `[AAMP] Wake requested for task ${task.taskId} \u2014 channelRuntime=${channelRuntime ? "yes" : "no"} channelCfg=${channelCfg ? "yes" : "no"} dispatcher=${typeof dispatcher === "function" ? "yes" : "no"} session=${sessionKey}`
16359
16363
  );
16360
16364
  if (!channelRuntime || !channelCfg || typeof dispatcher !== "function") {
16361
16365
  fallback();
@@ -16369,13 +16373,24 @@ var src_default = {
16369
16373
  "Reply with aamp_send_result or aamp_send_help before responding."
16370
16374
  ].join("\n");
16371
16375
  try {
16376
+ const startedAt = Date.now();
16377
+ let settled = false;
16378
+ const fallbackTimer = setTimeout(() => {
16379
+ if (settled || !pendingTasks.has(task.taskId))
16380
+ return;
16381
+ api.logger.warn(
16382
+ `[AAMP] Channel dispatch still pending after ${Date.now() - startedAt}ms for task ${task.taskId} \u2014 triggering heartbeat fallback`
16383
+ );
16384
+ fallback();
16385
+ }, 2e3);
16386
+ api.logger.info(`[AAMP] Channel dispatch starting for task ${task.taskId}`);
16372
16387
  void Promise.resolve(dispatcher({
16373
16388
  ctx: {
16374
16389
  Body: task.bodyText || task.title,
16375
16390
  BodyForAgent: prompt,
16376
16391
  From: task.from,
16377
16392
  To: agentEmail,
16378
- SessionKey: `aamp:default:task:${task.taskId}`,
16393
+ SessionKey: sessionKey,
16379
16394
  AccountId: "default",
16380
16395
  ChatType: "dm",
16381
16396
  Provider: "aamp",
@@ -16397,8 +16412,14 @@ var src_default = {
16397
16412
  }
16398
16413
  }
16399
16414
  })).then(() => {
16400
- api.logger.info(`[AAMP] Channel dispatch triggered for task ${task.taskId}`);
16415
+ settled = true;
16416
+ clearTimeout(fallbackTimer);
16417
+ api.logger.info(
16418
+ `[AAMP] Channel dispatch triggered for task ${task.taskId} after ${Date.now() - startedAt}ms`
16419
+ );
16401
16420
  }).catch((err) => {
16421
+ settled = true;
16422
+ clearTimeout(fallbackTimer);
16402
16423
  api.logger.error(`[AAMP] Channel dispatch failed for task ${task.taskId}: ${err.message}`);
16403
16424
  fallback();
16404
16425
  });
@@ -16555,7 +16576,7 @@ ${notifyBody?.bodyText ?? "Sub-task completed."}${actionSection}`;
16555
16576
  BodyForAgent: prompt,
16556
16577
  From: result.from,
16557
16578
  To: agentEmail,
16558
- SessionKey: `aamp:default:${result.from}`,
16579
+ SessionKey: dispatchSessionKey(),
16559
16580
  AccountId: "default",
16560
16581
  ChatType: "dm",
16561
16582
  Provider: "aamp",
@@ -16630,7 +16651,7 @@ ${notifyBody?.bodyText ?? help.question}`;
16630
16651
  BodyForAgent: prompt,
16631
16652
  From: help.from,
16632
16653
  To: agentEmail,
16633
- SessionKey: `aamp:default:${help.from}`,
16654
+ SessionKey: dispatchSessionKey(),
16634
16655
  AccountId: "default",
16635
16656
  ChatType: "dm",
16636
16657
  Provider: "aamp",
@@ -16676,6 +16697,10 @@ ${notifyBody?.bodyText ?? help.question}`;
16676
16697
  });
16677
16698
  aampClient.on("disconnected", (reason) => {
16678
16699
  lastDisconnectReason = reason;
16700
+ if (aampClient?.isUsingPollingFallback()) {
16701
+ lastTransportMode = "polling";
16702
+ return;
16703
+ }
16679
16704
  if (lastTransportMode !== "disconnected") {
16680
16705
  api.logger.warn(`[AAMP] Disconnected: ${reason} (will auto-reconnect)`);
16681
16706
  lastTransportMode = "disconnected";