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

The ScaiCore language and its standalone runtime are documented separately at /docs/scaicore. They are not part of this module. This page is about the ScaiGrid wrapper that hosts a compiled ScaiCore program inside ScaiGrid — what it adds and where the seam is.

Two ScaiCores, one diagram#

flowchart LR subgraph Machine[Your machine] Compiler[scaicore<br/>compiler] end subgraph ScaiGrid["ScaiGrid /v1/modules/scaicore/"] Row[Core row DB<br/>checkpoints<br/>delegations<br/>plugins<br/>FrontendModel] AdminAPI[Admin UI + API] end subgraph Library["ScaiCore (library)"] Engine[CoreEngine<br/>.ainvoke&#40;&#41;<br/>.aresume&#40;&#41;] Host[HostEnvironment<br/>memory, models,<br/>events, plugins,<br/>placement] end Compiler -- "IR bundle" --> Row Row -- "invoke / resume" --> Engine Engine --- Host

ScaiCore-the-library is invoked, not deployed. The wrapper holds the IR bundle, manages the row, calls CoreEngine.ainvoke() / aresume() on behalf of API or event callers, and threads ScaiGrid services into the HostEnvironment so the program can use real Redis, real MariaDB, real model inference, real S3, and real event bus instead of in-process stubs.

What the wrapper owns#

  • Persistence. The mod_scaicore_cores table holds the IR source, the runtime config, the identity mode, the plugins list, the (encrypted) environment, the avatar URL, and the lifecycle status.
  • Lifecycle state machine. created → starting → running → stopping → stopped; running → paused → running; running → error; crashed → restarting → running. The wrapper enforces the legal transitions.
  • HostEnvironment backends. Production backends for memory (Redis), checkpoints (S3 + MariaDB), models (InferenceService), events (EventBus), plugins (HTTP bridge), entity placement (Redis Grain Directory).
  • Checkpoints. Captured into mod_scaicore_checkpoints, routed by assignee, expired or escalated by a 5-minute cron, resolved via the API or the admin UI's checkpoint queue.
  • Identity. Service-account by default. Delegation lets a Core run as a specific human user, with explicit scopes and an optional expiry; the delegated user is resolved on start() exactly like JWT auth.
  • Plugins. Plugin definitions live on the Core row as a JSON list; the HTTP bridge in the HostEnvironment calls the registered endpoints when the program asks for them.
  • Publishing. A Core can be published as a FrontendModel (slug scaicore/{tenant_slug}/{core_slug}); after publication the Core is callable through any model-aware ScaiGrid API.
  • Admin UI pages. Dashboard, editor, console, logs, debugger, identity, checkpoint queue, checkpoint history, plugin marketplace, event monitor (mounted by the module registry).

What the language owns#

  • The DSL, the compiler, the IR format, semantic versioning of IR schema.
  • CoreEngine.ainvoke() / aresume() — interpreting the IR, calling models, materialising checkpoints, scheduling resume.
  • The HostEnvironment protocol — what the wrapper has to implement to host a Core.
  • Standalone-runtime concerns (CLI tooling, local dev, package layout).

If something feels like "how does the program execute?", that's the language. If something feels like "how do I run the program in ScaiGrid and let humans interact with it?", that's this module.

Request flow for one event#

  1. Caller posts POST /v1/modules/scaicore/cores/{id}/events with {event_name, data}.
  2. Auth. Standard ScaiGrid bearer-token auth; tenant scoping enforced on every row read.
  3. Routing. The wrapper resolves the Core, validates it is running, and dispatches to CoreEngine.ainvoke() with trigger_type=EVENT. (Eventing currently records the dispatch as accepted — runtime invocation is wired through the HostEnvironment.)
  4. Execution. The CoreEngine interprets the relevant flow; tool calls / inference go out through the InferenceService and back; events fire over the EventBus.
  5. Checkpoint (if any). Execution suspends; a row is written to mod_scaicore_checkpoints; a notifier emails the resolved assignee.
  6. Resolution. A human posts POST /checkpoints/{id}/resolve; the row is updated; the runtime resumes from the captured state.

State#

  • Cores, checkpoints, delegations, plugin configs — MariaDB tables under the mod_scaicore_* prefix.
  • Encrypted env varsenvironment_encrypted blob on the Core row, with a wrapped DEK + IV.
  • Avatars — Garage S3 under scaicore/{tenant_id}/{core_id}/avatar, served back through an internal proxy path.
  • Checkpoint state blob — S3, keyed by state_s3_key on the row.
  • Engine instances — in-process EngineRegistry keyed by core_id; cleaned up on stop / delete.

How it differs from the standalone runtime#

The standalone runtime (documented at /docs/scaicore) runs a Core in-process with stub backends. The wrapper differs in five places:

Concern Standalone ScaiGrid wrapper
Storage In-memory / local files MariaDB + S3, tenant-scoped
Identity Whatever you pass in Service-account or delegated human
Checkpoints Block until resolved in-process Persisted, routed to assignees, surfaced in admin UI
Models You wire them Resolved through ScaiGrid's inference router (accounted)
Multi-tenancy None Every row tenant-scoped, RBAC-gated, audit-logged

For everything else — the IR, the compiler, semantic versioning, language reference — see /docs/scaicore.

Updated 2026-05-18 15:01:29 View source (.md) rev 11