@@ -78,8 +78,7 @@ def get_ai_metrics_from_response(response: Any) -> LDAIMetrics:
7878 return LDAIMetrics (success = True , usage = get_ai_usage_from_response (response ))
7979
8080
81- # Tool names that require their own API type in the Chat Completions API.
82- # LD stores all tools as type="function"; these are converted to their correct type.
81+ # Tool ``name`` values that map to OpenAI hosted-tool ``type`` (same string as ``name``).
8382_NATIVE_API_TOOL_NAMES = frozenset ({
8483 'web_search' ,
8584 'file_search' ,
@@ -89,11 +88,12 @@ def get_ai_metrics_from_response(response: Any) -> LDAIMetrics:
8988
9089def normalize_tool_types (tool_definitions : List [Any ]) -> List [Dict [str , Any ]]:
9190 """
92- Convert LD tool definitions to Chat Completions API format .
91+ Set ``type`` on LD tool definitions for OpenAI hosted tools .
9392
94- LD emits all tools as ``type="function"`` with a flat structure. This helper
95- wraps regular function tools in the nested ``function`` key the API requires,
96- and converts known native tool names to their correct API type without a schema.
93+ When ``name`` is a known OpenAI hosted tool (e.g. ``file_search``), ``type`` is set
94+ to that name; all other keys are left unchanged (``vector_store_ids``, etc.
95+ come from the LD config). Other tools and non-dict entries are passed through
96+ unchanged (non-dicts are skipped).
9797
9898 :param tool_definitions: Tool definitions from the LD AI config
9999 :return: Tool list ready to pass to ``chat.completions.create``
@@ -103,7 +103,10 @@ def normalize_tool_types(tool_definitions: List[Any]) -> List[Dict[str, Any]]:
103103 if not isinstance (td , dict ):
104104 continue
105105 name = td .get ('name' , '' )
106- result .append ({** td , 'type' : name } if name in _NATIVE_API_TOOL_NAMES else td )
106+ if name in _NATIVE_API_TOOL_NAMES :
107+ result .append ({** td , 'type' : name })
108+ else :
109+ result .append (td )
107110 return result
108111
109112
0 commit comments