Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class _CustomToolFormat(BaseModel):
_ALLOWED_CALLERS_ADAPTER: Final = TypeAdapter(list[str] | None)


def _validated_allowed_callers(value: object) -> list[str] | None:
def validated_allowed_callers(value: object) -> list[str] | None:
try:
return _ALLOWED_CALLERS_ADAPTER.validate_python(value, strict=True)
except ValidationError as exc:
Expand Down Expand Up @@ -143,7 +143,7 @@ def convert_custom_tool_to_function_tool(tool: Mapping[str, object]) -> ChatComp
name: Final = raw_name if isinstance(raw_name, str) else ""
raw_description: Final = tool.get("description")
description = (raw_description if isinstance(raw_description, str) else "") + _grammar_suffix(tool.get("format"))
allowed_callers: Final = _validated_allowed_callers(tool.get("allowed_callers"))
allowed_callers: Final = validated_allowed_callers(tool.get("allowed_callers"))
function_chunk: Final = ChatCompletionToolParamFunctionChunk(
name=name,
description=description,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ def __init__(
self._accumulated_reasoning_content_parts: list[str] = []
self._accumulated_provider_specific_fields: dict[str, Any] = {}
self._custom_tool_names: set[str] = extract_custom_tool_names(self.responses_api_request.get("tools"))
self._namespace_tool_names = LiteLLMCompletionResponsesConfig.namespace_tool_name_map(
self.responses_api_request.get("tools")
)

def _get_or_assign_tool_output_index(self, call_id: str) -> int:
existing: Final = self._tool_output_index_by_call_id.get(call_id)
Expand All @@ -125,6 +128,13 @@ def _normalize_tool_call_index(self, tool_call: object) -> int | None:
except (TypeError, ValueError):
return None

def _responses_namespace_tool_call_fields(self, fn_name: str) -> tuple[str, str | None]:
mapped: Final = self._namespace_tool_names.get(fn_name)
if mapped:
namespace, tool_name = mapped
return tool_name, namespace
return fn_name, None
Comment thread
dcadenas marked this conversation as resolved.
Comment thread
dcadenas marked this conversation as resolved.

def _is_reasoning_end(self, chunk):
delta: Final = chunk.choices[0].delta

Expand Down Expand Up @@ -183,13 +193,17 @@ def _queue_tool_call_delta_events(self, tool_calls: object) -> None:
else:
fn_name = str(getattr(fn, "name", "") or "")
fn_args_delta = str(getattr(fn, "arguments", "") or "")
tool_name, tool_namespace = self._responses_namespace_tool_call_fields(fn_name)

output_index = self._get_or_assign_tool_output_index(call_id)

if call_id not in self._tool_args_by_call_id:
self._tool_args_by_call_id[call_id] = ""
self._sequence_number += 1
item_kwargs = build_tool_call_item_kwargs(call_id, fn_name, "", "in_progress", self._custom_tool_names)
names = self._custom_tool_names
item_kwargs = build_tool_call_item_kwargs(call_id, tool_name, "", "in_progress", names)
if tool_namespace:
item_kwargs["namespace"] = tool_namespace
event = OutputItemAddedEvent(
type=ResponsesAPIStreamEvents.OUTPUT_ITEM_ADDED,
output_index=output_index,
Expand Down Expand Up @@ -250,6 +264,7 @@ def _queue_final_tool_call_done_events(self, litellm_complete_object: ModelRespo
else:
fn_name = str(getattr(fn, "name", "") or "")
fn_args = str(getattr(fn, "arguments", "") or "")
tool_name, tool_namespace = self._responses_namespace_tool_call_fields(fn_name)

# Track if this is a new tool call that wasn't streamed
is_new_tool_call = call_id not in self._tool_args_by_call_id
Expand All @@ -258,7 +273,10 @@ def _queue_final_tool_call_done_events(self, litellm_complete_object: ModelRespo
if is_new_tool_call:
self._tool_args_by_call_id[call_id] = ""
self._sequence_number += 1
item_kwargs = build_tool_call_item_kwargs(call_id, fn_name, "", "in_progress", self._custom_tool_names)
names = self._custom_tool_names
item_kwargs = build_tool_call_item_kwargs(call_id, tool_name, "", "in_progress", names)
if tool_namespace:
item_kwargs["namespace"] = tool_namespace
event = OutputItemAddedEvent(
type=ResponsesAPIStreamEvents.OUTPUT_ITEM_ADDED,
output_index=output_index,
Expand Down Expand Up @@ -300,9 +318,10 @@ def _queue_final_tool_call_done_events(self, litellm_complete_object: ModelRespo
self._pending_tool_events.append(done_event)

self._sequence_number += 1
item_kwargs = build_tool_call_item_kwargs(
call_id, fn_name, final_args, "completed", self._custom_tool_names
)
names = self._custom_tool_names
item_kwargs = build_tool_call_item_kwargs(call_id, tool_name, final_args, "completed", names)
if tool_namespace:
item_kwargs["namespace"] = tool_namespace
item_done_event = OutputItemDoneEvent(
type=ResponsesAPIStreamEvents.OUTPUT_ITEM_DONE,
output_index=output_index,
Expand Down
Loading
Loading