Metadata-Version: 2.4
Name: pandaprobe
Version: 0.4.0
Summary: Python SDK for PandaProbe — open source agent engineering platform
Project-URL: Homepage, https://github.com/chirpz-ai/pandaprobe-sdk
Project-URL: Documentation, https://github.com/chirpz-ai/pandaprobe-sdk
Project-URL: Repository, https://github.com/chirpz-ai/pandaprobe-sdk
Author-email: PandaProbe | Chirpz AI <support@chirpz.ai>
License-Expression: MIT
Keywords: agents,ai,evaluation,llm,observability,tracing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
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 :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Requires-Dist: httpx>=0.25.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.80.0; extra == 'anthropic'
Provides-Extra: bedrock
Requires-Dist: boto3>=1.43.0; extra == 'bedrock'
Provides-Extra: claude-agent-sdk
Requires-Dist: claude-agent-sdk>=0.1.0; extra == 'claude-agent-sdk'
Requires-Dist: wrapt>=1.14.0; extra == 'claude-agent-sdk'
Provides-Extra: crewai
Requires-Dist: crewai>=0.100.0; extra == 'crewai'
Requires-Dist: wrapt>=1.14.0; extra == 'crewai'
Provides-Extra: deepagents
Requires-Dist: deepagents>=0.6.1; (python_version >= '3.11') and extra == 'deepagents'
Provides-Extra: dev
Requires-Dist: anthropic>=0.80.0; extra == 'dev'
Requires-Dist: boto3>=1.43.0; extra == 'dev'
Requires-Dist: build>=1.0.0; extra == 'dev'
Requires-Dist: google-genai>=1.0.0; extra == 'dev'
Requires-Dist: langchain-google-genai>=4.0.0; extra == 'dev'
Requires-Dist: langchain-openai>=0.2.0; extra == 'dev'
Requires-Dist: mistralai>=2.4.0; extra == 'dev'
Requires-Dist: openai>=1.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest-cov>=6.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21.0; extra == 'dev'
Requires-Dist: ruff>=0.8.0; extra == 'dev'
Requires-Dist: twine>=6.0.0; extra == 'dev'
Provides-Extra: examples
Requires-Dist: anthropic>=0.80.0; extra == 'examples'
Requires-Dist: boto3>=1.43.0; extra == 'examples'
Requires-Dist: google-genai>=1.0.0; extra == 'examples'
Requires-Dist: langchain-google-genai>=4.0.0; extra == 'examples'
Requires-Dist: langchain-openai>=0.2.0; extra == 'examples'
Requires-Dist: mistralai>=2.4.0; extra == 'examples'
Requires-Dist: openai>=1.0.0; extra == 'examples'
Provides-Extra: gemini
Requires-Dist: google-genai>=1.0.0; extra == 'gemini'
Provides-Extra: google-adk
Requires-Dist: google-adk>=1.0.0; extra == 'google-adk'
Requires-Dist: wrapt>=1.14.0; extra == 'google-adk'
Provides-Extra: langchain
Requires-Dist: langchain-core>=0.3.0; extra == 'langchain'
Requires-Dist: langchain>=1.0.0; extra == 'langchain'
Provides-Extra: langgraph
Requires-Dist: langchain-core>=0.3.0; extra == 'langgraph'
Requires-Dist: langgraph>=0.2.0; extra == 'langgraph'
Provides-Extra: mistral
Requires-Dist: mistralai>=2.4.0; extra == 'mistral'
Provides-Extra: openai
Requires-Dist: openai>=1.0.0; extra == 'openai'
Provides-Extra: openai-agents
Requires-Dist: openai-agents>=0.13.0; extra == 'openai-agents'
Description-Content-Type: text/markdown

# PandaProbe Python SDK

