Skip to content

fix(agents): wait for cron media completions#88695

Merged
steipete merged 2 commits into
mainfrom
fix/cron-media-sync-completions
May 31, 2026
Merged

fix(agents): wait for cron media completions#88695
steipete merged 2 commits into
mainfrom
fix/cron-media-sync-completions

Conversation

@steipete

@steipete steipete commented May 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep cron media generation detached, but suppress the interactive yield path and make the embedded runner wait for cron-owned image, music, and video tasks to finish before final closeout.
  • Record async task run IDs from tool results, with a task-registry fallback for already-active run-scoped media tasks and timeout-aware completion handling.
  • Relax generated-media delivery only for no-target cron completion handoffs, where there is no external reply target to satisfy.

Fixes #88001.

Verification

  • node scripts/run-vitest.mjs src/agents/embedded-agent-runner/run/attempt.async-tasks.test.ts src/agents/subagent-announce-delivery.test.ts src/agents/tools/image-generate-tool.test.ts src/agents/tools/media-generate-background-shared.test.ts src/agents/openclaw-tools.tts-config.test.ts (7 unit-fast tests, 157 agent tests)
  • node scripts/run-vitest.mjs src/agents/tools/video-generate-tool.test.ts src/agents/tools/music-generate-tool.test.ts src/agents/subagent-announce-delivery.test.ts src/agents/embedded-agent-runner/run/attempt-trajectory-status.test.ts src/agents/embedded-agent-runner/run.incomplete-turn.test.ts src/cron/isolated-agent.session-identity.test.ts src/cron/isolated-agent/run.message-tool-policy.test.ts (16 unit-fast tests, 49 cron tests, 253 agent tests)
  • git diff --check
  • pnpm exec oxlint ... on touched lint-fix files and async-task runner files
  • .agents/skills/autoreview/scripts/autoreview --mode local (first pass found timeout/video wait gaps; fixed; rerun clean with no accepted/actionable findings)
  • Testbox-through-Crabbox tbx_01kszpcj4j4w3w4v2343bsgw4p, Actions run 26721537214: corepack pnpm check:changed passed
  • Testbox-through-Crabbox tbx_01kszqtqh324fypas2y1yaz3c7, Actions run 26722125851: final corepack pnpm check:changed passed

Real behavior proof

Behavior addressed: isolated cron agentTurn runs that call image_generate followed by music_generate should not finish the cron turn while media tasks are still running.

Real environment tested: direct AWS Crabbox live cron harness with real provider credentials. OpenAI and MiniMax API keys were injected from 1Password for the command only; secret values were not printed. The direct lease was released after the run.

Exact steps or command run after this patch: Crabbox live cron harness executing an isolated cron agent turn that generated one image with OpenAI and one music track with MiniMax, then asserted the task registry for succeeded image_generation and music_generation task records.

Evidence after fix: live run run_f0087434d34b returned status ok; marker cron-media-live-1780249952289; image task tool:image_generate:7a25d54e-d1e7-4b8b-af56-4ec315028e70; music task tool:music_generate:05703bea-b42c-45f9-9b49-46e5282e2f63; task statuses image_generation:succeeded and music_generation:succeeded.

Observed result after fix: the cron agent turn waited through image completion, continued into music generation, waited for the music task, and returned final output containing both generated media paths instead of closing after the async-start response.

What was not tested: live video generation. Video uses the same registry-backed completion wait and has regression coverage here; the requested live proof was image plus music.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S maintainer Maintainer-authored PR labels May 31, 2026
@clawsweeper

clawsweeper Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed May 31, 2026, 3:40 PM ET / 19:40 UTC.

Summary
The PR makes isolated cron media generation stay detached while the embedded runner waits for cron-owned image, music, and video task completion before final closeout.

PR surface: Source +381, Tests +469. Total +850 across 27 files.

Reproducibility: yes. at source level: current main wires cron media async starts to onYield, detaches the task, and has no embedded-run wait helper before terminal closeout. I did not run a live current-main reproduction in this read-only review.

