.. code:: console
onechat daemon
- onechat chat
+ onechat
+
+``onechat`` with no command is the same as ``onechat chat``. ``onechat
+help`` lists the commands.
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
systemctl --user daemon-reload
systemctl --user enable --now onechat.service
systemctl --user status onechat.service
- ONECHAT_DIR=DATA_DIR ./result-service/bin/onechat chat
+ ONECHAT_DIR=DATA_DIR ./result-service/bin/onechat
journalctl --user -u onechat.service -f
After a pull, update the package and unit with:
"syscall"
)
+// usage is the help text of the command.
+const usage = `Usage: onechat [COMMAND]
+
+Commands:
+ chat talk to the agent in this terminal (default)
+ daemon run the agent, Telegram, and WhatsApp
+ login log in to ChatGPT with a device code
+ probe LOG COUNT [BUILDS] measure the compactor on a log, with real calls
+ help show this help
+
+Chat needs a running daemon. ONECHAT_DIR sets the data directory.
+`
+
func main() {
err := run()
if err != nil {
args := os.Args[1:]
switch {
- case len(args) == 0:
- _, err := fmt.Println("onechat")
+ case len(args) == 1 && (args[0] == "help" || args[0] == "--help" || args[0] == "-h"):
+ _, err := fmt.Print(usage)
if err != nil {
return err
}
// result does not include ctx.Err().
case len(args) == 1 && args[0] == "daemon":
return daemon(ctx, os.Stdout)
- case len(args) == 1 && args[0] == "chat":
+ case len(args) == 0 || len(args) == 1 && args[0] == "chat":
return terminal(ctx, os.Stdin, os.Stdout)
case len(args) > 0 && args[0] == "probe":
err := probe(ctx, args[1:], os.Stdout)
return err
}
default:
- return fmt.Errorf("unknown command %q", strings.Join(args, " "))
+ return fmt.Errorf("unknown command %q\n\n%s", strings.Join(args, " "), strings.TrimSuffix(usage, "\n"))
}
return ctx.Err()
doInstallCheck = true;
installCheckPhase = ''
runHook preInstallCheck
- test "$("$out/bin/onechat")" = onechat
+ [[ "$("$out/bin/onechat" help)" == "Usage: onechat "* ]]
runHook postInstallCheck
'';
// errTerminalDaemonClosed tells that the daemon closed the connection.
var errTerminalDaemonClosed = errors.New("the daemon closed the connection")
-// terminal runs "onechat chat": the terminal client of the daemon. Each line of
-// input is a user message, the line /stop interrupts the running turn, the line
-// /stop NAME stops the subagent NAME, and a line that starts with /whatsapp is
-// a WhatsApp command. The client shows the replies, the tool calls, and their
-// results as they happen. It ends at the end of the input or when the daemon
-// closes the connection.
+// terminal runs "onechat" and "onechat chat": the terminal client of the
+// daemon. Each line of input is a user message, the line /stop interrupts the
+// running turn, the line /stop NAME stops the subagent NAME, and a line that
+// starts with /whatsapp is a WhatsApp command. The client shows the replies,
+// the tool calls, and their results as they happen. It ends at the end of the
+// input or when the daemon closes the connection.
func terminal(ctx context.Context, in io.Reader, out io.Writer) error {
dir, err := dataDir()
if err != nil {