Catalog PyPI
Back to packageRELEASE DETAILS

0.9.0

PyPI

agentdynamics

Application performance monitoring for AI agents: flows, cost, reliability and process quality

ai-agentsapmlanggraphllmobservabilityopentelemetrytracing
Published8 Oct 2026
Direct dependencies6
Transitive dependenciesNot calculated

README

Version 0.9.0 documentation

AgentDynamics

CI PyPI Python License: Apache-2.0

APM for AI agents. AgentDynamics does for agents what AppDynamics does for services. It shows how your agents work through tasks, what each step costs, where flows loop, stall or fail, and whether the agent's process is any good.

  • Works with what you already have: LangGraph, LangChain, the OpenAI Agents SDK, the Anthropic and OpenAI SDKs, CrewAI, LlamaIndex, anything that speaks OpenTelemetry, LangSmith, Langfuse, log pipelines and Claude Code.
  • Zero dependencies: one pip install, one process, runs on a laptop or in Kubernetes.
  • Self-hosted: your prompts and traces never leave your network.

Quickstart (2 minutes)

pip install agentdynamics
agentdynamics serve --open          # console at http://127.0.0.1:8787

Then connect your agent with one of these options. Pick the first one that matches how your agent is built.

1. Python: one line

import agentdynamics
agentdynamics.init()      # auto-instruments Anthropic, OpenAI, LangChain/LangGraph and OpenTelemetry

Every model call is now tracked, with tokens, cost, latency, truncations and errors. To group calls into tasks and see your agent's flow, add a decorator and name the stages:

@agentdynamics.trace                     # one call = one task in the console
def handle_ticket(question):
    with agentdynamics.span("plan"):     # stages become nodes in the workflow graph
        plan = client.messages.create(...)
    with agentdynamics.span("act"):
        lookup_order(order_id)           # decorate tools with @agentdynamics.tool
    if escalated:
        agentdynamics.outcome("failed", reason="customer escalated")   # state it, don't let it be guessed
    ...

Without outcome(), success is inferred from errors, interrupts and follow-ups. The console always shows which outcomes were stated and which were guessed; grades can also be posted afterwards by a person or an eval pipeline (POST /api/outcomes), or by your own systems using your own ids: trace with agentdynamics.trace("support", ticket_id="T-123") and post {"key": {"ticket_id": "T-123"}, "outcome": "rework"} when the ticket is reopened.

2. Python, zero code changes

agentdynamics run python app.py         # like ddtrace-run / opentelemetry-instrument

3. LangGraph / LangChain (Python or JS): environment variables only

export LANGSMITH_TRACING=true
export LANGSMITH_ENDPOINT=http://127.0.0.1:8787/langsmith

AgentDynamics speaks the LangSmith ingestion API, so graphs, nodes, threads and feedback arrive unchanged.

4. Any OpenTelemetry app (OpenAI Agents SDK, CrewAI, LlamaIndex, Vercel AI SDK, Java/Go/.NET)

export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://127.0.0.1:8787/v1/traces

GenAI semantic conventions, OpenInference and OpenLLMetry are all understood, over protobuf or JSON.

5. Already using LangSmith or Langfuse? Don't change anything

agentdynamics connect langsmith         # prints the 4-line config to pull runs from your existing project

6. Anything else

agentdynamics connect http prints a single curl call. agentdynamics connect logs shows how to point Fluent Bit or Vector at AgentDynamics.

Check it works

agentdynamics doctor                    # checks URL + key, sends a test trace, confirms it shows up

The console's Get started page shows the same snippets and turns green when your first trace arrives.


What it looks like

The Flow Map: where work goes, what each hop costs, and what is failing. Red edges are errors.

Flow Map

The Overview: cost, Apdex and flow health against baselines learned from your own history.

Overview

Governance: what Aegis refused, which rule refused it, and which grants are never used.

Governance

Reproduce these locally from synthetic traffic, no API keys needed:

