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:
- New Inngest function
agent-sub-agent— accepts a task description and session key, runs an isolated agent loop with restricted tools - No recursion — sub-agents cannot spawn sub-agents (tool set excludes delegation)
- Parent sees summary only — sub-agent returns a text summary of what it did
- 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. - Observable — every sub-agent step visible in Inngest dashboard, linked to parent run
When to use which
| Delegation target | Use when |
|---|---|
step.invoke() sub-agent | Task needs same env, benefits from Inngest observability, doesn’t need sandbox isolation |
| Codex exec | Task 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