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

# Python API

> Drive the OpenSRE agent in-process from your own Python code

Use this when your Python code runs on the same machine as OpenSRE and you want
agent answers without shelling out to the CLI. To call OpenSRE over the network
instead, use the [HTTP API](/docs/api).

## Prerequisites

The standalone CLI installer does not expose an importable package, so embed
from a source checkout:

```bash theme={null}
git clone https://github.com/Tracer-Cloud/opensre.git
cd opensre && make install
```

Configure a provider once (`opensre onboard`) — the harness reuses the same
config and credentials as the CLI. Run your script inside the checkout's
environment with `uv run python your_script.py`.

## One turn

```python theme={null}
from core.agent_harness import AgentHarness

harness = AgentHarness.start()
result = harness.dispatch_message("why is checkout-api slow?")
if result.answered:
    print(result.primary_response_text)
```

`AgentHarness.start()` resolves the environment, opens a session, and attaches
an agent with the standard ports — the same tools and prompts the interactive
shell uses.

Always check `result.answered` before trusting the text: when a turn fails (for
example the LLM provider is unreachable), the error message itself lands in
`result.primary_response_text`.

## A conversation

Each `dispatch_message` call is one turn in the same session, so follow-ups see
earlier context:

```python theme={null}
harness.dispatch_message("list unresolved Sentry issues from the last 24 hours")
result = harness.dispatch_message("which of those affect checkout?")
```

To resume a previous session instead of starting a new one, pass its ID:

```python theme={null}
from core.agent_harness import AgentHarness, HarnessConfig

harness = AgentHarness.start(HarnessConfig(session_id="abc123"))
```

## Custom output and ports

`start()` buffers all output. To capture tool progress yourself — stream to a
websocket, collect for a report — build the agent explicitly and pass your own
sink:

```python theme={null}
from core.agent_harness import (
    AgentHarness,
    BufferOutputSink,
    HarnessConfig,
    build_default_headless_agent,
)

harness = AgentHarness(HarnessConfig())
startup = harness.startup()
sink = BufferOutputSink()
agent = build_default_headless_agent(session=startup.session, output=sink)
harness.attach_agent(agent)

harness.dispatch_message("summarize open incidents")
print(sink.lines)      # rendered output lines
print(sink.streamed)   # streamed answer chunks
```

Any object implementing the `OutputSink` protocol
(`core.agent_harness.ports.OutputSink`: `print`, `render_response_header`,
`render_error`, `stream`) works in place of `BufferOutputSink`.
`build_default_headless_agent` also accepts a custom logger, prompt surface,
and tool observers — see its docstring for the full port list.
