DocsUse it from3 min read

C & other languages#

Load a trained shad0w table from C and decide in about 1.0 µs. The core is one file, reflex.c, plus a header, shad0w.h. It needs only libc and libm. Use it from C, C++, or any language with a C FFI.

This page gives you the two files, a complete program, and the five functions. Training still happens in Python.

TL;DR#

D=$(python -c "import shad0w, os; print(os.path.dirname(shad0w.__file__))")/_native
cp $D/shad0w.h $D/reflex.c .
cc -O2 app.c reflex.c -lm -o app        # app.c below

1. Get the two files#

They ship inside the Python package, in shad0w/_native/. The commands above copy them next to your code.

2. Read the manifest#

A trained bundle is a folder: manifest.json plus one <question>.s0 file per question. The C core reads the .s0 file. Two values come from manifest.json, under questions.<name>:

Manifest field What it is Used for
options the option names, in table order turning the index k into a name
threshold the certified confidence threshold the answer is certified when probs[k] >= threshold. null means the table certifies nothing: always ask your LLM.
calibrated false when the table has no certificate treat every answer as uncertified
type "choice" or "yesno" for yes/no, options are ["no", "yes"]: k == 1 means yes

3. Decide#

#include <stdio.h>
#include <string.h>
#include "shad0w.h"

int main(void) {
  S0Reflex *m = s0_load("bundle/intent.s0");                               /* NULL if missing or corrupt */
  if (!m) return 1;
  const char *options[] = {"refund", "lost_card", "balance", "other"};     /* manifest.json "options", same order */
  const float threshold = 0.911f;                                          /* manifest.json "threshold" */

  const char *text = "my card was stolen";
  float probs[S0_MAX_CLASSES], radius;
  int k = s0_decide(m, text, (int)strlen(text), probs, &radius);
  if (probs[k] >= threshold) printf("%s (certified, %.3f)\n", options[k], probs[k]);
  else printf("ask the LLM (table guessed %s, %.3f)\n", options[k], probs[k]);

  s0_free(m);
  return 0;
}
cc -O2 app.c reflex.c -lm -o app && ./app
lost_card (certified, 0.993)

Text is UTF-8; pass its length in bytes. The answers are identical to Python's and JavaScript's on the same table.

Threads#

A loaded table is read-only and can be shared across threads. Give each thread its own probs buffer.

Functions#

Function What it does
S0Reflex *s0_load(const char *path) load a .s0 table; NULL on any error (missing file, wrong version, truncated, unsorted keys)
int s0_decide(m, text, len, probs, &radius) returns the index of the best option; writes every option's probability to probs (s0_num_classes(m) floats) and the robustness radius (how many inserted words it takes to flip the answer; INFINITY when none can)
uint32_t s0_num_classes(m) the number of options
double s0_bench(m, texts, lens, n, reps, per_call_ns) mean nanoseconds per decision over reps passes; per_call_ns may be NULL
void s0_free(m) release the table

S0_MAX_CLASSES (1024) is the largest number of options a table can have.

The C core does not apply the drift guard or the rollout settings (mode, canary, never_serve); those live in Python. For them, use the HTTP server or the proxy.

Other languages#

Language How
Go cgo: // #include "shad0w.h" and build reflex.c with the package
Rust bindgen, or a five-line extern "C" block
Swift / Objective-C add both files to the target
Java / Kotlin JNI or Panama
Anything else the HTTP server, or the proxy for OpenAI-compatible clients