catagories and bug fixes, few new tools.

This commit is contained in:
Jeremy Anderson 2026-08-29 07:49:58 -04:00
parent ece3b643df
commit f5aa97a475
41 changed files with 2484 additions and 605 deletions

View File

@ -1,5 +1,353 @@
# AI-LSC Changelog # AI-LSC Changelog
## v3.1.1b — taxonomy re-org: Routing restored (11 layers), canonical 24-dir /mnt/AI layout
Restores the Routing layer that was lost when the 13-layer model was
compressed to 10 (both "L6 AI Endpoints" and "L11 Intelligent Routing"
had been folded into Orchestrators), fixes the mis-categorized tools,
and aligns the backend to the revised canonical `/mnt/AI/` directory
tree. No tool count change (185 tools); validator still reports 0 errors.
### New layer ladder (10 → 11)
```
L1 Host Platform L7 Security
L2 Development Env L8 Observability
L3 GPU Runtimes L9 User Interfaces
L4 Engines L10 DevOps
L5 Routing (restored) L11 Knowledge Management
L6 Orchestrators
```
`NAV_LAYER_ORDER` inserts Routing between Engines and Orchestrators —
engines serve weights, routing proxies/load-balances/meshes them into
one OpenAI-compat endpoint, orchestrators build agent workflows on top.
### Tool moves (18 tools, all layers/levels updated)
| tool_id | Old | New |
|---------|-----|-----|
| `litellm` | L5 Orchestrators (Proxy / API Gateway) | **L5 Routing** |
| `9router_proxy` | L5 Orchestrators (LLM Router) | **L5 Routing** |
| `meshllm` | L5 Orchestrators (LLM Mesh) | **L5 Routing** |
| `dify` | L5 Orchestrators (Pipeline) | **L5 Routing** |
| `picode` | L5 Orchestrators (AI Coding Agent) | **L5 Routing** (category → `Mesh Client`) |
| `vllm` | L5 Orchestrators (Scaling) | **L4 Engines** (role → Engine; ADR-001 always listed vLLM under Inference Engines) |
| `sglang` | L5 Orchestrators (Scaling) | **L4 Engines** (role → Engine) |
| `eagle_eye` | L5 Orchestrators (category literally "Observability") | **L8 Observability** |
| `dma` | L5 Orchestrators (Build Monitoring) | **L8 Observability** |
| `aider`, `claude_code`, `codex`, `openhands`, `opencode`, `gemini_cli`, `qwen_code`, `goose`, `zcoder` | L5 Orchestrators (AI Coding Agent) | **L10 DevOps** — matches the DB editor's `AI Coding Agent → DevOps` mapping, which previously conflicted with the registry |
Remaining tools in the affected layers were renumbered (+1): 38 stay in
Orchestrators (L6), Security L7, Observability L8, User Interfaces L9,
DevOps L10, Knowledge Management L11. Per-layer level uniformity
verified. `picode`'s category changed `AI Coding Agent` → `Mesh Client`
so the category cascade cannot silently flip it back to DevOps.
### Tool DB editor (`CATEGORY_MAP`)
- All entries renumbered to the new ladder; map is now fully consistent
with the live registry (0 layer/level mismatches).
- 13 new categories so every registry category auto-fills correctly:
`LLM Mesh`, `Mesh Client` (Routing); `Observability` (Observability);
`Build`, `Debugging`, `Shell`, `Claude Code Skill`, `Container Ops`,
`Infrastructure`, `Memory System`, `Model Surgery`, `Networking`,
`Virtualization` (previously missing entirely).
- Fixed conflicts: `AI Coding Agent` → DevOps/L10 (role `Coding Agent`,
was `Autonomous Coder` at L9), `Build Monitoring` → Observability/L8,
`LLM Serving` → Engines/L4, `LLM Router` / `Proxy` / `Pipeline` →
Routing/L5.
### STACK_WIRINGS (`stack/connections.py`)
- 29 wiring `layer=` labels synced to the registry: the 13 moved tools
with wirings, plus `deep_eye`/`luxtts` (UI tools mislabeled
Orchestrators) and 14 pre-existing drifts (`heretic`, `unsloth`,
`parakeet`, `fabric`, `n8n`, `nightshift`, `hivemind`, `hermes_agent`,
`agno`, `hermes_dashboard_page`, `mnemo_cortex`, `everos_memory`,
`langflow`, `opensandbox`). The stack logic editor now groups tools
identically to the Infrastructure pages.
- Stale section comments annotated: `L6: AI Endpoints` → the restored
Routing layer; `L10: Intelligent Routing` → folded into Orchestrators.
### Canonical `/mnt/AI/` layout (26 → 24 dirs)
`REQUIRED_DIRS` now matches the target tree exactly:
- **Added `configs/`** — app configs templated for native runtime plus
app state. `main_window.config_root` moves from legacy `config/` to
`configs/`, taking `pipeline_state.json`, `pipeline.json`,
`license_approvals.json` with it; `controller_config.json` moves off
the `/mnt/AI/` root into `configs/`. A one-time
`_migrate_legacy_state_files()` pass moves old files on startup
(newer copies win; emptied legacy dirs are removed).
- **Dropped from the skeleton**: `bootstraps/ai-lsc`, `staging`,
`registry/manifests`. `registry/` remains as app-internal storage for
`ecosystem.json` and manifests — auto-created on demand by
`RegistryManager`, no longer part of the canonical tree.
- `paths.py`: `configs_root` added; `staging_root` / `bootstraps_root`
removed; the deprecated `config_root → runtime` alias now points at
`configs/`. Per-tool config subdirs (`configs/<tool>/`) are still
created on demand by `InstallerManager`.
- `license_gate.py` / `licenses.py` doc references updated to
`configs/license_approvals.json`.
Existing installs pick up all taxonomy changes automatically:
`RegistryManager._sync_with_upstream()` re-syncs structural fields
(layer, level, role, category) from the layer files on every start.
## v3.1.1a — registry validator fixes (5 errors → 0)
Fixes all 5 `validate_registry()` errors plus latent bugs surfaced
during the fix pass. No tool count change (185 tools).
### Installer fixes (validator errors)
All five failed the "script installer cmd should reference
{tools_root}" check — they installed into system dirs or the cwd:
| tool_id | Before | After |
|---------|--------|-------|
| `firecracker` | extracted into `/usr/local/bin/` (and silently broken: versioned tarball dirs never landed on PATH) | extracts into `{tools_root}/firecracker/`, symlinks `firecracker` + `jailer` into `{tools_root}/bin/` |
| `cloudflared` | downloaded to `/usr/local/bin/cloudflared` | downloads to `{tools_root}/bin/cloudflared` |
| `llamafile` | downloaded to cwd (mismatched launcher, which already expected `{tools_root}/bin/llamafile`) | downloads to `{tools_root}/bin/llamafile` |
| `meilisearch` | `curl \| sh` dropped binary in cwd | runs installer inside `{tools_root}/bin/` (official installer places the binary in the cwd) |
| `grafana_alloy` | `install.sh \| sh` — **URL dead (404): upstream dropped the script** | direct release asset `alloy-linux-amd64.zip`, extracted via `python3 -m zipfile` (no unzip dependency) |
### Launcher fixes (latent bugs)
- `firecracker`, `cloudflared`, `grafana_alloy` launchers now use
absolute `{tools_root}/bin/<name>` paths. Rationale: `tools_root/bin`
is on PATH at install time (`installer._env()`) but **not** at launch
time (`enriched_env()` builds PATH from `base_bin_dir` = uv/npm bins
only), so bare-name launcher cmds would pass preflight then fail
with "command not found". Absolute paths are immune to the gap.
- firecracker version discovery uses the Location header
(`curl -sIL … | grep -i '^location:'`) instead of
`-w '%{url_effective}'` — launcher/installer cmds are rendered with
`str.format()`, and the `{url_effective}` braces would raise
`KeyError` at render time.
### Dependency fixes (phantom missing-dep warnings)
- `dify` deps: `node` → `nodejs` (the actual registry tool_id).
- `RegistryManager.check_dependencies()` now allows system-level deps
(`kubectl`, `java`) via a `SYSTEM_DEPS` frozenset, mirroring the
existing `_system_deps` pattern in `stack/connections.py`. Previously
`crossplane` (kubectl) and `keycloak` (java) produced permanent
"missing dependency" warnings that could never be satisfied.
### Not fixed (observations, no behavior change)
- 9 duplicate `default_port` defaults across tools (e.g. 3000 shared
by grafana/opik/openhands/flowise). These are overridable per
service row; leaving as-is unless the stack compiler should
auto-assign.
- `TODO.md`'s `open_webui`/`openwebui` split no longer reproduces:
only `openwebui` exists in both the registry and `STACK_WIRINGS`.
## v3.1.1 — local-coder-mesh integration (this build)
Adds 4 new tools, corrects 1 existing tool, adds 4 new `STACK_WIRINGS`
entries (and rewires 1), adds 1 new stack template, and aligns all
hardcoded `/mnt/AI/` paths to the canonical 26-directory layout. No
containers in the dev path — every tool installs natively. ai-lsc's
Podman/Docker/LXC/Firecracker export is reserved for total-stack
deployment exports only, as before.
### New tools (181 → 185)
| tool_id | Layer | What | Install |
|---------|-------|------|---------|
| `picode` | L5 Orchestrators | PiCode (jasonjmcghee/picode) — local code-tinker agent | git clone |
| `meshllm` | L5 Orchestrators | MeshLLM (Mesh-LLM/mesh-llm) — native binary, pools GPUs/memory across machines, exposes OpenAI-compat API at :9337, web console at :3131. NOT a LiteLLM derivative. | script (official curl installer) |
| `zcoder` | L5 Orchestrators | Zhipu AI Z-Coder CLI coding agent | npm `zcoder-cli` |
| `hermes_webui` | L8 User Interfaces | Hermes-themed Open-WebUI instance on :8081 with its own data volume; backend points at `hermes_agent` (:17051) instead of Ollama direct | uv `open-webui` |
### Corrected tool
`graphify` was already in the registry but had wrong metadata. Fixed in place:
| Field | Old | New |
|-------|-----|-----|
| `role` | `Graph Builder` | `Knowledge Graph Builder` |
| `category` | `AI Agent` | `Claude Code Skill` |
| `installer` | `git: nicely-done/graphify` | `uv: graphifyy` (PyPI; CLI is `graphify`) |
| `license` | `Proprietary` | `MIT` (verified from pyproject.toml) |
| `flags.has_web` | `False` | `True` (graph.html output) |
| `flags.is_mcp` | `False` | `True` (`graphify --mcp` stdio server) |
| `description` | 1 line generic | 10 lines accurate (CLI + Claude Code skill + MCP server + LLM backend options) |
Graphify's wiring also changed — see below.
### New `STACK_WIRINGS` entries (133 → 137)
| tool_id | Exposes | Consumes |
|---------|---------|----------|
| `picode` | (none — CLI agent) | `meshllm` (primary), `litellm` (fallback), `ollama` (direct fallback) |
| `meshllm` | `openai_api` (:9337) + `mesh_web_console` (:3131) | `ollama` (optional, for `mesh-llm client --auto` mode) |
| `zcoder` | (none — CLI agent) | `meshllm` (primary), `litellm` (fallback), `ollama` (direct fallback) |
| `hermes_webui` | `hermes_webui_http` (:8081) | `hermes_agent` (required, primary backend), `ollama` (optional, for RAG embeddings) |
### Rewired entry
`graphify` removed from the L8 passive/CLI list and given a proper
`_reg(StackWiring(...))` block:
- **Exposes**: `graphify_mcp` (stdio MCP server, no port) — start with
`graphify --mcp`. Other MCP-aware agents can query the knowledge graph.
- **Consumes** (all optional, fallback chain for the extraction LLM):
`meshllm` (:9337/v1), `litellm` (:4000/v1), `ollama` (:11434/v1).
Graphify defaults to Claude (Anthropic API) but can be configured for
fully-local extraction by setting `OPENAI_API_BASE` to any of the
above.
### New stack template (13 → 14)
`local-coder-mesh.json` — "Local Coder Mesh — All-Ollama Coding Stack".
17 tools: ollama, litellm, meshllm, picode, aider, odysseus, opencode,
zcoder, graphify, hermes, hermes_agent, hermes_webui, hermes_desktop,
openwebui, ripgrep, fd, tree_sitter.
Topology: coding agents prefer MeshLLM (:9337) for mesh-pooled inference,
fall back to LiteLLM (:4000) for proxy routing, then Ollama direct
(:11434). Graphify builds knowledge graphs from the codebase and exposes
an MCP server that the coding agents query. Hermes WebUI talks to
hermes_agent (NOT Ollama direct) so every Hermes conversation flows
through the agent runtime's tool-use layer. OpenWebUI talks to Ollama
direct. ripgrep + fd + tree_sitter are passive filesystem tools used by
the coding agents for repo-map / symbol navigation.
Recommended models: `qwen2.5-coder:7b` (fast coding),
`qwen2.5-coder:32b` (heavy coding), `hermes3:8b` (Hermes stack),
`nomic-embed-text` (openwebui RAG, corpus indexing, graphify embeddings).
MeshLLM auto-downloads a suitable model on first `serve --auto` if none
is specified.
### Path alignment to canonical `/mnt/AI/` layout
Three files updated so ai-lsc's hardcoded paths match the 26-directory
canonical layout:
- **`src/ai_lsc/constants.py`** — `REQUIRED_DIRS` replaced with the 26
canonical entries (`bootstraps/ai-lsc`, `staging`, `backends`,
`distfiles`, `runtime`, `models/hot`, `models/cold`, `corpus/hot`,
`corpus/cold`, `datasets/wordlists`, `datasets/huggingface`,
`datasets/github`, `pipelines`, `registry/manifests`, `agents`,
`skills`, `projects/active`, `projects/labs`, `projects/vault`,
`blueprints`, `workspaces`, `dashboards`, `tools`, `exports/oci-images`,
`scripts`, `logs`). Old layout dirs (`config`, `cache`, `data`,
`containers`, `bin`, `tmp`, `backups`, `models/ollama`, `models/chroma`,
`datasets/raw`, `workspaces/hermes`, `workspaces/openwebui`,
`workspaces/n8n`) are NOT removed — they just become orphans. Clean
them up manually if desired.
- **`src/ai_lsc/utils/paths.py`** — `build_path_tree()` expanded from 10
keys to 24 keys. Old keys kept and repointed at canonical subdirs.
New keys added: `runtime_root`, `models_hot`, `models_cold`,
`corpus_root`, `pipelines_root`, `agents_root`, `projects_root`,
`blueprints_root`, `dashboards_root`, `scripts_root`, `backends_root`,
`distfiles_root`, `staging_root`, `bootstraps_root`. The `config_root`
key is kept as a deprecated alias pointing at `/mnt/AI/runtime/` so
existing callers don't break — new code should use
`tools_root / <tool_id> / "config"` or `runtime_root / <tool>` explicitly.
- **`src/ai_lsc/agents/litellm_config.py`** and
**`src/ai_lsc/agents/librechat_config.py`** — hardcoded save paths
moved from `/mnt/AI/config/litellm_config.yaml` and
`/mnt/AI/tools/librechat/librechat.yaml` to
`/mnt/AI/runtime/litellm/config.yaml` and
`/mnt/AI/runtime/librechat/config.yaml` respectively. Per-tool configs
for long-running services belong under `runtime/<tool>/` next to their
venv / cloned repo, since the spec has no top-level `/mnt/AI/config/`.
### Backfill script path fixes
Three helper scripts in `scripts/` had stale hardcoded absolute paths to
`/home/z/my-project/workspace/ai-lsc` (a developer machine path that
leaked into the v3.1 release). Replaced with
`Path(__file__).resolve().parent.parent` so they resolve to the project
root regardless of where the tarball is extracted:
- `scripts/backfill_default_licenses.py`
- `scripts/backfill_layer_flags.py`
- `scripts/backfill_tool_licenses.py`
### Verification (run against this build)
```
Registry: 185 tools (was 181)
Wirings: 137 entries (was 133)
Wiring validation errors: 0
Registry validation errors: 5 (all pre-existing in upstream v3.1 —
firecracker, cloudflared, llamafile, meilisearch, grafana_alloy —
none introduced by this build)
meshllm installer: uses {tools_root}/meshllm/bin (passes validator)
Templates: 14 (was 13) — local-coder-mesh added
Template tool resolution: 17/17 tools resolve in registry
build_path_tree() keys: 24 (was 10)
REQUIRED_DIRS entries: 26 (was 22)
graphify installer: uv:graphifyy (was git:nicely-done/graphify)
graphify license: MIT (was Proprietary)
graphify is_mcp flag: True (was False)
meshllm interfaces: ['openai_api' on :9337, 'mesh_web_console' on :3131]
graphify interfaces: ['graphify_mcp' stdio]
```
### Native-only install policy
Every tool in the new `local-coder-mesh` template installs natively into
`/mnt/AI/runtime/<tool_id>/` (venv via uv/pipx) or via pacman/AUR/curl-script.
ai-lsc's container export feature (Podman / Docker / LXC / Firecracker)
is intentionally NOT used at install time — it's reserved for total-stack
deployment exports via the Stack Editor, exactly as in v3.1.
### Rollback
To revert this entire build to upstream v3.1, restore from git or
re-extract the original tarball. There is no separate "patch pack" to
unapply — this is the integrated project.
---
## v3.1 — registry expansion: 2026-era coding agents, serving, and runtimes
Adds 11 tools to the layer registry (170 → 181) and 10 `STACK_WIRINGS` entries (123 → 133), and backfills 6 missing OSI licenses into the catalog. All facts (npm/PyPI package names, default ports, licenses) were verified against current upstream docs.
### New tools
| tool_id | Layer | What | Install |
|---------|-------|------|---------|
| `deno` | L2 Development | JavaScript/TypeScript/WASM runtime; runs many MCP servers via `deno run` | pacman `deno` |
| `uv` | L2 Development | Astral's Python package/project manager (AI-LSC's own install backend) | pacman `uv` |
| `tinygrad` | L3 GPU Runtimes | Minimalist autograd tensor library (CUDA/AMD/CPU backends) | uv `tinygrad` |
| `opencode` | L5 Orchestrators | SST's open-source terminal AI coding agent (TUI, LSP, 75+ providers) | npm `opencode-ai` |
| `gemini_cli` | L5 Orchestrators | Google's open-source terminal AI agent | npm `@google/gemini-cli` |
| `qwen_code` | L5 Orchestrators | Qwen's agentic terminal coding tool (Gemini CLI fork) | npm `@qwen-code/qwen-code` |
| `goose` | L5 Orchestrators | Block's extensible AI agent with MCP extensions | manual (opens releases page) |
| `letta` | L5 Orchestrators | Stateful agent framework (MemGPT) with persistent memory; `letta server` on :8283 | uv `letta` |
| `sglang` | L5 Orchestrators | Fast LLM serving with RadixAttention; OpenAI-compat API on :30000 | uv `sglang` |
| `jan` | L8 User Interfaces | Offline ChatGPT-alternative desktop app; OpenAI-compat local API on :1337 | npm `@janhq/jan` |
| `mem0` | L10 Knowledge Mgmt | Memory layer for AI apps/agents; pluggable vector backends | uv `mem0ai` |
`goose` uses installer type `custom` deliberately: its official install path is a `curl | sh` one-liner, which conflicts with the v3.1 no-remote-code-execution policy. The `custom` installer opens the GitHub releases page for a manual, download-first install instead. `deno` and `uv` are intentionally left unwired (language runtimes, consistent with `nodejs`/`python`).
### Wiring topology (Pipeline Ticker)
- **Terminal coding agents wired**: `opencode`, `gemini_cli`, `qwen_code`, `goose`, and the pre-existing `codex` each gained connections to Ollama (direct) and LiteLLM (proxied) — staging either backend now prevents orphan-flagging. `codex` had been an orphan since v3.1 because it had no `STACK_WIRINGS` entry.
- **`sglang`** mirrors the vLLM wiring: exposes `openai_api` on :30000, consumes `cuda_driver`.
- **`letta`** exposes its REST API on :8283 and optionally consumes PostgreSQL (`LETTA_PG_URI`) + Ollama.
- **`jan`** exposes `openai_api` on :1337 (bundled llama.cpp engine).
- **`mem0`** optionally consumes Ollama (LLM + embeddings) and Qdrant (vector storage).
- **`tinygrad`** optionally consumes `cuda_driver` (it also runs on CPU/AMD).
- `validate_wiring()` reports 0 errors across all 133 wirings.
### License catalog backfill (fixes 8 pre-existing validator errors)
The following SPDX IDs were referenced by layer files but missing from `registry/licenses.py`, producing `license is not in the license catalog` validation errors: `LGPL-2.1` (strace, lxc, libvirt), `GPL-1.0` (perl), `PHP-3.01` (php), `Ruby` (ruby), `MirOS` (mksh), `MIT/Apache-2.0` (rust). All six are OSI-approved and are now catalog entries (auto-approvable). The merged registry validates with **0 errors** — the only remaining messages are the 5 documented `script installer cmd should reference {{tools_root}}` warnings tied to the curl|sh policy decision (llamafile, meilisearch, grafana_alloy + the newer firecracker, cloudflared).
### Docs
README tool counts and the layer table were refreshed to the real merged-registry numbers (they had been stale since the DevOps→Orchestrators reorg moved the coding agents).
## v3.1 — 2026-07-07 ## v3.1 — 2026-07-07
Codename: **Ankh of Jah** (continuation) Codename: **Ankh of Jah** (continuation)

