Skip to content

Commit 060ef21

Browse files
committed
feat(atlas-dashboard): present n8n as the ai-agents layer
1 parent b21bfb1 commit 060ef21

7 files changed

Lines changed: 247 additions & 65 deletions

File tree

README.md

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
![CLI](https://img.shields.io/badge/CLI-Node.js%20%2B%20TypeScript-3C873A?logo=nodedotjs&logoColor=white)
88
![Dashboard](https://img.shields.io/badge/UI-Atlas%20Dashboard-0F172A?logo=antdesign&logoColor=white)
99
![Security](https://img.shields.io/badge/Ingress-HTTPS%20Only-0F766E)
10-
![Profiles](https://img.shields.io/badge/Layers-core%20%7C%20ai--llm%20%7C%20ai--image%20%7C%20workbench-7C3AED)
10+
![Profiles](https://img.shields.io/badge/Layers-core%20%7C%20ai--agents%20%7C%20ai--llm%20%7C%20ai--image%20%7C%20ai--video%20%7C%20workbench-7C3AED)
1111
![Persistence](https://img.shields.io/badge/Persistence-Docker%20Volumes-CA8A04)
1212

1313
> 🧭 **Atlas Lab** is a localhost-first self-hosted platform made of a Node.js/TypeScript CLI, a layered Docker Compose stack, and an operational React dashboard served by the gateway.
14-
> It is designed to provide Git hosting, automation, optional local AI LLM services, optional AI image generation, browser-based development workbenches, and structured image/volume backup workflows on a single machine.
14+
> It is designed to provide Git hosting, optional automation agents, optional local AI LLM services, optional AI image and video generation, browser-based development workbenches, and structured image/volume backup workflows on a single machine.
1515
1616
---
1717

@@ -21,9 +21,11 @@ Atlas Lab is built for a practical goal: run a repeatable local engineering plat
2121

2222
### What it gives you
2323

24-
- 🧱 An always-on **core layer** with Gitea, n8n, the gateway, and Atlas Dashboard
24+
- 🧱 An always-on **core layer** with Gitea, the gateway, and Atlas Dashboard
25+
- 🤖 An optional **AI agents layer** with n8n and external runners
2526
- 🧠 An optional **AI LLM layer** with Open WebUI and Ollama
2627
- 🖼️ An optional **AI image layer** with InvokeAI and a script-managed local model set
28+
- 🎬 An optional **AI video layer** with ComfyUI and managed local video models
2729
- 🛠️ An optional **workbench layer** with browser-based Node, Python, AI, and C++ environments plus shared PostgreSQL
2830
- 🔐 HTTPS-only ingress on `localhost`
2931
- 📦 A self-contained npm package that can run without a local repository checkout
@@ -63,13 +65,15 @@ Atlas Lab is built for a practical goal: run a repeatable local engineering plat
6365

6466
## 🏗️ Architecture
6567

66-
Atlas Lab is split into **four explicit layers**:
68+
Atlas Lab is split into **six explicit layers**:
6769

6870
| Layer | Status | Includes | Purpose |
6971
| --- | --- | --- | --- |
70-
| `core` | always on | gateway, Atlas Dashboard, Gitea, Gitea DB, n8n, n8n runners | baseline platform |
72+
| `core` | always on | gateway, Atlas Dashboard, Gitea, Gitea DB | baseline platform |
73+
| `ai-agents` | optional | n8n, n8n runners, AI agents gateway | workflow automation and agent orchestration |
7174
| `ai-llm` | optional | Open WebUI, Ollama, AI LLM gateway | local LLM workflows |
7275
| `ai-image` | optional | InvokeAI, AI image gateway, managed model staging | local image generation |
76+
| `ai-video` | optional | ComfyUI, AI video gateway, managed model staging | local video generation |
7377
| `workbench` | optional | Node Forge, Python Grid, AI Reactor, C++ Foundry, shared PostgreSQL, workbench gateway | browser-based development |
7478

7579
### Why the current topology
@@ -97,7 +101,7 @@ The CLI:
97101
- runs host preflight checks
98102
- reconciles runtime state
99103
- bootstraps Gitea
100-
- bootstraps n8n
104+
- bootstraps n8n only when the `ai-agents` layer is enabled
101105
- reconciles Ollama only when the AI LLM layer is enabled
102106
- cleans up legacy runtime artifacts
103107

@@ -112,10 +116,11 @@ The only host-level TCP service exposed directly is PostgreSQL from the workbenc
112116
| --- | --- | --- | --- |
113117
| Atlas Dashboard | `core` | `https://localhost:8443/` | operational dashboard |
114118
| Gitea | `core` | `https://localhost:8444/` | Git forge, issues, reviews |
115-
| n8n | `core` | `https://localhost:8445/` | workflow automation |
119+
| n8n | `ai-agents` | `https://localhost:8445/` | workflow automation |
116120
| Open WebUI | `ai-llm` | `https://localhost:8446/` | only with `--with-ai-llm` |
117121
| Ollama | `ai-llm` | `https://localhost:8447/` | HTTPS API |
118122
| InvokeAI | `ai-image` | `https://localhost:8448/` | only with `--with-ai-image` |
123+
| ComfyUI | `ai-video` | `https://localhost:8449/` | only with `--with-ai-video` |
119124
| Node Forge | `workbench` | `https://localhost:8450/` | Node / TypeScript workspace |
120125
| Python Grid | `workbench` | `https://localhost:8451/` | Python workspace |
121126
| AI Reactor | `workbench` | `https://localhost:8452/` | AI / notebook workspace |
@@ -135,9 +140,11 @@ The only host-level TCP service exposed directly is PostgreSQL from the workbenc
135140
| Network | Type | Purpose |
136141
| --- | --- | --- |
137142
| `edge-net` | exposed | published ingress ports |
138-
| `apps-net` | internal | core application services |
143+
| `apps-net` | internal | Gitea and shared browser-facing services |
144+
| `ai-agents-net` | internal | n8n and external runners |
139145
| `ai-llm-net` | internal | Open WebUI and Ollama |
140146
| `ai-image-net` | internal | InvokeAI and image-generation runtime |
147+
| `ai-video-net` | internal | ComfyUI and video-generation runtime |
141148
| `data-net` | internal | data services and infrastructure databases |
142149
| `workbench-net` | internal | workbenches and PostgreSQL |
143150
| `workbench-host-net` | bridge | host-side PostgreSQL bind |
@@ -206,6 +213,7 @@ The AI LLM and AI image layers require:
206213
- `8446`
207214
- `8447`
208215
- `8448`
216+
- `8449`
209217
- `8450`
210218
- `8451`
211219
- `8452`
@@ -246,12 +254,12 @@ Key variables include:
246254
- `APP_VERSION`
247255
- `LAB_HTTPS_PORT`, `GITEA_HTTPS_PORT`, `N8N_HTTPS_PORT`
248256
- `OPENWEBUI_HTTPS_PORT`, `OLLAMA_HTTPS_PORT`
249-
- `INVOKEAI_HTTPS_PORT`
257+
- `INVOKEAI_HTTPS_PORT`, `COMFYUI_HTTPS_PORT`
250258
- `NODE_DEV_HTTPS_PORT`, `PYTHON_DEV_HTTPS_PORT`, `AI_DEV_HTTPS_PORT`, `CPP_DEV_HTTPS_PORT`
251259
- `POSTGRES_DEV_HOST_PORT`
252260
- `OLLAMA_CHAT_MODEL`, `OLLAMA_EMBEDDING_MODEL`, `OLLAMA_RUNTIME_MODELS`
253261
- `INVOKEAI_MODEL_REPO`, `INVOKEAI_MODEL_REVISION`, `INVOKEAI_MODEL_TITLE`
254-
- `config/models/invokeai-models.json`
262+
- `config/models/invokeai-models.json`, `config/models/comfyui-models.json`
255263
- `GITEA_ROOT_USERNAME`, `GITEA_ROOT_PASSWORD`
256264
- `N8N_ROOT_EMAIL`, `N8N_ROOT_PASSWORD`
257265
- `OPENWEBUI_ROOT_EMAIL`, `OPENWEBUI_ROOT_PASSWORD`
@@ -432,19 +440,19 @@ Atlas Lab supports backup and restore for both **Docker images** and **Docker vo
432440
- one `.tar.gz` archive for selected volumes
433441
- embedded manifest metadata
434442
- realtime progress logs during export and restore
435-
- support for `core`, `ai-llm`, `ai-image`, and `workbench` layer selection
443+
- support for `core`, `ai-agents`, `ai-llm`, `ai-image`, `ai-video`, and `workbench` layer selection
436444

437445
### Examples
438446

439447
```powershell
440-
npm run dev -- save-images --with-ai-llm --with-ai-image --with-workbench
448+
npm run dev -- save-images --with-ai-agents --with-ai-llm --with-ai-image --with-ai-video --with-workbench
441449
npm run dev -- restore-images --input .\backups\images\atlas-lab-images.tar.gz
442450
npm run dev -- down
443-
npm run dev -- save-volumes --with-ai-llm --with-ai-image --with-workbench
451+
npm run dev -- save-volumes --with-ai-agents --with-ai-llm --with-ai-image --with-ai-video --with-workbench
444452
npm run dev -- restore-volumes --input .\backups\volumes\atlas-lab-volumes.tar.gz
445453
```
446454

447-
Bootstrap is idempotent and reconciles Gitea, n8n, and optionally Ollama.
455+
Bootstrap is idempotent and reconciles Gitea, n8n when `ai-agents` is enabled, and Ollama when `ai-llm` is enabled.
448456

449457
---
450458

@@ -460,6 +468,7 @@ Bootstrap is idempotent and reconciles Gitea, n8n, and optionally Ollama.
460468
| Open WebUI | `https://localhost:8446/` | `root@openwebui.local / RootOpenWebUI!2026` |
461469
| Ollama | `https://localhost:8447/` | gateway basic auth `root / RootOllama!2026` |
462470
| InvokeAI | `https://localhost:8448/` | gateway basic auth `root / RootInvokeAI!2026` |
471+
| ComfyUI | `https://localhost:8449/` | gateway basic auth `root / RootComfyUI!2026` |
463472
| PostgreSQL host-side | `localhost:15432` | `postgres / RootPostgresDev!2026` |
464473

465474
For DBeaver and other desktop PostgreSQL clients:

apps/atlas-dashboard/src/App.tsx

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ const toneStyles: Record<
7979
DashboardTone,
8080
{ accent: string; border: string; soft: string }
8181
> = {
82+
agents: {
83+
accent: atlasDashboardPalette.signal,
84+
border: 'rgba(77, 163, 255, 0.28)',
85+
soft: 'rgba(77, 163, 255, 0.14)'
86+
},
8287
ai: {
8388
accent: atlasDashboardPalette.ai,
8489
border: 'rgba(214, 138, 72, 0.28)',
@@ -202,6 +207,7 @@ export default function App() {
202207
</Col>
203208
<Col xs={24} xl={8} style={{ display: 'flex' }}>
204209
<LayerRail
210+
agentsLayer={dashboard.agentsLayer}
205211
aiLayer={dashboard.aiLayer}
206212
imageLayer={dashboard.imageLayer}
207213
videoLayer={dashboard.videoLayer}
@@ -255,6 +261,30 @@ export default function App() {
255261
))}
256262
</Row>
257263

264+
<SectionBand
265+
body={t(
266+
dashboard.agentsLayer.enabled
267+
? 'sections.agentsBodyEnabled'
268+
: 'sections.agentsBodyDisabled'
269+
)}
270+
kicker={t('sections.agentsKicker')}
271+
title={t('sections.agentsTitle')}
272+
/>
273+
<LayerStateCard layer={dashboard.agentsLayer} />
274+
{dashboard.agentsLayer.enabled ? (
275+
<Row gutter={[24, 24]}>
276+
{dashboard.agentServices.map((service) => (
277+
<Col xs={24} xl={12} key={service.id}>
278+
<OperationalCard
279+
item={service}
280+
primaryAction={service.action}
281+
tone={service.tone}
282+
/>
283+
</Col>
284+
))}
285+
</Row>
286+
) : null}
287+
258288
<SectionBand
259289
body={t(
260290
dashboard.imageLayer.enabled
@@ -687,11 +717,13 @@ function StatsRail({
687717
}
688718

689719
function LayerRail({
720+
agentsLayer,
690721
aiLayer,
691722
imageLayer,
692723
videoLayer,
693724
workbenchLayer
694725
}: {
726+
agentsLayer: { enabled: boolean; summary: string; tone: DashboardTone };
695727
aiLayer: { enabled: boolean; summary: string; tone: DashboardTone };
696728
imageLayer: { enabled: boolean; summary: string; tone: DashboardTone };
697729
videoLayer: { enabled: boolean; summary: string; tone: DashboardTone };
@@ -710,6 +742,12 @@ function LayerRail({
710742
title={t('cards.tones.core')}
711743
tone="core"
712744
/>
745+
<LayerSummaryTile
746+
enabled={agentsLayer.enabled}
747+
summary={agentsLayer.summary}
748+
title={t('cards.tones.agents')}
749+
tone={agentsLayer.tone}
750+
/>
713751
<LayerSummaryTile
714752
enabled={aiLayer.enabled}
715753
summary={aiLayer.summary}
@@ -839,7 +877,9 @@ function LayerSummaryTile({
839877
const { t } = useTranslation();
840878
const palette = toneStyles[tone];
841879
const IconGlyph =
842-
tone === 'ai'
880+
tone === 'agents'
881+
? BranchesOutlined
882+
: tone === 'ai'
843883
? ApiOutlined
844884
: tone === 'video'
845885
? VideoCameraOutlined
@@ -1008,7 +1048,9 @@ function LayerStateCard({
10081048
const { t } = useTranslation();
10091049
const palette = toneStyles[layer.tone];
10101050
const IconGlyph =
1011-
layer.tone === 'ai'
1051+
layer.tone === 'agents'
1052+
? BranchesOutlined
1053+
: layer.tone === 'ai'
10121054
? ApiOutlined
10131055
: layer.tone === 'video'
10141056
? VideoCameraOutlined
@@ -1383,6 +1425,8 @@ function SignalPill({
13831425
const capsuleBg =
13841426
tone === 'core'
13851427
? 'rgba(31, 159, 141, 0.18)'
1428+
: tone === 'agents'
1429+
? 'rgba(77, 163, 255, 0.18)'
13861430
: tone === 'ai'
13871431
? 'rgba(214, 138, 72, 0.18)'
13881432
: tone === 'image'

apps/atlas-dashboard/src/locales/en.json

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
"aiBodyEnabled": "The AI LLM layer is online: the dashboard takes you into Open WebUI or the Ollama APIs with credentials and operating context always visible.",
3939
"aiKicker": "optional plane",
4040
"aiTitle": "AI LLM Layer",
41+
"agentsBodyDisabled": "The AI agents layer stays off until you explicitly request it. When inactive, the dashboard shows the exact activation command.",
42+
"agentsBodyEnabled": "The AI agents layer is online: n8n is exposed on its dedicated gateway and the owner bootstrap stays aligned by the CLI.",
43+
"agentsKicker": "automation plane",
44+
"agentsTitle": "AI Agents Layer",
4145
"footerBody": "Four quick signals on routing, persistence, recommended usage, and layer segmentation.",
4246
"footerKicker": "atlas signals",
4347
"footerTitle": "Operational closeout",
@@ -70,6 +74,7 @@
7074
"cards": {
7175
"openBriefing": "Open briefing",
7276
"tones": {
77+
"agents": "AI Agents",
7378
"ai": "AI LLM",
7479
"core": "Core",
7580
"image": "AI Image",
@@ -139,20 +144,40 @@
139144
"alwaysOnForge": "always-on forge"
140145
},
141146
"dashboard": {
142-
"coreLayerSummary": "Gitea and n8n remain the always-on plane of the lab.",
147+
"coreLayerSummary": "Gitea remains the always-on core plane of the lab.",
143148
"accessNotes": {
149+
"agentsDisabled": "The AI agents layer remains optional and n8n stays off until you enable the dedicated automation plane.",
150+
"agentsEnabled": "n8n is online in the AI agents layer with the bootstrapped owner account already aligned.",
144151
"aiDisabled": "The AI LLM layer no longer starts by default: the deck marks it as optional instead of pretending that it is online.",
145152
"aiEnabled": "Open WebUI and Ollama are really online and reachable on the AI LLM gateway ports.",
146153
"credentials": "Operational credentials are exposed here and remain aligned with the lab bootstrap.",
147154
"https": "All browser ingresses use localhost with dedicated HTTPS, without custom DNS or hosts-file edits.",
148155
"imageDisabled": "The AI image layer remains optional and no dedicated image endpoint is exposed until you enable it.",
149156
"imageEnabled": "InvokeAI is online behind the dedicated AI image gateway, and the configured model set is already staged for the runtime.",
150-
"n8n": "n8n logs in directly with the bootstrapped owner account: there is no second gateway login.",
151157
"videoDisabled": "The AI video layer remains optional and no dedicated video endpoint is exposed until you enable it.",
152158
"videoEnabled": "ComfyUI is online behind the dedicated AI video gateway with the requested local video models already staged.",
153159
"workbenchDisabled": "Workbench and Postgres stay separated from the core operating plane until you enable the dedicated layer.",
154160
"workbenchEnabled": "Workbench and Postgres are active: you can open browser-based environments or connect from the desktop to the host Postgres port."
155161
},
162+
"agentsLayer": {
163+
"capabilities": {
164+
"n8n": "Local n8n",
165+
"runners": "External runners",
166+
"webhooks": "Webhook automation"
167+
},
168+
"description": "Optional AI agents layer for workflow automation, integrations, and operational agent pipelines. The lab enables it only when you explicitly request it.",
169+
"summaryDisabled": "AI agents layer is off. n8n and the external runners are not started or exposed until you enable the dedicated flag.",
170+
"summaryEnabled": "n8n and the external runners are active behind the AI agents gateway.",
171+
"title": "AI Agents Layer"
172+
},
173+
"agentServices": {
174+
"n8n": {
175+
"action": "Open n8n",
176+
"description": "Orchestration engine for webhooks, integrations, and agent automation flows, already bootstrapped with an application owner account.",
177+
"note": "The first access skips the setup wizard but still exposes the official templates available inside the application.",
178+
"title": "n8n Automation"
179+
}
180+
},
156181
"aiLayer": {
157182
"capabilities": {
158183
"llmModels": "GPU-backed LLM models",
@@ -228,7 +253,7 @@
228253
"label": "segmentation"
229254
},
230255
"usage": {
231-
"body": "Gitea and n8n are the always-on core plane; the AI LLM, AI image, AI video, and workbench layers are enabled only when they are actually needed.",
256+
"body": "Gitea is the always-on core plane; AI agents, AI LLM, AI image, AI video, and workbench layers are enabled only when they are actually needed.",
232257
"label": "usage"
233258
}
234259
},
@@ -237,6 +262,8 @@
237262
"pills": {
238263
"aiActive": "ai-llm active",
239264
"aiOptional": "ai-llm optional",
265+
"agentsActive": "ai-agents active",
266+
"agentsOptional": "ai-agents optional",
240267
"deck": "deck {{localUrl}}",
241268
"host": "host {{publicUrl}}",
242269
"httpsOnly": "https ingress only",
@@ -254,13 +281,21 @@
254281
"networkMapDescription": "Read the lab topology and the published network planes.",
255282
"networkMapLabel": "Network map"
256283
},
257-
"summary": "Unified control room for repository work, automation, optional AI LLM services, AI image generation, AI video generation, and development environments. Browser ports stay on HTTPS over localhost, while Postgres from the workbench layer also exposes a host-side TCP port.",
284+
"summary": "Unified control room for repository work, optional AI agents automation, optional AI LLM services, AI image generation, AI video generation, and development environments. Browser ports stay on HTTPS over localhost, while Postgres from the workbench layer also exposes a host-side TCP port.",
258285
"titleLines": {
259286
"first": "LAB",
260287
"second": "ATLAS"
261288
}
262289
},
263290
"metrics": {
291+
"agentsDisabled": {
292+
"caption": "AI agents layer not active",
293+
"label": "ai-agents live"
294+
},
295+
"agentsEnabled": {
296+
"caption": "n8n published on the dedicated AI agents gateway",
297+
"label": "ai-agents live"
298+
},
264299
"aiDisabled": {
265300
"caption": "AI LLM layer not active",
266301
"label": "ai-llm live"
@@ -306,10 +341,10 @@
306341
"title": "Network Map"
307342
},
308343
"operatingCharter": {
344+
"agents": "n8n and the runner fleet live in an explicitly optional AI agents layer.",
309345
"ai": "Open WebUI and Ollama live in an explicitly optional AI LLM layer.",
310346
"gitea": "Gitea governs code, review, and Git governance for the project.",
311347
"image": "InvokeAI lives in a dedicated AI image layer with a script-managed model set.",
312-
"n8n": "n8n coordinates automations, webhooks, and operational jobs in the lab.",
313348
"video": "ComfyUI lives in a dedicated AI video layer with preloaded LTX-Video and Wan 2.1 assets.",
314349
"workbench": "Code-server and Postgres stay in a workbench plane separated from the core."
315350
},

0 commit comments

Comments
 (0)