Serial Monitor with multiple filters

I am looking into making some custom serial monitor filters for interpreting a binary protocol, and I am curious about how multiple filters are applied.
If there are more than one, do subsequent filters just take the direct output of the previous ones and reprocess that?

Is there a way for a filter to control what gets sent to the next filter separately from what gets printed to the console?
I’m thinking something like how Qt has events and event filters, which can accept/reject or pass along events further down the line.

Edit: I just realized all comments below were a result of a stupid mistake on my part; I didn’t prefix the filename with filter_ when I copied it into my monitor path. It turns out that is important :wink:

I’m also having trouble getting a second custom filter to be recognized at all. I have <Project>/monitor with one filter that is copied/modified from builtin hexlify source. That one works when I specify it for monitor_filter. But then I created a second file in that directory and copied filter_demo.py from the docs, and now specifying monitor_filter=demo gives me:

Warning! Skipping unknown filters `demo`. ...

Additionaly I can see the .pyc for my first filter in my monitor/__pycache__ folder, but it seems that the demo.py file is never even looked at.
Does it only look at a single python file in monitor_dir and ignore the rest as soon as it finds one? Or is there some way to explicitly tell PIO to compile that second file? Really confused here.

After some developing and testing I think I have a better grip on the situation.

This is how I currently understand it:

  1. The value returned by a filter’s rx (or tx) function gets sent passed along to subsequent filters.
  2. Whatever the last filter returns will automatically be printed to serial monitor
  3. BUT, a filter can also call python print directly, and omit data from its returned string. In this way it can choose what is forwarded to subsequent filters or not.