Skip to content

Commit 5d34264

Browse files
authored
feat(rust-only): better tolerate malformed optional fields in deserialization (#1006)
* feat(rust-only): better tolerate malformed optional fields in deserialization Use `serde_with` helpers to default invalid optional values and skip bad vector entries across protocol types. Sometimes agents or clients send something not quite right. If it is an optional field, we can fallback to best-effort and retain as much information as possible without losing everything. * Apply `skip_serializing_none` across protocol structs so optional fields are omitted consistently. * Add optional tracing for skipped list entries Introduce a `tracing` feature that logs `VecSkipError` drops via a shared `SkipListener` inspector, while remaining a zero-cost no-op when the feature is disabled. Also add tests covering inspector callbacks for malformed entries. * Make List Deserialization Fall Back to Defaults Wrap list deserializers with `DefaultOnError` so invalid outer shapes default instead of failing, while still skipping invalid elements inside valid arrays.
1 parent 34c5176 commit 5d34264

File tree

14 files changed

+1193
-310
lines changed

14 files changed

+1193
-310
lines changed

Cargo.lock

Lines changed: 458 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ unstable_session_usage = []
4545
unstable_message_id = []
4646
unstable_boolean_config = []
4747

48+
# Emit `tracing::warn!` events when `VecSkipError` drops a malformed list
49+
# entry during deserialization. When disabled (the default), the inspector
50+
# hook compiles down to serde_with's built-in no-op and has zero runtime cost.
51+
tracing = ["dep:tracing"]
52+
4853
[[bin]]
4954
name = "generate"
5055
path = "src/bin/generate.rs"
@@ -55,7 +60,9 @@ derive_more = { version = "2", features = ["from", "display"] }
5560
schemars = { version = "1" }
5661
serde = { version = "1", features = ["derive", "rc"] }
5762
serde_json = { version = "1", features = ["raw_value"] }
63+
serde_with = { version = "3.18.0", features = ["json", "schemars_1"] }
5864
strum = { version = "0.28", features = ["derive"] }
65+
tracing = { version = "0.1", default-features = false, optional = true }
5966

6067
[lints.rust]
6168
future_incompatible = { level = "warn", priority = -1 }

clippy.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
allowed-duplicate-crates = [
2+
"hashbrown",
3+
"indexmap",
4+
"schemars",
5+
]

src/agent.rs

Lines changed: 214 additions & 109 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)