AI agent observability and control SDK for Syrin
Project description
Syrin SDK for Python
Mixpanel for AI agents — observability, remote configuration, evals, and debugging for any AI agent, framework, or LLM library. Minimal integration, maximum insight.
What you get
- Dashboard visibility — every LLM call, session, agent run, tool call, and custom event in one place
- Remote config — change model, temperature, prompts, and any parameter live from the dashboard — no redeploy
- Governance — stop or constrain agent behaviour from the backend at runtime
- Checkpoints — save and restore conversation state for recovery flows
- Custom logging — emit structured events that appear on the session timeline
- OpenTelemetry — standard
gen_ai.*spans +syrin.*extensions
Setup — 4 lines
pip install syrin-sdk
import syrin_sdk
syrin_sdk.init(api_key="syrin_...")
That is the entire setup. The SDK connects to your Syrin project and you can immediately start emitting events, using remote config, and scoping sessions.
Core API
1. Session scoping
Group all events for a user request into a single dashboard session.
# Web app — one session per request
with syrin_sdk.session(user_id=user_id, window="day") as sid:
reply = call_llm(messages)
# Background job — independent run each time
with syrin_sdk.session() as sid:
result = run_pipeline()
# Async
async with syrin_sdk.async_session(user_id=user_id) as sid:
reply = await call_llm_async(messages)
Session IDs are stable within a window — all of Alice's requests today share one session, letting you see her full conversation history in the dashboard.
| Call | Session ID |
|---|---|
session() |
ses_a1b2c3d (auto) |
session(user_id="alice", window="day") |
u:alice:2026-04-19 |
session(user_id="alice", window="forever") |
u:alice |
session(key="batch-etl", window="day") |
k:batch-etl:2026-04-19 |
2. Agent scoping
Tag events with the agent that produced them.
with syrin_sdk.agent("researcher"):
response = client.chat.completions.create(...)
# Register with metadata for the dashboard
syrin_sdk.register_agent("researcher", description="Searches and summarises")
Combine with workflow() or swarm() for multi-agent pipelines:
with syrin_sdk.workflow("pipeline"):
with syrin_sdk.agent("planner"):
plan = call_llm(plan_prompt)
with syrin_sdk.agent("executor"):
result = call_llm(exec_prompt)
3. Remote config — cfg()
Declare any parameter as remotely configurable. The dashboard shows a live control panel.
response = client.chat.completions.create(
model=syrin_sdk.cfg("llm.model", "gpt-4o"),
temperature=syrin_sdk.cfg("llm.temperature", 0.7, ge=0.0, le=2.0),
system_prompt=syrin_sdk.cfg("prompt.system", "You are a helpful assistant.", multiline=True),
messages=[...],
)
keyuses dot-notation:"section.field"— sections become accordion groups in the dashboard- The default is used until you push an override from the dashboard
- Inside
with agent("name"):the field is automatically scoped to that agent
4. Custom logging
Emit structured events that appear on the session timeline.
syrin_sdk.log("Retrieved 42 documents", metadata={"collection": "kb", "latency_ms": 45})
syrin_sdk.log("Cost budget at 80%", level="warning")
syrin_sdk.log("Tool call failed", level="error", metadata={"tool": "web_search"})
5. Governance
The backend can stop an agent mid-run. Catch GovernanceStopError:
from syrin_sdk import GovernanceStopError
try:
response = call_llm(messages)
except GovernanceStopError as e:
logger.warning("Agent stopped by governance: %s", e.reason)
return {"error": "request_blocked"}
Common patterns
Instrument a FastAPI route
import syrin_sdk
from fastapi import FastAPI
syrin_sdk.init(api_key="syrin_...")
app = FastAPI()
@app.post("/chat")
async def chat(request: ChatRequest):
async with syrin_sdk.async_session(user_id=request.user_id) as sid:
async with syrin_sdk.async_agent("chat-agent"):
reply = await call_llm(request.messages)
return {"reply": reply, "session_id": sid}
Instrument a tool
@syrin_sdk.tool("web_search")
def search(query: str) -> list[str]:
return web_search_api(query)
# Async
@syrin_sdk.async_tool("database_lookup")
async def lookup(id: str) -> dict:
return await db.get(id)
Checkpoints (save / restore conversation state)
# Save before a risky operation
checkpoint = syrin_sdk.create_checkpoint(messages, label="pre-tool-call")
# If the tool call fails, restore
try:
result = risky_tool_call()
except Exception:
messages = syrin_sdk.restore_checkpoint(checkpoint.checkpoint_id)
Typed agent config schema
For agents with many configurable fields, use AgentSchema:
from syrin_sdk import AgentSchema, field
class ResearchConfig(AgentSchema):
temperature: float = field(0.3, ge=0.0, le=2.0, label="Temperature")
system_prompt: str = field("Research thoroughly.", section="prompt", multiline=True)
max_results: int = field(10, ge=1, le=100)
syrin_sdk.register_agent("researcher", schema=ResearchConfig)
Skip telemetry for specific calls
with syrin_sdk.skip():
client.chat.completions.create(...) # not tracked — useful for health pings
Configuration
sdk = syrin_sdk.init(
api_key="syrin_...", # required
agent_id="my-agent", # optional — ties all calls to this agent by default
offline=False, # True = no network calls (local dev)
capture_content=False, # True = record prompt/response text (PII-sensitive)
capture_tool_calls=True, # record tool call events
backend_url="https://...", # defaults to Syrin cloud
otel_endpoint="http://...", # optional OTLP endpoint for Jaeger / Tempo
)
API reference
Always needed
| Symbol | What it does |
|---|---|
init(api_key, ...) |
Initialize the SDK |
shutdown() |
Flush events, tear down |
session(user_id, window) |
Scope events to a session |
async_session(...) |
Async version |
agent(id) |
Scope events to an agent |
async_agent(id) |
Async version |
cfg(key, default) |
Remote-configurable value |
log(message, level) |
Emit custom event |
GovernanceStopError |
Catch governance stops |
Common
| Symbol | What it does |
|---|---|
register_agent(id, ...) |
Register agent with dashboard |
register_endpoint(name, schema) |
Register run form schema |
configure(**overrides) |
Local config overrides |
on_config_change(callback) |
React to remote config pushes |
on_alert(callback) |
React to backend alerts |
workflow(id) / swarm(id) |
Multi-agent scoping |
tool(name) / async_tool(name) |
Instrument tool functions |
memory(name) |
Instrument memory access |
create_checkpoint(messages) |
Save conversation state |
restore_checkpoint(id) |
Restore conversation state |
skip() |
Exclude a block from telemetry |
health_check() |
Ping the backend |
Advanced (importable, not advertised)
ConfigGuard, ConfigFuse, ConfigAnchor — circuit-breaker and rollback for config changes
tunable / tune() — remote-tunable class decorator
TraceSpan — manual custom trace spans
SyrinSDKCore — raw instrumentation engine for framework authors
Event types (LLMCallEvent, SessionStartedEvent, etc.) — for on_config_change callbacks
Multi-instance
Most apps use the module-level helpers (syrin_sdk.cfg(...), etc.) which target the
default instance. For multiple named instances:
sdk_a = syrin_sdk.init(api_key="...", instance_name="agent-a")
sdk_b = syrin_sdk.init(api_key="...", instance_name="agent-b")
sdk_a.configure(temperature=0.3)
sdk_b.configure(temperature=0.7)
Docs
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file syrin_sdk-1.0.0.tar.gz.
File metadata
- Download URL: syrin_sdk-1.0.0.tar.gz
- Upload date:
- Size: 338.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ace31675af93625750d27f2c7e8503524b927aa2997ace2fff249f43ee1eae5
|
|
| MD5 |
e03375412c3d7333858287225319358f
|
|
| BLAKE2b-256 |
b6a80e2485463273dc8445397a871616f05e253a9d6d2c5aa0e4eb65ced9be82
|
File details
Details for the file syrin_sdk-1.0.0-py3-none-any.whl.
File metadata
- Download URL: syrin_sdk-1.0.0-py3-none-any.whl
- Upload date:
- Size: 137.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bab6b3b90bdbad665fac13e7adf2e189989525db447e1e67d05eda90dd139dbb
|
|
| MD5 |
fb9e4ea72827fb5ddeaf5e2da2b68782
|
|
| BLAKE2b-256 |
361eca1a6656fd9bd7cf40a0c416081db2d72f3c16a8d735e967ba3c07965e8a
|