Metadata-Version: 2.4
Name: neatlogs
Version: 1.3.5
Summary: A Python package for extracting and managing LLM logs to build a collaborative workspace
Author-email: Neatlogs <hello@neatlogs.com>
License: MIT
Project-URL: Homepage, https://github.com/NeatLogs/neatlogs
Project-URL: Repository, https://github.com/NeatLogs/neatlogs.git
Project-URL: Issues, https://github.com/NeatLogs/neatlogs/issues
Project-URL: Documentation, https://docs.neatlogs.com/
Keywords: llm,tracking,monitoring,logging,ai,machine-learning,observability,collaboration
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: System :: Logging
Classifier: Topic :: System :: Monitoring
Requires-Python: <3.14,>=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: openinference-instrumentation>=0.1.27
Requires-Dist: openinference-semantic-conventions>=0.1.13
Requires-Dist: opentelemetry-api>=1.33.1
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.33.1
Requires-Dist: opentelemetry-sdk>=1.33.1
Requires-Dist: requests>=2.31.0
Requires-Dist: agnost<0.2.0,>=0.1.8
Requires-Dist: opentelemetry-instrumentation>=0.50b0
Requires-Dist: opentelemetry-instrumentation-requests>=0.50b0
Requires-Dist: opentelemetry-instrumentation-httpx>=0.50b0
Requires-Dist: opentelemetry-instrumentation-urllib3>=0.50b0
Requires-Dist: opentelemetry-instrumentation-aiohttp-client>=0.50b0
Requires-Dist: opentelemetry-instrumentation-threading>=0.50b0
Requires-Dist: opentelemetry-instrumentation-logging>=0.50b0
Requires-Dist: wrapt>=1.0.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: aiohttp>=3.9.0
Requires-Dist: openinference-instrumentation-openai>=0.1.32
Requires-Dist: openinference-instrumentation-anthropic>=0.1.20
Requires-Dist: openinference-instrumentation-langchain>=0.1.56
Requires-Dist: openinference-instrumentation-groq>=0.1.12
Requires-Dist: openinference-instrumentation-litellm>=0.1.28
Requires-Dist: openinference-instrumentation-google-genai>=0.1.8
Requires-Dist: openinference-instrumentation-bedrock>=0.1.32
Requires-Dist: openinference-instrumentation-vertexai>=0.1.11
Requires-Dist: openinference-instrumentation-mistralai>=1.3.4
Requires-Dist: openinference-instrumentation-crewai>=0.1.17
Requires-Dist: openinference-instrumentation-dspy>=0.1.32
Requires-Dist: openinference-instrumentation-agno>=0.1.25
Requires-Dist: openinference-instrumentation-openai-agents>=1.4.0
Requires-Dist: openinference-instrumentation-pydantic-ai>=0.1.9
Requires-Dist: openinference-instrumentation-smolagents>=0.1.21
Requires-Dist: openinference-instrumentation-guardrails>=0.1.10
Requires-Dist: openinference-instrumentation-haystack>=0.1.29
Requires-Dist: openinference-instrumentation-instructor>=0.1.12
Requires-Dist: openinference-instrumentation-mcp>=1.3.3
Requires-Dist: openinference-instrumentation-portkey>=0.1.7
Requires-Dist: openinference-instrumentation-google-adk>=0.1.8
Requires-Dist: openinference-instrumentation-autogen-agentchat>=0.1.6
Requires-Dist: openinference-instrumentation-llama-index>=4.3.9
Provides-Extra: azure-ai-inference
Requires-Dist: neatlogs-instrumentations[azure-ai-inference]>=0.1.1; extra == "azure-ai-inference"
Provides-Extra: openai
Requires-Dist: openai>=1.0.0; extra == "openai"
Provides-Extra: azure-openai
Requires-Dist: openai>=1.0.0; extra == "azure-openai"
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.75.0; extra == "anthropic"
Provides-Extra: langchain
Requires-Dist: chromadb>=1.1.1; extra == "langchain"
Requires-Dist: langchain>=1.1.2; extra == "langchain"
Requires-Dist: langchain-classic>=1.0.0; extra == "langchain"
Requires-Dist: langchain-community>=0.4.1; extra == "langchain"
Requires-Dist: langchain-core>=0.3.0; extra == "langchain"
Requires-Dist: langchain-openai>=1.1.3; extra == "langchain"
Requires-Dist: qdrant-client<1.16; extra == "langchain"
Provides-Extra: langgraph
Requires-Dist: langgraph>=1.0.4; extra == "langgraph"
Requires-Dist: langchain-core>=0.3.0; extra == "langgraph"
Requires-Dist: langchain-openai>=1.1.3; extra == "langgraph"
Provides-Extra: crewai
Requires-Dist: crewai[azure-ai-inference]>=1.9.3; extra == "crewai"
Requires-Dist: litellm>=1.80.11; extra == "crewai"
Provides-Extra: llama-index
Requires-Dist: llama-index>=0.14.10; extra == "llama-index"
Provides-Extra: google-adk
Requires-Dist: google-adk>=1.14.1; extra == "google-adk"
Provides-Extra: groq
Requires-Dist: groq>=0.37.1; extra == "groq"
Provides-Extra: agno
Requires-Dist: agno>=2.3.13; extra == "agno"
Provides-Extra: bedrock
Requires-Dist: boto3>=1.42.11; extra == "bedrock"
Provides-Extra: dspy
Requires-Dist: dspy>=2.6.13; extra == "dspy"
Provides-Extra: litellm
Requires-Dist: litellm>=1.80.11; extra == "litellm"
Provides-Extra: google-genai
Requires-Dist: google-genai>=1.55.0; extra == "google-genai"
Provides-Extra: openai-agents
Requires-Dist: openai>=1.0.0; extra == "openai-agents"
Requires-Dist: openai-agents>=0.6.5; extra == "openai-agents"
Provides-Extra: guardrails
Requires-Dist: guardrails-ai>=0.4.0; extra == "guardrails"
Provides-Extra: haystack
Requires-Dist: haystack-ai>=2.0.0; extra == "haystack"
Provides-Extra: instructor
Requires-Dist: instructor>=1.0.0; extra == "instructor"
Provides-Extra: mcp
Requires-Dist: mcp>=1.0.0; extra == "mcp"
Provides-Extra: mistralai
Requires-Dist: mistralai>=1.0.0; extra == "mistralai"
Provides-Extra: portkey
Requires-Dist: portkey-ai>=1.0.0; extra == "portkey"
Provides-Extra: pydantic-ai
Requires-Dist: pydantic-ai>=0.0.9; extra == "pydantic-ai"
Provides-Extra: smolagents
Requires-Dist: smolagents>=1.0.0; extra == "smolagents"
Provides-Extra: hermes
Requires-Dist: hermes-agent>=0.15.1; extra == "hermes"
Provides-Extra: vertexai
Requires-Dist: google-cloud-aiplatform>=1.38.0; extra == "vertexai"
Provides-Extra: vertex-ai
Requires-Dist: google-genai>=1.55.0; extra == "vertex-ai"
Provides-Extra: autogen-agentchat
Requires-Dist: autogen-agentchat>=0.4.0; extra == "autogen-agentchat"
Provides-Extra: milvus
Requires-Dist: pymilvus<2.5.0,>=2.4.0; extra == "milvus"
Requires-Dist: milvus-lite<2.5.0,>=2.4.0; extra == "milvus"
Dynamic: license-file