View File

@ -5,7 +5,9 @@
<h1 align="center">AI - Local Stack Control</h1> <h1 align="center">AI - Local Stack Control</h1>
<p align="center"> <p align="center">
<strong>v3.1 — Codename: Ankh of Jah</strong><br> <strong>v3.1.1 — Codename: Ankh of Jah (local-coder-mesh build)</strong><br>
<p align="center"><em>This build includes the local-coder-mesh integration — see <a href="CHANGES.md">CHANGES.md</a> for the full list of changes vs upstream v3.1.</em></p>
<a href="http://dcos.net">http://dcos.net</a> <a href="http://dcos.net">http://dcos.net</a>
</p> </p>
@ -13,7 +15,7 @@
A PySide6 desktop application for orchestrating local AI/ML tool stacks across a 10-layer architecture. A PySide6 desktop application for orchestrating local AI/ML tool stacks across a 10-layer architecture.
</p> </p>
AI Local Stack Control (AI-LSC) provides a unified interface to discover, configure, launch, and manage 140 tools spanning the entire AI software stack — from GPU runtimes and inference engines to agent frameworks, security tooling, and knowledge management. AI Local Stack Control (AI-LSC) provides a unified interface to discover, configure, launch, and manage 181 tools spanning the entire AI software stack — from GPU runtimes and inference engines to agent frameworks, security tooling, and knowledge management.
![Overview](docs/screenshots/overview.png) ![Overview](docs/screenshots/overview.png)
@ -25,16 +27,16 @@ Every tool in the registry is classified within a 10-layer taxonomy, giving you
| Layer | Tools | Examples | | Layer | Tools | Examples |
|-------|-------|---------| |-------|-------|---------|
| L1 — Host Platform | 9 | PostgreSQL, MariaDB, Redis, SQLite3, DuckDB, Podman, Docker, Tmux, Git | | L1 — Host Platform | 16 | PostgreSQL, MariaDB, Redis, SQLite3, DuckDB, Podman, Docker, Tmux, Git |
| L2 — Development Environment | 7 | Python Environment, CuPy, ripgrep, fd, tree-sitter, SST, Unsloth | | L2 — Development Environment | 33 | Python Environment, Deno, uv, Node.js, CuPy, ripgrep, fd, tree-sitter, SST, Unsloth |
| L3 — GPU Runtimes | 3 | CUDA Toolkit, NVIDIA Apex, Heretic | | L3 — GPU Runtimes | 3 | CUDA Toolkit, NVIDIA Apex, tinygrad |
| L4 — Engines | 7 | Ollama, llama.cpp, KoboldCPP, Llamafile, TurboLLM, AirLLM, Locally-Uncensored | | L4 — Engines | 8 | Ollama, llama.cpp, KoboldCPP, Llamafile, TurboLLM, AirLLM, Locally-Uncensored |
| L5 — Orchestrators | 26 | vLLM, Ray, LiteLLM Proxy, 9Router Proxy, LangChain, LangFlow, Dify, CrewAI, AutoGen, Wayland AI, +17 more | | L5 — Orchestrators | 53 | vLLM, SGLang, LiteLLM Proxy, 9Router Proxy, LangChain, LangFlow, Dify, CrewAI, AutoGen, Letta, OpenCode, Gemini CLI, Qwen Code, goose, Codex, +38 more |
| L6 — Security | 6 | Keycloak, HashiCorp Vault, Trivy, Fail2Ban, ClamAV, Open Policy Agent | | L6 — Security | 6 | Keycloak, HashiCorp Vault, Trivy, Fail2Ban, ClamAV, Open Policy Agent |
| L7 — Observability | 8 | Btop, Glances, Prometheus, Grafana, Grafana Alloy, Opik, Pulse AI, Latitude | | L7 — Observability | 8 | Btop, Glances, Prometheus, Grafana, Grafana Alloy, Opik, Pulse AI, Latitude |
| L8 — User Interfaces | 16 | Open WebUI, AnythingLLM, LibreChat, Flowise, InvokeAI, Forge (A1111), ComfyUI, Dashy, Obsidian, +7 more | | L8 — User Interfaces | 17 | Open WebUI, AnythingLLM, LibreChat, Flowise, Jan, InvokeAI, Forge (A1111), ComfyUI, Dashy, Obsidian, +7 more |
| L9 — DevOps | 33 | Terraform, Ansible, Puppet, Pulumi, OpenTofu, AWS CDK, Crossplane, n8n, Aider, Claude Code, OpenHands, +23 more | | L9 — DevOps | 11 | Terraform, Ansible, Puppet, Pulumi, OpenTofu, AWS CDK, Crossplane, Terragrunt |
| L10 — Knowledge Management | 25 | Zotero, Calibre, Paperless-ngx, Logseq, Joplin, ChromaDB, LanceDB, Qdrant, LlamaIndex, +16 more | | L10 — Knowledge Management | 26 | Zotero, Calibre, Paperless-ngx, Logseq, Joplin, Mem0, ChromaDB, LanceDB, Qdrant, LlamaIndex, +16 more |
![Infrastructure Layers](docs/screenshots/infrastructure-layers.png) ![Infrastructure Layers](docs/screenshots/infrastructure-layers.png)

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# ────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────
# AI Local Stack Control v3.1.0 — Ankh of Jah # AI Local Stack Control v3.1.1 — Ankh of Jah
# Bootstrap Script # Bootstrap Script
# #
# Fully portable: works wherever the tarball lands. # Fully portable: works wherever the tarball lands.
@ -46,7 +46,7 @@ export AI_LSC_BASE_DIR="$AI_BASE"
echo "" echo ""
echo -e "${BOLD}╔══════════════════════════════════════════════════════╗${NC}" echo -e "${BOLD}╔══════════════════════════════════════════════════════╗${NC}"
echo -e "${BOLD}║ AI Local Stack Control v3.1.0 — Ankh of Jah ║${NC}" echo -e "${BOLD}║ AI Local Stack Control v3.1.1 — Ankh of Jah ║${NC}"
echo -e "${BOLD}╚══════════════════════════════════════════════════════╝${NC}" echo -e "${BOLD}╚══════════════════════════════════════════════════════╝${NC}"
echo "" echo ""
echo -e "${CYAN} Project root : ${SCRIPT_DIR}${NC}" echo -e "${CYAN} Project root : ${SCRIPT_DIR}${NC}"

0
docs/screenshots/ai-lsc-about.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

View File

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 154 KiB

0
docs/screenshots/ai-lsc-chat.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

0
docs/screenshots/ai-lsc-deployment-targets.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 59 KiB

View File

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

View File

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

0
docs/screenshots/ai-lsc-monitor-active-workstation.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

0
docs/screenshots/ai-lsc-settings.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

0
docs/screenshots/ai-lsc-skills-manager.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

0
docs/screenshots/ai-lsc-stack-logic-editor.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

0
docs/screenshots/ai-lsc-tool-db-editor.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 167 KiB

After

Width:  |  Height:  |  Size: 167 KiB

0
docs/screenshots/ai-lsc-workspaces.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "ai-lsc" name = "ai-lsc"
version = "3.1.0" version = "3.1.1"
description = "AI Local Stack Control — PySide6 desktop app for orchestrating local AI/ML tool stacks" description = "AI Local Stack Control — PySide6 desktop app for orchestrating local AI/ML tool stacks"
readme = "README.md" readme = "README.md"
license = {text = "AGPL-3.0-or-later"} license = {text = "AGPL-3.0-or-later"}

View File

@ -15,7 +15,7 @@ import re
import sys import sys
from pathlib import Path from pathlib import Path
ROOT = Path("/home/z/my-project/workspace/ai-lsc") ROOT = Path(__file__).resolve().parent.parent
LAYER_DIR = ROOT / "src/ai_lsc/registry/layers" LAYER_DIR = ROOT / "src/ai_lsc/registry/layers"
DEFAULTS_PATH = ROOT / "src/ai_lsc/registry/defaults.py" DEFAULTS_PATH = ROOT / "src/ai_lsc/registry/defaults.py"

View File

@ -14,7 +14,7 @@ import re
import sys import sys
from pathlib import Path from pathlib import Path
LAYER_DIR = Path("/home/z/my-project/workspace/ai-lsc/src/ai_lsc/registry/layers") LAYER_DIR = Path(__file__).resolve().parent.parent / "src/ai_lsc/registry/layers"
REQUIRED_KEYS = [ REQUIRED_KEYS = [
"has_cli", "has_cli",
"has_gui", "has_gui",

View File

@ -18,7 +18,7 @@ import re
import sys import sys
from pathlib import Path from pathlib import Path
ROOT = Path("/home/z/my-project/workspace/ai-lsc") ROOT = Path(__file__).resolve().parent.parent
LAYER_DIR = ROOT / "src/ai_lsc/registry/layers" LAYER_DIR = ROOT / "src/ai_lsc/registry/layers"
DEFAULTS_PATH = ROOT / "src/ai_lsc/registry/defaults.py" DEFAULTS_PATH = ROOT / "src/ai_lsc/registry/defaults.py"

View File

@ -15,7 +15,7 @@ Usage
config.set_ollama_endpoint(ollama_port=11434) config.set_ollama_endpoint(ollama_port=11434)
config.set_litellm_endpoint(litellm_port=4000) config.set_litellm_endpoint(litellm_port=4000)
config.set_tool_schemas(tool_schemas) config.set_tool_schemas(tool_schemas)
config.save("/mnt/AI/tools/librechat/librechat.yaml") config.save("/mnt/AI/runtime/librechat/config.yaml")
""" """
from __future__ import annotations from __future__ import annotations

View File

@ -16,7 +16,7 @@ Usage
config = LiteLLMConfigGenerator() config = LiteLLMConfigGenerator()
config.add_ollama_models(ollama_port=11434) config.add_ollama_models(ollama_port=11434)
yaml_str = config.generate_yaml() yaml_str = config.generate_yaml()
config.save("/mnt/AI/config/litellm_config.yaml") config.save("/mnt/AI/runtime/litellm/config.yaml")
""" """
from __future__ import annotations from __future__ import annotations

View File

@ -19,7 +19,7 @@ BASE_DIR: str = os.environ.get("AI_LSC_BASE_DIR", "/mnt/AI")
CANONICAL_BASE_DIR: str = BASE_DIR CANONICAL_BASE_DIR: str = BASE_DIR
# ── Filenames ──────────────────────────────────────────────────────────── # ── Filenames ────────────────────────────────────────────────────────────
APP_VERSION: str = "3.1.0" APP_VERSION: str = "3.1.1"
APP_CODENAME: str = "Ankh of Jah" APP_CODENAME: str = "Ankh of Jah"
APP_DISPLAY_NAME: str = f"AI - Local Stack Control v{APP_VERSION} - http://dcos.net" APP_DISPLAY_NAME: str = f"AI - Local Stack Control v{APP_VERSION} - http://dcos.net"
CONFIG_FILE: str = "controller_config.json" CONFIG_FILE: str = "controller_config.json"
@ -31,29 +31,41 @@ MANIFEST_FILE_NAME: str = ".ai-lsc-project.json"
JCL_FILE_NAME: str = ".ai-lsc-jobs.json" JCL_FILE_NAME: str = ".ai-lsc-jobs.json"
# ── Required sub-directories under BASE_DIR ──────────────────── # ── Required sub-directories under BASE_DIR ────────────────────
# The canonical /mnt/AI/ folder layout (v3.1.1b, 24 dirs). Per-tool
# subdirs (runtime/<tool>/, configs/<tool>/, dashboards/<tool>/) are
# created on demand by InstallerManager; only top-level layout dirs are
# listed here so a fresh install has the full skeleton.
#
# App-internal storage that is NOT part of the canonical layout:
# registry/ — ecosystem.json tool DB (RegistryManager mkdirs it)
# registry/manifests — SHA256 hashes, build logs, chunking records
# bootstraps/ — legacy minimal bootstrap scripts (no longer created)
# staging/ — legacy quarantine zone (no longer created)
REQUIRED_DIRS: list[str] = [ REQUIRED_DIRS: list[str] = [
"bin", "backends", # S3/MinIO/Ceph connection profiles + topology
"tools", "distfiles", # permanent mirror of raw source tarballs + installers
"registry", "runtime", # native compiled binaries (Ollama, llama.cpp, MinIO…)
"config", "models/hot", # active weights; loaded or VRAM-ready (SSD)
"cache", "models/cold", # archived weights; offline / long-term retention (HDD)
"runtime", "corpus/hot", # active text indexed in Vector DBs, used by agents
"logs", "corpus/cold", # raw, uningested, or unprocessed text archives
"skills", "datasets/wordlists", # fuzzing lists, dictionaries, tokenization test strings
"datasets/raw", "datasets/huggingface", # downloaded bulk datasets from Hugging Face
"models/ollama", "datasets/github", # scraped or exported repository data
"models/chroma", "pipelines", # ETL, chunking, and routing scripts (backends <-> DBs)
"workspaces/hermes", "configs", # app configs templated for native runtime + app state
"workspaces/openwebui", "agents", # configs and chains for autonomous AI actors
"workspaces/n8n", "skills", # 3rd-party skill files (QA and MoE templates, …)
"tmp", "projects/active", # primary focus; actively developed codebases
"exports", "projects/labs", # experimental, beta, or throwaway POC code
"data", "projects/vault", # archived masters, cloned refs, strict git histories
"containers", "blueprints", # Dockerfiles and build contexts for Podman exports
"configs", "workspaces", # interactive execution envs (Jupyter, OpenNotebook…)
"pipelines", "dashboards", # web UIs and landing pages (Dashy, Open-WebUI, …)
"dashboards", "tools", # standalone compiles (built from distfiles)
"backups", "exports/oci-images", # finalized Podman .tar snapshots (-> MinIO registry)
"scripts", # system admin / maintenance automation for the stack
"logs", # system, runtime, and pipeline service logs
] ]
# ── Default ports for every known tool ─────────────────────────────────── # ── Default ports for every known tool ───────────────────────────────────
@ -123,7 +135,7 @@ TREE_SKIP_PATTERNS: set[str] = {".", "__pycache__", "node_modules", "vendor"}
# ── Navigation layer order for the sidebar rack diagram ─────────────── # ── Navigation layer order for the sidebar rack diagram ───────────────
NAV_LAYER_ORDER: list[str] = [ NAV_LAYER_ORDER: list[str] = [
"Host Platform", "Development Environment", "GPU Runtimes", "Host Platform", "Development Environment", "GPU Runtimes",
"Engines", "Orchestrators", "Security", "Engines", "Routing", "Orchestrators", "Security",
"Observability", "User Interfaces", "DevOps", "Observability", "User Interfaces", "DevOps",
"Knowledge Management", "Knowledge Management",
] ]

View File

@ -3,7 +3,7 @@
Each entry follows the standard registry schema: Each entry follows the standard registry schema:
- ``name``: human-readable tool name - ``name``: human-readable tool name
- ``level``: 10-layer taxonomy level (1-10) - ``level``: 11-layer taxonomy level (1-11)
- ``layer``: this layer name - ``layer``: this layer name
- ``role``: role within the layer - ``role``: role within the layer
- ``category``: functional category - ``category``: functional category
@ -890,4 +890,64 @@ TOOLS: dict[str, dict] = {
"is_skills_collection": False "is_skills_collection": False
} }
}, },
'deno': {
"name": "Deno",
"level": 2,
"layer": "Development Environment",
"role": "Language",
"category": "Runtime",
"installer": {
"type": "pacman",
"pkg": "deno"
},
"launcher": {
"type": "desktop",
"cmd": "deno --version",
"default_port": None
},
"deps": [],
"description": "JavaScript/TypeScript/WASM runtime with secure-by-default "
"permissions and native TypeScript. Many MCP servers are "
"distributed as `deno run` one-liners.",
"license": "MIT",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'uv': {
"name": "uv",
"level": 2,
"layer": "Development Environment",
"role": "Package Manager",
"category": "Build",
"installer": {
"type": "pacman",
"pkg": "uv"
},
"launcher": {
"type": "desktop",
"cmd": "uv --version",
"default_port": None
},
"deps": [],
"description": "Astral's ultra-fast Python package and project manager. "
"Replaces pip/pipx/virtualenv workflows and is the "
"installer backend for AI-LSC's Python tool installs.",
"license": "MIT/Apache-2.0",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
} }

View File

