> ## 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.

# Quickstart

> Build from a model call to a stateful agent

This guide teaches the product in the same order you should use it:

1. call a model
2. stream a response
3. add a tool
4. create an agent
5. persist state
6. inspect a structured turn
7. build a live turn

## Install

<CodeGroup>
  ```bash pip theme={null}
  pip install ai-query
  ```

  ```bash uv theme={null}
  uv add ai-query
  ```

  ```bash poetry theme={null}
  poetry add ai-query
  ```
</CodeGroup>

## 1. Call A Model

Use `generate_text()` when you do not need state.

```python theme={null}
import asyncio

from ai_query import generate_text
from ai_query.providers import openai


async def main():
    result = await generate_text(
        model=openai("gpt-4o"),
        prompt="Explain quantum computing in one sentence.",
    )
    print(result.text)


asyncio.run(main())
```

What you learned:

* providers create models
* `generate_text()` runs one model loop
* the result contains text, usage, finish reason, and steps

## 2. Stream A Response

Use `stream_text()` for raw streaming.

```python theme={null}
from ai_query import stream_text
from ai_query.providers import openai


result = stream_text(
    model=openai("gpt-4o"),
    prompt="Write a haiku about programming.",
)

async for chunk in result.text_stream:
    print(chunk, end="", flush=True)
```

Use core streaming for scripts and simple UIs. Use `Agent.turn()` later when you need events and steering.

## 3. Add A Tool

Tools are typed Python functions the model can call.

```python theme={null}
from ai_query import Field, generate_text, tool
from ai_query.providers import openai


@tool(description="Get the current weather for a location")
async def get_weather(
    location: str = Field(description="The city name"),
) -> str:
    return f"The weather in {location} is 72F and sunny."


result = await generate_text(
    model=openai("gpt-4o"),
    prompt="What's the weather like in Tokyo?",
    tools={"get_weather": get_weather},
)

print(result.text)
```

What you learned:

* `@tool` turns a Python function into a model-callable tool
* tool arguments are described with type hints and `Field`
* ai-query handles the tool-call loop

## 4. Create An Agent

Use `Agent` when you want memory, state, or persistence.

```python theme={null}
from ai_query.agents import Agent
from ai_query.providers import openai


agent = Agent("assistant", model=openai("gpt-4o"))

async with agent:
    print(await agent.chat("My name is Alice."))
    print(await agent.chat("What's my name?"))
```

What changed:

* the agent has an identity: `assistant`
* message history is stored on the agent
* `chat()` appends the user message and assistant response

## 5. Persist Agent History

Use `SQLiteStorage` when you want history to survive restarts.

```python theme={null}
from ai_query.agents import Agent, SQLiteStorage
from ai_query.providers import openai


agent = Agent(
    "assistant",
    model=openai("gpt-4o"),
    storage=SQLiteStorage("agents.sqlite3"),
)

async with agent:
    print(await agent.chat("Remember: my favorite color is blue."))
```

Later, recreate the same agent ID with the same storage file:

```python theme={null}
agent = Agent(
    "assistant",
    model=openai("gpt-4o"),
    storage=SQLiteStorage("agents.sqlite3"),
)

async with agent:
    print(await agent.chat("What's my favorite color?"))
```

## 6. Get A Structured Result

Use `run()` when your app needs more than final text.

```python theme={null}
result = await agent.run("Investigate why the tests are failing.")

print(result.text)
print(result.finish_reason)
print(result.usage.total_tokens if result.usage else None)
print(len(result.steps))
```

Use `chat()` for user-facing responses. Use `run()` when your application logic needs the metadata.

## 7. Build A Live Turn

Use `turn()` for CLIs, web UIs, SSE streams, and controllable runtimes.

```python theme={null}
turn = agent.turn("Fix the failing test")

async for event in turn.events():
    if event.type == "text.delta":
        print(event.text, end="", flush=True)
    elif event.type == "step.started":
        print(f"\nstep {event.step_number}")

result = await turn.result()
```

Steer a live turn at the next safe step boundary:

```python theme={null}
await turn.send("Change direction: inspect database migrations first.")
```

Abort a live turn:

```python theme={null}
turn.abort("user cancelled")
```

## What To Read Next

<CardGroup cols={2}>
  <Card title="Concepts" icon="map" href="/core/overview">
    Learn the mental model behind the framework.
  </Card>

  <Card title="Navigating ai-query" icon="signs-post" href="/core/navigating-ai-query">
    Choose the right API for your use case.
  </Card>

  <Card title="Stateful Agents" icon="database" href="/core/stateful-agents">
    Go deeper on storage, state, and conversations.
  </Card>

  <Card title="Live Turns" icon="route" href="/core/live-turns">
    Build interactive runtimes with events and steering.
  </Card>
</CardGroup>
