Jail Stream
Overview
The JailedStream is a standalone implementation for handling “jail” detection in token streams. It provides a clean, builder-based API for accumulating tokens when certain sequences are detected, then releasing them as a single chunk when the jail ends.
Key Features
- Builder Pattern: Clean configuration API using the builder pattern
- Configurable Sequences: Support for multiple start/end jail sequences
- Tool Call Parsing: Integrated tool call detection and parsing
- Stream Macro: Uses
async-stream::stream!for clean async implementation - Standalone: Completely independent of existing code
- Annotations: Preserves annotations for observability
Implementation
Location
- Main implementation:
lib/llm/src/protocols/openai/chat_completions/jail.rs - Examples:
lib/llm/src/protocols/openai/chat_completions/jail_example.rs
Usage
Advanced Configuration
How It Works
- Detection: When a jail start sequence (or tool call start) is detected, the stream enters “jail” mode
- Accumulation: While jailed, tokens are accumulated in memory instead of being yielded
- Annotations: Empty chunks with annotations are sent downstream for observability
- Release: When a jail end sequence is detected OR the stream ends:
- Accumulated content is parsed for tool calls
- A single chunk with the parsed content is yielded
- Pass-through: Non-jailed content passes through unchanged
Testing
The implementation includes comprehensive tests:
test_jailed_stream_with_start_end_sequences: Tests explicit jail sequencestest_jailed_stream_with_tool_calls: Tests tool call detection and parsingtest_jailed_stream_no_jailing: Tests normal pass-through behavior
Run tests with:
Benefits
- Standalone: No modifications to existing code required
- Clean API: Builder pattern makes configuration intuitive
- Flexible: Supports multiple jail detection strategies
- Maintainable: Uses
stream!macro for cleaner async code - Testable: Comprehensive test suite with shared utilities
- Efficient: No unnecessary boxing or context handling in the library
- Composable: Can chain multiple stream transformers before re-adding context
Performance Optimizations
- No Boxing in Library: Returns
impl Streaminstead ofPin<Box<ResponseStream>> - Stack Pinning: Uses
tokio::pin!()instead ofBox::pin()for better performance - No Context Overhead: JailedStream doesn’t manage AsyncEngineContext
- Lazy Evaluation: Only processes what’s needed
- Efficient State Management: Minimal cloning, only when entering jail state
Integration Options
To replace the existing apply_tool_calling_jail_internal function:
Future Enhancements
- Add support for regex patterns for jail sequences
- Add metrics/telemetry for jail detection
- Support for partial sequence matching across chunk boundaries
- Configurable accumulation limits
- Support for nested jails