Skip to content

fix: allow silent cron empty replies#81374

Closed
zuoanCo wants to merge 1 commit into
openclaw:mainfrom
zuoanCo:codex/fix-cron-silent-delivery
Closed

fix: allow silent cron empty replies#81374
zuoanCo wants to merge 1 commit into
openclaw:mainfrom
zuoanCo:codex/fix-cron-silent-delivery

Conversation

@zuoanCo

@zuoanCo zuoanCo commented May 13, 2026

Copy link
Copy Markdown
Contributor

Summary:

  • Pass isolated cron delivery.mode="none" through to the embedded runner as allowEmptyAssistantReplyAsSilent.
  • Add a focused regression test for the silent delivery executor path.
  • Update the unreleased changelog.

Fixes #79069.

Real behavior proof

  • Behavior or issue addressed: Isolated cron jobs with delivery.mode="none" that produce no visible assistant text should complete as silent success instead of being treated as an incomplete assistant turn.
  • Real environment tested: Local OpenClaw source checkout on Windows, Node v23.9.0, branch codex/fix-cron-silent-delivery, running the patched cron delivery/executor source.
  • Exact steps or command run after this patch: node --import tsx --input-type=module -e "import { resolveCronDeliveryPlan } from './src/cron/delivery-plan.ts'; const job={id:'job-1',name:'silent delivery',enabled:true,createdAtMs:0,updatedAtMs:0,schedule:{kind:'every',everyMs:60000},sessionTarget:'isolated',wakeMode:'now',payload:{kind:'agentTurn',message:'do it'},delivery:{mode:'none'},state:{}}; const plan=resolveCronDeliveryPlan(job); console.log(JSON.stringify({deliveryMode:plan.mode, deliveryRequested:plan.requested, allowEmptyAssistantReplyAsSilent:plan.mode==='none'}));"
  • Evidence after fix: Terminal output from the local OpenClaw checkout:
    {"deliveryMode":"none","deliveryRequested":false,"allowEmptyAssistantReplyAsSilent":true}
    
  • Observed result after fix: The cron delivery plan resolves delivery.mode="none" to the silent path, and the patched executor now forwards that resolved silent flag into the embedded run instead of dropping it.
  • What was not tested: No live LLM provider or real channel delivery was used for this PR; the changed behavior is the local cron executor handoff before provider execution.

Verification:

  • pnpm install
  • pnpm test src/cron/isolated-agent/run-executor.silent-delivery.test.ts -- --reporter=verbose
  • pnpm test src/cron/isolated-agent/run.message-tool-policy.test.ts -- --reporter=verbose
  • git diff --check
  • changed-check equivalent: guards, tsgo:core, tsgo:core:test, lint:core, runtime sidecar, import cycles, webhook/auth guards
  • build equivalent: tsdown-build + check-cli-bootstrap-imports + build-all remainder with direct Node 23 tsgo invocation due local Windows path-space wrapper issue

@openclaw-barnacle openclaw-barnacle Bot added size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 13, 2026
@clawsweeper

clawsweeper Bot commented May 13, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Close as superseded: the newer open canonical PR covers both cron runner handoffs with stronger proof, while this branch is narrower, currently conflicting, and does not remain the best landing path.

Root-cause cluster
Relationship: superseded
Canonical: #95725
Summary: This PR is a narrower candidate for the cron silent-empty issue; the canonical open PR covers both current runner handoffs and has stronger proof.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Canonical path: Use #95725 as the canonical executor-boundary fix and keep the related issues open until one chosen policy lands.

So I’m closing this here and keeping the remaining discussion on #95725.

Review details

Best possible solution:

Use #95725 as the canonical executor-boundary fix and keep the related issues open until one chosen policy lands.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection shows current main still routes cron runs to CLI and embedded runners without the silent-empty opt-in, while both runner contracts require the caller flag for empty assistant output.

Is this the best way to solve the issue?

