Skip to main content

LangChain/LangGraph middleware for building AI agents with memory, skills, and filesystem support

Project description

Deep Analysts

LangChain/LangGraph middleware for building AI agents with memory, skills, filesystem support, and subagent orchestration.

Installation

pip install deepanalysts

Or with uv:

uv add deepanalysts

Overview

Deep Analysts provides a complete middleware stack for LangChain agents:

  • Middleware: Memory, Skills, Filesystem, Subagents, Summarization, Tool Error Handling
  • Backends: Store (LangGraph BaseStore), Sandbox (subprocess execution), Composite (path-based routing)
  • API Integration: Basement client for syncing skills/memories to cloud

Uses only langchain, langgraph, and standard libraries (no external embient dependencies).

Usage

SubAgent Middleware (Orchestration)

from deepanalysts.middleware import SubAgentMiddleware, SubAgent

# Define subagents
technical_analyst = SubAgent(
    name="technical_analyst",
    description="Analyzes charts and technical indicators",
    system_prompt="You are a technical analyst...",
    tools=[get_indicator, get_candles],
)

# Create middleware with subagent delegation
middleware = SubAgentMiddleware(
    default_model=model,
    default_tools=[],
    subagents=[technical_analyst, signal_manager],
)

Memory Middleware

from deepanalysts.middleware import MemoryMiddleware
from deepanalysts.backends import StoreBackend

# With backend (file-based)
middleware = MemoryMiddleware(
    backend=lambda rt: StoreBackend(rt),
    sources=[
        "~/.config/myapp/AGENTS.md",
        "./.myapp/AGENTS.md",
    ],
)

# With API loader
from deepanalysts.backends import BasementMemoryLoader

loader = BasementMemoryLoader(token_provider=get_jwt_token)
middleware = MemoryMiddleware(loader=loader)

Skills Middleware

from deepanalysts.middleware import SkillsMiddleware
from deepanalysts.backends import BasementSkillsLoader

# API mode with agent filtering
loader = BasementSkillsLoader(
    token_provider=get_jwt_token,
    store=app.state.store,  # For read_file access
)
middleware = SkillsMiddleware(
    loader=loader,
    agent_name="technical_analyst",  # Filter skills by target_agents
)

# Backend mode
middleware = SkillsMiddleware(
    backend=my_backend,
    sources=["/skills/user/", "/skills/project/"],
)

Filesystem Middleware

from deepanalysts.middleware import FilesystemMiddleware
from deepanalysts.backends import CompositeBackend, StoreBackend, RestrictedSubprocessBackend

# Create backends
store_backend = lambda rt: StoreBackend(rt)
sandbox = RestrictedSubprocessBackend(timeout=30)

# Composite routing
backend = CompositeBackend(
    default=sandbox,
    routes={
        "/skills/": store_backend,
        "/memories/": store_backend,
    }
)

middleware = FilesystemMiddleware(backend=backend)

Summarization Middleware

from deepanalysts.middleware import SummarizationMiddleware

middleware = SummarizationMiddleware(
    model=model,
    backend=backend_factory,
    trigger=("tokens", 100000),  # Trigger at 100k tokens
    keep=("messages", 20),       # Keep last 20 messages
    history_path_prefix="/conversation_history",
)

Tool Error Handling

from deepanalysts.middleware import ToolErrorHandlingMiddleware

# Place first in middleware stack to catch all tool errors
middleware_stack = [
    ToolErrorHandlingMiddleware(),  # First!
    MemoryMiddleware(...),
    SkillsMiddleware(...),
    FilesystemMiddleware(...),
    SubAgentMiddleware(...),
]

Patch Tool Calls (Dangling Tool Calls)

from deepanalysts.middleware import PatchToolCallsMiddleware

# Handles cases where AIMessage has tool calls but no ToolMessage response
middleware_stack = [
    PatchToolCallsMiddleware(),
    # ... other middleware
]

Basement Client

from deepanalysts.clients import BasementClient

client = BasementClient(
    base_url="https://basement.embient.ai",
    token="jwt-token",
)

# Fetch data
memories = await client.get_active_memories()
skills = await client.get_active_skills()

# Sync data back
await client.sync_memory("my-memory", "content")
await client.sync_skill("my-skill", "description", "SKILL.md content")

Package Structure

deepanalysts/
├── __init__.py           # Main exports
├── middleware/
│   ├── memory.py         # MemoryMiddleware (loader + backend modes)
│   ├── skills.py         # SkillsMiddleware (loader + backend modes)
│   ├── tool_errors.py    # ToolErrorHandlingMiddleware
│   ├── patch_tool_calls.py # PatchToolCallsMiddleware
│   ├── subagents.py      # SubAgentMiddleware with task tool
│   ├── filesystem.py     # FilesystemMiddleware with file tools
│   ├── summarization.py  # SummarizationMiddleware with backend offloading
│   └── _utils.py         # Internal utilities
├── backends/
│   ├── protocol.py       # BackendProtocol, SandboxBackendProtocol
│   ├── store.py          # StoreBackend (LangGraph BaseStore)
│   ├── sandbox.py        # BaseSandbox, RestrictedSubprocessBackend
│   ├── composite.py      # CompositeBackend (path-based routing)
│   ├── basement.py       # BasementMemoryLoader, BasementSkillsLoader
│   └── utils.py          # Shared utilities (formatting, grep, glob)
├── clients/
│   └── basement.py       # BasementClient (API client)
└── utils/
    └── retry.py          # Retry utilities for transient errors

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

deepanalysts-0.1.10.tar.gz (73.2 kB view details)

Uploaded Source

Built Distribution

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

deepanalysts-0.1.10-py3-none-any.whl (72.4 kB view details)

Uploaded Python 3

File details

Details for the file deepanalysts-0.1.10.tar.gz.

File metadata

  • Download URL: deepanalysts-0.1.10.tar.gz
  • Upload date:
  • Size: 73.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for deepanalysts-0.1.10.tar.gz
Algorithm Hash digest
SHA256 e41ba6a63cb06520f5f9d44f661de39673936def603b580e7aff0c16a53cc533
MD5 847cebc7e41e4b5b9ad0f9e34a4642fa
BLAKE2b-256 9edf9e8fda375fb694612444a945e1b394bd7b2724225457e11519b244ac67ca

See more details on using hashes here.

File details

Details for the file deepanalysts-0.1.10-py3-none-any.whl.

File metadata

  • Download URL: deepanalysts-0.1.10-py3-none-any.whl
  • Upload date:
  • Size: 72.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for deepanalysts-0.1.10-py3-none-any.whl
Algorithm Hash digest
SHA256 936012e1194b3da5de2854d0bd107d815baa64636c3310adefdd1709c5e48832
MD5 c054a53be18fe84bb29656ac4b257955
BLAKE2b-256 9094a500009fbdcce96dd173dcfc48dfd7c547445d8f7ea977bc364e06e58324

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