Avagenc Chat
2026 — A group chat where every other member is an AI agent
01 Problem
An AI assistant that plays music, reads email, and runs the smart home is usually one agent holding every tool, or several agents hidden behind a router. The router picks one agent, that agent answers, and whatever it saw is thrown away. When a request needs two of them, they pass each other a summary, and the person's own words are lost on the way.
The person never sees any of it. They talk to one voice, cannot tell which agent did what, and cannot ask a specialist directly.
02 Solution
Avagenc Chat is a group chat instead. Each person has exactly one thread, and they, Ava, and every specialist write into it and read from it. Ava listens and hands work on, to Zee for the Tuya smart home, Yori for Spotify, and Rafal for Gmail, Calendar, and Contacts.
So Ava never restates a request when she hands it on. Her whole turn is "@zee", and Zee reads the person's own words a few messages up. The thread is the only state there is, and a run is just the thread plus whatever woke it.
That puts the weight on the model, because every turn rereads a long thread the agent mostly did not write. Of the models tried, Gemini kept using that context better than the OpenAI, Qwen, and Kimi models, so it runs every agent.
The app is paused, so the video and screens here are the real web and iOS apps playing a scripted conversation, with the server's replies simulated on the device.
03 Who answers
A message with no mention goes to Ava. A message that mentions exactly one agent goes straight to that agent, so "@rafal any email today?" never passes through Ava. Mentioning two or more goes back to Ava, because work across specialists needs someone to order it.
Every turn records who triggered it, whether the human, Ava handing work on, or Postera waking Ava up. The same specialist answers a human who tagged it, but skips the greeting when Ava only passed the work on.
Silence is a valid answer. When a specialist has already replied in the thread, Ava's right turn is empty, and the server returns it as a success instead of an error.

if event.IsFinalResponse() {
var resp strings.Builder
if event.Content != nil {
for _, p := range event.Content.Parts {
resp.WriteString(p.Text)
}
}
apihttp.WriteJSON(w, http.StatusOK, struct {
Response string `json:"response"`
}{resp.String()})
return
}04 What it knows
Zep reads the thread and keeps a knowledge graph of the person on its own, made of people, objects, and preferences joined by facts that know when they became true. Nobody writes to the graph by hand.
In testing, a passing remark about a favourite food became a Preference node tied to the human and to Ava, and a message whose run failed still taught the graph a new hobby, because the graph learns from the thread, not from the reply.
The web app draws the whole graph, and resetting it is one action that forgets the chat and the knowledge together.

05 What it promised
Memory has a third kind that agent frameworks usually skip, which is remembering to do something later. Through Postera, Ava writes a message to her future self, a posterum, and Cloud Tasks delivers it back into the same thread at that moment.
Ava then speaks first. In a real thread, a reminder asked for at 11:39 came back on its own at 11:44.
She can also keep going. Told about picking up Nay at five, she sets a reminder for 4:30. When nobody answers it, she sets the next one for 4:45, then one for 5:00, then a last one for 5:10, and she cancels that last one once the human says they are on the way.
Nothing waits in memory meanwhile. The server scales to zero, so the process that scheduled a reminder is usually gone when it fires. The reminder lives in Postgres and the queue.
Ava, 09:15
Writes the posterum
"Remind the human to pick up Nay at 17:00"
Postarius
Saves it to Postgres
Enqueues it on Cloud Tasks
Cloud Tasks
Waits until 16:30
16:30
POST /ava/awaken
Hands the posterum back to Ava
Ava, 16:30
"it's 4:30, half an hour until you pick up Nay"
type Store interface {
Save(ctx context.Context, p Posterum) error
Get(ctx context.Context, id string) (Posterum, error)
Remove(ctx context.Context, id string) error
List(ctx context.Context, q Query) ([]Posterum, error)
}
type Queue interface {
Enqueue(ctx context.Context, p Posterum) error
Cancel(ctx context.Context, id string) error
}06 Paying per token
There is no subscription. Every run is charged to the person's rupiah wallet by the tokens it used, after it ends, because nobody knows the cost before.
The wallet is a double-entry ledger. Every charge is a set of postings that sum to zero, amounts are whole micro-rupiah, and a balance is never stored, only summed. A run that fails halfway is still charged for what it burned.

if _, err := b.ledger.Transact(context.WithoutCancel(ctx), wallet.Spec{
Type: TxAgentRun,
Metadata: metadata,
Postings: []wallet.Posting{
{AccountID: wallet.UserAccountID(userID, chargeCurrency), Amount: -micros},
{AccountID: wallet.RevenueAccountID(chargeCurrency), Amount: micros},
},
}); err != nil {
return fmt.Errorf("charge %s run: %w", run.Agent, err)
}07 Web and iOS
The web app is a SvelteKit single-page app and the iOS app is native SwiftUI, both signing in with Google through Firebase. The server derives the thread from the signed-in person, so the same conversation follows them from one device to the other.
Neither streams. A message waits for the whole run to finish while the client polls the thread, so a specialist's answer appears the moment it is written, before Ava's own turn returns.







08 System design
Both apps sign in with Google through Firebase Authentication and call one backend, the chat API. It is a single Go program on Cloud Run that runs Ava, Zee, Yori, and Rafal together on Google's Agent Development Kit, and it keeps nothing between requests, so it scales to zero when nobody is talking.
Every agent reads and writes the thread in Zep, which also builds the knowledge graph, and thinks with Gemini. The wallet and the reminders each have their own Neon Postgres, the tokens each person grants to Tuya, Google, and Spotify are kept in Firestore, and Cloud Tasks calls the API back when a reminder is due.
The API is written on open source Go libraries of mine. agentkit plugs each service into the Agent Development Kit and lets many agents share one Zep thread, postera schedules Ava's reminders, tuya, spotify, and gworkspace reach the smart home, the music, and Gmail, Calendar, and Contacts, and api reads who is calling and their time zone from every request.
09 Why it paused
Every integration works, and every one stops at the platform's gate before the public can use it. Spotify grants extended access only to organizations with 250,000 monthly users and plays music only for Premium accounts. Gmail's restricted scope needs a paid security assessment every year, and until then Google expires the sign-in after seven days. Tuya links a person's home only through a cloud partnership.
None of that is a code problem, so the app is paused with no plan to continue. In the development environment, Zee now tells the human that the Tuya IoT Core subscription has expired.
Avagenc Chat
Four agents share one thread on web and iOS, paused by what Spotify, Google, and Tuya require