Skip to content

v0.7.1 — the OpenWebUI v0.11.0 rebase, working chat attachments, and maintenance

  • operator
  • evaluator

Status: ready for the v0.7.1 tag. All four version strings are at 0.7.1 — the three that move together for the image tag (api/app/__init__.py, gateway/app/__init__.py, and info.version in the committed OpenAPI export), plus desktop/package.json and its lockfile for the separate desktop-v0.7.1 cut that follows it. See Release readiness.

This is a patch release. Nothing in it requires an operator to touch a working install, which is what makes it a patch under ADR 0025 rather than a minor. Its bulk is the quarterly web/ vendor-fork refresh: the OpenWebUI fork moves from upstream v0.9.2 to v0.11.0, the first refresh executed under the rebase runbook that ADR 0001 had asked for and never had. It also completes the already-contracted chat-attachment path in the web client: attached files now reach the model and show their ingestion state. The rest is dependency hygiene, release hardening, test cleanup, and a governance decision reaching ratification.

The through-line is deferred plumbing made operational: the fork was 1402 commits behind, the runbook did not exist, Dependabot was fighting the fork rather than serving it, and the web composer displayed attached files without sending their IDs. All four are addressed here.


Headline — the web/ fork moves to OpenWebUI v0.11.0 (#541)

Section titled “Headline — the web/ fork moves to OpenWebUI v0.11.0 (#541)”

The vendored OpenWebUI fork is rebased from v0.9.2 to v0.11.0, the quarterly refresh ADR 0001 mandates. 879 files changed, +187,454/−97,181 — every changed path under web/ except a single added line in docs/adr/0001-openwebui-fork-pin.md. That containment is the point: our LQ.AI code has no imports into upstream’s tree, so the refresh does not reach the api, the gateway, or the skills corpus. (#541)

It landed alongside the procedure that makes the next one repeatable:

  • The fork rebase runbook (docs/openwebui-rebase-runbook.md, 699 lines) — written against an actual merge dry-run rather than inferred, so it records what the inference got wrong. Its central correction: the documented git merge v0.11.0 cannot work (refusing to merge unrelated histories), and --allow-unrelated-histories is worse — it stages upstream’s tree at the repo root. The working procedure synthesises both upstream endpoints as web/-prefixed trees. (#539)
  • web/ Dependabot is scoped to security updates only. The fork tracks upstream; a Dependabot PR bumping a package upstream also bumps is a merge conflict waiting to happen. Version updates are off, security updates stay on. (#542)

What the rebase carries that no conflict marker announced: 15 new Alembic migrations, and the deletion of the 18-file legacy peewee migrations directory upstream removed. See Schema.


Chat attachments now reach the model (#402)

Section titled “Chat attachments now reach the model (#402)”

The web composer now sends attached file_ids with each chat message and polls uploads until they reach a terminal ingestion state. Status chips move from pending to ready or failed; failed files are excluded from the outgoing message; and uploads, polling, and draft attachment state are cancelled or reset when the user switches chats. The client also enforces the backend’s 16-file limit before send, with an inline explanation instead of a late 422 response. This completes the client half of the existing PRD §3.1 contract; the backend validation and context injection were already present. Frontend-only, with no schema, migration, configuration, or operator step. (#402)


  • Dependency group bumps across api/ and gateway/ — the api-minor-patch group twice (8 updates, then 4) and the gateway-minor-patch group twice (6 updates, then 4), covering pydantic-settings, starlette, alembic, greenlet, pymupdf, tiktoken, spacy, ruff, and mypy. (#550, #543, #513, #500)
  • cryptography 49.0.0 → 50.0.0 in the gateway, clearing a published advisory on the superseded version. (#516)
  • starlette’s gateway upper bound lifted to <1.5, paired with the api-side group bump so the two services resolve the same major. (#514, #513)
  • uvicorn[standard] requirement updated in both api and gateway. (#522, #517)
  • sqlalchemy[asyncio] requirement updated in the api. (#484)
  • pymdown-extensions → 11.0.2 in the web fork. (#538)
  • docker/login-action bumped in the release workflow. (#478)
  • langgraph excluded from the api-minor-patch Dependabot group, so a framework with its own upgrade cadence stops riding in on a routine group PR. (#546)

  • ADR 0026 ratified — Docling removed from near-term scope, the pluggable parser interface deferred. Confirmed by the committee at the 2026-08-23 call and flipped from Proposed to Accepted. The ADR also records something that cuts against its own case: the Flosters/lq-ai fork (“LegVolution”, an Argentine production deployment) repaired the Docling call site against the real 1.x API and runs it for scanned-PDF OCR. One operator does use Docling. That is recorded because the removal case leaned on Docling having never produced output, and the record should say so — it does not change the decision, since that operator had to fork the parser call site to get what an adapter seam would have handed them by configuration. DE-387 gains the fork as a working reference implementation. (#528)
  • The AG-01 retrieval-ownership closure is recorded across HONEST-STATE.md, PRD.md, and autonomous-layer.md, so the audit finding’s closure is documented where readers look rather than only in the PR that closed it. (#496)
  • The documented contributor workflow now matches the checks that actually run. CONTRIBUTING.md, the Makefile, CLAUDE.md, and the coding-agent onboarding guide are reconciled against the real gates — +140/−108 across four files. A contributor following the docs now runs what CI runs. (#505)
  • Release-range detection now ignores unreachable vendor tags. Both the runbook and release.yml choose the previous release only from tags reachable from the commit being released, so OpenWebUI’s own v0.9.2 and v0.11.0 tags can no longer turn the release range into 737 commits of unrelated upstream history. (#552)
  • Gateway tests share one example-environment fixture. The remaining issue-scoped copies were consolidated into gateway/tests/conftest.py, preserving test-specific overrides while removing five local definitions and the drift between them. Test cleanup only; runtime behaviour is unchanged. (#527)

  • A tailnet-hosted Ollama deployment recipe (deploy/tailnet-ollama/README.md, 174 lines) — how to point the gateway at an Ollama instance reachable only over a tailnet, keeping model inference on infrastructure the operator controls. (#510)

  • gateway: the config test fixture pins the remaining example environment variables, closing the last ambient-environment leak that let a developer’s shell change test behaviour. This finishes the job #443 started in v0.7.0. (#497)

Two people landed their first commit on main in this range.

Contributor What they landed

@Bhoomi-jain
four PRs — the AG-01 closure record (#496), the gateway config-fixture pin and shared-fixture cleanup (#497, #527), and the tailnet-Ollama deployment recipe (#510)
@katsugtgz
the pymdown-extensions bump in the web fork (#538)

And two came back. @pscripps, whose markdown-upload work landed in #206 back in June, returned to reconcile the contributor workflow with the checks that actually run (#505). @SaifAlYounan, who contributed release hardening and security fixes before v0.7.0, completed the web client’s chat-attachment path (#402).

The rest is maintainer work (@houfu) and Dependabot. Four human contributors on this patch, two of them new, continues the widening v0.7.0 recorded.


No LQ.AI schema change. The api’s Alembic head is unchanged at 0066 (0066_backfill_project_knowledge_bases), the same head v0.7.0 shipped.

The web/ fork gains 15 Alembic migrations from the upstream rebase, and loses the 18-file legacy peewee internal/migrations/ directory that upstream deleted. These are OpenWebUI’s own migrations against the OpenWebUI database, not ours. They apply automatically — web’s config.py calls command.upgrade(alembic_cfg, "head") at startup — so there is no operator step, which is what keeps this release a patch.

That is not the same as saying the upgrade is inert. One of the fifteen (461111b60977_add_missing_primary_keys_to_legacy_*) adds missing primary keys to legacy tables, which rewrites existing rows on first boot after the upgrade. An operator with a long-lived web database should expect the first web container start on v0.7.1 to take longer than usual, and should have a backup, as they should before any migrating upgrade.


Per ADR 0025 decision 1, api, gateway, web, and proxy share one release version — the image tag. This release moves api and gateway __version__ → 0.7.1. web/package.json now reads 0.11.0, tracking the OpenWebUI fork per ADR 0001 — it is not retitled to the release version, and the rebase is why the number moved.

Three strings, not two. The api version is also stamped into the committed OpenAPI export (docs/api/backend-openapi.generated.yaml → info.version, currently 0.7.0), so the bump needs a make openapi regeneration; test_generated_openapi_export_is_current (api/tests/test_openapi_export.py:31) fails otherwise. v0.7.0 recorded this as a follow-up; it is not in the release checklist yet.

Per ADR 0025 decision 3, this is a patch. Reading the 24 merged PRs against the standard — does a working install need a human to touch it after this upgrade? — nothing qualifies. No PR in the range carries the breaking-change label, and the three that do in project history (#396, #399, #400) all shipped in v0.7.0. #402 completes an existing client contract without changing backend configuration or requiring a migration, so it does not change that decision. The number is computed from what accumulated on main, not chosen from a milestone.

The desktop launcher versions independently. Per ADR 0025 decision 2 it carries its own desktop-vX.Y.Z tag and records the image set it ships against, so desktop/package.json moves 0.7.0 → 0.7.1 and desktop-v0.7.1 is cut after the v0.7.1 image set is published and verified — the launcher pulls those images, so the order is not interchangeable. Nothing in this range touched desktop/; the launcher is re-cut to ship against the new image set, not because its own code changed.


  • The remainder of the #288 audit stays open. No audit finding is closed in this release. Still outstanding: Medium — GW-02, GW-03, API-02, API-03, AG-02, D-02, E-05; Low — GW-05, AG-03, AG-04, D-03, E-03, the E-02 remainder (signing + packages:write still in the release job), E-04, E-06; Info — GW-06.
  • A fresh desktop install does not pin this image set. The launcher still ships imageTag: 'latest' (desktop/src/main/index.ts), so a new install runs the newest published images rather than the v0.7.1 set the .dmg was built against. ADR 0025 decision 2 asks for the opposite; changing the default is tracked with that work and does not land here. Pin LQ_AI_IMAGE_TAG in .env for a reproducible hand-run stack.
  • The macOS build is Apple-silicon only. desktop-release.yml runs on macos-14 and electron-builder.yml names no arch list, so the release publishes a single LQ.AI-0.7.1-arm64.dmg. Intel Macs are not served by the launcher.
  • Chat attachments are per-page draft state. #402 resets attachments safely when switching chats, but it does not restore them after a page reload. Persisting attachment state and replacing the two older route-specific polling loops remain follow-up work.

Unblocked. The version bump is prepared and the pre-flight below is satisfied.

Pre-flight, already satisfied:

  • api and gateway __version__ are both 0.7.1.
  • info.version in the committed OpenAPI export is 0.7.1, regenerated with make openapi; test_generated_openapi_export_is_current passes.
  • desktop/package.json and desktop/package-lock.json are both 0.7.1, resynced with no dependency churn.
  • No breaking-change-labelled PR merged since v0.7.0, so neither [allow-version-drift] nor [allow-breaking-in-patch] is needed.

Gates: api ruff/mypy + pytest; gateway ruff/mypy --strict + pytest; web check:lq-ai + vitest; the stack-boot smoke; and the version-consistency job (api == gateway == tag).

Steps (maintainer):

  1. Merge the version bump to legalquants/main.
  2. Tag v0.7.1 (annotated) on the merge commit and push it to legalquants — the Release workflow builds and signs the images and attaches the SBOM.
  3. Verify all published images carry the tag before going further (ADR 0025 decision 4 gates backend before frontend, but the intra-stage guarantee is partial).
  4. Then cut the launcher. Tag desktop-v0.7.1 and push it; desktop-release.yml runs on macos-14 and needs the five Apple signing secrets, all of which are set and working. Record the v0.7.1 image set it ships against (ADR 0025 decision 2). The order is not interchangeable — the launcher pulls the images, so they must be published and verified first.
  5. Verify the published .dmg, not the CI exit code. The runbook records that a watch command can report success on a failed run, so read the run’s conclusion field and then check the artifact itself — download the .dmg from the release and run spctl -a -vvv -t open --context context:primary-signature and xcrun stapler validate over it. Expect accepted / source=Notarized Developer ID / Developer ID Application: Tucuxi, Inc. (MC8BT9Z8GD), and “The validate action worked!” from stapler. A stapled-but-unsigned .dmg still fails Gatekeeper; both signature and staple are required.

  • The OpenAPI regeneration step is worth adding to the release checklist. Bumping api __version__ also requires make openapi, and docs/BUILD-AND-RELEASE.md does not yet say so. It is one line.
  • The runbook’s Apple-signing table is out of date. docs/BUILD-AND-RELEASE.md still marks three of the five signing secrets “⏳ pending”, written before the first successful cut and never updated. All five are working — desktop-release.yml has published a signed, notarized .dmg on every run through desktop-v0.7.0. A corrected runbook is drafted and not yet merged.

Drafted from the v0.7.0..main range on 2026-08-31 — 24 merged PRs, canon SHA e3625cce3, tag base 623a3b3f7. Every commit in the range was reconciled against GitHub’s merged-PR state; four (#402, #514, #528, #539) lost their (#N) suffix in squash and were matched through their merge commits. Version numbering per ADR 0025. Schema claims verified against the Alembic heads and web/backend/open_webui/config.py; contributor first-commit claims verified against git log main.