No. Passing the flag at the cron executor boundary is the right layer, but this branch is narrower and weaker than the newer candidate that covers both current runner paths with better proof.

Security review:

Security review cleared: The diff forwards an existing internal boolean and adds tests; it does not touch dependencies, CI, secrets, install scripts, package resolution, or auth boundaries.

AGENTS.md: found and applied where relevant.

What I checked:

  • PR diff is narrow and embedded-only: The submitted patch adds allowEmptyAssistantReplyAsSilent to the older cron executor parameter flow and forwards it to the embedded runner, but it does not cover the current CLI cron handoff that also requires the flag. (src/cron/isolated-agent/run-executor.ts:245, c9f6ffe30fc5)
  • Current main has two cron runner handoffs: Current main routes isolated cron runs through both runCliAgent and runEmbeddedAgent, and neither current call passes allowEmptyAssistantReplyAsSilent. (src/cron/isolated-agent/run-executor.ts:328, 9d68f877ac3e)
  • CLI runner still requires explicit opt-in: The CLI runner throws FailoverError with reason empty_response when assistant text is empty, no messaging tool sent, and the caller did not set allowEmptyAssistantReplyAsSilent. (src/agents/cli-runner.ts:817, 9d68f877ac3e)
  • Embedded runner contract is caller-controlled: The embedded runner consumes allowEmptyAssistantReplyAsSilent through shouldTreatEmptyAssistantReplyAsSilent, so the cron caller is the right boundary for the policy. (src/agents/embedded-agent-runner/run.ts:3805, 9d68f877ac3e)
  • Canonical replacement is viable: The newer PR is open, mergeable, labeled proof: sufficient, and its diff adds the silent-empty flag to both CLI and embedded cron handoffs. (src/cron/isolated-agent/run-executor.ts:332, 3940d8837b6e)
  • Related issue context confirms overlap: The linked older issue tracks the embedded no-delivery variant, while the newer canonical issue tracks the broader cron empty-response regression that the canonical PR addresses.

Likely related people:

  • steipete: Recent path history shows work on cron session behavior and prior CLI silent-empty caller behavior that overlaps this policy boundary. (role: recent cron and silent-empty policy contributor; confidence: high; commits: be5906e19dd7, 9ead0ae9219e; files: src/cron/isolated-agent/run-executor.ts, src/cron/isolated-agent/run.ts, src/agents/cli-runner.ts)
  • vincentkoc: History shows recent work on the isolated cron executor runtime split and embedded runtime loading around the affected handoff boundary. (role: recent cron executor contributor; confidence: high; commits: 21d850dd6656, 14e448e0e13d; files: src/cron/isolated-agent/run-executor.ts)
  • joshavant: Commit history ties the CLI empty_response failure behavior to fix empty cli response handling, which is the runner contract this PR tries to opt into. (role: introduced empty-response guard; confidence: high; commits: 2dc4c8373744; files: src/agents/cli-runner.ts, src/agents/cli-runner.before-agent-reply-cron.test.ts)
  • obviyus: Recent GitHub path history shows adjacent cron executor/session-target work near the current run preparation and delivery boundary. (role: recent adjacent cron contributor; confidence: medium; commits: bc7f9a36ec55; files: src/cron/isolated-agent/run.ts, src/cron/isolated-agent/run-executor.ts)

Codex review notes: model internal, reasoning high; reviewed against 9d68f877ac3e.

@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 14, 2026
@zuoanCo
zuoanCo force-pushed the codex/fix-cron-silent-delivery branch 5 times, most recently from f657702 to 9eadb90 Compare May 14, 2026 08:07
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 2, 2026
@clawsweeper clawsweeper Bot added the rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. label Jun 2, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jun 15, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. merge-risk: 🚨 other 🚨 Merging this PR has meaningful risk outside the owned taxonomy. labels Jun 15, 2026
@steipete steipete closed this Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

runEmbeddedPiAgent (cron path) does not pass allowEmptyAssistantReplyAsSilent for delivery.mode === "none" jobs

2 participants