Skip to content

Commit 6aebb03

Browse files
committed
Self-review
1 parent 54c9588 commit 6aebb03

File tree

4 files changed

+158
-89
lines changed

4 files changed

+158
-89
lines changed

src/llm/io_processing/output_parser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ std::optional<rapidjson::Document> OutputParser::parseReasoningChunk(ov::genai::
145145

146146
OutputParser::OutputParser(ov::genai::Tokenizer& tokenizer, const std::string toolParserName, const std::string reasoningParserName, const ToolsSchemas_t& toolNameSchemaMap) :
147147
tokenizer(tokenizer) {
148-
SPDLOG_ERROR("OutputParser created with toolNameSchemaMap of size: {}", toolNameSchemaMap.size());
148+
SPDLOG_TRACE("OutputParser created with toolNameSchemaMap of size: {}", toolNameSchemaMap.size());
149149
if (toolParserName == "llama3") {
150150
toolParser = std::make_unique<Llama3ToolParser>(tokenizer);
151151
} else if (toolParserName == "hermes3") {

src/llm/io_processing/qwen3coder/qwen3coder_tool_parser.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,14 @@ static void trimNewline(std::string& str) {
5555
}
5656
}
5757

58-
static std::string toJson(const std::vector<std::pair<std::string, std::string>>& items) {
58+
static std::string toJson(const ParametersValues_t& items) {
5959
std::ostringstream oss;
6060
oss << "{";
61-
for (size_t i = 0; i < items.size(); ++i) {
62-
const auto& [key, value] = items[i];
61+
size_t i = 0;
62+
for (const auto& [key, value] : items) {
6363
oss << "\"" << key << "\": ";
6464
oss << value;
65-
if (i + 1 < items.size()) {
65+
if (i++ + 1 < items.size()) {
6666
oss << ", ";
6767
}
6868
}
@@ -73,8 +73,7 @@ static std::string toJson(const std::vector<std::pair<std::string, std::string>>
7373
Status Qwen3CoderToolParserImpl::removeToolCallsFromContentIfNeeded(std::string& outContent) {
7474
if (toolsBeginStack.size() != toolsEndStack.size()) {
7575
SPDLOG_DEBUG("Mismatched tool tags, begin: {}, end: {}", toolsBeginStack.size(), toolsEndStack.size());
76-
throw std::runtime_error("Mismatched tool tags"); // FIXME replace with status
77-
return StatusCode::INTERNAL_ERROR;
76+
return Status(StatusCode::INTERNAL_ERROR, "Mismatched tool tags");
7877
}
7978
while (!toolsBeginStack.empty() && !toolsEndStack.empty()) {
8079
auto posBegin = toolsBeginStack.top();
@@ -225,7 +224,9 @@ bool Qwen3CoderToolParserImpl::stepUntilStateChange(ToolCalls& toolCalls) {
225224
} else {
226225
parameterValue = setCorrectValueType(parameterValue, this->currentParameterName, paramIt->second);
227226
}
228-
this->currentFunction.parameters.emplace_back(this->currentParameterName, parameterValue);
227+
auto res = this->currentFunction.parameters.try_emplace(this->currentParameterName, parameterValue);
228+
if (!res.second)
229+
SPDLOG_DEBUG("Parameter: {} already exists", this->currentParameterName);
229230
this->lastProcessedPosition = pos + Qwen3CoderToolParser::parameterEndTag.length();
230231
this->currentState = State::InsideFunction;
231232
break;
@@ -387,10 +388,9 @@ std::optional<rapidjson::Document> Qwen3CoderToolParser::sendFirstDeltaIfNeeded(
387388
}
388389

389390
std::optional<rapidjson::Document> Qwen3CoderToolParser::parseChunk(const std::string& newChunk, ov::genai::GenerationFinishReason finishReason) {
390-
// parse Chunk needs to use streamParser to process the chunk
391391
// streamParser will return optional toolCalls when a tool call is completed
392392
// if toolCalls is returned, we need to wrap it in the required JSON structure and return it
393-
// if toolCalls is not returned, but we are insideFunction state, we need to return the first delta with function name
393+
// if toolCalls is not returned, but we are insideFunction state, we need to return the first delta with function name once
394394
// otherwise nullopt
395395
SPDLOG_DEBUG("Chunk: '{}', finishReason: {}", newChunk, static_cast<int>(finishReason));
396396
this->lazyFillInitToolParamatersTypsMap();

src/llm/io_processing/qwen3coder/qwen3coder_tool_parser.hpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
//*****************************************************************************
1616
#pragma once
1717

18-
#include <openvino/genai/tokenizer.hpp>
18+
#include <map>
1919
#include <optional>
2020
#include <set>
2121
#include <stack>
@@ -25,6 +25,7 @@
2525
#include <utility>
2626
#include <vector>
2727

28+
#include <openvino/genai/tokenizer.hpp>
2829
#pragma warning(push)
2930
#pragma warning(disable : 6313)
3031
#include <rapidjson/document.h>
@@ -37,9 +38,10 @@
3738
#include "src/status.hpp"
3839

3940
namespace ovms {
41+
using ParametersValues_t = std::map<std::string, std::string>;
4042
struct Functool {
4143
std::string name;
42-
std::vector<std::pair<std::string, std::string>> parameters;
44+
ParametersValues_t parameters;
4345
void clear() {
4446
name.clear();
4547
parameters.clear();
@@ -106,10 +108,10 @@ class Qwen3CoderToolParser : public BaseOutputParser {
106108
static const std::string tagEnd;
107109

108110
private:
109-
const ToolsSchemas_t& toolSchemas; // we need to keep reference as this is not filled in OpenAIApiHandler during ToolParser creation, NOTE that its const here but it can change outside
110-
ToolsParameterTypeMap_t toolsParametersTypes; // FIXME do it once per request
111+
const ToolsSchemas_t& toolSchemas; // we need to keep reference as this is not filled in OpenAIApiHandler during ToolParser creation, NOTE that its const here but it can change outside
112+
ToolsParameterTypeMap_t toolsParametersTypes;
111113
bool filledParametersTypesMap{false};
112-
// streaming
114+
// for streaming parsing we need to keep parser as a member
113115
Qwen3CoderToolParserImpl streamParser;
114116
int toolCallIndex{-1};
115117
ToolCalls currentToolCalls;
@@ -125,15 +127,15 @@ class Qwen3CoderToolParser : public BaseOutputParser {
125127
void parse(ParsedOutput& parsedOutput, const std::vector<int64_t>& generatedTokens) override;
126128
std::optional<rapidjson::Document> parseChunk(const std::string& chunk, ov::genai::GenerationFinishReason finishReason) override;
127129
const std::string& getParsingStartTag() const override {
128-
return toolsStartTag; // FIXME CHECK
130+
return toolsStartTag;
129131
}
130132
const std::unordered_set<std::string>& getSpecialParsingStartTags() const override {
131-
static const std::unordered_set<std::string> specialParsingStartTags = {toolsStartTag}; // FIXME CHECK
133+
static const std::unordered_set<std::string> specialParsingStartTags = {toolsStartTag};
132134
return specialParsingStartTags;
133135
}
134136
// Tools calls are expected to be the last part of the content, so we do not specify an end tag.
135137
const std::string& getParsingEndTag() const override {
136-
return toolsEndTag; // FIXME CHECK
138+
return toolsEndTag;
137139
}
138140

139141
private:
@@ -145,7 +147,6 @@ class Qwen3CoderToolParser : public BaseOutputParser {
145147
template <>
146148
struct fmt::formatter<ovms::Qwen3CoderToolParserImpl::State> : fmt::formatter<std::string> {
147149
auto format(const ovms::Qwen3CoderToolParserImpl::State& state, fmt::format_context& ctx) const {
148-
// use unordered_map
149150
std::unordered_map<ovms::Qwen3CoderToolParserImpl::State, std::string> stateMap = {
150151
{ovms::Qwen3CoderToolParserImpl::State::Content, "Content"},
151152
{ovms::Qwen3CoderToolParserImpl::State::InsideToolCall, "InsideToolCall"},

0 commit comments

Comments
 (0)