Metadata-Version: 2.4
Name: agent-observatory
Version: 0.1.1
Summary: Observability primitives for AI agents (tracing and streaming introspection)
Project-URL: Homepage, https://github.com/darshankparmar/agent-observatory
Project-URL: Repository, https://github.com/darshankparmar/agent-observatory
Project-URL: Issues, https://github.com/darshankparmar/agent-observatory/issues
Project-URL: Security, https://github.com/darshankparmar/agent-observatory/security
Author-email: Darshan Parmar <darshanparmar.dev@gmail.com>
License: MIT License
        
        Copyright (c) 2026 Darshan Parmar
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: ai-agents,llm,observability,opentelemetry,streaming,tracing
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Provides-Extra: all
Requires-Dist: black; extra == 'all'
Requires-Dist: livekit-agents>=1.3.10; extra == 'all'
Requires-Dist: livekit-plugins-cartesia>=1.3.10; extra == 'all'
Requires-Dist: livekit-plugins-deepgram>=1.3.10; extra == 'all'
Requires-Dist: livekit-plugins-openai>=1.3.10; extra == 'all'
Requires-Dist: livekit-plugins-silero>=1.3.10; extra == 'all'
Requires-Dist: livekit-plugins-turn-detector>=1.3.10; extra == 'all'
Requires-Dist: mypy; extra == 'all'
Requires-Dist: opentelemetry-api>=1.0.0; extra == 'all'
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.0.0; extra == 'all'
Requires-Dist: opentelemetry-sdk>=1.0.0; extra == 'all'
Requires-Dist: pytest; extra == 'all'
Requires-Dist: pytest-asyncio; extra == 'all'
Requires-Dist: python-dotenv>=1.2.1; extra == 'all'
Requires-Dist: ruff; extra == 'all'
Requires-Dist: types-setuptools; extra == 'all'
Provides-Extra: dev
Requires-Dist: black; extra == 'dev'
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-asyncio; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Requires-Dist: types-setuptools; extra == 'dev'
Provides-Extra: livekit-example
Requires-Dist: livekit-agents>=1.3.10; extra == 'livekit-example'
Requires-Dist: livekit-plugins-cartesia>=1.3.10; extra == 'livekit-example'
Requires-Dist: livekit-plugins-deepgram>=1.3.10; extra == 'livekit-example'
Requires-Dist: livekit-plugins-openai>=1.3.10; extra == 'livekit-example'
Requires-Dist: livekit-plugins-silero>=1.3.10; extra == 'livekit-example'
Requires-Dist: livekit-plugins-turn-detector>=1.3.10; extra == 'livekit-example'
Requires-Dist: python-dotenv>=1.2.1; extra == 'livekit-example'
Provides-Extra: otel
Requires-Dist: opentelemetry-api>=1.0.0; extra == 'otel'
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.0.0; extra == 'otel'
Requires-Dist: opentelemetry-sdk>=1.0.0; extra == 'otel'
Description-Content-Type: text/markdown

# Agent Observatory

**Agent Observatory** is a lightweight, fail-open observability layer for **AI agents and agent-based systems**.

It provides structured tracing for:
- agent steps
- tool calls
- LLM interactions
- streaming workflows (tokens, audio, events)
- hierarchical agent execution

Agent Observatory is designed as **infrastructure**, not a platform:
- no UI
- no storage
- no vendor lock-in
- no global side effects

It emits **portable trace envelopes** that can be exported to JSON, OpenTelemetry, or custom backends.

---

## Why Agent Observatory?

Modern AI agents are:
- long-running
- stateful
- streaming
- hierarchical
- partially autonomous

Traditional request/response tracing breaks down.

Agent Observatory focuses on:
- **agent runtime introspection**
- **streaming-first tracing**
- **minimal overhead**
- **composability with existing observability stacks**

---

## Core Concepts

### Sessions
A **session** represents a single agent run.

```python
with observatory.start_session(ctx) as session:
    ...
````

A session:

* owns a trace ID
* buffers events
* flushes automatically on exit
* never throws on failure (fail-open)

---

### Spans

Spans represent logical units of agent work.

```python
with session.span("plan", kind="agent_step"):
    ...
```

Supported span types include:

* `agent_step`
* `tool_call`
* `llm_call`
* `stream`

Spans can be nested and are tracked via context propagation.

---

### Streaming Events

Streams are first-class.

```python
with session.stream("audio_stream") as stream:
    stream.emit_event("chunk", {"seq": 1})
```

Streaming events:

* are associated with a span
* are high-frequency safe
* preserve ordering
* export cleanly to OTEL span events

---

## Architecture Overview

```
┌──────────────┐
│ Agent Code   │
└─────┬────────┘
      │
      ▼
┌──────────────┐
│ AgentSession │
│  (buffering) │
└─────┬────────┘
      │ envelope
      ▼
┌───────────────────────┐
│ Exporter Worker       │
│                       │
│  inline  |  async     │
└─────┬─────────────────┘
      │
      ▼
┌───────────────────────┐
│ Exporter              │
│  JSON | OTEL | Custom │
└───────────────────────┘
```

---

## Execution Modes (Important)

Agent Observatory supports **two execution modes**.

### Inline Mode

**Use for:** Scripts, notebooks, tests, examples

```python
obs = Observatory(exporter=exporter, inline=True)

with obs.start_session(ctx) as session:
    ...
# automatic flush on exit
```

**Characteristics**

* synchronous
* deterministic
* exporter called immediately
* ideal for short-lived processes

---

### Server Mode (Long-Running Processes)
**Use for:** Production agents, servers, multi-session apps

```python
obs = Observatory(exporter)  # inline=False
await obs.start()            # start background worker

# ... handle many sessions ...

await obs.shutdown()         # graceful shutdown
```

**Characteristics**

* background worker
* buffered exporting
* backpressure handling
* designed for long-running agents

⚠️ **Important:** Server mode requires explicit shutdown. Use inline mode for short scripts.

---

## Exporters

### Exporter Contract

All exporters must:

* be **synchronous**
* never raise
* fail open
* accept a full session envelope

```python
class Exporter:
    def export(self, payload: dict) -> None:
        ...
```

---

### JSON Exporter

Useful for debugging and local inspection.

```python
from agent_observatory.exporters.json import JsonExporter
```

---

### OpenTelemetry Exporter

Agent Observatory integrates with OpenTelemetry **without owning global state**.

#### Design Contract (Critical)

> Agent Observatory **does not configure OpenTelemetry**.
> Applications must configure the `TracerProvider`.

This is intentional and required for:

* auto-instrumentation
* framework compatibility
* production safety

---

#### OpenTelemetry Example (Recommended)

```python
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter

from agent_observatory import Observatory, AgentContext
from agent_observatory.exporters.otel import OpenTelemetryExporter


provider = TracerProvider(
    resource=Resource.create({"service.name": "agent-demo"})
)
provider.add_span_processor(
    SimpleSpanProcessor(
        OTLPSpanExporter(
            endpoint="http://127.0.0.1:4317",
            insecure=True,
        )
    )
)
trace.set_tracer_provider(provider)

tracer = trace.get_tracer("agent-demo")
exporter = OpenTelemetryExporter(tracer)

obs = Observatory(exporter=exporter, inline=True)

ctx = AgentContext(
    session_id="demo-session",
    agent_id="demo-agent",
)

with obs.start_session(ctx) as session:
    with session.span("plan", kind="agent_step"):
        pass
```

---

## Timestamp Semantics

* Internal event timestamps use a **monotonic clock**
* Used for ordering and duration

Exporters (e.g. OTEL) are responsible for mapping timestamps to wall-clock time if needed.

---

## Failure Semantics

Agent Observatory is **fail-open by design**.

* exporter failures do not crash agents
* queue overflows drop traces
* internal errors are logged only
* agent execution is never blocked

This is intentional.

---

## What Agent Observatory Is NOT

* ❌ Not a tracing backend
* ❌ Not a UI
* ❌ Not a metrics system
* ❌ Not a logging framework
* ❌ Not opinionated about storage

It is a **runtime observability primitive**.

---

## When to Use Agent Observatory

Use it if you are building:

* AI agents
* multi-step reasoning systems
* streaming LLM pipelines
* LiveKit / real-time agents
* tool-heavy autonomous workflows

---

## Versioning & Stability

* `v0.x` — APIs may evolve
* Core design principles are stable
* Exporter contract is stable
* Inline vs async semantics are stable

---

## Contributing

Contributions are welcome.

Please respect:

* synchronous exporter contract
* fail-open guarantees
* zero global side effects
* minimal dependencies

See `CONTRIBUTING.md`.

---

## License

MIT License.
