Metadata-Version: 2.4
Name: traceotter
Version: 0.2.2
Summary: Production observability SDK for LLM apps and LangChain agents with OpenTelemetry-style tracing and low-friction callbacks.
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: grpcio<2.0.0,>=1.78.0
Requires-Dist: protobuf<7.0.0,>=5.29.0
Requires-Dist: httpx<1.0.0,>=0.28.0
Requires-Dist: langchain<0.4.0,>=0.3.0
Requires-Dist: langchain-core<0.4.0,>=0.3.0
Requires-Dist: langchain-openai<0.4.0,>=0.3.0
Dynamic: license-file

# Traceotter Python SDK

Traceotter is a production-grade observability SDK for LLM applications and agent workflows, designed for fast integration and reliable operations.

It captures your AI execution graph as structured spans (chains, tools, retrieval, generations) and exports telemetry to Traceotter with batching, retries, and graceful shutdown flushing so teams can:

- debug broken or slow agent runs with full context
- monitor model/tool behavior across real traffic
- evaluate quality and cost trends over time

## Installation

```bash
pip install traceotter
```

## Quick Start (LangChain)

### 1) Configure credentials

```bash
export TRACEOTTER_PUBLIC_KEY="your_public_key"
export TRACEOTTER_SECRET_KEY="your_secret_key"
export TRACEOTTER_HOST="https://api.traceotter.com"  # optional
```

### 2) Attach Traceotter callback to your chain/agent

```python
from traceotter import get_client
from traceotter.langchain import CallbackHandler
from langchain_openai import ChatOpenAI

# Singleton client with background batching + flush
client = get_client()
traceotter_handler = CallbackHandler()

llm = ChatOpenAI(model="gpt-4o-mini")
result = llm.invoke(
    "Write a haiku about observability.",
    config={"callbacks": [traceotter_handler]},
)
print(result.content)
```

## Real Agent Example (Tool + ReAct)

```python
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_react_agent
from langchain_core.prompts import PromptTemplate
from langchain_core.tools import tool

from traceotter.langchain import CallbackHandler

@tool
def add_numbers(expression: str) -> int:
    import re
    nums = [int(x) for x in re.findall(r"-?\d+", expression)]
    if len(nums) < 2:
        raise ValueError(f"Expected two numbers, got: {expression}")
    return nums[0] + nums[1]

llm = ChatOpenAI(model="gpt-4o-mini")
handler = CallbackHandler()

prompt = PromptTemplate.from_template(
    """Answer the question using tools when needed.

Question: {input}
Thought:{agent_scratchpad}"""
)

agent = create_react_agent(llm=llm, tools=[add_numbers], prompt=prompt)
executor = AgentExecutor(agent=agent, tools=[add_numbers])

result = executor.invoke(
    {"input": "What is 4232 + 5000?"},
    config={"callbacks": [handler]},
)
print(result)
```

## Runtime Behavior

- **Automatic batching:** spans are buffered and exported in batches.
- **Safe shutdown flush:** pending spans flush on process exit.
- **Retries:** HTTP ingestion retries transient failures.
- **Fallback mode:** without Traceotter credentials, spans are exported to console for local debugging.

## Environment Variables

- `TRACEOTTER_PUBLIC_KEY`: required for remote ingest
- `TRACEOTTER_SECRET_KEY`: required for remote ingest
- `TRACEOTTER_HOST`: API base URL (default: `https://api.traceotter.com`)
- `TRACEOTTER_TIMEOUT`: request timeout seconds (default: `5`)
- `TRACEOTTER_FLUSH_AT`: max spans per flush batch
- `TRACEOTTER_FLUSH_INTERVAL`: periodic flush interval in seconds
- `OTEL_BSP_MAX_EXPORT_BATCH_SIZE`: optional OpenTelemetry-style alias for batch size (used if `TRACEOTTER_FLUSH_AT` is not set)
- `OTEL_BSP_SCHEDULE_DELAY`: optional OpenTelemetry-style alias for flush interval in milliseconds (used if `TRACEOTTER_FLUSH_INTERVAL` is not set)
- `TRACEOTTER_USE_GRPC`: set `true/1/yes` to enable gRPC target resolution
- `TRACEOTTER_GRPC_PORT`: gRPC port (default: `50051`)

Note: `OPENAI_API_KEY` is not a Traceotter SDK variable; it is required only by the LangChain/OpenAI examples.
