Skip to content

feat: provider dispatch — backend registry (claude/codex/sdk/local) #262

@justrach

Description

@justrach

Parent: #257 — Layer 0 (Plumbing)

What

Provider-agnostic dispatch function that spawns one agent turn on one specified backend. No resolution logic, no preferences — just execute what resolve() decided.

const Backend = enum { claude, codex, sdk, local };

fn dispatch(
    alloc: Allocator,
    backend: Backend,
    model: []const u8,
    prompt: []const u8,
    opts: DispatchOpts,
    out: *ArrayList(u8),
) void {
    switch (backend) {
        .claude => spawnClaude(alloc, model, prompt, opts, out),
        .codex  => spawnCodex(alloc, model, prompt, opts, out),
        .sdk    => querySDK(alloc, model, prompt, opts, out),    // #178
        .local  => spawnLocal(alloc, model, prompt, opts, out),  // future
    }
}

Backends

Backend How When available
claude Spawn claude -p --model X (current tryClaudeAgent logic) claude on PATH
codex Spawn codex app-server (current codex_appserver.runTurnPolicy) codex on PATH
sdk Claude Agent SDK query() When #178 lands
local Spawn local model server (ollama, llama.cpp) Future

Changes

  • Extract tryClaudeAgent() from agent_sdk.zig into spawnClaude() in dispatch module
  • Extract codex_appserver.runTurnPolicy() into spawnCodex()
  • Each backend handles its own sandbox/permission mapping
  • Login shell fallback stays in spawnClaude()

What this does NOT do

  • No resolution logic (that's resolve())
  • No model/provider selection (that's the grid)
  • No prompt injection (that's run_agent)

Depends on

Blocks

  • run_agent refactor (needs dispatch to send agents)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions