Metadata-Version: 2.4
Name: pelennor
Version: 0.1.0
Summary: Send your AI agent's OpenTelemetry traces to Pelennor.
Project-URL: Homepage, https://pelennor.ai
Author: Pelennor
License-Expression: MIT
License-File: LICENSE
Keywords: agents,llm,observability,opentelemetry,otel,tracing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: System :: Monitoring
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.29
Requires-Dist: opentelemetry-sdk>=1.29
Provides-Extra: anthropic
Requires-Dist: openinference-instrumentation-anthropic>=0.1; extra == 'anthropic'
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == 'dev'
Provides-Extra: langchain
Requires-Dist: openinference-instrumentation-langchain>=0.1; extra == 'langchain'
Provides-Extra: llama-index
Requires-Dist: openinference-instrumentation-llama-index>=0.1; extra == 'llama-index'
Provides-Extra: openai
Requires-Dist: openinference-instrumentation-openai>=0.1; extra == 'openai'
Description-Content-Type: text/markdown

# pelennor

Send your AI agent's [OpenTelemetry](https://opentelemetry.io/) traces to
[Pelennor](https://pelennor.ai), where they become **conversations** you can
read, search, and turn into evals.

```bash
pip install pelennor
```

## Quickstart

```python
import pelennor

pelennor.init(
    api_key="plk_...",              # the key from your agent's Lens page
    endpoint="https://your-pelennor-host",
)

with pelennor.conversation(id=thread_id, user="cust_123"):
    agent.invoke(...)
```

That's it. Every LLM call, tool call, and span your agent produces inside the
`conversation` block is exported to Pelennor and stitched into a single
conversation keyed by `id`.

`init()` reads `PELENNOR_API_KEY` and `PELENNOR_ENDPOINT` from the environment
when you don't pass them, so nothing need live in code. Both are required — with
no key, or no endpoint to send to, tracing simply stays off and logs why.

## Why the `conversation` block?

OpenTelemetry has no concept of a conversation. Each request is its own trace,
and the next turn arrives later as a completely separate one. `pelennor.conversation(id=...)`
stamps a shared id onto every span started inside it, so Pelennor can join a
whole multi-turn exchange back together. The id is whatever your app already
calls a thread, session, or chat. Reuse it across turns and the turns line up.

It's built on `contextvars`, so the binding follows your code across `await`
points and worker threads, which is where agent frameworks do their work.

## Auto-instrumentation

The base install exports spans and stamps conversation ids. To capture LLM and
tool calls automatically, install the extra for your stack:

```bash
pip install "pelennor[openai]"        # OpenAI
pip install "pelennor[langchain]"     # LangChain / LangGraph
pip install "pelennor[anthropic]"     # Anthropic
pip install "pelennor[llama-index]"   # LlamaIndex
```

`init()` activates whichever of these are installed. Already using
[OpenInference](https://github.com/Arize-ai/openinference) or
[OpenLLMetry](https://github.com/traceloop/openllmetry)? Pelennor reads both, so
you can point your existing exporter at it and skip this SDK entirely.

## Options

```python
pelennor.init(
    api_key="plk_...",
    endpoint="https://your-pelennor-host",  # or PELENNOR_ENDPOINT
    service_name="support-bot",           # shows up on your traces
    capture_content=False,                # send metadata only, never message text
    instrument=True,                      # auto-activate installed instrumentors
)
```

`capture_content=False` tells the instrumentors not to record prompt or
completion text, for when conversation content can't leave your environment.

## It will never break your agent

`init()` never raises. A missing key, an unreachable endpoint, or a bad span all
degrade to "no telemetry" and a log line, never an exception in your request
path. Telemetry is not allowed to take your agent down.

## License

MIT
