PandaProbe Python SDK
Python SDK for PandaProbe — open source agent engineering platform.
Trace → Evaluate → Reflect. Opt-in PandaProbe Reflect lets your task agent maintain learned guidance through a supplied Bash filesystem, with external evaluation evidence and independent validation of shared changes.
Installation
pip install pandaprobe
To enable reflection, compose it with your existing framework extra:
pip install "pandaprobe[reflect,langchain]"
Reflect is explicitly enabled through pandaprobe.reflect.Reflect. Ordinary
tracing does not import or activate it. See the integration guide
and credential-free offline demo.
With optional LLM provider wrappers:
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:
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
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)
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)
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)
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)
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)
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
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
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).
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.
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
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
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
from pandaprobe.integrations.crewai import CrewAIAdapter
adapter = CrewAIAdapter()
adapter.instrument()
# All crew.kickoff() calls are now traced automatically
result = crew.kickoff()
OpenAI Agents SDK
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:
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
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.
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
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
Metadata
Release files for pandaprobe 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pandaprobe-0.6.0.tar.gz | 647.5 kB | With provenance | Details for pandaprobe-0.6.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pandaprobe-0.6.0-py3-none-any.whl | Python 3 | none | any | Details for pandaprobe-0.6.0-py3-none-any.whl |
Total release size: 801.6 kB
Release files / pandaprobe-0.6.0.tar.gz
| Download URL | pandaprobe-0.6.0.tar.gz |
|---|---|
| Size | 647.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7633623411462a92179410ac9b1db5902175a564164e37613aac3d3f7f0fc338
|
|
BLAKE2b-256 checksum How to use checksums |
f8bbf899ace3c5c31a3c4cbacf6f8381c48393e7cdf32527fd7342ce1048d84a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.
Transparency logRelease files / pandaprobe-0.6.0-py3-none-any.whl
| Download URL | pandaprobe-0.6.0-py3-none-any.whl |
|---|---|
| Size | 154.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
abbb81c971cb36204ae5101934933c2057dde8eb7ae379a727749083121a4dcb
|
|
BLAKE2b-256 checksum How to use checksums |
f20520011e8873a4ca5ffdbe47e16ed05cc22839f55704d602ebe038a43074f3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.
Transparency logSecurity for pandaprobe 0.6.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for pandaprobe-0.6.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.