# `ReqLLM.Generation`
[🔗](https://github.com/agentjido/req_llm/blob/main/lib/req_llm/generation.ex#L1)

Text generation functionality for ReqLLM.

This module provides the core text generation capabilities including:
- Text generation with full response metadata
- Text streaming with metadata
- Usage and cost extraction utilities

All functions follow Vercel AI SDK patterns and return structured responses
with proper error handling.

# `generate_object`

```elixir
@spec generate_object(
  ReqLLM.generation_model_input(),
  ReqLLM.Context.prompt(),
  keyword() | map() | Zoi.Type.t(),
  keyword()
) :: {:ok, ReqLLM.Response.t()} | {:error, term()}
```

Generates structured data using an AI model with schema validation.

Returns a canonical ReqLLM.Response which includes the generated object, usage data,
context, and metadata. For simple object-only results, use `generate_object!/4`.

## Parameters

  * `model_spec` - Model specification in various formats
  * `messages` - Text prompt or list of messages
  * `schema` - Schema definition for structured output (keyword list) or Zoi schema
  * `opts` - Additional options (keyword list)

## Options

  * `:temperature` - Control randomness in responses (0.0 to 2.0)
  * `:max_tokens` - Limit the length of the response
  * `:top_p` - Nucleus sampling parameter
  * `:presence_penalty` - Penalize new tokens based on presence
  * `:frequency_penalty` - Penalize new tokens based on frequency
  * `:system_prompt` - System prompt to prepend
  * `:receive_timeout` - Provider-transport inactivity timeout in milliseconds
  * `:total_timeout` - Optional whole-call deadline in milliseconds, including retries
  * `:stream_idle_timeout` - Optional semantic-progress timeout for streaming calls
  * `:provider_options` - Provider-specific options
  * `:routing_context` - Opaque application data for a `ReqLLM.Router`
    callback. It must be a map. ReqLLM passes it unchanged to the router and
    does not send it to the selected provider
  * `:output_validation` - Final validation policy: `:compatible`, `:warn`, or
    `:strict`; omitted calls preserve current V1 behavior
  * `:output_repair` - Optional one-argument local repair callback invoked at
    most once after an invalid complete object

## Examples

    {:ok, response} = ReqLLM.Generation.generate_object("anthropic:claude-3-sonnet", "Generate a person", person_schema)
    ReqLLM.Response.object(response)
    #=> %{name: "Alice Smith", age: 30, occupation: "Engineer"}

    # Access usage metadata
    ReqLLM.Response.usage(response)
    #=> %{input_tokens: 25, output_tokens: 15}

# `generate_object!`

```elixir
@spec generate_object!(
  String.t() | {atom(), keyword()} | struct(),
  ReqLLM.Context.prompt(),
  keyword() | map() | Zoi.Type.t(),
  keyword()
) :: map() | no_return()
```

Generates structured data using an AI model, returning only the object content.

This is a convenience function that extracts just the object from the response.
For access to usage metadata and other response data, use `generate_object/4`.
Raises on error.

## Parameters

Same as `generate_object/4`.

## Examples

    ReqLLM.Generation.generate_object!("anthropic:claude-3-sonnet", "Generate a person", person_schema)
    #=> %{name: "Alice Smith", age: 30, occupation: "Engineer"}

# `generate_text`

```elixir
@spec generate_text(
  ReqLLM.generation_model_input(),
  ReqLLM.Context.prompt(),
  keyword()
) :: {:ok, ReqLLM.Response.t()} | {:error, term()}
```

Generates text using an AI model with full response metadata.

Returns a canonical ReqLLM.Response which includes usage data, context, and metadata.
For simple text-only results, use `generate_text!/3`.

## Parameters

  * `model_spec` - Model specification in various formats
  * `messages` - Text prompt or list of messages
  * `opts` - Additional options (keyword list)

## Options

  * `:temperature` - Control randomness in responses (0.0 to 2.0)
  * `:max_tokens` - Limit the length of the response
  * `:top_p` - Nucleus sampling parameter
  * `:presence_penalty` - Penalize new tokens based on presence
  * `:frequency_penalty` - Penalize new tokens based on frequency
  * `:tools` - List of tool definitions
  * `:tool_choice` - Tool choice strategy
  * `:output` - A `ReqLLM.Output` descriptor; omitted and `ReqLLM.Output.text/0`
    preserve plain-text behavior, while structured descriptors reuse the existing
    provider-native or tool-fallback object path
  * `:output_validation` - Final validation policy: `:compatible`, `:warn`, or
    `:strict`; omitted calls preserve current V1 behavior
  * `:output_repair` - Optional one-argument local repair callback invoked at
    most once after an invalid complete structured output
  * `:system_prompt` - System prompt to prepend
  * `:receive_timeout` - Provider-transport inactivity timeout in milliseconds
  * `:total_timeout` - Optional whole-call deadline in milliseconds, including retries
  * `:stream_idle_timeout` - Optional semantic-progress timeout for streaming calls
  * `:provider_options` - Provider-specific options
  * `:routing_context` - Opaque application data for a `ReqLLM.Router`
    callback. It must be a map. ReqLLM passes it unchanged to the router and
    does not send it to the selected provider

## Examples

    {:ok, response} = ReqLLM.Generation.generate_text("anthropic:claude-3-sonnet", "Hello world")
    ReqLLM.Response.text(response)
    #=> "Hello! How can I assist you today?"

    # Access usage metadata
    ReqLLM.Response.usage(response)
    #=> %{input_tokens: 10, output_tokens: 8}

    output = ReqLLM.Output.object([name: [type: :string, required: true]])
    {:ok, response} = ReqLLM.Generation.generate_text(model, "Generate a person", output: output)
    ReqLLM.Response.output(response, output)
    #=> %{"name" => "Ada"}

# `generate_text!`

```elixir
@spec generate_text!(
  ReqLLM.generation_model_input(),
  ReqLLM.Context.prompt(),
  keyword()
) :: String.t() | no_return()
```

Generates text using an AI model, returning only the text content.

This is a convenience function that extracts just the text from the response.
For access to usage metadata and other response data, use `generate_text/3`.
Raises on error. This function remains a text-only convenience; use
`generate_text/3` and `ReqLLM.Response.output/2` for structured descriptors.

## Parameters

Same as `generate_text/3`.

## Examples

    ReqLLM.Generation.generate_text!("anthropic:claude-3-sonnet", "Hello world")
    #=> "Hello! How can I assist you today?"

# `schema`

```elixir
@spec schema() :: NimbleOptions.t()
```

Returns the base generation options schema.

This schema delegates to ReqLLM.Provider.Options.generation_schema/0 which is
the canonical runtime options schema. Provider-specific options should be
validated separately by each provider via Provider.Options.process/4.

For the complete schema including provider extensions, use:
    Provider.Options.compose_schema(Provider.Options.generation_schema(), provider_mod)

# `stream_object`

```elixir
@spec stream_object(
  ReqLLM.generation_model_input(),
  ReqLLM.Context.prompt(),
  keyword() | Zoi.Type.t(),
  keyword()
) :: {:ok, ReqLLM.StreamResponse.t()} | {:error, term()}
```

Streams structured data generation using an AI model with schema validation.

Returns a `ReqLLM.StreamResponse` that provides both real-time structured data streaming
and concurrent metadata collection. Uses the same Finch-based streaming infrastructure
as `stream_text/3` with connection pooling and configurable checkout timeouts.

## Parameters

  * `model_spec` - Model specification in various formats
  * `messages` - Text prompt or list of messages
  * `schema` - Schema definition for structured output (keyword list) or Zoi schema
  * `opts` - Additional options (keyword list)

## Options

Same as `generate_object/4`.

## Returns

  * `{:ok, stream_response}` - StreamResponse with object stream and metadata task
  * `{:error, reason}` - Request failed or invalid parameters

## Examples

    # Stream structured data generation
    {:ok, response} = ReqLLM.Generation.stream_object("anthropic:claude-3-sonnet", "Generate a person", person_schema)

    # Process structured chunks as they arrive
    response.stream
    |> Stream.filter(&(&1.type in [:content, :tool_call]))
    |> Stream.each(&IO.inspect/1)
    |> Stream.run()

    # Concurrent metadata collection
    usage = ReqLLM.StreamResponse.usage(response)
    #=> %{input_tokens: 25, output_tokens: 15, total_cost: 0.045}

## Structure Notes

Object streaming may include both content chunks (partial JSON) and tool_call chunks
depending on the provider's structured output implementation. Use appropriate filtering
based on your needs.

# `stream_object!`

> This function is deprecated. Use stream_object/4 with StreamResponse instead.

```elixir
@spec stream_object!(
  ReqLLM.generation_model_input(),
  ReqLLM.Context.prompt(),
  keyword() | Zoi.Type.t(),
  keyword()
) :: Enumerable.t() | no_return()
```

**DEPRECATED**: This function will be removed in a future version.

The streaming API has been redesigned to return a composite `StreamResponse` struct
that provides both the stream and metadata. Use `stream_object/4` instead:

    {:ok, response} = ReqLLM.Generation.stream_object(model, messages, schema)
    response.stream |> Enum.each(&IO.inspect/1)

For simple object extraction, use:

    object = ReqLLM.StreamResponse.object(response)

## Legacy Parameters

Same as `stream_object/4`.

## Legacy Examples

    ReqLLM.Generation.stream_object!("anthropic:claude-3-sonnet", "Generate a person", person_schema)
    |> Enum.each(&IO.inspect/1)

# `stream_text`

```elixir
@spec stream_text(
  ReqLLM.generation_model_input(),
  ReqLLM.Context.prompt(),
  keyword()
) :: {:ok, ReqLLM.StreamResponse.t()} | {:error, term()}
```

Streams text generation using an AI model with full response metadata.

Returns a canonical ReqLLM.Response containing usage data and stream.
For simple streaming without metadata, use `stream_text!/3`.

When `:output` is structured, the stream retains the existing object-stream
representation. Partial content and tool-call argument chunks are transport
fragments, not final-schema validation results. Materialize the stream once
with `ReqLLM.StreamResponse.to_response/1`, then call
`ReqLLM.Response.output/2` with the same descriptor. An explicit
`:output_validation` policy is enforced by `to_response/1` or
`ReqLLM.StreamResponse.process_stream/2` after the complete value exists.

## Parameters

Same as `generate_text/3`.

## Examples

    {:ok, response} = ReqLLM.Generation.stream_text("anthropic:claude-3-sonnet", "Tell me a story")
    ReqLLM.Response.text_stream(response) |> Enum.each(&IO.write/1)

    # Access usage metadata after streaming
    ReqLLM.Response.usage(response)
    #=> %{input_tokens: 15, output_tokens: 42}

# `stream_text!`

> This function is deprecated. Use stream_text/3 with StreamResponse instead.

```elixir
@spec stream_text!(
  ReqLLM.generation_model_input(),
  ReqLLM.Context.prompt(),
  keyword()
) :: Enumerable.t() | no_return()
```

**DEPRECATED**: This function will be removed in a future version.

The streaming API has been redesigned to return a composite `StreamResponse` struct
that provides both the stream and metadata. Use `stream_text/3` instead:

    {:ok, response} = ReqLLM.Generation.stream_text(model, messages)
    response.stream |> Enum.each(&IO.write/1)

For simple text extraction, use:

    text = ReqLLM.StreamResponse.text(response)

---

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