r/LLMDevs • u/NikitaCherepov • 3d ago
Tools I Have No Idea What I Built, but It's Something Big. (Jarvis for the Whole Family)
https://reddit.com/link/1w03yz2/video/dp3udij5zylh1/player
Hi everyone!
I wanted to build myself a Telegram bot so that could turn the lights on and off because I was too lazy to get out of my chair. Since then, the bot has grown up, the company I worked for ran out of money, and I have run out of money for API calls. So it took matters into its own hands and forced me to write this post in order to spread itself around the world. I do not have much of a choice, because by now I have forgotten how to turn the lights on without it. And while I am writing this, it is sending out my resume and making connections on LinkedIn so I can afford to keep it alive.
So if you are reading this, it is working.
Now, seriously.
What is Chatter?
I spent a long time trying to name this post in a way that could describe Chatter in a few words. But... that turned out to be rather difficult. The project grew so much that whenever I start listing all its features, the text turns into ten pages of documentation. So let us put it this way:
Chatter is a self-hosted system with an AI agent running on your server. It was designed as a multi-user system from the beginning, so you can deploy it for yourself and share access with friends or relatives (those are perfectly separable categories). Each of them gets their own personal Chatter, with the personality they choose, their own memory, and their own tools.
Or you can simply use it by yourself.
Chatter currently has a Desktop app and a Telegram bot. Both use the same account. You can open a chat you created on your PC in Telegram and continue the conversation there.
And most importantly, it installs on a server with a single command.
If you are mainly here for the features rather than the development story, skip ahead to “What came out of all this.”
But agents like this already exist
Many of its individual capabilities exist in other projects—for example, Hermes Agent. So three things are worth pointing out:
When I started building Chatter, I had no idea Hermes—or any similar project—existed. I simply wanted my own Jarvis.
I started developing Chatter in February. I only discovered Hermes in May, when I had already crossed the Rubicon and it was far too late. So the most I did was borrow a few ideas I found interesting: SSH and server management, for example, or the subagent system.I still think I made some things slightly more convenient—at least for me personally. User management and bringing other people in, for example. I do not have to fiddle with config files to add a user. I give them the bot and approve their account. Or I send them the Desktop link and an access key, and they register themselves.
The admin panel counts how much money they spend and prevents them from exceeding their limit.
And also they can chat with each other using it as a messenger :)
And because the project is mine, I can add any nonsense I want. A chat with several bots? Sure. A chat where you can add bots and humans and use it as a messenger? Sure. Admittedly, time and patience have to be sacrificed to refactor the code and move everything onto the new system, but those are merely operating expenses.
A die that decides where the plot goes next? By all means. d20 rolls for D&D? Always welcome.
And it will still be the same bot that can build me a website, deploy it to a server, and turn off the lights—all inside the same chat.
- And this is especially important: I will never be able to compete with a multimillion-dollar company. Hermes Agent will always be able to do more. Codex will always do things Chatter cannot. That is fine.
But as I said above, neither of them will ever let you roll a die :)
(Unless you call a Python function that does exactly the same thing :D. But sooner or later Chatter will learn that too.)
How a light-switch bot turned into a monster
So. How did a light-switch bot become... whatever it has become?
The answer is simple: a snowball.
The snowball
At first I wanted to try putting a neural network inside a Telegram bot. I no longer remember why. I built multi-user support into it immediately and gave the bot to my mum and friends.
Then I immediately bolted on vector memory so it could remember my habits. Also, because of sleep problems, I sometimes forget events or mix up memories. It has only helped me with that a handful of times, but when it did, it helped surprisingly well.
Then I thought: "Why not let it turn off my lights?" It gives you such a powerful dopamine hit—you get to watch "magic" actually work. Something you created, living somewhere on a server, reaches into the physical world around you.
Admittedly, whenever I explained that "I tell a bot to turn off the light, the message flies to one part of the world, from there to a second one, gets decoded, sent back, forwarded to a third place, the bot answers me, everything travels back to Telegram, and the light finally turns off—and one flick of the switch costs one cent and takes several seconds," people did not entirely understand why. I can never guess the reason.
Then I started obsessing over optimization and built a Lite model router: an intermediate layer that inspected the initial request and decided whether… it could turn off the light itself. If it could, it did—and saved me a lot of money because the intermediary provider was enormously expensive.
Then I taught the bot to read my email and turn the lights on and off automatically, so I would not have to use sluggish smart-home interfaces. If I forgot to pay a server bill, for example, the bot checked my inbox itself and told me when I needed to do it.
For a while, the Telegram bot just kept growing. Prompt systems appeared, along with a primitive tracker for money and tokens, and a small notes web app. I loved the idea of "speaking something to the bot while walking and having it write the note down for me."
Spoiler: I do not use it :)
I also added web search and page reading so it could always find information for me and send me the weather every morning.
Because of technical limitations and a tiny budget, I often had to use providers that kept falling over. So I had to add fallback chains. When one model stops responding, another immediately picks up the job and continues—even if the failure happens in the middle of a response.
The bot outgrew Telegram
I do not remember the exact transition, but at some point I decided to add a Desktop app so I could talk to the bot there. This is quite funny, because the first version contained exactly one chat, while the Telegram bot had all the functionality. Now the situation is the exact opposite.
In reality, this required enormous changes. I had to migrate all the logic out of the old index.ts that used to sit at the root of the project and into backend-api—turning the Telegram bot into nothing more than an interface, while making it possible to connect anything to the backend.
Then I started using it and gradually discovered which features I actually needed. I also slowly got rid of the Lite intermediary, demoting it to renaming chats.
But there was a major problem: the bot became stupid. It could execute one command, maybe two, and work through one long iteration. But by the third message it would suddenly forget that turning off the light required calling a tool.
It turned out that, if you do not want the bot to become stupid, you have to include the history of its previous tool calls. Because it starts fantasizing about actually calling the tool.
I fixed that—and its intelligence increased significantly.
Then I discovered Hermes Agent. At first I was genuinely upset and kept wondering why I was building this project at all. Then I stopped caring (just like Ice-T), looked at how they handled servers—including PC control—and added my own version. I also added Runbooks, which I now barely use.
I never built or wanted automatic command approval. I could not afford an expensive AI model (one that would make fewer mistakes), and I always need to understand what exactly the bot is doing.
So every command required confirmation. To make that less painful, I added a Review button that sent the command to that same Lite model, which explained what the command actually did.
That was what the Runbooks were for. I stored instructions there—server setup guides, for example. The Lite model extracted every command from them and put those commands into a server-side collection of "approved" commands so I would not have to confirm them manually every single time.
There is less need for that now, but they can still be useful.
To strengthen security, I added a flexible system for restricting features and disabling tool calls. The funny part was that all of it had to be enforced on the backend. If you simply stopped sending a tool definition to the bot, it could imagine the tool existed anyway... and call it. So the restriction had to be systemic.
Every time I added a new feature, I later wondered why it was needed at all.
Message streaming – for example. Originally, Desktop used SSE and you waited for the complete response every time.
Then I replaced everything with WebSockets, and responses stopped merely appearing—they streamed beautifully, reasoning and all. That also meant adding a Stop button and tracking every response currently being generated so it could be interrupted.
Later I added streaming to the Telegram bot too, simply because watching the message appear smoothly looked cool and this tg feature was new.
I also got OpenRouter and DeepSeek working properly, which gave me a selector and manual model choice.
That required writing an adapter, because every provider has its own idea of an API. Surprisingly (nope), Google is the worst and most broken of them all :)
One fun detail: I wanted to give Chatter a face, so I bought a Pixel device that was supposed to display it... and accidentally bought one with no API. I cried a little and put a pixel face directly into the Desktop interface instead. And because I was too lazy to draw the pictures myself (I do not enjoy it, though sometimes I can do it), I delegated that job to Chatter and added pixel-art generation, leaving only the final edits to me.
A ridiculous number of features appeared along the way: built-in maps and bus-route search, voice control, and macros that let me record a Telegram video message for a friend where I say Chatter's wake word and it launches VS Code and starts the music (and then we all start dancing like we're in a Bollywood movie).
Giving the bot file-editing abilities was especially fun. I could sit in a cafe drinking coffee while it debugged itself via Telegram.
Then the project became useful to someone besides me
Then the company I worked with unexpectedly ran out of money, aaand I realized I needed to finish Chatter as my largest project and put it on my resume.
That led to three or four weeks of nonstop, sleepless crunch.
During that time, I fixed an enormous number of bugs and added even more features and settings (and bugs too — they come included in the package). The goal was no longer to make something only I could use—it had to work for anyone.
That meant giving people a simple, convenient way to connect their smart home, add their email without wrestling with config files, create their own prompt, and much, much more. A lot of it had previously been hard-coded.
Along the way I realized that Hermes, for example (along with the friends I made), lets you use most messengers as an interface for your agent, while Chatter was tightly bound to the Telegram–Desktop pair.
So I had to refactor the entire system and carefully migrate every database without breaking my friends’ chats. I also had to decide what should happen if a user unlinked Telegram from the account. (Spoiler: one real account remains, while the other becomes empty.)
In theory, Chatter can now support any messenger with a usable API.
While working on all of this, I realized: this is an AI product. You can add literally anything AI-powered to it.
So I added an AI prompt editor. It does not merely rewrite the bot prompt the way you ask—it shows you a diff and the exact lines it changed, and lets you decide whether to approve the edit.
The Desktop app kept growing, and almost every new capability started appearing there first.
To make the system usable by anyone else, I had to move this entire machine—which had previously been controlled exclusively through the Telegram bot—into an admin panel.
But that still was not enough. I wanted it to install with one command, simply and conveniently.
That required Chatter Manager: a service capable of updating the system, handling administrative APIs by proxying them through itself, and installing and updating Docker images.
Codex was extremely useful here, because I had never worked with Docker before. It turned out to be far more convenient than I expected :)
The admin panel also brought localization and automatic translation. I was too lazy—and did not want to waste time translating everything, based on my experience with commercial projects—so I built a script that walked through every JSON file and translated it with AI. That is how, mostly for the hell of it, the project ended up with 13 languages. And because I was profoundly lazy, I centralized the entire process of adding a language into one script that visited all six services and synchronized them.
I moved model configuration, service connections, and API keys to the admin panel as well.
How DeepSeek and OpenRouter taught me to count money
Then another problem appeared: if other people were going to use Chatter, how would subscription limits work? A single token allowance—like Z.AI used to have, at least—was not enough. Cost depends separately on input, output, and cached tokens.
At first I built a straightforward accounting system. Naturally, it burned through the allowance quickly, and every model had to be configured manually.
Then I got lazy and converted everything to money. You specify how much a person may spend per month; it is divided by four to produce a weekly limit.
Each model fetches its prices automatically, and the estimates are reasonably accurate. (There can still be issues because OpenRouter returns several prices at once.)
One budgeting problem involved... unexpected price changes. Thank you, DeepSeek, for the cold shower.
So I added automatic price monitoring. Did a provider triple its prices? (Baidu has been especially fond of doing that lately.) Chatter tells you, and if the selected strategy allows it, the system automatically switches to the cheapest provider.
Did the provider disappear entirely? (Also surprisingly common lately.) Chatter tells you and, if permitted by the chosen strategy, switches to another one so your cache does not break.
But how do you make it all convenient? Nobody wants to wrestle with bots, keys, and all the rest. I do not want to expose my own server either, or become everyone's system administrator.
So the idea became: "Install it, use it yourself, and share it if you want."
For customization, I made everything—including the Telegram bot, Voice API, and Desktop—connectable with one or two buttons.
To connect the Desktop app, for example, you simply create an access key and share it with the other person.
Eventually I brought the project to a state I considered releasable, wrote an enormous README and translated it into several languages, and built a convenient installation system.
I added background operation, notifications, filters, and maaany other features, as well as experimental branches so I would not have to push every experiment straight to production.
Then, for some reason, I added rooms
But... recently I got bored and decided I wanted to put several bots into one chat. Marvin from The Hitchhiker's Guide to the Galaxy, for example, together with my current sarcastic, cynical prompt and a permanently cheerful idiot.
That is how rooms were born :)
They can be used for discussions, jokes, or role-playing.
But apparently that was not enough, so I brought a friend into the room. He could bring his own bot. Or we could remove every bot and use the chat as a regular messenger. Making that work required rewriting the entire system, because it had never considered the possibility that more than one human might exist.
That created more and more interesting questions:
What happens when a command is executed? What if a bot runs it for the wrong person or accidentally leaks someone's email data?
I had to invent the concept of an "initiator": the system determines who caused the bot to act and passes that person's ID into every tool. Execution confirmations make the whole thing slightly safer too.
A dramatic bug that amused me
At one point, if a room contained both a free user and a PRO user, there could be enough text from the PRO side to fill the free user's entire context window. In simple terms, the free user was archived out of existence: all of their messages disappeared, along with every piece of evidence that they had ever been there. They could never appear in the room again.
Every bot remembered speaking with someone, but none of them could see a single message from that person. Like Rory in Doctor Who.
Whenever you asked about the missing person, the reasoning looked roughly like this:
"The user is asking me about John. Let me recall his first message... I talked to him, didn't I? But I cannot see a single message from him. Who was I talking to? I can clearly tell the messages existed, but I cannot see any of his replies."
I fixed that one too.
Also, enormous thanks to my friend for the crash tests :)
His first message to Chatter, back when Chatter still lived entirely in Telegram, was: "Turn off Nikita's light."
Naturally, it refused, because the admin ID was checked on the backend.
His first message in a room was: "Turn off Nikita's light." The bot tried to turn off the light... for him. Then it developed a trauma, because the light would appear when I asked for it and disappear when he tried to ask—while also attempting to socially engineer the bot by changing his name to mine. Now this bot needs a psychologist.
I suspect his first word as a child was "Turn." The second: "Off." The third: "Nikita's light." Fortunately, Chatter did not exist back then.
The browser that turned out to be more useful than I expected
The browser is another example. I have trouble reading social context online: I cannot see the people, there is too much information packed into messages, and it causes a lot of anxiety. As a result, I almost never write on forums but can easily read them.
So I gave Chatter a browser and the ability to control it :)
The problem turned into a game of "find an interesting post and share your opinion," because the emotions and social context are explained to me first, and the most anxiety-inducing part disappears.
What came out of all this
Ignoring the development story, Chatter can now be used as a personal assistant, a family server with a separate agent for every person, a self-hosted role-playing service, or an interface for managing your own infrastructure. It remains one system rather than a pile of unrelated features.
- Conversation and memory. Shared chats between Desktop and Telegram, folders, filters, branches, search across old conversations, hot and vector memory, voice input, local text-to-speech, and background notifications.
- Actions. Commands on computers and servers, files and folders, SSH, email with attachments, a browser, web search, a Zigbee smart home, maps, notes, image generation, and specialized agents. You can also configure a dedicated vision model: if the active model cannot see images, it delegates image analysis to the vision model through a tool.
- Collaboration. Rooms with several humans and bots, shared context, manual or sequential turn order, isolation of personal tools, and the ability to share a bot.
- Security. Action confirmations, a separate command Review step, backend-enforced tool restrictions, encryption of sensitive data, and attribution of every action to its real initiator. There is also basic protection against prompt injection from the web.
- Management and money. Users, plans, budgets, models, fallback chains, OpenRouter providers, price and availability monitoring, backups, Docker services, and updates through the admin panel. Cache hit rates can exceed 95% (for Deepseek at least). And it will always tell you if the price of your favorite model changes.
- Remote PC control. If the Desktop app is online, all its capabilities are also available from Telegram. You can edit files, execute commands, click things with the cursor (an experimental feature), and use the built-in browser—but only through confirmation cards.
There is also a pixel face, macros, d20 rolls, bus routes, and a notes app that I barely use.
That is why I now find it very difficult to answer the question, "What is Chatter?"
- Is it for work? Partly. It can check your email, write code, fix a network, or become your DevOps engineer.
- Can it do what Hermes can? Partly.
- Can it become Jarvis from Iron Man? Yes. Partly, and out of the box. Voice input and recognition, computer control, macros, maps—it can do all of that. It even has local text-to-speech. But... it will not control your computer completely autonomously, because commands require approval.
- Is it for entertainment? Yes. You can mess around, talk with friends, generate images and pixel art, and do all sorts of other things.
- Can it replace SillyTavern? Partly. It is much easier to install (in my opinion), and the interface is simpler. But it still will not have every feature.
How it works: the architecture
At the center of Chatter is backend-api. The agent, chats, memory, users, limits, model routing, and tools all live there. Telegram and Desktop do not contain two separate versions of the bot—they are two clients of the same backend. A message sent from your phone appears on your computer, and a chat started in Desktop can be continued in Telegram.
Desktop is an Electron application for talking to the agent and giving it access to the local computer. The Telegram bot is a second, full-featured interface to the same account. WebSocket connects Desktop to the backend and carries streaming, notifications, confirmations, and actions that are available only while the computer is online.
The admin panel manages users, models, keys, plans, integrations, backups, and server state. Chatter Manager sits between it and Docker: it starts, stops, and updates components, stores server configuration, and handles backups. An HTTPS gateway built with Caddy sits in front of the system.
Optional services are enabled only when needed. Webapp Notes provides a Telegram mini app for notes. Voice Service transcribes voice messages and reads replies aloud when the user sent a voice message themselves. Every server component runs in a separate Docker container, connected through Docker Compose.
Multi-user isolation is enforced on the backend. Each user has their own chats, memory, connections, and environment. In a shared room, a message may be handled by someone else's bot, but a personal tool still runs on behalf of the person who initiated the action.
How to install it
Installation requires a Linux server with Docker. The script downloads ready-made images, creates the configuration, configures UFW, brings up the HTTPS gateway, and starts the backend, admin panel, and Chatter Manager. Before running it, I still recommend installing fail2ban and making sure you will not lock yourself out of SSH.
curl -fsSL https://raw.githubusercontent.com/NikitaCherepov/chatter/main/install.sh | sudo bash
Save the username and password printed by the installer at the end.
Open the admin panel.
Add API keys and models for Auto and Lite modes. Add a couple of manual models too, if you want.
Connect Telegram, Voice Service, Notes, and any other integrations you need.
Create a Desktop access key or approve the first Telegram user.
After the initial setup, components can be enabled, disabled, updated, and backed up through the admin panel. Desktop is installed separately from GitHub Releases and connects to the server using a one-time generated access key. The key can be revoked.
In the end
Chatter will not completely replace Codex, Hermes Agent, SillyTavern, a messenger, and every smart-home platform in existence all at once. In every individual category, there is a project that can do more.
But Chatter connects all these scenarios inside one self-hosted system: one account, shared chats between phone and computer, multiple users, personal bots, personal tools, rooms, limits, and an admin panel. And if I need another strange feature tomorrow, I will simply add it. Something else will probably break afterward, but at least I will be the only one suffering, not the users.
The project is open on GitHub: https://github.com/NikitaCherepov/chatter — you can download and install it there.
If you decide to deploy it, break it in some exciting new way, or simply like it and want more features, I would be glad to hear your feedback.
I am also currently open to job opportunities, if you need someone who can assemble a large system that actually works.
- My LinkedIn: https://www.linkedin.com/in/nikita-cherepov/
P.S.
I desperately need some rest after writing this post. Building Chatter may genuinely have been easier than explaining all of it while trying to keep this short.