Docs  /  Architecture

Architecture

Wylde is a fully native Windows platform — about twenty cooperating services, all running as host processes, all talking over Windows named pipes. The Fletch desktop app is the front door; everything else is interchangeable.

System overview

The platform is organised into six layers, each with its own responsibilities.

HOST (Windows 11)  —  all services run as native processes
Primary IPC:  \\.\pipe\wylde-{service}   (u32 length-prefix + msgpack)
Fallback IPC: HTTP loopback  127.0.0.1:{port}

  ┌──────────────────────────────────────────────────────────┐
  │  TAURI DESKTOP APP — Fletch GUI (Svelte 5 + Rust)        │
  │  Rust pipe client → \\.\pipe\wylde-*                     │
  └──────────────────────────────────────────────────────────┘
                       │
  ┌──────────────────────────────────────────────────────────┐
  │  CORE                                                    │
  │   security-api :5000   ──proxy──►  tool-registry :8004   │
  │   wylde-launcher :8012 ──spawn──►  all native services   │
  │   device-gate :7000                                      │
  │   tool-runner :8001                                      │
  │   wylde-sysmon :9100   (metrics + diagnostics/backup)    │
  └──────────────────────────────────────────────────────────┘
                       │
  ┌──────────────────────────────────────────────────────────┐
  │  DATA                                                    │
  │   wylde-rag :8008  ──graph queries──►  wylde-graph       │
  │   wylde-voice :8009                                      │
  │   wylde-caption :8015                                    │
  └──────────────────────────────────────────────────────────┘
                       │
  ┌──────────────────────────────────────────────────────────┐
  │  ORCHESTRATION                                           │
  │   wylde-orchestrator :8010 ──inference──►  Ollama :11434 │
  │   wylde-trainer :8013                                    │
  │   wylde-improve :8016                                    │
  └──────────────────────────────────────────────────────────┘
                       │
  ┌──────────────────────────────────────────────────────────┐
  │  NETWORK                                                 │
  │   n8n-service :5679 ──REST──►  n8n :5678                 │
  │   webcrawler-service :8003                               │
  │   wylde-vpn :8020 ──TURN──► [ coturn — Docker opt. ]    │
  └──────────────────────────────────────────────────────────┘
                       │
  ┌──────────────────────────────────────────────────────────┐
  │  GRAPH                                                   │
  │   wylde-graph  \\.\pipe\wylde-graph  /  Bolt :7687       │
  └──────────────────────────────────────────────────────────┘

Transport & IPC

Every native service registers a Windows named pipe at startup:

\\.\pipe\wylde-{service-name}

Wire format is a u32 big-endian length prefix followed by a msgpack body. HTTP loopback on a fixed port is always available as a fallback for debugging or external access — set WYLDE_TRANSPORT=http to force every call onto HTTP.

Hot-path latency:

  • ~0.1 ms over a named pipe
  • ~1.5 ms over HTTP loopback

That's why the pipe is the default — it adds up fast across multi-step orchestrator workflows.

Discovery

Two discovery backends run in parallel and are merged by tool-registry:

BackendScopeConfig
mDNS (python-zeroconf)Native servicesWYLDE_DISCOVERY=mdns (default)
ConsulLegacy / Docker containershttp://127.0.0.1:8500

The registry deduplicates by (name, address, port), polls every healthy service for its /api/tools definition, and re-publishes the unified catalog. New services appear automatically the moment they bind a pipe.

Execution path

A typical tool call from the desktop app looks like this:

Fletch GUI  (Rust pipe client)
  │  msgpack call → \\.\pipe\wylde-tool-registry
  ▼
tool-registry
  │  finds the tool → owned by tool-runner
  │  msgpack call → \\.\pipe\wylde-tool-runner
  ▼
tool-runner
  │  executes Python in a subprocess
  ▼
  {status, returncode, stdout, stderr}
  ↑  bubbles back to caller

Service adapter pattern

Services that wrap a third-party backend (e.g. n8n) follow a consistent adapter shape so the registry can route to them identically to first-party services:

tool-registry
  │  POST /api/n8n-service/execute_workflow
  ▼
n8n-service  (:5679)            # Flask adapter
  │  POST /rest/workflows/{id}/execute
  ▼
n8n  (:5678)                    # native third-party engine

Every adapter exposes GET /health, GET /api/tools, and POST /api/<tool_id>.

Remote access layer

When the Remote Access toggle in Fletch is on, an additional layer comes online:

Phone (Tailscale 100.x.x.x)
  │  http://<tailscale-ip>:3000
  ▼
fletch-web  (nginx :3000)
  │  auth_request → device-gate:7000/check
  │    ├─ 200 → serve Svelte SPA
  │    └─ 403 → pending.html (auto-refresh every 15s)
  │  /gate/     → device-gate:7000
  │  /registry/ → security-api:5000

The web build of the Svelte app sets VITE_IS_WEB=true, which auto-authenticates after the device-gate has approved the device — no double login.

Design rules

  • Loopback by default. All services bind to 127.0.0.1 except fletch-web, which only starts when Remote Access is on.
  • No hardcoded routes. Services self-register; the registry discovers them.
  • Health-driven exposure. If a service is down, its tools disappear from the catalog automatically.
  • Single source of truth. Components and tools live in YAML under docs/_data/; reference docs are generated from there.