Metadata-Version: 2.5
Name: neurosurfer
Version: 2.0.0
Summary: Build intelligent apps that blend LLM reasoning, tools, and retrieval, with a ready-to-run OpenAI-compatible gateway.
Project-URL: Homepage, https://github.com/NaumanHSA/neurosurfer
Project-URL: Repository, https://github.com/NaumanHSA/neurosurfer
Project-URL: Issues, https://github.com/NaumanHSA/neurosurfer/issues
Project-URL: Changelog, https://github.com/NaumanHSA/neurosurfer/blob/main/CHANGELOG.md
Author-email: Neurosurfer Team <naumanhsa965@gmail.com>
Maintainer-email: Neurosurfer Team <naumanhsa965@gmail.com>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agent,agent-framework,agentic,ai-agent,anthropic,claude,cli,fastapi,llm,lm-studio,local-llm,mcp,neurosurfer,observability,ollama,openai,openai-compatible,rag,tool-use,vllm,workflow
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: anthropic>=0.40.0
Requires-Dist: anyio>=4.0
Requires-Dist: httpx>=0.27
Requires-Dist: openai>=1.40.0
Requires-Dist: prompt-toolkit>=3.0
Requires-Dist: pydantic>=2.6
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.0
Provides-Extra: bedrock
Requires-Dist: anthropic[bedrock]>=0.40.0; extra == 'bedrock'
Provides-Extra: browser
Requires-Dist: playwright>=1.40; extra == 'browser'
Provides-Extra: dev
Requires-Dist: build; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Requires-Dist: twine; extra == 'dev'
Requires-Dist: types-pyyaml; extra == 'dev'
Provides-Extra: local
Requires-Dist: tiktoken>=0.7; extra == 'local'
Provides-Extra: mcp
Requires-Dist: mcp>=1.2; extra == 'mcp'
Provides-Extra: observability
Requires-Dist: langfuse<3,>=2.0; extra == 'observability'
Requires-Dist: opentelemetry-exporter-otlp>=1.20; extra == 'observability'
Requires-Dist: opentelemetry-sdk>=1.20; extra == 'observability'
Provides-Extra: qdrant
Requires-Dist: qdrant-client>=1.7; extra == 'qdrant'
Provides-Extra: rag
Requires-Dist: beautifulsoup4>=4.12; extra == 'rag'
Requires-Dist: chromadb>=1.0; extra == 'rag'
Requires-Dist: lxml>=5.0; extra == 'rag'
Requires-Dist: pydantic-settings>=2.0; extra == 'rag'
Requires-Dist: pymupdf>=1.24; extra == 'rag'
Requires-Dist: python-docx>=1.1; extra == 'rag'
Requires-Dist: python-pptx>=0.6; extra == 'rag'
Requires-Dist: sentence-transformers>=5.1; extra == 'rag'
Requires-Dist: sqlalchemy>=2.0; extra == 'rag'
Provides-Extra: search
Requires-Dist: beautifulsoup4>=4.12; extra == 'search'
Requires-Dist: ddgs>=6.0; extra == 'search'
Requires-Dist: lxml>=5.0; extra == 'search'
Requires-Dist: rank-bm25>=0.2; extra == 'search'
Provides-Extra: serve
Requires-Dist: fastapi<1.0,>=0.110; extra == 'serve'
Requires-Dist: pydantic-settings>=2.0; extra == 'serve'
Requires-Dist: uvicorn[standard]>=0.29; extra == 'serve'
Description-Content-Type: text/markdown

<div align="center">

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/NaumanHSA/neurosurfer/main/docs/assets/banner/neurosurfer-banner-light.png">
  <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/NaumanHSA/neurosurfer/main/docs/assets/banner/neurosurfer-banner-dark.png">
  <img alt="Neurosurfer — AI Agent Framework" src="https://raw.githubusercontent.com/NaumanHSA/neurosurfer/main/docs/assets/banner/neurosurfer-banner-dark.png" width="62%">
