1- from typing import List , Iterable , Union , Optional
1+ from typing import List , Iterable , Union , Optional , Tuple
22from openai import OpenAI , AzureOpenAI
33from httpx import Client
44from httpx_socks import SyncProxyTransport
5- from openai import NOT_GIVEN
5+ from openai import NOT_GIVEN , NotGiven
66from openai .types .chat import ChatCompletion , ChatCompletionReasoningEffort
77from openai .types .chat .chat_completion_stream_options_param import ChatCompletionStreamOptionsParam
88from openai .types .chat .chat_completion_message_param import ChatCompletionMessageParam
9+ from openai .types .chat .chat_completion_tool_param import ChatCompletionToolParam
910from openai .types .chat .chat_completion_chunk import ChatCompletionChunk
11+ from openai .types .chat .completion_create_params import Function
1012from ghostos .contracts .logger import LoggerItf , get_ghostos_logger
1113from ghostos .helpers import timestamp_ms
1214from ghostos .core .messages import (
1517 CompletionUsagePayload , Role ,
1618)
1719from ghostos .core .llms import (
18- LLMs , LLMDriver , LLMApi , ModelConf , ServiceConf , OPENAI_DRIVER_NAME , LITELLM_DRIVER_NAME , DEEPSEEK_DRIVER_NAME ,
20+ LLMDriver , LLMApi , ModelConf , ServiceConf , OPENAI_DRIVER_NAME , LITELLM_DRIVER_NAME , DEEPSEEK_DRIVER_NAME ,
1921 Prompt , PromptPayload , PromptStorage ,
22+ Compatible ,
2023 FunctionalToken ,
2124)
22- from ghostos .container import Bootstrapper , Container
2325
2426__all__ = [
2527 'OpenAIDriver' , 'OpenAIAdapter' ,
@@ -137,9 +139,7 @@ def _parse_system_to_develop(messages: List[Message]) -> List[Message]:
137139 return changed
138140
139141 def parse_by_compatible_settings (self , messages : List [Message ]) -> List [Message ]:
140- compatible = self .model .compatible
141- if compatible is None :
142- compatible = self .service .compatible
142+ compatible = self ._get_compatible_options ()
143143
144144 if compatible is None :
145145 return messages
@@ -191,12 +191,7 @@ def _chat_completion(self, prompt: Prompt, stream: bool) -> Union[ChatCompletion
191191 try :
192192 prompt .run_start = timestamp_ms ()
193193 self ._logger .debug (f"start chat completion messages %s" , messages )
194- functions = prompt .get_openai_functions ()
195- tools = prompt .get_openai_tools ()
196- if self .model .use_tools :
197- functions = NOT_GIVEN
198- else :
199- tools = NOT_GIVEN
194+ functions , tools = self ._get_prompt_functions_and_tools (prompt )
200195 return self ._client .chat .completions .create (
201196 messages = messages ,
202197 model = self .model .model ,
@@ -218,6 +213,22 @@ def _chat_completion(self, prompt: Prompt, stream: bool) -> Union[ChatCompletion
218213 self ._logger .debug (f"end chat completion for prompt { prompt .id } " )
219214 prompt .run_end = timestamp_ms ()
220215
216+ def _get_prompt_functions_and_tools (
217+ self ,
218+ prompt : Prompt ,
219+ ) -> Tuple [Union [List [Function ], NotGiven ], Union [List [ChatCompletionToolParam ], NotGiven ]]:
220+ functions = prompt .get_openai_functions ()
221+ tools = prompt .get_openai_tools ()
222+ if self .model .use_tools :
223+ functions = NOT_GIVEN
224+ else :
225+ tools = NOT_GIVEN
226+ # compatible check
227+ if not self ._get_compatible_options ().support_function_call :
228+ functions = NOT_GIVEN
229+ tools = NOT_GIVEN
230+ return functions , tools
231+
221232 def _reasoning_completion (self , prompt : Prompt ) -> ChatCompletion :
222233 if self .model .reasoning is None :
223234 raise NotImplementedError (f"current model { self .model } does not support reasoning completion " )
@@ -237,12 +248,7 @@ def _reasoning_completion(self, prompt: Prompt) -> ChatCompletion:
237248 try :
238249 prompt .run_start = timestamp_ms ()
239250 self ._logger .debug (f"start reasoning completion messages %s" , messages )
240- functions = prompt .get_openai_functions ()
241- tools = prompt .get_openai_tools ()
242- if self .model .use_tools :
243- functions = NOT_GIVEN
244- else :
245- tools = NOT_GIVEN
251+ functions , tools = self ._get_prompt_functions_and_tools (prompt )
246252 if self .model .reasoning .effort is None :
247253 reasoning_effort = NOT_GIVEN
248254 else :
@@ -292,12 +298,7 @@ def _reasoning_completion_stream(self, prompt: Prompt) -> Iterable[ChatCompletio
292298 try :
293299 prompt .run_start = timestamp_ms ()
294300 self ._logger .debug (f"start reasoning completion messages %s" , messages )
295- functions = prompt .get_openai_functions ()
296- tools = prompt .get_openai_tools ()
297- if self .model .use_tools :
298- functions = NOT_GIVEN
299- else :
300- tools = NOT_GIVEN
301+ functions , tools = self ._get_prompt_functions_and_tools (prompt )
301302 if self .model .reasoning .effort is None :
302303 reasoning_effort = NOT_GIVEN
303304 else :
@@ -415,6 +416,9 @@ def parse_prompt(self, prompt: Prompt) -> Prompt:
415416 prompt .model = self .model
416417 return prompt
417418
419+ def _get_compatible_options (self ) -> Compatible :
420+ return self .model .compatible or self .service .compatible or Compatible ()
421+
418422
419423class OpenAIDriver (LLMDriver ):
420424 """
0 commit comments