Tools and workspace content
This page lists what the seeder puts into Bebbi Bot on top of stock Open WebUI. The source of every item is a file under seeder/content/ in the kdkp-open-web-ui repository.
Tools, functions and skills in Open WebUI
Open WebUI separates two kinds of Python plugin. The official overview has the details.
- A tool is a Python class whose methods the language model can call. The method signature and docstring become the tool description the model reads. Examples here:
create_docx,search_web. - A function extends Open WebUI itself. It is one of three types. A pipe adds a model, a filter changes the request before it reaches the model and the response after it, and an action adds a button under a message.
Two other concepts show up below. A skill is a Markdown document of instructions that the model loads when a task needs it, instead of carrying it in every request. A tool server is an external MCP or OpenAPI service whose tools Open WebUI offers to the model.
Both tools and functions can declare valves, which are settings an admin edits in the UI and the seeder can pin from git.
Most seeded tools are attached to the Bebbi Bot models through meta.toolIds, so users get them without switching anything on.
Office files
The most used addition. Gemma 4 can write Markdown, but cantonal staff need Word, Excel, PowerPoint and PDF files in the canton's layout, and often need an existing file changed instead of rewritten.
Creating files
| Tool | Input | Output |
|---|---|---|
create_docx | Markdown and a title | Word file with the canton's template: numbered headings, table style, footer with page numbers |
create_pptx | Markdown, one ## heading per slide | PowerPoint deck from the canton's template layouts |
create_pdf | Markdown and a title | PDF, rendered from the Word layout |
create_xlsx | Rows and optional headers | Excel table with filters, frozen header row and sized columns |
The layout comes from the kdkp_office package in the custom image. The file is attached to the reply as a download.
The Excel tool compensates for a habit of the model. Gemma 4 sends numbers as strings in almost every call. The tool turns "1'250", "1.234,56" and "15 %" into real numbers with a number format, and Swiss and ISO dates into dates. It leaves postcodes, IDs, phone numbers and values with leading zeros as text, because they cannot be told from numbers by their value.
Editing files
A user attaches a Word, PowerPoint or Excel file and asks for a change. The model must not rebuild the file from its extracted text, which would lose the layout. The edit tools change only the affected spots and return a copy.
| File | Tools | What the user gets |
|---|---|---|
| Word | read_docx, edit_docx, render_docx | Changes as real tracked changes, with optional Word comments |
| PowerPoint | read_pptx, edit_pptx, render_pptx | Edited text. PowerPoint has no tracked changes, so the model names the changes in its answer |
| Excel | read_xlsx, edit_xlsx | Edited cell values and formulas, with the results of formulas calculated and reported |
The design borrows from coding agents:
- Read before edit.
read_*returns the file as text with numbered paragraphs and a version.edit_*refuses an edit without the current version, so paragraph numbers always refer to the file being edited. - Rewrite by paragraph number. The model sends the new wording of a whole paragraph. The tool compares old and new word by word and changes only what differs, so unchanged words keep their formatting and the model never has to copy text exactly.
- All or nothing. If one edit fails, nothing is written and the model gets the failing edits back.
- Self-check. For Word, rejecting all tracked changes must give back the original text. Every saved file must reopen and hold the written content.
- One copy per upload and chat. The first edit creates the copy, later edits overwrite it. This keeps the S3 bucket from filling up with intermediate versions.
- Render.
render_docxandrender_pptxreturn page and slide images that the model can look at, produced with headless LibreOffice.
The tools refuse files they would damage, for example workbooks with charts, pivot tables or macros, because the library that saves them would drop those parts. Each tool description lists its limits, and the model reads those descriptions.
Supporting content
- The filter
office_edit_hintis a global inlet filter. When a .docx, .pptx or .xlsx is attached and the matching edit tool is active, it adds a short note to the request that only the model sees: file name, available tools, and that a change request means returning the changed file. Without it, Gemma 4 often treated the attachment as a source to quote and answered in the chat. In the benchmark, three scenarios failed in every run before the filter. - The skills
dokumente-erstellenanddokumente-bearbeitenexplain which route to take, which formats suit which purpose and which Python libraries the code interpreter has. The models do not preload them. They see the list of skills and load one when needed. Attaching both to every message would cost about 3000 tokens per turn. - Two benchmark suites in the repository (
benchmarks/skills,benchmarks/office_edit) replay realistic requests against a running Open WebUI and check the traces and returned files. Run them after changing a tool, a prompt, the model or Open WebUI.
Web search
search_web replaces Open WebUI's built-in web search on the Web Suche models, for two reasons.
- The user reviews the query. Before anything leaves the infrastructure, a dialog shows the search query the model wrote. The user can edit it, remove sensitive details, or cancel. An empty query counts as a refusal, and the model is told to answer from its own knowledge. The banner of Bebbi Bot warns that personal data must not be entered when web search is on, and this dialog is the safeguard.
- The model reads pages, not snippets. The tool takes the top three results and scrapes them through Firecrawl (in the same namespace), strips images and link URLs, and cuts each page at 20,000 characters. A cut page is flagged to both the user and the model.
The search itself runs on Serper. The web search toggle of Open WebUI is off on all models, so this tool is the only route, and the janitor keeps user-built models from switching the toggle on.
Context usage
context_usage is a global filter. It adds a line under each answer with the tokens used and how full the context window is, for example when a long chat approaches the 256k limit of Gemma 4. Window sizes per model are valves of the function.
MCP tool servers
Open WebUI connects to external MCP servers over streamable HTTP, making their tools available to cantonal staff and models:
- Open Case Law (
mcp.opencaselaw.ch). Seeded viatool-servers/opencaselaw.json, offering tools to search Swiss federal and cantonal legislation and court decisions. The deep research agent uses it for legal research. - Statistik.bs MCP (
mcp.statistik.bs.ch/mcp). Indicator search, metadata, and time series from the statistical portal of Basel-Stadt, plus Excel web tables. - Data.bs.ch MCP (
mcp.data.bs.ch/mcp). Direct access to cantonal open government data (OGD), with ODSQL query and dataset metadata filtering. - Grosser Rat MCP (
mcp-grosserrat.statistik.bs.ch/mcp). Search and retrieval across parliamentary proceedings, motions, council minutes, and official records of the Grosser Rat Basel-Stadt since 1973.
For implementation details and endpoints of the Basel-Stadt servers, see the MCP section.
Built-in tools
Open WebUI 0.12 ships tools that the model can call without any setup: time and date, memory, task lists, sub-agents, the code interpreter and ask_user. Our models switch these on selectively and describe them in the system prompt, so the model uses them unprompted. Examples: it asks a clarifying question through ask_user instead of guessing, it runs numeric work in the code interpreter instead of doing arithmetic in its head, and it calls the date tool for "next Friday".
Switched off on our models: the built-in web search and image generation, notes, channels, calendar and automations. The code interpreter runs in the browser, and the image bundles its libraries. It is on by default in every chat (defaultFeatureIds), because Open WebUI only offers execute_code while the chat's code interpreter switch is on; the model-written Python runs in the user's browser (Pyodide), including in the web search models.
Prompts
Three slash commands are available to everyone:
| Command | Result |
|---|---|
/einfach | Rewrites a text in plain language, about CEFR level B1 |
/email | Drafts a polite email in German |
/checkliste | Turns a process description into a checklist |
How to add something
- Create the file in the matching folder of
seeder/content/of thekdkp-open-web-uirepository. The*.disabledexamples show the format. - For a tool, add its id to
meta.toolIdsof the models that should use it. The id is the file name in lowercase with underscores. - Run
mise run ci, merge tomain, bumpseeder.image.tagin the k8s repository. See Rolling out a change.
Python plugins run inside Open WebUI with full access to its internals, so only admins can create them. Some of our tools import Open WebUI modules directly, for example to store files. After an Open WebUI upgrade, check those imports against the list in the repository README. A renamed import fails when the tool runs, not when it loads, and the model then reports that the file could not be opened.
