SUVI · DeepSeek harness branch · read from the code, 11 Sep 2026

One message, start to finish

This follows one WhatsApp direct message from the moment it lands until the reply goes back. Stations are the steps. Amber signals are places the message waits in line. Branch lines show where memory is saved and where it is read. The red siding shows what happens when an answer comes back broken.

The message's path Step, no AI Step that calls the AI model Waits in a line Memory saved Memory read Retry path
01

Arrives

Every message
  • The signature is checked, which proves it really came from Meta, our WhatsApp gateway or Bifrost (groups).
  • The same delivery arriving twice is dropped.
  • Meta is told "got it" straight away; the work carries on in the background.
  • If there is a photo or file, it is downloaded first.

Other doors: Telegram works much like WhatsApp, but group messages there skip fact-saving. Web chat skips the per-chat line and goes through steps 04 and 06 onward.

LINE A

Per-chat line

One message at a time for each chat. The next message from the same chat does not start until this one's reply has been sent. Other chats run side by side. Each message gets 5 min. After that, the user gets "I got interrupted. Could you send that again?"

02

Sort

Every message
  • More duplicate checks: same message id, same text at the same time.
  • Which company? Found from the phone number or group, then that company's own database is opened. If nothing matches on a multi-company server, the message is refused.
  • Messages the owner typed on their own phone are stored, not answered.
  • Groups set to "listen only" store the message and stop here. So do "mention" groups, unless the bot is tagged or replied to.
03

Read the attachment

Only if a file is attachedUser waitsAI call for photos
  • Voice note: turned into text by Whisper (on the server, or the shared voice service).
  • Word, Excel, PowerPoint: the text inside is pulled out.
  • Photo: Qwen (vision) reads it to guess "bill, receipt or stock list?". Only that guess is added. The photo itself is handed to the model in step 07.
  • PDF, CSV, .txt, video: only the saved location is passed on. No text is pulled out.
  • Plain text messages skip this step completely.
04

Save for later

Memory savedUser waitsAI call
  • The message is saved to the database.
  • Fact-saving: for 40+ characters from someone the bot knows, Qwen looks for anything worth remembering. It runs in one background chat shared by the whole server (see line D).
  • Task check: if it sounds like work ("I fixed the bug") and they have open tasks, the AI picks which task it was.
  • Automations: if the owner has "when I send you X, do Y" rules, a yes/no question goes straight to OpenRouter (Qwen). A yes starts the automation in the background.

Nothing from this step is used in this reply. It only fills memory for later. In a direct message it runs before the block-list check (step 05). In groups it runs after the group rules.

05

Allowed to answer?

Every message
  • Direct message: blocked numbers are dropped silently. For a first-time stranger, the owner is asked "add or block?".
  • Group (checked before step 04): the group's rules decide "reply" or "store only". The bot stays quiet if no admin or owner is in the group.
06

Front desk

Every messageAI only for owner automations
  • Join-up (line B): waits 0.15 s, or 1.5 s in a burst, so rapid messages can be joined.
  • Greeting shortcut: "hi" or "thanks" from a known person, not in a group, gets an instant template reply, and the journey ends here. "yes" and "ok" never take this shortcut, because they may be confirming an action.
  • A note is prepared: who is speaking, their Google accounts, the time.
  • For owners, automation rules are checked again (up to 3), so the model does not repeat what an automation will show.
  • Some checks run in advance, such as "is Google connected?", with a 5 s cap each.
LINE C

Engine line

Only one message at a time goes into this chat's engine. Up to 20 can wait. When the line is full, the user gets "I've got too many things queued up right now."

07

Prepare this reply

Memory readEvery message
  • Role checked again: owner, admin, member or guest. Frozen users are refused.
  • Tool list for this role. If it is different from what the engine started with, the engine is restarted.
  • The person's profile note is added. In groups, the recent group chat is added too: the last 120 messages, up to 16,000 characters.
  • All of this is written as notes on top of the message.

Very short messages without question words, such as "yes", skip the memory lookup.

08

The engine

AI call, repeatedUser waits

Each chat has its own DeepSeek harness program. It sends everything to OpenRouter, which runs Qwen 3.8 27B with thinking set to "low". The model loops until it has an answer:

  • Our tools: each call comes in through a private, local-only door with a pass for this chat. The role is checked again, the company's own database is used, and the call is logged.
  • The engine's own tools: checked only by a safety gate. If anything goes wrong, the gate says no.
  • Limits: 80 tool uses per reply, then the engine is stopped. 30 min per reply. There is no way to stop midway except stopping the program.
