From b43e8d9787e5d3debea24d19be6ec7c27ad1dd82 Mon Sep 17 00:00:00 2001 From: patrick-chinchill Date: Thu, 18 Jun 2026 16:30:05 -0700 Subject: [PATCH] fix(core): root re-export deprecated chat/ai type aliases Upstream packages/chat/src/index.ts:8-27 re-exports toAiMessages plus eight deprecated AI type aliases (AiAssistantMessage, AiFilePart, AiImagePart, AiMessage, AiMessagePart, AiTextPart, AiUserMessage, ToAiMessagesOptions) from the package root for backwards compatibility, each marked @deprecated pointing at the chat/ai subpath. Ours re-exported only to_ai_messages, so chat_sdk.AiMessage et al. did not resolve. Add the eight deprecated root re-exports from chat_sdk.ai (the canonical home) to match upstream's deprecated-alias surface, and pin the behavior with a root re-export test. No new optional-dep cost: chat_sdk.ai is already imported at the root for to_ai_messages, and the aliased types are plain TypedDict/dataclass/Union with no ai/zod peer-dep imports. --- src/chat_sdk/__init__.py | 27 ++++++++++++++++++- tests/test_root_reexports.py | 51 ++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 tests/test_root_reexports.py diff --git a/src/chat_sdk/__init__.py b/src/chat_sdk/__init__.py index 2214d93..8a7f2aa 100644 --- a/src/chat_sdk/__init__.py +++ b/src/chat_sdk/__init__.py @@ -1,6 +1,22 @@ """Python port of Vercel Chat SDK.""" -from chat_sdk.ai import to_ai_messages +# Re-exported from `chat_sdk.ai` for backwards compatibility. +# +# Prefer importing these from `chat_sdk.ai` in new code — that subpackage is the +# home for every AI SDK helper (`to_ai_messages`, `create_chat_tools`, etc.). +# The AI type aliases below are deprecated at the root and mirror upstream's +# `packages/chat/src/index.ts` deprecated re-export surface (@deprecated → chat/ai). +from chat_sdk.ai import ( + AiAssistantMessage, + AiFilePart, + AiImagePart, + AiMessage, + AiMessagePart, + AiTextPart, + AiUserMessage, + ToAiMessagesOptions, + to_ai_messages, +) from chat_sdk.cards import ( Actions, ActionsElement, @@ -235,6 +251,15 @@ "post_postable_object", # AI "to_ai_messages", + # AI type aliases — deprecated at the root; canonical home is chat_sdk.ai. + "AiAssistantMessage", + "AiFilePart", + "AiImagePart", + "AiMessage", + "AiMessagePart", + "AiTextPart", + "AiUserMessage", + "ToAiMessagesOptions", # Standalone reviver for workflow-safe deserialization "reviver", # Card builders (PascalCase primary — matches source TS SDK) diff --git a/tests/test_root_reexports.py b/tests/test_root_reexports.py new file mode 100644 index 0000000..d4cb53a --- /dev/null +++ b/tests/test_root_reexports.py @@ -0,0 +1,51 @@ +"""Root package re-export surface. + +Upstream (`packages/chat/src/index.ts`) re-exports `toAiMessages` plus eight +deprecated AI type aliases from the package root for backwards compatibility, +each marked `@deprecated` and pointing at the canonical `chat/ai` subpath. + +These tests pin the Python equivalent: `chat_sdk.AiMessage` (and friends) +resolve at the root and are identical objects to their canonical +`chat_sdk.ai` home, while `chat_sdk.ai` remains the preferred import. +""" + +from __future__ import annotations + +import chat_sdk +import chat_sdk.ai as chat_sdk_ai + +# The exact set of deprecated AI type aliases re-exported from the root, +# mirroring upstream index.ts:8-27. +_DEPRECATED_AI_TYPE_ALIASES = ( + "AiAssistantMessage", + "AiFilePart", + "AiImagePart", + "AiMessage", + "AiMessagePart", + "AiTextPart", + "AiUserMessage", + "ToAiMessagesOptions", +) + + +def test_deprecated_ai_type_aliases_resolve_at_root() -> None: + for name in _DEPRECATED_AI_TYPE_ALIASES: + assert hasattr(chat_sdk, name), f"chat_sdk.{name} should resolve at the root" + + +def test_root_ai_aliases_are_the_canonical_objects() -> None: + # The root re-export must be the same object as the canonical chat_sdk.ai + # home — not a fresh shadow type — so isinstance / identity checks agree. + for name in _DEPRECATED_AI_TYPE_ALIASES: + assert getattr(chat_sdk, name) is getattr(chat_sdk_ai, name) + + +def test_deprecated_ai_type_aliases_in_dunder_all() -> None: + for name in _DEPRECATED_AI_TYPE_ALIASES: + assert name in chat_sdk.__all__, f"{name} missing from chat_sdk.__all__" + + +def test_to_ai_messages_still_re_exported_at_root() -> None: + # The helper that the aliases accompany stays available and canonical. + assert chat_sdk.to_ai_messages is chat_sdk_ai.to_ai_messages + assert "to_ai_messages" in chat_sdk.__all__