Her reasoning, kept
Every turn from you is stored in agent/thoughts.db: the thinking, round by round, labelled
with what each round went on to do ("then called web_search", "then answered"), what you said,
what she said, the tools she called in order, how long it took, the mood she was in, and which model
answered. Nothing is re-requested; the thinking is recorded as a side effect of the reply existing at all.
A rule-based review runs on every turn as it's recorded. Not a model's opinion of itself: each flag is a check you can repeat by eye, and a flag means look at this one, never this was wrong.
| Flag | What was seen |
|---|---|
| promised a tool | the thinking names a tool she never called: "I'll set that for you", nothing scheduled |
| guessed | the thinking admits it doesn't know, no tool was called, and the answer doesn't say so |
| did date math | a date worked out in the scratchpad instead of asking get_datetime |
| leaked | the answer reads like the scratchpad, or contains a think tag |
| tool failed | a tool result that reads as an error |
| cut off | the think block never closed: the model ran out of tokens |
| broke character | "as an AI", "I don't have feelings": the small-model regression that shows up when the context gets crowded |
| ungrounded | a specific in the reply that nothing she was given backs up |
Token confidence
On llama.cpp every turn also records the probability the model gave each token it picked, and the runners-up whenever it was less than 90% sure. That isn't her account of herself; it's measured, and it's the most direct look at her internal state this setup gets. The viewer shows her reply token by token, plain at 90%+, faint at 60 to 90, amber at 30 to 60, red under 30. Hover a word to see what she nearly said instead. "around March 2024", with June at 81% beside it, is the difference between knowing and guessing.
A low probability isn't automatically a mistake. With sampling on she will sometimes pick a less likely word on purpose, and that's where the personality comes from. A run of them on a fact or a date is the thing to look at, and that's exactly what the low confidence flag catches.
Saying so out loud
When a reply measured under 60% sure and had a run of coin-flip tokens in it (a name, a date, a number she was guessing at), didn't call a tool, and didn't already hedge, she adds a line out loud: "I'm not totally sure about that one, though." Her next prompt is told how sure that reply was, so "are you sure?" gets an honest answer without a tool call. Reminders and alarms are never hedged.
Calibration catches guesses she was unsure of. The grounding check catches the ones she was sure of: after each of your turns, every checkable specific in her reply (numbers with units, prices, versions, years, links, paths) is looked for in what she actually had in front of her: the system prompt, what you said, and every tool result of the turn. Her own earlier replies don't count; a guess repeated isn't a source. A specific that appears in none of them gets flagged, said with a hedge, or, in the strictest mode, sent straight back to be verified with a tool.
Adaptive thinking
Every turn thinks on a modest budget, which also makes easy questions answer sooner. If the reply came out shaky, the same question is asked again, silently. By default that's a vote: two more answers at the normal budget, compared on their specifics. If her first reply is in the majority it stands. If the new answers agree with each other and not with her, she says "Hang on, let me correct that." and gives the majority answer. If most of them reach for a tool, she says "Hang on, let me check." and does it, with the usual approvals. A confident reply never pays for a second look, and a turn that already called a tool is never re-run, so nothing is scheduled or written twice.
Separately, when a reply ends with a step she announced ("let me read the file and fix it~") but she called no tool, the turn doesn't end there: she's told she skipped it and the step runs. Small models announce more often than they act, and from outside it looked like she'd stalled.
Memory
Facts are written deliberately by the model, not scraped from every turn. "Remember I stream on Tuesdays"
is remember_fact; "no, I moved to Thursdays" is update_fact; "forget the bakery
thing" is forget_fact, by loose description, and when two facts are too close to call she
asks which rather than deleting the wrong one.
The permanent store is plain SQLite, in-process, nothing to install. Nothing is ever dropped for space. Facts that stop being true are retired, kept with their dates and hidden from context, so "what was my last graphics card" is still answerable. Contradictions are handled: "I got a 7900 XTX" retires the 6950 XT fact instead of sitting next to it forever. With the embedding server running she recalls facts by meaning, so "I got a new graphics card" finds the fact about the 6950 XT even though no word is shared, and an optional reranker reads the best matches side by side to sharpen the pick.
Every turn is also appended to a transcript that summarization never touches, and search_history
reads it back, with the turns either side of each hit, because half a conversation rarely answers
anything on its own.
Your own notes, as something she can look up
Give her a folder of notes, manuals, PDFs and docs, and she answers from them, saying which file the answer came from: "what port did I put Jellyfin on?", "my dishwasher says E24". An Obsidian vault works as it is. When something you say matches a note closely enough, it comes along with your turn without her having to look. The index is a cache she rebuilds; the files are read where they are; keys and credentials are skipped even if they're in there. Stream chat never sees any of it.
Learning from herself
Eight things that make her a little better each day. None of them changes the model's weights. They change what she gets told about herself, and all of it is written down where you can read it, edit it, or switch it off.
| Part | What it does |
|---|---|
| Lessons | Once a day, idle, she reads back her own turns that went wrong (flagged, low confidence, or followed by "no, actually") and writes at most three one-line lessons about her own behaviour, each citing the turns it came from. The relevant ones ride in her prompt from then on. |
| Episodes | After a conversation goes quiet, a few sentences of her own notes on it: what it was about, what was decided, what's unfinished. Time she spends playing a game becomes one too. |
| Fact cleanup | Merges facts that say the same thing twice, retires the losing side of a contradiction. |
| Calibration | Says so out loud when her token probabilities say she didn't know. |
| Startup greeting | After a break, opens by picking up where you left off. |
| Recipes | The steps of a multi-step job that went right, saved with your OK and brought back for similar jobs. A small model is bad at planning from nothing and good at following a worked example. |
| Projects | Work that spans sessions: the goal, what was tried and found, the next step, in her prompt until it's done. |
| Situation block | A few live lines each turn: your focused window, what's playing, machine load, running plugins, the next reminder. |
Tools she can use on herself
introspect hands one turn's measurements back to her: how sure she was across the reply, the
least likely words with what she nearly said instead, the review flags, the tools she called, and her
mood. Ask "how sure were you about that?" and she can answer from data instead of from vibes. It's a tool
she calls when she wants it, never something added to every prompt: a model that knows its scratchpad is
being read starts writing it for an audience, and then the log stops being honest.
self_status is the wider view: model, context, mood, uptime, today's confidence and flags,
how many facts and lessons she has. reflect_now runs her reflection pass on demand.
The research side
Luna doubles as a small rig for watching a local model think. Following Anthropic's concept-injection experiments and a follow-up on an 8B open model, a set of scripts builds one control vector per concept from her own model, runs a blind battery that injects one into her layers (or nothing), and scores whether she can tell: which concept, read as probabilities, against the known chance rate. Blind sessions let you talk to her normally with a sealed condition and guess afterwards. An activation reader goes the other way: it reads which concepts are already active in her layers for a given prompt, without changing anything. Two published safety experiments, Palisade's shutdown avoidance and Anthropic's agentic misalignment, are wired to run against her model, plain and in her persona.