Skip to content

Commit 828c0ed

Browse files
Merge pull request #114 from openai/codex/basic-root-build-and-deprecate-build-basic
[codex] Support Basic roots in WidgetTemplate.build
2 parents 88e4b30 + 5a1921d commit 828c0ed

2 files changed

Lines changed: 39 additions & 11 deletions

File tree

chatkit/widgets.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,22 +1098,22 @@ class DynamicWidgetComponent(WidgetComponentBase):
10981098
]
10991099

11001100

1101+
class BasicRoot(DynamicWidgetComponent):
1102+
"""Layout root capable of nesting components or other roots."""
1103+
1104+
type: Literal["Basic"] = Field(default="Basic", frozen=True) # pyright: ignore
1105+
1106+
11011107
StrictWidgetRoot = Annotated[
1102-
Card | ListView,
1108+
Card | ListView | BasicRoot,
11031109
Field(discriminator="type"),
11041110
]
11051111

11061112

11071113
class DynamicWidgetRoot(DynamicWidgetComponent):
11081114
"""Dynamic root widget restricted to root types."""
11091115

1110-
type: Literal["Card", "ListView"] # pyright: ignore
1111-
1112-
1113-
class BasicRoot(DynamicWidgetComponent):
1114-
"""Layout root capable of nesting components or other roots."""
1115-
1116-
type: Literal["Basic"] = Field(default="Basic", frozen=True) # pyright: ignore
1116+
type: Literal["Card", "ListView", "Basic"] # pyright: ignore
11171117

11181118

11191119
WidgetComponent = StrictWidgetComponent | DynamicWidgetComponent
@@ -1178,8 +1178,9 @@ def build(
11781178
widget_dict = json.loads(rendered)
11791179
return DynamicWidgetRoot.model_validate(widget_dict)
11801180

1181+
@deprecated("WidgetTemplate.build_basic is deprecated. Use WidgetTemplate.build instead.")
11811182
def build_basic(self, data: dict[str, Any] | BaseModel | None = None) -> BasicRoot:
1182-
"""Separate method for building basic root widgets until BasicRoot is supported for streamed widgets."""
1183+
"""Deprecated alias for building Basic root widgets."""
11831184
rendered = self.template.render(**self._normalize_data(data))
11841185
widget_dict = json.loads(rendered)
11851186
return BasicRoot.model_validate(widget_dict)

tests/test_widgets.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,18 +244,45 @@ def test_widget_template_from_file(
244244
assert widget.model_dump(exclude_none=True) == expected_widget_dict
245245

246246

247-
def test_widget_template_with_basic_root():
247+
def test_widget_template_build_with_basic_root():
248248
template = WidgetTemplate.from_file("assets/widgets/basic_root.widget")
249249

250250
with open("tests/assets/widgets/basic_root.json", "r") as file:
251251
expected_widget_dict = json.load(file)
252252

253-
widget = template.build_basic(
253+
widget = template.build(
254254
{
255255
"name": "Harry Potter",
256256
"bio": "The boy who lived",
257257
},
258258
)
259259

260+
assert isinstance(widget, DynamicWidgetRoot)
261+
assert widget.type == "Basic"
262+
assert widget.model_dump(exclude_none=True) == expected_widget_dict
263+
264+
widget_item = WidgetItem(
265+
thread_id="1", widget=widget, id="1", created_at=datetime.now()
266+
)
267+
assert widget_item.widget.type == "Basic"
268+
269+
270+
def test_widget_template_build_basic_is_deprecated():
271+
template = WidgetTemplate.from_file("assets/widgets/basic_root.widget")
272+
273+
with open("tests/assets/widgets/basic_root.json", "r") as file:
274+
expected_widget_dict = json.load(file)
275+
276+
with pytest.warns(
277+
DeprecationWarning,
278+
match="WidgetTemplate.build_basic is deprecated. Use WidgetTemplate.build instead.",
279+
):
280+
widget = template.build_basic(
281+
{
282+
"name": "Harry Potter",
283+
"bio": "The boy who lived",
284+
},
285+
)
286+
260287
assert isinstance(widget, BasicRoot)
261288
assert widget.model_dump(exclude_none=True) == expected_widget_dict

0 commit comments

Comments
 (0)