Review metrics: 1 noteworthy metric.

  • Completion-required media kinds: 3 task kinds covered. Image, music, and video now share one cron wait invariant, so maintainers should evaluate the session-lifecycle behavior as a single cross-media change.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Resolve the dirty merge state against current main before maintainer merge.
  • Decide whether image/music live proof plus shared video regression coverage is enough, or require one live video cron run.

Risk before merge

  • [P1] The PR is currently dirty/unmergeable against the GitHub base and carries the protected maintainer label, so it needs branch refresh and maintainer handling before merge.
  • [P1] The patch intentionally changes cron run terminal lifecycle by keeping active-run state open while image/music/video task completions finish; that is a real session-state risk even though the inspected source and tests support the approach.
  • [P1] Live proof covers image plus music, while live video generation is untested and relies on the shared registry-backed wait path plus regression coverage.

Maintainer options:

  1. Refresh and maintainer-land (recommended)
    Resolve the dirty merge state, rerun the relevant changed checks on the refreshed head, and land only after maintainer acceptance of the cron lifecycle wait behavior.
  2. Accept shared video proof
    Maintainers can accept the image/music live proof plus shared video regression coverage if they are comfortable that video uses the same registry wait path.
  3. Pause for lifecycle review
    If keeping cron active-run state open until media completion is too broad for this fix, pause the PR and request a narrower owner-boundary design before merge.

Next step before merge

  • [P2] The next step is maintainer handling: the branch is dirty/unmergeable and protected by the maintainer label, while the inspected patch has no narrow blocking defect for an automated repair lane.

Security
Cleared: The diff touches TypeScript runtime/tests only and does not change dependencies, lockfiles, workflows, package scripts, permissions, or secret handling.

Review details

Best possible solution:

Refresh the branch against current main, preserve the registry-backed wait and duplicate-guard behavior, and have a maintainer land it after accepting the cron session-lifecycle change.

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

Yes at source level: current main wires cron media async starts to onYield, detaches the task, and has no embedded-run wait helper before terminal closeout. I did not run a live current-main reproduction in this read-only review.

Is this the best way to solve the issue?

Yes, this looks like the right owner-boundary fix: keep media generation detached, suppress only the cron interactive-yield path, and make the embedded runner wait on the task registry before closeout. A fully inline media tool path would have lost duplicate-guard and detached-task behavior, which the final PR avoids.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 6b2cb4db67a0.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix live Crabbox output from a real isolated cron provider run with redacted credential handling, concrete run/task IDs, and succeeded image/music task statuses.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes after-fix live Crabbox output from a real isolated cron provider run with redacted credential handling, concrete run/task IDs, and succeeded image/music task statuses.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.
  • remove status: 📣 needs proof: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P1: The PR targets a P1 isolated cron media workflow bug where runs can report success while the intended multi-step agent work remains incomplete.
  • merge-risk: 🚨 session-state: The diff changes when embedded cron runs clear active-run state and final lifecycle handling while waiting for async media task completion.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes after-fix live Crabbox output from a real isolated cron provider run with redacted credential handling, concrete run/task IDs, and succeeded image/music task statuses.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix live Crabbox output from a real isolated cron provider run with redacted credential handling, concrete run/task IDs, and succeeded image/music task statuses.
Evidence reviewed

PR surface:

Source +381, Tests +469. Total +850 across 27 files.

View PR surface stats
Area Files Added Removed Net
Source 16 430 49 +381
Tests 11 682 213 +469
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 27 1112 262 +850

