deepanalysts 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- deepanalysts-0.1.0/PKG-INFO +258 -0
- deepanalysts-0.1.0/README.md +224 -0
- deepanalysts-0.1.0/deepanalysts/__init__.py +65 -0
- deepanalysts-0.1.0/deepanalysts/backends/__init__.py +48 -0
- deepanalysts-0.1.0/deepanalysts/backends/basement.py +450 -0
- deepanalysts-0.1.0/deepanalysts/backends/composite.py +295 -0
- deepanalysts-0.1.0/deepanalysts/backends/filesystem.py +300 -0
- deepanalysts-0.1.0/deepanalysts/backends/protocol.py +458 -0
- deepanalysts-0.1.0/deepanalysts/backends/sandbox.py +516 -0
- deepanalysts-0.1.0/deepanalysts/backends/store.py +588 -0
- deepanalysts-0.1.0/deepanalysts/backends/utils.py +455 -0
- deepanalysts-0.1.0/deepanalysts/clients/__init__.py +5 -0
- deepanalysts-0.1.0/deepanalysts/clients/basement.py +200 -0
- deepanalysts-0.1.0/deepanalysts/middleware/__init__.py +37 -0
- deepanalysts-0.1.0/deepanalysts/middleware/_utils.py +28 -0
- deepanalysts-0.1.0/deepanalysts/middleware/filesystem.py +967 -0
- deepanalysts-0.1.0/deepanalysts/middleware/memory.py +423 -0
- deepanalysts-0.1.0/deepanalysts/middleware/patch_tool_calls.py +67 -0
- deepanalysts-0.1.0/deepanalysts/middleware/skills.py +696 -0
- deepanalysts-0.1.0/deepanalysts/middleware/subagents.py +453 -0
- deepanalysts-0.1.0/deepanalysts/middleware/summarization.py +769 -0
- deepanalysts-0.1.0/deepanalysts/middleware/tool_errors.py +101 -0
- deepanalysts-0.1.0/deepanalysts/utils/__init__.py +9 -0
- deepanalysts-0.1.0/deepanalysts/utils/retry.py +123 -0
- deepanalysts-0.1.0/deepanalysts.egg-info/PKG-INFO +258 -0
- deepanalysts-0.1.0/deepanalysts.egg-info/SOURCES.txt +33 -0
- deepanalysts-0.1.0/deepanalysts.egg-info/dependency_links.txt +1 -0
- deepanalysts-0.1.0/deepanalysts.egg-info/requires.txt +15 -0
- deepanalysts-0.1.0/deepanalysts.egg-info/top_level.txt +1 -0
- deepanalysts-0.1.0/pyproject.toml +53 -0
- deepanalysts-0.1.0/setup.cfg +4 -0
- deepanalysts-0.1.0/tests/test_basement.py +292 -0
- deepanalysts-0.1.0/tests/test_composite_backend.py +366 -0
- deepanalysts-0.1.0/tests/test_sandbox_backend.py +232 -0
- deepanalysts-0.1.0/tests/test_summarization_middleware.py +322 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: deepanalysts
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: LangChain/LangGraph middleware for building AI agents with memory, skills, and filesystem support
|
|
5
|
+
Author-email: Ganchuluun Narantsatsralt <tsatsralt@swifttech.cloud>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/SKE-Labs/embient-cli
|
|
8
|
+
Project-URL: Documentation, https://github.com/SKE-Labs/embient-cli/tree/main/libs/deepanalysts
|
|
9
|
+
Project-URL: Repository, https://github.com/SKE-Labs/embient-cli.git
|
|
10
|
+
Project-URL: Issues, https://github.com/SKE-Labs/embient-cli/issues
|
|
11
|
+
Keywords: langchain,langgraph,agents,middleware,ai,trading
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Requires-Python: <4.0,>=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: langchain<2.0.0,>=1.2.3
|
|
22
|
+
Requires-Dist: langgraph>=0.2.0
|
|
23
|
+
Requires-Dist: httpx>=0.28.0
|
|
24
|
+
Requires-Dist: pyyaml>=6.0
|
|
25
|
+
Requires-Dist: tenacity>=8.2.0
|
|
26
|
+
Requires-Dist: wcmatch>=8.5.0
|
|
27
|
+
Provides-Extra: postgres
|
|
28
|
+
Requires-Dist: langgraph-checkpoint-postgres>=2.0.0; extra == "postgres"
|
|
29
|
+
Requires-Dist: psycopg[binary,pool]>=3.2.0; extra == "postgres"
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-anyio>=0.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: anyio>=4.0.0; extra == "dev"
|
|
34
|
+
|
|
35
|
+
# Deep Analysts
|
|
36
|
+
|
|
37
|
+
LangChain/LangGraph middleware for building AI agents with memory, skills, filesystem support, and subagent orchestration.
|
|
38
|
+
|
|
39
|
+
## Overview
|
|
40
|
+
|
|
41
|
+
Deep Analysts provides a complete middleware stack for LangChain agents:
|
|
42
|
+
|
|
43
|
+
- **Middleware**: Memory, Skills, Filesystem, Subagents, Summarization, Tool Error Handling
|
|
44
|
+
- **Backends**: Store (LangGraph BaseStore), Sandbox (subprocess execution), Composite (path-based routing)
|
|
45
|
+
- **API Integration**: Basement client for syncing skills/memories to cloud
|
|
46
|
+
|
|
47
|
+
**No dependencies on deepagents** - uses only langchain, langgraph, and standard libraries.
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
### For embient-cli (local development)
|
|
52
|
+
|
|
53
|
+
The package is already configured as a local dependency in `pyproject.toml`:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
cd embient-cli
|
|
57
|
+
uv sync
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### For park (proprietary cloud service)
|
|
61
|
+
|
|
62
|
+
Add to `pyproject.toml`:
|
|
63
|
+
|
|
64
|
+
```toml
|
|
65
|
+
[project]
|
|
66
|
+
dependencies = [
|
|
67
|
+
"deepanalysts>=0.1.0",
|
|
68
|
+
# ... other deps
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
[tool.uv.sources]
|
|
72
|
+
# Option 1: Git subdirectory (recommended for development)
|
|
73
|
+
deepanalysts = { git = "https://github.com/SKE-Labs/embient-cli.git", subdirectory = "libs/deepanalysts" }
|
|
74
|
+
|
|
75
|
+
# Option 2: After publishing to PyPI
|
|
76
|
+
# deepanalysts = ">=0.1.0"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Usage
|
|
80
|
+
|
|
81
|
+
### SubAgent Middleware (Orchestration)
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from deepanalysts.middleware import SubAgentMiddleware, SubAgent
|
|
85
|
+
|
|
86
|
+
# Define subagents
|
|
87
|
+
technical_analyst = SubAgent(
|
|
88
|
+
name="technical_analyst",
|
|
89
|
+
description="Analyzes charts and technical indicators",
|
|
90
|
+
system_prompt="You are a technical analyst...",
|
|
91
|
+
tools=[get_indicator, get_candles],
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Create middleware with subagent delegation
|
|
95
|
+
middleware = SubAgentMiddleware(
|
|
96
|
+
default_model=model,
|
|
97
|
+
default_tools=[],
|
|
98
|
+
subagents=[technical_analyst, signal_manager],
|
|
99
|
+
)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Memory Middleware
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from deepanalysts.middleware import MemoryMiddleware
|
|
106
|
+
from deepanalysts.backends import StoreBackend
|
|
107
|
+
|
|
108
|
+
# With backend (file-based)
|
|
109
|
+
middleware = MemoryMiddleware(
|
|
110
|
+
backend=lambda rt: StoreBackend(rt),
|
|
111
|
+
sources=[
|
|
112
|
+
"~/.embient/AGENTS.md",
|
|
113
|
+
"./.embient/AGENTS.md",
|
|
114
|
+
],
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# With API loader
|
|
118
|
+
from deepanalysts.backends import BasementMemoryLoader
|
|
119
|
+
|
|
120
|
+
loader = BasementMemoryLoader(token_provider=get_jwt_token)
|
|
121
|
+
middleware = MemoryMiddleware(loader=loader)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Skills Middleware
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from deepanalysts.middleware import SkillsMiddleware
|
|
128
|
+
from deepanalysts.backends import BasementSkillsLoader
|
|
129
|
+
|
|
130
|
+
# API mode with agent filtering
|
|
131
|
+
loader = BasementSkillsLoader(
|
|
132
|
+
token_provider=get_jwt_token,
|
|
133
|
+
store=app.state.store, # For read_file access
|
|
134
|
+
)
|
|
135
|
+
middleware = SkillsMiddleware(
|
|
136
|
+
loader=loader,
|
|
137
|
+
agent_name="technical_analyst", # Filter skills by target_agents
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
# Backend mode
|
|
141
|
+
middleware = SkillsMiddleware(
|
|
142
|
+
backend=my_backend,
|
|
143
|
+
sources=["/skills/user/", "/skills/project/"],
|
|
144
|
+
)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Filesystem Middleware
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from deepanalysts.middleware import FilesystemMiddleware
|
|
151
|
+
from deepanalysts.backends import CompositeBackend, StoreBackend, RestrictedSubprocessBackend
|
|
152
|
+
|
|
153
|
+
# Create backends
|
|
154
|
+
store_backend = lambda rt: StoreBackend(rt)
|
|
155
|
+
sandbox = RestrictedSubprocessBackend(timeout=30)
|
|
156
|
+
|
|
157
|
+
# Composite routing
|
|
158
|
+
backend = CompositeBackend(
|
|
159
|
+
default=sandbox,
|
|
160
|
+
routes={
|
|
161
|
+
"/skills/": store_backend,
|
|
162
|
+
"/memories/": store_backend,
|
|
163
|
+
}
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
middleware = FilesystemMiddleware(backend=backend)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Summarization Middleware
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
from deepanalysts.middleware import SummarizationMiddleware
|
|
173
|
+
|
|
174
|
+
middleware = SummarizationMiddleware(
|
|
175
|
+
model=model,
|
|
176
|
+
backend=backend_factory,
|
|
177
|
+
trigger=("tokens", 100000), # Trigger at 100k tokens
|
|
178
|
+
keep=("messages", 20), # Keep last 20 messages
|
|
179
|
+
history_path_prefix="/conversation_history",
|
|
180
|
+
)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Tool Error Handling
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
from deepanalysts.middleware import ToolErrorHandlingMiddleware
|
|
187
|
+
|
|
188
|
+
# Place first in middleware stack to catch all tool errors
|
|
189
|
+
middleware_stack = [
|
|
190
|
+
ToolErrorHandlingMiddleware(), # First!
|
|
191
|
+
MemoryMiddleware(...),
|
|
192
|
+
SkillsMiddleware(...),
|
|
193
|
+
FilesystemMiddleware(...),
|
|
194
|
+
SubAgentMiddleware(...),
|
|
195
|
+
]
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Patch Tool Calls (Dangling Tool Calls)
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
from deepanalysts.middleware import PatchToolCallsMiddleware
|
|
202
|
+
|
|
203
|
+
# Handles cases where AIMessage has tool calls but no ToolMessage response
|
|
204
|
+
middleware_stack = [
|
|
205
|
+
PatchToolCallsMiddleware(),
|
|
206
|
+
# ... other middleware
|
|
207
|
+
]
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Basement Client
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
from deepanalysts.clients import BasementClient
|
|
214
|
+
|
|
215
|
+
client = BasementClient(
|
|
216
|
+
base_url="https://basement.embient.ai",
|
|
217
|
+
token="jwt-token",
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
# Fetch data
|
|
221
|
+
memories = await client.get_active_memories()
|
|
222
|
+
skills = await client.get_active_skills()
|
|
223
|
+
|
|
224
|
+
# Sync data back
|
|
225
|
+
await client.sync_memory("my-memory", "content")
|
|
226
|
+
await client.sync_skill("my-skill", "description", "SKILL.md content")
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Package Structure
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
deepanalysts/
|
|
233
|
+
├── __init__.py # Main exports
|
|
234
|
+
├── middleware/
|
|
235
|
+
│ ├── memory.py # MemoryMiddleware (loader + backend modes)
|
|
236
|
+
│ ├── skills.py # SkillsMiddleware (loader + backend modes)
|
|
237
|
+
│ ├── tool_errors.py # ToolErrorHandlingMiddleware
|
|
238
|
+
│ ├── patch_tool_calls.py # PatchToolCallsMiddleware
|
|
239
|
+
│ ├── subagents.py # SubAgentMiddleware with task tool
|
|
240
|
+
│ ├── filesystem.py # FilesystemMiddleware with file tools
|
|
241
|
+
│ ├── summarization.py # SummarizationMiddleware with backend offloading
|
|
242
|
+
│ └── _utils.py # Internal utilities
|
|
243
|
+
├── backends/
|
|
244
|
+
│ ├── protocol.py # BackendProtocol, SandboxBackendProtocol
|
|
245
|
+
│ ├── store.py # StoreBackend (LangGraph BaseStore)
|
|
246
|
+
│ ├── sandbox.py # BaseSandbox, RestrictedSubprocessBackend
|
|
247
|
+
│ ├── composite.py # CompositeBackend (path-based routing)
|
|
248
|
+
│ ├── basement.py # BasementMemoryLoader, BasementSkillsLoader
|
|
249
|
+
│ └── utils.py # Shared utilities (formatting, grep, glob)
|
|
250
|
+
├── clients/
|
|
251
|
+
│ └── basement.py # BasementClient (API client)
|
|
252
|
+
└── utils/
|
|
253
|
+
└── retry.py # Retry utilities for transient errors
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## License
|
|
257
|
+
|
|
258
|
+
MIT
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# Deep Analysts
|
|
2
|
+
|
|
3
|
+
LangChain/LangGraph middleware for building AI agents with memory, skills, filesystem support, and subagent orchestration.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Deep Analysts provides a complete middleware stack for LangChain agents:
|
|
8
|
+
|
|
9
|
+
- **Middleware**: Memory, Skills, Filesystem, Subagents, Summarization, Tool Error Handling
|
|
10
|
+
- **Backends**: Store (LangGraph BaseStore), Sandbox (subprocess execution), Composite (path-based routing)
|
|
11
|
+
- **API Integration**: Basement client for syncing skills/memories to cloud
|
|
12
|
+
|
|
13
|
+
**No dependencies on deepagents** - uses only langchain, langgraph, and standard libraries.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
### For embient-cli (local development)
|
|
18
|
+
|
|
19
|
+
The package is already configured as a local dependency in `pyproject.toml`:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cd embient-cli
|
|
23
|
+
uv sync
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### For park (proprietary cloud service)
|
|
27
|
+
|
|
28
|
+
Add to `pyproject.toml`:
|
|
29
|
+
|
|
30
|
+
```toml
|
|
31
|
+
[project]
|
|
32
|
+
dependencies = [
|
|
33
|
+
"deepanalysts>=0.1.0",
|
|
34
|
+
# ... other deps
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[tool.uv.sources]
|
|
38
|
+
# Option 1: Git subdirectory (recommended for development)
|
|
39
|
+
deepanalysts = { git = "https://github.com/SKE-Labs/embient-cli.git", subdirectory = "libs/deepanalysts" }
|
|
40
|
+
|
|
41
|
+
# Option 2: After publishing to PyPI
|
|
42
|
+
# deepanalysts = ">=0.1.0"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
### SubAgent Middleware (Orchestration)
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from deepanalysts.middleware import SubAgentMiddleware, SubAgent
|
|
51
|
+
|
|
52
|
+
# Define subagents
|
|
53
|
+
technical_analyst = SubAgent(
|
|
54
|
+
name="technical_analyst",
|
|
55
|
+
description="Analyzes charts and technical indicators",
|
|
56
|
+
system_prompt="You are a technical analyst...",
|
|
57
|
+
tools=[get_indicator, get_candles],
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Create middleware with subagent delegation
|
|
61
|
+
middleware = SubAgentMiddleware(
|
|
62
|
+
default_model=model,
|
|
63
|
+
default_tools=[],
|
|
64
|
+
subagents=[technical_analyst, signal_manager],
|
|
65
|
+
)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Memory Middleware
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from deepanalysts.middleware import MemoryMiddleware
|
|
72
|
+
from deepanalysts.backends import StoreBackend
|
|
73
|
+
|
|
74
|
+
# With backend (file-based)
|
|
75
|
+
middleware = MemoryMiddleware(
|
|
76
|
+
backend=lambda rt: StoreBackend(rt),
|
|
77
|
+
sources=[
|
|
78
|
+
"~/.embient/AGENTS.md",
|
|
79
|
+
"./.embient/AGENTS.md",
|
|
80
|
+
],
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# With API loader
|
|
84
|
+
from deepanalysts.backends import BasementMemoryLoader
|
|
85
|
+
|
|
86
|
+
loader = BasementMemoryLoader(token_provider=get_jwt_token)
|
|
87
|
+
middleware = MemoryMiddleware(loader=loader)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Skills Middleware
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from deepanalysts.middleware import SkillsMiddleware
|
|
94
|
+
from deepanalysts.backends import BasementSkillsLoader
|
|
95
|
+
|
|
96
|
+
# API mode with agent filtering
|
|
97
|
+
loader = BasementSkillsLoader(
|
|
98
|
+
token_provider=get_jwt_token,
|
|
99
|
+
store=app.state.store, # For read_file access
|
|
100
|
+
)
|
|
101
|
+
middleware = SkillsMiddleware(
|
|
102
|
+
loader=loader,
|
|
103
|
+
agent_name="technical_analyst", # Filter skills by target_agents
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Backend mode
|
|
107
|
+
middleware = SkillsMiddleware(
|
|
108
|
+
backend=my_backend,
|
|
109
|
+
sources=["/skills/user/", "/skills/project/"],
|
|
110
|
+
)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Filesystem Middleware
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
from deepanalysts.middleware import FilesystemMiddleware
|
|
117
|
+
from deepanalysts.backends import CompositeBackend, StoreBackend, RestrictedSubprocessBackend
|
|
118
|
+
|
|
119
|
+
# Create backends
|
|
120
|
+
store_backend = lambda rt: StoreBackend(rt)
|
|
121
|
+
sandbox = RestrictedSubprocessBackend(timeout=30)
|
|
122
|
+
|
|
123
|
+
# Composite routing
|
|
124
|
+
backend = CompositeBackend(
|
|
125
|
+
default=sandbox,
|
|
126
|
+
routes={
|
|
127
|
+
"/skills/": store_backend,
|
|
128
|
+
"/memories/": store_backend,
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
middleware = FilesystemMiddleware(backend=backend)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Summarization Middleware
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
from deepanalysts.middleware import SummarizationMiddleware
|
|
139
|
+
|
|
140
|
+
middleware = SummarizationMiddleware(
|
|
141
|
+
model=model,
|
|
142
|
+
backend=backend_factory,
|
|
143
|
+
trigger=("tokens", 100000), # Trigger at 100k tokens
|
|
144
|
+
keep=("messages", 20), # Keep last 20 messages
|
|
145
|
+
history_path_prefix="/conversation_history",
|
|
146
|
+
)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Tool Error Handling
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
from deepanalysts.middleware import ToolErrorHandlingMiddleware
|
|
153
|
+
|
|
154
|
+
# Place first in middleware stack to catch all tool errors
|
|
155
|
+
middleware_stack = [
|
|
156
|
+
ToolErrorHandlingMiddleware(), # First!
|
|
157
|
+
MemoryMiddleware(...),
|
|
158
|
+
SkillsMiddleware(...),
|
|
159
|
+
FilesystemMiddleware(...),
|
|
160
|
+
SubAgentMiddleware(...),
|
|
161
|
+
]
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Patch Tool Calls (Dangling Tool Calls)
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
from deepanalysts.middleware import PatchToolCallsMiddleware
|
|
168
|
+
|
|
169
|
+
# Handles cases where AIMessage has tool calls but no ToolMessage response
|
|
170
|
+
middleware_stack = [
|
|
171
|
+
PatchToolCallsMiddleware(),
|
|
172
|
+
# ... other middleware
|
|
173
|
+
]
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Basement Client
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from deepanalysts.clients import BasementClient
|
|
180
|
+
|
|
181
|
+
client = BasementClient(
|
|
182
|
+
base_url="https://basement.embient.ai",
|
|
183
|
+
token="jwt-token",
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# Fetch data
|
|
187
|
+
memories = await client.get_active_memories()
|
|
188
|
+
skills = await client.get_active_skills()
|
|
189
|
+
|
|
190
|
+
# Sync data back
|
|
191
|
+
await client.sync_memory("my-memory", "content")
|
|
192
|
+
await client.sync_skill("my-skill", "description", "SKILL.md content")
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Package Structure
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
deepanalysts/
|
|
199
|
+
├── __init__.py # Main exports
|
|
200
|
+
├── middleware/
|
|
201
|
+
│ ├── memory.py # MemoryMiddleware (loader + backend modes)
|
|
202
|
+
│ ├── skills.py # SkillsMiddleware (loader + backend modes)
|
|
203
|
+
│ ├── tool_errors.py # ToolErrorHandlingMiddleware
|
|
204
|
+
│ ├── patch_tool_calls.py # PatchToolCallsMiddleware
|
|
205
|
+
│ ├── subagents.py # SubAgentMiddleware with task tool
|
|
206
|
+
│ ├── filesystem.py # FilesystemMiddleware with file tools
|
|
207
|
+
│ ├── summarization.py # SummarizationMiddleware with backend offloading
|
|
208
|
+
│ └── _utils.py # Internal utilities
|
|
209
|
+
├── backends/
|
|
210
|
+
│ ├── protocol.py # BackendProtocol, SandboxBackendProtocol
|
|
211
|
+
│ ├── store.py # StoreBackend (LangGraph BaseStore)
|
|
212
|
+
│ ├── sandbox.py # BaseSandbox, RestrictedSubprocessBackend
|
|
213
|
+
│ ├── composite.py # CompositeBackend (path-based routing)
|
|
214
|
+
│ ├── basement.py # BasementMemoryLoader, BasementSkillsLoader
|
|
215
|
+
│ └── utils.py # Shared utilities (formatting, grep, glob)
|
|
216
|
+
├── clients/
|
|
217
|
+
│ └── basement.py # BasementClient (API client)
|
|
218
|
+
└── utils/
|
|
219
|
+
└── retry.py # Retry utilities for transient errors
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
MIT
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""Deep Analysts - Middleware and backends for LangChain/LangGraph agents.
|
|
2
|
+
|
|
3
|
+
This package provides:
|
|
4
|
+
- Middleware for agent orchestration (subagents, memory, skills, filesystem, etc.)
|
|
5
|
+
- Backend implementations for file storage (store, sandbox, composite routing)
|
|
6
|
+
- Basement API client for syncing skills/memories
|
|
7
|
+
- Retry utilities for transient error handling
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
from deepanalysts.middleware import (
|
|
11
|
+
FilesystemMiddleware,
|
|
12
|
+
MemoryMiddleware,
|
|
13
|
+
PatchToolCallsMiddleware,
|
|
14
|
+
SkillsMiddleware,
|
|
15
|
+
SubAgentMiddleware,
|
|
16
|
+
SummarizationMiddleware,
|
|
17
|
+
ToolErrorHandlingMiddleware,
|
|
18
|
+
)
|
|
19
|
+
from deepanalysts.backends import (
|
|
20
|
+
CompositeBackend,
|
|
21
|
+
StoreBackend,
|
|
22
|
+
RestrictedSubprocessBackend,
|
|
23
|
+
)
|
|
24
|
+
from deepanalysts.clients import BasementClient
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from deepanalysts.middleware import (
|
|
28
|
+
TASK_SYSTEM_PROMPT,
|
|
29
|
+
TASK_TOOL_DESCRIPTION,
|
|
30
|
+
CompiledSubAgent,
|
|
31
|
+
FilesystemMiddleware,
|
|
32
|
+
MemoryMiddleware,
|
|
33
|
+
PatchToolCallsMiddleware,
|
|
34
|
+
SkillMetadata,
|
|
35
|
+
SkillsMiddleware,
|
|
36
|
+
SubAgent,
|
|
37
|
+
SubAgentMiddleware,
|
|
38
|
+
SummarizationMiddleware,
|
|
39
|
+
ToolErrorHandlingMiddleware,
|
|
40
|
+
TruncateArgsSettings,
|
|
41
|
+
build_session_context,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
__all__ = [
|
|
45
|
+
# Middleware classes
|
|
46
|
+
"FilesystemMiddleware",
|
|
47
|
+
"MemoryMiddleware",
|
|
48
|
+
"PatchToolCallsMiddleware",
|
|
49
|
+
"SkillsMiddleware",
|
|
50
|
+
"SubAgentMiddleware",
|
|
51
|
+
"SummarizationMiddleware",
|
|
52
|
+
"ToolErrorHandlingMiddleware",
|
|
53
|
+
# TypedDicts and types
|
|
54
|
+
"CompiledSubAgent",
|
|
55
|
+
"SkillMetadata",
|
|
56
|
+
"SubAgent",
|
|
57
|
+
"TruncateArgsSettings",
|
|
58
|
+
# Constants
|
|
59
|
+
"TASK_SYSTEM_PROMPT",
|
|
60
|
+
"TASK_TOOL_DESCRIPTION",
|
|
61
|
+
# Utility functions
|
|
62
|
+
"build_session_context",
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Backends for deepanalysts middleware storage."""
|
|
2
|
+
|
|
3
|
+
from deepanalysts.backends.composite import CompositeBackend
|
|
4
|
+
from deepanalysts.backends.filesystem import FilesystemBackend, LocalFilesystemBackend
|
|
5
|
+
from deepanalysts.backends.protocol import (
|
|
6
|
+
BACKEND_TYPES,
|
|
7
|
+
BackendProtocol,
|
|
8
|
+
EditResult,
|
|
9
|
+
ExecuteResponse,
|
|
10
|
+
FileDownloadResponse,
|
|
11
|
+
FileInfo,
|
|
12
|
+
FileUploadResponse,
|
|
13
|
+
GrepMatch,
|
|
14
|
+
SandboxBackendProtocol,
|
|
15
|
+
WriteResult,
|
|
16
|
+
)
|
|
17
|
+
from deepanalysts.backends.sandbox import BaseSandbox, RestrictedSubprocessBackend
|
|
18
|
+
from deepanalysts.backends.store import StoreBackend
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
# Protocols and types
|
|
22
|
+
"BACKEND_TYPES",
|
|
23
|
+
"BackendProtocol",
|
|
24
|
+
"SandboxBackendProtocol",
|
|
25
|
+
# Result types
|
|
26
|
+
"EditResult",
|
|
27
|
+
"ExecuteResponse",
|
|
28
|
+
"FileDownloadResponse",
|
|
29
|
+
"FileInfo",
|
|
30
|
+
"FileUploadResponse",
|
|
31
|
+
"GrepMatch",
|
|
32
|
+
"WriteResult",
|
|
33
|
+
# Backend implementations
|
|
34
|
+
"BaseSandbox",
|
|
35
|
+
"CompositeBackend",
|
|
36
|
+
"FilesystemBackend",
|
|
37
|
+
"LocalFilesystemBackend",
|
|
38
|
+
"RestrictedSubprocessBackend",
|
|
39
|
+
"StoreBackend",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
# Optional imports that require additional dependencies (Basement API loaders)
|
|
43
|
+
try:
|
|
44
|
+
from deepanalysts.backends.basement import BasementMemoryLoader, BasementSkillsLoader
|
|
45
|
+
|
|
46
|
+
__all__.extend(["BasementMemoryLoader", "BasementSkillsLoader"])
|
|
47
|
+
except ImportError:
|
|
48
|
+
pass
|