Metadata-Version: 2.4
Name: capsera
Version: 0.3.0
Summary: Per-agent token attribution and budget enforcement for multi-agent LLM systems
Project-URL: Homepage, https://capsera.ai
Project-URL: Dashboard, https://app.capsera.ai
Project-URL: Repository, https://github.com/Capsera/Token-Budget-Manager
Project-URL: Issues, https://github.com/Capsera/Token-Budget-Manager/issues
Author: Capsera
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: agents,anthropic,attribution,budget,cost,finops,llm,observability,openai,tokens
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
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
Classifier: Topic :: System :: Monitoring
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27.0
Provides-Extra: dev
Requires-Dist: jsonschema>=4.21; extra == 'dev'
Requires-Dist: mypy>=1.9; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-mock>=3.12; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: test-frameworks
Requires-Dist: crewai>=0.80; extra == 'test-frameworks'
Requires-Dist: dspy>=2.6; extra == 'test-frameworks'
Requires-Dist: haystack-ai>=2.8; extra == 'test-frameworks'
Requires-Dist: langchain-anthropic<2,>=1.4; extra == 'test-frameworks'
Requires-Dist: langchain-openai<2,>=1.3; extra == 'test-frameworks'
Requires-Dist: langchain<2,>=1.3; extra == 'test-frameworks'
Requires-Dist: langgraph<2,>=1.2; extra == 'test-frameworks'
Requires-Dist: llama-index-core>=0.12; extra == 'test-frameworks'
Requires-Dist: llama-index-llms-openai>=0.3; extra == 'test-frameworks'
Requires-Dist: pyautogen>=0.4; extra == 'test-frameworks'
Provides-Extra: test-providers
Requires-Dist: anthropic>=0.40; extra == 'test-providers'
Requires-Dist: boto3>=1.39; extra == 'test-providers'
Requires-Dist: cohere>=5.13; extra == 'test-providers'
Requires-Dist: google-genai>=1.0; extra == 'test-providers'
Requires-Dist: google-generativeai>=0.8; extra == 'test-providers'
Requires-Dist: mistralai>=1.2; extra == 'test-providers'
Requires-Dist: openai>=1.60; extra == 'test-providers'
Description-Content-Type: text/markdown

# Capsera SDK

Per-agent token attribution and budget enforcement for multi-agent LLM systems.

Install once, and every LLM call your app makes is attributed to the agent that
made it — with budget envelopes that can block or downgrade a call *before* it
reaches the provider.

```bash
pip install capsera
```

## Quickstart

```python
import capsera

capsera.init(api_key="cap-...")          # from your Capsera dashboard

@capsera.agent("researcher", team="core")
def research(question):
    return client.messages.create(       # captured automatically
        model="claude-sonnet-4-6",
        max_tokens=1024,
        messages=[{"role": "user", "content": question}],
    )
```

That's the whole integration. `init()` patches the provider clients already
installed in your environment; the decorator tells Capsera *which agent* the
spend belongs to. Calls made outside any decorated scope are still captured and
attributed to `unknown`.

## What gets captured

| Provider | Coverage |
| --- | --- |
| Anthropic | sync, async, streaming, errors |
| OpenAI chat | sync, async, streaming, errors |
| OpenAI embeddings | sync, async, errors |
| Google Gemini (`google-genai`, `google-generativeai`) | sync (plus async on the legacy client), errors |
| Mistral, Cohere, Vertex AI, AWS Bedrock | sync, errors |

Frameworks need no separate integration: they call the provider clients above,
so their calls are captured by construction. Where Capsera does extra work is
caller attribution — resolving the recorded file and line past the framework's
internals to *your* code. That skip-list covers LangChain, LangGraph, CrewAI,
LlamaIndex, AutoGen, Haystack, DSPy and the LiteLLM gateway.

Each captured call records token counts, cost from a maintained pricing catalog,
latency, the agent/team/session it belongs to, and the file and line that made
it.

## Design guarantees

**It stays out of the way.** Events are queued and shipped by a background
daemon thread, so your call path never blocks on Capsera. The queue is bounded
and drops rather than growing without limit. If the backend is unreachable, the
emitter retries with backoff, trips a circuit breaker, and gives up — your app
keeps working.

**It fails open.** Every interception path is wrapped: a bug or a shape change
in Capsera surfaces as missing telemetry, never as an exception in your
application. The one intentional exception is `BudgetExceededError`, raised only
when a blocking budget stops a call you configured it to stop.

**It never sends your prompts.** Optional prompt analysis records structure —
token estimates, message counts, a hash of the system prompt — and never
content. This is verified by a test that plants canary strings in prompts and
scans every emitted payload for them.

## Attribution

```python
from capsera import agent, tag, set_session

@agent("planner", team="core", task_type="planning")     # decorator
def plan(): ...

with tag("summarizer", customer_id="acme"):               # context manager
    ...

set_session("conv-42")     # thread-level, flows to every call without wrapping
```

## Configuration

```python
capsera.init(
    api_key="cap-...",
    enable_routing=True,              # route eligible calls to cheaper models
    enable_budget_enforcement=True,   # pre-call budget check (on by default)
    enable_prompt_analysis=True,      # structural metadata, never content
    debug=True,                       # one log line per intercepted call
)
```

`capsera.get_interception_report()` returns which provider surfaces are actually
hooked in the current process, so you can assert at startup that everything you
use is being tracked.

Requires Python 3.11+. The only runtime dependency is `httpx`.

## Links

- [Capsera](https://capsera.ai)
- [Dashboard](https://app.capsera.ai)

Licensed under the Apache License, Version 2.0.