</picture>


### The open-source framework for building AI agents — and the Architect that builds them for you.

<!-- <br/>

<a href="https://naumanhsa.github.io/neurosurfer/getting-started/quickstart/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/NaumanHSA/neurosurfer/main/docs/assets/buttons/pngs/quick-start-light.png"><img height="42" alt="Quick Start" src="https://raw.githubusercontent.com/NaumanHSA/neurosurfer/main/docs/assets/buttons/pngs/quick-start-dark.png"></picture></a>
<a href="https://naumanhsa.github.io/neurosurfer/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/NaumanHSA/neurosurfer/main/docs/assets/buttons/pngs/documentation-light.png"><img height="42" alt="Documentation" src="https://raw.githubusercontent.com/NaumanHSA/neurosurfer/main/docs/assets/buttons/pngs/documentation-dark.png"></picture></a>
<a href="https://naumanhsa.github.io/neurosurfer/tutorials/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/NaumanHSA/neurosurfer/main/docs/assets/buttons/pngs/examples-light.png"><img height="42" alt="Examples" src="https://raw.githubusercontent.com/NaumanHSA/neurosurfer/main/docs/assets/buttons/pngs/examples-dark.png"></picture></a>
<a href="https://pypi.org/project/neurosurfer/"><picture><source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/NaumanHSA/neurosurfer/main/docs/assets/buttons/pngs/pypi-light.png"><img height="42" alt="PyPI" src="https://raw.githubusercontent.com/NaumanHSA/neurosurfer/main/docs/assets/buttons/pngs/pypi-dark.png"></picture></a>

<br/> -->

<a href="https://pypi.org/project/neurosurfer/"><img alt="PyPI" src="https://img.shields.io/pypi/v/neurosurfer?style=flat-square&logo=pypi&logoColor=white&label=PyPI&labelColor=1F2328&color=3775A9"></a>
<a href="https://pypi.org/project/neurosurfer/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/neurosurfer?style=flat-square&logo=python&logoColor=white&label=Python&labelColor=1F2328&color=FFD43B"></a>
<a href="LICENSE"><img alt="License" src="https://img.shields.io/badge/License-Apache--2.0-D22128?style=flat-square&labelColor=1F2328"></a>
<a href="https://naumanhsa.github.io/neurosurfer/"><img alt="Docs" src="https://img.shields.io/badge/Docs-online-526CFE?style=flat-square&logo=readthedocs&logoColor=white&labelColor=1F2328"></a>
<a href="https://naumanhsa.github.io/neurosurfer/tutorials/"><img alt="Tutorials" src="https://img.shields.io/badge/Tutorials-7_notebooks-F9AB00?style=flat-square&logo=googlecolab&logoColor=white&labelColor=1F2328"></a>
<br/>
<a href="https://naumanhsa.github.io/neurosurfer/guides/providers/"><img alt="Providers" src="https://img.shields.io/badge/LLMs-Anthropic_·_OpenAI_·_Gemini_·_Bedrock-6E56CF?style=flat-square&labelColor=1F2328"></a>
<a href="https://naumanhsa.github.io/neurosurfer/guides/rag/"><img alt="Vector stores" src="https://img.shields.io/badge/Vectors-Chroma_·_Qdrant_·_memory-E5484D?style=flat-square&labelColor=1F2328"></a>
<a href="https://naumanhsa.github.io/neurosurfer/guides/mcp/"><img alt="MCP" src="https://img.shields.io/badge/MCP-client_+_registry-1F883D?style=flat-square&labelColor=1F2328"></a>
<a href="https://naumanhsa.github.io/neurosurfer/observability/"><img alt="Observability" src="https://img.shields.io/badge/Traces-Langfuse_·_OpenTelemetry-F5A623?style=flat-square&labelColor=1F2328"></a>
<a href="https://naumanhsa.github.io/neurosurfer/architect/"><img alt="Architect" src="https://img.shields.io/badge/Architect-plan_·_ground_·_verify-0EA5E9?style=flat-square&labelColor=1F2328"></a>
<br/>
<a href="https://pypi.org/project/neurosurfer/"><img alt="Downloads" src="https://img.shields.io/pypi/dm/neurosurfer?style=flat-square&logo=python&logoColor=white&label=Downloads&labelColor=1F2328&color=4C1"></a>
<a href="https://github.com/NaumanHSA/neurosurfer/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/NaumanHSA/neurosurfer?style=flat-square&logo=github&logoColor=white&label=Stars&labelColor=1F2328&color=FFB000"></a>
<a href="https://github.com/NaumanHSA/neurosurfer/discussions"><img alt="Discussions" src="https://img.shields.io/badge/Discussions-join-8250DF?style=flat-square&logo=github&logoColor=white&labelColor=1F2328"></a>
<a href="https://github.com/NaumanHSA/neurosurfer/blob/main/CHANGELOG.md"><img alt="Changelog" src="https://img.shields.io/badge/Changelog-read-57606A?style=flat-square&labelColor=1F2328"></a>