09

Check the answer

Every replyMay retry

Three cases send the answer down the retry siding:

ErrorThe AI service reports a problem: too many requests, out of credit, service down, time-out, or connection dropped.
EmptyNo text and no tool used. For example, the model spent its whole budget thinking and wrote nothing.
Fake tool useThe model writes a tool call as plain text instead of running it. Nothing happened, but it would say "Done".
  1. Wait 2 s, try again
  2. Wait 4 s, try again
  3. Switch to the second API key
  4. Switch to backup model: Qwen 3.8 Flash
  5. Give up and send an error message
Wrong API key → second key only Conversation too long → summarise, restart, try once Unknown error → no retry

Checks on the wording: "saved to memory" when no memory tool ran is replaced with an honest sentence. "Sent" or "created" when no action tool ran is only logged, and the user still sees it.

10

Deliver

Every reply
  • WhatsApp: the reply goes out through the send queue. Files the reply mentions are sent as files. If the user sent a voice note and the reply is 500 characters or fewer, a voice reply is made.
  • Telegram: text only, in pieces of 4,096 characters.
  • Web chat: the reply streams in live.
END

Line A opens

This chat's next message can now start at step 02.

The four lines a message can wait in

Waiting in line is time the user sees, even though no work is happening on their message.

A

Per-chat line

WhatsApp · before step 02

The next message waits until the previous reply has gone out. Each message gets 5 min.

B

Join-up

Step 06

Rapid messages are joined into one. On web chat, messages sent while the bot is busy are joined too, held for up to 90 s. On WhatsApp, line A means this rarely happens.

C

Engine line

Between steps 06 and 07

One message at a time into the chat's engine. When the line is full, the user is told to try again later.

D

Shared fact-saving line

Step 04 · whole server

One background chat does fact-saving for every chat on the server. When it is busy, everyone's messages wait here before their reply can start.

What the model is given

Four layers, from the most lasting to the newest.

Set when the engine starts

Main instructions

The rule book: who it is, how to talk, honesty rules, stock and billing rules. Added to it: the time, the team list, always/never rules, a knowledge summary, memory notes, summaries of earlier sessions, and the last 48 hours of chat (up to 20,000 characters). Some of these parts are for owner-level chats only.

  • "Full" setup (default): only the first 35,000 characters of the 148 KB rule file are used, and the whole thing is cut at 80 KB.
  • "Skills" setup (the shared-server example): a smaller 67 KB rule file is used whole. Detailed topics are opened when needed. The cut is at 110 KB.
  • The engine refuses anything over 96 KB.
Set when the engine starts, changed by role

Tool list

Only the business tools this role may use, out of about 300. Plus the engine's own tools (shell, files, file search, web search) for everyone the gate allows.

Grows with every message

The conversation so far

Every message, reply and tool result in this chat, kept inside the engine program. It is not re-read from the database on each message.

New on every message

Notes + the message

Who is speaking and their role, 5 related facts, related people and things, their profile note, recent group chat (groups only), and the chat tag. Then what the user actually typed.

When the engine restarts, layer 3 is lost. This happens after 15 min idle, when a speaker's tool list differs, every 20–40 messages (the chat is summarised first), on a model switch, or on a stop. Only the database parts come back: the last 48 hours of chat and the summaries, inside layer 1.

Two different visits to memory

Step 04 writes and step 07 reads. They are not the same check done twice.

Saved · step 04

  • What: facts, decisions, events, opinions, how-tos, promises, always/never rules, preferences
  • When: messages of 40+ characters from someone the bot knows
  • Who does it: Qwen 3.8 27B through the same engine, in one background chat shared by the whole server
  • Used now? No. It helps future messages.
  • The model can also save during the reply, when the user asks it to remember something.

Read · step 07

  • What: 5 saved facts linked to this message, plus related people and things
  • Used now? Yes, as notes on top of the message.
  • The model can search more itself during step 08.
RoleCan read
OwnerEverything in the company
AdminTheir own, shared, and their members'
MemberTheir own and shared
GuestNothing

Problems found on the way

All found by reading the code, not by testing live.