Skip to content

Conversation

@pavel-esir
Copy link
Contributor

Description

Return DeltaMessage in incremental TextStreamerParser instead of accumualated msg. But accumulated is still available via get_parsed_message()

CVS-CVS-176146

Fixes #(issue)

Checklist:

  • Tests have been updated or added to cover the new code.
  • This patch fully addresses the ticket.
  • I have made corresponding changes to the documentation. TODO

Copilot AI review requested due to automatic review settings November 17, 2025 11:58
@pavel-esir pavel-esir requested a review from apaniukov November 17, 2025 11:59
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the TextParserStreamer to return incremental delta messages in the write() callback instead of accumulated messages, while still maintaining accumulated message access via get_parsed_message(). The key changes update the reasoning parser implementation to properly handle delta messages and modify the concatenation logic in the streamer.

  • Modified TextParserStreamer to write delta messages instead of accumulated messages
  • Updated ReasoningIncrementalParser to populate message fields for incremental output
  • Added concatenate_json_containers() helper function for message accumulation

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
tests/python_tests/test_parsers.py Updated tests to use get_parsed_message() for assertions and removed manual message accumulation in custom streamers
src/cpp/src/text_streamer.cpp Added concatenate_json_containers() function and modified write() to return delta messages while maintaining internal accumulation
src/cpp/src/parsers.cpp Refactored ReasoningIncrementalParser to populate content field in delta messages and removed keep_original_content logic from helper methods

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 147 to 152
void concatenate_json_containers(JsonContainer& from, const JsonContainer& to, std::vector<std::string> keys_to_concatenate) {
for (const auto& key : keys_to_concatenate) {
if (to.contains(key) && from.contains(key)) {
// If both are strings, concatenate
if (to[key].is_string() && from[key].is_string()) {
to[key] = to[key].get_string() + from[key].get_string();
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameter order is reversed: from should be const and to should be mutable. Currently, modifications are applied to to (line 152) but the function signature suggests from is the destination. Either swap the parameter names or reverse their constness to match the intended behavior.

Copilot uses AI. Check for mistakes.
@pavel-esir pavel-esir force-pushed the write_chunks_during_parse branch from 9b7cd5c to a41f0d0 Compare November 21, 2025 12:08
Copilot AI review requested due to automatic review settings November 21, 2025 12:08
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (1)

tests/python_tests/test_parsers.py:1

  • Assignment to reason_str loses previously accumulated reasoning content. The variable should be appended to, not replaced, to preserve partial reasoning text from previous chunks.
# Copyright (C) 2023-2025 Intel Corporation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

# When parser is called from streamer, it is expected that content is accumulated inside streamer.
# Here we are calling parser manually therefore we need to accumulate content manually.
msg['content'] += subword
print(msg)
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug print statement should be removed before merging to production code.

Suggested change
print(msg)

Copilot uses AI. Check for mistakes.
return write(m_pimpl->m_parsed_message);

// std::cout << msg["content"].get_string() << std::endl;
// std::cout << msg["reasoning_content"].get_string() << std::endl;
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented-out debug statements should be removed before merging.

Suggested change
// std::cout << msg["reasoning_content"].get_string() << std::endl;

Copilot uses AI. Check for mistakes.
Comment on lines +28 to +33
// if (!message.contains("reasoning_content")) {
message["reasoning_content"] = "";
}
if (!message.contains("content")) {
// }
// if (!message.contains("content")) {
message["content"] = "";
}
// }
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented-out conditional checks should be removed. If unconditional initialization is the intended behavior, the comments add unnecessary clutter.

Copilot uses AI. Check for mistakes.

if (!m_keep_original_content) {
delta_text = std::string(txt_chunk.substr(close_idx + m_close_tag.size()));
// Despite the fact that we put txt_chung to delta_text it's correct.
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'txt_chung' to 'txt_chunk'.

Suggested change
// Despite the fact that we put txt_chung to delta_text it's correct.
// Despite the fact that we put txt_chunk to delta_text it's correct.

Copilot uses AI. Check for mistakes.
Comment on lines +194 to 195
delta_text.clear();
}
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] When think tag is not yet opened and accumulating in cache, delta_text is cleared. This means no delta content is returned to the user during this phase. Consider adding a comment explaining this behavior is intentional to avoid confusion.

Suggested change
delta_text.clear();
}
// Intentionally clear delta_text: no delta content is returned to the user during this phase
// (we are waiting for the <think> tag to be fully detected in the cache).
delta_text.clear();

Copilot uses AI. Check for mistakes.
@pavel-esir pavel-esir force-pushed the write_chunks_during_parse branch 2 times, most recently from d71fc3f to 4017fb5 Compare November 21, 2025 12:23
Copilot AI review requested due to automatic review settings November 21, 2025 12:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// Keep potential partial close tag in cache
m_text_cache = std::string(txt_chunk.substr(txt_chunk.size() - num_chars_to_keep));
reason_str.append(txt_chunk.substr(0, txt_chunk.size() - num_chars_to_keep));
reason_str = txt_chunk.substr(0, txt_chunk.size() - num_chars_to_keep);
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assignment instead of append changes semantics. Previously accumulated reasoning content in reason_str will be lost. This should use reason_str.append() or += to maintain accumulated content, or the accumulated content should be preserved through a different mechanism.

Copilot uses AI. Check for mistakes.
} else {
// No partial close tag, accumulate all text
reason_str.append(txt_chunk);
reason_str = txt_chunk;
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assignment instead of append discards previously accumulated reasoning content. This should use reason_str.append() or += to maintain accumulated content from previous calls.

Copilot uses AI. Check for mistakes.

};

void concatenate_json_containers(const JsonContainer& from, JsonContainer& to, std::vector<std::string> keys_to_concatenate) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to have it as the json container method.

/**
* @brief Ensure required fields exist in the message container.
*/
void ensure_message_fields(JsonContainer& message) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is either not needed or has to be renamed.

// Iterate over all parsers and apply them to the message
for (auto& parser: m_pimpl->m_parsers) {
message = parser->parse(m_pimpl->m_parsed_message, message, flushed_tokens);
message = parser->parse(msg, message, flushed_tokens);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated names: msg and message

reason_str = std::move(message["reasoning_content"].get_string());
}
std::string txt_chunk = m_text_cache + delta_text;
std::string reason_str = message.contains("reasoning_content") ? std::move(message["reasoning_content"].get_string()) : "";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::string reason_str = message.contains("reasoning_content") ? std::move(message["reasoning_content"].get_string()) : "";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants