@agentconnect.md/daemon 1.0.0-rc.129 → 1.0.0-rc.130

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
@@ -81633,6 +81633,46 @@ function clampTo(s, max) {
81633
81633
  function clampLabel(s) {
81634
81634
  return clampTo(s, MAX_LABEL);
81635
81635
  }
81636
+ /** Wrap tool activity (a command line, tool title, or tool output) in a CommonMark code
81637
+ * span so it renders monospace and verbatim — Slack posts these as `markdown` blocks, so
81638
+ * unwrapped text with `*` / `_` / `#` would otherwise be interpreted as emphasis. A
81639
+ * single-line value uses an inline span, multi-line (or `block`-forced) a fenced block;
81640
+ * the delimiter is grown past the longest internal backtick run so values containing
81641
+ * backticks stay intact (CommonMark's variable-length fence rule). */
81642
+ function codeSpan(s, block = false) {
81643
+ const text = s.trim();
81644
+ if (!text) return "";
81645
+ const longestRun = Math.max(0, ...[...text.matchAll(/`+/g)].map((m) => m[0].length));
81646
+ if (block || text.includes("\n")) {
81647
+ const fence = "`".repeat(Math.max(3, longestRun + 1));
81648
+ return `${fence}\n${text}\n${fence}`;
81649
+ }
81650
+ const ticks = "`".repeat(longestRun + 1);
81651
+ const pad = text.startsWith("`") || text.endsWith("`") ? " " : "";
81652
+ return `${ticks}${pad}${text}${pad}${ticks}`;
81653
+ }
81654
+ const MAX_TOOL_OUTPUT = 2800;
81655
+ function capOutput(s) {
81656
+ const t = s.trim();
81657
+ return t.length > MAX_TOOL_OUTPUT ? `${t.slice(0, MAX_TOOL_OUTPUT - 1)}…` : t;
81658
+ }
81659
+ /** Pull human-readable output text out of an ACP tool_call/_update. Prefers the `content[]`
81660
+ * text blocks (the tool's reported output); falls back to a string `rawOutput`. diff /
81661
+ * terminal blocks and non-string rawOutput are skipped — they have no compact inline text. */
81662
+ function extractToolOutput(update) {
81663
+ const content = update.content;
81664
+ if (Array.isArray(content)) {
81665
+ const parts = [];
81666
+ for (const item of content) {
81667
+ if (!item || typeof item !== "object") continue;
81668
+ if (item.type !== "content") continue;
81669
+ const block = item.content;
81670
+ if (block?.type === "text" && block.text) parts.push(block.text);
81671
+ }
81672
+ if (parts.length) return parts.join("\n").trim();
81673
+ }
81674
+ return typeof update.rawOutput === "string" ? update.rawOutput.trim() : "";
81675
+ }
81636
81676
  function planIcon(status) {
81637
81677
  if (status === "completed") return ":white_check_mark:";
81638
81678
  if (status === "in_progress") return ":hourglass_flowing_sand:";
@@ -81658,6 +81698,8 @@ var OutputConverger = class {
81658
81698
  reasoningDirty = false;
81659
81699
  activity = [];
81660
81700
  toolTitles = /* @__PURE__ */ new Map();
81701
+ toolOutputs = /* @__PURE__ */ new Map();
81702
+ emittedOutput = /* @__PURE__ */ new Set();
81661
81703
  constructor(mode) {
81662
81704
  this.mode = mode;
81663
81705
  }
@@ -81721,6 +81763,28 @@ var OutputConverger = class {
81721
81763
  }
81722
81764
  return (id && this.toolTitles.get(id)) ?? id ?? "tool";
81723
81765
  }
81766
+ /** high mode: surface a finished tool's output as a code-block `tool-output` action.
81767
+ * Tracks the latest output across streamed updates and emits it exactly once, when the
81768
+ * call reaches a terminal status (completed/failed) — so partial output isn't posted
81769
+ * early and the final result isn't re-posted. Returns [] when there's nothing to post. */
81770
+ drainToolOutput(update) {
81771
+ const id = update.toolCallId;
81772
+ if (!id) return [];
81773
+ if (update.content !== void 0 || update.rawOutput !== void 0) {
81774
+ const out = extractToolOutput(update);
81775
+ if (out) this.toolOutputs.set(id, out);
81776
+ else this.toolOutputs.delete(id);
81777
+ }
81778
+ if (!(update.status === "completed" || update.status === "failed") || this.emittedOutput.has(id)) return [];
81779
+ const text = this.toolOutputs.get(id);
81780
+ if (!text) return [];
81781
+ this.emittedOutput.add(id);
81782
+ this.toolOutputs.delete(id);
81783
+ return [{
81784
+ kind: "tool-output",
81785
+ text: `${update.status === "failed" ? ":x:" : ":page_facing_up:"}\n${codeSpan(capOutput(text), true)}`
81786
+ }];
81787
+ }
81724
81788
  onUpdate(update) {
81725
81789
  switch (update.sessionUpdate) {
81726
81790
  case "agent_message_chunk": {
@@ -81740,17 +81804,20 @@ var OutputConverger = class {
81740
81804
  return [...this.flush(), ...this.pushActivity(THINKING)];
81741
81805
  case "tool_call":
81742
81806
  case "tool_call_update": {
81743
- const label = this.toolLabel(update);
81807
+ const u = update;
81808
+ const label = this.toolLabel(u);
81744
81809
  const status = this.pushActivity(label);
81745
81810
  if (this.mode === "low") return [...this.flush(), ...status];
81746
- return [
81811
+ const actions = [
81747
81812
  ...this.flush(),
81748
81813
  ...status,
81749
81814
  {
81750
81815
  kind: "progress",
81751
- text: `:hammer_and_wrench: ${label}`
81816
+ text: `:hammer_and_wrench: ${codeSpan(label)}`
81752
81817
  }
81753
81818
  ];
81819
+ if (this.mode === "high") actions.push(...this.drainToolOutput(u));
81820
+ return actions;
81754
81821
  }
81755
81822
  case "plan": {
81756
81823
  const entries = update.entries ?? [];
@@ -85090,6 +85157,7 @@ var Daemon = class Daemon {
85090
85157
  return;
85091
85158
  }
85092
85159
  case "notice":
85160
+ case "tool-output":
85093
85161
  await conn.postMessage(p.channel, action.text, p.thread);
85094
85162
  return;
85095
85163
  case "progress":