From 47a0f349cab5ebc206b4787240fc9ab7a8ece08d Mon Sep 17 00:00:00 2001 From: ochafik Date: Mon, 26 May 2025 04:39:47 -0700 Subject: [PATCH 1/3] fix deltas of tool_call.name --- common/chat.cpp | 2 +- tools/server/tests/utils.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/chat.cpp b/common/chat.cpp index adfe51db5a7..757d6ffd2cb 100644 --- a/common/chat.cpp +++ b/common/chat.cpp @@ -101,9 +101,9 @@ std::vector common_chat_msg_diff::compute_diffs(const comm if (!args_diff.empty() || pref.id != newf.id) { auto & diff = diffs.emplace_back(); diff.tool_call_index = idx; - diff.tool_call_delta.name = newf.name; if (pref.id != newf.id) { diff.tool_call_delta.id = newf.id; + diff.tool_call_delta.name = newf.name; } diff.tool_call_delta.arguments = args_diff; } diff --git a/tools/server/tests/utils.py b/tools/server/tests/utils.py index 11672f515df..8a37e49058c 100644 --- a/tools/server/tests/utils.py +++ b/tools/server/tests/utils.py @@ -341,7 +341,7 @@ def make_any_request( tool_call['id'] = tc['id'] fct = tc['function'] if fct.get('name') is not None: - tool_call['function']['name'] = fct['name'] + tool_call['function']['name'] = tool_call['function'].get('name', '') + fct['name'] if fct.get('arguments') is not None: assert len(fct['arguments']) > 0, f'Expected non empty arguments delta!' tool_call['function']['arguments'] += fct['arguments'] From 82eb01df2ee24ee745c29f117c6c124b0a863f80 Mon Sep 17 00:00:00 2001 From: ochafik Date: Mon, 26 May 2025 04:57:03 -0700 Subject: [PATCH 2/3] Update test-chat.cpp --- tests/test-chat.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test-chat.cpp b/tests/test-chat.cpp index fb048022a06..5f542f02241 100644 --- a/tests/test-chat.cpp +++ b/tests/test-chat.cpp @@ -1356,8 +1356,7 @@ static void test_msg_diffs_compute() { common_chat_msg_diff diff12; diff12.tool_call_index = 0; - diff12.tool_call_delta.name = "special_function"; - // Note: id doesnt change here. + // Note: neither id nor name change here. diff12.tool_call_delta.arguments = "g1\": 1}"; assert_equals( From a7e6f3941da736babdedfde2ae0abfe2cd548e84 Mon Sep 17 00:00:00 2001 From: ochafik Date: Mon, 26 May 2025 05:42:48 -0700 Subject: [PATCH 3/3] fix tool_call.id (was in tool_call.function.id!) + add function type Co-Authored-By: ochafik --- common/chat.cpp | 21 +++++++++------------ tools/server/tests/utils.py | 6 +++++- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/common/chat.cpp b/common/chat.cpp index 757d6ffd2cb..2609970b2b4 100644 --- a/common/chat.cpp +++ b/common/chat.cpp @@ -387,22 +387,19 @@ template <> json common_chat_msg_diff_to_json_oaicompat(const common_chat_msg_di delta["content"] = diff.content_delta; } if (diff.tool_call_index != std::string::npos) { + json tool_call; + tool_call["index"] = diff.tool_call_index; + if (!diff.tool_call_delta.id.empty()) { + tool_call["id"] = diff.tool_call_delta.id; + tool_call["type"] = "function"; + } json function = json::object(); if (!diff.tool_call_delta.name.empty()) { function["name"] = diff.tool_call_delta.name; } - if (!diff.tool_call_delta.id.empty()) { - function["id"] = diff.tool_call_delta.id; - } - if (!diff.tool_call_delta.arguments.empty()) { - function["arguments"] = diff.tool_call_delta.arguments; - } - delta["tool_calls"] = json::array({ - json { - {"index", diff.tool_call_index}, - {"function", function} - } - }); + function["arguments"] = diff.tool_call_delta.arguments; + tool_call["function"] = function; + delta["tool_calls"] = json::array({tool_call}); } return delta; } diff --git a/tools/server/tests/utils.py b/tools/server/tests/utils.py index 8a37e49058c..f7e1b3b3b7b 100644 --- a/tools/server/tests/utils.py +++ b/tools/server/tests/utils.py @@ -328,6 +328,10 @@ def make_any_request( if 'function' not in tc: raise ValueError(f"Expected function type, got {tc['type']}") if tc['index'] >= len(tool_calls): + assert 'id' in tc + assert tc.get('type') == 'function' + assert 'function' in tc and 'name' in tc['function'] and len(tc['function']['name']) > 0, \ + f"Expected function call with name, got {tc.get('function')}" tool_calls.append(dict( id="", type="function", @@ -340,10 +344,10 @@ def make_any_request( if tc.get('id') is not None: tool_call['id'] = tc['id'] fct = tc['function'] + assert 'id' not in fct, f"Function call should not have id: {fct}" if fct.get('name') is not None: tool_call['function']['name'] = tool_call['function'].get('name', '') + fct['name'] if fct.get('arguments') is not None: - assert len(fct['arguments']) > 0, f'Expected non empty arguments delta!' tool_call['function']['arguments'] += fct['arguments'] print(f'Streamed response had {content_parts} content parts, {tool_call_parts} tool call parts incl. {arguments_parts} arguments parts')