# `Sake.Sampling`
[🔗](https://github.com/hattoriai/sake/blob/v0.4.3/lib/sake/sampling.ex#L1)

Asks the client's model to complete a conversation from inside a
component (`sampling/createMessage`).

    case Sake.Sampling.create_message(ctx, :summary, [user: "Summarize: " <> text], max_tokens: 200) do
      {:ok, %Sake.Sampling.Result{text: summary}} -> {:ok, summary}
      {:error, :unsupported} -> {:error, "This tool needs a client that supports sampling."}
      {:error, _reason} -> {:error, "The client could not sample."}
    end

Sampling is deprecated in the 2026-07-28 revision (SEP-2577) but still
part of it, and many clients still use it; Sake supports it on every
revision. The call travels exactly like a `Sake.Elicit` call: on a
modern connection it ends the handler and returns the answer when the
client retries (so no side effects before it), on a legacy connection it
blocks until the client answers on the stream, and inside a task it
waits for the client's `tasks/update`.

`messages` is a list of `{role, content}` pairs, as a prompt returns
them: `role` is `:user` or `:assistant`, `content` a string, a
`Sake.Content`, a list of them, or a content map as it goes on the wire.
A message map as it goes on the wire is accepted too.

Options: `max_tokens` (required), `system_prompt`, `temperature`,
`stop_sequences`, `model_preferences` (a wire map, or a keyword list of
`hints` (model names), `cost_priority`, `speed_priority` and
`intelligence_priority`), `include_context` (`:none`, `:this_server` or
`:all_servers`), `metadata`, and from revision 2025-11-25 on, `tools`
(tool modules, `Sake.Tool.Spec`s or wire maps) and `tool_choice`
(`:auto`, `:required` or `:none`).

Returns `{:ok, %Sake.Sampling.Result{}}`, `{:error, :unsupported}` when
the client did not declare `sampling` (or, with `tools`, did not declare
`sampling.tools`), `{:error, :cancelled}` when the task the call
waits in was cancelled, `{:error, :timeout}` when a legacy client never
answered, `{:error, :invalid_response}` when the answer is not a result
object, and `{:error, error}` with the JSON-RPC error map a legacy client
answered with.

# `message`

```elixir
@type message() ::
  {atom() | String.t(),
   String.t() | Sake.Content.t() | [Sake.Content.t() | map()] | map()}
  | map()
```

# `create_message`

```elixir
@spec create_message(Sake.Context.t(), atom() | String.t(), [message()], keyword()) ::
  {:ok, Sake.Sampling.Result.t()}
  | {:error, :unsupported | :cancelled | :timeout | :invalid_response | map()}
```

---

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