Recipes
Short, tested paths from an intent to a working result. Each recipe lists its
prerequisites, the commands, what they print, and what to do when they print
something else. Every command block in these files is run by
internal/srcgate.TestRecipesRun against a real jitllmd, so a recipe that
stops working fails a test instead of a reader.
| Recipe | What you end up with |
|---|---|
| Start a server and make the first request | jitllmd serving a model, and a completion and a chat reply from it |
| Connect an OpenAI-compatible client | the Python and JavaScript openai SDKs, and curl, talking to jitllmd |
| Tools and structured output | tool calls (chosen and forced) and replies held to a JSON schema |
| Choose a supported checkpoint and convert it | a .jlm container, and a way to tell an unsupported model before downloading it |
| Memory budgets and device placement | a model held to a memory budget, and blocks placed where you ask |
| Diagnose a slow or failed request | the server’s own account of where a request’s time and memory went |
All of them need the two binaries, jitllm and jitllmd, on your PATH
(install), and curl. They run on a machine with no
GPU. Every server in them listens on 127.0.0.1:4242.
The capability manifest (docs/capabilities.json, jitllm capabilities) and
jitllm doctor answer “does this build support my model and workload” and “what
is wrong with this machine” in machine-readable form, where a build has them.
How the test runs a recipe
Section titled “How the test runs a recipe”TestRecipesRun builds jitllm and jitllmd from the tree, then for each
recipe makes an empty working directory, puts the two binaries first on PATH,
and runs the fenced blocks in order:
```shblocks run withbash -euo pipefail, each in a fresh shell (a block does not inherit another’s variables).```pythonblocks run withJITLLM_RECIPE_PYTHON(defaultpython3) when it canimport openai, and are skipped by name when it cannot.```jsblocks run as ES modules withnodewhen it canimport 'openai'(from the working directory, which linksJITLLM_RECIPE_NODE_MODULESas itsnode_moduleswhen that is set), and are skipped by name when it cannot.```textand```jsonblocks are shown, not run.
Every 127.0.0.1:4242 and 127.0.0.1:80NN address is rewritten to a free port, the same one for the
same address throughout a recipe. An HTML comment directly before or after a
block steers it:
| Comment | Meaning |
|---|---|
<!-- test: background --> |
before a block: start it and leave it running; it is stopped when the recipe ends |
<!-- test: expect TEXT --> |
after a block: its output must contain TEXT (several may follow one block) |
<!-- test: exit N --> |
before a block: it must exit with status N |
<!-- test: instead COMMAND --> |
before a block: run COMMAND in its place. Only for downloads: COMMAND copies the same file from the repository ($JITLLM_REPO) or the test model directory ($JITLLM_TEST_MODELS) |
<!-- test: needs FILE --> |
every later block needs FILE in the test model directory (JITLLM_MODELS); without it they are reported missing, which fails the test except in the model-free run, where it is a named skip |
<!-- test: skip REASON --> |
before a block: not run, and the reason is logged |
Run them:
./scripts/cap 8G -- taskset -c 0,2,4,6,8,10 go test ./internal/srcgate -count=1 -run TestRecipesRun -vJITLLM_RECIPE=diagnose runs one recipe. CI’s model-free run executes every
block that needs only the repository’s own testdata/models/stories260K.gguf.