@ -1,7 +1,9 @@
"""Registry entries for the DevOps layer (L9). """Registry entries for the DevOps layer (L10).
Contains Infrastructure as Code tools, configuration management, OCI Contains Infrastructure as Code tools, configuration management, OCI
runtime packaging, and provisioning tools. runtime packaging, provisioning tools, and AI coding agents
(aider, claude_code, codex, openhands, opencode, gemini_cli,
qwen_code, goose, zcoder).
This module is consumed by This module is consumed by
:mod:`ai_lsc.registry.loader`. :mod:`ai_lsc.registry.loader`.
@ -10,7 +12,7 @@ This module is consumed by
TOOLS: dict[str, dict] = { TOOLS: dict[str, dict] = {
'terraform': { 'terraform': {
"name": "Terraform", "name": "Terraform",
"level": 9, "level": 10,
"layer": "DevOps", "layer": "DevOps",
"role": "Infrastructure as Code", "role": "Infrastructure as Code",
"category": "IaC", "category": "IaC",
@ -38,7 +40,7 @@ TOOLS: dict[str, dict] = {
}, },
'ansible': { 'ansible': {
"name": "Ansible", "name": "Ansible",
"level": 9, "level": 10,
"layer": "DevOps", "layer": "DevOps",
"role": "Configuration Management", "role": "Configuration Management",
"category": "Config Management", "category": "Config Management",
@ -66,7 +68,7 @@ TOOLS: dict[str, dict] = {
}, },
'puppet': { 'puppet': {
"name": "Puppet", "name": "Puppet",
"level": 9, "level": 10,
"layer": "DevOps", "layer": "DevOps",
"role": "Configuration Management", "role": "Configuration Management",
"category": "Config Management", "category": "Config Management",
@ -94,7 +96,7 @@ TOOLS: dict[str, dict] = {
}, },
'pulumi': { 'pulumi': {
"name": "Pulumi", "name": "Pulumi",
"level": 9, "level": 10,
"layer": "DevOps", "layer": "DevOps",
"role": "Infrastructure as Code", "role": "Infrastructure as Code",
"category": "IaC", "category": "IaC",
@ -122,7 +124,7 @@ TOOLS: dict[str, dict] = {
}, },
'bicep': { 'bicep': {
"name": "Bicep", "name": "Bicep",
"level": 9, "level": 10,
"layer": "DevOps", "layer": "DevOps",
"role": "Infrastructure as Code", "role": "Infrastructure as Code",
"category": "IaC", "category": "IaC",
@ -150,7 +152,7 @@ TOOLS: dict[str, dict] = {
}, },
'opentofu': { 'opentofu': {
"name": "OpenTofu", "name": "OpenTofu",
"level": 9, "level": 10,
"layer": "DevOps", "layer": "DevOps",
"role": "Infrastructure as Code", "role": "Infrastructure as Code",
"category": "IaC", "category": "IaC",
@ -178,7 +180,7 @@ TOOLS: dict[str, dict] = {
}, },
'aws_cdk': { 'aws_cdk': {
"name": "AWS CDK", "name": "AWS CDK",
"level": 9, "level": 10,
"layer": "DevOps", "layer": "DevOps",
"role": "Infrastructure as Code", "role": "Infrastructure as Code",
"category": "IaC", "category": "IaC",
@ -206,7 +208,7 @@ TOOLS: dict[str, dict] = {
}, },
'crossplane': { 'crossplane': {
"name": "Crossplane", "name": "Crossplane",
"level": 9, "level": 10,
"layer": "DevOps", "layer": "DevOps",
"role": "Infrastructure as Code", "role": "Infrastructure as Code",
"category": "IaC Control Plane", "category": "IaC Control Plane",
@ -236,7 +238,7 @@ TOOLS: dict[str, dict] = {
}, },
'terragrunt': { 'terragrunt': {
"name": "Terragrunt", "name": "Terragrunt",
"level": 9, "level": 10,
"layer": "DevOps", "layer": "DevOps",
"role": "Infrastructure as Code", "role": "Infrastructure as Code",
"category": "IaC Wrapper", "category": "IaC Wrapper",
@ -266,7 +268,7 @@ TOOLS: dict[str, dict] = {
}, },
'stack_exporter': { 'stack_exporter': {
"name": "Stack Container Packager", "name": "Stack Container Packager",
"level": 9, "level": 10,
"layer": "DevOps", "layer": "DevOps",
"role": "Runtime Packaging", "role": "Runtime Packaging",
"category": "OCI Export", "category": "OCI Export",
@ -294,7 +296,7 @@ TOOLS: dict[str, dict] = {
}, },
'homelab': { 'homelab': {
"name": "Homelab", "name": "Homelab",
"level": 9, "level": 10,
"layer": "DevOps", "layer": "DevOps",
"role": "Provisioning", "role": "Provisioning",
"category": "Provisioning", "category": "Provisioning",
@ -321,4 +323,281 @@ TOOLS: dict[str, dict] = {
"is_skills_collection": False "is_skills_collection": False
} }
}, },
'aider': {
"name": "Aider",
"level": 10,
"layer": "DevOps",
"role": "Coding Agent",
"category": "AI Coding Agent",
"installer": {
"type": "uv",
"pkg": "aider-chat"
},
"launcher": {
"type": "desktop",
"cmd": "aider --version",
"default_port": None
},
"deps": [],
"description": "AI pair programming assistant that works in your terminal.",
"license": 'Apache-2.0',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'claude_code': {
"name": "Claude Code",
"level": 10,
"layer": "DevOps",
"role": "Coding Agent",
"category": "AI Coding Agent",
"installer": {
"type": "npm",
"pkg": "@anthropic-ai/claude-code"
},
"launcher": {
"type": "desktop",
"cmd": "claude --version",
"default_port": None
},
"deps": [],
"description": "Anthropic's CLI-based AI coding agent powered by Claude.",
"license": 'Proprietary',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'codex': {
"name": "Codex",
"level": 10,
"layer": "DevOps",
"role": "Coding Agent",
"category": "AI Coding Agent",
"installer": {
"type": "npm",
"pkg": "@openai/codex"
},
"launcher": {
"type": "desktop",
"cmd": "codex --version",
"default_port": None
},
"deps": [],
"description": "OpenAI's CLI-based AI coding agent powered by GPT.",
"license": 'Proprietary',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'openhands': {
"name": "OpenHands",
"level": 10,
"layer": "DevOps",
"role": "Coding Agent",
"category": "AI Coding Agent",
"installer": {
"type": "uv",
"pkg": "openhands-ai"
},
"launcher": {
"type": "tmux",
"cmd": "openhands serve --port {port}",
"default_port": 3000
},
"deps": [],
"description": "Open-source AI coding agent platform with web UI for autonomous software engineering.",
"license": 'MIT',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'opencode': {
"name": "OpenCode",
"level": 10,
"layer": "DevOps",
"role": "Coding Agent",
"category": "AI Coding Agent",
"installer": {
"type": "npm",
"pkg": "opencode-ai"
},
"launcher": {
"type": "desktop",
"cmd": "opencode --version",
"default_port": None
},
"deps": [],
"description": "Open-source terminal AI coding agent from the SST team. "
"Native TUI, LSP integration, shareable sessions, and "
"75+ model providers including local Ollama.",
"license": "MIT",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'gemini_cli': {
"name": "Gemini CLI",
"level": 10,
"layer": "DevOps",
"role": "Coding Agent",
"category": "AI Coding Agent",
"installer": {
"type": "npm",
"pkg": "@google/gemini-cli"
},
"launcher": {
"type": "desktop",
"cmd": "gemini --version",
"default_port": None
},
"deps": [],
"description": "Google's open-source terminal AI agent. Supports "
"OpenAI-compatible local endpoints via OPENAI_BASE_URL, "
"MCP servers, and multi-turn agentic workflows.",
"license": "Apache-2.0",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'qwen_code': {
"name": "Qwen Code",
"level": 10,
"layer": "DevOps",
"role": "Coding Agent",
"category": "AI Coding Agent",
"installer": {
"type": "npm",
"pkg": "@qwen-code/qwen-code"
},
"launcher": {
"type": "desktop",
"cmd": "qwen --version",
"default_port": None
},
"deps": [],
"description": "Qwen's terminal-based agentic coding tool (Gemini CLI "
"fork) optimized for Qwen models, with subagents, MCP "
"support, and OpenAI-compatible local endpoints.",
"license": "Apache-2.0",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'goose': {
"name": "codename goose",
"level": 10,
"layer": "DevOps",
"role": "Coding Agent",
"category": "AI Coding Agent",
"installer": {
"type": "custom",
"pkg": "https://github.com/block/goose"
},
"launcher": {
"type": "desktop",
"cmd": "goose --version",
"default_port": None
},
"deps": [],
"description": "Block's open-source extensible AI agent. Runs MCP "
"extensions for coding, research, and automation; supports "
"local LLM backends including Ollama.",
"license": "Apache-2.0",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
# ---- zcoder -----------------------------------------------------------------
'zcoder': {
"name": "ZCoder",
"level": 10,
"layer": "DevOps",
"role": "Coding Agent",
"category": "AI Coding Agent",
"installer": {
"type": "npm",
"pkg": "zcoder-cli"
},
"launcher": {
"type": "desktop",
"cmd": "zcoder --version",
"default_port": None
},
"deps": [
"ollama"
],
"description": "Zhipu AI Z-Coder CLI coding agent. Speaks OpenAI-compat "
"— point OPENAI_API_BASE at MeshLLM (localhost:9337/v1), "
"LiteLLM (localhost:4000/v1), or Ollama direct "
"(localhost:11434/v1). If the upstream package name "
"differs in your region, override installer.pkg in "
"your local registry.",
"license": "Apache-2.0",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
} }

View File

@ -3,7 +3,7 @@
Each entry follows the standard registry schema: Each entry follows the standard registry schema:
- ``name``: human-readable tool name - ``name``: human-readable tool name
- ``level``: 10-layer taxonomy level (1-10) - ``level``: 11-layer taxonomy level (1-11)
- ``layer``: this layer name - ``layer``: this layer name
- ``role``: role within the layer - ``role``: role within the layer
- ``category``: functional category - ``category``: functional category
@ -75,5 +75,35 @@ TOOLS: dict[str, dict] = {
"is_mcp": False, "is_mcp": False,
"is_skills_collection": False "is_skills_collection": False
} }
},
'tinygrad': {
"name": "tinygrad",
"level": 3,
"layer": "GPU Runtimes",
"role": "GPU Acceleration",
"category": "GPU Computing",
"installer": {
"type": "uv",
"pkg": "tinygrad"
},
"launcher": {
"type": "desktop",
"cmd": "python3 -c \"from tinygrad import Tensor; print(Tensor([1,2,3]).sum().item())\"",
"default_port": None
},
"deps": [],
"description": "Minimalist autograd tensor library with a PyTorch-like API "
"targeting CUDA, AMD, and CPU backends. Powers tinybox "
"inference serving.",
"license": "MIT",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": True,
"is_mcp": False,
"is_skills_collection": False
}
}, },
} }

View File

@ -3,7 +3,7 @@
Each entry follows the standard registry schema: Each entry follows the standard registry schema:
- ``name``: human-readable tool name - ``name``: human-readable tool name
- ``level``: 10-layer taxonomy level (1-10) - ``level``: 11-layer taxonomy level (1-11)
- ``layer``: this layer name - ``layer``: this layer name
- ``role``: role within the layer - ``role``: role within the layer
- ``category``: functional category - ``category``: functional category
@ -306,11 +306,11 @@ TOOLS: dict[str, dict] = {
"category": "Virtualization", "category": "Virtualization",
"installer": { "installer": {
"type": "script", "type": "script",
"cmd": "curl -fsSL https://github.com/firecracker-microvm/firecracker/releases/latest/download/firecracker-v$(curl -s https://api.github.com/repos/firecracker-microvm/firecracker/releases/latest | grep tag_name | cut -d'\"' -f4)-x86_64.tgz | tar xz -C /usr/local/bin/" "cmd": "mkdir -p {tools_root}/bin {tools_root}/firecracker && FC_VER=$(curl -sIL https://github.com/firecracker-microvm/firecracker/releases/latest | grep -i '^location:' | tail -1 | sed 's|.*/tag/||' | tr -d '\r') && curl -fsSL 'https://github.com/firecracker-microvm/firecracker/releases/download/$FC_VER/firecracker-$FC_VER-x86_64.tgz' | tar xz -C {tools_root}/firecracker --strip-components=1 && ln -sf {tools_root}/firecracker/firecracker-$FC_VER-x86_64 {tools_root}/bin/firecracker && ln -sf {tools_root}/firecracker/jailer-$FC_VER-x86_64 {tools_root}/bin/jailer"
}, },
"launcher": { "launcher": {
"type": "desktop", "type": "desktop",
"cmd": "firecracker --version", "cmd": "{tools_root}/bin/firecracker --version",
"default_port": None "default_port": None
}, },
"deps": [], "deps": [],
@ -390,11 +390,11 @@ TOOLS: dict[str, dict] = {
"category": "Networking", "category": "Networking",
"installer": { "installer": {
"type": "script", "type": "script",
"cmd": "curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /usr/local/bin/cloudflared && chmod +x /usr/local/bin/cloudflared" "cmd": "mkdir -p {tools_root}/bin && curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o {tools_root}/bin/cloudflared && chmod +x {tools_root}/bin/cloudflared"
}, },
"launcher": { "launcher": {
"type": "tmux", "type": "tmux",
"cmd": "cloudflared tunnel --url http://localhost:{port}", "cmd": "{tools_root}/bin/cloudflared tunnel --url http://localhost:{port}",
"default_port": 8080 "default_port": 8080
}, },
"deps": [], "deps": [],

View File

@ -3,7 +3,7 @@
Each entry follows the standard registry schema: Each entry follows the standard registry schema:
- ``name``: human-readable tool name - ``name``: human-readable tool name
- ``level``: 10-layer taxonomy level (1-10) - ``level``: 11-layer taxonomy level (1-11)
- ``layer``: this layer name - ``layer``: this layer name
- ``role``: role within the layer - ``role``: role within the layer
- ``category``: functional category - ``category``: functional category
@ -110,7 +110,7 @@ TOOLS: dict[str, dict] = {
"category": "Single-File LLM", "category": "Single-File LLM",
"installer": { "installer": {
"type": "script", "type": "script",
"cmd": "curl -LO https://github.com/Mozilla-Ocho/llamafile/releases/latest/download/llamafile && chmod +x llamafile" "cmd": "mkdir -p {tools_root}/bin && curl -L https://github.com/Mozilla-Ocho/llamafile/releases/latest/download/llamafile -o {tools_root}/bin/llamafile && chmod +x {tools_root}/bin/llamafile"
}, },
"launcher": { "launcher": {
"type": "desktop", "type": "desktop",
@ -251,4 +251,68 @@ TOOLS: dict[str, dict] = {
"is_skills_collection": False "is_skills_collection": False
} }
}, },
'vllm': {
"name": "vLLM",
"level": 4,
"layer": "Engines",
"role": "Engine",
"category": "LLM Serving",
"installer": {
"type": "uv",
"pkg": "vllm"
},
"launcher": {
"type": "tmux",
"cmd": "python -m vllm.entrypoints.openai.api_server --port {port}",
"default_port": 8000
},
"deps": [
"cuda"
],
"description": "High-throughput and memory-efficient LLM serving.",
"license": 'Apache-2.0',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'sglang': {
"name": "SGLang",
"level": 4,
"layer": "Engines",
"role": "Engine",
"category": "LLM Serving",
"installer": {
"type": "uv",
"pkg": "sglang"
},
"launcher": {
"type": "tmux",
"cmd": "python -m sglang.launch_server --port {port}",
"default_port": 30000
},
"deps": [
"cuda"
],
"description": "Fast LLM serving engine with RadixAttention prefix "
"caching, structured generation, and an OpenAI-compatible "
"API.",
"license": "Apache-2.0",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
} }

View File

@ -1,4 +1,4 @@
"""Registry entries for the Knowledge Management layer (L10). """Registry entries for the Knowledge Management layer (L11).
Contains vector stores, graph databases, search engines, document parsers, Contains vector stores, graph databases, search engines, document parsers,
data pipelines, memory systems, and knowledge management tools. data pipelines, memory systems, and knowledge management tools.
@ -10,7 +10,7 @@ This module is consumed by
TOOLS: dict[str, dict] = { TOOLS: dict[str, dict] = {
'zotero': { 'zotero': {
"name": "Zotero", "name": "Zotero",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Reference Manager", "role": "Reference Manager",
"category": "Academic References", "category": "Academic References",
@ -38,7 +38,7 @@ TOOLS: dict[str, dict] = {
}, },
'calibre': { 'calibre': {
"name": "Calibre", "name": "Calibre",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Library Manager", "role": "Library Manager",
"category": "Ebook Library", "category": "Ebook Library",
@ -66,7 +66,7 @@ TOOLS: dict[str, dict] = {
}, },
'paperlessngx': { 'paperlessngx': {
"name": "Paperless-ngx", "name": "Paperless-ngx",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Document Archive", "role": "Document Archive",
"category": "Document Management", "category": "Document Management",
@ -97,7 +97,7 @@ TOOLS: dict[str, dict] = {
}, },
'logseq': { 'logseq': {
"name": "Logseq", "name": "Logseq",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Knowledge Graph", "role": "Knowledge Graph",
"category": "Outliner", "category": "Outliner",
@ -125,7 +125,7 @@ TOOLS: dict[str, dict] = {
}, },
'joplin': { 'joplin': {
"name": "Joplin", "name": "Joplin",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Note Taking", "role": "Note Taking",
"category": "Notes", "category": "Notes",
@ -153,7 +153,7 @@ TOOLS: dict[str, dict] = {
}, },
'chromadb': { 'chromadb': {
"name": "ChromaDB", "name": "ChromaDB",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Memory", "role": "Memory",
"category": "Vector Store", "category": "Vector Store",
@ -181,7 +181,7 @@ TOOLS: dict[str, dict] = {
}, },
'lancedb': { 'lancedb': {
"name": "LanceDB", "name": "LanceDB",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Memory", "role": "Memory",
"category": "Vector Store", "category": "Vector Store",
@ -209,7 +209,7 @@ TOOLS: dict[str, dict] = {
}, },
'qdrant': { 'qdrant': {
"name": "Qdrant", "name": "Qdrant",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Memory", "role": "Memory",
"category": "Vector Store", "category": "Vector Store",
@ -242,7 +242,7 @@ TOOLS: dict[str, dict] = {
}, },
'neo4j': { 'neo4j': {
"name": "Neo4j", "name": "Neo4j",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Memory", "role": "Memory",
"category": "Graph Database", "category": "Graph Database",
@ -270,7 +270,7 @@ TOOLS: dict[str, dict] = {
}, },
'elasticsearch': { 'elasticsearch': {
"name": "Elasticsearch", "name": "Elasticsearch",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Memory", "role": "Memory",
"category": "Search Engine", "category": "Search Engine",
@ -298,13 +298,13 @@ TOOLS: dict[str, dict] = {
}, },
'meilisearch': { 'meilisearch': {
"name": "Meilisearch", "name": "Meilisearch",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Memory", "role": "Memory",
"category": "Search Engine", "category": "Search Engine",
"installer": { "installer": {
"type": "script", "type": "script",
"cmd": "curl -L https://install.meilisearch.com | sh" "cmd": "mkdir -p {tools_root}/bin && cd {tools_root}/bin && curl -L https://install.meilisearch.com | sh"
}, },
"launcher": { "launcher": {
"type": "tmux", "type": "tmux",
@ -326,7 +326,7 @@ TOOLS: dict[str, dict] = {
}, },
'graphrag': { 'graphrag': {
"name": "GraphRAG", "name": "GraphRAG",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Knowledge Synthesis", "role": "Knowledge Synthesis",
"category": "Graph RAG", "category": "Graph RAG",
@ -354,7 +354,7 @@ TOOLS: dict[str, dict] = {
}, },
'turbovec': { 'turbovec': {
"name": "TurboVec", "name": "TurboVec",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Embedding", "role": "Embedding",
"category": "Vector Engine", "category": "Vector Engine",
@ -384,7 +384,7 @@ TOOLS: dict[str, dict] = {
}, },
'airweave': { 'airweave': {
"name": "Airweave", "name": "Airweave",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Integration", "role": "Integration",
"category": "Data Sync", "category": "Data Sync",
@ -412,7 +412,7 @@ TOOLS: dict[str, dict] = {
}, },
'crawl4ai': { 'crawl4ai': {
"name": "Crawl4AI", "name": "Crawl4AI",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Data Harvesting", "role": "Data Harvesting",
"category": "Web Crawler", "category": "Web Crawler",
@ -440,7 +440,7 @@ TOOLS: dict[str, dict] = {
}, },
'docling': { 'docling': {
"name": "Docling", "name": "Docling",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Memory", "role": "Memory",
"category": "File Parsing", "category": "File Parsing",
@ -468,7 +468,7 @@ TOOLS: dict[str, dict] = {
}, },
'markitdown': { 'markitdown': {
"name": "MarkItDown", "name": "MarkItDown",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "File Parsing", "role": "File Parsing",
"category": "Document Converter", "category": "Document Converter",
@ -496,7 +496,7 @@ TOOLS: dict[str, dict] = {
}, },
'opendataloader': { 'opendataloader': {
"name": "OpenDataLoader", "name": "OpenDataLoader",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Ingestion", "role": "Ingestion",
"category": "Data Pipeline", "category": "Data Pipeline",
@ -524,7 +524,7 @@ TOOLS: dict[str, dict] = {
}, },
'whisper': { 'whisper': {
"name": "Whisper", "name": "Whisper",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Memory", "role": "Memory",
"category": "Audio Parsing", "category": "Audio Parsing",
@ -552,7 +552,7 @@ TOOLS: dict[str, dict] = {
}, },
'mnemosyne': { 'mnemosyne': {
"name": "Mnemosyne", "name": "Mnemosyne",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Memory", "role": "Memory",
"category": "Spaced Repetition", "category": "Spaced Repetition",
@ -580,7 +580,7 @@ TOOLS: dict[str, dict] = {
}, },
'mnemo_cortex': { 'mnemo_cortex': {
"name": "Mnemo Cortex", "name": "Mnemo Cortex",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Memory", "role": "Memory",
"category": "Cortex Memory", "category": "Cortex Memory",
@ -610,7 +610,7 @@ TOOLS: dict[str, dict] = {
}, },
'everos_memory': { 'everos_memory': {
"name": "EverOS Memory", "name": "EverOS Memory",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Memory", "role": "Memory",
"category": "Persistent Memory", "category": "Persistent Memory",
@ -638,7 +638,7 @@ TOOLS: dict[str, dict] = {
}, },
'mirofish': { 'mirofish': {
"name": "Mirofish", "name": "Mirofish",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Transform", "role": "Transform",
"category": "Data Pipeline", "category": "Data Pipeline",
@ -666,7 +666,7 @@ TOOLS: dict[str, dict] = {
}, },
'opendataloader_pdf': { 'opendataloader_pdf': {
"name": "OpenDataLoader PDF", "name": "OpenDataLoader PDF",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Extraction", "role": "Extraction",
"category": "PDF Pipeline", "category": "PDF Pipeline",
@ -694,7 +694,7 @@ TOOLS: dict[str, dict] = {
}, },
'understand_anything': { 'understand_anything': {
"name": "Understand Anything", "name": "Understand Anything",
"level": 10, "level": 11,
"layer": "Knowledge Management", "layer": "Knowledge Management",
"role": "Comprehension", "role": "Comprehension",
"category": "Document Understanding", "category": "Document Understanding",
@ -721,5 +721,35 @@ TOOLS: dict[str, dict] = {
"is_mcp": False, "is_mcp": False,
"is_skills_collection": False "is_skills_collection": False
} }
},
'mem0': {
"name": "Mem0",
"level": 11,
"layer": "Knowledge Management",
"role": "Memory",
"category": "Memory System",
"installer": {
"type": "uv",
"pkg": "mem0ai"
},
"launcher": {
"type": "desktop",
"cmd": "python3 -c \"import mem0; print('ok')\"",
"default_port": None
},
"deps": [],
"description": "Memory layer for AI applications and agents — extracts, "
"stores, and retrieves long-term user/agent memories across "
"sessions, backed by pluggable vector stores.",
"license": "Apache-2.0",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": True,
"is_mcp": False,
"is_skills_collection": False
}
}, },
} }

View File

@ -1,6 +1,7 @@
"""Registry entries for the Observability layer (L7). """Registry entries for the Observability layer (L8).
Contains metrics, dashboards, tracing, AI monitoring, and LLM evaluation tools. Contains metrics, dashboards, tracing, AI monitoring, LLM
evaluation, and build/system monitoring tools.
This module is consumed by This module is consumed by
:mod:`ai_lsc.registry.loader`. :mod:`ai_lsc.registry.loader`.
@ -9,7 +10,7 @@ This module is consumed by
TOOLS: dict[str, dict] = { TOOLS: dict[str, dict] = {
'btop': { 'btop': {
"name": "Btop", "name": "Btop",
"level": 7, "level": 8,
"layer": "Observability", "layer": "Observability",
"role": "Dashboard", "role": "Dashboard",
"category": "Metrics", "category": "Metrics",
@ -37,7 +38,7 @@ TOOLS: dict[str, dict] = {
}, },
'glances': { 'glances': {
"name": "Glances", "name": "Glances",
"level": 7, "level": 8,
"layer": "Observability", "layer": "Observability",
"role": "Dashboard", "role": "Dashboard",
"category": "Metrics", "category": "Metrics",
@ -65,7 +66,7 @@ TOOLS: dict[str, dict] = {
}, },
'prometheus': { 'prometheus': {
"name": "Prometheus", "name": "Prometheus",
"level": 7, "level": 8,
"layer": "Observability", "layer": "Observability",
"role": "Metrics Collector", "role": "Metrics Collector",
"category": "Metrics", "category": "Metrics",
@ -93,7 +94,7 @@ TOOLS: dict[str, dict] = {
}, },
'grafana': { 'grafana': {
"name": "Grafana", "name": "Grafana",
"level": 7, "level": 8,
"layer": "Observability", "layer": "Observability",
"role": "Dashboard", "role": "Dashboard",
"category": "Visualization", "category": "Visualization",
@ -121,17 +122,17 @@ TOOLS: dict[str, dict] = {
}, },
'grafana_alloy': { 'grafana_alloy': {
"name": "Grafana Alloy", "name": "Grafana Alloy",
"level": 7, "level": 8,
"layer": "Observability", "layer": "Observability",
"role": "Collector", "role": "Collector",
"category": "Telemetry", "category": "Telemetry",
"installer": { "installer": {
"type": "script", "type": "script",
"cmd": "curl -fsSL https://raw.githubusercontent.com/grafana/alloy/main/install.sh | sh" "cmd": "mkdir -p {tools_root}/bin {tools_root}/alloy && curl -fsSL https://github.com/grafana/alloy/releases/latest/download/alloy-linux-amd64.zip -o {tools_root}/alloy/alloy.zip && python3 -m zipfile -e {tools_root}/alloy/alloy.zip {tools_root}/alloy && mv {tools_root}/alloy/alloy-linux-amd64 {tools_root}/bin/alloy && chmod +x {tools_root}/bin/alloy"
}, },
"launcher": { "launcher": {
"type": "tmux", "type": "tmux",
"cmd": "alloy run --server.http.listen-port={port}", "cmd": "{tools_root}/bin/alloy run --server.http.listen-port={port}",
"default_port": 12345 "default_port": 12345
}, },
"deps": [ "deps": [
@ -151,7 +152,7 @@ TOOLS: dict[str, dict] = {
}, },
'opik': { 'opik': {
"name": "Opik", "name": "Opik",
"level": 7, "level": 8,
"layer": "Observability", "layer": "Observability",
"role": "LLM Tracing", "role": "LLM Tracing",
"category": "AI Observability", "category": "AI Observability",
@ -179,7 +180,7 @@ TOOLS: dict[str, dict] = {
}, },
'pulse_ai': { 'pulse_ai': {
"name": "Pulse AI", "name": "Pulse AI",
"level": 7, "level": 8,
"layer": "Observability", "layer": "Observability",
"role": "Health Monitor", "role": "Health Monitor",
"category": "AI Monitoring", "category": "AI Monitoring",
@ -207,7 +208,7 @@ TOOLS: dict[str, dict] = {
}, },
'latitude': { 'latitude': {
"name": "Latitude", "name": "Latitude",
"level": 7, "level": 8,
"layer": "Observability", "layer": "Observability",
"role": "Evaluation", "role": "Evaluation",
"category": "LLM Evaluation", "category": "LLM Evaluation",
@ -235,4 +236,64 @@ TOOLS: dict[str, dict] = {
"is_skills_collection": False "is_skills_collection": False
} }
}, },
'eagle_eye': {
"name": "Eagle Eye",
"level": 8,
"layer": "Observability",
"role": "Monitoring",
"category": "Observability",
"installer": {
"type": "git",
"pkg": "https://github.com/nicely-done/eagle_eye"
},
"launcher": {
"type": "desktop",
"cmd": "eagle_eye --version",
"default_port": None
},
"deps": [],
"description": "AI-powered observability and monitoring agent.",
"license": 'Proprietary',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'dma': {
"name": "DMA (Distcc Monitor Agent)",
"level": 8,
"layer": "Observability",
"role": "Monitoring",
"category": "Build Monitoring",
"installer": {
"type": "git",
"pkg": "https://github.com/distcc/dma"
},
"launcher": {
"type": "desktop",
"cmd": "dma --version",
"default_port": None
},
"deps": [
"distcc"
],
"description": "Monitor for distributed compilation with distcc.",
"license": 'Proprietary',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
} }

View File

@ -1,46 +1,18 @@
"""Registry entries for the Orchestrators layer (L5). """Registry entries for the Orchestrators layer (L6).
Contains distributed compute, LLM serving, agent orchestration, Contains distributed compute, agent orchestration, workflow
workflow routing, pipeline coordination, and multi-agent frameworks. engines, pipeline coordination, and multi-agent frameworks.
(LLM serving moved to Engines; routing/gateways to Routing;
coding agents to DevOps in the 11-layer taxonomy.)
This module is consumed by This module is consumed by
:mod:`ai_lsc.registry.loader`. :mod:`ai_lsc.registry.loader`.
""" """
TOOLS: dict[str, dict] = { TOOLS: dict[str, dict] = {
'vllm': {
"name": "vLLM",
"level": 5,
"layer": "Orchestrators",
"role": "Scaling",
"category": "LLM Serving",
"installer": {
"type": "uv",
"pkg": "vllm"
},
"launcher": {
"type": "tmux",
"cmd": "python -m vllm.entrypoints.openai.api_server --port {port}",
"default_port": 8000
},
"deps": [
"cuda"
],
"description": "High-throughput and memory-efficient LLM serving.",
"license": 'Apache-2.0',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'distcc': { 'distcc': {
"name": "DistCC", "name": "DistCC",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Distribution", "role": "Distribution",
"category": "Distributed Compilation", "category": "Distributed Compilation",
@ -65,40 +37,10 @@ TOOLS: dict[str, dict] = {
"is_mcp": False, "is_mcp": False,
"is_skills_collection": False "is_skills_collection": False
} }
},
'dma': {
"name": "DMA (Distcc Monitor Agent)",
"level": 5,
"layer": "Orchestrators",
"role": "Monitoring",
"category": "Build Monitoring",
"installer": {
"type": "git",
"pkg": "https://github.com/distcc/dma"
},
"launcher": {
"type": "desktop",
"cmd": "dma --version",
"default_port": None
},
"deps": [
"distcc"
],
"description": "Monitor for distributed compilation with distcc.",
"license": 'Proprietary',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
}, },
'ray': { 'ray': {
"name": "Ray", "name": "Ray",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Scaling", "role": "Scaling",
"category": "Distributed Compute", "category": "Distributed Compute",
@ -126,7 +68,7 @@ TOOLS: dict[str, dict] = {
}, },
'pssh': { 'pssh': {
"name": "PSSH (Parallel SSH)", "name": "PSSH (Parallel SSH)",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Coordination", "role": "Coordination",
"category": "Cluster SSH", "category": "Cluster SSH",
@ -151,68 +93,10 @@ TOOLS: dict[str, dict] = {
"is_mcp": False, "is_mcp": False,
"is_skills_collection": False "is_skills_collection": False
} }
},
'litellm': {
"name": "LiteLLM Proxy",
"level": 5,
"layer": "Orchestrators",
"role": "API Gateway",
"category": "Proxy",
"installer": {
"type": "uv",
"pkg": "litellm"
},
"launcher": {
"type": "tmux",
"cmd": "litellm --port {port}",
"default_port": 4000
},
"deps": [],
"description": "Call 100+ LLMs using the OpenAI format.",
"license": 'MIT',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'9router_proxy': {
"name": "9Router Proxy",
"level": 5,
"layer": "Orchestrators",
"role": "API Gateway",
"category": "LLM Router",
"installer": {
"type": "git",
"pkg": "https://github.com/nicely-done/9router"
},
"launcher": {
"type": "tmux",
"cmd": "cd {tools_root}/9router && python3 main.py --port {port}",
"default_port": 4001
},
"deps": [
"ollama"
],
"description": "Intelligent LLM request router and load balancer.",
"license": 'MIT',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
}, },
'langchain': { 'langchain': {
"name": "LangChain", "name": "LangChain",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Orchestration", "role": "Orchestration",
"category": "LLM Framework", "category": "LLM Framework",
@ -240,7 +124,7 @@ TOOLS: dict[str, dict] = {
}, },
'langflow': { 'langflow': {
"name": "LangFlow", "name": "LangFlow",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Visual Builder", "role": "Visual Builder",
"category": "Workflow", "category": "Workflow",
@ -268,7 +152,7 @@ TOOLS: dict[str, dict] = {
}, },
'crewai': { 'crewai': {
"name": "CrewAI", "name": "CrewAI",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Brain", "role": "Brain",
"category": "Agent Workflow", "category": "Agent Workflow",
@ -296,7 +180,7 @@ TOOLS: dict[str, dict] = {
}, },
'autogen': { 'autogen': {
"name": "AutoGen", "name": "AutoGen",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Brain", "role": "Brain",
"category": "Agent Workflow", "category": "Agent Workflow",
@ -324,7 +208,7 @@ TOOLS: dict[str, dict] = {
}, },
'openai_swarm': { 'openai_swarm': {
"name": "OpenAI Swarm", "name": "OpenAI Swarm",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Multi-Agent", "role": "Multi-Agent",
"category": "Agent Framework", "category": "Agent Framework",
@ -352,7 +236,7 @@ TOOLS: dict[str, dict] = {
}, },
'agno': { 'agno': {
"name": "Agno", "name": "Agno",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Agent Framework", "role": "Agent Framework",
"category": "AI Agent", "category": "AI Agent",
@ -380,7 +264,7 @@ TOOLS: dict[str, dict] = {
}, },
'nvidia_agent_skills': { 'nvidia_agent_skills': {
"name": "NVIDIA Agent Skills", "name": "NVIDIA Agent Skills",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Tool Integration", "role": "Tool Integration",
"category": "Agent Toolkit", "category": "Agent Toolkit",
@ -410,7 +294,7 @@ TOOLS: dict[str, dict] = {
}, },
'openbrain': { 'openbrain': {
"name": "OpenBrain", "name": "OpenBrain",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Brain", "role": "Brain",
"category": "Reasoning Engine", "category": "Reasoning Engine",
@ -440,7 +324,7 @@ TOOLS: dict[str, dict] = {
}, },
'odysseus': { 'odysseus': {
"name": "Odysseus", "name": "Odysseus",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Reasoning", "role": "Reasoning",
"category": "Agent Workflow", "category": "Agent Workflow",
@ -467,43 +351,10 @@ TOOLS: dict[str, dict] = {
"is_mcp": False, "is_mcp": False,
"is_skills_collection": False "is_skills_collection": False
} }
},
'dify': {
"name": "Dify",
"level": 5,
"layer": "Orchestrators",
"role": "Pipeline Orchestrator",
"category": "Pipeline",
"installer": {
"type": "git",
"pkg": "https://github.com/langgenius/dify.git"
},
"launcher": {
"type": "tmux",
"cmd": "cd {tools_root}/dify/api && poetry run flask run --host 0.0.0.0 --port={port}",
"default_port": 5001
},
"deps": [
"postgresql",
"redis",
"python",
"node"
],
"description": "LLM application development platform (native install). Requires Poetry, Node.js 18+, FFmpeg. Backend (Flask) + Celery worker + Next.js frontend run as separate services.",
"license": 'Dify-OSL',
"flags": {
"has_cli": False,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
}, },
'n8n': { 'n8n': {
"name": "n8n", "name": "n8n",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Workflow Orchestrator", "role": "Workflow Orchestrator",
"category": "Workflow Automation", "category": "Workflow Automation",
@ -534,7 +385,7 @@ TOOLS: dict[str, dict] = {
}, },
'fabric': { 'fabric': {
"name": "Fabric", "name": "Fabric",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Curation", "role": "Curation",
"category": "AI Augmentation", "category": "AI Augmentation",
@ -564,7 +415,7 @@ TOOLS: dict[str, dict] = {
}, },
'synapscli': { 'synapscli': {
"name": "SynapsCLI", "name": "SynapsCLI",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Agent", "role": "Agent",
"category": "AI Agent", "category": "AI Agent",
@ -593,7 +444,7 @@ TOOLS: dict[str, dict] = {
}, },
'hivemind': { 'hivemind': {
"name": "HiveMind", "name": "HiveMind",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Coordination", "role": "Coordination",
"category": "Multi-Agent", "category": "Multi-Agent",
@ -623,7 +474,7 @@ TOOLS: dict[str, dict] = {
}, },
'hermes_agent': { 'hermes_agent': {
"name": "Hermes Agent", "name": "Hermes Agent",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Agent", "role": "Agent",
"category": "AI Agent", "category": "AI Agent",
@ -653,7 +504,7 @@ TOOLS: dict[str, dict] = {
}, },
'agentic_os': { 'agentic_os': {
"name": "Agentic OS", "name": "Agentic OS",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Hands", "role": "Hands",
"category": "Agent OS", "category": "Agent OS",
@ -683,7 +534,7 @@ TOOLS: dict[str, dict] = {
}, },
'mcp_drift_state_tracker': { 'mcp_drift_state_tracker': {
"name": "MCP Drift State Tracker", "name": "MCP Drift State Tracker",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Code Audit", "role": "Code Audit",
"category": "MCP Server", "category": "MCP Server",
@ -713,7 +564,7 @@ TOOLS: dict[str, dict] = {
}, },
'glassmind': { 'glassmind': {
"name": "GlassMind", "name": "GlassMind",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Reasoning", "role": "Reasoning",
"category": "Reasoning Engine", "category": "Reasoning Engine",
@ -740,122 +591,10 @@ TOOLS: dict[str, dict] = {
"is_mcp": False, "is_mcp": False,
"is_skills_collection": False "is_skills_collection": False
} }
},
'aider': {
"name": "Aider",
"level": 5,
"layer": "Orchestrators",
"role": "Coding Agent",
"category": "AI Coding Agent",
"installer": {
"type": "uv",
"pkg": "aider-chat"
},
"launcher": {
"type": "desktop",
"cmd": "aider --version",
"default_port": None
},
"deps": [],
"description": "AI pair programming assistant that works in your terminal.",
"license": 'Apache-2.0',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'claude_code': {
"name": "Claude Code",
"level": 5,
"layer": "Orchestrators",
"role": "Coding Agent",
"category": "AI Coding Agent",
"installer": {
"type": "npm",
"pkg": "@anthropic-ai/claude-code"
},
"launcher": {
"type": "desktop",
"cmd": "claude --version",
"default_port": None
},
"deps": [],
"description": "Anthropic's CLI-based AI coding agent powered by Claude.",
"license": 'Proprietary',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'codex': {
"name": "Codex",
"level": 5,
"layer": "Orchestrators",
"role": "Coding Agent",
"category": "AI Coding Agent",
"installer": {
"type": "npm",
"pkg": "@openai/codex"
},
"launcher": {
"type": "desktop",
"cmd": "codex --version",
"default_port": None
},
"deps": [],
"description": "OpenAI's CLI-based AI coding agent powered by GPT.",
"license": 'Proprietary',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'openhands': {
"name": "OpenHands",
"level": 5,
"layer": "Orchestrators",
"role": "Coding Agent",
"category": "AI Coding Agent",
"installer": {
"type": "uv",
"pkg": "openhands-ai"
},
"launcher": {
"type": "tmux",
"cmd": "openhands serve --port {port}",
"default_port": 3000
},
"deps": [],
"description": "Open-source AI coding agent platform with web UI for autonomous software engineering.",
"license": 'MIT',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
}, },
'honcho': { 'honcho': {
"name": "Honcho", "name": "Honcho",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Process Manager", "role": "Process Manager",
"category": "Workflow Automation", "category": "Workflow Automation",
@ -880,44 +619,16 @@ TOOLS: dict[str, dict] = {
"is_mcp": False, "is_mcp": False,
"is_skills_collection": False "is_skills_collection": False
} }
},
'eagle_eye': {
"name": "Eagle Eye",
"level": 5,
"layer": "Orchestrators",
"role": "Monitoring",
"category": "Observability",
"installer": {
"type": "git",
"pkg": "https://github.com/nicely-done/eagle_eye"
},
"launcher": {
"type": "desktop",
"cmd": "eagle_eye --version",
"default_port": None
},
"deps": [],
"description": "AI-powered observability and monitoring agent.",
"license": 'Proprietary',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
}, },
'graphify': { 'graphify': {
"name": "Graphify", "name": "Graphify",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Graph Builder", "role": "Knowledge Graph Builder",
"category": "AI Agent", "category": "Claude Code Skill",
"installer": { "installer": {
"type": "git", "type": "uv",
"pkg": "https://github.com/nicely-done/graphify" "pkg": "graphifyy"
}, },
"launcher": { "launcher": {
"type": "desktop", "type": "desktop",
@ -925,21 +636,31 @@ TOOLS: dict[str, dict] = {
"default_port": None "default_port": None
}, },
"deps": [], "deps": [],
"description": "Graph-based knowledge and workflow visualization agent.", "description": "Knowledge graph builder for code, docs, PDFs, and "
"license": 'Proprietary', "images. Installs as a Claude Code skill (type "
"`/graphify .` in Claude Code) or runs standalone "
"via CLI. Builds interactive graph.html, Obsidian "
"vault, Wikipedia-style wiki, and persistent "
"graph.json from any folder. MCP stdio server mode "
"(`graphify --mcp`) lets other agents query the "
"graph. Uses Claude vision by default; can be "
"configured to use any OpenAI-compat endpoint "
"(MeshLLM, LiteLLM, Ollama) for extraction. PyPI "
"package is `graphifyy` (CLI is `graphify`).",
"license": "MIT",
"flags": { "flags": {
"has_cli": True, "has_cli": True,
"has_gui": False, "has_gui": False,
"has_web": False, "has_web": True,
"is_ollama": False, "is_ollama": False,
"is_passive": False, "is_passive": False,
"is_mcp": False, "is_mcp": True,
"is_skills_collection": False "is_skills_collection": False
} }
}, },
'headroom': { 'headroom': {
"name": "Headroom", "name": "Headroom",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Resource Manager", "role": "Resource Manager",
"category": "Infrastructure", "category": "Infrastructure",
@ -967,7 +688,7 @@ TOOLS: dict[str, dict] = {
}, },
'loop_engineering': { 'loop_engineering': {
"name": "Loop Engineering", "name": "Loop Engineering",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Engineering Loop", "role": "Engineering Loop",
"category": "Workflow Automation", "category": "Workflow Automation",
@ -995,7 +716,7 @@ TOOLS: dict[str, dict] = {
}, },
'nightshift': { 'nightshift': {
"name": "Nightshift", "name": "Nightshift",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Night Ops", "role": "Night Ops",
"category": "Workflow Automation", "category": "Workflow Automation",
@ -1023,7 +744,7 @@ TOOLS: dict[str, dict] = {
}, },
'opensandbox': { 'opensandbox': {
"name": "OpenSandbox", "name": "OpenSandbox",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Sandbox", "role": "Sandbox",
"category": "Container Ops", "category": "Container Ops",
@ -1051,7 +772,7 @@ TOOLS: dict[str, dict] = {
}, },
'ponytail': { 'ponytail': {
"name": "Ponytail", "name": "Ponytail",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "CI/CD", "role": "CI/CD",
"category": "Workflow Automation", "category": "Workflow Automation",
@ -1079,7 +800,7 @@ TOOLS: dict[str, dict] = {
}, },
'promptops': { 'promptops': {
"name": "PromptOps", "name": "PromptOps",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Prompt Ops", "role": "Prompt Ops",
"category": "AI Agent", "category": "AI Agent",
@ -1107,7 +828,7 @@ TOOLS: dict[str, dict] = {
}, },
'agent_reach': { 'agent_reach': {
"name": "Agent Reach", "name": "Agent Reach",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Agent Discovery", "role": "Agent Discovery",
"category": "Multi-Agent", "category": "Multi-Agent",
@ -1135,7 +856,7 @@ TOOLS: dict[str, dict] = {
}, },
'algory': { 'algory': {
"name": "Algory", "name": "Algory",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Algorithm", "role": "Algorithm",
"category": "AI Agent", "category": "AI Agent",
@ -1163,7 +884,7 @@ TOOLS: dict[str, dict] = {
}, },
'atlas_os': { 'atlas_os': {
"name": "Atlas OS", "name": "Atlas OS",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "OS Framework", "role": "OS Framework",
"category": "Agent OS", "category": "Agent OS",
@ -1191,7 +912,7 @@ TOOLS: dict[str, dict] = {
}, },
'career_ops': { 'career_ops': {
"name": "Career Ops", "name": "Career Ops",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Career Ops", "role": "Career Ops",
"category": "Workflow Automation", "category": "Workflow Automation",
@ -1219,7 +940,7 @@ TOOLS: dict[str, dict] = {
}, },
'container_tool': { 'container_tool': {
"name": "Container Tool", "name": "Container Tool",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Containerization", "role": "Containerization",
"category": "Container Ops", "category": "Container Ops",
@ -1247,7 +968,7 @@ TOOLS: dict[str, dict] = {
}, },
'pm_skills': { 'pm_skills': {
"name": "PM Skills", "name": "PM Skills",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Project Management", "role": "Project Management",
"category": "Workflow Automation", "category": "Workflow Automation",
@ -1275,7 +996,7 @@ TOOLS: dict[str, dict] = {
}, },
'skillspector': { 'skillspector': {
"name": "Skillspector", "name": "Skillspector",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Skill Inspector", "role": "Skill Inspector",
"category": "AI Agent", "category": "AI Agent",
@ -1303,7 +1024,7 @@ TOOLS: dict[str, dict] = {
}, },
'spec_kit': { 'spec_kit': {
"name": "Spec Kit", "name": "Spec Kit",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Specification", "role": "Specification",
"category": "AI Agent", "category": "AI Agent",
@ -1331,7 +1052,7 @@ TOOLS: dict[str, dict] = {
}, },
'wayland_ai': { 'wayland_ai': {
"name": "Wayland AI", "name": "Wayland AI",
"level": 5, "level": 6,
"layer": "Orchestrators", "layer": "Orchestrators",
"role": "Agent Orchestrator", "role": "Agent Orchestrator",
"category": "AI Agent", "category": "AI Agent",
@ -1358,4 +1079,35 @@ TOOLS: dict[str, dict] = {
"is_skills_collection": False "is_skills_collection": False
} }
}, },
'letta': {
"name": "Letta",
"level": 6,
"layer": "Orchestrators",
"role": "Agent Framework",
"category": "Agent Framework",
"installer": {
"type": "uv",
"pkg": "letta"
},
"launcher": {
"type": "tmux",
"cmd": "letta server --port {port}",
"default_port": 8283
},
"deps": [],
"description": "Stateful agent framework (MemGPT) with persistent memory, "
"self-editing agents, and a REST API server for agent "
"management.",
"license": "Apache-2.0",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
} }

View File

@ -0,0 +1,187 @@
"""Registry entries for the Routing layer (L5).
Restored layer (v3.1.1b): model gateways, LLM proxies, request routers,
mesh transport, and the model-routing tier that sits between the Engines
(who serve weights) and the Orchestrators (who build agent workflows on
top of a single OpenAI-compatible endpoint). This re-unites the old
13-layer model's "AI Endpoints" tier (LiteLLM, model routers, API
gateways) that had been folded into Orchestrators during the 13-to-10
reorg, plus the mesh-aware clients that ride on it.
This module is consumed by :mod:`ai_lsc.registry.loader`.
"""
TOOLS: dict[str, dict] = {
'litellm': {
"name": "LiteLLM Proxy",
"level": 5,
"layer": "Routing",
"role": "API Gateway",
"category": "Proxy",
"installer": {
"type": "uv",
"pkg": "litellm"
},
"launcher": {
"type": "tmux",
"cmd": "litellm --port {port}",
"default_port": 4000
},
"deps": [],
"description": "Call 100+ LLMs using the OpenAI format.",
"license": 'MIT',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'9router_proxy': {
"name": "9Router Proxy",
"level": 5,
"layer": "Routing",
"role": "API Gateway",
"category": "LLM Router",
"installer": {
"type": "git",
"pkg": "https://github.com/nicely-done/9router"
},
"launcher": {
"type": "tmux",
"cmd": "cd {tools_root}/9router && python3 main.py --port {port}",
"default_port": 4001
},
"deps": [
"ollama"
],
"description": "Intelligent LLM request router and load balancer.",
"license": 'MIT',
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
# ---- meshllm ----------------------------------------------------------------
# MeshLLM is its own native binary — NOT a LiteLLM re-skin. It pools GPUs
# and memory across machines, exposes one OpenAI-compat API at :9337, and
# has a web console at :3131. Install via the official curl installer.
'meshllm': {
"name": "MeshLLM",
"level": 5,
"layer": "Routing",
"role": "API Gateway",
"category": "LLM Mesh",
"installer": {
"type": "script",
"cmd": "mkdir -p {tools_root}/meshllm/bin && curl -fsSL https://raw.githubusercontent.com/Mesh-LLM/mesh-llm/main/install.sh | MESH_LLM_INSTALL_DIR={tools_root}/meshllm/bin bash"
},
"launcher": {
"type": "tmux",
"cmd": "mesh-llm serve --auto --port {port}",
"default_port": 9337
},
"deps": [],
"description": "Native binary that pools GPUs and memory across "
"machines and exposes the result as one OpenAI-"
"compatible API at http://localhost:9337/v1. Start "
"one node, add more nodes later — the mesh decides "
"whether a model runs locally, routes to a peer, or "
"uses Skippy stage splits for models too large for "
"one box. Web console on :3131. Has subcommands "
"(`mesh-llm goose`, `mesh-llm opencode`, `mesh-llm "
"claude`, `mesh-llm pi`) that wrap other coding agents "
"to use the mesh. QUIC-encrypted peer transport via "
"Iroh relays. NOT a LiteLLM derivative — distinct "
"project at https://github.com/Mesh-LLM/mesh-llm.",
"license": "MIT",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'dify': {
"name": "Dify",
"level": 5,
"layer": "Routing",
"role": "Pipeline Orchestrator",
"category": "Pipeline",
"installer": {
"type": "git",
"pkg": "https://github.com/langgenius/dify.git"
},
"launcher": {
"type": "tmux",
"cmd": "cd {tools_root}/dify/api && poetry run flask run --host 0.0.0.0 --port={port}",
"default_port": 5001
},
"deps": [
"postgresql",
"redis",
"python",
"nodejs"
],
"description": "LLM application development platform (native install). Requires Poetry, Node.js 18+, FFmpeg. Backend (Flask) + Celery worker + Next.js frontend run as separate services.",
"license": 'Dify-OSL',
"flags": {
"has_cli": False,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'picode': {
"name": "PiCode",
"level": 5,
"layer": "Routing",
"role": "Coding Agent",
"category": "Mesh Client",
"installer": {
"type": "git",
"pkg": "https://github.com/jasonjmcghee/picode.git"
},
"launcher": {
"type": "desktop",
"cmd": "picode --version",
"default_port": None
},
"deps": [
"ollama"
],
"description": "Local code-tinker agent. Speaks OpenAI-compat — point "
"OPENAI_API_BASE at the mesh (localhost:9337 for MeshLLM, "
"localhost:4000 for LiteLLM) or directly at Ollama "
"(localhost:11434/v1).",
"license": "MIT",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
}

View File

@ -1,4 +1,4 @@
"""Registry entries for the Security layer (L6). """Registry entries for the Security layer (L7).
Contains identity management, secrets management, container scanning, Contains identity management, secrets management, container scanning,
intrusion prevention, antivirus, and policy enforcement tools for intrusion prevention, antivirus, and policy enforcement tools for
@ -11,7 +11,7 @@ This module is consumed by
TOOLS: dict[str, dict] = { TOOLS: dict[str, dict] = {
'keycloak': { 'keycloak': {
"name": "Keycloak", "name": "Keycloak",
"level": 6, "level": 7,
"layer": "Security", "layer": "Security",
"role": "Identity", "role": "Identity",
"category": "Auth", "category": "Auth",
@ -39,7 +39,7 @@ TOOLS: dict[str, dict] = {
}, },
'vault': { 'vault': {
"name": "HashiCorp Vault", "name": "HashiCorp Vault",
"level": 6, "level": 7,
"layer": "Security", "layer": "Security",
"role": "Secrets", "role": "Secrets",
"category": "Secrets Management", "category": "Secrets Management",
@ -67,7 +67,7 @@ TOOLS: dict[str, dict] = {
}, },
'trivy': { 'trivy': {
"name": "Trivy", "name": "Trivy",
"level": 6, "level": 7,
"layer": "Security", "layer": "Security",
"role": "Scanner", "role": "Scanner",
"category": "Container Security", "category": "Container Security",
@ -95,7 +95,7 @@ TOOLS: dict[str, dict] = {
}, },
'fail2ban': { 'fail2ban': {
"name": "Fail2Ban", "name": "Fail2Ban",
"level": 6, "level": 7,
"layer": "Security", "layer": "Security",
"role": "IDS", "role": "IDS",
"category": "Intrusion Prevention", "category": "Intrusion Prevention",
@ -123,7 +123,7 @@ TOOLS: dict[str, dict] = {
}, },
'clamav': { 'clamav': {
"name": "ClamAV", "name": "ClamAV",
"level": 6, "level": 7,
"layer": "Security", "layer": "Security",
"role": "Scanner", "role": "Scanner",
"category": "Antivirus", "category": "Antivirus",
@ -151,7 +151,7 @@ TOOLS: dict[str, dict] = {
}, },
'opa': { 'opa': {
"name": "Open Policy Agent", "name": "Open Policy Agent",
"level": 6, "level": 7,
"layer": "Security", "layer": "Security",
"role": "Policy", "role": "Policy",
"category": "Policy Engine", "category": "Policy Engine",

View File

@ -1,4 +1,4 @@
"""Registry entries for the User Interfaces layer (L8). """Registry entries for the User Interfaces layer (L9).
Contains frontends, dashboards, chat UIs, image generation interfaces, Contains frontends, dashboards, chat UIs, image generation interfaces,
sensory interfaces (vision, speech, voice), and knowledge graph tools. sensory interfaces (vision, speech, voice), and knowledge graph tools.
@ -10,7 +10,7 @@ This module is consumed by
TOOLS: dict[str, dict] = { TOOLS: dict[str, dict] = {
'openwebui': { 'openwebui': {
"name": "Open WebUI", "name": "Open WebUI",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Face", "role": "Face",
"category": "Chat Frontend", "category": "Chat Frontend",
@ -40,7 +40,7 @@ TOOLS: dict[str, dict] = {
}, },
'anythingllm': { 'anythingllm': {
"name": "AnythingLLM", "name": "AnythingLLM",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Face", "role": "Face",
"category": "Chat", "category": "Chat",
@ -68,7 +68,7 @@ TOOLS: dict[str, dict] = {
}, },
'librechat': { 'librechat': {
"name": "LibreChat", "name": "LibreChat",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Face", "role": "Face",
"category": "Chat Agent Platform", "category": "Chat Agent Platform",
@ -105,7 +105,7 @@ TOOLS: dict[str, dict] = {
}, },
'flowise': { 'flowise': {
"name": "Flowise", "name": "Flowise",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Face", "role": "Face",
"category": "Workflow", "category": "Workflow",
@ -133,7 +133,7 @@ TOOLS: dict[str, dict] = {
}, },
'invokeai': { 'invokeai': {
"name": "InvokeAI", "name": "InvokeAI",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Face", "role": "Face",
"category": "Image Generation", "category": "Image Generation",
@ -163,7 +163,7 @@ TOOLS: dict[str, dict] = {
}, },
'forge': { 'forge': {
"name": "Forge (A1111)", "name": "Forge (A1111)",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Face", "role": "Face",
"category": "Image Generation", "category": "Image Generation",
@ -193,7 +193,7 @@ TOOLS: dict[str, dict] = {
}, },
'dashy': { 'dashy': {
"name": "Dashy", "name": "Dashy",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Face", "role": "Face",
"category": "Homepage", "category": "Homepage",
@ -221,7 +221,7 @@ TOOLS: dict[str, dict] = {
}, },
'obsidian': { 'obsidian': {
"name": "Obsidian", "name": "Obsidian",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Face", "role": "Face",
"category": "Knowledge Graph Notes", "category": "Knowledge Graph Notes",
@ -249,7 +249,7 @@ TOOLS: dict[str, dict] = {
}, },
'hermes': { 'hermes': {
"name": "Hermes", "name": "Hermes",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Face", "role": "Face",
"category": "Ecosystem Dashboard", "category": "Ecosystem Dashboard",
@ -279,7 +279,7 @@ TOOLS: dict[str, dict] = {
}, },
'hermes_desktop': { 'hermes_desktop': {
"name": "Hermes Desktop", "name": "Hermes Desktop",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Face", "role": "Face",
"category": "Desktop Agent", "category": "Desktop Agent",
@ -309,7 +309,7 @@ TOOLS: dict[str, dict] = {
}, },
'hermes_dashboard_page': { 'hermes_dashboard_page': {
"name": "Hermes Dashboard", "name": "Hermes Dashboard",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Face", "role": "Face",
"category": "Dashboard", "category": "Dashboard",
@ -339,7 +339,7 @@ TOOLS: dict[str, dict] = {
}, },
'local_llm_launcher': { 'local_llm_launcher': {
"name": "Local LLM Launcher", "name": "Local LLM Launcher",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Face", "role": "Face",
"category": "LLM GUI", "category": "LLM GUI",
@ -369,7 +369,7 @@ TOOLS: dict[str, dict] = {
}, },
'openjarvis': { 'openjarvis': {
"name": "OpenJarvis", "name": "OpenJarvis",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Central Intelligence", "role": "Central Intelligence",
"category": "AI Assistant Platform", "category": "AI Assistant Platform",
@ -408,7 +408,7 @@ TOOLS: dict[str, dict] = {
}, },
'deep_eye': { 'deep_eye': {
"name": "Deep Eye", "name": "Deep Eye",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Vision", "role": "Vision",
"category": "Computer Vision", "category": "Computer Vision",
@ -438,7 +438,7 @@ TOOLS: dict[str, dict] = {
}, },
'parakeet': { 'parakeet': {
"name": "Parakeet.cpp", "name": "Parakeet.cpp",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Senses", "role": "Senses",
"category": "Speech Recognition", "category": "Speech Recognition",
@ -468,7 +468,7 @@ TOOLS: dict[str, dict] = {
}, },
'luxtts': { 'luxtts': {
"name": "LuxTTS", "name": "LuxTTS",
"level": 8, "level": 9,
"layer": "User Interfaces", "layer": "User Interfaces",
"role": "Voice", "role": "Voice",
"category": "Text-to-Speech", "category": "Text-to-Speech",
@ -494,4 +494,71 @@ TOOLS: dict[str, dict] = {
"is_skills_collection": False "is_skills_collection": False
} }
}, },
'jan': {
"name": "Jan",
"level": 9,
"layer": "User Interfaces",
"role": "Face",
"category": "LLM GUI",
"installer": {
"type": "npm",
"pkg": "@janhq/jan"
},
"launcher": {
"type": "desktop",
"cmd": "jan",
"default_port": None
},
"deps": [],
"description": "Offline-capable ChatGPT-alternative desktop app with a "
"built-in llama.cpp engine and an OpenAI-compatible local "
"API server at 127.0.0.1:1337.",
"license": "AGPL-3.0",
"flags": {
"has_cli": True,
"has_gui": True,
"has_web": False,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
'hermes_webui': {
"name": "Hermes WebUI",
"level": 9,
"layer": "User Interfaces",
"role": "Face",
"category": "Chat Frontend",
"installer": {
"type": "uv",
"pkg": "open-webui"
},
"launcher": {
"type": "tmux",
"cmd": "open-webui serve --port {port} --data-dir {workspaces_root}/hermes-webui --env OLLAMA_BASE_URL=http://localhost:17051",
"default_port": 8081
},
"deps": [
"hermes_agent",
"ollama"
],
"description": "Hermes-themed Open-WebUI instance running on a "
"separate port (8081) with its own data volume so "
"users, prompts, and RAG corpus don't collide with "
"the general openwebui instance. Backend points at "
"hermes_agent (17051) instead of Ollama direct, so "
"every conversation goes through the Hermes runtime.",
"license": "MIT",
"flags": {
"has_cli": False,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False
}
},
} }

View File

@ -8,7 +8,7 @@ tool's ``license`` SPDX ID against three sources:
tool_id is blocked, raise :class:`LicenseBlocked` immediately. No tool_id is blocked, raise :class:`LicenseBlocked` immediately. No
dialog, no acceptance, no install. dialog, no acceptance, no install.
2. **Auto-approval registry** (``config/license_approvals.json``) — a 2. **Auto-approval registry** (``configs/license_approvals.json``) — a
user-editable list of OSI-approved SPDX IDs that have been user-editable list of OSI-approved SPDX IDs that have been
pre-approved. If the tool's license is in this list, install pre-approved. If the tool's license is in this list, install
proceeds without a dialog. Only OSI-approved licenses can appear proceeds without a dialog. Only OSI-approved licenses can appear
@ -28,7 +28,7 @@ the install.
Files managed Files managed
------------- -------------
* ``config/license_approvals.json`` — ``{"licenses": ["MIT", "Apache-2.0"], "updated_at": "..."}`` * ``configs/license_approvals.json`` — ``{"licenses": ["MIT", "Apache-2.0"], "updated_at": "..."}``
* ``config/license_acceptances.json`` — ``{"ollama": {"spdx": "MIT", "accepted_at": "...", "via": "auto-approved"}, ...}`` * ``config/license_acceptances.json`` — ``{"ollama": {"spdx": "MIT", "accepted_at": "...", "via": "auto-approved"}, ...}``
""" """

View File

@ -20,7 +20,7 @@ Defines the three license categories the AI-LSC license gate recognizes:
a prominent disclaimer warning about ToS restrictions before a prominent disclaimer warning about ToS restrictions before
install. Example: Claude Code (Anthropic ToS). install. Example: Claude Code (Anthropic ToS).
The license-approvals registry (``config/license_approvals.json``) is The license-approvals registry (``configs/license_approvals.json``) is
a user-editable list of SPDX IDs that have been pre-approved. Only a user-editable list of SPDX IDs that have been pre-approved. Only
OSI-approved licenses can appear in this list — the OSI-approved licenses can appear in this list — the
:func:`LicenseGate.add_auto_approval` method rejects attempts to :func:`LicenseGate.add_auto_approval` method rejects attempts to
@ -224,6 +224,71 @@ CATALOG: dict[str, LicenseInfo] = {
"commercial use and modification." "commercial use and modification."
), ),
), ),
"LGPL-2.1": LicenseInfo(
spdx="LGPL-2.1",
name="GNU Lesser General Public License v2.1",
category=Category.OSI,
url="https://opensource.org/licenses/LGPL-2.1",
summary=(
"Weak copyleft license allowing linking from proprietary "
"software, but modifications to the LGPL-licensed code itself "
"must be shared under LGPL. Used by strace, LXC, libvirt."
),
),
"GPL-1.0": LicenseInfo(
spdx="GPL-1.0",
name="GNU General Public License v1.0",
category=Category.OSI,
url="https://opensource.org/licenses/GPL-1.0",
summary=(
"The original 1989 GNU copyleft license. Superseded by "
"GPL-2.0/GPL-3.0 but still applied by some legacy packages "
"(e.g. Perl)."
),
),
"PHP-3.01": LicenseInfo(
spdx="PHP-3.01",
name="PHP License v3.01",
category=Category.OSI,
url="https://opensource.org/licenses/PHP-3.01",
summary=(
"Permissive, PHP-specific license governing the PHP "
"interpreter. Allows commercial use and modification with "
"copyright notice; not derivatively-named redistribution."
),
),
"Ruby": LicenseInfo(
spdx="Ruby",
name="Ruby License",
category=Category.OSI,
url="https://www.ruby-lang.org/en/about/license.txt",
summary=(
"Permissive dual license (Ruby's own terms or BSD-2-Clause) "
"governing the Ruby interpreter and standard library."
),
),
"MirOS": LicenseInfo(
spdx="MirOS",
name="MirOS License",
category=Category.OSI,
url="https://opensource.org/licenses/MirOS",
summary=(
"Permissive BSD-style license with attribution requirement, "
"used by MirBSD and mksh."
),
),
"MIT/Apache-2.0": LicenseInfo(
spdx="MIT/Apache-2.0",
name="MIT OR Apache-2.0 (dual license)",
category=Category.OSI,
url="https://opensource.org/licenses/Apache-2.0",
summary=(
"Dual licensing under MIT OR Apache-2.0 at the recipient's "
"choice — the standard convention for Rust crates (and tools "
"like uv). Either grant applies; Apache-2.0 adds a patent "
"grant."
),
),
# ── Source-available / fair-code (NOT auto-approvable) ─────────── # ── Source-available / fair-code (NOT auto-approvable) ───────────
"BSL-1.1": LicenseInfo( "BSL-1.1": LicenseInfo(

View File

@ -133,6 +133,10 @@ class RegistryManager:
).append((t_id, meta)) ).append((t_id, meta))
return dict(sorted(layers.items())) return dict(sorted(layers.items()))
# Host-level prerequisites referenced in deps but not managed as
# registry tools (mirrors _system_deps in stack/connections.py).
SYSTEM_DEPS: frozenset[str] = frozenset({"kubectl", "java"})
def check_dependencies( def check_dependencies(
self, selected: list[str], self, selected: list[str],
) -> list[str]: ) -> list[str]:
@ -142,4 +146,7 @@ class RegistryManager:
for t in selected for t in selected
if not t.startswith("skill:") if not t.startswith("skill:")
)) ))
return list({d for d in all_deps if d not in selected}) return list({
d for d in all_deps
if d not in selected and d not in self.SYSTEM_DEPS
})

View File

@ -0,0 +1,48 @@
{
"id": "local-coder-mesh",
"name": "Local Coder Mesh — All-Ollama Coding Stack",
"description": "Every coding agent in this stack speaks OpenAI-compat and points at localhost Ollama, MeshLLM, or LiteLLM. Includes the four tools missing from the existing hermes-ai-coder-stack template: PiCode, MeshLLM (the native GPU-pooling mesh binary from Mesh-LLM/mesh-llm, NOT a LiteLLM re-skin), Hermes WebUI, ZCoder. Also includes Graphify for knowledge-graph-aware coding. Use this template when you want the complete local coding-agent fleet wired to one Ollama instance with no cloud calls.",
"version": "1.1",
"author": "ai-lsc-template-pack",
"tags": ["coding", "agent", "local-first", "ollama", "mesh", "hermes", "native", "knowledge-graph"],
"endpoints": {
"ollama_base": "http://localhost:11434/v1",
"litellm_base": "http://localhost:4000",
"meshllm_api": "http://localhost:9337/v1",
"meshllm_console": "http://localhost:3131",
"openwebui": "http://localhost:3000",
"hermes_webui": "http://localhost:8081",
"hermes_agent": "http://localhost:17051",
"hermes_dashboard": "http://localhost:17050"
},
"tools": [
"ollama",
"litellm",
"meshllm",
"picode",
"aider",
"odysseus",
"opencode",
"zcoder",
"graphify",
"hermes",
"hermes_agent",
"hermes_webui",
"hermes_desktop",
"openwebui",
"ripgrep",
"fd",
"tree_sitter"
],
"notes": {
"philosophy": "One Ollama, one mesh (MeshLLM for multi-node pooling, LiteLLM for proxy routing), every coding agent speaks OpenAI-compat to localhost. No cloud calls, no containers in the dev path — ai-lsc's Podman/Docker/LXC/Firecracker export is reserved for total-stack export only.",
"meshllm_clarification": "MeshLLM is the native binary from https://github.com/Mesh-LLM/mesh-llm. It pools GPUs and memory across machines, exposes one OpenAI-compat API at :9337, and has a web console at :3131. It is NOT a LiteLLM re-skin — the two tools coexist in this template: MeshLLM for mesh-pooled multi-node inference, LiteLLM for proxy routing to multiple backends. Coding agents prefer MeshLLM (:9337) first, fall back to LiteLLM (:4000), then Ollama direct (:11434).",
"graphify_role": "Graphify (https://github.com/Graphify-Labs/graphify) builds knowledge graphs from code, docs, PDFs, and images. It runs as a CLI (pip install graphifyy), a Claude Code skill (/graphify .), or an MCP stdio server (graphify --mcp). Other agents in this stack can query graphify's MCP server to navigate the codebase graph without re-reading source files — 71.5x fewer tokens per query vs reading raw files. Uses Claude vision by default but can be configured to use MeshLLM/LiteLLM/Ollama for fully-local extraction.",
"topology": "ollama (11434) <- litellm (4000, proxy mesh) + meshllm (9337, native mesh) <- {picode, aider, odysseus, opencode, zcoder}. graphify builds graphs from the codebase and exposes an MCP server that the coding agents query. hermes_webui + hermes_desktop talk to hermes (17050) -> hermes_agent (17051) -> ollama. openwebui talks to ollama directly. ripgrep + fd + tree_sitter are passive filesystem tools used by the coding agents for repo-map / symbol navigation.",
"recommended_models": "qwen2.5-coder:7b (fast coding), qwen2.5-coder:32b (heavy coding), hermes3:8b (Hermes stack), nomic-embed-text (openwebui RAG, corpus indexing, graphify embeddings). MeshLLM auto-downloads a suitable model on first `serve --auto` if none specified.",
"install_order": "1) ollama (already running). 2) litellm (proxy mesh) + meshllm (native mesh binary via curl installer). 3) hermes_agent -> hermes -> hermes_webui + hermes_desktop. 4) aider, picode, odysseus, opencode, zcoder (CLI agents, all native venvs/uv/npm). 5) graphify (uv install graphifyy). 6) openwebui (native uv). 7) ripgrep, fd, tree_sitter (pacman).",
"native_only_policy": "Every tool in this template installs natively into /mnt/AI/runtime/<tool_id>/ (venv/uv) or via pacman/AUR/curl-script. ai-lsc's container export feature is intentionally not used at install time — it's reserved for total-stack deployment exports via the Stack Editor.",
"non_destructive_policy": "Applying this template never removes existing installs. ai-lsc's InstallerManager.preflight() detects existing installs and skips them unless force=True.",
"missing_tools_added_by_template_pack": "picode, meshllm, hermes_webui, zcoder — these four require the registry + wirings patches in this template pack before the template will compile. graphify already exists in the registry but needs the graphify-update.diff and graphify-wiring-update.diff patches to fix its URL (Graphify-Labs/graphify), license (MIT), role (Knowledge Graph Builder), installer (uv graphifyy), and wiring (MCP server + LLM backend connections). See MERGE-GUIDE.md."
}
}

View File

@ -632,7 +632,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="heretic", tool_id="heretic",
layer="GPU Runtimes", layer="Engines",
interfaces=[], interfaces=[],
connections=[ connections=[
Connection( Connection(
@ -656,7 +656,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="unsloth", tool_id="unsloth",
layer="GPU Runtimes", layer="Development Environment",
interfaces=[], interfaces=[],
connections=[ connections=[
Connection( Connection(
@ -771,7 +771,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="vllm", tool_id="vllm",
layer="Orchestrators", layer="Engines",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="openai_api", interface_id="openai_api",
@ -931,12 +931,12 @@ _reg(StackWiring(
# ────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────
# L6: AI Endpoints # L6: AI Endpoints (→ the restored "Routing" layer in the 11-layer taxonomy)
# ────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────
_reg(StackWiring( _reg(StackWiring(
tool_id="litellm", tool_id="litellm",
layer="Orchestrators", layer="Routing",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="openai_api", interface_id="openai_api",
@ -1015,7 +1015,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="9router_proxy", tool_id="9router_proxy",
layer="Orchestrators", layer="Routing",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="router_api", interface_id="router_api",
@ -1041,7 +1041,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="deep_eye", tool_id="deep_eye",
layer="Orchestrators", layer="User Interfaces",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="deep_eye_api", interface_id="deep_eye_api",
@ -1066,7 +1066,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="luxtts", tool_id="luxtts",
layer="Orchestrators", layer="User Interfaces",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="tts_api", interface_id="tts_api",
@ -1234,7 +1234,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="parakeet", tool_id="parakeet",
layer="Knowledge Management", layer="User Interfaces",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="parakeet_api", interface_id="parakeet_api",
@ -1306,7 +1306,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="fabric", tool_id="fabric",
layer="Knowledge Management", layer="Orchestrators",
interfaces=[], interfaces=[],
connections=[], connections=[],
context=EngineeringContext( context=EngineeringContext(
@ -1408,7 +1408,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="n8n", tool_id="n8n",
layer="DevOps", layer="Orchestrators",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="n8n_api", interface_id="n8n_api",
@ -1454,7 +1454,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="nightshift", tool_id="nightshift",
layer="DevOps", layer="Orchestrators",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="nightshift_api", interface_id="nightshift_api",
@ -1470,7 +1470,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="hivemind", tool_id="hivemind",
layer="DevOps", layer="Orchestrators",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="hivemind_api", interface_id="hivemind_api",
@ -1495,7 +1495,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="hermes_agent", tool_id="hermes_agent",
layer="DevOps", layer="Orchestrators",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="hermes_agent_api", interface_id="hermes_agent_api",
@ -1546,7 +1546,7 @@ _reg(StackWiring(
# Passive / CLI-only tools in L8 — no interfaces or network connections # Passive / CLI-only tools in L8 — no interfaces or network connections
for _tid in [ for _tid in [
"agent_reach", "agentic_os", "aider", "algory", "atlas_os", "agent_reach", "agentic_os", "aider", "algory", "atlas_os",
"claude_code", "eagle_eye", "graphify", "headroom", "honcho", "claude_code", "eagle_eye", "headroom", "honcho",
"loop_engineering", "mcp_drift_state_tracker", "nvidia_agent_skills", "loop_engineering", "mcp_drift_state_tracker", "nvidia_agent_skills",
"ponytail", "promptops", "skillspector", "spec_kit", "synapscli", "ponytail", "promptops", "skillspector", "spec_kit", "synapscli",
"wayland_ai", "wayland_ai",
@ -1595,7 +1595,7 @@ for _tid in [
# agno has a web interface but no deps in defaults # agno has a web interface but no deps in defaults
_reg(StackWiring( _reg(StackWiring(
tool_id="agno", tool_id="agno",
layer="DevOps", layer="Orchestrators",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="agno_web", interface_id="agno_web",
@ -1787,7 +1787,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="hermes_dashboard_page", tool_id="hermes_dashboard_page",
layer="Observability", layer="User Interfaces",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="dashboard_api", interface_id="dashboard_api",
@ -1837,7 +1837,7 @@ _reg(StackWiring(
# ────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────
# L10: Intelligent Routing # L10: Intelligent Routing (folded into "Orchestrators" in the 11-layer taxonomy)
# ────────────────────────────────────────────────────────────────── # ──────────────────────────────────────────────────────────────────
_reg(StackWiring( _reg(StackWiring(
@ -1892,7 +1892,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="mnemo_cortex", tool_id="mnemo_cortex",
layer="Orchestrators", layer="Knowledge Management",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="mnemo_cortex_api", interface_id="mnemo_cortex_api",
@ -1942,7 +1942,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="everos_memory", tool_id="everos_memory",
layer="Orchestrators", layer="Knowledge Management",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="everos_memory_api", interface_id="everos_memory_api",
@ -2049,7 +2049,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="dify", tool_id="dify",
layer="User Interfaces", layer="Routing",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="dify_web", interface_id="dify_web",
@ -2271,7 +2271,7 @@ _reg(StackWiring(
_reg(StackWiring( _reg(StackWiring(
tool_id="langflow", tool_id="langflow",
layer="User Interfaces", layer="Orchestrators",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="langflow_web", interface_id="langflow_web",
@ -2381,7 +2381,7 @@ for _tid in ["hermes_desktop", "local_llm_launcher"]:
_reg(StackWiring( _reg(StackWiring(
tool_id="opensandbox", tool_id="opensandbox",
layer="DevOps", layer="Orchestrators",
interfaces=[ interfaces=[
ToolInterface( ToolInterface(
interface_id="opensandbox_web", interface_id="opensandbox_web",
@ -2529,6 +2529,378 @@ for _tid in [
)) ))
# ──────────────────────────────────────────────────────────────────
# L5 additions: terminal coding agents (registry expansion pass)
# (coding agents now live in DevOps L10; meshllm/picode in Routing L5)
# opencode / gemini_cli / qwen_code / goose / codex — all multi-provider
# CLI agents that consume an OpenAI-compatible endpoint. Wired to both
# Ollama (direct) and LiteLLM (proxied) so staging either backend
# prevents orphan-flagging in the Pipeline Ticker.
# ──────────────────────────────────────────────────────────────────
_CODING_AGENT_CTX = EngineeringContext(
decision="Terminal coding agents consume an OpenAI-compatible "
"chat endpoint for LLM inference.",
observation="Every modern coding agent (opencode, Gemini CLI, "
"Qwen Code, goose, Codex) speaks the OpenAI wire "
"format for at least one provider slot.",
alternatives="Native provider SDKs (Anthropic, Google) or a "
"custom proxy.",
constraints="The endpoint must be reachable and expose "
"/v1/chat/completions.",
reasoning="OpenAI-compat is the de-facto agent ↔ LLM contract; "
"pointing the agents at localhost keeps inference "
"local per AI-LSC policy.",
verification="Set the agent's base-URL env var to "
"http://127.0.0.1:11434/v1 and list models.",
lineage="Mirrors the OpenAI API spec; adopted by Ollama, vLLM, "
"SGLang, LiteLLM.",
assumptions="At least one model is served by the target backend.",
)
_reg(StackWiring(
tool_id="opencode",
layer="DevOps",
interfaces=[],
connections=[
Connection(
target_tool="ollama",
interface_id="openai_api",
purpose="Local LLM inference for terminal coding sessions.",
config_key="OPENAI_BASE_URL (ollama provider, opencode.json)",
required=False,
context=_CODING_AGENT_CTX,
),
Connection(
target_tool="litellm",
interface_id="openai_api",
purpose="Multi-model routing via LiteLLM proxy.",
config_key="OPENAI_BASE_URL",
required=False,
context=_LITELLM_CONSUMER_CTX,
),
],
))
_reg(StackWiring(
tool_id="gemini_cli",
layer="DevOps",
interfaces=[],
connections=[
Connection(
target_tool="ollama",
interface_id="openai_api",
purpose="Local LLM inference via the openai-compat provider.",
config_key="OPENAI_BASE_URL",
required=False,
context=_CODING_AGENT_CTX,
),
Connection(
target_tool="litellm",
interface_id="openai_api",
purpose="Multi-model routing via LiteLLM proxy.",
config_key="OPENAI_BASE_URL",
required=False,
context=_LITELLM_CONSUMER_CTX,
),
],
))
_reg(StackWiring(
tool_id="qwen_code",
layer="DevOps",
interfaces=[],
connections=[
Connection(
target_tool="ollama",
interface_id="openai_api",
purpose="Local Qwen model inference via openai-compat provider.",
config_key="OPENAI_BASE_URL",
required=False,
context=_CODING_AGENT_CTX,
),
Connection(
target_tool="litellm",
interface_id="openai_api",
purpose="Multi-model routing via LiteLLM proxy.",
config_key="OPENAI_BASE_URL",
required=False,
context=_LITELLM_CONSUMER_CTX,
),
],
))
_reg(StackWiring(
tool_id="goose",
layer="DevOps",
interfaces=[],
connections=[
Connection(
target_tool="ollama",
interface_id="openai_api",
purpose="Local LLM backend for goose sessions and MCP extensions.",
config_key="GOOSE_PROVIDER / OPENAI_BASE_URL",
required=False,
context=_CODING_AGENT_CTX,
),
Connection(
target_tool="litellm",
interface_id="openai_api",
purpose="Multi-model routing via LiteLLM proxy.",
config_key="OPENAI_BASE_URL",
required=False,
context=_LITELLM_CONSUMER_CTX,
),
],
))
# codex existed in the registry since v3.1 but had no STACK_WIRINGS
# entry, so it was flagged as an orphan by the Pipeline Ticker whenever
# it was staged. This wiring closes that gap.
_reg(StackWiring(
tool_id="codex",
layer="DevOps",
interfaces=[],
connections=[
Connection(
target_tool="ollama",
interface_id="openai_api",
purpose="Local LLM inference for terminal coding sessions.",
config_key="OPENAI_BASE_URL",
required=False,
context=_CODING_AGENT_CTX,
),
Connection(
target_tool="litellm",
interface_id="openai_api",
purpose="Multi-model routing via LiteLLM proxy.",
config_key="OPENAI_BASE_URL",
required=False,
context=_LITELLM_CONSUMER_CTX,
),
],
))
_reg(StackWiring(
tool_id="letta",
layer="Orchestrators",
interfaces=[
ToolInterface(
interface_id="http_api",
protocol="HTTP",
api_format="REST",
port=8283,
auth="Optional password (LETTA_SERVER_PASSWORD)",
description="Letta agent server REST API — create/state/"
"message agents with persistent memory.",
context=EngineeringContext(
decision="Expose the Letta server REST API as its "
"primary interface.",
observation="Letta (formerly MemGPT) manages stateful "
"agents whose memory/context survives across "
"sessions; the REST API is the management "
"surface.",
alternatives="Python SDK in-process, or Letta Cloud "
"(SaaS — excluded by policy).",
constraints="Requires a database — SQLite by default, "
"PostgreSQL recommended for persistence.",
reasoning="A local agent-memory server complements "
"stateless coding agents in the stack.",
verification="curl http://localhost:8283/v1/agents",
lineage="Letta — https://docs.letta.com/",
),
),
],
connections=[
Connection(
target_tool="ollama",
interface_id="openai_api",
purpose="LLM inference for agent reasoning and memory operations.",
config_key="LETTA_INFERENCE_BASE_URL / model config",
required=False,
context=_OLLAMA_CONSUMER_CTX,
),
Connection(
target_tool="postgresql",
interface_id="postgresql",
purpose="Persistent agent/state storage (SQLite fallback).",
config_key="LETTA_PG_URI",
required=False,
context=EngineeringContext(
decision="PostgreSQL as the optional durable backend for "
"Letta's state store.",
observation="Letta defaults to SQLite; PostgreSQL is "
"recommended for multi-user / long-lived "
"deployments.",
alternatives="Built-in SQLite (zero-config).",
reasoning="Sharing one PostgreSQL instance with other "
"stack tools keeps state management uniform.",
verification="letta server with LETTA_PG_URI set; "
"inspect created tables.",
lineage="Letta — https://docs.letta.com/",
),
),
],
))
_reg(StackWiring(
tool_id="sglang",
layer="Engines",
interfaces=[
ToolInterface(
interface_id="openai_api",
protocol="HTTP",
api_format="OpenAI",
port=30000,
base_path="/v1",
auth="None (or API key if configured)",
description="SGLang OpenAI-compatible API: /v1/chat/completions, "
"/v1/models, /v1/embeddings. High-throughput serving "
"with RadixAttention prefix caching.",
context=EngineeringContext(
decision="Expose SGLang's OpenAI-compatible API as its "
"primary interface.",
observation="SGLang rivals vLLM on throughput for "
"many-workload serving, and prefix caching "
"benefits agentic loops that resend context.",
alternatives="vLLM (port 8000), Ollama, llama.cpp server.",
constraints="Requires a CUDA GPU with sufficient VRAM for "
"the target model.",
reasoning="OpenAI API compatibility lets every consumer in "
"the stack use SGLang without code changes.",
verification="curl http://localhost:30000/v1/models",
lineage="SGLang — https://docs.sglang.ai/",
),
),
],
connections=[
Connection(
target_tool="cuda",
interface_id="cuda_driver",
purpose="GPU-accelerated inference kernels.",
config_key="CUDA_VISIBLE_DEVICES",
required=True,
context=EngineeringContext(
decision="SGLang requires CUDA for its serving kernels.",
observation="SGLang's throughput comes from custom CUDA "
"kernels and RadixAttention.",
reasoning="SGLang without a GPU has no advantage over "
"llama.cpp on CPU.",
verification="nvidia-smi confirms driver and GPU availability.",
lineage="SGLang — https://docs.sglang.ai/",
),
),
],
))
# ──────────────────────────────────────────────────────────────────
# L8 / L10 / L3 additions: jan, mem0, tinygrad
# ──────────────────────────────────────────────────────────────────
_reg(StackWiring(
tool_id="jan",
layer="User Interfaces",
interfaces=[
ToolInterface(
interface_id="openai_api",
protocol="HTTP",
api_format="OpenAI",
port=1337,
base_path="/v1",
auth="None (local only)",
description="Jan's built-in OpenAI-compatible local API server "
"powered by its bundled llama.cpp engine — a "
"drop-in replacement for cloud APIs.",
context=EngineeringContext(
decision="Expose Jan's local API server as its wiring "
"interface.",
observation="Jan is a self-contained desktop app: engine, "
"model manager, and API server in one; the API "
"server listens on 127.0.0.1:1337.",
alternatives="Ollama as the engine with a separate chat UI.",
constraints="The API server toggle must be enabled in Jan's "
"settings; Electron desktop UI is not "
"web-embeddable.",
reasoning="A GUI chat app that also serves an "
"OpenAI-compatible endpoint doubles as an "
"inference provider for other stack tools.",
verification="curl http://127.0.0.1:1337/v1/models",
lineage="Jan — https://jan.ai/docs/desktop/api-server",
assumptions="API server enabled (default on recent builds).",
),
),
],
connections=[],
))
_reg(StackWiring(
tool_id="mem0",
layer="Knowledge Management",
interfaces=[],
connections=[
Connection(
target_tool="ollama",
interface_id="openai_api",
purpose="LLM inference for memory extraction/summarisation "
"and embeddings for memory vectors.",
config_key="OPENAI_BASE_URL / embedding model config",
required=False,
context=_OLLAMA_CONSUMER_CTX,
),
Connection(
target_tool="qdrant",
interface_id="http_api",
purpose="Vector storage for long-term memories.",
config_key="QDRANT_HOST",
required=False,
context=EngineeringContext(
decision="Qdrant as an optional external vector backend "
"for stored memories.",
observation="Mem0 ships with an embedded vector store by "
"default and supports pluggable backends "
"(Qdrant, Chroma, pgvector).",
alternatives="Mem0's built-in store, or ChromaDB.",
reasoning="Sharing one Qdrant instance across knowledge "
"tools keeps embeddings co-located.",
verification="Configure vector_store.provider=qdrant in "
"mem0 config; run a memory add + search.",
lineage="Mem0 — https://docs.mem0.ai/",
),
),
],
))
_reg(StackWiring(
tool_id="tinygrad",
layer="GPU Runtimes",
interfaces=[],
connections=[
Connection(
target_tool="cuda",
interface_id="cuda_driver",
purpose="GPU-accelerated tensor ops on NVIDIA backends.",
config_key="CUDA_VISIBLE_DEVICES",
required=False,
context=EngineeringContext(
decision="CUDA is optional — tinygrad also runs on CPU and "
"AMD backends.",
observation="tinygrad's lazy execution compiles kernels per "
"backend at runtime; the NVIDIA backend needs "
"the CUDA driver.",
alternatives="CuPy for NumPy-compat GPU arrays; PyTorch for "
"a full training stack.",
reasoning="Wiring CUDA (optionally) surfaces tinygrad in "
"the ticker when a GPU stack is staged, without "
"forcing it on CPU-only hosts.",
verification="python3 -c \"from tinygrad import Tensor; "
"print(Tensor([1,2,3]).sum().item())\"",
lineage="tinygrad — https://github.com/tinygrad/tinygrad",
),
),
],
))
# ══════════════════════════════════════════════════════════════════ # ══════════════════════════════════════════════════════════════════
# Topology query helpers # Topology query helpers
# ══════════════════════════════════════════════════════════════════ # ══════════════════════════════════════════════════════════════════
@ -2637,3 +3009,391 @@ def validate_wiring() -> list[str]:
f"(available: {sorted(target_iface_ids) or 'none'})" f"(available: {sorted(target_iface_ids) or 'none'})"
) )
return errors return errors
# ──────────────────────────────────────────────────────────────────
# Graphify — knowledge graph builder + MCP server (rewired from passive)
# Removed from the L8 passive/CLI list above and given a proper wiring
# since graphify is both a CLI tool and an MCP stdio server.
# ──────────────────────────────────────────────────────────────────
_reg(StackWiring(
tool_id="graphify",
layer="Orchestrators",
interfaces=[
ToolInterface(
interface_id="graphify_mcp",
protocol="stdio",
api_format="MCP",
port=None,
base_path="",
auth="None (local stdio)",
description="Graphify MCP stdio server. Start with "
"`graphify --mcp`. Other MCP-aware agents "
"(Claude Code, opencode with MCP support, "
"etc.) can query the knowledge graph via the "
"standard MCP protocol. Exposes tools for "
"graph query, path finding, and concept "
"explanation.",
context=EngineeringContext(
decision="Expose graphify as an MCP server so other "
"agents can query its knowledge graph.",
observation="Graphify's --mcp mode runs a stdio MCP "
"server. Any MCP-aware agent can call "
"graphify's query/path/explain tools to "
"navigate the codebase graph without "
"re-reading source files.",
alternatives="CLI-only mode (graphify query '...') "
"or direct graph.json consumption.",
constraints="Graph must be built first via "
"`graphify .` before the MCP server can "
"answer queries.",
reasoning="MCP is the standard agent-to-tool protocol. "
"Exposing graphify via MCP lets every coding "
"agent in the stack benefit from the "
"knowledge graph without each one needing "
"a custom graphify integration.",
verification="Start `graphify --mcp` and send an MCP "
"initialize request on stdin.",
lineage="Graphify — https://github.com/Graphify-Labs/graphify",
assumptions="graphify installed (uv tool graphifyy) and "
"a graph has been built in the working "
"directory.",
),
),
],
connections=[
Connection(
target_tool="meshllm",
interface_id="openai_api",
purpose="Optional LLM backend for graphify's vision/extraction "
"pass. Graphify defaults to Claude (Anthropic API); "
"users who want fully-local extraction can configure "
"it to use MeshLLM (:9337/v1) instead.",
config_key="OPENAI_API_BASE (set to http://localhost:9337/v1 "
"to route extraction through the mesh)",
required=False,
context=EngineeringContext(
decision="Graphify can use MeshLLM as its extraction "
"backend instead of Claude.",
observation="Graphify uses an LLM to extract concepts "
"and relationships from files. The default "
"is Claude (Anthropic), but it speaks "
"OpenAI-compat so any OpenAI-format endpoint "
"works.",
reasoning="For a fully-local stack, route graphify's "
"extraction through MeshLLM or Ollama direct. "
"Claude gives better vision results for "
"images/diagrams, so the connection is "
"optional — users choose.",
lineage="Graphify docs — https://github.com/Graphify-Labs/graphify",
assumptions="MeshLLM has a vision-capable model if the "
"corpus contains images.",
),
),
Connection(
target_tool="litellm",
interface_id="openai_api",
purpose="Fallback LLM backend (general LiteLLM proxy on :4000).",
config_key="OPENAI_API_BASE",
required=False,
context=_LITELLM_CONSUMER_CTX,
),
Connection(
target_tool="ollama",
interface_id="openai_api",
purpose="Direct Ollama fallback for extraction (bypass both "
"meshes). Useful for single-node setups without "
"MeshLLM.",
config_key="OPENAI_API_BASE (set to http://localhost:11434/v1)",
required=False,
context=EngineeringContext(
decision="Ollama direct as a third extraction option.",
observation="Same OpenAI-compat contract as MeshLLM "
"and LiteLLM.",
reasoning="Single-node users who don't need mesh "
"pooling can point graphify straight at "
"Ollama for the extraction LLM calls.",
),
),
],
))
_reg(StackWiring(
tool_id="meshllm",
layer="Routing",
interfaces=[
ToolInterface(
interface_id="openai_api",
protocol="HTTP",
api_format="OpenAI",
port=9337,
base_path="/v1",
auth="API key (MESH_LLM_KEY, optional — local mesh is open by default)",
description="MeshLLM unified API. Exposes a single "
"OpenAI-compatible endpoint that routes requests "
"across pooled GPUs/memory. Supports "
"/v1/chat/completions, /v1/models, "
"/v1/embeddings. The mesh decides whether a "
"model runs locally, routes to a peer node, or "
"uses Skippy stage splits for models too large "
"for one box. Use model='mesh' to fan out one "
"prompt to every model in the mesh (MoA gateway).",
context=EngineeringContext(
decision="MeshLLM as the mesh-pooling LLM gateway for "
"multi-node inference.",
observation="MeshLLM pools GPUs and memory across "
"machines. Every node exposes the same /v1 "
"API. Requests are routed by the 'model' "
"field to the peer that can serve that "
"model. QUIC end-to-end encrypts peer "
"traffic via Iroh relays.",
alternatives="LiteLLM (proxy only, no mesh pooling), "
"vLLM (single-node high-throughput), "
"direct Ollama (single-node).",
constraints="mesh-llm setup must be run before first "
"serve. Multi-node mesh requires peers to "
"be discoverable via Nostr (public mesh) "
"or invite token (private mesh).",
reasoning="MeshLLM is the only tool in the stack that "
"can split a model too large for one GPU "
"across multiple nodes (Skippy stage splits). "
"For single-node workloads, Ollama or LiteLLM "
"are simpler; MeshLLM shines when you add a "
"second machine.",
verification="curl http://localhost:9337/v1/models",
lineage="MeshLLM — https://github.com/Mesh-LLM/mesh-llm",
assumptions="mesh-llm binary installed and `mesh-llm "
"setup` completed. At least one model is "
"available (auto-downloaded by `serve --auto` "
"or specified via --model).",
),
),
ToolInterface(
interface_id="mesh_web_console",
protocol="HTTP",
api_format="REST",
port=3131,
base_path="",
auth="None (local only)",
description="MeshLLM web console. Browser UI for mesh "
"management, node inventory, model routing, "
"and peer discovery. Use `mesh-llm serve "
"--headless` to hide the console while "
"keeping the management API.",
context=EngineeringContext(
decision="Expose a separate web console port for mesh "
"management.",
observation="The console is a browser UI distinct from "
"the OpenAI-compat API. Operators use it "
"to monitor mesh health, add peers, and "
"configure model routing.",
reasoning="Separating management UI from inference API "
"lets operators lock down :9337 (inference) "
"while keeping :3131 (console) accessible "
"only on the LAN.",
verification="curl http://localhost:3131/",
lineage="MeshLLM console — https://github.com/Mesh-LLM/mesh-llm",
assumptions="MeshLLM was started without --headless.",
),
),
],
connections=[
Connection(
target_tool="ollama",
interface_id="openai_api",
purpose="Optional: use Ollama as a local-model backend via "
"`mesh-llm client --auto` (API-only client mode). "
"When configured, MeshLLM routes to Ollama for "
"models not served by the mesh itself.",
config_key="mesh-llm client --auto (reads OLLAMA_BASE_URL)",
required=False,
context=EngineeringContext(
decision="Ollama is an OPTIONAL backend for MeshLLM, "
"not a required one.",
observation="MeshLLM can load GGUF models directly "
"(--model /path/to/model.gguf) without "
"Ollama. The `mesh-llm client --auto` "
"subcommand turns MeshLLM into a pure "
"client that routes to other meshes or "
"Ollama-compatible backends.",
reasoning="In the local-coder-mesh stack, most users "
"will run MeshLLM standalone (it auto-"
"downloads a suitable model). The Ollama "
"connection is for users who want to expose "
"their existing Ollama model fleet through "
"the mesh routing layer.",
),
),
],
))
# ──────────────────────────────────────────────────────────────────
# PiCode — coding agent, consumes mesh first, falls back to LiteLLM + Ollama
# ──────────────────────────────────────────────────────────────────
_reg(StackWiring(
tool_id="picode",
layer="Routing",
interfaces=[],
connections=[
Connection(
target_tool="meshllm",
interface_id="openai_api",
purpose="Primary LLM route for PiCode — mesh-pooled inference "
"across all available nodes.",
config_key="OPENAI_API_BASE (set to http://localhost:9337/v1)",
required=False,
context=EngineeringContext(
decision="PiCode points at MeshLLM first.",
observation="MeshLLM's :9337 endpoint gives PiCode "
"access to every model in the mesh via "
"one URL.",
alternatives="LiteLLM proxy (localhost:4000) or direct "
"Ollama (localhost:11434).",
reasoning="Mesh-pooled inference is preferable when "
"available — it can serve models larger than "
"any single GPU via Skippy stage splits.",
verification="Set OPENAI_API_BASE=http://localhost:9337/v1 "
"and list models.",
lineage="PiCode — https://github.com/jasonjmcghee/picode",
assumptions="MeshLLM is running and has at least one "
"model available.",
),
),
Connection(
target_tool="litellm",
interface_id="openai_api",
purpose="Fallback mesh (general LiteLLM proxy on :4000).",
config_key="OPENAI_API_BASE",
required=False,
context=_LITELLM_CONSUMER_CTX,
),
Connection(
target_tool="ollama",
interface_id="openai_api",
purpose="Direct Ollama fallback (bypass both meshes).",
config_key="OPENAI_API_BASE",
required=False,
context=_CODING_AGENT_CTX,
),
],
))
# ──────────────────────────────────────────────────────────────────
# ZCoder — coding agent, same consumer pattern as PiCode
# ──────────────────────────────────────────────────────────────────
_reg(StackWiring(
tool_id="zcoder",
layer="DevOps",
interfaces=[],
connections=[
Connection(
target_tool="meshllm",
interface_id="openai_api",
purpose="Primary LLM route for ZCoder — mesh-pooled inference.",
config_key="OPENAI_API_BASE (set to http://localhost:9337/v1)",
required=False,
context=EngineeringContext(
decision="ZCoder points at MeshLLM first.",
observation="Same OpenAI-compat contract as PiCode.",
reasoning="Consistent routing across all coding agents "
"in the stack — they all prefer the mesh.",
lineage="ZCoder (Zhipu AI)",
assumptions="MeshLLM is running.",
),
),
Connection(
target_tool="litellm",
interface_id="openai_api",
purpose="Fallback mesh (general LiteLLM proxy).",
config_key="OPENAI_API_BASE",
required=False,
context=_LITELLM_CONSUMER_CTX,
),
Connection(
target_tool="ollama",
interface_id="openai_api",
purpose="Direct Ollama fallback (bypass both meshes).",
config_key="OPENAI_API_BASE",
required=False,
context=_CODING_AGENT_CTX,
),
],
))
# ──────────────────────────────────────────────────────────────────
# Hermes WebUI — web frontend, backend is hermes_agent (NOT ollama direct)
# ──────────────────────────────────────────────────────────────────
_reg(StackWiring(
tool_id="hermes_webui",
layer="User Interfaces",
interfaces=[
ToolInterface(
interface_id="hermes_webui_http",
protocol="HTTP",
api_format="REST",
port=8081,
base_path="",
auth="WebUI auth (first-run admin signup)",
description="Hermes-themed Open-WebUI instance. Separate "
"port (8081) and data volume from the general "
"openwebui instance so user accounts and RAG "
"corpus don't collide.",
context=EngineeringContext(
decision="Run a second Open-WebUI instance dedicated "
"to the Hermes stack.",
observation="Open-WebUI supports multiple instances "
"with separate data-dir flags. The general "
"openwebui tool already occupies :3000 with "
"Ollama direct as backend.",
alternatives="Use a single Open-WebUI instance with "
"model name prefixes (hermes/*).",
constraints="Must run on a different port (8081) and "
"data-dir than the general openwebui.",
reasoning="Dedicated Hermes UI keeps the Hermes agent "
"runtime as the single backend, so every "
"Hermes WebUI conversation flows through "
"hermes_agent's tool-use / function-calling "
"layer instead of raw Ollama.",
verification="curl http://localhost:8081/health",
lineage="Open-WebUI — https://github.com/open-webui/open-webui",
assumptions="hermes_agent is running on :17051.",
),
),
],
connections=[
Connection(
target_tool="hermes_agent",
interface_id="hermes_agent_api",
purpose="Primary backend — every chat goes through the "
"Hermes agent runtime (tool use, function calling).",
config_key="OLLAMA_BASE_URL (set to http://localhost:17051)",
required=True,
context=EngineeringContext(
decision="Hermes WebUI talks to hermes_agent, NOT "
"Ollama direct.",
observation="hermes_agent exposes an OpenAI-compat "
"endpoint on :17051 that wraps Ollama with "
"Hermes function-calling logic.",
reasoning="Routing through hermes_agent gives the "
"WebUI access to Hermes tool use without "
"requiring the user to wire it manually.",
),
),
Connection(
target_tool="ollama",
interface_id="openai_api",
purpose="Embedding model for RAG (nomic-embed-text). "
"Embeddings bypass hermes_agent for speed.",
config_key="OLLAMA_BASE_URL (RAG_EMBEDDING_ENGINE=ollama)",
required=False,
context=EngineeringContext(
decision="Use Ollama direct for embeddings, "
"hermes_agent for chat.",
observation="Embeddings don't need Hermes function "
"calling — direct Ollama is faster.",
reasoning="Splitting chat vs. embedding traffic "
"keeps hermes_agent focused on tool-use "
"calls.",
),
),
],
))

View File

@ -210,13 +210,14 @@ if _HAS_QT:
self.logs_root: str = os.path.join(self.base_dir, "logs") self.logs_root: str = os.path.join(self.base_dir, "logs")
self.skills_root: str = os.path.join(self.base_dir, "skills") self.skills_root: str = os.path.join(self.base_dir, "skills")
self.datasets_root: str = os.path.join(self.base_dir, "datasets") self.datasets_root: str = os.path.join(self.base_dir, "datasets")
self.config_root: str = os.path.join(self.base_dir, "config") self.config_root: str = os.path.join(self.base_dir, "configs")
self.workspaces_root: str = os.path.join( self.workspaces_root: str = os.path.join(
self.base_dir, "workspaces" self.base_dir, "workspaces"
) )
self.exports_root: str = os.path.join(self.base_dir, "exports") self.exports_root: str = os.path.join(self.base_dir, "exports")
self._setup_environment_hierarchy() self._setup_environment_hierarchy()
self._migrate_legacy_state_files()
self.dtach_bin: str | None = find_binary("dtach-ng", "dtach") self.dtach_bin: str | None = find_binary("dtach-ng", "dtach")
# License gate — checks every tool's license before the # License gate — checks every tool's license before the
@ -291,6 +292,62 @@ if _HAS_QT:
# Environment setup # Environment setup
# ─────────────────────────────────────────────────────────────── # ───────────────────────────────────────────────────────────────
def _migrate_legacy_state_files(self) -> None:
"""One-time migration to the canonical configs/ directory.
v3.1.1b moved app state into <base_dir>/configs/. Older
installs kept files in three legacy locations:
* <base_dir>/config/ (pipeline_state.json, license_approvals.json)
* <base_dir>/controller_config.json (config persisted at the root)
Files are moved only when no newer copy exists in configs/;
emptied legacy dirs are removed. Never raises.
"""
import shutil
legacy_dir = os.path.join(self.base_dir, "config")
candidates: list[tuple[str, str]] = []
if os.path.isdir(legacy_dir):
for fname in os.listdir(legacy_dir):
if fname.endswith(".json"):
candidates.append(
(os.path.join(legacy_dir, fname), fname)
)
root_cfg = os.path.join(self.base_dir, CONFIG_FILE)
if os.path.isfile(root_cfg):
candidates.append((root_cfg, CONFIG_FILE))
moved: list[str] = []
for src_path, fname in candidates:
dst_path = os.path.join(self.config_root, fname)
try:
if not os.path.exists(dst_path):
shutil.move(src_path, dst_path)
moved.append(fname)
elif os.path.getmtime(src_path) > os.path.getmtime(dst_path):
# legacy copy is newer — keep it, drop the old one
shutil.move(
src_path, dst_path + ".legacy.bak"
)
moved.append(fname + " (kept as .legacy.bak)")
else:
os.remove(src_path)
except OSError:
continue
# remove the legacy config/ dir when it is now empty
try:
if os.path.isdir(legacy_dir) and not os.listdir(legacy_dir):
os.rmdir(legacy_dir)
except OSError:
pass
if moved:
from ai_lsc.utils.logging import get_logger
get_logger(__name__).info(
"Migrated legacy state files to %s: %s",
self.config_root, ", ".join(moved),
)
def _setup_environment_hierarchy(self) -> None: def _setup_environment_hierarchy(self) -> None:
for d in REQUIRED_DIRS: for d in REQUIRED_DIRS:
os.makedirs( os.makedirs(
@ -1480,7 +1537,7 @@ if _HAS_QT:
def _load_config(self) -> dict: def _load_config(self) -> dict:
# H-02: resolve config relative to BASE_DIR (not the cwd the # H-02: resolve config relative to BASE_DIR (not the cwd the
# app was launched from). # app was launched from).
config_path = os.path.join(self.base_dir, CONFIG_FILE) config_path = os.path.join(self.config_root, CONFIG_FILE)
if os.path.exists(config_path): if os.path.exists(config_path):
try: try:
with open(config_path, encoding="utf-8") as f: with open(config_path, encoding="utf-8") as f:
@ -1507,7 +1564,10 @@ if _HAS_QT:
"services": services_data, "services": services_data,
} }
# H-02 + H-03: write under base_dir atomically. # H-02 + H-03: write under base_dir atomically.
_atomic_write_json(os.path.join(self.base_dir, CONFIG_FILE), config) os.makedirs(self.config_root, exist_ok=True)
_atomic_write_json(
os.path.join(self.config_root, CONFIG_FILE), config
)
def closeEvent(self, event) -> None: def closeEvent(self, event) -> None:
self.save_config() self.save_config()

View File

@ -46,120 +46,136 @@ except ImportError:
_HAS_QT = False _HAS_QT = False
# ── Category → default Layer / Level / Role mapping ────────────────── # ── Category → default Layer / Level / Role mapping ──────────────────
# Derived from the canonical registry. When the user picks a category # Derived from the canonical registry (11-layer taxonomy, v3.1.1b:
# these fields auto-fill; the user can still override afterwards. # Routing=L5, Orchestrators=L6, Security=L7, Observability=L8,
# User Interfaces=L9, DevOps=L10, Knowledge Management=L11).
# When the user picks a category these fields auto-fill; the user can
# still override afterwards.
CATEGORY_MAP: dict[str, dict[str, object]] = { CATEGORY_MAP: dict[str, dict[str, object]] = {
"AI Agent": {"layer": "Orchestrators", "level": 5, "role": "Sensory Bridge"}, "AI Agent": {"layer": "Orchestrators", "level": 6, "role": "Sensory Bridge"},
"AI Assistant Platform": {"layer": "User Interfaces", "level": 8, "role": "Central Intelligence"}, "AI Assistant Platform": {"layer": "User Interfaces", "level": 9, "role": "Central Intelligence"},
"AI Augmentation": {"layer": "Orchestrators", "level": 5, "role": "Curation"}, "AI Augmentation": {"layer": "Orchestrators", "level": 6, "role": "Curation"},
"AI Coding Agent": {"layer": "DevOps", "level": 9, "role": "Autonomous Coder"}, "AI Coding Agent": {"layer": "DevOps", "level": 10, "role": "Coding Agent"},
"AI Monitoring": {"layer": "Observability", "level": 7, "role": "Health Monitor"}, "AI Monitoring": {"layer": "Observability", "level": 8, "role": "Health Monitor"},
"AI Observability": {"layer": "Observability", "level": 7, "role": "LLM Tracing"}, "AI Observability": {"layer": "Observability", "level": 8, "role": "LLM Tracing"},
"AI Operating System": {"layer": "DevOps", "level": 9, "role": "OS Integration"}, "AI Operating System": {"layer": "DevOps", "level": 10, "role": "OS Integration"},
"Academic References": {"layer": "Knowledge Management", "level": 10, "role": "Reference Manager"}, "Academic References": {"layer": "Knowledge Management", "level": 11, "role": "Reference Manager"},
"Agent Framework": {"layer": "Orchestrators", "level": 5, "role": "Multi-Agent"}, "Agent Framework": {"layer": "Orchestrators", "level": 6, "role": "Multi-Agent"},
"Agent Network": {"layer": "DevOps", "level": 9, "role": "Discovery"}, "Agent Network": {"layer": "DevOps", "level": 10, "role": "Discovery"},
"Agent OS": {"layer": "Orchestrators", "level": 5, "role": "Hands"}, "Agent OS": {"layer": "Orchestrators", "level": 6, "role": "Hands"},
"Agent Toolkit": {"layer": "Orchestrators", "level": 5, "role": "Tool Integration"}, "Agent Toolkit": {"layer": "Orchestrators", "level": 6, "role": "Tool Integration"},
"Agent Workflow": {"layer": "Orchestrators", "level": 5, "role": "Reasoning"}, "Agent Workflow": {"layer": "Orchestrators", "level": 6, "role": "Reasoning"},
"Algorithm Toolkit": {"layer": "DevOps", "level": 9, "role": "Hands"}, "Algorithm Toolkit": {"layer": "DevOps", "level": 10, "role": "Hands"},
"Analytical Database": {"layer": "Host Platform", "level": 1, "role": "Foundation"}, "Analytical Database": {"layer": "Host Platform", "level": 1, "role": "Foundation"},
"Antivirus": {"layer": "Security", "level": 6, "role": "Scanner"}, "Antivirus": {"layer": "Security", "level": 7, "role": "Scanner"},
"Audio Parsing": {"layer": "Knowledge Management", "level": 10, "role": "Memory"}, "Build": {"layer": "Development Environment", "level": 2, "role": "Build Tool"},
"Auth": {"layer": "Security", "level": 6, "role": "Identity"}, "Audio Parsing": {"layer": "Knowledge Management", "level": 11, "role": "Memory"},
"Build Monitoring": {"layer": "Orchestrators", "level": 5, "role": "Monitoring"}, "Auth": {"layer": "Security", "level": 7, "role": "Identity"},
"Build Monitoring": {"layer": "Observability", "level": 8, "role": "Monitoring"},
"Cache": {"layer": "Host Platform", "level": 1, "role": "Foundation"}, "Cache": {"layer": "Host Platform", "level": 1, "role": "Foundation"},
"Chat": {"layer": "User Interfaces", "level": 8, "role": "Face"}, "Chat": {"layer": "User Interfaces", "level": 9, "role": "Face"},
"Chat Agent Platform": {"layer": "User Interfaces", "level": 8, "role": "Face"}, "Chat Agent Platform": {"layer": "User Interfaces", "level": 9, "role": "Face"},
"Chat Frontend": {"layer": "User Interfaces", "level": 8, "role": "Face"}, "Chat Frontend": {"layer": "User Interfaces", "level": 9, "role": "Face"},
"Cluster SSH": {"layer": "Orchestrators", "level": 5, "role": "Coordination"}, "Claude Code Skill": {"layer": "Orchestrators", "level": 6, "role": "Knowledge Graph Builder"},
"Code Analysis": {"layer": "DevOps", "level": 9, "role": "Inspector"}, "Cluster SSH": {"layer": "Orchestrators", "level": 6, "role": "Coordination"},
"Code Generation": {"layer": "DevOps", "level": 9, "role": "Hands"}, "Code Analysis": {"layer": "DevOps", "level": 10, "role": "Inspector"},
"Computer Vision": {"layer": "User Interfaces", "level": 8, "role": "Vision"}, "Code Generation": {"layer": "DevOps", "level": 10, "role": "Hands"},
"Config Management": {"layer": "DevOps", "level": 9, "role": "Configuration Management"}, "Computer Vision": {"layer": "User Interfaces", "level": 9, "role": "Vision"},
"Container Security": {"layer": "Security", "level": 6, "role": "Scanner"}, "Config Management": {"layer": "DevOps", "level": 10, "role": "Configuration Management"},
"Container Ops": {"layer": "Orchestrators", "level": 6, "role": "Sandbox"},
"Container Security": {"layer": "Security", "level": 7, "role": "Scanner"},
"Containers": {"layer": "Host Platform", "level": 1, "role": "Container Runtime"}, "Containers": {"layer": "Host Platform", "level": 1, "role": "Container Runtime"},
"Context Manager": {"layer": "DevOps", "level": 9, "role": "Context"}, "Context Manager": {"layer": "DevOps", "level": 10, "role": "Context"},
"Cortex Memory": {"layer": "Knowledge Management", "level": 10, "role": "Memory"}, "Cortex Memory": {"layer": "Knowledge Management", "level": 11, "role": "Memory"},
"Dashboard": {"layer": "User Interfaces", "level": 8, "role": "Face"}, "Dashboard": {"layer": "User Interfaces", "level": 9, "role": "Face"},
"Data Pipeline": {"layer": "Knowledge Management", "level": 10, "role": "Ingestion"}, "Data Pipeline": {"layer": "Knowledge Management", "level": 11, "role": "Ingestion"},
"Data Sync": {"layer": "Knowledge Management", "level": 10, "role": "Integration"}, "Data Sync": {"layer": "Knowledge Management", "level": 11, "role": "Integration"},
"Debugging": {"layer": "Development Environment", "level": 2, "role": "Profiling"},
"Database": {"layer": "Host Platform", "level": 1, "role": "Foundation"}, "Database": {"layer": "Host Platform", "level": 1, "role": "Foundation"},
"Desktop Agent": {"layer": "User Interfaces", "level": 8, "role": "Face"}, "Desktop Agent": {"layer": "User Interfaces", "level": 9, "role": "Face"},
"Dev Automation": {"layer": "DevOps", "level": 9, "role": "Hands"}, "Dev Automation": {"layer": "DevOps", "level": 10, "role": "Hands"},
"Development": {"layer": "DevOps", "level": 9, "role": "Hands"}, "Development": {"layer": "DevOps", "level": 10, "role": "Hands"},
"Distributed Compilation": {"layer": "Orchestrators", "level": 5, "role": "Distribution"}, "Distributed Compilation": {"layer": "Orchestrators", "level": 6, "role": "Distribution"},
"Distributed Compute": {"layer": "Orchestrators", "level": 5, "role": "Scaling"}, "Distributed Compute": {"layer": "Orchestrators", "level": 6, "role": "Scaling"},
"Document Converter": {"layer": "Knowledge Management", "level": 10, "role": "File Parsing"}, "Document Converter": {"layer": "Knowledge Management", "level": 11, "role": "File Parsing"},
"Document Management": {"layer": "Knowledge Management", "level": 10, "role": "Document Archive"}, "Document Management": {"layer": "Knowledge Management", "level": 11, "role": "Document Archive"},
"Document Understanding": {"layer": "Knowledge Management", "level": 10, "role": "Comprehension"}, "Document Understanding": {"layer": "Knowledge Management", "level": 11, "role": "Comprehension"},
"Ebook Library": {"layer": "Knowledge Management", "level": 10, "role": "Library Manager"}, "Ebook Library": {"layer": "Knowledge Management", "level": 11, "role": "Library Manager"},
"Ecosystem Dashboard": {"layer": "User Interfaces", "level": 8, "role": "Face"}, "Ecosystem Dashboard": {"layer": "User Interfaces", "level": 9, "role": "Face"},
"Efficient LLM": {"layer": "Engines", "level": 4, "role": "Engine"}, "Efficient LLM": {"layer": "Engines", "level": 4, "role": "Engine"},
"File Parsing": {"layer": "Knowledge Management", "level": 10, "role": "Memory"}, "File Parsing": {"layer": "Knowledge Management", "level": 11, "role": "Memory"},
"Find Tool": {"layer": "Development Environment", "level": 2, "role": "Search"}, "Find Tool": {"layer": "Development Environment", "level": 2, "role": "Search"},
"GPU": {"layer": "GPU Runtimes", "level": 3, "role": "Acceleration"}, "GPU": {"layer": "GPU Runtimes", "level": 3, "role": "Acceleration"},
"GPU Computing": {"layer": "Development Environment", "level": 2, "role": "GPU Acceleration"}, "GPU Computing": {"layer": "Development Environment", "level": 2, "role": "GPU Acceleration"},
"Graph Database": {"layer": "Knowledge Management", "level": 10, "role": "Memory"}, "Graph Database": {"layer": "Knowledge Management", "level": 11, "role": "Memory"},
"Graph RAG": {"layer": "Knowledge Management", "level": 10, "role": "Knowledge Synthesis"}, "Graph RAG": {"layer": "Knowledge Management", "level": 11, "role": "Knowledge Synthesis"},
"Homepage": {"layer": "User Interfaces", "level": 8, "role": "Face"}, "Homepage": {"layer": "User Interfaces", "level": 9, "role": "Face"},
"IaC": {"layer": "DevOps", "level": 9, "role": "Infrastructure as Code"}, "IaC": {"layer": "DevOps", "level": 10, "role": "Infrastructure as Code"},
"IaC Control Plane": {"layer": "DevOps", "level": 9, "role": "Infrastructure as Code"}, "IaC Control Plane": {"layer": "DevOps", "level": 10, "role": "Infrastructure as Code"},
"IaC Wrapper": {"layer": "DevOps", "level": 9, "role": "Infrastructure as Code"}, "IaC Wrapper": {"layer": "DevOps", "level": 10, "role": "Infrastructure as Code"},
"Image Generation": {"layer": "User Interfaces", "level": 8, "role": "Face"}, "Image Generation": {"layer": "User Interfaces", "level": 9, "role": "Face"},
"Intrusion Prevention": {"layer": "Security", "level": 6, "role": "IDS"}, "Infrastructure": {"layer": "Orchestrators", "level": 6, "role": "Resource Manager"},
"Knowledge Graph": {"layer": "DevOps", "level": 9, "role": "Graph Builder"}, "Intrusion Prevention": {"layer": "Security", "level": 7, "role": "IDS"},
"Knowledge Graph Notes": {"layer": "User Interfaces", "level": 8, "role": "Face"}, "Knowledge Graph": {"layer": "DevOps", "level": 10, "role": "Graph Builder"},
"LLM Evaluation": {"layer": "Observability", "level": 7, "role": "Evaluation"}, "Knowledge Graph Notes": {"layer": "User Interfaces", "level": 9, "role": "Face"},
"LLM Evaluation": {"layer": "Observability", "level": 8, "role": "Evaluation"},
"Memory System": {"layer": "Knowledge Management", "level": 11, "role": "Memory"},
"LLM Fine-tuning": {"layer": "GPU Runtimes", "level": 3, "role": "Abliteration"}, "LLM Fine-tuning": {"layer": "GPU Runtimes", "level": 3, "role": "Abliteration"},
"LLM Framework": {"layer": "Orchestrators", "level": 5, "role": "Orchestration"}, "LLM Framework": {"layer": "Orchestrators", "level": 6, "role": "Orchestration"},
"LLM GUI": {"layer": "User Interfaces", "level": 8, "role": "Face"}, "LLM GUI": {"layer": "User Interfaces", "level": 9, "role": "Face"},
"LLM Router": {"layer": "Orchestrators", "level": 5, "role": "API Gateway"}, "LLM Mesh": {"layer": "Routing", "level": 5, "role": "API Gateway"},
"LLM Router": {"layer": "Routing", "level": 5, "role": "API Gateway"},
"LLM Runtime": {"layer": "Engines", "level": 4, "role": "Engine"}, "LLM Runtime": {"layer": "Engines", "level": 4, "role": "Engine"},
"LLM Serving": {"layer": "Orchestrators", "level": 5, "role": "Scaling"}, "LLM Serving": {"layer": "Engines", "level": 4, "role": "Engine"},
"MCP Server": {"layer": "Orchestrators", "level": 5, "role": "Code Audit"}, "MCP Server": {"layer": "Orchestrators", "level": 6, "role": "Code Audit"},
"Metrics": {"layer": "Observability", "level": 7, "role": "Metrics Collector"}, "Metrics": {"layer": "Observability", "level": 8, "role": "Metrics Collector"},
"Mesh Client": {"layer": "Routing", "level": 5, "role": "Coding Agent"},
"Mixed Precision": {"layer": "GPU Runtimes", "level": 3, "role": "Optimization"}, "Mixed Precision": {"layer": "GPU Runtimes", "level": 3, "role": "Optimization"},
"Model Surgery": {"layer": "Engines", "level": 4, "role": "Abliteration"},
"Model Training": {"layer": "Development Environment", "level": 2, "role": "Training"}, "Model Training": {"layer": "Development Environment", "level": 2, "role": "Training"},
"Multi-Agent": {"layer": "Orchestrators", "level": 5, "role": "Coordination"}, "Multi-Agent": {"layer": "Orchestrators", "level": 6, "role": "Coordination"},
"Notes": {"layer": "Knowledge Management", "level": 10, "role": "Note Taking"}, "Networking": {"layer": "Host Platform", "level": 1, "role": "Tunnel"},
"OCI Export": {"layer": "DevOps", "level": 9, "role": "Runtime Packaging"}, "Notes": {"layer": "Knowledge Management", "level": 11, "role": "Note Taking"},
"Outliner": {"layer": "Knowledge Management", "level": 10, "role": "Knowledge Graph"}, "OCI Export": {"layer": "DevOps", "level": 10, "role": "Runtime Packaging"},
"PDF Pipeline": {"layer": "Knowledge Management", "level": 10, "role": "Extraction"}, "Observability": {"layer": "Observability", "level": 8, "role": "Monitoring"},
"Outliner": {"layer": "Knowledge Management", "level": 11, "role": "Knowledge Graph"},
"PDF Pipeline": {"layer": "Knowledge Management", "level": 11, "role": "Extraction"},
"Parser": {"layer": "Development Environment", "level": 2, "role": "Parsing"}, "Parser": {"layer": "Development Environment", "level": 2, "role": "Parsing"},
"Persistent Memory": {"layer": "Knowledge Management", "level": 10, "role": "Memory"}, "Persistent Memory": {"layer": "Knowledge Management", "level": 11, "role": "Memory"},
"Pipeline": {"layer": "Orchestrators", "level": 5, "role": "Pipeline Orchestrator"}, "Pipeline": {"layer": "Routing", "level": 5, "role": "Pipeline Orchestrator"},
"Policy Engine": {"layer": "Security", "level": 6, "role": "Policy"}, "Policy Engine": {"layer": "Security", "level": 7, "role": "Policy"},
"Procfile Runner": {"layer": "DevOps", "level": 9, "role": "Process Manager"}, "Procfile Runner": {"layer": "DevOps", "level": 10, "role": "Process Manager"},
"Project Management": {"layer": "DevOps", "level": 9, "role": "Management"}, "Project Management": {"layer": "DevOps", "level": 10, "role": "Management"},
"Prompt Tooling": {"layer": "DevOps", "level": 9, "role": "Prompt Management"}, "Prompt Tooling": {"layer": "DevOps", "level": 10, "role": "Prompt Management"},
"Provisioning": {"layer": "DevOps", "level": 9, "role": "Provisioning"}, "Provisioning": {"layer": "DevOps", "level": 10, "role": "Provisioning"},
"Proxy": {"layer": "Orchestrators", "level": 5, "role": "API Gateway"}, "Proxy": {"layer": "Routing", "level": 5, "role": "API Gateway"},
"Reasoning Engine": {"layer": "Orchestrators", "level": 5, "role": "Brain"}, "Reasoning Engine": {"layer": "Orchestrators", "level": 6, "role": "Brain"},
"Runtime": {"layer": "Development Environment", "level": 2, "role": "Build System"}, "Runtime": {"layer": "Development Environment", "level": 2, "role": "Build System"},
"Sandbox": {"layer": "DevOps", "level": 9, "role": "Isolation"}, "Sandbox": {"layer": "DevOps", "level": 10, "role": "Isolation"},
"Search Engine": {"layer": "Knowledge Management", "level": 10, "role": "Memory"}, "Search Engine": {"layer": "Knowledge Management", "level": 11, "role": "Memory"},
"Search Tool": {"layer": "Development Environment", "level": 2, "role": "Search"}, "Search Tool": {"layer": "Development Environment", "level": 2, "role": "Search"},
"Secrets Management": {"layer": "Security", "level": 6, "role": "Secrets"}, "Shell": {"layer": "Development Environment", "level": 2, "role": "Shell"},
"Secrets Management": {"layer": "Security", "level": 7, "role": "Secrets"},
"Serverless Framework": {"layer": "Development Environment", "level": 2, "role": "Full-Stack Framework"}, "Serverless Framework": {"layer": "Development Environment", "level": 2, "role": "Full-Stack Framework"},
"Single-File LLM": {"layer": "Engines", "level": 4, "role": "Engine"}, "Single-File LLM": {"layer": "Engines", "level": 4, "role": "Engine"},
"Skill Analysis": {"layer": "DevOps", "level": 9, "role": "Assessment"}, "Skill Analysis": {"layer": "DevOps", "level": 10, "role": "Assessment"},
"Skill Inspection": {"layer": "DevOps", "level": 9, "role": "Analysis"}, "Skill Inspection": {"layer": "DevOps", "level": 10, "role": "Analysis"},
"Spaced Repetition": {"layer": "Knowledge Management", "level": 10, "role": "Memory"}, "Spaced Repetition": {"layer": "Knowledge Management", "level": 11, "role": "Memory"},
"Spec Writer": {"layer": "DevOps", "level": 9, "role": "Documentation"}, "Spec Writer": {"layer": "DevOps", "level": 10, "role": "Documentation"},
"Speech Recognition": {"layer": "User Interfaces", "level": 8, "role": "Senses"}, "Speech Recognition": {"layer": "User Interfaces", "level": 9, "role": "Senses"},
"Task Runner": {"layer": "DevOps", "level": 9, "role": "Scheduler"}, "Task Runner": {"layer": "DevOps", "level": 10, "role": "Scheduler"},
"Telemetry": {"layer": "Observability", "level": 7, "role": "Collector"}, "Telemetry": {"layer": "Observability", "level": 8, "role": "Collector"},
"Terminal": {"layer": "Host Platform", "level": 1, "role": "Multiplexer"}, "Terminal": {"layer": "Host Platform", "level": 1, "role": "Multiplexer"},
"Text-to-Speech": {"layer": "User Interfaces", "level": 8, "role": "Voice"}, "Text-to-Speech": {"layer": "User Interfaces", "level": 9, "role": "Voice"},
"Uncensored Models": {"layer": "Engines", "level": 4, "role": "Engine"}, "Uncensored Models": {"layer": "Engines", "level": 4, "role": "Engine"},
"VCS": {"layer": "Host Platform", "level": 1, "role": "Version Control"}, "VCS": {"layer": "Host Platform", "level": 1, "role": "Version Control"},
"Vector Engine": {"layer": "Knowledge Management", "level": 10, "role": "Embedding"}, "Vector Engine": {"layer": "Knowledge Management", "level": 11, "role": "Embedding"},
"Vector Store": {"layer": "Knowledge Management", "level": 10, "role": "Memory"}, "Vector Store": {"layer": "Knowledge Management", "level": 11, "role": "Memory"},
"Visualization": {"layer": "Observability", "level": 7, "role": "Dashboard"}, "Visualization": {"layer": "Observability", "level": 8, "role": "Dashboard"},
"Web Crawler": {"layer": "Knowledge Management", "level": 10, "role": "Data Harvesting"}, "Virtualization": {"layer": "Host Platform", "level": 1, "role": "MicroVM"},
"Workflow": {"layer": "Orchestrators", "level": 5, "role": "Visual Builder"}, "Web Crawler": {"layer": "Knowledge Management", "level": 11, "role": "Data Harvesting"},
"Workflow Automation": {"layer": "Orchestrators", "level": 5, "role": "Workflow Orchestrator"}, "Workflow": {"layer": "Orchestrators", "level": 6, "role": "Visual Builder"},
"Workflow Automation": {"layer": "Orchestrators", "level": 6, "role": "Workflow Orchestrator"},
} }
# ── Field-constant lookups (populated once on first use) ───────────── # ── Field-constant lookups (populated once on first use) ─────────────

View File

@ -31,30 +31,61 @@ def build_path_tree(base_dir: str | Path | None = None) -> dict[str, Path]:
Example:: Example::
{ {
"base_dir": Path("/mnt/AI"), "base_dir": Path("/mnt/AI"),
"tools_root": Path("/mnt/AI/tools"), "tools_root": Path("/mnt/AI/tools"), # standalone CLI utilities
"models_root": Path("/mnt/AI/models"), "runtime_root": Path("/mnt/AI/runtime"), # native binaries + per-tool venvs
"logs_root": Path("/mnt/AI/logs"), "models_root": Path("/mnt/AI/models"), # parent of hot/ and cold/
"skills_root": Path("/mnt/AI/skills"), "models_hot": Path("/mnt/AI/models/hot"), # active weights (SSD)
"datasets_root": Path("/mnt/AI/datasets"), "models_cold": Path("/mnt/AI/models/cold"), # archived weights (HDD)
"config_root": Path("/mnt/AI/config"), "corpus_root": Path("/mnt/AI/corpus"), # parent of hot/ and cold/
"workspaces_root": Path("/mnt/AI/workspaces"), "datasets_root": Path("/mnt/AI/datasets"), # parent of wordlists/, huggingface/, github/
"exports_root": Path("/mnt/AI/exports"), "pipelines_root": Path("/mnt/AI/pipelines"), # ETL / chunking / routing scripts
"registry_root": Path("/mnt/AI/registry"), "configs_root": Path("/mnt/AI/configs"), # app state + templated configs
"registry_root": Path("/mnt/AI/registry"), # app-internal: ecosystem.json + manifests/
"agents_root": Path("/mnt/AI/agents"), # configs and chains for autonomous actors
"skills_root": Path("/mnt/AI/skills"), # 3rd-party integrations and tool wrappers
"projects_root": Path("/mnt/AI/projects"), # parent of active/, labs/, vault/
"blueprints_root": Path("/mnt/AI/blueprints"), # Dockerfiles / build contexts for Podman exports
"workspaces_root": Path("/mnt/AI/workspaces"), # Jupyter, OpenNotebook, etc.
"dashboards_root": Path("/mnt/AI/dashboards"), # web UIs (Dashy, Open-WebUI, Hermes WebUI, etc.)
"exports_root": Path("/mnt/AI/exports"), # parent of oci-images/
"scripts_root": Path("/mnt/AI/scripts"), # system admin / maintenance automation
"logs_root": Path("/mnt/AI/logs"),
"backends_root": Path("/mnt/AI/backends"), # S3/MinIO/Ceph connection profiles
"distfiles_root": Path("/mnt/AI/distfiles"), # permanent local mirror of source tarballs
"config_root": Path("/mnt/AI/configs"), # app state + templated configs
} }
""" """
root = Path(base_dir) if base_dir is not None else Path(BASE_DIR) root = Path(base_dir) if base_dir is not None else Path(BASE_DIR)
return { return {
"base_dir": root, "base_dir": root,
"tools_root": root / "tools", "tools_root": root / "tools",
"runtime_root": root / "runtime",
"models_root": root / "models", "models_root": root / "models",
"logs_root": root / "logs", "models_hot": root / "models" / "hot",
"skills_root": root / "skills", "models_cold": root / "models" / "cold",
"corpus_root": root / "corpus",
"datasets_root": root / "datasets", "datasets_root": root / "datasets",
"config_root": root / "config", "pipelines_root": root / "pipelines",
"workspaces_root": root / "workspaces",
"exports_root": root / "exports",
"registry_root": root / "registry", "registry_root": root / "registry",
"agents_root": root / "agents",
"skills_root": root / "skills",
"projects_root": root / "projects",
"blueprints_root": root / "blueprints",
"workspaces_root": root / "workspaces",
"dashboards_root": root / "dashboards",
"exports_root": root / "exports",
"scripts_root": root / "scripts",
"logs_root": root / "logs",
"backends_root": root / "backends",
"distfiles_root": root / "distfiles",
"configs_root": root / "configs",
# App-state + templated app configs (controller_config.json,
# pipeline_state.json, license_approvals.json). Per-tool config
# subdirs (configs/<tool>/) are created on demand by
# InstallerManager. Legacy installs used base_dir/config or
# base_dir root — main_window migrates those on startup.
"config_root": root / "configs",
} }