# `Wardrik.Agent`

An agent, and the operations on one.

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

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

## Fields

  * `:id` - the agent's ID, as `"acme/triage"`.
  * `:name` - its name.
  * `: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.

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

# `t`

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

# `approve`

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

Approve a call an agent waits on

agent.decide with one approval. Recorded as the caller's.

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

# `ask`

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

Send an agent a message

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

# `authorization`

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

Read where a person authorizes a call

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

# `calls`

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

List the tool calls an agent is running

Answers not_found while the agent sleeps.

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

# `cancel`

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

Stop what an agent is doing

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

# `clear`

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

Empty an agent's conversation

Answers conflict while it runs a turn or waits on a person.

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

# `decide`

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

Approve or reject the calls an agent waits on

The decisions are taken together and recorded as the caller's. A rejection's reason is what the model is told in place of the call's answer. An approval's note is what it reads beside the answer.

`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

Starts the agent the definition describes, or brings the one running to it from its next turn. A definition put again replaces the last. A key nothing here supports yet answers not_supported, naming it.

`PUT /v1/agents/{agent}`

# `definition`

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

Read an agent's definition

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

# `deny`

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

Reject a call an agent waits on

agent.decide with one rejection. Recorded as the caller's.

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

# `events`

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

Read an agent's log

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

# `forget`

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

Forget an agent

`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 the `agents.list` output.

# `kill`

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

Stop one tool call

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

# `move`

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

Move an agent to another node

Starts the agent again on node, as it was. A turn it's taking ends, and what it waits on is abandoned, so ask it again once it's moved.

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

# `read`

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

Read what an agent is doing now

`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, "acme/triage", "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. Returns `{:error, %Wardrik.Error{}}`
if the agent can't be reached or the run fails. Takes the `:timeout` option of `stream/4`.

# `runs`

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

Read what an agent's runs did and cost

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

# `spawn`

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

Start an agent

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

# `stop`

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

Stop an agent

`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("acme/triage", "What's on fire?") |> Enum.each(&IO.write/1)

The stream ends when the run ends, including when it fails. Use `reply/4` to see how it ended.
Raises `Wardrik.Error` if the agent can't be reached.

With `to: pid`, returns `{:ok, ref}` and sends `pid` each item as `{Wardrik, ref, item}`:

  1. `{:text, chunk}`, any number of times.
  2. One of `{:done, %Wardrik.Reply{}}`, `{:waiting, interrupts}` or `{:failed, why}`.

## Options

  * `: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()) ::
  {:ok, Enumerable.t()} | :ok | {:error, Wardrik.Error.t()}
```

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

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

# `timeline`

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

Read an agent's conversation as a person reads it

`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(),
  String.t() | struct(),
  String.t() | struct(),
  term()
) ::
  term() | :ok | {:error, Wardrik.Error.t()}
```

Remove one of an agent's triggers

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

# `trigger_set`

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

Set one of an agent's triggers

Sets or changes one trigger of an agent with a definition, which keeps it; not_found where it has none. A trigger whose every and timezone stay keeps its next run.

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

---

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