@@ -388,9 +388,19 @@ def from_dict(cls, data: Dict[str, Any]) -> "ChatMessage":
388
388
389
389
raise ValueError (f"Missing 'content' or '_content' in serialized ChatMessage: `{ data } `" )
390
390
391
- def to_openai_dict_format (self ) -> Dict [str , Any ]:
391
+ def to_openai_dict_format (self , require_tool_call_ids : bool = True ) -> Dict [str , Any ]:
392
392
"""
393
393
Convert a ChatMessage to the dictionary format expected by OpenAI's Chat API.
394
+
395
+ :param require_tool_call_ids:
396
+ If True (default), enforces that each Tool Call includes a non-null `id` attribute.
397
+ Set to False to allow Tool Calls without `id`, which may be suitable for shallow OpenAI-compatible APIs.
398
+ :returns:
399
+ The ChatMessage in the format expected by OpenAI's Chat API.
400
+
401
+ :raises ValueError:
402
+ If the message format is invalid, or if `require_tool_call_ids` is True and any Tool Call is missing an
403
+ `id` attribute.
394
404
"""
395
405
text_contents = self .texts
396
406
tool_calls = self .tool_calls
@@ -411,28 +421,32 @@ def to_openai_dict_format(self) -> Dict[str, Any]:
411
421
412
422
if tool_call_results :
413
423
result = tool_call_results [0 ]
414
- if result .origin .id is None :
415
- raise ValueError ("`ToolCall` must have a non-null `id` attribute to be used with OpenAI." )
416
424
openai_msg ["content" ] = result .result
417
- openai_msg ["tool_call_id" ] = result .origin .id
425
+ if result .origin .id is not None :
426
+ openai_msg ["tool_call_id" ] = result .origin .id
427
+ elif require_tool_call_ids :
428
+ raise ValueError ("`ToolCall` must have a non-null `id` attribute to be used with OpenAI." )
429
+
418
430
# OpenAI does not provide a way to communicate errors in tool invocations, so we ignore the error field
419
431
return openai_msg
420
432
421
433
if text_contents :
422
434
openai_msg ["content" ] = text_contents [0 ]
423
435
if tool_calls :
424
436
openai_tool_calls = []
437
+
425
438
for tc in tool_calls :
426
- if tc .id is None :
439
+ openai_tool_call = {
440
+ "type" : "function" ,
441
+ # We disable ensure_ascii so special chars like emojis are not converted
442
+ "function" : {"name" : tc .tool_name , "arguments" : json .dumps (tc .arguments , ensure_ascii = False )},
443
+ }
444
+ if tc .id is not None :
445
+ openai_tool_call ["id" ] = tc .id
446
+ elif require_tool_call_ids :
427
447
raise ValueError ("`ToolCall` must have a non-null `id` attribute to be used with OpenAI." )
428
- openai_tool_calls .append (
429
- {
430
- "id" : tc .id ,
431
- "type" : "function" ,
432
- # We disable ensure_ascii so special chars like emojis are not converted
433
- "function" : {"name" : tc .tool_name , "arguments" : json .dumps (tc .arguments , ensure_ascii = False )},
434
- }
435
- )
448
+ openai_tool_calls .append (openai_tool_call )
449
+
436
450
openai_msg ["tool_calls" ] = openai_tool_calls
437
451
return openai_msg
438
452
0 commit comments