Validate model listener filter references before serving traffic#947
Merged
Conversation
146bf41 to
6a3948e
Compare
6a3948e to
fcc5f5d
Compare
fcc5f5d to
ee22001
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR closes a validation gap for model-listener filter chains by ensuring both input_filters and output_filters references are validated up-front, causing startup/config generation to fail fast (fail closed) when a referenced filter/agent ID is missing—before any traffic is served.
Changes:
- CLI config generation now validates listener-level
output_filtersthe same way asinput_filters. - Brightstaff startup now errors if a rendered config references missing filter IDs instead of silently dropping them.
- Added focused Brightstaff unit tests covering valid chains and missing input/output filter references.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
crates/brightstaff/src/main.rs |
Replaces silent filter-chain resolution with strict resolution that errors on missing IDs; adds unit tests. |
cli/planoai/config_generator.py |
Extends listener filter ID validation to include output_filters as well as input_filters. |
cli/test/test_config_generator.py |
Adds config-generator test cases for missing/valid output_filters references. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Collaborator
|
Thank you for the contribution! Will merge once CI is finished. |
Contributor
Author
Hi @Spherrrical - PR seems to be blocked by secret-backed e2e jobs. What's the recommendation? |
Spherrrical
approved these changes
May 19, 2026
Collaborator
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.
Summary
Fixes #945.
This makes model-listener filter references fail closed in both config generation and Brightstaff startup.
output_filtersare now validated the same way asinput_filters, and Brightstaff no longer silently drops missing filter IDs when resolving the runtime filter pipeline.This PR does not change runtime output-filter failure behavior. It only makes invalid filter references fail fast before traffic is served. Startup/config validation and runtime stream execution need different handling modes: a missing filter ID is a config bug, while an output filter service failing mid-stream is still handled by the existing log-and-pass-through behavior.
Why
Filter chains are part of Plano's guardrails path. If an
output_filtersID has a typo, config generation or startup should fail early with a clear error instead of allowing the response path to continue without the intended filter.This came up while working on a similar ingress/egress processing flow in SGLang: sgl-project/sglang#21154
Design Notes
plano_config.yamlpath before rendered config is produced.input_filtersreferences already fail during config generation; this makesoutput_filtersconsistent with that behavior.Changes
input_filtersandoutput_filtersagainst definedagents/filtersduring config generationoutput_filtersconfigs with a positive config-generator testLocal Testing
cd cli uv run pytest test/test_config_generator.pyResult locally: