pandaprobe 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pandaprobe-0.1.1/.gitignore +42 -0
- pandaprobe-0.1.1/Makefile +43 -0
- pandaprobe-0.1.1/PKG-INFO +253 -0
- pandaprobe-0.1.1/README.md +189 -0
- pandaprobe-0.1.1/examples/README.md +166 -0
- pandaprobe-0.1.1/examples/anthropic/01_chat_completion.py +46 -0
- pandaprobe-0.1.1/examples/anthropic/02_multi_turn.py +60 -0
- pandaprobe-0.1.1/examples/claude_agent_sdk/01_simple_agent.py +58 -0
- pandaprobe-0.1.1/examples/claude_agent_sdk/02_tool_agent.py +102 -0
- pandaprobe-0.1.1/examples/claude_agent_sdk/03_multi_turn.py +81 -0
- pandaprobe-0.1.1/examples/context_managers/01_rag_pipeline.py +115 -0
- pandaprobe-0.1.1/examples/context_managers/02_multi_turn.py +78 -0
- pandaprobe-0.1.1/examples/crewai/01_simple_crew.py +65 -0
- pandaprobe-0.1.1/examples/crewai/02_tool_crew.py +91 -0
- pandaprobe-0.1.1/examples/crewai/03_multi_agent.py +93 -0
- pandaprobe-0.1.1/examples/decorators/01_support_agent.py +81 -0
- pandaprobe-0.1.1/examples/decorators/02_multi_turn.py +77 -0
- pandaprobe-0.1.1/examples/gemini/01_chat_completion.py +45 -0
- pandaprobe-0.1.1/examples/gemini/02_multi_turn.py +61 -0
- pandaprobe-0.1.1/examples/google_adk/01_simple_agent.py +66 -0
- pandaprobe-0.1.1/examples/google_adk/02_tool_agent.py +94 -0
- pandaprobe-0.1.1/examples/google_adk/03_multi_turn.py +83 -0
- pandaprobe-0.1.1/examples/langgraph/01_chatbot.py +57 -0
- pandaprobe-0.1.1/examples/langgraph/02_tool_agent.py +97 -0
- pandaprobe-0.1.1/examples/langgraph/03_multi_turn.py +87 -0
- pandaprobe-0.1.1/examples/openai/01_chat_completion.py +40 -0
- pandaprobe-0.1.1/examples/openai/02_streaming.py +45 -0
- pandaprobe-0.1.1/examples/openai/03_multi_turn.py +56 -0
- pandaprobe-0.1.1/examples/openai/04_responses_api.py +47 -0
- pandaprobe-0.1.1/examples/openai_agents/01_simple_agent.py +51 -0
- pandaprobe-0.1.1/examples/openai_agents/02_tool_agent.py +79 -0
- pandaprobe-0.1.1/examples/openai_agents/03_multi_turn.py +69 -0
- pandaprobe-0.1.1/pyproject.toml +76 -0
- pandaprobe-0.1.1/src/pandaprobe/__init__.py +194 -0
- pandaprobe-0.1.1/src/pandaprobe/_version.py +1 -0
- pandaprobe-0.1.1/src/pandaprobe/client.py +240 -0
- pandaprobe-0.1.1/src/pandaprobe/config.py +96 -0
- pandaprobe-0.1.1/src/pandaprobe/decorators.py +197 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/__init__.py +10 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/_base.py +134 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/claude_agent_sdk/__init__.py +5 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/claude_agent_sdk/adapter.py +869 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/claude_agent_sdk/utils.py +244 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/crewai/__init__.py +5 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/crewai/adapter.py +607 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/crewai/utils.py +223 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/google_adk/__init__.py +5 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/google_adk/adapter.py +488 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/google_adk/utils.py +273 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/langgraph/__init__.py +5 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/langgraph/callback.py +334 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/langgraph/utils.py +347 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/openai_agents/__init__.py +5 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/openai_agents/adapter.py +544 -0
- pandaprobe-0.1.1/src/pandaprobe/integrations/openai_agents/utils.py +469 -0
- pandaprobe-0.1.1/src/pandaprobe/py.typed +0 -0
- pandaprobe-0.1.1/src/pandaprobe/schemas.py +224 -0
- pandaprobe-0.1.1/src/pandaprobe/tracing/__init__.py +6 -0
- pandaprobe-0.1.1/src/pandaprobe/tracing/context.py +193 -0
- pandaprobe-0.1.1/src/pandaprobe/tracing/session.py +53 -0
- pandaprobe-0.1.1/src/pandaprobe/tracing/span.py +163 -0
- pandaprobe-0.1.1/src/pandaprobe/transport.py +277 -0
- pandaprobe-0.1.1/src/pandaprobe/validation.py +137 -0
- pandaprobe-0.1.1/src/pandaprobe/wrappers/__init__.py +12 -0
- pandaprobe-0.1.1/src/pandaprobe/wrappers/_base.py +234 -0
- pandaprobe-0.1.1/src/pandaprobe/wrappers/anthropic/__init__.py +5 -0
- pandaprobe-0.1.1/src/pandaprobe/wrappers/anthropic/utils.py +117 -0
- pandaprobe-0.1.1/src/pandaprobe/wrappers/anthropic/wrapper.py +504 -0
- pandaprobe-0.1.1/src/pandaprobe/wrappers/gemini/__init__.py +5 -0
- pandaprobe-0.1.1/src/pandaprobe/wrappers/gemini/utils.py +195 -0
- pandaprobe-0.1.1/src/pandaprobe/wrappers/gemini/wrapper.py +328 -0
- pandaprobe-0.1.1/src/pandaprobe/wrappers/openai/__init__.py +5 -0
- pandaprobe-0.1.1/src/pandaprobe/wrappers/openai/utils.py +107 -0
- pandaprobe-0.1.1/src/pandaprobe/wrappers/openai/wrapper.py +602 -0
- pandaprobe-0.1.1/tests/test_client.py +129 -0
- pandaprobe-0.1.1/tests/test_config.py +67 -0
- pandaprobe-0.1.1/tests/test_decorators.py +199 -0
- pandaprobe-0.1.1/tests/test_integrations/__init__.py +0 -0
- pandaprobe-0.1.1/tests/test_integrations/test_claude_agent_sdk.py +1390 -0
- pandaprobe-0.1.1/tests/test_integrations/test_crewai.py +1492 -0
- pandaprobe-0.1.1/tests/test_integrations/test_google_adk.py +1021 -0
- pandaprobe-0.1.1/tests/test_integrations/test_langgraph.py +750 -0
- pandaprobe-0.1.1/tests/test_integrations/test_openai_agents.py +1450 -0
- pandaprobe-0.1.1/tests/test_schemas.py +117 -0
- pandaprobe-0.1.1/tests/test_session_context.py +229 -0
- pandaprobe-0.1.1/tests/test_tracing.py +120 -0
- pandaprobe-0.1.1/tests/test_transport.py +245 -0
- pandaprobe-0.1.1/tests/test_validation.py +215 -0
- pandaprobe-0.1.1/tests/test_wrappers/__init__.py +0 -0
- pandaprobe-0.1.1/tests/test_wrappers/test_anthropic.py +561 -0
- pandaprobe-0.1.1/tests/test_wrappers/test_gemini.py +437 -0
- pandaprobe-0.1.1/tests/test_wrappers/test_openai.py +482 -0
- pandaprobe-0.1.1/uv.lock +6183 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
*.egg
|
|
7
|
+
*.egg-info/
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
.eggs/
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
env/
|
|
16
|
+
|
|
17
|
+
# Testing
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.coverage
|
|
20
|
+
htmlcov/
|
|
21
|
+
.tox/
|
|
22
|
+
|
|
23
|
+
# Linting
|
|
24
|
+
.ruff_cache/
|
|
25
|
+
.mypy_cache/
|
|
26
|
+
|
|
27
|
+
# IDE
|
|
28
|
+
.vscode/
|
|
29
|
+
.cursor/plans/
|
|
30
|
+
.idea/
|
|
31
|
+
*.swp
|
|
32
|
+
*.swo
|
|
33
|
+
*~
|
|
34
|
+
|
|
35
|
+
# OS
|
|
36
|
+
.DS_Store
|
|
37
|
+
Thumbs.db
|
|
38
|
+
|
|
39
|
+
# Environment
|
|
40
|
+
.env
|
|
41
|
+
.env.*
|
|
42
|
+
!.env.example
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
.PHONY: install install-langgraph install-google-adk install-claude-agent-sdk install-crewai install-openai-agents lock lint format format-check test test-cov build clean
|
|
2
|
+
|
|
3
|
+
install:
|
|
4
|
+
uv sync --extra dev
|
|
5
|
+
|
|
6
|
+
install-langgraph:
|
|
7
|
+
uv sync --extra dev --extra langgraph
|
|
8
|
+
|
|
9
|
+
install-google-adk:
|
|
10
|
+
uv sync --extra dev --extra google-adk
|
|
11
|
+
|
|
12
|
+
install-claude-agent-sdk:
|
|
13
|
+
uv sync --extra dev --extra claude-agent-sdk
|
|
14
|
+
|
|
15
|
+
install-crewai:
|
|
16
|
+
uv sync --extra dev --extra crewai
|
|
17
|
+
|
|
18
|
+
install-openai-agents:
|
|
19
|
+
uv sync --extra dev --extra openai-agents
|
|
20
|
+
|
|
21
|
+
lock:
|
|
22
|
+
uv lock
|
|
23
|
+
|
|
24
|
+
lint:
|
|
25
|
+
uv run ruff check .
|
|
26
|
+
|
|
27
|
+
format:
|
|
28
|
+
uv run ruff format .
|
|
29
|
+
|
|
30
|
+
format-check:
|
|
31
|
+
uv run ruff format --check .
|
|
32
|
+
|
|
33
|
+
test:
|
|
34
|
+
uv run pytest tests/ -v
|
|
35
|
+
|
|
36
|
+
test-cov:
|
|
37
|
+
uv run pytest tests/ -v --cov=pandaprobe --cov-report=term-missing
|
|
38
|
+
|
|
39
|
+
build:
|
|
40
|
+
uv build
|
|
41
|
+
|
|
42
|
+
clean:
|
|
43
|
+
rm -rf dist/ build/ *.egg-info src/*.egg-info .pytest_cache .ruff_cache
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pandaprobe
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Python SDK for PandaProbe — open-source agent tracing and evaluation
|
|
5
|
+
Project-URL: Homepage, https://github.com/chirpz-ai/pandaprobe-sdk
|
|
6
|
+
Project-URL: Documentation, https://github.com/chirpz-ai/pandaprobe-sdk
|
|
7
|
+
Project-URL: Repository, https://github.com/chirpz-ai/pandaprobe-sdk
|
|
8
|
+
Author-email: PandaProbe | Chirpz AI <support@chirpz.ai>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Keywords: agents,ai,evaluation,llm,observability,tracing
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: httpx>=0.25.0
|
|
23
|
+
Requires-Dist: pydantic>=2.0.0
|
|
24
|
+
Provides-Extra: anthropic
|
|
25
|
+
Requires-Dist: anthropic>=0.80.0; extra == 'anthropic'
|
|
26
|
+
Provides-Extra: claude-agent-sdk
|
|
27
|
+
Requires-Dist: claude-agent-sdk>=0.1.0; extra == 'claude-agent-sdk'
|
|
28
|
+
Requires-Dist: wrapt>=1.14.0; extra == 'claude-agent-sdk'
|
|
29
|
+
Provides-Extra: crewai
|
|
30
|
+
Requires-Dist: crewai>=0.100.0; extra == 'crewai'
|
|
31
|
+
Requires-Dist: wrapt>=1.14.0; extra == 'crewai'
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: anthropic>=0.80.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: build>=1.0.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: google-genai>=1.0.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: langchain-google-genai>=4.0.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: langchain-openai>=0.2.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: openai>=1.0.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest-cov>=6.0; extra == 'dev'
|
|
41
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
42
|
+
Requires-Dist: respx>=0.21.0; extra == 'dev'
|
|
43
|
+
Requires-Dist: ruff>=0.8.0; extra == 'dev'
|
|
44
|
+
Requires-Dist: twine>=6.0.0; extra == 'dev'
|
|
45
|
+
Provides-Extra: examples
|
|
46
|
+
Requires-Dist: anthropic>=0.80.0; extra == 'examples'
|
|
47
|
+
Requires-Dist: google-genai>=1.0.0; extra == 'examples'
|
|
48
|
+
Requires-Dist: langchain-google-genai>=4.0.0; extra == 'examples'
|
|
49
|
+
Requires-Dist: langchain-openai>=0.2.0; extra == 'examples'
|
|
50
|
+
Requires-Dist: openai>=1.0.0; extra == 'examples'
|
|
51
|
+
Provides-Extra: gemini
|
|
52
|
+
Requires-Dist: google-genai>=1.0.0; extra == 'gemini'
|
|
53
|
+
Provides-Extra: google-adk
|
|
54
|
+
Requires-Dist: google-adk>=1.0.0; extra == 'google-adk'
|
|
55
|
+
Requires-Dist: wrapt>=1.14.0; extra == 'google-adk'
|
|
56
|
+
Provides-Extra: langgraph
|
|
57
|
+
Requires-Dist: langchain-core>=0.3.0; extra == 'langgraph'
|
|
58
|
+
Requires-Dist: langgraph>=0.2.0; extra == 'langgraph'
|
|
59
|
+
Provides-Extra: openai
|
|
60
|
+
Requires-Dist: openai>=1.0.0; extra == 'openai'
|
|
61
|
+
Provides-Extra: openai-agents
|
|
62
|
+
Requires-Dist: openai-agents>=0.13.0; extra == 'openai-agents'
|
|
63
|
+
Description-Content-Type: text/markdown
|
|
64
|
+
|
|
65
|
+
# PandaProbe Python SDK
|
|
66
|
+
|
|
67
|
+
Python SDK for [PandaProbe](https://github.com/chirpz-ai/pandaprobe-sdk) — open-source agent tracing and evaluation.
|
|
68
|
+
|
|
69
|
+
## Installation
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install pandaprobe
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
With optional integrations:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install pandaprobe[openai] # OpenAI wrapper
|
|
79
|
+
pip install pandaprobe[gemini] # Google Gemini wrapper
|
|
80
|
+
pip install pandaprobe[anthropic] # Anthropic wrapper
|
|
81
|
+
pip install pandaprobe[langgraph] # LangGraph integration
|
|
82
|
+
pip install pandaprobe[all] # Everything
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Quick Start
|
|
86
|
+
|
|
87
|
+
### 1. Set environment variables
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
export PANDAPROBE_API_KEY="sk_pp_..."
|
|
91
|
+
export PANDAPROBE_PROJECT_NAME="my-project"
|
|
92
|
+
export PANDAPROBE_ENDPOINT="my-pandaprobe-endpoint"
|
|
93
|
+
export PANDAPROBE_ENVIRONMENT="production" # optional
|
|
94
|
+
export PANDAPROBE_RELEASE="v1.2.0" # optional
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The SDK auto-initializes from these environment variables on first use — no explicit `init()` call is needed. To disable tracing, set `PANDAPROBE_ENABLED=false`.
|
|
98
|
+
|
|
99
|
+
You can still use `pandaprobe.init(...)` for programmatic configuration if preferred.
|
|
100
|
+
|
|
101
|
+
### 2. Decorator-based tracing (custom agents)
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
import pandaprobe
|
|
105
|
+
|
|
106
|
+
@pandaprobe.trace(name="my-agent")
|
|
107
|
+
def run_agent(query: str):
|
|
108
|
+
@pandaprobe.span(name="llm-call", kind="LLM")
|
|
109
|
+
def call_llm(prompt):
|
|
110
|
+
return openai_client.chat.completions.create(...)
|
|
111
|
+
|
|
112
|
+
@pandaprobe.span(name="search", kind="TOOL")
|
|
113
|
+
def search(q):
|
|
114
|
+
return search_engine.search(q)
|
|
115
|
+
|
|
116
|
+
context = search(query)
|
|
117
|
+
return call_llm(f"Context: {context}\nQuery: {query}")
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 3. OpenAI wrapper (automatic LLM tracing)
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from pandaprobe.wrappers import wrap_openai
|
|
124
|
+
import openai
|
|
125
|
+
|
|
126
|
+
client = wrap_openai(openai.OpenAI())
|
|
127
|
+
|
|
128
|
+
# Chat Completions API — automatically traced:
|
|
129
|
+
response = client.chat.completions.create(
|
|
130
|
+
model="gpt-5.4-nano",
|
|
131
|
+
messages=[{"role": "user", "content": "Hello"}],
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
# Responses API — also automatically traced, including reasoning summaries
|
|
135
|
+
# and built-in tool calls (web_search, function_call, etc.) as child spans:
|
|
136
|
+
response = client.responses.create(
|
|
137
|
+
model="gpt-5.4-nano",
|
|
138
|
+
input="Explain recursion in one sentence.",
|
|
139
|
+
reasoning={"effort": "low", "summary": "auto"},
|
|
140
|
+
)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### 4. Gemini wrapper (automatic LLM tracing)
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
from pandaprobe.wrappers import wrap_gemini
|
|
147
|
+
from google import genai
|
|
148
|
+
|
|
149
|
+
client = wrap_gemini(genai.Client())
|
|
150
|
+
|
|
151
|
+
response = client.models.generate_content(
|
|
152
|
+
model="gemini-2.5-flash",
|
|
153
|
+
contents="Explain recursion in one sentence.",
|
|
154
|
+
)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### 5. Anthropic wrapper (automatic LLM tracing)
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
from pandaprobe.wrappers import wrap_anthropic
|
|
161
|
+
import anthropic
|
|
162
|
+
|
|
163
|
+
client = wrap_anthropic(anthropic.Anthropic())
|
|
164
|
+
|
|
165
|
+
response = client.messages.create(
|
|
166
|
+
model="claude-sonnet-4-20250514",
|
|
167
|
+
max_tokens=150,
|
|
168
|
+
system="You are a concise assistant.",
|
|
169
|
+
messages=[{"role": "user", "content": "Explain recursion in one sentence."}],
|
|
170
|
+
)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 6. LangGraph integration
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
from pandaprobe.integrations.langgraph import LangGraphCallbackHandler
|
|
177
|
+
|
|
178
|
+
handler = LangGraphCallbackHandler()
|
|
179
|
+
result = graph.invoke(
|
|
180
|
+
{"messages": [HumanMessage(content="hello")]},
|
|
181
|
+
config={"callbacks": [handler]},
|
|
182
|
+
)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 7. Session and user tracking
|
|
186
|
+
|
|
187
|
+
Group related traces under a session and/or user using the universal context API:
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
import pandaprobe
|
|
191
|
+
|
|
192
|
+
# Context managers — scoped to the block
|
|
193
|
+
with pandaprobe.session("conversation-123"):
|
|
194
|
+
with pandaprobe.user("user-abc"):
|
|
195
|
+
run_agent("What is recursion?")
|
|
196
|
+
run_agent("Can you give me an example?")
|
|
197
|
+
|
|
198
|
+
# Imperative — useful for dynamic switching
|
|
199
|
+
pandaprobe.set_session("conversation-456")
|
|
200
|
+
pandaprobe.set_user("user-xyz")
|
|
201
|
+
run_agent("New topic")
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Both propagate across all SDK layers (decorators, wrappers, integrations, context managers). Explicit parameters (`session_id=`, `user_id=`) take precedence over the context.
|
|
205
|
+
|
|
206
|
+
### 8. Programmatic scoring
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
pandaprobe.score(
|
|
210
|
+
trace_id="...",
|
|
211
|
+
name="user_satisfaction",
|
|
212
|
+
value="0.9",
|
|
213
|
+
data_type="NUMERIC",
|
|
214
|
+
reason="User clicked thumbs up",
|
|
215
|
+
)
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### 9. Flushing
|
|
219
|
+
|
|
220
|
+
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.
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
pandaprobe.flush()
|
|
224
|
+
pandaprobe.shutdown()
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Configuration
|
|
228
|
+
|
|
229
|
+
| Environment Variable | Default | Description |
|
|
230
|
+
|---|---|---|
|
|
231
|
+
| `PANDAPROBE_API_KEY` | *(required)* | API key |
|
|
232
|
+
| `PANDAPROBE_PROJECT_NAME` | *(required)* | Project name |
|
|
233
|
+
| `PANDAPROBE_ENDPOINT` | `http://localhost:8000` | Backend URL |
|
|
234
|
+
| `PANDAPROBE_ENVIRONMENT` | `None` | Environment tag (e.g. `production`, `staging`) |
|
|
235
|
+
| `PANDAPROBE_RELEASE` | `None` | Release/version tag (e.g. `v1.2.0`) |
|
|
236
|
+
| `PANDAPROBE_ENABLED` | `true` | Enable/disable SDK |
|
|
237
|
+
| `PANDAPROBE_BATCH_SIZE` | `10` | Traces per flush batch |
|
|
238
|
+
| `PANDAPROBE_FLUSH_INTERVAL` | `5.0` | Seconds between flushes |
|
|
239
|
+
| `PANDAPROBE_DEBUG` | `false` | Verbose logging |
|
|
240
|
+
|
|
241
|
+
## Development
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
make py-install # Install all deps (providers, examples, dev tools)
|
|
245
|
+
make py-lint # Run linter
|
|
246
|
+
make py-format # Auto-format
|
|
247
|
+
make py-test # Run tests
|
|
248
|
+
make py-test-cov # Tests with coverage
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## License
|
|
252
|
+
|
|
253
|
+
MIT
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# PandaProbe Python SDK
|
|
2
|
+
|
|
3
|
+
Python SDK for [PandaProbe](https://github.com/chirpz-ai/pandaprobe-sdk) — open-source agent tracing and evaluation.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install pandaprobe
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
With optional integrations:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install pandaprobe[openai] # OpenAI wrapper
|
|
15
|
+
pip install pandaprobe[gemini] # Google Gemini wrapper
|
|
16
|
+
pip install pandaprobe[anthropic] # Anthropic wrapper
|
|
17
|
+
pip install pandaprobe[langgraph] # LangGraph integration
|
|
18
|
+
pip install pandaprobe[all] # Everything
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### 1. Set environment variables
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
export PANDAPROBE_API_KEY="sk_pp_..."
|
|
27
|
+
export PANDAPROBE_PROJECT_NAME="my-project"
|
|
28
|
+
export PANDAPROBE_ENDPOINT="my-pandaprobe-endpoint"
|
|
29
|
+
export PANDAPROBE_ENVIRONMENT="production" # optional
|
|
30
|
+
export PANDAPROBE_RELEASE="v1.2.0" # optional
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The SDK auto-initializes from these environment variables on first use — no explicit `init()` call is needed. To disable tracing, set `PANDAPROBE_ENABLED=false`.
|
|
34
|
+
|
|
35
|
+
You can still use `pandaprobe.init(...)` for programmatic configuration if preferred.
|
|
36
|
+
|
|
37
|
+
### 2. Decorator-based tracing (custom agents)
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
import pandaprobe
|
|
41
|
+
|
|
42
|
+
@pandaprobe.trace(name="my-agent")
|
|
43
|
+
def run_agent(query: str):
|
|
44
|
+
@pandaprobe.span(name="llm-call", kind="LLM")
|
|
45
|
+
def call_llm(prompt):
|
|
46
|
+
return openai_client.chat.completions.create(...)
|
|
47
|
+
|
|
48
|
+
@pandaprobe.span(name="search", kind="TOOL")
|
|
49
|
+
def search(q):
|
|
50
|
+
return search_engine.search(q)
|
|
51
|
+
|
|
52
|
+
context = search(query)
|
|
53
|
+
return call_llm(f"Context: {context}\nQuery: {query}")
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 3. OpenAI wrapper (automatic LLM tracing)
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from pandaprobe.wrappers import wrap_openai
|
|
60
|
+
import openai
|
|
61
|
+
|
|
62
|
+
client = wrap_openai(openai.OpenAI())
|
|
63
|
+
|
|
64
|
+
# Chat Completions API — automatically traced:
|
|
65
|
+
response = client.chat.completions.create(
|
|
66
|
+
model="gpt-5.4-nano",
|
|
67
|
+
messages=[{"role": "user", "content": "Hello"}],
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# Responses API — also automatically traced, including reasoning summaries
|
|
71
|
+
# and built-in tool calls (web_search, function_call, etc.) as child spans:
|
|
72
|
+
response = client.responses.create(
|
|
73
|
+
model="gpt-5.4-nano",
|
|
74
|
+
input="Explain recursion in one sentence.",
|
|
75
|
+
reasoning={"effort": "low", "summary": "auto"},
|
|
76
|
+
)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 4. Gemini wrapper (automatic LLM tracing)
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from pandaprobe.wrappers import wrap_gemini
|
|
83
|
+
from google import genai
|
|
84
|
+
|
|
85
|
+
client = wrap_gemini(genai.Client())
|
|
86
|
+
|
|
87
|
+
response = client.models.generate_content(
|
|
88
|
+
model="gemini-2.5-flash",
|
|
89
|
+
contents="Explain recursion in one sentence.",
|
|
90
|
+
)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 5. Anthropic wrapper (automatic LLM tracing)
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from pandaprobe.wrappers import wrap_anthropic
|
|
97
|
+
import anthropic
|
|
98
|
+
|
|
99
|
+
client = wrap_anthropic(anthropic.Anthropic())
|
|
100
|
+
|
|
101
|
+
response = client.messages.create(
|
|
102
|
+
model="claude-sonnet-4-20250514",
|
|
103
|
+
max_tokens=150,
|
|
104
|
+
system="You are a concise assistant.",
|
|
105
|
+
messages=[{"role": "user", "content": "Explain recursion in one sentence."}],
|
|
106
|
+
)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 6. LangGraph integration
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from pandaprobe.integrations.langgraph import LangGraphCallbackHandler
|
|
113
|
+
|
|
114
|
+
handler = LangGraphCallbackHandler()
|
|
115
|
+
result = graph.invoke(
|
|
116
|
+
{"messages": [HumanMessage(content="hello")]},
|
|
117
|
+
config={"callbacks": [handler]},
|
|
118
|
+
)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 7. Session and user tracking
|
|
122
|
+
|
|
123
|
+
Group related traces under a session and/or user using the universal context API:
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
import pandaprobe
|
|
127
|
+
|
|
128
|
+
# Context managers — scoped to the block
|
|
129
|
+
with pandaprobe.session("conversation-123"):
|
|
130
|
+
with pandaprobe.user("user-abc"):
|
|
131
|
+
run_agent("What is recursion?")
|
|
132
|
+
run_agent("Can you give me an example?")
|
|
133
|
+
|
|
134
|
+
# Imperative — useful for dynamic switching
|
|
135
|
+
pandaprobe.set_session("conversation-456")
|
|
136
|
+
pandaprobe.set_user("user-xyz")
|
|
137
|
+
run_agent("New topic")
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Both propagate across all SDK layers (decorators, wrappers, integrations, context managers). Explicit parameters (`session_id=`, `user_id=`) take precedence over the context.
|
|
141
|
+
|
|
142
|
+
### 8. Programmatic scoring
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
pandaprobe.score(
|
|
146
|
+
trace_id="...",
|
|
147
|
+
name="user_satisfaction",
|
|
148
|
+
value="0.9",
|
|
149
|
+
data_type="NUMERIC",
|
|
150
|
+
reason="User clicked thumbs up",
|
|
151
|
+
)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 9. Flushing
|
|
155
|
+
|
|
156
|
+
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.
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
pandaprobe.flush()
|
|
160
|
+
pandaprobe.shutdown()
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Configuration
|
|
164
|
+
|
|
165
|
+
| Environment Variable | Default | Description |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| `PANDAPROBE_API_KEY` | *(required)* | API key |
|
|
168
|
+
| `PANDAPROBE_PROJECT_NAME` | *(required)* | Project name |
|
|
169
|
+
| `PANDAPROBE_ENDPOINT` | `http://localhost:8000` | Backend URL |
|
|
170
|
+
| `PANDAPROBE_ENVIRONMENT` | `None` | Environment tag (e.g. `production`, `staging`) |
|
|
171
|
+
| `PANDAPROBE_RELEASE` | `None` | Release/version tag (e.g. `v1.2.0`) |
|
|
172
|
+
| `PANDAPROBE_ENABLED` | `true` | Enable/disable SDK |
|
|
173
|
+
| `PANDAPROBE_BATCH_SIZE` | `10` | Traces per flush batch |
|
|
174
|
+
| `PANDAPROBE_FLUSH_INTERVAL` | `5.0` | Seconds between flushes |
|
|
175
|
+
| `PANDAPROBE_DEBUG` | `false` | Verbose logging |
|
|
176
|
+
|
|
177
|
+
## Development
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
make py-install # Install all deps (providers, examples, dev tools)
|
|
181
|
+
make py-lint # Run linter
|
|
182
|
+
make py-format # Auto-format
|
|
183
|
+
make py-test # Run tests
|
|
184
|
+
make py-test-cov # Tests with coverage
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## License
|
|
188
|
+
|
|
189
|
+
MIT
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# PandaProbe SDK Examples
|
|
2
|
+
|
|
3
|
+
Real end-to-end examples that call live services and send traces to the PandaProbe backend. Use these to validate SDK integrations during development.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
### 1. Install the SDK with all dependencies
|
|
8
|
+
|
|
9
|
+
From the repo root:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
make py-install
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### 2. Export environment variables
|
|
16
|
+
|
|
17
|
+
All examples require:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
export PANDAPROBE_API_KEY="sk_pp_..."
|
|
21
|
+
export PANDAPROBE_PROJECT_NAME="my-project"
|
|
22
|
+
export PANDAPROBE_ENDPOINT="http://localhost:8000"
|
|
23
|
+
|
|
24
|
+
# Provider keys (set whichever you need):
|
|
25
|
+
export OPENAI_API_KEY="sk-..."
|
|
26
|
+
export GOOGLE_API_KEY="..."
|
|
27
|
+
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The SDK auto-initializes from these environment variables — no `pandaprobe.init()` call is needed.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
To enable debug logging:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
export PANDAPROBE_DEBUG=true
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
To disable tracing:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
export PANDAPROBE_ENABLED=false
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 3. Run any example
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cd libraries/python
|
|
49
|
+
uv run python examples/openai/01_chat_completion.py
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Examples
|
|
53
|
+
|
|
54
|
+
### Context Managers
|
|
55
|
+
|
|
56
|
+
| Example | Description |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `context_managers/01_rag_pipeline.py` | RAG pipeline with retrieval + LLM generation + scoring via `pandaprobe.start_trace()` and `trace.span()` |
|
|
59
|
+
| `context_managers/02_multi_turn.py` | Multi-turn tutoring agent with session grouping via `pandaprobe.session()` |
|
|
60
|
+
|
|
61
|
+
### Decorators
|
|
62
|
+
|
|
63
|
+
| Example | Description |
|
|
64
|
+
|---|---|
|
|
65
|
+
| `decorators/01_support_agent.py` | Customer support agent with retrieval + LLM via `@pandaprobe.trace` and `@pandaprobe.span` |
|
|
66
|
+
| `decorators/02_multi_turn.py` | Multi-turn topic assistant with session grouping via `pandaprobe.session()` + `@pandaprobe.trace` |
|
|
67
|
+
|
|
68
|
+
### OpenAI Wrapper
|
|
69
|
+
|
|
70
|
+
| Example | Description |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `openai/01_chat_completion.py` | Chat Completions API with automatic tracing via `wrap_openai` |
|
|
73
|
+
| `openai/02_streaming.py` | Streaming chat completion with automatic tracing via `wrap_openai` |
|
|
74
|
+
| `openai/03_multi_turn.py` | Multi-turn conversation with session grouping via `pandaprobe.session()` + `wrap_openai` |
|
|
75
|
+
| `openai/04_responses_api.py` | Responses API with reasoning summaries and automatic tracing via `wrap_openai` |
|
|
76
|
+
|
|
77
|
+
### Gemini Wrapper
|
|
78
|
+
|
|
79
|
+
| Example | Description |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `gemini/01_chat_completion.py` | generate_content with automatic tracing via `wrap_gemini` |
|
|
82
|
+
| `gemini/02_multi_turn.py` | Multi-turn conversation with session grouping via `pandaprobe.session()` + `wrap_gemini` |
|
|
83
|
+
|
|
84
|
+
### Anthropic Wrapper
|
|
85
|
+
|
|
86
|
+
| Example | Description |
|
|
87
|
+
|---|---|
|
|
88
|
+
| `anthropic/01_chat_completion.py` | messages.create with extended thinking and automatic tracing via `wrap_anthropic` |
|
|
89
|
+
| `anthropic/02_multi_turn.py` | Multi-turn conversation with extended thinking and session grouping via `pandaprobe.session()` + `wrap_anthropic` |
|
|
90
|
+
|
|
91
|
+
### LangGraph
|
|
92
|
+
|
|
93
|
+
| Example | Description |
|
|
94
|
+
|---|---|
|
|
95
|
+
| `langgraph/01_chatbot.py` | Simple chatbot with `LangGraphCallbackHandler` |
|
|
96
|
+
| `langgraph/02_tool_agent.py` | ReAct agent with weather + population tools via `LangGraphCallbackHandler` |
|
|
97
|
+
| `langgraph/03_multi_turn.py` | Multi-turn travel advisor with session grouping via `pandaprobe.session()` + `LangGraphCallbackHandler` |
|
|
98
|
+
|
|
99
|
+
### Google ADK
|
|
100
|
+
|
|
101
|
+
| Example | Description |
|
|
102
|
+
|---|---|
|
|
103
|
+
| `google_adk/01_simple_agent.py` | Simple chatbot agent with automatic tracing via `GoogleADKAdapter` |
|
|
104
|
+
| `google_adk/02_tool_agent.py` | Agent with weather + population tools via `GoogleADKAdapter` |
|
|
105
|
+
| `google_adk/03_multi_turn.py` | Multi-turn travel advisor with session grouping via `pandaprobe.session()` + `GoogleADKAdapter` |
|
|
106
|
+
|
|
107
|
+
### Claude Agent SDK
|
|
108
|
+
|
|
109
|
+
| Example | Description |
|
|
110
|
+
|---|---|
|
|
111
|
+
| `claude_agent_sdk/01_simple_agent.py` | Simple chatbot with automatic tracing via `ClaudeAgentSDKAdapter` |
|
|
112
|
+
| `claude_agent_sdk/02_tool_agent.py` | Agent with custom tools (weather + population) via `ClaudeAgentSDKAdapter` |
|
|
113
|
+
| `claude_agent_sdk/03_multi_turn.py` | Multi-turn travel advisor with session grouping via `pandaprobe.session()` + `ClaudeAgentSDKAdapter` |
|
|
114
|
+
|
|
115
|
+
### CrewAI
|
|
116
|
+
|
|
117
|
+
| Example | Description |
|
|
118
|
+
|---|---|
|
|
119
|
+
| `crewai/01_simple_crew.py` | Simple crew with a single agent and task via `CrewAIAdapter` |
|
|
120
|
+
| `crewai/02_tool_crew.py` | Crew with tool-calling agent (weather + population) via `CrewAIAdapter` |
|
|
121
|
+
| `crewai/03_multi_agent.py` | Multi-agent crew with sequential task execution via `CrewAIAdapter` |
|
|
122
|
+
|
|
123
|
+
### OpenAI Agents SDK
|
|
124
|
+
|
|
125
|
+
| Example | Description |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `openai_agents/01_simple_agent.py` | Simple agent with automatic tracing via `OpenAIAgentsAdapter` |
|
|
128
|
+
| `openai_agents/02_tool_agent.py` | Agent with function tools (weather + population) via `OpenAIAgentsAdapter` |
|
|
129
|
+
| `openai_agents/03_multi_turn.py` | Multi-turn conversation with session grouping via `pandaprobe.session()` + `OpenAIAgentsAdapter` |
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
## Session API
|
|
133
|
+
|
|
134
|
+
The SDK provides a universal `session_id` propagation mechanism that works across all layers:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
import uuid
|
|
138
|
+
import pandaprobe
|
|
139
|
+
|
|
140
|
+
session_id = str(uuid.uuid4())
|
|
141
|
+
|
|
142
|
+
# Option 1: Context manager (recommended for scoped usage)
|
|
143
|
+
with pandaprobe.session(session_id):
|
|
144
|
+
# All traces created here inherit the session_id
|
|
145
|
+
run_agent(query)
|
|
146
|
+
|
|
147
|
+
# Option 2: Imperative setter (for dynamic switching)
|
|
148
|
+
pandaprobe.set_session(str(uuid.uuid4()))
|
|
149
|
+
run_agent(query)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Session precedence (highest to lowest):
|
|
153
|
+
1. Explicit parameter (`session_id="..."` passed directly)
|
|
154
|
+
2. Context var (`pandaprobe.session()` / `pandaprobe.set_session()`)
|
|
155
|
+
3. None
|
|
156
|
+
|
|
157
|
+
## What to Look For
|
|
158
|
+
|
|
159
|
+
After running an example, check your PandaProbe backend to verify:
|
|
160
|
+
|
|
161
|
+
- **Traces** appear with the correct name and project
|
|
162
|
+
- **Spans** show proper parent-child hierarchy
|
|
163
|
+
- **LLM spans** capture model name, token usage, and input/output
|
|
164
|
+
- **Tool spans** (LangGraph examples) capture tool name and results
|
|
165
|
+
- **Scores** are attached to the correct traces
|
|
166
|
+
- **Sessions** group related traces together (multi-turn examples)
|