Three of the surfaces a user asks about most had nothing in `docs/`, so the assistant answered from guesswork: the chat itself (its two layouts, the tab bar and what lands on which tab, every control around the composer, the slash commands it must never forward to the model), the Inbox (why background work asks there rather than in the chat, and that an unanswered card is a stopped job, not a slow one), and security groups — the honest answer to "why does it keep asking me for permission?", including what a group is *not*: not a mode, not a data boundary, and not advisory. Each page states the misreadings users actually arrive with, since correcting those is most of the work; the tables list what the person is looking at, not what the code does.
This commit is contained in:
@@ -51,6 +51,10 @@ release PR may merge — and a section is closed at the commit that bumps it.
|
|||||||
- DeepInfra, as a declarative LLM provider.
|
- DeepInfra, as a declarative LLM provider.
|
||||||
- The project coordinator offers to keep a history of a project.
|
- The project coordinator offers to keep a history of a project.
|
||||||
- An agent can ask which connectors it holds instead of guessing.
|
- An agent can ask which connectors it holds instead of guessing.
|
||||||
|
- The assistant can now explain the chat window itself (tabs, the composer's controls,
|
||||||
|
the slash commands), the Inbox and its three kinds of pending request, and the security
|
||||||
|
groups behind "why is it asking me for permission?" — ask it in plain words instead of
|
||||||
|
hunting through the pages.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
# The chat window
|
||||||
|
|
||||||
|
This is where almost everything happens, so it is the page users ask about most. It is one single chat surface that changes shape rather than two different things:
|
||||||
|
|
||||||
|
- **On the home page it fills the screen** — the conversation *is* the landing page, with a short welcome and a few starter suggestions when it is empty.
|
||||||
|
- **On every other page it docks to the right** as a side panel, so the user can watch a project, a file or a settings page while still talking. The panel can be dragged wider or narrower by its left edge, and hidden entirely with the **›** button in its header — a ✨ button then appears in the top bar to bring it back.
|
||||||
|
|
||||||
|
Switching between the two is just navigation: nothing is lost, no message is dropped, the connection stays up. A user who says "my chat disappeared when I opened Files" has collapsed the panel, not lost the conversation.
|
||||||
|
|
||||||
|
The **"Private to you"** chip in the header is a real statement, not decoration: a conversation belongs to the person who had it and nobody else can read it — the admin included. Anything that would put information into the shared space asks for approval first.
|
||||||
|
|
||||||
|
## Tabs: several conversations at once
|
||||||
|
|
||||||
|
The bar under the header holds open conversations.
|
||||||
|
|
||||||
|
- **General** is always there and cannot be closed. It is the default chat.
|
||||||
|
- **A project tab** appears when a project's chat is opened (from the project board's *Open chat*, or from the sidebar). It is that project's own conversation, with the project's folder and members already in context.
|
||||||
|
- **The `+` button opens an extra chat** on General or on any project — a second conversation about the same thing, useful for working on two matters at once.
|
||||||
|
- **Double-clicking a tab renames it.** Clearing the name gives back the automatic one, so the box is also the undo.
|
||||||
|
- **The ✕ closes a tab, it does not delete the conversation.** A project chat comes back from its board with all its history; a closed extra chat is gone from the bar but not from the database.
|
||||||
|
|
||||||
|
Two things are worth explaining when they surprise someone:
|
||||||
|
|
||||||
|
- **The set of open tabs follows the person, not the browser.** It is stored in their own account, so the same tabs are there after a login on another device — and a second household member on the same laptop never sees them. *Which* tab is selected is per window, so two windows can sit on two different conversations.
|
||||||
|
- **Anything arriving from outside lands on the main tab of its source**, never on an extra one: a notification from a background agent, the result of a finished background task, an incoming Telegram message. An extra chat opened with `+` is a place to work, not a mailbox.
|
||||||
|
|
||||||
|
## The composer
|
||||||
|
|
||||||
|
**Enter** sends, **Shift+Enter** makes a new line. Around the box:
|
||||||
|
|
||||||
|
| Control | What it does |
|
||||||
|
| --- | --- |
|
||||||
|
| 📎 paperclip | Attach files. Dragging files onto the composer and pasting an image from the clipboard do the same thing. |
|
||||||
|
| 👁 eye | Share what the user currently has open with the next message — see [view-context.md](view-context.md). |
|
||||||
|
| ✨ model pill | Pin which LLM answers in *this* conversation. The list always starts with `auto`, which lets the instance pick per turn — that is the normal setting, and pinning is for "use the big one for this". |
|
||||||
|
| 🛡 shield pill | The conversation's security group — see [security-groups.md](security-groups.md). Only shown when the person's role allows more than one. |
|
||||||
|
| 🗑 bin | Start a fresh conversation on this tab. The old one is not deleted, but the tab moves on and the assistant starts with no memory of it. |
|
||||||
|
| 🎤 microphone | Dictate instead of typing — see [voice.md](voice.md). On the desktop, holding **Ctrl+Space** records for as long as it is held. |
|
||||||
|
| ⏹ stop | Appears while the assistant is working. It stops the current answer, including any tool still running under it. |
|
||||||
|
|
||||||
|
Attachments are uploaded before the message is sent and shown as chips above the box; the ✕ on a chip removes one. Whether an image is actually *looked at* depends on the model answering — a model without vision gets the file's path and can open it with its file tools instead.
|
||||||
|
|
||||||
|
Both pills are per conversation, not per person: pinning a model in one tab leaves the others alone.
|
||||||
|
|
||||||
|
## Slash commands
|
||||||
|
|
||||||
|
Typing `/` opens an autocomplete over the composer; ↑/↓ pick, Enter or Tab inserts. These are handled by the app itself and **never reach the model**:
|
||||||
|
|
||||||
|
| Command | Effect |
|
||||||
|
| --- | --- |
|
||||||
|
| `/help` | The list of commands, including any custom ones this instance has |
|
||||||
|
| `/clear`, `/new` | Start a new conversation on this tab |
|
||||||
|
| `/models` | List the configured models in priority order |
|
||||||
|
| `/model <name\|number\|auto>` | Pin the model for this conversation (the same thing the model pill does) |
|
||||||
|
| `/context` | Tokens used by the last turn |
|
||||||
|
| `/cost` | What this conversation has cost so far, in USD |
|
||||||
|
| `/compact` | Summarise the conversation so far and carry on from the summary |
|
||||||
|
| `/resettools` | Drop the tool groups activated during this conversation |
|
||||||
|
| `/sethome` | Send background notifications to the web app rather than elsewhere |
|
||||||
|
|
||||||
|
An **unknown** `/something` is answered with "unknown command" plus the help — it is never forwarded to the assistant as text, so a mistyped command costs nothing.
|
||||||
|
|
||||||
|
An instance can also have **custom commands**, added as folders on the box (`commands/<name>/`) with a description and a template. Those behave differently: they expand into a normal message and the assistant answers it as usual, so it can ask follow-up questions and use tools. They show up in `/help` and in the autocomplete alongside the built-ins.
|
||||||
|
|
||||||
|
`/compact` is the one worth explaining properly: long conversations eventually cost more and slow down, and compaction replaces the older part with a summary the assistant keeps working from. Nothing is deleted from the record; only what is sent to the model shrinks.
|
||||||
|
|
||||||
|
## While an answer is being written
|
||||||
|
|
||||||
|
- Text appears as it is produced. A **"Reasoning…"** block, collapsed by default, holds the model's thinking when the model exposes it — it is safe to ignore, and it is not part of the answer.
|
||||||
|
- **Tool calls appear as cards** in the transcript: what was called, and its result once it comes back.
|
||||||
|
- **A permission card appears inline** when the assistant needs approval for something mid-answer — the work waits there until it is answered. Requests raised by *background* work go to the [Inbox](inbox.md) instead, and appear above the composer.
|
||||||
|
- Scrolling up stops the auto-follow and shows a **jump to latest** button; sending or clicking it returns to the bottom.
|
||||||
|
|
||||||
|
## Common questions
|
||||||
|
|
||||||
|
- *"Where did my conversation go?"* — check the tab bar and the collapsed panel first; a `/clear` or the bin button starts a new one, which looks like the old one vanished.
|
||||||
|
- *"Does it remember what I said yesterday?"* — within a conversation, yes; across conversations only through memory (see [memory.md](memory.md)).
|
||||||
|
- *"Can my partner/parent read this chat?"* — no. Conversations are private to the account that had them. What can be shared is what goes into shared memory or a shared folder, and that asks first. (One exception worth being honest about: if the instance has a supervision arrangement, a background agent may write a *summary* report about a supervised account — see [system-agents.md](system-agents.md).)
|
||||||
|
- *"Why does it keep asking me for permission?"* — that is the security group, not the model being cautious: [security-groups.md](security-groups.md).
|
||||||
|
- *"It's stuck."* — look above the composer for a waiting request, and in the Inbox; otherwise the ⏹ button ends the turn cleanly.
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
# The Inbox (things waiting for a human)
|
||||||
|
|
||||||
|
The Inbox (sidebar → **Inbox**) is the one place where everything that is *waiting for this person* collects. The red number next to it is the count of pending items, and it updates by itself — no refresh needed.
|
||||||
|
|
||||||
|
The rule that explains the whole page: **work that happens in front of the user asks in the chat; work that happens out of sight asks here.** When the assistant needs permission mid-answer, the card appears inline in the transcript where the work is. When something running in the background needs an answer — a scheduled job, a background task, a connector — it has no conversation to interrupt, so it files a request here. Background tasks also surface theirs above the message box of the chat that started them (see [tasks.md](tasks.md)), but the Inbox is where they all end up.
|
||||||
|
|
||||||
|
Everything in the Inbox is **someone's work sitting still**. Until it is answered, that job is not slow, it is stopped.
|
||||||
|
|
||||||
|
## The three kinds of card
|
||||||
|
|
||||||
|
**Approval** — a tool call the rules say a human must confirm: running a command, writing into shared memory, sending something out. The card shows which tool, which agent asked, and the arguments that matter (path, command, URL, recipient…), with the full request available behind *Show raw JSON*.
|
||||||
|
|
||||||
|
**Question** — the agent itself is asking something it cannot decide: which of two files was meant, whether to use the work or the personal address. Some come with suggested answers as one-click chips; the answer box takes anything, Enter sends.
|
||||||
|
|
||||||
|
**Input** — a connector asking for a value directly, usually a login code or an API key. When the value is a secret the field is masked, it is sent once, and it is never shown again anywhere in the interface or written to the conversation.
|
||||||
|
|
||||||
|
## Answering an approval
|
||||||
|
|
||||||
|
- **Approve** runs the call, once.
|
||||||
|
- **Reject** asks for an optional reason. The reason is worth writing: it is handed back to the agent as the result of the call, so it can adjust and try something else instead of guessing why it was refused. A bare rejection just tells it "no".
|
||||||
|
- **×tool ▾ (15 min / 1 hour)** approves *and* stops asking for **that same tool** for that long — nothing wider. Approving "label this email" never un-gates "send this email".
|
||||||
|
- **Session** does the same for the rest of the conversation.
|
||||||
|
|
||||||
|
The time-limited buttons are missing on a request that has been waiting since before the server restarted; that one can still be approved or rejected normally.
|
||||||
|
|
||||||
|
A `deny` rule is never bypassed by any of these buttons: what the rules forbid outright never reaches the Inbox in the first place.
|
||||||
|
|
||||||
|
If someone finds themselves clicking the same approval every day, the answer is not a longer bypass — it is a rule change on the Security page, which is [security-groups.md](security-groups.md).
|
||||||
|
|
||||||
|
## Where a request can be answered
|
||||||
|
|
||||||
|
The same pending request appears everywhere at once: in the Inbox, in the chat that raised it, above the composer for a background task, and on the paired phone if the mobile app is set up. **Answering it in any one of those settles it everywhere**, and the others drop the card on their own. There is no "answer it in the right place".
|
||||||
|
|
||||||
|
Closing a card in the chat with ✕ is not an answer: it puts the card away and the request keeps waiting in the Inbox.
|
||||||
|
|
||||||
|
## What waits, and for how long
|
||||||
|
|
||||||
|
- Requests **do not time out**. One left overnight is still there in the morning, and so is the job behind it.
|
||||||
|
- They **survive a restart of the server**, because they are recorded, not just held in memory.
|
||||||
|
- Stopping the conversation or the task that raised a request (the ⏹ button) cancels its pending requests along with it — the card disappears because nothing is waiting for it any more.
|
||||||
|
- Every item belongs to one person. An admin does not see, and cannot answer, another member's Inbox.
|
||||||
|
|
||||||
|
## Common questions
|
||||||
|
|
||||||
|
- *"The assistant isn't doing anything."* — check the Inbox first. A stopped job with a pending card is the single most common cause.
|
||||||
|
- *"Why is it asking me at all? It did this yesterday without asking."* — either the bypass from yesterday has expired, or the conversation is on a different security group.
|
||||||
|
- *"I clicked reject by mistake."* — nothing is broken: ask again in the conversation. The rejection was recorded as the result of that one call, not as a standing rule.
|
||||||
|
- *"Can I make it stop asking for this forever?"* — yes, but that is an admin change to the rules ([security-groups.md](security-groups.md)), and it is worth saying out loud what it means: the assistant will then do that thing unattended.
|
||||||
|
- *"It asked for a password — is that safe?"* — the value goes to the connector that asked for it and is never echoed back, logged into the conversation, or shown again. Still worth checking *which* connector is asking, and the card says so.
|
||||||
+4
-1
@@ -4,12 +4,15 @@ This folder is written for **you, the assistant**, not for the human directly. I
|
|||||||
|
|
||||||
Keep answers grounded in what's actually enabled and configured for this instance — check with the relevant tool (e.g. list installed/enabled plugins) rather than assuming everything described here is turned on. A feature documented here may not be enabled on this particular instance.
|
Keep answers grounded in what's actually enabled and configured for this instance — check with the relevant tool (e.g. list installed/enabled plugins) rather than assuming everything described here is turned on. A feature documented here may not be enabled on this particular instance.
|
||||||
|
|
||||||
This index will grow over time. Right now it covers the interface, view context, files, agents, memory, projects, shared folders, background tasks, system agents, access grants, connectors, skills, the sandbox, voice input and plugins; more sections (security groups…) will be added later.
|
This index will grow over time. Right now it covers the chat window, the inbox, the interface, view context, files, agents, memory, projects, shared folders, background tasks, system agents, access grants, security groups, connectors, skills, the sandbox, voice input and plugins; more sections (the mobile app, the admin's Users and Roles pages, the Tasks page, models and providers…) will be added later.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
| Document | What it covers |
|
| Document | What it covers |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
|
| [chat.md](chat.md) | The chat window: full-page vs docked, the tab bar and what lands where, the composer's controls, the slash commands, and what happens while an answer is being written |
|
||||||
|
| [inbox.md](inbox.md) | The Inbox: the three kinds of pending request, why background work asks here rather than in the chat, answering one (and the time-limited approvals), and why an unanswered card means a stopped job |
|
||||||
|
| [security-groups.md](security-groups.md) | Security groups: allow / ask / deny per tool, the shield in the chat, what the default group already permits, and how an admin edits the rules |
|
||||||
| [memory.md](memory.md) | Private and shared memory: what goes where, the indexes and history log, why some shared facts can't be changed on request |
|
| [memory.md](memory.md) | Private and shared memory: what goes where, the indexes and history log, why some shared facts can't be changed on request |
|
||||||
| [agents.md](agents.md) | Agents: the three kinds (chat, task, system), which one you are talking to and why, the specialist agents the assistant delegates to, how the model is chosen, and adding a custom agent |
|
| [agents.md](agents.md) | Agents: the three kinds (chat, task, system), which one you are talking to and why, the specialist agents the assistant delegates to, how the model is chosen, and adding a custom agent |
|
||||||
| [files.md](files.md) | The Files page: everywhere a member can reach — home, both memory stores, shared folders, projects, skills and docs — what they can change there, and what is deliberately read-only |
|
| [files.md](files.md) | The Files page: everywhere a member can reach — home, both memory stores, shared folders, projects, skills and docs — what they can change there, and what is deliberately read-only |
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# Security groups (what the assistant may do without asking)
|
||||||
|
|
||||||
|
A **security group** answers one question, tool by tool: *may the assistant do this on its own, must it ask first, or is it off the table entirely?* Three possible answers — **allow**, **require** (ask a human), **deny**.
|
||||||
|
|
||||||
|
It is worth being precise about what a group is **not**, because the shield icon invites the wrong guess:
|
||||||
|
|
||||||
|
- It is **not a personality or a mode.** Switching group does not change how the assistant talks, what it knows, or which agent is answering.
|
||||||
|
- It is **not a data boundary.** It never decides which files exist, which folders a person is a member of, or what the sandbox can reach. Those come from membership and the container ([files.md](files.md), [sandbox.md](sandbox.md)).
|
||||||
|
- It is **not advisory.** The check happens on the server, before the tool runs. A denied tool is not even shown to the model, which is why the assistant will say it cannot do something rather than trying and failing.
|
||||||
|
|
||||||
|
## Choosing one: the shield in the chat
|
||||||
|
|
||||||
|
The shield pill next to the model pill shows the group the current conversation is on, and switching is immediate — mid-conversation is fine.
|
||||||
|
|
||||||
|
**It only appears when the person's role allows more than one group.** For most members there is exactly one, so there is no pill and nothing to choose; that is not a missing feature. Admins always see every group.
|
||||||
|
|
||||||
|
The choice is **per conversation** and it sticks: a chat left on a wider group is still on it tomorrow. Every open window of that conversation re-syncs when it changes, so two tabs never disagree.
|
||||||
|
|
||||||
|
If a role later loses access to a group, conversations already sitting on it quietly fall back to that role's normal group — at once for open chats, and at the latest next time the conversation is opened. It never falls back to "no group", because that would be *wider*, not narrower.
|
||||||
|
|
||||||
|
## What the default group already does
|
||||||
|
|
||||||
|
A new instance ships with one group, **Default**, and its policy is *ask unless told otherwise*:
|
||||||
|
|
||||||
|
- Anything with no rule of its own → **ask**. This is the catch-all at the bottom, and it is why a brand-new instance asks about things nobody has configured yet.
|
||||||
|
- Running a shell command → **ask**, always.
|
||||||
|
- Reading and writing the person's **own** memory → allowed, no friction.
|
||||||
|
- **Reading** shared memory → allowed. **Writing** it → ask. This is the deliberate one: the assistant must never push one person's information into the shared space without a human saying yes.
|
||||||
|
- Project folders and the scratch data folder → allowed both ways.
|
||||||
|
- Reading skills → allowed (a skill is trusted when it is installed, not at each read); the whole tree is read-only anyway.
|
||||||
|
- Harmless plumbing (showing a file to the user, sending a notification, writing a todo list) → allowed.
|
||||||
|
|
||||||
|
So the honest summary for a user asking "what can it do by itself?" is: *read your things freely, work in your own space freely, and ask before running commands or touching anything shared.*
|
||||||
|
|
||||||
|
## Editing the rules (admin)
|
||||||
|
|
||||||
|
Sidebar → **Security** (admin only). The page lists the groups; a group opens onto its rules, arranged by how they are evaluated:
|
||||||
|
|
||||||
|
1. **Overrides** — evaluated first, for exceptions that must beat everything else.
|
||||||
|
2. **File System** — path-scoped rows: one path per row, with read and write decided separately. This is where "the assistant may write into `docs/` without asking" is expressed.
|
||||||
|
3. **Per-tool** — one row per known tool, set with a chip: *—* (no opinion), *Allow*, *Req*, *Deny*. Tools are grouped by kind (File System, Shell, Agents, Introspection, Config, and everything a connector or plugin has offered at least once).
|
||||||
|
4. **Low priority** — broad rules meant to apply only when nothing above matched.
|
||||||
|
5. **Default action** — what happens when no rule matched at all.
|
||||||
|
|
||||||
|
**The first matching rule wins**, and a group's own rules are checked before the Default group's, which sits underneath every group as the fallback tier. That is the practical reason to create a new group by **duplicating** an existing one and changing a few rows, rather than starting from an empty one: an empty group inherits Default and changes nothing.
|
||||||
|
|
||||||
|
New groups are created, renamed and deleted from the same page. Assigning them is a separate job, on the **role**: sidebar → **Roles** → edit a role → its default group, plus the additional groups its members may switch to ([access.md](access.md) covers the rest of what a role decides).
|
||||||
|
|
||||||
|
## Common questions
|
||||||
|
|
||||||
|
- *"Why does it keep asking me the same thing?"* — the rules say ask. The quick fix is the time-limited approval on the card itself ("15 min", "1 hour", "Session" — see [inbox.md](inbox.md)); the durable fix is an admin changing that tool's rule.
|
||||||
|
- *"Make it stop asking, permanently."* — possible, and worth stating plainly before doing it: allowing a tool means the assistant will use it unattended, including during background work nobody is watching. Shell commands and writes to shared places are the ones to think twice about.
|
||||||
|
- *"It says it cannot do X — is it broken?"* — check whether X is denied for this group. A denied tool is invisible to the assistant, so it reports an inability, not a refusal.
|
||||||
|
- *"There is no shield in my chat."* — the role allows one group. Nothing is hidden or broken.
|
||||||
|
- *"Can a child switch to a wider group?"* — only if their role lists it. The check is on the server: a request naming a group the role does not allow is refused, whatever the interface shows.
|
||||||
Reference in New Issue
Block a user