Files
Agentic-OS/docs/architecture.md
2026-06-15 07:50:48 +03:00

6.6 KiB

Architecture

High-Level Design

Agentic OS is a multi-service Docker stack:

flowchart LR
  browser[Browser] --> frontend[Next.js Frontend]
  frontend --> backend[FastAPI Backend]
  backend --> postgres[(Postgres)]
  backend --> redis[(Redis)]
  worker[Worker] --> redis
  worker --> agent[LangGraph Agent]
  agent --> litellm[LiteLLM Gateway]
  litellm --> ollama[Ollama on Host]
  litellm --> cloud[Gemini DeepSeek OpenRouter]
  worker --> mcp[MCP Sidecars]
  mcp --> devices[Vessel Devices]
  agent --> memory[Project Memory MCP]
  agent --> obsidian[Obsidian Vault Git]

Services

Service Location Responsibility
frontend frontend/ Next.js operator console, task UX, dashboard, rules, skills, models, inventory.
backend backend/app/ FastAPI API, auth, schemas, inventory, tasks, MCP admin, balance polling.
worker backend/app/worker.py Consumes task queue, owns MCP manager, runs LangGraph task agent.
postgres docker-compose.yml Users, inventory, tasks, task events, approvals, balances, audit logs.
redis docker-compose.yml Task queue, live event pub/sub, cancel/escalate flags, MCP command queue/status.
litellm litellm/config.yaml Unified API for local Ollama and cloud providers.
MCP sidecars mcp-servers/ and cloned repos Device-facing tool servers.

Backend Modules

Path Purpose
backend/app/api/ REST and WebSocket endpoints.
backend/app/agent/ LangGraph workflow, device profiles, playbooks, tool execution, MCP development.
backend/app/mcp_manager/ MCP repository sync, subprocess lifecycle, command queue, tool discovery.
backend/app/services/ Rules, skills, balance, model routing, report formatting, memory/Obsidian integrations, audit.
backend/app/models/ SQLAlchemy models.
backend/alembic/ Database migrations.

Frontend Modules

Path Purpose
frontend/app/page.tsx Operations dashboard.
frontend/app/tasks/page.tsx Task list and guided task creation.
frontend/app/tasks/[id]/page.tsx Live task page, approvals, report, artifacts, run history.
frontend/app/inventory/page.tsx Vessel and device management.
frontend/app/mcp/page.tsx MCP server status and controls.
frontend/app/rules/page.tsx Troubleshooting rules editor.
frontend/app/skills/page.tsx Procedural skills editor/preview.
frontend/app/models/page.tsx LLM routing configuration.
frontend/components/ Shared UI, task status, task report panels, app shell.
frontend/lib/ API client, auth context, shared task types.

Task Lifecycle

flowchart TD
  create[Create Task] --> preview[Preview Scope]
  preview --> queue[Queue in Redis]
  queue --> worker[Worker Picks Task]
  worker --> context[Context Search]
  context --> triage[Triage and Scope]
  triage --> diagnose[Run MCP Diagnostics]
  diagnose --> reason[LLM Reasoning Cascade]
  reason --> report[Structured Report]
  report --> approvals[Approval Requests]
  report --> memory[Project Memory]
  report --> obsidian[Obsidian Note]
  report --> dashboard[Dashboard Summary]

1. Create and Preview

The frontend calls POST /api/tasks/preview with title, issue, and vessel. The backend uses select_devices_for_issue() from backend/app/services/troubleshooting_rules.py so preview and execution share the same routing logic.

2. Queue

POST /api/tasks inserts a Task, sets status queued, emits a log event, and pushes the task ID to Redis list agentic:task_queue.

3. Worker Execution

The worker consumes the queue, loads MCP servers, and calls run_task_agent() in backend/app/agent/graph.py.

4. LangGraph Pipeline

Node Responsibility
context_step Search project-memory and Obsidian for related past investigations.
triage_step Use local LLM plus rules/skills to plan checks and severity.
diagnose_step Run device-specific or generic MCP diagnostics.
reason_step Use tiered LLM cascade to interpret findings.
report_step Build structured report, create approvals, save artifacts.

5. Live Events

Events are sent through publish_event() in backend/app/services/events.py.

  • Persisted events go to task_events and Redis pub/sub.
  • Ephemeral high-frequency events such as progress and tool_start are streamed live but not stored.
  • The frontend WebSocket /api/tasks/{id}/stream replays recent persisted events and then streams live ones.

6. Report Shape

Reports are JSON stored on the tasks.report column. New reports include:

  • executive_summary;
  • scope_checked;
  • findings;
  • planned_steps;
  • actions_taken;
  • tools_run;
  • diagnostics with formatted evidence and raw metadata;
  • memory_id, memory_project_id;
  • obsidian_path, obsidian_push_error;
  • LLM usage and cost fields.

Backward-compatible fields such as summary, steps, devices_checked, root_cause, and resolution remain available.

Persistence

Postgres

Stores durable application state:

  • users and roles;
  • vessels and devices;
  • tasks, events, reports, approvals;
  • balance snapshots;
  • audit logs.

Database migrations live under backend/alembic/.

Redis

Stores operational state:

  • task queue;
  • live task event channels;
  • MCP command queue and status cache;
  • task cancellation and LLM escalation flags.

Project Memory

Task reports and durable operational facts are saved through an HTTP MCP server configured by MEMORY_MCP_URL. Task outputs use the project ID configured by MEMORY_TASK_PROJECT_ID.

Obsidian

The backend clones the configured vault repository into /runtime/obsidian-vault, writes task notes under OBSIDIAN_TASKS_FOLDER, and commits/pushes when OBSIDIAN_AUTO_PUSH=true.

MCP Integration Boundary

The application does not talk directly to infrastructure devices. It calls MCP tools. MCP servers hide the details of pfSense REST, Proxmox API/SSH, Asterisk shell/docker access, FortiGate/FortiSwitch APIs, and generic SSH.

This boundary makes the system extensible:

  1. Add or clone an MCP server.
  2. Add a device catalog entry if needed.
  3. Add rules/skills so the agent knows when to use it.
  4. Add diagnostics formatting for readable reports.

Security Boundaries

  • Device secrets are encrypted at rest.
  • Real .env values must not be committed.
  • MCP write tools are disabled by default unless each MCP explicitly enables writes.
  • MCP self-development requires approval by default.
  • Config-changing proposals are represented as approval requests before execution.
  • Project memory and Obsidian should store references and summaries, not secret values.