Metadata-Version: 2.4
Name: freesolo
Version: 0.1.3
Summary: OpenAI and Anthropic tracing package for LLM applications.
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Provides-Extra: dev
Requires-Dist: ruff>=0.11.0; extra == 'dev'
Provides-Extra: examples
Requires-Dist: anthropic>=0.40.0; extra == 'examples'
Requires-Dist: openai>=1.0.0; extra == 'examples'
Description-Content-Type: text/markdown

# freesolo

`freesolo` is a Python tracing package for LLM apps.

It is built for the lowest-friction integration possible:

1. Install the package
2. Set `FREESOLO_API_KEY`
3. Wrap your OpenAI or Anthropic client
4. Call the client normally

## Current provider support

`freesolo` currently supports automatic client instrumentation for:

- OpenAI
- Anthropic

## Install

Install the package plus the provider SDK you use:

```bash
pip install freesolo openai
```

or

```bash
pip install freesolo anthropic
```

## Environment

- `FREESOLO_API_KEY`

## Quickstart

```python
from openai import OpenAI
from freesolo import instrument_openai

client = instrument_openai(OpenAI())

result = client.chat.completions.create(
    model="gpt-4.1-mini",
    messages=[
        {"role": "user", "content": "How do I reset my password?"},
    ],
)

print(result.choices[0].message.content or "")
```

## Group Multiple Model Calls

For agentic or long-horizon tasks, strongly prefer wrapping the whole task in `start_trace(...)` so all of the model calls land in one trace.

For a single one-off OpenAI or Anthropic request, you can skip it.

```python
from anthropic import Anthropic
from freesolo import instrument_anthropic, start_trace

client = instrument_anthropic(Anthropic())

with start_trace("support-agent-run"):
    first = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=64,
        messages=[{"role": "user", "content": "Say hello"}],
    )
    second = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=64,
        messages=[{"role": "user", "content": "Say goodbye"}],
    )
```

## What Gets Stored

- Trace metadata if you explicitly pass it to `start_trace(..., metadata=...)`
- OpenAI and Anthropic request + response payloads
- Token usage when available
- Image inputs with inline previews for the trace UI

## Notes

- You do not need `@trace()` for ordinary LLM tracing.
- A single instrumented OpenAI or Anthropic request creates a trace automatically.
- For agentic or long-horizon workflows, strongly recommend `start_trace(trace_id=...)` so planning, retries, and follow-up calls stay grouped.
- Delivery is best-effort by default. Trace ingestion failures do not break your app.
