]> git.giacomolli.uk - onechat/blobdiff - README.rst
Store the subagents and read them with zoom
[onechat] / README.rst
index fdcc0e0af17f1c70de0795242da868f4a67fe2e9..e386c67566cacb7e0267bd651ed662a59bc24e0e 100644 (file)
@@ -2,8 +2,9 @@
  OneChat
 #########
 
-OneChat is a Go program. It prints its name. It is in early development.
-Linux is supported.
+OneChat is one AI agent in a single chat that never ends. A daemon owns
+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
@@ -32,7 +33,7 @@ field is an error.
 
    {
      "endpoint": "chatgpt",
-     "compactor": {"model": "gpt-6-luna", "effort": "high"}
+     "compactor": {"model": "gpt-6.1-sol", "effort": "high"}
    }
 
 ``endpoint``
@@ -43,7 +44,7 @@ field is an error.
 
 ``compactor``
    The model and the reasoning effort of the summaries. The defaults are
-   ``gpt-6-luna`` and ``high``.
+   ``gpt-6.1-sol`` and ``high``.
 
 *******
  Login
@@ -63,6 +64,110 @@ before they expire. The file belongs to OneChat only. Do not share it
 with the Codex CLI, because each program rotates the refresh token and
 logs the other out.
 
+*******
+ Agent
+*******
+
+Start the daemon, and then the client in another terminal:
+
+.. code:: console
+
+   onechat daemon
+   onechat chat
+
+The daemon owns the root agent in ``agent/`` in the data directory and
+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.
+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.
+
+``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.
+
+.. code:: json
+
+   {
+     "name": "OneChat",
+     "id": "0123456789abcdef0123456789abcdef",
+     "model": "gpt-6.1-sol",
+     "effort": "medium",
+     "workdir": "/home/user"
+   }
+
+``workdir`` is an absolute path, and its default is the home directory.
+``agent/instructions.md`` holds the user's instructions: who they are,
+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
+*******
+
+``onechat probe LOG COUNT [BUILDS]`` measures the compactor on a log. It
+appends the first COUNT messages of LOG, one JSON object ``{"kind",
+"text"}`` on each line, to a new chat in ``probe/`` in the data
+directory, and builds its tree with real model calls. The calls use the
+quota of the account. The run stops at the first failed call, after 660
+calls, or when the used percent of a quota window grows by more than 15
+points. At the end it reports the calls per message, the cached share of
+the input tokens, the retries, the line sizes, and the quota at the
+first and the last call. BUILDS, from 1 to 8, limits the model calls at
+once in the run.
+
+A test writes a generated log of readable made-up messages:
+
+.. code:: console
+
+   ONECHAT_PROBE_LOG=probe.jsonl go test -run TestProbeLogHasTheSyntheticMix
+
 *************
  Development
 *************
@@ -98,3 +203,6 @@ Format and check all files:
    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.