> ## Documentation Index
> Fetch the complete documentation index at: https://thethirdpenco-feat-tool-lifecycle-events.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# generate_text

> API reference for non-streaming text generation

`generate_text()` runs the model/tool loop and returns a completed `GenerateTextResult`.

Use it for one-off, non-streaming model calls where you do not need agent state.

## Import

```python theme={null}
from ai_query import generate_text
```

## Signature

```python theme={null}
async def generate_text(
    *,
    model: LanguageModel,
    prompt: str | None = None,
    system: str | None = None,
    messages: list[Message] | list[dict[str, Any]] | None = None,
    tools: ToolSet | None = None,
    stop_when: StopCondition | list[StopCondition] | None = None,
    on_step_start: OnStepStart | None = None,
    on_step_finish: OnStepFinish | None = None,
    retry: RetryPolicy | None = None,
    on_retry: OnRetry | None = None,
    provider_options: ProviderOptions | None = None,
    reasoning: ReasoningConfig | None = None,
    signal: AbortSignal | None = None,
    **kwargs: Any,
) -> GenerateTextResult
```

## Parameters

<ParamField path="model" type="LanguageModel" required>
  Language model instance. Create one with a provider factory such as `openai("gpt-4o")`, `anthropic(...)`, or `google(...)`.
</ParamField>

<ParamField path="prompt" type="str | None">
  Convenience user prompt. If `messages` is not provided, `prompt` is converted to a user message.
</ParamField>

<ParamField path="system" type="str | None">
  Optional system prompt. Only used when `messages` is not provided.
</ParamField>

<ParamField path="messages" type="list[Message] | list[dict[str, Any]] | None">
  Explicit message list. When provided, `prompt` and `system` are ignored.
</ParamField>

<ParamField path="tools" type="ToolSet | None">
  Mapping of tool name to `Tool`. Tool definitions are usually created with `@tool`.
</ParamField>

<ParamField path="stop_when" type="StopCondition | list[StopCondition] | None">
  Stop condition or list of stop conditions for the tool loop. Defaults to `step_count_is(1)`.
</ParamField>

<ParamField path="on_step_start" type="OnStepStart | None">
  Called before each provider request. May return `StepControl` to inject messages or stop at a step boundary.
</ParamField>

<ParamField path="on_step_finish" type="OnStepFinish | None">
  Called after each step completes, including tool calls and tool results.
</ParamField>

<ParamField path="retry" type="RetryPolicy | None">
  Provider-call retry policy. By default, retries are conservative: transient HTTP statuses (`408`, `409`, `425`, `429`, `500`, `502`, `503`, `504`) and network/timeout failures are retried; clear client errors such as `400`, `401`, and `403` are not. Retries happen at the current model step and do not re-run completed tools.
</ParamField>

<ParamField path="on_retry" type="OnRetry | None">
  Called before a retry attempt with the step number, attempt, delay, and sanitized error string.
</ParamField>

<ParamField path="provider_options" type="ProviderOptions | None">
  Provider-specific options keyed by provider name.
</ParamField>

<ParamField path="reasoning" type="ReasoningConfig | None">
  Provider-agnostic reasoning controls such as `effort` or `budget`.
</ParamField>

<ParamField path="signal" type="AbortSignal | None">
  Abort signal used to cancel the generation loop, including in-flight provider calls, retry sleeps, embeddings, and async tool calls.
</ParamField>

<ParamField path="**kwargs" type="Any">
  Additional provider-specific keyword arguments passed to the provider call.
</ParamField>

## Returns

<ResponseField name="GenerateTextResult" type="GenerateTextResult">
  Completed text generation result.
</ResponseField>

Fields:

<ResponseField name="text" type="str">
  Accumulated generated text.
</ResponseField>

<ResponseField name="steps" type="list[StepResult]">
  Step-by-step model/tool loop history.
</ResponseField>

<ResponseField name="finish_reason" type="str | None">
  Provider finish reason for the final response.
</ResponseField>

<ResponseField name="usage" type="Usage | None">
  Provider-reported usage for the final model step.
</ResponseField>

<ResponseField name="response" type="dict[str, Any]">
  Raw provider response metadata used by the provider implementation.
</ResponseField>

<ResponseField name="provider_metadata" type="dict[str, Any]">
  Additional provider metadata.
</ResponseField>

Computed properties:

<ResponseField name="tool_calls" type="list[ToolCall]">
  Flattened tool calls from all steps.
</ResponseField>

<ResponseField name="tool_results" type="list[ToolResult]">
  Flattened tool results from all steps.
</ResponseField>

## Raises

<ResponseField name="ValueError" type="Exception">
  Raised when neither `prompt` nor `messages` is provided.
</ResponseField>

<ResponseField name="AbortError" type="Exception">
  Raised when `signal` is aborted.
</ResponseField>

<ResponseField name="RuntimeError" type="Exception">
  Raised if the generation loop exits without a final result.
</ResponseField>

## Examples

### Basic call

```python theme={null}
result = await generate_text(
    model=openai("gpt-4o"),
    prompt="What is Python?",
)

print(result.text)
```

### Explicit messages

```python theme={null}
from ai_query.types import Message


result = await generate_text(
    model=model,
    messages=[
        Message(role="user", content="My name is Ada."),
        Message(role="assistant", content="Nice to meet you, Ada."),
        Message(role="user", content="What is my name?"),
    ],
)
```

### Tool loop

```python theme={null}
result = await generate_text(
    model=model,
    prompt="Search the docs and summarize installation.",
    tools={"search_docs": search_docs},
    stop_when=step_count_is(5),
)
```

### Step control

```python theme={null}
from ai_query import StepControl
from ai_query.types import Message


async def on_step_start(event):
    if event.step_number == 2:
        return StepControl(
            inject_messages=[Message(role="user", content="Keep the final answer short.")]
        )
    return None


result = await generate_text(
    model=model,
    prompt="Research this topic.",
    tools=tools,
    on_step_start=on_step_start,
)
```

### Retry provider failures

```python theme={null}
from ai_query import RetryPolicy


async def on_retry(event):
    print(f"retrying step {event.step_number}, attempt {event.attempt}")


result = await generate_text(
    model=model,
    prompt="Summarize the incident.",
    retry=RetryPolicy(max_attempts=3),
    on_retry=on_retry,
)
```

## See Also

* [stream\_text](/reference/stream-text)
* [Results](/reference/types/results)
* [Stop Conditions](/reference/types/stop-conditions)
* [Tool Loops](/core/agents)
