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

Uploaded Python 3

File details

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

File metadata

  • Download URL: deepanalysts-0.1.4.tar.gz
  • Upload date:
  • Size: 70.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","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.4.tar.gz
Algorithm Hash digest
SHA256 e210e5e0870bd527c02d4b475500cd4d552e5fcb77807e7096965bc6a0836e28
MD5 584783f8b7a52abd79eb03897c524419
BLAKE2b-256 b6759087ee72412ceb479a9de916b86a59814734f50e19841bebd654b1ff8cf5

See more details on using hashes here.

File details

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

File metadata

  • Download URL: deepanalysts-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 70.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","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.4-py3-none-any.whl
Algorithm Hash digest
SHA256 e8b835b218c0953e8eea1bbb3e5af70d80aed7a8a5ad8154a3e99d0598a687f3
MD5 e34efc496353fe849c53daa7f5b94105
BLAKE2b-256 e4c17b9c55159d5abd4ce70dba6ec8657da7fb44ed209438de942ddeb5a3829b

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