Memory & Sessions
Global Agent Identity
A single .agent/IDENTITY.md file defines the agent's persona, tone, and base
posture for every project and conversation -- it is the first block of the system
prompt.
- Edit it to rebrand the assistant.
- Delete it and the runtime regenerates a sensible default on next start.
- No environment variable, fixed path; read-only hosts (containers) fall back to the built-in default instead of failing to boot.
User Preference Memory
The agent keeps a small, durable profile of how you like to be helped
(preferences, communication style, expectations, workflow habits) in a single
.agent/USER.md file, rendered into the system prompt right after the Identity.
- The agent maintains the file itself during chats via an inline memory tool (add / replace / remove / consolidate). It reconciles rather than just appends: a newer explicit preference supersedes a conflicting older one, so mutually exclusive preferences (like your default answer language) stay a single line instead of piling up.
- A deterministic filter blocks secrets and sensitive personal data from ever
being stored, and the file is kept small (
USER_CHAR_LIMIT, default 1375). - Each session reads a frozen snapshot taken at session start, so prompts stay cache-stable and consistent across reloads; anything learned mid-session takes effect from your next session.
On by default; set USER_PROFILE_ENABLED=false to turn it off. Fixed path;
read-only hosts fall back to a built-in default.
Temporary Chat never reads or writes this profile, so throwaway conversations do not shape personalization.
Background reconciliation (optional)
Let the memory maintain itself. When enabled, a background pass periodically distills your recent conversation and reconciles the whole profile -- merging duplicates, resolving contradictions, dropping reversed or outdated preferences, and integrating new ones -- so it never drifts into a pile of conflicting lines.
USER_MEMORY_EXTRACTION=true # default: false (off, byte-for-byte prior behavior)
USER_MEMORY_EXTRACTION_EVERY_N_TURNS=4 # run at most once every N new user turns
The extraction model is assigned in the Model Offering Catalog under Model
Settings -> Task model assignments (the roles.user_memory_extraction binding, or
chatwalaau models role set user_memory_extraction <offering-id>). Leave it unset to use
the chat's own model. The dedicated USER_MEMORY_EXTRACTION_MODEL variable was removed
in v0.109.0.
- Requires
USER_PROFILE_ENABLED=true. Runs in the background and never blocks or delays your message. - Uses the same safety as the inline tool (secret/PII filter, size cap, and a backup of the previous file); an empty or unchanged result never wipes or needlessly rewrites your memory.
- Temporary Chat and demo mode never trigger it. Changes take effect from your next session (the running session keeps its frozen snapshot).
Agent Memory
Alongside the user-preference memory ("about you"), the agent keeps a second
curated memory about the work in a single .agent/MEMORY.md file: durable,
reusable facts about your environment and project -- conventions ("this project uses
pnpm"), commands ("run tests with uv run pytest"), tool quirks, and stable
operating rules. It is rendered into the system prompt as an <agent-memory> block,
right after the user profile.
It is stored as a list of independent entries (not one long note), which keeps it easy to de-duplicate, reconcile, and edit one fact at a time.
There are two ways it gets filled:
- The assistant notes things itself. During a chat it can record a durable fact
via an inline
manage_memorytool (add / remove / modify a single entry / batch). - You give a turn a thumbs-up. A "remember this turn" like sits on every message (user and assistant); clicking it runs a lightweight background pass that distills that turn into the memory. The like shows a live saving / saved / failed status and is saved with the chat, so it stays filled when you reload. Liking either message of a turn processes the pair as one set.
Every write shares the same safety as the user memory -- a deterministic filter
blocks secrets and sensitive data, the file is capped (MEMORY_CHAR_LIMIT, default
2200), and the previous file is backed up first -- plus a hardened write (exact
duplicates are rejected; writes are atomic and lock-guarded).
AGENT_MEMORY_ENABLED=true # default: true (matches USER_PROFILE_ENABLED)
MEMORY_CHAR_LIMIT=2200 # cap on the curated memory body
The curation model is assigned in the Model Offering Catalog under Model Settings ->
Task model assignments (roles.agent_memory_curation); leave it unset to use the chat's
own model. The dedicated AGENT_MEMORY_CURATION_MODEL variable was removed in v0.109.0.
On by default, but a fresh MEMORY.md is empty and adds nothing to the prompt,
so a new install is unchanged until something is actually remembered. Changes take
effect from your next session (the running session keeps its frozen snapshot).
Temporary Chat and demo mode never trigger curation. Set AGENT_MEMORY_ENABLED=false
to turn the whole feature off.
This memory is about the work; your personal preferences live in the separate
User Preference Memory (.agent/USER.md). The like never
writes to your preference memory.
Editing your memory files
Open the Agent Memory panel from the brain icon in the sidebar footer to view and edit all three built-in memory files yourself:
- Identity (
.agent/IDENTITY.md) -- the assistant's persona and tone - Preferences (
.agent/USER.md) -- what it remembers about you - Notes (
.agent/MEMORY.md) -- its own notes about your project
Each file opens in a Markdown editor with syntax highlighting and a live character-count against its limit. Saving writes a timestamped backup first, so a previous version is always recoverable, and closing with unsaved edits asks for confirmation. Edits apply from your next chat (the identity applies on the next restart) -- the running conversation keeps its frozen snapshot.
This editor is for you, the operator: your edits are saved as written (only a size limit is enforced -- the secret/PII filter that guards the assistant's own writes is not applied to your direct edits). Access is protected by the same sign-in as the rest of the app.
Session management
Conversations are saved as JSON files on your machine. You can save, search, organize into folders, pin, archive, fork, and rename them.
The chat sidebar
- The Folders and Chats sections each collapse from their header, so you can fold one away and give the other the whole panel. Both start expanded, and the choice is remembered per device.
- Rows are compact. At rest a row shows only its title; hover it to see when it
was last updated and its message / image counts. (The row does not change height when you
hover, so the list never shifts under your cursor. The chat you currently have open keeps
that line visible.) The
APIandTeamsbadges stay visible at all times -- they tell you the conversation did not come from the web UI. - Times are shown as
YYYY/MM/DD HH:mmin 24-hour form, the same on every machine regardless of the browser's language. - The chat list loads as you scroll rather than all at once, so the sidebar stays responsive with hundreds of conversations; skeleton rows show where the incoming chats will land. A folder's chats are loaded when you open it.
- Pinned chats always come first, then the most recently updated. That ordering
now comes from the server, so it is the same in the web UI and in
chatwalaau sessions list.
The server keeps a small index of chat metadata (.sessions/index.json) so listing
your chats does not have to open and re-read every conversation file. It is a cache:
deleting it is always safe -- the next listing simply rebuilds it.
Sidebar folders
- Assign a color from a preset palette (on create, or later via the folder menu)
- Reorder folders by drag-and-drop
- Folders are collapsed by default, with open/closed state remembered per device
- The folder list self-heals if its saved color/order values are ever corrupted
Export & import
Move a single chat between instances (or back it up / share it) as one self-contained file.
- Export -- open a chat's 3-dot menu and choose Export. The chat downloads
as a
.zipbundle that contains the conversation and every image it references, so it stays intact when re-imported on another machine. - Import -- click the upload icon in the
Chatssidebar section and pick a bundle. A spinner shows while it uploads; the new chat then appears in the list and is selected.
Import is safe by design: it always creates a new chat (never overwrites an
existing one), validates the file before saving anything, and drops the
exporter's personalization -- an imported chat lands unfiled, unpinned, and
de-personalized (your user-preference memory is never carried in the bundle).
SESSION_IMPORT_MAX_BYTES (default 25 MiB) caps the accepted upload size.
Auto chat titles (optional)
Set SESSION_TITLE_MODE=llm and a new chat is named by a short LLM summary of your
opening exchange instead of the first message's leading text.
SESSION_TITLE_MODE=llm # default: truncate (previous behavior, byte-for-byte)
The title model is assigned in the Model Offering Catalog under Model Settings ->
Task model assignments (roles.session_title, or chatwalaau models role set session_title <offering-id>); leave it unset to use the chat's own model. The dedicated
SESSION_TITLE_MODEL variable was removed in v0.109.0.
- The chat appears in the sidebar the instant you send (with a spinner while the title generates) and updates in real time when ready -- pushed over a WebSocket, no reload.
- Generation runs in the background and never blocks or delays your message; on any failure the simple truncated title remains.
- The spinner always resolves -- if the first reply errors, is stopped, or produces no text, the sidebar clears the pending state (keeping the simple title) instead of spinning forever.
- The WebSocket push is the primary way titles refresh, so an open chat does not continuously re-fetch the session list. If that channel is unavailable (for example an API-key-only LAN setup where the WebSocket cannot authenticate), the sidebar falls back to a periodic list refresh until the title resolves -- so titles still appear everywhere, just without the live push.