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

One agent as one `:gen_statem` process, its asynchronous turns run as Oban
jobs. Part of the experimental agent layer (see `ObanClaude.Agent`).

The process never blocks on claude: a prompt enqueues an `ObanClaude.Worker`
job and the machine parks in `:running` until the worker's callbacks route
the outcome back as a `{:job_finished, payload}` cast (via
`ObanClaude.Agent.job_finished/3`). States:

  * `:idle` -- ready for a prompt
  * `:running` -- an Oban job is in flight; further prompts are `:postpone`d
    and a `:state_timeout` watchdog guards against a turn that never reports
    back. A retryable failed attempt (`ObanClaude.Agent.job_retrying/3`)
    keeps the machine here and re-arms the watchdog, so `:job_timeout` should
    exceed one attempt's backoff plus its execution
  * `:waiting_for_user` -- the last turn asked a question (structured-output
    directive `"ask_user"`); the next prompt is treated as the answer and
    resumes the claude session
  * `:awaiting_permission` -- the last turn requested approval (directive
    `"request_permission"`); `approve` resumes the session with the action
    (under `:approved_args`, plus any per-approval `:args`, see below), `reject` records the denial and
    returns to `:idle`, and prompts are `:postpone`d until the gate clears.
    An approved turn that fails or hits the watchdog RE-GATES (same
    description, fresh id, `{:approval_incomplete, reason}` in history):
    the work was approved but not completed, and a re-approval resumes it
  * `:paused` -- lockdown via `:emergency_pause`, a correlated
    `ObanClaude.Agent.pause_after_turn/3`, or a host-requested
    `ObanClaude.Agent.quiesce/2`; every call is refused until an explicit
    `resume`

Every state change atomically synchronizes the registry value -- the state
atom, paired with the pending action or question in the gated states -- so
`ObanClaude.Agent.status/1` reads both without messaging the process. Each
change also emits `[:oban_claude, :agent, :transition]` telemetry with
`%{agent_id, from, to}` metadata (state atoms). Turn transitions also carry
the wrapper-owned generation, turn and arc identities, plus the optional
application `correlation_id` and applied `config_revision`.

Claude session ids are retained in bounded, host-named conversation arcs.
Prompts that omit an arc use `"default"`, preserving the original one-agent,
one-conversation behavior. Turn count and accumulated cost ride in the data
(see `ObanClaude.Agent.info/1`).

## Config

`start_agent/2` takes a keyword list or map:

  * `:args` -- default claude args merged under every turn's prompt (build
    with `ObanClaude.Args.defaults/1`; string keys); default `%{}`
  * `:approved_args` -- claude args merged over `:args` for approve
    continuations ONLY, so conversational approval actually unlocks
    something -- e.g. `%{"permission_mode" => "accept_edits"}` or an
    `allowed_tools` grant. Normal turns never carry these. Default `%{}`.
  * `:worker` -- the Oban worker module for turns; default
    `ObanClaude.Agent.Job`
  * `:oban` -- the Oban instance name to insert into; default `Oban`
  * `:job_timeout` -- the `:running` watchdog in milliseconds; default 60000
  * `:max_history` -- cap on retained history entries (newest win); default
    500, so an always-on agent's event log cannot grow without bound
  * `:session_arcs` -- optional `%{arc_id => session_id}` seed map for
    restoring provider conversations after this process restarts; default
    `%{}`
  * `:max_session_arcs` -- maximum retained provider handles; least-recently
    used inactive arcs are evicted as new ones arrive; default 32
  * `:config_revision` -- optional opaque non-empty string identifying the
    immutable host configuration applied to this process; default `nil`
  * `:enqueue_fun` -- a 2-arity `(args, meta) -> {:ok, term} | {:error, term}`
    override of the enqueue itself, for tests (no Oban, no DB)

# `child_spec`

# `start_link`

---

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