Skip to content

Commit 62825bc

Browse files
MarkDaoustcopybara-github
authored andcommitted
fix: preserve unknown fields and open-union variants in Interactions models
Enable `preserveUnknownFields` and `modelSerializationMethods` in the Python SDK. Unknown fields are kept at every nesting level, in responses and in requests: unknown request fields are forwarded instead of silently dropped, so unsupported options such as `transcription_config.diarization` are rejected by the API rather than ignored (#3162), and fields missing from the SDK schema reach the API. Unknown steps, content blocks and annotations round-trip as the payload the server sent, including stateless multi-turn history sent back as SDK objects or as stored dicts; known variants with invalid payloads still raise locally. PiperOrigin-RevId: 1010828113
1 parent 96f0f5a commit 62825bc

220 files changed

Lines changed: 5928 additions & 1326 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.

‎google/genai/_gaos/models/cancelinteractionbyid.py‎

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919

2020
from __future__ import annotations
2121
from ..types import BaseModel, UNSET_SENTINEL, current_exclude_none, serialize_with_info
22-
from ..types.basemodel import current_filtered_dump
22+
from ..types.basemodel import (
23+
current_by_alias,
24+
current_filtered_dump,
25+
current_serialization_methods_dump,
26+
)
2327
from ..utils import FieldMetadata, PathParamMetadata
2428
import pydantic
2529
from pydantic import model_serializer
@@ -46,19 +50,29 @@ def _serialize_model_with_info(self, handler, info):
4650
def serialize_model(self, handler):
4751
optional_fields = set(["api_version"])
4852
exclude_none = current_exclude_none()
49-
skip_filtered = exclude_none is False or current_filtered_dump()
53+
by_alias = current_by_alias()
54+
use_field_names = by_alias is False
55+
serialization_methods_dump = current_serialization_methods_dump()
56+
skip_filtered = (
57+
serialization_methods_dump
58+
or exclude_none is False
59+
or current_filtered_dump()
60+
)
5061
serialized = handler(self)
5162
m = {}
5263

5364
for n, f in type(self).model_fields.items():
5465
k = f.alias if f.alias is not None else n
55-
if k not in serialized and n not in serialized and skip_filtered:
66+
key = k if by_alias or k in serialized else n
67+
if key not in serialized and skip_filtered:
5668
continue
57-
val = serialized.get(k, serialized.get(n))
69+
val = serialized.pop(key, None)
5870

5971
if val != UNSET_SENTINEL:
6072
if val is not None or k not in optional_fields:
61-
m[k] = val
73+
m[n if use_field_names else k] = val
74+
for k, v in serialized.items():
75+
m[k] = v
6276

6377
return m
6478

@@ -91,18 +105,28 @@ def _serialize_model_with_info(self, handler, info):
91105
def serialize_model(self, handler):
92106
optional_fields = set(["api_version"])
93107
exclude_none = current_exclude_none()
94-
skip_filtered = exclude_none is False or current_filtered_dump()
108+
by_alias = current_by_alias()
109+
use_field_names = by_alias is False
110+
serialization_methods_dump = current_serialization_methods_dump()
111+
skip_filtered = (
112+
serialization_methods_dump
113+
or exclude_none is False
114+
or current_filtered_dump()
115+
)
95116
serialized = handler(self)
96117
m = {}
97118

98119
for n, f in type(self).model_fields.items():
99120
k = f.alias if f.alias is not None else n
100-
if k not in serialized and n not in serialized and skip_filtered:
121+
key = k if by_alias or k in serialized else n
122+
if key not in serialized and skip_filtered:
101123
continue
102-
val = serialized.get(k, serialized.get(n))
124+
val = serialized.pop(key, None)
103125

104126
if val != UNSET_SENTINEL:
105127
if val is not None or k not in optional_fields:
106-
m[k] = val
128+
m[n if use_field_names else k] = val
129+
for k, v in serialized.items():
130+
m[k] = v
107131

108132
return m

‎google/genai/_gaos/models/createagent.py‎

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
from __future__ import annotations
2121
from ..types import BaseModel, UNSET_SENTINEL, current_exclude_none, serialize_with_info
2222
from ..types.agents import agent as agents_agent
23-
from ..types.basemodel import current_filtered_dump
23+
from ..types.basemodel import (
24+
current_by_alias,
25+
current_filtered_dump,
26+
current_serialization_methods_dump,
27+
)
2428
from ..utils import FieldMetadata, PathParamMetadata, RequestMetadata
2529
from pydantic import model_serializer
2630
from typing import Optional
@@ -46,19 +50,29 @@ def _serialize_model_with_info(self, handler, info):
4650
def serialize_model(self, handler):
4751
optional_fields = set(["api_version"])
4852
exclude_none = current_exclude_none()
49-
skip_filtered = exclude_none is False or current_filtered_dump()
53+
by_alias = current_by_alias()
54+
use_field_names = by_alias is False
55+
serialization_methods_dump = current_serialization_methods_dump()
56+
skip_filtered = (
57+
serialization_methods_dump
58+
or exclude_none is False
59+
or current_filtered_dump()
60+
)
5061
serialized = handler(self)
5162
m = {}
5263

5364
for n, f in type(self).model_fields.items():
5465
k = f.alias if f.alias is not None else n
55-
if k not in serialized and n not in serialized and skip_filtered:
66+
key = k if by_alias or k in serialized else n
67+
if key not in serialized and skip_filtered:
5668
continue
57-
val = serialized.get(k, serialized.get(n))
69+
val = serialized.pop(key, None)
5870

5971
if val != UNSET_SENTINEL:
6072
if val is not None or k not in optional_fields:
61-
m[k] = val
73+
m[n if use_field_names else k] = val
74+
for k, v in serialized.items():
75+
m[k] = v
6276

6377
return m
6478

@@ -90,18 +104,28 @@ def _serialize_model_with_info(self, handler, info):
90104
def serialize_model(self, handler):
91105
optional_fields = set(["api_version"])
92106
exclude_none = current_exclude_none()
93-
skip_filtered = exclude_none is False or current_filtered_dump()
107+
by_alias = current_by_alias()
108+
use_field_names = by_alias is False
109+
serialization_methods_dump = current_serialization_methods_dump()
110+
skip_filtered = (
111+
serialization_methods_dump
112+
or exclude_none is False
113+
or current_filtered_dump()
114+
)
94115
serialized = handler(self)
95116
m = {}
96117

97118
for n, f in type(self).model_fields.items():
98119
k = f.alias if f.alias is not None else n
99-
if k not in serialized and n not in serialized and skip_filtered:
120+
key = k if by_alias or k in serialized else n
121+
if key not in serialized and skip_filtered:
100122
continue
101-
val = serialized.get(k, serialized.get(n))
123+
val = serialized.pop(key, None)
102124

103125
if val != UNSET_SENTINEL:
104126
if val is not None or k not in optional_fields:
105-
m[k] = val
127+
m[n if use_field_names else k] = val
128+
for k, v in serialized.items():
129+
m[k] = v
106130

107131
return m

‎google/genai/_gaos/models/createcredential.py‎

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919

2020
from __future__ import annotations
2121
from ..types import BaseModel, UNSET_SENTINEL, current_exclude_none, serialize_with_info
22-
from ..types.basemodel import current_filtered_dump
22+
from ..types.basemodel import (
23+
current_by_alias,
24+
current_filtered_dump,
25+
current_serialization_methods_dump,
26+
)
2327
from ..types.credentials import (
2428
credentialcreateparams as credentials_credentialcreateparams,
2529
)
@@ -48,19 +52,29 @@ def _serialize_model_with_info(self, handler, info):
4852
def serialize_model(self, handler):
4953
optional_fields = set(["api_version"])
5054
exclude_none = current_exclude_none()
51-
skip_filtered = exclude_none is False or current_filtered_dump()
55+
by_alias = current_by_alias()
56+
use_field_names = by_alias is False
57+
serialization_methods_dump = current_serialization_methods_dump()
58+
skip_filtered = (
59+
serialization_methods_dump
60+
or exclude_none is False
61+
or current_filtered_dump()
62+
)
5263
serialized = handler(self)
5364
m = {}
5465

5566
for n, f in type(self).model_fields.items():
5667
k = f.alias if f.alias is not None else n
57-
if k not in serialized and n not in serialized and skip_filtered:
68+
key = k if by_alias or k in serialized else n
69+
if key not in serialized and skip_filtered:
5870
continue
59-
val = serialized.get(k, serialized.get(n))
71+
val = serialized.pop(key, None)
6072

6173
if val != UNSET_SENTINEL:
6274
if val is not None or k not in optional_fields:
63-
m[k] = val
75+
m[n if use_field_names else k] = val
76+
for k, v in serialized.items():
77+
m[k] = v
6478

6579
return m
6680

@@ -92,18 +106,28 @@ def _serialize_model_with_info(self, handler, info):
92106
def serialize_model(self, handler):
93107
optional_fields = set(["api_version"])
94108
exclude_none = current_exclude_none()
95-
skip_filtered = exclude_none is False or current_filtered_dump()
109+
by_alias = current_by_alias()
110+
use_field_names = by_alias is False
111+
serialization_methods_dump = current_serialization_methods_dump()
112+
skip_filtered = (
113+
serialization_methods_dump
114+
or exclude_none is False
115+
or current_filtered_dump()
116+
)
96117
serialized = handler(self)
97118
m = {}
98119

99120
for n, f in type(self).model_fields.items():
100121
k = f.alias if f.alias is not None else n
101-
if k not in serialized and n not in serialized and skip_filtered:
122+
key = k if by_alias or k in serialized else n
123+
if key not in serialized and skip_filtered:
102124
continue
103-
val = serialized.get(k, serialized.get(n))
125+
val = serialized.pop(key, None)
104126

105127
if val != UNSET_SENTINEL:
106128
if val is not None or k not in optional_fields:
107-
m[k] = val
129+
m[n if use_field_names else k] = val
130+
for k, v in serialized.items():
131+
m[k] = v
108132

109133
return m

‎google/genai/_gaos/models/createenvironment.py‎

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919

2020
from __future__ import annotations
2121
from ..types import BaseModel, UNSET_SENTINEL, current_exclude_none, serialize_with_info
22-
from ..types.basemodel import current_filtered_dump
22+
from ..types.basemodel import (
23+
current_by_alias,
24+
current_filtered_dump,
25+
current_serialization_methods_dump,
26+
)
2327
from ..types.environments import (
2428
createenvironmentrequest as environments_createenvironmentrequest,
2529
)
@@ -48,19 +52,29 @@ def _serialize_model_with_info(self, handler, info):
4852
def serialize_model(self, handler):
4953
optional_fields = set(["api_version"])
5054
exclude_none = current_exclude_none()
51-
skip_filtered = exclude_none is False or current_filtered_dump()
55+
by_alias = current_by_alias()
56+
use_field_names = by_alias is False
57+
serialization_methods_dump = current_serialization_methods_dump()
58+
skip_filtered = (
59+
serialization_methods_dump
60+
or exclude_none is False
61+
or current_filtered_dump()
62+
)
5263
serialized = handler(self)
5364
m = {}
5465

5566
for n, f in type(self).model_fields.items():
5667
k = f.alias if f.alias is not None else n
57-
if k not in serialized and n not in serialized and skip_filtered:
68+
key = k if by_alias or k in serialized else n
69+
if key not in serialized and skip_filtered:
5870
continue
59-
val = serialized.get(k, serialized.get(n))
71+
val = serialized.pop(key, None)
6072

6173
if val != UNSET_SENTINEL:
6274
if val is not None or k not in optional_fields:
63-
m[k] = val
75+
m[n if use_field_names else k] = val
76+
for k, v in serialized.items():
77+
m[k] = v
6478

6579
return m
6680

@@ -92,18 +106,28 @@ def _serialize_model_with_info(self, handler, info):
92106
def serialize_model(self, handler):
93107
optional_fields = set(["api_version"])
94108
exclude_none = current_exclude_none()
95-
skip_filtered = exclude_none is False or current_filtered_dump()
109+
by_alias = current_by_alias()
110+
use_field_names = by_alias is False
111+
serialization_methods_dump = current_serialization_methods_dump()
112+
skip_filtered = (
113+
serialization_methods_dump
114+
or exclude_none is False
115+
or current_filtered_dump()
116+
)
96117
serialized = handler(self)
97118
m = {}
98119

99120
for n, f in type(self).model_fields.items():
100121
k = f.alias if f.alias is not None else n
101-
if k not in serialized and n not in serialized and skip_filtered:
122+
key = k if by_alias or k in serialized else n
123+
if key not in serialized and skip_filtered:
102124
continue
103-
val = serialized.get(k, serialized.get(n))
125+
val = serialized.pop(key, None)
104126

105127
if val != UNSET_SENTINEL:
106128
if val is not None or k not in optional_fields:
107-
m[k] = val
129+
m[n if use_field_names else k] = val
130+
for k, v in serialized.items():
131+
m[k] = v
108132

109133
return m

0 commit comments

Comments
 (0)