When a streamed reply from a Responses API connection stopped early, for example at the token limit or through a content filter, its token counts were lost. The chat showed no usage for that reply and the admin analytics recorded zero tokens for it. Such replies now keep the usage the provider reported, the same as replies that finished normally.
Fixes#33615
A note over 2 MB, which one pasted screenshot can reach because images are embedded in the note, opened as an empty page and discarded what you typed. Live editing of notes had its own 2 MB limit, smaller than what the server accepts in one transfer, so it refused to load such notes. That limit now matches the server's 16 MB transfer limit, so any note the server can receive opens and saves again.
Fixes#33606
With OpenTelemetry metrics on, a request for a URL the server has no API endpoint for was counted under its full address, so every distinct URL became a metric series of its own and the series count kept growing. When the web interface is not served (API-only setups) this happens for any unknown URL, such as bots probing for missing paths. With Starlette 1.3.1, the version pinned for source installs, it also happens for every page load, static file and websocket request, because that version tells the server nothing about which part of the app answered them. These requests are now counted without a URL label, while API requests keep theirs. Admins need to do nothing, as the old series stop growing and age out.
Fixes#33576
Saving the Sub-agents admin tab could turn sub-agents off and clear their system prompt when one of the limits was still 0. Older releases accepted 0 there, also from the SUBAGENTS_MAX_* environment variables, but the tab now fails to load such a value and shows everything blank and switched off, so saving writes that blank state back. A limit of 0 now shows as empty, meaning no limit, which matches what sub-agents already do with a 0 while they run.
Fixes#33609
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args: free_disk:false name:main suffix:]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_CUDA=true
USE_CUDA_VER=cu126
free_disk:true name:cuda126 suffix:-cuda126]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_CUDA=true free_disk:true name:cuda suffix:-cuda]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_OLLAMA=true free_disk:false name:ollama suffix:-ollama]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_SLIM=true free_disk:false name:slim suffix:-slim]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args: free_disk:false name:main suffix:]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_CUDA=true
USE_CUDA_VER=cu126
free_disk:true name:cuda126 suffix:-cuda126]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_CUDA=true free_disk:true name:cuda suffix:-cuda]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_OLLAMA=true free_disk:false name:ollama suffix:-ollama]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_SLIM=true free_disk:false name:slim suffix:-slim]) (push) Waiting to run
* fix: apply the document archive size guard to every zip file, not just named extensions
The decompression-bomb guard in the document loader only ran when the
filename extension or the declared content type matched a fixed list, so
an office archive renamed to a legacy or unknown extension (for example
an .xlsx saved as .xls, .bin, or served from a URL with no extension)
skipped the check entirely and was fully inflated in the worker. The
guard now detects zip archives by content and checks every one of them,
while non-archive files keep the previous behavior.
* refac: identify loader archives by content
The document loader now recognises archives by their content when checking their size.
Prompts could use the user's name and email but not their role, so role-aware system prompts needed a custom Filter function. Model system prompts, the user's own system prompt, saved prompts used with a slash command and chat requests through the API now replace {{USER_ROLE}} with the role, such as admin or user. Requested in #4765.
With native function calling, each model turn that calls tools counts as one iteration, and a single response was stopped with "Tool-call limit reached (256 iterations)." after 256 of them. The CHAT_RESPONSE_MAX_TOOL_CALL_ITERATIONS environment variable now defaults to 1024, also when it is set empty or to something that is not a number, and the error shows the new number. A model stuck calling tools in a loop now runs up to 1024 iterations before it is stopped; setting the variable to 256 keeps the old limit, and -1 still means no limit.
Adding, updating or removing knowledge base files through the API sent back the metadata of every file in the knowledge base, and so did renaming a knowledge base or changing its access. These calls got slower as the knowledge base grew, so bulk ingestion through the API lost speed with every batch. Adding or updating files now returns only those files, while removing a file, renaming or changing access returns an empty files list. API clients that read the files list from these responses now get only the affected files; the full list stays available, paginated, from `GET /api/v1/knowledge/{id}/files`. Timings with a local mock embedding server that answers instantly, median of 5 runs (at 1,000 files the per-file work of a batch still hides the difference):
| Files already in the knowledge base | Call | Before | After | Response size before | Response size after |
|---|---|---|---|---|---|
| 1,000 | batch add of 100 files | 519 ms | 528 ms | 437 KB | 39 KB |
| 10,000 | batch add of 100 files | 679 ms | 476 ms | 4.0 MB | 39 KB |
| 10,000 | single file add | 184 ms | 36 ms | 4.0 MB | 0.6 KB |
Closes#31397
When a tool returned an image, for example Open Terminal reading a PNG, a native tool or an MCP screenshot tool, the image was sent to the model even when the model has Vision turned off. A provider serving a text-only model rejects that request, so the reply failed with an error like "At most 0 image(s) may be provided in one prompt", and every later message in the chat failed the same way. With Vision off the model now gets a short "[image]" note in place of each tool image, including images already saved in the chat, so stuck chats work again. The images stay saved, so they reach the model again once Vision is turned on.
Fixes#32720
When the owner of a shared folder moved a chat a member created to another folder inside the shared folder, the chat lost the member's pin and dropped out of their Pinned list. The owner's move now keeps the member's pin, just as it already keeps the chat's unread status for them. Moving your own chat into a folder still unpins it, as before, so it shows up in that folder.
Fixes#33341