Skip to main content

Real-time monitoring for AI agents

Project description

Dunetrace SDK

Runtime observability for AI agents. Detects tool loops, context bloat, prompt injection, and 20 other failure patterns in real-time — with a Slack alert while the run is still live.

Zero external dependencies.

Install

pip install dunetrace                    # core SDK
pip install 'dunetrace[langchain]'       # + LangChain / LangGraph
pip install 'dunetrace[otel]'            # + OpenTelemetry exporter

Quickstart

LangChain / LangGraph

from dunetrace import Dunetrace
from dunetrace.integrations.langchain import DunetraceCallbackHandler

dt = Dunetrace()
callback = DunetraceCallbackHandler(dt, agent_id="my-agent")

result = agent.invoke(input, config={"callbacks": [callback]})
dt.shutdown()

Pure Python / custom agent — decorator style

from dunetrace import Dunetrace

dt = Dunetrace()

@dt.tool                                  # auto-emits tool.called / tool.responded
def web_search(query: str) -> list: ...   # args are transmitted as-is

@dt.trace                                 # agent_id defaults to "my_agent"
def my_agent(question: str) -> str:
    return web_search(question)[0]        # zero SDK calls needed inside function bodies

@dt.trace supports bare usage (@dt.trace with no parens), explicit agent ID (@dt.trace("research-agent")), and keyword args (@dt.trace(model="gpt-4o")). @dt.tool works on both sync and async functions and is a no-op when called outside a run context.

Or with @dt.agent + auto-instrumentation:

dt.init(agent_id="my-agent")   # patches openai, anthropic, httpx, requests, langchain, crewai

@dt.agent(model="gpt-4o")      # agent_id inherited from init()
def run_agent(query: str) -> str:
    return openai_client.chat.completions.create(...).choices[0].message.content

LangChain/LangGraph and CrewAI agents need zero manual callback wiring — see docs/integrations/auto-instrumentation.md for how agent attribution is resolved.

FastAPI / Flask — one line each, see docs/integrate-custom-python-agent.md.

What it detects

23 detectors run on every completed run — no configuration, no LLM. A few of the main ones:

Detector What it catches Severity
TOOL_LOOP Same tool called 3+ times in a 5-call window HIGH
RETRY_STORM Same tool fails 3+ times in a row HIGH
PROMPT_INJECTION_SIGNAL Input matches known injection / jailbreak patterns CRITICAL
COST_SPIKE Total tokens 3× above per-agent P75 baseline MEDIUM
PREMATURE_TERMINATION Agent claims success right after a tool call it made actually failed HIGH/CRITICAL
RUNAWAY_ITERATION Step or cost ceiling crossed with no completion signal HIGH/CRITICAL

docs/detectors.md for the full list of 23 detectors

Output modes

Mode How to enable Destination
HTTP ingest (default) endpoint="http://…" Dunetrace backend → detection, alerts, dashboard
Loki NDJSON emit_as_json=True stdout → Promtail / Grafana Alloy
OpenTelemetry otel_exporter=DunetraceOTelExporter(provider) Tempo, Honeycomb, Datadog, Jaeger

Backend

git clone https://github.com/dunetrace/dunetrace
cd dunetrace && cp .env.example .env && docker compose up -d

Dashboard → http://localhost:3000 · Ingest → http://localhost:8001

Deploy markers

Annotate the detector timeline with release boundaries so you can correlate failure spikes with deploys:

# Call from your deploy script, CI/CD pipeline, or app startup
dt.mark_deploy("my-agent", version="v1.4.2", commit="abc1234", env="production")

The dashboard renders blue dashed vertical lines at each deploy timestamp on the 30-day detector rate chart. Fire-and-forget — runs on a background thread, never blocks the caller.

Additional keyword arguments are stored as meta and shown on hover.

Policies

Runtime guardrails that fire mid-run — before a failure propagates. Define conditions with any supported trigger and attach a stop, switch_model, inject_prompt, or log action.

