Feat/rust output length guard clean - #4104
Closed
msureshkumar88 wants to merge 29 commits into
Closed
Conversation
…d dicts Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Add a PyO3-based Rust implementation of the output length guard's core processing logic (truncation, word-boundary search, token estimation, binary search cut-point, recursive container traversal). The Python plugin auto-detects the Rust engine at init and delegates str, list, dict, and nested structure processing to it, falling back to Python when unavailable or for MCP content dicts that need structuredContent priority logic. - 47 Rust unit tests mirroring the Python test contract - 331 existing Python tests pass with Rust engine active - Clean clippy (-D warnings) and rustfmt Signed-off-by: Pratik Gandhi <gandhipratik203@gmail.com>
…h guard Benchmarks Python vs Rust across 7 scenario groups: single string truncation, token-mode binary search, word-boundary truncation, list processing, nested dict traversal, block-mode violation detection, and under-limit passthrough. Rust shows 3-10x speedup on container traversal (lists, nested dicts, passthrough) while single string truncation is FFI-bound. Signed-off-by: Pratik Gandhi <gandhipratik203@gmail.com>
…unting Three key optimizations that eliminate O(n) full-string scans: 1. count_chars_capped(): early-exit char counting that stops once the limit is exceeded, plus byte-length fast path for ASCII strings. Turns O(n) into O(min(n, limit)). 2. byte_offset_of_char() + direct slicing: replaces .chars().take(n).collect() with &value[..byte_offset] for zero-copy truncation. 3. PyString pre-check in process_container(): uses Python's O(1) str.__len__() to skip string extraction entirely for under-limit strings in truncate mode. Results: 1MB string truncation dropped from 31us to 2.4us (constant regardless of input size). Passthrough improved to 12x faster. Deep/wide nested structures remain 5-7x faster. Signed-off-by: Pratik Gandhi <gandhipratik203@gmail.com>
Replace extract::<String>() (full copy) with PyString::cast() + to_str() (zero-copy borrow) for the string leaf path. Also skip is_numeric_string() for strings > 50 bytes, and extend the O(1) pre-check to both truncate and block modes. Results vs previous commit: - Deep nested dict: 5.4x → 7.1x faster - Wide nested dict: 6.2x → 8.4x faster - List passthrough: 9.7x → 13.6x faster - Block mode 10KB: 4.5x → 5.0x faster - All 331 Python tests + 47 Rust tests pass Signed-off-by: Pratik Gandhi <gandhipratik203@gmail.com>
Two optimizations informed by the rate limiter PR (#3809) patterns: 1. Batch list processing: for all-string lists in truncate mode, extract all &str borrows in one pass, process in a tight Rust loop, build output PyList in a single pass. Better cache locality and avoids per-item path string formatting and interleaved append calls. 2. Pre-sized String::with_capacity(): eliminate reallocation during truncation by pre-computing body + ellipsis size. Results: - Short list passthrough: 13.6x → 18.9x faster - List 10x10KB: 2.6x → 3.0x faster - Deep nested dict: 7.1x → 7.0x faster (stable) - Wide nested dict: 8.4x → 8.5x faster (stable) - 331 Python tests + 47 Rust tests pass Signed-off-by: Pratik Gandhi <gandhipratik203@gmail.com>
…ings Shallow Nested Dict and fix testcases Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
Signed-off-by: Suresh Kumar Moharajan <suresh.kumar.m@ibm.com>
msureshkumar88
requested review from
crivetimihai and
kevalmahajan
as code owners
April 9, 2026 12:54
msureshkumar88
requested review from
dima-zakharov,
lucarlig and
madhav165
as code owners
April 9, 2026 12:54
Collaborator
|
should this be moved to https://github.com/IBM/cpex-plugins? altough we have no good testing CI yet there |
msureshkumar88
force-pushed
the
feat/rust-output-length-guard-clean
branch
from
April 9, 2026 14:02
02d7261 to
8ba4faf
Compare
Collaborator
|
@lucarlig @msureshkumar88 Please close here and move work to https://github.com/IBM/cpex-plugins . Let's introduce whatever CI with think is necessary as a part of this move. I'm switching to draft until we confirm the move. |
jonpspri
marked this pull request as draft
April 9, 2026 19:12
Collaborator
Author
|
closing this pr as it is a duplicate of #3926 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔗 Related Issue
Closes #
📝 Summary
Recreation of PR #3926 in a clean branch with updated configuration to match the Python version of the output_length_guard plugin.
This PR introduces a Rust-accelerated implementation of the output_length_guard plugin that provides significant performance improvements while maintaining full feature parity with the Python implementation.
Key Changes:
🏷️ Type of Change
🧪 Verification
make lintmake testmake coveragemake rust-checkpython test_rust_output_length_guard.pyTest Results:
✅ Checklist
make black isort pre-commit)cargo fmt,cargo clippy)📓 Notes
Performance Characteristics:
Configuration Alignment:
The plugin configuration has been updated to exactly match the Python version's behavior:
max_chars: Character limit enforcementstrategy: "truncate" or "block" modesword_boundary: Smart truncation at word boundariesmin_length: Minimum content length enforcementClean Branch Recreation:
This is a clean recreation of PR #3926 with all configuration issues resolved and comprehensive testing in place.