Observed since 21 Oct, 09:19 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
agobs
AgentObserve: local-first diagnostics & observability for AI agents. Answers 'Why did my agent behave this way?' with one line and a single SQLite file.
Local-first diagnostics & observability for AI agents. One line to integrate, a single SQLite file, a built-in dashboard. AgentLens answers the question other tools don't:
Why did my agent behave this way?
Not a prompt tracker. Not a token dashboard. A diagnostics platform for agent behavior — tool usage, memory access, workflow paths, decisions, failures, retries, latency, and cost.
pip install agobs # core: store + dashboard + manual API + auto-patch
pip install "agobs[langchain]" # framework adapters as extras (langgraph, crewai, …)
pip install "agobs[all]" # every adapter
Package name on PyPI is
agobs; the import name isagentlens.
from agentlens import monitor
monitor.start() # auto-patches installed LLM SDKs — that's it
Full docs: see
Guide.md— in-depth reference for humans and AI coding agents (when-to-use-what tables, every API signature, per-framework snippets, troubleshooting, and an agent cheat sheet).
agentlens ui # dashboard at http://127.0.0.1:7180
No server to deploy. No cloud. No external services. Data lives in a hidden
./.agentlens/agentlens.db (SQLite, WAL).
monitor.start() detects and patches whatever is installed — OpenAI,
Anthropic, Google Gemini, Groq, LiteLLM — so every LLM call becomes an llm
span with tokens and cost, with no code changes.
import agentlens
agentlens.init(project="research-bot")
with agentlens.trace_session("chat"):
with agentlens.trace_agent("planner", role="lead"):
agentlens.log_decision(options=["search", "answer"], chosen="search", reason="needs fresh info")
agentlens.log_memory("read", "user_prefs", hit=True)
agentlens.log_tool("web_search", args={"q": "ai news"}, result=[...], retry_count=1)
agentlens.log_llm(model="gpt-4o", input_tokens=1200, output_tokens=400)
A tool/LLM logged with an error= (or a trace_* block that raises) is
automatically recorded as a failure.
| Framework | Import | Maturity |
|---|---|---|
| LangChain | agentlens.adapters.langchain.AgentLensCallbackHandler | full |
| LangGraph | agentlens.adapters.langgraph.AgentLensCallbackHandler | full (LangChain callbacks) |
| LlamaIndex | agentlens.adapters.llamaindex.AgentLensLlamaHandler | full |
| CrewAI | agentlens.adapters.crewai (step_callback, instrument_tools) | best-effort |
| AutoGen | agentlens.adapters.autogen.instrument_agent | best-effort |
| PydanticAI | agentlens.adapters.pydanticai.instrument_agent | best-effort |
| OpenAI Agents SDK | agentlens.adapters.openai_agents.install | best-effort |
| Strands Agents | agentlens.adapters.strands.callback_handler | best-effort |
| Anthropic Agent SDK | agentlens.adapters.anthropic_agents.traced_async_tool | tool-level |
| MCP | agentlens.adapters.mcp.instrument_server / traced_tool | tool-level |
| FastMCP | agentlens.adapters.fastmcp.instrument_server | tool-level |
Plus a universal agentlens.adapters.wrap_tool(fn) / @traced_tool() that works
with any framework or none.
pip install -e .
python examples/demo_agent.py
agentlens ui
Local-first, zero-config, framework-agnostic, async-safe. Observability code
never crashes your app (emit failures are swallowed). One Span model covers
every event; kind-specific data lives in attributes. Cost is computed from an
editable price book (agentlens/server/pricing.py).
CLI: agentlens ui [--port 7180] [--host] [--backend-store-uri PATH],
agentlens providers, agentlens version. Override the port with
AGENTLENS_PORT.
Single process writes straight to local SQLite. For multiple
processes/workers sharing one dashboard, run agentlens ui once and point each
worker at it: agentlens.init(project=..., tracking_uri="http://127.0.0.1:7180").
See Guide.md for the complete reference.
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
fastapiEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | fastapi>=0.100 | runtime |
uvicornEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | uvicorn>=0.23 | runtime |
jinja2Environment{
"extras": "",
"marker": null,
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | jinja2>=3.1 | runtime |
pydanticEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | pydantic>=2.0 | runtime |
httpxEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | httpx>=0.24 | runtime |
langchain-coreEnvironment{
"extras": "",
"marker": "extra == \"langchain\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | langchain-core>=0.1; extra == "langchain" | runtime |
langgraphEnvironment{
"extras": "",
"marker": "extra == \"langgraph\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | langgraph>=0.1; extra == "langgraph" | runtime |
llama-index-coreEnvironment{
"extras": "",
"marker": "extra == \"llamaindex\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | llama-index-core>=0.10; extra == "llamaindex" | runtime |
crewaiEnvironment{
"extras": "",
"marker": "extra == \"crewai\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | crewai>=0.1; extra == "crewai" | runtime |
pyautogenEnvironment{
"extras": "",
"marker": "extra == \"autogen\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | pyautogen>=0.2; extra == "autogen" | runtime |
pydantic-aiEnvironment{
"extras": "",
"marker": "extra == \"pydanticai\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | pydantic-ai>=0.0.1; extra == "pydanticai" | runtime |
openai-agentsEnvironment{
"extras": "",
"marker": "extra == \"openai-agents\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | openai-agents>=0.0.1; extra == "openai-agents" | runtime |
mcpEnvironment{
"extras": "",
"marker": "extra == \"mcp\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | mcp>=1.0; extra == "mcp" | runtime |
fastmcpEnvironment{
"extras": "",
"marker": "extra == \"fastmcp\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | fastmcp>=0.1; extra == "fastmcp" | runtime |
langchain-coreEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | langchain-core>=0.1; extra == "all" | runtime |
langgraphEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | langgraph>=0.1; extra == "all" | runtime |
llama-index-coreEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | llama-index-core>=0.10; extra == "all" | runtime |
crewaiEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | crewai>=0.1; extra == "all" | runtime |
pyautogenEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | pyautogen>=0.2; extra == "all" | runtime |
mcpEnvironment{
"extras": "",
"marker": "extra == \"all\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | mcp>=1.0; extra == "all" | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | pytest>=7.0; extra == "dev" | runtime |
bdist_wheel · 63.24 KB · Python py3
sdist · 54.74 KB · Python source
Observed since 21 Oct, 09:19 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:1c1f877ce40ce53b63342a2ddfcd6b8e10e37940539f13df7d4dedd367e3dc19