arizuko

arizuko › howto › Asymmetric channels

asymmetric channels

A folder can read messages from a channel and never reply there. The agent reads every message that arrives, and it replies only on the channel that you select. Use this when one source gives a lot of context, for example a busy WhatsApp group or a mailing list, and another channel holds the conversation.

The target fragment decides whether a message starts a turn

The target of a route can end with a #mode fragment. The fragment decides what routd does after it stores the message in the folder:

targeteffect
folderstore under folder and start a turn; the default
folder#observestore under folder and start no turn; the agent sees the message in the history at its next turn

One folder can have two routes with two effects. The ACL of the agent applies to the folder, so the agent can read every observed message. The mode only decides when routd starts the agent. It does not change what the agent can see.

Two routes to one folder make a channel read-only

Add two routes to the same folder, one in each mode:

seq  match                                          target
10   platform=<reply-platform> room=<your-room>     myfolder
20   platform=<ingest-platform> room=<src-room>    myfolder#observe
  1. Select the channel that answers. This is the channel where the user talks, for example a phone chat, a team Slack or a Telegram DM. Its route has no fragment.
  2. Select the channels that only give context. Give each one a route to the same folder with #observe.
  3. Put the answering route first. A lower seq comes first, and the first match wins. So a route for one chat must come before an observe route with a wider pattern.
  4. Change the context window if necessary. The answering turn adds the last OBSERVE_WINDOW_MESSAGES observed messages to the prompt, default 10, up to OBSERVE_WINDOW_CHARS characters, default 4000. For a busy source, increase the values for the instance, or for one route in the observe_window_messages and observe_window_chars fields of the route.

A mention-only channel uses the same two routes

One channel can answer only on a mention and observe the other messages. The first route matches the mentions, and the second route observes the rest of the same channel:

seq  match                                           target
10   chat_jid=slack:T012ABCD/channel/C0HJKL456 verb=mention  team
20   chat_jid=slack:T012ABCD/channel/C0HJKL456               team#observe

A reply to a bot message also has verb=mention, so a reply starts a turn too. After the agent replies, the thread is engaged, and the next messages in it start turns without a mention. Engagement explains the time window.

Telegram answers, and WhatsApp only gives context

seq  match                                           target
10   platform=telegram room=group/5229089286         rhias/nemo
20   platform=whatsapp room=120363012345678901@g.us  rhias/nemo#observe

The team talks on Telegram. The messages of the WhatsApp group go into the rhias/nemo folder as <observed> entries, and the agent never replies on WhatsApp. When a WhatsApp message is important, the agent posts to Telegram with a one-line source note.

The reality product uses this setup as a case study. This page gives the general recipe.

A rule in CLAUDE.md adds a second layer

The route mode is the enforcement: routd never starts a turn for an observed message. If you also want a rule that the agent itself reads, add it to the CLAUDE.md of the folder:

## Channels

Reply on Telegram only. Never call `send` with a WhatsApp chatJid.
Observed WhatsApp posts give context; the response goes on Telegram.

With the route mode in place, the rule changes nothing. It documents the intent.

Many observe routes can feed one folder

Many channels can feed one folder, and one channel answers:

The limit is on the folder, not on the channel. Any number of #observe routes can go to one folder. Each route is one more row in the table.

Four pages give the details

routing modes
All target fragments.
schema reference
The fields of a route, also the observe_window_* overrides.
OBSERVE_WINDOW_MESSAGES and OBSERVE_WINDOW_CHARS
The defaults for the instance.
reality product
The Nemo deployment.