diff --git a/.github/workflows/broken-access-control-check.yml b/.github/workflows/broken-access-control-check.yml index fe83961a..87eaf627 100644 --- a/.github/workflows/broken-access-control-check.yml +++ b/.github/workflows/broken-access-control-check.yml @@ -4,6 +4,7 @@ on: pull_request: branches: - Development + - feature/admin-settings-ia # temporary: Admin Settings IA staging branch paths: - 'application/**/*.py' - 'scripts/check_broken_access_control.py' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index af044401..3b02ae5f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -15,7 +15,7 @@ on: push: branches: [ "Development" ] pull_request: - branches: [ "Development" ] + branches: [ "Development", "feature/admin-settings-ia" ] workflow_dispatch: jobs: diff --git a/.github/workflows/malicious-pr-security-review.yml b/.github/workflows/malicious-pr-security-review.yml index 414f0dfd..6cd1c903 100644 --- a/.github/workflows/malicious-pr-security-review.yml +++ b/.github/workflows/malicious-pr-security-review.yml @@ -4,6 +4,7 @@ on: pull_request: branches: - Development + - feature/admin-settings-ia # temporary: Admin Settings IA staging branch paths: - 'application/**' - 'deployers/**' diff --git a/.github/workflows/python-syntax-check.yml b/.github/workflows/python-syntax-check.yml index 36b28a9a..6620ee41 100644 --- a/.github/workflows/python-syntax-check.yml +++ b/.github/workflows/python-syntax-check.yml @@ -5,6 +5,7 @@ on: branches: - main - Development + - feature/admin-settings-ia # temporary: Admin Settings IA staging branch paths: - 'application/single_app/**.py' - '.github/workflows/python-syntax-check.yml' diff --git a/.github/workflows/swagger-route-check.yml b/.github/workflows/swagger-route-check.yml index 1cf5c546..7ad558c0 100644 --- a/.github/workflows/swagger-route-check.yml +++ b/.github/workflows/swagger-route-check.yml @@ -6,6 +6,7 @@ on: - main - Development - Staging + - feature/admin-settings-ia # temporary: Admin Settings IA staging branch paths: - 'application/single_app/**/*.py' - 'scripts/check_swagger_routes.py' diff --git a/.github/workflows/xss-sink-check.yml b/.github/workflows/xss-sink-check.yml index 3aebd38f..8ec9cb46 100644 --- a/.github/workflows/xss-sink-check.yml +++ b/.github/workflows/xss-sink-check.yml @@ -4,6 +4,7 @@ on: pull_request: branches: - Development + - feature/admin-settings-ia # temporary: Admin Settings IA staging branch paths: - 'application/**/*.js' - 'application/**/*.html' diff --git a/application/single_app/config.py b/application/single_app/config.py index 179e2589..39d9a8a9 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.006" +VERSION = "0.260.007" 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_sidebar_nav.js b/application/single_app/static/js/admin/admin_sidebar_nav.js index ff628ec7..a5d85ad8 100644 --- a/application/single_app/static/js/admin/admin_sidebar_nav.js +++ b/application/single_app/static/js/admin/admin_sidebar_nav.js @@ -135,13 +135,14 @@ function initAdminSidebarNav() { }); }); - // Set the initial active tab (General) - but only if no tab is already active + // Set the initial active tab - but only if no tab is already active. + // Latest Features is deliberately excluded so it never opens by default. const activeTab = document.querySelector('.admin-nav-tab.active, .admin-nav-section.active'); if (!activeTab) { - const firstTab = document.querySelector('.admin-nav-tab[data-tab="latest-features"]'); + const firstTab = document.querySelector('.admin-nav-tab[data-tab="general"]'); if (firstTab) { firstTab.classList.add('active'); - showAdminTab('latest-features'); + showAdminTab('general'); } } else { console.log('initAdminSidebarNav - Found existing active tab, preserving current state:', activeTab.getAttribute('data-tab')); @@ -179,91 +180,17 @@ function showAdminTab(tabId) { window.showAdminTab = showAdminTab; function scrollToSection(sectionId) { - // Map section IDs to actual element IDs/classes in the admin settings + // Resolve a sidebar data-section value to the element it should scroll to. const sectionMap = { + // Only genuine aliases belong here. Any sidebar data-section value + // that already matches its element id resolves through the + // `sectionMap[sectionId] || sectionId` fallback below. 'gpt-config': 'gpt-configuration', - 'embeddings-config': 'embeddings-configuration', + 'embeddings-config': 'embeddings-configuration', 'image-config': 'image-generation-configuration', - 'multi-endpoint-configuration': 'multi-endpoint-configuration', - 'document-action-capabilities-card': 'document-action-capabilities-card', 'agents-config': 'agents-configuration', - 'agent-template-approvals-section': 'agent-template-approvals-section', 'actions-config': 'actions-configuration', - // Governance tab sections - 'governance-feature-toggles-section': 'governance-feature-toggles-section', - 'governance-mcp-destination-section': 'governance-mcp-destination-section', - 'governance-inbound-mcp-section': 'governance-inbound-mcp-section', - 'governance-feature-policies-section': 'governance-feature-policies-section', - 'governance-item-policies-section': 'governance-item-policies-section', - // General tab sections - 'branding-section': 'branding-section', - 'home-page-text-section': 'home-page-text-section', - 'appearance-section': 'appearance-section', - 'classification-banner-section': 'classification-banner-section', - 'ai-notice-section': 'ai-notice-section', - 'terms-of-use-section': 'terms-of-use-section', - 'custom-pages-section': 'custom-pages-section', - 'external-links-section': 'external-links-section', - 'health-check-section': 'health-check-section', - 'system-settings-section': 'system-settings-section', - 'control-center-admin-section': 'control-center-admin-section', - // Control Center tab sections - 'control-center-auto-refresh-section': 'control-center-auto-refresh-section', - 'control-center-overview-section': 'control-center-overview-section', - // Logging tab sections - 'application-insights-section': 'application-insights-section', - 'debug-logging-section': 'debug-logging-section', - 'file-processing-logs-section': 'file-processing-logs-section', - // Scale tab sections - 'redis-cache-section': 'redis-cache-section', - 'redis-monitoring-section': 'redis-monitoring-section', - 'conversation-cache-section': 'conversation-cache-section', - 'document-access-index-section': 'document-access-index-section', - 'cosmos-maintenance-section': 'cosmos-maintenance-section', - 'cosmos-throughput-section': 'cosmos-throughput-section', - 'cosmos-throughput-metrics-table-section': 'cosmos-throughput-metrics-table-section', - 'front-door-section': 'front-door-section', - // Workspaces tab sections - 'personal-workspaces-section': 'personal-workspaces-section', - 'group-workspaces-section': 'group-workspaces-section', - 'public-workspaces-section': 'public-workspaces-section', - 'file-sharing-section': 'file-sharing-section', - 'file-download-settings-section': 'file-download-settings-section', - 'chat-file-uploads-section': 'chat-file-uploads-section', - 'metadata-extraction-section': 'metadata-extraction-section', - 'multimodal-vision-section': 'multimodal-vision-section', - 'document-classification-section': 'document-classification-section', - 'workspace-scope-lock-section': 'workspace-scope-lock-section', - // Citations tab sections - 'standard-citations-section': 'standard-citations-section', - 'enhanced-citations-section': 'enhanced-citations-section', - // Safety tab sections - 'content-safety-section': 'content-safety-section', - 'user-feedback-section': 'user-feedback-section', - 'desktop-notifications-section': 'desktop-notifications-section', - 'permissions-section': 'permissions-section', - 'conversation-archiving-section': 'conversation-archiving-section', - // Security tab sections - 'keyvault-section': 'keyvault-section', - // Data Management tab sections - 'data-management-readiness-section': 'data-management-readiness-section', - 'data-management-backup-section': 'data-management-backup-section', - 'data-management-schedule-section': 'data-management-schedule-section', - 'data-management-storage-section': 'data-management-storage-section', - 'data-management-encryption-section': 'data-management-encryption-section', - 'data-management-migration-section': 'data-management-migration-section', - 'data-management-target-cosmos-section': 'data-management-target-cosmos-section', - 'data-management-backup-inventory-section': 'data-management-backup-inventory-section', - 'data-management-jobs-section': 'data-management-jobs-section', - // Search & Extract tab sections 'web-search-section': 'web-search-foundry-section', - 'url-access-section': 'url-access-section', - 'source-review-section': 'source-review-section', - 'azure-ai-search-section': 'azure-ai-search-section', - 'document-intelligence-section': 'document-intelligence-section', - 'chunk-size-section': 'chunk-size-section', - 'video-intelligence-section': 'video-intelligence-section', - 'ai-voice-chat-section': 'ai-voice-chat-section' }; const targetElementId = sectionMap[sectionId] || sectionId; diff --git a/application/single_app/templates/_sidebar_nav.html b/application/single_app/templates/_sidebar_nav.html index 198eab56..d3419b8d 100644 --- a/application/single_app/templates/_sidebar_nav.html +++ b/application/single_app/templates/_sidebar_nav.html @@ -442,59 +442,6 @@
+ {# Latest Features stays last so it never opens by default #} + {% if not latest_features_nav_is_hidden %} + + {% endif %}
diff --git a/application/single_app/templates/admin/_panes/agents.html b/application/single_app/templates/admin/_panes/agents.html new file mode 100644 index 00000000..5994976d --- /dev/null +++ b/application/single_app/templates/admin/_panes/agents.html @@ -0,0 +1,1021 @@ +
+ +

+ Configure AI agents and actions for enhanced functionality. Agents provide AI-driven task automation while Actions extend functionality with custom tools and integrations. +

+ + + + + + {% set analyze_capability = settings.document_action_capabilities.analyze %} + {% set comparison_capability = settings.document_action_capabilities.comparison %} +
+
+
+
Document Action Capabilities
+

Configure the document actions shown in the Action dropdown in Chat and Workflow. These controls live in the Agents and Actions tab, but remain separate from the global agent and custom action cards below.

+
+ Chat: 2-300 | Workflow: 2-1000 +
+ +
+
+
+
+ + + +
+
+
+ + {{ analyze_capability.chat_max_documents }} +
+
+
+ +
+
+ +
+
+
+ 2 + 300 +
+
+
+
+ + {{ analyze_capability.workflow_max_documents }} +
+
+
+ +
+
+ +
+
+
+ 2 + 1000 +
+
+
+
+
+
+
+ + + +
+
+
+ + {{ comparison_capability.chat_max_documents }} +
+
+
+ +
+
+ +
+
+
+ 2 + 300 +
+
+
+
+ + {{ comparison_capability.workflow_max_documents }} +
+
+
+ +
+
+ +
+
+
+ 2 + 1000 +
+
+
+
+
+
+ + +
+
+ Agents Configuration +
+

+ Configure AI agents powered by Semantic Kernel for task automation and orchestration. +

+
+
+ Agents Page Customization +
+

Customize the public Agents page hero, color treatment, and optional guidance message.

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
Used when two tone gradient is selected.
+
+
+ + +
Shown below the Agents page hero. Use this for contact details, request guidance, or governance reminders.
+
+
+
+ + +
+
When disabled, the Agents tab details popup hides instructions and the catalog API response omits them.
+
+
+
+
Promoted Popular Agents
+

Highlight selected agents in the Popular tab even before they have usage counts. Users only see promoted agents that are already visible to them.

+ +
+
+ + +
+
+ + +
+
+
+
+ + +
+
When enabled, promoted agents show the configured tag in the Popular tab.
+
+
+
+
+
+ + +
+
+ +
+
+
+ + + + + + + + + +
AgentShow InActions
+
+ + +
+
+
+
+
+ + + + + +
+ +
+ {% if not settings.enable_semantic_kernel %} +
+ Agents UI is not available while agents are disabled. +
+ {% else %} +
+
+ + + +
+ {% if settings.per_user_semantic_kernel %} + +
+
Workspace Feature Toggles
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + + +
+
+ + + +
+
+ + + +
+
+ + + {% endif %} + +
+

Agent Orchestration Settings

+
+
+

Configure how the chat system orchestrates agents (single or multi-agent group chat).

+
+ + +
+ + +
+
+

Global Agents

+
+ + +
+
+

Disable a global agent to keep it saved for admins while hiding it from runtime selection until it is re-enabled.

+
+ {% if settings.orchestration_type == "default_agent" %} + + {% else %} + + {% endif %} + + +
+ + + + + + + {% if settings.orchestration_type == "default_agent" %} + + {% else %} + + {% endif %} + + + + +
NameDisplay NameDescriptionSelected AgentOrchestrator AgentActions
+
+ {% endif %} +
+ + {% if settings.enable_agent_template_gallery %} +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+ Agent Template Approvals +
+

Template submissions are now reviewed from the shared approvals page.

+
+ + Open Approvals Queue + +
+
+ {% endif %} + + +
+
+ Global Actions Configuration +
+

+ Configure custom actions and tools to extend functionality with integrations and specialized capabilities. +

+ + {% if not settings.enable_semantic_kernel %} +
+ Actions are not available while agents are disabled. Enable agents above to configure actions. +
+ {% else %} +
+
+
Global Actions
+ +
+

Disable a global action to keep the configuration without exposing it to runtime action loading until it is re-enabled.

+ {% if settings.per_user_semantic_kernel %} + +
+
Workspace Action Feature Toggles
+
+ + + + +
+
+ + + + +
+
+ {% endif %} + + +
+
Core Action Toggles
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+ Tabular Processing Action + +
+ Automatically enabled when Enhanced Citations is enabled +
+
+ + + + + + + + + +
Display NameDescriptionActions
+
+ {% endif %} +
+ {% if mcp_ui_enabled %} +
+
+
+
+ Inbound MCP Server +
+

+ Configure the governed SimpleChat MCP endpoint used by external MCP clients. Personal tools use delegated user tokens by default; tool access remains deny-by-default until authentication, source, client, and governance policy all allow the request. +

+
+
+ Preview + +
+
+ + + +
+
+
+
Runtime Gate
+
+ + + +
+
+ + +
Default: DelegatedMcpServerAccess. VS Code and other user clients must present this delegated scope.
+
+
+ + +
Default: InboundMCPUserAccess. Governance determines which users/groups can use tools after this Entra role and delegated scope pass.
+
+
+ + +
Default: InboundMCPAppAccess. Reserved for future app-only MCP tools and still governed separately.
+
+
+
+ +
+
+
Endpoint Contract
+
+
MCP endpoint
+
{{ inbound_mcp_resource_path }}
+
Protected resource metadata
+
{{ inbound_mcp_prm_path }}
+
Transport
+
Streamable HTTP JSON-RPC
+
Current tool surface
+
Personal delegated tools only.
+
Tool identity
+
Delegated user token required for personal data.
+
+ +
+
+ +
+
+
+
+
Request Size & Throttling
+
Protect the inbound MCP endpoint from oversized payloads and noisy clients. Rate limits are enforced per caller and tool category across app instances.
+
+
+ + +
+
+
+
+ + +
Default: 65536. Range: 1 KB to 1 MB.
+
+
+ + +
Default: 60. Applies to each throttle category.
+
+
+ + +
Default: 120.
+
+
+ + +
Default: 30.
+
+
+ + +
Default: 10.
+
+
+ +
+
+ +
+ + + +
+ +
+
+
+
+
Allowed client app IDs
+
Required allowlist. Empty means no MCP clients can connect.
+
+ +
+
+ + + + + + + + + +
Client app IDDescriptionActions
+
+
+
+
+ +
+
+
+ + +
+
+ Off allows only the configured SimpleChat tenant. Turning this on auto-includes the SimpleChat tenant and lets admins add more tenants. +
+
+
+
Allowed tenant IDs
+ +
+
+ + + + + + + + + +
Tenant IDDescriptionActions
+
+
+
+
+
+ +
+
+
+ + +
+
+ Default on accepts any source signal at the runtime allowlist layer. Turn off to require explicit source values here. In both modes, admins must still create an inbound MCP source governance policy before tools are returned. +
+
+ + +
Default: X-SimpleChat-MCP-Source.
+
+ + + +
+
+
Allowed source IDs
+ +
+
+ + + + + + + + + +
Source valueDescriptionActions
+
+
+
+
+
+
+
+ + + + {% endif %} +
diff --git a/application/single_app/templates/admin/_panes/ai-models.html b/application/single_app/templates/admin/_panes/ai-models.html new file mode 100644 index 00000000..3df45b25 --- /dev/null +++ b/application/single_app/templates/admin/_panes/ai-models.html @@ -0,0 +1,831 @@ +
+ +

+ Configure all AI model settings including GPT for text generation, embeddings for semantic search, and image generation capabilities. +

+ +
+
+ Model Endpoints +
+

+ Manage multiple AI model endpoints (Azure OpenAI and Azure AI Foundry). When enabled, model selection in chat is driven by these endpoints. +

+ + {% if not settings.enable_multi_model_endpoints %} +
+ + +
+ {% endif %} + + {% if settings.enable_semantic_kernel %} +
+
+
+
Agent Default Model Review
+

+ Review local agents in a modal, bulk-bind inherited agents to the saved default model endpoint, and explicitly override selected agent model choices when you need to manage cost or move to newer models. +

+
+
+ +
+
+
+ {% if settings.enable_multi_model_endpoints %} + Save your AI model settings before reviewing or migrating agents. + {% else %} + Enable multi-endpoint model management to review and rebind agents to a saved default model. + {% endif %} +
+ +
+ +
+
+ Ready: 0 + Needs Default: 0 + Manual Review: 0 + Already Migrated: 0 +
+
+
+ Open the review modal to search, filter, and selectively rebind agents to the saved default model. +
+
+ + + {% else %} + + {% endif %} + +
+
+
+
Model Endpoint Identity Header
+

+ Send a stable HMAC-hashed user key to model endpoint backends for APIM counters, quota policies, or routing policies. +

+
+
+ + +
+
+
+
+ + +
Reserved auth/protocol headers cannot be used.
+
+
+ + +
The selected identity is HMAC-hashed before leaving SimpleChat. Missing identity values omit the header.
+
+
+
+ +
+ + +
+ Used for tasks such as conversation summarization, fallback, and other operations when an agent is selected. +
+
+ + + + +
+
+
Global Endpoints
+
+ + +
+
+
+ + + + + + + + + + + + + +
NameProviderSelected ModelsStatusActions
+
+
+ {% if not settings.enable_multi_model_endpoints %} + + {% endif %} +
+ + +
+
+ Processing Thoughts +
+

When enabled, real-time processing steps are shown to users during chat responses and persisted for later review.

+
+ + + +
+
+ + +
+
+ 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.

+
+ + + +
+
+ + +
+
+ Embeddings Configuration +
+

+ Configure your embeddings settings. These are used for semantic search, knowledge-base lookups, etc. +

+ + +
+ + + +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+
+ +
+ Save pending changes to settings before clicking Fetch Embedding Models
+ + + + + + + + +
+ +
+
+
+ + +
+
+
+
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+ + +
+
+ + +
+
+ Image Generation Configuration +
+

+ Configure image generation settings. Enable/disable, set endpoints, and choose a model. +

+ + +
+ + + +
+
+ +
+ + + +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+
+ +
+ + Save pending changes to settings before clicking Fetch Image Generation Models
+ + + + + + + + +
+ +
+
+
+ + +
+
+
+
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+
+ + +
+
+ + + + {% include '_multiendpoint_modal.html' %} + + + +
diff --git a/application/single_app/templates/admin/_panes/citation.html b/application/single_app/templates/admin/_panes/citation.html new file mode 100644 index 00000000..3c6542a2 --- /dev/null +++ b/application/single_app/templates/admin/_panes/citation.html @@ -0,0 +1,244 @@ +
+ +

+ Configure standard and enhanced citations features for your and group workspaces. +

+ + +
+
+ Standard Citations +
+

+ Standard citations is always enabled for both Your Workspace and Group Workspace. +

+

+ Users can see text content of the source/citation for documents. +

+
+ + +
+
+ Enhanced Citations +
+

+ Enable Enhanced Citation to store files in a Storage Account, + and show direct references (Preview feature, files are saved to storage, presentation + layer will be available in a future release). +

+ + {% set ec_storage_status = settings.enhanced_citations_storage_status or {} %} + {% set ec_storage_state = ec_storage_status.state or 'not_initialized' %} + {% if settings.enable_enhanced_citations %} +
+
Enhanced Citations storage startup status
+
{{ ec_storage_status.message or 'Enhanced Citations storage status is not available for this process.' }}
+
+ Startup skips live storage container checks so storage outages do not block application boot. + Use the connection test to validate current storage reachability and container access. +
+ +
+
+ {% endif %} + + +
+ + + +
+ + + +
+
diff --git a/application/single_app/templates/admin/_panes/control-center-config.html b/application/single_app/templates/admin/_panes/control-center-config.html new file mode 100644 index 00000000..dd214327 --- /dev/null +++ b/application/single_app/templates/admin/_panes/control-center-config.html @@ -0,0 +1,180 @@ +
+

+ Configure Control Center access and permissions for administrators. +

+ +
+
+
+
+ +
+
+

+ Automatic Data Refresh +

+

Run the Control Center metrics refresh overnight on a daily timezone-aware schedule

+
+
+
+ +
+ + + +
+ +
+
+ + + +
+ Your browser timezone is local time. +
+
+
+ +
+ {% if settings.control_center_auto_refresh_next_run %} + Loading local time... + {% else %} + Will be calculated when saved + {% endif %} +
+
+
+
+ + +
+
+
+
+ +
+
+

+ Control Center Access +

+

Manage who can access Control Center features and administrative tools

+
+
+ +
+ +
+ + About Control Center: The Control Center is a powerful administrative dashboard that provides user management, group oversight, public workspace control, and detailed activity monitoring. Use role-based access controls below to delegate administrative responsibilities. +
+ + +
+
+ + +
+

+ Required app role value: ControlCenterAdmin. Assign this role to users or groups in the Enterprise App before enabling the requirement. When enabled, only users assigned this role can access the Control Center and all management features. Regular Admins will lose access. +

+
+ + User Management + + + Group Management + + + Public Workspaces + + + Activity Logs + +
+
+ + +
+
+ + +
+

+ Dashboard-only app role value: ControlCenterDashboardReader. Assign this role to users or groups in the Enterprise App before enabling dashboard-only access. Users assigned ControlCenterAdmin can also access the dashboard when Control Center app-role enforcement is enabled. +

+
+ + Dashboard Statistics + + + Activity Trends + + + Usage Metrics + +
+
+ +
+ + Important: Configure these roles in your identity provider (Entra ID). When role requirements are enabled, standard Admins without the specific roles will be denied access to Control Center features. +
+ + +
+
+ Best Practices +
+
    +
  • ControlCenterAdmin: Grant to IT administrators who need full control over users, groups, and workspaces
  • +
  • ControlCenterDashboardReader: Grant to managers, compliance officers, or stakeholders who need visibility into platform usage without administrative powers
  • +
  • Separation of Duties: Enable role requirements if you need to restrict Control Center access from general application admins
  • +
  • Audit Trail: All Control Center actions are logged in Activity Logs for compliance and security auditing
  • +
+
+
+
diff --git a/application/single_app/templates/admin/_panes/custom-pages.html b/application/single_app/templates/admin/_panes/custom-pages.html new file mode 100644 index 00000000..a3d0f32e --- /dev/null +++ b/application/single_app/templates/admin/_panes/custom-pages.html @@ -0,0 +1,81 @@ +
+

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

+ +
+
+
+ Custom Pages +
+ +
+
+ + + + +
+

When disabled, /custom routes return Not Found before loading custom metadata, files, or Python extensions.

+ +
+
+ + + This name appears when custom pages are grouped into a menu. +
+ +
+ + + When disabled, 1-2 custom pages show as top-level nav items and 3+ pages show as a menu. +
+ +
+
+
Static Page Metadata
+

Create metadata contracts for simple pages that use files from custom_pages/html, css, js, assets, and json.

+
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + +
SlugTitleTypeAccessRolesStatusNavActions
Loading custom pages...
+
+
+
+
diff --git a/application/single_app/templates/admin/_panes/data-management.html b/application/single_app/templates/admin/_panes/data-management.html new file mode 100644 index 00000000..aba96639 --- /dev/null +++ b/application/single_app/templates/admin/_panes/data-management.html @@ -0,0 +1,1621 @@ +
+
+
+

Backup, Migrate & Restore

+

Protect SimpleChat data, move selected workspaces to another environment, and stage restore decisions with guided checks.

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

Start Here

+

Use these checkpoints before running backup, migration, restore, or advanced repair actions.

+
+ +
+
+
+
+
Back up
+

Configure dedicated storage, encryption, schedule, and backup scope before queueing jobs.

+ +
+
+
+
+
Migrate
+

Connect a destination, choose who moves, run preflight, then execute a recoverable transfer.

+ +
+
+
+
+
Restore
+

Review backup readiness and stage restore decisions from Backup Inventory.

+ +
+
+
+
+
RU Boost
+

Temporarily raise eligible Cosmos capacity during approved backup or migration windows.

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

Backup

+

Configure when backups run, where artifacts are stored, and how backup files are encrypted.

+
+
+ +
+
+
+
Schedule
+

Full backups run on the selected cadence; partial backups run daily only.

+
+
+
+ + +
+
+
+ + +
+
+ + +
Default is 03:00 UTC.
+
+
+ +
+ + + +
+ +
Automatic cleanup keeps the newest successful full backup as a safety baseline.
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ +
+
+
+ +
+
+
+ + +
Core application records required for meaningful restore and migration.
+
+
+
+
+ + +
Search index schemas and retrievable indexed documents.
+
+
+
+
+ + +
Original source files used by Enhanced Citations.
+
+
+
+
+
+
+
+ +
+
+
+
Storage
+

Store backup artifacts in Azure Blob Storage.

+
+ +
+
+ + Use a dedicated backup storage account. Data Management will reject storage that matches the Enhanced Citations connection string or Blob endpoint. +
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
No connection string saved yet.
+
+
+ + +
+
+
+ +
+
+
+
Encryption
+

Generate a 256-bit backup encryption key.

+
+ +
+
+ + +
+
+
Key storage
+
Not configured
+
Key reference
+
Not configured
+
+
+ +
+
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 +
+
+
+ +
+
+
+
Cosmos Backup Performance
+

Backups stream deterministic checkpoint batches and commit only verified work. Higher concurrency can increase source Cosmos cost and pressure.

+
+ +
+ +
+
+
Source Blob Backup Performance
+

Source files stream through bounded chunks and durable per-file checkpoints. Peak transfer buffering is bounded by concurrent transfers multiplied by chunk size.

+
+
+
+ + +
+
+ + +
+
+ + +
+
+
Defaults bound application transfer buffering to approximately 32 MiB, excluding Azure SDK overhead. Throttling temporarily reduces active transfers.
+
+
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
The backup records the current source capacity, raises only eligible targets up to 10,000 RU/s, and restores the original setting after completion, cancellation, failure, or recovery. This can increase Cosmos charges and requires source ARM throughput permission.
+
+
+
+ +
+
+
+
Backup Operations
+

Queue immediate full or partial backup jobs using the settings above.

+
+
+ + +
+
+

Jobs use Cosmos-backed leases so scaled-out App Service workers do not run the same backup twice.

+
+
+ + +
+
+
+

+ Migration +

+

Move SimpleChat data through a reviewed, recoverable environment transfer.

+
+
+ + Not reviewed +
+
+ +
+ + + + + +
+
+
+
Connect the destination
+

Configure the services this migration will write to. Stored credentials remain redacted.

+
+ Destination database: SimpleChat +
+ +
+
+
+
+
Target Cosmos Database
+

Required for every migration.

+
+ +
+
+ Managed identity requires Cosmos DB Data Contributor and target network access. +
+
+
+ + +
+
+ + +
+
+ + +
Fixed app contract.
+
+
+
+ + +
+
+ +
+
+
+
Target Search
+

Required when AI Search documents are included.

+
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+
+
+
Target Enhanced Citation Storage
+

Required only when source document blobs are included.

+
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+ + +
+
+
+
Choose who and what moves
+

Selections persist while you search and page. “All” always uses the exhaustive server count.

+
+
0 principal scopes selected
+
+ +
+ + + +
+ +
+ +
+ Migration mode +
+ + + +
+
+ +
+
+
+
+
Available users
+

Search the server catalog.

+
+ +
+
+
+ + Page 1 + +
+
+ +
+ +
+ +
+ Loading exhaustive count… + Every current user record will be resolved by the server when the job starts. +
+
+ +
+ + +
+
+ +
+ +
+ Migration mode +
+ + + +
+
+
+
+
+
+
Available groups
+

Search the server catalog.

+
+ +
+
+
+ + Page 1 + +
+
+ +
+
+ +
+ Loading exhaustive count… + Every current group record will be resolved by the server when the job starts. +
+
+
+ + +
+
+ +
+ +
+ Migration mode +
+ + + +
+
+
+
+
+
+
Available public workspaces
+

Search the server catalog.

+
+ +
+
+
+ + Page 1 + +
+
+ +
+
+ +
+ Loading exhaustive count… + Every current public workspace record will be resolved by the server when the job starts. +
+
+
+ + +
+
+
+ + +
+
+
+
Choose what happens at the destination
+

Choose whether to copy only missing items, catch up changes, or make migrated destination data match the source.

+
+
+ +
+ Destination behavior +
+ + + + + + +
+

+ Copies source items that are absent from the destination. Existing destination data is never updated or deleted. +

+
+
+ + +
Leave blank to let SimpleChat choose the latest compatible completed migration as the starting point for this catch-up run.
+
+
+
+ +
+ Data surfaces +
+
+
+ + +
+
+ + +
SimpleChat pauses its own target indexing. Freeze other writers before review.
+
+
+
+
+ + +
Requires Enhanced Citation storage at both source and destination.
+
+
+
+
+ +
+ Performance and resume +

Migration uses durable resource checkpoints and retains the same migration ID after Retry or Resume.

+
+
+ + +
+
+ + +
+
+ + +
+
+
+ + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
RU Boost validates Azure management-plane throughput permissions separately from Cosmos data-copy access. Eligible capacity is raised only up to 10,000 RU/s during execution and restored after completion or failure.
+
+
+
+
+ + +
+
+
+
Prove the plan is ready
+

Preflight runs server-owned access probes and inventory. Any earlier change makes this review stale.

+
+
+ + +
+
+
+ +
+ Review has not run. + Run preflight to verify target access, counts, collisions, locks, and capacity policy. +
+
+
+
+ +
+ + +
+
+
+
Confirm execution
+

Review the final server-normalized plan. Submission is guarded against duplicate requests.

+
+
+
+

Complete preflight review before confirmation.

+
+ +
+ + +
+ +
+ + +
+
+
+
Operate the migration
+

Progress comes from the durable job record. Cancel, Retry, and Resume retain verified checkpoints.

+
+
+ + +
+
+
+ +
+ No migration is attached to this workflow yet. + After execution, this stage follows the queued job and exposes its recovery actions. +
+
+
+
+
+
+
+
+ +
+
+ + +
+ Step 1 of 6 +
+
+
+ +
+
+
+

Cosmos DB JSON Editor

+

Query SimpleChat Cosmos DB containers, inspect one document, and save JSON changes with ETag protection.

+
+ +
+ +
+ The Cosmos DB JSON editor is locked. Acknowledge the danger prompt before querying or editing data. +
+
+
+
+ + +
Choose a known SimpleChat Cosmos DB container.
+
+
+ + +
Max 100 per request.
+
+
+ + +
Empty query returns only the first 100 documents. Custom SELECT queries can page beyond 100 with Next Page.
+
+
+
+ + No query has run yet. +
+
+ Query results and the JSON editor open in a modal so the Data Management page stays compact. +
+
+
+ +
+
+
+

Backup Inventory

+

Track completed full and partial backups created by Data Management jobs.

+
+
+ + + +
+
+
+
+
What does Run Retention Cleanup do?
+

+ It permanently deletes backups whose age exceeds the retention period configured in Data Management settings, + and removes their stored artifacts from the backup container. Backups newer than the retention cutoff are left alone. +

+
    +
  • Only backups in a finished state are eligible; running or queued jobs are skipped.
  • +
  • When Keep latest full backup is enabled, the most recent successful full backup is protected even if it is past the cutoff.
  • +
  • Each run deletes at most 25 backups, so very large cleanups may need several runs.
  • +
  • Cleanup also runs automatically on the configured schedule; this button just runs it now.
  • +
+

+ Seeing “found no expired backups to delete” means every backup is still inside the retention window. That is expected, not an error. +

+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + + + + + + + + + + + + + + + + +
BackupCompletedContentsStorageProtectionWarningsActions
Backup inventory has not loaded yet.
+
+ +
+ + + +
+
+

Job History

+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + + + + + + + + + + + + + + + +
CreatedOperationStatusProgressMessageActions
Job history has not loaded yet.
+
+ +
+ + + + + + + + + + + + + + + + + + + + +
diff --git a/application/single_app/templates/admin/_panes/file-sync.html b/application/single_app/templates/admin/_panes/file-sync.html new file mode 100644 index 00000000..fb31daf8 --- /dev/null +++ b/application/single_app/templates/admin/_panes/file-sync.html @@ -0,0 +1,411 @@ +
+

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

+ +
+
+
+ File Sync +
+ +
+

+ Enable File Sync globally, set conservative run limits, and choose whether workspace managers or SimpleChat admins manage sync sources. +

+ + + + {% if not settings.file_sync_redis_ready %} + + {% elif settings.requested_enable_file_sync and not settings.file_sync_effective_enabled %} + + {% endif %} + +
+ + + +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+
+ + +
+
+
+ + {% set file_sync_visible_source_types = settings.file_sync_visible_source_types|default(['smb', 'azure_files']) %} +
+
Visible Source Types
+

+ Choose which source types appear in the Add Source workflow. OneDrive, SharePoint, and Google Workspace connectors are coming soon while validation continues. +

+
+
+
+ + +
Available now.
+
+
+
+
+ + +
Available now.
+
+
+
+
+ + +
Available now.
+
+
+
+
+ + +
Coming Soon.
+
+
+
+
+ + +
Coming Soon.
+
+
+
+
+ + +
Coming Soon.
+
+
+
+
+ + + +
+
+
+
Personal Workspace Sync
+
+ + +
+
+ + +
+
+ + +
+
Required app role value: PersonalFileSyncUser. Assign this role to users or groups in the Enterprise App before enabling the requirement for personal sync.
+
+
+ +
+ + +
+
+
+ + +
+
No user selected.
+
+
+
+ +
+
+
Group Workspace Sync
+
+ + +
+
+ + +
+
+ + +
+
+ + No groups assigned. +
+ +
+
+ +
+ + +
+
+
+ + +
+
No group selected.
+
+
+
+ +
+
+
Public Workspace Sync
+
+ + +
+
+ + +
+
+ + +
+
+ + No public workspaces assigned. +
+ +
+
+ +
+ + +
+
+
+ + +
+
No public workspace selected.
+
+
+
+
+ +
+ SMB source credentials are stored in Azure Key Vault when Key Vault secret storage is enabled; otherwise they use the app's existing encrypted settings path. +
+
+
+ + + + + + + + +
diff --git a/application/single_app/templates/admin/_panes/general.html b/application/single_app/templates/admin/_panes/general.html new file mode 100644 index 00000000..bd3d5be4 --- /dev/null +++ b/application/single_app/templates/admin/_panes/general.html @@ -0,0 +1,682 @@ +
+ +

+ 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.html b/application/single_app/templates/admin/_panes/governance.html new file mode 100644 index 00000000..450af4b9 --- /dev/null +++ b/application/single_app/templates/admin/_panes/governance.html @@ -0,0 +1,250 @@ +
+
+

+ Configure governance enforcement for endpoint, agent, and action creation or usage. Governance is disabled by default and only enforced when toggled on. +

+ +
+ +
+
+ Governance Feature Toggles +
+

Turn on governance checks for each feature area. Save with the main Settings button to persist these toggles.

+ +
+
+
Personal Scope
+
+ + +
+
+ + +
+
+ + +
+
+
+
Group Scope
+
+ + +
+
+ + +
+
+ + +
+
+
+
Global Scope
+
+ + + Always On +
+
+ + +
+
+ + +
+
+
+
+ +
+
+ MCP Action Destination Governance +
+

+ Restrict outbound remote MCP servers by destination pattern and scope. Destination policies reuse delegated item policies, so admins can allow all users, specific users, or workspace groups for each approved destination. +

+
+
+
+ + +
+
+ + +
+
+ Save with the main Settings button. Unsafe literal-IP blocking can be enabled even before the allowlist is enforced. +
+
+
+
Supported destination patterns
+
    +
  • * for any remote MCP destination after identity/auth checks.
  • +
  • preconfiguration:microsoft_learn or preset:generic.
  • +
  • *.contoso.com, https://example.com/mcp*, or transport:streamable-http.
  • +
  • group:<group-id>::preconfiguration:github for one group-specific override.
  • +
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+ +
+
+ Inbound MCP Source Governance +
+

+ Control which delegated users and groups can use SimpleChat as an inbound MCP server through source-scoped policies. +

+ +
+
+
Policy required for inbound MCP
+
    +
  • inbound_mcp_source with delegated item *: allows selected users or groups to use any accepted source ID.
  • +
  • inbound_mcp_source with a configured source ID: allows selected users or groups to use only requests with that source value.
  • +
+
+ Client, tenant, delegated scope, and Entra role checks remain in Inbound MCP configuration. The source ID comes from the configured header when present and is advisory unless a trusted gateway sets or validates it. +
+
+
+
+
+ + +
+
+
+
+
+ +
+
+
Feature Policies
+ +
+

Set allow-all, explicit allow lists, and block lists for each governed feature. Block lists override allow settings.

+
+ + + + + + + + + + +
FeatureAllow AllAllow ListBlock List
+
+
+ +
+
+
Delegated Item Policies
+
+ + +
+
+

Manage delegated governance for configured global resources and action type entitlements that admins assign to specific users or groups.

+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + + + + + + + + + + +
PolicyEntity TypeItemAllow AllActions
+
+ +
+
+
+ + +
+
+
+ + +
diff --git a/application/single_app/templates/admin/_panes/latest-features.html b/application/single_app/templates/admin/_panes/latest-features.html new file mode 100644 index 00000000..81d30da6 --- /dev/null +++ b/application/single_app/templates/admin/_panes/latest-features.html @@ -0,0 +1,1253 @@ +
+

+ 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. +

+ + + {% for release_group in admin_latest_feature_release_groups %} + {% if release_group.id == 'current_release' %} +
+
+
{{ release_group.label }}
+

{{ release_group.description }}

+
+ {% if release_group.release_version %} + v{{ release_group.release_version }} + {% endif %} +
+ + {% for feature in release_group.features %} + {% set feature_card_id = 'latest-features-' ~ feature.id|replace('_', '-') ~ '-card' %} + {% set feature_collapse_id = feature_card_id ~ '-details' %} +
+
+
+
{{ feature.title }}
+

{{ feature.summary }}

+
+ +
+
+
+ {% if feature.details %} +

{{ feature.details }}

+ {% endif %} + {% if feature.why %} + + {% endif %} + {% if feature.guidance %} +
{% if feature.images %}Screenshot and rollout notes{% else %}Rollout notes{% endif %}
+
    + {% for tip in feature.guidance %} +
  • {{ tip }}
  • + {% endfor %} +
+ {% endif %} + {% if feature.images %} + + {% endif %} + {% if feature.actions %} +
+ {% for action in feature.actions %} + + {{ action.label }} + + {% endfor %} +
+ {% endif %} +
+
+
+ {% endfor %} + {% else %} + {% set release_card_id = 'latest-features-' ~ release_group.id|replace('_', '-') ~ '-card' %} + {% set release_collapse_id = release_group.collapse_id %} +
+
+
+
{{ release_group.label }}
+

{{ release_group.description }}

+
+ +
+
+
+ {% if release_group.release_version %} + + {% endif %} +
+ {% for feature in release_group.features %} +
+
+
+
+
{{ feature.title }}
+

{{ feature.summary }}

+
+

{{ feature.details }}

+ {% if feature.guidance %} +
    + {% for tip in feature.guidance %} +
  • {{ tip }}
  • + {% endfor %} +
+ {% endif %} + {% if feature.images %} + + {% endif %} + {% if feature.actions %} +
+ {% for action in feature.actions %} + + {{ action.label }} + + {% endfor %} +
+ {% endif %} +
+
+
+ {% endfor %} +
+
+
+
+ {% endif %} + {% endfor %} + + {% if false %} +
+
+
+
+ Registered / Unregistered Badge +
+

The badge next to the Admin Settings version number shows whether this admin instance is registered for latest release and community call notifications.

+
+ +
+
+
+ +

Use this badge as the quick status check for whether your environment is already registered to receive SimpleChat release updates.

+
    +
  • Unregistered means this environment has not saved release notification registration details yet.
  • +
  • Registered means the environment already has saved contact details for release and community call notifications.
  • +
  • Clicking the badge opens the registration modal where admins can add or edit the name, email, and organization for this instance.
  • +
  • Submitting the form opens a prefilled email draft to simplechat@microsoft.com and stores the registration details back in Admin Settings.
  • +
  • The badge lives beside the version number at the top of Admin Settings so admins can confirm status without hunting through tabs.
  • +
+
+
+
+ +
+
+
+
+ Performance Improvements for Apps running Native Python (not containers) +
+

Native Python App Service deployments should use Gunicorn as the startup command. Container deployments already do this for you.

+
+ +
+
+
+

If you run the native Python App Service deployment instead of the container deployment, set the App Service Startup command to the following:

+
python -m gunicorn -c gunicorn.conf.py app:app
+

Use container deployments when possible if you want the runtime defaults and startup behavior handled by the shipped image.

+ + +
+
+
+ +
+
+
+
+ Guided Tutorials +
+

New guided walkthroughs help users learn the live chat and personal workspace interfaces without leaving the app.

+
+ +
+
+
+

Admins can use these walkthroughs to accelerate onboarding for new users and reduce orientation time across the primary product surfaces.

+
    +
  • Guided Chat Tutorial covers the active chat experience, message actions, search flows, citations, thoughts, and export-related actions.
  • +
  • Personal Workspace Guided Tutorial walks through uploads, search, filters, list and grid views, prompts, agents, actions, and tags.
  • +
+ +
+
+
+ +
+
+
+
+ Background Chat Completion +
+

Personal chats can continue finishing after a user leaves the chat page, and completed responses surface as notifications with unread indicators.

+
+ +
+
+
+

This makes long-running responses more reliable for users who navigate into other areas of the app before generation finishes.

+
    +
  • Completion notifications deep-link back into the finished conversation.
  • +
  • Unread markers remain visible until the response is actually opened.
  • +
  • Personal, workspace, and navigation flows now behave more consistently while chat completion continues in the background.
  • +
+ +
+
+
+ +
+
+
+
+ Multi-Endpoint GPT Selection +
+

Admins can expose multiple GPT choices across Azure OpenAI and Azure AI Foundry, set a saved default fallback model, and now review agent rebinding in a modal before applying changes.

+
+ +
+
+
+

This is the high-value admin control for teams that want broader GPT choice without locking every workflow to a single deployment.

+
    +
  • Configure multiple model endpoints and choose which GPT deployments are available to users.
  • +
  • Set a default fallback model so summarization, agent requests, and other background flows still resolve a usable GPT when an explicit selection is missing.
  • +
  • Use the admin-only Agent Default Model Review modal to inspect inherited agents, search and filter large agent sets, and explicitly choose which review rows should be overridden to the saved default.
  • +
+ + + +
+
+
+ +
+
+
+
+ Tabular Data Analysis +
+

Enhanced citations now unlock a more consistent tabular analysis experience for normal chat and workspace-backed files, not just dedicated agent scenarios.

+
+ +
+
+
+

This is the highest-impact settings area to mirror here because it combines storage-backed citations, tabular previews, and consistent behavior across workspace and chat uploads.

+
    +
  • Tabular files can be analyzed with the same core approach whether they come from chat uploads or any workspace container.
  • +
  • Enhanced citations provide the blob-backed dependency for richer tabular processing and citation transparency.
  • +
  • Admins can right-size tabular preview limits based on the memory profile of their runtime.
  • +
+ +
+ + +
+ +
+
+
All filetypes
+
+ + +
+ +
+ +
+ + +
+
+ +
+ +
+ + +
+
+
+ +
+
Tabular Preview Limits
+
+ + + + Mirror of the Citations setting. Larger values support bigger previews but increase runtime memory pressure. + +
+
+
+ + +
+
+
+ +
+
+
+
+ Citation Improvements +
+

Conversation history citation replay and citation amplification keep more grounded evidence available across follow-up turns without making the chat history unwieldy.

+
+ +
+
+
+

These improvements make follow-up questions more reliable because the system can reuse prior grounded evidence instead of relying only on the assistant's last prose response.

+
    +
  • Conversation history citations carry forward prior citation summaries so later prompts can reuse earlier grounded results.
  • +
  • Citation amplification keeps richer supporting payloads available for inspection and export while keeping prompt history compact.
  • +
  • This is especially useful for larger or tabular outputs where users often ask multiple follow-up questions against the same evidence chain.
  • +
+ + +
+
+
+ +
+
+
+
+ Document Revisioning and Management +
+

Uploading a document with the same name now creates a new revision instead of overwriting the previous file, while older versions remain available for traceability and later analysis.

+
+ +
+
+
+

This improves both document management and citation integrity for long-lived conversations that span multiple document updates.

+
    +
  • Same-name uploads create a revision family with an incremented current version instead of destroying prior history.
  • +
  • Previous versions are retained for analysis or comparison, while workspace and search views focus on the current revision by default.
  • +
  • Older conversations can still resolve citations against the correct historical document version.
  • +
  • Updated revisions inherit document classifications and tags so admins do not have to reapply metadata after every refresh.
  • +
+ +
+
+
+ +
+
+
+
+ Conversation Summaries and Export +
+

Conversation export now includes persistent summaries, PDF output, and easier per-message reuse and sharing actions.

+
+ +
+
+
+
    +
  • Conversation details now surface a summary card with generate and regenerate actions.
  • +
  • Export supports PDF alongside existing export options.
  • +
  • Per-message actions support Markdown export, Word export, open in email, and use as prompt.
  • +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+ Agent and Action Operations +
+

Recent updates improve manageability for agents and actions with richer views, easier SQL connectivity checks, and better operational tracking.

+
+ +
+
+
+
    +
  • List and grid view toggles give admins and users a better way to browse agents and actions.
  • +
  • SQL actions now include an inline Test Connection button before save.
  • +
  • User tracking and activity logging improve auditability for agent and action changes.
  • +
+ +
+
+
+ +
+
+
+
+ AI Transparency +
+

Processing Thoughts provide a clearer view into model activity, duration, and execution flow while responses are being generated.

+
+ +
+
+
+

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

+ +
+ + +
+ +
+
+
+ +
+
+
+
+ Fact Memory +
+

Users can now save Instructions and Facts on their profile so the assistant can apply durable preferences every time and recall relevant personal context only when needed.

+
+ +
+
+
+

Fact Memory gives users a compact profile experience for managing two distinct memory types: always-on Instructions and relevance-based Facts.

+
    +
  • Instructions act like stable user preferences and are applied on every prompt unless the current message overrides them.
  • +
  • Facts are recalled only when relevant and now appear as dedicated thought and citation entries in chat.
  • +
  • The profile page includes a compact add flow plus a popup manager for search, paging, edit, retag, and delete actions.
  • +
  • Admins can choose whether this announcement is visible on the user-facing Latest Features page from General > User-Facing Latest Features.
  • +
+ + +
+
+
+ +
+
+
+
+ Redis and Key Vault +
+

Redis configuration now supports using a Key Vault secret name instead of storing the access key directly in settings.

+
+ +
+
+
+

This is useful for teams standardizing on Key Vault-backed secret storage while still using Redis for cache and session scenarios.

+
    +
  • Use Redis authentication type Key Vault when you want the stored value to represent a secret name instead of a raw Redis key.
  • +
  • This works best when Key Vault is already configured for the app.
  • +
+ +
+ + +
+ +
+
+
Redis Cache Settings
+
+ + +
+
+ + +
+
+ +
+ + +
+
+ When using Key Vault, store the secret name here instead of the raw Redis key. +
+
+
+
+ +
+
+
+ +
+
+
+
+ Send Feedback to the SimpleChat Team +
+

Admins now have a dedicated Send Feedback tab for bug reports and feature requests that opens a prefilled email draft and writes an audit record to the activity log.

+
+ +
+
+
+

Use the Send Feedback tab when you want to report a bug or suggest a feature directly from Admin Settings without leaving the page.

+
    +
  • Opens a prefilled email draft addressed to simplechat@microsoft.com.
  • +
  • Logs the action to the activity log so admins can audit when feedback emails were prepared.
  • +
  • Keeps the workflow simple by using text-only email content with no confusing pseudo-attachment step.
  • +
+ + Open Send Feedback + +
+
+
+ +
+
+
+
+ Support Menu +
+

Support can now expose user-facing Latest Features and Send Feedback workflows directly in everyday navigation.

+
+ +
+
+
+ +
    +
  • Admins can enable or disable the Support menu and rename it for user navigation.
  • +
  • Send Feedback now routes users to an internal recipient email address defined by admins.
  • +
  • The user-facing Latest Features page can be curated feature-by-feature so teams only share the items they want visible.
  • +
  • The General tab now includes a dedicated User-Facing Latest Features checklist so admins can quickly confirm which announcements will be visible to end users.
  • +
+ + Open General Settings + + +
+
+
+ {% endif %} + + {% for release_group in support_latest_feature_release_groups_preview %} + {% if release_group.id != 'current_release' %} + {% set preview_card_id = 'latest-features-user-preview-' ~ release_group.id|replace('_', '-') ~ '-card' %} + {% set preview_collapse_id = 'latestFeaturesUserPreview' ~ release_group.id|replace('_', ' ')|title|replace(' ', '') %} +
+
+
+
+ {{ release_group.label }} +
+

{{ release_group.description }}

+
+ +
+
+
+ +
+ {% for feature in release_group.features %} +
+
+
+
+
+
{{ feature.title }}
+

{{ feature.summary }}

+
+ + {% if settings.support_latest_features_visibility.get(feature.id, true) %}Shared with Users{% else %}Hidden from Users{% endif %} + +
+

{{ feature.details }}

+ {% if feature.guidance %} +
    + {% for tip in feature.guidance %} +
  • {{ tip }}
  • + {% endfor %} +
+ {% endif %} + {% if feature.images %} + + {% endif %} + {% if feature.actions %} +
+ {% for action in feature.actions %} + + {{ action.label }} + + {% endfor %} +
+ {% endif %} +
+
+
+ {% endfor %} +
+

Visibility still comes from General > User-Facing Latest Features, so admins can keep previous and archived release content available without promoting every item forever.

+
+
+
+ {% endif %} + {% endfor %} +
diff --git a/application/single_app/templates/admin/_panes/logging.html b/application/single_app/templates/admin/_panes/logging.html new file mode 100644 index 00000000..f8cf52e2 --- /dev/null +++ b/application/single_app/templates/admin/_panes/logging.html @@ -0,0 +1,177 @@ +
+

+ Configure logging settings for monitoring, debugging, and auditing purposes. These settings control various types of logging throughout the application including application insights, debug messages, and file processing events. +

+ +
+
+ Application Insights Logging +
+

Enable global logging to Application Insights for all agents and orchestration events.

+
+ + + +
+ +
+ +
+
+ Debug Logging +
+

Control debug print statements across the application for development and troubleshooting.

+
+ + + +
+ + +
+
+ + + +
+ +
+
+ + +
+
+ + +
+
+ +
+ {% if settings.debug_logging_turnoff_time %} + {% if settings.debug_logging_turnoff_time is string %} + {{ settings.debug_logging_turnoff_time }} + {% else %} + {{ settings.debug_logging_turnoff_time.strftime('%Y-%m-%d %H:%M:%S') }} + {% endif %} + {% else %} + Will be calculated when saved + {% endif %} +
+
+
+
+ + +
+ +
+
+ File Process Logging +
+

Enable logging of file processing events for debugging and auditing purposes. Logs are stored in the file_processing container in Cosmos DB.

+
+ + + +
+ + +
+
+ + + +
+ +
+
+ + +
+
+ + +
+
+ +
+ {% if settings.file_processing_logs_turnoff_time %} + {% if settings.file_processing_logs_turnoff_time is string %} + {{ settings.file_processing_logs_turnoff_time }} + {% else %} + {{ settings.file_processing_logs_turnoff_time.strftime('%Y-%m-%d %H:%M:%S') }} + {% endif %} + {% else %} + Will be calculated when saved + {% endif %} +
+
+
+
+ +
+
+
Delete stored logs
+

+ Permanently remove file processing logs from Cosmos DB. One month is treated as 30 days. +

+
+
+ + +
+ Enter a whole number greater than zero. +
+
+
+ + +
+
+ + +
+
+
+
+
diff --git a/application/single_app/templates/admin/_panes/safety.html b/application/single_app/templates/admin/_panes/safety.html new file mode 100644 index 00000000..b0b57c36 --- /dev/null +++ b/application/single_app/templates/admin/_panes/safety.html @@ -0,0 +1,280 @@ +
+ +

+ Configure content safety, archiving, and user feedback settings. If Content Safety is enabled, user + messages will be sent to the safety endpoint for analysis. If User Feedback is enabled, users will see + thumbs up/down to provide feedback on AI responses. +

+
+
+ Content Safety +
+

Enable content safety to filter out inappropriate content.

+
+ + + +
+ + +
+ + +
+ + + +
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+ + +
+
+ + +
+
+ +
+ + +
+
+
+ + +
+ + +
Displayed when Content Safety blocks a chat message.
+
+ +
+ + + +
+

Disable this option to show only the configured message.

+ + +
+
+
+ + +
+
+ User Feedback +
+

Enable user feedback (thumbs up/down) for AI responses.

+
+ + + +
+
+ +
+
+ Desktop Conversation Notifications +
+

+ Allow users to receive an operating system notification when an AI response finishes while SimpleChat is open in a hidden or unfocused browser tab. +

+
+ + +
+

+ Users can turn notifications off from Profile. Browser permission is required, and notifications stop when the SimpleChat tab is closed. +

+
+ + +
+
+ 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. +

+
+ + + +
+
+ Conversation Archiving +
+

When enabled, conversation deletions will be archived instead of permanently deleted.

+
+ + + +
+
+ +
diff --git a/application/single_app/templates/admin/_panes/scale.html b/application/single_app/templates/admin/_panes/scale.html new file mode 100644 index 00000000..ac6786cc --- /dev/null +++ b/application/single_app/templates/admin/_panes/scale.html @@ -0,0 +1,1628 @@ +
+ {% 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. +

+
+
+ Redis Cache +
+

+ Enable Redis Cache to store session data in a distributed cache. This is recommended for production and multi-instance deployments. +

+
+ + + +
+
+
+ +

(example: simple-chat.redis.cache.windows.net)

+ +
+
+ + +
+
+ +
+ + +
+
+ Enter the full Key Vault secret name. + Enable Key Vault for Agent and Action Secrets + must be enabled and configured. +
+
+ +
+
+
+
+
+
+ Redis Monitoring +
+

+ Monitor Redis availability, memory pressure, hit rate, evictions, and runtime cache usage before Redis-backed document list caching is enabled. +

+
+
+ + +
+
+
+
+
+
+
Configuration
+ Not loaded +
+
+
+
+
Health
+ Not loaded +
+
+
+
+
App Cache Runtime
+ Not loaded +
+
+
+
+
Session Runtime
+ Not loaded +
+
+
+
+
+
+
Ping Latency
+
Not loaded
+
+
+
+
+
Memory Usage
+
Not loaded
+
Not loaded
+
+
+
+
+
Connected Clients
+
Not loaded
+
+
+
+
+
Ops/sec
+
Not loaded
+
+
+
+
+
Keyspace Hit Rate
+
Not loaded
+
+
+
+
+
Tracked Keys
+
Not loaded
+
+
+
+
+
DAI Version Markers
+
Not loaded
+
Not loaded
+
+
+
+
+
DAI Cache Payloads
+
Not loaded
+
Not loaded
+
+
+
+
+
Expired / Evicted Keys
+
+ Not loaded + / + Not loaded +
+
+
+
+
+
Fragmentation Ratio
+
Not loaded
+
+
+
+
+
Error Replies
+
Not loaded
+
+
+
+
+
Rejected Connections
+
Not loaded
+
+
+
+
+
Redis Version
+
Not loaded
+
+
+
+
+
Monitoring Source
+
Not loaded
+
+
+
+
+
Last Checked
+
Not loaded
+
+
+
+
+
Last Error
+
Not loaded
+
+
+
+
+
+ + + +
+
+
+
+ Conversation Cache +
+

+ Cache conversation list, feed, and advanced-search results per user. Redis is optional; cache misses and disabled cache paths continue using source Cosmos queries. +

+
+ +
+
+
+
+ + +
+
When enabled, list/feed/search payloads are cached by user and version. Disabling this bypasses cache reads and writes without requiring Redis.
+
+
+ + +
Default 120 seconds. User-scoped version invalidation refreshes changed conversations; set to 0 to skip writing new entries.
+
+
+
+
+
+
Runtime Status
+ Not loaded +
+
+
+
+
15m Cache Hit Rate
+
Not loaded
+
+
+
+
+
15m Cache Hits / Misses
+
Not loaded
+
+
+
+
+
15m Cache Bypasses / Errors
+
Not loaded
+
+
+
+
+
15m Writes / Invalidations
+
Not loaded
+
+
+
+
+
15m Operation Mix
+
Not loaded
+
+
+
+
+
Last Cache Event
+
Not loaded
+
+
+
+
+
Last Invalidation
+
Not loaded
+
+
+
+
+ + Conversation cache metrics are lightweight in-process counters for the current app worker. Application Insights logs remain the durable fleet-wide source for cache warnings and fallback behavior. +
+
+
+
+ +
+
+
+
+ Cosmos Document Access Index +
+

+ Monitor the document access projection used to remove expensive cross-partition document access queries. +

+
+
+ + {% if enable_dai_debug %} + + + {% endif %} +
+
+ +
+ + Document access projection maintenance is automatic. The background scheduler repairs fail-open projection records first, then runs bounded backfill batches repeatedly while work remains. Production read metrics below show DAI-served reads, Redis cache hits, source fallbacks, RU, and latency without requiring shadow validation. + {% if enable_dai_debug %}Debug controls and shadow validation diagnostics are visible because enable_dai_debug is enabled in app settings.{% endif %} +
+ +
+ +
+
+
+
Container
+ Not loaded +
+
+
+
+
Write-through
+ Not loaded +
+
+
+
+
Read Path
+ Not loaded +
+
+
+
+
Redis List Cache
+ Not loaded +
+
+ {% if enable_dai_debug %} +
+
+
Shadow Validation
+ Not loaded +
+
+ {% endif %} +
+
+
Auto Maintenance
+ Not loaded +
+
+
+
+
Next Maintenance Action
+
Not loaded
+
+
+
+
+
More Work Pending
+
Not loaded
+
+
+
+
+
Active Loop Interval
+
Not loaded
+
+
+
+ + {% if enable_dai_debug %} +
+
Automatic Maintenance and Diagnostics
+
+
+
+ + +
+
Always on. New and changed documents synchronize into the access index and fail open to repair records if projection updates fail.
+
+
+
+ + +
+
Always on. Maintenance keeps running bounded repair and backfill batches until DAI is healthy.
+
+
+
+ + +
+
Compares source list results to projection rows and logs mismatches without changing reads.
+
+
+ + +
Documents processed per manual or scheduled batch.
+
+
+ + +
Fail-open repair records reconciled before each backfill batch.
+
+
+
+ +
+
Default Read Path
+
+
+
+ + +
+
Always on. DAI-backed document and tag list reads are the normal path; source-container fallback remains automatic when backfill is not ready, repairs are pending, or a DAI query fails.
+
+
+
+ + +
+
Uses Redis read-through caching for DAI document, tag, and legacy-count reads. If Redis is unavailable, reads bypass cache and use DAI directly.
+
+
+ + +
Default 900 seconds. Scope-version invalidation makes document changes visible immediately; TTL clears unreachable old entries.
+
+
+
+ {% endif %} + +
+
+
+
Backfill State
+ Not loaded +
+
+
+
+
Repair Backlog
+
Not loaded
+
+
+
+
+
15m DAI Read Attempts
+
Not loaded
+
+
+
+
+
15m Redis Cache Hit Rate
+
Not loaded
+
+
+
+
+
15m Cache Hits / Misses
+
Not loaded
+
+
+
+
+
15m Cache Bypasses / Errors
+
Not loaded
+
+
+
+
+
15m Cache Invalidations
+
Not loaded
+
+
+
+
+
15m Served from DAI
+
Not loaded
+
+
+
+
+
15m Source Fallbacks
+
Not loaded
+
+
+
+
+
15m Fallback Rate
+
Not loaded
+
+
+
+
+
15m DAI Read RU
+
Not loaded
+
+
+
+
+
15m Avg / P95 Latency
+
Not loaded
+
+
+
+
+
Last Fallback Reason
+
Not loaded
+
+
+
+
+
Last DAI Read Metric
+
Not loaded
+
+
+
+
+
Last Cache Event
+
Not loaded
+
+
+
+
+ + Production read metrics are lightweight in-process counters for the current app worker. Application Insights logs remain the durable fleet-wide source for fallback warnings and query failures. +
+
+ {% if enable_dai_debug %} +
+
+
Last Shadow Result
+ Not run +
+
+
+
+
Shadow Mismatches
+
Not loaded
+
+
+
+
+
Source / Validation RU
+
Not loaded
+
+
+
+
+
Validation Index RU
+
Not loaded
+
+
+
+
+
Candidate Read RU
+
Not loaded
+
+
+
+
+
Estimated Wave 5 Savings
+
Not loaded
+
+
+
+
+
Source / Candidate Latency
+
Not loaded
+
+
+
+
+
Estimated Wave 5 Latency
+
Not loaded
+
+
+
+
+ + Rolling decision metrics aggregate shadow-validation samples over recent windows. Use these totals to compare source container RU with candidate access-index RU before enabling the future read path or Redis document access cache. +
+
+
+
+
5m Source / Candidate RU
+
Not loaded
+
+
+
+
+
5m Estimated Wave 5 Savings
+
Not loaded
+
+
+
+
+
15m Source / Candidate RU
+
Not loaded
+
+
+
+
+
15m Estimated Wave 5 Savings
+
Not loaded
+
+
+
+
+
15m Validation Overhead
+
Not loaded
+
+
+
+
+
15m Shadow Samples
+
Not loaded
+
+
+ {% endif %} +
+
+
Current Scope
+
Not loaded
+
+
+
+
+
Completed Scopes
+
Not loaded
+
+
+
+
+
Total Documents Processed
+
Not loaded
+
+
+
+
+
Total Documents Failed
+
Not loaded
+
+
+
+
+
Rows Upserted
+
Not loaded
+
+
+
+
+
Rows Deleted
+
Not loaded
+
+
+
+
+
Last Batch Completed
+
Not loaded
+
+
+
+
+
Last Error
+
Not loaded
+
+
+
+
+ +
+
+
+
+ Cosmos Maintenance +
+

+ Review expected indexing policies and clean up stale operational cache documents without touching source configuration or user data. +

+
+
+ + + + +
+
+ +
+ + Indexing maintenance only adds missing expected composite indexes and preserves existing policy paths. Composite indexes can increase write-index overhead while improving supported lookup and ordered-query speed. Stale cleanup is allowlisted to obsolete cache artifacts, supports dry-run review, and deletes at most one bounded batch per run. +
+
+ +
+
+
+
Indexing Policy Status
+ Not loaded +
+
+
+
+
Indexing Mode
+
Not loaded
+
+
+
+
+
Containers Checked
+
Not loaded
+
+
+
+
+
Missing Expected Indexes
+
Not loaded
+
+
+
+
+
Updated Containers
+
Not loaded
+
+
+
+
+
Indexing Failures
+
Not loaded
+
+
+
+
+
Last Indexing Evaluation
+
Not loaded
+
+
+
+
+
Stale Cleanup Status
+ Not loaded +
+
+
+
+
Cleanup Mode
+
Not loaded
+
+
+
+
+
Cleanup Candidates
+
Not loaded
+
+
+
+
+
Deleted Docs
+
Not loaded
+
+
+
+
+
Cleanup Failures
+
Not loaded
+
+
+
+
+
More Candidates
+
Not loaded
+
+
+
+
+
Cleanup Categories
+
Not loaded
+
+
+
+
+
Last Cleanup Evaluation
+
Not loaded
+
+
+
+
+ + + + + + {% if enable_dai_debug %} + + {% endif %} + +
+
+
+
+ Cosmos DB Throughput +
+

+ Monitor RU utilization and automatically adjust shared database or dedicated container throughput. +

+
+ +
+ +
+ + + + + + +
+ +
+ + Automation checks Cosmos throughput on the Metrics Window cadence while enabled and saves the last observed database or container view. SimpleChat can scale throughput up or down at 10,000 RU/s or lower. Above 10,000 RU/s, SimpleChat monitors utilization only; use the Azure portal for capacity changes, which can take 4 to 6 hours. Native Cosmos autoscale conversion is separate from SimpleChat scale-up and scale-down automation. +
+ + + +
+ + + +
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
Metrics Window
+
+
+ +
+ + min +
+
+
+
+ +
+
Scale Up Policy
+
+
+
+ + +
+
+
+ +
+ + % +
+
+
+ +
+ + RU/s +
+
+
+ +
+ + min +
+
+
+ + +
SimpleChat-managed scaling stops at 10,000 RU/s. Use the Azure portal above this limit.
+
+
+
+ + +
+
+
+
+ +
+
Scale Down Policy
+
+
+
+ + +
+
+
+ +
+ + % +
+
+
+ +
+ + RU/s +
+
+
+ +
+ + min +
+
+
+ + +
+
+
+ + +
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ Use this when container throughput should follow one standard automation policy instead of per-container overrides. Global policy also applies the Cosmos autoscale conversion setting above to current and future dedicated-throughput containers. +
+
+
+ +
+ +
+
+
+
Mode
+
Not loaded
+
+
+
+
+
Current RU/s
+
Not loaded
+
+
+
+
+
RU Utilization
+
Not loaded
+
+
+
+
+
Last Checked
+
Not loaded
+
+
+
+ +
+
+ +
+ + + + +
+
+
+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + +
+ + Mode + + + + + + + + + + Actions
Refresh to load Cosmos metrics.
+
+
+ + + + + + +
+
+
+ Front Door +
+ +
+

Configure Front Door URL for authentication and redirect flows.

+ +
+ + + +
+ +
+ + + + The base URL of your Front Door or load balancer. The system will automatically generate: +
    +
  • Home redirect: https://your-frontdoor.azurefd.net
  • +
  • OAuth2 redirect: https://your-frontdoor.azurefd.net/getAToken
  • +
+
+
+
+
diff --git a/application/single_app/templates/admin/_panes/search-extract.html b/application/single_app/templates/admin/_panes/search-extract.html new file mode 100644 index 00000000..37dfa557 --- /dev/null +++ b/application/single_app/templates/admin/_panes/search-extract.html @@ -0,0 +1,1698 @@ +
+ +

+ 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/security.html b/application/single_app/templates/admin/_panes/security.html new file mode 100644 index 00000000..40d43e1a --- /dev/null +++ b/application/single_app/templates/admin/_panes/security.html @@ -0,0 +1,230 @@ +
+

+ Manage security settings for key vault and other security configurations. +

+
+
+
+ Key Vault +
+ +
+ +

+ Configure Key Vault settings. +

+
+ + + +
+ +
+
+ ⚠️ Warning: Once you enable Key Vault, you should NOT disable it. Disabling Key Vault after enabling WILL cause loss of access to secrets and break application functionality. +
+
+ + + +
+
+ + + +
+ +
+
+ +
+
+
+
+ Secret Expiration Reminders +
+

+ Track SimpleChat-owned Key Vault secrets with expiration dates, in-app reminders, and an admin inventory that maps opaque secret names back to their owner and source. +

+
+ +
+ + + +
+ External automation: SimpleChat emits a queryable Application Insights event named + key_vault_expiration_reminder_triggered whenever a reminder notification is created. + Use an Azure Monitor scheduled query alert with an action group, Logic App, Function, or webhook to send external notifications. Enable the routing email option below if downstream automation needs to send directly to the configured reminder contact. +
traces
+| where customDimensions.sc_event_name == 'key_vault_expiration_reminder_triggered'
+| project timestamp,
+          reminder_id = tostring(customDimensions.sc_event_reminder_id),
+          scope = tostring(customDimensions.sc_event_scope),
+          source_type = tostring(customDimensions.sc_event_source_type),
+          days_until_expiry = toint(customDimensions.sc_event_days_until_expiry),
+          expires_on = tostring(customDimensions.sc_event_expires_on),
+          contact_email = tostring(customDimensions.sc_event_contact_email)
+ The contact_email column is populated only when the opt-in below is enabled. For workspace-based Log Analytics queries, use the equivalent Application Insights traces table and dimensions/properties fields available in that workspace. +
+ +
+ + +
+ +
+
+
+ + +
+
+ + +
+
+ + +
Comma-separated roles for global-scope reminder notifications.
+
+
+ + +
+
+
+ + +
+
+
+
+ + +
+ Default off. Enable only when Azure Monitor, Logic Apps, Functions, or webhook automation needs the email address to route notifications directly. +
+
+
+
+
+ +
+
+ + + +
+ + + +
+ + + + + + + + + + + + + + + + + + +
ExpiresScopeSourceFieldContactStatusReminder IDSecret
Refresh inventory to load tracked secrets.
+
+
+
+
+
+
diff --git a/application/single_app/templates/admin/_panes/send-feedback.html b/application/single_app/templates/admin/_panes/send-feedback.html new file mode 100644 index 00000000..1d9cdb36 --- /dev/null +++ b/application/single_app/templates/admin/_panes/send-feedback.html @@ -0,0 +1,72 @@ +
+

+ 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. +

+ + +
+
+
+
+ Report a Bug +
+

Something isn’t working as expected.

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+
+
+ +
+
+
+ Request a Feature +
+

Suggest an improvement or new capability.

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+
+
+
+
diff --git a/application/single_app/templates/admin/_panes/workspace-identities.html b/application/single_app/templates/admin/_panes/workspace-identities.html new file mode 100644 index 00000000..da77b91b --- /dev/null +++ b/application/single_app/templates/admin/_panes/workspace-identities.html @@ -0,0 +1,21 @@ +
+

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

+
+
+ Global Identities +
+

+ Identities defined here are available across the deployment. Each one stores its secret in Key Vault when Key Vault is configured, and is referenced by name rather than by value wherever it is used. +

+
+
+
diff --git a/application/single_app/templates/admin/_panes/workspaces.html b/application/single_app/templates/admin/_panes/workspaces.html new file mode 100644 index 00000000..3bf8d4aa --- /dev/null +++ b/application/single_app/templates/admin/_panes/workspaces.html @@ -0,0 +1,1138 @@ +
+

+ 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. +

+
+ + + +
+
+ +
+
+ Chat File Uploads +
+

+ Control whether users can upload files directly into chat conversations. +

+
+ + + +
+ +
+
+ Conversation Contents Drawer +
+

+ Let users navigate long conversations from a list of their prompts. +

+
+ + + +
+

+ When enabled, users can turn the drawer off for their own account from Profile settings. +

+
+
+ + + +
+

+ Required app role value: ChatFileUploadUser. Assign this role to users or groups in the Enterprise App before enabling the requirement. Existing chat attachments remain visible; this only controls new uploads. +

+
+ +
+
+ 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.
+ + +
+
+
+ + + +
+
+ Document Classification +
+

+ Enable this feature to allow users to classify documents uploaded to their workspaces using predefined categories. +

+
+ + + +
+ + +
+
Classification Categories
+

Define the labels and corresponding colors for document classification.

+ + + + + + + + + + + +
LabelColorActions
+ + + +
+
+ + +
+
+ Retention Policy +
+

Automatically delete aged conversations and documents based on configurable retention periods. Users, group owners, and public workspace admins can set their own retention policies.

+ + + + +
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+ + +
+
Default Retention Policies
+

Set organization-wide default retention periods for each workspace type. Users can override these defaults with their own preferences. Setting a default here means new users/workspaces will start with this retention period.

+ + +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + Force Push: Override all user/group/workspace custom retention policies with the organization defaults above. Users will then use the organization default until they set their own preference. +
+ +
+
+
+ + +
+ + + Retention policy will run once daily at this hour (UTC timezone). +
+ + +
+
+ +
+ {% if settings.retention_policy_last_run %} + {{ settings.retention_policy_last_run }} + {% else %} + Never run + {% endif %} +
+
+
+ +
+ {% if settings.retention_policy_next_run %} + {{ settings.retention_policy_next_run }} + {% else %} + Not scheduled + {% endif %} +
+
+
+ + +
+ + + Trigger retention policy execution immediately for selected workspace types, bypassing the scheduled time. + +
+ + +
+ + +
+
+ Workspace Scope Lock +
+

+ Control whether users can unlock workspace scope in chat conversations. When scope is locked, conversations are restricted to the workspaces that produced search results, preventing accidental cross-contamination with other data sources. +

+
+ + + +
+
+ + +
+
+ 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 947f7f1b..8edfa33f 100644 --- a/application/single_app/templates/admin_settings.html +++ b/application/single_app/templates/admin_settings.html @@ -931,11964 +931,175 @@

12. Enhanced Citations and Image Generation

- {% endif %} - -
-
-

- Manage security settings for key vault and other security configurations. -

-
-
-
- Key Vault -
- -
- -

- Configure Key Vault settings. -

-
- - - -
- -
-
- ⚠️ Warning: Once you enable Key Vault, you should NOT disable it. Disabling Key Vault after enabling WILL cause loss of access to secrets and break application functionality. -
-
- - - -
-
- - - -
- -
-
- -
-
-
-
- Secret Expiration Reminders -
-

- Track SimpleChat-owned Key Vault secrets with expiration dates, in-app reminders, and an admin inventory that maps opaque secret names back to their owner and source. -

-
- -
- - - -
- External automation: SimpleChat emits a queryable Application Insights event named - key_vault_expiration_reminder_triggered whenever a reminder notification is created. - Use an Azure Monitor scheduled query alert with an action group, Logic App, Function, or webhook to send external notifications. Enable the routing email option below if downstream automation needs to send directly to the configured reminder contact. -
traces
-| where customDimensions.sc_event_name == 'key_vault_expiration_reminder_triggered'
-| project timestamp,
-          reminder_id = tostring(customDimensions.sc_event_reminder_id),
-          scope = tostring(customDimensions.sc_event_scope),
-          source_type = tostring(customDimensions.sc_event_source_type),
-          days_until_expiry = toint(customDimensions.sc_event_days_until_expiry),
-          expires_on = tostring(customDimensions.sc_event_expires_on),
-          contact_email = tostring(customDimensions.sc_event_contact_email)
- The contact_email column is populated only when the opt-in below is enabled. For workspace-based Log Analytics queries, use the equivalent Application Insights traces table and dimensions/properties fields available in that workspace. -
- -
- - -
- -
-
-
- - -
-
- - -
-
- - -
Comma-separated roles for global-scope reminder notifications.
-
-
- - -
-
-
- - -
-
-
-
- - -
- Default off. Enable only when Azure Monitor, Logic Apps, Functions, or webhook automation needs the email address to route notifications directly. -
-
-
-
-
- -
-
- - - -
- - - -
- - - - - - - - - - - - - - - - - - -
ExpiresScopeSourceFieldContactStatusReminder IDSecret
Refresh inventory to load tracked secrets.
-
-
-
-
-
-
- - -
- -

- Configure AI agents and actions for enhanced functionality. Agents provide AI-driven task automation while Actions extend functionality with custom tools and integrations. -

- - - - - - {% set analyze_capability = settings.document_action_capabilities.analyze %} - {% set comparison_capability = settings.document_action_capabilities.comparison %} -
-
-
-
Document Action Capabilities
-

Configure the document actions shown in the Action dropdown in Chat and Workflow. These controls live in the Agents and Actions tab, but remain separate from the global agent and custom action cards below.

-
- Chat: 2-300 | Workflow: 2-1000 -
- -
-
-
-
- - - -
-
-
- - {{ analyze_capability.chat_max_documents }} -
-
-
- -
-
- -
-
-
- 2 - 300 -
-
-
-
- - {{ analyze_capability.workflow_max_documents }} -
-
-
- -
-
- -
-
-
- 2 - 1000 -
-
-
-
-
-
-
- - - -
-
-
- - {{ comparison_capability.chat_max_documents }} -
-
-
- -
-
- -
-
-
- 2 - 300 -
-
-
-
- - {{ comparison_capability.workflow_max_documents }} -
-
-
- -
-
- -
-
-
- 2 - 1000 -
-
-
-
-
-
- - -
-
- Agents Configuration -
-

- Configure AI agents powered by Semantic Kernel for task automation and orchestration. -

-
-
- Agents Page Customization -
-

Customize the public Agents page hero, color treatment, and optional guidance message.

-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
Used when two tone gradient is selected.
-
-
- - -
Shown below the Agents page hero. Use this for contact details, request guidance, or governance reminders.
-
-
-
- - -
-
When disabled, the Agents tab details popup hides instructions and the catalog API response omits them.
-
-
-
-
Promoted Popular Agents
-

Highlight selected agents in the Popular tab even before they have usage counts. Users only see promoted agents that are already visible to them.

- -
-
- - -
-
- - -
-
-
-
- - -
-
When enabled, promoted agents show the configured tag in the Popular tab.
-
-
-
-
-
- - -
-
- -
-
-
- - - - - - - - - -
AgentShow InActions
-
- - -
-
-
-
-
- - - - - -
- -
- {% if not settings.enable_semantic_kernel %} -
- Agents UI is not available while agents are disabled. -
- {% else %} -
-
- - - -
- {% if settings.per_user_semantic_kernel %} - -
-
Workspace Feature Toggles
-
- - - - -
-
- - - - -
-
- - - - -
-
- - - - -
-
- - - -
-
- - - -
-
- - - {% endif %} - -
-

Agent Orchestration Settings

-
-
-

Configure how the chat system orchestrates agents (single or multi-agent group chat).

-
- - -
- - -
-
-

Global Agents

-
- - -
-
-

Disable a global agent to keep it saved for admins while hiding it from runtime selection until it is re-enabled.

-
- {% if settings.orchestration_type == "default_agent" %} - - {% else %} - - {% endif %} - - -
- - - - - - - {% if settings.orchestration_type == "default_agent" %} - - {% else %} - - {% endif %} - - - - -
NameDisplay NameDescriptionSelected AgentOrchestrator AgentActions
-
- {% endif %} -
- - {% if settings.enable_agent_template_gallery %} -
-
-
-
- - - -
-
-
-
- - - -
-
-
-
-
-
- Agent Template Approvals -
-

Template submissions are now reviewed from the shared approvals page.

-
- - Open Approvals Queue - -
-
- {% endif %} - - -
-
- Global Actions Configuration -
-

- Configure custom actions and tools to extend functionality with integrations and specialized capabilities. -

- - {% if not settings.enable_semantic_kernel %} -
- Actions are not available while agents are disabled. Enable agents above to configure actions. -
- {% else %} -
-
-
Global Actions
- -
-

Disable a global action to keep the configuration without exposing it to runtime action loading until it is re-enabled.

- {% if settings.per_user_semantic_kernel %} - -
-
Workspace Action Feature Toggles
-
- - - - -
-
- - - - -
-
- {% endif %} - - -
-
Core Action Toggles
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
- - - -
-
-
- Tabular Processing Action - -
- Automatically enabled when Enhanced Citations is enabled -
-
- - - - - - - - - -
Display NameDescriptionActions
-
- {% endif %} -
- {% if mcp_ui_enabled %} -
-
-
-
- Inbound MCP Server -
-

- Configure the governed SimpleChat MCP endpoint used by external MCP clients. Personal tools use delegated user tokens by default; tool access remains deny-by-default until authentication, source, client, and governance policy all allow the request. -

-
-
- Preview - -
-
- - - -
-
-
-
Runtime Gate
-
- - - -
-
- - -
Default: DelegatedMcpServerAccess. VS Code and other user clients must present this delegated scope.
-
-
- - -
Default: InboundMCPUserAccess. Governance determines which users/groups can use tools after this Entra role and delegated scope pass.
-
-
- - -
Default: InboundMCPAppAccess. Reserved for future app-only MCP tools and still governed separately.
-
-
-
- -
-
-
Endpoint Contract
-
-
MCP endpoint
-
{{ inbound_mcp_resource_path }}
-
Protected resource metadata
-
{{ inbound_mcp_prm_path }}
-
Transport
-
Streamable HTTP JSON-RPC
-
Current tool surface
-
Personal delegated tools only.
-
Tool identity
-
Delegated user token required for personal data.
-
- -
-
- -
-
-
-
-
Request Size & Throttling
-
Protect the inbound MCP endpoint from oversized payloads and noisy clients. Rate limits are enforced per caller and tool category across app instances.
-
-
- - -
-
-
-
- - -
Default: 65536. Range: 1 KB to 1 MB.
-
-
- - -
Default: 60. Applies to each throttle category.
-
-
- - -
Default: 120.
-
-
- - -
Default: 30.
-
-
- - -
Default: 10.
-
-
- -
-
- -
- - - -
- -
-
-
-
-
Allowed client app IDs
-
Required allowlist. Empty means no MCP clients can connect.
-
- -
-
- - - - - - - - - -
Client app IDDescriptionActions
-
-
-
-
- -
-
-
- - -
-
- Off allows only the configured SimpleChat tenant. Turning this on auto-includes the SimpleChat tenant and lets admins add more tenants. -
-
-
-
Allowed tenant IDs
- -
-
- - - - - - - - - -
Tenant IDDescriptionActions
-
-
-
-
-
- -
-
-
- - -
-
- Default on accepts any source signal at the runtime allowlist layer. Turn off to require explicit source values here. In both modes, admins must still create an inbound MCP source governance policy before tools are returned. -
-
- - -
Default: X-SimpleChat-MCP-Source.
-
- - - -
-
-
Allowed source IDs
- -
-
- - - - - - - - - -
Source valueDescriptionActions
-
-
-
-
-
-
-
- - - - {% endif %} -
- - - -
-
-

- Configure governance enforcement for endpoint, agent, and action creation or usage. Governance is disabled by default and only enforced when toggled on. -

- -
- -
-
- Governance Feature Toggles -
-

Turn on governance checks for each feature area. Save with the main Settings button to persist these toggles.

- -
-
-
Personal Scope
-
- - -
-
- - -
-
- - -
-
-
-
Group Scope
-
- - -
-
- - -
-
- - -
-
-
-
Global Scope
-
- - - Always On -
-
- - -
-
- - -
-
-
-
- -
-
- MCP Action Destination Governance -
-

- Restrict outbound remote MCP servers by destination pattern and scope. Destination policies reuse delegated item policies, so admins can allow all users, specific users, or workspace groups for each approved destination. -

-
-
-
- - -
-
- - -
-
- Save with the main Settings button. Unsafe literal-IP blocking can be enabled even before the allowlist is enforced. -
-
-
-
Supported destination patterns
-
    -
  • * for any remote MCP destination after identity/auth checks.
  • -
  • preconfiguration:microsoft_learn or preset:generic.
  • -
  • *.contoso.com, https://example.com/mcp*, or transport:streamable-http.
  • -
  • group:<group-id>::preconfiguration:github for one group-specific override.
  • -
-
-
-
-
- - -
-
- - -
-
- - -
-
-
-
-
- -
-
- Inbound MCP Source Governance -
-

- Control which delegated users and groups can use SimpleChat as an inbound MCP server through source-scoped policies. -

- -
-
-
Policy required for inbound MCP
-
    -
  • inbound_mcp_source with delegated item *: allows selected users or groups to use any accepted source ID.
  • -
  • inbound_mcp_source with a configured source ID: allows selected users or groups to use only requests with that source value.
  • -
-
- Client, tenant, delegated scope, and Entra role checks remain in Inbound MCP configuration. The source ID comes from the configured header when present and is advisory unless a trusted gateway sets or validates it. -
-
-
-
-
- - -
-
-
-
-
- -
-
-
Feature Policies
- -
-

Set allow-all, explicit allow lists, and block lists for each governed feature. Block lists override allow settings.

-
- - - - - - - - - - -
FeatureAllow AllAllow ListBlock List
-
-
- -
-
-
Delegated Item Policies
-
- - -
-
-

Manage delegated governance for configured global resources and action type entitlements that admins assign to specific users or groups.

- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
- - - - - - - - - - - -
PolicyEntity TypeItemAllow AllActions
-
- -
-
-
- - -
-
-
- - -
- - -
-

- Configure logging settings for monitoring, debugging, and auditing purposes. These settings control various types of logging throughout the application including application insights, debug messages, and file processing events. -

- -
-
- Application Insights Logging -
-

Enable global logging to Application Insights for all agents and orchestration events.

-
- - - -
- -
- -
-
- Debug Logging -
-

Control debug print statements across the application for development and troubleshooting.

-
- - - -
- - -
-
- - - -
- -
-
- - -
-
- - -
-
- -
- {% if settings.debug_logging_turnoff_time %} - {% if settings.debug_logging_turnoff_time is string %} - {{ settings.debug_logging_turnoff_time }} - {% else %} - {{ settings.debug_logging_turnoff_time.strftime('%Y-%m-%d %H:%M:%S') }} - {% endif %} - {% else %} - Will be calculated when saved - {% endif %} -
-
-
-
- - -
- -
-
- File Process Logging -
-

Enable logging of file processing events for debugging and auditing purposes. Logs are stored in the file_processing container in Cosmos DB.

-
- - - -
- - -
-
- - - -
- -
-
- - -
-
- - -
-
- -
- {% if settings.file_processing_logs_turnoff_time %} - {% if settings.file_processing_logs_turnoff_time is string %} - {{ settings.file_processing_logs_turnoff_time }} - {% else %} - {{ settings.file_processing_logs_turnoff_time.strftime('%Y-%m-%d %H:%M:%S') }} - {% endif %} - {% else %} - Will be calculated when saved - {% endif %} -
-
-
-
- -
-
-
Delete stored logs
-

- Permanently remove file processing logs from Cosmos DB. One month is treated as 30 days. -

-
-
- - -
- Enter a whole number greater than zero. -
-
-
- - -
-
- - -
-
-
-
-
- -
- -

- 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. - -
-
-
- -
-

- 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. -

- - - {% for release_group in admin_latest_feature_release_groups %} - {% if release_group.id == 'current_release' %} -
-
-
{{ release_group.label }}
-

{{ release_group.description }}

-
- {% if release_group.release_version %} - v{{ release_group.release_version }} - {% endif %} -
- - {% for feature in release_group.features %} - {% set feature_card_id = 'latest-features-' ~ feature.id|replace('_', '-') ~ '-card' %} - {% set feature_collapse_id = feature_card_id ~ '-details' %} -
-
-
-
{{ feature.title }}
-

{{ feature.summary }}

-
- -
-
-
- {% if feature.details %} -

{{ feature.details }}

- {% endif %} - {% if feature.why %} - - {% endif %} - {% if feature.guidance %} -
{% if feature.images %}Screenshot and rollout notes{% else %}Rollout notes{% endif %}
-
    - {% for tip in feature.guidance %} -
  • {{ tip }}
  • - {% endfor %} -
- {% endif %} - {% if feature.images %} - - {% endif %} - {% if feature.actions %} -
- {% for action in feature.actions %} - - {{ action.label }} - - {% endfor %} -
- {% endif %} -
-
-
- {% endfor %} - {% else %} - {% set release_card_id = 'latest-features-' ~ release_group.id|replace('_', '-') ~ '-card' %} - {% set release_collapse_id = release_group.collapse_id %} -
-
-
-
{{ release_group.label }}
-

{{ release_group.description }}

-
- -
-
-
- {% if release_group.release_version %} - - {% endif %} -
- {% for feature in release_group.features %} -
-
-
-
-
{{ feature.title }}
-

{{ feature.summary }}

-
-

{{ feature.details }}

- {% if feature.guidance %} -
    - {% for tip in feature.guidance %} -
  • {{ tip }}
  • - {% endfor %} -
- {% endif %} - {% if feature.images %} - - {% endif %} - {% if feature.actions %} -
- {% for action in feature.actions %} - - {{ action.label }} - - {% endfor %} -
- {% endif %} -
-
-
- {% endfor %} -
-
-
-
- {% endif %} - {% endfor %} - - {% if false %} -
-
-
-
- Registered / Unregistered Badge -
-

The badge next to the Admin Settings version number shows whether this admin instance is registered for latest release and community call notifications.

-
- -
-
-
- -

Use this badge as the quick status check for whether your environment is already registered to receive SimpleChat release updates.

-
    -
  • Unregistered means this environment has not saved release notification registration details yet.
  • -
  • Registered means the environment already has saved contact details for release and community call notifications.
  • -
  • Clicking the badge opens the registration modal where admins can add or edit the name, email, and organization for this instance.
  • -
  • Submitting the form opens a prefilled email draft to simplechat@microsoft.com and stores the registration details back in Admin Settings.
  • -
  • The badge lives beside the version number at the top of Admin Settings so admins can confirm status without hunting through tabs.
  • -
-
-
-
- -
-
-
-
- Performance Improvements for Apps running Native Python (not containers) -
-

Native Python App Service deployments should use Gunicorn as the startup command. Container deployments already do this for you.

-
- -
-
-
-

If you run the native Python App Service deployment instead of the container deployment, set the App Service Startup command to the following:

-
python -m gunicorn -c gunicorn.conf.py app:app
-

Use container deployments when possible if you want the runtime defaults and startup behavior handled by the shipped image.

- - -
-
-
- -
-
-
-
- Guided Tutorials -
-

New guided walkthroughs help users learn the live chat and personal workspace interfaces without leaving the app.

-
- -
-
-
-

Admins can use these walkthroughs to accelerate onboarding for new users and reduce orientation time across the primary product surfaces.

-
    -
  • Guided Chat Tutorial covers the active chat experience, message actions, search flows, citations, thoughts, and export-related actions.
  • -
  • Personal Workspace Guided Tutorial walks through uploads, search, filters, list and grid views, prompts, agents, actions, and tags.
  • -
- -
-
-
- -
-
-
-
- Background Chat Completion -
-

Personal chats can continue finishing after a user leaves the chat page, and completed responses surface as notifications with unread indicators.

-
- -
-
-
-

This makes long-running responses more reliable for users who navigate into other areas of the app before generation finishes.

-
    -
  • Completion notifications deep-link back into the finished conversation.
  • -
  • Unread markers remain visible until the response is actually opened.
  • -
  • Personal, workspace, and navigation flows now behave more consistently while chat completion continues in the background.
  • -
- -
-
-
- -
-
-
-
- Multi-Endpoint GPT Selection -
-

Admins can expose multiple GPT choices across Azure OpenAI and Azure AI Foundry, set a saved default fallback model, and now review agent rebinding in a modal before applying changes.

-
- -
-
-
-

This is the high-value admin control for teams that want broader GPT choice without locking every workflow to a single deployment.

-
    -
  • Configure multiple model endpoints and choose which GPT deployments are available to users.
  • -
  • Set a default fallback model so summarization, agent requests, and other background flows still resolve a usable GPT when an explicit selection is missing.
  • -
  • Use the admin-only Agent Default Model Review modal to inspect inherited agents, search and filter large agent sets, and explicitly choose which review rows should be overridden to the saved default.
  • -
- - - -
-
-
- -
-
-
-
- Tabular Data Analysis -
-

Enhanced citations now unlock a more consistent tabular analysis experience for normal chat and workspace-backed files, not just dedicated agent scenarios.

-
- -
-
-
-

This is the highest-impact settings area to mirror here because it combines storage-backed citations, tabular previews, and consistent behavior across workspace and chat uploads.

-
    -
  • Tabular files can be analyzed with the same core approach whether they come from chat uploads or any workspace container.
  • -
  • Enhanced citations provide the blob-backed dependency for richer tabular processing and citation transparency.
  • -
  • Admins can right-size tabular preview limits based on the memory profile of their runtime.
  • -
- -
- - -
- -
-
-
All filetypes
-
- - -
- -
- -
- - -
-
- -
- -
- - -
-
-
- -
-
Tabular Preview Limits
-
- - - - Mirror of the Citations setting. Larger values support bigger previews but increase runtime memory pressure. - -
-
-
- - -
-
-
- -
-
-
-
- Citation Improvements -
-

Conversation history citation replay and citation amplification keep more grounded evidence available across follow-up turns without making the chat history unwieldy.

-
- -
-
-
-

These improvements make follow-up questions more reliable because the system can reuse prior grounded evidence instead of relying only on the assistant's last prose response.

-
    -
  • Conversation history citations carry forward prior citation summaries so later prompts can reuse earlier grounded results.
  • -
  • Citation amplification keeps richer supporting payloads available for inspection and export while keeping prompt history compact.
  • -
  • This is especially useful for larger or tabular outputs where users often ask multiple follow-up questions against the same evidence chain.
  • -
- - -
-
-
- -
-
-
-
- Document Revisioning and Management -
-

Uploading a document with the same name now creates a new revision instead of overwriting the previous file, while older versions remain available for traceability and later analysis.

-
- -
-
-
-

This improves both document management and citation integrity for long-lived conversations that span multiple document updates.

-
    -
  • Same-name uploads create a revision family with an incremented current version instead of destroying prior history.
  • -
  • Previous versions are retained for analysis or comparison, while workspace and search views focus on the current revision by default.
  • -
  • Older conversations can still resolve citations against the correct historical document version.
  • -
  • Updated revisions inherit document classifications and tags so admins do not have to reapply metadata after every refresh.
  • -
- -
-
-
- -
-
-
-
- Conversation Summaries and Export -
-

Conversation export now includes persistent summaries, PDF output, and easier per-message reuse and sharing actions.

-
- -
-
-
-
    -
  • Conversation details now surface a summary card with generate and regenerate actions.
  • -
  • Export supports PDF alongside existing export options.
  • -
  • Per-message actions support Markdown export, Word export, open in email, and use as prompt.
  • -
-
-
- -
-
- -
-
-
-
-
- -
-
-
-
- Agent and Action Operations -
-

Recent updates improve manageability for agents and actions with richer views, easier SQL connectivity checks, and better operational tracking.

-
- -
-
-
-
    -
  • List and grid view toggles give admins and users a better way to browse agents and actions.
  • -
  • SQL actions now include an inline Test Connection button before save.
  • -
  • User tracking and activity logging improve auditability for agent and action changes.
  • -
- -
-
-
- -
-
-
-
- AI Transparency -
-

Processing Thoughts provide a clearer view into model activity, duration, and execution flow while responses are being generated.

-
- -
-
-
-

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

- -
- - -
- -
-
-
- -
-
-
-
- Fact Memory -
-

Users can now save Instructions and Facts on their profile so the assistant can apply durable preferences every time and recall relevant personal context only when needed.

-
- -
-
-
-

Fact Memory gives users a compact profile experience for managing two distinct memory types: always-on Instructions and relevance-based Facts.

-
    -
  • Instructions act like stable user preferences and are applied on every prompt unless the current message overrides them.
  • -
  • Facts are recalled only when relevant and now appear as dedicated thought and citation entries in chat.
  • -
  • The profile page includes a compact add flow plus a popup manager for search, paging, edit, retag, and delete actions.
  • -
  • Admins can choose whether this announcement is visible on the user-facing Latest Features page from General > User-Facing Latest Features.
  • -
- - -
-
-
- -
-
-
-
- Redis and Key Vault -
-

Redis configuration now supports using a Key Vault secret name instead of storing the access key directly in settings.

-
- -
-
-
-

This is useful for teams standardizing on Key Vault-backed secret storage while still using Redis for cache and session scenarios.

-
    -
  • Use Redis authentication type Key Vault when you want the stored value to represent a secret name instead of a raw Redis key.
  • -
  • This works best when Key Vault is already configured for the app.
  • -
- -
- - -
- -
-
-
Redis Cache Settings
-
- - -
-
- - -
-
- -
- - -
-
- When using Key Vault, store the secret name here instead of the raw Redis key. -
-
-
-
- -
-
-
- -
-
-
-
- Send Feedback to the SimpleChat Team -
-

Admins now have a dedicated Send Feedback tab for bug reports and feature requests that opens a prefilled email draft and writes an audit record to the activity log.

-
- -
-
-
-

Use the Send Feedback tab when you want to report a bug or suggest a feature directly from Admin Settings without leaving the page.

-
    -
  • Opens a prefilled email draft addressed to simplechat@microsoft.com.
  • -
  • Logs the action to the activity log so admins can audit when feedback emails were prepared.
  • -
  • Keeps the workflow simple by using text-only email content with no confusing pseudo-attachment step.
  • -
- - Open Send Feedback - -
-
-
- -
-
-
-
- Support Menu -
-

Support can now expose user-facing Latest Features and Send Feedback workflows directly in everyday navigation.

-
- -
-
-
- -
    -
  • Admins can enable or disable the Support menu and rename it for user navigation.
  • -
  • Send Feedback now routes users to an internal recipient email address defined by admins.
  • -
  • The user-facing Latest Features page can be curated feature-by-feature so teams only share the items they want visible.
  • -
  • The General tab now includes a dedicated User-Facing Latest Features checklist so admins can quickly confirm which announcements will be visible to end users.
  • -
- - Open General Settings - - -
-
-
- {% endif %} - - {% for release_group in support_latest_feature_release_groups_preview %} - {% if release_group.id != 'current_release' %} - {% set preview_card_id = 'latest-features-user-preview-' ~ release_group.id|replace('_', '-') ~ '-card' %} - {% set preview_collapse_id = 'latestFeaturesUserPreview' ~ release_group.id|replace('_', ' ')|title|replace(' ', '') %} -
-
-
-
- {{ release_group.label }} -
-

{{ release_group.description }}

-
- -
-
-
- -
- {% for feature in release_group.features %} -
-
-
-
-
-
{{ feature.title }}
-

{{ feature.summary }}

-
- - {% if settings.support_latest_features_visibility.get(feature.id, true) %}Shared with Users{% else %}Hidden from Users{% endif %} - -
-

{{ feature.details }}

- {% if feature.guidance %} -
    - {% for tip in feature.guidance %} -
  • {{ tip }}
  • - {% endfor %} -
- {% endif %} - {% if feature.images %} - - {% endif %} - {% if feature.actions %} -
- {% for action in feature.actions %} - - {{ action.label }} - - {% endfor %} -
- {% endif %} -
-
-
- {% endfor %} -
-

Visibility still comes from General > User-Facing Latest Features, so admins can keep previous and archived release content available without promoting every item forever.

-
-
-
- {% endif %} - {% endfor %} -
- -
-

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

- -
-
-
- Custom Pages -
- -
-
- - - - -
-

When disabled, /custom routes return Not Found before loading custom metadata, files, or Python extensions.

- -
-
- - - This name appears when custom pages are grouped into a menu. -
- -
- - - When disabled, 1-2 custom pages show as top-level nav items and 3+ pages show as a menu. -
- -
-
-
Static Page Metadata
-

Create metadata contracts for simple pages that use files from custom_pages/html, css, js, assets, and json.

-
-
- - -
-
- -
- - - - - - - - - - - - - - - - - - -
SlugTitleTypeAccessRolesStatusNavActions
Loading custom pages...
-
-
-
-
- - -
- -

- Configure all AI model settings including GPT for text generation, embeddings for semantic search, and image generation capabilities. -

- -
-
- Model Endpoints -
-

- Manage multiple AI model endpoints (Azure OpenAI and Azure AI Foundry). When enabled, model selection in chat is driven by these endpoints. -

- - {% if not settings.enable_multi_model_endpoints %} -
- - -
- {% endif %} - - {% if settings.enable_semantic_kernel %} -
-
-
-
Agent Default Model Review
-

- Review local agents in a modal, bulk-bind inherited agents to the saved default model endpoint, and explicitly override selected agent model choices when you need to manage cost or move to newer models. -

-
-
- -
-
-
- {% if settings.enable_multi_model_endpoints %} - Save your AI model settings before reviewing or migrating agents. - {% else %} - Enable multi-endpoint model management to review and rebind agents to a saved default model. - {% endif %} -
- -
- -
-
- Ready: 0 - Needs Default: 0 - Manual Review: 0 - Already Migrated: 0 -
-
-
- Open the review modal to search, filter, and selectively rebind agents to the saved default model. -
-
- - - {% else %} - - {% endif %} - -
-
-
-
Model Endpoint Identity Header
-

- Send a stable HMAC-hashed user key to model endpoint backends for APIM counters, quota policies, or routing policies. -

-
-
- - -
-
-
-
- - -
Reserved auth/protocol headers cannot be used.
-
-
- - -
The selected identity is HMAC-hashed before leaving SimpleChat. Missing identity values omit the header.
-
-
-
- -
- - -
- Used for tasks such as conversation summarization, fallback, and other operations when an agent is selected. -
-
- - - - -
-
-
Global Endpoints
-
- - -
-
-
- - - - - - - - - - - - - -
NameProviderSelected ModelsStatusActions
-
-
- {% if not settings.enable_multi_model_endpoints %} - - {% endif %} -
- - -
-
- Processing Thoughts -
-

When enabled, real-time processing steps are shown to users during chat responses and persisted for later review.

-
- - - -
-
- - -
-
- 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.

-
- - - -
-
- - -
-
- Embeddings Configuration -
-

- Configure your embeddings settings. These are used for semantic search, knowledge-base lookups, etc. -

- - -
- - - -
- -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
- - -
-
-
-
- -
- Save pending changes to settings before clicking Fetch Embedding Models
- - - - - - - - -
- -
-
-
- - -
-
-
-
-
- -
-
- - -
-
- - -
-
- - -
-
- -
- - -
-
-
- - -
-
- - -
-
- Image Generation Configuration -
-

- Configure image generation settings. Enable/disable, set endpoints, and choose a model. -

- - -
- - - -
-
- -
- - - -
- -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
- - -
-
-
-
- -
- - Save pending changes to settings before clicking Fetch Image Generation Models
- - - - - - - - -
- -
-
-
- - -
-
-
-
-
- -
-
- - -
-
- - -
-
- - -
-
- -
- - -
-
-
-
- - -
-
- - - - {% include '_multiendpoint_modal.html' %} - - - -
- - -
-

- Configure Control Center access and permissions for administrators. -

- -
-
-
-
- -
-
-

- Automatic Data Refresh -

-

Run the Control Center metrics refresh overnight on a daily timezone-aware schedule

-
-
-
- -
- - - -
- -
-
- - - -
- Your browser timezone is local time. -
-
-
- -
- {% if settings.control_center_auto_refresh_next_run %} - Loading local time... - {% else %} - Will be calculated when saved - {% endif %} -
-
-
-
- - -
-
-
-
- -
-
-

- Control Center Access -

-

Manage who can access Control Center features and administrative tools

-
-
- -
- -
- - About Control Center: The Control Center is a powerful administrative dashboard that provides user management, group oversight, public workspace control, and detailed activity monitoring. Use role-based access controls below to delegate administrative responsibilities. -
- - -
-
- - -
-

- Required app role value: ControlCenterAdmin. Assign this role to users or groups in the Enterprise App before enabling the requirement. When enabled, only users assigned this role can access the Control Center and all management features. Regular Admins will lose access. -

-
- - User Management - - - Group Management - - - Public Workspaces - - - Activity Logs - -
-
- - -
-
- - -
-

- Dashboard-only app role value: ControlCenterDashboardReader. Assign this role to users or groups in the Enterprise App before enabling dashboard-only access. Users assigned ControlCenterAdmin can also access the dashboard when Control Center app-role enforcement is enabled. -

-
- - Dashboard Statistics - - - Activity Trends - - - Usage Metrics - -
-
- -
- - Important: Configure these roles in your identity provider (Entra ID). When role requirements are enabled, standard Admins without the specific roles will be denied access to Control Center features. -
- - -
-
- Best Practices -
-
    -
  • ControlCenterAdmin: Grant to IT administrators who need full control over users, groups, and workspaces
  • -
  • ControlCenterDashboardReader: Grant to managers, compliance officers, or stakeholders who need visibility into platform usage without administrative powers
  • -
  • Separation of Duties: Enable role requirements if you need to restrict Control Center access from general application admins
  • -
  • Audit Trail: All Control Center actions are logged in Activity Logs for compliance and security auditing
  • -
-
-
-
- -
-
-
-

Backup, Migrate & Restore

-

Protect SimpleChat data, move selected workspaces to another environment, and stage restore decisions with guided checks.

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

Start Here

-

Use these checkpoints before running backup, migration, restore, or advanced repair actions.

-
- -
-
-
-
-
Back up
-

Configure dedicated storage, encryption, schedule, and backup scope before queueing jobs.

- -
-
-
-
-
Migrate
-

Connect a destination, choose who moves, run preflight, then execute a recoverable transfer.

- -
-
-
-
-
Restore
-

Review backup readiness and stage restore decisions from Backup Inventory.

- -
-
-
-
-
RU Boost
-

Temporarily raise eligible Cosmos capacity during approved backup or migration windows.

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

Backup

-

Configure when backups run, where artifacts are stored, and how backup files are encrypted.

-
-
- -
-
-
-
Schedule
-

Full backups run on the selected cadence; partial backups run daily only.

-
-
-
- - -
-
-
- - -
-
- - -
Default is 03:00 UTC.
-
-
- -
- - - -
- -
Automatic cleanup keeps the newest successful full backup as a safety baseline.
-
-
-
-
-
- - -
-
-
-
- - -
-
-
-
- -
-
-
- -
-
-
- - -
Core application records required for meaningful restore and migration.
-
-
-
-
- - -
Search index schemas and retrievable indexed documents.
-
-
-
-
- - -
Original source files used by Enhanced Citations.
-
-
-
-
-
-
-
- -
-
-
-
Storage
-

Store backup artifacts in Azure Blob Storage.

-
- -
-
- - Use a dedicated backup storage account. Data Management will reject storage that matches the Enhanced Citations connection string or Blob endpoint. -
-
-
- - -
-
- - -
-
- - -
-
-
-
- - -
No connection string saved yet.
-
-
- - -
-
-
- -
-
-
-
Encryption
-

Generate a 256-bit backup encryption key.

-
- -
-
- - -
-
-
Key storage
-
Not configured
-
Key reference
-
Not configured
-
-
- -
-
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 -
-
-
- -
-
-
-
Cosmos Backup Performance
-

Backups stream deterministic checkpoint batches and commit only verified work. Higher concurrency can increase source Cosmos cost and pressure.

-
- -
- -
-
-
Source Blob Backup Performance
-

Source files stream through bounded chunks and durable per-file checkpoints. Peak transfer buffering is bounded by concurrent transfers multiplied by chunk size.

-
-
-
- - -
-
- - -
-
- - -
-
-
Defaults bound application transfer buffering to approximately 32 MiB, excluding Azure SDK overhead. Throttling temporarily reduces active transfers.
-
-
-
- - -
-
- - -
-
- - -
-
-
- - -
-
-
- - -
-
-
The backup records the current source capacity, raises only eligible targets up to 10,000 RU/s, and restores the original setting after completion, cancellation, failure, or recovery. This can increase Cosmos charges and requires source ARM throughput permission.
-
-
-
- -
-
-
-
Backup Operations
-

Queue immediate full or partial backup jobs using the settings above.

-
-
- - -
-
-

Jobs use Cosmos-backed leases so scaled-out App Service workers do not run the same backup twice.

-
-
- - -
-
-
-

- Migration -

-

Move SimpleChat data through a reviewed, recoverable environment transfer.

-
-
- - Not reviewed -
-
- -
- - - - - -
-
-
-
Connect the destination
-

Configure the services this migration will write to. Stored credentials remain redacted.

-
- Destination database: SimpleChat -
- -
-
-
-
-
Target Cosmos Database
-

Required for every migration.

-
- -
-
- Managed identity requires Cosmos DB Data Contributor and target network access. -
-
-
- - -
-
- - -
-
- - -
Fixed app contract.
-
-
-
- - -
-
- -
-
-
-
Target Search
-

Required when AI Search documents are included.

-
- -
-
-
- - -
-
- - -
-
- - -
-
-
- -
-
-
-
Target Enhanced Citation Storage
-

Required only when source document blobs are included.

-
- -
-
-
- - -
-
- - -
-
- - -
-
-
-
-
- - -
-
-
-
Choose who and what moves
-

Selections persist while you search and page. “All” always uses the exhaustive server count.

-
-
0 principal scopes selected
-
- -
- - - -
- -
- -
- Migration mode -
- - - -
-
- -
-
-
-
-
Available users
-

Search the server catalog.

-
- -
-
-
- - Page 1 - -
-
- -
- -
- -
- Loading exhaustive count… - Every current user record will be resolved by the server when the job starts. -
-
- -
- - -
-
- -
- -
- Migration mode -
- - - -
-
-
-
-
-
-
Available groups
-

Search the server catalog.

-
- -
-
-
- - Page 1 - -
-
- -
-
- -
- Loading exhaustive count… - Every current group record will be resolved by the server when the job starts. -
-
-
- - -
-
- -
- -
- Migration mode -
- - - -
-
-
-
-
-
-
Available public workspaces
-

Search the server catalog.

-
- -
-
-
- - Page 1 - -
-
- -
-
- -
- Loading exhaustive count… - Every current public workspace record will be resolved by the server when the job starts. -
-
-
- - -
-
-
- - -
-
-
-
Choose what happens at the destination
-

Choose whether to copy only missing items, catch up changes, or make migrated destination data match the source.

-
-
- -
- Destination behavior -
- - - - - - -
-

- Copies source items that are absent from the destination. Existing destination data is never updated or deleted. -

-
-
- - -
Leave blank to let SimpleChat choose the latest compatible completed migration as the starting point for this catch-up run.
-
-
-
- -
- Data surfaces -
-
-
- - -
-
- - -
SimpleChat pauses its own target indexing. Freeze other writers before review.
-
-
-
-
- - -
Requires Enhanced Citation storage at both source and destination.
-
-
-
-
- -
- Performance and resume -

Migration uses durable resource checkpoints and retains the same migration ID after Retry or Resume.

-
-
- - -
-
- - -
-
- - -
-
-
- - - -
-
-
- - -
-
- - -
-
- - -
-
- -
-
-
RU Boost validates Azure management-plane throughput permissions separately from Cosmos data-copy access. Eligible capacity is raised only up to 10,000 RU/s during execution and restored after completion or failure.
-
-
-
-
- - -
-
-
-
Prove the plan is ready
-

Preflight runs server-owned access probes and inventory. Any earlier change makes this review stale.

-
-
- - -
-
-
- -
- Review has not run. - Run preflight to verify target access, counts, collisions, locks, and capacity policy. -
-
-
-
- -
- - -
-
-
-
Confirm execution
-

Review the final server-normalized plan. Submission is guarded against duplicate requests.

-
-
-
-

Complete preflight review before confirmation.

-
- -
- - -
- -
- - -
-
-
-
Operate the migration
-

Progress comes from the durable job record. Cancel, Retry, and Resume retain verified checkpoints.

-
-
- - -
-
-
- -
- No migration is attached to this workflow yet. - After execution, this stage follows the queued job and exposes its recovery actions. -
-
-
-
-
-
-
-
- -
-
- - -
- Step 1 of 6 -
-
-
- -
-
-
-

Cosmos DB JSON Editor

-

Query SimpleChat Cosmos DB containers, inspect one document, and save JSON changes with ETag protection.

-
- -
- -
- The Cosmos DB JSON editor is locked. Acknowledge the danger prompt before querying or editing data. -
-
-
-
- - -
Choose a known SimpleChat Cosmos DB container.
-
-
- - -
Max 100 per request.
-
-
- - -
Empty query returns only the first 100 documents. Custom SELECT queries can page beyond 100 with Next Page.
-
-
-
- - No query has run yet. -
-
- Query results and the JSON editor open in a modal so the Data Management page stays compact. -
-
-
- -
-
-
-

Backup Inventory

-

Track completed full and partial backups created by Data Management jobs.

-
-
- - - -
-
-
-
-
What does Run Retention Cleanup do?
-

- It permanently deletes backups whose age exceeds the retention period configured in Data Management settings, - and removes their stored artifacts from the backup container. Backups newer than the retention cutoff are left alone. -

-
    -
  • Only backups in a finished state are eligible; running or queued jobs are skipped.
  • -
  • When Keep latest full backup is enabled, the most recent successful full backup is protected even if it is past the cutoff.
  • -
  • Each run deletes at most 25 backups, so very large cleanups may need several runs.
  • -
  • Cleanup also runs automatically on the configured schedule; this button just runs it now.
  • -
-

- Seeing “found no expired backups to delete” means every backup is still inside the retention window. That is expected, not an error. -

-
-
-
-
- -
-
- -
-
- -
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- - - - - - - - - - - - - - - - - -
BackupCompletedContentsStorageProtectionWarningsActions
Backup inventory has not loaded yet.
-
- -
- - - -
-
-

Job History

- -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- - - - - - - - - - - - - - - - -
CreatedOperationStatusProgressMessageActions
Job history has not loaded yet.
-
- -
- - - - - - - - - - - - - - - - - - - - -
- -
- {% 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. -

-
-
- Redis Cache -
-

- Enable Redis Cache to store session data in a distributed cache. This is recommended for production and multi-instance deployments. -

-
- - - -
-
-
- -

(example: simple-chat.redis.cache.windows.net)

- -
-
- - -
-
- -
- - -
-
- Enter the full Key Vault secret name. - Enable Key Vault for Agent and Action Secrets - must be enabled and configured. -
-
- -
-
-
-
-
-
- Redis Monitoring -
-

- Monitor Redis availability, memory pressure, hit rate, evictions, and runtime cache usage before Redis-backed document list caching is enabled. -

-
-
- - -
-
-
-
-
-
-
Configuration
- Not loaded -
-
-
-
-
Health
- Not loaded -
-
-
-
-
App Cache Runtime
- Not loaded -
-
-
-
-
Session Runtime
- Not loaded -
-
-
-
-
-
-
Ping Latency
-
Not loaded
-
-
-
-
-
Memory Usage
-
Not loaded
-
Not loaded
-
-
-
-
-
Connected Clients
-
Not loaded
-
-
-
-
-
Ops/sec
-
Not loaded
-
-
-
-
-
Keyspace Hit Rate
-
Not loaded
-
-
-
-
-
Tracked Keys
-
Not loaded
-
-
-
-
-
DAI Version Markers
-
Not loaded
-
Not loaded
-
-
-
-
-
DAI Cache Payloads
-
Not loaded
-
Not loaded
-
-
-
-
-
Expired / Evicted Keys
-
- Not loaded - / - Not loaded -
-
-
-
-
-
Fragmentation Ratio
-
Not loaded
-
-
-
-
-
Error Replies
-
Not loaded
-
-
-
-
-
Rejected Connections
-
Not loaded
-
-
-
-
-
Redis Version
-
Not loaded
-
-
-
-
-
Monitoring Source
-
Not loaded
-
-
-
-
-
Last Checked
-
Not loaded
-
-
-
-
-
Last Error
-
Not loaded
-
-
-
-
-
- - - -
-
-
-
- Conversation Cache -
-

- Cache conversation list, feed, and advanced-search results per user. Redis is optional; cache misses and disabled cache paths continue using source Cosmos queries. -

-
- -
-
-
-
- - -
-
When enabled, list/feed/search payloads are cached by user and version. Disabling this bypasses cache reads and writes without requiring Redis.
-
-
- - -
Default 120 seconds. User-scoped version invalidation refreshes changed conversations; set to 0 to skip writing new entries.
-
-
-
-
-
-
Runtime Status
- Not loaded -
-
-
-
-
15m Cache Hit Rate
-
Not loaded
-
-
-
-
-
15m Cache Hits / Misses
-
Not loaded
-
-
-
-
-
15m Cache Bypasses / Errors
-
Not loaded
-
-
-
-
-
15m Writes / Invalidations
-
Not loaded
-
-
-
-
-
15m Operation Mix
-
Not loaded
-
-
-
-
-
Last Cache Event
-
Not loaded
-
-
-
-
-
Last Invalidation
-
Not loaded
-
-
-
-
- - Conversation cache metrics are lightweight in-process counters for the current app worker. Application Insights logs remain the durable fleet-wide source for cache warnings and fallback behavior. -
-
-
-
- -
-
-
-
- Cosmos Document Access Index -
-

- Monitor the document access projection used to remove expensive cross-partition document access queries. -

-
-
- - {% if enable_dai_debug %} - - - {% endif %} -
-
- -
- - Document access projection maintenance is automatic. The background scheduler repairs fail-open projection records first, then runs bounded backfill batches repeatedly while work remains. Production read metrics below show DAI-served reads, Redis cache hits, source fallbacks, RU, and latency without requiring shadow validation. - {% if enable_dai_debug %}Debug controls and shadow validation diagnostics are visible because enable_dai_debug is enabled in app settings.{% endif %} -
- -
- -
-
-
-
Container
- Not loaded -
-
-
-
-
Write-through
- Not loaded -
-
-
-
-
Read Path
- Not loaded -
-
-
-
-
Redis List Cache
- Not loaded -
-
- {% if enable_dai_debug %} -
-
-
Shadow Validation
- Not loaded -
-
- {% endif %} -
-
-
Auto Maintenance
- Not loaded -
-
-
-
-
Next Maintenance Action
-
Not loaded
-
-
-
-
-
More Work Pending
-
Not loaded
-
-
-
-
-
Active Loop Interval
-
Not loaded
-
-
-
- - {% if enable_dai_debug %} -
-
Automatic Maintenance and Diagnostics
-
-
-
- - -
-
Always on. New and changed documents synchronize into the access index and fail open to repair records if projection updates fail.
-
-
-
- - -
-
Always on. Maintenance keeps running bounded repair and backfill batches until DAI is healthy.
-
-
-
- - -
-
Compares source list results to projection rows and logs mismatches without changing reads.
-
-
- - -
Documents processed per manual or scheduled batch.
-
-
- - -
Fail-open repair records reconciled before each backfill batch.
-
-
-
- -
-
Default Read Path
-
-
-
- - -
-
Always on. DAI-backed document and tag list reads are the normal path; source-container fallback remains automatic when backfill is not ready, repairs are pending, or a DAI query fails.
-
-
-
- - -
-
Uses Redis read-through caching for DAI document, tag, and legacy-count reads. If Redis is unavailable, reads bypass cache and use DAI directly.
-
-
- - -
Default 900 seconds. Scope-version invalidation makes document changes visible immediately; TTL clears unreachable old entries.
-
-
-
- {% endif %} - -
-
-
-
Backfill State
- Not loaded -
-
-
-
-
Repair Backlog
-
Not loaded
-
-
-
-
-
15m DAI Read Attempts
-
Not loaded
-
-
-
-
-
15m Redis Cache Hit Rate
-
Not loaded
-
-
-
-
-
15m Cache Hits / Misses
-
Not loaded
-
-
-
-
-
15m Cache Bypasses / Errors
-
Not loaded
-
-
-
-
-
15m Cache Invalidations
-
Not loaded
-
-
-
-
-
15m Served from DAI
-
Not loaded
-
-
-
-
-
15m Source Fallbacks
-
Not loaded
-
-
-
-
-
15m Fallback Rate
-
Not loaded
-
-
-
-
-
15m DAI Read RU
-
Not loaded
-
-
-
-
-
15m Avg / P95 Latency
-
Not loaded
-
-
-
-
-
Last Fallback Reason
-
Not loaded
-
-
-
-
-
Last DAI Read Metric
-
Not loaded
-
-
-
-
-
Last Cache Event
-
Not loaded
-
-
-
-
- - Production read metrics are lightweight in-process counters for the current app worker. Application Insights logs remain the durable fleet-wide source for fallback warnings and query failures. -
-
- {% if enable_dai_debug %} -
-
-
Last Shadow Result
- Not run -
-
-
-
-
Shadow Mismatches
-
Not loaded
-
-
-
-
-
Source / Validation RU
-
Not loaded
-
-
-
-
-
Validation Index RU
-
Not loaded
-
-
-
-
-
Candidate Read RU
-
Not loaded
-
-
-
-
-
Estimated Wave 5 Savings
-
Not loaded
-
-
-
-
-
Source / Candidate Latency
-
Not loaded
-
-
-
-
-
Estimated Wave 5 Latency
-
Not loaded
-
-
-
-
- - Rolling decision metrics aggregate shadow-validation samples over recent windows. Use these totals to compare source container RU with candidate access-index RU before enabling the future read path or Redis document access cache. -
-
-
-
-
5m Source / Candidate RU
-
Not loaded
-
-
-
-
-
5m Estimated Wave 5 Savings
-
Not loaded
-
-
-
-
-
15m Source / Candidate RU
-
Not loaded
-
-
-
-
-
15m Estimated Wave 5 Savings
-
Not loaded
-
-
-
-
-
15m Validation Overhead
-
Not loaded
-
-
-
-
-
15m Shadow Samples
-
Not loaded
-
-
- {% endif %} -
-
-
Current Scope
-
Not loaded
-
-
-
-
-
Completed Scopes
-
Not loaded
-
-
-
-
-
Total Documents Processed
-
Not loaded
-
-
-
-
-
Total Documents Failed
-
Not loaded
-
-
-
-
-
Rows Upserted
-
Not loaded
-
-
-
-
-
Rows Deleted
-
Not loaded
-
-
-
-
-
Last Batch Completed
-
Not loaded
-
-
-
-
-
Last Error
-
Not loaded
-
-
-
-
- -
-
-
-
- Cosmos Maintenance -
-

- Review expected indexing policies and clean up stale operational cache documents without touching source configuration or user data. -

-
-
- - - - -
-
- -
- - Indexing maintenance only adds missing expected composite indexes and preserves existing policy paths. Composite indexes can increase write-index overhead while improving supported lookup and ordered-query speed. Stale cleanup is allowlisted to obsolete cache artifacts, supports dry-run review, and deletes at most one bounded batch per run. -
-
- -
-
-
-
Indexing Policy Status
- Not loaded -
-
-
-
-
Indexing Mode
-
Not loaded
-
-
-
-
-
Containers Checked
-
Not loaded
-
-
-
-
-
Missing Expected Indexes
-
Not loaded
-
-
-
-
-
Updated Containers
-
Not loaded
-
-
-
-
-
Indexing Failures
-
Not loaded
-
-
-
-
-
Last Indexing Evaluation
-
Not loaded
-
-
-
-
-
Stale Cleanup Status
- Not loaded -
-
-
-
-
Cleanup Mode
-
Not loaded
-
-
-
-
-
Cleanup Candidates
-
Not loaded
-
-
-
-
-
Deleted Docs
-
Not loaded
-
-
-
-
-
Cleanup Failures
-
Not loaded
-
-
-
-
-
More Candidates
-
Not loaded
-
-
-
-
-
Cleanup Categories
-
Not loaded
-
-
-
-
-
Last Cleanup Evaluation
-
Not loaded
-
-
-
-
- - - - - - {% if enable_dai_debug %} - - {% endif %} - -
-
-
-
- Cosmos DB Throughput -
-

- Monitor RU utilization and automatically adjust shared database or dedicated container throughput. -

-
- -
- -
- - - - - - -
- -
- - Automation checks Cosmos throughput on the Metrics Window cadence while enabled and saves the last observed database or container view. SimpleChat can scale throughput up or down at 10,000 RU/s or lower. Above 10,000 RU/s, SimpleChat monitors utilization only; use the Azure portal for capacity changes, which can take 4 to 6 hours. Native Cosmos autoscale conversion is separate from SimpleChat scale-up and scale-down automation. -
- - - -
- - - -
- -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
-
Metrics Window
-
-
- -
- - min -
-
-
-
- -
-
Scale Up Policy
-
-
-
- - -
-
-
- -
- - % -
-
-
- -
- - RU/s -
-
-
- -
- - min -
-
-
- - -
SimpleChat-managed scaling stops at 10,000 RU/s. Use the Azure portal above this limit.
-
-
-
- - -
-
-
-
- -
-
Scale Down Policy
-
-
-
- - -
-
-
- -
- - % -
-
-
- -
- - RU/s -
-
-
- -
- - min -
-
-
- - -
-
-
- - -
-
-
-
- - - -
-
- - - -
-
- - - -
-
- Use this when container throughput should follow one standard automation policy instead of per-container overrides. Global policy also applies the Cosmos autoscale conversion setting above to current and future dedicated-throughput containers. -
-
-
- -
- -
-
-
-
Mode
-
Not loaded
-
-
-
-
-
Current RU/s
-
Not loaded
-
-
-
-
-
RU Utilization
-
Not loaded
-
-
-
-
-
Last Checked
-
Not loaded
-
-
-
- -
-
- -
- - - - -
-
-
-
- -
-
- -
- - - - - - - - - - - - - - - - - -
- - Mode - - - - - - - - - - Actions
Refresh to load Cosmos metrics.
-
-
- - - - - - -
-
-
- Front Door -
- -
-

Configure Front Door URL for authentication and redirect flows.

- -
- - - -
- -
- - - - The base URL of your Front Door or load balancer. The system will automatically generate: -
    -
  • Home redirect: https://your-frontdoor.azurefd.net
  • -
  • OAuth2 redirect: https://your-frontdoor.azurefd.net/getAToken
  • -
-
-
-
-
- - -
-
-
-
-
- - -
-

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

- -
-
-
- File Sync -
- -
-

- Enable File Sync globally, set conservative run limits, and choose whether workspace managers or SimpleChat admins manage sync sources. -

- - - - {% if not settings.file_sync_redis_ready %} - - {% elif settings.requested_enable_file_sync and not settings.file_sync_effective_enabled %} - - {% endif %} - -
- - - -
- -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
-
- - -
-
-
- - -
-
-
- - {% set file_sync_visible_source_types = settings.file_sync_visible_source_types|default(['smb', 'azure_files']) %} -
-
Visible Source Types
-

- Choose which source types appear in the Add Source workflow. OneDrive, SharePoint, and Google Workspace connectors are coming soon while validation continues. -

-
-
-
- - -
Available now.
-
-
-
-
- - -
Available now.
-
-
-
-
- - -
Available now.
-
-
-
-
- - -
Coming Soon.
-
-
-
-
- - -
Coming Soon.
-
-
-
-
- - -
Coming Soon.
-
-
-
-
- - - -
-
-
-
Personal Workspace Sync
-
- - -
-
- - -
-
- - -
-
Required app role value: PersonalFileSyncUser. Assign this role to users or groups in the Enterprise App before enabling the requirement for personal sync.
-
-
- -
- - -
-
-
- - -
-
No user selected.
-
-
-
- -
-
-
Group Workspace Sync
-
- - -
-
- - -
-
- - -
-
- - No groups assigned. -
- -
-
- -
- - -
-
-
- - -
-
No group selected.
-
-
-
- -
-
-
Public Workspace Sync
-
- - -
-
- - -
-
- - -
-
- - No public workspaces assigned. -
- -
-
- -
- - -
-
-
- - -
-
No public workspace selected.
-
-
-
-
- -
- SMB source credentials are stored in Azure Key Vault when Key Vault secret storage is enabled; otherwise they use the app's existing encrypted settings path. -
-
-
- - - - - - - - -
- -
-

- 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. -

-
- - - -
-
- -
-
- Chat File Uploads -
-

- Control whether users can upload files directly into chat conversations. -

-
- - - -
- -
-
- Conversation Contents Drawer -
-

- Let users navigate long conversations from a list of their prompts. -

-
- - - -
-

- When enabled, users can turn the drawer off for their own account from Profile settings. -

-
-
- - - -
-

- Required app role value: ChatFileUploadUser. Assign this role to users or groups in the Enterprise App before enabling the requirement. Existing chat attachments remain visible; this only controls new uploads. -

-
- -
-
- 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.
- - -
-
-
- - - -
-
- Document Classification -
-

- Enable this feature to allow users to classify documents uploaded to their workspaces using predefined categories. -

-
- - - -
- - -
-
Classification Categories
-

Define the labels and corresponding colors for document classification.

- - - - - - - - - - - -
LabelColorActions
- - - -
-
- - -
-
- Retention Policy -
-

Automatically delete aged conversations and documents based on configurable retention periods. Users, group owners, and public workspace admins can set their own retention policies.

- - - - -
-
-
- - - -
-
-
-
- - - -
-
-
-
- - - -
-
-
- - -
-
Default Retention Policies
-

Set organization-wide default retention periods for each workspace type. Users can override these defaults with their own preferences. Setting a default here means new users/workspaces will start with this retention period.

- - -
-
- -
-
- - -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
-
- - -
-
-
- - Force Push: Override all user/group/workspace custom retention policies with the organization defaults above. Users will then use the organization default until they set their own preference. -
- -
-
-
- - -
- - - Retention policy will run once daily at this hour (UTC timezone). -
- - -
-
- -
- {% if settings.retention_policy_last_run %} - {{ settings.retention_policy_last_run }} - {% else %} - Never run - {% endif %} -
-
-
- -
- {% if settings.retention_policy_next_run %} - {{ settings.retention_policy_next_run }} - {% else %} - Not scheduled - {% endif %} -
-
-
- - -
- - - Trigger retention policy execution immediately for selected workspace types, bypassing the scheduled time. - -
- - -
- - -
-
- Workspace Scope Lock -
-

- Control whether users can unlock workspace scope in chat conversations. When scope is locked, conversations are restricted to the workspaces that produced search results, preventing accidental cross-contamination with other data sources. -

-
- - - -
-
- - -
-
- 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 - -
-
- - -
- - - -
- - -
- -
-
-
-
- - -
- -

- Configure standard and enhanced citations features for your and group workspaces. -

- - -
-
- Standard Citations -
-

- Standard citations is always enabled for both Your Workspace and Group Workspace. -

-

- Users can see text content of the source/citation for documents. -

-
- - -
-
- Enhanced Citations -
-

- Enable Enhanced Citation to store files in a Storage Account, - and show direct references (Preview feature, files are saved to storage, presentation - layer will be available in a future release). -

- - {% set ec_storage_status = settings.enhanced_citations_storage_status or {} %} - {% set ec_storage_state = ec_storage_status.state or 'not_initialized' %} - {% if settings.enable_enhanced_citations %} -
-
Enhanced Citations storage startup status
-
{{ ec_storage_status.message or 'Enhanced Citations storage status is not available for this process.' }}
-
- Startup skips live storage container checks so storage outages do not block application boot. - Use the connection test to validate current storage reachability and container access. -
- -
-
- {% endif %} - - -
- - - -
- - - -
-
- - -
- -

- Configure content safety, archiving, and user feedback settings. If Content Safety is enabled, user - messages will be sent to the safety endpoint for analysis. If User Feedback is enabled, users will see - thumbs up/down to provide feedback on AI responses. -

-
-
- Content Safety -
-

Enable content safety to filter out inappropriate content.

-
- - - -
- - -
- - -
- - - -
- - -
-
- - -
-
- - -
-
- -
- - -
-
-
- - -
-
- - -
-
- -
- - -
-
-
- - -
- - -
Displayed when Content Safety blocks a chat message.
-
- -
- - - -
-

Disable this option to show only the configured message.

- - -
-
-
- - -
-
- User Feedback -
-

Enable user feedback (thumbs up/down) for AI responses.

-
- - - -
-
- -
-
- Desktop Conversation Notifications -
-

- Allow users to receive an operating system notification when an AI response finishes while SimpleChat is open in a hidden or unfocused browser tab. -

-
- - -
-

- Users can turn notifications off from Profile. Browser permission is required, and notifications stop when the SimpleChat tab is closed. -

-
- - -
-
- 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. -

-
- - - -
-
- Conversation Archiving -
-

When enabled, conversation deletions will be archived instead of permanently deleted.

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

- 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
-
+ + + + + + {% endif %} -
- - -
The name of your Video Indexer account resource
-
+
+ {% include "admin/_panes/security.html" %} -
- - -
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
-
+ {% include "admin/_panes/agents.html" %} -
- - -
Default for {{ azure_environment_label }}: {{ default_video_indexer_arm_api_version }}
-
-
- - -
-
-
+ + {% include "admin/_panes/governance.html" %} - -
-
-
-
- -
-
-

- AI Voice Conversations -

-

Transform your AI experience with natural voice interactions

-
-
- -
+ + {% include "admin/_panes/logging.html" %} - -
-
- - -
-

- 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. -

-
+ {% include "admin/_panes/general.html" %} -
- - 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. -
+ {% include "admin/_panes/custom-pages.html" %} - -
- {% 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 - -
-
+ {% include "admin/_panes/ai-models.html" %} - -
-
- - -
-

- 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 - -
-
+ + {% include "admin/_panes/control-center-config.html" %} - -
-
- Azure Speech Service Configuration -
-

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

+ {% include "admin/_panes/data-management.html" %} -
- 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. -
+ {% include "admin/_panes/scale.html" %} -
- - -
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.
-
+ {% include "admin/_panes/workspace-identities.html" %} -
-
- 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.
-
-
- -
-
+ {% include "admin/_panes/file-sync.html" %} -
Provide Subscription ID, Resource Group, and Speech Resource Name to auto-build the ARM resource ID.
+ {% include "admin/_panes/workspaces.html" %} - - -
Required for Voice Responses when using Managed Identity. You can paste the full value manually, or let the fields above build it for you.
-
-
- - -
+ {% include "admin/_panes/citation.html" %} -
- - -
-
- -
- - -
-
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. -
+ {% include "admin/_panes/safety.html" %} -
-

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

-
-
-
-

- 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. -

- + {% include "admin/_panes/search-extract.html" %} -
-
-
-
- Report a Bug -
-

Something isn’t working as expected.

-
-
- - -
-
- - -
-
- - -
-
- - -
- - -
-
-
+ {% include "admin/_panes/send-feedback.html" %} -
-
-
- Request a Feature -
-

Suggest an improvement or new capability.

-
-
- - -
-
- - -
-
- - -
-
- - -
- - -
-
-
-
-
+ {# Latest Features stays last so it never opens by default #} + {% include "admin/_panes/latest-features.html" %}
@@ -13403,8 +1614,13 @@
{% endblock %} + +{% block scripts %} + -{% block scripts %} - ' in admin_settings_template assert 'id="content_safety_violation_message"' in admin_settings_template diff --git a/functional_tests/test_content_understanding_extraction_engine.py b/functional_tests/test_content_understanding_extraction_engine.py index 28246e0a..3b6b5c70 100644 --- a/functional_tests/test_content_understanding_extraction_engine.py +++ b/functional_tests/test_content_understanding_extraction_engine.py @@ -22,6 +22,7 @@ sys.path.insert(0, str(Path(__file__).resolve().parent)) from test_support.versioning import assert_app_version_at_least # noqa: E402 +from test_support.templates import compose_if_admin_settings def load_content_understanding_module(azure_environment="public"): @@ -305,7 +306,10 @@ def test_government_cloud_blocks_content_understanding(): def read_repo_file(relative_path): """Read a repository file as UTF-8 text.""" - return (REPO_ROOT / relative_path).read_text(encoding="utf-8") + _path = REPO_ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def assert_contains(content, expected_text, description): diff --git a/functional_tests/test_control_center_auto_refresh_schedule.py b/functional_tests/test_control_center_auto_refresh_schedule.py index bbe47b5d..c4497c60 100644 --- a/functional_tests/test_control_center_auto_refresh_schedule.py +++ b/functional_tests/test_control_center_auto_refresh_schedule.py @@ -17,6 +17,8 @@ from datetime import datetime, timezone from pathlib import Path +from test_support.templates import read_admin_settings_template + ROOT_DIR = Path(__file__).resolve().parents[1] APP_DIR = ROOT_DIR / "application" / "single_app" @@ -165,7 +167,7 @@ def test_integration_wiring(): background_source = BACKGROUND_TASKS_FILE.read_text(encoding="utf-8") admin_route_source = ADMIN_SETTINGS_ROUTE_FILE.read_text(encoding="utf-8") control_center_route_source = CONTROL_CENTER_ROUTE_FILE.read_text(encoding="utf-8") - template_source = ADMIN_TEMPLATE_FILE.read_text(encoding="utf-8") + template_source = read_admin_settings_template() javascript_source = CONTROL_CENTER_JS_FILE.read_text(encoding="utf-8") expected_settings = [ diff --git a/functional_tests/test_conversation_contents_drawer_settings.py b/functional_tests/test_conversation_contents_drawer_settings.py index 200b00b8..70be7c0f 100644 --- a/functional_tests/test_conversation_contents_drawer_settings.py +++ b/functional_tests/test_conversation_contents_drawer_settings.py @@ -13,6 +13,7 @@ from pathlib import Path from flask import Flask, jsonify, request +from test_support.templates import compose_if_admin_settings REPO_ROOT = Path(__file__).resolve().parents[1] @@ -27,7 +28,10 @@ def _read(relative_path): - return (REPO_ROOT / relative_path).read_text(encoding="utf-8") + _path = REPO_ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def test_admin_setting_defaults_on_and_persists(): diff --git a/functional_tests/test_cosmos_wave4a1_admin_document_access_ui.py b/functional_tests/test_cosmos_wave4a1_admin_document_access_ui.py index 588107e6..fb8a5e6a 100644 --- a/functional_tests/test_cosmos_wave4a1_admin_document_access_ui.py +++ b/functional_tests/test_cosmos_wave4a1_admin_document_access_ui.py @@ -20,6 +20,7 @@ import os import sys from test_support.versioning import assert_app_version_at_least +from test_support.templates import compose_if_admin_settings ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -27,8 +28,9 @@ def _read(relative_path): - with open(os.path.join(ROOT_DIR, relative_path), "r", encoding="utf-8") as file: - return file.read() + _path = os.path.join(ROOT_DIR, relative_path) + with open(_path, "r", encoding="utf-8") as file: + return compose_if_admin_settings(_path, file.read()) def test_admin_template_exposes_safe_document_access_controls(): diff --git a/functional_tests/test_cosmos_wave4b_document_access_shadow_validation.py b/functional_tests/test_cosmos_wave4b_document_access_shadow_validation.py index 817d17db..303cbae3 100644 --- a/functional_tests/test_cosmos_wave4b_document_access_shadow_validation.py +++ b/functional_tests/test_cosmos_wave4b_document_access_shadow_validation.py @@ -28,6 +28,7 @@ from contextlib import contextmanager from datetime import datetime, timezone from test_support.versioning import assert_app_version_at_least +from test_support.templates import read_admin_settings_template ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -673,11 +674,7 @@ def test_wave4b_admin_routes_and_version_are_wired(): "r", encoding="utf-8", ).read() - admin_template = open( - os.path.join(SINGLE_APP_DIR, "templates", "admin_settings.html"), - "r", - encoding="utf-8", - ).read() + admin_template = read_admin_settings_template() personal_route = open(os.path.join(SINGLE_APP_DIR, "route_backend_documents.py"), "r", encoding="utf-8").read() group_route = open(os.path.join(SINGLE_APP_DIR, "route_backend_group_documents.py"), "r", encoding="utf-8").read() public_route = open(os.path.join(SINGLE_APP_DIR, "route_external_public_documents.py"), "r", encoding="utf-8").read() diff --git a/functional_tests/test_cosmos_wave5a_document_access_read_switch.py b/functional_tests/test_cosmos_wave5a_document_access_read_switch.py index badcfafc..a0eb1acd 100644 --- a/functional_tests/test_cosmos_wave5a_document_access_read_switch.py +++ b/functional_tests/test_cosmos_wave5a_document_access_read_switch.py @@ -24,6 +24,7 @@ import types from contextlib import contextmanager from test_support.versioning import assert_app_version_at_least +from test_support.templates import read_admin_settings_template ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -799,11 +800,7 @@ def test_wave5b_route_and_admin_contract_are_wired(): "r", encoding="utf-8", ).read() - admin_template = open( - os.path.join(SINGLE_APP_DIR, "templates", "admin_settings.html"), - "r", - encoding="utf-8", - ).read() + admin_template = read_admin_settings_template() admin_route = open( os.path.join(SINGLE_APP_DIR, "route_frontend_admin_settings.py"), "r", diff --git a/functional_tests/test_custom_pages_wiring.py b/functional_tests/test_custom_pages_wiring.py index 702be5e9..d44ac9fc 100644 --- a/functional_tests/test_custom_pages_wiring.py +++ b/functional_tests/test_custom_pages_wiring.py @@ -12,6 +12,7 @@ from pathlib import Path import sys +from test_support.templates import compose_if_admin_settings REPO_ROOT = Path(__file__).resolve().parents[1] @@ -20,7 +21,10 @@ def read_text(relative_path): """Read a repository file as UTF-8 text.""" - return (REPO_ROOT / relative_path).read_text(encoding="utf-8") + _path = REPO_ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def assert_contains(content, expected, description): diff --git a/functional_tests/test_data_management_history_pagination.py b/functional_tests/test_data_management_history_pagination.py index 9233477e..7fe62697 100644 --- a/functional_tests/test_data_management_history_pagination.py +++ b/functional_tests/test_data_management_history_pagination.py @@ -35,6 +35,7 @@ sys.path.insert(0, str(Path(__file__).resolve().parent)) from test_support.versioning import compare_simplechat_versions +from test_support.templates import read_admin_settings_template class FakeHistoryContainer: @@ -823,9 +824,7 @@ def test_deployers_apply_the_data_management_history_index(): def test_retention_cleanup_button_explains_what_it_does(): """Give admins hover and expandable guidance before deleting expired backups.""" - template = ( - APP_ROOT / "templates" / "admin_settings.html" - ).read_text(encoding="utf-8") + template = read_admin_settings_template() cleanup_button_start = template.index("data-management-run-retention-cleanup-btn") cleanup_button = template[cleanup_button_start:cleanup_button_start + 600] diff --git a/functional_tests/test_data_management_security_patterns.py b/functional_tests/test_data_management_security_patterns.py index 9df41f80..682d8aa9 100644 --- a/functional_tests/test_data_management_security_patterns.py +++ b/functional_tests/test_data_management_security_patterns.py @@ -34,6 +34,7 @@ import re from pathlib import Path from test_support.versioning import assert_app_version_at_least +from test_support.templates import compose_if_admin_settings REPO_ROOT = Path(__file__).resolve().parents[1] @@ -50,7 +51,9 @@ def read_text(path): - return path.read_text(encoding="utf-8") + return compose_if_admin_settings( + path, path.read_text(encoding="utf-8") + ) def route_functions_with_decorators(): diff --git a/functional_tests/test_deep_research_explicit_toggle.py b/functional_tests/test_deep_research_explicit_toggle.py index 9476e424..d88dedbc 100644 --- a/functional_tests/test_deep_research_explicit_toggle.py +++ b/functional_tests/test_deep_research_explicit_toggle.py @@ -22,12 +22,13 @@ sys.path.insert(0, APP_ROOT) from functions_source_review import get_source_review_config, should_auto_enable_source_review # noqa: E402 +from test_support.templates import compose_if_admin_settings def read_text(path): """Read text content for static regression checks.""" with open(path, "r", encoding="utf-8") as file_handle: - return file_handle.read() + return compose_if_admin_settings(path, file_handle.read()) def test_web_search_does_not_auto_enable_deep_research(): diff --git a/functional_tests/test_default_model_selection_fallback.py b/functional_tests/test_default_model_selection_fallback.py index 76ec9400..9faa7a0f 100644 --- a/functional_tests/test_default_model_selection_fallback.py +++ b/functional_tests/test_default_model_selection_fallback.py @@ -12,11 +12,12 @@ """ import os +from test_support.templates import compose_if_admin_settings def read_file_text(file_path): with open(file_path, "r", encoding="utf-8") as file: - return file.read() + return compose_if_admin_settings(file_path, file.read()) def test_default_model_selection_wiring(): diff --git a/functional_tests/test_desktop_notification_settings.py b/functional_tests/test_desktop_notification_settings.py index df21c937..0b208567 100644 --- a/functional_tests/test_desktop_notification_settings.py +++ b/functional_tests/test_desktop_notification_settings.py @@ -9,13 +9,17 @@ """ from pathlib import Path +from test_support.templates import compose_if_admin_settings REPO_ROOT = Path(__file__).resolve().parents[1] def _read(relative_path): - return (REPO_ROOT / relative_path).read_text(encoding="utf-8") + _path = REPO_ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def test_desktop_notification_settings_are_wired_end_to_end(): diff --git a/functional_tests/test_disable_group_creation_fix.py b/functional_tests/test_disable_group_creation_fix.py index 4faffe70..451a8eb2 100644 --- a/functional_tests/test_disable_group_creation_fix.py +++ b/functional_tests/test_disable_group_creation_fix.py @@ -20,6 +20,7 @@ import sys import os +from test_support.templates import compose_if_admin_settings # Add parent directory to path for imports sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) @@ -37,7 +38,7 @@ def test_form_field_name_matches_backend(): ) with open(template_path, 'r', encoding='utf-8') as f: - template_content = f.read() + template_content = compose_if_admin_settings(template_path, f.read()) # Verify the form field exists with name="disable_group_creation" assert 'name="disable_group_creation"' in template_content, \ @@ -88,7 +89,7 @@ def test_control_center_toggle_exists(): ) with open(template_path, 'r', encoding='utf-8') as f: - template_content = f.read() + template_content = compose_if_admin_settings(template_path, f.read()) # Verify the toggle exists assert 'id="disableGroupCreation"' in template_content, \ diff --git a/functional_tests/test_document_action_capability_settings.py b/functional_tests/test_document_action_capability_settings.py index 8ff9114f..d8ba9e6d 100644 --- a/functional_tests/test_document_action_capability_settings.py +++ b/functional_tests/test_document_action_capability_settings.py @@ -12,13 +12,17 @@ from pathlib import Path from test_support.versioning import assert_app_version_at_least +from test_support.templates import compose_if_admin_settings ROOT = Path(__file__).resolve().parents[1] def read_text(relative_path: str) -> str: - return (ROOT / relative_path).read_text(encoding="utf-8") + _path = ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def test_document_action_capability_settings_wiring() -> None: diff --git a/functional_tests/test_document_intelligence_pdf_image_extraction_mode.py b/functional_tests/test_document_intelligence_pdf_image_extraction_mode.py index 155f66c2..abfe5ad6 100644 --- a/functional_tests/test_document_intelligence_pdf_image_extraction_mode.py +++ b/functional_tests/test_document_intelligence_pdf_image_extraction_mode.py @@ -16,6 +16,7 @@ import sys from pathlib import Path +from test_support.templates import compose_if_admin_settings REPO_ROOT = Path(__file__).resolve().parents[1] @@ -23,7 +24,10 @@ def read_repo_file(relative_path): """Read a repository file as UTF-8 text.""" - return (REPO_ROOT / relative_path).read_text(encoding="utf-8") + _path = REPO_ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def assert_contains(content, expected_text, description): diff --git a/functional_tests/test_endpoints_tab_order_visibility.py b/functional_tests/test_endpoints_tab_order_visibility.py index 90eed425..aa653af6 100644 --- a/functional_tests/test_endpoints_tab_order_visibility.py +++ b/functional_tests/test_endpoints_tab_order_visibility.py @@ -19,6 +19,7 @@ """ import os +from test_support.templates import compose_if_admin_settings REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) @@ -30,7 +31,7 @@ def read_file_text(file_path): with open(file_path, "r", encoding="utf-8") as file: - return file.read() + return compose_if_admin_settings(file_path, file.read()) def test_workspace_endpoints_tab_order_visibility(): diff --git a/functional_tests/test_enhanced_citations_startup_storage_degradation.py b/functional_tests/test_enhanced_citations_startup_storage_degradation.py index 21b585b8..29d6dff5 100644 --- a/functional_tests/test_enhanced_citations_startup_storage_degradation.py +++ b/functional_tests/test_enhanced_citations_startup_storage_degradation.py @@ -14,6 +14,7 @@ from pathlib import Path from test_support.versioning import assert_app_version_at_least +from test_support.templates import compose_if_admin_settings REPO_ROOT = Path(__file__).resolve().parents[1] @@ -27,7 +28,9 @@ def read_text(path): """Read a repository file as UTF-8 text.""" - return path.read_text(encoding="utf-8") + return compose_if_admin_settings( + path, path.read_text(encoding="utf-8") + ) def get_function_source(path, function_name): diff --git a/functional_tests/test_external_health_check_duplication_fix.py b/functional_tests/test_external_health_check_duplication_fix.py index fabfe15e..aa750b41 100644 --- a/functional_tests/test_external_health_check_duplication_fix.py +++ b/functional_tests/test_external_health_check_duplication_fix.py @@ -11,6 +11,7 @@ import sys import os import re +from test_support.templates import compose_if_admin_settings def test_external_health_check_duplication(): """Test that there is only one External Health Check section in admin settings.""" @@ -27,7 +28,7 @@ def test_external_health_check_duplication(): raise FileNotFoundError(f"Template file not found: {template_path}") with open(template_path, 'r', encoding='utf-8') as f: - content = f.read() + content = compose_if_admin_settings(template_path, f.read()) # Count occurrences of "External Health Check" headers header_pattern = r'
External Health Check
' @@ -81,7 +82,7 @@ def test_ui_structure_integrity(): ) with open(template_path, 'r', encoding='utf-8') as f: - content = f.read() + content = compose_if_admin_settings(template_path, f.read()) # Check for proper card structure card_open_count = len(re.findall(r'
', content)) diff --git a/functional_tests/test_file_sync_azure_blob_storage.py b/functional_tests/test_file_sync_azure_blob_storage.py index 45255d43..67ffd15b 100644 --- a/functional_tests/test_file_sync_azure_blob_storage.py +++ b/functional_tests/test_file_sync_azure_blob_storage.py @@ -27,6 +27,7 @@ from typing import Any, Dict, List, Optional, Tuple from urllib.parse import parse_qsl, quote, unquote, urlparse from test_support.versioning import assert_app_version_at_least +from test_support.templates import compose_if_admin_settings REPO_ROOT = Path(__file__).resolve().parents[1] @@ -34,7 +35,10 @@ def read_text(relative_path): """Read a repository file as UTF-8 text.""" - return (REPO_ROOT / relative_path).read_text(encoding="utf-8") + _path = REPO_ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def parse_app(relative_path): diff --git a/functional_tests/test_file_sync_azure_files_identity.py b/functional_tests/test_file_sync_azure_files_identity.py index e3af89e9..b7fbc739 100644 --- a/functional_tests/test_file_sync_azure_files_identity.py +++ b/functional_tests/test_file_sync_azure_files_identity.py @@ -19,6 +19,7 @@ import sys from pathlib import Path from test_support.versioning import assert_app_version_at_least +from test_support.templates import compose_if_admin_settings REPO_ROOT = Path(__file__).resolve().parents[1] @@ -27,7 +28,10 @@ def read_text(relative_path): """Read a repository file as UTF-8 text.""" - return (REPO_ROOT / relative_path).read_text(encoding="utf-8") + _path = REPO_ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def parse_app(relative_path): diff --git a/functional_tests/test_file_sync_capability.py b/functional_tests/test_file_sync_capability.py index fc3fd132..86644fd9 100644 --- a/functional_tests/test_file_sync_capability.py +++ b/functional_tests/test_file_sync_capability.py @@ -15,6 +15,7 @@ import sys from pathlib import Path from test_support.versioning import assert_app_version_at_least +from test_support.templates import compose_if_admin_settings REPO_ROOT = Path(__file__).resolve().parents[1] @@ -22,7 +23,10 @@ def read_text(relative_path): - return (REPO_ROOT / relative_path).read_text(encoding="utf-8") + _path = REPO_ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def test_config_version_and_containers(): diff --git a/functional_tests/test_file_sync_onedrive_personal.py b/functional_tests/test_file_sync_onedrive_personal.py index bdf0a8f9..828ceecc 100644 --- a/functional_tests/test_file_sync_onedrive_personal.py +++ b/functional_tests/test_file_sync_onedrive_personal.py @@ -19,6 +19,7 @@ import sys from pathlib import Path from test_support.versioning import assert_app_version_at_least +from test_support.templates import compose_if_admin_settings REPO_ROOT = Path(__file__).resolve().parents[1] @@ -26,7 +27,10 @@ def read_text(relative_path): """Read a repository file as UTF-8 text.""" - return (REPO_ROOT / relative_path).read_text(encoding="utf-8") + _path = REPO_ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def parse_app(relative_path): diff --git a/functional_tests/test_file_sync_workspace_assignment_gates.py b/functional_tests/test_file_sync_workspace_assignment_gates.py index 431f439b..b5bb09f9 100644 --- a/functional_tests/test_file_sync_workspace_assignment_gates.py +++ b/functional_tests/test_file_sync_workspace_assignment_gates.py @@ -13,6 +13,7 @@ import ast import sys from pathlib import Path +from test_support.templates import compose_if_admin_settings REPO_ROOT = Path(__file__).resolve().parents[1] @@ -21,7 +22,10 @@ def read_text(relative_path): """Read a repository file as UTF-8 text.""" - return (REPO_ROOT / relative_path).read_text(encoding="utf-8") + _path = REPO_ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def get_function_source(relative_path, function_name): diff --git a/functional_tests/test_governance_admin_scope_toggle_visibility.py b/functional_tests/test_governance_admin_scope_toggle_visibility.py index 9e154743..d0647a52 100644 --- a/functional_tests/test_governance_admin_scope_toggle_visibility.py +++ b/functional_tests/test_governance_admin_scope_toggle_visibility.py @@ -11,6 +11,7 @@ import os import sys +from test_support.templates import compose_if_admin_settings ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -19,7 +20,7 @@ def _read(*parts): path = os.path.join(ROOT_DIR, *parts) with open(path, "r", encoding="utf-8") as handle: - return handle.read() + return compose_if_admin_settings(path, handle.read()) GOVERNANCE_SCOPE_CONTROLS = { diff --git a/functional_tests/test_governance_enforcement_logic.py b/functional_tests/test_governance_enforcement_logic.py index 8f7c8868..0b826e49 100644 --- a/functional_tests/test_governance_enforcement_logic.py +++ b/functional_tests/test_governance_enforcement_logic.py @@ -53,6 +53,7 @@ def delete_item(self, item, partition_key): sys.modules.setdefault("functions_public_workspaces", functions_public_workspaces_stub) import functions_governance as governance +from test_support.templates import compose_if_admin_settings ROOT_DIR = os.path.dirname(CURRENT_DIR) @@ -61,7 +62,7 @@ def delete_item(self, item, partition_key): def _read_repo_file(*parts): path = os.path.join(ROOT_DIR, *parts) with open(path, "r", encoding="utf-8") as handle: - return handle.read() + return compose_if_admin_settings(path, handle.read()) def test_ensure_governance_access_allows_when_feature_toggle_disabled(): diff --git a/functional_tests/test_governance_route_and_wiring_coverage.py b/functional_tests/test_governance_route_and_wiring_coverage.py index c784ba46..a10b08ac 100644 --- a/functional_tests/test_governance_route_and_wiring_coverage.py +++ b/functional_tests/test_governance_route_and_wiring_coverage.py @@ -12,6 +12,7 @@ import os import sys +from test_support.templates import compose_if_admin_settings ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -23,7 +24,7 @@ def _read(*parts): path = os.path.join(ROOT_DIR, *parts) with open(path, "r", encoding="utf-8") as handle: - return handle.read() + return compose_if_admin_settings(path, handle.read()) def test_governance_route_registration_and_guards(): diff --git a/functional_tests/test_idle_logout_timeout.py b/functional_tests/test_idle_logout_timeout.py index 4dda5e7f..10d388ba 100644 --- a/functional_tests/test_idle_logout_timeout.py +++ b/functional_tests/test_idle_logout_timeout.py @@ -14,6 +14,8 @@ import ast import traceback +from test_support.templates import compose_if_admin_settings + sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -24,7 +26,7 @@ def _read_file(*path_parts): *path_parts ) with open(file_path, 'r', encoding='utf-8') as file_handle: - return file_handle.read() + return compose_if_admin_settings(file_path, file_handle.read()) def _parse_python_file(*path_parts): diff --git a/functional_tests/test_inbound_mcp_admin_ui.py b/functional_tests/test_inbound_mcp_admin_ui.py index 6f7bfaaa..2717e575 100644 --- a/functional_tests/test_inbound_mcp_admin_ui.py +++ b/functional_tests/test_inbound_mcp_admin_ui.py @@ -39,6 +39,7 @@ import sys from pathlib import Path from test_support.versioning import assert_app_version_at_least +from test_support.templates import compose_if_admin_settings ROOT_DIR = Path(__file__).resolve().parents[1] @@ -46,7 +47,10 @@ def read_repo_file(relative_path): """Read a repository file for source-level contract validation.""" - return (ROOT_DIR / relative_path).read_text(encoding="utf-8") + _path = ROOT_DIR / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def test_inbound_mcp_runtime_settings_are_app_settings(): diff --git a/functional_tests/test_latest_features_action_links.py b/functional_tests/test_latest_features_action_links.py index 3019b157..0e8807a6 100644 --- a/functional_tests/test_latest_features_action_links.py +++ b/functional_tests/test_latest_features_action_links.py @@ -13,6 +13,7 @@ from pathlib import Path import sys from test_support.versioning import assert_app_version_at_least +from test_support.templates import compose_if_admin_settings REPO_ROOT = Path(__file__).resolve().parents[1] @@ -29,7 +30,9 @@ def read_text(path: Path) -> str: - return path.read_text(encoding="utf-8") + return compose_if_admin_settings( + path, path.read_text(encoding="utf-8") + ) def assert_markers(file_path: Path, markers: list[str]) -> None: diff --git a/functional_tests/test_multimedia_support_reorganization.py b/functional_tests/test_multimedia_support_reorganization.py index 68bda79e..93e96dc0 100644 --- a/functional_tests/test_multimedia_support_reorganization.py +++ b/functional_tests/test_multimedia_support_reorganization.py @@ -15,6 +15,8 @@ import os import sys +from test_support.templates import compose_if_admin_settings + sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -29,8 +31,9 @@ def test_multimedia_support_move(): ) with open(admin_settings_path, 'r', encoding='utf-8') as file_handle: - content = file_handle.read() - + content = compose_if_admin_settings( + admin_settings_path, file_handle.read() + ) search_extract_section = content.find('id="search-extract" role="tabpanel"') multimedia_support_section = content.find('id="video-intelligence-section"') diff --git a/functional_tests/test_multimodal_vision_multi_endpoint_connection.py b/functional_tests/test_multimodal_vision_multi_endpoint_connection.py index 526599f7..58b2294d 100644 --- a/functional_tests/test_multimodal_vision_multi_endpoint_connection.py +++ b/functional_tests/test_multimodal_vision_multi_endpoint_connection.py @@ -13,6 +13,8 @@ import sys from pathlib import Path +from test_support.templates import read_admin_settings_template + REPO_ROOT = Path(__file__).resolve().parents[1] ADMIN_SETTINGS_JS = REPO_ROOT / "application" / "single_app" / "static" / "js" / "admin" / "admin_settings.js" @@ -31,7 +33,7 @@ def test_multimodal_vision_multi_endpoint_wiring(): print("Testing multi-endpoint Vision test connection wiring...") js_content = ADMIN_SETTINGS_JS.read_text(encoding="utf-8") - template_content = ADMIN_SETTINGS_TEMPLATE.read_text(encoding="utf-8") + template_content = read_admin_settings_template() backend_content = ROUTE_BACKEND_SETTINGS.read_text(encoding="utf-8") assert_contains(js_content, "opt.dataset.endpointId = ep.id || '';", "vision endpoint id option metadata") diff --git a/functional_tests/test_personal_workflows_feature.py b/functional_tests/test_personal_workflows_feature.py index 43044feb..e722495b 100644 --- a/functional_tests/test_personal_workflows_feature.py +++ b/functional_tests/test_personal_workflows_feature.py @@ -10,13 +10,17 @@ from pathlib import Path from test_support.versioning import assert_app_version_at_least +from test_support.templates import compose_if_admin_settings ROOT = Path(__file__).resolve().parents[1] def read_text(relative_path): - return (ROOT / relative_path).read_text(encoding="utf-8") + _path = ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def test_personal_workflows_feature_wiring(): diff --git a/functional_tests/test_public_workspace_display_name_settings.py b/functional_tests/test_public_workspace_display_name_settings.py index e36ef529..f8fc4682 100644 --- a/functional_tests/test_public_workspace_display_name_settings.py +++ b/functional_tests/test_public_workspace_display_name_settings.py @@ -16,6 +16,7 @@ from types import SimpleNamespace from jinja2 import Environment +from test_support.templates import compose_if_admin_settings sys.path.append(os.path.dirname(os.path.abspath(__file__))) @@ -29,7 +30,7 @@ def read_source(path): with open(path, "r", encoding="utf-8") as source_file: - return source_file.read() + return compose_if_admin_settings(path, source_file.read()) def assert_contains(source, needle, description): diff --git a/functional_tests/test_support/templates.py b/functional_tests/test_support/templates.py new file mode 100644 index 00000000..3b88eea8 --- /dev/null +++ b/functional_tests/test_support/templates.py @@ -0,0 +1,96 @@ +# templates.py +"""Shared helpers for reading composed SimpleChat templates in functional tests. + +Admin Settings is assembled from per-tab partials under +``templates/admin/``. Any test that asserts on the rendered structure has to +read the fully composed markup instead of the parent template alone, so these +helpers inline ``{% include %}`` directives before the markup is parsed. +""" + +import re +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[2] +TEMPLATE_DIR = REPO_ROOT / "application" / "single_app" / "templates" +ADMIN_SETTINGS_TEMPLATE = TEMPLATE_DIR / "admin_settings.html" + +INCLUDE_PATTERN = re.compile( + r'^(?P[ \t]*)\{%-?\s*include\s+["\'](?P[^"\']+)["\'].*?%\}', + flags=re.MULTILINE, +) + +# Only the Admin Settings tab partials are inlined by default. Unrelated +# includes (info modals and shared widgets) carry their own tab markup, and +# pulling them in would silently widen assertions that are meant to describe +# the Admin Settings panes alone. +DEFAULT_INCLUDE_PREFIX = "admin/" + + +def resolve_template_includes( + source, + template_dir=None, + include_prefix=DEFAULT_INCLUDE_PREFIX, + _seen=None, +): + """Return ``source`` with resolvable ``{% include %}`` directives inlined. + + Only includes whose target starts with ``include_prefix`` are expanded; + pass ``include_prefix=""`` to inline every resolvable include. Includes + that cannot be found on disk, and includes that would recurse into a + template already being expanded, are left untouched so the original markup + is still visible to the caller. + """ + directory = Path(template_dir) if template_dir else TEMPLATE_DIR + seen = set() if _seen is None else _seen + + def _replace(match): + target = match.group("target") + partial = directory / target + if include_prefix and not target.startswith(include_prefix): + return match.group(0) + if target in seen or not partial.is_file(): + return match.group(0) + + nested = resolve_template_includes( + partial.read_text(encoding="utf-8"), + directory, + include_prefix, + seen | {target}, + ) + indent = match.group("indent") + return "\n".join( + f"{indent}{line}" if line.strip() else line + for line in nested.split("\n") + ) + + return INCLUDE_PATTERN.sub(_replace, source) + + +def read_composed_template(path, template_dir=None, include_prefix=DEFAULT_INCLUDE_PREFIX): + """Read a template file with its Admin Settings includes inlined.""" + template_path = Path(path) + directory = Path(template_dir) if template_dir else template_path.parent + return resolve_template_includes( + template_path.read_text(encoding="utf-8"), + directory, + include_prefix, + ) + + +def compose_if_admin_settings(path, content): + """Inline Admin Settings partials when ``path`` is the admin template. + + Functional tests read many repository files through a single helper. Only + admin_settings.html is composed from partials, so this leaves every other + file untouched and keeps those tests reading exactly what is on disk. + """ + template_path = Path(path) + if template_path.name != "admin_settings.html": + return content + return resolve_template_includes(content, template_path.parent) + + +def read_admin_settings_template(): + """Read the fully composed Admin Settings template.""" + return read_composed_template(ADMIN_SETTINGS_TEMPLATE, TEMPLATE_DIR) diff --git a/functional_tests/test_support_menu_user_feature.py b/functional_tests/test_support_menu_user_feature.py index 0ea36578..236a26d0 100644 --- a/functional_tests/test_support_menu_user_feature.py +++ b/functional_tests/test_support_menu_user_feature.py @@ -15,6 +15,7 @@ import os import sys import importlib.util +from test_support.templates import compose_if_admin_settings CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -39,8 +40,8 @@ def read_text(path): - with open(path, 'r', encoding='utf-8') as file_handle: - return file_handle.read() + with open(path, "r", encoding="utf-8") as file_handle: + return compose_if_admin_settings(path, file_handle.read()) def load_module(path, module_name): diff --git a/functional_tests/test_tabular_processing_enhanced_citations_dependency.py b/functional_tests/test_tabular_processing_enhanced_citations_dependency.py index 7762d856..7a94e262 100644 --- a/functional_tests/test_tabular_processing_enhanced_citations_dependency.py +++ b/functional_tests/test_tabular_processing_enhanced_citations_dependency.py @@ -11,6 +11,7 @@ """ import os +from test_support.templates import compose_if_admin_settings CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -27,8 +28,8 @@ def read_text(path): - with open(path, 'r', encoding='utf-8') as file_handle: - return file_handle.read() + with open(path, "r", encoding="utf-8") as file_handle: + return compose_if_admin_settings(path, file_handle.read()) def test_functions_settings_derives_tabular_enablement(): diff --git a/functional_tests/test_thoughts_feature.py b/functional_tests/test_thoughts_feature.py index cc295159..aea6c11a 100644 --- a/functional_tests/test_thoughts_feature.py +++ b/functional_tests/test_thoughts_feature.py @@ -11,6 +11,7 @@ import sys import os +from test_support.templates import compose_if_admin_settings sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'application', 'single_app')) @@ -289,7 +290,7 @@ def test_thoughts_admin_settings(): ) with open(html_file, 'r', encoding='utf-8') as f: - content = f.read() + content = compose_if_admin_settings(html_file, f.read()) checks = { 'enable_thoughts checkbox': 'id="enable_thoughts"' in content, diff --git a/functional_tests/test_workflow_access_controls.py b/functional_tests/test_workflow_access_controls.py index 562ee7b2..544e858d 100644 --- a/functional_tests/test_workflow_access_controls.py +++ b/functional_tests/test_workflow_access_controls.py @@ -12,13 +12,17 @@ import json from pathlib import Path from test_support.versioning import assert_app_version_at_least +from test_support.templates import compose_if_admin_settings ROOT = Path(__file__).resolve().parents[1] def read_text(relative_path): - return (ROOT / relative_path).read_text(encoding="utf-8") + _path = ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def test_workflow_access_control_wiring(): diff --git a/functional_tests/test_workflow_auto_invoke_attempt_settings.py b/functional_tests/test_workflow_auto_invoke_attempt_settings.py index 0f3d80b1..23365d58 100644 --- a/functional_tests/test_workflow_auto_invoke_attempt_settings.py +++ b/functional_tests/test_workflow_auto_invoke_attempt_settings.py @@ -13,13 +13,17 @@ from pathlib import Path from test_support.versioning import assert_app_version_at_least +from test_support.templates import compose_if_admin_settings ROOT = Path(__file__).resolve().parents[1] def read_text(relative_path: str) -> str: - return (ROOT / relative_path).read_text(encoding="utf-8") + _path = ROOT / relative_path + return compose_if_admin_settings( + _path, _path.read_text(encoding="utf-8") + ) def test_workflow_auto_invoke_attempt_settings_wiring() -> None: