Skip to content

feat(builder,cli): enforce function returnType compatibility in Python component builders #3607

Open

Description

@jacobsimionato

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 void function like OpenUrl(url="https://example.com") can be passed to Text(text=OpenUrl(...)) (DynamicString) or Slider(value=OpenUrl(...)) (DynamicNumber).
  • A string-formatting function like FormatString(...) can be passed to Slider(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.

Activity

  1. jacobsimionato commented on Oct 25, 2026

    @jacobsimionato
    CollaboratorAuthor

    Coding agent prompt: Implement static and runtime return-type checking for generated catalog FunctionCall classes in dart/a2ui_cli and python/a2ui_agent.

    Context & References

    • Analyzer: @dart/a2ui_cli/lib/src/analyzer/catalog_analyzer.dart (_returnTypeToTypeDescriptor), @dart/a2ui_cli/lib/src/analyzer/types.dart (AnalysedFunctionApi.returnType)
    • Emitter & Type Mapper: @dart/a2ui_cli/lib/src/emitters/python/python_emitter.dart, @dart/a2ui_cli/lib/src/emitters/python/type_mapper.dart
    • Builder models: @python/a2ui_agent/src/a2ui/builder/v0_9/models.py and @python/a2ui_agent/src/a2ui/builder/v1_0/models.py
    • Checked-in generated catalogs: @python/a2ui_agent/src/a2ui/builder/v0_9/catalogs/basic.py and @python/a2ui_agent/src/a2ui/builder/v1_0/catalogs/basic.py

    Implementation Requirements

    1. Return-Typed Function Call Hierarchy:
      • Design a clean return-type representation for FunctionCall in a2ui.builder (for both v0_9 and v1_0) that preserves isinstance(fn, FunctionCall) and compatibility with a2ui.core.schema models, while distinguishing return types (string, number, boolean, array, object, validationResult, void, any) both statically (for mypy/pyright) and at runtime (for Pydantic validation).
      • Ensure raw/untyped FunctionCall(call="...", ...) (used for ad-hoc or external catalog calls) and functions with returnType="any" remain assignable to any Dynamic* slot, while specific catalog function classes (e.g., OpenUrl with void, FormatString with string, FormatNumber with string, And/Or/Not with boolean, Required/Regex/Email with boolean in v0.9 and validationResult in v1.0) are constrained to compatible target slots (e.g., DynamicString, DynamicNumber, DynamicBoolean, DynamicStringList, CheckRule.condition, Action.function_call).
    2. Update a2ui_cli Emitter:
      • Update PythonEmitter and type_mapper.dart to use AnalysedFunctionApi.returnType when emitting function classes and property type annotations.
      • Regenerate v0_9/catalogs/basic.py and v1_0/catalogs/basic.py.
    3. Verification:
      • Add unit tests in @dart/a2ui_cli/test/codegen_test.dart, @python/a2ui_agent/tests/test_pydantic_builders.py, and @python/a2ui_agent/tests/test_pydantic_builders_v1_0.py testing both valid and invalid function return-type placements (e.g., rejecting Text(text=OpenUrl(url="...")) while allowing Action(function_call=OpenUrl(url="..."))).
      • Verify all Dart and Python test suites and uv run mypy . pass.
  2. added
    status: needs-triageauto-managed: https://github.com/a2ui-project/a2ui/blob/main/scripts/triage.mjs
    on Oct 25, 2026
  3. added
    P2The team intends to work on this in the near future, or at a lower priority.
    feature: macrosAffects the Macros or Typesafe Builder API features
    component: specificationAffects the A2UI specification documents and JSON schemas
    lang: dartAffects SDKs or apps in the Dart programming language
    lang: pythonAffects SDKs or apps in the Python programming language
    and removed
    status: needs-triageauto-managed: https://github.com/a2ui-project/a2ui/blob/main/scripts/triage.mjs
    on Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2The team intends to work on this in the near future, or at a lower priority.component: agent sdkRelating to the agent SDK libraries in any languagecomponent: specificationAffects the A2UI specification documents and JSON schemasfeature: macrosAffects the Macros or Typesafe Builder API featureslang: dartAffects SDKs or apps in the Dart programming languagelang: pythonAffects SDKs or apps in the Python programming languagepythonAll issues relating to Python codebasesstatus: first-line-handledtype: feature/enhancement

    Type

    No type

    Projects

    • Status
      Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions