Four commands that shipped as deferred stubs in v0.68.0 are now real, validated end-to-end on tiny models (real DPO train on SmolLM2-135M + real Ollama teacher distillation, RTX 3050 4 GB).
What's New
soup local-rl train --once(#229) — harvest your latest 👍/👎 feedback into DPO pairs and train a real DPO/KTO/ORPO round viasoup train(argv list, no shell). Astatetable tracks the last train so a re-run with no new feedback skips, and a run with fewer than--min-pairs(default 10) skips. Without--onceit renders a systemd.service/.timer+ launchd.plistnightly scheduler scaffold into--scheduler-dir. New flags:--once,--min-pairs,--output/-o,--scheduler-dir,--hour,--minute.soup distill-prompt(#226) — call a teacher (Ollama / Anthropic / vLLM) once per trace and write a real distillation dataset:sft/kl→{messages},preference→{prompt, chosen, rejected}. New flags:--provider,--base-url,--temperature,--max-rows.soup compile(#225) — DSPy / GEPA / TextGrad prompt-program optimisation — andsoup compile-tools(#227) — TextGrad / GEPA tool-schema optimisation (reuses Agent Forge spec parsing) — both behind the new[compile]extra with a friendlyImportErrorwhen absent.--plan-onlyrenders the plan and exits 0.
Install / Upgrade
pip install -U soup-cli
pip install -U 'soup-cli[compile]' # for soup compile / compile-tools (dspy-ai + textgrad + gepa)Security
- systemd / launchd injection defence (#229) —
local-rland the scheduler renderers reject\n/\rin the model id and shell-quote everyExecStartargument, so a crafted model id cannot inject extra unit directives.
Fixed
- The nightly
soup trainYAML now rendersoutputas a plain string (schema-valid) instead of a{dir: ...}mapping; a regression test validates the rendered config againstSoupConfig. (Caught by the step-6 smoke — a real DPO train on SmolLM2-135M.)
Known Limitations
- #225 / #227 real-library run not validated in-tree — the live DSPy / TextGrad / GEPA dispatcher + injectable seam + a genuine missing-dep
ImportErrorpath all ship, but the actual optimiser run is exercised only whenpip install 'soup-cli[compile]'is present (the libs are not in the test env to avoid a pydantic/litellm conflict). The orchestration runs end-to-end on real input up to the honest[compile]gate. distill-promptteacher is called once per trace, sequentially — no batching; throughput is provider-bound.local-rl trainis single-round —--oncetrains one DPO/KTO/ORPO round from the current thumbs; multi-round refinement is the separatesoup iterative-dposurface.- scheduler scaffold is render-only —
write_scheduler_fileswrites the unit files but never runssystemctl/launchctl; the printed instructions show how to install them.
Full notes: CHANGELOG.md