# `ObanClaude.Agent.Job`
[🔗](https://github.com/genagent/oban_claude/blob/v0.10.2/lib/oban_claude/agent/job.ex#L1)

The default Oban worker for agent turns: runs claude, then routes the
outcome back to the owning `ObanClaude.Agent.Instance`.

The owning agent's id, instance generation, and logical turn id ride in the
job's meta, where `ObanClaude.Agent.Instance` puts them at enqueue time. The
generation prevents a job from an earlier same-id process from controlling
its replacement. The turn id keeps retries attached to one logical turn and
fences late or duplicate callbacks. A job without an `"agent_id"` (enqueued
by hand) runs normally and reports to no one.

## Retry-awareness

The routing is terminal-aware, so a worker with retries reports one logical
turn, not one event per attempt:

  * a success, a `{:cancel, _}` verdict, or an `{:error, _}` on the final
    attempt is terminal -> `ObanClaude.Agent.job_finished/3`
  * an `{:error, _}` with attempts remaining, or a `{:snooze, _}`, means
    Oban will re-run the job -> `ObanClaude.Agent.job_retrying/3`, which
    keeps the machine in `:running` and re-arms its watchdog

This worker itself stays at `max_attempts: 1` -- every retry is a fresh paid
claude call, so retrying is an explicit opt-in, not a default. To opt in,
point the agent's `:worker` config at your own worker and delegate the
callbacks here:

    defmodule MyApp.RetryingAgentJob do
      use ObanClaude.Worker, queue: :agents, max_attempts: 3

      @impl ObanClaude.Worker
      def handle_result(result, job), do: ObanClaude.Agent.Job.handle_result(result, job)

      @impl ObanClaude.Worker
      def handle_error(verdict, payload, job),
        do: ObanClaude.Agent.Job.handle_error(verdict, payload, job)
    end

---

*Consult [api-reference.md](api-reference.md) for complete listing*
