Skip to content

v1.8.7-ce — Controllable generation: GENERATE options + json_object()

Released: 2026-06-19 · Tag: v1.8.7-ce · Docker: synapcores/community:v1.8.7-ce

Before this release, GENERATE() took a prompt and nothing else. You got whatever the model felt like returning, capped at 200 tokens, with no way to make the output reproducible or to force it into a shape your next SQL statement could parse. This release makes generation controllable from SQL.

What's new

1. GENERATE(prompt, options) — sampling and output-shape knobs

The optional second argument is a JSON object. Build it with the new json_object() function:

SELECT GENERATE(
  'Summarize this review in one sentence: ' || review_text,
  json_object('temperature', 0.2, 'seed', 42, 'max_tokens', 200)
) AS summary
FROM reviews
WHERE rating <= 2;

Recognized keys:

Key Type Notes
max_tokens INT Default is now 4096 (was 200). See the breaking-change note below.
temperature FLOAT
top_p FLOAT 0–1
top_k INT
repeat_penalty FLOAT
seed INT Same seed + same prompt → reproducible output.
system TEXT System-prompt override.
grammar TEXT GBNF grammar constraining the sampler.
grammar_triggers JSON array With grammar, activates it lazily once a trigger string appears.
response_format "json" Applies a built-in lazy JSON grammar — output is a valid JSON value.

2. response_format => 'json' — output you can actually parse

Asking a model politely for JSON gets you JSON most of the time. Constraining the sampler gets you JSON every time:

SELECT GENERATE(
  'Extract the customer name and the sentiment from: ' || review_text,
  json_object('response_format', 'json')
) AS extracted
FROM reviews;

The engine installs a JSON grammar that activates lazily on the first {. The laziness matters: an eagerly-applied JSON grammar collapses llama.cpp's grammar stack on some models, which is why this ships as a built-in rather than something you hand-write into the grammar key.

3. json_object(key, value, ...) — build option objects in SQL

SELECT json_object('temperature', 0.1, 'seed', 7);
-- {"temperature":0.1,"seed":7}

It is a general-purpose JSON-object constructor, registered on both engine execution paths. It is how you pass structured arguments to any SQL function that takes them — today GENERATE(), and from v1.8.9 also AGENT_RUN() and MEMORY_UPSERT().

Breaking change to watch

GENERATE()'s default max_tokens moved from 200 to 4096.

If you relied on the old 200-token cap to keep responses short, they will now run longer, and per-row GENERATE over a large result set will be correspondingly slower and more expensive. Pin the old behavior explicitly:

SELECT GENERATE(prompt, json_object('max_tokens', 200)) FROM ...;

The old default was a footgun in the other direction — it silently truncated agent and summarization output mid-sentence, which read as a model quality problem rather than a configuration one.

Upgrading

No data migration. Pull the new image or re-run the installer:

curl -fsSL https://get.synapcores.com | sh
# or
docker pull synapcores/community:v1.8.7-ce

All pre-v1.8.7 GENERATE(prompt) calls keep working unchanged.

What's in this release

One commit on top of v1.8.6.1-ce:

Commit Subject
9d38e353 fix(query): v1.8.7 GENERATE options + json_object() SQL fn

Full SQL reference: GENERATE · Releases overview