from dunetrace import Dunetrace

dt = Dunetrace()

# Stop the run if tool call count exceeds 5
dt.add_policy(
    name="cap tool calls",
    condition={"trigger": "tool_call_count", "operator": "gt", "value": 5},
    action={"type": "stop"},
)

# Downgrade model when cost exceeds $0.50
dt.add_policy(
    name="cost cap",
    condition={"trigger": "cost_usd", "operator": "gt", "value": 0.50},
    action={"type": "switch_model", "params": {"model": "gpt-4o-mini"}},
)

# Inject a corrective prompt when a loop is detected
dt.add_policy(
    name="loop fix",
    condition={"trigger": "signal", "operator": "eq", "value": "TOOL_LOOP"},
    action={"type": "inject_prompt", "params": {"prompt": "Stop repeating tool calls. Summarise what you know and answer."}},
)

with dt.run("my-agent", user_input=query, tools=["search"]) as run:
    ...
    # After a stop policy fires, PolicyViolation is raised
    # After switch_model fires, check run.model_override
    # After inject_prompt fires, check run.pop_prompt_addition()

Policies can also be defined in the dashboard and fetched automatically at run start (60-second TTL cache per agent). See docs/policies.md for the full reference.

MCP server

Query agent signals directly from Claude Code, Cursor, or any MCP-compatible editor — no context switch to the dashboard required.

pip install dunetrace-mcp

Ten tools: list_agents, get_agent_signals, get_agent_health, get_run_detail, get_agent_runs, search_signals, get_signal_detail, get_agent_patterns, summarize_agent, get_instrumentation_guide.

Claude Code — add to ~/.claude.json:

{
  "mcpServers": {
    "dunetrace": {
      "command": "dunetrace-mcp",
      "env": {
        "DUNETRACE_API_URL": "http://localhost:8002",
        "DUNETRACE_API_KEY": "dt_dev_test"
      }
    }
  }
}

Cursor — add to .cursor/mcp.json in your project root (same shape as above).

Once connected, ask your editor things like:

  • "Is my agent healthy?"
  • "What failed in the last 24 hours?"
  • "Show me signal #42 with its fix."
  • "Is this failure systemic or a one-off?"

docs/mcp-server.md

Tests

python -m unittest discover -s tests -v          # SDK tests (no network required)
cd ../mcp-server && python -m pytest tests/ -v   # MCP server tests (no network required)

SDK: 620 tests · MCP server: 154 tests — both run fully offline.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dunetrace-0.4.1.tar.gz (141.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dunetrace-0.4.1-py3-none-any.whl (110.8 kB view details)

Uploaded Python 3

File details

Details for the file dunetrace-0.4.1.tar.gz.

File metadata

  • Download URL: dunetrace-0.4.1.tar.gz
  • Upload date:
  • Size: 141.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dunetrace-0.4.1.tar.gz
Algorithm Hash digest
SHA256 9aee2b71e41fc3d280cf0fae1671619fb0c84dc7a3743703f501847975bba227
MD5 71bbef702d23dd89c37a8157f94798b9
BLAKE2b-256 973a1f920fdc1d895592d6159dea9cfcab09ab7b8e85381b01478ced634f0fe9

See more details on using hashes here.

Provenance

The following attestation bundles were made for dunetrace-0.4.1.tar.gz:

Publisher: publish.yml on dunetrace/dunetrace

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dunetrace-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: dunetrace-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 110.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dunetrace-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 42a0a4df7eef3b490d1c92fc9533249be50473315f7dc174d9821f3dc7e08450
MD5 0246edd9f1f69d8670cebf0cce7b5f87
BLAKE2b-256 19e69cfee2689c1ad72cf714e1a93489990cdd7937c84405a97bb21bea65890c

See more details on using hashes here.

Provenance

The following attestation bundles were made for dunetrace-0.4.1-py3-none-any.whl:

Publisher: publish.yml on dunetrace/dunetrace

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page