Skip to content

Commit f9b33d7

Browse files
committed
Test fixes
1 parent f0fa10a commit f9b33d7

9 files changed

+124
-104
lines changed

src/llm/io_processing/base_output_parser.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <openvino/genai/tokenizer.hpp>
1919
#include <openvino/genai/generation_handle.hpp>
20+
#include <unordered_map>
2021
#include <unordered_set>
2122
#include <string>
2223
#include <optional>
@@ -58,7 +59,7 @@ enum class ParameterType_t {
5859
OBJECT,
5960
UNKNOWN
6061
};
61-
using ParametersTypeMap_t = std::unordered_map<std::string, ParameterType_t>; // param name -> param type
62+
using ParametersTypeMap_t = std::unordered_map<std::string, ParameterType_t>; // param name -> param type
6263
using ToolsParameterTypeMap_t = std::unordered_map<std::string, ParametersTypeMap_t>; // tool name -> (param name -> param type)
6364

6465
class BaseOutputParser {

src/llm/io_processing/qwen3/tool_parser.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
//*****************************************************************************
1616

1717
#include <openvino/genai/tokenizer.hpp>
18+
#include <algorithm>
1819
#include <string>
1920
#include <stack>
2021
#include <vector>
21-
#include <utility>
2222

2323
#pragma warning(push)
2424
#pragma warning(disable : 6313)
@@ -308,7 +308,6 @@ bool Parser::step(ToolCalls& toolCalls) {
308308
auto pos = content.find(Qwen3CoderToolParser::tagEnd, currentPosition);
309309
CHECK_IF_FOUND2(pos, Qwen3CoderToolParser::tagEnd, State::ErrorEnd);
310310
this->currentParameterName = content.substr(currentPosition, pos - currentPosition);
311-
;
312311
currentPosition = pos + Qwen3CoderToolParser::tagEnd.length();
313312
currentState = State::InsideParameter;
314313
break;
@@ -387,8 +386,8 @@ void Qwen3CoderToolParser::parse(ParsedOutput& parsedOutput, const std::vector<i
387386
}
388387

389388
Parser parser(parsedOutput.content, toolsParametersTypes);
390-
while (parser.step(parsedOutput.toolCalls))
391-
;
389+
while (parser.step(parsedOutput.toolCalls)) {
390+
}
392391
if (parser.currentState != Parser::State::End) {
393392
SPDLOG_DEBUG("Parsing ended with error, leaving content as is");
394393
return;

src/llm/io_processing/qwen3/tool_parser.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <stack>
2121
#include <string>
2222
#include <unordered_set>
23+
#include <utility>
2324
#include <vector>
2425

2526
#pragma warning(push)

src/test/llm/output_parsers/hermes3_output_parser_test.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const std::string tokenizerPath = "/ovms/src/test/llm_testing/NousResearch/Herme
3232
#endif
3333

3434
static std::unique_ptr<ov::genai::Tokenizer> hermes3Tokenizer;
35+
static ovms::ToolsSchemas_t toolsSchemas; // can be empty for hermes
3536

3637
class Hermes3OutputParserTest : public ::testing::Test {
3738
protected:
@@ -75,7 +76,7 @@ TEST_F(Hermes3OutputParserTest, ParseToolCallOutputWithSingleToolCall) {
7576
}
7677
auto generatedTensor = hermes3Tokenizer->encode(input, ov::genai::add_special_tokens(false)).input_ids;
7778
std::vector<int64_t> generatedTokens(generatedTensor.data<int64_t>(), generatedTensor.data<int64_t>() + generatedTensor.get_size());
78-
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true) : outputParserWithRegularToolParsing->parse(generatedTokens, true);
79+
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true, toolsSchemas) : outputParserWithRegularToolParsing->parse(generatedTokens, true, toolsSchemas);
7980
EXPECT_EQ(parsedOutput.content, "");
8081
EXPECT_EQ(parsedOutput.reasoning, "");
8182

@@ -104,7 +105,7 @@ TEST_F(Hermes3OutputParserTest, ParseToolCallOutputWithNoToolsInTheRequest) {
104105
}
105106
auto generatedTensor = hermes3Tokenizer->encode(testInput, ov::genai::add_special_tokens(false)).input_ids;
106107
std::vector<int64_t> generatedTokens(generatedTensor.data<int64_t>(), generatedTensor.data<int64_t>() + generatedTensor.get_size());
107-
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, false) : outputParserWithRegularToolParsing->parse(generatedTokens, false);
108+
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, false, toolsSchemas) : outputParserWithRegularToolParsing->parse(generatedTokens, false, toolsSchemas);
108109
EXPECT_EQ(parsedOutput.content, testInput);
109110
EXPECT_EQ(parsedOutput.reasoning, "");
110111

