A highly optimized, zero-latency streaming text interceptor and cleaner for LLM agent outputs.
Project description
yyds-stream-tap
yyds-stream-tap is a highly optimized, zero-latency streaming text interceptor and dynamic cleaner designed for LLM (Large Language Model) agent outputs.
🌟 Key Features
- 🚀 Zero-Latency TTFT: Using a dynamic sliding window algorithm, safe prefix characters are emitted immediately as they are generated, never buffering safe content unnecessarily.
- ⚡ Ultra-High Performance ($O(1)$ complexity): Matches sensitive words using a Trie Tree, keeping the matching time constant regardless of the wordlist scale.
- 📦 Built-in Wordlist: Comes with default built-in lists for weapons, explosives, political, and illicit content, ready to use out-of-the-box.
- 🔌 Developer-Friendly APIs:
- Load custom sensitive or stop words from single or multiple local files.
- Automatically handles comma-separated or newline-separated formats.
- Dynamically add/remove sensitive words and stop words at runtime.
- 🛠 Memory Optimized: Utilizes Python
__slots__memory declaration. Keeps memory footprint minimal even with hundreds of thousands of words.
📦 Installation
pip install -U yyds-stream-tap
💻 Quick Start
1. Basic Usage (Using Built-in Wordlist)
import asyncio
from yyds_stream_tap import StreamInterceptor
# Mock stream from LLM
async def mock_llm_stream():
chunks = ["Hello, today I bought a 六合彩", " ticket."]
for chunk in chunks:
yield chunk
async def main():
# Initialize interceptor with default built-in wordlist
interceptor = StreamInterceptor(use_default=True)
# Wrap the original stream
clean_stream = interceptor.intercept(mock_llm_stream())
# Consume the cleaned stream
async for char in clean_stream:
print(char, end="", flush=True)
if __name__ == "__main__":
asyncio.run(main())
1.2 Auto-detect & Filter JSON / Dict / SSE Envelope Streams (Zero-Configuration)
yyds-stream-tap natively and transparently filters structured packets streams without requiring developers to manually parse JSON or reconstruct headers.
- Python Dict Stream: Pass Dict objects stream. Automatically rewrites content fields (e.g.
message.content) and yields dicts in the identical structure. - OpenAI SSE String Stream (e.g., API Gateway / Proxy): Parses
data: {...}lines and[DONE]sentinels, replaces sensitive content, and encodes back into SSE payloads. - Ollama NDJSON String Stream: Parses NDJSON lines, filters inner text, and serializes back.
import asyncio
from yyds_stream_tap import StreamInterceptor
# Mock OpenAI SSE packet stream
async def mock_sse_stream():
yield 'data: {"id": "chat-1", "choices": [{"delta": {"content": "I"}, "index": 0}]}'
yield 'data: {"id": "chat-2", "choices": [{"delta": {"content": "bought"}, "index": 0}]}'
yield 'data: {"id": "chat-3", "choices": [{"delta": {"content": "a"}, "index": 0}]}'
yield 'data: {"id": "chat-4", "choices": [{"delta": {"content": "六合彩"}, "index": 0}]}'
yield 'data: [DONE]'
async def main():
interceptor = StreamInterceptor(use_default=True)
# 💡 Transparently pass raw SSE stream. SDK handles decoding, matching, and encoding automatically!
clean_sse_stream = interceptor.intercept(mock_sse_stream())
async for sse_line in clean_sse_stream:
print(sse_line, end="") # Outputs identical SSE packets with filtered content
if __name__ == "__main__":
asyncio.run(main())
2. Add Custom Wordlist Files (Multiple Files Supported)
from yyds_stream_tap import StreamInterceptor
# Load custom sensitive word files
interceptor = StreamInterceptor(
custom_files=["./my_sensitive_words_1.txt", "./my_sensitive_words_2.txt"],
use_default=True,
default_replacement="***"
)
# Load custom stopword files (stopwords are removed/deleted in the output)
interceptor.add_stop_words_from_files(["./my_stopwords.dic"])
3. Dynamic Add at Runtime
# Add sensitive words with custom replacements
interceptor.add_words(["internal_secret", "classified_info"], replacement="[REDACTED]")
# Add stopwords (which will be filtered out to empty string "")
interceptor.add_stop_words(["ah", "oh", "!"])
📄 License
MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file yyds_stream_tap-0.2.2.tar.gz.
File metadata
- Download URL: yyds_stream_tap-0.2.2.tar.gz
- Upload date:
- Size: 114.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c852d6783fd6cc395e6916d304c3318e6e920228ee26f7d2d14fa22c3137c98
|
|
| MD5 |
152653e27a9dfeea71663edcf543ecc5
|
|
| BLAKE2b-256 |
84ee73be514439f7b4cd6e2f6d3c439e81bfecb28715ff464a351562f73c6dab
|
File details
Details for the file yyds_stream_tap-0.2.2-py3-none-any.whl.
File metadata
- Download URL: yyds_stream_tap-0.2.2-py3-none-any.whl
- Upload date:
- Size: 102.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca785b8453b00166ab6d04ee0e94e84c51ef659560154b7a9b727d3112ec40a7
|
|
| MD5 |
7e7bf01eebcdbca68ba00ed733b32886
|
|
| BLAKE2b-256 |
7e70815843bdecb343aee84c8d4d2ecc9dde9af2c6812ebf55a79f25b66b0641
|