acoustic-carpenter-78188
02/23/2026, 11:08 PM_python_type_to_json_schema). This mapper was unaware of Flyte's internal type system, causing correctness failures - most critically, Literal["C", "F"] parameters produced {"type": "string"} instead of {"type": "string", "enum": ["C", "F"]}, because NativeInterface stores Literal as a dynamic Enum and the old code didn't recognise it.
This PR replaces the ad-hoc mapper with a proper type-engine.
Changes:
• src/flyte/_json_schema.py (new) — converts a LiteralType protobuf to a JSON schema dict
• src/flyte/models.py — adds NativeInterface.json_schema property, which calls TypeEngine.to_literal_type() per input and converts via _json_schema.py
• src/flyte/_task.py — adds AsyncFunctionTaskTemplate.json_schema delegating to self.interface.json_schema
• plugins/anthropic/.../agents/_function_tools.py — removes TYPE_MAP, _python_type_to_json_schema, _get_function_schema; replaces with func.json_schema / NativeInterface.from_callable(func).json_schema
• plugins/anthropic/tests/test_agents.py — rewrites type schema tests to use the new path; adds regression tests for Literal, datetime, timedelta, Optional, nested collections, and true unions
Design choices:
• json_schema lives on NativeInterface, not TypedInterface — NativeInterface is the right home because it also holds parameter defaults, which are needed to build the required list. TypedInterface is a serialization-time artifact and
not available during tool registration.
• Optional[X] is simplified to just X's schema — rather than emitting a full oneOf + null variant. Claude tool use already communicates optionality through the required array, so the null variant adds noise without value.
• Deferred imports in json_schema — TypeEngine and flyteidl2 (protobuf) are heavyweight. They are imported inside the property body rather than at module load time to avoid slowing down every import of flyte.models.
• input_schema is computed once at function_tool() call time and stored as a plain dict on the FunctionTool dataclass — it is never recomputed during the agent loop.
Example:
• Literal["C","F"] → NativeInterface (Enum) → TypeEngine → LiteralType → literal_type_to_json_schema → {"type":"string","enum":["C","F"]} → FunctionTool.input_schema → Claude API
---
Test Plan
• Run the full test suite: cd plugins/anthropic && uv run pytest tests/ -v
• All 58 tests pass with no failures
flyteorg/flyte-sdkacoustic-carpenter-78188
02/24/2026, 7:35 PM