]> git.giacomolli.uk - onechat/blobdiff - README.rst
Send messages to subagents with tell
[onechat] / README.rst
index c0c6c5d2b16a6457a56a6716229ceb37b8ecd989..3819e25bea5188c4a229be908f85415aec4b1508 100644 (file)
@@ -3,8 +3,8 @@
 #########
 
 OneChat is one AI agent in a single chat that never ends. A daemon owns
 #########
 
 OneChat is one AI agent in a single chat that never ends. A daemon owns
-the agent and its files, and a terminal client talks to it. It is in
-early development. Linux is supported.
+the agent and its files, and a terminal client and a Telegram bot talk
+to it. It is in early development. Linux is supported.
 
 ****************
  Data directory
 
 ****************
  Data directory
@@ -80,13 +80,27 @@ listens on the Unix socket ``onechat.sock`` there. In the client, each
 line is a message to the agent, the line ``/stop`` interrupts the
 running turn, and Ctrl-D ends the client. The client shows the replies,
 the tool calls, and the first lines of each tool result as they happen.
 line is a message to the agent, the line ``/stop`` interrupts the
 running turn, and Ctrl-D ends the client. The client shows the replies,
 the tool calls, and the first lines of each tool result as they happen.
-The daemon is the only process that uses the token file while it runs,
-so ``onechat login`` and ``onechat probe`` refuse to start until it
-stops.
+It also shows each message that the user sends from another client, with
+the client as a mark, such as ``[telegram] text``. The daemon is the
+only process that uses the token file while it runs, so ``onechat
+login`` and ``onechat probe`` refuse to start until it stops.
 
 The agent runs commands with bash as the user in its working directory,
 with no sandbox. It has the rights of the user, also on the token file.
 
 
 The agent runs commands with bash as the user in its working directory,
 with no sandbox. It has the rights of the user, also on the token file.
 
+When the user asks for it, the agent starts subagents for long tasks.
+Each subagent has a name, such as ``GreenOtter``, and runs in the
+background while the agent answers other messages. It gets the view of
+the agent and its task, and it runs its tools as the agent does, in
+``agent/subagents/NAME/work``. A task in a repository gives the path of
+the repository. The steps of a subagent go to its own log in
+``agent/subagents/NAME``, not to the chat, and its final reply comes
+back to the agent as one message that starts with ``[NAME]``. The agent
+can send a subagent more messages: a running subagent reads them between
+its tool calls, and a finished one goes on from its log, and its reply
+comes back in the same way. Each model call of a subagent has the name
+in the ``agent`` field of ``agent/usage.jsonl``.
+
 ``agent/config.json`` holds the settings of the agent. The first start
 writes it with the defaults and a random ID. Do not change the ID: the
 prompt cache key comes from it.
 ``agent/config.json`` holds the settings of the agent. The first start
 writes it with the defaults and a random ID. Do not change the ID: the
 prompt cache key comes from it.
@@ -106,6 +120,46 @@ prompt cache key comes from it.
 how their files are organized, and how they want work done. The prompt
 ends with them, and a change applies at the next call.
 
 how their files are organized, and how they want work done. The prompt
 ends with them, and a change applies at the next call.
 
+**********
+ Telegram
+**********
+
+The daemon also connects the agent to a Telegram bot when
+``telegram.json`` exists in the data directory. It polls the Bot API for
+new messages, so it needs no open port.
+
+#. Make a bot with BotFather and keep its token.
+
+#. Find your numeric Telegram user ID.
+
+#. Write the token and the ID to ``telegram.json``, and give the file
+   mode 0600, because the token is a secret. The daemon refuses the file
+   with any other mode.
+
+#. Start the daemon, open a private chat with the bot, and write.
+
+.. code:: json
+
+   {"token": "123456:ABC-token-from-BotFather", "owner": 123456789}
+
+The bot reads only the private chat of the owner and ignores all other
+updates. Each text message goes to the agent as a user message, and the
+line ``/stop`` interrupts the running turn. The bot sends the replies in
+parts of at most 4096 characters, with their Markdown as Telegram
+formats: bold, italic, strikethrough, code, code blocks, links, and
+headings as bold text. When Telegram refuses the formats of a part, the
+bot sends the part again as plain text. Each error goes as a short
+message in plain text. It shows the typing action while a turn runs. It
+does not send the tool calls. It sends each message that the user types
+in the terminal client, with the mark ``[terminal]``.
+
+``agent/telegram-offset.json`` holds the ID of the next update. The bot
+moves it past an update only after the message is durable in the log, so
+a restart of the daemon does not lose a message. A crash just after the
+write of a message can make the message repeat once. A network failure
+or a rate limit makes the bot wait and try again, and does not stop the
+daemon.
+
 *******
  Probe
 *******
 *******
  Probe
 *******
@@ -162,3 +216,6 @@ Format and check all files:
    bin/format
    bin/check
    nix flake check
    bin/format
    bin/check
    nix flake check
+
+``bin/check`` and ``nix build`` run a short replay of the synthetic log.
+``nix flake check`` also runs the full replay of 100,000 messages.