**[Quick start](https://naumanhsa.github.io/neurosurfer/getting-started/quickstart/)** ·
**[The Architect](https://naumanhsa.github.io/neurosurfer/architect/)** ·
**[Graph & workflows](https://naumanhsa.github.io/neurosurfer/graph/)** ·
**[RAG](https://naumanhsa.github.io/neurosurfer/guides/rag/)** ·
**[Tools & MCP](https://naumanhsa.github.io/neurosurfer/guides/tools/)** ·
**[Gateway](https://naumanhsa.github.io/neurosurfer/server/)** ·
**[Observability](https://naumanhsa.github.io/neurosurfer/observability/)** ·
**[Tutorials](https://naumanhsa.github.io/neurosurfer/tutorials/)**

</div>

---

**Neurosurfer is a Python framework for building AI agents** — models that don't only answer
questions, but *do* things: call tools, read and write files, search the web, look something up in
your own documents, and work through a task in several steps instead of one. You can wire those
steps together yourself as a graph, or describe what you want in plain English and let the
**Architect** build it for you — it works out which tools the job needs, runs what it made to check
it actually works, and tells you plainly when something can't be built rather than handing back a
workflow that quietly invents its results. The same code runs against Anthropic, OpenAI, Gemini,
Bedrock or a model on your own machine, and anything you build can be served behind an
OpenAI-compatible API.

<div align="center">
  <img alt="Neurosurfer architecture" src="https://raw.githubusercontent.com/NaumanHSA/neurosurfer/main/docs/assets/diagrams/neurosurfer-architecture.png" width="100%">
  <br/>
  <sub>The Architect turns a plain-English request into a workflow, one step at a time.</sub>
</div>

---

## 📰 What's new

- **The Architect** *(latest)*: describe a workflow in plain English and it builds one — planning
  the steps, finding the tool each one needs, writing the graph, **running it to check it works**,
  and registering it. If it can't be built, it says so and names what is missing instead of
  guessing. See **[the Architect](https://naumanhsa.github.io/neurosurfer/architect/)**, or watch a build end to end in
  **[tutorial 06](https://naumanhsa.github.io/neurosurfer/tutorials/the-architect/)**.

- **Retrieval you can measure**: **hybrid** dense + BM25 fused by reciprocal rank, cross-encoder
  **reranking**, MMR diversity and **citations** with character spans. **Qdrant** joins Chroma and
  in-memory behind one vector-store contract with a **conformance suite** — "implements
  `BaseVectorDB`" now means "passes the suite". Embeddings became a plugin point:
  sentence-transformers, OpenAI, or any `/v1/embeddings` server. Plus contextual retrieval,
  parent-document, multi-query/HyDE, sentence-window and semantic chunking, and an ingest manifest
  so one edited file costs one file's embeddings. See **[RAG](https://naumanhsa.github.io/neurosurfer/guides/rag/)**.

- **Google Gemini and Claude on Amazon Bedrock**: Gemini natively over `httpx` with no new
  dependency; Bedrock as a thin subclass of the Anthropic provider. Four provider families, one
  `Provider` protocol.

- **Observability: pluggable trace exporters**: ship **every agent run** to a real backend with no
  code changes — **[Langfuse](https://naumanhsa.github.io/neurosurfer/observability/langfuse/)** and
  **[OpenTelemetry](https://naumanhsa.github.io/neurosurfer/observability/opentelemetry/)** (GenAI-semconv over OTLP → Phoenix /
  Grafana / Datadog). Runs → traces, LLM turns → generations, tool calls → spans; sub-agents and
  workflow nodes nest automatically.

Full history in the [Changelog](CHANGELOG.md). Coming from 1.0.0, a few APIs moved — the
[upgrade notes](https://naumanhsa.github.io/neurosurfer/about/upgrading/) cover them.

---

## 📦 What's in the box

- 🤖 **Agent family:** `AgenticLoop` (native multi-step tool-use), `ReactAgent` (text-parsing ReAct for models without a native tool API), and `Agent` (one-shot, optionally with structured output).
- 🧠 **LLM providers:** Anthropic Claude (direct or on Amazon Bedrock), OpenAI, Google Gemini, and any OpenAI-compatible server (Ollama, LM Studio, vLLM, llama.cpp) behind one `Provider` protocol — with canonical types, so swapping provider changes one line.
- 🔧 **Rich tool ecosystem:** 19 built-in tools: web search (DuckDuckGo/SerpAPI), sandboxed Python execution, file ops, HTTP, headless browser, SQL, and sub-agents, plus a simple framework for your own.
- 📚 **RAG pipeline:** ingest → chunk → embed → retrieve → token-aware context injection, with hybrid (dense + BM25) retrieval, reranking, and citations. Chroma, Qdrant or in-memory behind one vector-store contract; embeddings from sentence-transformers, OpenAI, or any `/v1/embeddings` server.
- 📊 **Token accounting:** input, output and cache tokens on every agent run and every graph node, carried into traces for Langfuse/OTel to attribute.
- 🕸️ **Graph & Workflows:** a standalone DAG engine — 11 node kinds including `router`, `loop`, `map` and `subgraph` — with a rules-based validator and persisted, runnable Workflow packages.
- 🏗️ **Architect:** describe a workflow in plain English; it plans, sources the tools, builds the graph, **runs it**, judges the result, and registers it — or refuses and says what is missing.
- 🔌 **MCP client:** connect external Model Context Protocol servers and expose their tools to agents.
- ⚙️ **OpenAI-compatible gateway:** `/v1/models` + `/v1/chat/completions` with SSE streaming; proxy upstream backends or route to your own agents; request/response hooks.
- 🔭 **Observability:** pluggable trace exporters (Langfuse, OpenTelemetry) with zero-overhead-when-off tracing.
- 🧪 **Interactive CLI:** a `neurosurfer` REPL for chat and `neurosurfer serve` for the gateway.

---


## 🎓 Tutorials

Hands-on notebooks: open any of them directly in Google Colab.

| # | Tutorial | What you'll build |
|---|----------|-------------------|
| 0 | **[Installation](https://colab.research.google.com/github/NaumanHSA/neurosurfer/blob/main/tutorials/00_installation.ipynb)** | Install Neurosurfer and its optional extras; verify your setup. |
| 1 | **[Providers & Agents](https://colab.research.google.com/github/NaumanHSA/neurosurfer/blob/main/tutorials/01_providers_and_agents.ipynb)** | Connect cloud and local providers, then run `AgenticLoop`, `ReactAgent`, and one-shot `Agent`. |
| 2 | **[Custom Tools](https://colab.research.google.com/github/NaumanHSA/neurosurfer/blob/main/tutorials/02_custom_tools.ipynb)** | Write your own tools and give agents new capabilities. |
| 3 | **[Graph Agents](https://colab.research.google.com/github/NaumanHSA/neurosurfer/blob/main/tutorials/03_graph_agents.ipynb)** | Compose multi-step workflows with the graph engine and Workflow packages. |
| 4 | **[MCP Servers](https://colab.research.google.com/github/NaumanHSA/neurosurfer/blob/main/tutorials/04_mcp_servers.ipynb)** | Connect external Model Context Protocol servers and expose their tools to agents. |
| 5 | **[Capstone: Insight Engine](https://colab.research.google.com/github/NaumanHSA/neurosurfer/blob/main/tutorials/05_capstone_insight_engine.ipynb)** | Put it all together: a database-backed insight engine over MCP. |
| 6 | **[The Architect](https://colab.research.google.com/github/NaumanHSA/neurosurfer/blob/main/tutorials/06_the_architect.ipynb)** | Hand an agent an intent and watch it design, build, test and register the workflow itself. |

---

## ⚡ Quick start

**Install:**
```bash
pip install -U neurosurfer
# with web search + gateway:
pip install -U "neurosurfer[search,serve]"
```

**Run the interactive CLI:**
```bash
neurosurfer
```

**Run the OpenAI-compatible gateway:**
```bash
neurosurfer serve --host 0.0.0.0 --port 8000
# proxy an upstream backend:
neurosurfer serve --upstream-url http://localhost:1234
```

**Multi-step agent (Anthropic):**
```python
import asyncio, os
from pathlib import Path
from neurosurfer.llm.providers.anthropic import AnthropicProvider
from neurosurfer.agents import AgenticLoop, Guardrails
from neurosurfer.tools import default_pool

provider = AnthropicProvider(api_key=os.environ["ANTHROPIC_API_KEY"], model="claude-opus-4-8")

class AutoIO:  # auto-approving IOHandler for scripts (see the Agents guide)
    async def ask(self, question, options=None): return (options or ["yes"])[0]
    async def request_plan_approval(self, plan): return True, ""
    async def request_shell_approval(self, command, reason): return True
    async def request_write_approval(self, path, summary): return "once"
    def notify(self, message): pass

async def main():
    agent = AgenticLoop(
        provider=provider, tools=default_pool(),
        system_prompt="Use tools to answer, then finish.",
        guardrails=Guardrails(), io=AutoIO(), cwd=Path.cwd(),
    )
    async for event in agent.run("Search the web for the latest news on AI agents."):
        if hasattr(event, "text"):
            print(event.text, end="", flush=True)

asyncio.run(main())
```

**One-shot with structured output:**
```python
import asyncio
from pathlib import Path
from pydantic import BaseModel
from neurosurfer.agents import Agent, Guardrails
from neurosurfer.tools import default_pool

class Summary(BaseModel):
    title: str
    points: list[str]

agent = Agent(
    provider=provider, tools=default_pool(),
    system_prompt="Answer concisely.",
    guardrails=Guardrails(), io=AutoIO(), cwd=Path.cwd(),
    output_schema=Summary,
)
result = asyncio.run(agent.complete("Summarise the Neurosurfer framework in 3 bullet points."))
print(result.title, result.points)  # `result` is a validated Summary instance
```

**Register an agent as an OpenAI-compatible model:**
```python
from neurosurfer.app.server import NeurosurferServer
from neurosurfer.agents import AgenticLoop

server = NeurosurferServer()
server.register_agent(AgenticLoop(provider=provider), model_id="my-agent")
server.run()  # → http://localhost:8000/v1/chat/completions
```

---

## 🏗️ Two ways to build a workflow

Most frameworks give you the first. Neurosurfer gives you both, over the same engine.

**Write it** — a typed DAG with 11 node kinds, control flow, and a validator that refuses a graph
that cannot run *before* it spends a model call:

```python
from neurosurfer.graph import Graph, BaseNode

graph = Graph(
    name="summarise_and_title",
    inputs=[{"name": "article", "type": "string"}],
    nodes=[
        BaseNode(id="summary", goal="Summarise {article} in three sentences."),
        BaseNode(id="title", goal="Write a catchy title for the summary.",
                 depends_on=["summary"]),
    ],
    outputs=["title"],
)
```

**Or describe it** — and the **Architect** does the rest:

```python
from neurosurfer.architect import ArchitectAgent

path = await ArchitectAgent(provider).build(
    "Read a text file of customer feedback, pull out the recurring complaints, "
    "and write a short summary for the support lead."
)
```

An LLM step cannot read a file however well you word it. The Architect checks that before it
designs a node, **runs what it built** to see whether it works, and refuses rather than shipping a
workflow that invents its results. More in **[the Architect docs](https://naumanhsa.github.io/neurosurfer/architect/)**.

---


## 🔭 Observability

See and debug **what your agents actually do** in a real dashboard: the LLM turns, tool calls, token usage, and cost. Tracing is a cross-cutting, side-channel layer: it *observes* the event stream every agent already emits, never consumes it, so nothing about how you call `agent.run(...)` changes.

- **Zero code changes:** auto-on from the environment. Set a backend's connection vars and it activates on the next run.
- **Two backends in the box:** **Langfuse** (batteries-included LLM observability) and **OpenTelemetry** (vendor-neutral GenAI-semconv spans over OTLP → Honeycomb, Phoenix, Grafana Tempo, Datadog…). Or write your own `TraceExporter`.
- **Automatic nesting:** a run is a **trace**; each LLM turn a **generation** (with token cost); each tool call a **span**; spawned sub-agents and workflow nodes nest under the parent (`workflow → node → agent → tool`).
- **Safe by design:** zero overhead when off, and a misbehaving or unreachable exporter never breaks a run.

```bash
pip install "neurosurfer[observability]"

# Langfuse: auto-detected from the environment
export LANGFUSE_PUBLIC_KEY=pk-...  LANGFUSE_SECRET_KEY=sk-...
# …or any OTel backend:
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
```

That's it. Run any agent and the traces show up. Full guide: **[Observability docs](https://naumanhsa.github.io/neurosurfer/observability/)**.

---

## 🧩 Install options

| Extra | What you get |
|---|---|
| *(base)* | Agents, LLM providers, tools, RAG, server, CLI |
| `search` | Web search tool (DuckDuckGo, BM25 ranking, HTML extraction) |
| `browser` | Headless browser tool via Playwright |
| `local` | `tiktoken` for accurate token counting with local models |
| `rag` | ChromaDB, sentence-transformers, PDF/DOCX/PPTX readers |
| `qdrant` | Qdrant vector store client |
| `bedrock` | Claude on Amazon Bedrock (boto3) |
| `serve` | FastAPI + uvicorn for the OpenAI-compatible gateway |
| `mcp` | Model Context Protocol client SDK |
| `observability` | Langfuse + OpenTelemetry trace exporters |
| `dev` | pytest, ruff, mypy, build tools |

```bash
pip install "neurosurfer[search,serve,rag,observability]"
```

---

## 📄 License

Licensed under the **Apache-2.0 License**. See [`LICENSE`](LICENSE).

## 💬 Support

- Star the project on [GitHub](https://github.com/NaumanHSA/neurosurfer)
- Ask & share in [Discussions](https://github.com/NaumanHSA/neurosurfer/discussions)
- File [Issues](https://github.com/NaumanHSA/neurosurfer/issues)
- Security: report privately to **naumanhsa965@gmail.com**

## 📚 Citation

```bibtex
@software{neurosurfer,
  author  = {Neurosurfer Team},
  title   = {Neurosurfer: A Production-Ready AI Agent Framework},
  year    = {2026},
  url     = {https://github.com/NaumanHSA/neurosurfer},
  license = {Apache-2.0}
}
```

---

<div align="center">
  <sub>Built by the Neurosurfer team · Apache-2.0</sub>
</div>
