Skip to content

Add a language for the notes

The notes can be written in English (en) or Spanish (es). Adding another language is a data-only change: one entry in one file, no logic. This page is for a contributor who works from a copy of the source code; if you only want to choose between the two languages that exist, see Language of the notes.

The command line itself (messages, --help, errors) and the documentation stay English whatever language the notes are in.

What you change

Everything the program writes into the wiki, and everything it tells the model about the language, lives in the LANGUAGES dictionary in src/esbi_cli/lang.py. Nothing else in the code names a language.

  1. Copy the whole "en" entry and change its key to the language's code ("fr", "pt"...). The code is what a user writes in [notes].language.
  2. Translate the values. Leave the keys and the {placeholders} as they are: a label may be reordered, but each {name} must appear once, because the program fills it in.
Field What it is If you leave it empty
name The language's name in English, as the instruction to the model uses it (Write ALL text in French) Required
hint One more sentence appended to the instruction, for a language a small model needs help with. Add it only if a measurement shows a problem Nothing is added
relation_examples Short labels for how two ideas relate, written as the model should write them Required: the model copies this style
stopwords About twenty of the language's most frequent words, separated by spaces, to notice an answer in the wrong language The check is skipped: an answer in the wrong language is accepted. The worker never guesses
generic_terms Words too general to be a glossary entry (data, system, method...), separated by spaces, in the language's own words. A glossary term that is one of them is dropped Required: without it generic words fill the glossary
disclaimers A regular expression for a sentence that says there is nothing to say: a glossary definition that says it has none (not defined in the text), which is dropped, and a sentence of an sb ask answer that says the pages do not have the answer (there is no information), which the faithfulness check does not mark. Write the phrasings a small model uses, in this language Required: without it empty entries stay in the glossary, and sb ask marks "the pages do not say" sentences with ⚠
placeholders How a small model that copies the prompt's wording starts a summary ("Executive summary of ...") Required, but a short guess is fine
ask_example, rewrite_example A worked answer to show the model the exact format for sb ask and for the question rewrite. Written in the new language: a small model imitates it Required
labels Every heading and sentence written into the wiki: the sections of a note, the daily index, the lint and benchmark reports, the refusals of sb ask Required, all of them

These labels were added after the first two languages and are easy to forget (the test below fails if you do):

  • unsupported_footer: the line sb ask prints under an answer that has sentences the pages do not back (⚠ Not found in the cited pages: {words}). It takes one placeholder, {words}.
  • llm_down_one, llm_down_many: the first line of To review in the daily index when the last run could not reach the model ({at} is the time; llm_down_many also has {n}). stop_usd_budget: how the Runs line names a run that stopped at [run].max_usd_per_run.
  • concept_summary: the heading of the ## Summary on a concept or entity page.
  • not_read: the warning callout a note starts with when the call cap stopped the reading of a very long source (Not read: {unread} of {total} parts of the source (the last {percent}% of the text, starting at "{start}") because the limit of {max_calls} model calls per source ([run].max_calls_per_source) was reached.). It takes five placeholders: {unread}, {total}, {percent}, {start} and {max_calls}.
  • consolidate_review_name, consolidate_review_title, consolidate_review_footer: the review note written when a proposed summary fails its checks (named <page> - summary to review in English). The name has a {page} placeholder, the title a {link} one.
  • merge_review_name, merge_review_title, merge_review_footer: the review note that suggests two pages may be the same idea (<page> - possible merge), with the same two placeholders.

Check it

uv run pytest tests/test_lang.py

This fails if your entry lacks a key that en has, or if a label has different {placeholders} than the English one. Then try it on real material with a scratch vault (never your own):

sb init --vault /tmp/try --config-file /tmp/try.toml --language fr
sb add https://en.wikipedia.org/wiki/Zettelkasten --config /tmp/try.toml
sb run --config /tmp/try.toml

sb init --language accepts any code in LANGUAGES, and the error for a code that is not there lists the supported ones. Read the note: the headings, the daily index and the language of the prose. Then run sb bench on a few sources and look at the right language column: with the model you use, it should be 100% on the first try. If a small model keeps answering in the source's language, add a hint.

What you do not need to do

  • Teach the readers. A vault written in one language and read after switching to another still works: the privacy filters, sb ask, the read ticks and sb reingest recognise the headings of every language in LANGUAGES.
  • Change the prompts. They are in English for every language; only the language named in them changes.
  • Rewrite old notes. The worker never does. sb reingest --all rebuilds them in the new language.