@@ -215,9 +215,43 @@ def test_envelope_meta_defaults_to_empty_dict(self):
215215 env = ToolEnvelope (data = None , summary = "ok" )
216216 assert env .meta == {}
217217
218- def test_envelope_extra_fields_forbidden (self ):
219- with pytest .raises (Exception ):
220- ToolEnvelope .model_validate ({"data" : None , "summary" : "ok" , "extra" : 1 })
218+ def test_envelope_summary_is_optional_and_defaults_to_empty (self ):
219+ """Hardened envelope: omitting `summary` must not raise (footgun fix).
220+
221+ Internal paths that forget to set a summary should get an empty
222+ headline instead of a runtime ValidationError.
223+ """
224+ env = ToolEnvelope (data = None )
225+ assert env .summary == ""
226+ # Same via model_validate (the structured-output path).
227+ validated = ToolEnvelope .model_validate ({"data" : None })
228+ assert validated .summary == ""
229+
230+ def test_envelope_ignores_unexpected_extra_key (self ):
231+ """Hardened envelope: an unexpected extra key must be dropped, not raise.
232+
233+ ClientCompatibilityMiddleware already strips extras on the wire; this
234+ guarantees the model itself degrades gracefully if one slips through.
235+ """
236+ # Construction with an unexpected kwarg must not raise.
237+ env = ToolEnvelope (data = None , summary = "ok" , unexpected = "boom" )
238+ assert env .summary == "ok"
239+ assert not hasattr (env , "unexpected" )
240+ # And via model_validate (the round-trip path).
241+ validated = ToolEnvelope .model_validate (
242+ {"data" : None , "summary" : "ok" , "extra" : 1 }
243+ )
244+ assert validated .summary == "ok"
245+ # The extra key is ignored, so the serialized shape clients see is
246+ # unchanged (data/summary/meta only).
247+ assert set (validated .model_dump ().keys ()) == {"data" , "summary" , "meta" }
248+
249+ def test_envelope_no_args_does_not_raise (self ):
250+ """Belt-and-suspenders: a fully bare envelope is constructible."""
251+ env = ToolEnvelope ()
252+ assert env .data is None
253+ assert env .summary == ""
254+ assert env .meta == {}
221255
222256 def test_todo_status_enum_enforced (self ):
223257 with pytest .raises (Exception ):
0 commit comments