Skip to content
View dunetrace's full-sized avatar
  • https://dunetrace.com/
  • Berlin

Block or report dunetrace

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Content in all repositories owned by your account will be closed.
Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
dunetrace/README.md

Dunetrace

Dunetrace

Runtime reliability for AI agents. Structural and semantic detection, runtime prevention, native root cause, and one-click fixes.

PyPI version npm version CI License: Apache 2.0 Discord

AI agents fail silently. The API returns 200, latency and cost look normal, and yet:

  • ✗ The upstream API returned an error body. The agent invented the numbers and reported success.
  • ✗ Two agents delegated in a circle. Eight runs, all green, no progress.
  • ✗ A document your agent read last week wrote an instruction into its memory. It fired today.

Tracers answer "what happened?", after you already know it broke. Dunetrace answers "is something breaking right now?" with deterministic, zero-LLM checks on every run, and in the request path, where a policy can block the action before it executes.


Quick Start

You need Docker, plus Python 3.11+ or Node.js 22+.

1. Start Dunetrace (runs on localhost with auth off)

git clone https://github.com/dunetrace/dunetrace && cd dunetrace
docker compose -f docker-compose.ghcr.yml up -d
curl -s localhost:8001/ready    # ready once this prints "status":"ok" (the first start pulls images)

2. Watch it catch failures (no API key, no LLM calls)

pip install dunetrace
SCENARIO=failures python packages/sdk-py/examples/decorator_agent.py

Open http://localhost:3000. Within a few seconds three runs show TOOL_LOOP, RETRY_STORM and RAG_EMPTY_RETRIEVAL, each with what fired, why it matters and how to fix it.

3. Add it to your own agent

Using Claude Code, Cursor or Codex? Let the setup skill instrument your repo instead: npx skills add dunetrace/dunetrace-skills --skill dunetrace-setup, then run /dunetrace-setup (Claude Code, Cursor) or $dunetrace-setup (Codex).

Python (pip install dunetrace)

from dunetrace import Dunetrace
import openai

dt = Dunetrace()                    # sends to http://localhost:8001
dt.init(agent_id="support-agent")   # auto-instruments OpenAI, Anthropic, Mistral, Bedrock, LangChain,
                                    # LangGraph, CrewAI, FastAPI, Flask, httpx and requests

@dt.agent()                         # each call is one run
def answer(question: str) -> str:
    resp = openai.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": question}],
    )
    return resp.choices[0].message.content

TypeScript / Node.js (npm install dunetrace)

import { Dunetrace, autoInstrument } from "dunetrace";
import OpenAI from "openai";

const dt = new Dunetrace();          // sends to http://localhost:8001
autoInstrument({ openai: OpenAI });  // add anthropic: / mistral: too; also patches outbound fetch
const openai = new OpenAI();

await dt.run("support-agent", { model: "gpt-4o" }, async (run) => {   // one run
  await openai.chat.completions.create({
    model: "gpt-4o",
    messages: [{ role: "user", content: "Where is my order?" }],
  });
  run.finalAnswer();
});

LLM calls (streaming included) and outbound HTTP calls are tracked with no changes at the call site. Mark local tool functions with @dt.tool (TypeScript: dt.tool()) to record those too.

Why wrap the entry point? @dt.agent() / dt.run() mark where a run starts and ends. Without them Dunetrace still records your LLM calls as an implicit run, but holds that run's signals in shadow (no alerts), because its boundaries are a guess. FastAPI and Flask requests, LangGraph invoke / CrewAI kickoff, and the Vercel AI SDK wrappers already get exact runs.

Works with OpenAI, Anthropic, Mistral and Bedrock, plus LangChain / LangGraph · CrewAI · Pydantic AI · OpenAI Agents SDK · AutoGen · LlamaIndex · Haystack · smolagents · Hermes Agent · LiteLLM · Vercel AI SDK · Langdock · Dify · any OpenTelemetry source. Plain code: custom Python agent · TypeScript / JavaScript.

Nothing in the dashboard?

  • curl -s localhost:8001/ready should print "status":"ok". If the SDK runs somewhere other than this machine (another container, a server), set DUNETRACE_ENDPOINT to the ingest URL.
  • Runs appear but never any failures: wrap the entry point (above), since implicit runs stay in shadow.
  • Still stuck: /dunetrace-setup also debugs integrations that send no events.

More demos (LangChain, the Vercel AI SDK on local Ollama, approvals, policies, agent memory, voice) → examples index. Deploying beyond localhost → docs/operations.md.


What's inside

Pillar What it does
1 Sessions & Events Every run, every tool call, every LLM exchange: the raw data everything else is built on
2 Structural Detection 37 zero-LLM detectors (33 of them in-path, sub-500μs per hook), the always-on first line → Detectors
3 Semantic Evaluation LLM-based judgment (hallucination, task completion, cross-turn frustration), post-hoc, sampling-based, opt-in → Semantic evaluation
4 Runtime Prevention Policies that stop, redirect, or downgrade a run while it's happening, which no tracer offers → Policies
5 Root Cause & Fix Native root-cause analysis, auto-applied policy fixes, or a one-click draft PR → Diagnose & fix

Detectors

37 detectors run on every completed run, with no configuration and no LLM. A few of the main ones:

