Skip to main content

When you’d care

Most application developers consume Syni through a language SDK — the Flutter SDK, and (later) Swift / Kotlin equivalents — and never see the C ABI. This page is for the people who do:
  • SDK authors adding a new language binding over the same engine.
  • Native integrators plugging the runtime into a non-Flutter / non-mobile surface (a CLI tool, a server worker, a desktop app).
  • Debuggers chasing symbol-level issues across the FFI boundary.

ABI rules

  • The C ABI is the stable boundary. Runtime internals are not.
  • Symbols, struct shapes, error codes, and lifetimes documented here are the contract — they MUST NOT change without a major version bump on the runtime package.
  • Every handle has a _destroy counterpart. Leaks are the caller’s fault.
  • All strings are UTF-8, NUL-terminated, owned by the caller of the API unless explicitly documented otherwise.

Install

Runtime artifacts are distributed via dist.synheart.ai and installed by the Synheart CLI:
The CLI drops a vendor-ready tree under your project:
The same artifact layout is the source of truth for all language bindings.

1. Handle and lifecycle

The engine is opaque — callers hold a single SyniRuntimeHandle* for the lifetime of a load.
Lifecycle:
  • create validates config and allocates resources but does not mmap the model file.
  • load mmaps the model, materialises tokenizer + grammar, and is the expensive call (~hundreds of ms cold).
  • destroy is safe to call at any state. Subsequent calls on the handle are undefined.

2. Configuration

Per-platform notes:
  • Apple: set metal = true for GPU acceleration. Falls back to CPU automatically if Metal is unavailable.
  • Android: CPU only — the metal and cuda flags are ignored.
  • Backend: CANDLE is the default — it’s what the published artifacts on dist.synheart.ai ship with. LLAMA requires a runtime variant built with the llama.cpp backend enabled, which is not part of the default published artifacts today.

3. Generation

Generation is request/response, optionally streamed via a callback.
The streaming callback returns 0 to continue, non-zero to cancel. On cancel, syni_generate returns SYNI_STATUS_CANCELLED and out_full contains the partial response so far.

4. Grammar-constrained decoding

When grammar_gbnf is non-NULL, the runtime constrains decoding to outputs valid against the GBNF. Bind grammars to schemas via the Syni Spec registry:
GBNF parse failures surface as SYNI_STATUS_INVALID_GRAMMAR at request time, not at generation time.

5. Status codes

Status semantics:
  • OK — success.
  • INVALID_CONFIG / MODEL_NOT_FOUND — caller bug; surface verbatim.
  • LOAD_FAILED — likely corrupted model file or unsupported architecture.
  • INVALID_GRAMMAR — GBNF didn’t parse against the schema.
  • OOM — model too large for device; suggest a smaller variant.
  • CANCELLED — caller-initiated; not an error.
  • INTERNAL — bug in the runtime; capture logs and file an issue.

6. Memory management

  • Every *_create has a matching *_destroy. Caller owns the handle.
  • Returned C strings (out_full) are heap-allocated by the runtime and must be freed with syni_string_free.
  • The runtime is thread-safe per handle: concurrent calls on the same SyniRuntimeHandle are serialised internally; concurrent calls on different handles run in parallel.

7. Backends

Only the Candle backend is published to dist.synheart.ai today. The llama.cpp backend exists in the runtime but is not part of the default published variant; treat it as a future option rather than something you can opt into from the released artifacts.

Symbols this page does not document

This page covers the stable surface only. The runtime exports a number of internal symbols (_dbg_*, _unstable_*) for diagnostics — these may change without notice between patch releases.
  • Syni overview — how the runtime fits with the Flutter SDK and the spec
  • Syni Flutter SDK — the Dart wrapper over this ABI
  • Syni Spec — persona / grammar / safety contracts the runtime consumes
  • C header: synheart/vendor/syni-runtime/headers/syni_ffi.h after install