Kotoba

Where to start

What Kotoba isWho she is and where she runs, in one page
InstallingOne package, two commands
First runA key, a model, her first words
The approval gateHow she asks before she acts
The two voice modesLocal voice, or the agent tunnel
The soul fileChange who she is
RoadmapWhat grows next, and what was cut on purpose

Or a section

↑↓ move openesc close124 pages
All pages

The web app11 of 12

Sessions and history

About 3 minutes to read

On this page

This page is mostly about what the browser does not keep. It is short on purpose.

A session is one page load

The browser mints a fresh session id when the companion mounts, and holds it for as long as the page is open (components/CompanionExperience.tsx:935). Reloading the tab, opening a second tab, or navigating away and back all produce a different session.

The id is a UUID v4. On an insecure origin — http://<lan-ip>:3000, which is one self-host away — crypto.randomUUID does not exist, so it is built from crypto.getRandomValues instead: the same entropy source and the same shape, with no fallback to Math.random (CompanionExperience.tsx:53-67).

Calling and hanging up does not change the session. You can leave a call and start another in the same page and she is still in the same conversation.

What survives a page reload, and what does not

ThingSurvives a reload?Where it lives
FilesYes~/.kotoba/files on disk
Report .html filesYesthe file library, under reports/
Memory topicsYesthe backend's store, listed in Settings → Memory
RemindersYesthe backend's store, listed in Settings → Reminders
Saved keys and standing command grantsYesthe backend
SettingsYes~/.kotoba/settings.yaml
The transcript on screenNothe page's own memory
The terminal rowsNothe page's own memory, and cleared on hang-up
The plan and the helper chibisNothe same
The live report the panel showsNoa process-level dictionary keyed by session
The conversation thread she is givenNothe backend keys turns by session id

That last row is the one that surprises people. Turns are written down — the backend stores every turn and reads recent ones back to build her context — but the read is scoped to the session id (api/src/kotoba/db/database.py:252-260). A new page load means a new session id, so the thread starts empty.

What carries across a reload is what she deliberately remembered, not what was said. That is the memory system, and it is a different mechanism with its own surface in Settings → Memory.

There is no history browser

The web app has no conversation list, no session picker and no way to reopen a past conversation. Nothing in app/, components/ or lib/ fetches a list of sessions or a past transcript.

The backend can list past conversations — list_sessions returns them newest first (api/src/kotoba/db/database.py:282-287) — and the terminal client has a /sessions listing built on it. No HTTP route exposes it and no browser code calls it.

Even in the terminal that listing does not reopen anything. It is a list of when each conversation started and how much is in it, and it says so: "these don't reopen — say what you're after and she'll go and find it in them" (api/src/kotoba/cli/slash.py:807-817).

What does get re-read

Not history, but worth knowing: when the events channel reconnects mid-call, the browser re-reads three pieces of live state so the screen matches the backend again — the microphone's mute flag, the current task list, and whether work is still running (CompanionExperience.tsx:311-350). The mute resync is skipped in local voice mode, where the browser owns the microphone (CompanionExperience.tsx:313). The work read is repair only: it may clear the working flag but never set it, because a REST read can be older than a live frame.

And when a call connects, the browser asks whether a background job finished while nothing was listening, so she can tell you about it rather than letting it pass unmentioned (CompanionExperience.tsx:385-394).

Signing out

Signing out ends the browser session and does a full page navigation, which discards the session id along with everything else in memory. It touches nothing on disk: her memory and her files are untouched, and the panel says so (components/panels/SettingsPanel.tsx:698-701).