Signal What it catches
TOOL_LOOP Same tool called repeatedly with identical args
RETRY_STORM Tool failing, agent retrying it repeatedly
COST_SPIKE Total token consumption unusually high vs per-agent baseline
PROMPT_INJECTION_SIGNAL Input matched adversarial injection patterns
MEMORY_POISONING An injection directive was written into the agent's own memory, re-steering it when read back
DELEGATION_LOOP Agents delegate to each other in a cycle that never converges
RUNAWAY_ITERATION Step or cost ceiling crossed with no completion signal
SILENT_TRUNCATION A response was truncated and the agent used it without retrying
MODEL_FALLBACK_DRIFT The run silently switched to a weaker model (e.g. under rate limiting)

Each alert carries what fired, why it matters, a concrete fix, and rate context (first occurrence / recurring / systemic). → docs/detectors.md for all 37

  • Multi-agent: nested dt.run() calls auto-link into a delegation graph that DELEGATION_LOOP and HANDOFF_CONTEXT_LOSS read → docs/multi-agent.md
  • Agent memory: instrument memory writes/reads and MEMORY_POISONING flags adversarial content persisted into them → docs/memory.md
  • Custom detectors: describe one in plain English; it runs in shadow mode until you approve the fire rate → docs/detectors.md
  • Detector packs: opt-in bundles per org; the voice pack adds 9 detectors → detector packs · voice pack

Policies

Runtime guardrails that fire mid-run, before a failure propagates. Defined in code or in the dashboard (the SDK refetches every 60s).

dt.add_policy(                                  # stop, switch_model, escalate, inject, ...
    name="cap tool calls",
    condition={"trigger": "tool_call_count", "operator": "gt", "value": 5},
    action={"type": "stop"},
)
dt.add_policy(                                  # human-in-the-loop: blocks the call until
    name="approve-wires",                       # someone approves in Slack or the dashboard,
    condition={"trigger": "before_tool_call", "operator": "eq", "value": "wire_money"},
    action={"type": "require_approval", "params": {"timeout_s": 300}},   # fail-closed on timeout
)

→ docs/policies.md · docs/approvals.md


Diagnose & fix

Click Explain + on any alert: Dunetrace analyzes the run's own stored events (no third-party tracer) and returns a cause plus a fix. That is either a runtime policy it applies itself (tool loops, retry storms, runaway step counts) or a prompt/code diff you copy in or open as a draft PR. Fix effectiveness is tracked automatically.


Alerts

Slack and generic webhook (PagerDuty, Linear, custom). Put these in a .env file at the repo root (.env.example lists every option), then rerun docker compose -f docker-compose.ghcr.yml up -d to apply them; restart alone keeps the old values.

SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...
SLACK_MIN_SEVERITY=LOW   # LOW | MEDIUM | HIGH | CRITICAL
DIGEST_ENABLED=true      # weekly digest of top failure types, Monday 9am UTC

Slack alert

→ docs/alerts.md


Dashboard

Overview

Live at http://localhost:3000. Auto-refreshes every 15s. → docs/dashboard.md


Semantic evaluation

Opt-in LLM judgment for what structural checks can't see: seven DeepEval-backed evaluators (hallucination, task completion, task-understanding failure, off-topic drift, user frustration, confusion loops, sycophancy). Post-hoc and sampling-based, never in your agent's request path. It runs in its own container, off by default; turn it on with SEMANTIC_WORKER_ENABLED=true in .env (plus an LLM key).

→ docs/semantic-evaluation.md


MCP server

Ask about your agents from Claude Code, Cursor, or Codex ("what failed in the last 24 hours?") without leaving your editor.

pip install dunetrace-mcp

31 tools covering agents, runs, signals, fixes, issues, policies, custom detectors and voice calls. Claude Code registers the server automatically in ~/.claude.json (restart to load); Cursor and Codex need one config block. → docs/mcp-server.md


Architecture

Services share one Postgres and no message broker: the SDK ships events to the ingest API, and each worker polls for what it needs next. The core pipeline runs with no LLM key; three workers are opt-in.

→ docs/architecture.md (services, data flow, detection paths, schema) · docs/operations.md (deploying, probes and metrics, retention, redaction, rate limiting) · docs/state-machine.md (agent state machine)


Integrations

Model providers: OpenAI, Anthropic, Mistral and AWS Bedrock, auto-instrumented with no call-site changes.

Evaluation & tracing

Fix & workflow

Voice

Agent frameworks are listed under Works with in the Quick Start.


If Dunetrace helps you, a ⭐ on GitHub helps others find it.

Contributing

Fork, branch, change, make test, PR. Open an issue first for new integrations or architecture changes. Requires Python 3.11+, Node.js 22+, Docker + Docker Compose.

→ CONTRIBUTING.md (setup and workflow) · good first issues · adding a detector

Contact

Dunetrace UG (haftungsbeschränkt) · Kolonnenstr. 8, 10827 Berlin, Germany · vikas@dunetrace.com

License

Apache 2.0

Popular repositories Loading

  1. dunetrace dunetrace Public

    The runtime reliability layer for AI agents.

    Python 71 24

  2. dunetrace-skills dunetrace-skills Public