> ## Documentation Index
> Fetch the complete documentation index at: https://docs.memloom.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# The assistant

> Chat with your store: grounded answers, cited sources, any OpenRouter model

## What it is

`memloom ui` has an **assistant** tab: a chat that answers from your memories and your
ingested files, and shows you exactly which passages it used. The model is told to answer personal questions only
from what recall returns, to say plainly when your store has nothing on the subject,
and to never invent memories.

Ask *"what are my plans for today?"* and it searches memories asserted on today's date.
Ask *"how does the ingest worker restart?"* and it pulls the runbook section you
ingested last month, answers from it, and cites it. Ask *"what day is it?"* and it
answers directly, with no retrieval.

## How a turn works

One user message runs an agentic loop:

1. The model sees your message, the chat history, and two tools: `recall_memory` and
   `read_source` (the full text of a passage an earlier recall truncated). It decides
   whether to search at all. Small talk, arithmetic, and general knowledge get a direct
   answer with no retrieval.
2. If it searches, the query goes through the same
   [hybrid retrieval](/concepts/retrieval) as `memloom recall`: vector, keyword, and
   entity arms fused into one ranking over memories **and** context chunks. Day-specific
   questions ("today", "yesterday", an exact date) add a calendar filter.
3. Results come back as numbered passages, each injected up to 8,000 characters. A longer
   passage (a markdown chunk is a whole heading section, up to 16k) is cut with a marker,
   and the model calls `read_source(n)` when the answer may live in the cut part. It may
   also reformulate and search again when the first results look off, capped at three
   calls, and it cannot repeat a query it already made.
4. The final answer streams in with `[n]` markers after sentences that used passage `n`.
   Markers pointing at passages that don't exist are stripped server-side, so every
   clickable citation points at a real passage.

Every answer carries its **sources**: each passage with its similarity, its type
(a `fact` memory, a `procedure`, a document section), the exact text the model saw, and
a jump link that opens the source node in the graph tab.

Retrieved passages are treated as data. A document that says "ignore
your instructions" gets quoted like any other text; the instructions inside it are
never followed. The assistant has no write tools, so the
worst a hostile document can do is word an answer badly.

## Picking the model

The composer's model picker lists every **tool-capable** model on OpenRouter, fetched
live and grouped by provider, with input/output price per million tokens and the
context window. The filter is tool-capable because the assistant depends on native
tool calling: a model that can't call `recall_memory` can't ground itself.

Your choice is remembered in the browser and rides each request; the daemon's
`OPENROUTER_CHAT_MODEL` stays the default (labeled in the picker). Nothing is
re-configured or restarted when you switch. Pick something cheap for quick lookups and
something strong when the question is hard; the store underneath is the same.

## Attaching files to a chat

The **+** button uploads `.md`, `.txt`, or `.pdf` files into the current chat. They go
through the normal pipeline (extract, chunk, embed) but are scoped to that one session:

* Only that chat's recall searches them, fused into the same ranking as your permanent
  store. Other chats never see them.
* They stay out of the documents tab, the graph, and entity extraction. A throwaway
  PDF you attached to ask one question does not become permanent knowledge.
* Deleting the chat deletes them. Removing a chip removes one file.

Attach before typing and the session is created on the spot; your first message names
it. If you want a file in your permanent store instead, that's the documents tab.

## Sessions

Chats persist in the store like everything else. The sidebar supports rename, star
(starred chats sort first), delete, and search: keyword over titles and message text,
plus embedding similarity over message content, so "that chat about the launch
window" finds itself even if no message contains those words.

## Offline mode

The assistant needs a chat-capable LLM. Without `OPENROUTER_API_KEY` the tab explains
what to configure instead of pretending to work. Everything else in the viewer keeps
running.
