# `Nous.LLM`
[🔗](https://github.com/nyo16/nous/blob/v0.17.1/lib/nous/llm.ex#L1)

Simple LLM API for direct model calls without agents.

This module provides a lightweight interface for making LLM calls
without the full agent machinery. Use this when you need simple
text generation, optionally with tools.

## Examples

    # Simple generation
    {:ok, text} = Nous.generate_text("openai:gpt-4", "What is 2+2?")
    IO.puts(text) # "4"

    # With options
    text = Nous.generate_text!("anthropic:claude-haiku-4-5", "Hello",
      system: "You are a pirate",
      temperature: 0.7,
      max_tokens: 500
    )

    # With tools
    {:ok, text} = Nous.generate_text("openai:gpt-4", "What's the weather in Paris?",
      tools: [&MyTools.get_weather/2]
    )

    # Streaming
    {:ok, stream} = Nous.stream_text("openai:gpt-4", "Write a story")
    stream |> Stream.each(&IO.write/1) |> Stream.run()

# `option`

```elixir
@type option() ::
  {:system, String.t()}
  | {:temperature, float()}
  | {:max_tokens, pos_integer()}
  | {:top_p, float()}
  | {:base_url, String.t()}
  | {:api_key, String.t()}
  | {:receive_timeout, non_neg_integer()}
  | {:tools, [function() | Nous.Tool.t()]}
  | {:deps, map()}
  | {:fallback, [String.t() | Nous.Model.t()]}
  | {:approval_handler, Nous.RunContext.approval_handler()}
  | {:model_dispatcher, module()}
```

# `generate_text`

```elixir
@spec generate_text(String.t() | Nous.Model.t(), String.t(), [option()]) ::
  {:ok, String.t()} | {:error, term()}
```

Generate text from a model.

Returns `{:ok, text}` on success, `{:error, reason}` on failure.

If tools are provided and the model calls them, they will be executed
automatically and the conversation will continue until the model returns
a text response.

## Parameters

  * `model` - Model string ("provider:model-name") or `%Model{}` struct
  * `prompt` - The user prompt
  * `opts` - Options (see below)

## Options

  * `:system` - System prompt
  * `:temperature` - Sampling temperature (0.0 to 2.0)
  * `:max_tokens` - Maximum tokens to generate
  * `:top_p` - Nucleus sampling parameter
  * `:base_url` - Override API base URL
  * `:api_key` - Override API key
  * `:receive_timeout` - HTTP receive timeout in milliseconds (default varies by provider)
  * `:tools` - List of tool functions or Tool structs
  * `:deps` - Dependencies to pass to tool functions
  * `:fallback` - Ordered list of fallback model strings or `Model` structs to try
    when the primary model fails with a provider/model error
  * `:approval_handler` - Called before any tool with `requires_approval: true`
    runs (`Nous.Tools.Bash`, `FileWrite`, `FileEdit`). Without it those tools
    are rejected rather than executed — this entry point has no other gate.
  * `:model_dispatcher` - Override the module that performs the provider
    request, for this call only. Takes precedence over
    `config :nous, :model_dispatcher`. Mostly useful in tests; see
    `Nous.ModelDispatcher.resolve/1`.

## Examples

    {:ok, text} = Nous.LLM.generate_text("openai:gpt-4", "What is 2+2?")

    {:ok, text} = Nous.LLM.generate_text("anthropic:claude-haiku-4-5", "Hello",
      system: "You are helpful",
      temperature: 0.7
    )

    # With tools
    {:ok, text} = Nous.LLM.generate_text("openai:gpt-4", "What's the weather?",
      tools: [&MyTools.get_weather/2],
      deps: %{api_key: "..."}
    )

# `generate_text!`

```elixir
@spec generate_text!(String.t() | Nous.Model.t(), String.t(), [option()]) ::
  String.t()
```

Generate text from a model, raising on error.

Same as `generate_text/3` but raises `Nous.Errors.ModelError` on failure.

## Examples

    text = Nous.LLM.generate_text!("openai:gpt-4", "What is 2+2?")
    IO.puts(text) # "4"

# `stream_text`

```elixir
@spec stream_text(String.t() | Nous.Model.t(), String.t(), [option()]) ::
  {:ok, Enumerable.t()} | {:error, term()}
```

Stream text from a model.

Returns `{:ok, stream}` where `stream` yields text chunks as strings.

## Parameters

  * `model` - Model string ("provider:model-name") or `%Model{}` struct
  * `prompt` - The user prompt
  * `opts` - Options (same as `generate_text/3`)

## Examples

    {:ok, stream} = Nous.LLM.stream_text("openai:gpt-4", "Write a haiku")
    stream |> Stream.each(&IO.write/1) |> Stream.run()

---

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