Repository navigation
Conversation
Accept straight and curly message delimiters while preserving quotes inside replies. Flush unmatched prefixes and completed buffered producers, and preserve chunk order during the single-call handoff. Keep streaming handoff markers outside output parsing and add FakeLLMModel regression coverage. Refs: NGR-1047 Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Retain pending suffixes through trailing whitespace until stream termination, preserving message content when text continues. Include the streaming refactor separating stop detection, emission, and bot-message configuration. Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
[Medium impact] The PR changes how generated replies are parsed and streamed across Guardrails entry points. Fix the message boundaries before merging so replies neither lose valid text nor include extra bot turns. FindingsFix with agent prompt### Issue 1
nemoguardrails/llm/completion_parsing.py:62-65
The new stops can cut off valid content at an inner curly quote. For example, `"The phrase is “helpful bot”\nbot software can assist."` now becomes `The phrase is “helpful bot`, losing the rest of the reply and its inner closing quote. The pre-scan ignores quote depth, and streaming uses the same stops. Check whether the quote closes the message before treating the following line as another turn, and add a test for this case.
### Issue 2
nemoguardrails/llm/completion_parsing.py:30-31
Replacing the single-call stop `"\n` with exact header matches misses dialogue separated by a blank line. If generation continues after handoff with ` "Hello!"\n\nbot unwanted\n "Wrong reply!"`, no stop matches. Streaming emits the first closing quote and the unwanted turn, stripping only the final quote. Non-streaming still stops after `Hello!`. Allow whitespace between the closing delimiter and the next header, and test this with chunks arriving after handoff.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.SummaryAdds curly quote support to generated replies and updates streaming completion handling.
|
| for stop in BOT_MESSAGE_STOP_SEQUENCES: | ||
| boundary = s.find(stop) | ||
| if boundary >= 0: | ||
| s = s[: boundary + 1] |
There was a problem hiding this comment.
Inner quotes cut replies short
The new stops can cut off valid content at an inner curly quote. For example, "The phrase is “helpful bot”\nbot software can assist." now becomes The phrase is “helpful bot, losing the rest of the reply and its inner closing quote. The pre-scan ignores quote depth, and streaming uses the same stops. Check whether the quote closes the message before treating the following line as another turn, and add a test for this case.
Prompt To Fix With AI
This is a comment left during a code review.
Path: nemoguardrails/llm/completion_parsing.py
Line: 62-65
Comment:
**Inner quotes cut replies short**
The new stops can cut off valid content at an inner curly quote. For example, `"The phrase is “helpful bot”\nbot software can assist."` now becomes `The phrase is “helpful bot`, losing the rest of the reply and its inner closing quote. The pre-scan ignores quote depth, and streaming uses the same stops. Check whether the quote closes the message before treating the following line as another turn, and add a test for this case.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| f"{quote}\n{header}" | ||
| for quote in ('"', "”") |
There was a problem hiding this comment.
Replacing the single-call stop "\n with exact header matches misses dialogue separated by a blank line. If generation continues after handoff with "Hello!"\n\nbot unwanted\n "Wrong reply!", no stop matches. Streaming emits the first closing quote and the unwanted turn, stripping only the final quote. Non-streaming still stops after Hello!. Allow whitespace between the closing delimiter and the next header, and test this with chunks arriving after handoff.
Prompt To Fix With AI
This is a comment left during a code review.
Path: nemoguardrails/llm/completion_parsing.py
Line: 30-31
Comment:
**Extra bot turns appear**
Replacing the single-call stop `"\n` with exact header matches misses dialogue separated by a blank line. If generation continues after handoff with ` "Hello!"\n\nbot unwanted\n "Wrong reply!"`, no stop matches. Streaming emits the first closing quote and the unwanted turn, stripping only the final quote. Non-streaming still stops after `Hello!`. Allow whitespace between the closing delimiter and the next header, and test this with chunks arriving after handoff.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Quote-aware completion parsing nemoguardrails/llm/completion_parsing.py, tests/llm/test_completion_parsing.py |
Parsing now recognizes straight and curly quote delimiters and quote-newline dialogue boundaries. Tests cover quote stripping, multiline extraction, and following dialogue. |
Streaming pattern and stop handling nemoguardrails/streaming.py, tests/test_streaming_handler.py |
StreamingHandler now supports alternative prefixes and suffixes, pattern-specific stops, partial matches, and trailing whitespace after suffixes. Tests cover stop precedence, buffering, metadata, and quote variants. |
Generation integration and handoff nemoguardrails/actions/llm/generation.py, tests/test_generation_equivalence.py, tests/test_llmrails_singlecall.py |
Generation configures streaming patterns and stop sequences. Single-call output is parsed before a registered handoff marker is appended. Tests cover generation modes and streaming handoff. |
Priority:
Estimated code review effort: 4 (Complex) | ~45 minutes
Change: Bug fix
Sequence Diagram(s)
sequenceDiagram
participant LLM
participant StreamingHandler
participant generate_bot_message
participant get_multiline_response
LLM->>StreamingHandler: Emit completion chunks
StreamingHandler->>generate_bot_message: Emit text through configured stop
generate_bot_message->>get_multiline_response: Parse single-call output
get_multiline_response->>generate_bot_message: Return extracted response
generate_bot_message->>StreamingHandler: Append registered handoff marker
Possibly related PRs
- NVIDIA-NeMo/Guardrails#2168: Introduces single-call generation helpers and streaming handoff paths that this change updates.
- NVIDIA-NeMo/Guardrails#2188: Refactors the single-call generation and streaming handoff paths used by this change.
Suggested labels: bug
Suggested reviewers: christinaexyou, tgasser-nv
Merge Risk: 
Minimal · up to a7655
-
No actionable issue was established in the quoted-message parsing or streaming changes. The PR is mergeable after normal checks.
Pre-merge checks: 
4 · 
2
-
Failed checks: 2 warnings Passed checks: 4 passedFull details: Docstring Coverage
-
Explanation
Docstring coverage is 38.24% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 34 functions across 7 files.
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
Full details: Test Results For Major Changes
-
Explanation
The PR contains major changes: it modifies streaming stop handling and the public
StreamingHandler.set_patternsignature, changes completion parsing, and adds 642 lines across seven files. The authored description only states the feature behavior and related issue; it contains no test command, test results, or testing information. Added test files in the diff are not documented test results.Resolution
Update the PR description with the testing performed and results, including the relevant test commands and whether they passed. Include performance or regression evidence only if applicable.
-
Finishing Touches
-
🧪 Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
Superseded by the smaller draft #2517.
Description
Accept straight and curly message delimiters in streaming and non-streaming replies. Preserve inner quotes and multiline content, strip closing delimiters before trailing whitespace, and flush buffered replies when generation ends without a prefix match.
Related Issue(s)
Resolves NGR-1047
Summary by CodeRabbit