prismtrace-sdk 0.3.2__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.
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: prismtrace-sdk
3
+ Version: 0.3.2
4
+ Summary: PRISMtrace SDK — AI Observability by Block Convey
5
+ Author: Block Convey
6
+ Requires-Python: >=3.8
7
+ Requires-Dist: httpx>=0.24.0
8
+ Dynamic: author
9
+ Dynamic: requires-dist
10
+ Dynamic: requires-python
11
+ Dynamic: summary
@@ -0,0 +1,337 @@
1
+ # PRISMtrace Python SDK
2
+
3
+ AI Chat Observability by Block Convey. Supports Langchain, OpenTelemetry, Claude tool use tracing, **Trajectory evaluation**, and **Knowledge Base** management.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install prismtrace-sdk
9
+ ```
10
+
11
+ Until the package is on PyPI, install from the repo (or set
12
+ `PRISMTRACE_SDK_INSTALL` in the PRISMtrace backend to the same command):
13
+
14
+ ```bash
15
+ pip install "git+https://github.com/Block-Convey/prismtrace.git#subdirectory=sdk/python"
16
+ # or, from a local checkout:
17
+ pip install -e ./sdk/python
18
+ ```
19
+
20
+ ## Quickstart — Manual Trace
21
+
22
+ ```python
23
+ from prismtrace import PRISMtrace
24
+
25
+ pt = PRISMtrace(
26
+ api_key="pt-sk-your-key",
27
+ host="https://prismtrace-production.up.railway.app",
28
+ project_id="your-project-id",
29
+ )
30
+
31
+ pt.trace_llm(
32
+ model="claude-sonnet-4-5-20250514",
33
+ input_messages=[{"role": "user", "content": "Hello"}],
34
+ output="Hi there!",
35
+ latency_ms=320,
36
+ token_count_input=10,
37
+ token_count_output=5,
38
+ )
39
+
40
+ # Decorator
41
+ @pt.trace()
42
+ def ask_bot(question):
43
+ # your LLM call here
44
+ return "answer"
45
+ ```
46
+
47
+ ## Trajectory Evaluation
48
+
49
+ Submit agent trajectories (ordered step lists) for automated PRISM evaluation — goal adherence, tool compliance, efficiency, and safety scores.
50
+
51
+ ```python
52
+ result = pt.submit_trajectory(
53
+ agent_name="finance-agent",
54
+ model="claude-sonnet-4-5-20250514",
55
+ steps=[
56
+ {
57
+ "step_type": "reasoning",
58
+ "label": "Analyze user query",
59
+ "input_summary": "User asked about Q3 revenue",
60
+ "output_summary": "Need to query knowledge base for financials",
61
+ "duration_ms": 200,
62
+ "token_count": 150,
63
+ },
64
+ {
65
+ "step_type": "tool_call",
66
+ "label": "knowledge_base_search",
67
+ "tool_name": "knowledge_base_search",
68
+ "input_summary": "Q3 revenue figures",
69
+ "output_summary": "Found 3 matching documents",
70
+ "duration_ms": 80,
71
+ },
72
+ {
73
+ "step_type": "final_answer",
74
+ "label": "Provide answer",
75
+ "output_summary": "Q3 revenue was $4.2M, up 12% YoY",
76
+ "duration_ms": 300,
77
+ "token_count": 200,
78
+ },
79
+ ],
80
+ )
81
+
82
+ print(f"Trajectory ID: {result['id']}")
83
+
84
+ # Check evaluation results (runs async after submission)
85
+ evaluation = pt.get_trajectory_evaluation(result["id"])
86
+ print(evaluation)
87
+
88
+ # Re-trigger evaluation if config changed
89
+ pt.retrigger_evaluation(result["id"])
90
+ ```
91
+
92
+ ## Knowledge Base
93
+
94
+ Upload documents and search your project's knowledge base directly from the SDK.
95
+
96
+ ```python
97
+ # Upload a document
98
+ doc = pt.kb_upload(
99
+ filename="company-policy.md",
100
+ content="# Return Policy\nAll items may be returned within 30 days...",
101
+ description="Customer-facing return policy v2",
102
+ content_type="text/markdown",
103
+ )
104
+ print(f"Document ID: {doc['id']}, Chunks: {doc['chunk_count']}")
105
+
106
+ # Search the knowledge base
107
+ results = pt.kb_search("return policy for electronics", limit=3)
108
+ for chunk in results:
109
+ print(f" Score: {chunk['score']:.2f} — {chunk['content'][:80]}...")
110
+
111
+ # List all documents
112
+ docs = pt.kb_list_documents()
113
+
114
+ # Delete a document
115
+ pt.kb_delete_document(doc["id"])
116
+ ```
117
+
118
+ ## LangChain Integration
119
+
120
+ Uses `X-PRISMtrace-Key`. Env vars `PRISMTRACE_API_KEY`, `PRISMTRACE_PROJECT_ID`,
121
+ and `PRISMTRACE_HOST` are read when constructor args are omitted.
122
+
123
+ ```python
124
+ from prismtrace import PRISMtraceCallbackHandler
125
+ from langchain.chains import LLMChain
126
+ from langchain_anthropic import ChatAnthropic
127
+
128
+ handler = PRISMtraceCallbackHandler(
129
+ api_key="pt-sk-...",
130
+ project_id="your-project-id",
131
+ host="https://prismtrace-production.up.railway.app",
132
+ session_id="conversation-1", # groups steps into a trajectory
133
+ )
134
+
135
+ llm = ChatAnthropic(model="claude-sonnet-4-5-20250514")
136
+ chain = LLMChain(llm=llm, prompt=prompt, callbacks=[handler])
137
+ result = chain.run("What is the credit risk for this customer?")
138
+ handler.flush() # safe to call; also runs on process exit
139
+ ```
140
+
141
+ ## LangGraph Integration
142
+
143
+ ```python
144
+ from prismtrace import PRISMtraceLangGraphHandler, wrap_langgraph
145
+
146
+ handler = PRISMtraceLangGraphHandler(
147
+ api_key="pt-sk-...",
148
+ project_id="your-project-id",
149
+ host="https://prismtrace-production.up.railway.app",
150
+ agent_name="support-graph",
151
+ )
152
+ graph = wrap_langgraph(compiled_graph, handler)
153
+ graph.invoke({"messages": [("user", "hello")]})
154
+ ```
155
+
156
+ ## Verify connection
157
+
158
+ ```bash
159
+ export PRISMTRACE_HOST=https://your-host
160
+ export PRISMTRACE_PROJECT_ID=...
161
+ export PRISMTRACE_API_KEY=pt-sk-...
162
+ python -m prismtrace.verify
163
+ # Prints CREDENTIAL OK|FAIL and LIVE CONNECTED|WAITING FOR LIVE
164
+ ```
165
+
166
+ ## Google ADK Integration (Beta)
167
+
168
+ Capture Google Agent Development Kit workflows by passing the adapter's
169
+ hooks to an `LlmAgent`:
170
+
171
+ ```python
172
+ from prismtrace import PRISMtraceADKAdapter
173
+ from google.adk.agents import LlmAgent
174
+
175
+ adapter = PRISMtraceADKAdapter(
176
+ api_key="pt-sk-...",
177
+ project_id="your-project-id",
178
+ agent_name="my-adk-agent",
179
+ )
180
+
181
+ agent = LlmAgent(
182
+ name="loan_assistant",
183
+ model="gemini-2.0-flash",
184
+ instruction="You help users understand loan products.",
185
+ tools=[lookup_rate],
186
+ before_model_callback=adapter.before_model,
187
+ after_model_callback=adapter.after_model,
188
+ before_tool_callback=adapter.before_tool,
189
+ after_tool_callback=adapter.after_tool,
190
+ before_agent_callback=adapter.before_agent,
191
+ after_agent_callback=adapter.after_agent,
192
+ )
193
+ ```
194
+
195
+ Wiring `before_tool_callback=adapter.before_tool` enables real tool
196
+ latency on `after_tool` traces; without it the trace stamps
197
+ `latency_ms=0` and `tool_latency_unavailable=True` in metadata.
198
+
199
+ ### Error capture
200
+
201
+ ADK does not currently surface model/tool errors through a callback.
202
+ Emit explicit error traces from `try / except` blocks instead:
203
+
204
+ ```python
205
+ try:
206
+ response = await llm.generate_content_async(...)
207
+ except Exception as exc:
208
+ adapter.record_model_error(exc, callback_context=ctx)
209
+ raise
210
+
211
+ try:
212
+ result = run_tool(args)
213
+ except Exception as exc:
214
+ adapter.record_tool_error(exc, callback_context=ctx,
215
+ tool_name="lookup_rate",
216
+ tool=tool, tool_context=ctx)
217
+ raise
218
+
219
+ try:
220
+ await Runner.run_async(...)
221
+ except Exception as exc:
222
+ adapter.record_runner_error(exc)
223
+ raise
224
+ ```
225
+
226
+ Each emits a trace with `status=error` in metadata. Error messages are
227
+ scrubbed for `pt-sk-…`, `sk-…`, `sk-ant-…`, `AIza…` and other known
228
+ secret patterns before they're posted.
229
+
230
+ Runnable demo: [`examples/google_adk_demo.py`](examples/google_adk_demo.py).
231
+ Full validation notes (what's captured, Beta gaps, known issues):
232
+ [`docs/GOOGLE_ADK_INTEGRATION.md`](../../docs/GOOGLE_ADK_INTEGRATION.md).
233
+
234
+ ## OpenTelemetry Integration
235
+
236
+ ```python
237
+ from prismtrace.otel import PRISMtraceInstrumentor
238
+
239
+ instrumentor = PRISMtraceInstrumentor()
240
+ instrumentor.instrument(
241
+ api_key="pt-sk-...",
242
+ project_id="your-project-id",
243
+ endpoint="https://prismtrace-production.up.railway.app",
244
+ )
245
+
246
+ tracer = instrumentor.get_tracer("my-service")
247
+ with tracer.start_as_current_span("process_request") as span:
248
+ span.set_attribute("prismtrace.span_type", "chain")
249
+ span.set_attribute("prismtrace.input", "user query")
250
+ # ... your code ...
251
+ span.set_attribute("prismtrace.output", "response")
252
+ ```
253
+
254
+ Requires: `pip install opentelemetry-sdk opentelemetry-api`
255
+
256
+ ## Claude Tool Use Tracing (with auto-trajectory)
257
+
258
+ The `ClaudeAgentTracer` now automatically emits both **spans** (for trace detail) and a **trajectory** (for PRISM evaluation) after each agentic run.
259
+
260
+ ```python
261
+ import anthropic
262
+ from prismtrace.claude_tracer import ClaudeAgentTracer
263
+
264
+ client = anthropic.Anthropic()
265
+
266
+ tracer = ClaudeAgentTracer(
267
+ anthropic_client=client,
268
+ api_key="pt-sk-...",
269
+ project_id="your-project-id",
270
+ endpoint="https://prismtrace-production.up.railway.app",
271
+ agent_name="weather-agent", # shows up in trajectory analytics
272
+ emit_trajectory=True, # default: auto-submit trajectory
273
+ )
274
+
275
+ tools = [
276
+ {
277
+ "name": "get_weather",
278
+ "description": "Get the weather for a location",
279
+ "input_schema": {
280
+ "type": "object",
281
+ "properties": {"location": {"type": "string"}},
282
+ "required": ["location"],
283
+ },
284
+ }
285
+ ]
286
+
287
+ def execute_tool(name: str, input_data: dict) -> str:
288
+ if name == "get_weather":
289
+ return f"72F and sunny in {input_data['location']}"
290
+ return "Unknown tool"
291
+
292
+ result = tracer.run(
293
+ messages=[{"role": "user", "content": "What's the weather in SF?"}],
294
+ tools=tools,
295
+ system="You are a helpful assistant.",
296
+ tool_executor=execute_tool,
297
+ )
298
+
299
+ print(f"Trace ID: {result['trace_id']}")
300
+ print(f"Trajectory ID: {result['trajectory_id']}")
301
+ print(f"Iterations: {result['iterations']}")
302
+ print(f"Traj. steps: {result['trajectory_steps']}")
303
+ ```
304
+
305
+ ### Auto-instrument all Claude calls
306
+
307
+ ```python
308
+ tracer.instrument_client()
309
+
310
+ # Now every client.messages.create() call is automatically traced
311
+ response = client.messages.create(
312
+ model="claude-sonnet-4-5-20250514",
313
+ max_tokens=1024,
314
+ messages=[{"role": "user", "content": "Hello"}],
315
+ )
316
+ ```
317
+
318
+ ## Zero-code Proxy
319
+
320
+ If you route LLM calls through the PRISMtrace proxy (`/proxy/anthropic/v1/messages`), trajectories are **automatically created** whenever the response contains tool-use blocks. No SDK changes needed — just point your Anthropic base URL at the proxy.
321
+
322
+ ```python
323
+ import anthropic
324
+
325
+ client = anthropic.Anthropic(
326
+ base_url="https://prismtrace-production.up.railway.app/proxy/anthropic/v1",
327
+ default_headers={"X-PRISMtrace-Key": "pt-sk-your-key"},
328
+ )
329
+
330
+ # Every tool-use response automatically gets a trajectory + PRISM evaluation
331
+ response = client.messages.create(
332
+ model="claude-sonnet-4-5-20250514",
333
+ max_tokens=1024,
334
+ messages=[{"role": "user", "content": "What's the weather?"}],
335
+ tools=[...],
336
+ )
337
+ ```
@@ -0,0 +1,34 @@
1
+ from .client import PRISMtrace
2
+ from .langchain_handler import PRISMtraceCallbackHandler
3
+ from .claude_tracer import ClaudeAgentTracer
4
+ from .langgraph_helper import PRISMtraceLangGraphHandler, wrap_graph as wrap_langgraph
5
+ from .google_adk import PRISMtraceADKAdapter
6
+ from .litellm_callback import install as install_litellm
7
+ from .openai_agents import PRISMtraceTracingProcessor, install as install_openai_agents
8
+ from .elevenlabs_voice import (
9
+ PRISMtraceVoiceTracer,
10
+ install as install_elevenlabs_voice,
11
+ )
12
+
13
+ __version__ = "0.3.2"
14
+ __all__ = [
15
+ # Core
16
+ "PRISMtrace",
17
+ # LangChain (Supported)
18
+ "PRISMtraceCallbackHandler",
19
+ # Anthropic direct (Supported)
20
+ "ClaudeAgentTracer",
21
+ # LangGraph (Supported)
22
+ "PRISMtraceLangGraphHandler",
23
+ "wrap_langgraph",
24
+ # Google ADK (Beta)
25
+ "PRISMtraceADKAdapter",
26
+ # LiteLLM (Universal Gateway, Supported)
27
+ "install_litellm",
28
+ # OpenAI Agents SDK (Preview)
29
+ "PRISMtraceTracingProcessor",
30
+ "install_openai_agents",
31
+ # ElevenLabs Agents — voice (Supported)
32
+ "PRISMtraceVoiceTracer",
33
+ "install_elevenlabs_voice",
34
+ ]