# `Wardrik.Agent`

An agent, and the operations on one.

    Wardrik.Agent.ask(scope, "agt_1", "What's on fire?")
    #=> {:ok, %Wardrik.Message{id: "msg_Xq3f...", cursor: "W1siYWd0XzEiLG51bGwsNDFdXQ"}}

    Wardrik.Agent.read(scope, "agt_1")
    #=> {:ok, %Wardrik.Agent{id: "agt_1", status: :running, node: "wardrik@box1", pending: 0, ...}}

A conversation shares its agent's definition, with its own history:

    Wardrik.Agent.ask(scope, "agt_1", "What's on fire?", conversation: "C1")
    Wardrik.Agent.approve(scope, agent: "agt_1", interrupt: "call_1", conversation: "C1")

## Fields

  * `:id` - the agent's ID, as your app chose it.
  * `:conversation` - the conversation's ID, or `nil` for the main one.
  * `:status` - `:idle`, `:running`, `:parked` or `:asleep`.
  * `:node` - the node it runs on.
  * `:pending` - how many messages wait behind the current one.
  * `:next_run` - when it next runs.
  * `:spent_today` - what it has spent today.
  * `:activity` - what it's doing now. See `Wardrik.Activity`.
  * `:interrupts` - the calls it waits on a person for. See `Wardrik.Interrupt`.
  * `:cursor` - where its event log stands.

`Wardrik.Agents.list/2` leaves out `:activity`, `:interrupts` and `:cursor`.

# `t`

```elixir
@type t() :: %Wardrik.Agent{
  activity: term(),
  conversation: term(),
  cursor: term(),
  id: term(),
  interrupts: term(),
  next_run: term(),
  node: term(),
  pending: term(),
  spent_today: term(),
  status: term()
}
```

# `approve`

