@@ -269,13 +269,13 @@ static std::string setCorrectValueType(std::string& inputValue, const std::strin
269269}
270270
271271#define RETURN_NULL_IF_NOT_FOUND (POS ) \
272- if (POS == std::string::npos) { \
273- return std::nullopt ; \
272+ if (POS == std::string::npos) { \
273+ return std::nullopt ; \
274274 }
275275
276- #define LOG_AND_DEFINE_POS_AND_RETURN_NULL_IF_NOT_FOUND (STATE, TAG ) \
276+ #define LOG_AND_DEFINE_POS_AND_RETURN_NULL_IF_NOT_FOUND (STATE, TAG ) \
277277 SPDLOG_TRACE (" State: {}, current content:{} current pos:{}" , #STATE, streamContent, this ->lastStreamProcessedPosition); \
278- auto pos = streamContent.find(TAG, this ->lastStreamProcessedPosition); \
278+ auto pos = streamContent.find(TAG, this ->lastStreamProcessedPosition); \
279279 RETURN_NULL_IF_NOT_FOUND (pos)
280280
281281std::optional<ToolCalls> Parser::streamStep (const std::string& chunk) {
@@ -285,11 +285,11 @@ std::optional<ToolCalls> Parser::streamStep(const std::string& chunk) {
285285 this ->streamContent += chunk;
286286 switch (this ->currentState ) {
287287 case State::Content: {
288- LOG_AND_DEFINE_POS_AND_RETURN_NULL_IF_NOT_FOUND (Content, Qwen3CoderToolParser::toolsStartTag);
289- this ->lastStreamProcessedPosition = pos + Qwen3CoderToolParser::toolsStartTag.length ();
290- this ->currentState = State::InsideToolCall;
291- return std::nullopt ;
292- break ;
288+ LOG_AND_DEFINE_POS_AND_RETURN_NULL_IF_NOT_FOUND (Content, Qwen3CoderToolParser::toolsStartTag);
289+ this ->lastStreamProcessedPosition = pos + Qwen3CoderToolParser::toolsStartTag.length ();
290+ this ->currentState = State::InsideToolCall;
291+ return std::nullopt ;
292+ break ;
293293 }
294294 case State::InsideToolCall: {
295295 LOG_AND_DEFINE_POS_AND_RETURN_NULL_IF_NOT_FOUND (InsideToolCall, Qwen3CoderToolParser::toolPrefixTag);
@@ -341,7 +341,7 @@ std::optional<ToolCalls> Parser::streamStep(const std::string& chunk) {
341341 break ;
342342 }
343343 case State::AfterParameter: {
344- /*
344+ /*
345345 SPDLOG_TRACE("State: AfterParameter current content:{} current pos:{}", streamContent, this->lastStreamProcessedPosition);
346346 auto posToolEnd = streamContent.find(Qwen3CoderToolParser::toolEndTag, this->lastStreamProcessedPosition);
347347 auto posNewParameter = streamContent.find(Qwen3CoderToolParser::parameterPrefixTag, this->lastStreamProcessedPosition);
@@ -544,9 +544,11 @@ void Qwen3CoderToolParser::lazyFillInitToolParamatersTypsMap() {
544544}
545545
546546Qwen3CoderToolParser::Qwen3CoderToolParser (ov::genai::Tokenizer& tokenizer, const ToolsSchemas_t& toolSchemas) :
547- BaseOutputParser (tokenizer), toolSchemas(toolSchemas), streamParser(NULL_STRING_CONTENT, this ->toolsParametersTypes) {
548- SPDLOG_DEBUG (" Qwen3CoderToolParser created with {} tools" , toolsParametersTypes.size ());
549- }
547+ BaseOutputParser (tokenizer),
548+ toolSchemas (toolSchemas),
549+ streamParser (NULL_STRING_CONTENT, this ->toolsParametersTypes) {
550+ SPDLOG_DEBUG (" Qwen3CoderToolParser created with {} tools" , toolsParametersTypes.size ());
551+ }
550552
551553void Qwen3CoderToolParser::parse (ParsedOutput& parsedOutput, const std::vector<int64_t >& generatedTokens) {
552554 // there may be multiple parameters per function, there may be multiple linses per parameter value
@@ -589,7 +591,6 @@ void Qwen3CoderToolParser::parse(ParsedOutput& parsedOutput, const std::vector<i
589591// then we will send only one delta with all arguments
590592// we already have toJson functiont that turns all parameters into JSON string
591593
592-
593594static std::string documentToString (const rapidjson::Document& doc) {
594595 rapidjson::StringBuffer buffer;
595596 rapidjson::Writer<rapidjson::StringBuffer> writer (buffer);
@@ -630,60 +631,32 @@ std::optional<rapidjson::Document> Qwen3CoderToolParser::parseChunk(const std::s
630631 }
631632 if (toolCallsOpt.has_value ()) {
632633 // TODO we assume we could only get one by one
633- SPDLOG_ERROR (" Has value but not insideFunction" );
634- /*
635- Expected equality of these values:
636- docStr
637- Which is: "{\"arguments\":{\"delta\":{\"tool_calls\":[{\"\":0,\"function\":{\"arg1\":\"STRING_VALUE\"}}]}}}"
638- expected
639- Which is: "{\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":{\"arg1\":\"STRING_VALUE\"}}}]}}"
640- */
641- auto & toolCalls = toolCallsOpt.value ();
642- if (toolCalls.size () != 1 ) {
643- SPDLOG_WARN (" Expected one tool call, got: {}" , toolCalls.size ());
644- throw 42 ;
645- }
646- if (toolCalls.size () < 1 ) {
647- return std::nullopt ;
648- }
649- auto & toolCall = toolCalls[0 ];
650- rapidjson::Document argsDelta;
651- argsDelta.Parse (toolCall.arguments .c_str ());
652- this ->returnedCompleteDeltas .insert (this ->streamParser .toolCallIndex );
653- // we currently have this fail so we need to wrap argsDelta in the arguments fielda
654- /*
655- Expected equality of these values:
656- docStr
657- Which is: "{\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arg1\":\"STRING_VALUE\"}}]}}"
658- expected
659- Which is: "{\"delta\":{\"tool_calls\":[{\"index\":0,\"function\":{\"arguments\":{\"arg1\":\"STRING_VALUE\"}}}]}}"
660- */
661- rapidjson::Document argumentsWrapper;
634+ SPDLOG_ERROR (" Has value but not insideFunction" );
635+ auto & toolCalls = toolCallsOpt.value ();
636+ if (toolCalls.size () != 1 ) {
637+ SPDLOG_WARN (" Expected one tool call, got: {}" , toolCalls.size ());
638+ throw 42 ;
639+ }
640+ if (toolCalls.size () < 1 ) {
641+ return std::nullopt ;
642+ }
643+ auto & toolCall = toolCalls[0 ];
644+ rapidjson::Document argsDelta;
645+ argsDelta.Parse (toolCall.arguments .c_str ());
646+ this ->returnedCompleteDeltas .insert (this ->streamParser .toolCallIndex );
647+ rapidjson::Document argumentsWrapper;
662648 argumentsWrapper.SetObject ();
663649 rapidjson::Document::AllocatorType& allocator = argumentsWrapper.GetAllocator ();
664650 // now we need to add string toolCall.arguments to argumentsWrapper under "arguments" key
665651 rapidjson::Value toolCallsString (rapidjson::kStringType );
666652 toolCallsString.SetString (toolCall.arguments .c_str (), allocator);
667653 argumentsWrapper.AddMember (" arguments" , toolCallsString, allocator);
668654
669-
670- auto currentDelta = wrapDelta (argumentsWrapper, this ->streamParser .toolCallIndex );
671- // now we need wrap current delta in the required JSON structure
672- // {"arguments" : currentDelta}
673- /*
674- rapidjson::Document returnedDelta;
675- // create returned delta from scratch
676- returnedDelta.SetObject();
677- rapidjson::Document::AllocatorType& allocator = returnedDelta.GetAllocator();
678- returnedDelta.AddMember("arguments", currentDelta, allocator);
679- */
680- // return returnedDelta;
655+ auto currentDelta = wrapDelta (argumentsWrapper, this ->streamParser .toolCallIndex );
681656 SPDLOG_DEBUG (" First delta doc: {}" , documentToString (currentDelta));
682657 return currentDelta;
683658 }
684-
685659 if (parserState != streamParser.currentState ) {
686- // SPDLOG_DEBUG("Parser state changed from {} to {}", static_cast<int>(parserState), static_cast<int>(streamParser.currentState));
687660 SPDLOG_DEBUG (" Parser state changed from {} to {}" , parserState, this ->streamParser .currentState );
688661 }
689662 parserState = streamParser.currentState ;
0 commit comments