> ## Documentation Index
> Fetch the complete documentation index at: https://docs.overmindlab.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> Reference for the overmind package — init(), provider auto-instrumentation, span decorators, and context helpers.

The `overmind` package instruments your LLM stack over OpenTelemetry and exports spans to Overmind. One `init()` call captures every supported provider call automatically; decorators and span helpers trace the code around those calls.

```bash theme={"system"}
pip install overmind

# alongside the providers you use
pip install overmind openai
pip install overmind anthropic
pip install overmind google-genai
pip install overmind agno
```

The package also ships the `overmind` CLI used by [optimisation runs](/agent-testing/optimisers#prerequisites) and an OpenAI-compatible [inference client](/models/inference#calling-your-model).

## `init()`

Call once at process startup, before any LLM call. Idempotent and re-entrant — calling again with more `providers` enables them without tearing down the tracer.

```python theme={"system"}
import overmind

overmind.init(
    service_name="my-service",
    environment="production",
    providers=["openai", "anthropic"],
    agent_name="Support Triage",
)
```

| Parameter           | Type                | Description                                                                                     |
| ------------------- | ------------------- | ----------------------------------------------------------------------------------------------- |
| `overmind_api_key`  | `str \| None`       | Falls back to `OVERMIND_API_KEY`                                                                |
| `service_name`      | `str \| None`       | Shown in the console; falls back to `OVERMIND_SERVICE_NAME`                                     |
| `environment`       | `str \| None`       | e.g. `"production"`, `"staging"`                                                                |
| `providers`         | `list[str] \| None` | Any of `"openai"`, `"anthropic"`, `"google"`, `"agno"`. Omit to auto-detect installed providers |
| `overmind_base_url` | `str \| None`       | Falls back to `OVERMIND_API_URL`, then `https://api.overmindlab.ai`                             |
| `agent_id`          | `str \| None`       | Agent UUID; stamped as `overmind.agent.id` on every span                                        |
| `agent_name`        | `str \| None`       | Stable agent name; stamped as `overmind.agent.name`                                             |
| `project_id`        | `str \| None`       | Project UUID (`overmind.project.id`)                                                            |

Environment variables: `OVERMIND_API_KEY`, `OVERMIND_API_URL`, `OVERMIND_SERVICE_NAME`, `OVERMIND_STRICT_MODE`.

After `init()`, calls made with the OpenAI, Anthropic, Google Gemini, and Agno client libraries produce `llm_call` spans automatically, capturing messages and tool calls, model and request parameters, token usage, latency, and errors. Spans export via a batching OTLP/HTTP exporter to `POST {base_url}/api/v1/traces`.

## Tracing your own code

Auto-instrumentation only sees model calls. Wrapping the code around them — the entry point, tools, retrieval steps — turns flat spans into a tree that mirrors your agent's structure.

### Span types

```python theme={"system"}
from overmind import SpanType
```

| `SpanType`             | Attribute value | Meaning                                    |
| ---------------------- | --------------- | ------------------------------------------ |
| `SpanType.ENTRY_POINT` | `entry_point`   | The outermost traced function of a request |
| `SpanType.WORKFLOW`    | `workflow`      | A multi-step process or pipeline           |
| `SpanType.TOOL`        | `tool_call`     | A tool or function the agent invokes       |
| `SpanType.RETRIEVAL`   | `retrieval`     | A RAG / vector-search step                 |
| `SpanType.FUNCTION`    | `function`      | Any other traced function (the default)    |
| `SpanType.LLM`         | `llm_call`      | A model call (set by auto-instrumentation) |

### Decorators

`@observe` is the general decorator; `@entry_point`, `@workflow`, `@tool`, `@retrieval`, and `@function` are typed shortcuts. All of them capture arguments as `inputs` and the return value as `outputs` (JSON-serialised, best effort). They record duration and status, re-raise exceptions after recording them, and work on both sync and async functions.

```python theme={"system"}
import overmind

overmind.init(service_name="research-agent", providers=["openai"])

@overmind.tool()
def web_search(query: str) -> list[str]: ...

@overmind.workflow()
def research(topic: str) -> str:
    return summarize(web_search(topic))

@overmind.entry_point()
def handle_request(topic: str) -> str:
    return research(topic)
```

Because each function calls the next, spans nest into one tree: `handle_request` → `research` → `web_search` → the auto-captured `llm_call` spans underneath.

<Tip>
  Always add an `@entry_point()`. It marks the unit that trace scoring and dataset conversion treat as one run — without it, model calls arrive as disconnected spans. Tools are the next most valuable layer; most teams stop there.
</Tip>

For functions that handle secrets or oversized payloads, `observe_safe` traces without capturing inputs or outputs.

### `start_span()` — blocks and loops

A context manager for regions that aren't whole functions. It opens a child span under whatever span is active. Unlike the decorators, it captures nothing automatically — attach metadata via `attributes` or `set_tag()`.

```python theme={"system"}
from overmind import start_span, set_tag, SpanType

for i, doc in enumerate(documents):
    with start_span("process_document", span_type=SpanType.FUNCTION, attributes={"doc.index": i}):
        result = process(doc)
        set_tag("doc.tokens", result.tokens)
```

### `get_tracer()` — raw OpenTelemetry

For span lifetimes that don't fit a single block, drop down to the OTel tracer. Raises `RuntimeError` before `init()`.

```python theme={"system"}
from overmind import get_tracer

tracer = get_tracer()
with tracer.start_as_current_span("manual_step") as span:
    span.set_attribute("step", "load")
```

## Context helpers

All operate on the current span/trace — call them inside a traced function or request handler.

| Helper                                         | Effect                                                                                             |
| ---------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `set_agent_id(id)` / `set_agent_name(name)`    | Bind downstream spans to an [agent](/core/agents)                                                  |
| `set_project_id(id)`                           | Set the project explicitly                                                                         |
| `set_conversation_id(id)`                      | Group traces into a [session](/core/observability#sessions) (`conversation` is the decorator form) |
| `set_workflow_name(name)`                      | Label every downstream span with a workflow name                                                   |
| `set_user(user_id, email=None, username=None)` | Tag the trace with a user identity                                                                 |
| `set_tag(key, value)`                          | Attach arbitrary filterable metadata to the current span                                           |
| `capture_exception(exc)`                       | Record a handled exception and mark the span as an error                                           |
| `force_flush_traces()`                         | Flush buffered spans — call before scripts and serverless handlers exit                            |

```python theme={"system"}
from fastapi import FastAPI, Request
from overmind import set_user

app = FastAPI()

@app.middleware("http")
async def add_user_context(request: Request, call_next):
    user = getattr(request.state, "user", None)
    if user:
        set_user(user_id=user.id, email=user.email)
    return await call_next(request)
```

## `PromptString` — explicit prompt structure

Passing prompts as plain strings forces Overmind to infer which parts are template versus dynamic input. `PromptString` declares that structure, giving agent discovery a stable signal:

```python theme={"system"}
from overmind import PromptString

system_prompt = PromptString(
    id="support_greeter_v1",
    template="You are a helpful support agent. Your name is {agent_name}.",
    kwargs={"agent_name": "Astra"},
)
```

Use the same `id` for logically identical prompts across providers and versions, and Overmind groups them as one agent. Use one `PromptString` per LLM call — the SDK raises an error if it detects more.

## Full example

```python theme={"system"}
import overmind
from overmind import start_span, set_user, set_tag, capture_exception, SpanType
from openai import OpenAI

overmind.init(
    service_name="customer-support",
    environment="production",
    providers=["openai"],
    agent_name="Support Triage",
)

client = OpenAI()

@overmind.tool()
def lookup_order(order_id: str) -> dict:
    return {"id": order_id, "status": "shipped"}

@overmind.entry_point()
def handle_support_query(user_id: str, question: str) -> str:
    set_user(user_id=user_id)
    set_tag("workflow", "support")

    with start_span("gather_context", span_type=SpanType.FUNCTION):
        order = lookup_order("A-1001")

    try:
        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[
                {"role": "system", "content": "You are a helpful customer support agent."},
                {"role": "user", "content": f"{question}\n\nOrder: {order}"},
            ],
        )
        return response.choices[0].message.content
    except Exception as e:
        capture_exception(e)
        raise
```

One trace: `handle_support_query` (entry point) → `gather_context` → `lookup_order` (tool) → the OpenAI `llm_call`, tagged with the user and workflow, attributed to the Support Triage agent.
