diff --git a/application/single_app/admin_settings_nav.py b/application/single_app/admin_settings_nav.py index 00dd71d46..b5c8b5e6f 100644 --- a/application/single_app/admin_settings_nav.py +++ b/application/single_app/admin_settings_nav.py @@ -19,29 +19,35 @@ "icon": "bi-palette", "tabs": [ { - "id": "general", - "label": "General", - "icon": "bi-gear", + "id": "branding", + "label": "Branding", + "icon": "bi-palette", "sections": [ {"id": "branding-section", "label": "Branding", "icon": "bi-palette"}, {"id": "home-page-text-section", "label": "Home Page Text", "icon": "bi-house"}, {"id": "appearance-section", "label": "Appearance", "icon": "bi-brush"}, - {"id": "health-check-section", "label": "Health Check", "icon": "bi-heart-pulse"}, - {"id": "swagger-section", "label": "API Documentation", "icon": "bi-file-earmark-code"}, + ], + }, + { + # Everything the app states to the user before or during use: + # banners, notices and the agreements they must accept. + "id": "notices", + "label": "Notices & Agreements", + "icon": "bi-megaphone", + "sections": [ {"id": "classification-banner-section", "label": "Classification Banner", "icon": "bi-shield-exclamation"}, {"id": "ai-notice-section", "label": "Chat AI Notice", "icon": "bi-robot"}, {"id": "terms-of-use-section", "label": "Terms of Use", "icon": "bi-door-open"}, - {"id": "support-menu-section", "label": "Support", "icon": "bi-life-preserver"}, - {"id": "external-links-section", "label": "External Links", "icon": "bi-box-arrow-up-right"}, - {"id": "system-settings-section", "label": "System Settings", "icon": "bi-gear-fill"}, + {"id": "user-agreement-section", "label": "User Agreement", "icon": "bi-file-earmark-check"}, ], }, { "id": "custom-pages", - "label": "Custom Pages", + "label": "Pages & Links", "icon": "bi-window-plus", "sections": [ {"id": "custom-pages-section", "label": "Static Pages", "icon": "bi-file-earmark-richtext"}, + {"id": "external-links-section", "label": "External Links", "icon": "bi-box-arrow-up-right"}, ], }, ], @@ -93,7 +99,6 @@ "icon": "bi-cpu", "sections": [ {"id": "multi-endpoint-configuration", "label": "Model Endpoints", "icon": "bi-hdd-network"}, - {"id": "shared-conversation-file-approvals-section", "label": "Shared Conversation File Approvals", "icon": "bi-file-earmark-lock"}, {"id": "embeddings-config", "label": "Embeddings", "icon": "bi-vector-pen"}, {"id": "image-config", "label": "Image Generation", "icon": "bi-image"}, {"id": "gpt-config", "label": "Chat Model", "icon": "bi-chat-square-text"}, @@ -126,19 +131,25 @@ "icon": "bi-folder", "tabs": [ { - "id": "workspaces", - "label": "Workspaces", + "id": "workspace-types", + "label": "Workspace Types", "icon": "bi-folder", "sections": [ {"id": "personal-workspaces-section", "label": "Personal Workspaces", "icon": "bi-person"}, - {"id": "workflow-settings-section", "label": "Workflow", "icon": "bi-diagram-3"}, - {"id": "file-download-settings-section", "label": "File Downloads", "icon": "bi-download"}, {"id": "group-workspaces-section", "label": "Group Workspaces", "icon": "bi-people"}, {"id": "public-workspaces-section", "label": "Public Workspaces", "icon": "bi-globe"}, + ], + }, + { + # Who may take a file out of a workspace, and who must approve + # it first. + "id": "files-sharing", + "label": "Files & Sharing", + "icon": "bi-share", + "sections": [ + {"id": "file-download-settings-section", "label": "File Downloads", "icon": "bi-download"}, {"id": "file-sharing-section", "label": "File Sharing", "icon": "bi-share"}, - {"id": "metadata-extraction-section", "label": "Metadata Extraction", "icon": "bi-file-earmark-code"}, - {"id": "multimodal-vision-section", "label": "Multi-Modal Vision Analysis", "icon": "bi-eye"}, - {"id": "user-agreement-section", "label": "User Agreement", "icon": "bi-file-earmark-check"}, + {"id": "shared-conversation-file-approvals-section", "label": "Shared Conversation File Approvals", "icon": "bi-check2-square"}, ], }, { @@ -149,22 +160,65 @@ }, ], }, + { + # Workflow drives approvals and assignment across workspaces and is + # large enough to stand on its own rather than sit inside Workspaces. + "id": "workflow", + "label": "Workflow", + "icon": "bi-diagram-3", + "tabs": [ + { + "id": "workflow", + "label": "Workflow", + "icon": "bi-diagram-3", + "sections": [ + {"id": "workflow-settings-section", "label": "Workflow", "icon": "bi-diagram-3"}, + ], + }, + ], + }, { "id": "knowledge", "label": "Knowledge", "icon": "bi-search", "tabs": [ { - "id": "search-extract", - "label": "Search & Extract", - "icon": "bi-search", + # Reaching outside the tenant for material. + "id": "web-research", + "label": "Web & Research", + "icon": "bi-globe", "sections": [ {"id": "web-search-section", "label": "Web Search", "icon": "bi-globe"}, {"id": "url-access-section", "label": "URL Access", "icon": "bi-link-45deg"}, {"id": "source-review-section", "label": "Deep Research", "icon": "bi-binoculars"}, + ], + }, + { + "id": "search-index", + "label": "Search Index", + "icon": "bi-search", + "sections": [ {"id": "azure-ai-search-section", "label": "Azure AI Search", "icon": "bi-search"}, + ], + }, + { + # Turning a document into something searchable. + "id": "extraction", + "label": "Document Extraction", + "icon": "bi-file-earmark-text", + "sections": [ {"id": "document-intelligence-section", "label": "Document Intelligence", "icon": "bi-file-earmark-text"}, {"id": "chunk-size-section", "label": "Chunk Sizes", "icon": "bi-collection"}, + {"id": "metadata-extraction-section", "label": "Metadata Extraction", "icon": "bi-file-earmark-code"}, + {"id": "multimodal-vision-section", "label": "Multi-Modal Vision Analysis", "icon": "bi-eye"}, + ], + }, + { + # Voice and video are extraction pipelines, not chat features. + "id": "audio-video", + "label": "Audio & Video", + "icon": "bi-play-circle", + "sections": [ {"id": "video-intelligence-section", "label": "AI Video Intelligence", "icon": "bi-play-circle"}, {"id": "ai-voice-chat-section", "label": "AI Voice Conversations", "icon": "bi-mic"}, ], @@ -189,20 +243,40 @@ "icon": "bi-shield-lock", "tabs": [ { - "id": "security", - "label": "Security", - "icon": "bi-shield-lock", + # Who can get in and what role they need. Distinct from Content + # Safety, which is about what may be said once you are in. + "id": "access-roles", + "label": "Access & Roles", + "icon": "bi-person-check", + "sections": [ + {"id": "permissions-section", "label": "Permissions", "icon": "bi-person-check"}, + ], + }, + { + "id": "secrets", + "label": "Secrets", + "icon": "bi-safe", "sections": [ {"id": "keyvault-section", "label": "Key Vault", "icon": "bi-safe"}, ], }, { - "id": "safety", - "label": "Safety", - "icon": "bi-shield-check", + "id": "content-safety", + "label": "Content Safety", + "icon": "bi-shield-exclamation", "sections": [ {"id": "content-safety-section", "label": "Content Safety", "icon": "bi-shield-exclamation"}, - {"id": "permissions-section", "label": "Permissions", "icon": "bi-person-check"}, + ], + }, + { + # Interim home for the mixed System Settings card. Four of its + # eight fields are idle-timeout, which is the plurality; the + # rest are split out to their real homes in a later change. + "id": "session", + "label": "Session", + "icon": "bi-hourglass-split", + "sections": [ + {"id": "system-settings-section", "label": "System Settings", "icon": "bi-sliders"}, ], }, { @@ -348,12 +422,14 @@ }, { "id": "logging", - "label": "Logging", + "label": "Logging & Health", "icon": "bi-journal-text", "sections": [ {"id": "application-insights-section", "label": "Application Insights", "icon": "bi-graph-up"}, {"id": "debug-logging-section", "label": "Debug Logging", "icon": "bi-bug"}, {"id": "file-processing-logs-section", "label": "File Process Logging", "icon": "bi-file-earmark-text"}, + {"id": "health-check-section", "label": "Health Check", "icon": "bi-heart-pulse"}, + {"id": "swagger-section", "label": "API Documentation", "icon": "bi-file-earmark-code"}, ], }, ], @@ -363,6 +439,16 @@ "label": "Help", "icon": "bi-life-preserver", "tabs": [ + { + # Where an admin looks first when a user needs help, ahead of + # raising it with the project. + "id": "support-menu", + "label": "Support Menu", + "icon": "bi-life-preserver", + "sections": [ + {"id": "support-menu-section", "label": "Support", "icon": "bi-life-preserver"}, + ], + }, { "id": "send-feedback", "label": "Send Feedback", @@ -408,6 +494,18 @@ def get_group_for_tab(tab_id): return None +def get_landing_tab_id(): + """Return the tab an admin lands on when no tab is requested. + + This is the first tab of the first group rather than a fixed id, so the + landing pane follows the navigation map as cards are regrouped. Latest + Features is pinned last precisely so it can never win this. + """ + for _, tab in iter_tabs(): + return tab["id"] + return None + + def get_section_ids(): """Return every section target declared across the navigation.""" return [ diff --git a/application/single_app/app.py b/application/single_app/app.py index 35cc2d336..d8f837e33 100644 --- a/application/single_app/app.py +++ b/application/single_app/app.py @@ -31,7 +31,7 @@ from functions_content import * from functions_documents import * from functions_latest_features_nav import should_hide_latest_features_nav -from admin_settings_nav import ADMIN_NAV +from admin_settings_nav import ADMIN_NAV, get_landing_tab_id from functions_search import * from functions_settings import * from functions_mcp_server_config import is_mcp_ui_enabled @@ -600,6 +600,7 @@ def inject_settings(): user_settings=user_settings, custom_pages_nav=custom_pages_nav, admin_nav=ADMIN_NAV, + admin_landing_tab=get_landing_tab_id(), latest_features_current_version=VERSION, latest_features_nav_hidden=latest_features_nav_hidden, latest_features_nav_hidden_by_development=IS_DEVELOPMENT, diff --git a/application/single_app/config.py b/application/single_app/config.py index 0244ed3e0..992744396 100644 --- a/application/single_app/config.py +++ b/application/single_app/config.py @@ -96,7 +96,7 @@ EXECUTOR_TYPE = 'thread' EXECUTOR_MAX_WORKERS = 30 SESSION_TYPE = 'filesystem' -VERSION = "0.260.012" +VERSION = "0.260.014" IS_DEVELOPMENT = is_development_env_enabled() SESSION_COOKIE_SAMESITE = os.getenv('SESSION_COOKIE_SAMESITE', 'Lax') diff --git a/application/single_app/static/js/admin/admin_data_management.js b/application/single_app/static/js/admin/admin_data_management.js index 481b2069f..e8c2761a9 100644 --- a/application/single_app/static/js/admin/admin_data_management.js +++ b/application/single_app/static/js/admin/admin_data_management.js @@ -388,7 +388,8 @@ function bindEvents() { pendingDataManagementBackupDelete = null; }); elements.dataManagementConfirmBackupDeleteBtn?.addEventListener("click", deleteDataManagementBackup); - elements.dataManagementKeyVaultLink?.addEventListener("click", openKeyVaultSettings); + // The Key Vault link carries data-admin-link, so admin_card_links.js + // resolves the owning tab from the DOM and scrolls to the card. elements.dataManagementCosmosEditorOpenDangerBtn?.addEventListener("click", showCosmosEditorDangerModal); elements.datamanagementcosmoseditordangeraccept?.addEventListener("change", updateCosmosEditorDangerAcceptState); elements.dataManagementCosmosEditorAcceptDangerBtn?.addEventListener("click", acceptCosmosEditorDanger); @@ -909,20 +910,6 @@ function setKeyStorageAlert(variant, iconClass, title, message, linkText) { setText(elements.dataManagementKeyVaultLink, linkText); } -function openKeyVaultSettings(event) { - event?.preventDefault(); - const securityTabButton = document.getElementById("security-tab"); - if (securityTabButton && window.bootstrap?.Tab) { - window.bootstrap.Tab.getOrCreateInstance(securityTabButton).show(); - } else if (securityTabButton) { - securityTabButton.click(); - } - window.location.hash = "security"; - window.setTimeout(() => { - document.getElementById("keyvault-section")?.scrollIntoView({ block: "start", behavior: "smooth" }); - }, 100); -} - function collectSettings() { const backupStorageAuthenticationType = getValue(elements.datamanagementstorageauth) || backupStorageAuthManagedIdentity; return { diff --git a/application/single_app/static/js/admin/admin_sidebar_nav.js b/application/single_app/static/js/admin/admin_sidebar_nav.js index edad020d8..7e9538f73 100644 --- a/application/single_app/static/js/admin/admin_sidebar_nav.js +++ b/application/single_app/static/js/admin/admin_sidebar_nav.js @@ -145,12 +145,15 @@ function initAdminSidebarNav() { // Set the initial active tab - but only if no tab is already active. // Latest Features is deliberately excluded so it never opens by default. + // The landing tab is whichever tab the nav map renders first rather than a + // hardcoded id, so it stays correct as the information architecture moves. const activeTab = document.querySelector('.admin-nav-tab.active, .admin-nav-section.active'); if (!activeTab) { - const firstTab = document.querySelector('.admin-nav-tab[data-tab="general"]'); - if (firstTab) { + const firstTab = document.querySelector('.admin-nav-tab[data-tab]'); + const firstTabId = firstTab ? firstTab.getAttribute('data-tab') : null; + if (firstTabId) { firstTab.classList.add('active'); - showAdminTab('general'); + showAdminTab(firstTabId); } } else { console.log('initAdminSidebarNav - Found existing active tab, preserving current state:', activeTab.getAttribute('data-tab')); @@ -288,6 +291,11 @@ function revealAdminGroupForTab(tabId) { const LEGACY_TAB_REDIRECTS = { 'governance': 'feature-governance', 'scale': 'redis-caching', + 'general': 'branding', + 'safety': 'access-roles', + 'security': 'secrets', + 'workspaces': 'workspace-types', + 'search-extract': 'web-research', }; function resolveAdminTabId(tabId) { diff --git a/application/single_app/templates/admin/_panes/access-roles.html b/application/single_app/templates/admin/_panes/access-roles.html new file mode 100644 index 000000000..3e93d9ff7 --- /dev/null +++ b/application/single_app/templates/admin/_panes/access-roles.html @@ -0,0 +1,49 @@ +
+
+
+ Permissions +
+

Control which users can access specific administrative views related to safety and feedback.

+ + +
+ + + +
+

+ Required app role value: SafetyViolationAdmin. Assign this role to users or groups in the Enterprise App before enabling the requirement. If disabled, any user with the general Admin app role can access the Safety Violations admin page. +

+ + +
+ + + +
+

+ Required app role value: FeedbackAdmin. Assign this role to users or groups in the Enterprise App before enabling the requirement. If disabled, any user with the general Admin app role can access the User Feedback admin page. Requires Enable User Feedback to be active. +

+
+ + + + +
diff --git a/application/single_app/templates/admin/_panes/agents.html b/application/single_app/templates/admin/_panes/agents.html index 5994976d2..622dde43d 100644 --- a/application/single_app/templates/admin/_panes/agents.html +++ b/application/single_app/templates/admin/_panes/agents.html @@ -1,4 +1,4 @@ -
+

Configure AI agents and actions for enhanced functionality. Agents provide AI-driven task automation while Actions extend functionality with custom tools and integrations. diff --git a/application/single_app/templates/admin/_panes/ai-models.html b/application/single_app/templates/admin/_panes/ai-models.html index f12b06236..98e6590d4 100644 --- a/application/single_app/templates/admin/_panes/ai-models.html +++ b/application/single_app/templates/admin/_panes/ai-models.html @@ -1,4 +1,4 @@ -

+

Configure all AI model settings including GPT for text generation, embeddings for semantic search, and image generation capabilities. @@ -235,27 +235,6 @@

Global Endpoints
{% endif %}
- -
-
- Shared Conversation File Approvals -
-

Files generated by participants in a shared conversation are saved into the conversation owner's storage. When enabled, those files are held until an approver releases them.

-
- - - -
-
-
diff --git a/application/single_app/templates/admin/_panes/archiving.html b/application/single_app/templates/admin/_panes/archiving.html index 0d56b6223..d2943f47d 100644 --- a/application/single_app/templates/admin/_panes/archiving.html +++ b/application/single_app/templates/admin/_panes/archiving.html @@ -1,4 +1,4 @@ -
+
Conversation Archiving diff --git a/application/single_app/templates/admin/_panes/audio-video.html b/application/single_app/templates/admin/_panes/audio-video.html new file mode 100644 index 000000000..fba46cabe --- /dev/null +++ b/application/single_app/templates/admin/_panes/audio-video.html @@ -0,0 +1,472 @@ +
+
+
+
+
+ +
+
+

+ AI Video Intelligence +

+

Extract insights and make video content searchable and interactive

+
+
+ +
+ +
+ + Make Video Content Fully Searchable: Upload videos to your workspace and automatically extract transcripts, identify speakers, detect topics, and generate searchable timestamps. Your AI can then answer questions about video content, cite specific moments, and provide deep insights. +
+ + +
+
+ + +
+

+ Upload video files (MP4, AVI, MOV, etc.) to workspaces where Azure Video Indexer automatically processes them. + Extract spoken content, identify speakers, detect faces, recognize brands, and generate searchable metadata—perfect for meetings, presentations, training videos, and recorded content. +

+
+ + Full-Text Search + + + Speaker ID + + + Timestamped Citations + + + Multi-Language + +
+
+ + {% set public_video_indexer_endpoint = "https://api.videoindexer.ai" %} + {% set government_video_indexer_endpoint = "https://api.videoindexer.ai.azure.us" %} + {% set configured_video_indexer_endpoint = settings.video_indexer_endpoint or default_video_indexer_endpoint %} + {% if configured_video_indexer_endpoint == government_video_indexer_endpoint %} + {% set video_indexer_cloud = "usgovernment" %} + {% elif configured_video_indexer_endpoint == public_video_indexer_endpoint %} + {% set video_indexer_cloud = "public" %} + {% else %} + {% set video_indexer_cloud = "custom" %} + {% endif %} + {% if azure_environment == "usgovernment" %} + {% set azure_environment_label = "Azure Government" %} + {% elif azure_environment == "custom" %} + {% set azure_environment_label = "Custom Cloud" %} + {% else %} + {% set azure_environment_label = "Azure Public / Commercial" %} + {% endif %} + + +
+
+ Azure Video Indexer Configuration +
+

Connect to your Azure Video Indexer resource for advanced video processing and content extraction.

+ +
+ Identity overview: +
    +
  • Video Indexer can use its own managed identity to reach the linked Storage account during account creation.
  • +
  • SimpleChat authenticates to Video Indexer with the App Service system-assigned managed identity.
  • +
  • The App Service managed identity must have Contributor on the Video Indexer resource.
  • +
  • See Azure Video Indexer documentation for setup details
  • +
+
+ +
+ + +
Choose the endpoint family that matches your deployed cloud. Use Custom only when you need a non-standard Video Indexer endpoint.
+
+ +
+ Current App Service environment: {{ azure_environment_label }}. This selector saves the Video Indexer API endpoint. If you are switching between Azure Public, Azure Government, or a custom cloud, update AZURE_ENVIRONMENT in your App Service configuration as well. +
+ +
+ The selected Video Indexer cloud does not match this app's current AZURE_ENVIRONMENT. Update the App Service configuration if you are moving to a different cloud. +
+ + + +
+ + +
Only required when using a custom cloud or non-standard Video Indexer endpoint.
+
+ +
+ + +
Saved endpoint value used for Video Indexer API calls.
+
+ +
+ + +
The Azure resource group containing your Video Indexer account
+
+ +
+ + +
Your Azure subscription ID
+
+ +
+ + +
The name of your Video Indexer account resource
+
+ +
+ + +
Azure region where your Video Indexer account is deployed (e.g., eastus, westus2, northeurope)
+
+ +
+ + +
Found in the Video Indexer account Overview page in Azure Portal
+
+ +
+ + +
Default for {{ azure_environment_label }}: {{ default_video_indexer_arm_api_version }}
+
+ +
+ + +
+
+
+ + +
+
+
+
+ +
+
+

+ AI Voice Conversations +

+

Transform your AI experience with natural voice interactions

+
+
+ +
+ + +
+
+ + +
+

+ Let users opt in to a bundled sound when an AI response finishes outside their active view. + These local cues do not require Azure Speech Service. +

+
+ +
+ + One Speech resource, three features: Audio file uploads, Voice Input, and Voice Responses all use the same Azure Speech Service section below. Configure the Speech resource once, then turn on whichever speech features you need. +
+ + +
+ {% set audio_runtime = audio_runtime_capabilities or {} %} + {% set audio_supported_extensions = audio_runtime.supported_extensions or [] %} + {% set audio_direct_extensions = audio_runtime.direct_transcription_extensions or [] %} +
+ + +
+

+ Upload audio files (MP3, WAV, M4A, etc.) to workspaces where they're automatically transcribed and indexed. + The AI can then search, analyze, and answer questions about audio content—perfect for meetings, interviews, lectures, and podcasts. +

+
+
+ {{ audio_runtime.message or 'Audio runtime support has not been checked yet.' }} +
+
+ Supported audio upload extensions: {{ audio_supported_extensions|join(', ') }} +
+ {% if audio_direct_extensions %} +
+ Without FFmpeg, source-file fallback is best for: {{ audio_direct_extensions|join(', ') }}. Container builds can include FFmpeg for broader codec support. +
+ {% endif %} +
+
+ + +
+
+ + +
+

+ Talk to your AI instead of typing. Record voice messages up to 90 seconds directly in the chat interface. + Azure Speech Service instantly transcribes your speech with high accuracy, supporting multiple languages and accents. +

+
+ + Hands-Free + + + Accessible + + + Fast Input + +
+
+ + +
+
+ + +
+

+ Hear AI responses read aloud in natural, human-like voices powered by Azure's advanced neural Text-to-Speech. + Each message includes a speaker button—click to listen while multitasking, commuting, or whenever reading isn't convenient. +

+
+ + Natural Voices + + + Multitask-Friendly + + + Multi-Language + +
+
+ + +
+
+ Azure Speech Service Configuration +
+

Configure the shared Azure Speech resource used by audio transcription, voice input, and text-to-speech.

+ +
+ Shared configuration: These settings apply to all enabled speech features. If you use managed identity and also enable Voice Responses, fill in the Speech Resource ID field so the Speech SDK can authenticate synthesis requests. +
+ +
+ + +
Use the resource-specific custom-domain endpoint when selecting Managed Identity.
+
+ +
+ + +
Required for speech recognition locale defaults and for text-to-speech when using Managed Identity.
+
+ +
+
+ Resource ID builder: If the full ARM resource ID is hard to find in the portal, enter the subscription ID, resource group, and Speech resource name below. Simple Chat can build the resource ID for you. +
+ +
+
+ + +
+
+ + +
+
+ + +
If you use a custom-domain Speech endpoint, this is usually the first part of that hostname.
+
+
+ +
+
+ +
Provide Subscription ID, Resource Group, and Speech Resource Name to auto-build the ARM resource ID.
+ + + +
Required for Voice Responses when using Managed Identity. You can paste the full value manually, or let the fields above build it for you.
+
+ +
+ + +
+ +
+ + +
+
+ +
+ + +
+
Required only when Authentication Type is set to Key.
+
+ +
+ Managed identity roles: Start with Cognitive Services Speech User. If fast transcription or other write-style speech operations still return authorization errors, add Cognitive Services Speech Contributor. Managed identity also requires a custom-domain endpoint. +
+ +
+

+ + + Enhanced Citations + + will dramatically improve the citation experience for video and audio files. + +

+
+
diff --git a/application/single_app/templates/admin/_panes/branding.html b/application/single_app/templates/admin/_panes/branding.html new file mode 100644 index 000000000..c648c07fa --- /dev/null +++ b/application/single_app/templates/admin/_panes/branding.html @@ -0,0 +1,165 @@ +
+ +

+ Configure general application settings, including the application's title, logo, and landing page text. +

+
+
+ Branding +
+

+ Configure your application's title, logo, and branding elements. +

+
+ + +
+
Logo Settings
+
+ + + +
+
+ + + +
+
+
+ + {{ settings.landing_page_logo_scale_percent | default(100) }}% +
+ +
+ 50% + 500% +
+ + Adjust the logo size on the home page only. This does not change the logo size in the top or sidebar navigation. + +
+
+ + + This logo will be displayed in light mode and stored at up to 500px tall so the main page can render it sharply without keeping oversized assets in settings. +
+
+ + + This logo will be displayed in dark mode. If not provided, the light mode logo will be used in both themes. Dark logos are also stored at up to 500px tall. +
+
+ + + Recommended: 16x16 or 32x32 pixel png or jpg or ico. +
+
+ +
+
+ Home Page Text +
+

Configure the text content displayed on your application's home page using Markdown formatting.

+ +
+ + + Choose how the landing page markdown is aligned on the home page. +
+ +
+ + + +
+ + + + +
+ +
+
+ Appearance +
+

Configure the app appearance and theme settings.

+ +
+ +
+ + + +
+

Users can still toggle dark mode individually from the navigation bar.

+
+ +
+ +
+ + + +
+

Users can still toggle the left navigation sidebar individually from the header.

+
+
+ + + + + + +
diff --git a/application/single_app/templates/admin/_panes/chat-experience.html b/application/single_app/templates/admin/_panes/chat-experience.html index 223e1beb0..37d8033a6 100644 --- a/application/single_app/templates/admin/_panes/chat-experience.html +++ b/application/single_app/templates/admin/_panes/chat-experience.html @@ -1,4 +1,4 @@ -
+
Processing Thoughts diff --git a/application/single_app/templates/admin/_panes/citation.html b/application/single_app/templates/admin/_panes/citation.html index 94f9788e1..4d42286e9 100644 --- a/application/single_app/templates/admin/_panes/citation.html +++ b/application/single_app/templates/admin/_panes/citation.html @@ -1,4 +1,4 @@ -
+

Configure standard and enhanced citations features for your and group workspaces. diff --git a/application/single_app/templates/admin/_panes/classification.html b/application/single_app/templates/admin/_panes/classification.html index 597736e46..425eeedcf 100644 --- a/application/single_app/templates/admin/_panes/classification.html +++ b/application/single_app/templates/admin/_panes/classification.html @@ -1,4 +1,4 @@ -

+
Document Classification diff --git a/application/single_app/templates/admin/_panes/safety.html b/application/single_app/templates/admin/_panes/content-safety.html similarity index 75% rename from application/single_app/templates/admin/_panes/safety.html rename to application/single_app/templates/admin/_panes/content-safety.html index c4973acdb..88eae95bb 100644 --- a/application/single_app/templates/admin/_panes/safety.html +++ b/application/single_app/templates/admin/_panes/content-safety.html @@ -1,4 +1,4 @@ -
+

Configure content safety, archiving, and user feedback settings. If Content Safety is enabled, user @@ -174,49 +174,6 @@

-
-
- Permissions -
-

Control which users can access specific administrative views related to safety and feedback.

- - -
- - - -
-

- Required app role value: SafetyViolationAdmin. Assign this role to users or groups in the Enterprise App before enabling the requirement. If disabled, any user with the general Admin app role can access the Safety Violations admin page. -

- - -
- - - -
-

- Required app role value: FeedbackAdmin. Assign this role to users or groups in the Enterprise App before enabling the requirement. If disabled, any user with the general Admin app role can access the User Feedback admin page. Requires Enable User Feedback to be active. -

-
diff --git a/application/single_app/templates/admin/_panes/control-center-config.html b/application/single_app/templates/admin/_panes/control-center-config.html index dd2143276..6567e5537 100644 --- a/application/single_app/templates/admin/_panes/control-center-config.html +++ b/application/single_app/templates/admin/_panes/control-center-config.html @@ -1,4 +1,4 @@ -
+

Configure Control Center access and permissions for administrators.

diff --git a/application/single_app/templates/admin/_panes/cosmos.html b/application/single_app/templates/admin/_panes/cosmos.html index 9d1fa89ca..33cf6b0f3 100644 --- a/application/single_app/templates/admin/_panes/cosmos.html +++ b/application/single_app/templates/admin/_panes/cosmos.html @@ -1,4 +1,4 @@ -
+
diff --git a/application/single_app/templates/admin/_panes/custom-pages.html b/application/single_app/templates/admin/_panes/custom-pages.html index a3d0f32ef..00fc68987 100644 --- a/application/single_app/templates/admin/_panes/custom-pages.html +++ b/application/single_app/templates/admin/_panes/custom-pages.html @@ -1,4 +1,4 @@ -
+

Enable trusted deployment-time custom pages and manage metadata for simple static pages served from the application custom_pages folders.

@@ -78,4 +78,56 @@
Static Page Metadata
+
diff --git a/application/single_app/templates/admin/_panes/data-management.html b/application/single_app/templates/admin/_panes/data-management.html index aba966397..d99c04990 100644 --- a/application/single_app/templates/admin/_panes/data-management.html +++ b/application/single_app/templates/admin/_panes/data-management.html @@ -1,4 +1,4 @@ -
+

Backup, Migrate & Restore

@@ -241,7 +241,7 @@
Encryption
Key Vault is strongly recommended
Generated backup encryption keys are stored in the Data Management settings document when Key Vault is not enabled.
- Open Key Vault settings + Open Key Vault settings
diff --git a/application/single_app/templates/admin/_panes/extraction.html b/application/single_app/templates/admin/_panes/extraction.html new file mode 100644 index 000000000..9a056e8db --- /dev/null +++ b/application/single_app/templates/admin/_panes/extraction.html @@ -0,0 +1,724 @@ +
+
+
Document Intelligence
+

+ Configure Azure Document Intelligence settings. Document Intelligence always powers + Standard extraction and is required for workspaces and chat file uploads. +

+
+ + + +
+ +
+ {% if content_understanding_supported %} +
+ Enhanced extraction uses Azure AI Content Understanding, which returns tables, + page structure, checkbox states, and AI-generated descriptions of figures, charts, and images. + Configure the connection below. +
+ {% else %} +
+ Azure AI Content Understanding is not available in the + {{ azure_environment }} cloud, so Enhanced extraction uses + Document Intelligence Layout here. There is nothing more to configure — + Enhanced still captures tables, page structure, forms, and checkbox states. +
+ {% endif %} + +
+ + +
+ Enhanced captures more document detail for PDFs and images, including tables, page structure, and checked or unchecked marks. It adds latency and has a 6X increase for every 1000 pages when selected. +
+
+ + +
+ Auto samples this many first PDF pages with Document Intelligence Layout. If it detects tables, selection marks, or figures, the full PDF uses Enhanced; otherwise it finishes with Standard. Images use Enhanced in Auto mode. +
+
+
+
Standard: Document Intelligence Read. Fastest and lowest-cost path for plain text PDFs and images.
+
Enhanced: best for tables, section structure, page layout, forms, checkbox states, and figure descriptions. Expect more latency and higher cost.
+
Auto: samples the first pages with Document Intelligence Layout, then uses Enhanced only when the sample shows tables, selection marks, or figures.
+
+
+ +
+ + + +
+
+ Captures equations in PDFs and images as LaTeX rather than approximate OCR text. This is a + billed Document Intelligence add-on that adds per-page cost to every Enhanced + extraction, so it is off by default. It applies to the Layout model only, so it has no effect + while extraction is set to Standard. +
+ + {% if content_understanding_supported %} +
+
+
Azure AI Content Understanding
+ +
+

+ Required for Enhanced extraction. Deployed from a Microsoft Foundry resource. + If this is left blank, Enhanced falls back to Document Intelligence Layout. +

+ +
+ + +
+ Your Microsoft Foundry resource endpoint, without a trailing path. +
+
+ +
+ + +
+ Managed identity requires the Cognitive Services User role on the Foundry resource. +
+
+ +
+ +
+ + +
+
+ +
+
+ + +
Default: {{ content_understanding_api_version_default }}
+
+
+ + +
Default: {{ content_understanding_document_analyzer_default }}
+
+
+ + +
Default: {{ content_understanding_image_analyzer_default }}
+
+
+ + +
+
+ {% endif %} +
+ +
+
Images Inside Office Files
+

+ Neither extraction engine describes figures inside Word and PowerPoint files. When this is on, + embedded images are pulled out of the file, analyzed with whichever engine backs the selected + extraction mode, and indexed as their own citable chunks. This works with Standard extraction + too, using Document Intelligence. +

+
+ + +
+
+
+ + +
Images narrower or shorter than this are skipped as icons or spacers.
+
+
+ + +
Caps per-document cost. Duplicate images are analyzed once.
+
+
+
+ + + + +
+ + + +
+ +
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+ + + +
+
+
+ +
+
+
Chunk Sizes
+ Cap: {{ chunk_size_cap }} +
+

Custom chunk sizes apply to new uploads only. Existing documents keep their current chunks.

+
+ Heads up: Overrides are capped at {{ chunk_size_cap }} (2x embedding context window, fallback 16,384). +
+
+ + +
+ +
+ + + {% set chunk_settings = chunk_size_settings or {} %} + {% set chunk_defaults = chunk_size_defaults or {} %} +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
Minimum enforced at 50% of target on merge.
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ + +
Applies to new audio transcripts.
+
+
+ + +
Pages per chunk after extraction.
+
+
+ + +
Slides per chunk after extraction.
+
+
+
+
+ + +
+
+ Metadata Extraction +
+

+ Enable this to automatically parse and store file metadata for advanced indexing and search. +

+
+ + + +
+ +
+ + + +
+ Uses Global Endpoints when multi-endpoint model management is enabled; otherwise uses the legacy GPT/APIM deployment settings. +
+
+
+ + +
+
+ Multi-Modal Vision Analysis +
+

+ Enable AI-powered vision analysis for images uploaded to chat or workspace. When enabled alongside Document Intelligence OCR, images will receive both text extraction (OCR) and semantic understanding (vision AI). +

+ +
+ How it works: +
    +
  • Document Intelligence: Extracts text from images (OCR)
  • +
  • Vision Model: Provides semantic analysis, object detection, and contextual understanding
  • +
  • Both analyses are combined and available in citations when Enhanced Citations is enabled
  • +
+
+ +
+ + + +
+ +
+ + +
Select a GPT model with vision capabilities (for example, gpt-4o or supported GPT 5 and later models). Only vision-capable models are shown.
+ + +
+
+
+
diff --git a/application/single_app/templates/admin/_panes/feature-governance.html b/application/single_app/templates/admin/_panes/feature-governance.html index d0f153d74..0b7dcfed1 100644 --- a/application/single_app/templates/admin/_panes/feature-governance.html +++ b/application/single_app/templates/admin/_panes/feature-governance.html @@ -1,4 +1,4 @@ -
+

Configure governance enforcement for endpoint, agent, and action creation or usage. Governance is disabled by default and only enforced when toggled on. diff --git a/application/single_app/templates/admin/_panes/feedback-alerts.html b/application/single_app/templates/admin/_panes/feedback-alerts.html index 4ee6ae562..5488e7242 100644 --- a/application/single_app/templates/admin/_panes/feedback-alerts.html +++ b/application/single_app/templates/admin/_panes/feedback-alerts.html @@ -1,4 +1,4 @@ -

+
User Feedback diff --git a/application/single_app/templates/admin/_panes/file-sync.html b/application/single_app/templates/admin/_panes/file-sync.html index 2d56920d2..eb440758a 100644 --- a/application/single_app/templates/admin/_panes/file-sync.html +++ b/application/single_app/templates/admin/_panes/file-sync.html @@ -1,4 +1,4 @@ -
+

Configure file synchronization for personal, group, and public workspaces.

diff --git a/application/single_app/templates/admin/_panes/files-sharing.html b/application/single_app/templates/admin/_panes/files-sharing.html new file mode 100644 index 000000000..a66a04b76 --- /dev/null +++ b/application/single_app/templates/admin/_panes/files-sharing.html @@ -0,0 +1,223 @@ +
+
+
+ File Downloads +
+

+ Control when users can download original workspace document files from personal, group, and public workspaces. +

+
+ + + +
+
+
+ + + +
+
+ + + +
+
+ + No groups assigned. +
+ +
+
+ + + +
+
+ + + +
+
+ + No public workspaces assigned. +
+ +
+ + + + + + +
+
+ File Sharing +
+

+ Turn this on to enable file sharing capabilities between users and workspaces. +

+
+ + + +
+
+ + + + + +
+
+ Shared Conversation File Approvals +
+

Files generated by participants in a shared conversation are saved into the conversation owner's storage. When enabled, those files are held until an approver releases them.

+
+ + + +
+
+ +
diff --git a/application/single_app/templates/admin/_panes/general.html b/application/single_app/templates/admin/_panes/general.html deleted file mode 100644 index bd3d5be40..000000000 --- a/application/single_app/templates/admin/_panes/general.html +++ /dev/null @@ -1,682 +0,0 @@ -
- -

- Configure general application settings, including the application's title, logo, and landing page text. -

-
-
- Branding -
-

- Configure your application's title, logo, and branding elements. -

-
- - -
-
Logo Settings
-
- - - -
-
- - - -
-
-
- - {{ settings.landing_page_logo_scale_percent | default(100) }}% -
- -
- 50% - 500% -
- - Adjust the logo size on the home page only. This does not change the logo size in the top or sidebar navigation. - -
-
- - - This logo will be displayed in light mode and stored at up to 500px tall so the main page can render it sharply without keeping oversized assets in settings. -
-
- - - This logo will be displayed in dark mode. If not provided, the light mode logo will be used in both themes. Dark logos are also stored at up to 500px tall. -
-
- - - Recommended: 16x16 or 32x32 pixel png or jpg or ico. -
-
- -
-
- Home Page Text -
-

Configure the text content displayed on your application's home page using Markdown formatting.

- -
- - - Choose how the landing page markdown is aligned on the home page. -
- -
- - - -
- - - - -
- -
-
- Appearance -
-

Configure the app appearance and theme settings.

- -
- -
- - - -
-

Users can still toggle dark mode individually from the navigation bar.

-
- -
- -
- - - -
-

Users can still toggle the left navigation sidebar individually from the header.

-
-
- -
-
-
- Health Check -
- -
-

Configure health check endpoint for external monitoring systems.

- -
-
-
-
-
-
Authenticated Endpoint
-

Use when your monitoring system can reach a protected route and you want the endpoint governed by the normal app access boundary.

-
- Protected -
-
- - - -
-

Best for internal monitors or diagnostics tooling that already authenticates to the application.

-
-
-
-
-
-
-
Unauthenticated Endpoint
-

Use when a platform health probe cannot sign in and only needs a lightweight availability response.

-
- No Auth -
-
- - - -
- -
-
-
-
- -
-
-
- API Documentation -
-
- - - Open Swagger UI - -
-
-

Configure automatic OpenAPI/Swagger documentation for API endpoints.

- -
- - - -
-

- Provides interactive API documentation, endpoint testing, and schema validation. - Useful for developers, API integration, and system troubleshooting. -

-
- -
-
- Classification Banner -
-
- - - -
-
- - -
-
- - -
-
- - -
-
- - {{ settings.classification_banner_text or 'Banner Preview' }} - -
-
- -
-
- Chat AI Notice -
-

- Display an administrator-provided reminder directly below the chat input, such as guidance that responses are AI-generated and should be reviewed. -

-
- - -
-
-
- - -
Plain text only. Line breaks are preserved.
-
-
- - -
Changing the notice text or display behavior creates a new message version and shows it again.
-
-
-
- -
-
- Terms of Use -
-

- Require users to accept the Terms of Use before using SimpleChat. Standard Microsoft sign-in users see it before authentication; Teams SSO and other passive sign-in flows are gated immediately after the app session is created. -

- -
- - - -
- -
-
- - -
-
- - - Changing the title, message, or frequency creates a new terms version that users must accept again. -
-
- -
- - - Plain text is shown to users with line breaks preserved. -
- -
- - - Use a local path such as / or an admin-approved HTTP(S) URL. Signed-in users are locally logged out before this redirect. -
- -
-
- - -
-
- - -
-
- - -
- -
-
- Support -
-
- - - -
-

When enabled, users can access Support destinations like Send Feedback and Latest Features directly from navigation.

- -
-
- - - This name will appear in user navigation as the Support menu title. -
- -
- - - -
- -
- - - User Send Feedback drafts will be addressed to this internal email address. -
- -
- - - -
- -
-
User-Facing Latest Features
-

Choose which recent features are shared on the user Latest Features page. Deployment and Redis start unchecked because they are mainly admin-facing rollout and infrastructure topics.

-
- - - - When enabled, user-facing Latest Features cards can show public guide buttons in addition to the direct in-app shortcuts. -
- {% for release_group in support_latest_feature_release_groups %} - {% set checklist_collapse_id = release_group.collapse_id ~ 'Checklist' %} -
-
-
-
-
{{ release_group.label }}{% if release_group.release_version %}v{{ release_group.release_version }}{% endif %}
-

{{ release_group.description }}

-
- {% if not release_group.default_expanded %} - - {% endif %} -
-
-
- {% for feature in release_group.features %} -
-
- - -
-
- {% endfor %} -
-
-
-
- {% endfor %} -
-
-
- - - -
-
- System Settings -
-

- System-level settings that control application behavior, including file size limits, conversation history, - and default prompts. -

-
- - -
-
- - -
-
- - - -
-
-
- - - Users are logged out locally after this many minutes of inactivity. Minimum value: 10 minutes. -
-
- - - Show the warning modal after this many minutes of inactivity. Set this equal to the logout timeout to disable the warning dialog window. -
-
- - - Custom text shown at the top of the idle warning dialog. -
-
-
- - -
-
- - Shown to signed-in users who lack the required roles. Use Enter for line breaks. - -
-
-
diff --git a/application/single_app/templates/admin/_panes/governance-policies.html b/application/single_app/templates/admin/_panes/governance-policies.html index 8b9d2130f..da2b94fd1 100644 --- a/application/single_app/templates/admin/_panes/governance-policies.html +++ b/application/single_app/templates/admin/_panes/governance-policies.html @@ -1,4 +1,4 @@ -
+
Feature Policies
diff --git a/application/single_app/templates/admin/_panes/latest-features.html b/application/single_app/templates/admin/_panes/latest-features.html index 0ef37a941..a5d8c5f5d 100644 --- a/application/single_app/templates/admin/_panes/latest-features.html +++ b/application/single_app/templates/admin/_panes/latest-features.html @@ -1,4 +1,4 @@ -
+

Review the main capabilities introduced in v{{ config['VERSION'] }} and use this page as an admin-facing overview for what to highlight with your teams.

@@ -832,7 +832,7 @@

Admins can enable this once and let users see more of the model pipeline, including sending, generating, and responded states with clearer timing information.

  • Admins can choose whether this announcement is visible on the user-facing Latest Features page from General > User-Facing Latest Features.
  • +

    Configure health check endpoint for external monitoring systems.

    + +
    +
    +
    +
    +
    +
    Authenticated Endpoint
    +

    Use when your monitoring system can reach a protected route and you want the endpoint governed by the normal app access boundary.

    +
    + Protected +
    +
    + + + +
    +

    Best for internal monitors or diagnostics tooling that already authenticates to the application.

    +
    +
    +
    +
    +
    +
    +
    Unauthenticated Endpoint
    +

    Use when a platform health probe cannot sign in and only needs a lightweight availability response.

    +
    + No Auth +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    +
    + API Documentation +
    +
    + + + Open Swagger UI + +
    +
    +

    Configure automatic OpenAPI/Swagger documentation for API endpoints.

    + +
    + + + +
    +

    + Provides interactive API documentation, endpoint testing, and schema validation. + Useful for developers, API integration, and system troubleshooting. +

    +
    diff --git a/application/single_app/templates/admin/_panes/mcp-governance.html b/application/single_app/templates/admin/_panes/mcp-governance.html index 31080591e..8a57389de 100644 --- a/application/single_app/templates/admin/_panes/mcp-governance.html +++ b/application/single_app/templates/admin/_panes/mcp-governance.html @@ -1,4 +1,4 @@ -
    +
    MCP Action Destination Governance diff --git a/application/single_app/templates/admin/_panes/network.html b/application/single_app/templates/admin/_panes/network.html index 83ba4fb03..0f9216bad 100644 --- a/application/single_app/templates/admin/_panes/network.html +++ b/application/single_app/templates/admin/_panes/network.html @@ -1,4 +1,4 @@ -
    +
    diff --git a/application/single_app/templates/admin/_panes/notices.html b/application/single_app/templates/admin/_panes/notices.html new file mode 100644 index 000000000..c05ac2b68 --- /dev/null +++ b/application/single_app/templates/admin/_panes/notices.html @@ -0,0 +1,288 @@ +
    +
    +
    + Classification Banner +
    +
    + + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + {{ settings.classification_banner_text or 'Banner Preview' }} + +
    +
    + +
    +
    + Chat AI Notice +
    +

    + Display an administrator-provided reminder directly below the chat input, such as guidance that responses are AI-generated and should be reviewed. +

    +
    + + +
    +
    +
    + + +
    Plain text only. Line breaks are preserved.
    +
    +
    + + +
    Changing the notice text or display behavior creates a new message version and shows it again.
    +
    +
    +
    + +
    +
    + Terms of Use +
    +

    + Require users to accept the Terms of Use before using SimpleChat. Standard Microsoft sign-in users see it before authentication; Teams SSO and other passive sign-in flows are gated immediately after the app session is created. +

    + +
    + + + +
    + +
    +
    + + +
    +
    + + + Changing the title, message, or frequency creates a new terms version that users must accept again. +
    +
    + +
    + + + Plain text is shown to users with line breaks preserved. +
    + +
    + + + Use a local path such as / or an admin-approved HTTP(S) URL. Signed-in users are locally logged out before this redirect. +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + + +
    +
    + User Agreement +
    +

    + Configure a user agreement that users must accept before uploading files. + Supports Markdown formatting. +

    + + +
    + + + +
    + + +
    +
    + + +
    + +

    Select where the user agreement should be shown (at least one required):

    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + +
    + + +
    + + +
    + 0 / 200 words + +
    +
    + + +
    + + + +
    + + +
    + +
    +
    +
    +
    diff --git a/application/single_app/templates/admin/_panes/redis-caching.html b/application/single_app/templates/admin/_panes/redis-caching.html index 16d846c71..5bbaa8c4d 100644 --- a/application/single_app/templates/admin/_panes/redis-caching.html +++ b/application/single_app/templates/admin/_panes/redis-caching.html @@ -1,4 +1,4 @@ -
    +
    {% set enable_dai_debug = settings.enable_dai_debug | default(false) %}

    Configure Redis cache to improve enterprise scale and performance by caching session data. Enabling Redis allows you to horizontally scale your application across multiple instances without losing session data. diff --git a/application/single_app/templates/admin/_panes/retention.html b/application/single_app/templates/admin/_panes/retention.html index c3aa2258a..a2bc06781 100644 --- a/application/single_app/templates/admin/_panes/retention.html +++ b/application/single_app/templates/admin/_panes/retention.html @@ -1,4 +1,4 @@ -

    +
    Retention Policy diff --git a/application/single_app/templates/admin/_panes/search-extract.html b/application/single_app/templates/admin/_panes/search-extract.html deleted file mode 100644 index 1db055f2b..000000000 --- a/application/single_app/templates/admin/_panes/search-extract.html +++ /dev/null @@ -1,1698 +0,0 @@ -
    - -

    - Configure Azure AI Search, Document Intelligence, and multimedia support settings. -

    - -
    -
    -
    Web Search (Azure AI Foundry Agent)
    - -
    -

    Enable web search by routing queries through an Azure AI Foundry agent configured by admins.

    -
    - - -
    - - - -
    - -
    -
    -
    URL Access
    - Shared Policy -
    -

    Control direct URL content fetching for pasted chat links, workflow prompts, and Deep Research source review.

    -
    - - -
    -
    - - -
    Required app role value: UrlAccessUser. Assign this role to users or groups in the Enterprise App before enabling the requirement. When enabled, only assigned users can use URL Access in chat or enable it for workflows.
    -
    - -
    -
    - URL Access uses the same server-side URL protections as Deep Research: non-HTTP(S) URLs, credentialed URLs, literal IP targets, localhost, metadata hosts, unsafe redirects, unsupported content types, and oversized pages are blocked before fetch. -
    -
    -
    - - -
    Hard limit: 100 direct URLs per chat message.
    -
    -
    - - -
    Hard limit: 500 direct URLs per workflow prompt.
    -
    -
    -
    - -
    -
    -
    - - -
    - - -
    -
    -
    -
    Leave blank to allow any public domain that passes safety checks. Deep Research uses this same allow list.
    -
    -
    -
    - - -
    - - -
    -
    -
    -
    Blocked domains apply to URL Access and Deep Research source-page review.
    -
    -
    - -
    -
    -
    -
    URL Policy Test
    -
    Check a URL against the current allowed and blocked domain rules before saving.
    -
    - -
    -
    -
    - -
    -
    -
    Deep Research
    -
    - Optional - -
    -
    -

    Plan bounded web searches, inspect source pages, and keep an internal research ledger for evidence coverage. Direct pasted URLs use the shared URL Access controls above.

    -
    - - -
    - -
    -
    - Server-side protections always block non-HTTP(S) URLs, literal IP URL targets, localhost, metadata hosts, credentialed URLs, excessive redirects, unsupported content types, oversized pages, and requests beyond the configured page budget. DNS hostnames that resolve to private/internal addresses require the internal-host opt-in below. -
    - -
    - - -
    Required app role value: DeepResearchUser. Assign this role to users or groups in the Enterprise App before enabling the requirement. When enabled, only assigned users can use Deep Research.
    -
    - -
    - - -
    Allows DNS hostnames that resolve to private/internal addresses. Literal IP URL targets, localhost, metadata hosts, link-local addresses, and reserved addresses remain blocked.
    -
    - -
    -
    - - - -
    Deep Research runs only when the user selects it for the message.
    -
    -
    - - -
    Hard limit: 10 pages.
    -
    -
    - - -
    Limits initial search-result and direct URL pages so budget remains for child pages.
    -
    -
    - - -
    Direct URLs beyond this cap are recorded as omitted in the ledger.
    -
    -
    - - -
    Includes the original current-message query.
    -
    -
    - - -
    Hard limit: 30 seconds.
    -
    -
    - - -
    Every redirect target is revalidated.
    -
    -
    - - -
    Hard limit: 5 MB.
    -
    -
    - - -
    Depth 2 follows selected links from seed and child pages.
    -
    -
    - -
    -
    - {% set js_runtime = source_review_runtime_capabilities or {} %} -
    - - -
    -
    Deep Research follows only scored, policy-approved links within the page and depth budgets.
    -
    -
    -
    - - -
    -
    The selected chat model can propose bounded current-message-only query variants before page review.
    -
    -
    -
    - - -
    -
    Creates a Markdown chat artifact with search queries, reviewed sources, skipped URLs, and coverage.
    -
    -
    -
    - - -
    -
    When source pages expose candidate links, the selected chat model can rank those candidates before the server fetches them.
    -
    -
    -
    - - -
    -
    Requires verified Playwright browser runtime support on the app host.
    -
    - {{ js_runtime.message or 'Runtime support has not been checked yet.' }} -
    - {% if not js_runtime.js_rendering_available %} -
    Install/enable the Playwright Chromium runtime, then reload Admin Settings to enable this option.
    - {% endif %} - {% if js_runtime.sandbox_disabled %} -
    Chromium sandbox is disabled by environment configuration.
    - {% endif %} -
    -
    - - -
    When JavaScript rendering is enabled, Deep Research can click visible Load More controls until this cap is reached.
    -
    -
    -
    - - -
    -
    -
    -
    - - -
    -
    -
    -
    -
    - - - - - - - - -
    -
    Azure AI Search
    -

    - Configure Azure AI Search settings. -

    -
    - - - -
    - -
    - -
    -
    - - -
    -
    - - -
    -
    - -
    - - -
    -
    -
    - - -
    -
    - - -
    -
    - -
    - - -
    -
    -
    - - - -
    -
    -
    - - -
    -
    Document Intelligence
    -

    - Configure Azure Document Intelligence settings. Document Intelligence always powers - Standard extraction and is required for workspaces and chat file uploads. -

    -
    - - - -
    - -
    - {% if content_understanding_supported %} -
    - Enhanced extraction uses Azure AI Content Understanding, which returns tables, - page structure, checkbox states, and AI-generated descriptions of figures, charts, and images. - Configure the connection below. -
    - {% else %} -
    - Azure AI Content Understanding is not available in the - {{ azure_environment }} cloud, so Enhanced extraction uses - Document Intelligence Layout here. There is nothing more to configure — - Enhanced still captures tables, page structure, forms, and checkbox states. -
    - {% endif %} - -
    - - -
    - Enhanced captures more document detail for PDFs and images, including tables, page structure, and checked or unchecked marks. It adds latency and has a 6X increase for every 1000 pages when selected. -
    -
    - - -
    - Auto samples this many first PDF pages with Document Intelligence Layout. If it detects tables, selection marks, or figures, the full PDF uses Enhanced; otherwise it finishes with Standard. Images use Enhanced in Auto mode. -
    -
    -
    -
    Standard: Document Intelligence Read. Fastest and lowest-cost path for plain text PDFs and images.
    -
    Enhanced: best for tables, section structure, page layout, forms, checkbox states, and figure descriptions. Expect more latency and higher cost.
    -
    Auto: samples the first pages with Document Intelligence Layout, then uses Enhanced only when the sample shows tables, selection marks, or figures.
    -
    -
    - -
    - - - -
    -
    - Captures equations in PDFs and images as LaTeX rather than approximate OCR text. This is a - billed Document Intelligence add-on that adds per-page cost to every Enhanced - extraction, so it is off by default. It applies to the Layout model only, so it has no effect - while extraction is set to Standard. -
    - - {% if content_understanding_supported %} -
    -
    -
    Azure AI Content Understanding
    - -
    -

    - Required for Enhanced extraction. Deployed from a Microsoft Foundry resource. - If this is left blank, Enhanced falls back to Document Intelligence Layout. -

    - -
    - - -
    - Your Microsoft Foundry resource endpoint, without a trailing path. -
    -
    - -
    - - -
    - Managed identity requires the Cognitive Services User role on the Foundry resource. -
    -
    - -
    - -
    - - -
    -
    - -
    -
    - - -
    Default: {{ content_understanding_api_version_default }}
    -
    -
    - - -
    Default: {{ content_understanding_document_analyzer_default }}
    -
    -
    - - -
    Default: {{ content_understanding_image_analyzer_default }}
    -
    -
    - - -
    -
    - {% endif %} -
    - -
    -
    Images Inside Office Files
    -

    - Neither extraction engine describes figures inside Word and PowerPoint files. When this is on, - embedded images are pulled out of the file, analyzed with whichever engine backs the selected - extraction mode, and indexed as their own citable chunks. This works with Standard extraction - too, using Document Intelligence. -

    -
    - - -
    -
    -
    - - -
    Images narrower or shorter than this are skipped as icons or spacers.
    -
    -
    - - -
    Caps per-document cost. Duplicate images are analyzed once.
    -
    -
    -
    - - - - -
    - - - -
    - -
    - -
    -
    - - -
    -
    - - -
    -
    - -
    - - -
    -
    -
    - - -
    -
    - - -
    -
    - -
    - - -
    -
    -
    - - - -
    -
    -
    - -
    -
    -
    Chunk Sizes
    - Cap: {{ chunk_size_cap }} -
    -

    Custom chunk sizes apply to new uploads only. Existing documents keep their current chunks.

    -
    - Heads up: Overrides are capped at {{ chunk_size_cap }} (2x embedding context window, fallback 16,384). -
    -
    - - -
    - -
    - - - {% set chunk_settings = chunk_size_settings or {} %} - {% set chunk_defaults = chunk_size_defaults or {} %} -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    Minimum enforced at 50% of target on merge.
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    - -
    - - -
    Applies to new audio transcripts.
    -
    -
    - - -
    Pages per chunk after extraction.
    -
    -
    - - -
    Slides per chunk after extraction.
    -
    -
    -
    -
    - - -
    -
    -
    -
    - -
    -
    -

    - AI Video Intelligence -

    -

    Extract insights and make video content searchable and interactive

    -
    -
    - -
    - -
    - - Make Video Content Fully Searchable: Upload videos to your workspace and automatically extract transcripts, identify speakers, detect topics, and generate searchable timestamps. Your AI can then answer questions about video content, cite specific moments, and provide deep insights. -
    - - -
    -
    - - -
    -

    - Upload video files (MP4, AVI, MOV, etc.) to workspaces where Azure Video Indexer automatically processes them. - Extract spoken content, identify speakers, detect faces, recognize brands, and generate searchable metadata—perfect for meetings, presentations, training videos, and recorded content. -

    -
    - - Full-Text Search - - - Speaker ID - - - Timestamped Citations - - - Multi-Language - -
    -
    - - {% set public_video_indexer_endpoint = "https://api.videoindexer.ai" %} - {% set government_video_indexer_endpoint = "https://api.videoindexer.ai.azure.us" %} - {% set configured_video_indexer_endpoint = settings.video_indexer_endpoint or default_video_indexer_endpoint %} - {% if configured_video_indexer_endpoint == government_video_indexer_endpoint %} - {% set video_indexer_cloud = "usgovernment" %} - {% elif configured_video_indexer_endpoint == public_video_indexer_endpoint %} - {% set video_indexer_cloud = "public" %} - {% else %} - {% set video_indexer_cloud = "custom" %} - {% endif %} - {% if azure_environment == "usgovernment" %} - {% set azure_environment_label = "Azure Government" %} - {% elif azure_environment == "custom" %} - {% set azure_environment_label = "Custom Cloud" %} - {% else %} - {% set azure_environment_label = "Azure Public / Commercial" %} - {% endif %} - - -
    -
    - Azure Video Indexer Configuration -
    -

    Connect to your Azure Video Indexer resource for advanced video processing and content extraction.

    - -
    - Identity overview: -
      -
    • Video Indexer can use its own managed identity to reach the linked Storage account during account creation.
    • -
    • SimpleChat authenticates to Video Indexer with the App Service system-assigned managed identity.
    • -
    • The App Service managed identity must have Contributor on the Video Indexer resource.
    • -
    • See Azure Video Indexer documentation for setup details
    • -
    -
    - -
    - - -
    Choose the endpoint family that matches your deployed cloud. Use Custom only when you need a non-standard Video Indexer endpoint.
    -
    - -
    - Current App Service environment: {{ azure_environment_label }}. This selector saves the Video Indexer API endpoint. If you are switching between Azure Public, Azure Government, or a custom cloud, update AZURE_ENVIRONMENT in your App Service configuration as well. -
    - -
    - The selected Video Indexer cloud does not match this app's current AZURE_ENVIRONMENT. Update the App Service configuration if you are moving to a different cloud. -
    - - - -
    - - -
    Only required when using a custom cloud or non-standard Video Indexer endpoint.
    -
    - -
    - - -
    Saved endpoint value used for Video Indexer API calls.
    -
    - -
    - - -
    The Azure resource group containing your Video Indexer account
    -
    - -
    - - -
    Your Azure subscription ID
    -
    - -
    - - -
    The name of your Video Indexer account resource
    -
    - -
    - - -
    Azure region where your Video Indexer account is deployed (e.g., eastus, westus2, northeurope)
    -
    - -
    - - -
    Found in the Video Indexer account Overview page in Azure Portal
    -
    - -
    - - -
    Default for {{ azure_environment_label }}: {{ default_video_indexer_arm_api_version }}
    -
    - -
    - - -
    -
    -
    - - -
    -
    -
    -
    - -
    -
    -

    - AI Voice Conversations -

    -

    Transform your AI experience with natural voice interactions

    -
    -
    - -
    - - -
    -
    - - -
    -

    - Let users opt in to a bundled sound when an AI response finishes outside their active view. - These local cues do not require Azure Speech Service. -

    -
    - -
    - - One Speech resource, three features: Audio file uploads, Voice Input, and Voice Responses all use the same Azure Speech Service section below. Configure the Speech resource once, then turn on whichever speech features you need. -
    - - -
    - {% set audio_runtime = audio_runtime_capabilities or {} %} - {% set audio_supported_extensions = audio_runtime.supported_extensions or [] %} - {% set audio_direct_extensions = audio_runtime.direct_transcription_extensions or [] %} -
    - - -
    -

    - Upload audio files (MP3, WAV, M4A, etc.) to workspaces where they're automatically transcribed and indexed. - The AI can then search, analyze, and answer questions about audio content—perfect for meetings, interviews, lectures, and podcasts. -

    -
    -
    - {{ audio_runtime.message or 'Audio runtime support has not been checked yet.' }} -
    -
    - Supported audio upload extensions: {{ audio_supported_extensions|join(', ') }} -
    - {% if audio_direct_extensions %} -
    - Without FFmpeg, source-file fallback is best for: {{ audio_direct_extensions|join(', ') }}. Container builds can include FFmpeg for broader codec support. -
    - {% endif %} -
    -
    - - -
    -
    - - -
    -

    - Talk to your AI instead of typing. Record voice messages up to 90 seconds directly in the chat interface. - Azure Speech Service instantly transcribes your speech with high accuracy, supporting multiple languages and accents. -

    -
    - - Hands-Free - - - Accessible - - - Fast Input - -
    -
    - - -
    -
    - - -
    -

    - Hear AI responses read aloud in natural, human-like voices powered by Azure's advanced neural Text-to-Speech. - Each message includes a speaker button—click to listen while multitasking, commuting, or whenever reading isn't convenient. -

    -
    - - Natural Voices - - - Multitask-Friendly - - - Multi-Language - -
    -
    - - -
    -
    - Azure Speech Service Configuration -
    -

    Configure the shared Azure Speech resource used by audio transcription, voice input, and text-to-speech.

    - -
    - Shared configuration: These settings apply to all enabled speech features. If you use managed identity and also enable Voice Responses, fill in the Speech Resource ID field so the Speech SDK can authenticate synthesis requests. -
    - -
    - - -
    Use the resource-specific custom-domain endpoint when selecting Managed Identity.
    -
    - -
    - - -
    Required for speech recognition locale defaults and for text-to-speech when using Managed Identity.
    -
    - -
    -
    - Resource ID builder: If the full ARM resource ID is hard to find in the portal, enter the subscription ID, resource group, and Speech resource name below. Simple Chat can build the resource ID for you. -
    - -
    -
    - - -
    -
    - - -
    -
    - - -
    If you use a custom-domain Speech endpoint, this is usually the first part of that hostname.
    -
    -
    - -
    -
    - -
    Provide Subscription ID, Resource Group, and Speech Resource Name to auto-build the ARM resource ID.
    - - - -
    Required for Voice Responses when using Managed Identity. You can paste the full value manually, or let the fields above build it for you.
    -
    - -
    - - -
    - -
    - - -
    -
    - -
    - - -
    -
    Required only when Authentication Type is set to Key.
    -
    - -
    - Managed identity roles: Start with Cognitive Services Speech User. If fast transcription or other write-style speech operations still return authorization errors, add Cognitive Services Speech Contributor. Managed identity also requires a custom-domain endpoint. -
    - -
    -

    - - - Enhanced Citations - - will dramatically improve the citation experience for video and audio files. - -

    -
    -
    diff --git a/application/single_app/templates/admin/_panes/search-index.html b/application/single_app/templates/admin/_panes/search-index.html new file mode 100644 index 000000000..285f96da9 --- /dev/null +++ b/application/single_app/templates/admin/_panes/search-index.html @@ -0,0 +1,119 @@ +
    +
    +
    Azure AI Search
    +

    + Configure Azure AI Search settings. +

    +
    + + + +
    + +
    + +
    +
    + + +
    +
    + + +
    +
    + +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + +
    + + +
    +
    +
    + + + +
    +
    +
    + + +
    diff --git a/application/single_app/templates/admin/_panes/security.html b/application/single_app/templates/admin/_panes/secrets.html similarity index 99% rename from application/single_app/templates/admin/_panes/security.html rename to application/single_app/templates/admin/_panes/secrets.html index 40d43e1a9..dbf36ddc0 100644 --- a/application/single_app/templates/admin/_panes/security.html +++ b/application/single_app/templates/admin/_panes/secrets.html @@ -1,4 +1,4 @@ -
    +

    Manage security settings for key vault and other security configurations.

    diff --git a/application/single_app/templates/admin/_panes/send-feedback.html b/application/single_app/templates/admin/_panes/send-feedback.html index 1d9cdb365..5acd28833 100644 --- a/application/single_app/templates/admin/_panes/send-feedback.html +++ b/application/single_app/templates/admin/_panes/send-feedback.html @@ -1,4 +1,4 @@ -
    +

    Prepare a prefilled email draft for bug reports or feature requests. This utility is separate from saved settings and records each submission intent in the activity log before opening your local email client.

    diff --git a/application/single_app/templates/admin/_panes/session.html b/application/single_app/templates/admin/_panes/session.html new file mode 100644 index 000000000..cb8fe9abe --- /dev/null +++ b/application/single_app/templates/admin/_panes/session.html @@ -0,0 +1,87 @@ +
    +
    +
    + System Settings +
    +

    + System-level settings that control application behavior, including file size limits, conversation history, + and default prompts. +

    +
    + + +
    +
    + + +
    +
    + + + +
    +
    +
    + + + Users are logged out locally after this many minutes of inactivity. Minimum value: 10 minutes. +
    +
    + + + Show the warning modal after this many minutes of inactivity. Set this equal to the logout timeout to disable the warning dialog window. +
    +
    + + + Custom text shown at the top of the idle warning dialog. +
    +
    +
    + + +
    +
    + + Shown to signed-in users who lack the required roles. Use Enter for line breaks. + +
    +
    +
    \ No newline at end of file diff --git a/application/single_app/templates/admin/_panes/support-menu.html b/application/single_app/templates/admin/_panes/support-menu.html new file mode 100644 index 000000000..57c11877b --- /dev/null +++ b/application/single_app/templates/admin/_panes/support-menu.html @@ -0,0 +1,105 @@ +
    +
    +
    + Support +
    +
    + + + +
    +

    When enabled, users can access Support destinations like Send Feedback and Latest Features directly from navigation.

    + +
    +
    + + + This name will appear in user navigation as the Support menu title. +
    + +
    + + + +
    + +
    + + + User Send Feedback drafts will be addressed to this internal email address. +
    + +
    + + + +
    + +
    +
    User-Facing Latest Features
    +

    Choose which recent features are shared on the user Latest Features page. Deployment and Redis start unchecked because they are mainly admin-facing rollout and infrastructure topics.

    +
    + + + + When enabled, user-facing Latest Features cards can show public guide buttons in addition to the direct in-app shortcuts. +
    + {% for release_group in support_latest_feature_release_groups %} + {% set checklist_collapse_id = release_group.collapse_id ~ 'Checklist' %} +
    +
    +
    +
    +
    {{ release_group.label }}{% if release_group.release_version %}v{{ release_group.release_version }}{% endif %}
    +

    {{ release_group.description }}

    +
    + {% if not release_group.default_expanded %} + + {% endif %} +
    +
    +
    + {% for feature in release_group.features %} +
    +
    + + +
    +
    + {% endfor %} +
    +
    +
    +
    + {% endfor %} +
    +
    +
    +
    \ No newline at end of file diff --git a/application/single_app/templates/admin/_panes/web-research.html b/application/single_app/templates/admin/_panes/web-research.html new file mode 100644 index 000000000..7ad547075 --- /dev/null +++ b/application/single_app/templates/admin/_panes/web-research.html @@ -0,0 +1,519 @@ +
    + +

    + Configure Azure AI Search, Document Intelligence, and multimedia support settings. +

    + +
    +
    +
    Web Search (Azure AI Foundry Agent)
    + +
    +

    Enable web search by routing queries through an Azure AI Foundry agent configured by admins.

    +
    + + +
    + + + +
    + +
    +
    +
    URL Access
    + Shared Policy +
    +

    Control direct URL content fetching for pasted chat links, workflow prompts, and Deep Research source review.

    +
    + + +
    +
    + + +
    Required app role value: UrlAccessUser. Assign this role to users or groups in the Enterprise App before enabling the requirement. When enabled, only assigned users can use URL Access in chat or enable it for workflows.
    +
    + +
    +
    + URL Access uses the same server-side URL protections as Deep Research: non-HTTP(S) URLs, credentialed URLs, literal IP targets, localhost, metadata hosts, unsafe redirects, unsupported content types, and oversized pages are blocked before fetch. +
    +
    +
    + + +
    Hard limit: 100 direct URLs per chat message.
    +
    +
    + + +
    Hard limit: 500 direct URLs per workflow prompt.
    +
    +
    +
    + +
    +
    +
    + + +
    + + +
    +
    +
    +
    Leave blank to allow any public domain that passes safety checks. Deep Research uses this same allow list.
    +
    +
    +
    + + +
    + + +
    +
    +
    +
    Blocked domains apply to URL Access and Deep Research source-page review.
    +
    +
    + +
    +
    +
    +
    URL Policy Test
    +
    Check a URL against the current allowed and blocked domain rules before saving.
    +
    + +
    +
    +
    + +
    +
    +
    Deep Research
    +
    + Optional + +
    +
    +

    Plan bounded web searches, inspect source pages, and keep an internal research ledger for evidence coverage. Direct pasted URLs use the shared URL Access controls above.

    +
    + + +
    + +
    +
    + Server-side protections always block non-HTTP(S) URLs, literal IP URL targets, localhost, metadata hosts, credentialed URLs, excessive redirects, unsupported content types, oversized pages, and requests beyond the configured page budget. DNS hostnames that resolve to private/internal addresses require the internal-host opt-in below. +
    + +
    + + +
    Required app role value: DeepResearchUser. Assign this role to users or groups in the Enterprise App before enabling the requirement. When enabled, only assigned users can use Deep Research.
    +
    + +
    + + +
    Allows DNS hostnames that resolve to private/internal addresses. Literal IP URL targets, localhost, metadata hosts, link-local addresses, and reserved addresses remain blocked.
    +
    + +
    +
    + + + +
    Deep Research runs only when the user selects it for the message.
    +
    +
    + + +
    Hard limit: 10 pages.
    +
    +
    + + +
    Limits initial search-result and direct URL pages so budget remains for child pages.
    +
    +
    + + +
    Direct URLs beyond this cap are recorded as omitted in the ledger.
    +
    +
    + + +
    Includes the original current-message query.
    +
    +
    + + +
    Hard limit: 30 seconds.
    +
    +
    + + +
    Every redirect target is revalidated.
    +
    +
    + + +
    Hard limit: 5 MB.
    +
    +
    + + +
    Depth 2 follows selected links from seed and child pages.
    +
    +
    + +
    +
    + {% set js_runtime = source_review_runtime_capabilities or {} %} +
    + + +
    +
    Deep Research follows only scored, policy-approved links within the page and depth budgets.
    +
    +
    +
    + + +
    +
    The selected chat model can propose bounded current-message-only query variants before page review.
    +
    +
    +
    + + +
    +
    Creates a Markdown chat artifact with search queries, reviewed sources, skipped URLs, and coverage.
    +
    +
    +
    + + +
    +
    When source pages expose candidate links, the selected chat model can rank those candidates before the server fetches them.
    +
    +
    +
    + + +
    +
    Requires verified Playwright browser runtime support on the app host.
    +
    + {{ js_runtime.message or 'Runtime support has not been checked yet.' }} +
    + {% if not js_runtime.js_rendering_available %} +
    Install/enable the Playwright Chromium runtime, then reload Admin Settings to enable this option.
    + {% endif %} + {% if js_runtime.sandbox_disabled %} +
    Chromium sandbox is disabled by environment configuration.
    + {% endif %} +
    +
    + + +
    When JavaScript rendering is enabled, Deep Research can click visible Load More controls until this cap is reached.
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + + + + + + + +
    diff --git a/application/single_app/templates/admin/_panes/workflow.html b/application/single_app/templates/admin/_panes/workflow.html new file mode 100644 index 000000000..242119643 --- /dev/null +++ b/application/single_app/templates/admin/_panes/workflow.html @@ -0,0 +1,157 @@ +
    +
    +
    + Workflow +
    +

    + Control personal and group workflow authoring and execution for users. +

    +
    + + + +
    +
    + + + +
    +

    + Required app role value: WorkflowUser. Assign this role to users or groups in the Enterprise App before enabling the requirement. +

    + +
    + + +
    + Maximum automatic tool or action calls an agent can make during one workflow run. Default is 60; increase for large document sets. +
    + +
    + +
    + + +
    + Maximum ordered instruction tasks users can add to one workflow. Default is 50; supported range is 1-100. +
    +
    + +
    + +
    + + + +
    +
    + + + +
    +
    + + No groups assigned. +
    + +

    + Group workflow authoring is available to group Owners and Admins by default. Enable the owner-only setting below to limit group agent, action, and workflow management to Owners. +

    +
    + + + + +
    diff --git a/application/single_app/templates/admin/_panes/workspace-identities.html b/application/single_app/templates/admin/_panes/workspace-identities.html index da77b91b5..7c3569ebd 100644 --- a/application/single_app/templates/admin/_panes/workspace-identities.html +++ b/application/single_app/templates/admin/_panes/workspace-identities.html @@ -1,4 +1,4 @@ -
    +

    Manage the global authentication profiles that File Sync sources and Actions reuse, so credentials stay scoped and are resolved server-side.

    diff --git a/application/single_app/templates/admin/_panes/workspace-types.html b/application/single_app/templates/admin/_panes/workspace-types.html new file mode 100644 index 000000000..83123fd7a --- /dev/null +++ b/application/single_app/templates/admin/_panes/workspace-types.html @@ -0,0 +1,159 @@ +
    +

    + Configure workspace settings like personal/group access, multimedia support, metadata, and document classification. +

    + + +
    +
    + Personal Workspaces +
    +

    + Turn this on to allow access and management of your personal workspace. +

    +
    + + + +
    +
    + +
    +
    + Group Workspaces +
    +

    + Turn this on to allow access and management of group workspaces, as well as group collaboration features. +

    +
    + + + +
    + + +
    +
    + + +
    + + + +
    +

    + When enabled, no users will be able to create new groups, regardless of app role assignment. This global setting overrides the Require CreateGroups App Role setting below. +

    + +
    + + + +
    +

    + Required app role value: CreateGroups. Assign this role to users or groups in the Enterprise App before enabling the requirement. If disabled, any authenticated user can create groups while group workspaces and group creation are enabled. +

    + +
    + + +
    + + + +
    +

    + If enabled, only the group Owner can create, edit, and delete group agents, group actions, and group workflows. Admins and other roles will only be able to view them. +

    +
    + +
    + +
    +
    + Public Workspaces +
    +

    + Turn this on to enable public workspaces that are visible to everyone in the organization. +

    +
    + + + +
    + +
    + + +
    + Optional. End users will see this label instead of Public Workspace. Admin settings and internal references continue to use Public Workspace. +
    +
    + +
    +
    +
    + + + +
    +

    + Required app role value: CreatePublicWorkspaces. Assign this role to users or groups in the Enterprise App before enabling the requirement. If disabled, any authenticated user can create public workspaces while public workspaces are enabled. +

    +
    + +
    + + +
    diff --git a/application/single_app/templates/admin/_panes/workspaces.html b/application/single_app/templates/admin/_panes/workspaces.html deleted file mode 100644 index 9200f71d9..000000000 --- a/application/single_app/templates/admin/_panes/workspaces.html +++ /dev/null @@ -1,746 +0,0 @@ -
    -

    - Configure workspace settings like personal/group access, multimedia support, metadata, and document classification. -

    - - -
    -
    - Personal Workspaces -
    -

    - Turn this on to allow access and management of your personal workspace. -

    -
    - - - -
    -
    - -
    -
    - Workflow -
    -

    - Control personal and group workflow authoring and execution for users. -

    -
    - - - -
    -
    - - - -
    -

    - Required app role value: WorkflowUser. Assign this role to users or groups in the Enterprise App before enabling the requirement. -

    - -
    - - -
    - Maximum automatic tool or action calls an agent can make during one workflow run. Default is 60; increase for large document sets. -
    - -
    - -
    - - -
    - Maximum ordered instruction tasks users can add to one workflow. Default is 50; supported range is 1-100. -
    -
    - -
    - -
    - - - -
    -
    - - - -
    -
    - - No groups assigned. -
    - -

    - Group workflow authoring is available to group Owners and Admins by default. Enable the owner-only setting below to limit group agent, action, and workflow management to Owners. -

    -
    - -
    -
    - File Downloads -
    -

    - Control when users can download original workspace document files from personal, group, and public workspaces. -

    -
    - - - -
    -
    -
    - - - -
    -
    - - - -
    -
    - - No groups assigned. -
    - -
    -
    - - - -
    -
    - - - -
    -
    - - No public workspaces assigned. -
    - -
    - - - - - - - - -
    -
    - Group Workspaces -
    -

    - Turn this on to allow access and management of group workspaces, as well as group collaboration features. -

    -
    - - - -
    - - -
    -
    - - -
    - - - -
    -

    - When enabled, no users will be able to create new groups, regardless of app role assignment. This global setting overrides the Require CreateGroups App Role setting below. -

    - -
    - - - -
    -

    - Required app role value: CreateGroups. Assign this role to users or groups in the Enterprise App before enabling the requirement. If disabled, any authenticated user can create groups while group workspaces and group creation are enabled. -

    - -
    - - -
    - - - -
    -

    - If enabled, only the group Owner can create, edit, and delete group agents, group actions, and group workflows. Admins and other roles will only be able to view them. -

    -
    - -
    - -
    -
    - Public Workspaces -
    -

    - Turn this on to enable public workspaces that are visible to everyone in the organization. -

    -
    - - - -
    - -
    - - -
    - Optional. End users will see this label instead of Public Workspace. Admin settings and internal references continue to use Public Workspace. -
    -
    - -
    -
    -
    - - - -
    -

    - Required app role value: CreatePublicWorkspaces. Assign this role to users or groups in the Enterprise App before enabling the requirement. If disabled, any authenticated user can create public workspaces while public workspaces are enabled. -

    -
    - -
    - -
    -
    - File Sharing -
    -

    - Turn this on to enable file sharing capabilities between users and workspaces. -

    -
    - - - -
    -
    - - -
    -
    - Metadata Extraction -
    -

    - Enable this to automatically parse and store file metadata for advanced indexing and search. -

    -
    - - - -
    - -
    - - - -
    - Uses Global Endpoints when multi-endpoint model management is enabled; otherwise uses the legacy GPT/APIM deployment settings. -
    -
    -
    - - -
    -
    - Multi-Modal Vision Analysis -
    -

    - Enable AI-powered vision analysis for images uploaded to chat or workspace. When enabled alongside Document Intelligence OCR, images will receive both text extraction (OCR) and semantic understanding (vision AI). -

    - -
    - How it works: -
      -
    • Document Intelligence: Extracts text from images (OCR)
    • -
    • Vision Model: Provides semantic analysis, object detection, and contextual understanding
    • -
    • Both analyses are combined and available in citations when Enhanced Citations is enabled
    • -
    -
    - -
    - - - -
    - -
    - - -
    Select a GPT model with vision capabilities (for example, gpt-4o or supported GPT 5 and later models). Only vision-capable models are shown.
    - - -
    -
    -
    - - - -
    -
    - User Agreement -
    -

    - Configure a user agreement that users must accept before uploading files. - Supports Markdown formatting. -

    - - -
    - - - -
    - - -
    -
    - - -
    - -

    Select where the user agreement should be shown (at least one required):

    -
    -
    -
    - - -
    -
    - - -
    -
    -
    -
    - - -
    -
    - - -
    -
    -
    - -
    - - -
    - - -
    - 0 / 200 words - -
    -
    - - -
    - - - -
    - - -
    - -
    -
    -
    -
    diff --git a/application/single_app/templates/admin_settings.html b/application/single_app/templates/admin_settings.html index 65e958b1d..0d1d9e4b1 100644 --- a/application/single_app/templates/admin_settings.html +++ b/application/single_app/templates/admin_settings.html @@ -980,7 +980,10 @@

    12. Enhanced Citations and Image Generation

    visible whichever governance tab is active. #}
    - {% include "admin/_panes/security.html" %} + {% include "admin/_panes/secrets.html" %} + {% include "admin/_panes/access-roles.html" %} + {% include "admin/_panes/content-safety.html" %} + {% include "admin/_panes/session.html" %} {% include "admin/_panes/agents.html" %} @@ -994,7 +997,8 @@

    12. Enhanced Citations and Image Generation

    {% include "admin/_panes/logging.html" %} - {% include "admin/_panes/general.html" %} + {% include "admin/_panes/branding.html" %} + {% include "admin/_panes/notices.html" %} {% include "admin/_panes/custom-pages.html" %} @@ -1016,7 +1020,9 @@

    12. Enhanced Citations and Image Generation

    {% include "admin/_panes/file-sync.html" %} - {% include "admin/_panes/workspaces.html" %} + {% include "admin/_panes/workspace-types.html" %} + {% include "admin/_panes/files-sharing.html" %} + {% include "admin/_panes/workflow.html" %} {# Data Lifecycle: what happens to user data over time #} {% include "admin/_panes/retention.html" %} @@ -1031,11 +1037,14 @@

    12. Enhanced Citations and Image Generation

    {% include "admin/_panes/feedback-alerts.html" %} - {% include "admin/_panes/safety.html" %} - {% include "admin/_panes/search-extract.html" %} + {% include "admin/_panes/web-research.html" %} + {% include "admin/_panes/search-index.html" %} + {% include "admin/_panes/extraction.html" %} + {% include "admin/_panes/audio-video.html" %} + {% include "admin/_panes/support-menu.html" %} {% include "admin/_panes/send-feedback.html" %} {# Latest Features stays last so it never opens by default #} diff --git a/docs/explanation/features/ADMIN_SETTINGS_IA_REWORK_STATUS.md b/docs/explanation/features/ADMIN_SETTINGS_IA_REWORK_STATUS.md index 0e9a7ef64..8fd27d02d 100644 --- a/docs/explanation/features/ADMIN_SETTINGS_IA_REWORK_STATUS.md +++ b/docs/explanation/features/ADMIN_SETTINGS_IA_REWORK_STATUS.md @@ -22,8 +22,8 @@ Development ─── feature/admin-settings-ia ──┬── #1297 stage 1 └──► final PR ──► Development ``` -Current version: **0.260.012**. Fingerprint: **462 field names / 110 card ids**. -Navigation: **13 groups / 27 tabs / 88 sections**. +Current version: **0.260.014**. Fingerprint: **462 field names / 110 card ids**. +Navigation: **14 groups / 36 tabs / 88 sections**. ### Shipped @@ -109,6 +109,57 @@ moved from Scale to Security that way. | Scale | → Redis & Caching, Cosmos; Front Door moved to Security as Network | | Data Lifecycle | **New group.** Retention + Classification pulled from Workspaces, Archiving pulled from Safety | | Chat | **New group.** Chat Experience (thoughts from AI Models, file uploads + contents drawer and scope lock from Workspaces), Feedback & Alerts (feedback + desktop notifications from Safety) | +| Appearance | **General dismantled.** → Branding, Notices & Agreements (+ user agreement from Workspaces), Pages & Links (+ external links) | +| Security | **Safety dismantled.** → Access & Roles, Secrets, Content Safety, Session, Network | +| Operations | Logging is now Logging & Health, gaining health check and API documentation from General | +| Help | Gains Support Menu from General | +| Knowledge | **Search & Extract dismantled.** → Web & Research, Search Index, Document Extraction (+ metadata extraction and multi-modal vision from Workspaces), Audio & Video | +| Workspaces | → Workspace Types, Files & Sharing (+ shared conversation file approvals from AI Models), Global Identities | +| Workflow | **New group**, split out of Workspaces | + +### Card container ids are not the nav section ids + +Several cards are wrapped in a container whose id differs from the nav map's +section id, which is an inner anchor: + +| Nav section id | Card container id | +|---|---| +| `web-search-section` | `web-search-foundry-section` | +| `embeddings-config` | `embeddings-configuration` | +| `image-config` | `image-generation-configuration` | +| `gpt-config` | `gpt-configuration` | +| `agents-config` | `agents-configuration` | +| `actions-config` | `actions-configuration` | + +**The move and split tools take container ids**; the nav map keeps its own. +Run `list_pane_cards.py` for the real container id rather than assuming. + +### Trap: gpt-configuration is inside a modal + +`gpt-configuration` is **not** a top-level card. It lives inside +`legacyModelSettingsModal` in the AI Models pane. Splitting AI Models means +moving a modal, not a card, which is why AI Models and Agents are deliberately +left for their own change rather than bundled with Knowledge and Workspaces. + + +### Two hardcoded-id traps found and closed + +Both were latent breakage that only surfaced because a tab id changed: + +- **`openKeyVaultSettings`** in `admin_data_management.js` switched tabs by the + literal id `security-tab`. It was dead weight anyway — the link now carries + `data-admin-link` and `admin_card_links.js` resolves the tab from the DOM. +- **The landing pane** was `show active` hardcoded in one pane's markup and + `showAdminTab('general')` hardcoded in the sidebar script. Splitting that + pane left Admin Settings with **no active pane at all**. Every pane now + renders `{% if admin_landing_tab == '' %} show active{% endif %}`, fed by + `get_landing_tab_id()`, and the sidebar reads the first rendered tab. + +**Assert durable properties, not current ids.** Four test files hardcoded +`general` or `security` and had to be rewritten to assert what actually matters +— Latest Features is last, exactly one pane is active, every tab renders one +pane. Any new test that names a tab id will need the same treatment next time. + ### The cross-pane move tool diff --git a/docs/explanation/release_notes.md b/docs/explanation/release_notes.md index 3d12d8127..5d5f6154b 100644 --- a/docs/explanation/release_notes.md +++ b/docs/explanation/release_notes.md @@ -2,6 +2,68 @@ For feature-focused and fix-focused drill-downs by version, see [Features by Version](/explanation/features/) and [Fixes by Version](/explanation/fixes/). +### **(v0.260.014)** + +#### User Interface Enhancements + +* **Knowledge Settings Split By What They Actually Do** + * Search & Extract held eight cards spanning four unrelated jobs, from Bing consent to voice transcription. + * Knowledge now has **Web & Research** (web search, URL access, deep research), **Search Index** (Azure AI Search), **Document Extraction** (document intelligence, chunk sizes, plus metadata extraction and multi-modal vision brought over from Workspaces) and **Audio & Video** (video intelligence, voice conversations), alongside the existing File Sync. + * Voice and video sit under Knowledge rather than Chat because they are extraction pipelines that turn recordings into searchable content. + * (Ref: `web-research`, `search-index`, `extraction`, `audio-video`) + +* **Workspaces Focused On Workspaces** + * Workspaces mixed workspace types with file rules, workflow and extraction settings. + * It is now **Workspace Types** (personal, group, public), **Files & Sharing** (downloads, sharing, and shared conversation file approvals brought over from AI Models) and the existing Global Identities. + * (Ref: `workspace-types`, `files-sharing`) + +* **Workflow Is Its Own Area** + * Workflow drives approvals and assignment across every workspace type and was too large to sit as one card inside Workspaces. It now has its own group. + * (Ref: `workflow`, `workflow-settings-section`) + +#### Bug Fixes + +* **Group Workflow Assignment Dialog Could Not Open** + * The Group Workflow Assignment dialog ended up in a different tab from the button that opens it. Because an inactive tab is hidden, the dialog would not have appeared at all. + * The dialog now sits with its button, and a new check verifies this for every dialog in Admin Settings so it cannot happen again. + * (Ref: `groupWorkflowAssignmentModal`, `test_admin_settings_modal_placement.py`) + +* **Misplaced Section Comments In AI Models** + * Two section comments had drifted onto the wrong cards while settings were being regrouped, labelling the embeddings card as processing thoughts. + * (Ref: `ai-models` pane) + +### **(v0.260.013)** + +#### User Interface Enhancements + +* **General Tab Broken Up Into Focused Tabs** + * General had grown into a catch-all of eleven unrelated cards: branding sat next to health checks, API documentation, terms of use and system settings. + * Appearance now has **Branding** (branding, home page text, appearance), **Notices & Agreements** (classification banner, chat AI notice, terms of use and the user agreement pulled across from Workspaces) and **Pages & Links** (static pages plus external links). + * Health Check and API Documentation moved to Operations, which is now **Logging & Health** — they report on how the app is running rather than how it looks. + * Support moved to Help as its own **Support Menu** tab, next to Send Feedback. + * (Ref: `branding`, `notices`, `custom-pages`, `logging`, `support-menu`) + +* **Security Split Into Five Purposeful Tabs** + * Security held a single Key Vault card while an unrelated Safety tab mixed content filtering with role permissions, which are different jobs. + * Security is now **Access & Roles** (who gets in and with what role), **Secrets** (Key Vault), **Content Safety** (what may be said once you are in), **Session** (idle timeout and related system settings) and **Network** (Azure Front Door). + * (Ref: `access-roles`, `secrets`, `content-safety`, `session`, `network`) + +#### Bug Fixes + +* **"Open Key Vault Settings" Link No Longer Depends On A Hardcoded Tab** + * The link from Data Management to Key Vault switched tabs by a hardcoded id, so it silently stopped working whenever that tab was renamed. + * It now uses the standard card link, which finds the owning tab from the page itself and stays correct however the settings are grouped. + * (Ref: `data-management-key-vault-link`, `admin_card_links.js`, `admin_data_management.js`) + +* **Admin Settings Always Opens On A Real Tab** + * The tab shown on arrival was pinned to a specific id in both the markup and the sidebar script. Regrouping settings could leave Admin Settings opening with no tab selected at all. + * The landing tab is now taken from the navigation map, so it follows the settings and can never be Latest Features. + * (Ref: `admin_landing_tab`, `get_landing_tab_id`, `admin_sidebar_nav.js`) + +* **Stale Tab Names In Latest Features** + * Several Latest Features entries pointed readers at tabs by their old names after the settings moved. + * (Ref: `latest-features` pane) + ### **(v0.260.012)** #### User Interface Enhancements diff --git a/functional_tests/test_admin_latest_features_tab.py b/functional_tests/test_admin_latest_features_tab.py index 322bfea1a..31d96dfc4 100644 --- a/functional_tests/test_admin_latest_features_tab.py +++ b/functional_tests/test_admin_latest_features_tab.py @@ -341,7 +341,7 @@ def test_latest_features_sidebar_navigation(): # Tab order is defined once in the nav map, which the sidebar renders from, # so ordering is asserted there rather than against the rendered markup. tab_ids = get_tab_ids() - assert tab_ids.index('latest-features') > tab_ids.index('general'), 'Latest Features should appear after General' + assert tab_ids[-1] == 'latest-features', 'Latest Features should be the last destination of all' assert tab_ids.index('latest-features') > tab_ids.index('send-feedback'), 'Latest Features should be the last destination, after Send Feedback' print('Latest Features sidebar navigation is present') @@ -372,10 +372,18 @@ def test_latest_features_top_nav_priority(): ) # Latest Features opened on every visit to Admin Settings, which is why it - # is pinned last and General is the landing tab instead. - assert 'class="tab-pane fade" id="latest-features" role="tabpanel" aria-labelledby="latest-features-tab"' in template_content, 'Latest Features pane should not be the default active tab' - assert 'class="tab-pane fade show active" id="general" role="tabpanel" aria-labelledby="general-tab"' in template_content, 'General pane should be the default active tab' - assert tab_ids[0] == 'general', 'General should be the first tab in the navigation map' + # is pinned last. The landing pane is not hardcoded: every pane derives its + # active state from admin_landing_tab, which is the first tab of the first + # group, so regrouping cards can never leave Admin Settings with no pane + # showing or with Latest Features showing. + assert '
    1}) assert not duplicates, f'Tabs listed more than once in the nav map: {duplicates}' - assert template_content.count('id="security" role="tabpanel"') == 1, 'Security tab pane should appear exactly once' - assert template_content.count('tab-pane fade show active') == 1, 'Only one tab pane should be marked show active' + # Every tab in the map must render exactly one pane. Checking all of them + # is stronger than naming one tab, and cannot go stale as tabs are renamed. + for tab_id in tab_ids: + pane_count = template_content.count(f'id="{tab_id}" role="tabpanel"') + assert pane_count == 1, f"Tab pane '{tab_id}' should appear exactly once, found {pane_count}" + # No pane may hardcode the active state; exactly one resolves it at render + # time from the nav map. + assert template_content.count('tab-pane fade show active') == 0, ( + 'No pane should hardcode "show active"; it is derived from admin_landing_tab' + ) + landing_conditionals = template_content.count("{% if admin_landing_tab == '") + assert landing_conditionals == len(tab_ids), ( + f'Every one of the {len(tab_ids)} panes should derive its active state ' + f'from admin_landing_tab, found {landing_conditionals}' + ) assert 'Managesecuritysettingsforkeyvaultandothersecurityconfigurations.

    ' in normalized_template, 'Security intro paragraph should be properly closed' # Every tab in the map must have a pane to activate. diff --git a/functional_tests/test_admin_settings_modal_placement.py b/functional_tests/test_admin_settings_modal_placement.py new file mode 100644 index 000000000..483f0ec02 --- /dev/null +++ b/functional_tests/test_admin_settings_modal_placement.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 +""" +Functional test for Admin Settings modal placement across tab panes. +Version: 0.260.014 +Implemented in: 0.260.014 + +Admin Settings modals are interleaved between cards rather than collected at the +end of the template, so splitting a tab pane can silently strand a modal in a +pane that never opens it. A modal inside an inactive tab pane cannot be shown, +because the pane itself is hidden, so the failure is invisible until a user +clicks the button. + +This test ensures every modal lives in a pane that can actually open it. +""" + +import os +import re +import sys +import collections + +sys.path.append(os.path.dirname(os.path.abspath(__file__))) + +PANES_DIR = os.path.join( + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + "application", + "single_app", + "templates", + "admin", + "_panes", +) +SHELL = os.path.join( + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + "application", + "single_app", + "templates", + "admin_settings.html", +) + +MODAL_PATTERN = re.compile(r'class="modal fade[^"]*"\s+id="([^"]+)"') +TRIGGER_PATTERN = re.compile(r'data-bs-target="#([^"]+)"') + +# The shell sits outside every pane, so a modal there is reachable from anywhere +# and a trigger there is not owned by any one pane. +SHELL_KEY = "__shell__" + + +def _read(path): + with open(path, "r", encoding="utf-8") as handle: + return handle.read() + + +def _collect(): + """Map each modal id to its pane, and each modal id to the panes opening it.""" + modal_home = {} + trigger_homes = collections.defaultdict(set) + + sources = [(SHELL_KEY, SHELL)] + for name in sorted(os.listdir(PANES_DIR)): + if name.endswith(".html"): + sources.append((name[: -len(".html")], os.path.join(PANES_DIR, name))) + + for pane, path in sources: + markup = _read(path) + for match in MODAL_PATTERN.finditer(markup): + modal_home[match.group(1)] = pane + for match in TRIGGER_PATTERN.finditer(markup): + trigger_homes[match.group(1)].add(pane) + + return modal_home, trigger_homes + + +def test_modals_live_where_they_are_opened(): + """Every modal must sit in a pane that can open it, or in the shell.""" + print("Testing Admin Settings modal placement...") + + modal_home, trigger_homes = _collect() + assert modal_home, "No modals found; the collector is probably looking in the wrong place" + + stranded = [] + for modal_id, home in sorted(modal_home.items()): + if home == SHELL_KEY: + continue + openers = trigger_homes.get(modal_id) + if not openers: + # Opened from JavaScript rather than markup, which this test cannot + # attribute to a pane. Those are covered by the card link tests. + continue + foreign = {pane for pane in openers if pane not in (home, SHELL_KEY)} + if foreign and home not in openers: + stranded.append((modal_id, home, sorted(foreign))) + + assert not stranded, "Modals stranded in a pane that never opens them:\n" + "\n".join( + f" '{modal_id}' lives in '{home}' but is only opened from {openers}" + for modal_id, home, openers in stranded + ) + + print(f"All {len(modal_home)} modals sit in a pane that can open them.") + return True + + +def test_modal_ids_are_unique(): + """A duplicated modal id would make the wrong dialog open.""" + print("Testing Admin Settings modal id uniqueness...") + + counts = collections.Counter() + paths = [SHELL] + [ + os.path.join(PANES_DIR, name) + for name in sorted(os.listdir(PANES_DIR)) + if name.endswith(".html") + ] + for path in paths: + for match in MODAL_PATTERN.finditer(_read(path)): + counts[match.group(1)] += 1 + + duplicates = sorted(modal_id for modal_id, count in counts.items() if count > 1) + assert not duplicates, f"Modal ids declared more than once: {duplicates}" + + print(f"All {len(counts)} modal ids are unique.") + return True + + +if __name__ == "__main__": + tests = [ + test_modals_live_where_they_are_opened, + test_modal_ids_are_unique, + ] + results = [] + for test in tests: + print(f"\nRunning {test.__name__}...") + try: + results.append(bool(test())) + except Exception as error: # noqa: BLE001 - report and continue + print(f"Test failed: {error}") + import traceback + + traceback.print_exc() + results.append(False) + + print(f"\nResults: {sum(results)}/{len(results)} tests passed") + sys.exit(0 if all(results) else 1) diff --git a/functional_tests/test_admin_settings_nav_map.py b/functional_tests/test_admin_settings_nav_map.py index ce015c6f6..0754dddf9 100644 --- a/functional_tests/test_admin_settings_nav_map.py +++ b/functional_tests/test_admin_settings_nav_map.py @@ -143,14 +143,23 @@ def test_latest_features_stays_last(): assert tab_ids[-1] == "latest-features", ( f"Latest Features must be the last tab, got '{tab_ids[-1]}'" ) - assert tab_ids[0] == "general", ( - f"General must be the first tab, got '{tab_ids[0]}'" - ) assert ADMIN_NAV[-1]["id"] == "help", ( "Latest Features should sit in the last group" ) - print("Latest Features is last; General leads.") + # The landing tab is whatever the map lists first, so it moves freely as the + # information architecture changes. What must never drift is that the admin + # does not land on Latest Features, which is the whole point of the move. + assert tab_ids[0] != "latest-features", ( + "Latest Features must never be the landing tab" + ) + assert ADMIN_NAV[0]["tabs"], "The first group must expose at least one tab" + assert tab_ids[0] == ADMIN_NAV[0]["tabs"][0]["id"], ( + "The landing tab must be the first tab of the first group, so the " + "sidebar and the tab strip agree on where an admin lands" + ) + + print(f"Latest Features is last; '{tab_ids[0]}' leads.") if __name__ == "__main__": diff --git a/functional_tests/test_admin_source_review_depth_save.py b/functional_tests/test_admin_source_review_depth_save.py index fa7a602cd..528bf0c0e 100644 --- a/functional_tests/test_admin_source_review_depth_save.py +++ b/functional_tests/test_admin_source_review_depth_save.py @@ -41,9 +41,11 @@ def test_source_review_depth_has_single_form_field(): f"Expected exactly one source_review_max_depth form field, found {depth_field_name_count}." ) + # Bound the Latest Features visibility block by its own container rather + # than by a neighbouring card, so the check survives cards moving between + # tabs during information architecture work. latest_features_start = template_content.index('id="support_latest_features_settings"') - external_links_start = template_content.index('id="external-links-section"') - latest_features_section = template_content[latest_features_start:external_links_start] + latest_features_section = template_content[latest_features_start:latest_features_start + 8000] assert 'name="source_review_max_depth"' not in latest_features_section, ( "Latest Features visibility controls must not post source_review_max_depth." diff --git a/functional_tests/test_data_management_security_patterns.py b/functional_tests/test_data_management_security_patterns.py index 422e3dfbf..284c123be 100644 --- a/functional_tests/test_data_management_security_patterns.py +++ b/functional_tests/test_data_management_security_patterns.py @@ -345,7 +345,6 @@ def test_admin_javascript_uses_safe_dom_patterns(): for required_snippet in [ 'document.createElement("tr")', 'document.createElement("td")', - 'openKeyVaultSettings', 'buildMigrationPlan()', 'queueMigration(false)', 'loadMigrationCatalog(targetType, "reset")',