docs/decisions/0052-python-ai-connector-new-abstract-methods.md
ChatCompletionClientBase and TextCompletionClientBase (Semantic Kernel Python)The ChatCompletionClientBase class currently contains two abstract methods, namely get_chat_message_contents and get_streaming_chat_message_contents. These methods offer standardized interfaces for clients to engage with various models.
We will focus on
ChatCompletionClientBasein this ADR butTextCompletionClientBasewill be having a similar structure.
With the introduction of function calling to many models, Semantic Kernel has implemented an amazing feature known as auto function invocation. This feature relieves developers from the burden of manually invoking the functions requested by the models, making the development process much smoother.
Auto function invocation can cause a side effect where a single call to get_chat_message_contents or get_streaming_chat_message_contents may result in multiple calls to the model. However, this presents an excellent opportunity for us to introduce another layer of abstraction that is solely responsible for making a single call to the model.
get_chat_message_contents and get_streaming_chat_message_contents.Revision: In order to not break existing customers who have implemented their own AI connectors, these two methods are not decorated with the
@abstractmethoddecorator, but instead throw an exception if they are not implemented in the built-in AI connectors.
async def _inner_get_chat_message_content(
self,
chat_history: ChatHistory,
settings: PromptExecutionSettings
) -> list[ChatMessageContent]:
raise NotImplementedError
async def _inner_get_streaming_chat_message_content(
self,
chat_history: ChatHistory,
settings: PromptExecutionSettings
) -> AsyncGenerator[list[StreamingChatMessageContent], Any]:
raise NotImplementedError
ClassVar[bool] variable in ChatCompletionClientBase to indicate whether a connector supports function callingThis class variable will be overridden in derived classes and be used in the default implementations of get_chat_message_contents and get_streaming_chat_message_contents.
class ChatCompletionClientBase(AIServiceClientBase, ABC):
"""Base class for chat completion AI services."""
SUPPORTS_FUNCTION_CALLING: ClassVar[bool] = False
...
class MockChatCompletionThatSupportsFunctionCalling(ChatCompletionClientBase):
SUPPORTS_FUNCTION_CALLING: ClassVar[bool] = True
@override
async def get_chat_message_contents(
self,
chat_history: ChatHistory,
settings: "PromptExecutionSettings",
**kwargs: Any,
) -> list[ChatMessageContent]:
if not self.SUPPORTS_FUNCTION_CALLING:
return ...
...