Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

Architecture

flowchart TB Canvas["Canvas (SolidJS + SVG)<br/><code>apps/canvas</code><br/>drag/drop, property panels, live preview,<br/>CRDT real-time editing, debugger overlay"] API["ScaiFlow API (FastAPI)<br/><code>apps/api</code><br/>/v1/flows, /v1/admin, /v1/catalog,<br/>/v1/scaicore proxy, /v1/scaiqueue,<br/>/v1/scaibunker, /v1/scaigrid/models"] DB[("DB<br/>MariaDB Galera<br/>flow metadata<br/>(alembic-managed)")] Store[("Object store<br/>filesystem or S3<br/>per-version flow JSON")] ScaiGrid["ScaiGrid (control plane)<br/>POST /v1/modules/scaicore/cores<br/>POST /v1/modules/.../{id}/publish<br/>GET /v1/modules/scaicore/events"] ScaiCore["ScaiCore<br/>runtime that actually executes invocations"] Canvas -->|ScaiKey JWT via BFF<br/>/v1/auth/exchange| API API --> DB API --> Store API -->|ScaiCore YAML manifest| ScaiGrid ScaiGrid --> ScaiCore

Pieces#

Canvas (apps/canvas)#

A SolidJS single-page app. Hand-written SVG renderer (no xyflow, no reactflow). Edits run through flowStore, which keeps the canonical FlowGraph JSON in memory; persistence is autosave-to-localStorage plus an explicit Save to the backend.

When ScaiKey OIDC is configured, the canvas authenticates via PKCE and exchanges the auth code for tokens through the backend's BFF (POST /v1/auth/exchange). A dev-token fallback exists for environments without ScaiKey.

ScaiFlow API (apps/api)#

FastAPI backend exposing /v1/*. Owns:

  • Flow CRUD + deploy (/v1/flows) — list, get, create, update, delete, deploy, run-tests, list versions.
  • Auth (/v1/auth/*) — runtime ScaiKey config, BFF token exchange + refresh, /v1/me.
  • Admin (/v1/admin/*) — ScaiKey-driven user/group sync, super_admin role grants, tenant flow visibility for tenant admins.
  • Catalog (/v1/catalog/*) — per-tenant private flow packages.
  • Lookups (/v1/scaiqueue/*, /v1/scaibunker/*, /v1/scaigrid/*, /v1/scaicore/*) — read-only proxies into ScaiGrid so the canvas never holds tenant API keys.
  • Webhooks (/v1/webhooks/scaikey) — ScaiKey-signed events that update the local user/group mirror.
  • CRDT relay (/v1/flows/{id}/sync WebSocket) — Yjs document fan-out for real-time editing.

Persistence is split: SQLAlchemy async on MariaDB for metadata (Alembic-managed schema), filesystem or S3 for the actual flow JSON content (keyed by flows/{tenant_id}/{flow_id}/v{version}.flow.json, never updated in place).

Compiler (apps/compiler)#

A Python library, not a service. compile_flow(flow_json, output_format="yaml") turns flow JSON into either:

  • A YAML manifest for ScaiGrid (POST /v1/modules/scaicore/cores) — the default, the deploy artifact.
  • A SCIR MessagePack IR bundle (output_format="ir") — the upstream-canonical binary form, useful for verification and direct-runtime experiments.
  • A .scai text source (output_format="scai") — deprecated, mostly for inspection.

The same compiler runs in the API backend (for the live preview + deploy paths) and in the standalone CLI.

ScaiGrid (control plane)#

External — see the ScaiGrid docs. Accepts the YAML manifest, persists the Core, can optionally publish it as a chat model. ScaiFlow talks to ScaiGrid via the scaigrid-client SDK.

ScaiCore (runtime)#

External — see the ScaiCore docs. Actually executes invocations against the Core that ScaiGrid persisted. ScaiFlow doesn't talk to ScaiCore directly; the deployed Core does the runtime work.

Auth flow at a glance#

sequenceDiagram participant Canvas as Canvas (browser) participant API as ScaiFlow API (BFF) participant ScaiKey participant ScaiGrid Canvas->>API: 1. PKCE code + verifier API->>ScaiKey: 2. add client_secret, exchange ScaiKey-->>API: access_token + refresh_token API-->>Canvas: 3. user JWT (aud = client_id) Canvas->>API: 4. bearer on every subsequent call API->>ScaiGrid: forward user JWT Note over API,ScaiGrid: Background jobs fall back to<br/>per-tenant API key from ScaiVault

The single ScaiKey client_id is shared by the canvas (browser) and the backend. The backend keeps the client_secret server-side; the canvas hands the auth code over for exchange.

ScaiGrid accepts the user JWT directly (its audience is the ScaiKey client_id, which ScaiGrid trusts), so the same token flows end-to-end. For non-user contexts (cron jobs, background sync), the backend falls back to a per-tenant sgk_* API key stored in ScaiVault under tenants/{tenant_id}/scaigrid_api_key.

Updated 2026-05-18 16:05:17 View source (.md) rev 3