← Otto Developer Guideotto-agents-kit

User guide: Ask and Agents
Specs: Launcher, Dictation, Preview

components/otto-agents-kit/ holds what Otto’s agent interfaces have in common: the feed of otto-agents sessions and the rows that show them, the keys that walk a list and edit its field, the Ask chat, and the log the chat is drawn in. It is a library in the kit layer of architecture.toml. It has no process of its own: it runs inside each host, which keeps its own window and field and talks to the service through the kit. The hosts are otto-launcher (Ask and agents mode), otto-canvas (the side canvas’s session list) and otto-preview (Studio’s chat beside a document).

otto-agents-kit inside a host process: chat, log and session feed on a connection thread that wakes the host’s loop

Modules

ModuleWhat it does
linkLink, the connection thread. A host’s loop is not async, so Link runs the AHP client on a thread with its own current-thread tokio runtime, sends updates over a channel and wakes the loop through a socket the loop polls (Link::poll_fd)
sessionsSessionFeed, which lists the agents and sessions and lists them again whenever the service announces a change, until it is dropped; and session_items, which turns sessions into rows (title, agent, activity, folder)
openerWhere a picked session opens: in Ask, or in Studio beside the file named by otto.app and otto.subject in the session’s _meta
chatAsk, the conversation: queueing requests on a session’s chat, attachments and stashed items, permission requests, the agent’s questions (chat::input), modes, and handing a session to its terminal
logThe chat’s log: laid out at the host’s width (layout), painted a band at a time (paint::LogPainter), selectable (selection), and kept between events by view::ChatView, a ScrollContent the host puts in its own scroll pane
keysThe keys a field over a list answers to: list_step, wrap, edit_field, copy_to_clipboard. Each host checks its own keys (Enter, Escape) first
dictationCtrl+D dictation into a host’s field. Built only with the dictation feature

item and rows are re-exports of otto_kit::components::item_list, which the settings sidebar search uses too.

How a host uses it

The host owns its window, its TextInput field and its main loop. It starts a SessionFeed or an Ask (each with a Link inside), adds their poll_fd to the file descriptors its loop waits on, and takes the updates when the loop wakes. The kit never draws into a scene: the rows and the log paint onto a Skia canvas the host hands them, so the same code paints into the launcher’s card, a canvas item and a plain otto-kit window.

HostWhat it takes
otto-launcherchat (whose Ask also lists the sessions for agents mode and picks their opener), log, keys, dictation, rows
otto-canvassessions, keys, opener, rows; it holds the feed only while the canvas is shown
otto-previewchat, log, keys, dictation; it creates its sessions with otto.app and otto.subject in their _meta

Ask queues each request on the session’s chat rather than starting a turn, so a host can close at any moment: the service already owns the request. Agents walks through that flow.

Dependencies

Going deeper