You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat: agent configs can be YAML or TOML files (1.11.0) - #192
Agent configs could only be saved as JSON, which is hard to read and edit by hand for configs this deeply nested. A config file's extension now sets its format, so agent_configs/ can hold .json, .yaml/.yml or .toml files, and agents add and agents pull take --config-format to pick the format of new files.
Details
Where the format comes from: the extension of the config path in agents.json (or tools.json, tests.json). Anything that isn't .yaml/.yml/.toml is read as JSON, so existing projects behave exactly as before. The index files themselves stay JSON.
Which commands it reaches: every config read and write goes through project::read_value / write_config_in_project, so push, status, test, graph, workflow diagram and the tool and test commands all handle the three formats. write_json_in_project is renamed to write_config_in_project to match.
--config-format (json, yaml, toml):
On pull, it applies to new files only. Existing files keep their format, and a new branch file follows its agent's config unless the flag says otherwise.
On add, it defaults to the format of --from-file, then JSON. It conflicts with --output-path, whose extension decides.
add converts before it creates: the config is rendered before the agent is created, so a config the format can't hold doesn't leave a remote agent with no local file.
TOML has no null, so writing TOML drops null fields and null array elements. Agents lose nothing: push sends a PATCH, where a missing field is left alone, and a field that pulled as null was unset already. The gap is that a TOML config can't clear a field, because deleting its line leaves the remote value as it is; that needs null in JSON or YAML. Tests are updated with a PUT, so a TOML test config relies on the server treating null and missing the same.
TOML layout: objects become [sections] and arrays of objects [[sections]]; parents that hold only subtables print no header, and empty objects keep theirs so they survive a round trip. Multi-line prompts come out as """ strings.
Rejected values: integers above i64::MAX are an error rather than a lossy float, and TOML nan/inf can't be read. TOML datetimes read as strings.
Libraries: uses serde_yaml and toml_edit, both already dependencies, so Cargo.lock only changes for the version bump.
Not included:--format toml for API command output. src/formatter.rs is generated by Fern and not in .fernignore, so that change belongs in the generator; we'll ask Fern if people want it. tests push auto-discovery still only scans .json files.
Bumps the version to 1.11.0, since this adds behavior and main is at 1.10.0.
A config file's extension now sets its format: .json, .yaml/.yml or
.toml. Index files stay JSON and their config paths can point at any of
the three. `agents add` and `agents pull` take --config-format for new
files; existing files keep their format, a new branch file follows its
agent's, and `add --from-file` follows the file it read.
TOML has no null, so writing TOML drops null fields. Agents lose nothing,
since push PATCHes, but a TOML config cannot clear a field.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rays
- An object whose fields are all null rendered as an implicit, empty
table and vanished from the TOML file. Decide the header from the
filled table, so it round-trips as {}.
- A null array element is data (a tool's constant value, say), not an
unset field, so dropping it changed what push sends. Writing TOML now
refuses, naming the field and pointing at JSON or YAML.
- `pull --branch` always made a new branch file, leaving the registered
one stale and, with --config-format, switching its format. It now
reuses the file registered under that branch's name or ID.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Configuration conversion silently drops nulls from literal JSON constants and converts non-finite YAML numbers to null, allowing pushes to corrupt tool arguments or clear settings.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
TOML conversion silently drops null members from literal JSON payloads, so a round trip followed by a push changes the tool’s configured payload.
No open issues 🎉
2 previously missed issues
In code that hasn't changed since last review
Preserve nulls in literal JSON payloads during TOML conversion
cli/elevenlabs/workflow/config_format.rs:149
Null members can be literal payload data: ObjectJsonSchemaPropertyInput::constant_value accepts arbitrary JSON, so {"key": null} must not become {}. This recursion silently drops those members, including in all-object arrays such as [{"key": null}], and a subsequent push changes the tool's configured payload. Reject nulls in literal-data subtrees with a JSON/YAML recommendation, or restrict omission to schema-known optional configuration fields.
Persist successful agent registrations when a later conversion fails
cli/elevenlabs/workflow/agents.rs:1106
When a multi-agent TOML pull writes one new config and a later config contains an unsupported value such as [null], this ? exits before save_agents after the loop. The earlier file remains unregistered, and retrying generates a suffixed duplicate. Preflight conversions before writing files, or persist successful registrations before returning a conversion error, including errors from branch writes.
…ble configs
A null inside constant_value, dynamic variables or a tool's schemas is part
of the value, so writing TOML now refuses it instead of dropping it. A pull
that can't write one config reports it, still writes and registers the
rest, and exits with an error.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Agent configs could only be saved as JSON, which is hard to read and edit by hand for configs this deeply nested. A config file's extension now sets its format, so
agent_configs/can hold.json,.yaml/.ymlor.tomlfiles, andagents addandagents pulltake--config-formatto pick the format of new files.Details
agents.json(ortools.json,tests.json). Anything that isn't.yaml/.yml/.tomlis read as JSON, so existing projects behave exactly as before. The index files themselves stay JSON.project::read_value/write_config_in_project, sopush,status,test,graph,workflow diagramand the tool and test commands all handle the three formats.write_json_in_projectis renamed towrite_config_in_projectto match.--config-format(json, yaml, toml):pull, it applies to new files only. Existing files keep their format, and a new branch file follows its agent's config unless the flag says otherwise.add, it defaults to the format of--from-file, then JSON. It conflicts with--output-path, whose extension decides.addconverts before it creates: the config is rendered before the agent is created, so a config the format can't hold doesn't leave a remote agent with no local file.null, so writing TOML drops null fields and null array elements. Agents lose nothing:pushsends a PATCH, where a missing field is left alone, and a field that pulled as null was unset already. The gap is that a TOML config can't clear a field, because deleting its line leaves the remote value as it is; that needsnullin JSON or YAML. Tests are updated with a PUT, so a TOML test config relies on the server treating null and missing the same.[sections]and arrays of objects[[sections]]; parents that hold only subtables print no header, and empty objects keep theirs so they survive a round trip. Multi-line prompts come out as"""strings.i64::MAXare an error rather than a lossy float, and TOMLnan/infcan't be read. TOML datetimes read as strings.serde_yamlandtoml_edit, both already dependencies, soCargo.lockonly changes for the version bump.--format tomlfor API command output.src/formatter.rsis generated by Fern and not in.fernignore, so that change belongs in the generator; we'll ask Fern if people want it.tests pushauto-discovery still only scans.jsonfiles.mainis at 1.10.0.Testing
cargo test: everything passes (2155 lib, 265 workflow unit, 875 wire).config_format.rs:tests/agents_config_format_test.rs, run against a mock API:pull --config-format tomlwrites a.tomlconfig without nulls, andpushPATCHes the same fields backpullkeeps an existing.yamlfile's format despite--config-format tomladd --from-file support.ymlcreates a YAML config and sends the file's fields.tomlfile reports "Invalid TOML"cargo clippy --all-targets: no warnings in the changed code.🤖 Generated with Claude Code