@@ -131,7 +132,7 @@ TEST_F(Hermes3OutputParserTest, ParseToolCallOutputWithThreeToolCalls) {
131132
}
132133
auto generatedTensor = hermes3Tokenizer->encode(input, ov::genai::add_special_tokens(false)).input_ids;
133134
std::vector<int64_t> generatedTokens(generatedTensor.data<int64_t>(), generatedTensor.data<int64_t>() + generatedTensor.get_size());
134-
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true) : outputParserWithRegularToolParsing->parse(generatedTokens, true);
135+
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true, toolsSchemas) : outputParserWithRegularToolParsing->parse(generatedTokens, true, toolsSchemas);
135136
EXPECT_EQ(parsedOutput.content, "");
136137
EXPECT_EQ(parsedOutput.reasoning, "");
137138

@@ -178,7 +179,7 @@ TEST_F(Hermes3OutputParserTest, ParseToolCallOutputWithTwoValidToolCallsAndOneIn
178179
}
179180
auto generatedTensor = hermes3Tokenizer->encode(input, ov::genai::add_special_tokens(false)).input_ids;
180181
std::vector<int64_t> generatedTokens(generatedTensor.data<int64_t>(), generatedTensor.data<int64_t>() + generatedTensor.get_size());
181-
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true) : outputParserWithRegularToolParsing->parse(generatedTokens, true);
182+
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true, toolsSchemas) : outputParserWithRegularToolParsing->parse(generatedTokens, true, toolsSchemas);
182183
EXPECT_EQ(parsedOutput.content, "");
183184
EXPECT_EQ(parsedOutput.reasoning, "");
184185

