@@ -75,35 +75,18 @@ async def _auto_invoke_function(
7575 )
7676
7777
78- def tool_to_json_schema_spec ( tool : AITool ) -> dict [str , Any ]:
79- """Convert a AITool to the JSON Schema function specification format."""
78+ def ai_function_to_json_schema_spec ( function : AIFunction [ BaseModel , Any ] ) -> dict [str , Any ]:
79+ """Convert a AIFunction to the JSON Schema function specification format."""
8080 return {
8181 "type" : "function" ,
8282 "function" : {
83- "name" : tool .name ,
84- "description" : tool .description ,
85- "parameters" : tool .parameters (),
83+ "name" : function .name ,
84+ "description" : function .description ,
85+ "parameters" : function .parameters (),
8686 },
8787 }
8888
8989
90- def _prepare_tools_and_tool_choice (chat_options : ChatOptions ) -> None :
91- """Prepare the tools and tool choice for the chat options."""
92- chat_tool_mode : ChatToolMode | None = chat_options .tool_choice # type: ignore
93- if chat_tool_mode is None or chat_tool_mode == ChatToolMode .NONE :
94- chat_options .tools = None
95- chat_options .tool_choice = ChatToolMode .NONE .mode
96- return
97- chat_options .tools = [
98- (tool_to_json_schema_spec (t ) if isinstance (t , AITool ) else t )
99- for t in chat_options ._ai_tools or [] # type: ignore[reportPrivateUsage]
100- ]
101- if not chat_options .tools :
102- chat_options .tool_choice = ChatToolMode .NONE .mode
103- else :
104- chat_options .tool_choice = chat_tool_mode .mode
105-
106-
10790def _tool_call_non_streaming (func : TInnerGetResponse ) -> TInnerGetResponse :
10891 """Decorate the internal _inner_get_response method to enable tool calls."""
10992
@@ -163,7 +146,7 @@ async def wrapper(
163146
164147 # Failsafe: give up on tools, ask model for plain answer
165148 chat_options .tool_choice = "none"
166- _prepare_tools_and_tool_choice (chat_options = chat_options )
149+ self . _prepare_tools_and_tool_choice (chat_options = chat_options ) # type: ignore[reportPrivateUsage]
167150 response = await func (self , messages = messages , chat_options = chat_options )
168151 if fcc_messages :
169152 for msg in reversed (fcc_messages ):
@@ -231,7 +214,7 @@ async def wrapper(
231214
232215 # Failsafe: give up on tools, ask model for plain answer
233216 chat_options .tool_choice = "none"
234- _prepare_tools_and_tool_choice (chat_options = chat_options )
217+ self . _prepare_tools_and_tool_choice (chat_options = chat_options ) # type: ignore[reportPrivateUsage]
235218 async for update in func (self , messages = messages , chat_options = chat_options , ** kwargs ):
236219 yield update
237220
@@ -542,7 +525,7 @@ async def get_response(
542525 additional_properties = additional_properties or {},
543526 )
544527 prepped_messages = self ._prepare_messages (messages )
545- _prepare_tools_and_tool_choice (chat_options = chat_options )
528+ self . _prepare_tools_and_tool_choice (chat_options = chat_options )
546529 return await self ._inner_get_response (messages = prepped_messages , chat_options = chat_options , ** kwargs )
547530
548531 async def get_streaming_response (
@@ -623,12 +606,32 @@ async def get_streaming_response(
623606 ** kwargs ,
624607 )
625608 prepped_messages = self ._prepare_messages (messages )
626- _prepare_tools_and_tool_choice (chat_options = chat_options )
609+ self . _prepare_tools_and_tool_choice (chat_options = chat_options )
627610 async for update in self ._inner_get_streaming_response (
628611 messages = prepped_messages , chat_options = chat_options , ** kwargs
629612 ):
630613 yield update
631614
615+ def _prepare_tools_and_tool_choice (self , chat_options : ChatOptions ) -> None :
616+ """Prepare the tools and tool choice for the chat options.
617+
618+ This function should be overridden by subclasses to customize tool handling.
619+ Because it currently parses only AIFunctions.
620+ """
621+ chat_tool_mode : ChatToolMode | None = chat_options .tool_choice # type: ignore
622+ if chat_tool_mode is None or chat_tool_mode == ChatToolMode .NONE :
623+ chat_options .tools = None
624+ chat_options .tool_choice = ChatToolMode .NONE .mode
625+ return
626+ chat_options .tools = [
627+ (ai_function_to_json_schema_spec (t ) if isinstance (t , AIFunction ) else t ) # type: ignore[reportUnknownArgumentType]
628+ for t in chat_options ._ai_tools or [] # type: ignore[reportPrivateUsage]
629+ ]
630+ if not chat_options .tools :
631+ chat_options .tool_choice = ChatToolMode .NONE .mode
632+ else :
633+ chat_options .tool_choice = chat_tool_mode .mode
634+
632635
633636# region: Embedding Client
634637
0 commit comments