Repository navigation
feat(builder,cli): enforce function returnType compatibility in Python component builders #3607
Description
Summary
In the A2UI specification (v0.9, v0.9.1, and v1.0), every catalog function declares its returnType (string, number, boolean, array, object, validationResult, void, or any). While CatalogAnalyzer in dart/a2ui_cli already parses fn.returnType, PythonEmitter currently emits all catalog function classes as plain subclasses of FunctionCall, and emits component properties as <primitive> | DataBinding | FunctionCall.
Consequently, neither static type checkers (mypy, pyright) nor runtime Pydantic validation catch return-type mismatches at component property call sites:
- A
voidfunction likeOpenUrl(url="https://example.com")can be passed toText(text=OpenUrl(...))(DynamicString) orSlider(value=OpenUrl(...))(DynamicNumber). - A string-formatting function like
FormatString(...)can be passed toSlider(value=FormatString(...))(DynamicNumber).
Goal
Encode catalog function returnType into the Python builder type hierarchy and generated catalog classes so static type checkers and runtime validation enforce return-type compatibility on DynamicString, DynamicNumber, DynamicBoolean, DynamicStringList, CheckRule.condition, and Action.function_call, while still permitting untyped FunctionCall(...) (or returnType="any") for custom/external catalog functions.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTodo
Activity
jacobsimionato commentedon Oct 25, 2026
Coding agent prompt: Implement static and runtime return-type checking for generated catalog
FunctionCallclasses indart/a2ui_cliandpython/a2ui_agent.Context & References
_returnTypeToTypeDescriptor), @dart/a2ui_cli/lib/src/analyzer/types.dart (AnalysedFunctionApi.returnType)Implementation Requirements
FunctionCallina2ui.builder(for bothv0_9andv1_0) that preservesisinstance(fn, FunctionCall)and compatibility witha2ui.core.schemamodels, while distinguishing return types (string,number,boolean,array,object,validationResult,void,any) both statically (formypy/pyright) and at runtime (for Pydantic validation).FunctionCall(call="...", ...)(used for ad-hoc or external catalog calls) and functions withreturnType="any"remain assignable to anyDynamic*slot, while specific catalog function classes (e.g.,OpenUrlwithvoid,FormatStringwithstring,FormatNumberwithstring,And/Or/Notwithboolean,Required/Regex/Emailwithbooleanin v0.9 andvalidationResultin v1.0) are constrained to compatible target slots (e.g.,DynamicString,DynamicNumber,DynamicBoolean,DynamicStringList,CheckRule.condition,Action.function_call).a2ui_cliEmitter:PythonEmitterandtype_mapper.dartto useAnalysedFunctionApi.returnTypewhen emitting function classes and property type annotations.v0_9/catalogs/basic.pyandv1_0/catalogs/basic.py.Text(text=OpenUrl(url="..."))while allowingAction(function_call=OpenUrl(url="..."))).uv run mypy .pass.