```elixir
@spec approve(Wardrik.Scope.t(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Approve a pending tool call.

    Wardrik.Agent.approve(scope, agent: "agt_1", interrupt: "call_1")

Same as agent.decide with one approval. Recorded under the caller.

Add `conversation: "C1"` to act on one of the agent's conversations.

`POST /v1/agents/{agent}/interrupts/{interrupt}/approve`

# `ask`

```elixir
@spec ask(Wardrik.Scope.t(), String.t() | struct(), term(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Send a message to an agent.

    Wardrik.Agent.ask(scope, "agt_1", input)

Add `conversation: "C1"` to act on one of the agent's conversations.

`POST /v1/agents/{agent}/messages`

# `authorization`

```elixir
@spec authorization(Wardrik.Scope.t(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Read the authorization URL for a pending call.

    Wardrik.Agent.authorization(scope, agent: "agt_1", interrupt: "call_1")

Add `conversation: "C1"` to act on one of the agent's conversations.

`GET /v1/agents/{agent}/interrupts/{interrupt}/authorization`

# `calls`

```elixir
@spec calls(Wardrik.Scope.t(), String.t() | struct(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

List an agent's running tool calls.

    Wardrik.Agent.calls(scope, "agt_1")

Returns not_found while the agent is asleep.

Add `conversation: "C1"` to act on one of the agent's conversations.

`GET /v1/agents/{agent}/calls`

# `cancel`

```elixir
@spec cancel(Wardrik.Scope.t(), String.t() | struct(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Cancel an agent's current turn.

    Wardrik.Agent.cancel(scope, "agt_1")

Add `conversation: "C1"` to act on one of the agent's conversations.

`POST /v1/agents/{agent}/cancel`

# `clear`

```elixir
@spec clear(Wardrik.Scope.t(), String.t() | struct(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Clear an agent's history.

    Wardrik.Agent.clear(scope, "agt_1")

Deletes the agent's history. The agent, its definition and its other conversations are kept. Returns conflict while the agent is running a turn or waiting for an approval.

Add `conversation: "C1"` to act on one of the agent's conversations.

`DELETE /v1/agents/{agent}/conversation`

# `decide`

```elixir
@spec decide(Wardrik.Scope.t(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Approve or reject pending tool calls.

    Wardrik.Agent.decide(scope, agent: "agt_1", decisions: decisions)

All decisions are applied together and recorded under the caller. A rejection's reason is sent to the model instead of the tool's result. An approval's note is sent with the result.

Add `conversation: "C1"` to act on one of the agent's conversations.

`POST /v1/agents/{agent}/decisions`

# `define`

```elixir
@spec define(Wardrik.Scope.t(), String.t() | struct(), term()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Define an agent.

    Wardrik.Agent.define(scope, "agt_1", input)

Creates the agent from this definition, or updates a running agent from its next turn. Each call replaces the whole definition. An unsupported key returns not_supported with the key's name.

`PUT /v1/agents/{agent}`

# `definition`

```elixir
@spec definition(Wardrik.Scope.t(), String.t() | struct()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Read an agent's definition.

    Wardrik.Agent.definition(scope, "agt_1")

`GET /v1/agents/{agent}/definition`

# `deny`

```elixir
@spec deny(Wardrik.Scope.t(), keyword()) :: term() | :ok | {:error, Wardrik.Error.t()}
```

Reject a pending tool call.

    Wardrik.Agent.deny(scope, agent: "agt_1", interrupt: "call_1")

Same as agent.decide with one rejection. Recorded under the caller.

Add `conversation: "C1"` to act on one of the agent's conversations.

`POST /v1/agents/{agent}/interrupts/{interrupt}/deny`

# `events`

```elixir
@spec events(Wardrik.Scope.t(), String.t() | struct(), term(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Read an agent's events.

    Wardrik.Agent.events(scope, "agt_1", input)

Add `conversation: "C1"` to act on one of the agent's conversations.

`GET /v1/agents/{agent}/events`

# `forget`

```elixir
@spec forget(Wardrik.Scope.t(), String.t() | struct()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Delete an agent.

    Wardrik.Agent.forget(scope, "agt_1")

`DELETE /v1/agents/{agent}`

# `from_json`

```elixir
@spec from_json(map()) :: t()
```

Builds one from the protocol's JSON.

# `from_summary`

```elixir
@spec from_summary(map()) :: t()
```

Builds an agent from one item of `agents.list`'s output.

# `kill`

```elixir
@spec kill(Wardrik.Scope.t(), keyword()) :: term() | :ok | {:error, Wardrik.Error.t()}
```

Stop a tool call.

    Wardrik.Agent.kill(scope, agent: "agt_1", call: "call_1")

Add `conversation: "C1"` to act on one of the agent's conversations.

`DELETE /v1/agents/{agent}/calls/{call}`

# `move`

```elixir
@spec move(Wardrik.Scope.t(), String.t() | struct(), term(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Move an agent to another node.

    Wardrik.Agent.move(scope, "agt_1", input)

Restarts the agent on the given node, with its state. A turn in progress is stopped, and pending approvals are dropped. Send the request again after the move.

Add `conversation: "C1"` to act on one of the agent's conversations.

`POST /v1/agents/{agent}/move`

# `read`

```elixir
@spec read(Wardrik.Scope.t(), String.t() | struct(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Read an agent's current status.

    Wardrik.Agent.read(scope, "agt_1")

Add `conversation: "C1"` to act on one of the agent's conversations.

`GET /v1/agents/{agent}`

# `reply`

```elixir
@spec reply(Wardrik.Scope.t(), String.t() | t(), term(), keyword()) ::
  {:ok, Wardrik.Reply.t()}
  | {:waiting, [Wardrik.Interrupt.t()]}
  | {:error, Wardrik.Error.t()}
```

Sends the agent a message and returns its answer once the run ends.

    Wardrik.Agent.reply(scope, "agt_1", "What's on fire?")
    #=> {:ok, %Wardrik.Reply{message: "msg_Xq3f...", run: "0af76519...", text: "Nothing's on fire."}}

Returns `{:waiting, interrupts}` if the run waits on a person, or `{:error, %Wardrik.Error{}}`.
Takes `stream/4`'s `:conversation` and `:timeout`.

# `resolved`

```elixir
@spec resolved(Wardrik.Scope.t(), String.t() | struct()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Read what an agent gets.

    Wardrik.Agent.resolved(scope, "agt_1")

Returns what the app gives the agent: who it works for, its policies, MCP servers and their tools, notify targets, channels and workspaces.

`GET /v1/agents/{agent}/resolved`

# `runs`

```elixir
@spec runs(Wardrik.Scope.t(), String.t() | struct(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Read an agent's runs and their cost.

    Wardrik.Agent.runs(scope, "agt_1")

Add `conversation: "C1"` to act on one of the agent's conversations.

`GET /v1/agents/{agent}/runs`

# `runtime`

```elixir
@spec runtime(Wardrik.Scope.t(), String.t() | struct()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Read an agent's resource use.

    Wardrik.Agent.runtime(scope, "agt_1")

Returns the memory, mailbox size and work of a running agent's processes. Returns not_found while the agent is asleep.

`GET /v1/agents/{agent}/runtime`

# `spawn`

```elixir
@spec spawn(Wardrik.Scope.t(), String.t() | struct()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Start an agent.

    Wardrik.Agent.spawn(scope, "agt_1")

`POST /v1/agents/{agent}/spawn`

# `stop`

```elixir
@spec stop(Wardrik.Scope.t(), String.t() | struct(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Stop an agent.

    Wardrik.Agent.stop(scope, "agt_1")

Add `conversation: "C1"` to act on one of the agent's conversations.

`POST /v1/agents/{agent}/stop`

# `stream`

```elixir
@spec stream(Wardrik.Scope.t(), String.t() | t(), term(), keyword()) ::
  Enumerable.t() | {:ok, reference()}
```

Sends the agent a message and streams the text of its answer.

    scope |> Wardrik.Agent.stream("agt_1", "What's on fire?") |> Enum.each(&IO.write/1)

  * The stream ends when the run ends or fails. `reply/4` says how it ended.
  * Raises `Wardrik.Error` if the agent can't be reached.
  * With `to: pid`, returns `{:ok, ref}`. `pid` receives `{Wardrik, ref, {:text, chunk}}`, then
    `{:done, %Wardrik.Reply{}}`, `{:waiting, interrupts}` or `{:failed, why}`.

## Options

  * `:conversation` - the conversation to send it to. The main one unless set.
  * `:to` - a pid to send the answer to, in place of returning a stream.
  * `:timeout` - milliseconds to wait for each part of the answer. Ten minutes unless set.

# `stream_events`

```elixir
@spec stream_events(Wardrik.Scope.t(), String.t() | struct(), term(), keyword()) ::
  {:ok, Enumerable.t()} | :ok | {:error, Wardrik.Error.t()}
```

Read an agent's events, then follow new events as they arrive. Returns `{:ok, stream}` of `{%Wardrik.Event{}, cursor}` pairs.

    Wardrik.Agent.stream_events(scope, "agt_1", input)

Add `conversation: "C1"` to act on one of the agent's conversations.

`GET /v1/agents/{agent}/events`

# `timeline`

```elixir
@spec timeline(Wardrik.Scope.t(), String.t() | struct(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Read an agent's conversation.

    Wardrik.Agent.timeline(scope, "agt_1")

Add `conversation: "C1"` to act on one of the agent's conversations.

`GET /v1/agents/{agent}/timeline`

# `to_json`

```elixir
@spec to_json(t()) :: map()
```

Returns it as the protocol's JSON, without fields that are `nil`.

# `trigger_remove`

```elixir
@spec trigger_remove(Wardrik.Scope.t(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Remove an agent's trigger.

    Wardrik.Agent.trigger_remove(scope, agent: "agt_1", trigger: "daily")

`DELETE /v1/agents/{agent}/triggers/{trigger}`

# `trigger_set`

```elixir
@spec trigger_set(Wardrik.Scope.t(), keyword()) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Create or update an agent's trigger.

    Wardrik.Agent.trigger_set(scope, agent: "agt_1", trigger: "daily")

Creates or updates one trigger and saves it in the agent's definition. Returns not_found if the agent has no definition. If every and timezone don't change, the next run time is kept.

`PUT /v1/agents/{agent}/triggers/{trigger}`

---

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