diff --git a/README.md b/README.md
index e4bdcb5..0bacce2 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,8 @@ boundary - without an opinion about what the agent is for. A setup is one
holds the primitives, [beaver-agent](https://git.kotikot.com/beaver/beaver-agent)
is a full setup built on them.
+
+
## What it gives a setup
- **agents/** - what an agent is: a Claude agent with a prompt per
@@ -32,7 +34,13 @@ is a full setup built on them.
- **storage/** - SQLModel tables and the Postgres session store.
`config.py` defines `Gateway` and loads a setup; `app.py` builds the runtime
-from it; `cli.py` is the entrypoint. Every string the gateway puts in front of
+from it; `cli.py` is the entrypoint. The admin SPA in `ui/` is the browser
+window on all of it: conversations by day, the thread with the tree of tool
+calls, the context of the last turn, memory, jobs, usage, tokens and the audit.
+
+
+
+ Every string the gateway puts in front of
a model or a user has an English default and is overridable
(`ConversationTexts`, `TelegramTexts`).
diff --git a/preview/shots/admin-context.webp b/preview/shots/admin-context.webp
new file mode 100644
index 0000000..69fbd8c
Binary files /dev/null and b/preview/shots/admin-context.webp differ
diff --git a/preview/shots/admin-now.webp b/preview/shots/admin-now.webp
new file mode 100644
index 0000000..557b063
Binary files /dev/null and b/preview/shots/admin-now.webp differ
diff --git a/preview/shots/admin-thread.webp b/preview/shots/admin-thread.webp
new file mode 100644
index 0000000..13b122a
Binary files /dev/null and b/preview/shots/admin-thread.webp differ
diff --git a/ui/src/lib/panel/conversation-view.svelte b/ui/src/lib/panel/conversation-view.svelte
index 90f4b50..e4587b0 100644
--- a/ui/src/lib/panel/conversation-view.svelte
+++ b/ui/src/lib/panel/conversation-view.svelte
@@ -18,6 +18,7 @@
onOpen,
showTitle = true,
initialView = "chat",
+ onViewChange,
}: {
client: ApiClient;
id: string;
@@ -27,6 +28,8 @@
showTitle?: boolean;
// "activity" beside a deep chat's own note: the file is the thread.
initialView?: string;
+ // The page keeps the open tab in the URL so it survives a reload.
+ onViewChange?: (view: string) => void;
} = $props();
const host = usePanelHost();
@@ -50,6 +53,10 @@
historyKey += 1;
}
+ $effect(() => {
+ onViewChange?.(view);
+ });
+
$effect(() => {
const { running } = feed.model;
if (!running) {
diff --git a/ui/src/routes/conversations/[id]/+page.svelte b/ui/src/routes/conversations/[id]/+page.svelte
index 6630ee2..c57976a 100644
--- a/ui/src/routes/conversations/[id]/+page.svelte
+++ b/ui/src/routes/conversations/[id]/+page.svelte
@@ -1,5 +1,5 @@
Conversation ยท Beaver
@@ -17,7 +33,9 @@
client={session.client}
{href}
{id}
+ {initialView}
onOpen={(target) => goto(href(target))}
+ onViewChange={remember}
/>
{/key}
{/if}