nodal-agents 0.5.5 → 0.6.1
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.
- package/README.md +192 -310
- package/cli.js +288 -1
- package/migrations/0049_skill_assignment_files_writable.sql +1 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/runner.js +780 -117
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/app-path-routes-manifest.json +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js +6 -4
- package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/agents/[id]/edit/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page.js +2 -2
- package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/agents/page.js +2 -2
- package/web/.next/server/app/(dashboard)/agents/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/agents/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/approvals/page.js +2 -2
- package/web/.next/server/app/(dashboard)/approvals/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/approvals/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/automations/page.js +2 -2
- package/web/.next/server/app/(dashboard)/automations/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/billing/page.js +1 -1
- package/web/.next/server/app/(dashboard)/billing/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/chat/page.js +2 -2
- package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/connectors/page.js +2 -2
- package/web/.next/server/app/(dashboard)/connectors/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/connectors/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/credentials/page.js +2 -2
- package/web/.next/server/app/(dashboard)/credentials/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/credentials/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/jobs/[id]/page.js +2 -2
- package/web/.next/server/app/(dashboard)/jobs/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/jobs/page.js +2 -2
- package/web/.next/server/app/(dashboard)/jobs/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/jobs/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/learned-skills/page.js +1 -1
- package/web/.next/server/app/(dashboard)/learned-skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/llm-providers/page.js +2 -2
- package/web/.next/server/app/(dashboard)/llm-providers/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/logs/page.js +1 -1
- package/web/.next/server/app/(dashboard)/logs/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/mcp/page.js +1 -1
- package/web/.next/server/app/(dashboard)/mcp/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/memories/page.js +2 -2
- package/web/.next/server/app/(dashboard)/memories/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page.js +3 -3
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/settings/page.js +2 -2
- package/web/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/settings/root-context/page.js +1 -1
- package/web/.next/server/app/(dashboard)/settings/root-context/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js +2 -2
- package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/skills/[id]/edit/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/skills/new/page.js +2 -2
- package/web/.next/server/app/(dashboard)/skills/new/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/skills/new/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/skills/page.js +1 -1
- package/web/.next/server/app/(dashboard)/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error/page.js +1 -1
- package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +1 -1
- package/web/.next/server/app/_global-error.rsc +3 -3
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +3 -3
- package/web/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page.js +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/server/app/_not-found.rsc +4 -4
- package/web/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- package/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
- package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/web/.next/server/app/login/page.js +1 -1
- package/web/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/onboarding/page.js +1 -1
- package/web/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/onboarding.html +1 -1
- package/web/.next/server/app/onboarding.rsc +4 -4
- package/web/.next/server/app/onboarding.segments/_full.segment.rsc +4 -4
- package/web/.next/server/app/onboarding.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/onboarding.segments/_index.segment.rsc +4 -4
- package/web/.next/server/app/onboarding.segments/_tree.segment.rsc +2 -2
- package/web/.next/server/app/onboarding.segments/onboarding/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/onboarding.segments/onboarding.segment.rsc +1 -1
- package/web/.next/server/app-paths-manifest.json +1 -1
- package/web/.next/server/chunks/1445.js +1 -0
- package/web/.next/server/chunks/1761.js +1 -1
- package/web/.next/server/chunks/3024.js +1 -0
- package/web/.next/server/chunks/3966.js +1 -1
- package/web/.next/server/chunks/3971.js +1 -0
- package/web/.next/server/chunks/4370.js +60 -21
- package/web/.next/server/chunks/4574.js +1 -1
- package/web/.next/server/chunks/6012.js +1 -0
- package/web/.next/server/chunks/7928.js +1 -0
- package/web/.next/server/chunks/8909.js +1 -0
- package/web/.next/server/middleware-build-manifest.js +1 -1
- package/web/.next/server/pages/404.html +1 -1
- package/web/.next/server/pages/500.html +1 -1
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +1 -1
- package/web/.next/static/chunks/2787-b32c92cd300d8dc6.js +1 -0
- package/web/.next/static/chunks/4414-4e856db2be92b231.js +1 -0
- package/web/.next/static/chunks/{4905-65b5713d2e04086d.js → 4905-272003c6fbcb2e79.js} +1 -1
- package/web/.next/static/chunks/6097-d568d74074f2dad0.js +1 -0
- package/web/.next/static/chunks/8370-18663baebcb57ea1.js +1 -0
- package/web/.next/static/chunks/8502-10b8c3517f2f6c63.js +1 -0
- package/web/.next/static/chunks/{8666-2e66ac2d8f9b71a3.js → 8666-ee79795cd5f52e9c.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-e3522f5beaa39d00.js +6 -0
- package/web/.next/static/chunks/app/(dashboard)/agents/page-fa24d21f3dd81779.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/automations/{page-3b724d8f6e8c957f.js → page-54d3b31e9f8319ba.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/chat/page-0756eef0efe47d26.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/connectors/page-e155c796daf03636.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/credentials/{page-ef2666c5ac3ede9b.js → page-38a4707132e529ba.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/jobs/[id]/{page-7e9af908ef12f252.js → page-d24cf11cba87c25c.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/jobs/page-addbc7ca9fd29056.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/layout-74abd51f1d4f4847.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/learned-skills/page-596febd5d9d3130e.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/llm-providers/page-3e569fa57980ef9b.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/logs/{page-21d587049e8a6ccb.js → page-c9543d1a5b387378.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/mcp/page-cc885192e6efce48.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/memories/page-2bc309d3e59fb48d.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/page-b6ce64251f732896.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/settings/page-b73e0e200ee4d9fa.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/settings/root-context/page-af7ccec522050199.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/skills/new/{page-6246f9236b209e76.js → page-95280e7f506e3443.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/skills/page-8e381563f665bb68.js +1 -0
- package/web/.next/static/chunks/app/{error-f106e9e65e16edb3.js → error-dc3b2db3bdb5b34e.js} +1 -1
- package/web/.next/static/css/ef13c0ab64dcfa86.css +3 -0
- package/web/.next/server/chunks/234.js +0 -1
- package/web/.next/server/chunks/473.js +0 -1
- package/web/.next/server/chunks/6200.js +0 -1
- package/web/.next/server/chunks/6778.js +0 -1
- package/web/.next/server/chunks/7415.js +0 -1
- package/web/.next/static/chunks/269-dc034ed29e6c72ee.js +0 -1
- package/web/.next/static/chunks/3233-e6efb7fb1fa24591.js +0 -1
- package/web/.next/static/chunks/5436-c1006a40e59853ed.js +0 -1
- package/web/.next/static/chunks/6078-abdc3955397924b3.js +0 -1
- package/web/.next/static/chunks/6097-12165ea99c077896.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-113e915a8d6bc208.js +0 -4
- package/web/.next/static/chunks/app/(dashboard)/agents/page-4796ad5efe8f9d82.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/chat/page-b98de38c17f2cd96.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/connectors/page-ca2e5aabaadd7588.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/jobs/page-9b09d95cc1a8053c.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/layout-a34502d1a8386a62.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/learned-skills/page-447ba18bc6af3c57.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/llm-providers/page-c0c5aa806b9b47d4.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/mcp/page-d53d13942bd635a4.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/memories/page-ebcc28ea081ae566.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/page-2a69294b49293833.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/settings/page-8b16269593b01037.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/settings/root-context/page-6830a271484d97d5.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/skills/page-9375adacecc0d76b.js +0 -1
- package/web/.next/static/css/f93e519b745ac2de.css +0 -3
- /package/web/.next/static/{KOOaOEQcp6DLMYS1kFfRL → KhwbJu08qtDMXMHHv9JeS}/_buildManifest.js +0 -0
- /package/web/.next/static/{KOOaOEQcp6DLMYS1kFfRL → KhwbJu08qtDMXMHHv9JeS}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -1,310 +1,192 @@
|
|
|
1
|
-
# Nodal-Agents
|
|
2
|
-
|
|
3
|
-
> **Your AI agents. Your data. Your machine.**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
├── auth Pluggable auth provider
|
|
194
|
-
├── catalog Shipped system skills (office-editing, telegram-responder,
|
|
195
|
-
│ obsidian, task-planning, markdown-output, language-mirror …)
|
|
196
|
-
└── secrets AES-256-GCM key vault
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
---
|
|
200
|
-
|
|
201
|
-
## Architecture rules (enforced by `dependency-cruiser`)
|
|
202
|
-
|
|
203
|
-
- `apps/*` may import `packages/*` — never the reverse.
|
|
204
|
-
- `apps/web` and `apps/runner` cannot import each other (DB or HTTP only).
|
|
205
|
-
- Only `packages/db` may import `postgres` / `drizzle-orm` / `pg`.
|
|
206
|
-
- `packages/runner-adapters/*` may only import from `packages/tools` and
|
|
207
|
-
`packages/shared`.
|
|
208
|
-
- No circular dependencies.
|
|
209
|
-
|
|
210
|
-
```bash
|
|
211
|
-
pnpm deps:check # runs locally and in CI before every release
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
## Status
|
|
217
|
-
|
|
218
|
-
**Current release:** `0.5.2` on npm `latest`. Used daily by the
|
|
219
|
-
maintainer, stable enough for personal production. Pre-1.0 — breaking
|
|
220
|
-
changes are still possible between minors.
|
|
221
|
-
|
|
222
|
-
### Shipped and working
|
|
223
|
-
|
|
224
|
-
- Multi-LLM, **per-agent model selection** — provider setup is just an API key
|
|
225
|
-
(one per provider); each agent chooses its own model on top. Frontier and
|
|
226
|
-
local providers, plus **native DeepSeek** (`api.deepseek.com`) and **native
|
|
227
|
-
MiniMax** (`api.minimax.io`) endpoints alongside OpenRouter — pick the route
|
|
228
|
-
per key. **DeepSeek V4** non-spec tool-call args are normalized automatically
|
|
229
|
-
and **reasoning models like MiniMax M3** have their hidden chain-of-thought
|
|
230
|
-
round-tripped across tool calls so they keep reasoning on multi-turn tasks,
|
|
231
|
-
plus native tool-call parsing for Kimi K2 / Qwen3-Coder / GLM
|
|
232
|
-
- **Provider failover** — an opt-in ordered key chain per agent; on a 5xx /
|
|
233
|
-
timeout / quota mid-job the runner fails over to the next key, and fails loud
|
|
234
|
-
(`all_providers_failed`) only when the whole chain is exhausted
|
|
235
|
-
- **Reliability guards (generic, model-agnostic)** — a per-job **real-dollar
|
|
236
|
-
cost cap** (read from the provider's actually-billed cost, `cost_budget_exceeded`)
|
|
237
|
-
+ token budget + no-progress / no-delivery detectors (kill runaway loops), an
|
|
238
|
-
**atomic job claim** so the same job never executes twice, a no-false-success
|
|
239
|
-
guard that refuses to complete a job as "success" when a tool action failed and
|
|
240
|
-
was never resolved (fail loud, never fake it), a **recoverable** path for a
|
|
241
|
-
mis-named tool call (a bounded "did you mean…" nudge, not an instant kill), and
|
|
242
|
-
context compaction that evicts stale tool output before the context window overflows
|
|
243
|
-
- **Never a silent stop** — every failed *or blocked* job hands the user a short,
|
|
244
|
-
specific reason (in the agent's own words when it blocks), propagated up through
|
|
245
|
-
delegation; a blocked job is honestly `failed`, never a fake "completed"
|
|
246
|
-
- **Diagnosable failures** — every failed job persists its full transcript, the
|
|
247
|
-
real upstream provider error (not an opaque "provider returned error"), and the
|
|
248
|
-
actual upstream that served each turn, so you can see exactly what the agent did
|
|
249
|
-
and why it stopped
|
|
250
|
-
- **Self-improving agents (opt-in learning loop)** — after a substantial job, an
|
|
251
|
-
agent reflects on its transcript and writes itself a reusable skill (sandboxed
|
|
252
|
-
provenance); a weekly curator consolidates and prunes them. Review, assign,
|
|
253
|
-
archive or revoke every learned skill from `/learned-skills` (off by default,
|
|
254
|
-
per workspace; auto-assign or require approval)
|
|
255
|
-
- **Install any community skill** — fetch any open `SKILL.md` from a GitHub repo,
|
|
256
|
-
a skills.sh slug, or a ClawHub package and install it as a first-class skill
|
|
257
|
-
(pure HTTPS, SSRF allow-list, zip-slip guard; bundled scripts flagged, never run)
|
|
258
|
-
- Persistent memory (sanitation, dedup, importance ranking, auto-injection,
|
|
259
|
-
feedback loop)
|
|
260
|
-
- Session-thread continuity on chat channels (Telegram today)
|
|
261
|
-
- **Unified orchestrator** — every orchestrator gets both delegation styles and
|
|
262
|
-
picks per request: route to one specialist and resume on its result (router),
|
|
263
|
-
or fan out independent tasks to a parallel task board that compiles + delivers
|
|
264
|
-
the combined result (planner). One commits to a single style per job
|
|
265
|
-
- Multi-instance connectors with OAuth (Gmail, Drive, Sheets, Docs, Notion,
|
|
266
|
-
Airtable) and API-key (Notion, Airtable, Apify, Firecrawl, Tavily)
|
|
267
|
-
- MCP catalog — Streamable HTTP *and* stdio (local subprocess) servers, API-key auth; a growing catalogue (Stripe, n8n, Supabase, Airtable, Notion…) with a "test pending" badge on entries not yet verified live, plus add *and edit* your own custom HTTP/stdio servers from the dashboard
|
|
268
|
-
- Top-level workspaces — multiple isolated entities (agents/skills/connectors/jobs/memory per workspace), switch in the sidebar
|
|
269
|
-
- In-app ROOT chat — talk to your workspace ROOT right in the dashboard: conversation-first (pure chat never creates a job — recall is free, the agent's memory is auto-loaded), multiple conversations with searchable history, and inline "dispatched to N agents" cards when it escalates a real action into a tracked job
|
|
270
|
-
- ROOT agent — your first orchestrator automatically becomes the workspace ROOT (the single top-level agent; later orchestrators slot under it). It can create *and update* skills, create agents and assign them, and create MCP servers + API connectors — each gated by per-grant toggles + an autonomy/approval level (powers start off, opt in per grant). Provisioning verifies before it writes (an MCP server is connected and its tools listed first); skill authoring is grounded in the workspace's real tools (a linter rejects skills referencing tools the agent doesn't have)
|
|
271
|
-
- Office file editing — Excel in-place edit, Word/PowerPoint create, in the agent workspace (office-editing skill)
|
|
272
|
-
- Multiple filesystem folders per agent (sandboxed `file_*` tools)
|
|
273
|
-
- **Shell execution** — agents can run shell commands in their workspace
|
|
274
|
-
(`run_command`: install deps, run scripts, build steps) via an opt-in
|
|
275
|
-
`command-execution` skill. Safe-by-default: every command pauses for your
|
|
276
|
-
approval, with an optional per-agent auto-run ("Yolo"). On a shared / LAN
|
|
277
|
-
install auto-run is gated behind an explicit workspace-owner opt-in and
|
|
278
|
-
**enforced at execution time** — flip the workspace switch off and even an
|
|
279
|
-
already-trusted agent drops back to requiring approval. A live bell surfaces
|
|
280
|
-
pending approvals from anywhere in the dashboard
|
|
281
|
-
- Telegram delivery (long-poll, group filters, multi-agent routing,
|
|
282
|
-
delegation gracefulness) — exactly-once delivery contract: anti-spam guard
|
|
283
|
-
against runaway message loops + a guard that re-prompts (then fails loud)
|
|
284
|
-
rather than completing a job without ever replying
|
|
285
|
-
- Approval gates for risky tools (execute-the-approved-action on resume) — on a chat channel, the agent sends a heads-up before the job pauses so the user knows an approval is waiting
|
|
286
|
-
- Cron scheduling — trigger any automation out-of-band ("Run now") + opt-in Telegram confirmation when a scheduled job succeeds
|
|
287
|
-
- Duplicate any automation in one click; opt-in retention to purge old terminal jobs
|
|
288
|
-
- `nodal-agents update` — one-command upgrade + boot version notice
|
|
289
|
-
- Encryption at rest for LLM keys + MCP keys; in LAN / multi-user modes the
|
|
290
|
-
runner requires a shared `WORKER_SECRET` on every mutating route (no
|
|
291
|
-
unauthenticated job/LLM spend from other devices on the network)
|
|
292
|
-
- Embedded Postgres distribution via npm (no external DB to install)
|
|
293
|
-
|
|
294
|
-
### On the roadmap (genuine, not vaporware)
|
|
295
|
-
|
|
296
|
-
- **MCP OAuth flow** → unlocks Linear, Notion remote, GitHub remote,
|
|
297
|
-
Atlassian, Sentry, and the rest of the SaaS-as-MCP ecosystem.
|
|
298
|
-
- **Dry-run mode + a test-workflow meta-tool** → preview what the ROOT would
|
|
299
|
-
do before it runs, and let it validate an automation end-to-end.
|
|
300
|
-
- **pgvector binaries bundled in the npm pack** → semantic memory search
|
|
301
|
-
active out-of-the-box. Today, installs without pgvector fall back to
|
|
302
|
-
keyword search (which works, just less smart for cross-vocabulary
|
|
303
|
-
recall).
|
|
304
|
-
- Data migration tools from the legacy Python stack.
|
|
305
|
-
|
|
306
|
-
---
|
|
307
|
-
|
|
308
|
-
## License
|
|
309
|
-
|
|
310
|
-
TBD.
|
|
1
|
+
# Nodal-Agents
|
|
2
|
+
|
|
3
|
+
> **Your AI agents. Your data. Your machine.**
|
|
4
|
+
|
|
5
|
+
A self-hosted platform for building and orchestrating a **team of AI agents** on your own hardware — each with its own personality, tools, memory, and model. Talk to them in the dashboard or on Telegram; they research, write files, call your connectors, and delegate to each other to get the job done.
|
|
6
|
+
|
|
7
|
+
**No SaaS lock-in. No per-token markup. No cloud roundtrip.** Two commands to install, runs on any machine with Node 22+ (Mac, Windows, Linux), and works with **any LLM** — frontier or local, paid or free.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/nodal-agents)
|
|
10
|
+
[](https://nodejs.org)
|
|
11
|
+
[](https://www.typescriptlang.org)
|
|
12
|
+
[](https://kwintspiracy.github.io/nodal-agents/)
|
|
13
|
+
[](CHANGELOG.md)
|
|
14
|
+
|
|
15
|
+
| Home dashboard — light theme | Agent detail — dark theme |
|
|
16
|
+
| :---: | :---: |
|
|
17
|
+
|  |  |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Quickstart
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install -g nodal-agents
|
|
25
|
+
nodal-agents up
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Open <http://localhost:3000>, paste an LLM API key under **LLM Providers**, and you have a working agent. The CLI spawns an embedded Postgres on a free port, applies migrations, seeds the system skills, and starts the runner (`:3001`) and dashboard (`:3000`).
|
|
29
|
+
|
|
30
|
+
> Node 22+ · no external Postgres, no Redis, no cloud config · data lives in `~/.nodalai/` · stop with `nodal-agents down`
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## What you can build
|
|
35
|
+
|
|
36
|
+
- **A research desk** — an orchestrator fans a question out to specialists (web search, your Notion, your Drive), each writes a section, then it compiles the brief and emails it to you.
|
|
37
|
+
- **A Telegram concierge** — message a bot; it routes to the right agent, remembers the conversation, runs shell commands or calls your APIs, and asks for approval before anything risky.
|
|
38
|
+
- **An automation crew** — cron-scheduled agents that run every morning, hit your connectors and MCP servers, and ping you on Telegram when they're done.
|
|
39
|
+
|
|
40
|
+
Every agent runs on the model **you** choose, with the tools **you** grant, in a workspace **you** own.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Why Nodal-Agents
|
|
45
|
+
|
|
46
|
+
### 🏠 Own your whole stack
|
|
47
|
+
|
|
48
|
+
- **Local-first** — single command, embedded Postgres, zero cloud dependency.
|
|
49
|
+
- **Your data & keys** — conversations, memory, and credentials never leave your machine; API keys are AES-256-GCM encrypted at rest.
|
|
50
|
+
- **Workspaces** — multiple isolated workspaces on one install (personal vs work), each with its own agents, skills, connectors, jobs, and memory.
|
|
51
|
+
- **No markup** — bring your own API keys; you pay the provider directly, nothing on top.
|
|
52
|
+
|
|
53
|
+
### 🔌 Any model — and it stays reliable
|
|
54
|
+
|
|
55
|
+
- **A model per agent** — run Claude for the orchestrator and a cheap OSS model for the workers; setup is just one API key per provider.
|
|
56
|
+
- **OSS frontier models, handled** — DeepSeek's non-spec tool args, Kimi/Qwen/GLM XML tool formats, and round-tripping a reasoning model's chain-of-thought (MiniMax M3, DeepSeek, Gemini 3) across tool calls — all automatic, so they don't degrade mid-task.
|
|
57
|
+
- **Provider failover** — give an agent a backup key chain; on a 5xx, timeout, or quota mid-job the runner fails over to the next one and only fails loud when the whole chain is down.
|
|
58
|
+
- **Guards against runaway, lies, and silent stops** — a real-dollar cost cap (from the provider's billed cost), a no-progress detector, an atomic job claim (never run the same job twice), and a no-false-success guard that refuses to report "done" when an action actually failed.
|
|
59
|
+
- **Diagnosable failures** — every failed job keeps its full transcript, the real upstream error, and a short, specific reason — propagated up through delegation, never a silent stop.
|
|
60
|
+
|
|
61
|
+
### 🤝 Agents that actually finish
|
|
62
|
+
|
|
63
|
+
- **Orchestrators that finish** — pick the delegation style per request: route to one specialist and resume on its result, or fan work out to many sub-agents in parallel and compile the answer.
|
|
64
|
+
- **Memory that compounds** — persistent facts auto-injected into every job, plus chat-thread continuity (your agent remembers what it said 30 seconds ago — and yesterday).
|
|
65
|
+
- **Self-improving (opt-in)** — after a substantial job an agent can reflect and write itself a reusable skill; a weekly curator consolidates and prunes them. Every learned skill is reviewable, assignable, and revocable.
|
|
66
|
+
- **Self-extending ROOT** — designate an orchestrator as ROOT and let it create skills, agents, MCP servers, and connectors on your behalf — gated by per-grant toggles and an autonomy level (propose-confirm → fully-autonomous).
|
|
67
|
+
- **Human-in-the-loop** — risky tools pause for approval, and the prompt leads with the agent's plain-language explanation of *what* it wants to do and *why* (plus any ⚠️ impact) — not a wall of raw shell.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Available now
|
|
72
|
+
|
|
73
|
+
**Models** — Anthropic · OpenAI · Google · Groq · Mistral · OpenRouter · **native DeepSeek** (`api.deepseek.com`) · **native MiniMax** (`api.minimax.io`) · any local model (LM Studio, Ollama). One key per provider; each agent picks its own model.
|
|
74
|
+
|
|
75
|
+
**Connectors** — multi-instance (Gmail perso *and* boulot on one install), managed from the dashboard:
|
|
76
|
+
- *OAuth* — Gmail · Google Drive · Sheets · Docs · Calendar · Notion · Airtable
|
|
77
|
+
- *API key* — Notion · Airtable · Apify · Firecrawl · Tavily
|
|
78
|
+
|
|
79
|
+
**MCP servers** — over Streamable HTTP *and* stdio, plus add/edit your own:
|
|
80
|
+
Stripe · GitHub · Supabase · Notion · Linear · Sentry · n8n · PostgreSQL · Playwright · Perplexity · Apify · Filesystem · Git · Fetch · Sequential Thinking · Composio · Cogni Cortex
|
|
81
|
+
|
|
82
|
+
**Skills** — built-in: office editing (Excel/Word/PowerPoint), shell execution, Obsidian, Telegram etiquette, task planning, markdown output, citation discipline, research methodology, results delivery, language mirroring, HTML design. Plus **install any community `SKILL.md`** from GitHub / skills.sh / ClawHub — and agents can **write their own**.
|
|
83
|
+
|
|
84
|
+
**Channels** — Telegram (long-poll, multi-agent routing via `/ask <slug>`, group-chat filters, conversation continuity) and the dashboard chat.
|
|
85
|
+
|
|
86
|
+
**Other** — shell execution (`run_command`, approval-gated), per-agent sandboxed filesystem folders, cron automations, tool-call audit log, full job transcripts.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## How it works
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
┌─────────────┐ Telegram / ┌────────────────────────────────┐
|
|
94
|
+
│ Channel │ Dashboard ───▶ │ Runner (Hono) │
|
|
95
|
+
│ (telegram, │ POST /api ◀── │ • Job queue + executor │
|
|
96
|
+
│ web …) │ │ • Anti-runaway guards │
|
|
97
|
+
└─────────────┘ │ • Per-agent tool whitelist │
|
|
98
|
+
│ • Memory auto-injection │
|
|
99
|
+
│ • Session-thread continuity │
|
|
100
|
+
└────────┬───────────┬───────────┘
|
|
101
|
+
│ │
|
|
102
|
+
┌──────▼────┐ ┌───▼─────────────┐
|
|
103
|
+
│ LLM │ │ Connectors / │
|
|
104
|
+
│ client │ │ MCP servers │
|
|
105
|
+
│ (multi- │ │ (Gmail, Drive, │
|
|
106
|
+
│ provider) │ │ Notion …) │
|
|
107
|
+
└────────────┘ └─────────────────┘
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Every agent is a **row in Postgres** — personality, skills, connectors, memory budget, and team assignments all live in the database. The runtime is generic: **zero hardcoded agent metadata.** Adding a capability means inserting rows, not editing code.
|
|
111
|
+
|
|
112
|
+
A message becomes an `agent_jobs` row. The runner loads the agent's prior chat-thread history, injects relevant memories, dispatches to the LLM, executes the tool calls it emits, and finalizes the reply. Delegations create child jobs that resume the parent on completion.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## The dashboard
|
|
117
|
+
|
|
118
|
+
| Route | Purpose |
|
|
119
|
+
| --- | --- |
|
|
120
|
+
| `/agents` | Create + edit agents; assign skills, connectors, MCP servers; pick each agent's provider, model, and failover chain. |
|
|
121
|
+
| `/llm-providers` | Connect each LLM provider with one API key. Models are chosen per-agent. |
|
|
122
|
+
| `/jobs` | Live job stream — task, agent, status, full transcript, tool I/O. |
|
|
123
|
+
| `/connectors` | Active connector instances + Marketplace (multi-instance, OAuth or API key). |
|
|
124
|
+
| `/mcp` | Active MCP servers + Marketplace — HTTP & stdio, plus your own custom servers. |
|
|
125
|
+
| `/memories` | Persistent facts per workspace — search, edit, archive. |
|
|
126
|
+
| `/skills` | Assigned / Custom / Built-in Library — write your own, customise built-ins, or install any community `SKILL.md`. |
|
|
127
|
+
| `/learned-skills` | Skills the agents wrote themselves — review, assign, archive, restore. |
|
|
128
|
+
| `/approvals` | Human-in-the-loop gates for risky tools and the ROOT agent's meta-tools. |
|
|
129
|
+
| `/automations` | Cron-scheduled agent triggers. |
|
|
130
|
+
| `/settings` | Auth mode, network (loopback / LAN), bot tokens, workspaces, ROOT grants + autonomy. |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## For developers
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
git clone https://github.com/Kwintspiracy/nodal-agents.git
|
|
138
|
+
cd nodal-agents
|
|
139
|
+
pnpm install
|
|
140
|
+
pnpm --filter nodal-agents exec tsx src/index.ts --dev # hot-reloading dashboard
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Stack** — Node 22+, TypeScript strict (no `any`), pnpm + Turborepo, embedded-postgres + Drizzle ORM (idempotent migrations), Zod everywhere, Hono (runner) + Next.js (dashboard), the Vercel AI SDK for multi-provider LLM, Vitest + Playwright + dependency-cruiser.
|
|
144
|
+
|
|
145
|
+
**Monorepo**
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
apps/ cli · runner (Hono) · web (Next.js dashboard)
|
|
149
|
+
packages/ db · shared · llm · tools · memory · orchestration
|
|
150
|
+
adapters · runner-adapters · delivery · auth · catalog · secrets
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Architecture rules** (enforced by `dependency-cruiser`, run in CI before every release):
|
|
154
|
+
|
|
155
|
+
- `apps/*` may import `packages/*` — never the reverse.
|
|
156
|
+
- `apps/web` and `apps/runner` cannot import each other (DB or HTTP only).
|
|
157
|
+
- Only `packages/db` may import `postgres` / `drizzle-orm` / `pg`.
|
|
158
|
+
- No circular dependencies.
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
pnpm deps:check
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Status
|
|
167
|
+
|
|
168
|
+
Used daily by the maintainer; stable enough for personal production. **Pre-1.0** — breaking changes are still possible between minors. See the [changelog](CHANGELOG.md) for what shipped in each release.
|
|
169
|
+
|
|
170
|
+
**On the roadmap** (genuine, not vaporware):
|
|
171
|
+
|
|
172
|
+
- **MCP OAuth** → unlocks Linear, Notion remote, GitHub remote, Atlassian, Sentry, and the rest of the SaaS-as-MCP ecosystem.
|
|
173
|
+
- **Dry-run + test-workflow meta-tool** → preview what the ROOT would do before it runs.
|
|
174
|
+
- **Bundled pgvector** → semantic memory search out of the box (today: keyword fallback).
|
|
175
|
+
- **More channels** → Discord, Slack, and beyond Telegram.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Upgrade
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
nodal-agents update # stop, install @latest, restart — data preserved
|
|
183
|
+
nodal-agents update --no-restart
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
When a newer version is available, `nodal-agents up` prints a one-line notice.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## License
|
|
191
|
+
|
|
192
|
+
TBD.
|