<div align="center">

<h1>neatlogs</h1>

<p>LLM observability for AI agents.<br/>Instrument once. Inspect everything.</p>

<p>
  <a href="https://badge.fury.io/py/neatlogs"><img src="https://badge.fury.io/py/neatlogs.svg" alt="PyPI version" /></a>
  <img src="https://img.shields.io/badge/python-3.10+-blue.svg" alt="Python 3.10+" />
  <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="MIT License" />
</p>

<p>
  <a href="https://neatlogs.com">Website</a> &nbsp;·&nbsp;
  <a href="https://docs.neatlogs.com">Docs</a> &nbsp;·&nbsp;
  <a href="https://app.neatlogs.com">Get API key</a> &nbsp;·&nbsp;
  <a href="https://github.com/neatlogs/skills">AI Skill</a>
</p>

<br/>

<p><i>Agent failures don't throw exceptions — they produce wrong outputs, miss tool calls, or hallucinate.<br/>Neatlogs captures every trace so you can see exactly what the model was given, what it decided, and what each step returned.</i></p>

</div>

---

![neatlogs](assets/hero.png)

## Installation

```bash
pip install neatlogs
```

Optional extras install the underlying LLM / framework libraries:

```bash
pip install "neatlogs[openai]"
pip install "neatlogs[crewai]"
pip install "neatlogs[langchain,langgraph]"
pip install "neatlogs[google-genai]"
```