@@ -204,13 +205,13 @@ TEST_F(Hermes3OutputParserTest, ParseToolCallOutputWithContentAndNoToolCalls) {
204205
std::string input = "This is a regular model response without tool calls.";
205206
auto generatedTensor = hermes3Tokenizer->encode(input, ov::genai::add_special_tokens(false)).input_ids;
206207
std::vector<int64_t> generatedTokens(generatedTensor.data<int64_t>(), generatedTensor.data<int64_t>() + generatedTensor.get_size());
207-
ParsedOutput parsedOutput = outputParserWithRegularToolParsing->parse(generatedTokens, true);
208+
ParsedOutput parsedOutput = outputParserWithRegularToolParsing->parse(generatedTokens, true, toolsSchemas);
208209
EXPECT_EQ(parsedOutput.content, "This is a regular model response without tool calls.");
209210
ASSERT_EQ(parsedOutput.toolCalls.size(), 0);
210211
EXPECT_EQ(parsedOutput.reasoning, "");
211212

212213
// Immediate parsing expects tool call right away, so it fails yielding empty both content and tool calls
213-
ParsedOutput parsedOutputImmediate = outputParserWithImmediateToolParsing->parse(generatedTokens, true);
214+
ParsedOutput parsedOutputImmediate = outputParserWithImmediateToolParsing->parse(generatedTokens, true, toolsSchemas);
214215
EXPECT_EQ(parsedOutputImmediate.content, "");
215216
ASSERT_EQ(parsedOutputImmediate.toolCalls.size(), 0);
216217
EXPECT_EQ(parsedOutputImmediate.reasoning, "");
@@ -221,7 +222,7 @@ TEST_F(Hermes3OutputParserTest, ParseToolCallOutputWithContentAndSingleToolCall)
221222
auto generatedTensor = hermes3Tokenizer->encode(input, ov::genai::add_special_tokens(false)).input_ids;
222223
std::vector<int64_t> generatedTokens(generatedTensor.data<int64_t>(), generatedTensor.data<int64_t>() + generatedTensor.get_size());
223224
// generatedTokens should now contain content followed by bot token ID and then tool call
224-
ParsedOutput parsedOutput = outputParserWithRegularToolParsing->parse(generatedTokens, true);
225+
ParsedOutput parsedOutput = outputParserWithRegularToolParsing->parse(generatedTokens, true, toolsSchemas);
225226
EXPECT_EQ(parsedOutput.content, "This is a content part and next will be a tool call.\n\n");
226227
EXPECT_EQ(parsedOutput.reasoning, "");
227228

src/test/llm/output_parsers/llama3_output_parser_test.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const std::string tokenizerPath = getWindowsRepoRootPath() + "\\src\\test\\llm_t
3131
const std::string tokenizerPath = "/ovms/src/test/llm_testing/meta-llama/Llama-3.1-8B-Instruct";
3232
#endif
3333

34+
static ovms::ToolsSchemas_t toolsSchemas; // can be empty for llama3
3435
static std::unique_ptr<ov::genai::Tokenizer> llama3Tokenizer;
3536

3637
// Id of the <|python_tag|> which is a special token used to indicate the start of a tool calls
@@ -68,7 +69,7 @@ TEST_F(Llama3OutputParserTest, ParseToolCallOutputWithSingleToolCall) {
6869
std::vector<int64_t> generatedTokens(generatedTensor.data<int64_t>(), generatedTensor.data<int64_t>() + generatedTensor.get_size());
6970
generatedTokens.insert(generatedTokens.begin(), botTokenId);
7071
for (bool immediateParsing : {false, true}) {
71-
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true) : outputParserWithRegularToolParsing->parse(generatedTokens, true);
72+
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true, toolsSchemas) : outputParserWithRegularToolParsing->parse(generatedTokens, true, toolsSchemas);
7273
EXPECT_EQ(parsedOutput.content, "");
7374
EXPECT_EQ(parsedOutput.reasoning, "");
7475
ASSERT_EQ(parsedOutput.toolCalls.size(), 1);
@@ -83,7 +84,7 @@ TEST_F(Llama3OutputParserTest, ParseToolCallOutputNoToolsInTheRequest) {
8384
auto generatedTensor = llama3Tokenizer->encode(input, ov::genai::add_special_tokens(false)).input_ids;
8485
std::vector<int64_t> generatedTokens(generatedTensor.data<int64_t>(), generatedTensor.data<int64_t>() + generatedTensor.get_size());
8586
for (bool immediateParsing : {false, true}) {
86-
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, false) : outputParserWithRegularToolParsing->parse(generatedTokens, false);
87+
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, false, toolsSchemas) : outputParserWithRegularToolParsing->parse(generatedTokens, false, toolsSchemas);
8788
EXPECT_EQ(parsedOutput.content, input);
8889
EXPECT_EQ(parsedOutput.reasoning, "");
8990
ASSERT_EQ(parsedOutput.toolCalls.size(), 0);
@@ -96,7 +97,7 @@ TEST_F(Llama3OutputParserTest, ParseRegularJsonOutputToolsInTheRequest) {
9697
auto generatedTensor = llama3Tokenizer->encode(input, ov::genai::add_special_tokens(false)).input_ids;
9798
std::vector<int64_t> generatedTokens(generatedTensor.data<int64_t>(), generatedTensor.data<int64_t>() + generatedTensor.get_size());
9899
for (bool immediateParsing : {false, true}) {
99-
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true) : outputParserWithRegularToolParsing->parse(generatedTokens, true);
100+
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true, toolsSchemas) : outputParserWithRegularToolParsing->parse(generatedTokens, true, toolsSchemas);
100101
EXPECT_EQ(parsedOutput.content, "");
101102
EXPECT_EQ(parsedOutput.reasoning, "");
102103
ASSERT_EQ(parsedOutput.toolCalls.size(), 0);
@@ -109,7 +110,7 @@ TEST_F(Llama3OutputParserTest, ParseRegularJsonOutputNoToolsInTheRequest) {
109110
auto generatedTensor = llama3Tokenizer->encode(input, ov::genai::add_special_tokens(false)).input_ids;
110111
std::vector<int64_t> generatedTokens(generatedTensor.data<int64_t>(), generatedTensor.data<int64_t>() + generatedTensor.get_size());
111112
for (bool immediateParsing : {false, true}) {
112-
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, false) : outputParserWithRegularToolParsing->parse(generatedTokens, false);
113+
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, false, toolsSchemas) : outputParserWithRegularToolParsing->parse(generatedTokens, false, toolsSchemas);
113114
EXPECT_EQ(parsedOutput.content, input);
114115
EXPECT_EQ(parsedOutput.reasoning, "");
115116
}
@@ -122,7 +123,7 @@ TEST_F(Llama3OutputParserTest, ParseToolCallOutputWithThreeToolCalls) {
122123
auto generatedTensor = llama3Tokenizer->encode(input, ov::genai::add_special_tokens(false)).input_ids;
123124
std::vector<int64_t> generatedTokens(generatedTensor.data<int64_t>(), generatedTensor.data<int64_t>() + generatedTensor.get_size());
124125
for (bool immediateParsing : {false, true}) {
125-
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true) : outputParserWithRegularToolParsing->parse(generatedTokens, true);
126+
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true, toolsSchemas) : outputParserWithRegularToolParsing->parse(generatedTokens, true, toolsSchemas);
126127
EXPECT_EQ(parsedOutput.content, "");
127128
EXPECT_EQ(parsedOutput.reasoning, "");
128129
ASSERT_EQ(parsedOutput.toolCalls.size(), 3);
@@ -149,7 +150,7 @@ TEST_F(Llama3OutputParserTest, ParseToolCallOutputWithContentAndNoToolCalls) {
149150
auto generatedTensor = llama3Tokenizer->encode(input, ov::genai::add_special_tokens(false)).input_ids;
150151
std::vector<int64_t> generatedTokens(generatedTensor.data<int64_t>(), generatedTensor.data<int64_t>() + generatedTensor.get_size());
151152
for (bool immediateParsing : {false, true}) {
152-
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true) : outputParserWithRegularToolParsing->parse(generatedTokens, true);
153+
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true, toolsSchemas) : outputParserWithRegularToolParsing->parse(generatedTokens, true, toolsSchemas);
153154
EXPECT_EQ(parsedOutput.content, immediateParsing ? "" : "This is a regular model response without tool calls.");
154155
ASSERT_EQ(parsedOutput.toolCalls.size(), 0);
155156
EXPECT_EQ(parsedOutput.reasoning, "");
@@ -168,7 +169,7 @@ TEST_F(Llama3OutputParserTest, ParseToolCallOutputWithContentAndSingleToolCall)
168169
generatedTokens.insert(generatedTokens.end(), botTokenId);
169170
generatedTokens.insert(generatedTokens.end(), generatedToolCallTokens.begin(), generatedToolCallTokens.end());
170171
for (bool immediateParsing : {false, true}) {
171-
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true) : outputParserWithRegularToolParsing->parse(generatedTokens, true);
172+
ParsedOutput parsedOutput = immediateParsing ? outputParserWithImmediateToolParsing->parse(generatedTokens, true, toolsSchemas) : outputParserWithRegularToolParsing->parse(generatedTokens, true, toolsSchemas);
172173
EXPECT_EQ(parsedOutput.content, immediateParsing ? "" : "This is a content part and next will be a tool call.");
173174
EXPECT_EQ(parsedOutput.reasoning, "");
174175
ASSERT_EQ(parsedOutput.toolCalls.size(), immediateParsing ? 0 : 1);

0 commit comments

Comments
 (0)