Repository navigation
server: serve --config FILE.toml reads flags from a file - #2885
Conversation
|
Marked ready for review. One dependency to keep in view when you queue it:
After #2883 lands I rebase this branch onto main, so that it holds only its own commits, and I refresh the checks on the new head. Against current main ( If you prefer to land both as one, this branch already contains #2883 in full and #2883 can be closed in its favour. |
|
Thanks @laudney, this is careful work. The reader is tight, the refusals read well, and the argv pin is exactly what we wanted. On relative paths, (a) is right: only
It lands after the 1.2.7 release, so there's no rush.
|
bddbcd7 to
0beaab4
Compare
|
Thanks for the review. All seven points are in head
On this head: |
|
Thanks @laudney, all seven are in on On the relative-path question in #2882: (a), as you built it. Only For the order: #2883 lands right after today's release, then please rebase this onto main so it holds only its own commits. CI hasn't started on
|
0beaab4 to
01b94ec
Compare
|
@laudney, rebased onto today's main on top of the rebased #2883 and force-pushed (
|
|
Thanks for the rebase. I leave both branches as you pushed them. Two checks on
The |
01b94ec to
63f6278
Compare
|
#2883 landed, so as you asked I rebased this onto main ( |
|
Choices, preferred first:
I will do (2) if you prefer it. |
A serve config file needs a reader, and Zig's standard library has none for TOML. This one takes a strict subset of TOML 1.0, top-level key = value lines with strings, decimal numbers, booleans and arrays of them, and refuses the rest by line, so every file it accepts is valid TOML with the same meaning and tables stay free for later use.
A launch of ten to twenty flags could live only in a shell script, where vLLM and SGLang take a config file. serve --config FILE.toml now turns the file's keys into flags ahead of the command line's, so the one parser runs and the command line wins; each key is checked against the flag table first, so an unknown key, a wrong type or an unserved flag is refused with the file and its line.
Operators need the key rule, the precedence and its three consequences before they move a launch into a file. This adds the flag's row to the README table, a page with an example, the value types, what the reader refuses and how errors name the file, and the changelog line that also records the --compact-at fix.
The engine now lists --config in its capabilities, so the launcher took it as an extra flag while it checks only the tokens it sees, and a file could turn on --cortheon, a learning flag or a key that Settings manages. The flag joins the managed set, with tests for both spellings, and the config page states that an integer loses its leading plus and that the launcher refuses the flag.
The maintainer accepted serve --config with four conditions, since the file chooses what is served and can hold a key. A relative path now starts at the file's folder, a file that other users can write is refused before it is read, a pair of switches has one key (thinking = false), and arrays hold strings only; the flag table marks which flags name a path.
The maintainer's review of serve --config found that a refused value named no line, that a command-line key left the file's key in force, and that the file was checked by path and then read by path. Each value now runs its flag's own check before the merge, a repeatable flag on the command line replaces the file's list, the file is opened once without following a link and read through that handle, an api-key file must be unreadable by others, and a path flag refuses a tilde.
63f6278 to
38a997a
Compare
|
Thank you @laudney. This is merged into main with your commits under your own name, so you're listed as a TensorFold contributor. It ships in the next release, credited to you in the changelog and the release notes. |
What this changes
tensorfold serve --config FILE.tomlreads serve flags from a TOML file. The file becomes flags ahead of the command line's and the existing table and parser read the result, so the command line wins and every flag keeps its one validation.tensorfold serve --config glm.toml--config glm.toml --port 9000: the command line winsglm.toml line 7: unknown key 'prot'glm.toml line 3: argument --port: invalid port: '99999'--api-key newleaves no file key in force)api-keyand that others can readchmod 600orapi-key-file--configcapabilities --json--config--config--config, since a file could set what Settings managesThe points from #2882, each as built:
toml_flat.zig, written here, no outside code: strings, decimal integers and floats, booleans, arrays of strings. Tables, dotted keys, inline tables, nested arrays, multi-line strings, dates,0x/0o/0bintegers and a byte order mark are refused by name with the line. Every file it accepts is valid TOML 1.0 with the same meaning.-or_. A pair of switches has one key, the positive one:thinking = false;no-thinkingis refused with the form to write. A switch with no positive twin keeps its name (no-drafts = true). A repeated key, an unknown key, an unserved flag or a wrong type is refused with file and line. A switch takes onlytrueorfalse.--configis refused. A relative path starts at the file's folder for the flags the table marks as paths (Flag.path);modelanddraftercan be a repo id, so only./and../values are placed beside the file. The page says so.auth.openKeys), checked on the handle and read from it.mode & 0o022, or not a regular file: refused. A file that setsapi-keywithmode & 0o044: refused with the line. A path flag refuses~. The startup log prints the file and a count, never a value.expandreturns the very slice it was given; the argument walk refuses nothing unless a--configis present.Argsand engine request as the flags typed by hand.100e4a084; this branch now holds only its own six commits,21a96990c..63f62789b.atc overlap --json: run 2026-11-11 09:43 UTC before the rebase:complete: false(the snapshot's limits); conflicts inCHANGELOG.mdonly, except Implement GLP control vectors with a fused Metal kernel for Qwen3.8-27B #1835 (open since October), which also adds a serve flag row inREADME.md,cli.zigandmain.zig. After the rebase GitHub reports the branch mergeable.Checks on this head
python3 tools/zig/lean_check.py, on the base and on this head: 341 and 341, 0 new (tools/pr_check.py --base upstream/main --pr 2885: 0 errors).cli.zigis 594 of 600 lines.zig build test-serve-flags-host test-server-cpuon this head: 1393 pass, 5 skip, 0 fail of 1398 (the server suite 1359 pass and 5 skip; the filtered step 34 pass).pytest web/tests/test_native.py web/tests/test_review_fixes.pyon this head: 43 pass.pytest456 pass, 1 skip, 1 fail. The failure istest_stand_in_reports_build_version_not_an_old_path_binary, which also fails without this change on my host (an oldertensorfoldonPATH). The newcheck_extracase fails without thenative.pychange.ruff checkclean.zig fmt --check build.zig zigandgit diff --check: clean.tensorfold-native, each exit 2:port = 99999(line 3, the flag's message),api-keyin a mode 0644 file,recall-dir = "~/r", a symlinked file. A mode 0600 file withapi-key = ["old"]under--api-key newlogsconfig: conf/good.toml (3 options), placesmodel = "./weights"atconf/weightsand reaches the hub's refusal for a model that is not cached.tomllib; it agrees on each.zig build test test-goldenin full, and the macOS and Windows builds. I have no Mac; thefchmodatmode is now@intCastas your Mac run showed, and the missing-file test expectsOpenFailedon Windows, whereauth.openKeysreports that.Receipt
n/a: the change reads a file into serve flags before the existing parser. It reaches no kernel, token path or arithmetic, and a command without
--configpasses the same argv to the parser.--config FILE.toml; no default (off); accepts one path that ends in.toml; no profile row, since it sets no environment switch.Checklist