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.7.tar.gz (70.8 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.7-py3-none-any.whl (71.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: deepanalysts-0.1.7.tar.gz
  • Upload date:
  • Size: 70.8 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.7.tar.gz
Algorithm Hash digest
SHA256 0d5970a543e8631c49a8e83516e12e5653cdef87f689c433ed6bfe3d95878761
MD5 a24d317b48f20a45431c9afd764aec7f
BLAKE2b-256 a781263ca6f78b524f3e321600ff1403bb60e35971539c9d747cf3f0fbb67527

See more details on using hashes here.

File details

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

File metadata

  • Download URL: deepanalysts-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 71.1 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.7-py3-none-any.whl
Algorithm Hash digest
SHA256 08108691f8e041be827b2509cdfcf38efbb2c02a53bfdd8fb88231d1a0a4c678
MD5 e8072f84394b281edd69c5aadf1467a5
BLAKE2b-256 b02c67afc5894703c2e0dab5f3e2de0a7eef86d62bacd2a3749886ebdb05ef74

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