Skip to content

Gemini 1.20.0: Open WebUI 0.12 features, shared chats, thinking levels per model - #201

Merged
owndev merged 13 commits into
mainfrom
feature/gemini-1.20
Oct 11, 2026
Merged

owndev merged 13 commits into
mainfrom
feature/gemini-1.20

Conversation

@owndev

@owndev owndev commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

Why

After the Open WebUI 0.12 compatibility fixes (#199), the remaining 0.12 topics for the Gemini pipeline were:

  • the new features (context compaction between tool rounds, Tool Search, model controls, per-chat streaming);
  • the new shared chats with "Allow replies".

Checking them turned up two bugs and one gap. Two older weaknesses were found along the way.

Change (Google Gemini pipeline 1.19.1 → 1.20.0)

Open WebUI 0.12 features

  • Tool Search:
    • Before: Gemini could not call a tool found through search_tools. Open WebUI leaves deferred tools out of body["tools"], so the call was rejected as undeclared.
    • Now: the pipe declares every deferred tool (metadata["deferred_tools"]) that a search_tools result in the conversation names, from the next round on and in later turns. Name mapping applies as usual.
  • Context compaction: Open WebUI asks the chat model for the summary (task context_compaction).
    • Before: a failed or empty summary request returned the pipe's error text, e.g. Error generating content: 400 … or [No content generated]. Open WebUI then stored that text as the conversation summary (on 0.11 too).
    • Now: such an answer becomes empty, so Open WebUI uses its own summary, and one WARNING is logged.
    • Unchanged: compaction between tool rounds itself already produced valid Gemini requests (signatures, call/response pairing).
  • Model controls: Open WebUI 0.12 refuses them on pipe models (HTTP 400). Custom params (reasoning_effort, thinking_budget, include_thoughts) still reach the pipe.
  • Streaming: both per-chat and per-model "Stream Chat Response" work. The pipe's streamed tool round for stream=false chat requests is still needed on 0.11 and 0.12.

Shared chats with "Allow replies" (Open WebUI 0.12)

  • Before: participants got neither the chat's earlier generated images nor the owner's uploads for image edits, and the pipeline's generated images showed as broken (404) for them. The pipeline never linked its images to the chat, as Open WebUI's own image generation does.
  • Now the pipe uses Open WebUI's own checks:
    • Chats.get_accessible_chat_by_id(..., permission="write"): exactly what Open WebUI requires before it calls the pipe.
    • has_access_to_file(id, "read", user): the same as GET /api/v1/files/<id>/content.
    • Detection is by shape, not by version. On 0.11 the owner/admin rule is unchanged.
    • Generated images are linked to the chat (insert_chat_files), only for saved chats the user may continue.
  • Security review findings, all LOW and all fixed:
    • A file named by another participant's message is read only if that author may read it too. This closes a confused deputy: a participant could name a private file of the owner and get the derived image.
    • Linking re-checks the chat.
    • At most max(4 × IMAGE_HISTORY_MAX_REFERENCES, 8) history images are checked per request.
    • The chat check accepts only the chat itself, not any truthy value.

Thinking

  • Levels per Gemini 3 model, per Google's thinking docs:

    • gemini-3-flash, 3.5-flash-lite and 3.6-flash: minimal…high;
    • gemini-3.1-pro and 3.8-flash: low/medium/high;
    • gemini-3-pro: low/high.

    Before, every Gemini 3 text model was limited to low/high, so medium became high. Unknown Gemini 3 text models keep low/high.

  • Invalid per-chat values: a reasoning_effort that is not a string, or a thinking_budget that is not a number, is ignored with a warning. Before, it silently dropped the whole thinking config, including include_thoughts. A number sent as a string ("1024") is accepted.

Docs: the Gemini guide (Tool Search, compaction, shared chats, thinking levels), README, docs/testing.md. CLAUDE.md now also counts valve types as public API: since 0.12, saving a function validates its stored valves.

Tests

  • New gemini group owui012, 12 checks: compaction, compaction follow-up, summary error / empty / saved, Tool Search (also follow-up and mapped names), controls, custom params, per-chat and per-model streaming. On 0.11, a check of a 0.12 feature verifies what 0.11 does instead.
  • New gemini group shared:
    • On 0.12: real shares through Open WebUI's API (participant, group member, Clone-only viewer with a read-only folder, outsider, admin).
    • A test-only filter hands the pipe other chat ids and injects helper errors.
    • Security checks: deputy, link-chat, history-cap, pipe-truthy.
    • On 0.11: unsupported and legacy.
  • New in thinking: level-models, params-robust.
  • check_owui_api.sh: the import of the submodule open_webui.utils.access_control.files failed the static check, which looked for files as a name in __init__.py. A submodule is now ok, and the functions called on it or its alias are checked like methods. A missing method that the function looks up with getattr first is a WARN, not a FAIL: Chats.get_accessible_chat_by_id on 0.11.x. Results: 0.12.0, 0.11.4 and 0.11.3 all ok.
  • Mutation rounds: all mutants killed, both on the access logic (11) and on the security fixes (5).
  • Every new check fails on the code it guards against:
    • 1.19.1: 6 owui012 checks and 10 shared checks;
    • the pre-review state: the 4 security checks;
    • the pre-fix state: the 2 thinking checks.

Verification

Run Result
v0.12.0-slim, all suites, --strict-known 580 PASS, 0 FAIL, 0 KNOWN (1263 s)
v0.11.4-slim (default), all suites, --strict-known 565 PASS, 0 FAIL, 0 KNOWN (1213 s before the security fixes; 565/0/0 again after them)
v0.11.3-slim, all suites, --strict-known 565 PASS, 0 FAIL, 0 KNOWN (1786 s, host shared with other runs)
Meta-test (main 6b99dcf, E2E_MOCK_FAULT=500, gemini azure n8n infomaniak) 59 PASS, 402 FAIL, 0 KNOWN (595 s)
Smoke runner dry run (e2e Gemini mock) 15 PASS, 0 FAIL, 2 SKIP; key in no output
ruff format --check / ruff check (0.11.10) clean
CI on dd31038: v0.11.4 E2E, meta-test, API check (latest = 0.12.0); dispatched E2E on v0.12.0-slim (0e72790) all green

Known limits

  • Images generated before 1.20.0 are not linked to their chat. Participants still can't see them, and they are not sent for participants.
  • Open WebUI 0.12 lets a chat owner edit any message of a shared chat, or add one under a participant's user_id. A message forged that way counts as the participant's own. Closing this would also require the owner's access for participants' own messages; that is left as is.
  • Not verified against the real Gemini API: that it rejects undeclared calls, and that it accepts a turn whose earlier rounds were compacted. The mock models both.

🤖 Generated with Claude Code

owndev and others added 13 commits October 11, 2026 14:47
…bUI 0.12

Tool Search (Open WebUI 0.12, experimental): Open WebUI leaves tools with
long definitions out of body["tools"] (utils/middleware.py:3288-3295,
utils/tool_search.py:40-103), lists them in an <available_tools> block of
the system prompt and declares search_tools, which returns their
definitions; the model is expected to call a found tool by name, and Open
WebUI runs it from metadata["tools"]. Gemini only calls declared
functions, so the found tool could not be called (the mock answers
"undeclared function", the turn ended there). _build_function_declarations
now also declares every deferred tool (metadata["deferred_tools"]) that a
search_tools result in the messages names, with the spec from
metadata["tools"]; names are mapped like any other tool. A tool found in
one round is callable in the next round and in later turns while its
search result is in the history.

Context compaction: Open WebUI asks the chat's model for the summary
(utils/context_compaction.py:351-422, metadata task "context_compaction")
and takes the answer text as the conversation summary; before a reply it
saves it with the chat (context_compaction.py:122-128), and 0.12 also
compacts between tool rounds (utils/middleware.py:6299-6330). The pipe
answered a failed request ("Error generating content: 400 ...") or an
answer without text ("[No content generated]") with that text, which
then replaced the compacted messages, permanently when saved. pipe() is
now a thin wrapper around the former body (_pipe) that answers the
compaction task with an empty text in those cases, so Open WebUI falls
back to its own summary of the compacted messages (logged as a WARNING).

Version 1.20.0.

+semver: minor

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ecks

Open WebUI 0.12 lets a chat or folder be shared with "Allow replies", so
that its participants write in the owner's chat. The image history and
the file reads of the pipeline accepted only the owner or an admin, so a
participant's edit request lacked the chat's generated images.

With Open WebUI's own checks (detected by their shape: an async
Chats.get_accessible_chat_by_id with a permission keyword and an async
has_access_to_file), the pipeline now
- reads a saved chat's history when Open WebUI lets the user continue
  the chat: get_accessible_chat_by_id(chat_id, user, permission="write"),
  the check chat_completion makes before it calls the pipe (an admin
  only reads other users' chats in 0.12, so no longer continues them);
- reads a file of another user only for an admin or when
  has_access_to_file(file_id, "read", user) allows it, Open WebUI's own
  rule for file downloads;
- links its generated images to their chat message (chat_file), as Open
  WebUI does for its own image generation and uploads, so participants
  may read them in the web UI and in their image history.

Errors of the checks refuse. Older Open WebUI versions keep the owner /
admin rule unchanged.

+semver: minor

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
suites/_gemini_shared.py drives real shares on Open WebUI 0.12: a
participant (user grant, Allow replies), the owner after the participant
and a group member edit with every image of the chat; a Clone only
viewer (also with a read-only folder share) and an outsider are refused
by Open WebUI. A test-only global filter hands the pipe the chat without
Open WebUI's check, so the pipe's own check is tested for the admin, the
read-only viewer and the outsider, and injects errors into both access
helpers. Markdown links: the owner's upload of the shared chat is read,
foreign files are not (logged without their ids); Veo image-to-video.
On Open WebUI 0.11 the group reports that the feature is missing and
checks that the owner / admin rule stays.

With google_gemini.py 1.19.1 on v0.12.0-slim 10 of the 13 checks fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New group in suites/_gemini_owui012.py (12 checks, version-gated: on
Open WebUI 0.11 a check of a missing feature passes with "feature not in
Open WebUI <version>" and checks what that version does instead):

- compaction, compaction-followup: compaction between tool rounds with a
  threshold of 1 token; the summary request has no tools and the next
  request holds the summary, the user message and the kept rounds with
  their signatures; in a follow-up turn whose boundary falls into the
  earlier turn Open WebUI moves the user message before that turn's kept
  round (kinds= in the detail), the request stays valid
- summary-error, summary-empty (between tool rounds) and saved-summary
  (before a reply, also on 0.11): a failed (HTTP 400) or empty summary
  request leaves Open WebUI's fallback summary, not the pipe's error or
  placeholder text, also in the summary saved with the chat
- toolsearch, toolsearch-followup, toolsearch-mapped: search_tools and the
  <available_tools> list, the found tool declared and run in the next round,
  in the next turn, and an OpenAPI tool whose name needs mapping
- controls: 0.12 refuses model controls on a workspace model of a Gemini
  pipe model (HTTP 400); custom-params: the custom params a control would
  set reach the pipe from a workspace model and from the chat's Controls
- stream-chat, stream-model: tool turns with stream=false per chat and
  per model (Open WebUI sets stream=false for the model)

mock_gemini.py answers Open WebUI's compaction prompt with "MOCK-SUMMARY of
<call ids>" of the compacted section; triggers summary-400 and
summary-empty affect only that request.

With google_gemini.py 1.19.1 six checks fail on 0.12.0 (summary-error,
summary-empty, saved-summary and the three toolsearch checks); with 1.20.0
all pass on 0.12.0 and 0.11.4.

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The gemini row and a new "Shared chats" section describe the shared
group (13 checks on Open WebUI 0.12, shared.unsupported and
shared.legacy before), the test-only redirect filter and the mutation
round on the access logic. Counts per version (562 on v0.12.0-slim, 551
on v0.11.4-slim and v0.11.3-slim, all PASS in strict known mode), the
timing of a full run and the meta-test (58 PASS / 389 FAIL / 0 KNOWN)
as measured on 2026-10-11.

The Gemini guide says that generated images are linked to their chat on
every Open WebUI version and what an access check error refuses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…controls

google-gemini-integration.md: Tool Search (deferred tools found by
search_tools are declared from 1.20.0), context compaction during tool
runs (what Open WebUI sends after a compaction, the summary request and
the empty answer for a failed or empty summary, the reordering when the
boundary falls into an earlier turn), stream=false tool rounds on 0.12,
and the per-chat thinking parameters (reasoning_effort, thinking_budget,
include_thoughts) with the note that 0.12 model controls are refused for
pipe models. README: feature bullets.

testing.md: the gemini.owui012 group (checks, version gating, the mock's
compaction answer and triggers, the 1.19.1 failures and the no-stream
experiment), counts (gemini 178, all 561) and timing: all suites in strict
known mode 561 PASS / 0 FAIL / 0 KNOWN on v0.12.0-slim (1105 s),
v0.11.4-slim (1215 s) and v0.11.3-slim (1232 s); meta-test with main
6b99dcf 58 PASS / 399 FAIL / 0 KNOWN (527 s); smoke dry-run 15 PASS,
2 SKIP, 38 requests (76 s).

+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
…d valves)

Since Open WebUI 0.12, saving a function validates its stored valves against
the new Valves model (models/functions.py, utils/valves.py). A changed valve
type can therefore block the update for users who set that valve.

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ams no longer drop the thinking config

- Gemini 3 text models now get the thinking_level values Google lists per
  model (https://ai.google.dev/gemini-api/docs/thinking): gemini-3-flash,
  3.5-flash-lite and 3.6-flash "minimal".."high", gemini-3.1-pro and
  3.8-flash "low"/"medium"/"high", gemini-3-pro "low"/"high". Before, every
  Gemini 3 text model was limited to "low"/"high", so "medium" became "high"
  and "minimal" became "low". Unknown Gemini 3 text models keep "low"/"high".
- A reasoning_effort that is not a string, or a thinking_budget that is not a
  number, is ignored with a warning. Before, it raised inside the thinking
  setup and silently dropped the whole thinking config (include_thoughts
  too). A number sent as a string ("1024") is accepted.

New checks gemini.thinking.level-models and gemini.thinking.params-robust;
both fail with the previous pipeline.

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A file named by a message of another user (markdown link or file entry
  in the saved chain) is read only when that author may read it too, not
  only the user whose turn it is. Author of a user message: its user_id
  (Open WebUI 0.12 stores it for every message), else the chat owner, as
  Open WebUI reads it; of an answer: the author of its parent user
  message; unknown author: the file is not read. The requesting user's
  own messages, the current message and API histories keep the
  requester's rights. Up to Open WebUI 0.11 an admin continuing a user's
  chat no longer reads the admin's files named in the user's messages.
- Generated images (and Veo videos) are linked to a chat only when the
  user may continue it (_chat_to_link); the decision of the image
  history is reused within the request.
- At most 4 x IMAGE_HISTORY_MAX_REFERENCES (at least 8) images of earlier
  messages are looked at per request; accounts are fetched once per
  request (_RequestAccess).
- _may_continue_chat allows only the chat itself, not any truthy value.

Tests: gemini.shared.deputy, .history-cap, .link-chat, .pipe-truthy (the
test filter gains e2e-link and e2e-chat-truthy); imgedit.admin on 0.11.

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…shared group checks

- google-gemini-integration.md: a file named in another user's message is
  read only if that author may read it too (author = user_id, else the chat
  owner; answers = author of their user message), the cap on images of
  earlier messages, linking only to chats the user may continue, the 0.11
  admin case.
- testing.md: gemini.shared gains pipe-truthy, deputy, history-cap and
  link-chat (17 checks on 0.12), the filter markers e2e-link and
  e2e-chat-truthy, imgedit.admin on 0.11, the results of 3443671, the second
  mutation round and the counts (580 on v0.12.0-slim, 565 on v0.11.4-slim).
- README: the shared chat bullet.

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
check_owui_api.sh failed on google_gemini.py 1.20.0: "from
open_webui.utils.access_control import files" imports a submodule, which
the check looked for as a name in __init__.py. A submodule is now ok and
the functions called on it (or its alias) are checked like methods. A
missing method the function looks up with getattr first (feature
detection, Chats.get_accessible_chat_by_id on 0.11.x) is a WARN.

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@owndev
owndev merged commit b76e578 into main Oct 11, 2026
8 checks passed
@owndev
owndev deleted the feature/gemini-1.20 branch October 11, 2026 20:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant