Skip to content

feat(azure)!: Azure AI Search retrieval without On Your Data (3.0.0) - #195

Merged
owndev merged 10 commits into
mainfrom
feature/azure-search-pipeline-mode
Oct 10, 2026
Merged

owndev merged 10 commits into
mainfrom
feature/azure-search-pipeline-mode

Conversation

@owndev

@owndev owndev commented Oct 10, 2026

Copy link
Copy Markdown
Owner

Problem

Microsoft retires Azure OpenAI On Your Data on October 14, 2026. The Azure AI Search integration of azure_ai_foundry.py (up to 2.8.1) is built entirely on it: the pipeline adds data_sources to the chat request and Azure runs the search. After that date, chats configured with AZURE_AI_DATA_SOURCES are expected to fail or to be answered without the index.

On Your Data also had other limits:

  • it only supports GPT-4o / GPT-4o-mini;
  • it ignores the data source when tools are present;
  • it rejects stream_options.

This is step 2 of #187. Step 1, the notice in 2.8.1, was merged in #190.

Change (Azure AI Foundry 2.8.1 → 3.0.0)

The pipeline queries Azure AI Search itself and adds the hits to the prompt as [doc1]..[docN]. This works for every chat endpoint and model: Azure OpenAI deployments, Foundry /models, serverless and non-OpenAI models.

  • Configuration: the existing AZURE_AI_DATA_SOURCES JSON (azure_search) is read as the search configuration: endpoint, index, fields_mapping, query_type, semantic_configuration, filter, top_n_documents, strictness, in_scope, role_information, embedding_dependency, authentication.
  • Search:
    • Search REST 2026-04-01 for simple, semantic, vector, vector_simple_hybrid and vector_semantic_hybrid;
    • query vectors from embedding_dependency (/openai/v1/embeddings or an endpoint), or from the index vectorizer;
    • strictness is approximated per query, hits are merged and de-duplicated, then cut to top_n_documents and a token budget;
    • document text is sanitised against prompt injection.
  • Query generation, as On Your Data's "intent" step: on follow-up turns, the same deployment turns the conversation into search queries. Any failure falls back to the user's text, and after 3 timeouts in a row it pauses for that model. Valve AZURE_AI_SEARCH_QUERY_GENERATION: auto (default) | always | off.
  • Citations as before. The 2.x citation, [docX] link, relevance-score and history-unlink code runs on an On Your Data-shaped context built from the hits. API clients still receive context, in the first SSE event or in message.context. In tool rounds each source is emitted once.
  • Auth:
    • the new encrypted valve AZURE_AI_SEARCH_KEY, which wins over a key in the JSON;
    • access_token;
    • managed identity of the Open WebUI host, through the bundled azure-identity (system- or user-assigned).
  • Fail closed: search, embeddings or configuration errors end with Error: Azure AI Search: … and a terminal status. Nobody gets an answer without the documents.
  • Safety:
    • The retrieval cache is keyed per user, chat and message, and only reused by tool rounds of the same message.
    • Search and embeddings responses are size-limited at 16 MiB.
    • No key and no document text appears in the logs.
  • Now allowed in RAG chats: tools, tool_choice and stream_options.
  • New valves: AZURE_AI_SEARCH_KEY, AZURE_AI_SEARCH_API_VERSION, AZURE_AI_SEARCH_QUERY_GENERATION, AZURE_AI_SEARCH_MAX_CONTEXT_TOKENS. No released valve is renamed or removed.

BREAKING (hence 3.0.0)

  • data_sources sent by a client or an inlet filter now end the request with a clear error and are never forwarded.
  • With a managed identity, the Open WebUI host's identity calls Azure AI Search and needs the Search Index Data Reader role. The Open WebUI host must also reach the search service over the network.
  • Vector query types need embedding_dependency or an index vectorizer.
  • strictness, in_scope and role_information are applied by the pipeline and are approximations of On Your Data.
  • The 2.8.1 retirement warning is gone.

docs/azure-ai-integration.md has a "Migrating from On Your Data (2.x)" section with a checklist. Users who need On Your Data until Microsoft turns it off can stay on 2.8.1 (permalink).

E2E

  • New:
    • mocks/mock_search.py: Search and token endpoints with request recording;
    • embeddings and query-generation routes in mock_azure.py;
    • the rag group in suites/_azure_rag.py.
  • Removed:
    • the oyd group: every check whose behaviour still exists was ported to pipeline mode, the OYD-only checks were removed (the PR's commit history lists each one);
    • the On Your Data emulation of the mock;
    • all temporary markers.
  • Coverage: the azure suite grows from 75 to 198 checks. Among them is an in-process DEBUG-log check, because the server runs at INFO.

Verification

Run Result
All suites, v0.11.4-slim, normal and --strict-known 418 PASS, 0 FAIL, 1 KNOWN (infomaniak-name-prefix, no fix yet)
azure suite, v0.11.3-slim, normal and --strict-known 198 PASS, 0 FAIL, 0 KNOWN
Meta-test (E2E_MOCK_FAULT=500) 0 KNOWN
Helper and flow tests in a container (with -X dev) 112/112 and 83/83, no ResourceWarning
Mutation testing, 2.9.0 round (4 reviews) 32 findings fixed, among them nested-tag prompt injection, the per-user cache key, user-assigned MI parameter names (mi_res_id/msi_res_id), and size limits. All surviving mutants killed
Mutation testing, 3.0.0 round (3 reviews) 12 findings fixed, among them a stream-only data_sources bypass and a held-back link after [DONE]. All surviving mutants killed

The spec was built from Microsoft Learn: Search REST, embeddings, auth, and the On Your Data semantics. A critic reviewed it, and the maintainer decided its open points: pipeline only (no legacy mode), query generation auto, fail closed.

Not verified against real Azure

  • the managed-identity token requests on App Service, Container Apps, AKS and VMs;
  • whether models cite [docN] reliably with the prompt format;
  • the strictness thresholds against real scores;
  • the /openai/v1/embeddings route on every resource type behind API Management.

Please test with a real search index before release.

Closes #187

🤖 Generated with Claude Code

owndev and others added 10 commits October 9, 2026 14:50
Azure OpenAI On Your Data (data_sources) is retired on 2026-10-14 and
only works with gpt-4o on Azure OpenAI endpoints. The new default
AZURE_AI_SEARCH_MODE=pipeline reads the existing AZURE_AI_DATA_SOURCES
JSON, queries Azure AI Search itself (query generation for follow-up
turns, embeddings, strictness, merge, token budget), adds the documents
to the prompt and feeds an On-Your-Data-shaped context into the existing
citation code. RAG then works with every chat endpoint and model and
keeps tools and token usage; search and configuration errors fail
closed. AZURE_AI_SEARCH_MODE=on_your_data keeps the 2.8.1 behaviour.
New valves AZURE_AI_SEARCH_MODE, AZURE_AI_SEARCH_KEY (encrypted),
AZURE_AI_SEARCH_API_VERSION, AZURE_AI_SEARCH_QUERY_GENERATION and
AZURE_AI_SEARCH_MAX_CONTEXT_TOKENS. Refs #187.

+semver: minor

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2.9.0 defaults to pipeline mode, which would query the fake
mock-search host of the oyd valves instead of sending data_sources
(spec section 20.5).

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Azure pipeline 2.9.0 queries Azure AI Search itself instead of
sending data_sources to On Your Data, which Azure retires on
2026-10-14. Add the harness of spec section 20: an Azure AI Search
mock on port 9106 (with an App Service managed identity token endpoint
that run.sh points azure-identity at), query generation, embeddings,
tool calls and an emulated On Your Data retirement in the Azure mock,
and the azure rag group (suites/_azure_rag.py) with a check for every
behaviour of the pipeline mode. Before 2.9.0 the 112 tagged rag checks
are KNOWN azure-oyd-retired (known_azure.py); the oyd group and
tasks.title.oyd are pinned to AZURE_AI_SEARCH_MODE=on_your_data.

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ure-search-pipeline-mode

+semver: none

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

After the merge of the e2e branch the azure suite runs against 2.9.0: 194 checks
pass and the 112 rag markers are obsolete. The counts table described only the
2.8.1 state, and one oyd check failed once because Open WebUI 0.11.4 overwrites
a saved status when the initial title task writes the chat in parallel.

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The rag group and its log check add 119 azure checks and about three
minutes, so "about 300 checks in 7-10 minutes" no longer fits.

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of the unreleased 2.9.0 pipeline mode found real defects: a
user-assigned managed identity was requested with a parameter no token
endpoint knows (now mi_res_id on App Service / Functions / Container
Apps, msi_res_id on IMDS), nested tags could rebuild </documents>, the
tool-round cache ignored the user and served any request with the same
client-chosen message id, search and embeddings answers were read
without a size limit (now 16 MB, large JSON parsed off the event
loop), deeply nested query-generation JSON raised RecursionError
instead of falling back, chat-key reuse ignored the scheme, and an
empty AZURE_AI_SEARCH_MODE logged a warning. The docs gain migration
notes (network path, identity, api-version for stream_options) and the
e2e rag group gains checks that kill the surviving mutants, including
an in-process DEBUG log check of the pipe.

+semver: none

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

Main now carries the 2.8.1 On Your Data retirement notice as merged in #190;
the branch was built on that hotfix branch, so the merge only records it.

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ithout On Your Data

Microsoft retires Azure OpenAI On Your Data on 2026-10-14 (#187). The
pipeline already queries Azure AI Search itself and works with every
chat endpoint and model. Keeping a second On Your Data mode would mean
keeping and testing a path that stops working five days after the
release. So 3.0.0 drops it: nothing sends data_sources to Azure any
more. The unreleased AZURE_AI_SEARCH_MODE valve goes too, together with
the On Your Data paths: data_sources injection, include_contexts,
dropping tools and stream_options for data_sources, putting the search
key into data_sources, the 2.8.1 retirement notice and the retirement
hint on chat 400/404. Their dead helpers are removed as well.
AZURE_AI_DATA_SOURCES stays as the search configuration. The citation,
[docX] link, score and history-unlink code stays, fed by the pipeline's
own context.

The e2e oyd group goes away. Each of its checks whose behaviour still
exists now has a rag check of the same strength: split and parenthesised
links in API and browser streams, a dotted deployment, history
unlinking, a context event over 128 KiB, upstream events of 300 KB and
over 4 MiB, content null, and tasks without a websocket session. New checks
cover client data_sources (the error names the removal, nothing is
forwarded, an empty list is ignored) and a stale AZURE_AI_SEARCH_MODE
value, stored by a pre-release or set in the environment, which is
ignored. The mock's On Your Data emulation and the 137
azure-oyd-retired known-bug markers (known_azure.py) are dropped.

BREAKING CHANGE: Azure OpenAI On Your Data is no longer used. A request
body with data_sources (from an API client or an inlet filter) now ends
with "Error: Azure AI Search: data_sources in the request is not
supported: this pipeline no longer uses Azure OpenAI On Your Data
(removed in 3.0.0); ..." and is not forwarded. Data source types other
than azure_search are a configuration error, and so is an
AZURE_AI_DATA_SOURCES that is not valid JSON (2.8.x ignored it and
answered without the index). With a managed identity,
the Open WebUI host's identity now calls Azure AI Search and needs
Search Index Data Reader. The Open WebUI host must be able to reach the
search service. Vector query types need embedding_dependency or an index
vectorizer. strictness, in_scope and role_information are applied by
the pipeline and only approximate On Your Data. Every released valve
keeps its name. To keep On Your Data until 2026-10-14, stay on 2.8.1:
https://github.com/owndev/Open-WebUI-Functions/blob/3ff6cf9/pipelines/azure/azure_ai_foundry.py

+semver: major

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

The review of the On Your Data removal left six mutants alive in a full
azure run: a streamed request with data_sources answered from the valve's
search (only non-stream requests carried data_sources), the refusal
returned before the try without its ERROR line and terminal status, an On
Your Data hint appended to every chat 400/404, a held-back [docX] link sent
after data: [DONE], an answer citing only [doc9] saving no sources, and the
2.8.1 retirement notice logged again. Each now fails at least one check:
client data_sources in streamed API requests and in the browser path (the
inlet-filter case) with the exact error, the required ERROR line and the
only, final status; exact error texts for the chat 400 and
context_length_exceeded checks; parse_sse counts events after [DONE] and
the API stream checks require none; mock triggers bad-ref and mixed-ref
for references to documents that do not exist; rag.notice.none scans the
whole suite run; rag.log.debug refuses a streamed client request too.

The migration guide now covers Open WebUI hosts without a managed identity
(service principal or api_key, plus troubleshooting rows for the token and
azure-identity errors), index field names of the portal's Import data
wizard (content_fields, text_vector), putting the key back into
authentication.key when going back to 2.8.1, api-version 2024-10-21 in the
examples, and that only query_type values accept camel case. The citation
path loses the None fallback and defaults that only the removed On Your
Data callers used (no behaviour change, version stays 3.0.0).

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@owndev
owndev merged commit 4b80e24 into main Oct 10, 2026
8 checks passed
owndev added a commit that referenced this pull request Oct 10, 2026
Brings in Azure AI Foundry 3.0.0 (#195): pipeline-side Azure AI Search,
mocks/mock_search.py on 127.0.0.1:9106 and the azure rag group.
Conflicts: README.md and docs/testing.md keep both sides (counts table:
azure 198 from main, filters 101 from this branch). The azure docs, pipeline
and suite conflicted only through the criss-cross merge base; this branch
never changed them, so main's version is taken.

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
owndev added a commit that referenced this pull request Oct 10, 2026
main brought Azure AI Foundry 3.0.0 with the pipeline's own Azure AI
Search retrieval (#195): mocks/mock_search.py on 127.0.0.1:9106, the
managed identity variables in run.sh and the azure rag group.

The merge has two bases (3ff6cf9, 7ba3569); the Azure files, which this
branch never changed, are taken from main. config.py and serve_all.py
keep search 9106 next to tools 9111 and MCP 9112. BrowserSession.chat()
keeps tool_ids, tool_servers, extra_body, until and user_files next to
main's files and extra; parse_sse() collects the tool calling fields
and main's after_done counters. docs/testing.md keeps the gemini row,
the native tool calling section and the smoke section, takes main's
azure row and rag paragraphs, and combines the counts of both sides
(re-measured after the next merge).

+semver: none

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@owndev
owndev deleted the feature/azure-search-pipeline-mode branch October 10, 2026 17:48
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.

[Feature]: Azure AI Search (RAG) — migrate away from Azure OpenAI "On Your Data" (data_sources) before its retirement on October 14, 2026

1 participant