Skip to content

Feature Request: Async exec callback — inject result back to session when process exits #18237

@albert-mochi

Description

@albert-mochi

Problem

When an agent launches a long-running process (e.g., Claude Code via exec), there is no way to receive the result without either:

  1. Blocking the agent turn — The agent sits idle waiting for the process (wastes resources, and sub-agent sessions get killed by system lifetime limits before the process finishes)
  2. Polling — The agent repeatedly checks process status via process poll/log (wastes tokens, unreliable)
  3. External workarounds — Fire-and-forget with hook scripts, signal files, fswatch, etc. (fragile, complex)

This is a fundamental gap for any workflow that needs to run an external tool for 10-60 minutes (coding agents, build pipelines, test suites, etc.).

Proposed Solution

Add an async exec callback mode:

exec command="claude -p '...' --dangerously-skip-permissions" timeout=3600 callback=true

Behavior:

  • callback=true → exec launches the process, agent turn ends immediately (like background=true)
  • When the process exits, the result (stdout, exit code) is automatically injected back into the same session as a system event or tool result
  • The agent wakes up and processes the result in a new turn

This is similar to how webhook callbacks work — the agent does not need to stay alive or poll; the system handles the lifecycle.

Why This Matters

We have been building a programming task workflow (Claude Code + Spec Kit + GitHub PRs) and tried every available pattern:

Approach Result
Sub-agent + blocking exec Sub-agent killed by session lifetime limits (even with generous runTimeoutSeconds)
Sub-agent + yieldMs=3600000 Sub-agent still killed after ~2 min
Sub-agent + polling Burns 30-100K tokens on useless poll loops
Sub-agent + fswatch blocking Sub-agent token budget exhausted (100K+), orphans CC process
Fire-and-forget + hook wake Works but requires external hook scripts, signal files, task-meta routing — fragile

With async exec callback, all of these reduce to a single exec call. No sub-agents needed, no polling, no external hooks, no orphaned processes.

Desired Behavior

# Agent launches long-running process
exec command="some-long-task" timeout=3600 callback=true
# → Agent turn ends immediately
# → Agent is free for other conversations

# ... 20 minutes later, process exits ...

# → System injects result into session:
#   { "type": "execCallback", "sessionId": "xxx", "exitCode": 0, "stdout": "...", "stderr": "..." }
# → Agent wakes up and processes the result

Additional Context

  • This would make OpenClaw a first-class orchestrator for coding agents (Claude Code, Codex CLI, etc.)
  • The hook mechanism (/hooks/wake, /hooks/agent) already provides similar functionality but requires external scripts and manual routing
  • A native callback would be simpler, more reliable, and work out of the box

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleMarked as stale due to inactivity

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions