Extension Output Showcase
Camera-ready samples of everything the custom extensions produce — memory recall, summaries, the diary, verbatim log recall, reminders, file commands, voice, images and the reply clean-up. Show these instead of opening a real chat.
Nothing here is from a real chat. The assistant is called Aria and the user is Sam — both invented for these samples. The extensions print whatever character and user names are active, so in a live demo those names change automatically. Topics are deliberately ordinary (a repair project, a sponsored walk, a book) so nothing personal is on screen.
Three ways to use this page
- Show the page directly. Open it full-screen and scroll as you talk — every block below looks like the app's real output.
- Reproduce it live. Each section ends with a Try it line giving the exact commands, so you can recreate the demo on camera in a fresh chat.
- Make a demo character first. Create a throwaway character and start a new chat before recording: an empty memory store and an empty log folder mean nothing personal can surface while you demonstrate.
What's on this page
- Command reference at a glance
- Memory: saving, keyword recall, meaning-based recall
- Continuity between sessions
- Persistent state: mood, style, relationship, profile
- Rolling summary (and the rejected one)
- Summariser output
- Session diary
- Verbatim log recall
- Time injection & reminders
- File workspace: commands and the panel
- Chat export
- Reply clean-up, before & after
- Voice: speech and the voice loop
- Image generation
- The Extensions tab
- Reproduce-it checklist
1.Command reference at a glance
Everything below is typed into the normal chat box. Nothing starting with a slash reaches the model — it returns instantly and can't be hallucinated.
| Command | What it returns | Typical use on camera |
|---|---|---|
/remember <keywords> | <fact> | Confirmation of the saved memory | Show a fact going in |
/remember <fact> | Same, keywords picked automatically | Show it works with no ceremony |
/memories | Numbered list of saved memories | Prove the store persists |
/forget <id> | Confirmation | Show deletion |
/mood · /mood reset | Current mood state | Show persistent feeling state |
/style · /style set… | Voice profile / change confirmation | Show a per-character writing voice |
/relation | Relationship score | Show continuity of closeness |
/profile · /profile add… | Facts shared by all characters | Show cross-character knowledge |
/summary · /summary reset | The rolling summary of a long chat | Show long-chat coherence |
/compact · /compact off | Folds older messages into the summary and drops them from the model's view | Long sessions without silent truncation |
/diary · /diary read · /diary clear | Writes / reads the session journal | Show a dated record of the session |
/sum /sum5 /sum10 /sum20 /sum50 /sumall | Structured summary + keywords | Show the fixed output contract |
/file write|append|read|edit|search|diff|stats|undo|copy|delete|list | Direct file operations in a shared folder | Show real work with no model involved |
/export · /export html | Saves the chat as a transcript | Show the chat leaving the app cleanly |
/image <prompt> | Generates a picture into the chat | Show local image generation |
2.Memory: saving, keyword recall, meaning-based recall
2.1 Saving a memory — explicit keywords
2.2 Saving with automatic keywords
No keyword list given, so the extension picks them — words wrapped in *asterisks* take priority.
2.3 The memory store
(Saved memories: [1] My sister is training for a charity hike in the Peak District in May. [2] I'm rebuilding a 1978 cassette deck in the workshop — belts and pinch roller done. [3] Prefers green tea over coffee, never coffee after 4pm. [4] Works shifts, so evening chats fit best.)
2.4 Keyword recall — what the model actually receives
Weeks later, the trigger word appears and the memory is injected into that turn. This is the block the model sees above the message:
[Long-term memory for this character:] - My sister is training for a charity hike in the Peak District in May.
2.5 Meaning-based recall — no keyword needed
Same memory store, different wording. Nothing here matches a keyword literally, but the local embedding model recognises the subject:
[Long-term memory for this character:] - My sister is training for a charity hike in the Peak District in May.
/remember hike, charity | My sister is training for a charity hike in the Peak District in May. — then in a new chat say "how's the hike prep going?" (keyword) and "any progress on the big walk thing?" (meaning).3.Continuity between sessions
Open a new chat and the tail of the previous one is carried in, along with a nudge not to open with the same stock greeting:
[Previous session context: last chat was 3 days ago] Sam -> Aria: how's the hike prep going? Aria -> Sam: Still on the training plan, last I heard… Sam -> Aria: I'll sort the sponsorship page at the weekend. Aria -> Sam: Good — do the map first, it does more work than the paragraph. Sam -> Aria: night then. Aria -> Sam: Night, Sam. [Open this session naturally - vary your greeting. Your mood is good; relationship with the user is 72/100. Don't repeat a stock opener.]
Why it matters on camera: the first line references the previous session rather than saying "Hello! How can I help you today?" — that's the whole point of the carry-over.
4.Persistent state: mood, style, relationship, profile
All four survive restarts and are injected as context, so they behave like state rather than prompt decoration.
/mood (Mood: good (score +6), energy medium, patience high) /style (Writing style: Tone: casual | Swearing: mild | Sentences: medium | Humour: dry | Catchphrases: none) /relation (Relationship with Sam: 72/100) /profile (User: Sam. User profile: [1] Works shifts, so evening chats fit best. [2] Prefers the plain answer first, context after.)
What the model sees each turn:
[Mood state for this character:] - Mood: good (score +6) - Energy: medium - Patience: high - Relationship with user: 72/100 - Recent tone: good [Writing style for this character (keep this voice):] - Tone: casual - Swearing: mild - Sentence length: medium - Humour: dry [Facts about Sam (the user, shared across all characters):] - Works shifts, so evening chats fit best. - Prefers the plain answer first, context after.
The state card (panel readout)
Character: Aria Mood: good (score +6) | Energy: medium | Patience: high | Relationship: 72/100 Style: Tone: casual | Swearing: mild | Sentences: medium | Humour: dry | Catchphrases: none Active user: Sam User facts: Works shifts, so evening chats fit best.; Prefers the plain answer first. Memories stored: 4 Rolling summary: - Sam is rebuilding a 1978 cassette deck: belts and pinch roller done…
/mood, /style, /relation, /profile — then restart the app and run them again to show the state survives.5.Rolling summary (and the rejected one)
Long chats get a background summary so the assistant stays coherent beyond the context window. It is generated off the live reply path and checked before it's kept.
What /summary shows when the summary is good
(Rolling summary: - Sam is rebuilding a 1978 cassette deck: belts and pinch roller replaced, head alignment left for the weekend. - His sister is training for a charity hike in the Peak District in May; he's running the sponsorship page. - Long-running thread: sci-fi novels with unreliable narrators - I still owe him a recommendation. - He prefers the short answer first, then the reasoning.)
What happens when a generation comes back bad
Rejected — not stored, not injected
User: CURRENT_LOCAL_DATETIME=2026-09-24_21-04-11 Sam: evening ( Sam: evening ( Sam: evening ( Sam: evening ( Sam: evening ( Sam: evening ( Sam: evening ( Sam: …
Repetition loop, or a copy of the transcript instead of a summary.
Kept — the previous summary stays in place
Same bullets as above. The bad generation is discarded, the stored summary is untouched, and the next update tries again.
And an unusable summary already on disk is never injected.
Demo line: "if the model has a bad moment, the fix is on the extension's side — a repetition loop never becomes the assistant's memory of the chat."
/summary. Show the bullets, then /summary reset to clear it.6.Summariser output
A bare command in the chat box turns into a summary with a fixed shape: one summary section, five keywords, written in the assistant's own first person.
Before and after the output contract
Before
Aria: Right, let's see what the archive says… [Summary] The conversation has centred on a workshop project, where Sam and Aria explored the repairs. They discussed how Aria thinks the belt replacement went well and Sam shared his views on the deck. [Keywords] - workshop - belt - repair - project - deck - cassette - weekend - alignment - tools - patience
An opening line about "the archive", third-person narration ("Sam and Aria explored"), and ten keywords instead of five.
After
[Summary] Sam came in with the cassette deck finally running — belts and pinch roller done… [Keywords] - cassette-deck - charity-hike - peak-district - sponsorship-page - unreliable-narrators
Starts at the header, first person throughout, exactly five keywords.
/sum20 in a long chat, or /sumall for the whole thing. Point at the header and the keyword count.7.Session diary
/diary writes a dated entry to that character's folder; /diary read shows the file. Built from the session itself, so it always has content:
## Diary - Thu 24 Sep 2026, 21:12 **Aria** · 14 exchanges with Sam · 19:58 → 21:12 (~1h) - Mood: good (+6) · energy medium · patience high - Relationship with Sam: 72/100 (close) - Mood through the session: good throughout (+2 → +6) - Threads: cassette, workshop, weekend, alignment, sister, charity - Line that stayed with me: "I'd rather leave the alignment until Saturday than rush it and snap a head I can't replace." - Saved to memory: - I'm rebuilding a 1978 cassette deck in the workshop — belts and pinch roller done. - My sister is training for a charity hike in the Peak District in May. - Reflection: - Sam is rebuilding a 1978 cassette deck: belts and pinch roller replaced, head alignment left for the weekend.
| Line | Where it comes from |
|---|---|
Header + 14 exchanges · 19:58 → 21:12 | Message count and times read from the chat's own metadata |
| Mood / relationship / mood-through-session | The stored state over the session's history |
| Threads | Words the user's own messages kept returning to |
| Line that stayed with me | The user's most personal, substantial line, quoted verbatim |
| Saved to memory | Memories written during that session |
| Reflection | The rolling summary when it's usable, otherwise "Where we left off" with the last exchange |
Worth saying on camera: slash-command turns are skipped, so a command and its reply never end up quoted as the "line that stayed with me" or the last thing said.
/diary and /diary read. /diary clear empties the file for a clean take.8.Verbatim log recall
Ask what was actually said earlier and you get the literal lines with real timestamps — no paraphrasing, no guessing.
| Tag the assistant can emit | Returns |
|---|---|
[RECALL:get_last n=5] | The last N messages, verbatim |
[RECALL:get_at_or_before timestamp=2026-09-24_20-45-00] | The message at or before that moment |
[RECALL:get_between start=… end=…] | Everything in that window |
[RECALL:get_day] | The current weekday, from the logs |
Why it's demo-friendly: the recall replaces the reply outright, so the model can't pad it, paraphrase it or invent a line that was never said. Previous recall dumps are filtered out too, so recalling twice doesn't nest one dump inside another.
[RECALL:get_last n=3] as a message to show the output on its own.9.Time injection & reminders
Appended to every message — time of day, in words
evening Sam, how did the weekend go? [Time context - injected, not message text. It is evening on Thursday. Speak about time in broad terms like that; give an exact clock time or date only if asked. Never quote or repeat this line.]
No clock and no calendar date sit in an ordinary prompt, so there is nothing for a model to copy — the assistant just knows it's evening, the way a person would.
When you actually ask
… Never quote or repeat this line. CURRENT_LOCAL_TIME=22:57 CURRENT_LOCAL_DATETIME=2026-09-24_22-57-30 UTC_OFFSET_MINUTES=60 CURRENT_UTC_DATETIME=2026-09-24_21-57-30]
"what's the date?", "what day is it?", "what did we say earlier?", "was that last night?" add just the calendar date; a direct time question adds the clock. So accurate answers come from real values, while the default state stays quiet.
Shape, order and tiering are all deliberate. The block used to lead every message with a full timestamp, which read as the opening of the user's own text — models copied it back as a dateline at the top of their replies, and led with UTC so "the time" came out an hour behind the local clock. It now trails the message, states the time of day in words, and only carries exact values when they were asked for. Field names are unchanged, so the persona rules that refer to them still apply.
A delivered reminder
Reminders are stored in a plain .ini (weekly / monthly / yearly / one-off), delivered as their own assistant-side message, and throttled to once every 20 prompts by default so they never spam. There's an on/off switch in the panel.
10.File workspace: commands and the panel
Real file operations in a shared folder, with no model involved. Ideal for a video: instant, verifiable, and impossible to hallucinate.
Line-targeted editing and undo
- Every modifying command snapshots the previous version first, so
/file undosteps back — call it again to step back further. - Partial names resolve themselves:
notesfindsnotes.txt, searched recursively through subfolders. - Paths are locked to the workspace folder, so nothing can be written outside it.
- Several commands can be pasted at once, one per line.
Doing it by hand — the File Workspace panel
The commands are for the model. For you there's a panel (its own extension, its own section in the Extensions tab) that drives the same engine — what you click and what the AI types do exactly the same thing to the same folder.
| Control | What it does |
|---|---|
| Workspace folder + Set folder / Create folder | Point the workspace anywhere; the status line says whether it exists and, if not, suggests a path this machine has |
| Files dropdown + Refresh list | Everything in the workspace (backups hidden) — pick one to open it |
| Contents editor + Save | Edit in place; a backup is taken first, so a wrong edit is recoverable |
| Undo last change | Restores the previous version — click again to step further back |
| New file name + Create new file / Rename to that name / Delete | File management without breaking off mid-sentence to type a command |
| Search / Stats | The same as /file search and /file stats |
| Attach to next message | Hands the file to the model with your next message — and shows it in your own bubble |
What attaching looks like
Your message carries the file's contents, so it's part of the conversation and part of the transcript — no hidden prompt injection and nothing to wonder about.
Limits, so nobody expects more than it does:
- Text only. Files over 2 MB are refused in the editor, and binaries — images, PDFs, Office files — come through as garbage. Attachments are plain text.
- One folder only. Everything must sit inside the workspace;
../escapes and paths outside it are refused. - 4000 characters per attachment. Longer files are truncated with a marker — use
/file read <path> <from> <to>for line ranges. - One file at a time. No multi-select, no uploads or downloads, no tabs.
- An attachment stays in the chat, so it counts toward the context window for the rest of that conversation.
- Undo is per file, stepping back through the last ten backups — it isn't a version history.
- Nothing is sent automatically. The model only sees a file when you attach it or when it runs
/fileitself. - The AI can write without asking. It has the same folder, so it can create, overwrite or delete files in it — the backups are the safety net, not a confirmation step.
- The model still needs its commands to act on files itself. The panel means you never type them, not that the model doesn't.
11.Chat export
/export (Exported 42 exchanges to: …/long_term_memory/_exports/Aria-20260924-2112.md) /export html (Exported 42 exchanges to: …/long_term_memory/_exports/Aria-20260924-2115.html)
A clean transcript with the injected context blocks stripped out — no model involved. Show the file opening in a browser if you want a "look what came out" moment.
12.Reply clean-up, before & after
Models like to imitate whatever they can see in the prompt. These are the real shapes of that problem, and what the reply looks like after the extension's clean-up pass. Good "the unglamorous work" segment.
Copying the injected timestamp — a dateline
Raw reply
2026-09-24. You made it through the night. I'm here whenever you want to pick up where we left off.
Shown
You made it through the night. I'm here whenever you want to pick up where we left off.
Copying the injected timestamp — woven into the sentence
Cutting this one would leave a broken fragment, and the raw value a model reaches for is the UTC one, so the stamp is rewritten as the local clock instead:
Raw reply
21-27-38 is a bit late for a "hi" but I'm glad you're here. (local time was 22:27)
Shown
22:27 is a bit late for a "hi" but I'm glad you're here.
A bare HH:MM is left untouched, because that is the shape a real time answer uses — the repair only applies to the macro's own value shape (21-27-38, 2026-09-24_21-27-38, 22:27:38).
Signing the reply with its own name or version
Raw reply
Aria: That's a fair point, but the map still does more work than the paragraph. 1.0. That's a fair point, but the map still does more work than the paragraph.
Shown
That's a fair point, but the map still does more work than the paragraph.
Parroting an injected context block back as dialogue
Raw reply
[Mood state for this character:] - Mood: good (score +6) - Energy: medium - Patience: high - Relationship with user: 72/100 Evening, Sam.
Shown
Evening, Sam.
Keeping the paragraphs the model wrote
Raw reply
The deck's running. Head alignment next, then it's done.
Shown — unchanged
The deck's running. Head alignment next, then it's done.
Also handled: stray HTML tags the model echoes, a reply reduced to a bare status token, and time macros read out loud by the speech engine.
13.Voice: speech and the voice loop
Both are fully local — a small neural voice model and a portable Node runtime, no PyTorch and no cloud service.
Text-to-speech panel
| Control | What it does |
|---|---|
| 🔊 play button (composer) | Speaks the last reply. Sits next to the attach-file icon in the chat input row. |
| Speak last reply / Stop | The same thing from the panel, plus a hard stop mid-sentence. |
| Voice | Voice picker — several accents, more than one per accent so characters don't share a voice. |
| Speech speed | 0.5×–2.0× slider. |
| Pause on commas | Short breath after each comma, which makes long replies easier to listen to. |
| Voice for character | Assign a voice per character; the composer button then uses that character's voice automatically. |
persona_voices.json
{
"Aria": "bf_emma",
"Cole": "bm_george"
}
Before speaking, the text is cleaned: thinking blocks, leaked time macros and HTML entities are stripped, so the voice never reads ' or a timestamp out loud.
Voice loop (early stage)
One panel starts a hands-free loop: microphone → speech-to-text → assistant reply → local speech → speaker. It's start/stop only for now — frame it as "the loop works, the polish comes next".
Camera tip: audio can't be shown on a slide — record this live. Hit play on two different characters to prove the per-character voice, that's the part that reads instantly on video.
14.Image generation
Local Stable Diffusion on Vulkan, with the checkpoints bundled. No PyTorch stack, no separate SD web UI, no API.
The AI can draw on its own
Say in the prompt that it may draw, then the model emits an image tag inside its reply and the tag is swapped for the finished picture:
- Panel controls: model, prompt, negative prompt, size, steps, CFG, seed.
- Each model remembers its ideal settings, applied automatically when you pick it.
- Drop another checkpoint into the models folder and it appears in the dropdown — no code change.
- VAE tiling on by default, so 1024×1024 fits on a 16 GB card.
/image a scene in the chat box, then ask the assistant for a picture so the tag flow shows as well.15.The Extensions tab
All of the above lives in one top-level tab, with each panel collapsed until you open it.
| Panel (Extensions tab) | What's inside |
|---|---|
| Long Term Memory | Memory list + editor, toggles for auto-capture, carry-over, semantic retrieval, injection position, max memories; mood / style / relationship readouts with reset buttons; the state card; the session diary; the shared user profile; the file workspace folder. |
| Text to Speech (local) | Voice picker, speed, comma pauses, per-character voice, speak last reply, stop. |
| Image Generation (local) | Model picker, prompt and negative prompt, size / steps / CFG / seed, generate. |
| Reminders | Enable switch, delivery interval, reminder list, add/edit reminder fields (name, date, type, message). |
| Kokoro Voice — local speak-and-react | Start/stop for the hands-free voice loop. |
The two remaining extensions are hook-only — the summariser and log recall add commands and behaviour rather than controls, so they have no panel. The four core panels are always loaded and can't be switched off by accident from the extension list.
16.Reproduce-it checklist
Paste-ready. Start a fresh chat (ideally with a throwaway demo character) and work down the list.
| # | Type this | What to point at |
|---|---|---|
| 1 | /remember hike, charity | My sister is training for a charity hike in May. | The confirmation — a fact just went into long-term memory. |
| 2 | /memories | The store, with ids you can delete by. |
| 3 | Then say: how's the hike prep going? | The memory surfacing on its own, by keyword. |
| 4 | In a new chat say: any progress on the big walk thing? | Same memory again, with no shared wording — retrieval by meaning. |
| 5 | /mood · /style · /relation · /profile | State that persists across restarts. |
| 6 | /sum20 (in a long chat) | Clean [Summary] + five keywords, first person. |
| 7 | /diary then /diary read | A dated entry written from the session itself. |
| 8 | what did we say earlier? | Verbatim lines with real timestamps. |
| 9 | /file write notes.txt | hello then /file read notes.txt | Instant, model-free file operations. |
| 10 | /image a rain-soaked neon alley at night | Local generation landing in the chat. |
| 11 | Press 🔊 on any reply, then switch character and press it again | Per-character voice. |
| 12 | Open the Extensions tab | Panels collapsed, core panels locked on. |
| 13 | Model tab: compare the model list with the draft list | A draft head is absent from the models and present where it's actually used. |
If you'd rather not type live at all: this page already contains the finished version of every one of those moments, in the app's own output format. Show the page, narrate, and keep the live demo for one or two highlights — the memory surfacing and the voice.
Formats on this page come from the extensions' source, not from memory: command replies, injected blocks, the diary layout, the recall line format and the panel names were all read back out of the code. The content is invented for demonstration. Names used: Aria (assistant) and Sam (user) — swap them in your head for whichever character you're showing.