What I checked:

  • Repository policy read: Root and scoped AGENTS.md guidance for agents, embedded runner tests, agent tools, and extensions was read and applied to this session-state-sensitive PR review. (AGENTS.md:1, 07150819904f)
  • Current main lacks the wait path: Current main has no waitForCompletionRequiredAsyncTasks, asyncTaskRunId, or cron-specific media async callback suppression in the agent source tree, so the central fix is not already implemented on main. (src/agents/embedded-agent-runner/run/attempt.ts:3056, 6b2cb4db67a0)
  • Current main still routes cron media through yield: On current main, cron run session keys are selected for media tools, but onAsyncTaskStarted is still wired directly to options.onYield, which matches the reported premature cron-yield behavior. (src/agents/openclaw-tools.ts:251, 6b2cb4db67a0)
  • Current main detaches and records media tasks: The current image tool detaches any session-backed generation and records the recent request key before scheduling completion, which is the duplicate-guard path the PR needs to preserve. (src/agents/tools/image-generate-tool.ts:1021, 6b2cb4db67a0)
  • PR suppresses cron yield without stopping detach: At the PR head, cron media tools receive undefined for the async-start callback while non-cron sessions still receive options.onYield, avoiding the interactive yield path for cron runs. (src/agents/openclaw-tools.ts:218, 76ae8c421af8)
  • PR preserves duplicate guarding: At the PR head, image, music, and video still detach for session-backed tasks and keep the recordRecentMediaGenerationTaskStartForSession path before scheduling background completion. (src/agents/tools/image-generate-tool.ts:1022, 76ae8c421af8)

Likely related people:

  • steipete: Current-main blame for the media task detachment, cron media tool wiring, embedded runner terminal cleanup, and task registry lookup paths points to e014145ac1922ec468bddb5a3756c5822b88f253, and this PR continues the same cron media/session-state work. (role: current-main feature author and recent area contributor; confidence: high; commits: e014145ac192, 6bd065d7f835, 76ae8c421af8; files: src/agents/tools/image-generate-tool.ts, src/agents/tools/music-generate-tool.ts, src/agents/tools/video-generate-tool.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 09d9130eb3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


export function shouldDetachMediaGenerationTask(sessionKey: string | undefined): boolean {
const normalizedSessionKey = sessionKey?.trim();
return Boolean(normalizedSessionKey && !isCronRunSessionKey(normalizedSessionKey));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve duplicate guarding for inline cron media

When a cron run session returns false here, the image/video/music tools skip the recordRecentMediaGenerationTaskStartForSession(...) block that is currently the only place caching the requestKey used by findDuplicateGuardMediaGenerationTaskForSession to suppress recent successful duplicate requests. In cron runs that now execute inline, an agent retrying the same image_generate/video_generate/music_generate call after the first inline completion will generate the media again instead of getting the recent-task guard that interactive async sessions still get; keep recording the recent start for inline cron task handles or otherwise persist the request key for the completed task.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels May 31, 2026
@steipete
steipete force-pushed the fix/cron-media-sync-completions branch from 09d9130 to 76ae8c4 Compare May 31, 2026 19:33
@openclaw-barnacle openclaw-barnacle Bot added channel: discord Channel integration: discord channel: imessage Channel integration: imessage channel: slack Channel integration: slack commands Command implementations extensions: google size: XL and removed size: S labels May 31, 2026
@steipete steipete changed the title fix(agents): keep cron media generation inline fix(agents): wait for cron media completions May 31, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 76ae8c421a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +4263 to +4268
if (
requiresCompletionRequiredAsyncTaskWait({
sessionKey: params.sessionKey,
toolMetas,
})
) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not wait with a finished agent registered active

For cron media runs where the model returns after starting image_generate/video_generate/music_generate, this wait happens after activeSession.prompt(...) has already resolved, so the underlying agent loop has emitted agent_end and will not drain new steering messages again (packages/agent-core/src/agent.ts:306, packages/agent-core/src/agent-loop.ts:324). Because onBeforeLifecycleTerminal now keeps the embedded run registered as active until this wait finishes, the media completion path sees an active requester and tries to queue the completion back into this finished run; that queued completion cannot be committed, so delivery stalls until the active-wake timeout or the cron run deadline instead of completing inline.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels May 31, 2026
@steipete
steipete force-pushed the fix/cron-media-sync-completions branch from 76ae8c4 to 4275a00 Compare May 31, 2026 20:50
@openclaw-barnacle openclaw-barnacle Bot removed channel: discord Channel integration: discord channel: imessage Channel integration: imessage channel: slack Channel integration: slack labels May 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling maintainer Maintainer-authored PR merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: L status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: image_generate in isolated cron session closes turn before receiving callback — cron never completes

1 participant