Routing rules
A routing rule (binding) has four fields: the first two say “which messages to match”, the last two say “what to do on a match”.match_value is an exact match (not a prefix, not a regex); only "*" is special and matches everything. When match_key points at a key in metadata, the matchable values are platform-defined: Feishu’s chat_type is group / p2p, Discord’s is guild / dm; see each platform’s page.
Session scope
session_scope decides how messages that hit the same rule are grouped into sessions. Messages in the same session share context.
Even when they resolve to the same agent,
per_chat and per_chat_user put messages into different sessions. So after you change the scope, later messages are regrouped under the new scheme. Different agents never share a session.
Match order
Rules are matched top to bottom, first match wins, the same way firewall rules or Nginxlocation blocks work. Put specific exceptions first and the catch-all last.
Saving a config runs three checks so that every message has a definite, unique destination:
A full example
Suppose you’ve deployed two agents: a general assistantfriday and a product expert product-expert. Let’s follow one real message and see which agent and session it lands in under different rules.
1
A message arrives
The bot is in a Feishu group called “Product Team” and receives a line from a member, Alice. The message looks roughly like this (only routing-relevant fields shown):
Inbound message
2
Rules decide where it goes
The same message, under different rules, goes to different agents and sessions. Each tab below is one configuration:
3
The catch-all rule
Every config must end with a catch-all rule (
match_value of "*") so that a message matching none of the earlier rules still has a definite destination. The last rule in all three examples above is exactly that:Catch-all rule
Further reading
Connect Feishu
Create a Feishu bot and let agents chat in Feishu.
Connect Discord
Create a Discord bot and let agents chat in Discord.