Repository navigation
Description
Area
[Engine] (speed, kernels, models, the server and API) — the server's run config, rewritten by strata launch.
Desktop app, Terminal or source?
Docker
What happened
On a Docker install I added a documented run-config key to the run config file that GET /config names for the running model:
$ curl -s -H "x-api-key: $KEY" http://127.0.0.1:8080/config
{"file": "gyrom.json", "keys": [ … ], "note": "Saved to the run config; used from the next start of the model."}
I added "tool_call_recovery": true (and "reasoning_close_retry": true) to that file at top level, next to "args", then ran docker restart strata. After the restart both keys were gone from the file, the settings were not in effect, and nothing in docker logs strata mentioned it.
The same file is the one Strata's own Model settings card writes: POST /config ends up in serve/runconfig.py:save(path, cfg), which writes the file the server loaded and says the change is "used from the next start of the model". On Docker that promise cannot hold, because the next start goes through strata launch, which re-derives that file from the installed config before the server reads it:
docker/entrypoint.shends instrata launch --no-tui --access lan … --preset "$PRESET", plus--save-preset "$PRESET"whenever any setting environment variable is set — the normal compose setup (MODEL_PATH,CONTEXT,KV, …).strata_cli/launch/runner.py:build_config()runs on every launch, not only on--save-preset:base = read_config(base_path)— the installed config from setup (strata-<model>.json,/data/install/in the Docker layout),cfg = derive_config(base, self.s, …)— "the installed one plus the choices that are not setup's",out = launch_dir() / f"{self.name}.json"; write_private(out, cfg)— it overwrites the private run config (thegyrom.jsonabove), andself.config_path = outmakes that overwritten file the one the server runs with.
Net effect: in a Docker install there is no path a user has for a run-config key that GET /config does not expose:
- the Model settings card cannot set it —
serve/runconfig.py:EDITABLElists 16 keys and neithertool_call_recoverynorreasoning_close_retryis among them; strata profile setaccepts onlyOVERRIDE_KEYS(strata_control/profiles.py:host,port,parallel,batch_groups,max_queue,queue_timeout,offline, …);STRATA_SET/launch --setare documented as engine settings orSTRATA_*variables;- hand-editing the file named by
GET /configis discarded by the next launch as shown above.
This matters in practice because both affected keys are the documented remedy for the "a reply ends inside its thinking / a call written in the thinking, so no tool call is delivered and the agent stops" family: tool_call_recovery (docs/DETAILS.md: "On 1,462 agent turns 98.3% read as intended with it and 92.9% without") and reasoning_close_retry (#1053, #2731). Following that advice on a Docker install is what led me to this report.
Smallest steps or command that reproduce it
- Docker install, any model, started through the image's own entry point (
docker run … -v strata-data:/data …with at least one setting such asMODEL_PATHorCONTEXT, so the entry point re-saves the preset on every start). - Find the file
GET /confignames:curl -s -H "x-api-key: $KEY" http://127.0.0.1:8080/config | head -c 120 docker exec strata sh -c 'find /data -name "gyrom.json"' # the same name; the launch writes it under the state folder's launch/ directory
- Add
"tool_call_recovery": trueat top level (not inside"args"), keep a copy:cp gyrom.json gyrom.json.mine. docker restart strata, wait for the model to load.- Diff:
docker exec strata sh -c 'grep -n tool_call_recovery $(find /data -name "*.json")'→ nothing;diffagainstgyrom.json.mineshows the launch rewrote the file./data/install/strata-<model>.json(the installed config) is unchanged, which is where the key belongs — see the workaround below.
Expected: either the key stays, or the launch says it dropped something.
Reproduction status
Unconfirmed static analysis (I read code or ran a scanner; I did not see it fail)
The loss of the key was observed on a live Docker install (0.2.7, engine 0.1.52) and matches the code path quoted above line for line, but I did not run the sequence myself end to end. Logs, the file before and after, and any further command output I will add on request.
Strata version
Strata 0.2.7 · engine 0.1.52 — Docker image; /props build_info = Strata 0.1.52, /metrics engine.version = 0.1.52
Graphics card, memory and system
NVIDIA GeForce RTX 5060 Ti 16 GB · 64 GB RAM · Linux host, Docker container (/data volume), context 163840, --kv int8, 2 slots
Model, size and settings
Qwen3.8-Flash-Next-Gyro-M TQ2_0 (single GGUF) · 163840 context · kv int8 · parallel 2 · vision on · thinking on at xhigh
Logs
Nothing is logged when the key is dropped — no [strata] … line, no warning — which is part of the report. docker logs strata for that restart shows only the ordinary launch lines (preset, model, tuning kept, engine start). I can attach them, and the before/after copies of the run config, on request; they contain an API key and paths, so I would redact first.
Suggested directions
build_config()could start from the existing private run config when it is newer than the installed one, or merge its keys, instead of deriving it from scratch frombase.- Or report the difference the way the [Engine] Tool-call parser silently returns a malformed <function=...> block as plain assistant content #3441 path does: one
[strata] … discarded run config key "tool_call_recovery"line would have made this visible indocker logs. - Or expose
tool_call_recoveryandreasoning_close_retryinserve/runconfig.py:EDITABLE(both are documented config keys indocs/DETAILS.md), so the Model settings card can set them likeapi_monitorandreasoning_budget_tokens.
Workaround, if this is by design
Put the key in the installed config instead of the private one: /data/install/strata-<model>.json in the Docker layout. derive_config() starts from that file, so the key is copied into the private config on every launch and survives restarts. Worth a line in docs/DOCKER.md next to STRATA_SET, since "edit strata-<model>.json and restart" (docs/DETAILS.md, Quick start step 4) reads as if the file /config shows is that file.
Related issues
Not a duplicate of #4077 / #4078 (parser behaviour, reasoning and tool-call markup) — this is about the run config being rewritten before the server reads it, and it blocks the remedy those threads recommend. #1503 (fixed in 0.2.7) and #2518 are about the conversation cache, not the config file.
Activity