aamp-openclaw-plugin 0.1.33 → 0.1.34

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 CHANGED
@@ -2535,6 +2535,8 @@ function baseUrl(aampHost) {
2535
2535
  }
2536
2536
  var pendingTasks = /* @__PURE__ */ new Map();
2537
2537
  var activeTaskStreams = /* @__PURE__ */ new Map();
2538
+ var sessionTaskBindings = /* @__PURE__ */ new Map();
2539
+ var taskVisibleStreamState = /* @__PURE__ */ new Map();
2538
2540
  var terminalTaskIds = new Set(loadTaskState(defaultTaskStatePath()).terminalTaskIds ?? []);
2539
2541
  var AAMP_SESSION_PREFIX = "aamp:";
2540
2542
  var DEFAULT_OPENCLAW_AGENT_ID = "main";
@@ -2554,6 +2556,7 @@ var lastLoggedTransportMode = "disconnected";
2554
2556
  var reconcileTimer = null;
2555
2557
  var transportMonitorTimer = null;
2556
2558
  var historicalReconcileCompleted = false;
2559
+ var stopAgentEventSubscription = null;
2557
2560
  var channelRuntime = null;
2558
2561
  var channelCfg = null;
2559
2562
  async function ensureTaskStream(task) {
@@ -2702,6 +2705,80 @@ function resolvePendingKeyFromSessionKey(sessionKey) {
2702
2705
  }
2703
2706
  return void 0;
2704
2707
  }
2708
+ function normalizeBoundSessionKey(sessionKey) {
2709
+ if (typeof sessionKey !== "string")
2710
+ return void 0;
2711
+ const normalized = stripOpenClawAgentScope(sessionKey).trim();
2712
+ return normalized || void 0;
2713
+ }
2714
+ function bindSessionToTask(sessionKey, taskId) {
2715
+ const normalized = normalizeBoundSessionKey(sessionKey);
2716
+ if (!normalized)
2717
+ return;
2718
+ if (!taskId) {
2719
+ sessionTaskBindings.delete(normalized);
2720
+ return;
2721
+ }
2722
+ sessionTaskBindings.set(normalized, taskId);
2723
+ }
2724
+ function resolveStreamTaskId(sessionKey) {
2725
+ const pendingKey = resolvePendingKeyFromSessionKey(sessionKey);
2726
+ if (pendingKey && !isSyntheticPendingKey(pendingKey))
2727
+ return pendingKey;
2728
+ const normalized = normalizeBoundSessionKey(sessionKey);
2729
+ if (!normalized)
2730
+ return void 0;
2731
+ const taskId = sessionTaskBindings.get(normalized);
2732
+ if (!taskId)
2733
+ return void 0;
2734
+ if (!pendingTasks.has(taskId) && !activeTaskStreams.has(taskId)) {
2735
+ sessionTaskBindings.delete(normalized);
2736
+ return void 0;
2737
+ }
2738
+ return taskId;
2739
+ }
2740
+ function forgetTaskStreamContext(taskId) {
2741
+ taskVisibleStreamState.delete(taskId);
2742
+ for (const [sessionKey, boundTaskId] of sessionTaskBindings) {
2743
+ if (boundTaskId === taskId) {
2744
+ sessionTaskBindings.delete(sessionKey);
2745
+ }
2746
+ }
2747
+ }
2748
+ async function handleAgentVisibleTextEvent(event) {
2749
+ if (event.stream !== "assistant")
2750
+ return;
2751
+ const taskId = resolveStreamTaskId(event.sessionKey);
2752
+ if (!taskId || !activeTaskStreams.has(taskId))
2753
+ return;
2754
+ const payload = event.data && typeof event.data === "object" ? event.data : {};
2755
+ const fullText = typeof payload.text === "string" ? payload.text : void 0;
2756
+ const deltaText = typeof payload.delta === "string" ? payload.delta : void 0;
2757
+ if (!fullText && !deltaText)
2758
+ return;
2759
+ const runId = typeof event.runId === "string" && event.runId.trim() ? event.runId : "__default__";
2760
+ const previousState = taskVisibleStreamState.get(taskId);
2761
+ const previousText = previousState?.runId === runId ? previousState.text : "";
2762
+ let nextText = previousText;
2763
+ let nextDelta = "";
2764
+ if (typeof fullText === "string") {
2765
+ nextText = fullText;
2766
+ if (fullText.startsWith(previousText)) {
2767
+ nextDelta = fullText.slice(previousText.length);
2768
+ } else if (!previousText) {
2769
+ nextDelta = fullText;
2770
+ } else if (deltaText) {
2771
+ nextDelta = deltaText;
2772
+ }
2773
+ } else if (deltaText) {
2774
+ nextText = `${previousText}${deltaText}`;
2775
+ nextDelta = deltaText;
2776
+ }
2777
+ taskVisibleStreamState.set(taskId, { runId, text: nextText });
2778
+ if (!nextDelta)
2779
+ return;
2780
+ await appendTaskStream(taskId, "text.delta", { text: nextDelta });
2781
+ }
2705
2782
  function saveTerminalTaskIds() {
2706
2783
  saveTaskState({ terminalTaskIds: [...terminalTaskIds] }, defaultTaskStatePath());
2707
2784
  }
