ai-lsc/README.md

396 lines
18 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div align="center">
<img src="ai-lsc-logo.png" alt="AI-LSC Logo" width="280">
</div>
<h1 align="center">AI - Local Stack Control</h1>
<p align="center">
<strong>v3.1 — Codename: Ankh of Jah</strong><br>
<a href="http://dcos.net">http://dcos.net</a>
</p>
<p align="center">
A PySide6 desktop application for orchestrating local AI/ML tool stacks across a 13-layer architecture.
</p>
AI Local Stack Control (AI-LSC) provides a unified interface to discover, configure, launch, and manage 125 tools spanning the entire AI software stack — from GPU runtimes and inference engines to agent frameworks and container deployment targets.
![Overview](docs/screenshots/overview.png)
## Features
### 13-Layer Architecture
Every tool in the registry is classified within a 13-layer taxonomy, giving you a clear mental model of your entire AI stack:
| Layer | Name | Tools |
|-------|------|-------|
| L1 | Host Platform | PostgreSQL, MariaDB, Redis, SQLite3, DuckDB |
| L2 | Development Environment | Python, CuPy, ripgrep, fd, tree-sitter, SST |
| L3 | GPU Runtime | CUDA Toolkit, ROCm, Vulkan |
| L4 | Inference Engines | Ollama, llama.cpp, vLLM, SGlang, TGI, LMDeploy, TextGen |
| L5 | Distributed Runtime | vLLM (distributed) |
| L6 | AI Endpoints | LiteLLM Proxy, 9Router Proxy, Odysseus, LangChain, LangFlow, OpenAI Swarm, Agno |
| L7 | Data & Knowledge Pipelines | Dify, LangChain, LlamaIndex, LangGraph, Docling, Whisper, Unstructured, Haystack, Craw4AI, Firecrawl, LakeFS, DVC, nomic-embed |
| L8 | Automation & Execution | Aider, Claude Code, OpenHands, Fabric, Jupyter, Streamlit, Gradio, Chainlit, Marqo, PyPDF, Docling (ETL), Codex, and more |
| L9 | Observability | Btop, Glances, Prometheus, Grafana, Loki, Jaeger, OpenTelemetry |
| L10 | Intelligent Routing | CrewAI, AutoGen, OpenBrain, Mnemosyne, Mnemo Cortex |
| L11 | User Interfaces | Open WebUI, ChatUI, InvokeAI, Forge (A1111), ComfyUI, Gradio Web, Streamlit Web |
| L12 | DevOps | Terraform, Ansible, Puppet, Pulumi, Bicep, OpenTofu, AWS CDK, Crossplane, Terragrunt, Stack Exporter |
| L13 | Knowledge Management | Zotero, Calibre, Paperless-ngx, Logseq, Joplin |
![Infrastructure Layers](docs/screenshots/infrastructure-layers.png)
### Tool Registry
Browse and search across 125 tools with real-time status detection, dependency tracking, and per-tool configuration. Each tool entry includes installer type, launcher specification, required dependencies, and the full 8-key feature-flag schema (CLI / GUI / Web / Ollama / Docker / Passive / MCP / Skills-collection).
![Tools Registry](docs/screenshots/tools-registry.png)
### Pipeline Ticker
A horizontally scrolling status bar at the top of every workspace tab that visualizes the wiring topology of your currently-staged tools in real time. Edges are drawn from the live `STACK_WIRINGS` data: `provider ──interface──▶ consumer`, with arrow color encoding the interface type (blue = openai_api, green = vector, orange = redis_pubsub, purple = postgresql, teal = http_api, etc.). Orphan tools — active but with no wiring to any other active tool — are flagged in red with an `❗` prefix so you can immediately see which tools in your staged flow are disconnected. Hover to pause the scroll; click any tool pill to jump to the Tools tab and highlight that row.
### Workspace (Peek-Style Orchestration)
A new **Workspace** nav entry (between Chat and Git Sources) provides virt-manager / aqemustyle orchestration: one sub-tab per active tool. Web-interface tools (OpenWebUI, Hermes, Odysseus, etc.) are embedded directly via `QWebEngineView` at `http://127.0.0.1:{port}` — no need to leave the app for a browser. CLI tools (Aider, Claude Code, OpenHands, etc.) attach to their tmux session and render the live `tmux capture-pane` output in an embedded terminal pane at 4 Hz. Passive / library tools get a placeholder explaining they have no interactive surface. Not-yet-running tools show a **Start tool** button that wires back to the existing service-start flow.
> **Servo note:** The web embedding uses `PySide6.QtWebEngineWidgets.QWebEngineView` by default. Swapping in Mozilla's servo engine later is a one-line change to `_make_web_view()` in `workspace_tab.py` — just provide a widget exposing the same `setUrl()` / `url()` / `load()` API.
### IPC Stack Editor
Visually compose your tool stack using the AI-LSC Stack Editor — a drag-and-drop flow compiler. Validate dependencies, then compile the stack state to a portable JSON configuration file.
![IPC Stack Editor](docs/screenshots/ipc-stack-editor.png)
### Stack Templates
Get started quickly with pre-configured stack templates:
- **Claude Code Setup** — Full Claude Code ecosystem (11 tools: claude_code, ollama, aider, claude_mem, godmod3, awesome_claude_code, superpowers, ui_ux_pro_max, vibe_kanban, claude_squad, rcode)
- **Free Claude Code** — Minimal Claude Code setup (4 tools: claude_code, ollama, claude_mem, rcode)
- **SaaS Integrations** — Production deployment stack (12 tools including cloudflared, nginx_proxy, certbot, backup_agent)
- **Local LLM Lab** — Self-hosted LLM playground (10 tools: ollama, llamacpp, vllm, litellm, openwebui, chromadb, whisper, docling, aider, fabric)
### Multi-Backend Container Export
Export your compiled stack to multiple deployment targets:
- **Podman Compose** — Rootless OCI containers via `compose.yaml`
- **Docker Compose** — Standard Docker Compose output
- **LXC Containers** — Per-container `.conf` files + `lxc-launch.sh` lifecycle script
- **Firecracker microVMs** — Per-VM `vm-config.json` files + `firecracker-launch.sh` lifecycle script for ultra-lightweight KVM-backed microVMs
![Deployment Targets](docs/screenshots/deployment-targets.png)
### Runtime Management
Launch and manage tools via four runtime backends, all with shell-injection-safe list-form subprocess calls and validated tool_ids / port ranges:
- **systemd** — Persistent system services with `systemctl` (5 s timeout on `is-active` queries)
- **tmux** — Session-managed terminal processes with user-scoped session names (`ai_lsc_<uid>`)
- **desktop** — One-shot CLI commands
- **lxc** — Full LXC container lifecycle (create, start, stop, freeze, attach) with `shlex.split()` argument preservation and validated container names
All child processes are tracked in a `ProcessManager._launched` list and reaped on application exit so the GUI does not orphan tmux windows or desktop launches.
### Skills System
Extend AI-LSC with skill modules that add specialized behaviors to your tool stack. The Skills Console provides activation toggles, behavior bindings, and runtime integration.
![Skills Console](docs/screenshots/skills-console.png)
### AI Chat Console
Built-in chat interface for interacting with local LLM endpoints. Supports model selection, conversation history, and direct integration with your running stack.
![Chat Console](docs/screenshots/chat-console.png)
### Monitor Dashboard
Real-time system health monitoring with CPU/memory metrics, per-service status indicators, and log aggregation across all running tools.
![Monitor Dashboard](docs/screenshots/monitor-dashboard.png)
### Code Analysis
Source code analysis with syntax highlighting, complexity metrics, and dependency visualization.
![Code Analysis](docs/screenshots/code-analysis.png)
### Settings
Configure base directories, model defaults, API endpoints, logging levels, and application preferences.
![Settings](docs/screenshots/settings.png)
## Architecture
```
ai_lsc/
__init__.py # Public API re-exports
constants.py # App constants, styles, navigation order
types.py # Data classes: ToolMetadata, PipelineState, etc.
guardrails.py # Import guard for PySide6
registry/
__init__.py
defaults.py # Master registry (124 tools, full 8-key flags)
loader.py # Merges per-layer files at runtime
manager.py # RegistryManager — query/filter tools
validator.py # Schema validation (8-key flags enforced)
layers/ # 13 per-layer tool files (123 tools)
automation.py # L8: 32 tools
data_knowledge.py # L7: 13 tools
development.py # L2: 4 tools
devops.py # L12: 10 tools
distributed.py # L5: 5 tools
endpoints.py # L6: 11 tools
gpu.py # L3: 2 tools
host_platform.py # L1: 9 tools
inference.py # L4: 7 tools
intelligent_routing.py # L10: 5 tools
knowledge_management.py # L13: 5 tools
observability.py # L9: 7 tools
user_interfaces.py # L11: 13 tools
stack_templates/ # 13 pre-configured stack templates
runtime/
__init__.py
executor.py # RuntimeExecutor — dispatch + tool_id/port validation
installer.py # Tool installation (URL/port/tool_id validation)
process.py # ProcessManager with reap()/shutdown()
status.py # Service status detection
systemd.py # systemd lifecycle (no shell=True)
tmux.py # tmux session mgmt (validated names, XDG sockets)
lxc.py # LXC lifecycle (validated names, shlex.split)
stack/
export.py # ContainerBackend — compose/LXC/Firecracker export
connections.py # 60-entry STACK_WIRINGS topology (the ticker's data source)
ui/
__init__.py
protocol.py # MainWindowProtocol (TYPE_CHECKING-typed)
main_window.py # AILocalStackControl — master QMainWindow
dialogs/
__init__.py
stack_wizard.py # First-launch template selection wizard
pages/ # 13 page widgets
chatbot_console.py
code_analysis_tab.py
container_stacks_tab.py
datasets_tab.py
git_worktree_tab.py
infrastructure_layer_page.py
ipc_stack_tab.py
service_row.py # adds is_running_now() for ticker
settings_page.py
skills_console.py
tools_tab.py # adds highlight_tool() for ticker click
widgets/ # NEW: shared cross-page widgets
__init__.py
pipeline_ticker.py # scrolling wiring-topology status bar
workspace_tab.py # peek-style embedded web + CLI orchestration
chat/
api.py # Async chat API worker (sanitized errors)
skills/
resolver.py # SkillRuntimeResolver
manifest/
support.py # Manifest generation
utils/
filesystem.py # Path.rglob-based walk_tree
logging.py
paths.py
process.py
```
## Installation
### Prerequisites
- Python 3.11+
- PySide6 (`pip install PySide6`)
- Arch Linux (pacman) or equivalent package manager
### Quick Install
```bash
git clone https://github.com/your-username/ai-lsc.git
cd ai-lsc
pip install -e .
```
See [quickstart.md](quickstart.md) for detailed setup instructions.
### Bootstrap Script
```bash
./bootstrap.sh
```
The bootstrap script installs all system dependencies (pacman packages), Python dependencies, and verifies your environment.
## Usage
### Launch the Application
```bash
python -m ai_lsc
```
### First Launch
On first launch, the Stack Template Wizard appears. Choose a pre-configured template (Claude Code Setup, Local LLM Lab, etc.) or start from scratch and manually select your tools.
### Typical Workflow
1. **Select a template** or manually pick tools from the registry
2. **Configure dependencies** — AI-LSC resolves tool dependencies automatically
3. **Compile your stack** — IPC Stack Editor validates and saves the configuration
4. **Watch the Pipeline Ticker** — the scrolling status bar at the top of every tab shows the live wiring topology of your staged tools; orphans (disconnected tools) are flagged red
5. **Launch services** — Tools start via systemd, tmux, desktop, or LXC launchers
6. **Orchestrate from the Workspace tab** — every active tool gets its own sub-tab; web tools embed via QWebEngineView, CLI tools attach via tmux
7. **Monitor** — Dashboard shows real-time status across all running tools
8. **Export** — Generate Podman/Docker Compose, LXC, or Firecracker microVM configs
## Security & Reliability (v3.1)
The v3.1 pass applied the full master code critique (91 of 93 findings addressed; see [whatremains.txt](whatremains.txt) for the two intentionally skipped items and deferred polish):
- **No more `shell=True`** in any subprocess call across `runtime/process.py`, `systemd.py`, `tmux.py`, `lxc.py`, or `installer.py` (15+ sites converted to list-form argv). The only remaining `shell=True` is the user-preserved `curl … | sh` installers (Ollama / Grafana Alloy / Meilisearch) — see `whatremains.txt`.
- **Path-traversal protection** at every subprocess boundary: `_validate_tool_id()` rejects `..`, `.`, `/`, and shell metacharacters before any tool_id reaches a path or argv slot.
- **Port range validation** on every user-supplied port (`1 ≤ port ≤ 65535`).
- **URL scheme validation** on every `install_custom` URL (http/https only — no `file://`, `javascript:`, etc.).
- **Atomic JSON writes** via `tempfile` + `fsync` + `os.replace` with `fcntl.flock` advisory locking so two ai-lsc instances cannot corrupt each other's state.
- **Hardened error messages** in the chat API (no internal-detail leakage to the user; full detail kept in server-side logs).
- **Process lifecycle cleanup** on application exit (`ProcessManager.shutdown()` terminates every tracked child).
- **API keys moved out of source** — `librechat_config.py` reads `AI_LSC_LITELLM_KEY` / `AI_LSC_OPENWEBUI_KEY` from the environment instead of hardcoding `sk-ai-lsc-local`.
- **Word-boundary error detection** in the orchestrator's quality enforcer (no more false positives on phrases like `error-correction module initialized`).
- **Dynamic Qdrant embedding dimension probe** (no more hardcoded `dimension=768` mismatch when you switch embedding models).
## Development
### Project Structure
The project follows a layered architecture with clear separation of concerns:
- **registry/** — Tool definitions, loader, validator, templates
- **runtime/** — Process management, launchers, installers
- **stack/** — Container export backends
- **ui/** — PySide6 interface (guarded imports, protocol-based DI)
- **chat/** — Async chat API integration
- **skills/** — Skill runtime resolver
- **utils/** — Filesystem, logging, path helpers
### PySide6 Guard Pattern
All UI modules use a try/except guard:
```python
try:
from PySide6.QtWidgets import QMainWindow
_HAS_QT = True
except ImportError:
_HAS_QT = False
if _HAS_QT:
class MyWidget(QMainWindow):
...
MyWidget = None
```
This allows the registry, runtime, and utility modules to be imported and tested without PySide6 installed.
### Registry-Driven Dispatch
Tool behavior is driven entirely by registry entries. No hardcoded switch statements:
```python
LAUNCHER_DISPATCH = {
"systemd": systemd_start,
"tmux": tmux_start,
"desktop": desktop_start,
"lxc": lxc_start,
}
handler = LAUNCHER_DISPATCH[tool["launcher"]["type"]]
handler(tool)
```
### Adding a New Tool
1. Identify the correct layer file in `registry/layers/`
2. Add a new entry to the `TOOLS` dict — note that the validator now enforces the full 8-key flags schema:
```python
'my_tool': {
"name": "My Tool",
"level": 8,
"layer": "Automation & Execution",
"role": "Hands",
"category": "Development",
"installer": {"type": "npm", "pkg": "my-tool"},
"launcher": {"type": "tmux", "cmd": "my-tool serve --port {port}",
"default_port": 8080},
"deps": ["ollama"],
"description": "My awesome AI tool.",
"flags": {
"has_cli": True,
"has_gui": False,
"has_web": True,
"is_ollama": False,
"is_docker": False,
"is_passive": False,
"is_mcp": False,
"is_skills_collection": False,
},
},
```
3. Run `python -m ai_lsc.registry.validator` (or `python scripts/backfill_layer_flags.py` if you're migrating an older entry that's missing keys)
4. Optionally add it to a stack template JSON in `registry/stack_templates/`
5. Optionally add a `STACK_WIRINGS` entry in `stack/connections.py` so the Pipeline Ticker can visualize its connections to other tools
### Creating a Stack Template
```json
{
"id": "my-template",
"name": "My Custom Stack",
"description": "A custom stack for my workflow",
"version": "1.0",
"author": "your-name",
"tags": ["custom", "development"],
"tools": ["ollama", "aider", "claude_code", "vllm"]
}
```
Save as `registry/stack_templates/my-template.json`.
## Tech Stack
| Component | Technology |
|-----------|-----------|
| UI Framework | PySide6 (Qt for Python) |
| Web Embedding | PySide6 QtWebEngine (servo-swap path documented) |
| CLI Embedding | tmux `capture-pane` polling at 4 Hz |
| Language | Python 3.11+ |
| Package Manager | pip / uv |
| Container Backends | Podman, Docker, LXC, Firecracker microVMs |
| Service Management | systemd, tmux |
| IaC Tools | Terraform, Pulumi, OpenTofu, AWS CDK, Crossplane, Bicep, Terragrunt |
| Config Format | JSON (atomic writes via `tempfile` + `fsync` + `os.replace`) |
| Concurrency | `threading.Lock` for model pool, `fcntl.flock` for cross-process state files |
## Changelog
See [CHANGES.md](CHANGES.md) for the v3.1 release notes covering the critique pass and the new Pipeline Ticker + Workspace widgets. See [whatremains.txt](whatremains.txt) for the two intentionally-skipped findings (curl|sh remote installers) and deferred polish items.
## License
AGPLv3
## Contributing
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/my-feature`)
3. Add tools to the appropriate layer file
4. Ensure all 13 layer files pass AST validation (`python3 -c "import ast; ..."`)
5. Submit a pull request