Skip to main content

Dottle SDK — Instrument your AI agents in 3 lines of code. See every LLM call, tool, cost, and failure in real time.

Project description

Dottle SDK

Monitor your AI agents in minutes. See every LLM call, tool use, cost, latency, and failure — in real time.

dottle.dev · Dashboard · Docs


Install

pip install dottle-sdk

Quickstart

import dottle

# 1. Configure once at startup
dottle.configure(api_key="dtl_live_...")

# 2. Wrap your agent run in a session
with dottle.session("my-agent", user_id="user_123") as sid:

    # 3. Track each LLM call as a span
    with dottle.span("llm", "gpt-4o reply") as s:
        response = openai_client.chat.completions.create(...)
        s.record_tokens(
            prompt_tokens=response.usage.prompt_tokens,
            completion_tokens=response.usage.completion_tokens,
            model="gpt-4o",
        )

That's it. Open app.dottle.dev to see your agent's sessions, costs, and errors live.


Get your API key

  1. Sign up at app.dottle.dev
  2. Create an organization → create a project
  3. Copy the dtl_live_... key from Project Settings

What gets tracked

Signal How
LLM calls dottle.span("llm", ...) + s.record_tokens(...)
Tool calls dottle.span("tool", ...)
Errors s.record_error(exc) or automatic on exception
Cost Calculated from token counts + model
Latency Automatic (start/end of each span)
User Pass user_id / user_email to dottle.session()

Full example with Anthropic

import anthropic
import dottle

dottle.configure(api_key="dtl_live_...")
client = anthropic.Anthropic()

def run_agent(user_message: str, user_email: str):
    with dottle.session("support-agent", user_email=user_email) as sid:
        with dottle.span("llm", "claude-3-5-sonnet") as s:
            response = client.messages.create(
                model="claude-3-5-sonnet-20241022",
                max_tokens=1024,
                messages=[{"role": "user", "content": user_message}],
            )
            s.record_tokens(
                prompt_tokens=response.usage.input_tokens,
                completion_tokens=response.usage.output_tokens,
                model="claude-3-5-sonnet-20241022",
            )
        return response.content[0].text

Prompt management

Version-control your prompts in the Dottle dashboard and fetch the active version at runtime — no redeploy needed when you update a prompt.

import os
import dottle

dottle.configure(
    api_key=os.environ["DOTTLE_API_KEY"],
    project_id=os.environ["DOTTLE_PROJECT_ID"],  # or pass to get_prompt()
)

# Fetch the active version (always up-to-date — changes in the UI are live instantly)
prompt = dottle.get_prompt("summarize-article")

# Compile {{variable}} placeholders into messages
messages = prompt.compile(article=article_text, language="English")
# → [{"role": "system", "content": "..."}, {"role": "user", "content": "..."}]

# Pass to any LLM client
response = openai_client.chat.completions.create(
    model=prompt.model,          # model stored on the prompt in the dashboard
    messages=messages,
    **prompt.parameters,         # temperature, max_tokens, etc.
)

# Or let Dottle call the model for you (routes to OpenAI / Anthropic / Gemini automatically)
result = prompt.invoke(article=article_text, language="English")

Version pinning

# Pin to a specific version number
prompt = dottle.get_prompt("summarize-article", version=3)

# Pin to a named label (e.g. "production", "staging")
prompt = dottle.get_prompt("summarize-article", label="production")

Tool calls

If you defined tools on the prompt in the dashboard, they're available on prompt.tools in OpenAI format:

prompt = dottle.get_prompt("agent-prompt")

response = openai_client.chat.completions.create(
    model=prompt.model,
    messages=prompt.compile(task=user_task),
    tools=prompt.tools,          # OpenAI tool-call format
)

Auto-tracking inside a session

When .invoke() is called inside a dottle.session(), it automatically creates an LLM span with the prompt name, version, token counts, and cost — no extra code needed:

with dottle.session("my-agent") as sid:
    result = prompt.invoke(article=text)
    # ↑ recorded in the dashboard as span "summarize-article v3"
    #   with input_tokens, output_tokens, cost, and prompt text

Caching

get_prompt() caches the active version in-process for 60 seconds by default, so hot paths don't hit the API on every request:

# Default: 60-second TTL
prompt = dottle.get_prompt("summarize-article")

# Custom TTL
prompt = dottle.get_prompt("summarize-article", ttl=300)  # 5 minutes

# Bypass cache (always fetch fresh)
prompt = dottle.get_prompt("summarize-article", ttl=0)

# Pinned version/label fetches are never cached
prompt = dottle.get_prompt("summarize-article", version=3)

# Clear cache (useful in tests)
dottle.clear_prompt_cache()

PromptHandle attributes

Attribute Type Description
prompt.name str Prompt slug
prompt.version int Version number
prompt.label str | None Named label (e.g. "production")
prompt.model str Model stored on the prompt
prompt.parameters dict LLM parameters (temperature, max_tokens, …)
prompt.tools list OpenAI-format tool definitions
prompt.variables list[str] Detected {{variable}} names
prompt.messages list Uncompiled messages (system + user)

LangChain integration

Zero-code-change tracking for LangChain chains, agents, and LangGraph — attach one callback handler and every LLM call and tool use is automatically recorded.

from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor
from dottle.integrations.langchain import DottleCallbackHandler
import dottle

dottle.configure(api_key="dtl_live_...")
handler = DottleCallbackHandler()

llm = ChatOpenAI(model="gpt-4o", callbacks=[handler])
agent_executor = AgentExecutor(agent=agent, tools=tools, callbacks=[handler])

with dottle.session("my-langchain-agent", user_id="user_123") as sid:
    result = agent_executor.invoke({"input": "What is the weather in Tokyo?"})

What gets tracked automatically: model name, input/output text, token counts, cost, latency, tool call inputs/outputs, errors, and loop detection.

Works with: ChatOpenAI, ChatAnthropic, ChatGoogleGenerativeAI, all LangChain tools, LCEL chains, LangGraph nodes.

Full LangChain integration guide


Zero performance impact

All calls are fire-and-forget (background thread). Your agent never waits for Dottle. If Dottle is unreachable, your agent keeps running — monitoring failures are silently swallowed.


License

MIT

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

dottle_sdk-0.1.5.tar.gz (23.2 kB view details)

Uploaded Source

Built Distribution

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

dottle_sdk-0.1.5-py3-none-any.whl (30.8 kB view details)

Uploaded Python 3

File details

Details for the file dottle_sdk-0.1.5.tar.gz.

File metadata

  • Download URL: dottle_sdk-0.1.5.tar.gz
  • Upload date:
  • Size: 23.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for dottle_sdk-0.1.5.tar.gz
Algorithm Hash digest
SHA256 1948c3cb7419a6d6fed55c959b1df7239e162e411181cb174987f2904fb67b07
MD5 c9476f29db64692317b7e06fed48474a
BLAKE2b-256 d29496b73ae99cef7182037d96abd591eecc72233619c49003ad12b4f2b115a5

See more details on using hashes here.

File details

Details for the file dottle_sdk-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: dottle_sdk-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 30.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for dottle_sdk-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 de79cf3e97bd990837b9f5fd7510b857b468d8ad136f9ec09bfabe1ec2c38cd4
MD5 05bd7fa7077a5ef47c9ff780b5436ebd
BLAKE2b-256 8c93e788aa92c1f0a2b2af712798e2a02541535f08831604879fc89d7e35d61f

See more details on using hashes here.

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