@@ -2913,6 +2990,22 @@ var src_default = {
2913
2990
  api.logger.warn(`[AAMP] Could not trigger heartbeat for ${label}: ${err.message}`);
2914
2991
  }
2915
2992
  }
2993
+ if (stopAgentEventSubscription) {
2994
+ try {
2995
+ stopAgentEventSubscription();
2996
+ } catch {
2997
+ }
2998
+ stopAgentEventSubscription = null;
2999
+ }
3000
+ const onAgentEvent = api.runtime?.events?.onAgentEvent;
3001
+ if (typeof onAgentEvent === "function") {
3002
+ const unsubscribe = onAgentEvent((event) => {
3003
+ void handleAgentVisibleTextEvent(event).catch((err) => {
3004
+ api.logger.warn(`[AAMP] Failed to mirror assistant stream: ${err.message}`);
3005
+ });
3006
+ });
3007
+ stopAgentEventSubscription = typeof unsubscribe === "function" ? unsubscribe : null;
3008
+ }
2916
3009
  function getConfiguredCardText() {
2917
3010
  const inline = cfg.cardText?.trim();
2918
3011
  if (inline)
@@ -3081,6 +3174,7 @@ var src_default = {
3081
3174
  pendingTasks.delete(`help:${cancel.taskId}`);
3082
3175
  dispatchedSubtasks.delete(cancel.taskId);
3083
3176
  waitingDispatches.delete(cancel.taskId);
3177
+ forgetTaskStreamContext(cancel.taskId);
3084
3178
  rememberTerminalTask(cancel.taskId);
3085
3179
  void closeTaskStream(cancel.taskId, { reason: "task.cancel" }).catch(() => {
3086
3180
  });
@@ -3413,6 +3507,13 @@ ${notifyBody?.bodyText ?? help.question}`;
3413
3507
  } catch {
3414
3508
  }
3415
3509
  }
3510
+ if (stopAgentEventSubscription) {
3511
+ try {
3512
+ stopAgentEventSubscription();
3513
+ } catch {
3514
+ }
3515
+ stopAgentEventSubscription = null;
3516
+ }
3416
3517
  }
3417
3518
  });
3418
3519
  api.on("gateway_start", () => {
@@ -3483,6 +3584,10 @@ ${notifyBody?.bodyText ?? help.question}`;
3483
3584
  return rankDiff;
3484
3585
  return new Date(a.receivedAt).getTime() - new Date(b.receivedAt).getTime();
3485
3586
  });
3587
+ bindSessionToTask(
3588
+ ctx?.sessionKey,
3589
+ isNotification ? actionableTasks.length === 1 ? actionableTasks[0]?.taskId : void 0 : task.taskId
3590
+ );
3486
3591
  const otherActionableTasks = actionableTasks.filter((pendingTask) => pendingTask.taskId !== task.taskId);
3487
3592
  const hasAttachmentInfo = isNotification && (task.bodyText?.includes("aamp_download_attachment") ?? false);
3488
3593
  const actionRequiredSection = isNotification && actionableTasks.length > 0 ? [
@@ -3706,14 +3811,17 @@ ${task.contextLinks.map((l) => ` - ${l}`).join("\n")}` : "",
3706
3811
  state: "completing",
3707
3812
  label: `Sending ${p.status} result`
3708
3813
  });
3709
- if (p.output) {
3710
- await appendTaskStream(task.taskId, "text.delta", { text: p.output });
3814
+ const streamedText = taskVisibleStreamState.get(task.taskId)?.text ?? "";
3815
+ const finalOutputDelta = streamedText && p.output.startsWith(streamedText) ? p.output.slice(streamedText.length) : p.output;
3816
+ if (finalOutputDelta) {
3817
+ await appendTaskStream(task.taskId, "text.delta", { text: finalOutputDelta });
3711
3818
  }
3712
3819
  await closeTaskStream(task.taskId, {
3713
3820
  reason: "task.result",
3714
3821
  status: p.status,
3715
3822
  ...p.errorMsg ? { error: p.errorMsg } : {}
3716
3823
  });
3824
+ forgetTaskStreamContext(task.taskId);
3717
3825
  await aampClient.sendResult({
3718
3826
  to: task.from,
3719
3827
  taskId: task.taskId,
@@ -3790,6 +3898,7 @@ ${task.contextLinks.map((l) => ` - ${l}`).join("\n")}` : "",
3790
3898
  await closeTaskStream(task.taskId, {
3791
3899
  reason: "task.help_needed"
3792
3900
  });
3901
+ forgetTaskStreamContext(task.taskId);
3793
3902
  await aampClient.sendHelp({
3794
3903
  to: task.from,
3795
3904
  taskId: task.taskId,