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 deepalpha 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.deepalpha.mn",
    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.7.1.tar.gz (146.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.7.1-py3-none-any.whl (114.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: deepanalysts-0.7.1.tar.gz
  • Upload date:
  • Size: 146.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.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.7.1.tar.gz
Algorithm Hash digest
SHA256 6bcf2fb5e6ba6bd507bdbc754c45e5977e002e4aaee31226b3d062065715c621
MD5 1fb4b0e170732914156c9d7ff97aac51
BLAKE2b-256 7d19260a061ac52248a5ee7d1f4daa9bad93958f50b838751a0e9a72ff2b165e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: deepanalysts-0.7.1-py3-none-any.whl
  • Upload date:
  • Size: 114.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.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.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 391d2d1c1ea11043472362c3510972ec12ce745b7e70dc58f86690a075953ecc
MD5 2f133b7e5cd07f2265ca5c8fe77ff67a
BLAKE2b-256 a0ec7b0c38820774c6b39092f24c89659424b7139abf7ba9bda325d01cea4782

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