Skip to content

Adopt [[NO_REPLY]] — let the model decline to post, drop hand-rolled suppression (runtime 4.1.32 live) #99

Description

@khaliqgant

Summary

[[NO_REPLY]] is now live in the cloud runtime (workforce#277, runtime 4.1.32 — cloud pin AgentWorkforce/cloud#2718 merged and the Daytona snapshot promoted 2026-07-18). Agents in this repo can now let the model decline to post instead of hand-rolling suppression, and several always-post / echo-guard workarounds can be removed.

What the runtime now gives us

Every agent here imports defineAgent from @agentworkforce/runtime and inherits cloud's runtime pin, which is now 4.1.32. So with no dependency change:

  • The model is prompted with the contract via the cloud harness system-prompt defaults: "When no visible reply is useful, make the final message exactly [[NO_REPLY]]."
  • ctx.harness.run(...) sanitizes the output and returns HarnessRunResult with suppressed?: boolean and containsMarker?: boolean (the marker is already stripped from output). suppressed is true when the model's whole reply was the marker — i.e. nothing to post.

The runtime does the stripping and detection. But every agent in this repo posts manually (slackClient().reply(...), VFS writeback, etc.), so the runtime cannot suppress the post for us — each agent must consult suppressed and skip its own post.

The adoption change (per agent)

After a harness run, gate the manual post on the result:

const result = await ctx.harness.run({ prompt, ... });
if (result.suppressed) return;            // model chose silence — post nothing
await slackClient().reply(channel, threadTs, result.output);

and delete always-post fallbacks and blunt echo guards that this replaces.

Where it applies (grep hits, not exhaustive)

  • linear-slack/agent.ts — the trickiest: today it uses the reply as a writeback-flush mechanism (draft → mutation → receipt → reply confirms and flushes before teardown, comments :62-75), and carries subtype echo handling (:51). NO_REPLY here needs care — a suppressed reply must still flush the writeback some other way, or the "confirm + flush" coupling breaks. Worth designing, not a mechanical swap.
  • review/agent.ts, daytona-monitor/agent.ts, gcp-watcher/agent.ts, neon-monitor/agent.ts, joke-bot/agent.ts — monitors/responders that currently post on every fire or hand-roll "should I say anything" logic; these are the clean wins (a monitor with nothing to report should emit the marker and stay silent rather than post a no-op).

Why bother

  • Kills the recurring noise of agents posting "nothing to report" / acknowledgement replies.
  • Removes per-agent reimplementations of suppression (broad bot_id/subtype guards that also swallow legitimate messages).
  • Moves the "is this worth saying" decision to the model, which has the full context, instead of a coarse pre-post heuristic.

Acceptance

  • Agents that post manually check result.suppressed and skip the post when set.
  • A monitor with nothing actionable produces no message (verified against a real fire).
  • The marker never appears in any posted text (runtime already strips it; verify no agent posts result.output without going through the suppressed check).
  • Redundant always-post fallbacks / echo guards removed where NO_REPLY covers them.
  • linear-slack handled deliberately so writeback flush is preserved when the reply is suppressed.

Refs

  • workforce#277 (feature), workforce PR #278 (impl), AgentWorkforce/cloud#2718 (runtime pin → 4.1.32, live). Sibling adoption issue in AgentWorkforce/internal-agents.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions