5 OneChat is one AI agent in a single chat that never ends. A daemon owns
6 the agent and its memory, and you talk to it from a terminal client,
7 Telegram, and through your WhatsApp chats. It is in early development.
17 OneChat keeps all its data in one directory, with mode 0700. It uses
18 ``ONECHAT_DIR`` when it is set, else ``$XDG_DATA_HOME/onechat``, else
19 ``~/.local/share/onechat``. The development shell sets ``ONECHAT_DIR``
20 to ``.devenv/onechat`` in the checkout.
22 Optional settings go in ``config.json`` in the data directory:
27 "endpoint": "chatgpt",
28 "compactor": {"model": "gpt-6.1-sol", "effort": "high"}
31 ``endpoint`` is ``chatgpt`` (the ChatGPT subscription, the default) or
32 ``api`` (the OpenAI API, with ``OPENAI_API_KEY`` set). ``compactor`` is
33 the model and effort of the memory summaries.
42 Open the link on any device and enter the code. Device code login must
43 be allowed in the ChatGPT security settings. Do not share the login with
44 the Codex CLI: each program logs the other out.
49 #. Make a bot with BotFather and keep its token.
50 #. Find your numeric Telegram user ID.
51 #. Write both to ``telegram.json`` in the data directory, with mode
56 {"token": "123456:ABC-token-from-BotFather", "owner": 123456789}
58 Start the daemon and write to the bot in a private chat. It answers only
64 Link your WhatsApp account as a linked device from the terminal client
67 ``/whatsapp pair PHONE``
68 Gives a pairing code. On the phone, open Linked devices, Link a
69 device, Link with phone number instead, and enter the code.
72 Shows the link and the routes of chats to child agents.
77 The session file gives full access to the account. If it leaks, remove
78 the device in Linked devices on the phone.
83 Run the daemon as a systemd user service. Keep the ``result-service``
84 link, so that Nix keeps the package:
88 nix build --out-link result-service
89 systemctl --user link --force "$PWD/result-service/share/systemd/user/onechat.service"
90 systemctl --user edit onechat.service
92 In the editor, set the data directory, and the tools that the agent may
98 Environment="ONECHAT_DIR=DATA_DIR"
99 Environment="PATH=TOOLS_PATH"
101 Then start it, and let it run while you are logged out:
105 systemctl --user daemon-reload
106 systemctl --user enable --now onechat.service
107 loginctl enable-linger "$USER"
109 After a ``git pull``, ``bin/service-update`` builds and restarts it.
110 Never run two daemons on the same data.
117 onechat backup BACKUP_DIR/onechat.tar.gz
118 ONECHAT_DIR=EMPTY_DIR onechat restore BACKUP_DIR/onechat.tar.gz
120 A backup runs while the daemon runs. Restore needs a stopped daemon and
121 an empty directory. **An archive holds your logins, the bot token, and
122 the WhatsApp link**, so keep it private.
124 For a daily backup with the last 14 kept, save this script, with
125 ``BACKUP_DIR`` replaced by a private directory outside the data
134 onechat backup "onechat-$(date +%F).tar.gz"
135 ls -1 onechat-????-??-??.tar.gz | sort -r | tail -n +15 | xargs -r rm --
137 and run it from a ``Type=oneshot`` user service with the same
138 ``ONECHAT_DIR`` and an ``OnCalendar=daily`` timer.
148 ``onechat`` connects to the running daemon. Each line is a message, and
149 replies show with Markdown styles and tables. These lines are commands:
152 Interrupts the running turn.
155 Stops the subagent NAME.
157 ``/image PATH [caption]``
158 Sends a JPEG, PNG, or WebP image. Quote a path with spaces.
161 The WhatsApp commands above.
163 In Telegram, write as in the client, also with photos and image files.
164 ``onechat help`` lists all commands.
166 *********************
168 *********************
171 The agent remembers the whole chat as summaries that it can open
172 again, so it never starts over. ``agent/instructions.md`` holds your
173 lasting preferences. The agent can propose a change to it and makes
174 the change only after you agree.
177 The agent runs shell commands as you, in its working directory, with
181 For long tasks it starts subagents in the background, such as
182 ``GreenOtter``, and gets their reports as messages.
185 A child is a permanent agent for one area of your life, such as
186 ``House``, with its own memory. The root creates it, talks to it, and
187 hears from it only what needs you. Children never send WhatsApp
188 messages; they draft replies for you to approve.
191 The agent reads your chats in batches and wakes for a private message
192 or a mention of you. It finds chats and sends messages only when you
193 ask. It proposes to route a chat that is only about one area to the
194 child of that area, and sets the route after you agree.
197 Send a photo in Telegram, WhatsApp, or with ``/image`` to the agent.
198 Its memory keeps what the image shows, and it can look at an older
199 image again. Ask it to show an image or send one to a WhatsApp chat.
202 Ask for reminders and timed tasks, such as "every weekday at 8, tell
203 me what my groups talked about". Each run uses the quota, so runs are
204 at least 5 minutes apart.
207 Old WhatsApp chats can join the memory in date order. Stop the
208 daemon, export the chat as a ZIP, and run the plan before the import.
209 The import rebuilds the target's memory with model calls:
213 onechat import -n [--agent NAME] CHAT.zip
214 onechat import [--agent NAME] CHAT.zip
220 The daemon writes short events with ``key=value`` attributes to the user
221 journal, at three levels: info, warning for a failure that is retried or
222 loses nothing, and error for a failure that loses data or stops work.
226 journalctl --user -u onechat -f
227 journalctl --user -u onechat -p warning
233 Nix supplies the Go toolchain and all tools. Enter the development shell
234 with ``direnv allow`` or ``nix develop``. Then:
239 ./result/bin/onechat version
244 ``onechat version`` prints ``yyyy-mm-dd-gitshort`` for a Nix build and
245 ``dev`` for a direct Go build. ``bin/check`` runs the linters and a
246 short replay of a synthetic log, and ``nix flake check`` also runs the
247 full replay of 100,000 messages. ``onechat probe LOG COUNT`` measures
248 the memory summaries on a log with real model calls.