# `WardrikCore.Context`

The state passed through a turn's middleware.

`step` says which step is running: `:turn`, `:generate` (a model call), `{:tool_call, call}`, or
`{:step, name}` for your own. Middleware reads and changes the rest, such as `messages`,
`response` and `attributes`.

# `entry`

```elixir
@type entry() :: module() | {module(), term()}
```

# `step`

```elixir
@type step() ::
  :turn
  | :generate
  | {:tool_call, WardrikCore.ToolCall.t()}
  | {:step, String.t()}
```

# `t`

```elixir
@type t() :: %WardrikCore.Context{
  agent_id: String.t(),
  attributes: map(),
  call_started: (String.t() -&gt; :ok) | nil,
  capabilities: [entry()],
  checkpoint: (map() -&gt; :ok) | nil,
  credentials: entry() | nil,
  events: entry() | nil,
  instructions: String.t() | nil,
  keys: entry() | nil,
  max_rounds: pos_integer() | :infinity,
  measurements: %{optional(term()) =&gt; number()},
  messages: [ReqLLM.Message.t()],
  metadata: map(),
  middleware: [entry()],
  model: LLMDB.Model.t() | String.t(),
  on_chunk: [(ReqLLM.StreamChunk.t() -&gt; any())],
  prices: %{optional(String.t()) =&gt; WardrikCore.Usage.price()},
  principal: WardrikCore.Principal.t() | nil,
  private: map(),
  response: ReqLLM.Response.t() | {:ok, term()} | {:error, term()} | nil,
  resume: WardrikCore.Resume.t() | nil,
  retries: WardrikCore.Retry.t(),
  span: WardrikCore.Span.t() | nil,
  step: step() | nil,
  subagent: String.t() | nil,
  timeout: timeout(),
  tools: [WardrikCore.Tool.t()]
}
```

# `acting_for`

```elixir
@spec acting_for(t()) :: WardrikCore.Principal.t() | nil
```

Returns who the turn acts for.

That's the principal who sent the latest message. If it has none, it's the agent's own
principal, or `nil`.

# `attribute`

```elixir
@spec attribute(t(), String.t() | atom(), term()) :: t()
```

Sets an attribute on the current step, like an OpenTelemetry span attribute.

    Context.attribute(context, "gen_ai.tool.name", call.name)

Use OpenTelemetry's names, or your own prefix.

# `entry`

```elixir
@spec entry(entry()) :: {module(), term()}
```

Returns a capability or middleware entry as `{module, opts}`. A bare module gets `[]`.

# `get_private`

```elixir
@spec get_private(t(), term(), term()) :: term()
```

Returns the private value under `key`, or `default`.

# `labels`

```elixir
@spec labels(t() | [ReqLLM.Message.t()]) :: [String.t()]
```

Returns the labels in the turn's messages, or in `messages`, sorted and without duplicates.

A label stays with the history it came in until the history is cleared. Core carries labels but
decides nothing from them.

`"outside"` marks content nobody on the agent's side wrote, such as a web page or an issue a
stranger filed. Such content may be what asks for the next call.

# `measure`

```elixir
@spec measure(t(), map()) :: t()
```

Adds each of `measurements`, such as those `WardrikCore.evaluate/4` returns.

# `measure`

```elixir
@spec measure(t(), term(), number()) :: t()
```

Adds `amount` to the measurement `key`, such as tokens or dollars spent.

    Context.measure(context, :usd, 0.01)

Measurements add up over the turn. Each step reports its own share when it ends.

Core measures each model call's `input_tokens` and `output_tokens`. It also measures `usd` if
the model has a price in the agent's `prices` or the model catalog. Otherwise it counts the call
in `unpriced_calls`.

# `new`

# `put_private`

```elixir
@spec put_private(t(), term(), term()) :: t()
```

Puts `value` in the private data under `key`. Use your own module as the key.

# `run`

```elixir
@spec run(t(), WardrikCore.Middleware.next()) :: WardrikCore.Middleware.result()
```

Runs `fun` through the context's middleware. The first in the list runs outermost.

# `run`

```elixir
@spec run(t(), step(), WardrikCore.Middleware.next()) ::
  WardrikCore.Middleware.result()
```

Runs `fun` through the middleware as `step`, in a span of its own. Then restores the outer step.

    Context.run(context, {:step, "summarize"}, &summarize/1)

Name your own steps `{:step, name}`.

# `tool`

```elixir
@spec tool(t(), WardrikCore.ToolCall.t()) :: WardrikCore.Tool.t() | nil
```

Returns the tool `call` names, or `nil`.

# `update_private`

```elixir
@spec update_private(t(), term(), term(), (term() -&gt; term())) :: t()
```

Updates the private value under `key` with `fun`. Puts `default` if there's none yet.

---

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