ADR-0197accepted

Sub-Agent Delegation via step.invoke()

Status

Proposed

Context

joelclaw delegates heavy coding work to Codex via codex exec — a separate process that runs outside Inngest’s observability. We get the final result but no step traces, no retry semantics, no cancellation, and no visibility into what the sub-agent did.

Utah spawns sub-agents via step.invoke() — calling another Inngest function with an isolated context window and restricted tools (no delegate_task = no recursion). The sub-agent runs as a full Inngest function with step-level traces, retries, and observability.

Decision

Add a step.invoke()-based sub-agent pattern alongside Codex delegation:

  1. New Inngest function agent-sub-agent — accepts a task description and session key, runs an isolated agent loop with restricted tools
  2. No recursion — sub-agents cannot spawn sub-agents (tool set excludes delegation)
  3. Parent sees summary only — sub-agent returns a text summary of what it did
  4. Codex still available — for sandbox-isolated code execution where filesystem access must be constrained. step.invoke() sub-agents are for tasks that need the same environment as the parent.
  5. Observable — every sub-agent step visible in Inngest dashboard, linked to parent run

When to use which

Delegation targetUse when
step.invoke() sub-agentTask needs same env, benefits from Inngest observability, doesn’t need sandbox isolation
Codex execTask needs sandboxed filesystem, or is pure coding work where Codex’s model/tooling excels

Consequences

  • Full observability — sub-agent work visible in Inngest dashboard with step traces
  • Retry semantics — if a sub-agent step fails, Inngest retries it
  • Cancellation — parent can cancel sub-agent via Inngest primitives
  • Complexity — two delegation paths to maintain and choose between

Agent Readiness

  • Confidence: 3 — pattern proven in Utah but our gateway architecture differs
  • Agent-ready: 3 — needs design work on tool restriction and session isolation
  • NRC: High — new function + delegation routing logic
  • Novelty: Medium — step.invoke() for sub-agents is novel for joelclaw

References