Skip to content

Commit 762e41b

Browse files
Merge branch 'master' into perf/optional-prometheus-tui
2 parents 200a177 + bf5873c commit 762e41b

43 files changed

Lines changed: 5760 additions & 1754 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,4 @@ playground/
6060
rust_out
6161

6262
# Auto-generated Tauri schemas
63-
apps/tauri/gen/schemas/linux-schema.json
63+
apps/tauri/gen/schemas/

CONTRIBUTING.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,56 @@ Use these quick examples to align implementation choices before opening a PR.
387387
- **Bad**: config key changes without migration notes.
388388
- **Good**: config/schema changes include defaults, compatibility impact, migration steps, and rollback guidance.
389389

390+
## Config Schema Versioning and Migrations
391+
392+
ZeroClaw uses a forward-only schema versioning system for `config.toml`. This section
393+
explains when and how to create a migration.
394+
395+
### When a migration IS needed
396+
397+
A schema version bump is required when you **rename, move, or remove** an existing
398+
config prop. Examples:
399+
400+
- Renaming `room_id` to something else
401+
- Moving a prop from one section to another
402+
- Removing a deprecated prop entirely
403+
404+
### When a migration is NOT needed
405+
406+
Adding a new config prop does **not** require a schema version bump. Use
407+
`#[serde(default)]` on the new field and it will be filled with its default value
408+
when loading older config files. This is the common case.
409+
410+
### How the migration system works
411+
412+
1. `crates/zeroclaw-config/src/migration.rs` contains `V1Compat`, a wrapper struct
413+
that uses `#[serde(flatten)]` to deserialize both old-format and current-format
414+
TOML into a single pass. Old fields live on `V1Compat`; current fields land on
415+
`Config`.
416+
2. `V1Compat::into_config()` moves old field values into their new locations on
417+
`Config` using typed field access — no string-based key manipulation. All call
418+
sites use `config.providers.*` directly.
419+
3. For schema versions beyond V2, add `fn vN_to_vM(&mut Config)` functions that
420+
mutate the `Config` struct directly.
421+
422+
### How to add a new migration step
423+
424+
1. Bump `CURRENT_SCHEMA_VERSION` in `crates/zeroclaw-config/src/migration.rs`.
425+
2. If the old field was on `V1Compat`, update the `migrate_providers()` or similar
426+
method. If the change is between V2+ layouts, add a new `fn vN_to_vM(&mut Config)`
427+
and call it from `into_config()` after the schema version check.
428+
3. Add tests in `tests/component/config_migration.rs` that:
429+
- Deserialize a TOML string with the old layout
430+
- Assert the migrated `Config` has values in the new locations
431+
- Assert the old locations are empty/cleared
432+
4. Run `cargo test --test component -- config_migration` to verify.
433+
434+
### `zeroclaw config migrate`
435+
436+
Users can run `zeroclaw config migrate` to rewrite their on-disk `config.toml` to the
437+
current schema version. This command uses `toml_edit` to preserve comments and
438+
formatting while making structural changes.
439+
390440
## How to Add a New Provider
391441

392442
Create `src/providers/your_provider.rs`:

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ serde_json = { version = "1.0", default-features = false, features = ["std"] }
9292
# Config
9393
directories = "6.0"
9494
toml = "1.0"
95+
toml_edit = "0.25" # already a transitive dep via toml — zero added compile/binary cost
9596
shellexpand = "3.1"
9697

9798
# JSON Schema generation for config export

crates/zeroclaw-api/src/provider.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,14 @@ impl<T: Provider + ?Sized> Provider for Arc<T> {
504504
self.as_ref().convert_tools(tools)
505505
}
506506

507+
fn supports_native_tools(&self) -> bool {
508+
self.as_ref().supports_native_tools()
509+
}
510+
511+
fn supports_vision(&self) -> bool {
512+
self.as_ref().supports_vision()
513+
}
514+
507515
async fn chat_with_system(
508516
&self,
509517
system_prompt: Option<&str>,

0 commit comments

Comments
 (0)