Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,25 @@ Draive is a python framework helping to build high-quality Gen-AI applications.
Top-level code lives under `src/draive/`, with key packages:

- `draive/models/` — core model abstractions (`GenerativeModel`, context/input/output types, session and tool-related model types)
- `draive/tools/` — tool abstractions and orchestration (`Tool`, `FunctionTool`, `Toolbox`, providers)
- `draive/agents/` — lightweight async agent wrappers and delegation (`Agent`, `AgentsGroup`, agent message/identity types)
- `draive/tools/` — tool abstractions and orchestration (`tool`, `Tool`, `CoroutineTool`, `GeneratorTool`, `Toolbox`, `ToolsProvider`)
- `draive/agents/` — lightweight async agent wrappers and delegation (`Agent`, `AgentsGroup`, `AgentMemory`, agent message/identity types)
- `draive/generation/` — typed generation facades (`text/`, `image/`, `audio/`, `model/`) with `state.py`, `types.py`, and `default.py`
- `draive/conversation/` — higher-level chat/realtime flows (`completion/`, `realtime/`)
- `draive/multimodal/` — multimodal content and templates (`MultimodalContent`, `TextContent`, `ArtifactContent`, template helpers)
- `draive/resources/` — resource references, fetching/uploading interfaces, repository abstractions
- `draive/embedding/` — embeddings, similarity/search/mmr, and typed embedding/vector index state
- `draive/guardrails/` — moderation, privacy, quality, and safety guardrail states/types
- `draive/steps/` — pipeline step abstractions (`Step`, `StepState`, composition/execution helpers)
- `draive/skills/` — skill abstractions (`Skill`, `SkillResource`) used by agents and tools
- `draive/evaluation/` — evaluation primitives (evaluators, scenarios, suites, scores)
- `draive/evaluators/` — ready-to-use evaluator catalog (coherence, relevance, safety, jailbreak, etc.)
- `draive/splitters/` — text splitting helpers
- `draive/helpers/` — high-level utilities (instruction preparation/refinement, volatile vector index)
- `draive/helpers/` — high-level utilities (instruction preparation/refinement, evaluation case generation, volatile vector index)
- `draive/utils/` — shared low-level utility helpers
- Provider adapters (feature-specific modules per provider):
- `draive/openai/`, `draive/anthropic/`, `draive/mistral/`, `draive/gemini/`, `draive/vllm/`, `draive/ollama/`, `draive/bedrock/`, `draive/cohere/`
- Integrations (opt-in extras):
- `draive/httpx/`, `draive/aws/`, `draive/qdrant/`, `draive/mcp/`, `draive/postgres/`, `draive/opentelemetry/`, `draive/rabbitmq/`
- `draive/httpx/`, `draive/aws/`, `draive/qdrant/`, `draive/surreal/`, `draive/mcp/`, `draive/postgres/`, `draive/opentelemetry/`, `draive/rabbitmq/`, `draive/starlette/`, `draive/fastapi/`

Public exports are centralized in `src/draive/__init__.py`.

Expand Down Expand Up @@ -66,7 +67,7 @@ Public exports are centralized in `src/draive/__init__.py`.

### Logging & Observability

- Use `ctx` observability helpers (`ctx.log_*`, `ctx.record`) instead of `print`/`logging`
- Use `ctx` observability helpers (`ctx.log_*`, `ctx.record_*`) instead of `print`/`logging`
- Surface user-facing failures via structured events before raising typed exceptions

## Testing & CI
Expand All @@ -75,7 +76,7 @@ Public exports are centralized in `src/draive/__init__.py`.
- Keep tests fast and specific to changed code
- Use fixtures from `tests/` or add focused ones; avoid heavy integration scaffolding for unit coverage
- Linting/type gates: `make format` then `make lint`
- Mirror package layout in `tests/`; prefer parametrization over loops
- Add tests as flat `tests/test_<area>_<feature>.py` modules (or into existing groups like `tests/evaluators/`, `tests/ollama/`); prefer parametrization over loops
- Test async flows with `pytest.mark.asyncio`; use `ctx.scope` in tests to isolate state
- Keep `reveal_type`-style type assertions local and remove before committing

Expand All @@ -98,7 +99,7 @@ Public exports are centralized in `src/draive/__init__.py`.

- Site is built with MkDocs + Material; PlantUML diagrams are built via `mkdocs-build-plantuml-plugin`
- Register navigation in `mkdocs.yml` (`nav:` section)
- Lint docs with `make docs-lint` and format with `make docs-format` after edits
- Lint docs with `make docs-lint` and format with `make docs-format` after edits; `make docs` builds the site with `--strict`
- Keep docstrings high-quality and aligned with public APIs

## Security & Secrets
Expand Down
38 changes: 36 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ from draive.openai import OpenAI, OpenAIResponsesConfig
async def current_time(location: str) -> str:
return f"Time in {location} is 9:53:22"

async with ctx.scope( # create execution context
async with ctx.scope( # create execution context
"example", # give it a name
OpenAIResponsesConfig(model="gpt-4o-mini"), # prepare configuration
OpenAIResponsesConfig(model="gpt-5.5"), # prepare configuration
disposables=(OpenAI(),), # define resources and service clients available
):
result: str = await TextGeneration.generate( # choose a right generation abstraction
Expand Down Expand Up @@ -91,6 +91,8 @@ documents, handling audio or images — Draive has your back.

## 🖥️ Install

Draive requires Python 3.14 or newer.

With pip:

```bash
Expand Down Expand Up @@ -166,6 +168,14 @@ Use AWS Bedrock-backed models.
pip install 'draive[bedrock]'
```

- AWS:

Use AWS services client, including S3, SQS and CloudWatch observability.

```bash
pip install 'draive[aws]'
```

- MCP:

Use Model Context Protocol integrations.
Expand Down Expand Up @@ -198,6 +208,30 @@ Use Qdrant vector database integration.
pip install 'draive[qdrant]'
```

- SurrealDB:

Use SurrealDB integration, including vector index, templates and conversation memory.

```bash
pip install 'draive[surrealdb]'
```

Remote connections require a SurrealDB 3.x server - the session handling relies on RPC methods
older servers do not provide. Namespaces and databases are not created implicitly, they have to be
defined before use.

- RabbitMQ:

Use RabbitMQ messaging client.

```bash
pip install 'draive[rabbitmq]'
```

Variant extras are available for provider-specific setups: `openai_realtime` (OpenAI Realtime API),
`anthropic_bedrock` and `cohere_bedrock` (those providers accessed through AWS Bedrock), and
`httpx` (shared HTTP client).

## 👷 Contributing

Draive is open-source and always growing — and we’d love your help.
Expand Down
8 changes: 6 additions & 2 deletions docs/cookbooks/BasicDataExtraction.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ document = "John Doe is 21 and lives in Vancouver, Canada."

async with ctx.scope(
"data_extraction",
OpenAIResponsesConfig(model="gpt-5-mini"),
OpenAIResponsesConfig(model="gpt-5.5"),
disposables=(OpenAI(),),
):
result: PersonalData = await ModelGeneration.generate(
Expand All @@ -57,12 +57,16 @@ Schema injection controls how much schema guidance is injected into instructions
```python
result: PersonalData = await ModelGeneration.generate(
PersonalData,
instructions="Extract fields from the input. Return JSON matching the schema:\n{%schema%}",
instructions="Extract fields from the input. Return JSON matching the schema:\n{model_schema}",
input=document,
schema_injection="simplified",
)
```

The schema is delivered by substituting a `{model_schema}` placeholder in the instructions, so
instructions without one are passed through unchanged. `Template` instructions use the
`{%model_schema%}` form instead.

`schema_injection` values:

- `"full"` inject full JSON schema
Expand Down
35 changes: 32 additions & 3 deletions docs/cookbooks/BasicMCP.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ setup_logging("mcp")

async with ctx.scope(
"mcp",
OpenAIResponsesConfig(model="gpt-5-mini"),
OpenAIResponsesConfig(model="gpt-5.5"),
disposables=(
OpenAI(),
# Start MCP stdio transport and register tool/resource states in context.
Expand All @@ -34,13 +34,13 @@ async with ctx.scope(
# Build toolbox from currently available MCP tools.
toolbox = await ToolsProvider.toolbox(suggesting=True)

stream = await Conversation.completion(
stream = Conversation.completion(
instructions=(
"You can access user files using available tools. "
"Directory path is /Users/myname/checkmeout."
),
message="What files are in checkmeout directory?",
toolbox=toolbox,
tools=toolbox,
)

async for chunk in stream:
Expand All @@ -49,3 +49,32 @@ async with ctx.scope(

`MCPClient` contributes `ToolsProvider`/`ResourcesRepository` states inside `ctx.scope(...)`, so you
can load MCP tools dynamically and keep all dependencies lifecycle-managed by context.

## Example: Remote MCP Server

For remote servers use the Streamable HTTP transport. `MCPClient.sse` is still available but the
SSE transport is deprecated by the protocol, prefer Streamable HTTP for new integrations.

```python
from draive.mcp import MCPClient

MCPClient.streamable_http(
url="https://example.com/mcp",
headers={"Authorization": "Bearer <token>"},
)
```

Exposing Draive tools and resources the other way around works through `MCPServer`, which serves
either stdio or an ASGI app:

```python
from draive.mcp import MCPServer

server = MCPServer(name="my-server", version="1.0.0", tools=[my_tool])

# stdio for local subprocess usage
await server.run_stdio()

# or an ASGI app to serve over Streamable HTTP
app = server.prepare_streamable_http_asgi(path="/mcp")
```
2 changes: 1 addition & 1 deletion docs/cookbooks/BasicRAG.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ async def index_search_tool(query: str) -> str:
async with ctx.scope(
"rag",
index,
OpenAIResponsesConfig(model="gpt-5-mini"),
OpenAIResponsesConfig(model="gpt-5.5"),
OpenAIEmbeddingConfig(model="text-embedding-3-small"),
disposables=(OpenAI(),),
):
Expand Down
13 changes: 10 additions & 3 deletions docs/getting-started/first-steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ from draive.openai import OpenAI, OpenAIResponsesConfig

async with ctx.scope(
"app",
OpenAIResponsesConfig(model="gpt-5-mini"),
OpenAIResponsesConfig(model="gpt-5.5"),
disposables=(OpenAI(),),
):
# Inside this block, ctx.state(...) can resolve these states.
Expand Down Expand Up @@ -98,13 +98,15 @@ answer = await TextGeneration.generate(
## 6. Add Retrieval With `VectorIndex`

`VectorIndex` is a context state API. In this example we use the in-memory implementation from
`VolatileVectorIndex()`.
`VolatileVectorIndex()`. Indexing and searching text delegates to `TextEmbedding`, so the scope also
needs a provider supplying it.

```python
from collections.abc import Sequence

from draive import State, VectorIndex, ctx
from draive.helpers import VolatileVectorIndex
from draive.openai import OpenAI, OpenAIEmbeddingConfig


class Chunk(State, serializable=True):
Expand All @@ -117,7 +119,12 @@ chunks: Sequence[Chunk] = (
)


async with ctx.scope("retrieval", VolatileVectorIndex()):
async with ctx.scope(
"retrieval",
VolatileVectorIndex(),
OpenAIEmbeddingConfig(model="text-embedding-3-small"),
disposables=(OpenAI(),),
):
await VectorIndex.index(Chunk, values=chunks, attribute=Chunk._.text)
hits: Sequence[Chunk] = await VectorIndex.search(Chunk, query="semantic", limit=2)
```
Expand Down
14 changes: 7 additions & 7 deletions docs/getting-started/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,22 @@ Throughout the getting-started journey you will assemble:
histories, snapshots, and metrics consistent.
1. **Context scoping** – `ctx.scope(...)` activates a stack of `State` instances and disposables for
a logical unit of work, ensuring structured concurrency and clean teardown.
1. **Generation flows** – typed facades in `draive.generation` orchestrate text, image, and audio
calls, while provider adapters translate the request to each backend.
1. **Generation flows** – typed facades in `draive.generation` orchestrate text, structured model,
image, and audio calls, while provider adapters translate the request to each backend.
1. **Tools and multimodal content** – `MultimodalContent`, `ResourceContent`, and tool abstractions
let you stream artifacts, call Python functions, or chain agents without sacrificing type
safety.
1. **Guardrails and observability** – moderation, privacy, metrics, and logging integrations keep
your application auditable. Use `ctx.log_*` for structured logs and `ctx.record` for metrics.
your application auditable. Use `ctx.log_*` for structured logs and `ctx.record_*` for metrics.

## Next Steps

1. Follow the [Installation](installation.md) guide to set up dependencies and the runtime
environment.
1. Walk through the quickstart notebooks and examples under `docs/cookbooks/` to see Draive in
action.
1. Explore provider-specific instructions in `docs/guides/` when you are ready to connect to
production endpoints.
1. Work through the [Quickstart](quickstart.md) and [First Steps](first-steps.md), then the
walkthroughs under `docs/cookbooks/` to see Draive in action.
1. Explore the integration guides in `docs/guides/` (for example `Postgres.md` and `Qdrant.md`) when
you are ready to connect to production backends.

You now have the core mental model for Draive. Continue with installation to bring the toolkit to
life.
10 changes: 8 additions & 2 deletions docs/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,14 @@ uv sync --all-groups --all-extras --frozen
LLMs.
- `draive[bedrock]`, `draive[aws]` for AWS model/runtime integrations.
- `draive[ollama]`, `draive[vllm]` for local or self-hosted deployments.
- `draive[qdrant]`, `draive[postgres]` for vector/storage backends; add `pgvector` separately where
needed.
- `draive[qdrant]`, `draive[postgres]`, `draive[surrealdb]` for vector/storage backends; the
Postgres index requires the `pgvector` server extension, while a remote SurrealDB connection
requires a SurrealDB 3.x server with its namespace and database already defined. SurrealDB
tables have to be defined upfront as well - each feature provides a static `migrate()`
(`SurrealConversationMemory`, `SurrealTemplatesRepository`, `SurrealVectorIndex`), while
custom models are defined with `Surreal.define_table`.
- `draive[rabbitmq]` for message-queue integrations.
- `draive[starlette]`, `draive[fastapi]` for serving draive applications over HTTP.
- `draive[httpx]`, `draive[mcp]`, `draive[opentelemetry]`, `draive[docs]` for HTTP utilities, MCP,
tracing, and docs site builds.

Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started/multimodal-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ content = MultimodalContent.of(

Useful helpers include:

- `texts()`, `images()`, `audio()`, `resources()` for part extraction
- `texts()`, `images()`, `audio()`, `video()`, `resources()` for part extraction
- `artifacts(...)`, `tags(...)` for structured component retrieval
- `matching_meta(...)`, `split_by_meta(...)` for metadata-aware filtering
- `without_resources()`, `without_artifacts()` for creating reduced variants
Expand Down
Loading
Loading