From 97c9d0e7027d44e54bfaaa3ccbf9a5e2de361969 Mon Sep 17 00:00:00 2001
From: Paul Lizer
Date: Tue, 6 Oct 2026 14:58:00 -0400
Subject: [PATCH] Lead Enhanced extraction with its own V2 admin section
In V2 Admin Settings, "Enable Enhanced extraction" was buried in a collapsed
group of the Document Intelligence card, and Content Understanding was a
separate card that could be filled in while Enhanced was off, when it is never
called. Turning Enhanced on in V2 also left the mode on Standard, so Content
Understanding never ran.
- New Enhanced Extraction section (replaces content-understanding-section),
led by the switch as its capability. Mode, Auto sample pages, formula
extraction and the Content Understanding connection sit beneath it and are
hidden while it is off. Document Intelligence keeps only its connection.
- Engine notice names Content Understanding or the Document Intelligence
Layout fallback (and why) from the settings on screen.
- Schema vocabulary: on_enable (switch companions; moves Standard to Auto in
the draft and on the server), group open_until_set (opens the optional
Content Understanding connection while blank), flag support in Python
evaluate_dependency.
- content_understanding_supported runtime flag hides Content Understanding in
clouds without it; SettingsSection now receives runtime flags, so
flag-gated fields (Inbound MCP included) are no longer dropped.
- Document Intelligence connection test sends the mode only while Enhanced
is on.
- Classic pane gains the enhanced-extraction-section anchor only.
- Functional, TS logic and Playwright tests; docs, inventory and release
notes; version 0.261.260.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
---
.../single_app/admin_settings_fields.py | 342 +++++++++++++----
application/single_app/admin_settings_nav.py | 14 +-
application/single_app/config.py | 2 +-
application/single_app/route_backend_v2.py | 10 +-
.../templates/admin/_panes/extraction.html | 3 +-
.../admin/EnhancedExtractionEngine.tsx | 126 ++++++
.../src/components/admin/SettingsSection.tsx | 21 +-
application/v2_ui/src/lib/adminFields.ts | 73 ++++
application/v2_ui/src/lib/adminSections.ts | 9 +
.../v2_ui/src/lib/enhancedExtraction.ts | 69 ++++
.../v2_ui/src/pages/AdminSettingsPage.tsx | 42 +-
docs/_data/app_surface.yml | 8 +-
docs/admin/knowledge.md | 66 ++--
...NTENT_UNDERSTANDING_ENHANCED_EXTRACTION.md | 13 +-
.../features/V2_ADMIN_KNOWLEDGE_SETTINGS.md | 5 +
.../V2_ENHANCED_EXTRACTION_ADMIN_SECTION.md | 147 +++++++
docs/explanation/release_notes.md | 17 +
.../test_v2_admin_capability_placement.py | 6 +-
...st_v2_admin_enhanced_extraction_section.py | 361 ++++++++++++++++++
.../test_v2_admin_knowledge_extraction.py | 126 +++---
.../test_v2_admin_schema_vocabulary.py | 96 ++++-
.../test_v2_admin_section_logic.ts | 313 ++++++++++++++-
.../test_v2_admin_settings_schema.py | 8 +-
...st_v2_admin_enhanced_extraction_section.py | 197 ++++++++++
24 files changed, 1901 insertions(+), 173 deletions(-)
create mode 100644 application/v2_ui/src/components/admin/EnhancedExtractionEngine.tsx
create mode 100644 application/v2_ui/src/lib/enhancedExtraction.ts
create mode 100644 docs/explanation/features/V2_ENHANCED_EXTRACTION_ADMIN_SECTION.md
create mode 100644 functional_tests/test_v2_admin_enhanced_extraction_section.py
create mode 100644 ui_tests/test_v2_admin_enhanced_extraction_section.py
diff --git a/application/single_app/admin_settings_fields.py b/application/single_app/admin_settings_fields.py
index 374c9632f..ac81bc432 100644
--- a/application/single_app/admin_settings_fields.py
+++ b/application/single_app/admin_settings_fields.py
@@ -30,7 +30,7 @@
to the same normalizers the server-rendered form uses. Both interfaces
therefore agree on what a valid value is.
-Beyond a field's type, four optional descriptors shape how a section reads:
+Beyond a field's type, five optional descriptors shape how a section reads:
``group``
Names the cluster a field belongs to, either as a label or with a variant
@@ -40,6 +40,12 @@
Intelligence is a flat run of forty controls in which the credential that
makes the rest work is simply the last one.
+ A group may also name ``open_until_set``: a key in the same group whose
+ blank value opens the group while the section's capability is on. That is
+ for an optional connection the administrator most likely wants next --
+ Content Understanding under Enhanced extraction -- which cannot be marked
+ ``required`` because the capability works without it.
+
``depends_on``
Shows a field only while a condition holds. See ``evaluate_dependency`` for
the supported shapes; ``any_of`` exists because the Speech resource block is
@@ -59,6 +65,17 @@
input would otherwise save to a top-level key nothing reads. See
``_apply_nested_paths``.
+``on_enable``
+ Companion values a switch sets when it is turned on, as
+ ``{"set": {key: value}, "when": }``. Enhanced extraction is the
+ case: the extraction mode only matters while it is on, and turning it on
+ with the mode still on Standard would change nothing, so the mode moves to
+ Auto, which is what the server-rendered form has always done. The browser
+ applies it to the draft as the switch flips, so the new value is visible
+ before saving; ``_apply_enable_defaults`` applies it to a save that turns
+ the switch on without naming the companion, so an API client gets the same
+ result. A value named in the same save always wins.
+
The Appearance, Agents & Actions, Chat, Knowledge, Workflow, Workspaces and
Security groups are described in full. Sections with no entry here fall back to the V2 surface's
``enable_*`` scan, so undescribed groups keep working exactly as they did. A
@@ -1795,9 +1812,11 @@
# and then scrolls past everything that depends on the connection before
# reaching the connection itself.
#
- # Here the connection comes first and the behaviour that needs it follows,
- # declaring `requires` so a toggle flipped without a configured endpoint says
- # so rather than silently doing nothing.
+ # Here Document Intelligence is the connection and nothing else. It is needed
+ # whatever else is configured -- Standard extraction is its Read model, and
+ # Enhanced falls back to its Layout model -- so it comes first, and the
+ # settings that only matter once Enhanced extraction is on live in the
+ # section after it.
# ------------------------------------------------------------------
"document-intelligence-section": [
{
@@ -1815,8 +1834,9 @@
"label": "Connection",
"variant": "connection",
"help": (
- "Document Intelligence reads PDFs and images. Nothing else in this "
- "tab works until it is reachable."
+ "Document Intelligence reads PDFs and images. Standard extraction "
+ "is its Read model and Enhanced extraction falls back to its Layout "
+ "model, so nothing else in this tab works until it is reachable."
),
},
},
@@ -1886,11 +1906,15 @@
"test_type": "azure_doc_intelligence",
"test_payload": {
"enable_apim": {"key": "enable_document_intelligence_apim"},
+ # With Enhanced extraction off every document uses Standard,
+ # whatever mode is stored, so the test exercises Read too.
"document_intelligence_pdf_image_extraction_mode": {
- "key": "document_intelligence_pdf_image_extraction_mode"
+ "key": "document_intelligence_pdf_image_extraction_mode",
+ "when": {"key": "enable_enhanced_extraction", "equals": True},
},
"document_intelligence_auto_sample_pages": {
- "key": "document_intelligence_auto_sample_pages"
+ "key": "document_intelligence_auto_sample_pages",
+ "when": {"key": "enable_enhanced_extraction", "equals": True},
},
"direct.endpoint": {
"key": "azure_document_intelligence_endpoint",
@@ -1915,15 +1939,61 @@
},
"group": {"id": "connection", "label": "Connection", "variant": "connection"},
},
+ ],
+ # ------------------------------------------------------------------
+ # Knowledge / Document Extraction / Enhanced Extraction
+ #
+ # One card for the capability and everything it governs. Enhanced extraction
+ # used to be a switch inside the collapsed Extraction group of Document
+ # Intelligence, while Content Understanding -- the engine behind it -- was a
+ # card of its own that could be filled in with Enhanced off, where it is
+ # never called. The switch now leads this card, and every setting that only
+ # means something while it is on sits beneath it and is hidden while it is
+ # off, so the relationship is shown rather than remembered.
+ #
+ # Content Understanding stays optional: without it Enhanced uses Document
+ # Intelligence Layout, which still captures tables and checkbox states but
+ # does not describe figures. The engine notice says which applies. Its
+ # fields are also gated on the cloud, because the service is not offered in
+ # Azure Government or custom clouds; the server-rendered pane does the same
+ # with ``content_understanding_supported``.
+ # ------------------------------------------------------------------
+ "enhanced-extraction-section": [
+ {
+ "key": "enable_enhanced_extraction",
+ "type": "switch",
+ "label": "Enable Enhanced extraction",
+ "help": (
+ "Extracts tables, page structure, forms and checkbox states from PDFs "
+ "and images, and with Azure AI Content Understanding connected, "
+ "descriptions of figures and charts. The extraction mode and the "
+ "Content Understanding connection appear here once it is on. While it "
+ "is off, every document uses Standard extraction (Document "
+ "Intelligence Read)."
+ ),
+ "default": False,
+ "role": "capability",
+ "on_enable": {
+ # Enhanced with the mode still on Standard would change nothing.
+ # The server-rendered form moves to Auto at this point as well.
+ "set": {"document_intelligence_pdf_image_extraction_mode": "auto"},
+ "when": {
+ "key": "document_intelligence_pdf_image_extraction_mode",
+ "equals": "read",
+ },
+ },
+ },
{
"key": "document_intelligence_pdf_image_extraction_mode",
"type": "select",
"label": "PDF and Image Extraction Mode",
"help": (
- "Standard is Document Intelligence Read: fastest and cheapest for plain "
- "text. Enhanced captures tables, page structure, forms and checkbox "
- "states, at roughly six times the cost per thousand pages. Auto samples "
- "the first pages and picks."
+ "What new PDF and image uploads use. Standard is Document Intelligence "
+ "Read: fastest and cheapest for plain text. Enhanced captures tables, "
+ "page structure, forms and checkbox states, at roughly six times the "
+ "cost per thousand pages. Auto samples the first pages and picks. With "
+ "Standard selected, a document can still be extracted again as "
+ "Enhanced from its workspace."
),
"default": "read",
"options": [
@@ -1937,7 +2007,7 @@
"label": "Auto — sample first pages, then choose",
},
],
- "group": {"id": "extraction", "label": "Extraction", "variant": "behavior"},
+ "depends_on": {"key": "enable_enhanced_extraction", "equals": True},
},
{
"key": "document_intelligence_auto_sample_pages",
@@ -1951,53 +2021,63 @@
"default": 3,
"min": 1,
"max": 20,
- "group": {"id": "extraction", "label": "Extraction", "variant": "behavior"},
- "depends_on": {
- "key": "document_intelligence_pdf_image_extraction_mode",
- "equals": "auto",
- },
+ "depends_on": [
+ {"key": "enable_enhanced_extraction", "equals": True},
+ {"key": "document_intelligence_pdf_image_extraction_mode", "equals": "auto"},
+ ],
},
{
- "key": "enable_enhanced_extraction",
+ "key": "enable_document_intelligence_formula_extraction",
"type": "switch",
- "label": "Enable Enhanced extraction",
+ "label": "Extract mathematical formulas",
"help": (
- "Uses Azure AI Content Understanding, which returns tables, page "
- "structure, checkbox states and descriptions of figures and charts. "
- "Falls back to Document Intelligence Layout where Content Understanding "
- "is unavailable or unconfigured."
+ "Captures equations as LaTeX rather than approximate OCR text. It is a "
+ "billed add-on to the Document Intelligence Layout model, so it adds "
+ "per-page cost wherever Layout runs: Auto's page sampling, and Enhanced "
+ "extraction without Content Understanding. Standard and Content "
+ "Understanding extractions do not use it."
),
"default": False,
- "group": {"id": "extraction", "label": "Extraction", "variant": "behavior"},
+ "depends_on": {"key": "enable_enhanced_extraction", "equals": True},
},
{
- "key": "enable_document_intelligence_formula_extraction",
- "type": "switch",
- "label": "Extract mathematical formulas",
+ "type": "component",
+ "component": "enhanced-extraction-engine",
+ "label": "Extraction engine",
"help": (
- "Captures equations as LaTeX rather than approximate OCR text. This is a "
- "billed Document Intelligence add-on that adds per-page cost to every "
- "Enhanced extraction, and it has no effect while extraction is Standard."
+ "Which engine runs when a document is extracted as Enhanced, judged "
+ "from the settings on this page. Test the Content Understanding "
+ "connection to confirm it is reachable."
),
- "default": False,
- "group": {"id": "extraction", "label": "Extraction", "variant": "behavior"},
+ "depends_on": {"key": "enable_enhanced_extraction", "equals": True},
},
- ],
- # Its own section now. The card has always been in the extraction pane but
- # was missing from ADMIN_NAV, so neither interface could navigate to it.
- "content-understanding-section": [
{
"key": "azure_content_understanding_endpoint",
"type": "text",
"label": "Foundry Endpoint",
"help": (
"The Microsoft Foundry resource endpoint, with no trailing path. Leave "
- "blank and Enhanced extraction falls back to Document Intelligence "
- "Layout."
+ "it blank to use Document Intelligence Layout instead."
),
"default": "",
"placeholder": "https://your-resource.services.ai.azure.com",
- "group": {"id": "connection", "label": "Connection", "variant": "connection"},
+ "group": {
+ "id": "content-understanding",
+ "label": "Content Understanding connection",
+ "variant": "connection",
+ "help": (
+ "Optional. Azure AI Content Understanding backs Enhanced extraction "
+ "and adds descriptions of figures and charts. Without it, Enhanced "
+ "uses Document Intelligence Layout."
+ ),
+ # Starts open while unconnected, because it is the step most
+ # administrators want next after turning Enhanced on.
+ "open_until_set": "azure_content_understanding_endpoint",
+ },
+ "depends_on": [
+ {"key": "enable_enhanced_extraction", "equals": True},
+ {"flag": "content_understanding_supported", "equals": True},
+ ],
},
{
"key": "azure_content_understanding_authentication_type",
@@ -2012,18 +2092,58 @@
{"value": "key", "label": "Key"},
{"value": "managed_identity", "label": "Managed Identity"},
],
- "group": {"id": "connection", "label": "Connection", "variant": "connection"},
+ "group": {
+ "id": "content-understanding",
+ "label": "Content Understanding connection",
+ "variant": "connection",
+ },
+ "depends_on": [
+ {"key": "enable_enhanced_extraction", "equals": True},
+ {"flag": "content_understanding_supported", "equals": True},
+ ],
},
{
"key": "azure_content_understanding_key",
"type": "secret",
"default": "",
"label": "Content Understanding Key",
- "group": {"id": "connection", "label": "Connection", "variant": "connection"},
- "depends_on": {
- "key": "azure_content_understanding_authentication_type",
- "equals": "key",
+ "group": {
+ "id": "content-understanding",
+ "label": "Content Understanding connection",
+ "variant": "connection",
+ },
+ "depends_on": [
+ {"key": "enable_enhanced_extraction", "equals": True},
+ {"flag": "content_understanding_supported", "equals": True},
+ {"key": "azure_content_understanding_authentication_type", "equals": "key"},
+ ],
+ },
+ {
+ "type": "component",
+ "component": "connection-test",
+ "label": "Test Content Understanding connection",
+ "test_type": "content_understanding",
+ "test_payload": {
+ "endpoint": {"key": "azure_content_understanding_endpoint"},
+ "authentication_type": {
+ "key": "azure_content_understanding_authentication_type"
+ },
+ "key": {"key": "azure_content_understanding_key"},
+ "api_version": {"key": "azure_content_understanding_api_version"},
+ "analyzer_id": {"key": "azure_content_understanding_analyzer_id"},
+ "image_analyzer_id": {
+ "key": "azure_content_understanding_image_analyzer_id"
+ },
},
+ "group": {
+ "id": "content-understanding",
+ "label": "Content Understanding connection",
+ "variant": "connection",
+ },
+ "depends_on": [
+ {"key": "enable_enhanced_extraction", "equals": True},
+ {"flag": "content_understanding_supported", "equals": True},
+ ],
},
{
"key": "azure_content_understanding_api_version",
@@ -2031,7 +2151,15 @@
"label": "API Version",
"default": "",
"fallback_when_empty": True,
- "group": {"id": "analyzers", "label": "Analyzers", "variant": "advanced"},
+ "group": {
+ "id": "analyzers",
+ "label": "Content Understanding analyzers",
+ "variant": "advanced",
+ },
+ "depends_on": [
+ {"key": "enable_enhanced_extraction", "equals": True},
+ {"flag": "content_understanding_supported", "equals": True},
+ ],
},
{
"key": "azure_content_understanding_analyzer_id",
@@ -2039,7 +2167,15 @@
"label": "Document Analyzer",
"default": "",
"fallback_when_empty": True,
- "group": {"id": "analyzers", "label": "Analyzers", "variant": "advanced"},
+ "group": {
+ "id": "analyzers",
+ "label": "Content Understanding analyzers",
+ "variant": "advanced",
+ },
+ "depends_on": [
+ {"key": "enable_enhanced_extraction", "equals": True},
+ {"flag": "content_understanding_supported", "equals": True},
+ ],
},
{
"key": "azure_content_understanding_image_analyzer_id",
@@ -2047,29 +2183,18 @@
"label": "Image Analyzer",
"default": "",
"fallback_when_empty": True,
- "group": {"id": "analyzers", "label": "Analyzers", "variant": "advanced"},
- },
- {
- "type": "component",
- "component": "connection-test",
- "label": "Test Content Understanding connection",
- "test_type": "content_understanding",
- "test_payload": {
- "endpoint": {"key": "azure_content_understanding_endpoint"},
- "authentication_type": {
- "key": "azure_content_understanding_authentication_type"
- },
- "key": {"key": "azure_content_understanding_key"},
- "api_version": {"key": "azure_content_understanding_api_version"},
- "analyzer_id": {"key": "azure_content_understanding_analyzer_id"},
- "image_analyzer_id": {
- "key": "azure_content_understanding_image_analyzer_id"
- },
+ "group": {
+ "id": "analyzers",
+ "label": "Content Understanding analyzers",
+ "variant": "advanced",
},
- "group": {"id": "connection", "label": "Connection", "variant": "connection"},
+ "depends_on": [
+ {"key": "enable_enhanced_extraction", "equals": True},
+ {"flag": "content_understanding_supported", "equals": True},
+ ],
},
],
- # Also promoted out of the extraction card into a section of its own. It is
+ # Promoted out of the extraction card into a section of its own. It is
# independent of Enhanced extraction despite sitting inside it in the V1
# markup, which is what made it read as part of that feature.
"office-embedded-image-section": [
@@ -6495,23 +6620,30 @@ def get_nested_path_fields():
}
-def evaluate_dependency(dependency, read_value):
+def evaluate_dependency(dependency, read_value, runtime_flags=None):
"""Whether a ``depends_on`` condition holds, given a value reader.
``read_value`` takes a settings key and returns its current value, so the
same rules apply whether the caller is reading a stored document or a draft
that has not been saved yet.
- Four shapes are supported, and they compose:
+ Five shapes are supported, and they compose:
``{"key": k, "equals": v}`` k currently equals v
``{"key": k, "not_equals": v}`` k currently differs from v
+ ``{"flag": f, "equals": b}`` runtime flag f is b
``{"any_of": [...]}`` at least one nested condition holds
``{"all_of": [...]}`` every nested condition holds
``equals`` against a boolean compares truthiness rather than identity,
because a settings document written by the server-rendered form stores
checkbox state as the string ``"on"``.
+
+ A runtime flag is resolved by the server rather than read from the settings
+ document -- whether Content Understanding is offered in this cloud, say.
+ ``runtime_flags`` supplies them. Without it a flag condition counts as met,
+ as ``_dependency_is_satisfied`` treats it, so validation is never suppressed
+ for a field behind a gate the caller cannot see.
"""
if not dependency:
return True
@@ -6519,18 +6651,28 @@ def evaluate_dependency(dependency, read_value):
# A list means every condition has to hold. It is the shorthand the Security
# and Workspaces sections declare, and is equivalent to ``all_of``.
if isinstance(dependency, list):
- return all(evaluate_dependency(nested, read_value) for nested in dependency)
+ return all(
+ evaluate_dependency(nested, read_value, runtime_flags) for nested in dependency
+ )
if "any_of" in dependency:
return any(
- evaluate_dependency(nested, read_value) for nested in dependency["any_of"]
+ evaluate_dependency(nested, read_value, runtime_flags)
+ for nested in dependency["any_of"]
)
if "all_of" in dependency:
return all(
- evaluate_dependency(nested, read_value) for nested in dependency["all_of"]
+ evaluate_dependency(nested, read_value, runtime_flags)
+ for nested in dependency["all_of"]
)
+ if dependency.get("flag"):
+ if runtime_flags is None:
+ return True
+ expected = _coerce_bool(dependency.get("equals", True))
+ return bool(runtime_flags.get(dependency["flag"])) is expected
+
current = read_value(dependency["key"])
if "not_equals" in dependency:
@@ -7481,6 +7623,10 @@ def normalize_admin_settings_updates(updates, current_settings=None):
_check_acknowledgements(updates, current, errors)
+ # A switch turned on may bring companion values with it. Applied before the
+ # checks below so they judge the state that will actually be stored.
+ _apply_enable_defaults(normalized, current, warnings)
+
# "At least one" style constraints can only be judged once the whole payload
# is known, because the capability toggle and its selection may arrive apart.
_check_minimum_selections(normalized, current, errors)
@@ -7578,6 +7724,58 @@ def _check_planner_model_selection(normalized, current_settings, errors):
errors[key] = message
+def _apply_enable_defaults(normalized, current_settings, warnings):
+ """Set the companion values a switch declares through ``on_enable``.
+
+ The browser does this to its draft as the switch flips. Doing it here as
+ well means a save that turns Enhanced extraction on through the API without
+ naming a mode still moves Standard to Auto, rather than enabling a
+ capability that then changes nothing.
+
+ Only a transition counts: re-saving a switch that is already on leaves its
+ companions alone, and a companion named in the same save is the
+ administrator's explicit choice and always wins.
+ """
+ def merged(key):
+ if key in normalized:
+ return normalized[key]
+ if key in current_settings:
+ return current_settings[key]
+ # A key that has never been saved reads as its declared default, which
+ # is what get_settings would have merged in.
+ definition = get_field_definition(key) or {}
+ return definition.get("default")
+
+ for _section_id, field in iter_fields():
+ key = field.get("key")
+ effect = field.get("on_enable")
+ if not key or not effect or field.get("readonly"):
+ continue
+ if key not in normalized or not _coerce_bool(normalized[key]):
+ continue
+ if _coerce_bool(current_settings.get(key)):
+ continue
+ if not evaluate_dependency(effect.get("when"), merged):
+ continue
+
+ for companion, value in (effect.get("set") or {}).items():
+ if companion in normalized:
+ continue
+ normalized[companion] = value
+ companion_field = get_field_definition(companion) or {}
+ shown = next(
+ (
+ option.get("label", value)
+ for option in companion_field.get("options", [])
+ if option.get("value") == value
+ ),
+ value,
+ )
+ warnings[companion] = (
+ f'Set to "{shown}" because {field.get("label", key)} was turned on.'
+ )
+
+
def _apply_cross_field_rules(normalized, current_settings, warnings):
"""Reconcile settings whose valid range depends on another setting.
diff --git a/application/single_app/admin_settings_nav.py b/application/single_app/admin_settings_nav.py
index f63b48806..110461cb3 100644
--- a/application/single_app/admin_settings_nav.py
+++ b/application/single_app/admin_settings_nav.py
@@ -278,11 +278,15 @@
"icon": "bi-file-earmark-text",
"sections": [
{"id": "document-intelligence-section", "label": "Document Intelligence", "icon": "bi-file-earmark-text"},
- # These two cards have always existed in the extraction pane but
- # were absent from this list, so neither interface could
- # navigate to them. Their ids are the ones already in the
- # markup, so the server-rendered sidebar resolves them as-is.
- {"id": "content-understanding-section", "label": "Content Understanding", "icon": "bi-stars"},
+ # Enhanced extraction and the Content Understanding connection
+ # that backs it are one section, led by the switch. Content
+ # Understanding used to be a section of its own, which let it be
+ # configured while Enhanced was off and it could never run.
+ {"id": "enhanced-extraction-section", "label": "Enhanced Extraction", "icon": "bi-stars"},
+ # This card has always existed in the extraction pane but was
+ # absent from this list, so neither interface could navigate to
+ # it. Its id is the one already in the markup, so the
+ # server-rendered sidebar resolves it as-is.
{"id": "office-embedded-image-section", "label": "Images Inside Office Files", "icon": "bi-images"},
{"id": "chunk-size-section", "label": "Chunk Sizes", "icon": "bi-collection"},
# The upload ceiling belongs with the extraction pipeline it
diff --git a/application/single_app/config.py b/application/single_app/config.py
index 670ab4808..3a890675e 100644
--- a/application/single_app/config.py
+++ b/application/single_app/config.py
@@ -101,7 +101,7 @@
EXECUTOR_TYPE = 'thread'
EXECUTOR_MAX_WORKERS = 30
SESSION_TYPE = 'filesystem'
-VERSION = "0.261.259"
+VERSION = "0.261.260"
IS_DEVELOPMENT = is_development_env_enabled()
# Opt-out for deployments where App Service Easy Auth is active but the platform
diff --git a/application/single_app/route_backend_v2.py b/application/single_app/route_backend_v2.py
index 424079ae1..cb4e9f7ab 100644
--- a/application/single_app/route_backend_v2.py
+++ b/application/single_app/route_backend_v2.py
@@ -140,6 +140,7 @@
is_admin_settings_redacted_secret,
is_chat_file_upload_enabled_for_user,
is_chat_workflow_results_enabled_for_user,
+ is_content_understanding_supported_environment,
is_user_workflows_enabled_for_user,
is_workflow_assistant_enabled_for_user,
merge_model_endpoint_payload,
@@ -1409,7 +1410,14 @@ def v2_admin_get_settings():
# rather than a stored setting. Inbound MCP is gated by an
# App Service application setting, so its value cannot be
# read out of the settings document the SPA already holds.
- "runtime_flags": {"mcp_ui_enabled": is_mcp_ui_enabled()},
+ # Content Understanding is not offered in every Azure cloud,
+ # which only the server's AZURE_ENVIRONMENT can say.
+ "runtime_flags": {
+ "mcp_ui_enabled": is_mcp_ui_enabled(),
+ "content_understanding_supported": (
+ is_content_understanding_supported_environment()
+ ),
+ },
"suppressed_capabilities": get_suppressed_capability_keys(),
"version": VERSION,
}
diff --git a/application/single_app/templates/admin/_panes/extraction.html b/application/single_app/templates/admin/_panes/extraction.html
index 5030744d6..857acb69f 100644
--- a/application/single_app/templates/admin/_panes/extraction.html
+++ b/application/single_app/templates/admin/_panes/extraction.html
@@ -11,7 +11,8 @@ Document Intelligence
Configure Azure Document Intelligence settings. Document Intelligence always powers
Standard extraction and is required for workspaces and chat file uploads.
-