Python SDK for [PandaProbe](https://www.pandaprobe.com/) — open source agent engineering platform.

## Installation

```bash
pip install pandaprobe
```

With optional LLM provider wrappers:

```bash
pip install "pandaprobe[openai]"       # OpenAI wrapper
pip install "pandaprobe[gemini]"       # Google Gemini wrapper
pip install "pandaprobe[anthropic]"    # Anthropic wrapper
pip install "pandaprobe[mistral]"      # Mistral AI wrapper
pip install "pandaprobe[bedrock]"      # AWS Bedrock wrapper (beta)
```

With optional agent framework integrations:

```bash
pip install "pandaprobe[langgraph]"         # LangGraph
pip install "pandaprobe[langchain]"         # LangChain (create_agent, LCEL)
pip install "pandaprobe[deepagents]"        # DeepAgents (requires Python ≥3.11)
pip install "pandaprobe[google-adk]"        # Google Agent Development Kit
pip install "pandaprobe[claude-agent-sdk]"  # Anthropic Claude Agent SDK
pip install "pandaprobe[crewai]"            # CrewAI
pip install "pandaprobe[openai-agents]"     # OpenAI Agents SDK
```

## Quick Start

### 1. Set environment variables

```bash
export PANDAPROBE_API_KEY="sk_pp_..."
export PANDAPROBE_PROJECT_NAME="my-project"
export PANDAPROBE_ENDPOINT="https://api.pandaprobe.com"   # optional — this is the default
export PANDAPROBE_ENVIRONMENT="production"   # optional
export PANDAPROBE_RELEASE="v1.2.0"           # optional
```

The SDK auto-initializes from these environment variables on first use — no explicit `init()` call is needed. To disable tracing, set `PANDAPROBE_ENABLED=false`.

You can still use `pandaprobe.init(...)` for programmatic configuration if preferred.

### 2. Decorator-based tracing (custom agents)

```python
import pandaprobe

@pandaprobe.trace(name="my-agent")
def run_agent(query: str):
    @pandaprobe.span(name="llm-call", kind="LLM")
    def call_llm(prompt):
        return openai_client.chat.completions.create(...)

    @pandaprobe.span(name="search", kind="TOOL")
    def search(q):
        return search_engine.search(q)

    context = search(query)
    return call_llm(f"Context: {context}\nQuery: {query}")
```

### 3. OpenAI wrapper (automatic LLM tracing)

```python
from pandaprobe.wrappers import wrap_openai
import openai

client = wrap_openai(openai.OpenAI())

# Chat Completions API — automatically traced:
response = client.chat.completions.create(
    model="gpt-5.4-nano",
    messages=[{"role": "user", "content": "Hello"}],
)

# Responses API — also automatically traced, including reasoning summaries
# and built-in tool calls (web_search, function_call, etc.) as child spans:
response = client.responses.create(
    model="gpt-5.4-nano",
    input="Explain recursion in one sentence.",
    reasoning={"effort": "low", "summary": "auto"},
)
```

### 4. Gemini wrapper (automatic LLM tracing)

```python
from pandaprobe.wrappers import wrap_gemini
from google import genai

client = wrap_gemini(genai.Client())

response = client.models.generate_content(
    model="gemini-2.5-flash",
    contents="Explain recursion in one sentence.",
)
```

### 5. Anthropic wrapper (automatic LLM tracing)

```python
from pandaprobe.wrappers import wrap_anthropic
import anthropic

client = wrap_anthropic(anthropic.Anthropic())

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=150,
    system="You are a concise assistant.",
    messages=[{"role": "user", "content": "Explain recursion in one sentence."}],
)
```

### 6. Mistral wrapper (automatic LLM tracing)

```python
from pandaprobe.wrappers import wrap_mistral
from mistralai.client import Mistral

client = wrap_mistral(Mistral(api_key="..."))

response = client.chat.complete(
    model="mistral-small-latest",
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "Explain recursion in one sentence."},
    ],
    temperature=0.5,
    max_tokens=200,
)
```

Both `chat.complete` / `chat.complete_async` and the streaming variants
(`chat.stream` / `chat.stream_async`) are automatically traced.

### 7. AWS Bedrock wrapper (automatic LLM tracing) — _beta_

```python
import boto3
from pandaprobe.wrappers import wrap_bedrock

client = wrap_bedrock(boto3.client("bedrock-runtime", region_name="us-east-1"))

response = client.converse(
    modelId="us.anthropic.claude-haiku-4-5-20251001-v1:0",
    system=[{"text": "You are a concise assistant."}],
    messages=[{"role": "user", "content": [{"text": "Explain recursion in one sentence."}]}],
    inferenceConfig={"temperature": 0.5, "maxTokens": 200},
)
```

The Bedrock wrapper instruments both the **Converse** API (recommended,
provider-agnostic) and the legacy **InvokeModel** API, with full streaming
support on both.  Async `aioboto3` clients are detected and instrumented
automatically when used.

### 8. Agent framework integrations

All integrations below auto-trace agent execution — LLM calls, tool use, handoffs, and more — with no manual span creation.

#### LangGraph

```python
from pandaprobe.integrations.langgraph import LangGraphCallbackHandler

handler = LangGraphCallbackHandler()
result = graph.invoke(
    {"messages": [HumanMessage(content="hello")]},
    config={"callbacks": [handler]},
)
```

#### LangChain

Works with `create_agent` agents and plain LCEL pipelines (`prompt | model | parser`).

```python
from langchain.agents import create_agent
from pandaprobe.integrations.langchain import LangChainCallbackHandler

handler = LangChainCallbackHandler()
agent = create_agent(model="openai:gpt-5.4-nano", tools=[...])
result = agent.invoke(
    {"messages": [{"role": "user", "content": "hello"}]},
    config={"callbacks": [handler]},
)
```

#### DeepAgents

`deepagents` is an opinionated harness on top of `create_agent`. `create_deep_agent(...)` returns a LangGraph compiled graph, so a single handler captures the parent agent **and** every sub-agent dispatched via the built-in `task` tool.

```python
from deepagents import create_deep_agent
from pandaprobe.integrations.deepagents import DeepAgentsCallbackHandler

handler = DeepAgentsCallbackHandler()
agent = create_deep_agent(
    model="openai:gpt-5.4-nano",
    tools=[...],
    system_prompt="...",
    subagents=[{"name": "researcher", "description": "...", "system_prompt": "...", "tools": [...]}],
)
result = agent.invoke(
    {"messages": [{"role": "user", "content": "hello"}]},
    config={"callbacks": [handler]},
)
```

#### Google ADK

```python
from pandaprobe.integrations.google_adk import GoogleADKAdapter

adapter = GoogleADKAdapter()
adapter.instrument()

# All Runner.run_async() calls are now traced automatically
result = await runner.run_async(user_id="user-1", session_id="s-1", new_message=msg)
```

#### Claude Agent SDK

```python
from pandaprobe.integrations.claude_agent_sdk import ClaudeAgentSDKAdapter

adapter = ClaudeAgentSDKAdapter()
adapter.instrument()

# All client.query() / client.receive_response() calls are now traced automatically
result = client.query(prompt="Explain recursion.")
```

#### CrewAI

```python
from pandaprobe.integrations.crewai import CrewAIAdapter

adapter = CrewAIAdapter()
adapter.instrument()

# All crew.kickoff() calls are now traced automatically
result = crew.kickoff()
```

#### OpenAI Agents SDK

```python
from pandaprobe.integrations.openai_agents import OpenAIAgentsAdapter

adapter = OpenAIAgentsAdapter()
adapter.instrument()

# All Runner.run() calls are now traced automatically
result = await Runner.run(agent, input="Explain recursion.")
```

### 9. Session and user tracking

Group related traces under a session and/or user using the universal context API:

```python
import pandaprobe

# Context managers — scoped to the block
with pandaprobe.session("conversation-123"):
    with pandaprobe.user("user-abc"):
        run_agent("What is recursion?")
        run_agent("Can you give me an example?")

# Imperative — useful for dynamic switching
pandaprobe.set_session("conversation-456")
pandaprobe.set_user("user-xyz")
run_agent("New topic")
```

Both propagate across all SDK layers (decorators, wrappers, integrations, context managers). Explicit parameters (`session_id=`, `user_id=`) take precedence over the context.

### 10. Programmatic scoring

```python
pandaprobe.score(
    trace_id="...",
    name="user_satisfaction",
    value="0.9",
    data_type="NUMERIC",
    reason="User clicked thumbs up",
)
```

### 11. Flushing

For short-lived scripts, call `pandaprobe.flush()` before exiting to ensure all traces are sent. For long-running processes, the SDK flushes automatically via a background thread and an `atexit` handler.

```python
pandaprobe.flush()
pandaprobe.shutdown()
```

## Configuration

| Environment Variable | Default | Description |
|---|---|---|
| `PANDAPROBE_API_KEY` | *(required)* | API key |
| `PANDAPROBE_PROJECT_NAME` | *(required)* | Project name |
| `PANDAPROBE_ENDPOINT` | `https://api.pandaprobe.com` | Backend URL |
| `PANDAPROBE_ENVIRONMENT` | `None` | Environment tag (e.g. `production`, `staging`) |
| `PANDAPROBE_RELEASE` | `None` | Release/version tag (e.g. `v1.2.0`) |
| `PANDAPROBE_ENABLED` | `true` | Enable/disable SDK |
| `PANDAPROBE_BATCH_SIZE` | `10` | Traces per flush batch |
| `PANDAPROBE_FLUSH_INTERVAL` | `5.0` | Seconds between flushes |
| `PANDAPROBE_DEBUG` | `false` | Verbose logging |

## Development

```bash
make py-install       # Install all deps (providers, examples, dev tools)
make py-lint          # Run linter
make py-format        # Auto-format
make py-test          # Run tests
make py-test-cov      # Tests with coverage
```

## License

MIT