agentdynamics --data .demo-data --claude-root "" serve --port 8790 &
LANGSMITH_ENDPOINT=http://127.0.0.1:8790/langsmith python examples/langgraph_style_app.py 70
python examples/otel_multiagent.py 45 http://127.0.0.1:8790
AGENTDYNAMICS_URL=http://127.0.0.1:8790 python examples/governed_agent.py 40

What you get

Flow MapLive topology: users → agents (including agent-to-agent handoffs) → models and tools, with volume, latency and errors
WorkflowsThe real execution graph mined from your traces: path variants and their success rates, loops, the critical node, handoffs
Task snapshotsSpan-tree waterfall for each request: context growth, cost against the baseline, what went wrong, what the user said next
Baselines & Apdex"Normal" cost and latency per workflow, learned automatically, plus an agent Apdex score
Health rules & alerts29 rules (runaway cost, policy denials, boundary probing, tripwires, revocations, retry loops, node loops, truncation, rate limits, ping-pong handoffs, unverified code changes, …) sent to Slack, PagerDuty or webhooks, routed by project, rule and severity
Tools & ModelsError rate and p95 per tool; per model TTFT, tokens/s, truncation rate, cache hit rate and spend, and the estimate beside what Anthropic billed (with an Admin API key)
SLOsSuccess rate, Apdex, good-task rate, latency and cost objectives with error budgets and burn rates
GovernanceAegis policy enforcement per task: denials by rule, budget stops, kill-switch revocations, unused grants, policy export, and what a policy change would refuse
Incidents & trustTripwires, probing, refused calls and revocations about one agent, grouped into one incident with its evidence; revoke the agent or resolve it as real or a false alarm, and alert once per incident. Each agent's trust score (0-100) weighs that evidence by age and by the verdicts given, and is exported to Prometheus. An optional checker has a model review each incident in shadow mode, and keeps score of how often it agreed with you
Process ReviewScores how well the agent works (efficiency, focus, reliability, verification, context, autonomy, compliance) and suggests fixes
Analytics & CompareAny metric by any dimension; compare models, prompts or releases side by side

The full metric catalog is in docs/METRICS.md.

Governance with Aegis

Aegis decides what an agent may do. AgentDynamics shows what it did. Connecting them takes one call:

from agentdynamics.integrations import aegis as governance
governance.instrument(kernel, root, watchdog=governance.Watchdog(max_repeated_denials=3))

That call sets up four flows:

  1. Every Aegis decision appears in its task. Denials carry the rule id, and the Aegis audit log carries the task's run id so the two logs join.
  2. Model calls are charged to the Aegis budget before they're sent. When the budget runs out, the call is refused and never made.
  3. A watchdog revokes the grant of an agent that keeps probing a boundary, for example after a prompt injection, and tripwires (decoy tools and planted canary values) stop a run before the call that touches one is made. For tools that can't be undone, an opt-in reviewer model checks each call against what the user asked before Aegis admits it, and refuses what goes beyond it (review={"tools": ["payments.refund"]}).
  4. agentdynamics policy export writes a tighter, least-privilege policy from observed behaviour. aegis ratify and aegis drift verify its declaration; agentdynamics policy check replays the traffic that actually ran through it and reports how much it would refuse, so a policy change can be gated in CI.

The console's Governance page shows denials, budget stops, revocations, unused grants and budget headroom per policy version. See docs/GOVERNANCE.md.

Python API

agentdynamics.init(url=None, api_key=None, project=None, environment=None, capture_content=None)Connect and auto-instrument. Every argument falls back to an environment variable (below). Safe to call twice.
@agentdynamics.trace / @trace("name") / with trace("name", prompt=..., thread_id=..., user_id=...)One task. A nested trace becomes a node. Works on sync and async functions.
with agentdynamics.span("node")A stage or graph node. Model and tool calls inside it are attributed to the node.
@agentdynamics.tool / @tool(name="search")Records a function as a tool call: arguments, output size and errors.
t.feedback("user_rating", 0.0..1.0)Attach a user or eval score to a task (with trace(...) as t).
with agentdynamics.llm_call(model, max_tokens=..., input=...) as c: ... c.usage(input_tokens=..., output_tokens=...)Records a call from any other model client (local models, raw HTTP), with the same gating as the patched SDKs.
agentdynamics.flush()Wait for queued telemetry. This also runs automatically at exit.

