Repository navigation
feat(gemini): thinking as Open WebUI's native, localized reasoning block (1.19.0) - #198
Merged
Merged
Conversation
…ng block
google_gemini.py 1.19.0. Answers without tool calls (streaming and
non-streaming, API path) now carry the thinking summary as
<details type="reasoning" done="true" duration="N">, so Open WebUI renders
it as its own reasoning item and writes the title in each user's language
("Thought for N seconds", "Nachgedacht fuer N Sekunden"). The summary
"Thought (Ns)" stays in every block for API clients and other renderers,
and the #176 history regex keeps matching both the old plain <details>
blocks and the new shape. No new valve.
- In a chat stream the thoughts so far are shown as a live done="false"
block through throttled replace events (every 0.4 s at most) instead of
the English "Thinking... <preview>" status; the first answer part sends
the finished block plus that part, then deltas as before. The thinking
status and its close are gone.
- A streamed thinking lasts from the first thought to the first answer
part (it used to include the answer time); non-streaming keeps the
request duration.
- A round that ends with tool calls clears its live block before Open
WebUI's output items take over; tool rounds and live mode are unchanged.
- Google Search grounding uses Open WebUI's own localized web search
statuses: web_search_queries_generated with the queries, then
web_search "Searched {{count}} sites" with items (no urls, which the
frontend would count instead).
Supersedes #160 (thanks @swarnat).
+semver: minor
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…atuses
- api / browser / thinking checks assert the 1.19.0 block shape
(type="reasoning", done="true", duration equal to the "Thought (Ns)"
summary) instead of the literal "<details>"; include-off checks for
"<details" so it cannot pass vacuously.
- thinking.strip keeps the legacy plain block; thinking.strip-reasoning
replays a real done="true" answer and a stopped done="false" block.
- thinking.live / thinking.duration (mock trigger paced-thinking): throttled
done="false" replace events, the switch to done="true" with all thoughts
on the first answer part, deltas after it, no thinking status, and a
duration up to the first answer part only.
- thinking.stop (slow-thinking): Stop while thinking saves the done="false"
block, and the next turn sends neither the block nor its thoughts.
- thinking.tool-round: a first round ending with a tool call clears its
live block; the saved turn has a reasoning item and no <details>.
- grounding.status: web_search_queries_generated with the queries, then
web_search "Searched {{count}} sites" with items and no urls.
- toolsapi.unchanged matches the new block shape (one line).
+semver: none
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
image.browser-preview / image.browser-ga check that the non-streamed answer of an image model starts with the <details type="reasoning" done="true"> block (duration = summary) followed by the text. +semver: none Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…19.0 - gemini 155 checks (6 new: thinking.strip-reasoning, thinking.live, thinking.duration, thinking.stop, thinking.tool-round, grounding.status), all 537 PASS / 0 KNOWN on v0.11.4-slim in strict mode (main ecac3fb plus 1.19.0); the gemini suite gives 155 / 0 on v0.11.3-slim too. - gemini row: the thinking block, the live block, its duration, Stop while thinking, the tool round and the search statuses; mock triggers paced-thinking and slow-thinking. - Timing of the full run (1147 s) and of the thinking group's browser scenarios (about 20 s); meta-test 57 PASS / 376 FAIL / 0 KNOWN; smoke dry run unchanged (15 PASS, 2 SKIP, 38 requests). - With google_gemini.py 1.18.0, 12 of the 32 checks of the affected groups FAIL. +semver: none Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
+semver: none Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> # Conflicts: # docs/testing.md
…pdates Gemini can repeat a web search query across the grounding metadata of a stream. Open WebUI keys the query chips of `web_search_queries_generated` by their text, and a duplicate key throws in its status component, so the pipe now removes duplicates. The Gemini mock repeats its query, and `grounding.status` expects it once. The docs said the live block updates "about every 0.4 seconds". It updates when new thoughts arrive, at most every 0.4 s. The tool calling section now names the `type="reasoning"` block for answers without tool calls. Both come from the review of the 1.19.0 change. +semver: none Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…7bcc +semver: none Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Why
Since 1.18.0, Gemini's thinking looked different depending on the chat:
<details><summary>Thought (5s)</summary>and showed the English statusThinking… <preview>. The duration also counted the answer time.#160 (@swarnat) proposed instance-wide valves for translating those texts. It was closed in favour of this change: Open WebUI's frontend already renders and localizes
<details type="reasoning">blocks per user, so no valve is needed. Thanks to @swarnat for raising it.Change (Google Gemini pipeline 1.18.0 → 1.19.0)
_thinking_details_blockwrites<details type="reasoning" done="true" duration="N">. Open WebUI shows "Thought for N seconds" in the user's language ("Nachgedacht für N Sekunden").<summary>Thought (Ns)</summary>stays for API clients and other renderers._THINKING_DETAILS_RE) is unchanged. It still strips the plain blocks of older chats, the new blocks, and a stoppeddone="false"block.done="false"block: Open WebUI's "Thinking..." with a spinner, plus the thoughts so far when expanded.replaceevents when new thoughts arrive, at most every 0.4 s.replaceswitches the block todone="true". The answer then continues aschat:message:delta.Thinking… <preview>status is gone.web_search_queries_generated: "Suche..." with the query chips; each query is sent once, because Open WebUI's keyed list throws on duplicates.web_search: "N Seiten durchsucht", withitemsand nourls, as Open WebUI's backend does.reasoning_content/reasoning_details);Verification
--strict-known(merged with main 2fc7bcc)--strict-knownE2E_MOCK_FAULT=500)--dry-run-mockcheck_owui_api.sh, ruff 0.11.10 check + format--file)gemini.grounding.statusFAIL (queries sent twice)Mutation round: 15 mutants of the new behaviour, all killed. They cover:
urls/itemsand the statuses;Against 1.18.0: 12 of the 32 checks in the affected groups fail.
Independent review: no blocking finding. The duplicate-query and docs findings are fixed in be4dab5.
Verified against the Open WebUI v0.11.4 sources:
utils/marked/extension.ts) andCollapsible.svelte;StatusItem.svelteand the de-DE translations;Collapsible.svelteof v0.9.0 has the same reasoning block, sorequired_open_webui_versionstays 0.9.0.Not verified yet
A real browser with a German UI and the real Gemini API (the maintainer tests before merge):
gemini-2.5-flashstreamed:Non-streaming (
GOOGLE_STREAMING_ENABLED=false): the finished block only.A grounded answer:
[n]citations and sources still there.Every site shows the same favicon, because Gemini's links are Google redirect URLs.
Stop while thinking: "Gedanke" without a spinner; the next message works.
An image model: the localized block above the image.
Supersedes #160.
🤖 Generated with Claude Code