Requires **Python >= 3.10, < 3.14**.

---

## Quickstart

```python
import neatlogs
from neatlogs import span

neatlogs.init(
    api_key="your-api-key",       # or NEATLOGS_API_KEY env var
    endpoint="https://staging-cloud.neatlogs.com",  # or NEATLOGS_ENDPOINT env var
    workflow_name="my-agent",
    instrumentations=["openai"],
)

# Import instrumented libraries AFTER init()
from openai import OpenAI


@span(kind="WORKFLOW", name="quickstart")
def main():
    client = OpenAI()
    return client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": "What is AI?"}],
    )


main()
neatlogs.flush()
neatlogs.shutdown()
```

Auto-instrumentation captures LLM calls, tools, and retrievals as child spans. Use `@span(kind="WORKFLOW")` on your main function or request handler so each run shows up as a top-level trace in the dashboard.

Call `neatlogs.init()` **before** importing any instrumented library.

For long-running servers (FastAPI, Celery workers), call `init()` once at startup and decorate each request handler with `@span(kind="WORKFLOW")`. Do **not** call `flush()` / `shutdown()` per request.

Full walkthrough: [Your First Trace](https://docs.neatlogs.com/quickstart/your-first-trace).

---

## Integrate into your codebase (recommended)

The fastest way to add NeatLogs to an existing project is the official **Agent Skill** — it encodes import order, `@span` kinds, CrewAI prompt binding, and troubleshooting so your coding agent gets it right.

**Repo:** [github.com/neatlogs/skills](https://github.com/neatlogs/skills)

```bash
npx skills add neatlogs/skills --skill "neatlogs-py"
```

For **Cursor**:

```bash
npx skills add neatlogs/skills --skill "neatlogs-py" --agent "cursor"
```

No Node.js? Ask in chat: *"Install the NeatLogs AI skill from github.com/neatlogs/skills"*

Example prompts once installed:

- *"Add neatlogs tracing to my OpenAI calls"*
- *"Instrument my CrewAI agents with neatlogs"*
- *"Wrap my FastAPI handler so each request is a top-level trace"*

Full install options: [skills README](https://github.com/neatlogs/skills/blob/main/README.md)

API reference: [docs.neatlogs.com](https://docs.neatlogs.com)

---

## Platform features

- **[Traces](https://docs.neatlogs.com/features/traces)**: Full span trees — LLM calls, tools, retrievals, reranking, guardrails — with inputs, outputs, tokens, cost, and latency.

- **[Timeline view](https://docs.neatlogs.com/features/traces#timeline)**: See which steps ran in parallel, where latency concentrated, and where the process was idle.

- **[AI assistant](https://docs.neatlogs.com/features/traces#ai-assistant)**: Ask questions grounded in the actual span data for a trace.

- **[AI Search](https://docs.neatlogs.com/features/ai-search)**: Query traces in plain English without writing SQL.

- **[Detections](https://docs.neatlogs.com/features/detections)**: Rules that flag matching spans — regex, numeric conditions, PII, or model classifiers.

- **[Prompt management](https://docs.neatlogs.com/features/experiments)**: Version prompts, promote labels, test in the Playground.

- **[Evals](https://app.neatlogs.com/evals)**: Human review campaigns — select traces or spans (or auto-collect future ones via filters), send custom rating forms to assigned reviewers, and track batch progress and scores.

- **[Comments & voting](https://docs.neatlogs.com/features/comments)**: Pin notes to spans, @mention teammates, and thumbs-up/down vote outputs while debugging a trace.

---

## Supported libraries

Pass keys to `instrumentations` in `neatlogs.init()`. Install extras when noted.

### LLM providers

| Provider | Key | Install |
|---|---|---|
| OpenAI | `openai` | `pip install "neatlogs[openai]"` |
| Anthropic | `anthropic` | `pip install "neatlogs[anthropic]"` |
| Google Gemini | `google_genai` | `pip install "neatlogs[google-genai]"` |
| Azure OpenAI | `azure_ai_inference` | `pip install "neatlogs[azure-ai-inference]"` |
| AWS Bedrock | `bedrock` | `pip install "neatlogs[bedrock]"` |
| LiteLLM | `litellm` | `pip install "neatlogs[litellm]"` |
| Groq | `groq` | `pip install "neatlogs[groq]"` |
| Vertex AI | `vertexai` | `pip install "neatlogs[vertexai]"` |
| Mistral | `mistralai` | `pip install "neatlogs[mistralai]"` |

### Agent frameworks

| Framework | Key | Install |
|---|---|---|
| LangChain | `langchain` | `pip install "neatlogs[langchain]"` |
| LangGraph | `langgraph` | `pip install "neatlogs[langgraph]"` |
| CrewAI | `crewai` | `pip install "neatlogs[crewai]"` |
| LlamaIndex | `llamaindex` | `pip install "neatlogs[llama-index]"` |
| Haystack | `haystack` | `pip install "neatlogs[haystack]"` |
| AutoGen | `autogen` | `pip install "neatlogs[autogen-agentchat]"` |
| DSPy | `dspy` | `pip install "neatlogs[dspy]"` |
| MCP | `mcp` | `pip install "neatlogs[mcp]"` |

### Vector stores & HTTP

| Library | Key | Notes |
|---|---|---|
| ChromaDB | `chromadb` | Auto-instrumented when installed |
| Pinecone | `pinecone` | Auto-instrumented when installed |
| Qdrant | `qdrant` | Auto-instrumented when installed |
| Weaviate | `weaviate` | Auto-instrumented when installed |
| Milvus | `milvus` | `pip install "neatlogs[milvus]"` |
| Redis | `redis` | Auto-instrumented when installed |
| OpenSearch | `opensearch` | Auto-instrumented when installed |
| Elasticsearch | `elasticsearch` | Auto-instrumented when installed |
| Marqo | `marqo` | Auto-instrumented when installed |
| HTTP clients | `requests`, `httpx`, `urllib3`, `aiohttp` | Auto-instrumented when installed |

---

## Configuration

```bash
NEATLOGS_API_KEY=your-api-key
NEATLOGS_ENDPOINT=https://staging-cloud.neatlogs.com   # optional — this is the default
```

Get your API key from the [NeatLogs dashboard](https://app.neatlogs.com). Full `init()` options: [reference](https://docs.neatlogs.com/reference/init-reference).

---

## Examples

Runnable reference apps live in [`examples/sdk_examples/`](examples/sdk_examples/). Each folder has a `requirements.txt` (PyPI install) and `.env.example`.

| Example | Framework | Run |
|---------|-----------|-----|
| `anthropic_multiagent/` | Anthropic + Bedrock | `python main.py` |
| `openai_multiagent/` | OpenAI via Azure | `python main.py` |
| `google_genai_multiagent/` | Google GenAI | `python main.py` |
| `langchain_react/` | LangChain ReAct | `python react_agent.py` |
| `langgraph_multiagent/` | LangGraph | `python main.py` |
| `langgraph_research_assistant/` | LangGraph | `python main.py` |
| `marketing_strategy_demo/` | CrewAI + Gemini search | `python main.py` |
| `neatlogs_support_bot/` | CrewAI RAG bot | `python main.py` |
| `reasoning_model_workflow/` | Multi-provider reasoning | `python main.py` |
| `support_copilot_demo/` | Support agent demo traces | `RUN=A python support_copilot.py` |
| `support_copilot_demo_triaged/` | Post-Triage support demo | `SENDGRID_FAKE_SUCCESS=1 RUN=B python support_copilot.py` |

**Adding NeatLogs to your own code?** Use the [AI skill](#integrate-into-your-codebase-recommended) above — not copy-paste from this README.

---

## Best practices

1. **`init()` before LLM imports** — auto-instrumentation patches libraries at import time.
2. **Wrap script/server entry points in `@span(kind="WORKFLOW")`** — each run gets a clear top-level trace in the dashboard.
3. **Use auto-instrumentation first** — only add more `@span` decorators for custom orchestration.
4. **`trace()` for prompts and sessions** — not as a wrapper around `@span(kind="WORKFLOW")`.
5. **`workflow_name` = feature name** — put env/version/tech stack in `tags=`.
6. **Scripts:** `flush()` then `shutdown()` at exit. **Servers:** `init()` once, no per-request shutdown.

---

## License

MIT — see [LICENSE](LICENSE).
