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.
- 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. - 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 linesb askprints 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_manyalso 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## Summaryon 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 reviewin 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 andsb reingestrecognise the headings of every language inLANGUAGES. - 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 --allrebuilds them in the new language.