Environment variables:

VariableDefaultPurpose
AGENTDYNAMICS_URLhttp://127.0.0.1:8787Where to send telemetry
AGENTDYNAMICS_API_KEYnoneIngest key, if auth is on
AGENTDYNAMICS_PROJECTcurrent folder nameProject the telemetry is filed under
AGENTDYNAMICS_ENVIRONMENTdevelopmentEnvironment label
AGENTDYNAMICS_CAPTURE_CONTENT10 sends sizes only, never prompt text
AGENTDYNAMICS_DISABLEDunset1 turns everything off

Telemetry is sent from a background thread with a bounded queue. Your agent never waits on it and never fails because of it.

Running it for a team

agentdynamics keys create --role ingest     # for apps / collectors
agentdynamics keys create --role read       # for people and Grafana
agentdynamics keys create --role admin      # for rules, SLOs and config
agentdynamics keys create --role read --project checkout    # one team: sees and sends only its projects
docker compose -f deploy/docker-compose.yml up -d   # AgentDynamics + OpenTelemetry Collector gateway

The store is a SQLite file by default. For several instances behind a load balancer, or a database you back up and operate like any other, use Postgres: pip install "agentdynamics[postgres]" and set AGENTDYNAMICS_DB_URL=postgresql://... (or deploy/docker-compose.postgres.yml). One instance is elected to write the analysis; the others serve the console and take ingest, and one takes over if the writer goes away. An existing install moves with its history: agentdynamics store copy --to postgresql://..., then agentdynamics store verify.

  • Security: role-based API keys, optionally scoped to projects. A scoped key reads only its projects' tasks, runs, steps and events, on every endpoint, and can't write into or over another project's traces.
  • Privacy: redaction of emails, API keys and card numbers, or store_content = false to keep metadata only.
  • Operations: retention, Prometheus /metrics, /healthz, a status page for every source, and alerts to Slack, PagerDuty or any webhook: health-rule events and SLO burn-rate pages, delivered in order with retries (agentdynamics alerts test checks a destination end to end).

See deploy/ and docs/ARCHITECTURE.md.

Development

pip install -e ".[test,toml]" && pip install "aegis-kernel>=0.4.0"
python -m unittest discover tests   # real LangSmith/Anthropic/OpenAI SDKs, Aegis kernel, OTLP protobuf, pull connectors

Demo traffic is under What it looks like above. CLAUDE.md has the architecture and the invariants to work within; ROADMAP.md is what is planned and what is deliberately not.

License

Apache 2.0. See LICENSE.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 6

Native requirements
6 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
tomli
Environment
{
  "extras": "",
  "marker": "python_version < \"3.11\" and extra == \"toml\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
tomli; python_version < "3.11" and extra == "toml"runtime
psycopg
Environment
{
  "extras": "binary",
  "marker": "extra == \"postgres\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
psycopg[binary]>=3.1; extra == "postgres"runtime
langchain-core
Environment
{
  "extras": "",
  "marker": "extra == \"test\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
langchain-core==0.2.33; extra == "test"runtime
langsmith
Environment
{
  "extras": "",
  "marker": "extra == \"test\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
langsmith==0.1.99; extra == "test"runtime
anthropic
Environment
{
  "extras": "",
  "marker": "extra == \"test\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
anthropic==0.87.0; extra == "test"runtime
openai
Environment
{
  "extras": "",
  "marker": "extra == \"test\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
openai==2.30.0; extra == "test"runtime

Distribution files

2 collected
agentdynamics-0.9.0-py3-none-any.whl

bdist_wheel · 266.87 KB · Python py3

Source file
agentdynamics-0.9.0.tar.gz

sdist · 353 KB · Python source

Source file

Repository

PENDING
aditya31398/agentdynamics

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 21:50 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:be56790614d7347bb552d2d70da92beff089e55c69bdd949366d0f763809a09b

Other collected versions

View all collected versions →