Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions python/openai/openai_frontend/engine/utils/triton.py
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,12 @@ def _get_guided_json_from_tool(
if tool_name not in tools:
raise ClientError(f"Tool '{tool_name}' has not been passed in `tools`.")
tool = tools[tool_name]
# A function without "parameters" takes no arguments, so constrain
# the call to an empty JSON object.
if tool.parameters is None:
return json.dumps(
{"type": "object", "properties": {}, "additionalProperties": False}
)
return tool.parameters.model_dump_json()

return None
Expand Down
24 changes: 24 additions & 0 deletions python/openai/tests/test_tool_calling.py
Original file line number Diff line number Diff line change
Expand Up @@ -741,3 +741,27 @@ async def test_abandoned_completion_stream_cancels_backend_inference(self, clien

_, status = self._stream(client, "cancellation-status", with_tools=False)
assert status == "cancelled"


# OpenAI allows a function without "parameters": it takes no arguments.
@pytest.mark.parametrize(
"tool_choice",
[{"type": "function", "function": {"name": "get_current_time"}}, "required"],
)
def test_guided_json_for_tool_without_parameters(tool_choice):
from engine.utils.triton import _get_guided_json_from_tool
from schemas.openai import CreateChatCompletionRequest

request = CreateChatCompletionRequest(
model="test-model",
messages=[{"role": "user", "content": "What time is it?"}],
tools=[{"type": "function", "function": {"name": "get_current_time"}}],
tool_choice=tool_choice,
)

guided_json = _get_guided_json_from_tool(request)
assert json.loads(guided_json) == {
"type": "object",
"properties": {},
"additionalProperties": False,
}