Wiki: add librarian, strengthen prompt, fix delete button#5
Merged
Conversation
…utton
Three changes addressing observations from production traffic.
**Delete button visibility**: Wiki.svelte's local `.danger` CSS reset
the button's `color` to red on top of the global red background fill,
painting the button text invisible. Drop the local override and trust
the global `button.danger` rule (matches the inline note in
Memories.svelte's stylesheet section).
**Per-conversation wiki agent prompt**: production traffic showed the
agent generating one new article per conversation - the per-thread
shape biased it hard toward "this conversation is its own topic,
write a new article". The prompt now opens with an explicit rule
("UPDATE is the default, CREATE is rare") and workflow step 1
mandates at least two different `wiki_search` query angles before
considering `wiki_create`. Most conversations should produce zero
edits; chitchat / tactical Q&A should produce nothing at all. Bumps
the rationale comment block accordingly.
**Wiki librarian agent**: a second background agent whose job is to
make the wiki more coherent than it found it. Reads the full
alphabetical article list, fact-checks specific claims against
conversation history via `conversation_search`, consolidates
duplicates via `wiki_update` + `wiki_delete`. Critically, the
librarian has NO access to `wiki_create` - new articles flow from
the per-conversation agent or the user. The librarian only
consolidates what exists.
- schema: `profiles.wiki_librarian_last_run_at` plus
`claim_wiki_librarian_run(int)` RPC. UPDATE-with-WHERE
atomically returns true at most once per min-interval across
all of a user's devices.
- timing: 12h minimum interval; 1h idle nap so a too-soon device
rechecks the claim hourly without spamming.
- lease partition `'wiki-librarian'` and lock
`nak:wiki-librarian-worker`, distinct from the per-
conversation wiki worker so both run alongside each other.
- new toolbox `wikiLibrarianToolbox` (search/update/delete +
conversation_search) parallel to the existing `wikiToolbox`.
- new `AgentRole 'wikiLibrarian'` pinned to deepseek-v4-flash;
rationale documented next to the existing wiki entry.
- new `wikiLibrarianEnabled` setting, independent toggle from
`wikiAutomaticEnabled` so the user can run one without the
other. Default-on. Settings -> Wiki has both toggles.
User and dev docs updated to describe the librarian, the dual
toggles, and the `update-is-default` discipline.
https://claude.ai/code/session_015XcR7xzLdij66ZbYERUdLH
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
=head1 SYNOPSIS
Three changes addressing observations from production traffic on the
just-shipped wiki:
.dangerCSS painted red text on a red background.
conversation instead of updating existing ones.
consolidates duplicates and fact-checks against conversation
history.
=head1 PURPOSE
After the initial wiki ship landed, two issues surfaced in
production:
inspection showed the global
button.dangerrule fills thebutton red and uses light text, while the local
.dangeroverride I added re-set
colorto red - red text on redbackground = invisible.
per settled conversation - the per-thread invocation shape
biased it hard toward "this conversation is its own topic, so
write a new article". The wiki was accumulating near-duplicates
instead of coherent topical pages.
The user also asked for a separate "librarian" agent whose job is
to organise the wiki by subject and fact-check articles against the
conversation history.
=head1 DESCRIPTION
=head2 Layer 1: how the existing wiki behaves
Wiki.svelterenders the open article with three trailingbuttons (Edit / Ask agent to update / Delete). The local
stylesheet block defines
.danger { color: var(--error) }toborder-and-color the Delete button red. The global
button.dangerrule already paints the button solid red withcontrasting light text via
--ink-on-danger.The autonomous wiki agent (
src/lib/agents/wiki/) claims onesettled thread per cycle, builds a prompt out of
WIKI_AUTONOMOUS_PROMPT, and runsrunHeadlessToolLoopagainstwikiToolbox(search + create + update + delete). The prompttold the agent to "search before write", but its workflow steps
landed equally on update vs create - and there was no instruction
to retry the search with different angles before falling back to
create.
There is no second agent. Articles only mutate from the per-
conversation agent's tool calls or from manual user edits.
=head2 Layer 2: what this PR changes, parallel to layer 1
Delete button. Drop the local
.dangerblock fromWiki.svelteand inline a comment explaining why. The globalrule wins; the button now reads "Delete" in light text on the red
fill, matching the Memories panel's delete styling.
Autonomous prompt. Rewrite
WIKI_AUTONOMOUS_PROMPT:discipline: UPDATE is the default, CREATE is rare." Plus an
explicit framing that zero edits is a normal outcome on
chitchat / tactical conversations.
multiple query angles" - at least TWO different
wiki_searchcalls with different phrasings before concluding nothing
exists. Includes concrete examples ("kombucha" might already
exist as "fermented drinks").
article is usually the right home for new information". The
goal is to extend rather than fragment.
wiki_createas "the lastresort", with three preconditions before firing.
The rationale block above the prompt now records the historical
"one article per conversation" failure mode so a future revisit
won't quietly relax the discipline.
Wiki librarian (the new agent):
profiles.wiki_librarian_last_run_atcolumn +claim_wiki_librarian_run(int)RPC. UPDATE-with-WHEREatomically returns true at most once per
min_interval_secondsacross all of a user's devices.
src/lib/agents/wiki-librarian/{types,prompt,agent, loop,worker,manager}.ts. Lock namenak:wiki-librarian-worker, lease partition'wiki-librarian', defaults to 12h minimum interval and a1h idle nap.
wikiLibrarianToolboxbundleswiki_search + wiki_update + wiki_delete + conversation_search. Nowiki_create - the librarian only consolidates.
listWikiArticles,project to
(id, title, excerpt), render into the prompt,run
runHeadlessToolLoop. Skips when fewer than 3 articles(
LIBRARIAN_MIN_ARTICLES) or when the cross-device claimreturned
too-soon.wikiLibrarianEnabledtoggle onSettings -> Wiki. Default-on. The two toggles(
wikiAutomaticEnabledandwikiLibrarianEnabled) areindependent so the user can run one without the other.
deepseek-v4-flash(same as the per-conversation wiki agent and journal/reflection); rationale
documented inline above
AGENT_MODELS.=head2 Layer 3: how that resolves PURPOSE
as every other delete button in the app.
articles. New article creation should be rare; chitchat
conversations should produce zero edits, which the prompt
explicitly names as a correct outcome.
per-conversation agent occasionally lets a duplicate slip
through, the librarian's 12h cycle catches it, consolidates,
and fact-checks against conversation history.
=head1 Notes for AI reviewers
wiki_create. New articlesflow from the per-conversation agent or the user. Removing this
constraint would let the librarian invent articles at every
cycle.
unconditional on
done(no change). With the strengthenedprompt, "no edits" cycles will be more common than before;
that's deliberate.
client-side timing is just an optimisation to not spam Postgres.
Two devices that both wake up will both call the RPC; only one
succeeds.
LIBRARIAN_MIN_ARTICLES = 3is a soft floor - the librarianhas nothing useful to do on a brand-new wiki with one or two
articles. Bump if you want.
https://claude.ai/code/session_015XcR7xzLdij66ZbYERUdLH
Generated by Claude Code