diff --git a/README.md b/README.md index b6f26b975..a2b24bf1a 100644 --- a/README.md +++ b/README.md @@ -205,7 +205,7 @@ azd up - The repo-provided `azd`, Bicep, Terraform, and Azure CLI deployers are **container-based** App Service deployments. - For those container deployments, do **not** set an App Service Stack Settings Startup command. - The container already starts Gunicorn through `application/single_app/Dockerfile`. -- If your environment needs private or self-signed certificate authorities for outbound TLS checks to internal services, add them during image build using [docs/how-to/docker_customization.md](docs/how-to/docker_customization.md). +- If your environment needs private or self-signed certificate authorities for outbound TLS checks to internal services, add them during image build using [docs/guides/docker-customization.md](docs/guides/docker-customization.md). ### Native Python - For **native Python App Service** deployments, deploy the `application/single_app` folder and set the App Service Startup command explicitly. @@ -236,11 +236,11 @@ python -m gunicorn -c gunicorn.conf.py app:app ## Upgrade Paths -- For a concise upgrade decision guide, see [docs/how-to/upgrade_paths.md](docs/how-to/upgrade_paths.md). +- For a concise upgrade decision guide, see [docs/guides/upgrade-paths.md](docs/guides/upgrade-paths.md). ### Container - **Container-based upgrades** should usually start with `azd deploy` for code-only changes. Use `azd up` only when the release also changes infrastructure. -- If your App Service is already configured to pull from ACR and you want image-only rollouts, use the ACR/image refresh approach described in [docs/how-to/upgrade_paths.md](docs/how-to/upgrade_paths.md) instead of treating every release as a full reprovisioning event. +- If your App Service is already configured to pull from ACR and you want image-only rollouts, use the ACR/image refresh approach described in [docs/guides/upgrade-paths.md](docs/guides/upgrade-paths.md) instead of treating every release as a full reprovisioning event. ### Native Python - **Native Python App Service upgrades** should reuse the manual deployment path, validate the Startup command above, and deploy the `application/single_app` folder with VS Code or Azure CLI ZIP deploy. diff --git a/application/single_app/config.py b/application/single_app/config.py index 38d7d2fe2..36591a2e6 100644 --- a/application/single_app/config.py +++ b/application/single_app/config.py @@ -97,7 +97,7 @@ EXECUTOR_TYPE = 'thread' EXECUTOR_MAX_WORKERS = 30 SESSION_TYPE = 'filesystem' -VERSION = "0.261.002" +VERSION = "0.261.003" IS_DEVELOPMENT = is_development_env_enabled() SESSION_COOKIE_SAMESITE = os.getenv('SESSION_COOKIE_SAMESITE', 'Lax') diff --git a/deployers/azurecli/README.md b/deployers/azurecli/README.md index cac816eb8..64c052244 100644 --- a/deployers/azurecli/README.md +++ b/deployers/azurecli/README.md @@ -1,6 +1,6 @@ # Simple Chat - Deployment using Azure CLI + PowerShell -[Return to Main](../README.md) +[Return to Main](../../README.md) ## Overview diff --git a/deployers/azurecli/deploy-simplechat.ps1 b/deployers/azurecli/deploy-simplechat.ps1 index c4ea3f2ef..e0bf9b01e 100644 --- a/deployers/azurecli/deploy-simplechat.ps1 +++ b/deployers/azurecli/deploy-simplechat.ps1 @@ -112,7 +112,7 @@ For Azure Government, use the corresponding sovereign-cloud private DNS zones su For detailed private networking guidance, see: - `deployers/bicep/README.md` -- `docs/how-to/enterprise_networking.md` +- `docs/guides/enterprise-networking.md` ============================================ Manual changes post-deployment. diff --git a/deployers/bicep/README.md b/deployers/bicep/README.md index 817539bf5..5c71a86af 100644 --- a/deployers/bicep/README.md +++ b/deployers/bicep/README.md @@ -542,7 +542,7 @@ A: Base infrastructure (without optional services) costs approximately: ### Upgrading **Q: How do I upgrade to a new version?** -A: For **code-only** container updates, prefer `azd deploy`. Use `azd provision --preview` and then `azd up` only when the release also changes infrastructure. See [../../docs/how-to/upgrade_paths.md](../../docs/how-to/upgrade_paths.md) for the upgrade decision guide. +A: For **code-only** container updates, prefer `azd deploy`. Use `azd provision --preview` and then `azd up` only when the release also changes infrastructure. See [../../docs/guides/upgrade-paths.md](../../docs/guides/upgrade-paths.md) for the upgrade decision guide. --- diff --git a/deployers/terraform/ReadMe.md b/deployers/terraform/ReadMe.md index 0debb99c0..8013b7f82 100644 --- a/deployers/terraform/ReadMe.md +++ b/deployers/terraform/ReadMe.md @@ -1,6 +1,6 @@ # Simple Chat - Deployment using Terraform -[Return to Main](../README.md) +[Return to Main](../../README.md) ## Login to Azure CLI @@ -49,7 +49,7 @@ If you plan to reuse enterprise-managed networking, make sure these prerequisite For detailed networking guidance, see: - [../bicep/README.md](../bicep/README.md) -- [../../docs/how-to/enterprise_networking.md](../../docs/how-to/enterprise_networking.md) +- [../../docs/guides/enterprise-networking.md](../../docs/guides/enterprise-networking.md) ## Configure Terraform Secrets @@ -93,7 +93,7 @@ If you use `az acr build`, run it from the repository root so the Docker build c - For **code-only** container updates, publish a new image to ACR and follow the existing App Service container rollout process instead of rerunning Terraform for every release. - Use Terraform when you are intentionally changing infrastructure or configuration that belongs in Terraform state. -- See [../../docs/how-to/upgrade_paths.md](../../docs/how-to/upgrade_paths.md) for the native-vs-container upgrade guide and the ACR/image-only rollout notes. +- See [../../docs/guides/upgrade-paths.md](../../docs/guides/upgrade-paths.md) for the native-vs-container upgrade guide and the ACR/image-only rollout notes. ## Terraform deployment diff --git a/deployers/version.txt b/deployers/version.txt index 4a4127c37..8955a0173 100644 --- a/deployers/version.txt +++ b/deployers/version.txt @@ -1 +1 @@ -1.0.25 +1.0.26 diff --git a/docs/admin/knowledge.md b/docs/admin/knowledge.md index 38e2b852f..7198718aa 100644 --- a/docs/admin/knowledge.md +++ b/docs/admin/knowledge.md @@ -37,7 +37,13 @@ These settings decide what evidence enters the system and how it becomes searcha ### Web Search {#web-search-section} -The Web Search section belongs to the Web & Research tab. Use it with the adjacent settings in this group so related rollout, access, and operational choices stay aligned. +Web Search lets chat ground a single message in current public web results. SimpleChat does not call a search API directly. It calls an Azure AI Foundry agent that you create and configure, and that agent uses the Grounding with Bing Search tool to run the query and return results with citations. + +Two things gate the capability, and both are required. `enable_web_search` turns it on, and `web_search_consent_accepted` records that an administrator acknowledged that Grounding with Bing Search moves data outside the Azure compliance boundary and operates under separate terms. Enabling the toggle without accepting the consent leaves the feature off. + +Only the user's current chat message is sent to the agent. Conversation history, workspace documents, attached file contents, and system prompts are never included in the outbound query. Decide your rollout policy on that basis, and use the notice settings below if you want users reminded of it in the composer. + +An agent ID is not optional. If it is missing, chat tells the user web search is unavailable rather than silently answering from training data, so a half-finished configuration fails loudly instead of quietly degrading. ### URL Access {#url-access-section} @@ -51,19 +57,19 @@ The Deep Research section belongs to the Web & Research tab. Use it with the adj | Setting | What it does | Default | Notes | | --- | --- | --- | --- | -| Enable Web Search via Foundry Agent | Adds web search through the configured Azure AI Foundry agent for approved chat flows. | Off | `enable_web_search`; capability toggle | -| Show data notice to users when web search is used | Exposes the capability after required services, permissions, and rollout policy are ready. | Off | `enable_web_search_user_notice`; capability toggle | -| Notice Text | This message will be shown to users once per session when they first use web search. | N/A (runtime control) | `web_search_user_notice_text` | +| Enable Web Search via Foundry Agent | Adds web search through the configured Azure AI Foundry agent for approved chat flows. Requires accepted consent to take effect. | Off | `enable_web_search`; capability toggle | +| Show data notice to users when web search is used | Shows a dismissible banner above the chat composer while web search is active, so users know the message will leave the tenant. | Off | `enable_web_search_user_notice`; capability toggle | +| Notice Text | The banner wording. Shown once per browser session, from the first time the user activates web search until they dismiss it. | N/A (runtime control) | `web_search_user_notice_text` | | Foundry Project Endpoint | Project endpoint format: https://.services.ai.azure.com/api/projects/ (not the inference endpoint). | N/A (runtime control) | `web_search_foundry_endpoint` | | Foundry API Version | Pins the service API version SimpleChat sends with requests for this feature. | N/A (runtime control) | `web_search_foundry_api_version` | -| Foundry Agent ID | Narrows the admin list shown for foundry agent id. | N/A (runtime control) | `web_search_foundry_agent_id` | -| Authentication Type | Identity must have Cognitive Services User and AI Developer roles on the Foundry project. | N/A (runtime control) | `web_search_foundry_auth_type` | -| Cloud | Narrows the admin list shown for cloud. | N/A (runtime control) | `web_search_foundry_cloud` | -| Managed Identity Type | Narrows the admin list shown for managed identity type. | N/A (runtime control) | `web_search_foundry_managed_identity_type` | -| Authority Endpoint (Custom Cloud) | Narrows the admin list shown for authority endpoint (custom cloud). | N/A (runtime control) | `web_search_foundry_authority` | -| Managed Identity Client ID (UAMI) | Narrows the admin list shown for managed identity client id (uami). | N/A (runtime control) | `web_search_foundry_managed_identity_client_id` | -| Tenant ID | Narrows the admin list shown for tenant id. | N/A (runtime control) | `web_search_foundry_tenant_id` | -| Client ID | Narrows the admin list shown for client id. | N/A (runtime control) | `web_search_foundry_client_id` | +| Foundry Agent ID | Identifies the agent that carries the Grounding with Bing Search tool. Without it, chat reports web search as unavailable. | N/A (runtime control) | `web_search_foundry_agent_id` | +| Authentication Type | Selects how SimpleChat authenticates to the Foundry project. The identity must have Cognitive Services User and AI Developer roles on that project. | N/A (runtime control) | `web_search_foundry_auth_type` | +| Cloud | Selects the Azure cloud whose endpoints and authority are used to reach the Foundry project. | N/A (runtime control) | `web_search_foundry_cloud` | +| Managed Identity Type | Chooses between the system-assigned identity and a user-assigned identity when authenticating with a managed identity. | N/A (runtime control) | `web_search_foundry_managed_identity_type` | +| Authority Endpoint (Custom Cloud) | Overrides the login authority when the selected cloud is a custom or sovereign environment. | N/A (runtime control) | `web_search_foundry_authority` | +| Managed Identity Client ID (UAMI) | Identifies which user-assigned managed identity to authenticate with. | N/A (runtime control) | `web_search_foundry_managed_identity_client_id` | +| Tenant ID | Directory the service principal authenticates against. | N/A (runtime control) | `web_search_foundry_tenant_id` | +| Client ID | Application ID of the service principal used for authentication. | N/A (runtime control) | `web_search_foundry_client_id` | | Client Secret | Provides the secret credential used when the selected authentication mode requires one. | N/A (runtime control) | `web_search_foundry_client_secret` | | Enable URL Access for chat and workflows | Allows chat and workflows to inspect user-provided URLs within the configured URL limits and domain policy. | Off | `enable_url_access`; capability toggle | | Require UrlAccessUser App Role | 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. | Off | `require_member_of_url_access_user` | diff --git a/docs/explanation/features/index.md b/docs/explanation/features/index.md index 03353656b..402b91ff7 100644 --- a/docs/explanation/features/index.md +++ b/docs/explanation/features/index.md @@ -8,13 +8,13 @@ category: Version History ## Tutorial Features -- [Guided Tutorials](GUIDED_TUTORIALS.md) -- [User Tutorial Visibility Preference](USER_TUTORIAL_VISIBILITY_PREFERENCE.md) +- [Guided Tutorials](v0.241.001/GUIDED_TUTORIALS.md) +- [User Tutorial Visibility Preference](v0.241.001/USER_TUTORIAL_VISIBILITY_PREFERENCE.md) ## Admin Experience Features - [Azure OpenAI Identity Setup Guide](v0.250.001/AZURE_OPENAI_IDENTITY_SETUP_GUIDE.md) -- [AI Voice Conversations Setup Guide](AI_VOICE_CONVERSATIONS_SETUP_GUIDE.md) +- [AI Voice Conversations Setup Guide](v0.241.006/AI_VOICE_CONVERSATIONS_SETUP_GUIDE.md) - [Activity Log Auto-Refresh](CONTROL_CENTER_ACTIVITY_LOG_AUTO_REFRESH.md) - [Activity Log Layout Presets](ACTIVITY_LOG_LAYOUT_PRESETS.md) - [Content Safety Violation Messages](CONTENT_SAFETY_VIOLATION_MESSAGES.md) diff --git a/docs/explanation/features/v0.229.058/TIME_BASED_LOGGING_TURNOFF.md b/docs/explanation/features/v0.229.058/TIME_BASED_LOGGING_TURNOFF.md index 13d6a209e..7f3fec3e7 100644 --- a/docs/explanation/features/v0.229.058/TIME_BASED_LOGGING_TURNOFF.md +++ b/docs/explanation/features/v0.229.058/TIME_BASED_LOGGING_TURNOFF.md @@ -270,8 +270,8 @@ The timer framework can be extended to support: ## Related Documentation -- [Admin Configuration Guide](../admin_configuration.md) -- [Application Workflows](../application_workflows.md) +- [Admin Configuration Guide](../../../admin_configuration.md) +- Application Workflows - [Fix Documentation](../fixes/) - [Functional Tests](../../functional_tests/) diff --git a/docs/explanation/features/v0.235.001/APPROVAL_WORKFLOW_SYSTEM.md b/docs/explanation/features/v0.235.001/APPROVAL_WORKFLOW_SYSTEM.md index 9660b947e..2b3917c93 100644 --- a/docs/explanation/features/v0.235.001/APPROVAL_WORKFLOW_SYSTEM.md +++ b/docs/explanation/features/v0.235.001/APPROVAL_WORKFLOW_SYSTEM.md @@ -492,9 +492,9 @@ No dedicated functional test file created yet. Recommended test file: 10. **Approval Comments**: Threaded comments/discussion on approval requests ## Related Documentation -- [Control Center Overview](../admin_configuration.md) -- [Notification System](../features/NOTIFICATION_SYSTEM.md) (if exists) -- [Group Management](../features/GROUP_MANAGEMENT.md) (if exists) +- [Control Center Overview](../../../admin_configuration.md) +- Notification System +- Group Management ## Support & Troubleshooting diff --git a/docs/explanation/features/v0.235.001/DOCUMENT_METADATA_UPDATE_ACTIVITY_LOGGING.md b/docs/explanation/features/v0.235.001/DOCUMENT_METADATA_UPDATE_ACTIVITY_LOGGING.md index a1f3dbfbd..3a34cf049 100644 --- a/docs/explanation/features/v0.235.001/DOCUMENT_METADATA_UPDATE_ACTIVITY_LOGGING.md +++ b/docs/explanation/features/v0.235.001/DOCUMENT_METADATA_UPDATE_ACTIVITY_LOGGING.md @@ -242,9 +242,9 @@ The test validates: ## Related Documentation -- [Document Creation Activity Logging](./DOCUMENT_CREATION_ACTIVITY_LOGGING.md) -- [Document Deletion Activity Logging](./DOCUMENT_DELETION_ACTIVITY_LOGGING.md) -- [Activity Logging Architecture](./ACTIVITY_LOGGING_ARCHITECTURE.md) +- Document Creation Activity Logging +- Document Deletion Activity Logging +- Activity Logging Architecture ## Performance Considerations diff --git a/docs/explanation/features/v0.235.001/EMBEDDING_TOKEN_TRACKING.md b/docs/explanation/features/v0.235.001/EMBEDDING_TOKEN_TRACKING.md index c0465daa7..9a48c7aed 100644 --- a/docs/explanation/features/v0.235.001/EMBEDDING_TOKEN_TRACKING.md +++ b/docs/explanation/features/v0.235.001/EMBEDDING_TOKEN_TRACKING.md @@ -255,8 +255,8 @@ If the Azure OpenAI API doesn't return token usage (older API versions or differ ## Related Documentation -- [Tabular Data CSV Storage Fix](../fixes/TABULAR_DATA_CSV_STORAGE_FIX.md) -- [Agent Model Display Fixes](../fixes/AGENT_MODEL_DISPLAY_FIXES.md) +- [Tabular Data CSV Storage Fix](../../fixes/v0.229.001/TABULAR_DATA_CSV_STORAGE_FIX.md) +- [Agent Model Display Fixes](../../fixes/v0.229.001/AGENT_MODEL_DISPLAY_FIXES.md) - Main codebase: `application/single_app/` ## Implementation Notes diff --git a/docs/explanation/features/v0.235.001/GROUP_MEMBER_DELETED_ACTIVITY_LOGGING.md b/docs/explanation/features/v0.235.001/GROUP_MEMBER_DELETED_ACTIVITY_LOGGING.md index 475fd3d3f..e47f486d1 100644 --- a/docs/explanation/features/v0.235.001/GROUP_MEMBER_DELETED_ACTIVITY_LOGGING.md +++ b/docs/explanation/features/v0.235.001/GROUP_MEMBER_DELETED_ACTIVITY_LOGGING.md @@ -315,9 +315,9 @@ The test validates: ## Related Documentation -- [Group Status Change Activity Logging](./GROUP_STATUS_CHANGE_ACTIVITY_LOGGING.md) -- [Document Creation Activity Logging](./DOCUMENT_CREATION_ACTIVITY_LOGGING.md) -- [Activity Logging Architecture](./ACTIVITY_LOGGING_ARCHITECTURE.md) +- Group Status Change Activity Logging +- Document Creation Activity Logging +- Activity Logging Architecture ## Performance Considerations diff --git a/docs/explanation/features/v0.235.001/GROUP_STATUS_MANAGEMENT.md b/docs/explanation/features/v0.235.001/GROUP_STATUS_MANAGEMENT.md index e0ed9b7cd..1a4528b12 100644 --- a/docs/explanation/features/v0.235.001/GROUP_STATUS_MANAGEMENT.md +++ b/docs/explanation/features/v0.235.001/GROUP_STATUS_MANAGEMENT.md @@ -582,4 +582,4 @@ This prevents all modifications while maintaining full read access. **Related Documentation:** - [Group Status UI Visibility](GROUP_STATUS_UI_VISIBILITY.md) - Dynamic UI hiding feature -- [Activity Logging](../explanation/activity_logging.md) +- Activity Logging diff --git a/docs/explanation/features/v0.235.001/MESSAGE_THREADING_SYSTEM.md b/docs/explanation/features/v0.235.001/MESSAGE_THREADING_SYSTEM.md index 589261ac5..1dfb61bdf 100644 --- a/docs/explanation/features/v0.235.001/MESSAGE_THREADING_SYSTEM.md +++ b/docs/explanation/features/v0.235.001/MESSAGE_THREADING_SYSTEM.md @@ -288,9 +288,9 @@ No configuration changes required. The feature is enabled by default for all new ## Related Documentation -- [Message Management Architecture](./MESSAGE_MANAGEMENT_ARCHITECTURE.md) -- [Conversation Metadata](./CONVERSATION_METADATA.md) -- [Message Masking](../fixes/MESSAGE_MASKING_FIX.md) +- Message Management Architecture +- Conversation Metadata +- Message Masking ## References diff --git a/docs/explanation/features/v0.235.001/SPEECH_TO_TEXT_CHAT_INPUT.md b/docs/explanation/features/v0.235.001/SPEECH_TO_TEXT_CHAT_INPUT.md index 287b3cb0e..e59d34e7c 100644 --- a/docs/explanation/features/v0.235.001/SPEECH_TO_TEXT_CHAT_INPUT.md +++ b/docs/explanation/features/v0.235.001/SPEECH_TO_TEXT_CHAT_INPUT.md @@ -359,8 +359,8 @@ Potential improvements for future versions: ## Related Documentation -- [Audio File Support Feature](AUDIO_FILE_SUPPORT.md) (uses same Speech Service) -- [Admin Configuration Guide](../admin_configuration.md) +- Audio File Support Feature (uses same Speech Service) +- [Admin Configuration Guide](../../../admin_configuration.md) - [Azure Speech Service Documentation](https://learn.microsoft.com/azure/ai-services/speech-service/) ## Version History diff --git a/docs/explanation/features/v0.235.001/TEXT_TO_SPEECH.md b/docs/explanation/features/v0.235.001/TEXT_TO_SPEECH.md index a09f0ddb9..bd09e2fbe 100644 --- a/docs/explanation/features/v0.235.001/TEXT_TO_SPEECH.md +++ b/docs/explanation/features/v0.235.001/TEXT_TO_SPEECH.md @@ -343,8 +343,8 @@ Tests: ## Related Documentation - [Azure Speech Service Documentation](https://docs.microsoft.com/azure/cognitive-services/speech-service/) -- [Speech-to-Text Feature](./SPEECH_TO_TEXT.md) -- [Agent Integration](./AGENT_ORCHESTRATION.md) +- Speech-to-Text Feature +- Agent Integration ## Support and Feedback For issues, feature requests, or feedback, please contact the development team or file an issue in the project repository. diff --git a/docs/explanation/features/v0.237.001/WEB_SEARCH_AZURE_AI_FOUNDRY.md b/docs/explanation/features/v0.237.001/WEB_SEARCH_AZURE_AI_FOUNDRY.md index 440626a17..131549c2f 100644 --- a/docs/explanation/features/v0.237.001/WEB_SEARCH_AZURE_AI_FOUNDRY.md +++ b/docs/explanation/features/v0.237.001/WEB_SEARCH_AZURE_AI_FOUNDRY.md @@ -172,7 +172,7 @@ When consent is accepted, the following information is logged: ## Related Features -- [Azure AI Foundry Agent Support](AZURE_AI_FOUNDRY_AGENT_SUPPORT.md) +- Azure AI Foundry Agent Support - Agent-based chat with real-time information ## Dependencies diff --git a/docs/explanation/fixes/v0.229.001/LARGE_PDF_SUMMARIZATION_SUPPORT.md b/docs/explanation/fixes/v0.229.001/LARGE_PDF_SUMMARIZATION_SUPPORT.md index a9b0e8b79..435ca39a6 100644 --- a/docs/explanation/fixes/v0.229.001/LARGE_PDF_SUMMARIZATION_SUPPORT.md +++ b/docs/explanation/fixes/v0.229.001/LARGE_PDF_SUMMARIZATION_SUPPORT.md @@ -293,6 +293,6 @@ This enhancement is backward compatible: ## Related Documentation -- [Smart HTTP Plugin PDF Support](SMART_HTTP_PLUGIN_PDF_SUPPORT.md) -- [Enhanced Citations Implementation](ENHANCED_CITATIONS_IMPLEMENTATION.md) -- [Plugin Documentation and Testing Standards](DOCUMENTATION_AND_TESTING_STANDARDS.md) \ No newline at end of file +- Smart HTTP Plugin PDF Support +- Enhanced Citations Implementation +- Plugin Documentation and Testing Standards \ No newline at end of file diff --git a/docs/explanation/fixes/v0.235.001/ALL_FILE_TYPES_EMBEDDING_TOKEN_TRACKING_FIX.md b/docs/explanation/fixes/v0.235.001/ALL_FILE_TYPES_EMBEDDING_TOKEN_TRACKING_FIX.md index 92f8aef10..c64cb1ed3 100644 --- a/docs/explanation/fixes/v0.235.001/ALL_FILE_TYPES_EMBEDDING_TOKEN_TRACKING_FIX.md +++ b/docs/explanation/fixes/v0.235.001/ALL_FILE_TYPES_EMBEDDING_TOKEN_TRACKING_FIX.md @@ -297,7 +297,7 @@ To validate the fix: ## Related Documentation -- [EMBEDDING_TOKEN_TRACKING.md](EMBEDDING_TOKEN_TRACKING.md) - Original feature documentation (v0.233.298) +- [EMBEDDING_TOKEN_TRACKING.md](../../features/v0.235.001/EMBEDDING_TOKEN_TRACKING.md) - Original feature documentation (v0.233.298) - [PDF_EMBEDDING_TOKEN_TRACKING_FIX.md](PDF_EMBEDDING_TOKEN_TRACKING_FIX.md) - PDF fix documentation (v0.233.299) - [Functional Test: test_embedding_token_tracking.py](../../functional_tests/test_embedding_token_tracking.py) diff --git a/docs/explanation/fixes/v0.235.001/PDF_EMBEDDING_TOKEN_TRACKING_FIX.md b/docs/explanation/fixes/v0.235.001/PDF_EMBEDDING_TOKEN_TRACKING_FIX.md index e3996c4af..5749b95c8 100644 --- a/docs/explanation/fixes/v0.235.001/PDF_EMBEDDING_TOKEN_TRACKING_FIX.md +++ b/docs/explanation/fixes/v0.235.001/PDF_EMBEDDING_TOKEN_TRACKING_FIX.md @@ -162,6 +162,6 @@ embedding_model_deployment_name: "text-embedding-3-small" ``` ## Related Documentation -- [Embedding Token Tracking Feature](../features/EMBEDDING_TOKEN_TRACKING.md) +- [Embedding Token Tracking Feature](../../features/v0.235.001/EMBEDDING_TOKEN_TRACKING.md) - Main implementation: `application/single_app/functions_documents.py` - Test: `functional_tests/test_embedding_token_tracking.py` diff --git a/docs/explanation/fixes/v0.237.001/WEB_SEARCH_FAILURE_GRACEFUL_HANDLING_FIX.md b/docs/explanation/fixes/v0.237.001/WEB_SEARCH_FAILURE_GRACEFUL_HANDLING_FIX.md index ad18d356b..93a4a2fef 100644 --- a/docs/explanation/fixes/v0.237.001/WEB_SEARCH_FAILURE_GRACEFUL_HANDLING_FIX.md +++ b/docs/explanation/fixes/v0.237.001/WEB_SEARCH_FAILURE_GRACEFUL_HANDLING_FIX.md @@ -175,7 +175,7 @@ DEBUG_LOG_ENABLED = True ## Related -- [Azure AI Foundry Agent Support](../features/v0.236.011/AZURE_AI_FOUNDRY_AGENT_SUPPORT.md) +- Azure AI Foundry Agent Support - Bing Grounding Tool Configuration - Error Handling Best Practices diff --git a/docs/explanation/fixes/v0.237.004/RETENTION_POLICY_NULL_LAST_ACTIVITY_FIX.md b/docs/explanation/fixes/v0.237.004/RETENTION_POLICY_NULL_LAST_ACTIVITY_FIX.md index 315792af1..0481366ae 100644 --- a/docs/explanation/fixes/v0.237.004/RETENTION_POLICY_NULL_LAST_ACTIVITY_FIX.md +++ b/docs/explanation/fixes/v0.237.004/RETENTION_POLICY_NULL_LAST_ACTIVITY_FIX.md @@ -128,6 +128,6 @@ After the fix, retention policy execution should: ## Related Documentation -- [Retention Policy Feature Documentation](../../features/RETENTION_POLICY.md) +- Retention Policy Feature Documentation - [v0.236.012 NotFound Error Fix](../v0.236.012/RETENTION_POLICY_NOTFOUND_FIX.md) - [v0.235.022 Document Deletion Fix](../v0.235.022/RETENTION_POLICY_DOCUMENT_DELETION_FIX.md) diff --git a/docs/explanation/fixes/v0.237.005/RETENTION_POLICY_FIELD_NAME_FIX.md b/docs/explanation/fixes/v0.237.005/RETENTION_POLICY_FIELD_NAME_FIX.md index da74b2dc0..7c7ae81d5 100644 --- a/docs/explanation/fixes/v0.237.005/RETENTION_POLICY_FIELD_NAME_FIX.md +++ b/docs/explanation/fixes/v0.237.005/RETENTION_POLICY_FIELD_NAME_FIX.md @@ -198,4 +198,4 @@ This fix ensures compatibility with all three conversation schemas that exist in - [v0.237.004 Null Last Activity Fix](../v0.237.004/RETENTION_POLICY_NULL_LAST_ACTIVITY_FIX.md) - [v0.236.012 NotFound Error Fix](../v0.236.012/RETENTION_POLICY_NOTFOUND_FIX.md) -- [Retention Policy Feature Documentation](../../features/RETENTION_POLICY.md) +- Retention Policy Feature Documentation diff --git a/docs/explanation/release-notes/index.md b/docs/explanation/release-notes/index.md index c164f91e5..510f205a1 100644 --- a/docs/explanation/release-notes/index.md +++ b/docs/explanation/release-notes/index.md @@ -20,18 +20,21 @@ This page includes the latest release notes inline. Older release sections are s | Version | Page | | --- | --- | -| v0.260.025 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | -| v0.260.024 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | -| v0.260.023 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | -| v0.260.021 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | -| v0.260.020 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | -| v0.260.019 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | -| v0.260.018 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | -| v0.260.017 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | -| v0.260.016 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | -| v0.260.015 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | -| v0.260.014 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | -| v0.260.013 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | +| v0.261.003 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | +| v0.261.002 | [Release notes index]({{ '/explanation/release_notes/' | relative_url }}) | +| v0.261.001 | [Release notes 0.261 series]({{ '/explanation/release-notes/v0.261/' | relative_url }}) | +| v0.260.025 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | +| v0.260.024 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | +| v0.260.023 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | +| v0.260.021 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | +| v0.260.020 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | +| v0.260.019 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | +| v0.260.018 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | +| v0.260.017 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | +| v0.260.016 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | +| v0.260.015 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | +| v0.260.014 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | +| v0.260.013 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | | v0.260.012 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | | v0.260.011 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | | v0.260.010 | [Release notes 0.260 series]({{ '/explanation/release-notes/v0.260/' | relative_url }}) | @@ -68,266 +71,69 @@ This page includes the latest release notes inline. Older release sections are s ## Latest release notes -### **(v0.260.025)** +### **(v0.261.003)** #### Bug Fixes -* **Agent Actions Are No Longer Skipped When A Workspace Is In Scope** - * Selecting an agent that has actions and enabling a workspace produced answers that never invoked any of the agent's actions. The assistant answered from retrieved document text alone, even when the retrieved excerpts did not contain what the question asked for. - * The retrieval prompt instructed the model to base its answer *only* on the retrieved excerpts, so although the agent's actions were attached and available, the model was told not to reach for them. Retrieved excerpts are now framed as starting evidence, and the model is directed to call an available action when the excerpts lack what the question needs, then reason over the excerpts and the action results together. The rule against fabricating unsupported values is unchanged. - * (Ref: `build_search_augmentation_system_prompt`, `build_mixed_source_evidence_handoff`, agent actions, workspace search, [#1332](https://github.com/microsoft/simplechat/issues/1332)) - -* **Spreadsheets In A Workspace Are Now Actually Computed** - * A quantitative question about a spreadsheet could return values that were not in the file. Tabular computation was suppressed whenever workspace search also returned any narrative document, and the heuristic treated topic words such as "report", "policy", and "memo" as reasons to skip computation entirely. - * Because only a truncated three-row preview of a spreadsheet is indexed for search, skipping computation left the model deriving totals and averages from those preview rows. Tabular sources in scope are now computed unless the question unambiguously names a narrative artifact such as a PDF or presentation, restoring parity with the behavior already used when mixed-source search is disabled. - * (Ref: `should_run_tabular_evidence`, `functions_mixed_source_orchestration.py`, tabular processing, mixed-source evidence, [#1332](https://github.com/microsoft/simplechat/issues/1332)) - -* **A Skipped Spreadsheet Now Tells The Model What It Is Missing** - * When tabular computation is skipped, the evidence record previously said processing "was not needed", which implied the source was irrelevant and left the model free to compute from indexed preview rows. - * It now states that the full table was never read, that any indexed excerpt is a truncated preview, that numeric conclusions must not be drawn from it, and that the tabular analysis action should be called if values from that source are required. - * (Ref: `execute_tabular_evidence_sources`, evidence envelopes, tabular citations, [#1332](https://github.com/microsoft/simplechat/issues/1332)) - -### **(v0.260.024)** - -#### Bug Fixes - -* **Inline Images And Videos Now Show Only Cited Media** - * Assistant messages rendered an inline image or video gallery for every media file that retrieval returned, so a search that surfaced five workspace images produced five inline tiles even when the answer referenced only one of them, or none at all. Media that had nothing to do with the answer was presented inside the message bubble as though it supported the answer. - * Inline galleries now render only the media the response actually cited. The five-item gallery cap therefore goes to genuinely cited media instead of retrieval noise, and unreferenced workspace files no longer trigger enhanced-citation fetches. - * Galleries produced by an action or tool the assistant actually ran are unaffected, since those are executed results rather than unused search candidates. Conversations created before cited-source tracking existed also keep their previous behavior. - * The **Sources** disclosure is unchanged and still lists every retrieved document and web result, so nothing becomes harder to find. - * (Ref: `chat-citation-tracking.js`, `chat-inline-images.js`, `chat-inline-videos.js`, `chat-messages.js`, `cited_hybrid_citations`, [#1329](https://github.com/microsoft/simplechat/issues/1329)) - -### **(v0.260.023)** - -#### Bug Fixes - -* **Running Simple Chat Directly No Longer Fails To Start When An Agent Has Actions** - * Starting Simple Chat with `python app.py` (including via `uv run`) aborted with `RuntimeError: Working outside of request context` whenever any agent had an action assigned. The app started normally until the first action was saved, which made the failure look intermittent. - * Semantic Kernel initialization runs before any request exists on that path, but agent plugin loading read the signed-in user from the Flask session. It now resolves the user only when a request is actually in progress and otherwise loads with no user identity, matching how global plugin loading already behaved. - * Container and App Service deployments were never affected, because they start through gunicorn and initialize during the first request. Their behavior is unchanged. - * Three further identity lookups used for group scope and personal model endpoints had the same latent problem and were corrected at the same time. - * (Ref: `semantic_kernel_loader.py`, `functions_authentication.py`, `get_current_user_id_or_none`, issue #1327) - -### **(v0.260.021)** - -#### Bug Fixes - -* **Documentation Screenshot Viewer Validates Its Image Source** - * The documentation site's click-to-enlarge screenshot viewer assigned an image URL taken from a data attribute in the page. Because that value flows from page content into a URL, CodeQL flagged it as a potential DOM-based cross-site scripting sink. - * The viewer now resolves the value and requires a same-origin `http` or `https` URL ending in an image extension before using it, so scheme-based payloads such as `javascript:` and `data:` URLs, and any off-site source, are rejected. All documentation media is local, so no legitimate image is affected. - * (Ref: `docs/assets/js/media.js`, `safeMediaUrl`, `ui_tests/test_docs_media_lightbox_source_validation.js`, CodeQL `js/xss-through-dom`) - -### **(v0.260.020)** - -#### New Features - -* **Admin Documentation Rebuilt For The Grouped Settings Layout** - * Admin Settings was reorganized from 18 flat tabs into 14 groups containing 44 tabs and 93 settings sections. The documentation was still written against the old flat layout, so it described tabs that no longer exist and omitted the new ones. - * The admin documentation is now one page per group, with every tab reachable by its own anchor so links to a specific tab keep working. Every retired tab URL redirects to the group that now owns its settings, so existing links and bookmarks continue to resolve. - * (Ref: `docs/admin/`, `application/single_app/admin_settings_nav.py`, `docs/_data/app_surface.yml`) - -* **Collaborating In A Conversation Is Now Documented** - * Added a guide covering shared conversations end to end: sharing a conversation, mentioning a participant with `@` and Tab completion, how shared files are approved before they become available, and what participants can and cannot do. - * The Blob Storage action reference now explains its managed identity and account key options. - * (Ref: `docs/guides/collaborate-in-a-conversation/`, `docs/reference/actions/blob-storage/`, `enable_collaborative_conversations`) - -* **Documentation Site Now Reflects the v0.260.001 Release** - * The documentation site's Latest Release section was a full release behind, still presenting v0.250.001 as current. It now mirrors the same three-tier model the application uses: v0.260.001 as the current release, v0.250.001 as the previous release, and v0.239.001-v0.241.007 in the archive. - * Added 20 feature guides for the v0.260.001 release covering enhanced extraction, embedded Office images, workflow task sequences, the MCP platform, the Yamcs and RocksDB actions, agent instruction references, action test connections, Azure Blob file sync, terms of use, audio file support, completion notifications, the chat AI notice, conversation context grounding, used documents on fork, the conversation contents drawer, font size and zoom, message audio export, public workspace display names, and chat scroll accessibility. - * (Ref: `docs/_data/latest_release_features.yml`, `docs/latest-release/release-260-*`, `application/single_app/support_menu_config.py`) - -* **Placeholder Screenshots Are Now Tracked** - * The v0.260.001 release ships branded "Screenshot pending" placeholder graphics so feature cards render while final captures are pending. Those placeholders are now listed on the documentation media status page with the exact file paths to overwrite, so they are visible work rather than a silent gap. - * (Ref: `docs/_data/media_pending.yml`, `/contributing/media-status/`) - -#### User Interface Enhancements - -* **Admin Settings Pages Show Real Screenshots** - * Fourteen admin settings tab pages were rendering "screenshot needed" placeholders even though real screenshots already existed in the repository. Those pages now display the actual screenshots for the General, AI Models, Search and Extract, Workspaces, File Sync, Workspace Identities, Citation, Safety, Security, Agents, Scale, Control Center, Logging, and Send Feedback tabs. - * The four tabs with no captured screenshot still show a placeholder naming the exact file to create, so genuine gaps stay visible. - * (Ref: `docs/admin/`, `docs/images/admin-settings/`) - -#### Bug Fixes - -* **Release Notes Pages No Longer Break On Quoted Template Syntax** - * Release notes legitimately quote template syntax when describing template work, such as a Jinja `block` tag. The page generator emitted that verbatim, so the site build failed with an unknown tag error. Quoted template syntax is now escaped in generated pages and renders as literal text. - * (Ref: `scripts/build_release_notes_pages.py`) - -* **Release Notes Links To Internal Engineering Notes** - * Some release note entries linked to the internal feature and fix note trees, which are intentionally not published on the documentation site. Those links now point at the repository. - * (Ref: `docs/explanation/release_notes.md`) - -* **Release Notes Index No Longer Exceeds Its Page Budget** - * The release notes page generator inlined a fixed number of recent releases on its index. The consolidated v0.260.001 rollup is large enough on its own that this pushed the index past the maximum page size and failed generation. The index now fills its inline section by size rather than by count, so a single large rollup cannot break it. - * (Ref: `scripts/build_release_notes_pages.py`) - -* **Archived Release Notes Links** - * The archived release notes page linked to the internal feature and fix note trees, which are intentionally not published on the documentation site. Those links now point at the repository instead. - * (Ref: `docs/explanation/archive_release_notes.md`) - -### **(v0.260.019)** - -#### Bug Fixes - -* **Admin Settings Loads Again** - * Admin Settings returned a 500 error on every request after the settings restructure. The Document Action Capabilities card moved to the Actions tab but the two values it reads stayed behind in the Agents tab, and each tab is rendered separately, so those values were never there when the card asked for them. - * Both values are now defined in the tab that uses them, and a new test renders the two tabs together to keep them there. - * (Ref: `admin/_panes/actions.html`, `admin/_panes/agents.html`, document action capabilities) - -* **Server Errors Are Visible In The App Service Log Again** - * Once Application Insights was configured it took ownership of logging, which had the side effect of stopping Flask writing unhandled errors to the container log. A failing page left nothing behind but its access-log line, so diagnosing it meant querying Application Insights. - * Unhandled errors are now written to both, so the reason for a failure is visible in the App Service log stream. - * (Ref: `functions_appinsights.py`, `ensure_console_error_logging`, App Service console logs) - -* **Document Access Index Diagnostics Appear When Enabled** - * The Cosmos DB tab checked the wrong thing for the debug setting, so the backfill controls, shadow validation metrics and reset option stayed hidden even after an admin turned the setting on. - * (Ref: `admin/_panes/cosmos.html`, `enable_dai_debug`) - -### **(v0.260.018)** - -#### Bug Fixes - -* **Setup Walkthrough Lands On The Right Settings Again** - * The guided setup walkthrough sent each step to a named tab. After the Admin Settings restructure, eleven of its twelve steps named tabs that no longer existed, so those steps would have moved nowhere and left the admin looking at whatever was already on screen. - * Each step now names the setting it is about and the tab is worked out from the page, so the walkthrough follows settings wherever they live. - * (Ref: setup walkthrough, `admin_settings.js`, `admin_card_links.js`) - -* **Cosmos Throughput Validation Reveals The Invalid Field** - * When Cosmos throughput values failed validation, the page tried to switch to a tab that no longer exists, so the field needing attention could be left on a hidden tab with no indication of where to look. - * Validation now jumps to wherever the invalid field actually is. - * (Ref: Cosmos throughput validation, `admin_settings.js`) +* **Broken Documentation Links Repaired** + * Clicking the upgrade guide, Docker customization, or enterprise networking links from the repository README or the deployer READMEs led to a "page not found". Those pages were reorganized from `docs/how-to/.md` to `docs/guides/.md`, and the site kept redirects, but redirects do not apply when browsing files on GitHub. No documentation was ever lost, only mislinked. + * Repaired 46 broken relative links in total: 12 in the README and deployer READMEs, and 34 in archived per-version engineering notes. Archived links whose target was never migrated now keep the prose without a dead link, rather than pointing at a file that does not exist. + * Also corrected the "Return to Main" link in the Azure CLI and Terraform deployer READMEs, which pointed one directory too shallow. + * (Ref: `README.md`, `deployers/*/README.md`, `docs/explanation/features/`, `docs/explanation/fixes/`, [#1371](https://github.com/microsoft/simplechat/issues/1371)) + +* **Recovered 27 Release Note Sections Missing From The Source File** + * `docs/explanation/release_notes.md` had been truncated from 46 version sections to 19, dropping every v0.260 entry along with v0.250.229 through v0.250.231. The published site still showed them, because the pages that render release notes are generated from this file and had not been rebuilt since the truncation. + * That left the repository one routine `build_release_notes_pages.py` run away from erasing roughly 2,400 lines of release history from the site with no obvious cause. The sections have been restored from history and the pages regenerated, so the source and the site agree again. + * (Ref: `docs/explanation/release_notes.md`, `scripts/build_release_notes_pages.py`, [#1371](https://github.com/microsoft/simplechat/issues/1371)) + +#### Documentation + +* **Web Search Documentation Now Describes What Actually Happens** + * The web search guide still described the Bing Web Search API integration that was removed back in v0.229.001. Web search has since run through an Azure AI Foundry agent using the Grounding with Bing Search tool, which is why an admin has to configure a Foundry project and agent ID before the **Web** control appears. + * Added a dedicated **What leaves SimpleChat** section stating the egress boundary plainly: only the message the user just typed is sent to the external search service. Conversation history, workspace documents, attached file contents, system prompts, agent instructions, and workspace or document names are never included. This behavior was hardened in v0.241.022 but was previously mentioned only in passing. + * Documented the Deep Research nuance: it runs several planned queries instead of one, but every query is still derived from the current message alone, so no conversation history is introduced. + * Added the Grounding with Bing Search compliance-boundary notice to the user-facing guide, replaced the placeholder text in the admin Web Search settings table with real descriptions, and reused the existing web search flow diagram instead of leaving a "recording planned" video card. + * (Ref: `docs/guides/use-web-search.md`, `docs/admin/knowledge.md`, `docs/reference/chat-controls.md`, `build_web_search_query_text`, [#1371](https://github.com/microsoft/simplechat/issues/1371)) + +* **Documentation Link Rot Now Fails A Test** + * Added `functional_tests/test_docs_link_integrity.py`, which fails when any relative markdown link in the README, `docs/`, or `deployers/` points at a missing file, when a Jekyll `relative_url` page link does not resolve, or when a media include names an unregistered slot. Outstanding screenshots are reported but never fail the run. + * Added `functional_tests/test_docs_web_search_accuracy.py`, which ties the published privacy claim to the implementation. If the web search query builder ever starts folding conversation history back into the outbound query, the test fails and forces the documentation to be corrected with it. + * (Ref: `test_docs_link_integrity.py`, `test_docs_web_search_accuracy.py`, [#1371](https://github.com/microsoft/simplechat/issues/1371)) + +* **First Batch Of Documentation Screenshots** + * Filled 54 empty screenshot slots, taking documentation screenshot coverage from 18 of 122 to 72 of 122. The Administration group is now fully illustrated. + * Added the four admin settings overviews (Backup & Recovery, Data Lifecycle, Governance, Workflow), six chat control references (conversation list, conversation header, composer, selectors, grounded search, and advanced conversation search), thirty-three task guide steps, and configuration panes for eleven action types (Azure Maps, Blob Storage, Chart, Cosmos Query, Databricks, Document Search, Log Analytics, MCP, Microsoft Graph, OpenAPI, RocksDB, and SimpleChat). + * The web search screenshot captures the live data notice, so the guide's claim that only the current message is sent is now visible rather than only asserted. + * Action configuration panes were captured without saving any action, so every credential field shows only its placeholder text and no tenant values were recorded. Where an admin settings pane already held real values, those fields were replaced with example values before capture and the page was reloaded without saving. + * Replaced the generated placeholder alt text on every filled slot with a description of what the reader actually learns from the image. + * (Ref: `docs/images/admin/`, `docs/images/reference/`, `docs/images/guides/`, [#1371](https://github.com/microsoft/simplechat/issues/1371)) + +### **(v0.261.002)** #### User Interface Enhancements -* **Admin Settings Restructure Merged With Current Development** - * Version bump covering the merge of the Admin Settings information architecture work with the generated file output fixes developed in parallel. Both reached v0.260.011 independently, so their release notes are combined under that version. - * (Ref: Admin Settings navigation, generated file exports) - -### **(v0.260.017)** - -#### New Features - -* **All App Role Requirements In One Place** - * Ten settings across seven tabs can each require an Entra app role, which made the overall access policy impossible to read without hunting through the whole of Admin Settings. - * **Security → Access & Roles** now lists every one of them with a switch and a link to the setting in its own tab. Changing a switch here changes the setting itself. - * The list is built from the page, so a new role requirement added anywhere appears here automatically. - * (Ref: `app-role-requirements-section`, `admin_access_roles_roster.js`) - -#### User Interface Enhancements - -* **System Settings Card Split To Where Each Setting Belongs** - * One card mixed maximum file size, conversation history, idle timeout, the default system prompt and the access denied message — five unrelated concerns under one heading. - * Maximum File Size is now in **Workspaces → Files & Sharing**, Conversation History and Default System Prompt in **Chat → Chat Experience**, and Access Denied Message in **Security → Access & Roles**. - * What remains in **Security → Session** is the idle timeout, and the card is now named for it. - * Every setting keeps its saved value; nothing needs re-entering. - * (Ref: `idle-timeout-section`, `file-size-limit-section`, `conversation-history-section`, `default-system-prompt-section`, `access-denied-message-section`) - -### **(v0.260.016)** - -#### User Interface Enhancements - -* **Backup, Migrate & Restore Split Into Five Tabs** - * One tab carried the entire backup, migration, restore, Cosmos editing and job history surface — over 1,600 lines in a single scroll. - * Backup & Recovery now has **Backup** (readiness, backup, schedule, storage, encryption), **Migrate**, **Restore**, **Cosmos Editor** and **Jobs**. - * The save button, status line and operational-hours warning are shared by all five tabs, so they sit above the tabs and stay available wherever you are in the group. - * This completes the Admin Settings restructure: **14 groups and 44 tabs**, from an original 17 flat tabs. - * (Ref: `backup`, `migrate`, `restore`, `cosmos-editor`, `jobs`) - -#### Bug Fixes - -* **Backup Dialogs Remain Available From Every Tab** - * The eleven Backup & Recovery dialogs are opened from more than one place and several are opened from code rather than a button. Left inside a tab, a dialog cannot appear while a different tab is showing. - * They now sit outside the tabs, so restore, migration cancel, job detail, the Cosmos editor dialogs and the five setup guides all open wherever they are triggered from. - * (Ref: Backup & Recovery dialogs, `admin_data_management.js`) - -* **Shared Controls Work In Both Navigation Layouts** - * Shared group controls resolve their group from whichever navigation is on screen, so the Backup & Recovery save button is present in the sidebar layout as well as the tab layout. - * (Ref: `data-admin-group-shared`, `admin_sidebar_nav.js`) - -### **(v0.260.015)** - -#### User Interface Enhancements - -* **AI Models Split By Model Purpose** - * AI Models presented every model setting on one tab. It is now **Model Endpoints** (endpoint and fallback configuration, plus the Chat Model dialog opened from it), **Embeddings** and **Image Generation**. - * (Ref: `model-endpoints`, `embeddings`, `image-generation`) - -* **Agents And Actions Are Now Separate Tabs** - * A single "Agents and Actions" tab carried agent configuration, template approvals, document action capabilities, action configuration and the whole inbound MCP surface. - * It is now **Agents**, **Actions** and **Inbound MCP**. - * Inbound MCP is a large area with its own dialogs and diagnostics, and the whole tab is hidden when the inbound MCP interface is turned off rather than showing an empty tab. - * (Ref: `agents`, `actions`, `inbound-mcp`) - -#### Bug Fixes - -* **Model Setup Guide Available From Every Model Tab** - * The Azure OpenAI Model Setup Guide dialog is opened from the endpoints, embeddings and image generation cards. Once those moved to separate tabs it could only have opened from one of them. - * The dialog now sits outside the tabs, so it opens from all three. - * (Ref: `legacyModelDiscoveryIdentityGuideModal`) - -* **Dangling Section Comments Removed** - * Seven tabs ended with a comment labelling a card that had since moved to another tab. - * (Ref: admin settings tab panes) - -### **(v0.260.014)** - -#### User Interface Enhancements - -* **Knowledge Settings Split By What They Actually Do** - * Search & Extract held eight cards spanning four unrelated jobs, from Bing consent to voice transcription. - * Knowledge now has **Web & Research** (web search, URL access, deep research), **Search Index** (Azure AI Search), **Document Extraction** (document intelligence, chunk sizes, plus metadata extraction and multi-modal vision brought over from Workspaces) and **Audio & Video** (video intelligence, voice conversations), alongside the existing File Sync. - * Voice and video sit under Knowledge rather than Chat because they are extraction pipelines that turn recordings into searchable content. - * (Ref: `web-research`, `search-index`, `extraction`, `audio-video`) - -* **Workspaces Focused On Workspaces** - * Workspaces mixed workspace types with file rules, workflow and extraction settings. - * It is now **Workspace Types** (personal, group, public), **Files & Sharing** (downloads, sharing, and shared conversation file approvals brought over from AI Models) and the existing Global Identities. - * (Ref: `workspace-types`, `files-sharing`) - -* **Workflow Is Its Own Area** - * Workflow drives approvals and assignment across every workspace type and was too large to sit as one card inside Workspaces. It now has its own group. - * (Ref: `workflow`, `workflow-settings-section`) - -#### Bug Fixes - -* **Group Workflow Assignment Dialog Could Not Open** - * The Group Workflow Assignment dialog ended up in a different tab from the button that opens it. Because an inactive tab is hidden, the dialog would not have appeared at all. - * The dialog now sits with its button, and a new check verifies this for every dialog in Admin Settings so it cannot happen again. - * (Ref: `groupWorkflowAssignmentModal`, `test_admin_settings_modal_placement.py`) - -* **Misplaced Section Comments In AI Models** - * Two section comments had drifted onto the wrong cards while settings were being regrouped, labelling the embeddings card as processing thoughts. - * (Ref: `ai-models` pane) - -### **(v0.260.013)** - -#### User Interface Enhancements - -* **General Tab Broken Up Into Focused Tabs** - * General had grown into a catch-all of eleven unrelated cards: branding sat next to health checks, API documentation, terms of use and system settings. - * Appearance now has **Branding** (branding, home page text, appearance), **Notices & Agreements** (classification banner, chat AI notice, terms of use and the user agreement pulled across from Workspaces) and **Pages & Links** (static pages plus external links). - * Health Check and API Documentation moved to Operations, which is now **Logging & Health** — they report on how the app is running rather than how it looks. - * Support moved to Help as its own **Support Menu** tab, next to Send Feedback. - * (Ref: `branding`, `notices`, `custom-pages`, `logging`, `support-menu`) - -* **Security Split Into Five Purposeful Tabs** - * Security held a single Key Vault card while an unrelated Safety tab mixed content filtering with role permissions, which are different jobs. - * Security is now **Access & Roles** (who gets in and with what role), **Secrets** (Key Vault), **Content Safety** (what may be said once you are in), **Session** (idle timeout and related system settings) and **Network** (Azure Front Door). - * (Ref: `access-roles`, `secrets`, `content-safety`, `session`, `network`) +* **Inbound MCP Enablement Guidance** + * Added a visible **Inbound MCP** tab state for deployments where the preview admin UI is disabled by the missing `ENABLE_MCP_UI=true` App Service application setting. + * The disabled-state card explains how to enable the preview UI while making clear that the inbound MCP runtime remains off until an admin turns on **Enable inbound MCP server** after authentication, client allowlist, source, and governance prerequisites are ready. + * (Ref: `admin/_panes/inbound-mcp.html`, `admin_settings_nav.py`, [#1364](https://github.com/microsoft/simplechat/issues/1364)) #### Bug Fixes -* **"Open Key Vault Settings" Link No Longer Depends On A Hardcoded Tab** - * The link from Data Management to Key Vault switched tabs by a hardcoded id, so it silently stopped working whenever that tab was renamed. - * It now uses the standard card link, which finds the owning tab from the page itself and stays correct however the settings are grouped. - * (Ref: `data-management-key-vault-link`, `admin_card_links.js`, `admin_data_management.js`) - -* **Admin Settings Always Opens On A Real Tab** - * The tab shown on arrival was pinned to a specific id in both the markup and the sidebar script. Regrouping settings could leave Admin Settings opening with no tab selected at all. - * The landing tab is now taken from the navigation map, so it follows the settings and can never be Latest Features. - * (Ref: `admin_landing_tab`, `get_landing_tab_id`, `admin_sidebar_nav.js`) - -* **Stale Tab Names In Latest Features** - * Several Latest Features entries pointed readers at tabs by their old names after the settings moved. - * (Ref: `latest-features` pane) +* **Delegated Governance New Policy Modal Opens On Split Governance Tabs** + * Fixed the delegated item governance **New Policy** button so it opens the policy editor after Admin Settings governance was split into Feature Governance, Policies, and MCP Governance tabs. + * Updated governance quick links to target the correct split tab panes instead of the retired aggregate Governance pane. + * (Ref: `admin_governance.js`, delegated item policy editor, [#1362](https://github.com/microsoft/simplechat/issues/1362)) + +* **Large Markdown Files No Longer Fail To Upload** + * Uploading a Markdown file could fail with `Failed processing Markdown file ...` and take down the whole document, not just the oversized part of it. Long pages with a big section under a single heading, such as a release notes file, were the usual trigger. + * Markdown was the only ingestion path with no maximum chunk size. Its splitter divided the file on headings, and the step afterwards only ever merged chunks that were **too small** — nothing split a chunk that was too large. A heading with no subheading beneath it therefore became one chunk as large as all the text under it, which the embedding model refused. + * Lowering **Markdown (words)** in Admin Settings did not work around this, because that value was only ever used as a minimum. It is now a real target, so the setting behaves the way its name implies. + * Sections are now split to the configured size, a character limit is applied after merging to catch content such as tables and code blocks that take up more of the model's budget than their word count suggests, and a final safeguard keeps any remaining outlier inside the limit. That safeguard trims only the text used to build the chunk's search vector — the chunk itself is still stored in full, so citations and content are unaffected. + * (Ref: `process_md`, `save_chunks`, `functions_content.py`, `functions_documents.py`) + +* **Chunk Size Limits Now Respect Their Unit** + * Chunk sizes are configured per file type in words, characters, or pages, but a single shared limit was applied to all of them. That let a word-based field be set to 16,384 words — far more than can be indexed — while implying the value was valid. + * Word and character fields now have separate limits, both derived from the embedding model's context window, and the Document Extraction tab shows the current values. A value above its limit is reduced on save and the page names the fields it changed. + * Page and slide counts are left uncapped here, since how much text a page holds is not known until extraction runs. They are bounded when the chunk is indexed instead. + * No shipping default changed. Only custom overrides that could never have been indexed are affected. + * (Ref: `get_chunk_size_cap`, `get_chunk_size_config`, Document Extraction settings, `admin_settings.js`) diff --git a/docs/explanation/release-notes/v0.260.md b/docs/explanation/release-notes/v0.260.md index b364c885b..1e4050cb6 100644 --- a/docs/explanation/release-notes/v0.260.md +++ b/docs/explanation/release-notes/v0.260.md @@ -1,6 +1,6 @@ --- title: "Release notes 0.260 series" -description: "SimpleChat release notes for 0.260.012 – 0.260.001." +description: "SimpleChat release notes for 0.260.025 – 0.260.001." section: "Reference" layout: page --- @@ -11,6 +11,270 @@ layout: page [Back to release notes index]({{ '/explanation/release_notes/' | relative_url }}) +### **(v0.260.025)** + +#### Bug Fixes + +* **Agent Actions Are No Longer Skipped When A Workspace Is In Scope** + * Selecting an agent that has actions and enabling a workspace produced answers that never invoked any of the agent's actions. The assistant answered from retrieved document text alone, even when the retrieved excerpts did not contain what the question asked for. + * The retrieval prompt instructed the model to base its answer *only* on the retrieved excerpts, so although the agent's actions were attached and available, the model was told not to reach for them. Retrieved excerpts are now framed as starting evidence, and the model is directed to call an available action when the excerpts lack what the question needs, then reason over the excerpts and the action results together. The rule against fabricating unsupported values is unchanged. + * (Ref: `build_search_augmentation_system_prompt`, `build_mixed_source_evidence_handoff`, agent actions, workspace search, [#1332](https://github.com/microsoft/simplechat/issues/1332)) + +* **Spreadsheets In A Workspace Are Now Actually Computed** + * A quantitative question about a spreadsheet could return values that were not in the file. Tabular computation was suppressed whenever workspace search also returned any narrative document, and the heuristic treated topic words such as "report", "policy", and "memo" as reasons to skip computation entirely. + * Because only a truncated three-row preview of a spreadsheet is indexed for search, skipping computation left the model deriving totals and averages from those preview rows. Tabular sources in scope are now computed unless the question unambiguously names a narrative artifact such as a PDF or presentation, restoring parity with the behavior already used when mixed-source search is disabled. + * (Ref: `should_run_tabular_evidence`, `functions_mixed_source_orchestration.py`, tabular processing, mixed-source evidence, [#1332](https://github.com/microsoft/simplechat/issues/1332)) + +* **A Skipped Spreadsheet Now Tells The Model What It Is Missing** + * When tabular computation is skipped, the evidence record previously said processing "was not needed", which implied the source was irrelevant and left the model free to compute from indexed preview rows. + * It now states that the full table was never read, that any indexed excerpt is a truncated preview, that numeric conclusions must not be drawn from it, and that the tabular analysis action should be called if values from that source are required. + * (Ref: `execute_tabular_evidence_sources`, evidence envelopes, tabular citations, [#1332](https://github.com/microsoft/simplechat/issues/1332)) + +### **(v0.260.024)** + +#### Bug Fixes + +* **Inline Images And Videos Now Show Only Cited Media** + * Assistant messages rendered an inline image or video gallery for every media file that retrieval returned, so a search that surfaced five workspace images produced five inline tiles even when the answer referenced only one of them, or none at all. Media that had nothing to do with the answer was presented inside the message bubble as though it supported the answer. + * Inline galleries now render only the media the response actually cited. The five-item gallery cap therefore goes to genuinely cited media instead of retrieval noise, and unreferenced workspace files no longer trigger enhanced-citation fetches. + * Galleries produced by an action or tool the assistant actually ran are unaffected, since those are executed results rather than unused search candidates. Conversations created before cited-source tracking existed also keep their previous behavior. + * The **Sources** disclosure is unchanged and still lists every retrieved document and web result, so nothing becomes harder to find. + * (Ref: `chat-citation-tracking.js`, `chat-inline-images.js`, `chat-inline-videos.js`, `chat-messages.js`, `cited_hybrid_citations`, [#1329](https://github.com/microsoft/simplechat/issues/1329)) + +### **(v0.260.023)** + +#### Bug Fixes + +* **Running Simple Chat Directly No Longer Fails To Start When An Agent Has Actions** + * Starting Simple Chat with `python app.py` (including via `uv run`) aborted with `RuntimeError: Working outside of request context` whenever any agent had an action assigned. The app started normally until the first action was saved, which made the failure look intermittent. + * Semantic Kernel initialization runs before any request exists on that path, but agent plugin loading read the signed-in user from the Flask session. It now resolves the user only when a request is actually in progress and otherwise loads with no user identity, matching how global plugin loading already behaved. + * Container and App Service deployments were never affected, because they start through gunicorn and initialize during the first request. Their behavior is unchanged. + * Three further identity lookups used for group scope and personal model endpoints had the same latent problem and were corrected at the same time. + * (Ref: `semantic_kernel_loader.py`, `functions_authentication.py`, `get_current_user_id_or_none`, issue #1327) + +### **(v0.260.021)** + +#### Bug Fixes + +* **Documentation Screenshot Viewer Validates Its Image Source** + * The documentation site's click-to-enlarge screenshot viewer assigned an image URL taken from a data attribute in the page. Because that value flows from page content into a URL, CodeQL flagged it as a potential DOM-based cross-site scripting sink. + * The viewer now resolves the value and requires a same-origin `http` or `https` URL ending in an image extension before using it, so scheme-based payloads such as `javascript:` and `data:` URLs, and any off-site source, are rejected. All documentation media is local, so no legitimate image is affected. + * (Ref: `docs/assets/js/media.js`, `safeMediaUrl`, `ui_tests/test_docs_media_lightbox_source_validation.js`, CodeQL `js/xss-through-dom`) + +### **(v0.260.020)** + +#### New Features + +* **Admin Documentation Rebuilt For The Grouped Settings Layout** + * Admin Settings was reorganized from 18 flat tabs into 14 groups containing 44 tabs and 93 settings sections. The documentation was still written against the old flat layout, so it described tabs that no longer exist and omitted the new ones. + * The admin documentation is now one page per group, with every tab reachable by its own anchor so links to a specific tab keep working. Every retired tab URL redirects to the group that now owns its settings, so existing links and bookmarks continue to resolve. + * (Ref: `docs/admin/`, `application/single_app/admin_settings_nav.py`, `docs/_data/app_surface.yml`) + +* **Collaborating In A Conversation Is Now Documented** + * Added a guide covering shared conversations end to end: sharing a conversation, mentioning a participant with `@` and Tab completion, how shared files are approved before they become available, and what participants can and cannot do. + * The Blob Storage action reference now explains its managed identity and account key options. + * (Ref: `docs/guides/collaborate-in-a-conversation/`, `docs/reference/actions/blob-storage/`, `enable_collaborative_conversations`) + +* **Documentation Site Now Reflects the v0.260.001 Release** + * The documentation site's Latest Release section was a full release behind, still presenting v0.250.001 as current. It now mirrors the same three-tier model the application uses: v0.260.001 as the current release, v0.250.001 as the previous release, and v0.239.001-v0.241.007 in the archive. + * Added 20 feature guides for the v0.260.001 release covering enhanced extraction, embedded Office images, workflow task sequences, the MCP platform, the Yamcs and RocksDB actions, agent instruction references, action test connections, Azure Blob file sync, terms of use, audio file support, completion notifications, the chat AI notice, conversation context grounding, used documents on fork, the conversation contents drawer, font size and zoom, message audio export, public workspace display names, and chat scroll accessibility. + * (Ref: `docs/_data/latest_release_features.yml`, `docs/latest-release/release-260-*`, `application/single_app/support_menu_config.py`) + +* **Placeholder Screenshots Are Now Tracked** + * The v0.260.001 release ships branded "Screenshot pending" placeholder graphics so feature cards render while final captures are pending. Those placeholders are now listed on the documentation media status page with the exact file paths to overwrite, so they are visible work rather than a silent gap. + * (Ref: `docs/_data/media_pending.yml`, `/contributing/media-status/`) + +#### User Interface Enhancements + +* **Admin Settings Pages Show Real Screenshots** + * Fourteen admin settings tab pages were rendering "screenshot needed" placeholders even though real screenshots already existed in the repository. Those pages now display the actual screenshots for the General, AI Models, Search and Extract, Workspaces, File Sync, Workspace Identities, Citation, Safety, Security, Agents, Scale, Control Center, Logging, and Send Feedback tabs. + * The four tabs with no captured screenshot still show a placeholder naming the exact file to create, so genuine gaps stay visible. + * (Ref: `docs/admin/`, `docs/images/admin-settings/`) + +#### Bug Fixes + +* **Release Notes Pages No Longer Break On Quoted Template Syntax** + * Release notes legitimately quote template syntax when describing template work, such as a Jinja `block` tag. The page generator emitted that verbatim, so the site build failed with an unknown tag error. Quoted template syntax is now escaped in generated pages and renders as literal text. + * (Ref: `scripts/build_release_notes_pages.py`) + +* **Release Notes Links To Internal Engineering Notes** + * Some release note entries linked to the internal feature and fix note trees, which are intentionally not published on the documentation site. Those links now point at the repository. + * (Ref: `docs/explanation/release_notes.md`) + +* **Release Notes Index No Longer Exceeds Its Page Budget** + * The release notes page generator inlined a fixed number of recent releases on its index. The consolidated v0.260.001 rollup is large enough on its own that this pushed the index past the maximum page size and failed generation. The index now fills its inline section by size rather than by count, so a single large rollup cannot break it. + * (Ref: `scripts/build_release_notes_pages.py`) + +* **Archived Release Notes Links** + * The archived release notes page linked to the internal feature and fix note trees, which are intentionally not published on the documentation site. Those links now point at the repository instead. + * (Ref: `docs/explanation/archive_release_notes.md`) + +### **(v0.260.019)** + +#### Bug Fixes + +* **Admin Settings Loads Again** + * Admin Settings returned a 500 error on every request after the settings restructure. The Document Action Capabilities card moved to the Actions tab but the two values it reads stayed behind in the Agents tab, and each tab is rendered separately, so those values were never there when the card asked for them. + * Both values are now defined in the tab that uses them, and a new test renders the two tabs together to keep them there. + * (Ref: `admin/_panes/actions.html`, `admin/_panes/agents.html`, document action capabilities) + +* **Server Errors Are Visible In The App Service Log Again** + * Once Application Insights was configured it took ownership of logging, which had the side effect of stopping Flask writing unhandled errors to the container log. A failing page left nothing behind but its access-log line, so diagnosing it meant querying Application Insights. + * Unhandled errors are now written to both, so the reason for a failure is visible in the App Service log stream. + * (Ref: `functions_appinsights.py`, `ensure_console_error_logging`, App Service console logs) + +* **Document Access Index Diagnostics Appear When Enabled** + * The Cosmos DB tab checked the wrong thing for the debug setting, so the backfill controls, shadow validation metrics and reset option stayed hidden even after an admin turned the setting on. + * (Ref: `admin/_panes/cosmos.html`, `enable_dai_debug`) + +### **(v0.260.018)** + +#### Bug Fixes + +* **Setup Walkthrough Lands On The Right Settings Again** + * The guided setup walkthrough sent each step to a named tab. After the Admin Settings restructure, eleven of its twelve steps named tabs that no longer existed, so those steps would have moved nowhere and left the admin looking at whatever was already on screen. + * Each step now names the setting it is about and the tab is worked out from the page, so the walkthrough follows settings wherever they live. + * (Ref: setup walkthrough, `admin_settings.js`, `admin_card_links.js`) + +* **Cosmos Throughput Validation Reveals The Invalid Field** + * When Cosmos throughput values failed validation, the page tried to switch to a tab that no longer exists, so the field needing attention could be left on a hidden tab with no indication of where to look. + * Validation now jumps to wherever the invalid field actually is. + * (Ref: Cosmos throughput validation, `admin_settings.js`) + +#### User Interface Enhancements + +* **Admin Settings Restructure Merged With Current Development** + * Version bump covering the merge of the Admin Settings information architecture work with the generated file output fixes developed in parallel. Both reached v0.260.011 independently, so their release notes are combined under that version. + * (Ref: Admin Settings navigation, generated file exports) + +### **(v0.260.017)** + +#### New Features + +* **All App Role Requirements In One Place** + * Ten settings across seven tabs can each require an Entra app role, which made the overall access policy impossible to read without hunting through the whole of Admin Settings. + * **Security → Access & Roles** now lists every one of them with a switch and a link to the setting in its own tab. Changing a switch here changes the setting itself. + * The list is built from the page, so a new role requirement added anywhere appears here automatically. + * (Ref: `app-role-requirements-section`, `admin_access_roles_roster.js`) + +#### User Interface Enhancements + +* **System Settings Card Split To Where Each Setting Belongs** + * One card mixed maximum file size, conversation history, idle timeout, the default system prompt and the access denied message — five unrelated concerns under one heading. + * Maximum File Size is now in **Workspaces → Files & Sharing**, Conversation History and Default System Prompt in **Chat → Chat Experience**, and Access Denied Message in **Security → Access & Roles**. + * What remains in **Security → Session** is the idle timeout, and the card is now named for it. + * Every setting keeps its saved value; nothing needs re-entering. + * (Ref: `idle-timeout-section`, `file-size-limit-section`, `conversation-history-section`, `default-system-prompt-section`, `access-denied-message-section`) + +### **(v0.260.016)** + +#### User Interface Enhancements + +* **Backup, Migrate & Restore Split Into Five Tabs** + * One tab carried the entire backup, migration, restore, Cosmos editing and job history surface — over 1,600 lines in a single scroll. + * Backup & Recovery now has **Backup** (readiness, backup, schedule, storage, encryption), **Migrate**, **Restore**, **Cosmos Editor** and **Jobs**. + * The save button, status line and operational-hours warning are shared by all five tabs, so they sit above the tabs and stay available wherever you are in the group. + * This completes the Admin Settings restructure: **14 groups and 44 tabs**, from an original 17 flat tabs. + * (Ref: `backup`, `migrate`, `restore`, `cosmos-editor`, `jobs`) + +#### Bug Fixes + +* **Backup Dialogs Remain Available From Every Tab** + * The eleven Backup & Recovery dialogs are opened from more than one place and several are opened from code rather than a button. Left inside a tab, a dialog cannot appear while a different tab is showing. + * They now sit outside the tabs, so restore, migration cancel, job detail, the Cosmos editor dialogs and the five setup guides all open wherever they are triggered from. + * (Ref: Backup & Recovery dialogs, `admin_data_management.js`) + +* **Shared Controls Work In Both Navigation Layouts** + * Shared group controls resolve their group from whichever navigation is on screen, so the Backup & Recovery save button is present in the sidebar layout as well as the tab layout. + * (Ref: `data-admin-group-shared`, `admin_sidebar_nav.js`) + +### **(v0.260.015)** + +#### User Interface Enhancements + +* **AI Models Split By Model Purpose** + * AI Models presented every model setting on one tab. It is now **Model Endpoints** (endpoint and fallback configuration, plus the Chat Model dialog opened from it), **Embeddings** and **Image Generation**. + * (Ref: `model-endpoints`, `embeddings`, `image-generation`) + +* **Agents And Actions Are Now Separate Tabs** + * A single "Agents and Actions" tab carried agent configuration, template approvals, document action capabilities, action configuration and the whole inbound MCP surface. + * It is now **Agents**, **Actions** and **Inbound MCP**. + * Inbound MCP is a large area with its own dialogs and diagnostics, and the whole tab is hidden when the inbound MCP interface is turned off rather than showing an empty tab. + * (Ref: `agents`, `actions`, `inbound-mcp`) + +#### Bug Fixes + +* **Model Setup Guide Available From Every Model Tab** + * The Azure OpenAI Model Setup Guide dialog is opened from the endpoints, embeddings and image generation cards. Once those moved to separate tabs it could only have opened from one of them. + * The dialog now sits outside the tabs, so it opens from all three. + * (Ref: `legacyModelDiscoveryIdentityGuideModal`) + +* **Dangling Section Comments Removed** + * Seven tabs ended with a comment labelling a card that had since moved to another tab. + * (Ref: admin settings tab panes) + +### **(v0.260.014)** + +#### User Interface Enhancements + +* **Knowledge Settings Split By What They Actually Do** + * Search & Extract held eight cards spanning four unrelated jobs, from Bing consent to voice transcription. + * Knowledge now has **Web & Research** (web search, URL access, deep research), **Search Index** (Azure AI Search), **Document Extraction** (document intelligence, chunk sizes, plus metadata extraction and multi-modal vision brought over from Workspaces) and **Audio & Video** (video intelligence, voice conversations), alongside the existing File Sync. + * Voice and video sit under Knowledge rather than Chat because they are extraction pipelines that turn recordings into searchable content. + * (Ref: `web-research`, `search-index`, `extraction`, `audio-video`) + +* **Workspaces Focused On Workspaces** + * Workspaces mixed workspace types with file rules, workflow and extraction settings. + * It is now **Workspace Types** (personal, group, public), **Files & Sharing** (downloads, sharing, and shared conversation file approvals brought over from AI Models) and the existing Global Identities. + * (Ref: `workspace-types`, `files-sharing`) + +* **Workflow Is Its Own Area** + * Workflow drives approvals and assignment across every workspace type and was too large to sit as one card inside Workspaces. It now has its own group. + * (Ref: `workflow`, `workflow-settings-section`) + +#### Bug Fixes + +* **Group Workflow Assignment Dialog Could Not Open** + * The Group Workflow Assignment dialog ended up in a different tab from the button that opens it. Because an inactive tab is hidden, the dialog would not have appeared at all. + * The dialog now sits with its button, and a new check verifies this for every dialog in Admin Settings so it cannot happen again. + * (Ref: `groupWorkflowAssignmentModal`, `test_admin_settings_modal_placement.py`) + +* **Misplaced Section Comments In AI Models** + * Two section comments had drifted onto the wrong cards while settings were being regrouped, labelling the embeddings card as processing thoughts. + * (Ref: `ai-models` pane) + +### **(v0.260.013)** + +#### User Interface Enhancements + +* **General Tab Broken Up Into Focused Tabs** + * General had grown into a catch-all of eleven unrelated cards: branding sat next to health checks, API documentation, terms of use and system settings. + * Appearance now has **Branding** (branding, home page text, appearance), **Notices & Agreements** (classification banner, chat AI notice, terms of use and the user agreement pulled across from Workspaces) and **Pages & Links** (static pages plus external links). + * Health Check and API Documentation moved to Operations, which is now **Logging & Health** — they report on how the app is running rather than how it looks. + * Support moved to Help as its own **Support Menu** tab, next to Send Feedback. + * (Ref: `branding`, `notices`, `custom-pages`, `logging`, `support-menu`) + +* **Security Split Into Five Purposeful Tabs** + * Security held a single Key Vault card while an unrelated Safety tab mixed content filtering with role permissions, which are different jobs. + * Security is now **Access & Roles** (who gets in and with what role), **Secrets** (Key Vault), **Content Safety** (what may be said once you are in), **Session** (idle timeout and related system settings) and **Network** (Azure Front Door). + * (Ref: `access-roles`, `secrets`, `content-safety`, `session`, `network`) + +#### Bug Fixes + +* **"Open Key Vault Settings" Link No Longer Depends On A Hardcoded Tab** + * The link from Data Management to Key Vault switched tabs by a hardcoded id, so it silently stopped working whenever that tab was renamed. + * It now uses the standard card link, which finds the owning tab from the page itself and stays correct however the settings are grouped. + * (Ref: `data-management-key-vault-link`, `admin_card_links.js`, `admin_data_management.js`) + +* **Admin Settings Always Opens On A Real Tab** + * The tab shown on arrival was pinned to a specific id in both the markup and the sidebar script. Regrouping settings could leave Admin Settings opening with no tab selected at all. + * The landing tab is now taken from the navigation map, so it follows the settings and can never be Latest Features. + * (Ref: `admin_landing_tab`, `get_landing_tab_id`, `admin_sidebar_nav.js`) + +* **Stale Tab Names In Latest Features** + * Several Latest Features entries pointed readers at tabs by their old names after the settings moved. + * (Ref: `latest-features` pane) + ### **(v0.260.012)** #### User Interface Enhancements diff --git a/docs/explanation/release-notes/v0.261.md b/docs/explanation/release-notes/v0.261.md new file mode 100644 index 000000000..90389ba31 --- /dev/null +++ b/docs/explanation/release-notes/v0.261.md @@ -0,0 +1,1651 @@ +--- +title: "Release notes 0.261 series" +description: "SimpleChat release notes for 0.261.001." +section: "Reference" +layout: page +--- + + + +# Release notes 0.261 series + +[Back to release notes index]({{ '/explanation/release_notes/' | relative_url }}) + +{% raw %} +### **(v0.261.001)** + +#### New Features + +* **Facts And Memories Now Work In Standard Chat, Without Agents Or Actions** + * Fact memory is now a chat capability. With it enabled, the assistant recalls a user's saved memories during normal conversation and can save, change, or remove them when the user asks, such as "remember that I prefer bullet points" or "stop calling me Paul". Agents and actions can stay off. + * Previously, memory recall worked without agents but memory *writes* did not. The memory tool was only attached to the model on the Semantic Kernel agent path, so a request to remember or forget something silently did nothing unless an administrator had turned on agents. + * Writes run through a small memory-only Semantic Kernel pass after the response is already finished, so it never changes or delays the answer. An intent check runs first, so ordinary chat turns take no extra work. If a memory update fails, the chat response is unaffected. + * Instruction memories still apply to every prompt, fact memories are still recalled only when relevant, and memory activity appears in processing thoughts. Users continue to review, edit, and delete their own entries from Profile > Fact Memory. + * (Ref: `functions_fact_memory_autosave.py`, `route_backend_chats.py`, `fact_memory_plugin.py`, [#1352](https://github.com/microsoft/simplechat/issues/1352), [#1153](https://github.com/microsoft/simplechat/issues/1153)) + +* **Admin-Configurable Rate Limit Message With Markdown Support** + * A new **Security → Rate Limiting** tab in Admin Settings controls what a user is told when a request is refused with HTTP 429. The message supports Markdown, so it can link to an internal runbook or a capacity request form. + * Leaving the toggle off, or saving an empty message, keeps the built-in wording. A throttled user never receives an empty response. + * The same message now reaches every surface that returns a 429: chat, chat image generation, text to speech, the Swagger specification endpoints, and inbound MCP tool calls. Inbound MCP keeps its structured limit, window, and reset values so clients can still back off correctly. + * (Ref: `functions_rate_limit.py`, `enable_custom_rate_limit_message`, `rate_limit_message`, Security settings, [#1354](https://github.com/microsoft/simplechat/issues/1354)) + +* **All App Role Requirements In One Place** + * Ten settings across seven tabs can each require an Entra app role, which made the overall access policy impossible to read without hunting through the whole of Admin Settings. + * **Security → Access & Roles** now lists every one of them with a switch and a link to the setting in its own tab. Changing a switch here changes the setting itself. + * The list is built from the page, so a new role requirement added anywhere appears here automatically. + * (Ref: `app-role-requirements-section`, `admin_access_roles_roster.js`) + +* **Admin Settings Navigation Is Now Grouped** + * Admin Settings presented 18 tabs in one flat list. Related tabs are now collected under 12 groups such as Appearance, Knowledge, Security and Operations, so the list is scannable and has room to grow. + * In the sidebar, groups are collapsible and remember whether you left them open. In the tab layout, a row of group pills filters the tab strip to one group at a time. + * Opening a tab always reveals its group first, so a deep link or a cross-reference can never land you on a pane whose tab is hidden. + * Sidebar search now matches group names as well as tab and setting names, and expands whatever it needs to show a result. + * No settings moved in this release. Every tab keeps its contents; only the navigation around them changed. + * (Ref: `admin_settings_nav.py`, `_sidebar_nav.html`, `admin_settings.html`, `admin_sidebar_nav.js`) + +* **Admin Settings Form Field Contract Is Now Enforced** + * Admin Settings submits one form and the backend reads every value by field name, so the set of `name` attributes is the real contract between the template and the settings backend. Renaming or dropping one silently stops that setting from saving, with no error anywhere. + * A new test pins every field name against a committed baseline, and fails the build if one disappears. Adding settings is unaffected; removing one now requires regenerating the baseline in the same commit, which makes it a visible, reviewed decision. + * The same test rejects duplicate field names, which is what prevents a mirrored control from submitting a value twice. + * (Ref: `test_admin_settings_field_contract.py`, `admin_settings_field_baseline.json`) + +* **Settings That Need Another Setting Now Say So** + * Some Admin Settings options only work when a different option is enabled, and the two often live in different tabs. That was previously explained only in prose, in a tooltip, or in a warning after saving, so you could switch something on and have nothing happen with no visible reason. + * Affected cards now show an inline notice naming what they need, with a switch to enable the prerequisite without leaving the tab and a link straight to its full configuration. + * **File Sync** announces its **Redis Cache** requirement live, and keeps its save-your-intent behaviour: settings can still be saved and activate once Redis is ready. + * The **FeedbackAdmin** role control is disabled until **User Feedback** is enabled, since the role only governs access to the User Feedback report. The unrelated SafetyViolationAdmin control in the same card stays usable. + * These notices are guidance only. The server still validates every prerequisite. + * (Ref: `admin_settings_dependencies.js`, `data-requires`, File Sync, Permissions) + +* **Admin Settings Template Split Into Per-Tab Partials** + * `admin_settings.html` had grown to 13,526 lines in a single 1 MB file. Each tab pane now lives in `templates/admin/_panes/` and is included by the parent, which keeps the global form, the modals, and the script blocks. + * No settings behaviour changes: every form field name and all 110 configuration card ids are byte-identical, so the submitted payload and the settings backend are untouched. + * **Migration**: code or tests that read `templates/admin_settings.html` directly now see only the parent shell. Use `test_support.templates.read_admin_settings_template()` in functional tests, or `compose_if_admin_settings()` inside a shared file-reading helper. A new contract test fails if a test asserts on a partial-backed card or field without composing the template first. + * (Ref: `templates/admin/_panes/`, `functional_tests/test_support/templates.py`, `test_admin_settings_template_composition.py`) + +* **Shared Conversation File Approvals** + * Files generated by a participant in a shared conversation are now created immediately and held in a **pending approval** state instead of being refused, because they are saved into the conversation owner's storage. + * The conversation owner approves personal shared conversations; any group **Owner**, **Admin**, or **Document Manager** approves group shared conversations. Requesters can never approve their own file. + * Approvers get an inline **Approve / Deny** card on the pending file plus a notification. Approving releases the file, denying deletes the stored file and records who declined it. + * A staged file is not downloadable by anyone, including the requester, until it is released. + * Only downloadable deliverables are gated (CSV, XLSX, DOCX, PDF, JSON, XML). Generated images and charts are never gated. + * Unapproved files are automatically declined and deleted after 3 days, matching the existing Control Center approval window. + * New Admin Settings toggle **Require approval for participant-generated files**, enabled by default. + * (Ref: `functions_generated_file_approvals.py`, `chat-file-approvals.js`, `require_shared_conversation_file_approval`, `/api/collaboration/file-approvals`) + +* **Workflow Alert Configuration Model** + * The legacy single `alert_priority` workflow field is superseded by `alert_mode`, `alert_rules`, and `alert_evaluation` for rules-based workflow notifications. + * Existing workflows are auto-migrated on read into equivalent failed-run and completed-run notification rules. + * **Migration**: Review upgraded workflow alert rules and prune any always-notify completed-run rule that is no longer desired. + +* **New Yamcs Client Dependency** + * The Yamcs Mission Control action adds `yamcs-client==2.1.0`, the repository's first LGPL-3.0 dynamically linked pip dependency. + * SimpleChat can still start without it, but Yamcs actions return an actionable dependency error until installed. + * **Migration**: Run `pip install -r requirements.txt` or rebuild deployment images so the Yamcs client dependency is present where Yamcs actions are used. + +* **Internal Route Name Hardening** + * Blueprint security hardening changed internal route names and required broad route policy/test updates. + * Shared-conversation streaming regressions from the rename sequence were fixed in the consolidated patch history. + * **Migration**: Update any custom integrations that call SimpleChat by internal endpoint name rather than public route URL. + +* **Conversation Cache Fallback Behavior** + * Volatile chat bootstrap and conversation cache payloads no longer fall back to the Cosmos `settings` container when Redis is unavailable. + * Deployments without Redis keep full functionality, but bypass these cache benefits. + * **Migration**: Configure Redis for deployments that depend on chat bootstrap or conversation cache acceleration. + +* **Enhanced Document Extraction and Analysis** + * Azure AI Content Understanding supports AI-generated figure descriptions for PDFs/images, with Auto mode figure detection. + * Embedded Office images, including EMF/WMF diagrams and legacy DOC/PPT media, are rasterized, analyzed, and indexed as citable chunks. + * Optional Document Intelligence formula extraction adds LaTeX equation capture for PDFs when enabled. + * (Ref: Azure AI Content Understanding, Document Intelligence, embedded image extraction, formula extraction) + +* **Workflow Multi-Task Automation and Alerts** + * Workflows now support ordered instruction tasks with prior-task context chaining, per-task document actions, retry/failure handling, and configurable task limits. + * Conditional alert rules cover run status, text/regex matches, File Sync summaries, AI-judged results, and agent-raised signals across five severity levels. + * Active workflow runs can be cancelled from workspace rows, run history, or activity surfaces. + * (Ref: workflow task sequencing, workflow alert rules, `raise_workflow_alert`, run cancellation) + +* **Expanded Agent and Action Integrations** + * Yamcs and RocksDB action types add mission-control and HTTP/JSON data-service integrations. + * Inbound MCP exposes governed SimpleChat capabilities for conversations, documents, prompts, tags, and workflows. + * Action connection testing now covers OpenAPI, Maps, Blob, Databricks, Log Analytics, MCP, Snowflake, Tableau, RocksDB, Yamcs, SQL, and Cosmos DB. + * (Ref: Yamcs action, RocksDB action, MCP inbound server, action test connection) + +* **Governance, Security, and Model Administration** + * Governance policies support explicit block lists for feature and delegated item policies alongside allow rules. + * Key Vault secret expiration reminders track per-action secrets with background sweeps, notifications, and telemetry. + * Model requests can include HMAC-hashed user identity headers, and admins can configure per-model output token ceilings. + * (Ref: governance policies, Key Vault secret inventory, model endpoint identity header, output token limits) + +* **Chat Productivity, Grounding, and Notifications** + * Users can opt into response completion sounds, desktop notifications, configurable AI notices, and per-message MP3 export. + * Conversation grounding now exposes model/workspace/document/agent context, used-document panes, assistant-response forks, and a contents drawer. + * User font size preferences, generated JSON/XML export artifacts, and smarter scroll behavior improve long-session usability. + * (Ref: chat notifications, grounding citations, used documents pane, conversation fork, contents drawer, export artifacts) + +* **Workspace, Sync, and Data Management Operations** + * Azure Blob Storage File Sync adds SAS, managed identity, service principal auth, virtual-folder browsing, and ETag change detection. + * Admin operations add automatic Control Center statistics refresh, backup cleanup/retention, restore workflows, Cosmos JSON editing, Redis Explorer, feedback/safety lifecycle controls, and file-processing log cleanup. + * Multi-select metadata extraction, configurable Public Workspace naming, and index auto-login improve workspace administration. + * (Ref: File Sync, Control Center, Backup Inventory, Data Management, Redis Explorer, metadata extraction) + +* **Caching, Runtime, and Durable Processing Capabilities** + * DAI Redis read-through caches document lists, tag lists, and legacy counts with scope-version invalidation. + * Conversation list/feed caching adds Redis hit/miss metrics for Admin Settings visibility. + * Durable tabular analyze/search preflight parity, FFmpeg audio runtime support, and the model capability catalog broaden platform readiness. + * (Ref: DAI Redis cache, conversation cache metrics, tabular durable preflight, FFmpeg, model capability catalog) + +* **Latest Features Release Tiers for v0.260.001** + * Shifted the end-user Latest Features page and Admin Settings tab into current, previous, and archive release tiers for the v0.260.001 rollout. + * Preserved per-tenant visibility choices across the shift. The new v0.260.001 user-facing cards ship hidden until their placeholder screenshots are replaced, so admins publish each card once its real capture is in place. + * (Ref: Latest Features release groups, support catalog, admin catalog, visibility normalization) + +* **Deeper End-User Feature Cards** + * Added 20 v0.260.001 end-user cards with seven concrete How To Try It steps and a three-image gallery each. + * Expanded the Latest Features card helper with the `images=[...]` gallery form for multi-image cards. + * (Ref: `_latest_feature_card`, `_SUPPORT_RELEASE_260_FEATURE_CATALOG`, Latest Features image galleries) + +* **Admin Latest Features Archive Tier** + * Brought the Admin Settings Latest Features tab to the same three-tier current, previous, and archive model used by the end-user page. + * Keeps v0.250.001 admin cards and older v0.241.x admin highlights available without crowding the current release tier. + * (Ref: `_ADMIN_LATEST_FEATURE_RELEASE_GROUPS`, `_ADMIN_RELEASE_260_FEATURE_CATALOG`, Admin Settings Latest Features tab) + +* **Latest Features PR Workflow Hooks** + * Added a Latest Features authoring prompt, PR template checklist, and CI warning path so feature PRs consider release notes, cards, and screenshots together. + * Helps future releases keep in-app Latest Features content aligned with shipped user and admin changes. + * (Ref: `.github/prompts/update-latest-features.prompt.md`, `.github/PULL_REQUEST_TEMPLATE.md`, `release-notes-check.yml`) + +* **Documentation Site Redesign** + * The documentation site was rebuilt for search, navigation, page simplicity, mobile support, and content coverage. + * Search now indexes page content instead of titles only. Previously 84% of the 986 indexed pages were internal engineering notes, 88% of entries had no description, and no page body text was indexed at all, so a search for "agent" returned mostly internal fix notes. The index is now 165 entries with a description on every one and no engineering notes. + * Added a dedicated search results page with section filters and highlighted excerpts, a `Ctrl+K` shortcut, keyboard navigation, and a full-screen mobile search sheet. Search was previously hidden entirely on phones. + * Navigation was rebuilt so the top bar and sidebar expose the same six sections: Start, Guides, Features, Administration, Deploy and operate, and Reference. Coverage went from 27 links to 74, all verified to resolve. + * (Ref: `docs/search-index.json`, `docs/assets/js/search.js`, `docs/_config.yml` navigation, `docs/search.md`) + +* **Screenshot and Video Placeholders for Documentation** + * Documentation pages can now declare a screenshot or video slot. When the asset does not exist yet the page renders a visible card naming the exact file path to create; adding the file at that path replaces the placeholder automatically on the next build with no configuration or code change. + * Videos render as a local poster card that links out to YouTube or Microsoft Stream, so no video files are committed to the repository and no third-party embed scripts are loaded. + * Added a media status page listing every slot and whether it is filled, as a capture worklist for contributors. + * (Ref: `docs/_includes/media.html`, `docs/_data/media.yml`, `docs/contributing/media-status.md`) + +* **Complete Documentation Coverage of the Application** + * Added one page per admin settings tab covering what the tab controls, why it matters, every setting with its default and governing settings key, prerequisites, and the common tasks admins perform there. + * Added task guides for creating actions, agents, agents with actions, multi-task workflows, triggering workflows, file sync connectors, tags, tags in chat, tags on conversations, and exporting conversations, plus further guides derived from the application surface. Each guide explains what the task does and why before the steps. + * Added a chat interface reference covering all 47 chat controls and an action reference covering all 27 actions. + * Added a feature catalog in which every one of the 111 capability toggles is claimed by exactly one capability entry. + * (Ref: `docs/admin/`, `docs/guides/`, `docs/reference/chat-controls.md`, `docs/reference/actions/`, `docs/_data/features.yml`) + +* **Documentation Coverage Enforcement** + * Added a generated inventory of the application surface and functional tests that fail when a new capability toggle, admin settings tab, action plugin, or chat control ships without documentation, so coverage stays complete as changes land. + * (Ref: `scripts/build_docs_inventory.py`, `functional_tests/test_docs_app_surface_coverage.py`, `functional_tests/test_docs_site_quality.py`) + +* **Workspace Documents Are Now Configured Per Workflow Task** + * Each task in a workflow now owns its own **Workspace documents** setup — document action, document target, selected documents, Compare source and targets, per-document analysis, and windowing — instead of sharing one configuration across the whole workflow. + * Adding a task resets the document fields, and returning to a previously configured task restores that task's setup, so tasks are self-contained. + * Every task now executes with its own document action at run time. Previously the single workflow-level action only ever applied to task 1, and every later task ran with no document context. + * Existing workflows keep working: their saved document action is inherited by task 1 only, matching how they actually ran. Group workflows still force every task into the owning group workspace. + * Task cards and the Review step now summarize which documents each task uses. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `workspace_workflows.js`, `functions_personal_workflows.py`, `functions_group_workflows.py`, `functions_workflow_runner.py`, per-task document actions) + +* **Optional Mathematical Formula Extraction** + * Added an **Extract mathematical formulas** toggle to the Document Intelligence settings. When enabled, equations in PDFs and images are captured as LaTeX instead of being approximated as OCR text. + * This requests a **billed Document Intelligence add-on**, so it is off by default and must be turned on deliberately. It applies to the Layout model only, so it has no effect while extraction is set to Standard. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_content.py`, `functions_settings.py`, `admin_settings.html`, Document Intelligence formulas add-on) + +* **Index Auto-Login** + * Added an opt-in `ENABLE_AUTO_LOGIN_ON_INDEX` setting that redirects unauthenticated home-page visits to the existing Microsoft Entra sign-in flow. + * Supports government tenant SSO scenarios where users already have a browser session and should enter SimpleChat without first clicking the sign-in link. + * (Ref: `app.py`, `config.py`, `INDEX_AUTO_LOGIN.md`, Microsoft Entra sign-in) + +* **Enhanced Extraction Now Uses Azure AI Content Understanding** + * Enhanced extraction for PDFs and images now uses Azure AI Content Understanding (`prebuilt-documentSearch`) instead of Document Intelligence Layout. In addition to tables, page structure, and checkbox states, it returns AI-generated descriptions of figures, charts, and diagrams — structure Document Intelligence never produced. + * Standard extraction is unchanged and always uses Document Intelligence, which remains required for workspaces and chat file uploads. + * A new **Enable Enhanced extraction** toggle in Admin Settings reveals the Content Understanding configuration. Turning it on defaults the extraction mode to **Auto**, so documents are only upgraded when the sample shows structure worth paying for. + * Content Understanding supports both key and managed identity authentication, with a **Test Connection** button and an in-app setup guide covering Foundry resource creation, supported regions, required model deployment defaults, and the Cognitive Services User role. + * Enhanced never becomes a hard dependency. Content Understanding is not offered in Azure Government, so Enhanced automatically uses Document Intelligence Layout in Government and custom clouds — the admin UI says so plainly and there is nothing to configure there. Enhanced also falls back when Content Understanding is unconfigured or a request fails, and the reason is recorded on the document and shown in workspace tooltips. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_content_understanding.py`, `functions_content.py`, `functions_settings.py`, `route_backend_settings.py`, `admin_settings.html`, `CONTENT_UNDERSTANDING_ENHANCED_EXTRACTION.md`) + +* **Images Inside Word and PowerPoint Files Are Now Analyzed** + * Neither extraction engine describes figures inside Office files, so SimpleChat now pulls embedded images out of DOCX and PPTX packages and analyzes them with whichever engine backs the selected extraction mode — Content Understanding when Enhanced is active, Document Intelligence otherwise. This works with Standard extraction too. + * Each analyzed image is indexed as its own citable chunk, and PowerPoint images are attributed to the slide that references them. + * Cost is bounded by design: icons, bullets, and spacer graphics are filtered out by a configurable minimum size, byte-identical images such as repeated header logos are analyzed once, and a per-document cap limits the total. + * Uploaded Office files are treated as untrusted: extracted file names are generated rather than reused from the archive, entries are streamed with a hard byte ceiling instead of trusting the archive's declared size, compression methods and entry counts are bounded, and slide relationship parts are parsed with a hardened XML parser. + * Can be turned off entirely with **Analyze images embedded in DOCX and PPTX files**. Image analysis failures never fail the document. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_office_media.py`, `functions_documents.py`, embedded Office image analysis) + +* **Test Connection for Eight More Action Types** + * Added a **Test Connection** button to the Step 3 configuration for OpenAPI, Azure Maps, Blob Storage, Databricks, Log Analytics, MCP, Snowflake, and Tableau actions. Previously only SQL, Cosmos DB, Yamcs, and RocksDB actions could be validated before saving. + * Each test authenticates with the credentials entered in the modal and performs one lightweight read against the configured resource, so a wrong warehouse ID, container name, subscription key, personal access token, or MCP endpoint is caught immediately instead of failing later during a chat. + * Failures name the cause — rejected credentials, a missing warehouse or container, an unreachable host, or a driver that is not installed — and successes report useful detail such as the Databricks warehouse state, the Snowflake version, the Tableau API version, or the MCP tool count. + * Editing an existing action works without retyping credentials: masked secrets and reusable workspace identities are resolved server-side for the test only, and no credential value is ever returned to the browser. + * The MCP test enforces the same stdio scope restriction and outbound destination policy as MCP tool discovery, and it does not overwrite discovered tool metadata. + * (Ref: [#1267](https://github.com/microsoft/simplechat/issues/1267), `functions_action_connection_tests.py`, `route_backend_plugins.py`, `_plugin_modal.html`, `plugin_modal_stepper.js`, `ACTION_TEST_CONNECTION.md`) + +* **RocksDB Action** + * Added a new `rocksdb` action type so agents can read an ordered [RocksDB](https://github.com/facebook/rocksdb) key-value store, with a dedicated configuration card and Test Connection button in the action modal. + * RocksDB is an embedded library with no network protocol, so the action calls a RocksDB-backed HTTP/JSON service that you operate alongside your data. SimpleChat never runs RocksDB locally or opens a database directory on the application host. + * Supports no-auth, bearer token, and API key header authentication with a configurable header name. TLS certificate validation is always enforced. + * Exposes `get_value`, `get_values`, `key_exists`, `scan_prefix`, `scan_range`, `list_column_families`, and `get_database_stats` for reads, plus `put_value`, `delete_value`, and `write_batch` that stay blocked until an action explicitly allows writes. + * Handles binary data through configurable UTF-8, base64, and JSON key and value encodings that are sent to the service on every request, caps returned records, and flags values truncated by the size limit. + * The RocksDB HTTP service contract is fully documented so operators can implement a conforming service. + * (Ref: `rocksdb_plugin.py`, `route_backend_plugins.py`, `plugin_health_checker.py`, `_plugin_modal.html`, `plugin_modal_stepper.js`, `rocksdb.definition.json`, `test_rocksdb_plugin.py`, `test_workspace_rocksdb_action_modal.py`, `docs/explanation/features/v0.250.216/ROCKSDB_ACTION.md`) + +* **Agent Instruction Context References (`#action` and `#knowledge`)** + * Instructions can now reference the exact actions, action capabilities, and assigned knowledge that were selected for the agent, so authors can spell out *when* and *why* each capability or document should be used. + * Typing `#` in the Instruction Brief or the instructions editor opens an autocomplete that drills down from the `action` / `knowledge` namespace, to the actions selected in the Actions step, to that action's enabled capabilities. `#knowledge:` lists the assigned documents, workspaces, tag limits, and web sources with type badges. + * Tokens such as `#action:"Simple Chat":create_group` and `#knowledge:doc:"Employee Handbook.pdf"` are stored literally with the instructions so they stay editable and round-trip unchanged when an agent is edited. Values containing a space or colon are quoted automatically. + * Navigate with the arrow keys, insert with `Tab` or `Enter`, dismiss with `Esc`, or use the mouse. Document titles containing spaces stay searchable while typing. + * Foundry agents manage their instructions and tools in Foundry, so the references stay inert for Classic Foundry, New Foundry, and Foundry Workflow agents. + * (Ref: [#1257](https://github.com/microsoft/simplechat/issues/1257), [#1263](https://github.com/microsoft/simplechat/pull/1263), `agent_instruction_mentions.js`, `agent_modal_stepper.js`, `_agent_modal.html`) + +* **Context-Aware Draft Instructions** + * The **Draft Instructions** helper now receives the selected actions with their enabled capabilities and the assigned knowledge configuration, instead of only the agent name, description, and brief. + * Drafts reference only real, selected actions and documents, and use the new `#action:` / `#knowledge:` token convention. + * Client-supplied context is normalized, length-capped, count-capped, and bounded by a shared total character budget on the backend. It is used purely as prompt text and never affects authorization, and whitespace collapsing prevents newline-based prompt injection through action or document names. + * (Ref: [#1257](https://github.com/microsoft/simplechat/issues/1257), [#1263](https://github.com/microsoft/simplechat/pull/1263), `route_backend_agents.py`, `POST /api/agents/draft-instructions`) + +* **Workflow Alert Rules** + * Workflow alerts are now conditional. Instead of a single Pop-up Alert Priority that notified on every run, a workflow can define rules that describe *why* it should notify you, and a run that matches nothing stays completely silent. + * Conditions cover run status, task status, output text (contains, does not contain, or regex), File Sync results, empty output, an agent-raised signal, and a plain-English condition judged by a model, such as "any certificate expires within 14 days." + * Each rule can be scoped to the final output, any task output, or one specific task. + * Model-judged conditions are batched into a single call per run and skipped entirely when a deterministic rule already matched at a higher severity, so workflows that use only deterministic conditions add no model calls. + * (Ref: `functions_workflow_alerts.py`, `functions_workflow_runner.py`, `functions_personal_workflows.py`, `functions_group_workflows.py`, `workspace_workflows.js`, `WORKFLOW_ALERT_RULES.md`) + +* **Expanded Alert Severities and a Distinct Failure Style** + * The severity ladder grew from low/medium/high to **info, low, medium, high and critical**. + * Info and low alerts land quietly in the notification bell, while medium and above open the pop-up. Any rule can override this. + * Runs that error now carry a separate *failure* category that changes the icon and wording independently of severity, so "the workflow broke" is visually distinct from "the workflow found something." + * When several rules match the same run, the highest severity wins and the alert lists every matched rule with its reason under a new "Triggered by" section. + * (Ref: `functions_notifications.py`, `notifications.js`, `base.html`, workflow alert modal) + +* **Agent-Raised Workflow Alerts** + * Agents running inside a workflow can now raise an alert signal mid-run with severity, title and reason through the new `raise_workflow_alert` SimpleChat capability, and an `agent_signal` rule decides whether it notifies anyone. + * The rule's severity acts as a floor the agent can escalate above but never quiet below, and named signals can route to their own rules. + * The capability is opt-in and refuses outside an active workflow run, so existing agents do not gain the ability to create notifications and a normal chat cannot fabricate one. + * (Ref: `simplechat_plugin.py`, `functions_simplechat_operations.py`, `agent_modal_stepper.js`, `plugin_modal_stepper.js`) + +* **Alert Decision Visibility** + * Each run now records why it did or did not alert, including the winning severity and every matched rule, surfaced through the workflow activity view so noisy or silent workflows can be diagnosed. + * (Ref: `functions_workflow_activity.py`, `functions_workflow_runner.py`) + +* **Yamcs Mission Control Action** + * Added a first-class, read-only `yamcs` action type that connects agents to a Yamcs mission control server using the official `yamcs-client` Python package. + * Exposes eleven read-only tools: instances, data links, mission database parameters and parameter detail, command *definitions*, live parameter values, parameter history, events, packets, alarms, and an optional guarded archive SQL query. + * Strictly read-only by design. The action cannot issue commands, set parameter values, run scripts, or enable/disable data links, and command listing returns definitions only. + * Archive SQL is disabled by default and, when enabled, is restricted to `SELECT`, `SHOW`, `DESC`, and `DESCRIBE` statements with a forbidden-keyword guard and an automatic row limit. + * Every retrieval is bounded by a row limit, a serialized byte limit, and a request timeout so a broad query cannot walk an entire archive, and error text is scrubbed of credentials. + * (Ref: `functions_yamcs_operations.py`, `semantic_kernel_plugins/yamcs_plugin.py`, `semantic_kernel_plugins/yamcs_plugin_factory.py`, `docs/explanation/features/YAMCS_ACTION.md`) + +* **Yamcs Action Configuration Panel and Test Connection** + * Added a dedicated Yamcs configuration section to the Add/Edit Action modal covering server URL, instance, processor, authentication, TLS verification, archive SQL opt-in, and retrieval limits. + * Supports username/password, API key, bearer token, and unauthenticated Yamcs servers, plus reusable workspace identities using `api_key`, `bearer_token`, or `username_password`. + * Added a **Test Yamcs Connection** button backed by `POST /api/plugins/test-yamcs-connection`, which verifies reachability and credentials and confirms the configured instance exists. Saved actions resolve their stored credential from Key Vault, so secrets do not need to be re-entered to run a test. + * (Ref: `_plugin_modal.html`, `plugin_modal_stepper.js`, `route_backend_plugins.py`, `workspace/view-utils.js`) + +* **Governance Policy Block Lists** + * Added admin-managed block lists for feature and delegated item governance policies so specific users or groups can be denied even when allow-all or allow-list rules would otherwise grant access. + * Enables administrator-friendly APIM quota-tier separation, such as allowing a high-threshold group to a high endpoint while blocking that group from a default low-threshold endpoint without maintaining a large low-user allow list. + * (Ref: [#1252](https://github.com/microsoft/simplechat/issues/1252), `functions_governance.py`, `route_backend_governance.py`, `admin_governance.js`, MCP governance) + +* **Model Endpoint Identity Header** + * Added admin controls to send a stable HMAC-hashed user identity key with model endpoint requests for APIM counters, quota policies, and backend routing policies. + * Supports global enablement, custom safe header names, selectable identity inputs, and per-endpoint inherit/enable/disable overrides without exposing raw UPN, object ID, or tenant ID values. + * (Ref: [#1250](https://github.com/microsoft/simplechat/issues/1250), Model Endpoint Identity Header, `functions_model_endpoint_identity_header.py`, model endpoint runtime, Admin Settings) + +* **Tabular Analyze/Search Durable Preflight Parity** + * Unified exhaustive tabular Search and Analyze requests behind a shared route-neutral planner that can queue durable work before bounded foreground tools or immediate synthesis run. + * Preserved truthful pending, failed, canceled, and completed evidence across pure tabular, mixed-source, per-document, and multi-table workflows, including deferred mixed-source composition and public lifecycle coverage. + * Added backend-only shadow and canary controls, privacy-safe telemetry and status metadata, and evidence-backed legacy fallback retirement while reusing existing authorization, source-version, rollback, and artifact-card contracts. + * (Ref: [#1031](https://github.com/microsoft/simplechat/issues/1031), [#1055](https://github.com/microsoft/simplechat/issues/1055), [#1058](https://github.com/microsoft/simplechat/issues/1058), `functions_tabular_orchestration.py`, `functions_workflow_runner.py`, `route_backend_chats.py`) + +* **Chat Used Documents Pane** + * Added a Used Documents mode to the existing chat conversation side pane so users can review documents that were actually cited in the conversation without opening the full details modal. + * Reuses the same conversation metadata document tags as the details modal, excludes selected-but-unused documents, and auto-opens once when cited documents first appear. + * (Ref: [#1209](https://github.com/microsoft/simplechat/issues/1209), conversation contents drawer, cited document metadata, `chat-conversation-contents.js`, `chat-conversation-details.js`) + +* **Configurable Workflow Task Limit** + * Added an admin setting that controls how many ordered instruction tasks users can add to a workflow. + * The default is 50 tasks, with backend and browser enforcement clamped to a supported range of 1-100 tasks. + * (Ref: workflow task sequences, Admin Settings Workflow section, `functions_personal_workflows.py`, `workspace_workflows.js`) + +* **Key Vault Reminder Contact Email Telemetry Opt-In** + * Added a default-off admin setting that allows Key Vault reminder contact email addresses to be included in the external Application Insights telemetry event for direct Azure Monitor, Logic App, Function, or webhook routing. + * Kept raw secret names redacted from external telemetry and added Reminder ID visibility/search in the admin inventory for fixed admin-channel alert workflows. + * (Ref: [#1156](https://github.com/microsoft/simplechat/issues/1156), `functions_appinsights.py`, `functions_keyvault_reminders.py`, Admin Key Vault reminder external alert guidance) + +* **Key Vault Reminder External Telemetry** + * Added a privacy-safe, queryable Application Insights event when Key Vault expiration reminder notifications are created, enabling Azure Monitor scheduled query alerts, action groups, Logic Apps, Functions, or webhooks for external notification workflows. + * Added admin and feature documentation guidance with a sample KQL query while avoiding raw secret names and email values in telemetry dimensions. + * (Ref: [#1156](https://github.com/microsoft/simplechat/issues/1156), `functions_appinsights.py`, `functions_keyvault_reminders.py`, Azure Monitor external notification guidance) + +* **Key Vault Expiration Reminder Inventory** + * Added SimpleChat-managed Key Vault secret expiration reminder tracking with per-action reminder metadata, expiration dates, lead days, reminder contact email, friendly labels, and rotation notes. + * Added an admin Key Vault reminder dashboard that maps generated Key Vault secret names back to SimpleChat scope, source action, field, owner/contact context, sync status, and remediation details. + * Added a background reminder sweep and `key_vault_secret_expiring` in-app notifications while preserving Azure Monitor/Event Grid as the recommended email alert path. + * (Ref: [#1156](https://github.com/microsoft/simplechat/issues/1156), `functions_keyvault_reminders.py`, `admin_settings.html`, `plugin_modal_stepper.js`, Key Vault reminder inventory) + +* **Generated JSON and XML Export Artifacts** + * JSON and XML generation requests can now save valid generated output as downloadable chat artifacts instead of leaving large file-shaped content in the assistant response. + * Document Analyze and generated export flows now recognize natural JSON/XML conversion and XML template-population phrasing, with XML serialization support added to durable generated exports. + * XML document processing now uses a consolidated token-aware pipeline for more reliable analysis and export workflows. + * (Ref: [#1071](https://github.com/microsoft/simplechat/issues/1071), `functions_generated_file_exports.py`, generated analysis artifacts, XML document processing) + +* **Model Capability Catalog** + * Added an initial JSON source of truth for model feature capabilities across OpenAI GPT-5+, recent Claude models, Meta Llama and Code Llama, xAI Grok, and Microsoft Phi/MAI models. + * Catalog entries track support for text, image, audio, video, binary/file input, coding optimization, tool calling, and structured output so future multimodal routing can move away from regex-only model-name checks. + * This release is data-only and does not change backend or frontend runtime behavior. + * (Ref: Closes [#1147](https://github.com/microsoft/simplechat/issues/1147), `model_capabilities.json`, model capability detection) + +* **Per-Model Response Length Overrides** + * Administrators can now set an optional response-length/output-token ceiling on each model in global multi-endpoint GPT configuration. + * Standard chat applies the selected model's configured ceiling with the correct backend token parameter for GPT-5/o-series aliases and other OpenAI-compatible chat models. + * Existing endpoint model records remain compatible when the field is blank or absent. + * (Ref: Closes [#1143](https://github.com/microsoft/simplechat/issues/1143), related [#1047](https://github.com/microsoft/simplechat/issues/1047) and [#358](https://github.com/microsoft/simplechat/issues/358), `functions_settings.py`, `route_backend_chats.py`, `admin_model_endpoints.js`) + +* **Configurable Public Workspace Display Name** + * Admins can now set an optional end-user display name for Public Workspace, capped at 32 characters, so organizations can present tenant-specific terms such as "Domain Knowledge". + * End users see the configured label across navigation, Profile, Public Directory, Public Workspace pages, chat scope selection, and related browser messages while admin settings and internal identifiers continue to use Public Workspace/public_workspace. + * Empty or unset values preserve the existing Public Workspace/Public Workspaces defaults. + * (Ref: [#1146](https://github.com/microsoft/simplechat/issues/1146), `functions_settings.py`, `admin_settings.html`, public workspace templates and JavaScript, `PUBLIC_WORKSPACE_DISPLAY_NAME.md`) + +* **Backup Cleanup and Retention Policy Controls** + * Added Data Management backup cleanup controls so administrators can manually delete backup artifacts and metadata from Backup Inventory. + * Added unit-based backup retention settings for days, weeks, months, and years, with automatic cleanup that preserves the newest successful full backup as a restore safety baseline. + * Cleanup removes stored backup blobs, job timeline records, and differential sidecar state so future partial backups re-export affected unchanged items instead of pointing to deleted artifacts. + * (Ref: Closes [#1130](https://github.com/microsoft/simplechat/issues/1130), `functions_data_management.py`, `route_backend_data_management.py`, `admin_settings.html`, `admin_data_management.js`) + +* **Multi-Select Metadata Extraction** + * Personal, group, and public workspace document multi-select bars now include an **Extract Metadata** action when metadata extraction is enabled. + * Selected documents are queued through the shared metadata extraction background workflow, preserving generated titles along with authors, abstracts, keywords, publication dates, and organization metadata. + * (Ref: Closes [#1134](https://github.com/microsoft/simplechat/issues/1134), `route_backend_documents.py`, `route_backend_group_documents.py`, `route_backend_public_documents.py`, workspace document multi-select actions) + +* **Data Management Backup Restore Workflow** + * Added an admin-only restore workflow for completed Data Management backups, with manifest preflight, create-only default policy, explicit overwrite confirmation, durable restore jobs, cancellation/retry support, and sanitized progress in Job History. + * Restore supports configured target Cosmos DB, AI Search, and Enhanced Citation blob targets while preserving secret-safe review and job responses. + * (Ref: Closes [#1091](https://github.com/microsoft/simplechat/issues/1091), `functions_data_management.py`, `functions_data_management_restore_state.py`, `route_backend_data_management.py`, `admin_settings.html`, `admin_data_management.js`, `DATA_MANAGEMENT_RESTORE.md`) + +* **Reviewed, Scalable Data Migration Workflow** + * Replaced the Admin Data Management migration form with a six-stage Target, Scope, Content & Options, Review, Confirm, and Progress workflow. + * Added server-paginated principal catalogs, exhaustive all-mode counts, persistent cross-page selections, sanitized preflight checks, single-use administrator-bound review authorization, settings-drift protection, separate destructive confirmation, duplicate-submit prevention, and inline durable job recovery controls. + * (Ref: Closes [#1097](https://github.com/microsoft/simplechat/issues/1097), `functions_data_management.py`, `route_backend_data_management.py`, `admin_settings.html`, `admin_data_management.js`) + +* **Configurable AI Response Completion Audio Cues** + * Administrators can enable locally bundled completion sounds, while each user can opt in, choose and preview one of ten cues, set volume, or mute cues without losing their preferences. + * Cues play once for newly completed personal-chat responses outside the active visible conversation, with server-authoritative gating, cross-tab preference synchronization, and historical/duplicate suppression. + * (Ref: Closes [#1062](https://github.com/microsoft/simplechat/issues/1062), `completion-audio-cues.js`, notification polling, Profile and Admin Settings, `AI_RESPONSE_COMPLETION_AUDIO_CUES.md`) + +* **High-Throughput Resumable Source Blob Backups** + * Source document backups now stream bounded Azure SDK blocks with configurable file concurrency and chunk size instead of buffering complete blobs or copying files serially. + * Added durable per-file verification and resume, source/target generation fencing, adaptive Retry-After-aware throttling, isolated file failures, authenticated chunked encryption, throughput telemetry, and a reproducible AzCopy/server-copy/SDK benchmark harness. + * (Ref: Closes [#1095](https://github.com/microsoft/simplechat/issues/1095), `functions_data_management.py`, `test_data_management_blob_backup_transfers.py`, `benchmark_data_management_blob_backup.py`, `DATA_MANAGEMENT_BLOB_BACKUP_THROUGHPUT.md`) + +* **Desktop Conversation Notifications** + * Administrators can enable operating system notifications for completed AI responses, and users can manage their own preference from Profile. + * Notifications appear only while SimpleChat is open in a hidden or unfocused tab, show the application and conversation titles without response content, and focus the existing tab when selected. + * (Ref: Fixes [#866](https://github.com/microsoft/simplechat/issues/866), `chat-desktop-notifications.js`, `chat-streaming.js`, Profile and Admin Settings) + +* **Automatic Overnight Control Center Statistics Refresh** + * Added an enabled-by-default daily Control Center metrics refresh at 2:00 AM Eastern, with an administrator toggle and configurable time under Admin Settings > Control Center. + * The recurring schedule follows Eastern daylight-saving changes, stores concrete execution timestamps in UTC, and shows last-run and next-run values in each administrator's browser timezone. + * (Ref: Closes [#706](https://github.com/microsoft/simplechat/issues/706), `functions_control_center.py`, `background_tasks.py`, `admin_settings.html`, `control-center.js`) + +* **Configurable Chat AI Notice** + * Administrators can display custom plain-text AI guidance directly below the chat composer. + * Supports non-dismissible, per-session, daily, and once-per-message-version behavior with validated dismissal persistence and automatic redisplay when the configured notice changes. + * (Ref: [#715](https://github.com/microsoft/simplechat/issues/715), `functions_ai_notice.py`, `admin_settings.html`, `chats.html`, `chat-ai-notice.js`) + +* **Per-Message Audio Export** + * Users can export completed user and assistant chat messages as MP3 audio when text-to-speech is enabled. + * Downloads reuse the active Azure Speech voice and speed, include only visible message text, and remain transient without storing generated audio in SimpleChat. + * (Ref: [#628](https://github.com/microsoft/simplechat/issues/628), `chat-tts.js`, `chat-message-export.js`, `chat-messages.js`, `MESSAGE_AUDIO_EXPORT.md`) + +* **Adaptive Exhaustive Azure AI Search Backups** + * Azure AI Search backups now export personal, group, and public indexes through deterministic keyset-paged artifacts with durable checkpoints, exact resume behavior, schema validation, and restore-readiness integrity status. + * Added fair bounded concurrency, Retry-After-aware handling for throttling and service interruptions, adaptive pressure reduction and recovery, and sanitized per-index throughput and failure metrics. + * (Ref: Closes [#1094](https://github.com/microsoft/simplechat/issues/1094), `functions_data_management.py`, `test_data_management_ai_search_backup_export.py`, `DATA_MANAGEMENT_BACKUP_MIGRATION.md`) + +* **Conversation Context Grounding** + * Models and agents now receive bounded, credential-sanitized metadata for every user turn, including the active model, SimpleChat version, workspace scope, selected documents, agent, and capability state. + * Each assistant response exposes the identical snapshot as a visible Conversation Context citation across streaming, non-streaming, retry, fallback, collaboration, and document-action paths. + * (Ref: [#508](https://github.com/microsoft/simplechat/issues/508), `functions_conversation_context.py`, `route_backend_chats.py`, `functions_workflow_runner.py`) + +* **MCP Current-State Platform** + * Added the governed inbound SimpleChat MCP server with a bounded personal tool surface for conversations, documents, prompts, tags, workflow discovery, and workflow execution. + * Hardened outbound MCP actions with presets, server-side preconfiguration catalogs, destination governance, custom headers, result policy controls, and redaction-safe discovery/runtime telemetry. + * (Ref: [#1013](https://github.com/microsoft/simplechat/issues/1013), [#1014](https://github.com/microsoft/simplechat/issues/1014), [#1015](https://github.com/microsoft/simplechat/issues/1015), [#1017](https://github.com/microsoft/simplechat/issues/1017), [#1018](https://github.com/microsoft/simplechat/issues/1018), MCP current-state roadmap) + +* **Bounded Parallel Cosmos Backup Export and Source Capacity Recovery** + * Cosmos backup export now streams deterministic JSONL checkpoint batches through configurable bounded concurrency, preserving durable fencing, latest-item state, cancellation, retry/resume, and recovery semantics without materializing complete containers in memory. + * Added bounded `408`, `429`, `449`, and `5xx` retry with Retry-After-aware jittered backoff, adaptive staging pressure, sanitized per-container and aggregate RU/rate/retry telemetry, and deterministic no-replay checkpoint outcomes. + * Added opt-in local/source Cosmos throughput boosts capped at 10,000 RU/s with topology discovery, immutable pre-mutation snapshots, fenced restore-pending recovery, safe external-change protection, minimum ARM role support in Terraform, and explicit fail-or-continue policy for unsupported or denied capacity mutations. + * (Ref: Closes [#1093](https://github.com/microsoft/simplechat/issues/1093), `functions_data_management.py`, `admin_data_management.js`, `test_data_management_backup_parallelism.py`, `DATA_MANAGEMENT_BACKUP_MIGRATION.md`) + +* **Admin Feedback and Safety Record Lifecycle** + * Added archive, unarchive, and permanently delete actions to the Feedback Review and Safety Violations admin pages, with active/archived filtering across lists, cards, statistics, pagination, and CSV exports. + * Archived records are hidden from user profile history, destructive deletion requires confirmation, and safety violations with pending remediation approvals cannot be deleted. + * Archive, unarchive, and delete actions create non-sensitive admin activity audit records, while audit persistence failures are surfaced without undoing successful lifecycle changes. + * (Ref: [#991](https://github.com/microsoft/simplechat/issues/991), `functions_review_lifecycle.py`, `route_backend_feedback.py`, `route_backend_safety.py`, `ADMIN_REVIEW_RECORD_LIFECYCLE.md`) + +* **File Processing Log Cleanup** + * Added admin controls to permanently delete file-processing logs older than a chosen number of days, weeks, or fixed 30-day months, or delete every stored log through a separate action. + * Added explicit confirmation, exact and partial deletion counts, admin activity logging, validation, and secured cross-partition Cosmos DB cleanup. + * (Ref: [#398](https://github.com/microsoft/simplechat/issues/398), `functions_logging.py`, `route_frontend_admin_settings.py`, `admin_settings.js`, `FILE_PROCESSING_LOG_CLEANUP.md`) + +* **Conversation Contents Drawer** + * Added an admin-controlled, default-on conversation contents drawer that indexes persisted user messages and lets users jump directly to earlier prompts in long chats. + * Added a default-on user profile preference so each user can hide the drawer while the global admin feature remains enabled. + * (Ref: [#1026](https://github.com/microsoft/simplechat/issues/1026), `chat-conversation-contents.js`, `admin_settings.html`, `profile.html`) + +* **Fork Personal Conversations from Assistant Responses** + * Added a Fork conversation action for persisted assistant messages, creating an independent personal conversation containing the active history through the selected response while leaving the source unchanged. + * Forks remap conversation, message, thread, reply, and artifact identifiers; copy blob-backed attachments to independent paths; reject unauthorized or changed sources; and clean up failed copies before they become visible. + * Added confirmation, duplicate-click prevention, failure feedback, immediate fork navigation, backend regression coverage, and browser workflow coverage. + * (Ref: [#1025](https://github.com/microsoft/simplechat/issues/1025), `functions_simplechat_operations.py`, `route_backend_conversations.py`, `chat-messages.js`, `FORK_CONVERSATION.md`) + +* **User Font Size Preferences** + * Added persisted XS, S, M, L, and XL font-size choices to the user profile, ranging from 75% to 200% with medium as the default. + * Font-size selections preview immediately and apply across SimpleChat after the user saves the preference. + * (Ref: [#1099](https://github.com/microsoft/simplechat/issues/1099), `profile.html`, `functions_settings.py`, `FONT_SIZE_AND_200_PERCENT_ZOOM_FIX.md`) + +* **Durable Data Management Backup Jobs** + * Full and partial backups now persist immutable plans and source cutoffs, fenced attempts, resource/batch checkpoints, and latest-only Cosmos, AI Search, and Blob item state without mutating source records or metadata. + * Added source-scoped overlap protection, authenticated cancellation and focused retry/resume controls, stale/queued worker recovery, bounded sanitized progress, and explicit non-destructive differential/deletion semantics in backup manifests. + * (Ref: Closes [#1092](https://github.com/microsoft/simplechat/issues/1092), `functions_data_management.py`, `functions_data_management_backup_state.py`, `DATA_MANAGEMENT_BACKUP_MIGRATION.md`) + +* **Azure Blob Storage File Sync** + * Added Azure Blob Storage as an admin-controlled File Sync source for personal, group, and public workspaces, with account, container, prefix, selected-path, filter, tag, schedule, and remote-delete controls. + * Added managed identity, Key Vault-backed service principal and connection string authentication, connection testing, virtual-folder browsing, ETag change detection, and streamed ingestion through the existing document pipeline. + * (Ref: [#1027](https://github.com/microsoft/simplechat/issues/1027), `functions_file_sync.py`, `workspace-file-sync.js`, `AZURE_BLOB_STORAGE_FILE_SYNC.md`) + +* **Task-Level Workflow Model and Agent Selection** + * Each ordered workflow task can now inherit the workflow's Default Runner or select its own authorized Direct Model or Agent. + * Task runners are normalized on save and revalidated before execution, including current personal/group/global agent scope, group membership, and enabled model endpoint/model availability. + * Unavailable runners follow the workflow's retry and stop-or-continue strategy, while task run items record non-secret runner audit details, execution deployment/provider, output preview, and token usage when available. + * Existing tasks without runner configuration inherit the workflow default, and workflows without task sequences retain the legacy execution path. + * (Ref: [#1084](https://github.com/microsoft/simplechat/issues/1084), `functions_personal_workflows.py`, `functions_group_workflows.py`, `functions_workflow_runner.py`) + +* **Configurable Content Safety Violation Messages** + * Administrators can now configure the Markdown message shown when Content Safety blocks a chat request using the standard Markdown editor toolbar. + * A new setting controls whether the block reason, detected categories and severities, and blocklist matches are included beneath the custom message. + * The editor now renders correctly when the hidden Safety tab opens, and Markdown-only edits activate Save Settings before submission. + * (Ref: [#989](https://github.com/microsoft/simplechat/issues/989), `functions_content_safety.py`, `admin_settings.html`, `route_backend_chats.py`) + +* **Optional Terms of Use Gate** + * Added an admin-configurable Terms of Use prompt that can require users to accept rules of behavior, terms, or an entry notice before using SimpleChat. + * Supports every-session, once-per-day, and once-per-version recurrence modes, with server-side browser/API enforcement and activity logging for accept/decline events. + * (Ref: [#504](https://github.com/microsoft/simplechat/issues/504), `TERMS_OF_USE.md`, `functions_terms_of_use.py`, `route_frontend_terms_of_use.py`, `terms_of_use.html`) + +* **Admin Cosmos DB JSON Editor** + * Added an admin-only Data Management tool for selecting SimpleChat Cosmos DB containers, running paged SELECT queries, opening individual documents, editing JSON, and saving changes with ETag concurrency protection. + * Empty browse mode is capped at the first 100 documents, while custom SELECT queries page beyond 100 through continuation tokens without returning oversized result sets in one request. + * The interface is protected by danger acknowledgements, blocks `id` and partition key edits, and records editor actions plus save summaries in Activity Logs. + * (Ref: [#1006](https://github.com/microsoft/simplechat/issues/1006), `COSMOS_DB_JSON_EDITOR.md`, `functions_data_management.py`, `route_backend_data_management.py`, `admin_settings.html`, `admin_data_management.js`) + +* **Redis Explorer** + * Added an admin-only Redis Explorer in Admin Settings > Scale > Redis Monitoring for read-only, cursor-paginated Redis key browsing with substring filtering and page-size controls. + * Admins can select a key to view sanitized metadata and bounded preview content; session, token, cookie, credential, password, secret, authorization, and CSRF-like keys return restricted previews. + * JSON previews redact sensitive fields and all browser rendering uses text-safe DOM updates. + * (Ref: `REDIS_EXPLORER.md`, `functions_redis_monitoring.py`, `route_backend_settings.py`, `admin_settings.html`, `admin_settings.js`) + +* **Conversation Cache Metrics Dashboard** + * Added DAI-style rolling metrics for conversation list, feed, and advanced-search cache activity, including 15-minute hit rate, hits/misses, bypasses/errors, writes/invalidations, operation mix, last cache event, and last invalidation. + * Exposed normalized conversation cache settings and metrics through app maintenance status without adding Cosmos reads to the conversation hot path. + * Removed the Phase 4 badge from the Conversation Cache card now that the feature is part of the operational dashboard. + * (Ref: conversation cache metrics, `functions_conversation_cache.py`, `functions_app_maintenance.py`, `admin_settings.html`, `admin_settings.js`) + +* **Redis Document Access Index Cache** + * Added Redis read-through caching for DAI-backed document list, tag list, and legacy-count reads with scope-version invalidation and bounded TTL controls. + * Admin Settings now shows Redis DAI cache health, hit/miss/bypass/error metrics, invalidations, and the latest cache event alongside DAI read and maintenance status. + * (Ref: DAI Redis cache, `functions_document_access_index.py`, `admin_settings.html`, `admin_settings.js`) + +* **Audio File Runtime Support** + * Added default-on FFmpeg and FFprobe packaging for container builds so SimpleChat can transcode a much broader set of audio files before Azure Speech transcription. + * Expanded recognized audio upload extensions to include common containers and codecs such as 3GA, AAC, AC3, AIFF, AMR, AU, CAF, FLAC, M4A/M4B/M4R, Matroska audio, MP2/MP3/MPA, OGG/Opus/Speex, WAV, WebM audio, WMA, and WavPack. + * Added Admin Settings runtime guidance showing whether FFmpeg broad transcoding is available in the current app runtime and which audio upload extensions are recognized. + * Added `SIMPLECHAT_INSTALL_FFMPEG` / `INSTALL_AUDIO_FFMPEG` build controls for deployments that need to opt out of bundling FFmpeg. + * (Ref: audio uploads, FFmpeg runtime, `Dockerfile`, `functions_documents.py`, `admin_settings.html`, `AUDIO_FILE_RUNTIME_SUPPORT.md`) + +* **Chat Scroll Behavior and 508 Usability** + * Updated chat message rendering so the viewport no longer jumps to the very bottom of long assistant responses when they finish loading while the user is reading near the top. + * Auto-scroll now only occurs when the user is already near the bottom of the conversation, and a floating "scroll to latest message" button appears when new content arrives below the current view. + * This aligns the chat experience more closely with other AI chat tools and reduces unexpected motion for 508 testers and keyboard users. + * (Ref: `chats.html`, `chat-global.js`, `chat-messages.js`) + +#### User Interface Enhancements + +* **Fact Memory Moved To Chat Settings** + * The fact memory control now lives in **Admin Settings > Chat > Chat Experience > Fact Memory**, with wording that explains it works without agents or actions and that users manage their own entries in Profile. + * It was previously only reachable from **Agents & Actions > Actions** as "Enable Fact Memory Action", so administrators running plain chat had no reason to open that tab and never found it. + * The Actions tab now shows a read-only note pointing at the Chat setting, matching how Tabular Processing points at Enhanced Citations. Existing configurations are unchanged; the underlying setting and any saved memories are preserved. + * (Ref: `chat-experience.html`, `actions.html`, `admin_settings.js`, `admin_settings_nav.py`, [#1352](https://github.com/microsoft/simplechat/issues/1352)) + +* **Throttled Chat Responses Now Explain Themselves** + * SimpleChat retries throttled model calls with backoff, but once those retries ran out the chat response fell through to the generic "Something went wrong while streaming the response" error. That was indistinguishable from a genuine failure, which mattered most in deployments that throttle deliberately through API Management. + * An exhausted throttle is now recognized as rate limiting and shown in its own banner, with an hourglass icon, a "Rate limited:" heading, and the administrator's rendered Markdown. Any partial content already streamed is still saved. + * (Ref: `chat-streaming.js`, `appendStreamErrorBanner`, `is_rate_limit_error`, [#1354](https://github.com/microsoft/simplechat/issues/1354)) + +* **Admin Settings Pages Show Real Screenshots** + * Fourteen admin settings tab pages were rendering "screenshot needed" placeholders even though real screenshots already existed in the repository. Those pages now display the actual screenshots for the General, AI Models, Search and Extract, Workspaces, File Sync, Workspace Identities, Citation, Safety, Security, Agents, Scale, Control Center, Logging, and Send Feedback tabs. + * The four tabs with no captured screenshot still show a placeholder naming the exact file to create, so genuine gaps stay visible. + * (Ref: `docs/admin/`, `docs/images/admin-settings/`) + +* **Admin Settings Restructure Merged With Current Development** + * Version bump covering the merge of the Admin Settings information architecture work with the generated file output fixes developed in parallel. Both reached v0.260.011 independently, so their release notes are combined under that version. + * (Ref: Admin Settings navigation, generated file exports) + +* **System Settings Card Split To Where Each Setting Belongs** + * One card mixed maximum file size, conversation history, idle timeout, the default system prompt and the access denied message — five unrelated concerns under one heading. + * Maximum File Size is now in **Workspaces → Files & Sharing**, Conversation History and Default System Prompt in **Chat → Chat Experience**, and Access Denied Message in **Security → Access & Roles**. + * What remains in **Security → Session** is the idle timeout, and the card is now named for it. + * Every setting keeps its saved value; nothing needs re-entering. + * (Ref: `idle-timeout-section`, `file-size-limit-section`, `conversation-history-section`, `default-system-prompt-section`, `access-denied-message-section`) + +* **Backup, Migrate & Restore Split Into Five Tabs** + * One tab carried the entire backup, migration, restore, Cosmos editing and job history surface — over 1,600 lines in a single scroll. + * Backup & Recovery now has **Backup** (readiness, backup, schedule, storage, encryption), **Migrate**, **Restore**, **Cosmos Editor** and **Jobs**. + * The save button, status line and operational-hours warning are shared by all five tabs, so they sit above the tabs and stay available wherever you are in the group. + * This completes the Admin Settings restructure: **14 groups and 44 tabs**, from an original 17 flat tabs. + * (Ref: `backup`, `migrate`, `restore`, `cosmos-editor`, `jobs`) + +* **AI Models Split By Model Purpose** + * AI Models presented every model setting on one tab. It is now **Model Endpoints** (endpoint and fallback configuration, plus the Chat Model dialog opened from it), **Embeddings** and **Image Generation**. + * (Ref: `model-endpoints`, `embeddings`, `image-generation`) + +* **Agents And Actions Are Now Separate Tabs** + * A single "Agents and Actions" tab carried agent configuration, template approvals, document action capabilities, action configuration and the whole inbound MCP surface. + * It is now **Agents**, **Actions** and **Inbound MCP**. + * Inbound MCP is a large area with its own dialogs and diagnostics, and the whole tab is hidden when the inbound MCP interface is turned off rather than showing an empty tab. + * (Ref: `agents`, `actions`, `inbound-mcp`) + +* **Knowledge Settings Split By What They Actually Do** + * Search & Extract held eight cards spanning four unrelated jobs, from Bing consent to voice transcription. + * Knowledge now has **Web & Research** (web search, URL access, deep research), **Search Index** (Azure AI Search), **Document Extraction** (document intelligence, chunk sizes, plus metadata extraction and multi-modal vision brought over from Workspaces) and **Audio & Video** (video intelligence, voice conversations), alongside the existing File Sync. + * Voice and video sit under Knowledge rather than Chat because they are extraction pipelines that turn recordings into searchable content. + * (Ref: `web-research`, `search-index`, `extraction`, `audio-video`) + +* **Workspaces Focused On Workspaces** + * Workspaces mixed workspace types with file rules, workflow and extraction settings. + * It is now **Workspace Types** (personal, group, public), **Files & Sharing** (downloads, sharing, and shared conversation file approvals brought over from AI Models) and the existing Global Identities. + * (Ref: `workspace-types`, `files-sharing`) + +* **Workflow Is Its Own Area** + * Workflow drives approvals and assignment across every workspace type and was too large to sit as one card inside Workspaces. It now has its own group. + * (Ref: `workflow`, `workflow-settings-section`) + +* **General Tab Broken Up Into Focused Tabs** + * General had grown into a catch-all of eleven unrelated cards: branding sat next to health checks, API documentation, terms of use and system settings. + * Appearance now has **Branding** (branding, home page text, appearance), **Notices & Agreements** (classification banner, chat AI notice, terms of use and the user agreement pulled across from Workspaces) and **Pages & Links** (static pages plus external links). + * Health Check and API Documentation moved to Operations, which is now **Logging & Health** — they report on how the app is running rather than how it looks. + * Support moved to Help as its own **Support Menu** tab, next to Send Feedback. + * (Ref: `branding`, `notices`, `custom-pages`, `logging`, `support-menu`) + +* **Security Split Into Five Purposeful Tabs** + * Security held a single Key Vault card while an unrelated Safety tab mixed content filtering with role permissions, which are different jobs. + * Security is now **Access & Roles** (who gets in and with what role), **Secrets** (Key Vault), **Content Safety** (what may be said once you are in), **Session** (idle timeout and related system settings) and **Network** (Azure Front Door). + * (Ref: `access-roles`, `secrets`, `content-safety`, `session`, `network`) + +* **New Data Lifecycle Group For Retention, Classification And Archiving** + * Retention policy, document classification and conversation archiving all decide how long content lives and how it is labelled, but they were split across Workspaces and Safety. They now sit together in a **Data Lifecycle** group with a tab each: **Retention**, **Classification** and **Archiving**. + * Conversation archiving in particular was buried under Safety, which described what it protects against rather than what it does. + * (Ref: navigation map, `retention-policy-section`, `document-classification-section`, `conversation-archiving-section`) + +* **Chat Group Gathers The Settings That Shape A Conversation** + * Settings that change what a conversation looks and behaves like were spread across AI Models, Workspaces and Safety. The **Chat** group now holds them in two tabs. + * **Chat Experience** collects model thought display, chat file uploads (with the conversation contents drawer) and workspace scope lock. + * **Feedback & Alerts** collects user feedback and desktop notifications, which are both about how the app talks back to the user rather than about safety enforcement. + * (Ref: `chat-experience`, `feedback-alerts`, `processing-thoughts-section`, `chat-file-uploads-section`, `workspace-scope-lock-section`, `user-feedback-section`, `desktop-notifications-section`) + +* **Settings Keep Their Values Through The Move** + * Cards were relocated between tabs without renaming a single field, so every saved value is preserved and the form submits exactly the payload it did before. + * Sidebar search still finds a setting by group, tab or card name, so you can reach anything without knowing where it now lives. + * (Ref: admin settings field contract, `admin_settings_nav.py`) + +* **Governance And Scale Split Into Focused Tabs** + * Governance held five cards covering three different jobs. It is now **Feature Governance** (which features are governed), **Policies** (the policies themselves), and **MCP Governance**. + * Scale mixed cache configuration with Cosmos capacity, and is now **Redis & Caching** and **Cosmos**. + * **Azure Front Door** moved out of Scale into Security, under a new **Network** tab. It configures authentication and redirect flows rather than throughput, so it never belonged with capacity settings. + * Existing links and bookmarks to `#governance` and `#scale` still work and land on the first tab of each group. + * No settings changed. Every option keeps its name and its saved value. + * (Ref: navigation map, `feature-governance`, `governance-policies`, `mcp-governance`, `redis-caching`, `cosmos`, `network`) + +* **Latest Features No Longer Opens Every Time You Visit Admin Settings** + * Latest Features was pinned first in both the top tabs and the admin sidebar, and its pane was hard-coded as the default active tab, so a curated release-notes page behaved like the Admin Settings landing page. + * It now sits last in both navigations, after **Send Feedback**, and **General** is the landing tab instead. + * The Latest Features content is unchanged, including its **New** badge and the hide/unhide option. + * (Ref: `admin_settings.html` top-tab strip, `_sidebar_nav.html`, `admin_sidebar_nav.js` default tab) + +* **Global Identities Is No Longer An Unlabelled Widget** + * The Global Identities tab rendered a bare control with no heading or description, unlike every other Admin Settings tab. + * It now has a heading and explains that identities are deployment-wide and that secrets are stored in Key Vault when Key Vault storage is configured. + * (Ref: Global Identities, `workspace-identities-section`, `functions_workspace_identities.py`) + +* **File Sync Is Now Reachable From The Sidebar** + * File Sync is one of the larger settings surfaces but was the only tab with no sidebar submenu, so its sub-areas could not be jumped to or found with sidebar search. + * **Visible Source Types**, **Personal Workspace Sync**, **Group Workspace Sync**, and **Public Workspace Sync** are now sidebar destinations. + * (Ref: File Sync, `_sidebar_nav.html`, `file-sync-submenu`) + +* **Blob Storage Actions Can Now Use Managed Identity or an Account Key** + * The Blob Storage action modal gained an authentication selector offering **Connection String**, **Managed Identity**, and **Account Key**, along with blob service endpoint and account key fields. + * Previously the modal only collected a connection string even though the backend accepted other methods, so managed identity was not reachable through the UI. + * The endpoint field is validated against the Azure Blob hostname allowlist before the action is saved. + * (Ref: `_plugin_modal.html`, `plugin_modal_stepper.js`, `blob_storage.definition.json`) +* **Shared Conversations No Longer Fail With "Stream interrupted: Forbidden"** + * Fixed invited participants being unable to invoke the AI at all in a shared conversation. Any explicit AI request returned `Forbidden` with no content. + * Root cause was the hidden source conversation behind every shared conversation being owned by its creator, so participants failed a plain ownership comparison in the chat streaming route even though they are legitimate members. + * Because shared conversations only call the AI on an explicit mention, this surfaced the first time a participant asked the assistant for something, which made it look file-specific. + * Participants can also now download generated files from a shared conversation, which was blocked by the same comparison. + * Also fixed background CSV exports queued by a participant becoming unreadable for the owner, because publication checks looked up the export run under the wrong user partition. + * (Ref: `build_conversation_participation_context`, `route_backend_chats.py`, `route_enhanced_citations.py`, `functions_simplechat_operations.py`) + +* **Clearer Group Workspace Save Errors** + * Attempting to save a generated document into a group workspace without document rights now names the roles that can complete it and suggests requesting the content as a downloadable file instead of failing with a bare permission error. + * (Ref: `_resolve_group_upload_target_for_current_user`) + +* **Tab Now Completes an @ Mention in Shared Conversations** + * In multi-user conversations, pressing **Tab** while the `@` suggestion menu is open now accepts the highlighted participant, agent, model, or invite suggestion, exactly like **Enter** already did. + * Previously **Tab** moved focus out of the message box and left the half-typed `@par` text behind, which broke the autocomplete habit most people bring from other editors and chat clients. + * **Shift+Tab** is deliberately unchanged and still moves focus backwards, and **Tab** still moves focus normally when the menu is showing "No matching participants...". + * The chat mention menu now matches the agent instruction mention menu, which already accepted **Tab**. + * (Ref: `chat-collaboration.js`, `handleComposerKeydown`, `selectActiveMentionSuggestion`, Fixes #1299) + +* **Mention Menu Is Now Announced Correctly By Screen Readers** + * Each `@` suggestion is now exposed as a proper listbox option with `aria-selected`, and the message box references the highlighted suggestion through `aria-activedescendant` paired with `aria-controls` so assistive technology can resolve it. + * The highlighted suggestion is also scrolled into view while arrowing through a long list, so keyboard navigation no longer highlights an off-screen entry. + * (Ref: `chat-collaboration.js`, `renderMentionMenu`, `updateMentionMenuActiveItem`, `applyMentionComboboxState`, `chats.html`) + +* **Finished Jobs No Longer Look Stuck** + * Completed backup jobs no longer display **Current container: Waiting**, which made a finished job look like it was still churning. + * Migration jobs no longer display a **Liveness: Running** row after reaching a terminal status. + * Live-only telemetry is now hidden once a job is `completed`, `completed_with_warnings`, `failed`, or `canceled`. + * (Ref: `admin_data_management.js`, `getBackupLiveMetrics`, `getMigrationLiveMetrics`, `isTerminalJobStatus`) + +* **Run Retention Cleanup Now Explains Itself** + * Added a hover tooltip and an `(i)` toggle that expands inline guidance next to the **Run Retention Cleanup** button. + * Documents that cleanup permanently deletes backups past the retention period along with their artifacts, skips jobs that are still running, honors **Keep latest full backup**, and deletes at most 25 backups per run. + * Clarifies that "found no expired backups to delete" means every backup is still inside the retention window, which is expected rather than a failure. + * (Ref: `admin_settings.html`, backup retention cleanup, Data Management) + +* **Agent and Workflow Builder Refresh** + * Agent configuration now follows Actions → Knowledge → Instructions, with selected actions visible in the Instructions step. + * Workflows use a stepped General/Trigger/Tasks/Reliability/Review builder with per-task runner controls and alert-rule editing. + * (Ref: agent modal, workflow builder, workflow runner controls, alert rules editor) + +* **Administration and Configuration UX Improvements** + * Workspace sections now use a consistent Documents → Prompts → Identities → Sync → Endpoints → Actions → Agents → Workflows order. + * Governance policy copy/inverse/show-users actions, dedicated Log Analytics configuration, refreshed backup/migrate/restore flows, and reviewed data migration steps reduce admin friction. + * External links can be reordered, custom pages can be opened directly, and non-blocking Bootstrap toasts replace browser alerts across admin, workspace, and profile pages. + * (Ref: workspace section order, governance UI, Log Analytics settings, data migration UI, toast notifications) + +* **Chat, Navigation, and Accessibility Enhancements** + * Chat, navigation, and sidebar layouts remain usable at 200% zoom and with large text. + * The Conversation Contents drawer adds safe labels, keyboard focus handling, active-location tracking, and responsive desktop/mobile navigation. + * Long source lists collapse behind a disclosure, document picker rows show file-name context, and Refresh Documents preserves selection with clearer status. + * (Ref: 508 usability, conversation contents drawer, source disclosure, document picker, refresh documents) + +* **Data Explorer and Extraction Status UX** + * Redis Explorer uses a fixed-height modal with independent key-list and preview scrolling. + * Cosmos query results open in a scrollable modal so the main editor stays focused on query setup. + * Extraction badges identify the engine that ran and show Content Understanding vs. Document Intelligence fallback reasons. + * (Ref: Redis Explorer, Cosmos editor results modal, extraction badges) + +* **Placeholder Screenshots for Pending Captures** + * Added 76 branded "Screenshot pending" placeholders so every v0.260.001 Latest Features card renders a valid local image while final captures are pending. + * Placeholders can be replaced in place with real screenshots without changing the catalog configuration. + * (Ref: `application/single_app/static/images/features/`, Latest Features image galleries) + +* **Documentation Site Works on Phones and Tablets** + * Standardized the responsive breakpoints, which previously mixed `768px` and `767.98px` and left gaps, and exported the desktop breakpoint to JavaScript so it is no longer duplicated by hand. + * Wide tables and long code blocks are now contained in horizontal scroll regions instead of widening the page, images are lazy-loaded with intrinsic sizing, touch targets meet a 44px minimum, and the mobile navigation drawer and search sheet trap and restore focus. + * Verified with browser tests at 360x640, 390x844, 768x1024, 1280x800, and 1920x1080. + * (Ref: `docs/assets/css/main.scss`, `docs/assets/js/sidebar.js`, `ui_tests/test_docs_site_responsive.js`) + +* **Simpler Documentation Pages** + * Landing pages were rewritten from hand-written HTML card markup into plain markdown. The home page previously had 82 blocks of card markup and zero markdown headings, and the features page 119 blocks and zero headings, which meant neither page had a working "On this page" table of contents or heading anchors. + * The FAQ was rebuilt so every question is its own heading with a linkable anchor. + * The decorative page hero, with its gradient banner, pill row, and icon orb, was replaced with a plain documentation header across the 38 pages that used it. + * Split the 452 KB release notes page into per-version-series pages while keeping the existing release notes URL working. + * (Ref: `docs/index.md`, `docs/features.md`, `docs/start/faqs.md`, `scripts/build_release_notes_pages.py`) + +* **Documentation URLs Now Match Their Section** + * Guides previously lived under three different URL spaces that all meant the same thing. Tutorials and how-to guides are consolidated under `/guides/`, orientation pages moved under `/start/`, deployment scenarios under `/deploy/`, and reference pages under `/reference/`. + * **Existing links and bookmarks continue to work.** Every moved page redirects from its old URL, and the URLs the application itself links to were deliberately left unchanged. + * (Ref: documentation navigation, `jekyll-redirect-from`, `ui_tests/check_docs_links.js`) + +* **"Refresh documents" Now Actually Refreshes** + * The **Refresh selected documents** button previously warned `Select one or more workspace documents in the picker first.` even though the picker was empty and nothing could be selected. + * It is now labeled **Refresh documents**, reloads the document list while preserving the current selection, and reports what it found — including a clear message when the selected scope has no documents. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `workspace.html`, `group_workspaces.html`, `workspace_workflows.js`) + +* **Extraction Badges Name the Engine That Actually Ran** + * Extraction tooltips in personal, group, and public workspaces now say whether a document was processed with Azure AI Content Understanding or Document Intelligence Layout, and explain any fallback that occurred. + * The **Change Extraction** action now works for images as well as PDFs, and refuses a change to Enhanced while Enhanced extraction is disabled. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `workspace-documents.js`, `public_workspace.js`, `group_workspaces.html`, `functions_documents.py`) + +* **Auto Mode Also Upgrades for Figures** + * Auto mode still samples the first pages with Document Intelligence Layout as the cheaper detector, but now upgrades to Enhanced when it finds figures or images, not just tables and selection marks. This matters because figure description is the main reason to use Enhanced. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_documents.py`, Auto mode detection) + +* **Collapsed Long Source Lists** + * The per-message Sources disclosure now shows the first 25 document sources and collapses the rest behind a **Show N more sources** control, so an agent that retrieves hundreds of chunks no longer floods the panel. + * No source data is discarded — the full set is still stored, exported, and available for citation matching. + * (Ref: [#1239](https://github.com/microsoft/simplechat/issues/1239), `chat-messages.js`, `chat-citations.js`) + +* **Dedicated Log Analytics Configuration Section** + * Log Analytics actions now have their own Step 3 configuration section instead of reusing the generic endpoint and authentication form. + * Workspace ID, Cloud, API Endpoint, and the authentication method moved out of *Advanced → Additional Fields* and into the main configuration step, next to the new Test Connection button. Authority Host and Endpoint Override appear only when the Custom cloud is selected. + * Existing Log Analytics actions are unaffected — the section reads and writes the same manifest fields and preserves stored values such as `query_history`. + * (Ref: [#1267](https://github.com/microsoft/simplechat/issues/1267), `_plugin_modal.html`, `plugin_modal_stepper.js`, Log Analytics action configuration) + +* **Agent Modal Step Reorder: Instructions After Actions and Knowledge** + * The agent modal now runs Basic Info → Model & Connection → **Actions** → **Knowledge** → **Instructions** → Advanced → Summary, so instructions are written once the agent's real capabilities are known. + * Added a collapsible **Selected Actions & Knowledge** panel at the top of the Instructions step listing the selected actions with badges for their enabled capabilities, plus the assigned workspaces, documents, tags, and web sources, each with its reference token. + * Step navigation, validation, and Foundry agent-type visibility now key off named steps rather than hard-coded step numbers. + * (Ref: [#1257](https://github.com/microsoft/simplechat/issues/1257), [#1263](https://github.com/microsoft/simplechat/pull/1263), `_agent_modal.html`, `agent_modal_stepper.js`) + +* **Workflow Alert Rules Editor** + * The Review step of the personal and group workflow builders replaces the single Pop-up Alert Priority dropdown with an alert mode selector and a rule editor for adding, editing, enabling and removing alert rules. + * Each rule row exposes its name, condition, severity, delivery and, where relevant, the task or output it should watch, with condition-specific fields appearing as the condition is chosen. + * The workflow list now summarizes alerts as the number of active rules, and the Review summary names the rules that will notify you. + * Invalid rules are caught before saving, such as a missing regex pattern, empty match values, an unwritten model condition, or a task-scoped rule with no task selected. + * (Ref: `workspace.html`, `group_workspaces.html`, `workspace_workflows.js`, workflow builder review step) + +* **Consistent Workspace Section Order** + * Workspace sections now follow a single order of operations everywhere they are listed: Documents, Prompts, Identities, Sync, Endpoints, Actions, Agents, Workflows. + * The order reflects how a workspace is actually built up, so it is clearer that Identities feed both Sync and Actions, that Actions belong to Agents, and that Workflows run Agents. + * Applied to the tab strip, the collapsed Section dropdown, and the left-hand sidebar submenus for personal and group workspaces. Public workspaces already matched this order and were left unchanged. + * Sections that an admin has disabled stay hidden; the remaining sections simply close up while keeping their relative positions. + * (Ref: [#1255](https://github.com/microsoft/simplechat/issues/1255), `workspace.html`, `group_workspaces.html`, `_sidebar_nav.html`, `WORKSPACE_SECTION_ORDER.md`) + +* **File Name Shown in Document Picker Rows** + * Document rows in the chat grounded-search picker now show the file name as a smaller muted line beneath the title whenever the two differ, so it is clear which file a search matched. + * Rows without distinct titles are unchanged, and the row tooltip carries both the title and the file name. + * (Ref: [#1256](https://github.com/microsoft/simplechat/issues/1256), `chat-documents.js`, `chats.css`, document picker rows) + +* **Governance Policy Copy and Principal Review Actions** + * Added Duplicate and Inverse actions for delegated item governance policies so admins can quickly clone a policy or create an allow/block-list-swapped version before saving it as a new policy. + * Added a Show Users modal and removed the allowed/blocked user and group columns from the main delegated policy table, keeping the table easier to scan while preserving principal detail access. + * (Ref: [#1252](https://github.com/microsoft/simplechat/issues/1252), `admin_governance.js`, `admin_settings.html`, governance delegated item policies) + +* **Backup, Migrate & Restore Admin Refresh** + * Reworked the Admin Settings data-management tab into a clearer Backup, Migrate & Restore control center with start-here guidance, setup modals, and plain-language migration choices. + * Separated destination Cosmos **RU Boost** configuration and testing from Cosmos data-copy access validation so admins can verify the correct Azure management-plane permissions before migration. + * Aligned the refresh with the restore workflow from Backup Inventory so admins can review backup readiness, choose restore policy/surfaces, run preflight, and queue supported restore jobs. + * (Ref: [#1140](https://github.com/microsoft/simplechat/issues/1140), `admin_settings.html`, `admin_data_management.js`, `functions_data_management.py`, Data Management docs and tests) + +* **Custom Pages Admin Open Action** + * Added an Open action to the Admin Settings Custom Pages table so administrators can launch enabled static or Python-backed custom pages directly from their metadata row. + * The action opens encoded `/custom/` URLs in a new tab while preserving existing Custom Pages route authorization, enabled-state checks, access-level rules, role restrictions, and `.html` alias compatibility. + * Disabled or unavailable pages now show a disabled Open action with explanatory tooltip copy instead of silently omitting the action. + * (Ref: Closes [#951](https://github.com/microsoft/simplechat/issues/951), PR [#1131](https://github.com/microsoft/simplechat/pull/1131), `admin_custom_pages.js`, `CUSTOM_PAGES.md`) + +* **External Link Ordering Controls** + * Admins can now move saved external links up or down and save the resulting navigation order without deleting and recreating links. + * The first and last links expose disabled boundary controls, and the visible order stays synchronized with the Admin Settings save payload. + * (Ref: Closes [#793](https://github.com/microsoft/simplechat/issues/793), `admin_settings.js`, `test_admin_external_link_ordering.py`, `EXTERNAL_LINK_ORDERING_FIX.md`) + +* **Application-Wide Non-Blocking Toast Notifications** + * Replaced native browser alerts across admin, group, public, personal workspace, profile, feedback, safety, and control-center workflows with consistent Bootstrap toast notifications. + * Added a shared, accessible toast utility that safely renders dynamic messages as text and preserves specialized chat toast positioning. + * (Ref: Closes [#739](https://github.com/microsoft/simplechat/issues/739), `toast.js`, `chat-toast.js`, first-party templates and workspace scripts) + +* **MCP Admin And Observability Surfaces** + * Added Admin Settings controls for inbound MCP runtime settings, source governance guidance, Easy Auth setup verification, request-size and throttle tuning, tool registry visibility, and copyable Application Insights starter queries. + * Added Governance controls for outbound MCP destination policies and inbound MCP source policies using the current source-first access model. + * (Ref: [#1020](https://github.com/microsoft/simplechat/issues/1020), MCP governance/admin UX, `admin_settings.html`, `admin_settings.js`, `admin_governance.js`) + +* **Responsive Long-Chat Navigation** + * Added safe plain-text labels, active-location tracking, keyboard focus management, destination highlighting, and persistent desktop or off-canvas mobile layouts. + * (Ref: [#1026](https://github.com/microsoft/simplechat/issues/1026), `chats.html`, `chats.css`, `test_chat_conversation_contents_drawer.py`) + +* **200% Zoom and Large-Text Layout Support** + * Updated Chat, top navigation, classification banners, and sidebar scrolling to reserve font-relative space and keep messages, navigation, tools, and the composer reachable at 200% browser zoom and large saved font sizes. + * (Ref: [#1099](https://github.com/microsoft/simplechat/issues/1099), `chats.css`, `navigation.css`, `sidebar.css`) + +* **Per-Task Runner Controls** + * Renamed the workflow-level Runner field to Default Runner and added Workflow default, Direct Model, and Agent selection to each task editor. + * Task rows and Review now show the resolved runner, with responsive conditional model/agent controls and text-safe rendering for endpoint, model, and agent labels. + * (Ref: [#1084](https://github.com/microsoft/simplechat/issues/1084), `workspace.html`, `group_workspaces.html`, `workspace_workflows.js`) + +* **Versioned Latest Features Navigation Hide Preference** + * Users can now hide Latest Features navigation entries for the current SimpleChat version from the ellipsis action and restore them from Profile Settings. + * The hidden state is version-aware, so Latest Features automatically appears again after the app version changes. + * Added a development-only `is_development=true` environment override that hides Latest Features nav entries without affecting production behavior when unset or false. + * (Ref: [#987](https://github.com/microsoft/simplechat/issues/987), `latestFeaturesHiddenVersion`, `_sidebar_nav.html`, `_top_nav.html`, `profile.html`, `latest-features-nav.js`) + +#### Bug Fixes + +* **Core Action Toggles No Longer Interfere With Fact Memory** + * Fact memory and the built-in core actions were saved through the same admin endpoint, which required fact memory to be included in every request. With the control relocated to Chat, that contract would have let a change to any unrelated core action overwrite the fact memory setting. + * The endpoint now treats fact memory as optional and ignores it, so the Chat setting is the only thing that changes it. Older clients that still send the value continue to work. + * (Ref: `route_backend_plugins.py`, `route_frontend_admin_settings.py`, core plugin settings endpoint, [#1352](https://github.com/microsoft/simplechat/issues/1352)) + +* **Agent Actions Are No Longer Skipped When A Workspace Is In Scope** + * Selecting an agent that has actions and enabling a workspace produced answers that never invoked any of the agent's actions. The assistant answered from retrieved document text alone, even when the retrieved excerpts did not contain what the question asked for. + * The retrieval prompt instructed the model to base its answer *only* on the retrieved excerpts, so although the agent's actions were attached and available, the model was told not to reach for them. Retrieved excerpts are now framed as starting evidence, and the model is directed to call an available action when the excerpts lack what the question needs, then reason over the excerpts and the action results together. The rule against fabricating unsupported values is unchanged. + * (Ref: `build_search_augmentation_system_prompt`, `build_mixed_source_evidence_handoff`, agent actions, workspace search, [#1332](https://github.com/microsoft/simplechat/issues/1332)) + +* **Spreadsheets In A Workspace Are Now Actually Computed** + * A quantitative question about a spreadsheet could return values that were not in the file. Tabular computation was suppressed whenever workspace search also returned any narrative document, and the heuristic treated topic words such as "report", "policy", and "memo" as reasons to skip computation entirely. + * Because only a truncated three-row preview of a spreadsheet is indexed for search, skipping computation left the model deriving totals and averages from those preview rows. Tabular sources in scope are now computed unless the question unambiguously names a narrative artifact such as a PDF or presentation, restoring parity with the behavior already used when mixed-source search is disabled. + * (Ref: `should_run_tabular_evidence`, `functions_mixed_source_orchestration.py`, tabular processing, mixed-source evidence, [#1332](https://github.com/microsoft/simplechat/issues/1332)) + +* **A Skipped Spreadsheet Now Tells The Model What It Is Missing** + * When tabular computation is skipped, the evidence record previously said processing "was not needed", which implied the source was irrelevant and left the model free to compute from indexed preview rows. + * It now states that the full table was never read, that any indexed excerpt is a truncated preview, that numeric conclusions must not be drawn from it, and that the tabular analysis action should be called if values from that source are required. + * (Ref: `execute_tabular_evidence_sources`, evidence envelopes, tabular citations, [#1332](https://github.com/microsoft/simplechat/issues/1332)) + +* **Inline Images And Videos Now Show Only Cited Media** + * Assistant messages rendered an inline image or video gallery for every media file that retrieval returned, so a search that surfaced five workspace images produced five inline tiles even when the answer referenced only one of them, or none at all. Media that had nothing to do with the answer was presented inside the message bubble as though it supported the answer. + * Inline galleries now render only the media the response actually cited. The five-item gallery cap therefore goes to genuinely cited media instead of retrieval noise, and unreferenced workspace files no longer trigger enhanced-citation fetches. + * Galleries produced by an action or tool the assistant actually ran are unaffected, since those are executed results rather than unused search candidates. Conversations created before cited-source tracking existed also keep their previous behavior. + * The **Sources** disclosure is unchanged and still lists every retrieved document and web result, so nothing becomes harder to find. + * (Ref: `chat-citation-tracking.js`, `chat-inline-images.js`, `chat-inline-videos.js`, `chat-messages.js`, `cited_hybrid_citations`, [#1329](https://github.com/microsoft/simplechat/issues/1329)) + +* **Running Simple Chat Directly No Longer Fails To Start When An Agent Has Actions** + * Starting Simple Chat with `python app.py` (including via `uv run`) aborted with `RuntimeError: Working outside of request context` whenever any agent had an action assigned. The app started normally until the first action was saved, which made the failure look intermittent. + * Semantic Kernel initialization runs before any request exists on that path, but agent plugin loading read the signed-in user from the Flask session. It now resolves the user only when a request is actually in progress and otherwise loads with no user identity, matching how global plugin loading already behaved. + * Container and App Service deployments were never affected, because they start through gunicorn and initialize during the first request. Their behavior is unchanged. + * Three further identity lookups used for group scope and personal model endpoints had the same latent problem and were corrected at the same time. + * (Ref: `semantic_kernel_loader.py`, `functions_authentication.py`, `get_current_user_id_or_none`, issue #1327) + +* **Documentation Screenshot Viewer Validates Its Image Source** + * The documentation site's click-to-enlarge screenshot viewer assigned an image URL taken from a data attribute in the page. Because that value flows from page content into a URL, CodeQL flagged it as a potential DOM-based cross-site scripting sink. + * The viewer now resolves the value and requires a same-origin `http` or `https` URL ending in an image extension before using it, so scheme-based payloads such as `javascript:` and `data:` URLs, and any off-site source, are rejected. All documentation media is local, so no legitimate image is affected. + * (Ref: `docs/assets/js/media.js`, `safeMediaUrl`, `ui_tests/test_docs_media_lightbox_source_validation.js`, CodeQL `js/xss-through-dom`) + +* **Admin Documentation Rebuilt For The Grouped Settings Layout** + * Admin Settings was reorganized from 18 flat tabs into 14 groups containing 44 tabs and 93 settings sections. The documentation was still written against the old flat layout, so it described tabs that no longer exist and omitted the new ones. + * The admin documentation is now one page per group, with every tab reachable by its own anchor so links to a specific tab keep working. Every retired tab URL redirects to the group that now owns its settings, so existing links and bookmarks continue to resolve. + * (Ref: `docs/admin/`, `application/single_app/admin_settings_nav.py`, `docs/_data/app_surface.yml`) + +* **Collaborating In A Conversation Is Now Documented** + * Added a guide covering shared conversations end to end: sharing a conversation, mentioning a participant with `@` and Tab completion, how shared files are approved before they become available, and what participants can and cannot do. + * The Blob Storage action reference now explains its managed identity and account key options. + * (Ref: `docs/guides/collaborate-in-a-conversation/`, `docs/reference/actions/blob-storage/`, `enable_collaborative_conversations`) + +* **Documentation Site Now Reflects the v0.260.001 Release** + * The documentation site's Latest Release section was a full release behind, still presenting v0.250.001 as current. It now mirrors the same three-tier model the application uses: v0.260.001 as the current release, v0.250.001 as the previous release, and v0.239.001-v0.241.007 in the archive. + * Added 20 feature guides for the v0.260.001 release covering enhanced extraction, embedded Office images, workflow task sequences, the MCP platform, the Yamcs and RocksDB actions, agent instruction references, action test connections, Azure Blob file sync, terms of use, audio file support, completion notifications, the chat AI notice, conversation context grounding, used documents on fork, the conversation contents drawer, font size and zoom, message audio export, public workspace display names, and chat scroll accessibility. + * (Ref: `docs/_data/latest_release_features.yml`, `docs/latest-release/release-260-*`, `application/single_app/support_menu_config.py`) + +* **Placeholder Screenshots Are Now Tracked** + * The v0.260.001 release ships branded "Screenshot pending" placeholder graphics so feature cards render while final captures are pending. Those placeholders are now listed on the documentation media status page with the exact file paths to overwrite, so they are visible work rather than a silent gap. + * (Ref: `docs/_data/media_pending.yml`, `/contributing/media-status/`) + +* **Release Notes Pages No Longer Break On Quoted Template Syntax** + * Release notes legitimately quote template syntax when describing template work, such as a Jinja `block` tag. The page generator emitted that verbatim, so the site build failed with an unknown tag error. Quoted template syntax is now escaped in generated pages and renders as literal text. + * (Ref: `scripts/build_release_notes_pages.py`) + +* **Release Notes Links To Internal Engineering Notes** + * Some release note entries linked to the internal feature and fix note trees, which are intentionally not published on the documentation site. Those links now point at the repository. + * (Ref: `docs/explanation/release_notes.md`) + +* **Release Notes Index No Longer Exceeds Its Page Budget** + * The release notes page generator inlined a fixed number of recent releases on its index. The consolidated v0.260.001 rollup is large enough on its own that this pushed the index past the maximum page size and failed generation. The index now fills its inline section by size rather than by count, so a single large rollup cannot break it. + * (Ref: `scripts/build_release_notes_pages.py`) + +* **Archived Release Notes Links** + * The archived release notes page linked to the internal feature and fix note trees, which are intentionally not published on the documentation site. Those links now point at the repository instead. + * (Ref: `docs/explanation/archive_release_notes.md`) + +* **Admin Settings Loads Again** + * Admin Settings returned a 500 error on every request after the settings restructure. The Document Action Capabilities card moved to the Actions tab but the two values it reads stayed behind in the Agents tab, and each tab is rendered separately, so those values were never there when the card asked for them. + * Both values are now defined in the tab that uses them, and a new test renders the two tabs together to keep them there. + * (Ref: `admin/_panes/actions.html`, `admin/_panes/agents.html`, document action capabilities) + +* **Server Errors Are Visible In The App Service Log Again** + * Once Application Insights was configured it took ownership of logging, which had the side effect of stopping Flask writing unhandled errors to the container log. A failing page left nothing behind but its access-log line, so diagnosing it meant querying Application Insights. + * Unhandled errors are now written to both, so the reason for a failure is visible in the App Service log stream. + * (Ref: `functions_appinsights.py`, `ensure_console_error_logging`, App Service console logs) + +* **Document Access Index Diagnostics Appear When Enabled** + * The Cosmos DB tab checked the wrong thing for the debug setting, so the backfill controls, shadow validation metrics and reset option stayed hidden even after an admin turned the setting on. + * (Ref: `admin/_panes/cosmos.html`, `enable_dai_debug`) + +* **Setup Walkthrough Lands On The Right Settings Again** + * The guided setup walkthrough sent each step to a named tab. After the Admin Settings restructure, eleven of its twelve steps named tabs that no longer existed, so those steps would have moved nowhere and left the admin looking at whatever was already on screen. + * Each step now names the setting it is about and the tab is worked out from the page, so the walkthrough follows settings wherever they live. + * (Ref: setup walkthrough, `admin_settings.js`, `admin_card_links.js`) + +* **Cosmos Throughput Validation Reveals The Invalid Field** + * When Cosmos throughput values failed validation, the page tried to switch to a tab that no longer exists, so the field needing attention could be left on a hidden tab with no indication of where to look. + * Validation now jumps to wherever the invalid field actually is. + * (Ref: Cosmos throughput validation, `admin_settings.js`) + +* **Backup Dialogs Remain Available From Every Tab** + * The eleven Backup & Recovery dialogs are opened from more than one place and several are opened from code rather than a button. Left inside a tab, a dialog cannot appear while a different tab is showing. + * They now sit outside the tabs, so restore, migration cancel, job detail, the Cosmos editor dialogs and the five setup guides all open wherever they are triggered from. + * (Ref: Backup & Recovery dialogs, `admin_data_management.js`) + +* **Shared Controls Work In Both Navigation Layouts** + * Shared group controls resolve their group from whichever navigation is on screen, so the Backup & Recovery save button is present in the sidebar layout as well as the tab layout. + * (Ref: `data-admin-group-shared`, `admin_sidebar_nav.js`) + +* **Model Setup Guide Available From Every Model Tab** + * The Azure OpenAI Model Setup Guide dialog is opened from the endpoints, embeddings and image generation cards. Once those moved to separate tabs it could only have opened from one of them. + * The dialog now sits outside the tabs, so it opens from all three. + * (Ref: `legacyModelDiscoveryIdentityGuideModal`) + +* **Dangling Section Comments Removed** + * Seven tabs ended with a comment labelling a card that had since moved to another tab. + * (Ref: admin settings tab panes) + +* **Group Workflow Assignment Dialog Could Not Open** + * The Group Workflow Assignment dialog ended up in a different tab from the button that opens it. Because an inactive tab is hidden, the dialog would not have appeared at all. + * The dialog now sits with its button, and a new check verifies this for every dialog in Admin Settings so it cannot happen again. + * (Ref: `groupWorkflowAssignmentModal`, `test_admin_settings_modal_placement.py`) + +* **Misplaced Section Comments In AI Models** + * Two section comments had drifted onto the wrong cards while settings were being regrouped, labelling the embeddings card as processing thoughts. + * (Ref: `ai-models` pane) + +* **"Open Key Vault Settings" Link No Longer Depends On A Hardcoded Tab** + * The link from Data Management to Key Vault switched tabs by a hardcoded id, so it silently stopped working whenever that tab was renamed. + * It now uses the standard card link, which finds the owning tab from the page itself and stays correct however the settings are grouped. + * (Ref: `data-management-key-vault-link`, `admin_card_links.js`, `admin_data_management.js`) + +* **Admin Settings Always Opens On A Real Tab** + * The tab shown on arrival was pinned to a specific id in both the markup and the sidebar script. Regrouping settings could leave Admin Settings opening with no tab selected at all. + * The landing tab is now taken from the navigation map, so it follows the settings and can never be Latest Features. + * (Ref: `admin_landing_tab`, `get_landing_tab_id`, `admin_sidebar_nav.js`) + +* **Stale Tab Names In Latest Features** + * Several Latest Features entries pointed readers at tabs by their old names after the settings moved. + * (Ref: `latest-features` pane) + +* **Governance Status Messages No Longer Get Stuck On One Tab** + * The inline governance status message lived inside the Governance pane, so a message raised while working in one area could end up rendered on a tab you were not looking at. + * It now sits outside the tabs and is visible wherever you are in Governance. + * (Ref: `governance-status`, `admin_governance.js`) + +* **Reliable File Generation From Agent Action Results** + * Asking an agent for a downloadable file built from action results now produces the complete dataset in the requested format. Previously these requests could fail outright, publish a three-row sample of a large result, overwrite the assistant's written answer, or return nothing at all. Delivered across v0.260.004 through v0.260.011. + * **Files no longer fail to generate.** A CSV built from several actions in one turn could stop with `Generated output schema mismatch at row 2`, because each action returned a different set of columns. The export now pins a union of every column before the run starts and pads the missing cells, so mixed-shape results serialize instead of failing. + * **The written answer is no longer replaced by the file card.** CSV replies were suppressed alongside JSON and XML, but only JSON and XML withhold their payload from the response. CSV, DOCX, and PDF now keep the assistant's answer and append the file card beneath it. + * **Files contain the retrieved data, not a sample of it.** When the assistant pasted a few example rows above its answer, that excerpt outranked the real result set, producing a 3-row file from a 900-row query. Pasted rows are now used only when they are not an excerpt of the data actually retrieved. + * **Discovery calls no longer dilute the dataset.** A turn that lists instances, lists parameters, then retrieves history used to blend all three into one file. Rows are grouped by the action that produced them, and the action holding the substantive dataset wins. + * **Follow-up requests reuse data already gathered.** Asking "now make that a CSV" after the data was retrieved in an earlier turn no longer returns an empty result. The export reaches back through stored conversation citations, bounded by the **conversation history limit** in Admin Settings, and reuses the rows already collected instead of re-querying the source. + * **Answering a clarifying question now delivers the file.** When the assistant asks which rows and columns to include, replying "yes, all columns" now publishes the file that was originally requested. The clarification turn itself no longer publishes a placeholder file built from the question text. + * **The assistant no longer claims it cannot create files.** Every format now states the publication contract to the model, including on the turn that only answers a clarification, so replies stop saying "I cannot create or attach a file in this interface" and then producing one anyway. + * **Overlapping result pages no longer double the row count.** Agents frequently re-request a range from the same start time rather than paging forward, which produced a 1,000-row file for a window holding roughly 500 distinct records. Rows an earlier page of the same action already returned are dropped, while genuinely repeated records inside a single response are preserved. + * **Partial data is now labeled.** When an action reports that it truncated its own results, the file carries a **Partial** badge and a note explaining that it covers only the rows the action returned. Agents are also instructed to request the remainder starting after the last row they already hold, rather than repeating the original range. + * **CSV, DOCX, PDF, JSON, and XML now behave identically.** All five formats resolve rows the same way, reach back to earlier turns, decline to publish on a clarification turn, and report truncation. + * (Ref: `functions_generated_file_exports.py`, `functions_tabular_generated_exports.py`, `route_backend_chats.py`, `chat-messages.js`, [Generated Artifact Paging, Truncation, and Guidance Carry-Forward Fix](https://github.com/microsoft/simplechat/blob/main/docs/explanation/fixes/GENERATED_ARTIFACT_PAGING_AND_GUIDANCE_FIX.md), Refs #1071) + +* **Shared Conversation File Approvals Is Reachable From The Sidebar** + * The Shared Conversation File Approvals card had no navigation entry, so it could only be found by scrolling the AI Models tab. It is now listed like every other setting. + * (Ref: `shared-conversation-file-approvals-section`, navigation map) + +* **Navigation Labels And Order Can No Longer Drift** + * The tab strip and the sidebar each maintained the same structure by hand and had diverged: tab order differed between them, and Agents, Custom Pages and Search and Extract each showed a different name depending on which navigation you used. + * Both now render from one definition, so a change is made once and appears in both. + * (Ref: `admin_settings_nav.py`, `test_admin_settings_nav_map.py`) + +* **Cross-Tab Links In Admin Settings Now Point At The Right Place** + * Links that send you from one Admin Settings tab to a related setting used to name a tab button directly, so they broke silently whenever a tab was renamed or reorganised: no tab opened, and the address bar was left pointing at nothing. + * Two were already wrong. The **Video File Support** and **Audio File Support** references in Citations sent you to the **Workspaces** tab, but those settings live under **Search and Extract**. Both now open the correct card. + * All twelve cross-tab links now name the card they want, and the owning tab is worked out when you click. The destination card is briefly highlighted so it is obvious where you landed. + * (Ref: `admin_card_links.js`, `data-admin-link`, `openAdminCard`, `test_admin_card_links.py`) + +* **User Agreement Preview Sanitized At The Sink** + * The User Agreement preview rendered Markdown through a guarded reassignment, which reads as unsanitized to static analysis and matched the pattern already corrected for the Home Page Text preview. + * Now sanitized inline with `DOMPurify.sanitize(...)` at the point of rendering. `marked` and DOMPurify are both loaded globally, so the availability guards were redundant. + * (Ref: User Agreement, `admin_settings.html` preview handler, DOMPurify) + +* **Classification Banner Preview Now Updates As You Type** + * The live preview in Admin Settings never updated, because its script sat between template blocks where Jinja discards it, so the code was never rendered to the page. + * The preview now responds to banner text, background colour, and text colour changes. + * (Ref: Classification Banner, `admin_settings.html` `{% block scripts %}`) + +* **Admin Sidebar Section Map Cleaned Up** + * The sidebar's `sectionMap` had grown to 72 entries, but 66 of them mapped a key to itself, which the existing fallback already handled, and one pointed at an element that no longer exists. + * Reduced to the 6 entries that are genuine aliases. A new test now fails if a redundant, dangling, or unreferenced entry is reintroduced. + * (Ref: `admin_sidebar_nav.js`, `scrollToSection`, `test_admin_settings_sidebar_card_parity.py`) + +* **Home Page Text Preview No Longer Reinterprets Editor Text As HTML** + * The Home Page Text preview in Admin Settings assigned the raw editor contents to `innerHTML` when the Markdown editor had not initialized, so text typed into the editor was reinterpreted as HTML. CodeQL flagged this as `js/xss-through-dom` (high severity). + * The raw fallback now uses `textContent`, which is what the code intended by "just show raw text", and the Markdown path is sanitized inline with `DOMPurify.sanitize(...)` at the sink. DOMPurify is loaded globally from the local vendored bundle, so no external asset is introduced. + * (Ref: Home Page Text, `admin_settings.html` `showPreview`, DOMPurify) + +* **Actions Using the Application Identity Are Now Restricted to Azure Endpoints** + * Actions that authenticate with the application's own managed identity can no longer be pointed at an arbitrary endpoint. Blob Storage, Queue Storage, Cosmos, Databricks, and Log Analytics actions now accept only canonical Azure service hostnames for the public, US Government, China, and Germany clouds. + * Previously a caller holding only the normal **User** role could save a personal action with an attacker-controlled endpoint and application managed-identity authentication, causing the application to send a token minted for its own workload identity to that destination. + * Endpoints are validated when the action is saved and again immediately before the client is built, so actions stored before this release stop working rather than continuing to send credentials. + * Log Analytics custom clouds can no longer choose the Microsoft Entra token authority or the OAuth resource used for delegated tokens. + * Existing actions using standard Azure hostnames are unaffected. Custom domains, development storage, Azure Stack, and direct private-link hostnames are intentionally rejected, matching the Azure Blob File Sync hardening in v0.250.068. + * (Ref: `functions_azure_endpoint_validation.py`, `plugin_health_checker.py`, `blob_storage_plugin.py`, `queue_storage_plugin.py`, `cosmos_query_plugin.py`, `databricks_plugin.py`, `log_analytics_plugin.py`, [Action App-Identity Endpoint Hardening Fix](https://github.com/microsoft/simplechat/blob/main/docs/explanation/fixes/ACTION_APP_IDENTITY_ENDPOINT_HARDENING_FIX.md)) + +* **Action Authentication Types Are Now Enforced on the Server** + * Each action type's supported authentication methods, declared in its schema definition file, are now enforced when an action is saved or tested. Previously the list was only used to populate the action modal and was never checked by the backend. + * This prevents an action type from being configured with an authentication method it was never designed to support, such as requesting application-identity authentication for an OpenAPI or Microsoft Graph action. + * The auth-types API now resolves through the same helper the save paths use, so the modal and the backend cannot drift apart. + * (Ref: `json_schema_validation.py`, `get_allowed_auth_types_for_plugin_type`, `validate_plugin_auth_type_allowed`, `route_backend_plugins.py`) + +* **New Chat Now Clears The Conversation Documents Side Pane** + * Fixed the conversation side drawer keeping the previous conversation's documents after clicking **New chat**. The stale list, the header documents toggle, and its count badge all stayed visible, and the drawer would not close. + * Root cause was the New chat reset signal carrying a null conversation id while `window.currentConversationId` still pointed at the conversation being left, so the drawer fell back to the old conversation and re-fetched its documents instead of clearing. The **Contents** pane was unaffected because it resets from a separate chatbox observer. + * The **Documents** pane now empties out and the drawer closes, matching **Contents** behavior. Switching between existing conversations is unchanged, and one redundant conversation-metadata request per New chat click is eliminated. + * (Ref: `chat-conversation-contents.js`, `refreshConversationDocuments`, `chat:conversation-context-changed`, `updateDrawerTriggers`, Fixes #1298) + +* **Data Management Timeline Steps Now Show Their Own Status** + * Fixed completed job steps showing a `running` badge on the Data Management job timeline. Events such as "Cosmos DB export step completed" and "Migration reconciliation completed" now read `completed`. + * Root cause was `_set_job_progress` stamping the **job** status onto every step event it recorded, so a finished step inherited `running` because the job itself was still running. + * Step status is now decoupled from job status: steps that start report `running`, steps that finish report `completed`, and the job continues running until it genuinely finishes. + * Applies to backup, restore, and migration timelines. + * (Ref: `functions_data_management.py`, `_set_job_progress`, `_complete_job_step`, `_record_data_management_job_event`) + +* **Backup Inventory No Longer Fails To Load** + * Fixed the Backup Inventory panel in Admin Settings → Data Management always returning `503` and showing `0` for available, full, and partial backups. + * The global summary used a Cosmos `GROUP BY` with a non-VALUE aggregate (`COUNT(1) AS count`), a combination the `azure-cosmos` Python client does not support. Cosmos rejected the query during plan negotiation with `BadRequest ... GroupBy NonValueAggregate`. + * Counts are now computed with bounded, fully supported `SELECT VALUE COUNT(1)` queries, so the panel renders real numbers without loading backup history into memory. + * This was not a throttling or indexing problem; the composite index was already aligned. Backup Inventory had been broken since the summary shipped. + * (Ref: `functions_data_management.py`, `_get_data_management_backup_global_summary`, `_count_data_management_backups`, `/api/admin/data-management/backups`) + +* **Missing Release Highlight Screenshots Now Display** + * The Latest Release pages referenced 24 screenshots that were never present in the documentation site, so every one of them rendered as a broken image. + * The images already existed in the application at `application/single_app/static/images/features/`, where the in-app Latest Features gallery reads them. They are now also published with the documentation site, so the release highlight pages show the same screenshots users see in the product. + * (Ref: `docs/images/latest-release/`, `docs/_data/latest_release_features.yml`, Latest Release highlight pages) + +* **Broken Documentation Links Repaired** + * Fixed the remaining broken internal links on the documentation site. Links that pointed at renamed pages now resolve, and links that target files kept in the repository rather than published on the site, such as the Custom Pages developer guide, the Teams app manifest, and a CI workflow, now open on GitHub instead of returning a missing page. + * Removed two references to a ServiceNow multi-action setup guide that was never written. + * The documentation site now has zero broken internal links across 31,649 checked links. + * (Ref: `ui_tests/check_docs_links.js`, ServiceNow guides, Custom Pages guide, upgrade paths guide) + +* **Documentation Site No Longer Overflows Horizontally on Desktop** + * The main content region combined a full-width rule with a sidebar offset, so every desktop viewport scrolled sideways by exactly the sidebar width. This was a long-standing defect on the published site. + * (Ref: `.docs-main-content`, `docs/assets/css/main.scss`) + +* **Documentation Section Labels and Page Titles** + * Path-scoped Jekyll defaults used collection names as their type and therefore never applied, so nearly every page fell back to a generic "Docs" section and search facets were meaningless. Three scenario index pages also had a comment above their front matter, so it was never parsed and they were titled with their own file path and rendered through an empty layout. + * (Ref: `docs/_config.yml` defaults, `docs/explanation/scenarios/`) + +* **Documentation Site Loads No Third-Party Assets** + * Removed jQuery, DataTables, marked, DOMPurify, and split.js, none of which the site used, and vendored Bootstrap, Bootstrap Icons, Prism, Lunr, and the site fonts locally with their licenses. The site now makes zero external requests. + * (Ref: `docs/assets/vendor/`, `docs/_layouts/default.html`, local browser asset policy) + +* **Admin Latest Features Previous and Archive Preview Restored** + * The read-only user-facing preview panel in Admin Settings > Latest Features never rendered, because it sat inside a disabled template block that also holds the legacy hardcoded feature cards from before the tab became data-driven. + * The admin route was already computing and passing `support_latest_feature_release_groups_preview` for a panel that could never display, so admins had no way to review previous and archive release cards alongside their sharing status. + * Closed the disabled block after the legacy cards so the preview panel renders again, and namespaced its element ids to avoid colliding with the admin release-group cards. + * (Ref: `admin_settings.html` Latest Features tab, `support_latest_feature_release_groups_preview`, `route_frontend_admin_settings.py`) + +* **Latest Features Sidebar Card Id Special Case Removed** + * The admin sidebar built the previous-release section link through a redundant conditional that produced the same id as the general dynamic expression. + * Simplified to the dynamic form so every non-current tier, including the new archive tier, is handled the same way. + * (Ref: `_sidebar_nav.html`, admin Latest Features navigation) + +* **Orphaned Latest Features Metadata Tables Removed** + * Removed `_SUPPORT_CURRENT_FEATURE_IMAGE_METADATA` and `_SUPPORT_CURRENT_FEATURE_USER_METADATA` along with the two helpers that consumed them. Their keys matched no feature id in any release tier, so both helpers were no-ops, and the `_CURRENT_` naming became misleading after the release tiers shifted. + * Verified behavior-neutral: the full serialized catalog output across every accessor and several settings permutations is byte-identical before and after removal. + * Added a regression test that generically detects orphaned per-feature metadata tables, so this class of drift is caught in future rather than only these two names. + * (Ref: `support_menu_config.py`, `test_support_menu_config_dead_metadata_removal.py`) + +* **Citations and Source Rendering** + * Citation parsing preserves line breaks after inline citations, agent document search results render as document sources, retrieved and cited sources remain separated, prior grounded references resolve in follow-up turns, and source-reading intent is no longer misclassified as artifact generation. + * (Ref: citation parser, agent document search, grounded source references, generated artifacts) + +* **Shared Conversations and Conversation Forks** + * Shared conversations load, render messages, generate AI responses, refresh uploads/task documents, and survive Blueprint security hardening. + * Forking from group/public workspace knowledge no longer returns HTTP 500, and structured logging normalization prevents logger errors from replacing HTTP responses. + * (Ref: shared conversations, streaming bridge, conversation fork, structured logging) + +* **Workflow Execution Reliability** + * File Sync summaries reach task-based workflow models, task instructions scope document search queries, run history preserves per-task document status, zero-retry settings persist, and invalid task document actions are contained. + * (Ref: workflow execution, task document status, retries, File Sync summaries) + +* **Backup, Restore, and Data Management Reliability** + * Backup ETag normalization, Cosmos pagination, checkpoint batching, and provider status diagnostics improve backup completeness and troubleshooting. + * (Ref: Data Management backup, Backup Inventory, Cosmos pagination, checkpoint batching) + +* **Tabular Analyze/Search Durability** + * Exhaustive Markdown output includes all rows, line-phrased requests route to the durable pipeline, artifact lifecycle finishes before run completion, stale settings migrations correct disabled preflight flags, and `filter_rows contains` semantics match across foreground and durable paths. + * (Ref: tabular analyze, durable preflight, generated artifacts, filter_rows) + +* **Document Extraction and Grounded Search** + * Legacy DOC/PPT embedded images are analyzed, image chunks merge into the correct surrounding-text chunk, document picker search matches file names, and multi-word grounded queries support punctuation word breaks. + * (Ref: embedded images, chunk placement, document picker search, grounded search) + +* **Cosmos, Redis, and Cache Performance** + * Settings container idle RU usage is reduced, no-op read invalidation is skipped, Docker multi-worker startup conflicts recover, DAI Redis TTLs are bounded/refreshed, cache invalidation fails closed on unknown safety state, and cache parity improves for pending shared documents, legacy revisions, and generated-artifact identity. + * (Ref: Cosmos RU usage, conversation cache invalidation, DAI Redis cache, public workspace artifacts) + +* **Authentication and Security** + * Credential-like field names are no longer logged in clear text, action secret references are scoped to their owning action, Terms of Use redirects happen server-side with HTTPS enforcement, and `/getAToken` without an authorization code redirects to sign-in. + * (Ref: credential redaction, action secrets, Terms of Use, authentication redirects) + +* **Model Endpoints and MCP Outbound** + * Managed identity cloud values are normalized, vision test connection uses the correct multi-endpoint target, GPT 5.6+ models appear in the multi-modal vision selector, and MCP tool arguments no longer get wrapped in incompatible `kwargs` payloads. + * (Ref: model endpoints, vision selector, managed identity, MCP outbound) + +* **Governance, Navigation, and Admin Settings** + * Retargeting policies no longer creates duplicates, block-list modals stack correctly, Group Workflows appears in the sidebar, hidden tabs hide sidebar links, logo/favicon save paths no longer 500, and update banner version comparison no longer shows stale releases as newer. + * (Ref: governance policies, workspace sidebar, admin settings, update banner) + +* **Retention, Notifications, Logging, and Public Workspace Edge Cases** + * Group and collaboration conversations now use correct retention policy/activity timestamps, unauthenticated pages avoid notification polling 401 noise, Application Insights events carry sanitized diagnostic values with standardized tags, custom Databricks-prefixed plugin discovery avoids built-in defaults, and hidden public workspace documents can ground chat searches. + * (Ref: retention policy, notification polling, Application Insights logging, plugin discovery, public workspace search) + +* **Citations No Longer Eat the Line Break After Them** + * Text that came after an inline document citation was jammed onto the end of the closing parenthesis instead of starting a new paragraph — you would see `(Source: uploading_documents.md, Page: 1)Thank you, Paul.` with no break at all. + * The citation parser matched the `[#citation-id]` marker along with the whitespace that followed it, then rebuilt the citation without putting that whitespace back. Because this runs on the raw markdown before it is rendered, a deleted blank line did not just remove a space — it changed how the rest of the block was read, so a paragraph after a cited list item got absorbed into the list item itself. + * Spacing is now restored exactly as the model wrote it. Paragraphs, bullets, and numbered lists after a citation render in their intended structure, a citation followed by more text on the same line keeps its space, and back-to-back citations stop colliding. Copied and exported message text keeps its line breaks for the same reason. + * The cleanup pass for leftover citation markers had the same flaw in reverse and could swallow the blank line *before* a stray marker. It now only removes horizontal spacing, or the marker's whole line when it sits on one. + * (Ref: [#1289](https://github.com/microsoft/simplechat/issues/1289), `chat-citations.js`, `parseCitations()`, chat message rendering) + +* **Figures Now Stay in the Chunk They Came From** + * Images extracted from Word and PowerPoint files were appended as extra chunks at the end of the document, with page numbers continuing past the real content. A figure on page 5 of a 15-page document became chunk 16, so a search hit on the figure lost its surrounding text and citations pointed at a page that did not exist. + * Embedded images are now merged into the chunk containing the text they appear with. PowerPoint images follow the slide that references them; Word images are placed by their position in reading order; and legacy `.doc` and `.ppt` images, which carry no recoverable position, anchor to the final chunk instead of creating a page beyond the document. + * Merging rather than adding a chunk also removes a latent indexing hazard: chunk ids are derived from the page number, so a second chunk sharing a page number would have overwritten the first in the search index. + * PDFs were already correct — Content Understanding attributes each figure to its page by span, and Document Intelligence Layout inlines tables and figures into the page markdown. That behavior is unchanged and now covered by a regression test. + * **Existing documents keep their current chunks until they are extracted again.** Use *Change Extraction* or re-upload to pick up the new placement. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_documents.py`, `functions_office_media.py`, figure chunk association) + +* **Shared Conversation Stream Errors Stay Attached to the Shared Conversation** + * Follow-up hardening to the v0.250.224 shared conversation fix. When an AI request in a shared conversation failed, the error the browser received did not say which kind of conversation it belonged to, so the recovery path could have reloaded from the personal endpoint and produced the same "Conversation not found" error that was just fixed. + * It could not actually happen yet because of an unrelated guard, but it would have come back the moment anyone added a message id to those errors. All shared stream failures now go through a single serializer that always tags the conversation, and a test walks the code to prove no failure path can skip it. + * (Ref: [#1281](https://github.com/microsoft/simplechat/issues/1281), `route_backend_collaboration.py`, `chat-streaming.js`, collaborative AI streaming) + +* **Repaired Route Assertions Across the Test Suite** + * The recent Blueprint security hardening renamed how routes are declared, but 82 assertions across 40 test files still checked for the old form. Those tests were failing on the rename before they ever reached the behavior they were written to protect. + * This is how the shared conversation streaming bug reached users: the test guarding that exact code path was already red for an unrelated reason. 59 assertions across 32 files were corrected, each verified against a real route first. 14 were deliberately left alone because they point at routes that no longer exist, which is a separate issue worth investigating rather than hiding. + * (Ref: [#1281](https://github.com/microsoft/simplechat/issues/1281), `functional_tests/`, Blueprint route registration) + +* **File Sync Now Tells the Workflow What Changed** + * File Sync builds a summary of each run — the scan counts plus every new or changed document — but that summary never reached the model in any workflow that uses tasks, which is every workflow the builder creates. + * The failure was silent and misleading: the summary *was* written into the conversation, so the transcript showed the changed-document list as though the model had received it. In practice the model saw only the raw task instructions and usually replied that it knew nothing about any documents. + * This hit **Monitor File Sync Changes** workflows hardest, along with any workflow using Search or no document action, or with **Use changed documents** turned off. The first task in the sequence now receives the summary, and later tasks get it through the first task's response. + * The summary is also bounded now, with a clear truncation notice, so a very large sync cannot crowd out the actual instructions. + * (Ref: [#1285](https://github.com/microsoft/simplechat/issues/1285), `functions_workflow_runner.py`, File Sync prompt context) + +* **Document Search Queries Are No Longer Diluted by Injected Context** + * A workflow's document search used the entire task prompt as its search query, including the File Sync summary and the previous task's full response. A search for "find the renewal clause" could end up querying 50 lines of file paths. + * Search queries now use the task's own instructions. Retrieved content and context still reach the model exactly as before — only the query is scoped. + * (Ref: [#1285](https://github.com/microsoft/simplechat/issues/1285), `functions_workflow_runner.py`, workflow document search) + +* **Workflow Document Picker No Longer Hangs on "Loading tags..."** + * Choosing a Document action of Search, Analyze, or Compare in the workflow builder revealed the document picker but never loaded it. Tags stayed disabled showing `Loading tags...` forever, the document list stayed empty, and no console error appeared. + * The picker was only ever loaded when the modal opened, and that path returned early whenever the action was `No document action` — which is always true for a new workflow. The Document action dropdown's change handler only toggled visibility and never triggered a load. + * Changing the Document action or Document Target now loads the picker, and the tags control always resolves to the available tags or `No tags available for this scope`. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `workspace_workflows.js`, `chat-documents.js`, workflow document picker) + +* **Workflow Run History No Longer Masks a Failed Document** + * When two tasks in the same run process the same document, the later task's status used to overwrite the earlier one's, so a document that failed in one task could be shown as succeeded. + * Document run items are now recorded per task, and each item records which task produced it. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `functions_workflow_runner.py`, workflow run history) + +* **Resume Failed Items Respects Per-Task Documents** + * Resuming failed documents narrowed only the workflow-level document action. Now that tasks own their own documents, it also narrows each task's analyze action to the documents that failed in that task, and group resumes keep every task inside the owning group workspace. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `route_backend_workflows.py`, resume failed items) + +* **A Workflow Task Configured for Zero Retries Per Window Stays at Zero** + * Saving a multi-task workflow rewrote a stored `Retries Per Window` of `0` to `1` on any task other than the one being edited. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `workspace_workflows.js`, retries per window) + +* **An Invalid Task Document Action No Longer Aborts the Whole Run** + * If a workflow's document action stopped validating between runs — for example an administrator disabled Analyze or Compare, or lowered the workflow document limit — the run failed outright with no task-level error recorded. + * The failure is now contained to that task and follows the workflow's retry and failure-handling settings. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `functions_workflow_runner.py`, workflow task error handling) + +* **Shared Conversations Load and Answer Again** + * Sharing a personal conversation left it unusable. Every reload or click on the shared conversation raised a "Conversation not found" error, because the chat page was still asking for its messages from the personal conversation endpoint — and a shared conversation is stored separately, under its own id. + * Shared conversations now load their messages only from the collaboration endpoint, so the failed request and the error banner are gone. + * (Ref: [#1281](https://github.com/microsoft/simplechat/issues/1281), `chat-conversations.js`, `chat-collaboration.js`, shared conversation loading) + +* **AI Responses Work Again in Shared Conversations** + * Asking the AI anything in a shared conversation failed immediately with "Stream interrupted: Chat streaming endpoint is unavailable" and no answer was ever generated. + * The recent Blueprint security hardening renamed the internal chat streaming endpoint, and the shared-conversation bridge was still looking for the old name. The bridge now resolves the endpoint correctly and logs a diagnostic if it ever cannot, so this fails loudly instead of silently. Group shared conversations are restored by the same fix. + * (Ref: [#1281](https://github.com/microsoft/simplechat/issues/1281), `route_backend_collaboration.py`, `app.py`, collaborative AI streaming) + +* **Chat Uploads and Task Documents in Shared Conversations** + * Files uploaded inside a shared conversation never showed up in the Analyze and Compare document pickers, and task documents from the previously opened conversation stayed attached after switching to a shared one. + * Shared conversations now refresh both when their messages load, matching personal conversation behavior. + * (Ref: [#1281](https://github.com/microsoft/simplechat/issues/1281), `chat-collaboration.js`, `chat-messages.js`, Compare and Analyze document pickers) + +* **Images in Legacy `.doc` and `.ppt` Files Are Now Analyzed** + * Embedded image analysis previously covered only DOCX and PPTX, because legacy Office files are OLE compound documents rather than zip packages and have no media parts to enumerate. + * Pictures and embedded equation previews are now carved out of the legacy container by metafile signature, using the length recorded in the metafile's own header, then rasterized and analyzed like any other embedded image. + * Validation is strict — record type, signature position, and a length that fits the remaining bytes — so a coincidental byte sequence is not mistaken for an image. Duplicate images are still collapsed and the per-document cap still applies. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_office_media.py`, `functions_documents.py`, legacy Office image extraction) + +* **Diagrams in Word and PowerPoint Files Are Now Analyzed** + * Images embedded in Office documents as EMF or WMF metafiles were silently skipped. Word stores pasted diagrams, SmartArt, Visio drawings, and charts in this format, so architecture diagrams — often the most information-dense figures in a document — were never analyzed or indexed. + * Metafiles are now rasterized in-process and sent to the configured extraction engine like any other image. Text drawn inside the diagram is recovered as well, so figure labels such as service and resource names become searchable even when the vision engine returns no description. + * The renderer is pure Python on top of Pillow, with no system packages or external converters, so it behaves the same in the Linux container as it does locally. Fidelity is intentionally a description aid rather than a pixel-accurate reproduction; unsupported drawing records are skipped rather than failing the document. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_emf_render.py`, `functions_office_media.py`, embedded Office image analysis) + +* **Embedded Image Processing Is Now Visible in the Workspace Log** + * A document whose images were all skipped looked exactly like a document with no images at all, so there was no way to tell whether embedded image analysis had run. + * Processing now reports how many embedded images were found, how many were analyzed, and why any were skipped — too small, duplicates, unsupported format, or over the per-document cap. Progress is reported per image rather than only once at the start. + * The found, analyzed, and skipped counts are stored on the document so the outcome can be confirmed after processing completes. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_documents.py`, `functions_office_media.py`, embedded image diagnostics) + +* **Data Management History Failure Diagnostics** + * Backup Inventory and Job History failures returned a generic 503 telling admins to review application logs, while the logs recorded only the exception class name. The provider status code and message were discarded, making the failure impossible to diagnose. + * Failures now log the Cosmos status code and sanitized provider message. Provider text stays in operator logs and is never returned to the browser. + * (Ref: [#1275](https://github.com/microsoft/simplechat/issues/1275), `functions_data_management.py`, `route_backend_data_management.py`, Data Management history) + +* **Data Management History Throttle Handling** + * Throttled history reads previously produced the same opaque error as a permanent failure. + * Cosmos throttling is now detected, retried up to three times with jittered backoff, and reported as temporary busy guidance with a retryable flag instead of a generic error. + * (Ref: [#1275](https://github.com/microsoft/simplechat/issues/1275), `functions_data_management.py`, Cosmos history query retry) + +* **Data Management History Index Guidance** + * Missing-index detection required the exact phrase "composite index", so equivalent provider wording fell through to the generic error. + * Detection now also matches `ORDER BY` failures reported as having no corresponding index, keeping the Cosmos indexing maintenance guidance actionable. + * (Ref: [#1275](https://github.com/microsoft/simplechat/issues/1275), `functions_data_management.py`, Cosmos indexing maintenance) + +* **Source Blob Backup ETag Failure** + * Fixed every source blob failing backup with "Source blob changed while it was being backed up", which meant user documents, group documents, public documents, and chat attachments were never actually backed up. + * Root cause was comparing an ETag from `list_blobs()` (unquoted XML element) against one from `get_blob_properties()` (RFC-quoted HTTP header); the two never matched, so the post-transfer consistency check always failed after the blob had already been downloaded and uploaded. + * Both values are now normalized before comparison. The precondition sent to Azure is unchanged, and a genuine mid-transfer source change is still rejected. + * (Ref: [#1271](https://github.com/microsoft/simplechat/issues/1271), `functions_data_management.py`, source blob transfer verification) + +* **Source Blob Backup Checkpoint Throughput** + * Source blob backups previously wrote one Cosmos checkpoint per blob, capping throughput at roughly six items per second and stretching a single container to over an hour. + * Checkpoints are now batched per 100 items or 15 seconds, whichever comes first, while still asserting the job lease on every item. + * (Ref: [#1271](https://github.com/microsoft/simplechat/issues/1271), `functions_data_management.py`, source blob checkpointing) + +* **Functional Tests Silently Passing Under pytest** + * Backup functional tests written with the try/except and `return False` template were reported as passed by pytest because they returned a value instead of raising. + * The backup ETag and Cosmos pagination test files now assert directly, so real failures are reported by both pytest and standalone execution. + * (Ref: [#1271](https://github.com/microsoft/simplechat/issues/1271), `test_data_management_backup_source_blob_etag.py`, `test_data_management_backup_cosmos_pagination.py`) + +* **Agent Document Search Now Produces Real Document Citations** + * Documents an agent retrieved through the document search action are now recorded as document sources instead of only as an agent tool call. Previously they appeared solely as a raw JSON tool modal, so the documents were missing from the message Sources disclosure, were not clickable, never opened in the enhanced citation viewer, and could never reach the Used documents drawer. + * Covers all three document search functions — relevance-ranked search, ordered chunk retrieval, and document summarization — across personal, group, and public workspaces. + * Document search results now carry a ready-to-copy citation value, and the action instructs the model to reuse it verbatim. When the answer cites a document, it is correctly separated from the retrieved sources and recorded in the conversation's used documents. + * Applies to streaming and non-streaming chat, document actions, cancelled and interrupted streams, and scheduled workflow runs. + * Retrieved sources are deliberately not capped, so a search that sources hundreds of chunks records all of them. Chunks retrieved by both the document search toggle and an agent are listed once. + * Cancelled and interrupted streams keep the documents the agent had already retrieved, and citation locations no longer relabel a valid page or sequence of `0` as page 1, which affected video chunks keyed by second. + * Workspace capability metadata now reports document usage for agent-only document turns, which previously under-reported as unused. + * (Ref: [#1239](https://github.com/microsoft/simplechat/issues/1239), `functions_agent_document_citations.py`, `route_backend_chats.py`, `functions_workflow_runner.py`, `document_search_plugin.py`, `AGENT_DOCUMENT_SEARCH_CITATION_FIX.md`) + +* **Credential Field Names Logged in Clear Text** + * Fixed a gap where credential values could be written to application logs and Application Insights in clear text. The log redactor matched only a fixed list of key-name substrings, so field names this codebase actually uses for secrets were missed. The most significant were `auth_key`, used by the action connection-test routes for the caller-supplied secret, and the plugin manifest's `auth.key`, which holds connection strings and service principal passwords. + * Eighteen credential key names were affected in total, including `pwd`, `key_pair`, `master_key`, `primary_key`, `secondary_key`, `encryption_key`, `signing_key`, `session_key`, and `storage_key`. + * Benign configuration keys that merely contain the word "key", such as `key_encoding`, `key_prefix_hints`, and `partition_key_path`, deliberately stay visible so logs keep their diagnostic value. + * (Ref: `functions_appinsights.py`, `test_log_credential_key_redaction.py`, `LOG_CREDENTIAL_KEY_REDACTION_FIX.md`) + +* **CosmosClient Import Bindings in Helper Scripts** + * Completed the v0.250.047 import-binding cleanup by updating the two remaining scripts that bound `CosmosClient` directly, so patching `azure.cosmos.CosmosClient` is observed consistently. No direct `CosmosClient` imports remain in the repository. + * (Ref: `scripts/resolve_multiendpoint_gpt.py`, `deployers/bicep/postconfig.py`) + +* **Privacy Logging Audit Test Restored** + * The privacy logging and telemetry audit had been failing since v0.242.072 because it asserted an exact `config.py` version and never reached its assertions. It now asserts a version floor, per the repository's version-assertion guidance, so the audit runs again. + * (Ref: `test_privacy_logging_telemetry_audit.py`) + +* **Action Secret References Now Resolved Only Within Their Own Scope** + * Action connection tests resolve a stored Key Vault secret reference strictly against the scope of the action being tested, instead of resolving any reference name supplied in the request. + * The unscoped resolver has been removed, and the existing MCP tool discovery, Cosmos DB, SQL, Yamcs, and RocksDB test paths now share the same scope-checked resolution used by the new connection tests. A reference that does not match the action's scope is rejected instead of resolved. + * Loading a global action for a connection test now requires the Admin role at the shared loader, so every test route inherits the check rather than relying on each route to gate it. + * Only affects deployments with Key Vault secret storage enabled. Normal editing is unchanged — testing an existing action still works without retyping stored credentials. + * (Ref: [#1267](https://github.com/microsoft/simplechat/issues/1267), `route_backend_plugins.py`, `functions_keyvault.py`, action secret scoping) + +* **Retrieved Sources and Cited References** + * Separated complete document/web retrieval results from the exact references used in final assistant responses, while preserving all returned results under **Sources**. + * Used documents now follows active cited responses, conversation details marks cited items within the full source inventory, and conversation/message export references exclude retrieved-only sources. + * Historical conversations retain their previous fallback without a migration or ordinary read-time history parsing. + * (Ref: [#1249](https://github.com/microsoft/simplechat/issues/1249), `functions_citation_tracking.py`, `route_backend_chats.py`, `route_backend_conversation_export.py`, `SOURCE_AND_CITED_REFERENCE_DISTINCTION_FIX.md`) + +* **Agent Summary Step Referenced the Wrong Step Number** + * The Summary step's empty-actions message pointed authors at "step 4" to add actions. Actions is step 3 under the new order, and step 4 is now Assigned Knowledge. + * (Ref: [#1263](https://github.com/microsoft/simplechat/pull/1263), `_agent_modal.html`, agent modal summary step) + +* **Group Workflows Missing From Sidebar Navigation** + * Added the missing Group Workflows link to the left-hand group workspace submenu. Group workflows previously had a working tab but no way to reach it from the sidebar. + * (Ref: [#1255](https://github.com/microsoft/simplechat/issues/1255), `_sidebar_nav.html`, group workflows navigation) + +* **Sidebar Links Pointing At Unrendered Workspace Tabs** + * Fixed left-hand navigation links whose visibility rules did not match the tabs they opened, so a link could appear for a section that was never rendered. + * Personal Agents and Actions links now respect the user agent and plugin permissions, group Agents and Actions links now respect per-user Semantic Kernel and group plugin permissions, and both Identities links now match their tab's File Sync and Semantic Kernel conditions. + * (Ref: [#1255](https://github.com/microsoft/simplechat/issues/1255), `_sidebar_nav.html`, `test_workspace_section_order.py`) + +* **Chat Document Search Now Matches File Names** + * Fixed the chat grounded-search document picker only matching on a document's title, which made file names completely unsearchable for any document that had extracted title metadata. + * Typing any fragment of a file name now surfaces the document, anywhere in the name — searching `200` finds `Quarterly_Report_200_final.pdf`. + * Multi-word queries are also supported, with `_`, `-`, and `.` treated as word breaks, so `report 200` matches `Quarterly_Report_200_final.pdf`. The same improvement applies to the scope, tags, prompt, model, and agent selectors. + * (Ref: [#1256](https://github.com/microsoft/simplechat/issues/1256), `chat-documents.js`, `chat-searchable-select.js`, chat grounded search, document picker) + +* **Leftover Separator Lines in Filtered Dropdowns** + * Fixed filtered dropdowns leaving orphaned workspace separator lines behind — commonly two stacked horizontal rules directly under the "Select All" / "Clear All" row — when a search removed the leading sections. + * Divider visibility now follows the section it separates instead of the nearest visible row, and separator lines can no longer be leading, trailing, or stacked. Affects the Document, Scope, and Tags dropdowns, plus the Compare modal document picker. + * (Ref: [#1256](https://github.com/microsoft/simplechat/issues/1256), `chat-searchable-select.js`, dropdown filtering, section dividers) + +* **Cosmos Backup Continuation Token Failure** + * Fixed Data Management backups silently omitting every Cosmos container that held more than one page of documents, which in most deployments meant personal conversations and personal messages were never backed up. + * Affected containers failed with `BadRequest: Invalid Continuation Token` and were dropped from the backup artifact set while the job still reported completion with warnings. + * Root cause was rebuilding the cross-partition query for each page and replaying the previous pager's continuation token; the backup now drains a single pager so the SDK's cross-partition execution context is preserved. + * (Ref: [#1258](https://github.com/microsoft/simplechat/issues/1258), `functions_data_management.py`, Cosmos backup source paging) + +* **Missing Backup Failure Diagnostics** + * Source blob transfer failures previously produced no log output at all, so a run with nearly 20,000 failed blobs left no trace in App Service logs. + * Backups now log the first failure for each resource plus a bounded rollup of distinct failure reasons and counts when the resource finishes. + * (Ref: [#1258](https://github.com/microsoft/simplechat/issues/1258), `functions_data_management.py`, source blob backup logging) + +* **Application Insights Log Message Text** + * Structured log events reached Application Insights as the constant `[SIMPLE_CHAT_LOG_EVENT]` with every string property reduced to a character count, making traces unusable for diagnosis. + * Traces now carry the sanitized message text and an allowlist of non-sensitive diagnostic values such as job ID, resource, container, status code, and error. Sensitive keys still collapse to a presence flag and secret redaction is unchanged. + * (Ref: [#1258](https://github.com/microsoft/simplechat/issues/1258), `functions_appinsights.py`, log event properties) + +* **Intentional Governance Item Policy Retargeting** + * Updated delegated item policy edits so admins can intentionally move an existing policy to a different delegated item without creating a duplicate policy document. + * The admin UI keeps the policy ID stable, warns that changing the target will move the policy, and the backend saves the new target while deleting the original source document when original target metadata is supplied. + * Also prevents ambiguous policy-ID reuse and keeps feature-policy saves and item-policy deletes out of the retarget conflict path. + * (Ref: [#1252](https://github.com/microsoft/simplechat/issues/1252), `functions_governance.py`, `route_backend_governance.py`, `admin_governance.js`) + +* **Governance Item Policy Retarget Protection** + * Fixed delegated item policy edits so changing the selected target no longer creates a duplicate policy document for the new item while leaving the old policy behind. + * Locks the target controls during existing policy edits and rejects conflicting backend saves when an existing policy ID is reused for a different delegated item. + * (Ref: [#1252](https://github.com/microsoft/simplechat/issues/1252), `admin_governance.js`, `route_backend_governance.py`, `functions_governance.py`) + +* **Governance Block List Modal Handoff** + * Fixed the delegated item block-list editor opening behind the item policy editor by hiding the parent modal before opening the shared principal editor, then restoring the item editor after the principal editor closes. + * Keeps Bootstrap modal focus, backdrop, and scroll handling consistent by ensuring only one governance modal is visible at a time. + * (Ref: [#1252](https://github.com/microsoft/simplechat/issues/1252), `admin_governance.js`, `test_admin_governance_tab.py`) + +* **Live User Message Metadata During Streaming** + * Made submitted user-message metadata available as soon as storage is acknowledged, without waiting for the assistant response to finish or requiring a page refresh. + * Preserved finalized metadata across success, server errors, cancellation, disconnect, recovery, image generation, document actions, and shared-chat streams while keeping in-flight message mutations gated until terminal completion. + * (Ref: [#1244](https://github.com/microsoft/simplechat/issues/1244), `functions_chat_stream_events.py`, `chat-streaming.js`, `chat-messages.js`, `USER_MESSAGE_METADATA_STREAMING_FIX.md`) + +* **Exhaustive Row-by-Row Markdown Output** + * Fixed line-by-line Markdown analysis reading every source row but publishing only 12 summarized findings because the previous hierarchical lane intentionally bounded findings and notable rows. + * Search now produces one exhaustive Markdown artifact containing every source row and every requested answer; Analyze produces a concise Markdown summary plus a separate exhaustive row-by-row Markdown artifact. + * Exact-row Markdown uses ordered checkpoints, output-aware batching, consecutive answer-field validation, non-empty answer enforcement, final row-count/source-order checks, and literal Markdown escaping for untrusted content. + * (Ref: [#1233](https://github.com/microsoft/simplechat/issues/1233), `functions_tabular_orchestration.py`, `functions_tabular_generated_exports.py`, `route_backend_chats.py`, `TABULAR_EXHAUSTIVE_ROW_MARKDOWN_FIX.md`) + +* **Hidden Public Workspace Document Chat Grounding** + * Fixed document chat handoffs from accessible public workspaces that users had hidden from the public directory, so the selected document is now available to grounded search instead of appearing selected while being silently excluded. + * Adds the selected workspace to the user's visible Chat workspaces without hiding any existing choices and revalidates the requested public workspace before updating user settings. + * (Ref: [#1245](https://github.com/microsoft/simplechat/issues/1245), `route_frontend_chats.py`, `test_public_workspace_hidden_document_chat_visibility.py`, `PUBLIC_WORKSPACE_HIDDEN_DOCUMENT_CHAT_VISIBILITY_FIX.md`) + +* **Tabular Analyze/Search Artifact Lifecycle Completion** + * Preserved the selected model endpoint for pure-tabular Analyze background work, preventing non-default model selections from falling back to an unavailable deployment on the default Azure OpenAI resource. + * Enforced one artifact contract across Search and Analyze: Search CSV produces CSV; Analyze CSV produces Markdown plus CSV; exhaustive requests without an explicit output format produce Markdown in either mode. + * Made artifact publication complete before run completion, repaired previously uploaded-but-hidden Markdown artifacts during status reconciliation, and preserved original generation failures instead of masking them as schema errors. + * Removed misleading one-row Analyze CSV handoff artifacts and added sanitized user-visible failure reasons without exposing provider errors or endpoint details. + * (Ref: `functions_tabular_orchestration.py`, `functions_workflow_runner.py`, `functions_tabular_generated_exports.py`, `TABULAR_DURABLE_ARTIFACT_LIFECYCLE_FIX.md`) + +* **Tabular Parity Stale Settings Migration** + * Fixed the four backend-only tabular durable-preflight parity flags (`tabular_request_planner_mode`, `enable_tabular_search_shared_preflight`, `enable_tabular_analyze_durable_preflight`, `enable_tabular_hierarchical_analysis`) silently staying disabled on any deployment whose Cosmos settings document already stored them from before their defaults were raised to active. + * `get_settings()` merges code defaults into the persisted document via `deep_merge_dicts()`, which only fills in missing keys and never overwrites an existing one, so raising a default in code alone never took effect for upgraded-in-place deployments. + * Both Analyze and Search durable preflight now self-correct to the active defaults on the next settings load and persist the fix back to Cosmos DB; the `SIMPLECHAT_DISABLE_TABULAR_PARITY_DURABLE_PREFLIGHT` emergency rollback env var continues to work unchanged. + * (Ref: `functions_settings.py`, `normalize_tabular_parity_durable_preflight_defaults()`, `TABULAR_PARITY_STALE_SETTINGS_MIGRATION_FIX.md`) + +* **Tabular "Line" Terminology Routing** + * Recognized "line"-phrased exhaustive tabular requests (for example, "for each line," "line by line," "one line per") as equivalent to "row"-phrased requests across eight duplicated keyword-detection functions, so they route through the durable generated-output/analysis pipeline instead of the bounded foreground tool-calling path. + * Activated `enable_tabular_hierarchical_analysis` by default so narrative (non-export) exhaustive whole-dataset Analyze/Search requests can resolve to the durable `hierarchical_analysis` task type, extending the existing emergency env kill switch to also cover this flag. + * (Ref: `functions_tabular_orchestration.py`, `functions_tabular_parity_contract.py`, `route_backend_chats.py`, `functions_document_analysis.py`, `TABULAR_LINE_TERMINOLOGY_ROUTING_FIX.md`) + +* **Top Navigation Public Workspace Lockout** + * Fixed a server-rendering failure that could lock users out after they selected top navigation while Public Workspaces was enabled. + * Preserved the saved navigation preference and default or customized Public Workspace labels without requiring a Cosmos profile repair. + * (Ref: `_top_nav.html`, `test_public_workspace_display_name_settings.py`, `TOP_NAV_PUBLIC_WORKSPACE_LABEL_CRASH_FIX.md`) + +* **Analyze Combined Generated Output Routing** + * Treats Analyze requests that ask for row-level answers plus CSV/JSON/XML output as first-class combined durable work, producing both the Markdown analysis artifact and requested structured output artifacts. + * Queues planner-approved combined tabular Analyze work before foreground tabular tools run, preventing empty inline tool output from becoming a stream-level 500. + * Carries the selected model endpoint context into background generated-output runs so non-default endpoints do not fall back to an Azure OpenAI deployment name lookup. + * (Ref: [#1233](https://github.com/microsoft/simplechat/issues/1233), `functions_tabular_orchestration.py`, `functions_workflow_runner.py`, Analyze deliverable contract, combined durable generated output) + +* **Data Management Scheduler Context Guard** + * Prevented the background Data Management scheduler from using request-context-copying executor APIs when no Flask request context exists. + * Scheduler-submitted jobs now use the existing worker-thread path outside request handling, while route-triggered submissions can still use the configured executor. + * (Ref: `functions_data_management.py`, Data Management scheduler, background job submission) + +* **Analyze Artifact Copilot Review Cleanup** + * Preserved explicit request order for combined JSON/XML artifact requests when both formats share the same action phrase. + * Kept explicit unchanged-copy requests eligible even when source field names include descriptive terms such as risk or status. + * Made semantic validation shadow mode fail open on verifier errors and prevented the chat UI from falling back to withheld legacy artifacts when `generated_artifacts` is explicitly empty. + * (Ref: PR [#1238](https://github.com/microsoft/simplechat/pull/1238), Copilot review comments, generated artifact ordering, semantic validation shadow mode, plural artifact UI) + +* **Analyze Artifact Advanced Security Cleanup** + * Replaced a self-comparison float finite check in the tabular transformation validator with an explicit finite-number check. + * Simplified an unnecessary callable wrapper in the Phase 7B production-correctness functional test harness. + * (Ref: PR [#1238](https://github.com/microsoft/simplechat/pull/1238), GitHub Advanced Security comments, tabular transformation validation) + +* **Analyze Artifact Output Contract Closure** + * Made Analyze generated-output delivery Markdown-first and contract-faithful across durable tabular execution by adding reviewed transformation planning, deterministic server-side rules, bounded semantic verification and repair, and exact Search/Analyze 200-row parity validation. + * Hardened artifact-set publication so new staged generated artifacts are not downloadable or promotable until the completed run manifest commits every required member, while preserving legacy generated artifact compatibility. + * Restored explicit Word/DOCX current-turn function-result serialization and repaired cumulative lifecycle, scale, route, and UI validation harnesses through 30,000-row bounded finalization and 100,000-row deterministic planning/hardening contracts. + * (Ref: [#1233](https://github.com/microsoft/simplechat/issues/1233), PR [#1234](https://github.com/microsoft/simplechat/pull/1234), PR [#1235](https://github.com/microsoft/simplechat/pull/1235), PR [#1236](https://github.com/microsoft/simplechat/pull/1236), Analyze deliverable contract, tabular transformation contract, artifact-set publication lifecycle) + +* **Rendered Admin Tabular Run Controls Coverage** + * Replaced source-only coverage with an authenticated browser regression that verifies the Admin Settings controls render, submit, survive reload, and restore their original values. + * Guarded shared settings mutation behind an explicit isolated-environment opt-in and limited configured-model testing to routable legacy direct or APIM deployments. + * (Ref: [#1201](https://github.com/microsoft/simplechat/issues/1201), `ui_tests/test_admin_tabular_run_controls.py`, Admin Settings tabular run controls) + +* **Large Tabular Run Confirmation Deduplication** + * Prevented repeated Send clicks or Enter presses from opening concurrent confirmation waiters and starting the same expensive tabular run more than once. + * Restored normal sending after the user continues, narrows scope, dismisses the dialog, or an unexpected confirmation error occurs. + * (Ref: Fixes [#1200](https://github.com/microsoft/simplechat/issues/1200), `chat-messages.js`, `test_chat_background_generated_export_status.py`) + +* **Tabular Execution Settings Sanitization** + * Prevented normal user-facing settings responses from exposing admin-only hierarchical-analysis, chunk-model deployment, and model-validation retry controls. + * Preserved the durable-run confirmation settings required by chat so users continue to receive prompts before very large tabular runs. + * (Ref: [#1199](https://github.com/microsoft/simplechat/issues/1199), `sanitize_settings_for_user()`, `TABULAR_GENERATION_BACKEND_SETTING_KEYS`) + +* **Tabular Parity Rollout and Lifecycle Hardening** + * Enforced parity canary assignment before durable execution and included authorized source versions in request and unit fingerprints. + * Preserved failed and canceled durable outputs as terminal incomplete evidence, including all-canceled per-document Analyze results, and corrected Analyze parity telemetry classification. + * Renamed incomplete multi-file and deferred-composition controls as planning-only and exposed that durable fan-out and automatic continuation are unavailable without changing working single-source or per-document behavior. + * (Ref: PR [#1219](https://github.com/microsoft/simplechat/pull/1219), [#1031](https://github.com/microsoft/simplechat/issues/1031), [#1055](https://github.com/microsoft/simplechat/issues/1055), [#1058](https://github.com/microsoft/simplechat/issues/1058), `functions_tabular_orchestration.py`, `functions_workflow_runner.py`, `route_backend_chats.py`) + +* **getAToken Missing Authorization Code Redirect** + * Redirects direct `/getAToken` browser visits without an OAuth authorization code back to the home sign-in page instead of showing a technical callback error. + * Preserves the normal Microsoft Entra authorization-code callback flow and keeps `/getATokenApi` explicit error behavior unchanged for API token callbacks. + * (Ref: `/getAToken` OAuth callback, `route_frontend_authentication.py`, `test_getatoken_missing_code_redirect.py`) + +* **Prior Grounded Source Continuity** + * Follow-up mixed-source turns can now detect references such as "that XML file," "same template," or "previous spreadsheet" and merge reauthorized prior grounded sources with the current selected sources. + * Preserved authorization boundaries by deriving prior sources from `last_grounded_document_refs` and revalidating scope before use. + * (Ref: [#1204](https://github.com/microsoft/simplechat/issues/1204), mixed-source source continuity, `route_backend_chats.py`, `test_chat_history_grounded_follow_up_fix.py`) + +* **JSON/XML Source-Only Intent Guardrails** + * Prevented source-reading prompts such as "Summarize this XML document" and "Validate this JSON object" from being misclassified as generated artifact requests. + * Kept explicit output requests such as "Export as JSON" and "Create an XML file" routed to generated artifact workflows. + * (Ref: [#1198](https://github.com/microsoft/simplechat/issues/1198), structured artifact intent detection, `functions_generated_file_exports.py`, `test_generated_json_xml_exports.py`) + +* **Tabular Contains Replay Semantics** + * Aligned foreground `filter_rows contains` matching with durable CSV replay by using literal, case-insensitive containment in both paths. + * Added regression coverage for regex-shaped values such as `A.*` so previews and generated export replays select the same row cohort. + * (Ref: [#1197](https://github.com/microsoft/simplechat/issues/1197), tabular durable replay descriptors, `tabular_processing_plugin.py`, `test_tabular_large_result_pagination.py`) + +* **Outbound MCP Tool Argument Normalization** + * Fixed outbound MCP tool calls that could wrap parameters inside a `kwargs` object, preventing standards-compliant MCP servers from seeing required top-level fields such as `type`. + * Added schema-aware normalization before MCP argument validation and invocation while preserving tools that explicitly define a real top-level `kwargs` property. + * (Ref: [#1163](https://github.com/microsoft/simplechat/issues/1163), MCP `tools/call` arguments, `functions_mcp_operations.py`, `mcp_plugin.py`, `mcp_plugin_factory.py`) + +* **Replayable Exhaustive Tabular Exports** + * Generalized version-pinned CSV source descriptors so exhaustive `filter_rows` and `search_rows` requests can replay the complete authorized cohort through the existing durable export runner instead of failing on bounded preview gaps. + * Added exhaustive per-row request routing for natural phrases such as "for each row," "every row," and "one row per," while preserving direct deterministic aggregation behavior. + * Non-replayable semantics such as normalized entity matching now fail closed with an explicit reason and never publish a partial CSV. + * (Ref: [#1031](https://github.com/microsoft/simplechat/issues/1031), tabular source descriptors, durable generated exports, `functions_tabular_csv_query.py`, `tabular_processing_plugin.py`, `route_backend_chats.py`) + +* **Enhanced Citations Startup Storage Degradation** + * Prevented Enhanced Citations storage connectivity problems from blocking application startup when Cosmos DB is otherwise available. + * Deferred live storage container checks to upload/admin-test paths and added Admin Settings diagnostics for explicit storage validation. + * (Ref: [#1155](https://github.com/microsoft/simplechat/issues/1155), PR [#1161](https://github.com/microsoft/simplechat/pull/1161), Enhanced Citations storage startup, `config.py`, `functions_documents.py`, Admin Settings) + +* **Functional Test Version Assertion Resilience** + * Added shared functional-test version helpers so tests can assert the app version is at least the feature implementation version instead of exactly equal to an older release. + * Migrated brittle exact `config.py` version checks and added a guardrail test to prevent reintroducing exact app-version assertions. + * (Ref: functional test version helpers, `test_support/versioning.py`, `test_app_version_assertion_guardrails.py`) + +* **Logging Tag Standardization** + * Standardized Python logging prefixes to `[UPPERCASE_WITH_UNDERSCORES]` so Application Insights, debug logs, and operational searches use consistent tag names. + * Added a logging tag reference inventory and functional coverage to keep future logging tags normalized and documented. + * (Ref: logging tag inventory, `docs/reference/logging-tags.md`, `test_logging_tag_standardization.py`) + +* **Key Vault Reminder PR Security Hardening** + * Replaced raw exception text returned from plugin/action Key Vault save paths with stable user-safe messages while preserving server-side logging for diagnostics. + * Renamed the external Key Vault reminder telemetry event to avoid security scanner false positives on secret-related terminology while keeping queryable Application Insights dimensions. + * (Ref: [#1156](https://github.com/microsoft/simplechat/issues/1156), PR [#1157](https://github.com/microsoft/simplechat/pull/1157), `route_backend_plugins.py`, `functions_appinsights.py`, CodeQL findings) + +* **Reliable Key Vault Secret Rotation** + * Fixed action secret save behavior so replacing a Key Vault-backed secret with a new literal value writes a new Key Vault version for global, group, and personal actions. + * `Stored_In_KeyVault` placeholders now only preserve validated existing references; placeholder-only saves without an existing secret are rejected instead of creating dead references. + * Key Vault write failures now surface as errors instead of falling back to raw secret persistence. + * (Ref: [#1156](https://github.com/microsoft/simplechat/issues/1156), `functions_keyvault.py`, action save helpers, Key Vault secret reference validation) + +* **Duplicate Chat Stream JSON Import Cleanup** + * Removed the redundant local `json` import from the chat streaming route while keeping the existing module-level import, clearing the PR #1145 CodeQL duplicate-module-import notice without changing streaming behavior. + * Updated the PR 1145 remediation plan with the implementation version and validation results. + * (Ref: [#1145](https://github.com/microsoft/simplechat/pull/1145), `route_backend_chats.py`, CodeQL alert 30) + +* **Semantic Kernel Return Contract Cleanup** + * Made the nested chat Semantic Kernel invocation helper return `None` explicitly when an async generator completes without yielding, clearing the PR #1145 CodeQL mixed explicit/implicit return alert without changing runtime behavior. + * Added focused functional coverage for direct values, coroutine results, yielded async-generator values, and empty async generators. + * (Ref: [#1145](https://github.com/microsoft/simplechat/pull/1145), `route_backend_chats.py`, `test_chat_semantic_kernel_return_contract.py`) + +* **Token Usage Aggregation Fixture Cleanup** + * Removed duplicate mocked helper keys from the document action token usage aggregation functional test so the fixture intent is explicit and CodeQL no longer reports overwritten dictionary entries. + * Kept comparison coverage focused on cross-format compare behavior while preserving aggregate token usage assertions for analysis, comparison, workflow assistant persistence, and chat persistence markers. + * (Ref: [#1145](https://github.com/microsoft/simplechat/pull/1145), `test_document_action_token_usage_aggregation.py`, token usage aggregation fixtures) + +* **Foundry Citation Thought Detail Cleanup** + * Fixed a CodeQL finding where Foundry citation thoughts iterated citations without using the citation value, causing duplicate generic thought messages. + * Foundry citation thoughts now include safe citation-specific labels when available while avoiding raw payloads, URL query strings, userinfo, and long unbounded text. + * (Ref: [#1145](https://github.com/microsoft/simplechat/pull/1145), `route_backend_chats.py`, `test_foundry_citation_thoughts.py`) + +* **Data Management Restore Route Registration** + * Fixed application startup failure caused by duplicate Data Management restore review route and endpoint registrations. + * Preserved the authorization-aware restore review workflow and added regression coverage requiring unique Blueprint endpoint names. + * (Ref: `route_backend_data_management.py`, `test_data_management_security_patterns.py`, `DATA_MANAGEMENT_RESTORE_ROUTE_ENDPOINT_COLLISION_FIX.md`) + +* **Mixed Source Manifest Storage Locator Preservation** + * Preserved explicit blob storage locators for authorized non-chat mixed-source manifest entries when archived-revision document metadata already contains a resolved container and blob path. + * Updated focused mixed-source Analyze and conversation-continuity tests for the current rollout/version contract. + * (Ref: [#1055](https://github.com/microsoft/simplechat/issues/1055), [#1056](https://github.com/microsoft/simplechat/issues/1056), mixed-source manifests, `functions_mixed_source_orchestration.py`, `test_mixed_source_manifest_contracts.py`) + +* **Retry and Edit Streaming Parity** + * Retry and edit chat flows now use the same full SSE streaming path as first-send chat, restoring live token updates, streamed thoughts, stop controls, and recovery behavior. + * The stream path reuses the retry/edit user message and thread metadata created by the preparation endpoints, preserving carousel attempt history without duplicating user messages. + * (Ref: Fixes [#963](https://github.com/microsoft/simplechat/issues/963), `route_backend_chats.py`, `chat-retry.js`, `chat-edit.js`, `test_chat_retry_edit_streaming_parity.py`) + +* **Retention Coverage Across Group and Collaborative Conversations** + * Group-scoped private conversations now follow their primary group's retention policy instead of the creator's personal policy. + * Personal and group collaborative conversations now use their correct governing policy and activity timestamp, while linked conversion sources are cleaned once without duplicate counting. + * Collaboration cleanup now covers messages, per-user state, linked sources, blob-backed files, thoughts, activity logs, and conversation caches; new groups also persist explicit default retention values. + * (Ref: Closes [#1054](https://github.com/microsoft/simplechat/issues/1054), `functions_retention_policy.py`, `functions_collaboration.py`, `functions_group.py`, `RETENTION_POLICY_CONVERSATION_SCOPE_COVERAGE_FIX.md`) + +* **Custom Databricks-Prefixed Action Discovery** + * Fixed action type discovery so custom plugin types such as `databricks_table_dscmo` no longer inherit the built-in Databricks discovery defaults. + * Custom Databricks-prefixed plugin types now stay on the standard plugin configuration path and visual treatment unless their type is exactly `databricks` or `databricks_table`. + * Added a regression test that scaffolds a temporary fake custom Databricks-prefixed plugin, schema, and definition file to validate discovery and settings merge behavior. + * (Ref: [#1124](https://github.com/microsoft/simplechat/issues/1124), `functions_databricks_operations.py`, `route_backend_plugins.py`, `view-utils.js`, `test_plugin_type_discovery_custom_databricks.py`) + +* **Conversation Fork Workspace Context and HTTP 500 Fix** + * Fixed conversation forks returning HTTP 500 when an owned single-user conversation used group or public workspace knowledge. + * Forking now revalidates current workspace access, preserves the authorized context and chat type, and returns controlled conflicts when access is stale or unavailable. + * Corrected fork-specific structured logging so validation, conflict, cleanup, and cache errors retain their intended response behavior. + * (Ref: [#1025](https://github.com/microsoft/simplechat/issues/1025), `functions_simplechat_operations.py`, `route_backend_conversations.py`, `chat-messages.js`, `CONVERSATION_FORK_HTTP_500_FIX.md`) + +* **Application-Wide Log Event Contract Guard** + * Fixed conversation fork conflict and recovery logging that used unsupported metadata keywords, preventing logger errors from replacing intended HTTP responses such as eligibility conflicts with HTTP 500. + * Standardized structured metadata on `extra=` and added an application-wide call-signature check plus route regression coverage for the HTTP 409 conflict path. + * (Ref: [#1112](https://github.com/microsoft/simplechat/issues/1112), `functions_simplechat_operations.py`, `route_backend_conversations.py`, `test_log_event_call_contract.py`) + +* **MCP PR CodeQL Cleanup** + * Resolved CodeQL findings from the MCP pull request by replacing exception text returned to clients with stable public messages, tightening inbound MCP correlation IDs, and removing raw query text from search/cache logs. + * Cleaned up MCP catalog imports, test stubs, and JavaScript defaults that produced CodeQL note-level findings. + * (Ref: [#1013](https://github.com/microsoft/simplechat/issues/1013), CodeQL scan, MCP PR readiness, `functions_appinsights.py`, `route_inbound_mcp.py`, `route_backend_plugins.py`) + +* **MCP Enterprise Hardening** + * Added inbound MCP request correlation, bounded payloads, Cosmos-backed tool throttles, clear JSON-RPC tool error transport, and OAuth/PRM discovery compatibility for MCP clients. + * Added outbound MCP discovery/factory telemetry with safe destination metadata and redaction to make connector failures easier to diagnose. + * (Ref: [#1015](https://github.com/microsoft/simplechat/issues/1015), [#1017](https://github.com/microsoft/simplechat/issues/1017), [#1020](https://github.com/microsoft/simplechat/issues/1020), MCP observability and enterprise readiness) + +* **Selected Public Workspace Prompt Migration** + * Selected public-workspace Data Management migrations now copy current prompts owned through `public_id` while retaining compatibility with legacy `public_workspace_id` records. + * Prompts outside the selected workspaces remain excluded, transitional records migrate once, and copied prompt artifact counts are accurate. All-workspaces migration behavior is unchanged. + * (Ref: [#1033](https://github.com/microsoft/simplechat/issues/1033), `functions_data_management.py`, `test_data_management_public_prompt_migration.py`) + +* **Azure Blob Container SAS Support and Credential Guidance** + * Added support for storage connection strings, full container SAS URLs, and standalone SAS tokens. Pasted SAS URLs derive the canonical account, selected container, and default source name without persisting the token in connection metadata. + * Validates required Read and List permissions, HTTPS-only protocol, account-SAS Blob resource scope, start time, and expiry. Extra permissions and broader account credentials remain usable but produce least-privilege warnings. + * Shows non-secret SAS scope, named permissions, exact expiry, days remaining, stored-policy status, IP restrictions, and warnings in connection tests and source rows. + * Supports saving Blob credentials with or without Azure Key Vault; Key Vault is used when enabled and existing File Sync credential persistence is used otherwise. + * (Ref: [#1027](https://github.com/microsoft/simplechat/issues/1027), `functions_file_sync.py`, `workspace-file-sync.js`, `AZURE_BLOB_CONTAINER_SAS_SUPPORT_FIX.md`) + +* **Azure Blob File Sync Endpoint and Error Hardening** + * Restricted Azure Blob File Sync URLs and connection strings to validated HTTPS Azure Blob endpoints, blocking arbitrary, internal, development-storage, and credential-bearing endpoint forms before SDK requests are created. + * Replaced raw File Sync route, run-history, activity, and item exception text with fixed client-safe messages while retaining detailed sanitized diagnostics in server logs. + * (Ref: [#1027](https://github.com/microsoft/simplechat/issues/1027), PR [#1088](https://github.com/microsoft/simplechat/pull/1088) security review, `functions_file_sync.py`, `route_backend_file_sync.py`) + +* **GPT 5.6+ Multi-Modal Vision Model Selection** + * Enabled GPT 5.6 Luna, Sol, Terra, and later supported GPT deployments to appear in the Multi-Modal Vision Analysis selector across Azure OpenAI and Foundry endpoints. + * Model detection now evaluates model, display, and deployment names with normalized separators while preserving disabled-model and unsupported-family filtering. + * (Ref: [#1086](https://github.com/microsoft/simplechat/issues/1086), `admin_settings.js`, `test_admin_multimodal_vision_model_options.py`) + +* **Repeatable AI Workflow Task Sequences** + * Personal and group workflows can now run with only instructions and a selected model or agent; workspace documents, File Sync, URL access, schedules, and completion alerts remain optional. + * Workflows support ordered instruction tasks that share the selected runner and receive bounded prior-task output as context. + * Added per-task retries and stop-or-continue error handling, with task outcomes recorded in run history and workflow activity. + * Existing document Search, Analyze, and Compare behavior remains available as optional input for the first task, while existing workflows without task sequences retain their prior execution path. + * (Ref: [#1082](https://github.com/microsoft/simplechat/issues/1082), `functions_personal_workflows.py`, `functions_group_workflows.py`, `functions_workflow_runner.py`) + +* **Cosmos Container Startup Conflict Recovery** + * Fixed a local Docker startup failure where multiple gunicorn workers could race while creating first-run Cosmos containers, causing a `NotFound` followed by a `Conflict` during app import. + * Container initialization now re-reads and returns the existing container when another worker creates it first, preserving normal startup behavior for already-provisioned environments. + * (Ref: `config.py`, `test_cosmos_container_conflict_recovery.py`, `COSMOS_CONTAINER_STARTUP_CONFLICT_FIX.md`) + +* **Terms of Use Redirect Hardening** + * Replaced wildcard config imports in the Terms of Use route with explicit Flask imports. + * Moved post-acceptance return paths from hidden form values to server-side session storage, keeping user-controlled return targets local-only. + * Restricted admin-configured external decline redirects to HTTPS URLs without embedded credentials while preserving local-path redirects. + * (Ref: [#504](https://github.com/microsoft/simplechat/issues/504), `route_frontend_terms_of_use.py`, `functions_terms_of_use.py`, `terms_of_use.html`) + +* **Control Center Left Nav Endpoint Fix** + * Fixed an issue where admins could open Control Center while the left navigation Control Center section stayed hidden when ControlCenterAdmin enforcement was disabled. + * Updated the sidebar endpoint check to use the blueprint-qualified `frontend_control_center.control_center` route and added regression coverage for the regular Admin fallback. + * (Ref: [#1009](https://github.com/microsoft/simplechat/issues/1009), `_sidebar_nav.html`, `test_control_center_left_nav_endpoint.py`) + +* **Cosmos Editor Page Size Enforcement** + * Empty Cosmos editor browse mode now respects the selected page size up to the 100-document cap instead of always requesting 100 items. + * This keeps small page-size selections useful for compact validation and targeted inspection. + * (Ref: [#1006](https://github.com/microsoft/simplechat/issues/1006), Cosmos DB JSON Editor, `functions_data_management.py`) + +* **CosmosClient Import Binding CodeQL Cleanup** + * Replaced direct `CosmosClient` imports with module-qualified `azure_cosmos.CosmosClient` lookups so tests and diagnostics that patch `azure.cosmos.CosmosClient` are observed consistently. + * Updated the Cosmos query plugin functional test to patch the module-qualified SDK client and avoid live Cosmos connections during app-module imports. + * (Ref: `config.py`, `functions_data_management.py`, `route_backend_plugins.py`, `cosmos_query_plugin.py`, `test_cosmos_query_plugin.py`) + +* **Conversation Cache Invalidation Authorization** + * Route-level message mutation cache invalidation now loads personal conversations through the existing ownership authorization helper instead of directly reading a request-derived conversation id. + * Updated PR-readiness functional test fixtures to match the current document access index config imports and avoid live Cosmos connections during notification regression tests. + * (Ref: `route_backend_conversations.py`, `test_chat_completion_notifications.py`, DAI functional test fixtures) + +* **iPhone M4A Upload FFmpeg Fallback** + * Fixed supported iPhone `.m4a` audio uploads failing before transcription when the app runtime could not resolve a local `ffmpeg` executable. + * Public Azure environments can now fall back to Azure Speech fast transcription using the original supported source audio file and content type when local segmentation fails because FFmpeg is missing. + * FFmpeg segmentation now targets the first audio stream and emits mono 16 kHz PCM WAV chunks for Speech when FFmpeg is available. + * (Ref: [#974](https://github.com/microsoft/simplechat/issues/974), `.m4a` upload processing, Azure Speech fast transcription, `IPHONE_M4A_FFMPEG_FALLBACK_FIX.md`) + +* **Multi-Endpoint Vision Test Connection** + * Fixed the Admin Settings Vision Model test button so multi-endpoint models are tested against their configured endpoint instead of always using the legacy GPT endpoint. + * Vision model options now preserve endpoint and model metadata for the test call while keeping the saved deployment-name value compatible with existing settings. + * Removed duplicate backend Vision test connection logic and preserved GPT-5/o-series token handling for Vision test requests. + * (Ref: Vision Model test, multi-endpoint model endpoints, `admin_settings.js`, `admin_settings.html`, `route_backend_settings.py`, `MULTI_ENDPOINT_VISION_TEST_CONNECTION_FIX.md`) + +* **Malicious PR Security Review Workflow** + * Added a static malicious-change review workflow for pull requests into `Development`, with manual dispatch options for custom review ranges and full-file scans. + * Added a reusable security review prompt and focused functional coverage for dependency pinning policy, hidden Unicode detection, suspicious egress markers, and workflow wiring. + * (Ref: malicious PR security review, `.github/workflows/malicious-pr-security-review.yml`, `scripts/check_malicious_pr_security_review.py`) + +* **Admin Settings Save 500 Fix** + * Fixed an issue where saving Admin Settings returned an HTTP 500 error even though configuration changes were successfully persisted. + * The `/admin/settings` POST handler now uses Flask's `current_app` when regenerating custom logo and favicon files after a successful settings update, eliminating the `NameError: name 'app' is not defined` in the post-save path. + * (Ref: admin settings save, logo/favicon regeneration, `route_frontend_admin_settings.py`, `ADMIN_SETTINGS_SAVE_500_FIX.md`) + +* **Model Endpoint Management Cloud Normalization** + * Fixed model endpoint saves so managed identity and other non-editable cloud paths derive `management_cloud` from `AZURE_ENVIRONMENT` instead of persisting the hidden UI default of `public`. + * Added custom-cloud handling for inherited model endpoint authority and Foundry scope defaults while preserving explicit Foundry service-principal cross-cloud selections. + * (Ref: model endpoint authentication, `normalize_model_endpoints`, `AZURE_ENVIRONMENT`, `test_model_endpoint_management_cloud_environment.py`) + +* **Admin Settings Update Banner Version Comparison** + * Fixed stale cached update-check settings so Admin Settings no longer displays an older release such as `v0.250.001` as available when the running app version is newer. + * The render path now recomputes `update_available` from the cached latest version and the current app version before showing the banner. + * (Ref: Admin Settings update banner, `compare_versions`, `test_admin_update_banner_version_comparison.py`) +{% endraw %} diff --git a/docs/explanation/release_notes.md b/docs/explanation/release_notes.md index 1488a6d31..65727de9f 100644 --- a/docs/explanation/release_notes.md +++ b/docs/explanation/release_notes.md @@ -2,6 +2,43 @@ For feature-focused and fix-focused drill-downs by version, see [Features by Version](https://github.com/microsoft/simplechat/tree/main/docs/explanation/features) and [Fixes by Version](https://github.com/microsoft/simplechat/tree/main/docs/explanation/fixes). +### **(v0.261.003)** + +#### Bug Fixes + +* **Broken Documentation Links Repaired** + * Clicking the upgrade guide, Docker customization, or enterprise networking links from the repository README or the deployer READMEs led to a "page not found". Those pages were reorganized from `docs/how-to/.md` to `docs/guides/.md`, and the site kept redirects, but redirects do not apply when browsing files on GitHub. No documentation was ever lost, only mislinked. + * Repaired 46 broken relative links in total: 12 in the README and deployer READMEs, and 34 in archived per-version engineering notes. Archived links whose target was never migrated now keep the prose without a dead link, rather than pointing at a file that does not exist. + * Also corrected the "Return to Main" link in the Azure CLI and Terraform deployer READMEs, which pointed one directory too shallow. + * (Ref: `README.md`, `deployers/*/README.md`, `docs/explanation/features/`, `docs/explanation/fixes/`, [#1371](https://github.com/microsoft/simplechat/issues/1371)) + +* **Recovered 27 Release Note Sections Missing From The Source File** + * `docs/explanation/release_notes.md` had been truncated from 46 version sections to 19, dropping every v0.260 entry along with v0.250.229 through v0.250.231. The published site still showed them, because the pages that render release notes are generated from this file and had not been rebuilt since the truncation. + * That left the repository one routine `build_release_notes_pages.py` run away from erasing roughly 2,400 lines of release history from the site with no obvious cause. The sections have been restored from history and the pages regenerated, so the source and the site agree again. + * (Ref: `docs/explanation/release_notes.md`, `scripts/build_release_notes_pages.py`, [#1371](https://github.com/microsoft/simplechat/issues/1371)) + +#### Documentation + +* **Web Search Documentation Now Describes What Actually Happens** + * The web search guide still described the Bing Web Search API integration that was removed back in v0.229.001. Web search has since run through an Azure AI Foundry agent using the Grounding with Bing Search tool, which is why an admin has to configure a Foundry project and agent ID before the **Web** control appears. + * Added a dedicated **What leaves SimpleChat** section stating the egress boundary plainly: only the message the user just typed is sent to the external search service. Conversation history, workspace documents, attached file contents, system prompts, agent instructions, and workspace or document names are never included. This behavior was hardened in v0.241.022 but was previously mentioned only in passing. + * Documented the Deep Research nuance: it runs several planned queries instead of one, but every query is still derived from the current message alone, so no conversation history is introduced. + * Added the Grounding with Bing Search compliance-boundary notice to the user-facing guide, replaced the placeholder text in the admin Web Search settings table with real descriptions, and reused the existing web search flow diagram instead of leaving a "recording planned" video card. + * (Ref: `docs/guides/use-web-search.md`, `docs/admin/knowledge.md`, `docs/reference/chat-controls.md`, `build_web_search_query_text`, [#1371](https://github.com/microsoft/simplechat/issues/1371)) + +* **Documentation Link Rot Now Fails A Test** + * Added `functional_tests/test_docs_link_integrity.py`, which fails when any relative markdown link in the README, `docs/`, or `deployers/` points at a missing file, when a Jekyll `relative_url` page link does not resolve, or when a media include names an unregistered slot. Outstanding screenshots are reported but never fail the run. + * Added `functional_tests/test_docs_web_search_accuracy.py`, which ties the published privacy claim to the implementation. If the web search query builder ever starts folding conversation history back into the outbound query, the test fails and forces the documentation to be corrected with it. + * (Ref: `test_docs_link_integrity.py`, `test_docs_web_search_accuracy.py`, [#1371](https://github.com/microsoft/simplechat/issues/1371)) + +* **First Batch Of Documentation Screenshots** + * Filled 54 empty screenshot slots, taking documentation screenshot coverage from 18 of 122 to 72 of 122. The Administration group is now fully illustrated. + * Added the four admin settings overviews (Backup & Recovery, Data Lifecycle, Governance, Workflow), six chat control references (conversation list, conversation header, composer, selectors, grounded search, and advanced conversation search), thirty-three task guide steps, and configuration panes for eleven action types (Azure Maps, Blob Storage, Chart, Cosmos Query, Databricks, Document Search, Log Analytics, MCP, Microsoft Graph, OpenAPI, RocksDB, and SimpleChat). + * The web search screenshot captures the live data notice, so the guide's claim that only the current message is sent is now visible rather than only asserted. + * Action configuration panes were captured without saving any action, so every credential field shows only its placeholder text and no tenant values were recorded. Where an admin settings pane already held real values, those fields were replaced with example values before capture and the page was reloaded without saving. + * Replaced the generated placeholder alt text on every filled slot with a description of what the reader actually learns from the image. + * (Ref: `docs/images/admin/`, `docs/images/reference/`, `docs/images/guides/`, [#1371](https://github.com/microsoft/simplechat/issues/1371)) + ### **(v0.261.002)** #### User Interface Enhancements @@ -1664,6 +1701,2434 @@ For feature-focused and fix-focused drill-downs by version, see [Features by Ver * Added custom-cloud handling for inherited model endpoint authority and Foundry scope defaults while preserving explicit Foundry service-principal cross-cloud selections. * (Ref: model endpoint authentication, `normalize_model_endpoints`, `AZURE_ENVIRONMENT`, `test_model_endpoint_management_cloud_environment.py`) +* **Admin Settings Update Banner Version Comparison** + * Fixed stale cached update-check settings so Admin Settings no longer displays an older release such as `v0.250.001` as available when the running app version is newer. + * The render path now recomputes `update_available` from the cached latest version and the current app version before showing the banner. + * (Ref: Admin Settings update banner, `compare_versions`, `test_admin_update_banner_version_comparison.py`) + +### **(v0.260.025)** + +#### Bug Fixes + +* **Agent Actions Are No Longer Skipped When A Workspace Is In Scope** + * Selecting an agent that has actions and enabling a workspace produced answers that never invoked any of the agent's actions. The assistant answered from retrieved document text alone, even when the retrieved excerpts did not contain what the question asked for. + * The retrieval prompt instructed the model to base its answer *only* on the retrieved excerpts, so although the agent's actions were attached and available, the model was told not to reach for them. Retrieved excerpts are now framed as starting evidence, and the model is directed to call an available action when the excerpts lack what the question needs, then reason over the excerpts and the action results together. The rule against fabricating unsupported values is unchanged. + * (Ref: `build_search_augmentation_system_prompt`, `build_mixed_source_evidence_handoff`, agent actions, workspace search, [#1332](https://github.com/microsoft/simplechat/issues/1332)) + +* **Spreadsheets In A Workspace Are Now Actually Computed** + * A quantitative question about a spreadsheet could return values that were not in the file. Tabular computation was suppressed whenever workspace search also returned any narrative document, and the heuristic treated topic words such as "report", "policy", and "memo" as reasons to skip computation entirely. + * Because only a truncated three-row preview of a spreadsheet is indexed for search, skipping computation left the model deriving totals and averages from those preview rows. Tabular sources in scope are now computed unless the question unambiguously names a narrative artifact such as a PDF or presentation, restoring parity with the behavior already used when mixed-source search is disabled. + * (Ref: `should_run_tabular_evidence`, `functions_mixed_source_orchestration.py`, tabular processing, mixed-source evidence, [#1332](https://github.com/microsoft/simplechat/issues/1332)) + +* **A Skipped Spreadsheet Now Tells The Model What It Is Missing** + * When tabular computation is skipped, the evidence record previously said processing "was not needed", which implied the source was irrelevant and left the model free to compute from indexed preview rows. + * It now states that the full table was never read, that any indexed excerpt is a truncated preview, that numeric conclusions must not be drawn from it, and that the tabular analysis action should be called if values from that source are required. + * (Ref: `execute_tabular_evidence_sources`, evidence envelopes, tabular citations, [#1332](https://github.com/microsoft/simplechat/issues/1332)) + +### **(v0.260.024)** + +#### Bug Fixes + +* **Inline Images And Videos Now Show Only Cited Media** + * Assistant messages rendered an inline image or video gallery for every media file that retrieval returned, so a search that surfaced five workspace images produced five inline tiles even when the answer referenced only one of them, or none at all. Media that had nothing to do with the answer was presented inside the message bubble as though it supported the answer. + * Inline galleries now render only the media the response actually cited. The five-item gallery cap therefore goes to genuinely cited media instead of retrieval noise, and unreferenced workspace files no longer trigger enhanced-citation fetches. + * Galleries produced by an action or tool the assistant actually ran are unaffected, since those are executed results rather than unused search candidates. Conversations created before cited-source tracking existed also keep their previous behavior. + * The **Sources** disclosure is unchanged and still lists every retrieved document and web result, so nothing becomes harder to find. + * (Ref: `chat-citation-tracking.js`, `chat-inline-images.js`, `chat-inline-videos.js`, `chat-messages.js`, `cited_hybrid_citations`, [#1329](https://github.com/microsoft/simplechat/issues/1329)) + +### **(v0.260.023)** + +#### Bug Fixes + +* **Running Simple Chat Directly No Longer Fails To Start When An Agent Has Actions** + * Starting Simple Chat with `python app.py` (including via `uv run`) aborted with `RuntimeError: Working outside of request context` whenever any agent had an action assigned. The app started normally until the first action was saved, which made the failure look intermittent. + * Semantic Kernel initialization runs before any request exists on that path, but agent plugin loading read the signed-in user from the Flask session. It now resolves the user only when a request is actually in progress and otherwise loads with no user identity, matching how global plugin loading already behaved. + * Container and App Service deployments were never affected, because they start through gunicorn and initialize during the first request. Their behavior is unchanged. + * Three further identity lookups used for group scope and personal model endpoints had the same latent problem and were corrected at the same time. + * (Ref: `semantic_kernel_loader.py`, `functions_authentication.py`, `get_current_user_id_or_none`, issue #1327) + +### **(v0.260.021)** + +#### Bug Fixes + +* **Documentation Screenshot Viewer Validates Its Image Source** + * The documentation site's click-to-enlarge screenshot viewer assigned an image URL taken from a data attribute in the page. Because that value flows from page content into a URL, CodeQL flagged it as a potential DOM-based cross-site scripting sink. + * The viewer now resolves the value and requires a same-origin `http` or `https` URL ending in an image extension before using it, so scheme-based payloads such as `javascript:` and `data:` URLs, and any off-site source, are rejected. All documentation media is local, so no legitimate image is affected. + * (Ref: `docs/assets/js/media.js`, `safeMediaUrl`, `ui_tests/test_docs_media_lightbox_source_validation.js`, CodeQL `js/xss-through-dom`) + +### **(v0.260.020)** + +#### New Features + +* **Admin Documentation Rebuilt For The Grouped Settings Layout** + * Admin Settings was reorganized from 18 flat tabs into 14 groups containing 44 tabs and 93 settings sections. The documentation was still written against the old flat layout, so it described tabs that no longer exist and omitted the new ones. + * The admin documentation is now one page per group, with every tab reachable by its own anchor so links to a specific tab keep working. Every retired tab URL redirects to the group that now owns its settings, so existing links and bookmarks continue to resolve. + * (Ref: `docs/admin/`, `application/single_app/admin_settings_nav.py`, `docs/_data/app_surface.yml`) + +* **Collaborating In A Conversation Is Now Documented** + * Added a guide covering shared conversations end to end: sharing a conversation, mentioning a participant with `@` and Tab completion, how shared files are approved before they become available, and what participants can and cannot do. + * The Blob Storage action reference now explains its managed identity and account key options. + * (Ref: `docs/guides/collaborate-in-a-conversation/`, `docs/reference/actions/blob-storage/`, `enable_collaborative_conversations`) + +* **Documentation Site Now Reflects the v0.260.001 Release** + * The documentation site's Latest Release section was a full release behind, still presenting v0.250.001 as current. It now mirrors the same three-tier model the application uses: v0.260.001 as the current release, v0.250.001 as the previous release, and v0.239.001-v0.241.007 in the archive. + * Added 20 feature guides for the v0.260.001 release covering enhanced extraction, embedded Office images, workflow task sequences, the MCP platform, the Yamcs and RocksDB actions, agent instruction references, action test connections, Azure Blob file sync, terms of use, audio file support, completion notifications, the chat AI notice, conversation context grounding, used documents on fork, the conversation contents drawer, font size and zoom, message audio export, public workspace display names, and chat scroll accessibility. + * (Ref: `docs/_data/latest_release_features.yml`, `docs/latest-release/release-260-*`, `application/single_app/support_menu_config.py`) + +* **Placeholder Screenshots Are Now Tracked** + * The v0.260.001 release ships branded "Screenshot pending" placeholder graphics so feature cards render while final captures are pending. Those placeholders are now listed on the documentation media status page with the exact file paths to overwrite, so they are visible work rather than a silent gap. + * (Ref: `docs/_data/media_pending.yml`, `/contributing/media-status/`) + +#### User Interface Enhancements + +* **Admin Settings Pages Show Real Screenshots** + * Fourteen admin settings tab pages were rendering "screenshot needed" placeholders even though real screenshots already existed in the repository. Those pages now display the actual screenshots for the General, AI Models, Search and Extract, Workspaces, File Sync, Workspace Identities, Citation, Safety, Security, Agents, Scale, Control Center, Logging, and Send Feedback tabs. + * The four tabs with no captured screenshot still show a placeholder naming the exact file to create, so genuine gaps stay visible. + * (Ref: `docs/admin/`, `docs/images/admin-settings/`) + +#### Bug Fixes + +* **Release Notes Pages No Longer Break On Quoted Template Syntax** + * Release notes legitimately quote template syntax when describing template work, such as a Jinja `block` tag. The page generator emitted that verbatim, so the site build failed with an unknown tag error. Quoted template syntax is now escaped in generated pages and renders as literal text. + * (Ref: `scripts/build_release_notes_pages.py`) + +* **Release Notes Links To Internal Engineering Notes** + * Some release note entries linked to the internal feature and fix note trees, which are intentionally not published on the documentation site. Those links now point at the repository. + * (Ref: `docs/explanation/release_notes.md`) + +* **Release Notes Index No Longer Exceeds Its Page Budget** + * The release notes page generator inlined a fixed number of recent releases on its index. The consolidated v0.260.001 rollup is large enough on its own that this pushed the index past the maximum page size and failed generation. The index now fills its inline section by size rather than by count, so a single large rollup cannot break it. + * (Ref: `scripts/build_release_notes_pages.py`) + +* **Archived Release Notes Links** + * The archived release notes page linked to the internal feature and fix note trees, which are intentionally not published on the documentation site. Those links now point at the repository instead. + * (Ref: `docs/explanation/archive_release_notes.md`) + +### **(v0.260.019)** + +#### Bug Fixes + +* **Admin Settings Loads Again** + * Admin Settings returned a 500 error on every request after the settings restructure. The Document Action Capabilities card moved to the Actions tab but the two values it reads stayed behind in the Agents tab, and each tab is rendered separately, so those values were never there when the card asked for them. + * Both values are now defined in the tab that uses them, and a new test renders the two tabs together to keep them there. + * (Ref: `admin/_panes/actions.html`, `admin/_panes/agents.html`, document action capabilities) + +* **Server Errors Are Visible In The App Service Log Again** + * Once Application Insights was configured it took ownership of logging, which had the side effect of stopping Flask writing unhandled errors to the container log. A failing page left nothing behind but its access-log line, so diagnosing it meant querying Application Insights. + * Unhandled errors are now written to both, so the reason for a failure is visible in the App Service log stream. + * (Ref: `functions_appinsights.py`, `ensure_console_error_logging`, App Service console logs) + +* **Document Access Index Diagnostics Appear When Enabled** + * The Cosmos DB tab checked the wrong thing for the debug setting, so the backfill controls, shadow validation metrics and reset option stayed hidden even after an admin turned the setting on. + * (Ref: `admin/_panes/cosmos.html`, `enable_dai_debug`) + +### **(v0.260.018)** + +#### Bug Fixes + +* **Setup Walkthrough Lands On The Right Settings Again** + * The guided setup walkthrough sent each step to a named tab. After the Admin Settings restructure, eleven of its twelve steps named tabs that no longer existed, so those steps would have moved nowhere and left the admin looking at whatever was already on screen. + * Each step now names the setting it is about and the tab is worked out from the page, so the walkthrough follows settings wherever they live. + * (Ref: setup walkthrough, `admin_settings.js`, `admin_card_links.js`) + +* **Cosmos Throughput Validation Reveals The Invalid Field** + * When Cosmos throughput values failed validation, the page tried to switch to a tab that no longer exists, so the field needing attention could be left on a hidden tab with no indication of where to look. + * Validation now jumps to wherever the invalid field actually is. + * (Ref: Cosmos throughput validation, `admin_settings.js`) + +#### User Interface Enhancements + +* **Admin Settings Restructure Merged With Current Development** + * Version bump covering the merge of the Admin Settings information architecture work with the generated file output fixes developed in parallel. Both reached v0.260.011 independently, so their release notes are combined under that version. + * (Ref: Admin Settings navigation, generated file exports) + +### **(v0.260.017)** + +#### New Features + +* **All App Role Requirements In One Place** + * Ten settings across seven tabs can each require an Entra app role, which made the overall access policy impossible to read without hunting through the whole of Admin Settings. + * **Security → Access & Roles** now lists every one of them with a switch and a link to the setting in its own tab. Changing a switch here changes the setting itself. + * The list is built from the page, so a new role requirement added anywhere appears here automatically. + * (Ref: `app-role-requirements-section`, `admin_access_roles_roster.js`) + +#### User Interface Enhancements + +* **System Settings Card Split To Where Each Setting Belongs** + * One card mixed maximum file size, conversation history, idle timeout, the default system prompt and the access denied message — five unrelated concerns under one heading. + * Maximum File Size is now in **Workspaces → Files & Sharing**, Conversation History and Default System Prompt in **Chat → Chat Experience**, and Access Denied Message in **Security → Access & Roles**. + * What remains in **Security → Session** is the idle timeout, and the card is now named for it. + * Every setting keeps its saved value; nothing needs re-entering. + * (Ref: `idle-timeout-section`, `file-size-limit-section`, `conversation-history-section`, `default-system-prompt-section`, `access-denied-message-section`) + +### **(v0.260.016)** + +#### User Interface Enhancements + +* **Backup, Migrate & Restore Split Into Five Tabs** + * One tab carried the entire backup, migration, restore, Cosmos editing and job history surface — over 1,600 lines in a single scroll. + * Backup & Recovery now has **Backup** (readiness, backup, schedule, storage, encryption), **Migrate**, **Restore**, **Cosmos Editor** and **Jobs**. + * The save button, status line and operational-hours warning are shared by all five tabs, so they sit above the tabs and stay available wherever you are in the group. + * This completes the Admin Settings restructure: **14 groups and 44 tabs**, from an original 17 flat tabs. + * (Ref: `backup`, `migrate`, `restore`, `cosmos-editor`, `jobs`) + +#### Bug Fixes + +* **Backup Dialogs Remain Available From Every Tab** + * The eleven Backup & Recovery dialogs are opened from more than one place and several are opened from code rather than a button. Left inside a tab, a dialog cannot appear while a different tab is showing. + * They now sit outside the tabs, so restore, migration cancel, job detail, the Cosmos editor dialogs and the five setup guides all open wherever they are triggered from. + * (Ref: Backup & Recovery dialogs, `admin_data_management.js`) + +* **Shared Controls Work In Both Navigation Layouts** + * Shared group controls resolve their group from whichever navigation is on screen, so the Backup & Recovery save button is present in the sidebar layout as well as the tab layout. + * (Ref: `data-admin-group-shared`, `admin_sidebar_nav.js`) + +### **(v0.260.015)** + +#### User Interface Enhancements + +* **AI Models Split By Model Purpose** + * AI Models presented every model setting on one tab. It is now **Model Endpoints** (endpoint and fallback configuration, plus the Chat Model dialog opened from it), **Embeddings** and **Image Generation**. + * (Ref: `model-endpoints`, `embeddings`, `image-generation`) + +* **Agents And Actions Are Now Separate Tabs** + * A single "Agents and Actions" tab carried agent configuration, template approvals, document action capabilities, action configuration and the whole inbound MCP surface. + * It is now **Agents**, **Actions** and **Inbound MCP**. + * Inbound MCP is a large area with its own dialogs and diagnostics, and the whole tab is hidden when the inbound MCP interface is turned off rather than showing an empty tab. + * (Ref: `agents`, `actions`, `inbound-mcp`) + +#### Bug Fixes + +* **Model Setup Guide Available From Every Model Tab** + * The Azure OpenAI Model Setup Guide dialog is opened from the endpoints, embeddings and image generation cards. Once those moved to separate tabs it could only have opened from one of them. + * The dialog now sits outside the tabs, so it opens from all three. + * (Ref: `legacyModelDiscoveryIdentityGuideModal`) + +* **Dangling Section Comments Removed** + * Seven tabs ended with a comment labelling a card that had since moved to another tab. + * (Ref: admin settings tab panes) + +### **(v0.260.014)** + +#### User Interface Enhancements + +* **Knowledge Settings Split By What They Actually Do** + * Search & Extract held eight cards spanning four unrelated jobs, from Bing consent to voice transcription. + * Knowledge now has **Web & Research** (web search, URL access, deep research), **Search Index** (Azure AI Search), **Document Extraction** (document intelligence, chunk sizes, plus metadata extraction and multi-modal vision brought over from Workspaces) and **Audio & Video** (video intelligence, voice conversations), alongside the existing File Sync. + * Voice and video sit under Knowledge rather than Chat because they are extraction pipelines that turn recordings into searchable content. + * (Ref: `web-research`, `search-index`, `extraction`, `audio-video`) + +* **Workspaces Focused On Workspaces** + * Workspaces mixed workspace types with file rules, workflow and extraction settings. + * It is now **Workspace Types** (personal, group, public), **Files & Sharing** (downloads, sharing, and shared conversation file approvals brought over from AI Models) and the existing Global Identities. + * (Ref: `workspace-types`, `files-sharing`) + +* **Workflow Is Its Own Area** + * Workflow drives approvals and assignment across every workspace type and was too large to sit as one card inside Workspaces. It now has its own group. + * (Ref: `workflow`, `workflow-settings-section`) + +#### Bug Fixes + +* **Group Workflow Assignment Dialog Could Not Open** + * The Group Workflow Assignment dialog ended up in a different tab from the button that opens it. Because an inactive tab is hidden, the dialog would not have appeared at all. + * The dialog now sits with its button, and a new check verifies this for every dialog in Admin Settings so it cannot happen again. + * (Ref: `groupWorkflowAssignmentModal`, `test_admin_settings_modal_placement.py`) + +* **Misplaced Section Comments In AI Models** + * Two section comments had drifted onto the wrong cards while settings were being regrouped, labelling the embeddings card as processing thoughts. + * (Ref: `ai-models` pane) + +### **(v0.260.013)** + +#### User Interface Enhancements + +* **General Tab Broken Up Into Focused Tabs** + * General had grown into a catch-all of eleven unrelated cards: branding sat next to health checks, API documentation, terms of use and system settings. + * Appearance now has **Branding** (branding, home page text, appearance), **Notices & Agreements** (classification banner, chat AI notice, terms of use and the user agreement pulled across from Workspaces) and **Pages & Links** (static pages plus external links). + * Health Check and API Documentation moved to Operations, which is now **Logging & Health** — they report on how the app is running rather than how it looks. + * Support moved to Help as its own **Support Menu** tab, next to Send Feedback. + * (Ref: `branding`, `notices`, `custom-pages`, `logging`, `support-menu`) + +* **Security Split Into Five Purposeful Tabs** + * Security held a single Key Vault card while an unrelated Safety tab mixed content filtering with role permissions, which are different jobs. + * Security is now **Access & Roles** (who gets in and with what role), **Secrets** (Key Vault), **Content Safety** (what may be said once you are in), **Session** (idle timeout and related system settings) and **Network** (Azure Front Door). + * (Ref: `access-roles`, `secrets`, `content-safety`, `session`, `network`) + +#### Bug Fixes + +* **"Open Key Vault Settings" Link No Longer Depends On A Hardcoded Tab** + * The link from Data Management to Key Vault switched tabs by a hardcoded id, so it silently stopped working whenever that tab was renamed. + * It now uses the standard card link, which finds the owning tab from the page itself and stays correct however the settings are grouped. + * (Ref: `data-management-key-vault-link`, `admin_card_links.js`, `admin_data_management.js`) + +* **Admin Settings Always Opens On A Real Tab** + * The tab shown on arrival was pinned to a specific id in both the markup and the sidebar script. Regrouping settings could leave Admin Settings opening with no tab selected at all. + * The landing tab is now taken from the navigation map, so it follows the settings and can never be Latest Features. + * (Ref: `admin_landing_tab`, `get_landing_tab_id`, `admin_sidebar_nav.js`) + +* **Stale Tab Names In Latest Features** + * Several Latest Features entries pointed readers at tabs by their old names after the settings moved. + * (Ref: `latest-features` pane) + +### **(v0.260.012)** + +#### User Interface Enhancements + +* **New Data Lifecycle Group For Retention, Classification And Archiving** + * Retention policy, document classification and conversation archiving all decide how long content lives and how it is labelled, but they were split across Workspaces and Safety. They now sit together in a **Data Lifecycle** group with a tab each: **Retention**, **Classification** and **Archiving**. + * Conversation archiving in particular was buried under Safety, which described what it protects against rather than what it does. + * (Ref: navigation map, `retention-policy-section`, `document-classification-section`, `conversation-archiving-section`) + +* **Chat Group Gathers The Settings That Shape A Conversation** + * Settings that change what a conversation looks and behaves like were spread across AI Models, Workspaces and Safety. The **Chat** group now holds them in two tabs. + * **Chat Experience** collects model thought display, chat file uploads (with the conversation contents drawer) and workspace scope lock. + * **Feedback & Alerts** collects user feedback and desktop notifications, which are both about how the app talks back to the user rather than about safety enforcement. + * (Ref: `chat-experience`, `feedback-alerts`, `processing-thoughts-section`, `chat-file-uploads-section`, `workspace-scope-lock-section`, `user-feedback-section`, `desktop-notifications-section`) + +* **Settings Keep Their Values Through The Move** + * Cards were relocated between tabs without renaming a single field, so every saved value is preserved and the form submits exactly the payload it did before. + * Sidebar search still finds a setting by group, tab or card name, so you can reach anything without knowing where it now lives. + * (Ref: admin settings field contract, `admin_settings_nav.py`) + +### **(v0.260.011)** + +#### User Interface Enhancements + +* **Governance And Scale Split Into Focused Tabs** + * Governance held five cards covering three different jobs. It is now **Feature Governance** (which features are governed), **Policies** (the policies themselves), and **MCP Governance**. + * Scale mixed cache configuration with Cosmos capacity, and is now **Redis & Caching** and **Cosmos**. + * **Azure Front Door** moved out of Scale into Security, under a new **Network** tab. It configures authentication and redirect flows rather than throughput, so it never belonged with capacity settings. + * Existing links and bookmarks to `#governance` and `#scale` still work and land on the first tab of each group. + * No settings changed. Every option keeps its name and its saved value. + * (Ref: navigation map, `feature-governance`, `governance-policies`, `mcp-governance`, `redis-caching`, `cosmos`, `network`) + +#### Bug Fixes + +* **Governance Status Messages No Longer Get Stuck On One Tab** + * The inline governance status message lived inside the Governance pane, so a message raised while working in one area could end up rendered on a tab you were not looking at. + * It now sits outside the tabs and is visible wherever you are in Governance. + * (Ref: `governance-status`, `admin_governance.js`) + +#### Bug Fixes + +* **Reliable File Generation From Agent Action Results** + * Asking an agent for a downloadable file built from action results now produces the complete dataset in the requested format. Previously these requests could fail outright, publish a three-row sample of a large result, overwrite the assistant's written answer, or return nothing at all. Delivered across v0.260.004 through v0.260.011. + * **Files no longer fail to generate.** A CSV built from several actions in one turn could stop with `Generated output schema mismatch at row 2`, because each action returned a different set of columns. The export now pins a union of every column before the run starts and pads the missing cells, so mixed-shape results serialize instead of failing. + * **The written answer is no longer replaced by the file card.** CSV replies were suppressed alongside JSON and XML, but only JSON and XML withhold their payload from the response. CSV, DOCX, and PDF now keep the assistant's answer and append the file card beneath it. + * **Files contain the retrieved data, not a sample of it.** When the assistant pasted a few example rows above its answer, that excerpt outranked the real result set, producing a 3-row file from a 900-row query. Pasted rows are now used only when they are not an excerpt of the data actually retrieved. + * **Discovery calls no longer dilute the dataset.** A turn that lists instances, lists parameters, then retrieves history used to blend all three into one file. Rows are grouped by the action that produced them, and the action holding the substantive dataset wins. + * **Follow-up requests reuse data already gathered.** Asking "now make that a CSV" after the data was retrieved in an earlier turn no longer returns an empty result. The export reaches back through stored conversation citations, bounded by the **conversation history limit** in Admin Settings, and reuses the rows already collected instead of re-querying the source. + * **Answering a clarifying question now delivers the file.** When the assistant asks which rows and columns to include, replying "yes, all columns" now publishes the file that was originally requested. The clarification turn itself no longer publishes a placeholder file built from the question text. + * **The assistant no longer claims it cannot create files.** Every format now states the publication contract to the model, including on the turn that only answers a clarification, so replies stop saying "I cannot create or attach a file in this interface" and then producing one anyway. + * **Overlapping result pages no longer double the row count.** Agents frequently re-request a range from the same start time rather than paging forward, which produced a 1,000-row file for a window holding roughly 500 distinct records. Rows an earlier page of the same action already returned are dropped, while genuinely repeated records inside a single response are preserved. + * **Partial data is now labeled.** When an action reports that it truncated its own results, the file carries a **Partial** badge and a note explaining that it covers only the rows the action returned. Agents are also instructed to request the remainder starting after the last row they already hold, rather than repeating the original range. + * **CSV, DOCX, PDF, JSON, and XML now behave identically.** All five formats resolve rows the same way, reach back to earlier turns, decline to publish on a clarification turn, and report truncation. + * (Ref: `functions_generated_file_exports.py`, `functions_tabular_generated_exports.py`, `route_backend_chats.py`, `chat-messages.js`, [Generated Artifact Paging, Truncation, and Guidance Carry-Forward Fix](https://github.com/microsoft/simplechat/blob/main/docs/explanation/fixes/GENERATED_ARTIFACT_PAGING_AND_GUIDANCE_FIX.md), Refs #1071) + +### **(v0.260.010)** + +#### New Features + +* **Admin Settings Navigation Is Now Grouped** + * Admin Settings presented 18 tabs in one flat list. Related tabs are now collected under 12 groups such as Appearance, Knowledge, Security and Operations, so the list is scannable and has room to grow. + * In the sidebar, groups are collapsible and remember whether you left them open. In the tab layout, a row of group pills filters the tab strip to one group at a time. + * Opening a tab always reveals its group first, so a deep link or a cross-reference can never land you on a pane whose tab is hidden. + * Sidebar search now matches group names as well as tab and setting names, and expands whatever it needs to show a result. + * No settings moved in this release. Every tab keeps its contents; only the navigation around them changed. + * (Ref: `admin_settings_nav.py`, `_sidebar_nav.html`, `admin_settings.html`, `admin_sidebar_nav.js`) + +#### Bug Fixes + +* **Shared Conversation File Approvals Is Reachable From The Sidebar** + * The Shared Conversation File Approvals card had no navigation entry, so it could only be found by scrolling the AI Models tab. It is now listed like every other setting. + * (Ref: `shared-conversation-file-approvals-section`, navigation map) + +* **Navigation Labels And Order Can No Longer Drift** + * The tab strip and the sidebar each maintained the same structure by hand and had diverged: tab order differed between them, and Agents, Custom Pages and Search and Extract each showed a different name depending on which navigation you used. + * Both now render from one definition, so a change is made once and appears in both. + * (Ref: `admin_settings_nav.py`, `test_admin_settings_nav_map.py`) + +### **(v0.260.009)** + +#### New Features + +* **Admin Settings Form Field Contract Is Now Enforced** + * Admin Settings submits one form and the backend reads every value by field name, so the set of `name` attributes is the real contract between the template and the settings backend. Renaming or dropping one silently stops that setting from saving, with no error anywhere. + * A new test pins every field name against a committed baseline, and fails the build if one disappears. Adding settings is unaffected; removing one now requires regenerating the baseline in the same commit, which makes it a visible, reviewed decision. + * The same test rejects duplicate field names, which is what prevents a mirrored control from submitting a value twice. + * (Ref: `test_admin_settings_field_contract.py`, `admin_settings_field_baseline.json`) + +### **(v0.260.008)** + +#### New Features + +* **Settings That Need Another Setting Now Say So** + * Some Admin Settings options only work when a different option is enabled, and the two often live in different tabs. That was previously explained only in prose, in a tooltip, or in a warning after saving, so you could switch something on and have nothing happen with no visible reason. + * Affected cards now show an inline notice naming what they need, with a switch to enable the prerequisite without leaving the tab and a link straight to its full configuration. + * **File Sync** announces its **Redis Cache** requirement live, and keeps its save-your-intent behaviour: settings can still be saved and activate once Redis is ready. + * The **FeedbackAdmin** role control is disabled until **User Feedback** is enabled, since the role only governs access to the User Feedback report. The unrelated SafetyViolationAdmin control in the same card stays usable. + * These notices are guidance only. The server still validates every prerequisite. + * (Ref: `admin_settings_dependencies.js`, `data-requires`, File Sync, Permissions) + +#### Bug Fixes + +* **Cross-Tab Links In Admin Settings Now Point At The Right Place** + * Links that send you from one Admin Settings tab to a related setting used to name a tab button directly, so they broke silently whenever a tab was renamed or reorganised: no tab opened, and the address bar was left pointing at nothing. + * Two were already wrong. The **Video File Support** and **Audio File Support** references in Citations sent you to the **Workspaces** tab, but those settings live under **Search and Extract**. Both now open the correct card. + * All twelve cross-tab links now name the card they want, and the owning tab is worked out when you click. The destination card is briefly highlighted so it is obvious where you landed. + * (Ref: `admin_card_links.js`, `data-admin-link`, `openAdminCard`, `test_admin_card_links.py`) + +* **User Agreement Preview Sanitized At The Sink** + * The User Agreement preview rendered Markdown through a guarded reassignment, which reads as unsanitized to static analysis and matched the pattern already corrected for the Home Page Text preview. + * Now sanitized inline with `DOMPurify.sanitize(...)` at the point of rendering. `marked` and DOMPurify are both loaded globally, so the availability guards were redundant. + * (Ref: User Agreement, `admin_settings.html` preview handler, DOMPurify) + +### **(v0.260.007)** + +#### User Interface Enhancements + +* **Latest Features No Longer Opens Every Time You Visit Admin Settings** + * Latest Features was pinned first in both the top tabs and the admin sidebar, and its pane was hard-coded as the default active tab, so a curated release-notes page behaved like the Admin Settings landing page. + * It now sits last in both navigations, after **Send Feedback**, and **General** is the landing tab instead. + * The Latest Features content is unchanged, including its **New** badge and the hide/unhide option. + * (Ref: `admin_settings.html` top-tab strip, `_sidebar_nav.html`, `admin_sidebar_nav.js` default tab) + +* **Global Identities Is No Longer An Unlabelled Widget** + * The Global Identities tab rendered a bare control with no heading or description, unlike every other Admin Settings tab. + * It now has a heading and explains that identities are deployment-wide and that secrets are stored in Key Vault when Key Vault storage is configured. + * (Ref: Global Identities, `workspace-identities-section`, `functions_workspace_identities.py`) + +* **File Sync Is Now Reachable From The Sidebar** + * File Sync is one of the larger settings surfaces but was the only tab with no sidebar submenu, so its sub-areas could not be jumped to or found with sidebar search. + * **Visible Source Types**, **Personal Workspace Sync**, **Group Workspace Sync**, and **Public Workspace Sync** are now sidebar destinations. + * (Ref: File Sync, `_sidebar_nav.html`, `file-sync-submenu`) + +#### Bug Fixes + +* **Classification Banner Preview Now Updates As You Type** + * The live preview in Admin Settings never updated, because its script sat between template blocks where Jinja discards it, so the code was never rendered to the page. + * The preview now responds to banner text, background colour, and text colour changes. + * (Ref: Classification Banner, `admin_settings.html` `{% block scripts %}`) + +* **Admin Sidebar Section Map Cleaned Up** + * The sidebar's `sectionMap` had grown to 72 entries, but 66 of them mapped a key to itself, which the existing fallback already handled, and one pointed at an element that no longer exists. + * Reduced to the 6 entries that are genuine aliases. A new test now fails if a redundant, dangling, or unreferenced entry is reintroduced. + * (Ref: `admin_sidebar_nav.js`, `scrollToSection`, `test_admin_settings_sidebar_card_parity.py`) + +* **Home Page Text Preview No Longer Reinterprets Editor Text As HTML** + * The Home Page Text preview in Admin Settings assigned the raw editor contents to `innerHTML` when the Markdown editor had not initialized, so text typed into the editor was reinterpreted as HTML. CodeQL flagged this as `js/xss-through-dom` (high severity). + * The raw fallback now uses `textContent`, which is what the code intended by "just show raw text", and the Markdown path is sanitized inline with `DOMPurify.sanitize(...)` at the sink. DOMPurify is loaded globally from the local vendored bundle, so no external asset is introduced. + * (Ref: Home Page Text, `admin_settings.html` `showPreview`, DOMPurify) + +#### Breaking Changes + +* **Admin Settings Template Split Into Per-Tab Partials** + * `admin_settings.html` had grown to 13,526 lines in a single 1 MB file. Each tab pane now lives in `templates/admin/_panes/` and is included by the parent, which keeps the global form, the modals, and the script blocks. + * No settings behaviour changes: every form field name and all 110 configuration card ids are byte-identical, so the submitted payload and the settings backend are untouched. + * **Migration**: code or tests that read `templates/admin_settings.html` directly now see only the parent shell. Use `test_support.templates.read_admin_settings_template()` in functional tests, or `compose_if_admin_settings()` inside a shared file-reading helper. A new contract test fails if a test asserts on a partial-backed card or field without composing the template first. + * (Ref: `templates/admin/_panes/`, `functional_tests/test_support/templates.py`, `test_admin_settings_template_composition.py`) + +### **(v0.260.006)** + +#### New Features + +* **Shared Conversation File Approvals** + * Files generated by a participant in a shared conversation are now created immediately and held in a **pending approval** state instead of being refused, because they are saved into the conversation owner's storage. + * The conversation owner approves personal shared conversations; any group **Owner**, **Admin**, or **Document Manager** approves group shared conversations. Requesters can never approve their own file. + * Approvers get an inline **Approve / Deny** card on the pending file plus a notification. Approving releases the file, denying deletes the stored file and records who declined it. + * A staged file is not downloadable by anyone, including the requester, until it is released. + * Only downloadable deliverables are gated (CSV, XLSX, DOCX, PDF, JSON, XML). Generated images and charts are never gated. + * Unapproved files are automatically declined and deleted after 3 days, matching the existing Control Center approval window. + * New Admin Settings toggle **Require approval for participant-generated files**, enabled by default. + * (Ref: `functions_generated_file_approvals.py`, `chat-file-approvals.js`, `require_shared_conversation_file_approval`, `/api/collaboration/file-approvals`) + +#### Bug Fixes + +* **Actions Using the Application Identity Are Now Restricted to Azure Endpoints** + * Actions that authenticate with the application's own managed identity can no longer be pointed at an arbitrary endpoint. Blob Storage, Queue Storage, Cosmos, Databricks, and Log Analytics actions now accept only canonical Azure service hostnames for the public, US Government, China, and Germany clouds. + * Previously a caller holding only the normal **User** role could save a personal action with an attacker-controlled endpoint and application managed-identity authentication, causing the application to send a token minted for its own workload identity to that destination. + * Endpoints are validated when the action is saved and again immediately before the client is built, so actions stored before this release stop working rather than continuing to send credentials. + * Log Analytics custom clouds can no longer choose the Microsoft Entra token authority or the OAuth resource used for delegated tokens. + * Existing actions using standard Azure hostnames are unaffected. Custom domains, development storage, Azure Stack, and direct private-link hostnames are intentionally rejected, matching the Azure Blob File Sync hardening in v0.250.068. + * (Ref: `functions_azure_endpoint_validation.py`, `plugin_health_checker.py`, `blob_storage_plugin.py`, `queue_storage_plugin.py`, `cosmos_query_plugin.py`, `databricks_plugin.py`, `log_analytics_plugin.py`, [Action App-Identity Endpoint Hardening Fix](https://github.com/microsoft/simplechat/blob/main/docs/explanation/fixes/ACTION_APP_IDENTITY_ENDPOINT_HARDENING_FIX.md)) + +* **Action Authentication Types Are Now Enforced on the Server** + * Each action type's supported authentication methods, declared in its schema definition file, are now enforced when an action is saved or tested. Previously the list was only used to populate the action modal and was never checked by the backend. + * This prevents an action type from being configured with an authentication method it was never designed to support, such as requesting application-identity authentication for an OpenAPI or Microsoft Graph action. + * The auth-types API now resolves through the same helper the save paths use, so the modal and the backend cannot drift apart. + * (Ref: `json_schema_validation.py`, `get_allowed_auth_types_for_plugin_type`, `validate_plugin_auth_type_allowed`, `route_backend_plugins.py`) + +#### User Interface Enhancements + +* **Blob Storage Actions Can Now Use Managed Identity or an Account Key** + * The Blob Storage action modal gained an authentication selector offering **Connection String**, **Managed Identity**, and **Account Key**, along with blob service endpoint and account key fields. + * Previously the modal only collected a connection string even though the backend accepted other methods, so managed identity was not reachable through the UI. + * The endpoint field is validated against the Azure Blob hostname allowlist before the action is saved. + * (Ref: `_plugin_modal.html`, `plugin_modal_stepper.js`, `blob_storage.definition.json`) +* **Shared Conversations No Longer Fail With "Stream interrupted: Forbidden"** + * Fixed invited participants being unable to invoke the AI at all in a shared conversation. Any explicit AI request returned `Forbidden` with no content. + * Root cause was the hidden source conversation behind every shared conversation being owned by its creator, so participants failed a plain ownership comparison in the chat streaming route even though they are legitimate members. + * Because shared conversations only call the AI on an explicit mention, this surfaced the first time a participant asked the assistant for something, which made it look file-specific. + * Participants can also now download generated files from a shared conversation, which was blocked by the same comparison. + * Also fixed background CSV exports queued by a participant becoming unreadable for the owner, because publication checks looked up the export run under the wrong user partition. + * (Ref: `build_conversation_participation_context`, `route_backend_chats.py`, `route_enhanced_citations.py`, `functions_simplechat_operations.py`) + +#### User Interface Enhancements + +* **Clearer Group Workspace Save Errors** + * Attempting to save a generated document into a group workspace without document rights now names the roles that can complete it and suggests requesting the content as a downloadable file instead of failing with a bare permission error. + * (Ref: `_resolve_group_upload_target_for_current_user`) + +### **(v0.260.005)** + +#### User Interface Enhancements + +* **Tab Now Completes an @ Mention in Shared Conversations** + * In multi-user conversations, pressing **Tab** while the `@` suggestion menu is open now accepts the highlighted participant, agent, model, or invite suggestion, exactly like **Enter** already did. + * Previously **Tab** moved focus out of the message box and left the half-typed `@par` text behind, which broke the autocomplete habit most people bring from other editors and chat clients. + * **Shift+Tab** is deliberately unchanged and still moves focus backwards, and **Tab** still moves focus normally when the menu is showing "No matching participants...". + * The chat mention menu now matches the agent instruction mention menu, which already accepted **Tab**. + * (Ref: `chat-collaboration.js`, `handleComposerKeydown`, `selectActiveMentionSuggestion`, Fixes #1299) + +* **Mention Menu Is Now Announced Correctly By Screen Readers** + * Each `@` suggestion is now exposed as a proper listbox option with `aria-selected`, and the message box references the highlighted suggestion through `aria-activedescendant` paired with `aria-controls` so assistive technology can resolve it. + * The highlighted suggestion is also scrolled into view while arrowing through a long list, so keyboard navigation no longer highlights an off-screen entry. + * (Ref: `chat-collaboration.js`, `renderMentionMenu`, `updateMentionMenuActiveItem`, `applyMentionComboboxState`, `chats.html`) + +### **(v0.260.004)** + +#### Bug Fixes + +* **New Chat Now Clears The Conversation Documents Side Pane** + * Fixed the conversation side drawer keeping the previous conversation's documents after clicking **New chat**. The stale list, the header documents toggle, and its count badge all stayed visible, and the drawer would not close. + * Root cause was the New chat reset signal carrying a null conversation id while `window.currentConversationId` still pointed at the conversation being left, so the drawer fell back to the old conversation and re-fetched its documents instead of clearing. The **Contents** pane was unaffected because it resets from a separate chatbox observer. + * The **Documents** pane now empties out and the drawer closes, matching **Contents** behavior. Switching between existing conversations is unchanged, and one redundant conversation-metadata request per New chat click is eliminated. + * (Ref: `chat-conversation-contents.js`, `refreshConversationDocuments`, `chat:conversation-context-changed`, `updateDrawerTriggers`, Fixes #1298) + +### **(v0.260.003)** + +#### Bug Fixes + +* **Data Management Timeline Steps Now Show Their Own Status** + * Fixed completed job steps showing a `running` badge on the Data Management job timeline. Events such as "Cosmos DB export step completed" and "Migration reconciliation completed" now read `completed`. + * Root cause was `_set_job_progress` stamping the **job** status onto every step event it recorded, so a finished step inherited `running` because the job itself was still running. + * Step status is now decoupled from job status: steps that start report `running`, steps that finish report `completed`, and the job continues running until it genuinely finishes. + * Applies to backup, restore, and migration timelines. + * (Ref: `functions_data_management.py`, `_set_job_progress`, `_complete_job_step`, `_record_data_management_job_event`) + +#### User Interface Enhancements + +* **Finished Jobs No Longer Look Stuck** + * Completed backup jobs no longer display **Current container: Waiting**, which made a finished job look like it was still churning. + * Migration jobs no longer display a **Liveness: Running** row after reaching a terminal status. + * Live-only telemetry is now hidden once a job is `completed`, `completed_with_warnings`, `failed`, or `canceled`. + * (Ref: `admin_data_management.js`, `getBackupLiveMetrics`, `getMigrationLiveMetrics`, `isTerminalJobStatus`) + +### **(v0.260.002)** + +#### Bug Fixes + +* **Backup Inventory No Longer Fails To Load** + * Fixed the Backup Inventory panel in Admin Settings → Data Management always returning `503` and showing `0` for available, full, and partial backups. + * The global summary used a Cosmos `GROUP BY` with a non-VALUE aggregate (`COUNT(1) AS count`), a combination the `azure-cosmos` Python client does not support. Cosmos rejected the query during plan negotiation with `BadRequest ... GroupBy NonValueAggregate`. + * Counts are now computed with bounded, fully supported `SELECT VALUE COUNT(1)` queries, so the panel renders real numbers without loading backup history into memory. + * This was not a throttling or indexing problem; the composite index was already aligned. Backup Inventory had been broken since the summary shipped. + * (Ref: `functions_data_management.py`, `_get_data_management_backup_global_summary`, `_count_data_management_backups`, `/api/admin/data-management/backups`) + +#### User Interface Enhancements + +* **Run Retention Cleanup Now Explains Itself** + * Added a hover tooltip and an `(i)` toggle that expands inline guidance next to the **Run Retention Cleanup** button. + * Documents that cleanup permanently deletes backups past the retention period along with their artifacts, skips jobs that are still running, honors **Keep latest full backup**, and deletes at most 25 backups per run. + * Clarifies that "found no expired backups to delete" means every backup is still inside the retention window, which is expected rather than a failure. + * (Ref: `admin_settings.html`, backup retention cleanup, Data Management) + +### **(v0.260.001)** + +v0.260.001 consolidates all work released after v0.250.001 into one major release note, spanning 117 incremental patch builds. This rollup highlights the major feature, UI, reliability, security, and operations themes while preserving the full per-build history in the Detailed Change Log at the end of this section. + +#### Breaking Changes + +* **Workflow Alert Configuration Model** + * The legacy single `alert_priority` workflow field is superseded by `alert_mode`, `alert_rules`, and `alert_evaluation` for rules-based workflow notifications. + * Existing workflows are auto-migrated on read into equivalent failed-run and completed-run notification rules. + * **Migration**: Review upgraded workflow alert rules and prune any always-notify completed-run rule that is no longer desired. +* **New Yamcs Client Dependency** + * The Yamcs Mission Control action adds `yamcs-client==2.1.0`, the repository's first LGPL-3.0 dynamically linked pip dependency. + * SimpleChat can still start without it, but Yamcs actions return an actionable dependency error until installed. + * **Migration**: Run `pip install -r requirements.txt` or rebuild deployment images so the Yamcs client dependency is present where Yamcs actions are used. +* **Internal Route Name Hardening** + * Blueprint security hardening changed internal route names and required broad route policy/test updates. + * Shared-conversation streaming regressions from the rename sequence were fixed in the consolidated patch history. + * **Migration**: Update any custom integrations that call SimpleChat by internal endpoint name rather than public route URL. +* **Conversation Cache Fallback Behavior** + * Volatile chat bootstrap and conversation cache payloads no longer fall back to the Cosmos `settings` container when Redis is unavailable. + * Deployments without Redis keep full functionality, but bypass these cache benefits. + * **Migration**: Configure Redis for deployments that depend on chat bootstrap or conversation cache acceleration. + +#### Upgrade Notes + +* **Enhanced Extraction Settings Migration** + * Deployments already configured for Enhanced or Auto extraction are automatically migrated on first settings read to preserve their existing extraction mode. + * No manual change is required unless admins want to revise extraction defaults after upgrade. +* **Embedded Image Chunk Placement** + * Word and PowerPoint figures are now merged into chunks with surrounding text instead of appended as extra chunks. + * Existing documents keep their current chunk layout until re-extracted. + * Use Change Extraction or re-upload documents to benefit from the new placement behavior. +* **Workflow Alert Review** + * Rules-based workflow notifications can express run status, text/regex matches, File Sync results, AI-judged outcomes, and agent signals. + * Review workflow owner expectations after upgrade because migrated rules intentionally preserve prior notification behavior. +* **Redis-Backed Cache Operations** + * DAI document/tag caches and conversation list/feed caches now include Redis-backed invalidation and metrics behavior. + * Monitor Redis availability to keep cache acceleration active; safety-sensitive cache invalidation fails closed when state is unknown. +* **Detailed Patch Traceability** + * The original v0.250.003 through v0.250.229 entries are preserved verbatim below with demoted headings for audit and support lookup. + +#### New Features + +* **Enhanced Document Extraction and Analysis** + * Azure AI Content Understanding supports AI-generated figure descriptions for PDFs/images, with Auto mode figure detection. + * Embedded Office images, including EMF/WMF diagrams and legacy DOC/PPT media, are rasterized, analyzed, and indexed as citable chunks. + * Optional Document Intelligence formula extraction adds LaTeX equation capture for PDFs when enabled. + * (Ref: Azure AI Content Understanding, Document Intelligence, embedded image extraction, formula extraction) +* **Workflow Multi-Task Automation and Alerts** + * Workflows now support ordered instruction tasks with prior-task context chaining, per-task document actions, retry/failure handling, and configurable task limits. + * Conditional alert rules cover run status, text/regex matches, File Sync summaries, AI-judged results, and agent-raised signals across five severity levels. + * Active workflow runs can be cancelled from workspace rows, run history, or activity surfaces. + * (Ref: workflow task sequencing, workflow alert rules, `raise_workflow_alert`, run cancellation) +* **Expanded Agent and Action Integrations** + * Yamcs and RocksDB action types add mission-control and HTTP/JSON data-service integrations. + * Inbound MCP exposes governed SimpleChat capabilities for conversations, documents, prompts, tags, and workflows. + * Action connection testing now covers OpenAPI, Maps, Blob, Databricks, Log Analytics, MCP, Snowflake, Tableau, RocksDB, Yamcs, SQL, and Cosmos DB. + * (Ref: Yamcs action, RocksDB action, MCP inbound server, action test connection) +* **Governance, Security, and Model Administration** + * Governance policies support explicit block lists for feature and delegated item policies alongside allow rules. + * Key Vault secret expiration reminders track per-action secrets with background sweeps, notifications, and telemetry. + * Model requests can include HMAC-hashed user identity headers, and admins can configure per-model output token ceilings. + * (Ref: governance policies, Key Vault secret inventory, model endpoint identity header, output token limits) +* **Chat Productivity, Grounding, and Notifications** + * Users can opt into response completion sounds, desktop notifications, configurable AI notices, and per-message MP3 export. + * Conversation grounding now exposes model/workspace/document/agent context, used-document panes, assistant-response forks, and a contents drawer. + * User font size preferences, generated JSON/XML export artifacts, and smarter scroll behavior improve long-session usability. + * (Ref: chat notifications, grounding citations, used documents pane, conversation fork, contents drawer, export artifacts) +* **Workspace, Sync, and Data Management Operations** + * Azure Blob Storage File Sync adds SAS, managed identity, service principal auth, virtual-folder browsing, and ETag change detection. + * Admin operations add automatic Control Center statistics refresh, backup cleanup/retention, restore workflows, Cosmos JSON editing, Redis Explorer, feedback/safety lifecycle controls, and file-processing log cleanup. + * Multi-select metadata extraction, configurable Public Workspace naming, and index auto-login improve workspace administration. + * (Ref: File Sync, Control Center, Backup Inventory, Data Management, Redis Explorer, metadata extraction) +* **Caching, Runtime, and Durable Processing Capabilities** + * DAI Redis read-through caches document lists, tag lists, and legacy counts with scope-version invalidation. + * Conversation list/feed caching adds Redis hit/miss metrics for Admin Settings visibility. + * Durable tabular analyze/search preflight parity, FFmpeg audio runtime support, and the model capability catalog broaden platform readiness. + * (Ref: DAI Redis cache, conversation cache metrics, tabular durable preflight, FFmpeg, model capability catalog) + +* **Latest Features Release Tiers for v0.260.001** + * Shifted the end-user Latest Features page and Admin Settings tab into current, previous, and archive release tiers for the v0.260.001 rollout. + * Preserved per-tenant visibility choices across the shift. The new v0.260.001 user-facing cards ship hidden until their placeholder screenshots are replaced, so admins publish each card once its real capture is in place. + * (Ref: Latest Features release groups, support catalog, admin catalog, visibility normalization) +* **Deeper End-User Feature Cards** + * Added 20 v0.260.001 end-user cards with seven concrete How To Try It steps and a three-image gallery each. + * Expanded the Latest Features card helper with the `images=[...]` gallery form for multi-image cards. + * (Ref: `_latest_feature_card`, `_SUPPORT_RELEASE_260_FEATURE_CATALOG`, Latest Features image galleries) +* **Admin Latest Features Archive Tier** + * Brought the Admin Settings Latest Features tab to the same three-tier current, previous, and archive model used by the end-user page. + * Keeps v0.250.001 admin cards and older v0.241.x admin highlights available without crowding the current release tier. + * (Ref: `_ADMIN_LATEST_FEATURE_RELEASE_GROUPS`, `_ADMIN_RELEASE_260_FEATURE_CATALOG`, Admin Settings Latest Features tab) +* **Latest Features PR Workflow Hooks** + * Added a Latest Features authoring prompt, PR template checklist, and CI warning path so feature PRs consider release notes, cards, and screenshots together. + * Helps future releases keep in-app Latest Features content aligned with shipped user and admin changes. + * (Ref: `.github/prompts/update-latest-features.prompt.md`, `.github/PULL_REQUEST_TEMPLATE.md`, `release-notes-check.yml`) + +#### User Interface Enhancements + +* **Agent and Workflow Builder Refresh** + * Agent configuration now follows Actions → Knowledge → Instructions, with selected actions visible in the Instructions step. + * Workflows use a stepped General/Trigger/Tasks/Reliability/Review builder with per-task runner controls and alert-rule editing. + * (Ref: agent modal, workflow builder, workflow runner controls, alert rules editor) +* **Administration and Configuration UX Improvements** + * Workspace sections now use a consistent Documents → Prompts → Identities → Sync → Endpoints → Actions → Agents → Workflows order. + * Governance policy copy/inverse/show-users actions, dedicated Log Analytics configuration, refreshed backup/migrate/restore flows, and reviewed data migration steps reduce admin friction. + * External links can be reordered, custom pages can be opened directly, and non-blocking Bootstrap toasts replace browser alerts across admin, workspace, and profile pages. + * (Ref: workspace section order, governance UI, Log Analytics settings, data migration UI, toast notifications) +* **Chat, Navigation, and Accessibility Enhancements** + * Chat, navigation, and sidebar layouts remain usable at 200% zoom and with large text. + * The Conversation Contents drawer adds safe labels, keyboard focus handling, active-location tracking, and responsive desktop/mobile navigation. + * Long source lists collapse behind a disclosure, document picker rows show file-name context, and Refresh Documents preserves selection with clearer status. + * (Ref: 508 usability, conversation contents drawer, source disclosure, document picker, refresh documents) +* **Data Explorer and Extraction Status UX** + * Redis Explorer uses a fixed-height modal with independent key-list and preview scrolling. + * Cosmos query results open in a scrollable modal so the main editor stays focused on query setup. + * Extraction badges identify the engine that ran and show Content Understanding vs. Document Intelligence fallback reasons. + * (Ref: Redis Explorer, Cosmos editor results modal, extraction badges) + +* **Placeholder Screenshots for Pending Captures** + * Added 76 branded "Screenshot pending" placeholders so every v0.260.001 Latest Features card renders a valid local image while final captures are pending. + * Placeholders can be replaced in place with real screenshots without changing the catalog configuration. + * (Ref: `application/single_app/static/images/features/`, Latest Features image galleries) +### **(v0.250.231)** + +#### Bug Fixes + +* **Missing Release Highlight Screenshots Now Display** + * The Latest Release pages referenced 24 screenshots that were never present in the documentation site, so every one of them rendered as a broken image. + * The images already existed in the application at `application/single_app/static/images/features/`, where the in-app Latest Features gallery reads them. They are now also published with the documentation site, so the release highlight pages show the same screenshots users see in the product. + * (Ref: `docs/images/latest-release/`, `docs/_data/latest_release_features.yml`, Latest Release highlight pages) + +* **Broken Documentation Links Repaired** + * Fixed the remaining broken internal links on the documentation site. Links that pointed at renamed pages now resolve, and links that target files kept in the repository rather than published on the site, such as the Custom Pages developer guide, the Teams app manifest, and a CI workflow, now open on GitHub instead of returning a missing page. + * Removed two references to a ServiceNow multi-action setup guide that was never written. + * The documentation site now has zero broken internal links across 31,649 checked links. + * (Ref: `ui_tests/check_docs_links.js`, ServiceNow guides, Custom Pages guide, upgrade paths guide) + +### **(v0.250.230)** + +#### New Features + +* **Documentation Site Redesign** + * The documentation site was rebuilt for search, navigation, page simplicity, mobile support, and content coverage. + * Search now indexes page content instead of titles only. Previously 84% of the 986 indexed pages were internal engineering notes, 88% of entries had no description, and no page body text was indexed at all, so a search for "agent" returned mostly internal fix notes. The index is now 165 entries with a description on every one and no engineering notes. + * Added a dedicated search results page with section filters and highlighted excerpts, a `Ctrl+K` shortcut, keyboard navigation, and a full-screen mobile search sheet. Search was previously hidden entirely on phones. + * Navigation was rebuilt so the top bar and sidebar expose the same six sections: Start, Guides, Features, Administration, Deploy and operate, and Reference. Coverage went from 27 links to 74, all verified to resolve. + * (Ref: `docs/search-index.json`, `docs/assets/js/search.js`, `docs/_config.yml` navigation, `docs/search.md`) + +* **Screenshot and Video Placeholders for Documentation** + * Documentation pages can now declare a screenshot or video slot. When the asset does not exist yet the page renders a visible card naming the exact file path to create; adding the file at that path replaces the placeholder automatically on the next build with no configuration or code change. + * Videos render as a local poster card that links out to YouTube or Microsoft Stream, so no video files are committed to the repository and no third-party embed scripts are loaded. + * Added a media status page listing every slot and whether it is filled, as a capture worklist for contributors. + * (Ref: `docs/_includes/media.html`, `docs/_data/media.yml`, `docs/contributing/media-status.md`) + +* **Complete Documentation Coverage of the Application** + * Added one page per admin settings tab covering what the tab controls, why it matters, every setting with its default and governing settings key, prerequisites, and the common tasks admins perform there. + * Added task guides for creating actions, agents, agents with actions, multi-task workflows, triggering workflows, file sync connectors, tags, tags in chat, tags on conversations, and exporting conversations, plus further guides derived from the application surface. Each guide explains what the task does and why before the steps. + * Added a chat interface reference covering all 47 chat controls and an action reference covering all 27 actions. + * Added a feature catalog in which every one of the 111 capability toggles is claimed by exactly one capability entry. + * (Ref: `docs/admin/`, `docs/guides/`, `docs/reference/chat-controls.md`, `docs/reference/actions/`, `docs/_data/features.yml`) + +* **Documentation Coverage Enforcement** + * Added a generated inventory of the application surface and functional tests that fail when a new capability toggle, admin settings tab, action plugin, or chat control ships without documentation, so coverage stays complete as changes land. + * (Ref: `scripts/build_docs_inventory.py`, `functional_tests/test_docs_app_surface_coverage.py`, `functional_tests/test_docs_site_quality.py`) + +#### User Interface Enhancements + +* **Documentation Site Works on Phones and Tablets** + * Standardized the responsive breakpoints, which previously mixed `768px` and `767.98px` and left gaps, and exported the desktop breakpoint to JavaScript so it is no longer duplicated by hand. + * Wide tables and long code blocks are now contained in horizontal scroll regions instead of widening the page, images are lazy-loaded with intrinsic sizing, touch targets meet a 44px minimum, and the mobile navigation drawer and search sheet trap and restore focus. + * Verified with browser tests at 360x640, 390x844, 768x1024, 1280x800, and 1920x1080. + * (Ref: `docs/assets/css/main.scss`, `docs/assets/js/sidebar.js`, `ui_tests/test_docs_site_responsive.js`) + +* **Simpler Documentation Pages** + * Landing pages were rewritten from hand-written HTML card markup into plain markdown. The home page previously had 82 blocks of card markup and zero markdown headings, and the features page 119 blocks and zero headings, which meant neither page had a working "On this page" table of contents or heading anchors. + * The FAQ was rebuilt so every question is its own heading with a linkable anchor. + * The decorative page hero, with its gradient banner, pill row, and icon orb, was replaced with a plain documentation header across the 38 pages that used it. + * Split the 452 KB release notes page into per-version-series pages while keeping the existing release notes URL working. + * (Ref: `docs/index.md`, `docs/features.md`, `docs/start/faqs.md`, `scripts/build_release_notes_pages.py`) + +* **Documentation URLs Now Match Their Section** + * Guides previously lived under three different URL spaces that all meant the same thing. Tutorials and how-to guides are consolidated under `/guides/`, orientation pages moved under `/start/`, deployment scenarios under `/deploy/`, and reference pages under `/reference/`. + * **Existing links and bookmarks continue to work.** Every moved page redirects from its old URL, and the URLs the application itself links to were deliberately left unchanged. + * (Ref: documentation navigation, `jekyll-redirect-from`, `ui_tests/check_docs_links.js`) + +#### Bug Fixes + +* **Documentation Site No Longer Overflows Horizontally on Desktop** + * The main content region combined a full-width rule with a sidebar offset, so every desktop viewport scrolled sideways by exactly the sidebar width. This was a long-standing defect on the published site. + * (Ref: `.docs-main-content`, `docs/assets/css/main.scss`) + +* **Documentation Section Labels and Page Titles** + * Path-scoped Jekyll defaults used collection names as their type and therefore never applied, so nearly every page fell back to a generic "Docs" section and search facets were meaningless. Three scenario index pages also had a comment above their front matter, so it was never parsed and they were titled with their own file path and rendered through an empty layout. + * (Ref: `docs/_config.yml` defaults, `docs/explanation/scenarios/`) + +* **Documentation Site Loads No Third-Party Assets** + * Removed jQuery, DataTables, marked, DOMPurify, and split.js, none of which the site used, and vendored Bootstrap, Bootstrap Icons, Prism, Lunr, and the site fonts locally with their licenses. The site now makes zero external requests. + * (Ref: `docs/assets/vendor/`, `docs/_layouts/default.html`, local browser asset policy) + +### **(v0.250.229)** + +#### Bug Fixes + +* **Admin Latest Features Previous and Archive Preview Restored** + * The read-only user-facing preview panel in Admin Settings > Latest Features never rendered, because it sat inside a disabled template block that also holds the legacy hardcoded feature cards from before the tab became data-driven. + * The admin route was already computing and passing `support_latest_feature_release_groups_preview` for a panel that could never display, so admins had no way to review previous and archive release cards alongside their sharing status. + * Closed the disabled block after the legacy cards so the preview panel renders again, and namespaced its element ids to avoid colliding with the admin release-group cards. + * (Ref: `admin_settings.html` Latest Features tab, `support_latest_feature_release_groups_preview`, `route_frontend_admin_settings.py`) +* **Latest Features Sidebar Card Id Special Case Removed** + * The admin sidebar built the previous-release section link through a redundant conditional that produced the same id as the general dynamic expression. + * Simplified to the dynamic form so every non-current tier, including the new archive tier, is handled the same way. + * (Ref: `_sidebar_nav.html`, admin Latest Features navigation) +* **Orphaned Latest Features Metadata Tables Removed** + * Removed `_SUPPORT_CURRENT_FEATURE_IMAGE_METADATA` and `_SUPPORT_CURRENT_FEATURE_USER_METADATA` along with the two helpers that consumed them. Their keys matched no feature id in any release tier, so both helpers were no-ops, and the `_CURRENT_` naming became misleading after the release tiers shifted. + * Verified behavior-neutral: the full serialized catalog output across every accessor and several settings permutations is byte-identical before and after removal. + * Added a regression test that generically detects orphaned per-feature metadata tables, so this class of drift is caught in future rather than only these two names. + * (Ref: `support_menu_config.py`, `test_support_menu_config_dead_metadata_removal.py`) +* **Citations and Source Rendering** + * Citation parsing preserves line breaks after inline citations, agent document search results render as document sources, retrieved and cited sources remain separated, prior grounded references resolve in follow-up turns, and source-reading intent is no longer misclassified as artifact generation. + * (Ref: citation parser, agent document search, grounded source references, generated artifacts) +* **Shared Conversations and Conversation Forks** + * Shared conversations load, render messages, generate AI responses, refresh uploads/task documents, and survive Blueprint security hardening. + * Forking from group/public workspace knowledge no longer returns HTTP 500, and structured logging normalization prevents logger errors from replacing HTTP responses. + * (Ref: shared conversations, streaming bridge, conversation fork, structured logging) +* **Workflow Execution Reliability** + * File Sync summaries reach task-based workflow models, task instructions scope document search queries, run history preserves per-task document status, zero-retry settings persist, and invalid task document actions are contained. + * (Ref: workflow execution, task document status, retries, File Sync summaries) +* **Backup, Restore, and Data Management Reliability** + * Backup ETag normalization, Cosmos pagination, checkpoint batching, and provider status diagnostics improve backup completeness and troubleshooting. + * (Ref: Data Management backup, Backup Inventory, Cosmos pagination, checkpoint batching) +* **Tabular Analyze/Search Durability** + * Exhaustive Markdown output includes all rows, line-phrased requests route to the durable pipeline, artifact lifecycle finishes before run completion, stale settings migrations correct disabled preflight flags, and `filter_rows contains` semantics match across foreground and durable paths. + * (Ref: tabular analyze, durable preflight, generated artifacts, filter_rows) +* **Document Extraction and Grounded Search** + * Legacy DOC/PPT embedded images are analyzed, image chunks merge into the correct surrounding-text chunk, document picker search matches file names, and multi-word grounded queries support punctuation word breaks. + * (Ref: embedded images, chunk placement, document picker search, grounded search) +* **Cosmos, Redis, and Cache Performance** + * Settings container idle RU usage is reduced, no-op read invalidation is skipped, Docker multi-worker startup conflicts recover, DAI Redis TTLs are bounded/refreshed, cache invalidation fails closed on unknown safety state, and cache parity improves for pending shared documents, legacy revisions, and generated-artifact identity. + * (Ref: Cosmos RU usage, conversation cache invalidation, DAI Redis cache, public workspace artifacts) +* **Authentication and Security** + * Credential-like field names are no longer logged in clear text, action secret references are scoped to their owning action, Terms of Use redirects happen server-side with HTTPS enforcement, and `/getAToken` without an authorization code redirects to sign-in. + * (Ref: credential redaction, action secrets, Terms of Use, authentication redirects) +* **Model Endpoints and MCP Outbound** + * Managed identity cloud values are normalized, vision test connection uses the correct multi-endpoint target, GPT 5.6+ models appear in the multi-modal vision selector, and MCP tool arguments no longer get wrapped in incompatible `kwargs` payloads. + * (Ref: model endpoints, vision selector, managed identity, MCP outbound) +* **Governance, Navigation, and Admin Settings** + * Retargeting policies no longer creates duplicates, block-list modals stack correctly, Group Workflows appears in the sidebar, hidden tabs hide sidebar links, logo/favicon save paths no longer 500, and update banner version comparison no longer shows stale releases as newer. + * (Ref: governance policies, workspace sidebar, admin settings, update banner) +* **Retention, Notifications, Logging, and Public Workspace Edge Cases** + * Group and collaboration conversations now use correct retention policy/activity timestamps, unauthenticated pages avoid notification polling 401 noise, Application Insights events carry sanitized diagnostic values with standardized tags, custom Databricks-prefixed plugin discovery avoids built-in defaults, and hidden public workspace documents can ground chat searches. + * (Ref: retention policy, notification polling, Application Insights logging, plugin discovery, public workspace search) + +#### Detailed Change Log (v0.250.003 - v0.250.229) + +The individual patch builds consolidated into v0.260.001 are preserved below for traceability. + +##### **(v0.250.229)** + +###### Bug Fixes + +* **Citations No Longer Eat the Line Break After Them** + * Text that came after an inline document citation was jammed onto the end of the closing parenthesis instead of starting a new paragraph — you would see `(Source: uploading_documents.md, Page: 1)Thank you, Paul.` with no break at all. + * The citation parser matched the `[#citation-id]` marker along with the whitespace that followed it, then rebuilt the citation without putting that whitespace back. Because this runs on the raw markdown before it is rendered, a deleted blank line did not just remove a space — it changed how the rest of the block was read, so a paragraph after a cited list item got absorbed into the list item itself. + * Spacing is now restored exactly as the model wrote it. Paragraphs, bullets, and numbered lists after a citation render in their intended structure, a citation followed by more text on the same line keeps its space, and back-to-back citations stop colliding. Copied and exported message text keeps its line breaks for the same reason. + * The cleanup pass for leftover citation markers had the same flaw in reverse and could swallow the blank line *before* a stray marker. It now only removes horizontal spacing, or the marker's whole line when it sits on one. + * (Ref: [#1289](https://github.com/microsoft/simplechat/issues/1289), `chat-citations.js`, `parseCitations()`, chat message rendering) + +##### **(v0.250.228)** + +###### Bug Fixes + +* **Figures Now Stay in the Chunk They Came From** + * Images extracted from Word and PowerPoint files were appended as extra chunks at the end of the document, with page numbers continuing past the real content. A figure on page 5 of a 15-page document became chunk 16, so a search hit on the figure lost its surrounding text and citations pointed at a page that did not exist. + * Embedded images are now merged into the chunk containing the text they appear with. PowerPoint images follow the slide that references them; Word images are placed by their position in reading order; and legacy `.doc` and `.ppt` images, which carry no recoverable position, anchor to the final chunk instead of creating a page beyond the document. + * Merging rather than adding a chunk also removes a latent indexing hazard: chunk ids are derived from the page number, so a second chunk sharing a page number would have overwritten the first in the search index. + * PDFs were already correct — Content Understanding attributes each figure to its page by span, and Document Intelligence Layout inlines tables and figures into the page markdown. That behavior is unchanged and now covered by a regression test. + * **Existing documents keep their current chunks until they are extracted again.** Use *Change Extraction* or re-upload to pick up the new placement. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_documents.py`, `functions_office_media.py`, figure chunk association) + +##### **(v0.250.227)** + +###### Bug Fixes + +* **Shared Conversation Stream Errors Stay Attached to the Shared Conversation** + * Follow-up hardening to the v0.250.224 shared conversation fix. When an AI request in a shared conversation failed, the error the browser received did not say which kind of conversation it belonged to, so the recovery path could have reloaded from the personal endpoint and produced the same "Conversation not found" error that was just fixed. + * It could not actually happen yet because of an unrelated guard, but it would have come back the moment anyone added a message id to those errors. All shared stream failures now go through a single serializer that always tags the conversation, and a test walks the code to prove no failure path can skip it. + * (Ref: [#1281](https://github.com/microsoft/simplechat/issues/1281), `route_backend_collaboration.py`, `chat-streaming.js`, collaborative AI streaming) + +* **Repaired Route Assertions Across the Test Suite** + * The recent Blueprint security hardening renamed how routes are declared, but 82 assertions across 40 test files still checked for the old form. Those tests were failing on the rename before they ever reached the behavior they were written to protect. + * This is how the shared conversation streaming bug reached users: the test guarding that exact code path was already red for an unrelated reason. 59 assertions across 32 files were corrected, each verified against a real route first. 14 were deliberately left alone because they point at routes that no longer exist, which is a separate issue worth investigating rather than hiding. + * (Ref: [#1281](https://github.com/microsoft/simplechat/issues/1281), `functional_tests/`, Blueprint route registration) + +##### **(v0.250.226)** + +###### Bug Fixes + +* **File Sync Now Tells the Workflow What Changed** + * File Sync builds a summary of each run — the scan counts plus every new or changed document — but that summary never reached the model in any workflow that uses tasks, which is every workflow the builder creates. + * The failure was silent and misleading: the summary *was* written into the conversation, so the transcript showed the changed-document list as though the model had received it. In practice the model saw only the raw task instructions and usually replied that it knew nothing about any documents. + * This hit **Monitor File Sync Changes** workflows hardest, along with any workflow using Search or no document action, or with **Use changed documents** turned off. The first task in the sequence now receives the summary, and later tasks get it through the first task's response. + * The summary is also bounded now, with a clear truncation notice, so a very large sync cannot crowd out the actual instructions. + * (Ref: [#1285](https://github.com/microsoft/simplechat/issues/1285), `functions_workflow_runner.py`, File Sync prompt context) + +* **Document Search Queries Are No Longer Diluted by Injected Context** + * A workflow's document search used the entire task prompt as its search query, including the File Sync summary and the previous task's full response. A search for "find the renewal clause" could end up querying 50 lines of file paths. + * Search queries now use the task's own instructions. Retrieved content and context still reach the model exactly as before — only the query is scoped. + * (Ref: [#1285](https://github.com/microsoft/simplechat/issues/1285), `functions_workflow_runner.py`, workflow document search) + +##### **(v0.250.225)** + +###### New Features + +* **Workspace Documents Are Now Configured Per Workflow Task** + * Each task in a workflow now owns its own **Workspace documents** setup — document action, document target, selected documents, Compare source and targets, per-document analysis, and windowing — instead of sharing one configuration across the whole workflow. + * Adding a task resets the document fields, and returning to a previously configured task restores that task's setup, so tasks are self-contained. + * Every task now executes with its own document action at run time. Previously the single workflow-level action only ever applied to task 1, and every later task ran with no document context. + * Existing workflows keep working: their saved document action is inherited by task 1 only, matching how they actually ran. Group workflows still force every task into the owning group workspace. + * Task cards and the Review step now summarize which documents each task uses. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `workspace_workflows.js`, `functions_personal_workflows.py`, `functions_group_workflows.py`, `functions_workflow_runner.py`, per-task document actions) + +###### Bug Fixes + +* **Workflow Document Picker No Longer Hangs on "Loading tags..."** + * Choosing a Document action of Search, Analyze, or Compare in the workflow builder revealed the document picker but never loaded it. Tags stayed disabled showing `Loading tags...` forever, the document list stayed empty, and no console error appeared. + * The picker was only ever loaded when the modal opened, and that path returned early whenever the action was `No document action` — which is always true for a new workflow. The Document action dropdown's change handler only toggled visibility and never triggered a load. + * Changing the Document action or Document Target now loads the picker, and the tags control always resolves to the available tags or `No tags available for this scope`. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `workspace_workflows.js`, `chat-documents.js`, workflow document picker) + +* **Workflow Run History No Longer Masks a Failed Document** + * When two tasks in the same run process the same document, the later task's status used to overwrite the earlier one's, so a document that failed in one task could be shown as succeeded. + * Document run items are now recorded per task, and each item records which task produced it. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `functions_workflow_runner.py`, workflow run history) + +* **Resume Failed Items Respects Per-Task Documents** + * Resuming failed documents narrowed only the workflow-level document action. Now that tasks own their own documents, it also narrows each task's analyze action to the documents that failed in that task, and group resumes keep every task inside the owning group workspace. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `route_backend_workflows.py`, resume failed items) + +* **A Workflow Task Configured for Zero Retries Per Window Stays at Zero** + * Saving a multi-task workflow rewrote a stored `Retries Per Window` of `0` to `1` on any task other than the one being edited. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `workspace_workflows.js`, retries per window) + +* **An Invalid Task Document Action No Longer Aborts the Whole Run** + * If a workflow's document action stopped validating between runs — for example an administrator disabled Analyze or Compare, or lowered the workflow document limit — the run failed outright with no task-level error recorded. + * The failure is now contained to that task and follows the workflow's retry and failure-handling settings. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `functions_workflow_runner.py`, workflow task error handling) + +###### User Interface Enhancements + +* **"Refresh documents" Now Actually Refreshes** + * The **Refresh selected documents** button previously warned `Select one or more workspace documents in the picker first.` even though the picker was empty and nothing could be selected. + * It is now labeled **Refresh documents**, reloads the document list while preserving the current selection, and reports what it found — including a clear message when the selected scope has no documents. + * (Ref: [#1282](https://github.com/microsoft/simplechat/issues/1282), `workspace.html`, `group_workspaces.html`, `workspace_workflows.js`) + +##### **(v0.250.224)** + +###### Bug Fixes + +* **Shared Conversations Load and Answer Again** + * Sharing a personal conversation left it unusable. Every reload or click on the shared conversation raised a "Conversation not found" error, because the chat page was still asking for its messages from the personal conversation endpoint — and a shared conversation is stored separately, under its own id. + * Shared conversations now load their messages only from the collaboration endpoint, so the failed request and the error banner are gone. + * (Ref: [#1281](https://github.com/microsoft/simplechat/issues/1281), `chat-conversations.js`, `chat-collaboration.js`, shared conversation loading) + +* **AI Responses Work Again in Shared Conversations** + * Asking the AI anything in a shared conversation failed immediately with "Stream interrupted: Chat streaming endpoint is unavailable" and no answer was ever generated. + * The recent Blueprint security hardening renamed the internal chat streaming endpoint, and the shared-conversation bridge was still looking for the old name. The bridge now resolves the endpoint correctly and logs a diagnostic if it ever cannot, so this fails loudly instead of silently. Group shared conversations are restored by the same fix. + * (Ref: [#1281](https://github.com/microsoft/simplechat/issues/1281), `route_backend_collaboration.py`, `app.py`, collaborative AI streaming) + +* **Chat Uploads and Task Documents in Shared Conversations** + * Files uploaded inside a shared conversation never showed up in the Analyze and Compare document pickers, and task documents from the previously opened conversation stayed attached after switching to a shared one. + * Shared conversations now refresh both when their messages load, matching personal conversation behavior. + * (Ref: [#1281](https://github.com/microsoft/simplechat/issues/1281), `chat-collaboration.js`, `chat-messages.js`, Compare and Analyze document pickers) + +###### New Features + +* **Optional Mathematical Formula Extraction** + * Added an **Extract mathematical formulas** toggle to the Document Intelligence settings. When enabled, equations in PDFs and images are captured as LaTeX instead of being approximated as OCR text. + * This requests a **billed Document Intelligence add-on**, so it is off by default and must be turned on deliberately. It applies to the Layout model only, so it has no effect while extraction is set to Standard. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_content.py`, `functions_settings.py`, `admin_settings.html`, Document Intelligence formulas add-on) + +###### Bug Fixes + +* **Images in Legacy `.doc` and `.ppt` Files Are Now Analyzed** + * Embedded image analysis previously covered only DOCX and PPTX, because legacy Office files are OLE compound documents rather than zip packages and have no media parts to enumerate. + * Pictures and embedded equation previews are now carved out of the legacy container by metafile signature, using the length recorded in the metafile's own header, then rasterized and analyzed like any other embedded image. + * Validation is strict — record type, signature position, and a length that fits the remaining bytes — so a coincidental byte sequence is not mistaken for an image. Duplicate images are still collapsed and the per-document cap still applies. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_office_media.py`, `functions_documents.py`, legacy Office image extraction) + +##### **(v0.250.223)** + +###### Bug Fixes + +* **Diagrams in Word and PowerPoint Files Are Now Analyzed** + * Images embedded in Office documents as EMF or WMF metafiles were silently skipped. Word stores pasted diagrams, SmartArt, Visio drawings, and charts in this format, so architecture diagrams — often the most information-dense figures in a document — were never analyzed or indexed. + * Metafiles are now rasterized in-process and sent to the configured extraction engine like any other image. Text drawn inside the diagram is recovered as well, so figure labels such as service and resource names become searchable even when the vision engine returns no description. + * The renderer is pure Python on top of Pillow, with no system packages or external converters, so it behaves the same in the Linux container as it does locally. Fidelity is intentionally a description aid rather than a pixel-accurate reproduction; unsupported drawing records are skipped rather than failing the document. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_emf_render.py`, `functions_office_media.py`, embedded Office image analysis) + +* **Embedded Image Processing Is Now Visible in the Workspace Log** + * A document whose images were all skipped looked exactly like a document with no images at all, so there was no way to tell whether embedded image analysis had run. + * Processing now reports how many embedded images were found, how many were analyzed, and why any were skipped — too small, duplicates, unsupported format, or over the per-document cap. Progress is reported per image rather than only once at the start. + * The found, analyzed, and skipped counts are stored on the document so the outcome can be confirmed after processing completes. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_documents.py`, `functions_office_media.py`, embedded image diagnostics) + +##### **(v0.250.222)** + +###### New Features + +* **Index Auto-Login** + * Added an opt-in `ENABLE_AUTO_LOGIN_ON_INDEX` setting that redirects unauthenticated home-page visits to the existing Microsoft Entra sign-in flow. + * Supports government tenant SSO scenarios where users already have a browser session and should enter SimpleChat without first clicking the sign-in link. + * (Ref: `app.py`, `config.py`, `INDEX_AUTO_LOGIN.md`, Microsoft Entra sign-in) + +##### **(v0.250.221)** + +###### New Features + +* **Enhanced Extraction Now Uses Azure AI Content Understanding** + * Enhanced extraction for PDFs and images now uses Azure AI Content Understanding (`prebuilt-documentSearch`) instead of Document Intelligence Layout. In addition to tables, page structure, and checkbox states, it returns AI-generated descriptions of figures, charts, and diagrams — structure Document Intelligence never produced. + * Standard extraction is unchanged and always uses Document Intelligence, which remains required for workspaces and chat file uploads. + * A new **Enable Enhanced extraction** toggle in Admin Settings reveals the Content Understanding configuration. Turning it on defaults the extraction mode to **Auto**, so documents are only upgraded when the sample shows structure worth paying for. + * Content Understanding supports both key and managed identity authentication, with a **Test Connection** button and an in-app setup guide covering Foundry resource creation, supported regions, required model deployment defaults, and the Cognitive Services User role. + * Enhanced never becomes a hard dependency. Content Understanding is not offered in Azure Government, so Enhanced automatically uses Document Intelligence Layout in Government and custom clouds — the admin UI says so plainly and there is nothing to configure there. Enhanced also falls back when Content Understanding is unconfigured or a request fails, and the reason is recorded on the document and shown in workspace tooltips. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_content_understanding.py`, `functions_content.py`, `functions_settings.py`, `route_backend_settings.py`, `admin_settings.html`, `CONTENT_UNDERSTANDING_ENHANCED_EXTRACTION.md`) + +* **Images Inside Word and PowerPoint Files Are Now Analyzed** + * Neither extraction engine describes figures inside Office files, so SimpleChat now pulls embedded images out of DOCX and PPTX packages and analyzes them with whichever engine backs the selected extraction mode — Content Understanding when Enhanced is active, Document Intelligence otherwise. This works with Standard extraction too. + * Each analyzed image is indexed as its own citable chunk, and PowerPoint images are attributed to the slide that references them. + * Cost is bounded by design: icons, bullets, and spacer graphics are filtered out by a configurable minimum size, byte-identical images such as repeated header logos are analyzed once, and a per-document cap limits the total. + * Uploaded Office files are treated as untrusted: extracted file names are generated rather than reused from the archive, entries are streamed with a hard byte ceiling instead of trusting the archive's declared size, compression methods and entry counts are bounded, and slide relationship parts are parsed with a hardened XML parser. + * Can be turned off entirely with **Analyze images embedded in DOCX and PPTX files**. Image analysis failures never fail the document. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_office_media.py`, `functions_documents.py`, embedded Office image analysis) + +###### Upgrade Notes + +* **Existing Enhanced and Auto Deployments Keep Their Setting** + * The new **Enable Enhanced extraction** toggle defaults to off, so deployments already set to Enhanced or Auto are migrated automatically on first settings read: the toggle is switched on and persisted, preserving the previously selected mode. + * Without this migration an upgrade would have silently downgraded those deployments to Standard and then overwritten the stored mode on the next settings save. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_settings.py`, `get_settings()` migration) + +###### User Interface Enhancements + +* **Extraction Badges Name the Engine That Actually Ran** + * Extraction tooltips in personal, group, and public workspaces now say whether a document was processed with Azure AI Content Understanding or Document Intelligence Layout, and explain any fallback that occurred. + * The **Change Extraction** action now works for images as well as PDFs, and refuses a change to Enhanced while Enhanced extraction is disabled. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `workspace-documents.js`, `public_workspace.js`, `group_workspaces.html`, `functions_documents.py`) + +* **Auto Mode Also Upgrades for Figures** + * Auto mode still samples the first pages with Document Intelligence Layout as the cheaper detector, but now upgrades to Enhanced when it finds figures or images, not just tables and selection marks. This matters because figure description is the main reason to use Enhanced. + * (Ref: [#1277](https://github.com/microsoft/simplechat/issues/1277), `functions_documents.py`, Auto mode detection) +##### **(v0.250.220)** + +###### Bug Fixes + +* **Data Management History Failure Diagnostics** + * Backup Inventory and Job History failures returned a generic 503 telling admins to review application logs, while the logs recorded only the exception class name. The provider status code and message were discarded, making the failure impossible to diagnose. + * Failures now log the Cosmos status code and sanitized provider message. Provider text stays in operator logs and is never returned to the browser. + * (Ref: [#1275](https://github.com/microsoft/simplechat/issues/1275), `functions_data_management.py`, `route_backend_data_management.py`, Data Management history) + +* **Data Management History Throttle Handling** + * Throttled history reads previously produced the same opaque error as a permanent failure. + * Cosmos throttling is now detected, retried up to three times with jittered backoff, and reported as temporary busy guidance with a retryable flag instead of a generic error. + * (Ref: [#1275](https://github.com/microsoft/simplechat/issues/1275), `functions_data_management.py`, Cosmos history query retry) + +* **Data Management History Index Guidance** + * Missing-index detection required the exact phrase "composite index", so equivalent provider wording fell through to the generic error. + * Detection now also matches `ORDER BY` failures reported as having no corresponding index, keeping the Cosmos indexing maintenance guidance actionable. + * (Ref: [#1275](https://github.com/microsoft/simplechat/issues/1275), `functions_data_management.py`, Cosmos indexing maintenance) + +* **Source Blob Backup ETag Failure** + * Fixed every source blob failing backup with "Source blob changed while it was being backed up", which meant user documents, group documents, public documents, and chat attachments were never actually backed up. + * Root cause was comparing an ETag from `list_blobs()` (unquoted XML element) against one from `get_blob_properties()` (RFC-quoted HTTP header); the two never matched, so the post-transfer consistency check always failed after the blob had already been downloaded and uploaded. + * Both values are now normalized before comparison. The precondition sent to Azure is unchanged, and a genuine mid-transfer source change is still rejected. + * (Ref: [#1271](https://github.com/microsoft/simplechat/issues/1271), `functions_data_management.py`, source blob transfer verification) + +* **Source Blob Backup Checkpoint Throughput** + * Source blob backups previously wrote one Cosmos checkpoint per blob, capping throughput at roughly six items per second and stretching a single container to over an hour. + * Checkpoints are now batched per 100 items or 15 seconds, whichever comes first, while still asserting the job lease on every item. + * (Ref: [#1271](https://github.com/microsoft/simplechat/issues/1271), `functions_data_management.py`, source blob checkpointing) + +* **Functional Tests Silently Passing Under pytest** + * Backup functional tests written with the try/except and `return False` template were reported as passed by pytest because they returned a value instead of raising. + * The backup ETag and Cosmos pagination test files now assert directly, so real failures are reported by both pytest and standalone execution. + * (Ref: [#1271](https://github.com/microsoft/simplechat/issues/1271), `test_data_management_backup_source_blob_etag.py`, `test_data_management_backup_cosmos_pagination.py`) + +##### **(v0.250.219)** + +###### Bug Fixes + +* **Agent Document Search Now Produces Real Document Citations** + * Documents an agent retrieved through the document search action are now recorded as document sources instead of only as an agent tool call. Previously they appeared solely as a raw JSON tool modal, so the documents were missing from the message Sources disclosure, were not clickable, never opened in the enhanced citation viewer, and could never reach the Used documents drawer. + * Covers all three document search functions — relevance-ranked search, ordered chunk retrieval, and document summarization — across personal, group, and public workspaces. + * Document search results now carry a ready-to-copy citation value, and the action instructs the model to reuse it verbatim. When the answer cites a document, it is correctly separated from the retrieved sources and recorded in the conversation's used documents. + * Applies to streaming and non-streaming chat, document actions, cancelled and interrupted streams, and scheduled workflow runs. + * Retrieved sources are deliberately not capped, so a search that sources hundreds of chunks records all of them. Chunks retrieved by both the document search toggle and an agent are listed once. + * Cancelled and interrupted streams keep the documents the agent had already retrieved, and citation locations no longer relabel a valid page or sequence of `0` as page 1, which affected video chunks keyed by second. + * Workspace capability metadata now reports document usage for agent-only document turns, which previously under-reported as unused. + * (Ref: [#1239](https://github.com/microsoft/simplechat/issues/1239), `functions_agent_document_citations.py`, `route_backend_chats.py`, `functions_workflow_runner.py`, `document_search_plugin.py`, `AGENT_DOCUMENT_SEARCH_CITATION_FIX.md`) + +###### User Interface Enhancements + +* **Collapsed Long Source Lists** + * The per-message Sources disclosure now shows the first 25 document sources and collapses the rest behind a **Show N more sources** control, so an agent that retrieves hundreds of chunks no longer floods the panel. + * No source data is discarded — the full set is still stored, exported, and available for citation matching. + * (Ref: [#1239](https://github.com/microsoft/simplechat/issues/1239), `chat-messages.js`, `chat-citations.js`) + +##### **(v0.250.218)** + +###### Bug Fixes + +* **Credential Field Names Logged in Clear Text** + * Fixed a gap where credential values could be written to application logs and Application Insights in clear text. The log redactor matched only a fixed list of key-name substrings, so field names this codebase actually uses for secrets were missed. The most significant were `auth_key`, used by the action connection-test routes for the caller-supplied secret, and the plugin manifest's `auth.key`, which holds connection strings and service principal passwords. + * Eighteen credential key names were affected in total, including `pwd`, `key_pair`, `master_key`, `primary_key`, `secondary_key`, `encryption_key`, `signing_key`, `session_key`, and `storage_key`. + * Benign configuration keys that merely contain the word "key", such as `key_encoding`, `key_prefix_hints`, and `partition_key_path`, deliberately stay visible so logs keep their diagnostic value. + * (Ref: `functions_appinsights.py`, `test_log_credential_key_redaction.py`, `LOG_CREDENTIAL_KEY_REDACTION_FIX.md`) + +* **CosmosClient Import Bindings in Helper Scripts** + * Completed the v0.250.047 import-binding cleanup by updating the two remaining scripts that bound `CosmosClient` directly, so patching `azure.cosmos.CosmosClient` is observed consistently. No direct `CosmosClient` imports remain in the repository. + * (Ref: `scripts/resolve_multiendpoint_gpt.py`, `deployers/bicep/postconfig.py`) + +* **Privacy Logging Audit Test Restored** + * The privacy logging and telemetry audit had been failing since v0.242.072 because it asserted an exact `config.py` version and never reached its assertions. It now asserts a version floor, per the repository's version-assertion guidance, so the audit runs again. + * (Ref: `test_privacy_logging_telemetry_audit.py`) + +##### **(v0.250.217)** + +###### New Features + +* **Test Connection for Eight More Action Types** + * Added a **Test Connection** button to the Step 3 configuration for OpenAPI, Azure Maps, Blob Storage, Databricks, Log Analytics, MCP, Snowflake, and Tableau actions. Previously only SQL, Cosmos DB, Yamcs, and RocksDB actions could be validated before saving. + * Each test authenticates with the credentials entered in the modal and performs one lightweight read against the configured resource, so a wrong warehouse ID, container name, subscription key, personal access token, or MCP endpoint is caught immediately instead of failing later during a chat. + * Failures name the cause — rejected credentials, a missing warehouse or container, an unreachable host, or a driver that is not installed — and successes report useful detail such as the Databricks warehouse state, the Snowflake version, the Tableau API version, or the MCP tool count. + * Editing an existing action works without retyping credentials: masked secrets and reusable workspace identities are resolved server-side for the test only, and no credential value is ever returned to the browser. + * The MCP test enforces the same stdio scope restriction and outbound destination policy as MCP tool discovery, and it does not overwrite discovered tool metadata. + * (Ref: [#1267](https://github.com/microsoft/simplechat/issues/1267), `functions_action_connection_tests.py`, `route_backend_plugins.py`, `_plugin_modal.html`, `plugin_modal_stepper.js`, `ACTION_TEST_CONNECTION.md`) + +###### User Interface Enhancements + +* **Dedicated Log Analytics Configuration Section** + * Log Analytics actions now have their own Step 3 configuration section instead of reusing the generic endpoint and authentication form. + * Workspace ID, Cloud, API Endpoint, and the authentication method moved out of *Advanced → Additional Fields* and into the main configuration step, next to the new Test Connection button. Authority Host and Endpoint Override appear only when the Custom cloud is selected. + * Existing Log Analytics actions are unaffected — the section reads and writes the same manifest fields and preserves stored values such as `query_history`. + * (Ref: [#1267](https://github.com/microsoft/simplechat/issues/1267), `_plugin_modal.html`, `plugin_modal_stepper.js`, Log Analytics action configuration) + +###### Bug Fixes + +* **Action Secret References Now Resolved Only Within Their Own Scope** + * Action connection tests resolve a stored Key Vault secret reference strictly against the scope of the action being tested, instead of resolving any reference name supplied in the request. + * The unscoped resolver has been removed, and the existing MCP tool discovery, Cosmos DB, SQL, Yamcs, and RocksDB test paths now share the same scope-checked resolution used by the new connection tests. A reference that does not match the action's scope is rejected instead of resolved. + * Loading a global action for a connection test now requires the Admin role at the shared loader, so every test route inherits the check rather than relying on each route to gate it. + * Only affects deployments with Key Vault secret storage enabled. Normal editing is unchanged — testing an existing action still works without retyping stored credentials. + * (Ref: [#1267](https://github.com/microsoft/simplechat/issues/1267), `route_backend_plugins.py`, `functions_keyvault.py`, action secret scoping) + +##### **(v0.250.216)** + +###### New Features + +* **RocksDB Action** + * Added a new `rocksdb` action type so agents can read an ordered [RocksDB](https://github.com/facebook/rocksdb) key-value store, with a dedicated configuration card and Test Connection button in the action modal. + * RocksDB is an embedded library with no network protocol, so the action calls a RocksDB-backed HTTP/JSON service that you operate alongside your data. SimpleChat never runs RocksDB locally or opens a database directory on the application host. + * Supports no-auth, bearer token, and API key header authentication with a configurable header name. TLS certificate validation is always enforced. + * Exposes `get_value`, `get_values`, `key_exists`, `scan_prefix`, `scan_range`, `list_column_families`, and `get_database_stats` for reads, plus `put_value`, `delete_value`, and `write_batch` that stay blocked until an action explicitly allows writes. + * Handles binary data through configurable UTF-8, base64, and JSON key and value encodings that are sent to the service on every request, caps returned records, and flags values truncated by the size limit. + * The RocksDB HTTP service contract is fully documented so operators can implement a conforming service. + * (Ref: `rocksdb_plugin.py`, `route_backend_plugins.py`, `plugin_health_checker.py`, `_plugin_modal.html`, `plugin_modal_stepper.js`, `rocksdb.definition.json`, `test_rocksdb_plugin.py`, `test_workspace_rocksdb_action_modal.py`, `docs/explanation/features/v0.250.216/ROCKSDB_ACTION.md`) + +##### **(v0.250.215)** + +###### Bug Fixes + +* **Retrieved Sources and Cited References** + * Separated complete document/web retrieval results from the exact references used in final assistant responses, while preserving all returned results under **Sources**. + * Used documents now follows active cited responses, conversation details marks cited items within the full source inventory, and conversation/message export references exclude retrieved-only sources. + * Historical conversations retain their previous fallback without a migration or ordinary read-time history parsing. + * (Ref: [#1249](https://github.com/microsoft/simplechat/issues/1249), `functions_citation_tracking.py`, `route_backend_chats.py`, `route_backend_conversation_export.py`, `SOURCE_AND_CITED_REFERENCE_DISTINCTION_FIX.md`) + +##### **(v0.250.214)** + +###### New Features + +* **Agent Instruction Context References (`#action` and `#knowledge`)** + * Instructions can now reference the exact actions, action capabilities, and assigned knowledge that were selected for the agent, so authors can spell out *when* and *why* each capability or document should be used. + * Typing `#` in the Instruction Brief or the instructions editor opens an autocomplete that drills down from the `action` / `knowledge` namespace, to the actions selected in the Actions step, to that action's enabled capabilities. `#knowledge:` lists the assigned documents, workspaces, tag limits, and web sources with type badges. + * Tokens such as `#action:"Simple Chat":create_group` and `#knowledge:doc:"Employee Handbook.pdf"` are stored literally with the instructions so they stay editable and round-trip unchanged when an agent is edited. Values containing a space or colon are quoted automatically. + * Navigate with the arrow keys, insert with `Tab` or `Enter`, dismiss with `Esc`, or use the mouse. Document titles containing spaces stay searchable while typing. + * Foundry agents manage their instructions and tools in Foundry, so the references stay inert for Classic Foundry, New Foundry, and Foundry Workflow agents. + * (Ref: [#1257](https://github.com/microsoft/simplechat/issues/1257), [#1263](https://github.com/microsoft/simplechat/pull/1263), `agent_instruction_mentions.js`, `agent_modal_stepper.js`, `_agent_modal.html`) + +* **Context-Aware Draft Instructions** + * The **Draft Instructions** helper now receives the selected actions with their enabled capabilities and the assigned knowledge configuration, instead of only the agent name, description, and brief. + * Drafts reference only real, selected actions and documents, and use the new `#action:` / `#knowledge:` token convention. + * Client-supplied context is normalized, length-capped, count-capped, and bounded by a shared total character budget on the backend. It is used purely as prompt text and never affects authorization, and whitespace collapsing prevents newline-based prompt injection through action or document names. + * (Ref: [#1257](https://github.com/microsoft/simplechat/issues/1257), [#1263](https://github.com/microsoft/simplechat/pull/1263), `route_backend_agents.py`, `POST /api/agents/draft-instructions`) + +###### User Interface Enhancements + +* **Agent Modal Step Reorder: Instructions After Actions and Knowledge** + * The agent modal now runs Basic Info → Model & Connection → **Actions** → **Knowledge** → **Instructions** → Advanced → Summary, so instructions are written once the agent's real capabilities are known. + * Added a collapsible **Selected Actions & Knowledge** panel at the top of the Instructions step listing the selected actions with badges for their enabled capabilities, plus the assigned workspaces, documents, tags, and web sources, each with its reference token. + * Step navigation, validation, and Foundry agent-type visibility now key off named steps rather than hard-coded step numbers. + * (Ref: [#1257](https://github.com/microsoft/simplechat/issues/1257), [#1263](https://github.com/microsoft/simplechat/pull/1263), `_agent_modal.html`, `agent_modal_stepper.js`) + +###### Bug Fixes + +* **Agent Summary Step Referenced the Wrong Step Number** + * The Summary step's empty-actions message pointed authors at "step 4" to add actions. Actions is step 3 under the new order, and step 4 is now Assigned Knowledge. + * (Ref: [#1263](https://github.com/microsoft/simplechat/pull/1263), `_agent_modal.html`, agent modal summary step) + +##### **(v0.250.213)** + +###### New Features + +* **Workflow Alert Rules** + * Workflow alerts are now conditional. Instead of a single Pop-up Alert Priority that notified on every run, a workflow can define rules that describe *why* it should notify you, and a run that matches nothing stays completely silent. + * Conditions cover run status, task status, output text (contains, does not contain, or regex), File Sync results, empty output, an agent-raised signal, and a plain-English condition judged by a model, such as "any certificate expires within 14 days." + * Each rule can be scoped to the final output, any task output, or one specific task. + * Model-judged conditions are batched into a single call per run and skipped entirely when a deterministic rule already matched at a higher severity, so workflows that use only deterministic conditions add no model calls. + * (Ref: `functions_workflow_alerts.py`, `functions_workflow_runner.py`, `functions_personal_workflows.py`, `functions_group_workflows.py`, `workspace_workflows.js`, `WORKFLOW_ALERT_RULES.md`) + +* **Expanded Alert Severities and a Distinct Failure Style** + * The severity ladder grew from low/medium/high to **info, low, medium, high and critical**. + * Info and low alerts land quietly in the notification bell, while medium and above open the pop-up. Any rule can override this. + * Runs that error now carry a separate *failure* category that changes the icon and wording independently of severity, so "the workflow broke" is visually distinct from "the workflow found something." + * When several rules match the same run, the highest severity wins and the alert lists every matched rule with its reason under a new "Triggered by" section. + * (Ref: `functions_notifications.py`, `notifications.js`, `base.html`, workflow alert modal) + +* **Agent-Raised Workflow Alerts** + * Agents running inside a workflow can now raise an alert signal mid-run with severity, title and reason through the new `raise_workflow_alert` SimpleChat capability, and an `agent_signal` rule decides whether it notifies anyone. + * The rule's severity acts as a floor the agent can escalate above but never quiet below, and named signals can route to their own rules. + * The capability is opt-in and refuses outside an active workflow run, so existing agents do not gain the ability to create notifications and a normal chat cannot fabricate one. + * (Ref: `simplechat_plugin.py`, `functions_simplechat_operations.py`, `agent_modal_stepper.js`, `plugin_modal_stepper.js`) + +* **Alert Decision Visibility** + * Each run now records why it did or did not alert, including the winning severity and every matched rule, surfaced through the workflow activity view so noisy or silent workflows can be diagnosed. + * (Ref: `functions_workflow_activity.py`, `functions_workflow_runner.py`) + +###### User Interface Enhancements + +* **Workflow Alert Rules Editor** + * The Review step of the personal and group workflow builders replaces the single Pop-up Alert Priority dropdown with an alert mode selector and a rule editor for adding, editing, enabling and removing alert rules. + * Each rule row exposes its name, condition, severity, delivery and, where relevant, the task or output it should watch, with condition-specific fields appearing as the condition is chosen. + * The workflow list now summarizes alerts as the number of active rules, and the Review summary names the rules that will notify you. + * Invalid rules are caught before saving, such as a missing regex pattern, empty match values, an unwritten model condition, or a task-scoped rule with no task selected. + * (Ref: `workspace.html`, `group_workspaces.html`, `workspace_workflows.js`, workflow builder review step) + +###### Breaking Changes + +* **Workflow Alert Configuration Model** + * The single `alert_priority` field is superseded by `alert_mode`, `alert_rules` and `alert_evaluation`. The old field is retained and still honored. + * **Migration**: None required. Workflows that only carry `alert_priority` are migrated on read into two editable rules, `Run failed → high` and `Run completed → `, which reproduce the previous behavior exactly, including always opening the pop-up and staying silent on cancelled runs. Owners can then prune the noisy rule. + +##### **(v0.250.212)** + +###### New Features + +* **Yamcs Mission Control Action** + * Added a first-class, read-only `yamcs` action type that connects agents to a Yamcs mission control server using the official `yamcs-client` Python package. + * Exposes eleven read-only tools: instances, data links, mission database parameters and parameter detail, command *definitions*, live parameter values, parameter history, events, packets, alarms, and an optional guarded archive SQL query. + * Strictly read-only by design. The action cannot issue commands, set parameter values, run scripts, or enable/disable data links, and command listing returns definitions only. + * Archive SQL is disabled by default and, when enabled, is restricted to `SELECT`, `SHOW`, `DESC`, and `DESCRIBE` statements with a forbidden-keyword guard and an automatic row limit. + * Every retrieval is bounded by a row limit, a serialized byte limit, and a request timeout so a broad query cannot walk an entire archive, and error text is scrubbed of credentials. + * (Ref: `functions_yamcs_operations.py`, `semantic_kernel_plugins/yamcs_plugin.py`, `semantic_kernel_plugins/yamcs_plugin_factory.py`, `docs/explanation/features/YAMCS_ACTION.md`) + +* **Yamcs Action Configuration Panel and Test Connection** + * Added a dedicated Yamcs configuration section to the Add/Edit Action modal covering server URL, instance, processor, authentication, TLS verification, archive SQL opt-in, and retrieval limits. + * Supports username/password, API key, bearer token, and unauthenticated Yamcs servers, plus reusable workspace identities using `api_key`, `bearer_token`, or `username_password`. + * Added a **Test Yamcs Connection** button backed by `POST /api/plugins/test-yamcs-connection`, which verifies reachability and credentials and confirms the configured instance exists. Saved actions resolve their stored credential from Key Vault, so secrets do not need to be re-entered to run a test. + * (Ref: `_plugin_modal.html`, `plugin_modal_stepper.js`, `route_backend_plugins.py`, `workspace/view-utils.js`) + +###### Breaking Changes + +* **New `yamcs-client` Dependency** + * Added `yamcs-client==2.1.0` to `application/single_app/requirements.txt`. + * This package is licensed **LGPL-3.0**, the first LGPL dependency in this repository. It is used as an unmodified, dynamically linked pip dependency. + * It vendorizes its own protobuf runtime, so it does not conflict with the pinned `protobuf==6.33.5`. + * **Migration**: run `pip install -r requirements.txt` when upgrading. Deployments that do not install it can still run SimpleChat; Yamcs actions will return an actionable dependency error until the package is present. + * (Ref: `requirements.txt`, `semantic_kernel_plugins/yamcs_plugin.py`) + +##### **(v0.250.211)** + +###### User Interface Enhancements + +* **Consistent Workspace Section Order** + * Workspace sections now follow a single order of operations everywhere they are listed: Documents, Prompts, Identities, Sync, Endpoints, Actions, Agents, Workflows. + * The order reflects how a workspace is actually built up, so it is clearer that Identities feed both Sync and Actions, that Actions belong to Agents, and that Workflows run Agents. + * Applied to the tab strip, the collapsed Section dropdown, and the left-hand sidebar submenus for personal and group workspaces. Public workspaces already matched this order and were left unchanged. + * Sections that an admin has disabled stay hidden; the remaining sections simply close up while keeping their relative positions. + * (Ref: [#1255](https://github.com/microsoft/simplechat/issues/1255), `workspace.html`, `group_workspaces.html`, `_sidebar_nav.html`, `WORKSPACE_SECTION_ORDER.md`) + +###### Bug Fixes + +* **Group Workflows Missing From Sidebar Navigation** + * Added the missing Group Workflows link to the left-hand group workspace submenu. Group workflows previously had a working tab but no way to reach it from the sidebar. + * (Ref: [#1255](https://github.com/microsoft/simplechat/issues/1255), `_sidebar_nav.html`, group workflows navigation) + +* **Sidebar Links Pointing At Unrendered Workspace Tabs** + * Fixed left-hand navigation links whose visibility rules did not match the tabs they opened, so a link could appear for a section that was never rendered. + * Personal Agents and Actions links now respect the user agent and plugin permissions, group Agents and Actions links now respect per-user Semantic Kernel and group plugin permissions, and both Identities links now match their tab's File Sync and Semantic Kernel conditions. + * (Ref: [#1255](https://github.com/microsoft/simplechat/issues/1255), `_sidebar_nav.html`, `test_workspace_section_order.py`) + +##### **(v0.250.210)** + +###### Bug Fixes + +* **Chat Document Search Now Matches File Names** + * Fixed the chat grounded-search document picker only matching on a document's title, which made file names completely unsearchable for any document that had extracted title metadata. + * Typing any fragment of a file name now surfaces the document, anywhere in the name — searching `200` finds `Quarterly_Report_200_final.pdf`. + * Multi-word queries are also supported, with `_`, `-`, and `.` treated as word breaks, so `report 200` matches `Quarterly_Report_200_final.pdf`. The same improvement applies to the scope, tags, prompt, model, and agent selectors. + * (Ref: [#1256](https://github.com/microsoft/simplechat/issues/1256), `chat-documents.js`, `chat-searchable-select.js`, chat grounded search, document picker) + +* **Leftover Separator Lines in Filtered Dropdowns** + * Fixed filtered dropdowns leaving orphaned workspace separator lines behind — commonly two stacked horizontal rules directly under the "Select All" / "Clear All" row — when a search removed the leading sections. + * Divider visibility now follows the section it separates instead of the nearest visible row, and separator lines can no longer be leading, trailing, or stacked. Affects the Document, Scope, and Tags dropdowns, plus the Compare modal document picker. + * (Ref: [#1256](https://github.com/microsoft/simplechat/issues/1256), `chat-searchable-select.js`, dropdown filtering, section dividers) + +###### User Interface Enhancements + +* **File Name Shown in Document Picker Rows** + * Document rows in the chat grounded-search picker now show the file name as a smaller muted line beneath the title whenever the two differ, so it is clear which file a search matched. + * Rows without distinct titles are unchanged, and the row tooltip carries both the title and the file name. + * (Ref: [#1256](https://github.com/microsoft/simplechat/issues/1256), `chat-documents.js`, `chats.css`, document picker rows) + +##### **(v0.250.209)** + +###### Bug Fixes + +* **Cosmos Backup Continuation Token Failure** + * Fixed Data Management backups silently omitting every Cosmos container that held more than one page of documents, which in most deployments meant personal conversations and personal messages were never backed up. + * Affected containers failed with `BadRequest: Invalid Continuation Token` and were dropped from the backup artifact set while the job still reported completion with warnings. + * Root cause was rebuilding the cross-partition query for each page and replaying the previous pager's continuation token; the backup now drains a single pager so the SDK's cross-partition execution context is preserved. + * (Ref: [#1258](https://github.com/microsoft/simplechat/issues/1258), `functions_data_management.py`, Cosmos backup source paging) + +* **Missing Backup Failure Diagnostics** + * Source blob transfer failures previously produced no log output at all, so a run with nearly 20,000 failed blobs left no trace in App Service logs. + * Backups now log the first failure for each resource plus a bounded rollup of distinct failure reasons and counts when the resource finishes. + * (Ref: [#1258](https://github.com/microsoft/simplechat/issues/1258), `functions_data_management.py`, source blob backup logging) + +* **Application Insights Log Message Text** + * Structured log events reached Application Insights as the constant `[SIMPLE_CHAT_LOG_EVENT]` with every string property reduced to a character count, making traces unusable for diagnosis. + * Traces now carry the sanitized message text and an allowlist of non-sensitive diagnostic values such as job ID, resource, container, status code, and error. Sensitive keys still collapse to a presence flag and secret redaction is unchanged. + * (Ref: [#1258](https://github.com/microsoft/simplechat/issues/1258), `functions_appinsights.py`, log event properties) + +##### **(v0.250.208)** + +###### User Interface Enhancements + +* **Governance Policy Copy and Principal Review Actions** + * Added Duplicate and Inverse actions for delegated item governance policies so admins can quickly clone a policy or create an allow/block-list-swapped version before saving it as a new policy. + * Added a Show Users modal and removed the allowed/blocked user and group columns from the main delegated policy table, keeping the table easier to scan while preserving principal detail access. + * (Ref: [#1252](https://github.com/microsoft/simplechat/issues/1252), `admin_governance.js`, `admin_settings.html`, governance delegated item policies) + +##### **(v0.250.207)** + +###### Bug Fixes + +* **Intentional Governance Item Policy Retargeting** + * Updated delegated item policy edits so admins can intentionally move an existing policy to a different delegated item without creating a duplicate policy document. + * The admin UI keeps the policy ID stable, warns that changing the target will move the policy, and the backend saves the new target while deleting the original source document when original target metadata is supplied. + * Also prevents ambiguous policy-ID reuse and keeps feature-policy saves and item-policy deletes out of the retarget conflict path. + * (Ref: [#1252](https://github.com/microsoft/simplechat/issues/1252), `functions_governance.py`, `route_backend_governance.py`, `admin_governance.js`) + +##### **(v0.250.206)** + +###### Bug Fixes + +* **Governance Item Policy Retarget Protection** + * Fixed delegated item policy edits so changing the selected target no longer creates a duplicate policy document for the new item while leaving the old policy behind. + * Locks the target controls during existing policy edits and rejects conflicting backend saves when an existing policy ID is reused for a different delegated item. + * (Ref: [#1252](https://github.com/microsoft/simplechat/issues/1252), `admin_governance.js`, `route_backend_governance.py`, `functions_governance.py`) + +##### **(v0.250.205)** + +###### Bug Fixes + +* **Governance Block List Modal Handoff** + * Fixed the delegated item block-list editor opening behind the item policy editor by hiding the parent modal before opening the shared principal editor, then restoring the item editor after the principal editor closes. + * Keeps Bootstrap modal focus, backdrop, and scroll handling consistent by ensuring only one governance modal is visible at a time. + * (Ref: [#1252](https://github.com/microsoft/simplechat/issues/1252), `admin_governance.js`, `test_admin_governance_tab.py`) + +##### **(v0.250.204)** + +###### New Features + +* **Governance Policy Block Lists** + * Added admin-managed block lists for feature and delegated item governance policies so specific users or groups can be denied even when allow-all or allow-list rules would otherwise grant access. + * Enables administrator-friendly APIM quota-tier separation, such as allowing a high-threshold group to a high endpoint while blocking that group from a default low-threshold endpoint without maintaining a large low-user allow list. + * (Ref: [#1252](https://github.com/microsoft/simplechat/issues/1252), `functions_governance.py`, `route_backend_governance.py`, `admin_governance.js`, MCP governance) + +##### **(v0.250.203)** + +###### New Features + +* **Model Endpoint Identity Header** + * Added admin controls to send a stable HMAC-hashed user identity key with model endpoint requests for APIM counters, quota policies, and backend routing policies. + * Supports global enablement, custom safe header names, selectable identity inputs, and per-endpoint inherit/enable/disable overrides without exposing raw UPN, object ID, or tenant ID values. + * (Ref: [#1250](https://github.com/microsoft/simplechat/issues/1250), Model Endpoint Identity Header, `functions_model_endpoint_identity_header.py`, model endpoint runtime, Admin Settings) + +##### **(v0.250.202)** + +###### Bug Fixes + +* **Live User Message Metadata During Streaming** + * Made submitted user-message metadata available as soon as storage is acknowledged, without waiting for the assistant response to finish or requiring a page refresh. + * Preserved finalized metadata across success, server errors, cancellation, disconnect, recovery, image generation, document actions, and shared-chat streams while keeping in-flight message mutations gated until terminal completion. + * (Ref: [#1244](https://github.com/microsoft/simplechat/issues/1244), `functions_chat_stream_events.py`, `chat-streaming.js`, `chat-messages.js`, `USER_MESSAGE_METADATA_STREAMING_FIX.md`) + +##### **(v0.250.201)** + +###### Bug Fixes + +* **Exhaustive Row-by-Row Markdown Output** + * Fixed line-by-line Markdown analysis reading every source row but publishing only 12 summarized findings because the previous hierarchical lane intentionally bounded findings and notable rows. + * Search now produces one exhaustive Markdown artifact containing every source row and every requested answer; Analyze produces a concise Markdown summary plus a separate exhaustive row-by-row Markdown artifact. + * Exact-row Markdown uses ordered checkpoints, output-aware batching, consecutive answer-field validation, non-empty answer enforcement, final row-count/source-order checks, and literal Markdown escaping for untrusted content. + * (Ref: [#1233](https://github.com/microsoft/simplechat/issues/1233), `functions_tabular_orchestration.py`, `functions_tabular_generated_exports.py`, `route_backend_chats.py`, `TABULAR_EXHAUSTIVE_ROW_MARKDOWN_FIX.md`) + +##### **(v0.250.200)** + +###### Bug Fixes + +* **Hidden Public Workspace Document Chat Grounding** + * Fixed document chat handoffs from accessible public workspaces that users had hidden from the public directory, so the selected document is now available to grounded search instead of appearing selected while being silently excluded. + * Adds the selected workspace to the user's visible Chat workspaces without hiding any existing choices and revalidates the requested public workspace before updating user settings. + * (Ref: [#1245](https://github.com/microsoft/simplechat/issues/1245), `route_frontend_chats.py`, `test_public_workspace_hidden_document_chat_visibility.py`, `PUBLIC_WORKSPACE_HIDDEN_DOCUMENT_CHAT_VISIBILITY_FIX.md`) + +##### **(v0.250.199)** + +###### Bug Fixes + +* **Tabular Analyze/Search Artifact Lifecycle Completion** + * Preserved the selected model endpoint for pure-tabular Analyze background work, preventing non-default model selections from falling back to an unavailable deployment on the default Azure OpenAI resource. + * Enforced one artifact contract across Search and Analyze: Search CSV produces CSV; Analyze CSV produces Markdown plus CSV; exhaustive requests without an explicit output format produce Markdown in either mode. + * Made artifact publication complete before run completion, repaired previously uploaded-but-hidden Markdown artifacts during status reconciliation, and preserved original generation failures instead of masking them as schema errors. + * Removed misleading one-row Analyze CSV handoff artifacts and added sanitized user-visible failure reasons without exposing provider errors or endpoint details. + * (Ref: `functions_tabular_orchestration.py`, `functions_workflow_runner.py`, `functions_tabular_generated_exports.py`, `TABULAR_DURABLE_ARTIFACT_LIFECYCLE_FIX.md`) + +##### **(v0.250.198)** + +###### Bug Fixes + +* **Tabular Parity Stale Settings Migration** + * Fixed the four backend-only tabular durable-preflight parity flags (`tabular_request_planner_mode`, `enable_tabular_search_shared_preflight`, `enable_tabular_analyze_durable_preflight`, `enable_tabular_hierarchical_analysis`) silently staying disabled on any deployment whose Cosmos settings document already stored them from before their defaults were raised to active. + * `get_settings()` merges code defaults into the persisted document via `deep_merge_dicts()`, which only fills in missing keys and never overwrites an existing one, so raising a default in code alone never took effect for upgraded-in-place deployments. + * Both Analyze and Search durable preflight now self-correct to the active defaults on the next settings load and persist the fix back to Cosmos DB; the `SIMPLECHAT_DISABLE_TABULAR_PARITY_DURABLE_PREFLIGHT` emergency rollback env var continues to work unchanged. + * (Ref: `functions_settings.py`, `normalize_tabular_parity_durable_preflight_defaults()`, `TABULAR_PARITY_STALE_SETTINGS_MIGRATION_FIX.md`) + +##### **(v0.250.197)** + +###### Bug Fixes + +* **Tabular "Line" Terminology Routing** + * Recognized "line"-phrased exhaustive tabular requests (for example, "for each line," "line by line," "one line per") as equivalent to "row"-phrased requests across eight duplicated keyword-detection functions, so they route through the durable generated-output/analysis pipeline instead of the bounded foreground tool-calling path. + * Activated `enable_tabular_hierarchical_analysis` by default so narrative (non-export) exhaustive whole-dataset Analyze/Search requests can resolve to the durable `hierarchical_analysis` task type, extending the existing emergency env kill switch to also cover this flag. + * (Ref: `functions_tabular_orchestration.py`, `functions_tabular_parity_contract.py`, `route_backend_chats.py`, `functions_document_analysis.py`, `TABULAR_LINE_TERMINOLOGY_ROUTING_FIX.md`) + +##### **(v0.250.196)** + +###### Bug Fixes + +* **Top Navigation Public Workspace Lockout** + * Fixed a server-rendering failure that could lock users out after they selected top navigation while Public Workspaces was enabled. + * Preserved the saved navigation preference and default or customized Public Workspace labels without requiring a Cosmos profile repair. + * (Ref: `_top_nav.html`, `test_public_workspace_display_name_settings.py`, `TOP_NAV_PUBLIC_WORKSPACE_LABEL_CRASH_FIX.md`) + +##### **(v0.250.185)** + +###### Bug Fixes + +* **Analyze Combined Generated Output Routing** + * Treats Analyze requests that ask for row-level answers plus CSV/JSON/XML output as first-class combined durable work, producing both the Markdown analysis artifact and requested structured output artifacts. + * Queues planner-approved combined tabular Analyze work before foreground tabular tools run, preventing empty inline tool output from becoming a stream-level 500. + * Carries the selected model endpoint context into background generated-output runs so non-default endpoints do not fall back to an Azure OpenAI deployment name lookup. + * (Ref: [#1233](https://github.com/microsoft/simplechat/issues/1233), `functions_tabular_orchestration.py`, `functions_workflow_runner.py`, Analyze deliverable contract, combined durable generated output) + +* **Data Management Scheduler Context Guard** + * Prevented the background Data Management scheduler from using request-context-copying executor APIs when no Flask request context exists. + * Scheduler-submitted jobs now use the existing worker-thread path outside request handling, while route-triggered submissions can still use the configured executor. + * (Ref: `functions_data_management.py`, Data Management scheduler, background job submission) + +##### **(v0.250.182)** + +###### Bug Fixes + +* **Analyze Artifact Copilot Review Cleanup** + * Preserved explicit request order for combined JSON/XML artifact requests when both formats share the same action phrase. + * Kept explicit unchanged-copy requests eligible even when source field names include descriptive terms such as risk or status. + * Made semantic validation shadow mode fail open on verifier errors and prevented the chat UI from falling back to withheld legacy artifacts when `generated_artifacts` is explicitly empty. + * (Ref: PR [#1238](https://github.com/microsoft/simplechat/pull/1238), Copilot review comments, generated artifact ordering, semantic validation shadow mode, plural artifact UI) + +##### **(v0.250.181)** + +###### Bug Fixes + +* **Analyze Artifact Advanced Security Cleanup** + * Replaced a self-comparison float finite check in the tabular transformation validator with an explicit finite-number check. + * Simplified an unnecessary callable wrapper in the Phase 7B production-correctness functional test harness. + * (Ref: PR [#1238](https://github.com/microsoft/simplechat/pull/1238), GitHub Advanced Security comments, tabular transformation validation) + +##### **(v0.250.180)** + +###### Bug Fixes + +* **Analyze Artifact Output Contract Closure** + * Made Analyze generated-output delivery Markdown-first and contract-faithful across durable tabular execution by adding reviewed transformation planning, deterministic server-side rules, bounded semantic verification and repair, and exact Search/Analyze 200-row parity validation. + * Hardened artifact-set publication so new staged generated artifacts are not downloadable or promotable until the completed run manifest commits every required member, while preserving legacy generated artifact compatibility. + * Restored explicit Word/DOCX current-turn function-result serialization and repaired cumulative lifecycle, scale, route, and UI validation harnesses through 30,000-row bounded finalization and 100,000-row deterministic planning/hardening contracts. + * (Ref: [#1233](https://github.com/microsoft/simplechat/issues/1233), PR [#1234](https://github.com/microsoft/simplechat/pull/1234), PR [#1235](https://github.com/microsoft/simplechat/pull/1235), PR [#1236](https://github.com/microsoft/simplechat/pull/1236), Analyze deliverable contract, tabular transformation contract, artifact-set publication lifecycle) + +##### **(v0.250.170)** + +###### Bug Fixes + +* **Rendered Admin Tabular Run Controls Coverage** + * Replaced source-only coverage with an authenticated browser regression that verifies the Admin Settings controls render, submit, survive reload, and restore their original values. + * Guarded shared settings mutation behind an explicit isolated-environment opt-in and limited configured-model testing to routable legacy direct or APIM deployments. + * (Ref: [#1201](https://github.com/microsoft/simplechat/issues/1201), `ui_tests/test_admin_tabular_run_controls.py`, Admin Settings tabular run controls) + +##### **(v0.250.169)** + +###### Bug Fixes + +* **Large Tabular Run Confirmation Deduplication** + * Prevented repeated Send clicks or Enter presses from opening concurrent confirmation waiters and starting the same expensive tabular run more than once. + * Restored normal sending after the user continues, narrows scope, dismisses the dialog, or an unexpected confirmation error occurs. + * (Ref: Fixes [#1200](https://github.com/microsoft/simplechat/issues/1200), `chat-messages.js`, `test_chat_background_generated_export_status.py`) + +##### **(v0.250.168)** + +###### Bug Fixes + +* **Tabular Execution Settings Sanitization** + * Prevented normal user-facing settings responses from exposing admin-only hierarchical-analysis, chunk-model deployment, and model-validation retry controls. + * Preserved the durable-run confirmation settings required by chat so users continue to receive prompts before very large tabular runs. + * (Ref: [#1199](https://github.com/microsoft/simplechat/issues/1199), `sanitize_settings_for_user()`, `TABULAR_GENERATION_BACKEND_SETTING_KEYS`) + +##### **(v0.250.167)** + +###### Bug Fixes + +* **Tabular Parity Rollout and Lifecycle Hardening** + * Enforced parity canary assignment before durable execution and included authorized source versions in request and unit fingerprints. + * Preserved failed and canceled durable outputs as terminal incomplete evidence, including all-canceled per-document Analyze results, and corrected Analyze parity telemetry classification. + * Renamed incomplete multi-file and deferred-composition controls as planning-only and exposed that durable fan-out and automatic continuation are unavailable without changing working single-source or per-document behavior. + * (Ref: PR [#1219](https://github.com/microsoft/simplechat/pull/1219), [#1031](https://github.com/microsoft/simplechat/issues/1031), [#1055](https://github.com/microsoft/simplechat/issues/1055), [#1058](https://github.com/microsoft/simplechat/issues/1058), `functions_tabular_orchestration.py`, `functions_workflow_runner.py`, `route_backend_chats.py`) + +##### **(v0.250.166)** + +###### New Features + +* **Tabular Analyze/Search Durable Preflight Parity** + * Unified exhaustive tabular Search and Analyze requests behind a shared route-neutral planner that can queue durable work before bounded foreground tools or immediate synthesis run. + * Preserved truthful pending, failed, canceled, and completed evidence across pure tabular, mixed-source, per-document, and multi-table workflows, including deferred mixed-source composition and public lifecycle coverage. + * Added backend-only shadow and canary controls, privacy-safe telemetry and status metadata, and evidence-backed legacy fallback retirement while reusing existing authorization, source-version, rollback, and artifact-card contracts. + * (Ref: [#1031](https://github.com/microsoft/simplechat/issues/1031), [#1055](https://github.com/microsoft/simplechat/issues/1055), [#1058](https://github.com/microsoft/simplechat/issues/1058), `functions_tabular_orchestration.py`, `functions_workflow_runner.py`, `route_backend_chats.py`) + +##### **(v0.250.160)** + +###### Bug Fixes + +* **getAToken Missing Authorization Code Redirect** + * Redirects direct `/getAToken` browser visits without an OAuth authorization code back to the home sign-in page instead of showing a technical callback error. + * Preserves the normal Microsoft Entra authorization-code callback flow and keeps `/getATokenApi` explicit error behavior unchanged for API token callbacks. + * (Ref: `/getAToken` OAuth callback, `route_frontend_authentication.py`, `test_getatoken_missing_code_redirect.py`) + +##### **(v0.250.159)** + +###### New Features + +* **Chat Used Documents Pane** + * Added a Used Documents mode to the existing chat conversation side pane so users can review documents that were actually cited in the conversation without opening the full details modal. + * Reuses the same conversation metadata document tags as the details modal, excludes selected-but-unused documents, and auto-opens once when cited documents first appear. + * (Ref: [#1209](https://github.com/microsoft/simplechat/issues/1209), conversation contents drawer, cited document metadata, `chat-conversation-contents.js`, `chat-conversation-details.js`) + +##### **(v0.250.157)** + +###### Bug Fixes + +* **Prior Grounded Source Continuity** + * Follow-up mixed-source turns can now detect references such as "that XML file," "same template," or "previous spreadsheet" and merge reauthorized prior grounded sources with the current selected sources. + * Preserved authorization boundaries by deriving prior sources from `last_grounded_document_refs` and revalidating scope before use. + * (Ref: [#1204](https://github.com/microsoft/simplechat/issues/1204), mixed-source source continuity, `route_backend_chats.py`, `test_chat_history_grounded_follow_up_fix.py`) + +##### **(v0.250.156)** + +###### Bug Fixes + +* **JSON/XML Source-Only Intent Guardrails** + * Prevented source-reading prompts such as "Summarize this XML document" and "Validate this JSON object" from being misclassified as generated artifact requests. + * Kept explicit output requests such as "Export as JSON" and "Create an XML file" routed to generated artifact workflows. + * (Ref: [#1198](https://github.com/microsoft/simplechat/issues/1198), structured artifact intent detection, `functions_generated_file_exports.py`, `test_generated_json_xml_exports.py`) + +##### **(v0.250.155)** + +###### Bug Fixes + +* **Tabular Contains Replay Semantics** + * Aligned foreground `filter_rows contains` matching with durable CSV replay by using literal, case-insensitive containment in both paths. + * Added regression coverage for regex-shaped values such as `A.*` so previews and generated export replays select the same row cohort. + * (Ref: [#1197](https://github.com/microsoft/simplechat/issues/1197), tabular durable replay descriptors, `tabular_processing_plugin.py`, `test_tabular_large_result_pagination.py`) + +##### **(v0.250.129)** + +###### New Features + +* **Configurable Workflow Task Limit** + * Added an admin setting that controls how many ordered instruction tasks users can add to a workflow. + * The default is 50 tasks, with backend and browser enforcement clamped to a supported range of 1-100 tasks. + * (Ref: workflow task sequences, Admin Settings Workflow section, `functions_personal_workflows.py`, `workspace_workflows.js`) + +##### **(v0.250.128)** + +###### Bug Fixes + +* **Outbound MCP Tool Argument Normalization** + * Fixed outbound MCP tool calls that could wrap parameters inside a `kwargs` object, preventing standards-compliant MCP servers from seeing required top-level fields such as `type`. + * Added schema-aware normalization before MCP argument validation and invocation while preserving tools that explicitly define a real top-level `kwargs` property. + * (Ref: [#1163](https://github.com/microsoft/simplechat/issues/1163), MCP `tools/call` arguments, `functions_mcp_operations.py`, `mcp_plugin.py`, `mcp_plugin_factory.py`) + +##### **(v0.250.127)** + +###### Bug Fixes + +* **Replayable Exhaustive Tabular Exports** + * Generalized version-pinned CSV source descriptors so exhaustive `filter_rows` and `search_rows` requests can replay the complete authorized cohort through the existing durable export runner instead of failing on bounded preview gaps. + * Added exhaustive per-row request routing for natural phrases such as "for each row," "every row," and "one row per," while preserving direct deterministic aggregation behavior. + * Non-replayable semantics such as normalized entity matching now fail closed with an explicit reason and never publish a partial CSV. + * (Ref: [#1031](https://github.com/microsoft/simplechat/issues/1031), tabular source descriptors, durable generated exports, `functions_tabular_csv_query.py`, `tabular_processing_plugin.py`, `route_backend_chats.py`) + +##### **(v0.250.126)** + +###### Bug Fixes + +* **Enhanced Citations Startup Storage Degradation** + * Prevented Enhanced Citations storage connectivity problems from blocking application startup when Cosmos DB is otherwise available. + * Deferred live storage container checks to upload/admin-test paths and added Admin Settings diagnostics for explicit storage validation. + * (Ref: [#1155](https://github.com/microsoft/simplechat/issues/1155), PR [#1161](https://github.com/microsoft/simplechat/pull/1161), Enhanced Citations storage startup, `config.py`, `functions_documents.py`, Admin Settings) + +* **Functional Test Version Assertion Resilience** + * Added shared functional-test version helpers so tests can assert the app version is at least the feature implementation version instead of exactly equal to an older release. + * Migrated brittle exact `config.py` version checks and added a guardrail test to prevent reintroducing exact app-version assertions. + * (Ref: functional test version helpers, `test_support/versioning.py`, `test_app_version_assertion_guardrails.py`) + +##### **(v0.250.125)** + +###### Bug Fixes + +* **Logging Tag Standardization** + * Standardized Python logging prefixes to `[UPPERCASE_WITH_UNDERSCORES]` so Application Insights, debug logs, and operational searches use consistent tag names. + * Added a logging tag reference inventory and functional coverage to keep future logging tags normalized and documented. + * (Ref: logging tag inventory, `docs/reference/logging-tags.md`, `test_logging_tag_standardization.py`) + +##### **(v0.250.124)** + +###### Bug Fixes + +* **Key Vault Reminder PR Security Hardening** + * Replaced raw exception text returned from plugin/action Key Vault save paths with stable user-safe messages while preserving server-side logging for diagnostics. + * Renamed the external Key Vault reminder telemetry event to avoid security scanner false positives on secret-related terminology while keeping queryable Application Insights dimensions. + * (Ref: [#1156](https://github.com/microsoft/simplechat/issues/1156), PR [#1157](https://github.com/microsoft/simplechat/pull/1157), `route_backend_plugins.py`, `functions_appinsights.py`, CodeQL findings) + +##### **(v0.250.123)** + +###### New Features + +* **Key Vault Reminder Contact Email Telemetry Opt-In** + * Added a default-off admin setting that allows Key Vault reminder contact email addresses to be included in the external Application Insights telemetry event for direct Azure Monitor, Logic App, Function, or webhook routing. + * Kept raw secret names redacted from external telemetry and added Reminder ID visibility/search in the admin inventory for fixed admin-channel alert workflows. + * (Ref: [#1156](https://github.com/microsoft/simplechat/issues/1156), `functions_appinsights.py`, `functions_keyvault_reminders.py`, Admin Key Vault reminder external alert guidance) + +##### **(v0.250.122)** + +###### New Features + +* **Key Vault Reminder External Telemetry** + * Added a privacy-safe, queryable Application Insights event when Key Vault expiration reminder notifications are created, enabling Azure Monitor scheduled query alerts, action groups, Logic Apps, Functions, or webhooks for external notification workflows. + * Added admin and feature documentation guidance with a sample KQL query while avoiding raw secret names and email values in telemetry dimensions. + * (Ref: [#1156](https://github.com/microsoft/simplechat/issues/1156), `functions_appinsights.py`, `functions_keyvault_reminders.py`, Azure Monitor external notification guidance) + +##### **(v0.250.121)** + +###### New Features + +* **Key Vault Expiration Reminder Inventory** + * Added SimpleChat-managed Key Vault secret expiration reminder tracking with per-action reminder metadata, expiration dates, lead days, reminder contact email, friendly labels, and rotation notes. + * Added an admin Key Vault reminder dashboard that maps generated Key Vault secret names back to SimpleChat scope, source action, field, owner/contact context, sync status, and remediation details. + * Added a background reminder sweep and `key_vault_secret_expiring` in-app notifications while preserving Azure Monitor/Event Grid as the recommended email alert path. + * (Ref: [#1156](https://github.com/microsoft/simplechat/issues/1156), `functions_keyvault_reminders.py`, `admin_settings.html`, `plugin_modal_stepper.js`, Key Vault reminder inventory) + +###### Bug Fixes + +* **Reliable Key Vault Secret Rotation** + * Fixed action secret save behavior so replacing a Key Vault-backed secret with a new literal value writes a new Key Vault version for global, group, and personal actions. + * `Stored_In_KeyVault` placeholders now only preserve validated existing references; placeholder-only saves without an existing secret are rejected instead of creating dead references. + * Key Vault write failures now surface as errors instead of falling back to raw secret persistence. + * (Ref: [#1156](https://github.com/microsoft/simplechat/issues/1156), `functions_keyvault.py`, action save helpers, Key Vault secret reference validation) + +##### **(v0.250.119)** + +###### Bug Fixes + +* **Duplicate Chat Stream JSON Import Cleanup** + * Removed the redundant local `json` import from the chat streaming route while keeping the existing module-level import, clearing the PR #1145 CodeQL duplicate-module-import notice without changing streaming behavior. + * Updated the PR 1145 remediation plan with the implementation version and validation results. + * (Ref: [#1145](https://github.com/microsoft/simplechat/pull/1145), `route_backend_chats.py`, CodeQL alert 30) + +##### **(v0.250.118)** + +###### Bug Fixes + +* **Semantic Kernel Return Contract Cleanup** + * Made the nested chat Semantic Kernel invocation helper return `None` explicitly when an async generator completes without yielding, clearing the PR #1145 CodeQL mixed explicit/implicit return alert without changing runtime behavior. + * Added focused functional coverage for direct values, coroutine results, yielded async-generator values, and empty async generators. + * (Ref: [#1145](https://github.com/microsoft/simplechat/pull/1145), `route_backend_chats.py`, `test_chat_semantic_kernel_return_contract.py`) + +##### **(v0.250.115)** + +###### Bug Fixes + +* **Token Usage Aggregation Fixture Cleanup** + * Removed duplicate mocked helper keys from the document action token usage aggregation functional test so the fixture intent is explicit and CodeQL no longer reports overwritten dictionary entries. + * Kept comparison coverage focused on cross-format compare behavior while preserving aggregate token usage assertions for analysis, comparison, workflow assistant persistence, and chat persistence markers. + * (Ref: [#1145](https://github.com/microsoft/simplechat/pull/1145), `test_document_action_token_usage_aggregation.py`, token usage aggregation fixtures) + +##### **(v0.250.114)** + +###### Bug Fixes + +* **Foundry Citation Thought Detail Cleanup** + * Fixed a CodeQL finding where Foundry citation thoughts iterated citations without using the citation value, causing duplicate generic thought messages. + * Foundry citation thoughts now include safe citation-specific labels when available while avoiding raw payloads, URL query strings, userinfo, and long unbounded text. + * (Ref: [#1145](https://github.com/microsoft/simplechat/pull/1145), `route_backend_chats.py`, `test_foundry_citation_thoughts.py`) + +##### **(v0.250.114)** + +###### New Features + +* **Generated JSON and XML Export Artifacts** + * JSON and XML generation requests can now save valid generated output as downloadable chat artifacts instead of leaving large file-shaped content in the assistant response. + * Document Analyze and generated export flows now recognize natural JSON/XML conversion and XML template-population phrasing, with XML serialization support added to durable generated exports. + * XML document processing now uses a consolidated token-aware pipeline for more reliable analysis and export workflows. + * (Ref: [#1071](https://github.com/microsoft/simplechat/issues/1071), `functions_generated_file_exports.py`, generated analysis artifacts, XML document processing) + +##### **(v0.250.112)** + +###### New Features + +* **Model Capability Catalog** + * Added an initial JSON source of truth for model feature capabilities across OpenAI GPT-5+, recent Claude models, Meta Llama and Code Llama, xAI Grok, and Microsoft Phi/MAI models. + * Catalog entries track support for text, image, audio, video, binary/file input, coding optimization, tool calling, and structured output so future multimodal routing can move away from regex-only model-name checks. + * This release is data-only and does not change backend or frontend runtime behavior. + * (Ref: Closes [#1147](https://github.com/microsoft/simplechat/issues/1147), `model_capabilities.json`, model capability detection) + +##### **(v0.250.111)** + +###### Bug Fixes + +* **Data Management Restore Route Registration** + * Fixed application startup failure caused by duplicate Data Management restore review route and endpoint registrations. + * Preserved the authorization-aware restore review workflow and added regression coverage requiring unique Blueprint endpoint names. + * (Ref: `route_backend_data_management.py`, `test_data_management_security_patterns.py`, `DATA_MANAGEMENT_RESTORE_ROUTE_ENDPOINT_COLLISION_FIX.md`) + +##### **(v0.250.110)** + +###### New Features + +* **Configurable Public Workspace Display Name** + * Admins can now set an optional end-user display name for Public Workspace, capped at 32 characters, so organizations can present tenant-specific terms such as "Domain Knowledge". + * End users see the configured label across navigation, Profile, Public Directory, Public Workspace pages, chat scope selection, and related browser messages while admin settings and internal identifiers continue to use Public Workspace/public_workspace. + * Empty or unset values preserve the existing Public Workspace/Public Workspaces defaults. + * (Ref: [#1146](https://github.com/microsoft/simplechat/issues/1146), `functions_settings.py`, `admin_settings.html`, public workspace templates and JavaScript, `PUBLIC_WORKSPACE_DISPLAY_NAME.md`) + +##### **(v0.250.109)** + +###### New Features + +* **Per-Model Response Length Overrides** + * Administrators can now set an optional response-length/output-token ceiling on each model in global multi-endpoint GPT configuration. + * Standard chat applies the selected model's configured ceiling with the correct backend token parameter for GPT-5/o-series aliases and other OpenAI-compatible chat models. + * Existing endpoint model records remain compatible when the field is blank or absent. + * (Ref: Closes [#1143](https://github.com/microsoft/simplechat/issues/1143), related [#1047](https://github.com/microsoft/simplechat/issues/1047) and [#358](https://github.com/microsoft/simplechat/issues/358), `functions_settings.py`, `route_backend_chats.py`, `admin_model_endpoints.js`) + +##### **(v0.250.108)** + +###### User Interface Enhancements + +* **Backup, Migrate & Restore Admin Refresh** + * Reworked the Admin Settings data-management tab into a clearer Backup, Migrate & Restore control center with start-here guidance, setup modals, and plain-language migration choices. + * Separated destination Cosmos **RU Boost** configuration and testing from Cosmos data-copy access validation so admins can verify the correct Azure management-plane permissions before migration. + * Aligned the refresh with the restore workflow from Backup Inventory so admins can review backup readiness, choose restore policy/surfaces, run preflight, and queue supported restore jobs. + * (Ref: [#1140](https://github.com/microsoft/simplechat/issues/1140), `admin_settings.html`, `admin_data_management.js`, `functions_data_management.py`, Data Management docs and tests) + +##### **(v0.250.107)** + +###### Bug Fixes + +* **Mixed Source Manifest Storage Locator Preservation** + * Preserved explicit blob storage locators for authorized non-chat mixed-source manifest entries when archived-revision document metadata already contains a resolved container and blob path. + * Updated focused mixed-source Analyze and conversation-continuity tests for the current rollout/version contract. + * (Ref: [#1055](https://github.com/microsoft/simplechat/issues/1055), [#1056](https://github.com/microsoft/simplechat/issues/1056), mixed-source manifests, `functions_mixed_source_orchestration.py`, `test_mixed_source_manifest_contracts.py`) + +##### **(v0.250.106)** + +###### New Features + +* **Backup Cleanup and Retention Policy Controls** + * Added Data Management backup cleanup controls so administrators can manually delete backup artifacts and metadata from Backup Inventory. + * Added unit-based backup retention settings for days, weeks, months, and years, with automatic cleanup that preserves the newest successful full backup as a restore safety baseline. + * Cleanup removes stored backup blobs, job timeline records, and differential sidecar state so future partial backups re-export affected unchanged items instead of pointing to deleted artifacts. + * (Ref: Closes [#1130](https://github.com/microsoft/simplechat/issues/1130), `functions_data_management.py`, `route_backend_data_management.py`, `admin_settings.html`, `admin_data_management.js`) + +* **Multi-Select Metadata Extraction** + * Personal, group, and public workspace document multi-select bars now include an **Extract Metadata** action when metadata extraction is enabled. + * Selected documents are queued through the shared metadata extraction background workflow, preserving generated titles along with authors, abstracts, keywords, publication dates, and organization metadata. + * (Ref: Closes [#1134](https://github.com/microsoft/simplechat/issues/1134), `route_backend_documents.py`, `route_backend_group_documents.py`, `route_backend_public_documents.py`, workspace document multi-select actions) + +* **Data Management Backup Restore Workflow** + * Added an admin-only restore workflow for completed Data Management backups, with manifest preflight, create-only default policy, explicit overwrite confirmation, durable restore jobs, cancellation/retry support, and sanitized progress in Job History. + * Restore supports configured target Cosmos DB, AI Search, and Enhanced Citation blob targets while preserving secret-safe review and job responses. + * (Ref: Closes [#1091](https://github.com/microsoft/simplechat/issues/1091), `functions_data_management.py`, `functions_data_management_restore_state.py`, `route_backend_data_management.py`, `admin_settings.html`, `admin_data_management.js`, `DATA_MANAGEMENT_RESTORE.md`) + +###### Bug Fixes + +* **Retry and Edit Streaming Parity** + * Retry and edit chat flows now use the same full SSE streaming path as first-send chat, restoring live token updates, streamed thoughts, stop controls, and recovery behavior. + * The stream path reuses the retry/edit user message and thread metadata created by the preparation endpoints, preserving carousel attempt history without duplicating user messages. + * (Ref: Fixes [#963](https://github.com/microsoft/simplechat/issues/963), `route_backend_chats.py`, `chat-retry.js`, `chat-edit.js`, `test_chat_retry_edit_streaming_parity.py`) + +###### User Interface Enhancements + +* **Custom Pages Admin Open Action** + * Added an Open action to the Admin Settings Custom Pages table so administrators can launch enabled static or Python-backed custom pages directly from their metadata row. + * The action opens encoded `/custom/` URLs in a new tab while preserving existing Custom Pages route authorization, enabled-state checks, access-level rules, role restrictions, and `.html` alias compatibility. + * Disabled or unavailable pages now show a disabled Open action with explanatory tooltip copy instead of silently omitting the action. + * (Ref: Closes [#951](https://github.com/microsoft/simplechat/issues/951), PR [#1131](https://github.com/microsoft/simplechat/pull/1131), `admin_custom_pages.js`, `CUSTOM_PAGES.md`) + +##### **(v0.250.105)** + +###### User Interface Enhancements + +* **Reviewed, Scalable Data Migration Workflow** + * Replaced the Admin Data Management migration form with a six-stage Target, Scope, Content & Options, Review, Confirm, and Progress workflow. + * Added server-paginated principal catalogs, exhaustive all-mode counts, persistent cross-page selections, sanitized preflight checks, single-use administrator-bound review authorization, settings-drift protection, separate destructive confirmation, duplicate-submit prevention, and inline durable job recovery controls. + * (Ref: Closes [#1097](https://github.com/microsoft/simplechat/issues/1097), `functions_data_management.py`, `route_backend_data_management.py`, `admin_settings.html`, `admin_data_management.js`) + +##### **(v0.250.103)** + +###### New Features + +* **Configurable AI Response Completion Audio Cues** + * Administrators can enable locally bundled completion sounds, while each user can opt in, choose and preview one of ten cues, set volume, or mute cues without losing their preferences. + * Cues play once for newly completed personal-chat responses outside the active visible conversation, with server-authoritative gating, cross-tab preference synchronization, and historical/duplicate suppression. + * (Ref: Closes [#1062](https://github.com/microsoft/simplechat/issues/1062), `completion-audio-cues.js`, notification polling, Profile and Admin Settings, `AI_RESPONSE_COMPLETION_AUDIO_CUES.md`) + +###### Bug Fixes + +* **Retention Coverage Across Group and Collaborative Conversations** + * Group-scoped private conversations now follow their primary group's retention policy instead of the creator's personal policy. + * Personal and group collaborative conversations now use their correct governing policy and activity timestamp, while linked conversion sources are cleaned once without duplicate counting. + * Collaboration cleanup now covers messages, per-user state, linked sources, blob-backed files, thoughts, activity logs, and conversation caches; new groups also persist explicit default retention values. + * (Ref: Closes [#1054](https://github.com/microsoft/simplechat/issues/1054), `functions_retention_policy.py`, `functions_collaboration.py`, `functions_group.py`, `RETENTION_POLICY_CONVERSATION_SCOPE_COVERAGE_FIX.md`) + +* **Custom Databricks-Prefixed Action Discovery** + * Fixed action type discovery so custom plugin types such as `databricks_table_dscmo` no longer inherit the built-in Databricks discovery defaults. + * Custom Databricks-prefixed plugin types now stay on the standard plugin configuration path and visual treatment unless their type is exactly `databricks` or `databricks_table`. + * Added a regression test that scaffolds a temporary fake custom Databricks-prefixed plugin, schema, and definition file to validate discovery and settings merge behavior. + * (Ref: [#1124](https://github.com/microsoft/simplechat/issues/1124), `functions_databricks_operations.py`, `route_backend_plugins.py`, `view-utils.js`, `test_plugin_type_discovery_custom_databricks.py`) + +##### **(v0.250.102)** + +###### New Features + +* **High-Throughput Resumable Source Blob Backups** + * Source document backups now stream bounded Azure SDK blocks with configurable file concurrency and chunk size instead of buffering complete blobs or copying files serially. + * Added durable per-file verification and resume, source/target generation fencing, adaptive Retry-After-aware throttling, isolated file failures, authenticated chunked encryption, throughput telemetry, and a reproducible AzCopy/server-copy/SDK benchmark harness. + * (Ref: Closes [#1095](https://github.com/microsoft/simplechat/issues/1095), `functions_data_management.py`, `test_data_management_blob_backup_transfers.py`, `benchmark_data_management_blob_backup.py`, `DATA_MANAGEMENT_BLOB_BACKUP_THROUGHPUT.md`) + +* **Desktop Conversation Notifications** + * Administrators can enable operating system notifications for completed AI responses, and users can manage their own preference from Profile. + * Notifications appear only while SimpleChat is open in a hidden or unfocused tab, show the application and conversation titles without response content, and focus the existing tab when selected. + * (Ref: Fixes [#866](https://github.com/microsoft/simplechat/issues/866), `chat-desktop-notifications.js`, `chat-streaming.js`, Profile and Admin Settings) + +* **Automatic Overnight Control Center Statistics Refresh** + * Added an enabled-by-default daily Control Center metrics refresh at 2:00 AM Eastern, with an administrator toggle and configurable time under Admin Settings > Control Center. + * The recurring schedule follows Eastern daylight-saving changes, stores concrete execution timestamps in UTC, and shows last-run and next-run values in each administrator's browser timezone. + * (Ref: Closes [#706](https://github.com/microsoft/simplechat/issues/706), `functions_control_center.py`, `background_tasks.py`, `admin_settings.html`, `control-center.js`) + +* **Configurable Chat AI Notice** + * Administrators can display custom plain-text AI guidance directly below the chat composer. + * Supports non-dismissible, per-session, daily, and once-per-message-version behavior with validated dismissal persistence and automatic redisplay when the configured notice changes. + * (Ref: [#715](https://github.com/microsoft/simplechat/issues/715), `functions_ai_notice.py`, `admin_settings.html`, `chats.html`, `chat-ai-notice.js`) + +* **Per-Message Audio Export** + * Users can export completed user and assistant chat messages as MP3 audio when text-to-speech is enabled. + * Downloads reuse the active Azure Speech voice and speed, include only visible message text, and remain transient without storing generated audio in SimpleChat. + * (Ref: [#628](https://github.com/microsoft/simplechat/issues/628), `chat-tts.js`, `chat-message-export.js`, `chat-messages.js`, `MESSAGE_AUDIO_EXPORT.md`) + +###### User Interface Enhancements + +* **External Link Ordering Controls** + * Admins can now move saved external links up or down and save the resulting navigation order without deleting and recreating links. + * The first and last links expose disabled boundary controls, and the visible order stays synchronized with the Admin Settings save payload. + * (Ref: Closes [#793](https://github.com/microsoft/simplechat/issues/793), `admin_settings.js`, `test_admin_external_link_ordering.py`, `EXTERNAL_LINK_ORDERING_FIX.md`) + +* **Application-Wide Non-Blocking Toast Notifications** + * Replaced native browser alerts across admin, group, public, personal workspace, profile, feedback, safety, and control-center workflows with consistent Bootstrap toast notifications. + * Added a shared, accessible toast utility that safely renders dynamic messages as text and preserves specialized chat toast positioning. + * (Ref: Closes [#739](https://github.com/microsoft/simplechat/issues/739), `toast.js`, `chat-toast.js`, first-party templates and workspace scripts) + +##### **(v0.250.101)** + +###### New Features + +* **Adaptive Exhaustive Azure AI Search Backups** + * Azure AI Search backups now export personal, group, and public indexes through deterministic keyset-paged artifacts with durable checkpoints, exact resume behavior, schema validation, and restore-readiness integrity status. + * Added fair bounded concurrency, Retry-After-aware handling for throttling and service interruptions, adaptive pressure reduction and recovery, and sanitized per-index throughput and failure metrics. + * (Ref: Closes [#1094](https://github.com/microsoft/simplechat/issues/1094), `functions_data_management.py`, `test_data_management_ai_search_backup_export.py`, `DATA_MANAGEMENT_BACKUP_MIGRATION.md`) + +* **Conversation Context Grounding** + * Models and agents now receive bounded, credential-sanitized metadata for every user turn, including the active model, SimpleChat version, workspace scope, selected documents, agent, and capability state. + * Each assistant response exposes the identical snapshot as a visible Conversation Context citation across streaming, non-streaming, retry, fallback, collaboration, and document-action paths. + * (Ref: [#508](https://github.com/microsoft/simplechat/issues/508), `functions_conversation_context.py`, `route_backend_chats.py`, `functions_workflow_runner.py`) + +###### Bug Fixes + +* **Conversation Fork Workspace Context and HTTP 500 Fix** + * Fixed conversation forks returning HTTP 500 when an owned single-user conversation used group or public workspace knowledge. + * Forking now revalidates current workspace access, preserves the authorized context and chat type, and returns controlled conflicts when access is stale or unavailable. + * Corrected fork-specific structured logging so validation, conflict, cleanup, and cache errors retain their intended response behavior. + * (Ref: [#1025](https://github.com/microsoft/simplechat/issues/1025), `functions_simplechat_operations.py`, `route_backend_conversations.py`, `chat-messages.js`, `CONVERSATION_FORK_HTTP_500_FIX.md`) + +* **Application-Wide Log Event Contract Guard** + * Fixed conversation fork conflict and recovery logging that used unsupported metadata keywords, preventing logger errors from replacing intended HTTP responses such as eligibility conflicts with HTTP 500. + * Standardized structured metadata on `extra=` and added an application-wide call-signature check plus route regression coverage for the HTTP 409 conflict path. + * (Ref: [#1112](https://github.com/microsoft/simplechat/issues/1112), `functions_simplechat_operations.py`, `route_backend_conversations.py`, `test_log_event_call_contract.py`) + +##### **(v0.250.100)** + +###### Bug Fixes + +* **MCP PR CodeQL Cleanup** + * Resolved CodeQL findings from the MCP pull request by replacing exception text returned to clients with stable public messages, tightening inbound MCP correlation IDs, and removing raw query text from search/cache logs. + * Cleaned up MCP catalog imports, test stubs, and JavaScript defaults that produced CodeQL note-level findings. + * (Ref: [#1013](https://github.com/microsoft/simplechat/issues/1013), CodeQL scan, MCP PR readiness, `functions_appinsights.py`, `route_inbound_mcp.py`, `route_backend_plugins.py`) + +##### **(v0.250.098)** + +###### New Features + +* **MCP Current-State Platform** + * Added the governed inbound SimpleChat MCP server with a bounded personal tool surface for conversations, documents, prompts, tags, workflow discovery, and workflow execution. + * Hardened outbound MCP actions with presets, server-side preconfiguration catalogs, destination governance, custom headers, result policy controls, and redaction-safe discovery/runtime telemetry. + * (Ref: [#1013](https://github.com/microsoft/simplechat/issues/1013), [#1014](https://github.com/microsoft/simplechat/issues/1014), [#1015](https://github.com/microsoft/simplechat/issues/1015), [#1017](https://github.com/microsoft/simplechat/issues/1017), [#1018](https://github.com/microsoft/simplechat/issues/1018), MCP current-state roadmap) + +###### User Interface Enhancements + +* **MCP Admin And Observability Surfaces** + * Added Admin Settings controls for inbound MCP runtime settings, source governance guidance, Easy Auth setup verification, request-size and throttle tuning, tool registry visibility, and copyable Application Insights starter queries. + * Added Governance controls for outbound MCP destination policies and inbound MCP source policies using the current source-first access model. + * (Ref: [#1020](https://github.com/microsoft/simplechat/issues/1020), MCP governance/admin UX, `admin_settings.html`, `admin_settings.js`, `admin_governance.js`) + +###### Bug Fixes + +* **MCP Enterprise Hardening** + * Added inbound MCP request correlation, bounded payloads, Cosmos-backed tool throttles, clear JSON-RPC tool error transport, and OAuth/PRM discovery compatibility for MCP clients. + * Added outbound MCP discovery/factory telemetry with safe destination metadata and redaction to make connector failures easier to diagnose. + * (Ref: [#1015](https://github.com/microsoft/simplechat/issues/1015), [#1017](https://github.com/microsoft/simplechat/issues/1017), [#1020](https://github.com/microsoft/simplechat/issues/1020), MCP observability and enterprise readiness) + +##### **(v0.250.076)** + +###### New Features + +* **Bounded Parallel Cosmos Backup Export and Source Capacity Recovery** + * Cosmos backup export now streams deterministic JSONL checkpoint batches through configurable bounded concurrency, preserving durable fencing, latest-item state, cancellation, retry/resume, and recovery semantics without materializing complete containers in memory. + * Added bounded `408`, `429`, `449`, and `5xx` retry with Retry-After-aware jittered backoff, adaptive staging pressure, sanitized per-container and aggregate RU/rate/retry telemetry, and deterministic no-replay checkpoint outcomes. + * Added opt-in local/source Cosmos throughput boosts capped at 10,000 RU/s with topology discovery, immutable pre-mutation snapshots, fenced restore-pending recovery, safe external-change protection, minimum ARM role support in Terraform, and explicit fail-or-continue policy for unsupported or denied capacity mutations. + * (Ref: Closes [#1093](https://github.com/microsoft/simplechat/issues/1093), `functions_data_management.py`, `admin_data_management.js`, `test_data_management_backup_parallelism.py`, `DATA_MANAGEMENT_BACKUP_MIGRATION.md`) + +##### **(v0.250.075)** + +###### New Features + +* **Admin Feedback and Safety Record Lifecycle** + * Added archive, unarchive, and permanently delete actions to the Feedback Review and Safety Violations admin pages, with active/archived filtering across lists, cards, statistics, pagination, and CSV exports. + * Archived records are hidden from user profile history, destructive deletion requires confirmation, and safety violations with pending remediation approvals cannot be deleted. + * Archive, unarchive, and delete actions create non-sensitive admin activity audit records, while audit persistence failures are surfaced without undoing successful lifecycle changes. + * (Ref: [#991](https://github.com/microsoft/simplechat/issues/991), `functions_review_lifecycle.py`, `route_backend_feedback.py`, `route_backend_safety.py`, `ADMIN_REVIEW_RECORD_LIFECYCLE.md`) + +* **File Processing Log Cleanup** + * Added admin controls to permanently delete file-processing logs older than a chosen number of days, weeks, or fixed 30-day months, or delete every stored log through a separate action. + * Added explicit confirmation, exact and partial deletion counts, admin activity logging, validation, and secured cross-partition Cosmos DB cleanup. + * (Ref: [#398](https://github.com/microsoft/simplechat/issues/398), `functions_logging.py`, `route_frontend_admin_settings.py`, `admin_settings.js`, `FILE_PROCESSING_LOG_CLEANUP.md`) + +##### **(v0.250.074)** + +###### New Features + +* **Conversation Contents Drawer** + * Added an admin-controlled, default-on conversation contents drawer that indexes persisted user messages and lets users jump directly to earlier prompts in long chats. + * Added a default-on user profile preference so each user can hide the drawer while the global admin feature remains enabled. + * (Ref: [#1026](https://github.com/microsoft/simplechat/issues/1026), `chat-conversation-contents.js`, `admin_settings.html`, `profile.html`) + +* **Fork Personal Conversations from Assistant Responses** + * Added a Fork conversation action for persisted assistant messages, creating an independent personal conversation containing the active history through the selected response while leaving the source unchanged. + * Forks remap conversation, message, thread, reply, and artifact identifiers; copy blob-backed attachments to independent paths; reject unauthorized or changed sources; and clean up failed copies before they become visible. + * Added confirmation, duplicate-click prevention, failure feedback, immediate fork navigation, backend regression coverage, and browser workflow coverage. + * (Ref: [#1025](https://github.com/microsoft/simplechat/issues/1025), `functions_simplechat_operations.py`, `route_backend_conversations.py`, `chat-messages.js`, `FORK_CONVERSATION.md`) + +###### User Interface Enhancements + +* **Responsive Long-Chat Navigation** + * Added safe plain-text labels, active-location tracking, keyboard focus management, destination highlighting, and persistent desktop or off-canvas mobile layouts. + * (Ref: [#1026](https://github.com/microsoft/simplechat/issues/1026), `chats.html`, `chats.css`, `test_chat_conversation_contents_drawer.py`) + +##### **(v0.250.073)** + +###### New Features + +* **User Font Size Preferences** + * Added persisted XS, S, M, L, and XL font-size choices to the user profile, ranging from 75% to 200% with medium as the default. + * Font-size selections preview immediately and apply across SimpleChat after the user saves the preference. + * (Ref: [#1099](https://github.com/microsoft/simplechat/issues/1099), `profile.html`, `functions_settings.py`, `FONT_SIZE_AND_200_PERCENT_ZOOM_FIX.md`) + +* **Durable Data Management Backup Jobs** + * Full and partial backups now persist immutable plans and source cutoffs, fenced attempts, resource/batch checkpoints, and latest-only Cosmos, AI Search, and Blob item state without mutating source records or metadata. + * Added source-scoped overlap protection, authenticated cancellation and focused retry/resume controls, stale/queued worker recovery, bounded sanitized progress, and explicit non-destructive differential/deletion semantics in backup manifests. + * (Ref: Closes [#1092](https://github.com/microsoft/simplechat/issues/1092), `functions_data_management.py`, `functions_data_management_backup_state.py`, `DATA_MANAGEMENT_BACKUP_MIGRATION.md`) + +###### User Interface Enhancements + +* **200% Zoom and Large-Text Layout Support** + * Updated Chat, top navigation, classification banners, and sidebar scrolling to reserve font-relative space and keep messages, navigation, tools, and the composer reachable at 200% browser zoom and large saved font sizes. + * (Ref: [#1099](https://github.com/microsoft/simplechat/issues/1099), `chats.css`, `navigation.css`, `sidebar.css`) + +##### **(v0.250.072)** + +###### Bug Fixes + +* **Selected Public Workspace Prompt Migration** + * Selected public-workspace Data Management migrations now copy current prompts owned through `public_id` while retaining compatibility with legacy `public_workspace_id` records. + * Prompts outside the selected workspaces remain excluded, transitional records migrate once, and copied prompt artifact counts are accurate. All-workspaces migration behavior is unchanged. + * (Ref: [#1033](https://github.com/microsoft/simplechat/issues/1033), `functions_data_management.py`, `test_data_management_public_prompt_migration.py`) + +##### **(v0.250.071)** + +###### New Features + +* **Resilient Data Management Migrations** + * Added durable migration provenance, per-resource checkpoints, bounded concurrent transfers, retry/resume controls, and long-running Cosmos, Search, Blob, inventory, and reconciliation heartbeats. + * Added New only, Delta / upsert, and explicitly confirmed Mirror with deletions modes with durable baseline watermarks, migration-owned update/delete protection, and server-owned live previews. + * Added post-copy Cosmos, AI Search, and Blob reconciliation with cutover readiness, actual outcome totals, and preview-versus-actual divergence reporting. + * Replaced deep AI Search pagination with persisted `id` keyset cursors, including selected-scope filter batching and coverage beyond 100,000 documents. + * Added memory-bounded reconciliation, two-phase mirror deletion with current-source/ETag revalidation, target-side coordination across independent SimpleChat sources, and retryable `not_ready` cutover failures. + * Preserved Blob content settings, metadata, tags, tier, type, and available content verification while adding mid-stream lease heartbeats, cooperative cancellation, source ETag stability, and pending-to-succeeded provenance. + * Added durable privacy-safe per-item outcome batches plus admin JSONL manifest and failure-list downloads. + * Made unresolved temporary Cosmos capacity restoration a retryable terminal state; retry restores the saved snapshot without reapplying the boost. + * Added a durable target AI Search write fence that drains normal SimpleChat indexing before transfer or mirror deletion, bounds Search requests, rejects self-targeting migrations, and requires explicit external-writer freeze acknowledgement before Search writes begin. + * Added target-side coordinator fencing across independent SimpleChat source deployments and retained uncertain target Search write slots through their full quarantine window. Authorization-reducing unshare requests now defer safely while target Search ACL writes are frozen. + * (Ref: [#1043](https://github.com/microsoft/simplechat/issues/1043), `functions_data_management.py`, `functions_migration_provenance.py`, `admin_data_management.js`, `DATA_MANAGEMENT_MIGRATION_RESILIENCE.md`) + +##### **(v0.250.070)** + +###### Bug Fixes + +* **Azure Blob Container SAS Support and Credential Guidance** + * Added support for storage connection strings, full container SAS URLs, and standalone SAS tokens. Pasted SAS URLs derive the canonical account, selected container, and default source name without persisting the token in connection metadata. + * Validates required Read and List permissions, HTTPS-only protocol, account-SAS Blob resource scope, start time, and expiry. Extra permissions and broader account credentials remain usable but produce least-privilege warnings. + * Shows non-secret SAS scope, named permissions, exact expiry, days remaining, stored-policy status, IP restrictions, and warnings in connection tests and source rows. + * Supports saving Blob credentials with or without Azure Key Vault; Key Vault is used when enabled and existing File Sync credential persistence is used otherwise. + * (Ref: [#1027](https://github.com/microsoft/simplechat/issues/1027), `functions_file_sync.py`, `workspace-file-sync.js`, `AZURE_BLOB_CONTAINER_SAS_SUPPORT_FIX.md`) + +##### **(v0.250.068)** + +###### Bug Fixes + +* **Azure Blob File Sync Endpoint and Error Hardening** + * Restricted Azure Blob File Sync URLs and connection strings to validated HTTPS Azure Blob endpoints, blocking arbitrary, internal, development-storage, and credential-bearing endpoint forms before SDK requests are created. + * Replaced raw File Sync route, run-history, activity, and item exception text with fixed client-safe messages while retaining detailed sanitized diagnostics in server logs. + * (Ref: [#1027](https://github.com/microsoft/simplechat/issues/1027), PR [#1088](https://github.com/microsoft/simplechat/pull/1088) security review, `functions_file_sync.py`, `route_backend_file_sync.py`) + +##### **(v0.250.067)** + +###### New Features + +* **Azure Blob Storage File Sync** + * Added Azure Blob Storage as an admin-controlled File Sync source for personal, group, and public workspaces, with account, container, prefix, selected-path, filter, tag, schedule, and remote-delete controls. + * Added managed identity, Key Vault-backed service principal and connection string authentication, connection testing, virtual-folder browsing, ETag change detection, and streamed ingestion through the existing document pipeline. + * (Ref: [#1027](https://github.com/microsoft/simplechat/issues/1027), `functions_file_sync.py`, `workspace-file-sync.js`, `AZURE_BLOB_STORAGE_FILE_SYNC.md`) +##### **(v0.250.066)** + +###### Bug Fixes + +* **GPT 5.6+ Multi-Modal Vision Model Selection** + * Enabled GPT 5.6 Luna, Sol, Terra, and later supported GPT deployments to appear in the Multi-Modal Vision Analysis selector across Azure OpenAI and Foundry endpoints. + * Model detection now evaluates model, display, and deployment names with normalized separators while preserving disabled-model and unsupported-family filtering. + * (Ref: [#1086](https://github.com/microsoft/simplechat/issues/1086), `admin_settings.js`, `test_admin_multimodal_vision_model_options.py`) + +##### **(v0.250.065)** + +###### New Features + +* **Task-Level Workflow Model and Agent Selection** + * Each ordered workflow task can now inherit the workflow's Default Runner or select its own authorized Direct Model or Agent. + * Task runners are normalized on save and revalidated before execution, including current personal/group/global agent scope, group membership, and enabled model endpoint/model availability. + * Unavailable runners follow the workflow's retry and stop-or-continue strategy, while task run items record non-secret runner audit details, execution deployment/provider, output preview, and token usage when available. + * Existing tasks without runner configuration inherit the workflow default, and workflows without task sequences retain the legacy execution path. + * (Ref: [#1084](https://github.com/microsoft/simplechat/issues/1084), `functions_personal_workflows.py`, `functions_group_workflows.py`, `functions_workflow_runner.py`) + +###### User Interface Enhancements + +* **Per-Task Runner Controls** + * Renamed the workflow-level Runner field to Default Runner and added Workflow default, Direct Model, and Agent selection to each task editor. + * Task rows and Review now show the resolved runner, with responsive conditional model/agent controls and text-safe rendering for endpoint, model, and agent labels. + * (Ref: [#1084](https://github.com/microsoft/simplechat/issues/1084), `workspace.html`, `group_workspaces.html`, `workspace_workflows.js`) + +##### **(v0.250.064)** + +###### New Features + +* **Repeatable AI Workflow Task Sequences** + * Personal and group workflows can now run with only instructions and a selected model or agent; workspace documents, File Sync, URL access, schedules, and completion alerts remain optional. + * Workflows support ordered instruction tasks that share the selected runner and receive bounded prior-task output as context. + * Added per-task retries and stop-or-continue error handling, with task outcomes recorded in run history and workflow activity. + * Existing document Search, Analyze, and Compare behavior remains available as optional input for the first task, while existing workflows without task sequences retain their prior execution path. + * (Ref: [#1082](https://github.com/microsoft/simplechat/issues/1082), `functions_personal_workflows.py`, `functions_group_workflows.py`, `functions_workflow_runner.py`) + +###### User Interface Enhancements + +* **Stepped Workflow Builder** + * Replaced the single-pane personal and group workflow form with a five-step General, Trigger, Tasks, Reliability, and Review builder. + * Users can add, edit, remove, and reorder tasks, configure retry and failure behavior, and review runner, trigger, document input, File Sync, and pop-up alert settings before saving. + * (Ref: [#1082](https://github.com/microsoft/simplechat/issues/1082), `workspace.html`, `group_workspaces.html`, `workspace_workflows.js`, `workspace-responsive.css`) + +##### **(v0.250.062)** + +###### Bug Fixes + +* **Cosmos Container Startup Conflict Recovery** + * Fixed a local Docker startup failure where multiple gunicorn workers could race while creating first-run Cosmos containers, causing a `NotFound` followed by a `Conflict` during app import. + * Container initialization now re-reads and returns the existing container when another worker creates it first, preserving normal startup behavior for already-provisioned environments. + * (Ref: `config.py`, `test_cosmos_container_conflict_recovery.py`, `COSMOS_CONTAINER_STARTUP_CONFLICT_FIX.md`) + +###### New Features + +* **Workflow Run Cancellation** + * Personal and group workflows can now be cancelled from workspace rows and cards, run history, or the workflow activity view while a run is active. + * Cancellation is persisted for the active run and cooperatively stops further File Sync, document action, model, agent, artifact, notification, and scheduling work after any in-flight external request returns. + * Cancelled scheduled and File Sync workflows return to an idle state and advance to their next scheduled run instead of immediately restarting. + * (Ref: [#990](https://github.com/microsoft/simplechat/issues/990), `route_backend_workflows.py`, `functions_workflow_runner.py`, `workspace_workflows.js`) + +##### **(v0.250.061)** + +###### New Features + +* **Configurable Content Safety Violation Messages** + * Administrators can now configure the Markdown message shown when Content Safety blocks a chat request using the standard Markdown editor toolbar. + * A new setting controls whether the block reason, detected categories and severities, and blocklist matches are included beneath the custom message. + * The editor now renders correctly when the hidden Safety tab opens, and Markdown-only edits activate Save Settings before submission. + * (Ref: [#989](https://github.com/microsoft/simplechat/issues/989), `functions_content_safety.py`, `admin_settings.html`, `route_backend_chats.py`) + +##### **(v0.250.059)** + +###### New Features + +* **Versioned Latest Features Navigation Hide Preference** + * Users can now hide Latest Features navigation entries for the current SimpleChat version from the ellipsis action and restore them from Profile Settings. + * The hidden state is version-aware, so Latest Features automatically appears again after the app version changes. + * Added a development-only `is_development=true` environment override that hides Latest Features nav entries without affecting production behavior when unset or false. + * (Ref: [#987](https://github.com/microsoft/simplechat/issues/987), `latestFeaturesHiddenVersion`, `_sidebar_nav.html`, `_top_nav.html`, `profile.html`, `latest-features-nav.js`) + +##### **(v0.250.057)** + +###### Bug Fixes + +* **Terms of Use Redirect Hardening** + * Replaced wildcard config imports in the Terms of Use route with explicit Flask imports. + * Moved post-acceptance return paths from hidden form values to server-side session storage, keeping user-controlled return targets local-only. + * Restricted admin-configured external decline redirects to HTTPS URLs without embedded credentials while preserving local-path redirects. + * (Ref: [#504](https://github.com/microsoft/simplechat/issues/504), `route_frontend_terms_of_use.py`, `functions_terms_of_use.py`, `terms_of_use.html`) + +##### **(v0.250.056)** + +###### New Features + +* **Optional Terms of Use Gate** + * Added an admin-configurable Terms of Use prompt that can require users to accept rules of behavior, terms, or an entry notice before using SimpleChat. + * Supports every-session, once-per-day, and once-per-version recurrence modes, with server-side browser/API enforcement and activity logging for accept/decline events. + * (Ref: [#504](https://github.com/microsoft/simplechat/issues/504), `TERMS_OF_USE.md`, `functions_terms_of_use.py`, `route_frontend_terms_of_use.py`, `terms_of_use.html`) + +##### **(v0.250.052)** + +###### Bug Fixes + +* **Control Center Left Nav Endpoint Fix** + * Fixed an issue where admins could open Control Center while the left navigation Control Center section stayed hidden when ControlCenterAdmin enforcement was disabled. + * Updated the sidebar endpoint check to use the blueprint-qualified `frontend_control_center.control_center` route and added regression coverage for the regular Admin fallback. + * (Ref: [#1009](https://github.com/microsoft/simplechat/issues/1009), `_sidebar_nav.html`, `test_control_center_left_nav_endpoint.py`) + +##### **(v0.250.051)** + +###### User Interface Enhancements + +* **Cosmos Editor Independent Results Scrolling** + * Cosmos editor query results now use a dedicated scroll area inside the results modal, so long result lists do not stretch the rest of the modal. + * Added a smaller results-list cap for narrower screens while keeping the document editor and modal footer accessible. + * (Ref: [#1006](https://github.com/microsoft/simplechat/issues/1006), `admin_settings.html`, `styles.css`, Cosmos DB JSON Editor) + +##### **(v0.250.049)** + +###### Bug Fixes + +* **Cosmos Editor Page Size Enforcement** + * Empty Cosmos editor browse mode now respects the selected page size up to the 100-document cap instead of always requesting 100 items. + * This keeps small page-size selections useful for compact validation and targeted inspection. + * (Ref: [#1006](https://github.com/microsoft/simplechat/issues/1006), Cosmos DB JSON Editor, `functions_data_management.py`) + +###### User Interface Enhancements + +* **Cosmos Editor Results Modal** + * Moved Cosmos editor query results and the JSON document editor into a large scrollable modal opened by Run Query. + * Kept the Data Management card focused on unlock, container selection, page size, and query setup while the modal provides compact result rows, a scrollable results pane, document refresh, Next Page, and Save JSON controls. + * (Ref: [#1006](https://github.com/microsoft/simplechat/issues/1006), `admin_settings.html`, `admin_data_management.js`, `COSMOS_DB_JSON_EDITOR.md`) + +##### **(v0.250.048)** + +###### New Features + +* **Admin Cosmos DB JSON Editor** + * Added an admin-only Data Management tool for selecting SimpleChat Cosmos DB containers, running paged SELECT queries, opening individual documents, editing JSON, and saving changes with ETag concurrency protection. + * Empty browse mode is capped at the first 100 documents, while custom SELECT queries page beyond 100 through continuation tokens without returning oversized result sets in one request. + * The interface is protected by danger acknowledgements, blocks `id` and partition key edits, and records editor actions plus save summaries in Activity Logs. + * (Ref: [#1006](https://github.com/microsoft/simplechat/issues/1006), `COSMOS_DB_JSON_EDITOR.md`, `functions_data_management.py`, `route_backend_data_management.py`, `admin_settings.html`, `admin_data_management.js`) + +##### **(v0.250.047)** + +###### Bug Fixes + +* **CosmosClient Import Binding CodeQL Cleanup** + * Replaced direct `CosmosClient` imports with module-qualified `azure_cosmos.CosmosClient` lookups so tests and diagnostics that patch `azure.cosmos.CosmosClient` are observed consistently. + * Updated the Cosmos query plugin functional test to patch the module-qualified SDK client and avoid live Cosmos connections during app-module imports. + * (Ref: `config.py`, `functions_data_management.py`, `route_backend_plugins.py`, `cosmos_query_plugin.py`, `test_cosmos_query_plugin.py`) + +##### **(v0.250.046)** + +###### Bug Fixes + +* **Conversation Cache Invalidation Authorization** + * Route-level message mutation cache invalidation now loads personal conversations through the existing ownership authorization helper instead of directly reading a request-derived conversation id. + * Updated PR-readiness functional test fixtures to match the current document access index config imports and avoid live Cosmos connections during notification regression tests. + * (Ref: `route_backend_conversations.py`, `test_chat_completion_notifications.py`, DAI functional test fixtures) + +##### **(v0.250.044)** + +###### New Features + +* **Development Requirements Overlay** + * Added a root `requirements-dev.txt` for test and development-only Python dependencies that are not already included in the base app requirements. + * The overlay includes pytest, pytest Playwright integration, and Azure Playwright management support so local validation can be installed without duplicating the production dependency set. + * (Ref: `requirements-dev.txt`, testing dependencies, local development setup) + +##### **(v0.250.043)** + +###### New Features + +* **Redis Explorer SimpleChat Resolution** + * Redis Explorer now resolves `DAI_LIST_CACHE_VERSION:{hash}` keys to safe SimpleChat scope metadata when possible, including user/group/public workspace identity, workspace name/status, DAI row counts, and source/access-role summaries. + * Added DAI cache hygiene counters to Redis Monitoring for payload keys, version markers, no-expiry markers, and the active version-marker TTL policy. + * (Ref: `functions_redis_monitoring.py`, `functions_document_access_index.py`, `admin_settings.html`, `admin_settings.js`, `REDIS_EXPLORER.md`) + +###### Bug Fixes + +* **DAI Redis Version Marker TTL Hygiene** + * DAI Redis version marker keys now receive a bounded TTL that outlives DAI payload cache entries instead of remaining in Redis indefinitely. + * Marker TTLs refresh on DAI cache reads, cache invalidations, and app-maintenance hygiene; existing no-expiry markers are repaired in place rather than deleted. + * With the current 900-second DAI payload TTL, version markers are refreshed to 3,600 seconds. + * (Ref: DAI Redis cache version markers, `refresh_document_access_cache_version_marker_ttls`, app maintenance) + +##### **(v0.250.041)** + +###### User Interface Enhancements + +* **Redis Explorer Browse-All Layout** + * Improved Redis Explorer with a fixed-height modal where the key list and sanitized preview pane scroll independently, keeping pagination controls and selected preview context easier to use. + * Added an explicit Browse All action, clearer Apply Filter and Previous Page/Next Page controls, page/scope status text, and guidance for app settings cache key names such as `APP_SETTINGS_CACHE`. + * (Ref: `REDIS_EXPLORER.md`, `admin_settings.html`, `admin_settings.js`, Redis Explorer) + +##### **(v0.250.040)** + +###### New Features + +* **Redis Explorer** + * Added an admin-only Redis Explorer in Admin Settings > Scale > Redis Monitoring for read-only, cursor-paginated Redis key browsing with substring filtering and page-size controls. + * Admins can select a key to view sanitized metadata and bounded preview content; session, token, cookie, credential, password, secret, authorization, and CSRF-like keys return restricted previews. + * JSON previews redact sensitive fields and all browser rendering uses text-safe DOM updates. + * (Ref: `REDIS_EXPLORER.md`, `functions_redis_monitoring.py`, `route_backend_settings.py`, `admin_settings.html`, `admin_settings.js`) + +##### **(v0.250.039)** + +###### New Features + +* **Phase 9 Cosmos Performance Runbooks** + * Added support guidance for rebuilding caches, rebuilding the Document Access Index, cleaning stale operational cache documents, applying expected Cosmos composite indexes, interpreting shadow validation diffs, and interpreting DAI fallback/cache metrics. + * Documented when broad source fallback should remain available while DAI repair, backfill, Redis cache, and production fallback telemetry stabilize. + * (Ref: `COSMOS_PERFORMANCE_OPTIMIZATION_PLAN.md`, Cosmos maintenance, DAI runbooks) + +###### User Interface Enhancements + +* **Guarded Cosmos Index Apply Action** + * Added an Admin Settings > Scale > Cosmos Maintenance action for applying missing expected Cosmos composite indexes through the existing app-maintenance endpoint. + * The confirmation modal explains that updates are additive and preserve existing indexing policy paths, but can add write-index overhead and trigger asynchronous Cosmos index transformation. + * (Ref: `admin_settings.html`, `admin_settings.js`, `functions_cosmos_indexing.py`, app maintenance) + +##### **(v0.250.037)** + +###### Bug Fixes + +* **Settings Container RU Write Suppression** + * Reduced idle Cosmos DB `settings` container RU consumption by stopping routine status refreshes, no-op autoscale checks, and generic settings writes from creating unrelated cache/version churn. + * Conversation cache versioning and volatile chat bootstrap/conversation payloads now require Redis; when Redis is unavailable, the app bypasses those caches and falls back to source Cosmos query behavior instead of writing cache artifacts to `settings`. + * Document Access Index status now uses short-lived in-process state caching and skips shadow-validation state reads when shadow validation is disabled. + * Post-deploy validation showed `settings` dropped out of the top normalized RU consumers during idle monitoring. + * (Ref: `functions_settings.py`, `functions_cosmos_throughput.py`, `functions_shared_cache.py`, `functions_conversation_cache.py`, `functions_document_access_index.py`, `SETTINGS_CONTAINER_RU_WRITE_SUPPRESSION_FIX.md`) + +##### **(v0.250.035)** + +###### Bug Fixes + +* **Conversation Cache Mark-Read Invalidation Tuning** + * Normal conversation switching now skips mark-read requests when the client has no unread assistant-response state, reducing unnecessary conversation feed cache invalidations during page reloads and navigation. + * The mark-read API now only upserts the conversation and bumps the user-scoped conversation cache version when unread conversation fields actually changed; notification clearing remains intact. + * (Ref: conversation cache invalidation, mark-read flow, `chat-conversations.js`, `route_backend_conversations.py`, `test_conversations_read_ownership_authorization.py`) + +##### **(v0.250.034)** + +###### New Features + +* **Conversation Cache Metrics Dashboard** + * Added DAI-style rolling metrics for conversation list, feed, and advanced-search cache activity, including 15-minute hit rate, hits/misses, bypasses/errors, writes/invalidations, operation mix, last cache event, and last invalidation. + * Exposed normalized conversation cache settings and metrics through app maintenance status without adding Cosmos reads to the conversation hot path. + * Removed the Phase 4 badge from the Conversation Cache card now that the feature is part of the operational dashboard. + * (Ref: conversation cache metrics, `functions_conversation_cache.py`, `functions_app_maintenance.py`, `admin_settings.html`, `admin_settings.js`) + +##### **(v0.250.033)** + +###### New Features + +* **Phase 4 Conversation Cache Hardening** + * Hardened conversation list, feed, and advanced-search caching behind an explicit `enable_conversation_cache` setting. + * Added Admin Settings > Scale controls for enabling conversation cache and adjusting the conversation cache TTL without requiring direct Cosmos settings edits. + * Redis remains optional: enabled cache paths use the shared Redis-first/Cosmos-fallback helper, while disabled cache paths bypass cache reads and writes and continue using source Cosmos queries. + * Conversation cache entries remain user-scoped and versioned, with collaboration-aware feed/search fingerprints based on the user's group-access state. + * (Ref: conversation cache, optional Redis fallback, `functions_conversation_cache.py`, `route_backend_conversations.py`, `admin_settings.html`) + +###### Bug Fixes + +* **Conversation Cache Invalidation Coverage** + * Added cache invalidation after metadata reads normalize and persist legacy/missing `chat_type` values so cached list/search payloads do not remain stale. + * Updated conversation cache and ownership authorization regressions to cover disabled-cache bypass, source fallback, and route wiring. + * (Ref: conversation metadata normalization, cache invalidation, `test_cosmos_wave2b_conversation_cache.py`, `test_conversations_read_ownership_authorization.py`) + +##### **(v0.250.032)** + +###### New Features + +* **Phase 3 Low-Churn Cache Hardening** + * Hardened the shared low-churn cache foundation for custom pages/navigation and chat bootstrap data. + * Added safe shared-cache diagnostics for hit, miss, write, delete, and version-bump activity using hashed cache-key context, and exposed those metrics through app maintenance status. + * Expanded chat bootstrap cache invalidation coverage across group and public workspace metadata, membership, role, ownership, status, model endpoint, Control Center, and SimpleChat operation mutations. + * (Ref: shared cache metrics, chat bootstrap cache, custom pages cache, `functions_shared_cache.py`, `functions_app_maintenance.py`) + +###### Bug Fixes + +* **Low-Churn Cache Invalidation Coverage** + * Fixed stale chat bootstrap labels after group rename/update paths by invalidating the global chat bootstrap cache after successful group metadata writes. + * Custom pages/navigation cache now invalidates after app settings writes so menu and feature-setting changes do not wait for TTL expiry. + * (Ref: group metadata updates, custom page settings invalidation, `route_backend_groups.py`, `functions_settings.py`) + +* **Public Workspace Document Manager Approval** + * Fixed document-manager request approval so the manager addition and pending-request cleanup are persisted in a single workspace update instead of risking a stale overwrite. + * The approval and rejection flows now invalidate chat bootstrap cache state for public workspace visibility updates. + * (Ref: public workspace document managers, `functions_public_workspaces.py`, `test_cosmos_wave2a_chat_bootstrap_cache.py`) + +##### **(v0.250.030)** + +###### New Features + +* **Redis Document Access Index Cache** + * Added Redis read-through caching for DAI-backed document list, tag list, and legacy-count reads with scope-version invalidation and bounded TTL controls. + * Admin Settings now shows Redis DAI cache health, hit/miss/bypass/error metrics, invalidations, and the latest cache event alongside DAI read and maintenance status. + * (Ref: DAI Redis cache, `functions_document_access_index.py`, `admin_settings.html`, `admin_settings.js`) + +###### Bug Fixes + +* **DAI Cache Invalidation and Repair Safety** + * Hardened DAI cache invalidation so access changes fail closed when Redis invalidation cannot be proven safe, including revoked-share, delete, partial projection failure, and untracked repair-state scenarios. + * Preserved historical revoked scopes through repair and blocked DAI/cache reads while repair safety is unknown. + * (Ref: DAI cache invalidation, projection repair backlog, `test_cosmos_wave6_document_access_cache.py`) + +* **DAI List Parity Improvements** + * DAI document-list reads now include pending shared documents needed by approval UI, preserve generated-artifact requester identity for public workspace actions, collapse legacy revisions like source reads, and match source exact/case-sensitive classification and array filters. + * DAI tag-list reads now project file names for legacy rows so distinct legacy documents without revision-family metadata do not collapse into a single tag-count identity. + * External public DAI lists now use unfiltered DAI legacy counts so legacy-update prompts match source-backed behavior. + * (Ref: DAI list parity, public workspace documents, external public documents) + +* **Maintenance Failure Visibility** + * Manual app maintenance runs now surface failed step status instead of reporting full success, and Admin Settings keeps detailed DAI status visible when a run completes with errors. + * The DAI maintenance status now reports automatic maintenance only when the app-maintenance scheduler gates are enabled and startup maintenance can actually run. + * Optional shadow-validation source queries now fail open after successful DAI reads so diagnostics cannot break served list responses. + * (Ref: app maintenance, DAI shadow validation, `functions_app_maintenance.py`, document list routes) + +##### **(v0.250.015)** + +###### Bug Fixes + +* **Anonymous Notification Polling 401 Log Reduction** + * Stopped loading the notification polling script for unauthenticated sessions, preventing the login screen from repeatedly calling `/api/notifications/count` after idle timeout or before sign-in. + * This reduces expected 401 noise in App Service log streams and Application Insights while preserving notification badge polling for authenticated users. + * (Ref: notification polling, idle timeout, `base.html`, `notifications.js`, `test_notification_polling_redirect_guard.py`) + +##### **(v0.250.010)** + +###### New Features + +* **Audio File Runtime Support** + * Added default-on FFmpeg and FFprobe packaging for container builds so SimpleChat can transcode a much broader set of audio files before Azure Speech transcription. + * Expanded recognized audio upload extensions to include common containers and codecs such as 3GA, AAC, AC3, AIFF, AMR, AU, CAF, FLAC, M4A/M4B/M4R, Matroska audio, MP2/MP3/MPA, OGG/Opus/Speex, WAV, WebM audio, WMA, and WavPack. + * Added Admin Settings runtime guidance showing whether FFmpeg broad transcoding is available in the current app runtime and which audio upload extensions are recognized. + * Added `SIMPLECHAT_INSTALL_FFMPEG` / `INSTALL_AUDIO_FFMPEG` build controls for deployments that need to opt out of bundling FFmpeg. + * (Ref: audio uploads, FFmpeg runtime, `Dockerfile`, `functions_documents.py`, `admin_settings.html`, `AUDIO_FILE_RUNTIME_SUPPORT.md`) + +###### Bug Fixes + +* **iPhone M4A Upload FFmpeg Fallback** + * Fixed supported iPhone `.m4a` audio uploads failing before transcription when the app runtime could not resolve a local `ffmpeg` executable. + * Public Azure environments can now fall back to Azure Speech fast transcription using the original supported source audio file and content type when local segmentation fails because FFmpeg is missing. + * FFmpeg segmentation now targets the first audio stream and emits mono 16 kHz PCM WAV chunks for Speech when FFmpeg is available. + * (Ref: [#974](https://github.com/microsoft/simplechat/issues/974), `.m4a` upload processing, Azure Speech fast transcription, `IPHONE_M4A_FFMPEG_FALLBACK_FIX.md`) + +##### **(v0.250.008)** + +###### Bug Fixes + +* **Multi-Endpoint Vision Test Connection** + * Fixed the Admin Settings Vision Model test button so multi-endpoint models are tested against their configured endpoint instead of always using the legacy GPT endpoint. + * Vision model options now preserve endpoint and model metadata for the test call while keeping the saved deployment-name value compatible with existing settings. + * Removed duplicate backend Vision test connection logic and preserved GPT-5/o-series token handling for Vision test requests. + * (Ref: Vision Model test, multi-endpoint model endpoints, `admin_settings.js`, `admin_settings.html`, `route_backend_settings.py`, `MULTI_ENDPOINT_VISION_TEST_CONNECTION_FIX.md`) + +##### **(v0.250.007)** + +* **Malicious PR Security Review Workflow** + * Added a static malicious-change review workflow for pull requests into `Development`, with manual dispatch options for custom review ranges and full-file scans. + * Added a reusable security review prompt and focused functional coverage for dependency pinning policy, hidden Unicode detection, suspicious egress markers, and workflow wiring. + * (Ref: malicious PR security review, `.github/workflows/malicious-pr-security-review.yml`, `scripts/check_malicious_pr_security_review.py`) + +##### **(v0.250.006)** + +###### New Features + +* **Chat Scroll Behavior and 508 Usability** + * Updated chat message rendering so the viewport no longer jumps to the very bottom of long assistant responses when they finish loading while the user is reading near the top. + * Auto-scroll now only occurs when the user is already near the bottom of the conversation, and a floating "scroll to latest message" button appears when new content arrives below the current view. + * This aligns the chat experience more closely with other AI chat tools and reduces unexpected motion for 508 testers and keyboard users. + * (Ref: `chats.html`, `chat-global.js`, `chat-messages.js`) + +##### **(v0.250.005)** + +###### Bug Fixes + +* **Admin Settings Save 500 Fix** + * Fixed an issue where saving Admin Settings returned an HTTP 500 error even though configuration changes were successfully persisted. + * The `/admin/settings` POST handler now uses Flask's `current_app` when regenerating custom logo and favicon files after a successful settings update, eliminating the `NameError: name 'app' is not defined` in the post-save path. + * (Ref: admin settings save, logo/favicon regeneration, `route_frontend_admin_settings.py`, `ADMIN_SETTINGS_SAVE_500_FIX.md`) + +##### **(v0.250.004)** + +###### Bug Fixes + +* **Model Endpoint Management Cloud Normalization** + * Fixed model endpoint saves so managed identity and other non-editable cloud paths derive `management_cloud` from `AZURE_ENVIRONMENT` instead of persisting the hidden UI default of `public`. + * Added custom-cloud handling for inherited model endpoint authority and Foundry scope defaults while preserving explicit Foundry service-principal cross-cloud selections. + * (Ref: model endpoint authentication, `normalize_model_endpoints`, `AZURE_ENVIRONMENT`, `test_model_endpoint_management_cloud_environment.py`) + +##### **(v0.250.003)** + +###### Bug Fixes + * **Admin Settings Update Banner Version Comparison** * Fixed stale cached update-check settings so Admin Settings no longer displays an older release such as `v0.250.001` as available when the running app version is newer. * The render path now recomputes `update_available` from the cached latest version and the current app version before showing the banner. diff --git a/docs/features.md b/docs/features.md index 8c2a2066d..33164f079 100644 --- a/docs/features.md +++ b/docs/features.md @@ -22,7 +22,7 @@ This catalog covers **38 capabilities** backed by **111 capability toggles**. | [Grounded document search](/features/grounded-document-search/) | Controls Azure AI Search-backed retrieval, cached search results, and mixed-source evidence reuse in chat. | End users | Mixed | [Search and Extract](/admin/knowledge/) | | [Source history summaries](/features/source-history-summaries/) | Summarizes older conversation context so search and long-running chats can keep useful history. | End users | Disabled | [Search and Extract](/admin/knowledge/) | | [URL access](/features/url-access/) | Lets chat and workflows fetch approved pasted URLs under admin-controlled limits and domain policy. | End users | Disabled | [Search and Extract](/admin/knowledge/) | -| [Web search](/features/web-search/) | Adds Bing-backed web search through a configured Azure AI Foundry agent for current external information. | End users | Disabled | [Search and Extract](/admin/knowledge/) | +| [Web search](/features/web-search/) | Grounds a chat message in current public web results through a configured Azure AI Foundry agent using Grounding with Bing Search. Only the current message leaves the application. | End users | Disabled | [Search and Extract](/admin/knowledge/) | ## Documents and workspaces diff --git a/docs/guides/admin-enable-a-capability.md b/docs/guides/admin-enable-a-capability.md index c662b0e5b..fab209894 100644 --- a/docs/guides/admin-enable-a-capability.md +++ b/docs/guides/admin-enable-a-capability.md @@ -31,7 +31,7 @@ A capability toggle is usually the last step, not the first one. Many SimpleChat Read the capability's tab page and list every dependency it names. Examples include Azure AI Content Safety for Content Safety, Storage for Enhanced Citations, Azure Cache for Redis for Redis-backed cache, Key Vault for agent and action secrets, Foundry agent details for Web Search, Speech service for audio and voice features, or Entra app roles for gated workspace actions. {% include media.html src="guides/admin-enable-a-capability-dependencies.png" - alt="Admin checklist showing the backing Azure resource, role, policy, quota, and limit required before enabling a capability." + alt="The Web Search configuration guide explaining Grounding with Bing Search, warning that customer data is transferred outside the Azure compliance boundary, and listing the numbered prerequisites for creating the agent and choosing a compatible model." title="Confirm capability dependencies" capture="Capture a dependency checklist for one capability with resource names redacted and readiness marked before the toggle is enabled." %} @@ -44,7 +44,7 @@ Choose the authentication mode shown on the tab: key, managed identity, APIM sub Configure limits, domains, scopes, thresholds, retention windows, source counts, concurrency, or guardrails before making the capability visible. This is especially important for URL Access, Deep Research, File Sync, tabular runs, Cosmos throughput automation, MCP destinations, and workspace downloads because those controls define how far the feature can reach. {% include media.html src="guides/admin-enable-a-capability-guardrails.png" - alt="Admin Settings page showing limits, roles, allowlists, and thresholds configured before enabling the user-facing switch." + alt="The Web Search settings pane with the capability enabled, the user data notice switched on with its notice text, and the Foundry project endpoint, API version, agent ID and authentication fields populated above a Test Web Search button." title="Set guardrails before enabling" capture="Capture the relevant Admin Settings tab with limits and policy fields populated before the final capability switch is turned on." %} diff --git a/docs/guides/admin-first-configuration.md b/docs/guides/admin-first-configuration.md index 012675283..6238a1414 100644 --- a/docs/guides/admin-first-configuration.md +++ b/docs/guides/admin-first-configuration.md @@ -31,7 +31,7 @@ Some Admin Settings tabs unlock experiences that depend on earlier tabs. Workspa Start with [General settings]({{ '/admin/appearance/' | relative_url }}). Publish the approved application title, logo, landing page copy, access-denied message, support destinations, health-check behavior, Terms of Use, AI notice, idle timeout, and upload/session limits. These are first because every user sees them before feature-specific settings matter. {% include media.html src="guides/admin-first-configuration-general.png" - alt="General settings page showing tenant branding, terms, support, health check, and session controls." + alt="The Branding settings pane showing the application title field, logo visibility toggles, the home page logo size slider, and upload fields for light-mode and dark-mode logos and a favicon." title="Configure general settings first" capture="Capture the General tab after tenant-facing copy and support controls are populated, with any private URLs redacted." %} @@ -44,7 +44,7 @@ Use [Security settings]({{ '/admin/security/' | relative_url }}) if the deployme Open [AI Models settings]({{ '/admin/ai-models/' | relative_url }}) and configure GPT routing before users test chat or agents. Configure embeddings before enabling document-heavy workspace use because retrieval depends on embeddings and Azure AI Search. Add image generation only after the image deployment, quota, and policy approval are ready. {% include media.html src="guides/admin-first-configuration-models.png" - alt="AI Models settings page with chat and embedding endpoint sections configured." + alt="The Model Endpoints pane showing the agent default model review panel with its readiness counts, the saved default model, and the model endpoint identity header settings." title="Configure model endpoints" capture="Capture the AI Models tab showing chat and embedding sections complete, with keys and subscription details redacted." %} @@ -57,7 +57,7 @@ Use [Search and Extract settings]({{ '/admin/knowledge/' | relative_url }}) next Move to [Workspaces settings]({{ '/admin/workspaces/' | relative_url }}) after model and retrieval prerequisites are ready. Enable only the personal, group, public, workflow, upload, download, retention, classification, and agreement capabilities the tenant has approved. Test role-gated behavior with assigned and unassigned users before wider rollout. {% include media.html src="guides/admin-first-configuration-workspaces.png" - alt="Workspaces settings page showing enabled scopes, role requirements, retention, and agreement choices." + alt="The Workspace Types pane showing the personal, group, and public workspace switches alongside the group creation and app role requirements that gate who can create each kind of workspace." title="Set workspace scope and retention" capture="Capture the Workspaces tab with approved scopes and retention controls visible." %} diff --git a/docs/guides/create-a-file-sync.md b/docs/guides/create-a-file-sync.md index 286491214..fb4519825 100644 --- a/docs/guides/create-a-file-sync.md +++ b/docs/guides/create-a-file-sync.md @@ -32,7 +32,7 @@ Use File Sync when important documents already live in a share or storage contai 3. Select **Add Sync Source**. {% include media.html src="guides/create-a-file-sync-step-3.png" - alt="Screenshot showing create a file sync step 3." + alt="The Add Sync Source dialog on the Source Type step, offering SMB Share, Azure Files, and Azure Blob Storage as available source types." title="Create a file sync step 3" capture="Capture the create a file sync task at this step in SimpleChat with realistic sample data and redact secrets." %} @@ -44,7 +44,7 @@ Use File Sync when important documents already live in a share or storage contai 9. In **Tags**, choose fixed tags; in **Sync Schedule**, enable **Scheduled sync** only when automatic refresh is wanted. {% include media.html src="guides/create-a-file-sync-step-9.png" - alt="Screenshot showing create a file sync step 9." + alt="The Configure step of the Add Sync Source dialog for an SMB share, showing source name and UNC path, the reusable identity and authentication choices, and the subfolder and filter selection controls." title="Create a file sync step 9" capture="Capture the create a file sync task at this step in SimpleChat with realistic sample data and redact secrets." %} diff --git a/docs/guides/create-a-workflow.md b/docs/guides/create-a-workflow.md index 17d7ff43d..55ec7e733 100644 --- a/docs/guides/create-a-workflow.md +++ b/docs/guides/create-a-workflow.md @@ -32,8 +32,8 @@ Use workflows for repeatable work where sequence matters: weekly document checks 3. Select **New Personal Workflow** or **New Group Workflow**. {% include media.html src="guides/create-a-workflow-step-3.png" - alt="Screenshot showing create a workflow step 3." - title="Create a workflow step 3" + alt="The Create Group Workflow dialog on the General step, showing the workflow name, default runner, description, and model source fields, with Trigger, Tasks, Reliability, and Review still ahead." + title="Creating a group workflow" capture="Capture the create a workflow task at this step in SimpleChat with realistic sample data and redact secrets." %} 4. In **General**, enter a name, description, and default runner. diff --git a/docs/guides/create-an-action.md b/docs/guides/create-an-action.md index 48bc037bb..a666d659d 100644 --- a/docs/guides/create-an-action.md +++ b/docs/guides/create-an-action.md @@ -32,8 +32,8 @@ Use an action when a model needs to do more than write an answer, such as query 3. Select **Add Action** or the workspace new action button. {% include media.html src="guides/create-an-action-step-3.png" - alt="Screenshot showing create an action step 3." - title="Create an action step 3" + alt="The Add Action dialog on Select Type, showing a searchable grid of action type cards including Azure Maps, Blob Storage, Cosmos Query, Databricks, Document Search, Interactive Charts, Log Analytics, Microsoft Graph, and Model Context Protocol." + title="Choosing an action type" capture="Capture the create an action task at this step in SimpleChat with realistic sample data and redact secrets." %} 4. On **Select Action Type**, search for the type you need, such as **OpenAPI**, **MCP**, **Log Analytics**, or another enabled card. @@ -41,7 +41,7 @@ Use an action when a model needs to do more than write an answer, such as query 6. Complete the type-specific configuration, including **OpenAPI Specification File**, **Base URL**, **Authentication Type**, **Reusable Identity**, or MCP discovery fields when shown. {% include media.html src="guides/create-an-action-step-6.png" - alt="Screenshot showing create an action step 6." + alt="The Add Action wizard on the Configuration step for an Azure Maps action, showing the credentials section, the subscription key field, and a Test Connection button." title="Create an action step 6" capture="Capture the create an action task at this step in SimpleChat with realistic sample data and redact secrets." %} diff --git a/docs/guides/create-an-agent-with-actions.md b/docs/guides/create-an-agent-with-actions.md index 021a3936e..443b64ded 100644 --- a/docs/guides/create-an-agent-with-actions.md +++ b/docs/guides/create-an-agent-with-actions.md @@ -32,7 +32,7 @@ Binding an action to an agent turns a broad tool into a safer task assistant. Us 3. Complete **Basic Information** and **Model & Connection**. {% include media.html src="guides/create-an-agent-with-actions-step-3.png" - alt="Screenshot showing create an agent with actions step 3." + alt="The Actions step of the Add Agent wizard showing searchable action cards for document search, Microsoft Graph, and a Yamcs simulation, above an empty Selected Actions panel." title="Create an agent with actions step 3" capture="Capture the create an agent with actions task at this step in SimpleChat with realistic sample data and redact secrets." %} @@ -41,7 +41,7 @@ Binding an action to an agent turns a broad tool into a safer task assistant. Us 6. In **Instructions**, explain when to use the action and when to answer without it. {% include media.html src="guides/create-an-agent-with-actions-step-6.png" - alt="Screenshot showing create an agent with actions step 6." + alt="The Instructions step of the Add Agent wizard, showing the Selected Actions and Knowledge summary bar with its counts, the Instruction Brief box, a Draft Instructions button, and the agent instructions editor." title="Create an agent with actions step 6" capture="Capture the create an agent with actions task at this step in SimpleChat with realistic sample data and redact secrets." %} diff --git a/docs/guides/create-an-agent.md b/docs/guides/create-an-agent.md index 8215935e4..fd012a86d 100644 --- a/docs/guides/create-an-agent.md +++ b/docs/guides/create-an-agent.md @@ -32,8 +32,8 @@ Create an agent when a task benefits from consistent behavior, such as policy re 3. Select **New Agent**. {% include media.html src="guides/create-an-agent-step-3.png" - alt="Screenshot showing create an agent step 3." - title="Create an agent step 3" + alt="The Add Agent dialog on Basic Info, showing the Agent Type choice between Local and Foundry options and the seven-step progress bar through Model, Actions, Knowledge, Instructions, Advanced, and Summary." + title="The Add Agent wizard" capture="Capture the create an agent task at this step in SimpleChat with realistic sample data and redact secrets." %} 4. Choose **Local** in **Agent Type** unless an admin told you to use a Foundry option. @@ -43,7 +43,7 @@ Create an agent when a task benefits from consistent behavior, such as policy re 8. In **Instructions**, write **Agent Instructions** or use **Instruction Brief** and **Draft Instructions**. {% include media.html src="guides/create-an-agent-step-8.png" - alt="Screenshot showing create an agent step 8." + alt="The Instructions step of the Add Agent wizard, with the Instruction Brief box and Draft Instructions button above the agent instructions editor, and the seven-step progress bar showing Basic Info through Knowledge already complete." title="Create an agent step 8" capture="Capture the create an agent task at this step in SimpleChat with realistic sample data and redact secrets." %} diff --git a/docs/guides/create-and-manage-tags.md b/docs/guides/create-and-manage-tags.md index 595474150..d20175a36 100644 --- a/docs/guides/create-and-manage-tags.md +++ b/docs/guides/create-and-manage-tags.md @@ -32,8 +32,8 @@ Use tags when folders and file names are not enough: a document can belong to a 3. Select **Manage Tags**. {% include media.html src="guides/create-and-manage-tags-step-3.png" - alt="Screenshot showing create and manage tags step 3." - title="Create and manage tags step 3" + alt="The Manage Workspace Tags dialog with the Add New Tag name and color fields, and an Existing Tags table listing each tag with the number of documents using it." + title="Managing workspace tags" capture="Capture the create and manage tags task at this step in SimpleChat with realistic sample data and redact secrets." %} 4. In **Manage Workspace Tags**, enter a name in **Tag name (lowercase, alphanumeric)**. @@ -42,7 +42,7 @@ Use tags when folders and file names are not enough: a document can belong to a 7. Use **Tag Assignment** or **Tag Selected**. {% include media.html src="guides/create-and-manage-tags-step-7.png" - alt="Screenshot showing create and manage tags step 7." + alt="The Tag Assignment dialog for ten selected documents, showing the action selector set to Add Tags, the available tag chips to apply, and the Apply to Selected Documents button." title="Create and manage tags step 7" capture="Capture the create and manage tags task at this step in SimpleChat with realistic sample data and redact secrets." %} diff --git a/docs/guides/generate-images.md b/docs/guides/generate-images.md index ef064c582..81c8a48a9 100644 --- a/docs/guides/generate-images.md +++ b/docs/guides/generate-images.md @@ -32,7 +32,7 @@ Use image generation for visual concepts, drafts, illustrations, and creative ex 3. Type a clear visual request with subject, style, setting, and constraints. {% include media.html src="guides/generate-images-step-3.png" - alt="Screenshot showing generate images step 3." + alt="The chat composer with Image mode active and its tooltip showing, an image prompt typed in the message box, and the other source controls greyed out." title="Generate images step 3" capture="Capture the generate images task at this step in SimpleChat with realistic sample data and redact secrets." %} diff --git a/docs/guides/index.md b/docs/guides/index.md index 0fc543a70..1e21b2d05 100644 --- a/docs/guides/index.md +++ b/docs/guides/index.md @@ -46,7 +46,7 @@ Use this section when you want momentum first: each page is a practical path thr | [Collaborate in a conversation]({{ '/guides/collaborate-in-a-conversation/' | relative_url }}) | Invite others into a shared chat, use mentions, and approve participant-generated files. | Users | | [Lock workspace scope in chat]({{ '/guides/lock-workspace-scope/' | relative_url }}) | Keep a conversation tied to the same selected workspaces after grounded answers. | Users | | [Use deep research]({{ '/guides/use-deep-research/' | relative_url }}) | Ask chat to perform deeper evidence review for URLs and sources in a message. | Users | -| [Use web search]({{ '/guides/use-web-search/' | relative_url }}) | Send the current chat message to Bing web search when fresh web information is needed. | Users | +| [Use web search]({{ '/guides/use-web-search/' | relative_url }}) | Ground an answer in current public web results, and see exactly what leaves SimpleChat when you do. | Users | | [Review pasted URLs]({{ '/guides/review-pasted-urls/' | relative_url }}) | Use URL Access to review links included in the current chat message. | Users | | [Generate images]({{ '/guides/generate-images/' | relative_url }}) | Use the chat Image control to request AI-generated images. | Users | diff --git a/docs/guides/lock-workspace-scope.md b/docs/guides/lock-workspace-scope.md index a96f71be9..f7e40fba9 100644 --- a/docs/guides/lock-workspace-scope.md +++ b/docs/guides/lock-workspace-scope.md @@ -32,8 +32,8 @@ Use scope lock when a conversation should stay inside one team's documents or on 3. Choose a **Scope**, then optionally choose **Tags** and **Document**. {% include media.html src="guides/lock-workspace-scope-step-3.png" - alt="Screenshot showing lock workspace scope in chat step 3." - title="Lock workspace scope in chat step 3" + alt="The Grounded Search panel open above the composer, showing the Action, Scope, Document, and Tags selectors used to choose what a message searches." + title="Choosing scope in Grounded Search" capture="Capture the lock workspace scope in chat task at this step in SimpleChat with realistic sample data and redact secrets." %} 4. Send a grounded message. diff --git a/docs/guides/manage-group-workspaces.md b/docs/guides/manage-group-workspaces.md index bd461608a..f26882a64 100644 --- a/docs/guides/manage-group-workspaces.md +++ b/docs/guides/manage-group-workspaces.md @@ -32,16 +32,16 @@ Use a group workspace when a team needs common source documents, prompts, agents 3. Open **Group Workspaces**. {% include media.html src="guides/manage-group-workspaces-step-3.png" - alt="Screenshot showing manage group workspaces step 3." - title="Manage group workspaces step 3" + alt="The Group Workspace page showing the active group banner, the group selector with the viewer's role, and the Documents, Prompts, Identities, Sync, Actions, Agents, and Workflows tabs." + title="The group workspace and its tabs" capture="Capture the manage group workspaces task at this step in SimpleChat with realistic sample data and redact secrets." %} 4. Select the active group from the group selector. 5. Use **Documents** to upload, filter, tag, and chat with shared files. {% include media.html src="guides/manage-group-workspaces-step-5.png" - alt="Screenshot showing manage group workspaces step 5." - title="Manage group workspaces step 5" + alt="The group Documents tab with search and filter fields expanded, showing filters for file name, author, keywords, abstract, and tags above the shared document list." + title="Filtering shared group documents" capture="Capture the manage group workspaces task at this step in SimpleChat with realistic sample data and redact secrets." %} 6. Use **Prompts**, **Sync**, **Workflows**, **Agents**, or **Actions** when those tabs are enabled and your role allows them. diff --git a/docs/guides/manage-notifications.md b/docs/guides/manage-notifications.md index 4f01da24e..d17642437 100644 --- a/docs/guides/manage-notifications.md +++ b/docs/guides/manage-notifications.md @@ -32,7 +32,7 @@ Use notifications to catch workflow activity, shared conversation events, approv 3. Choose **10 per page**, **20 per page**, or **50 per page**. {% include media.html src="guides/manage-notifications-step-3.png" - alt="Screenshot showing manage notifications step 3." + alt="The Notifications page showing the All, Unread, and Read filter buttons, the per-page selector, and a search box narrowing the list to document-ready notifications, with paging beneath." title="Manage notifications step 3" capture="Capture the manage notifications task at this step in SimpleChat with realistic sample data and redact secrets." %} diff --git a/docs/guides/review-approval-requests.md b/docs/guides/review-approval-requests.md index 98398ddf9..7488c8094 100644 --- a/docs/guides/review-approval-requests.md +++ b/docs/guides/review-approval-requests.md @@ -32,7 +32,7 @@ Approvals create a checkpoint before sensitive actions execute. Use this page wh 3. Set **Pending Only** or **All Statuses**. {% include media.html src="guides/review-approval-requests-step-3.png" - alt="Screenshot showing review approval requests step 3." + alt="The Approval Requests page with the search box, the Pending Only status filter, the request type filter, and the results table, shown here with an empty queue." title="Review approval requests step 3" capture="Capture the review approval requests task at this step in SimpleChat with realistic sample data and redact secrets." %} diff --git a/docs/guides/review-pasted-urls.md b/docs/guides/review-pasted-urls.md index f822cc2ee..b8bb23604 100644 --- a/docs/guides/review-pasted-urls.md +++ b/docs/guides/review-pasted-urls.md @@ -32,7 +32,7 @@ Use URL Access when you already know the exact pages the model should review. It 3. Select **URLs**; its tooltip is **Review pasted URLs**. {% include media.html src="guides/review-pasted-urls-step-3.png" - alt="Screenshot showing review pasted urls step 3." + alt="The chat composer with a message containing two pasted URLs, the URL review control now active in the toolbar alongside Research." title="Review pasted URLs step 3" capture="Capture the review pasted urls task at this step in SimpleChat with realistic sample data and redact secrets." %} diff --git a/docs/guides/send-feedback.md b/docs/guides/send-feedback.md index 5f098013d..9b9443b05 100644 --- a/docs/guides/send-feedback.md +++ b/docs/guides/send-feedback.md @@ -32,7 +32,7 @@ Use the feedback form when admins need enough context to reproduce a problem or 3. For a bug, use **Bug Report** and fill **Name**, **Email**, **Organization**, and **Bug Details**. {% include media.html src="guides/send-feedback-step-3.png" - alt="Screenshot showing send feedback step 3." + alt="The Send Feedback page with side-by-side Bug Report and Feature Request forms, each carrying name, email, organization, and details fields above a button that opens an email draft." title="Send feedback step 3" capture="Capture the send feedback task at this step in SimpleChat with realistic sample data and redact secrets." %} @@ -41,7 +41,7 @@ Use the feedback form when admins need enough context to reproduce a problem or 6. For an improvement, use **Feature Request**, fill the same contact fields, and describe the problem and desired outcome. {% include media.html src="guides/send-feedback-step-6.png" - alt="Screenshot showing send feedback step 6." + alt="The Feature Request form completed with contact details and a description of the requested improvement, ready for Open Feature Request Draft to hand it to the local mail client." title="Send feedback step 6" capture="Capture the send feedback task at this step in SimpleChat with realistic sample data and redact secrets." %} diff --git a/docs/guides/trigger-a-workflow.md b/docs/guides/trigger-a-workflow.md index 4641af1a5..879dfeb1b 100644 --- a/docs/guides/trigger-a-workflow.md +++ b/docs/guides/trigger-a-workflow.md @@ -32,7 +32,7 @@ A workflow only helps when it runs at the right moment and leaves evidence you c 3. Search with **Search workflows by name, runner, or task prompt...** if needed. {% include media.html src="guides/trigger-a-workflow-step-3.png" - alt="Screenshot showing trigger a workflow step 3." + alt="The personal workspace Workflows tab listing a saved workflow with its runner, manual trigger, last run status, and the Run, Activity, and History buttons." title="Trigger a workflow step 3" capture="Capture the trigger a workflow task at this step in SimpleChat with realistic sample data and redact secrets." %} diff --git a/docs/guides/update-profile-preferences.md b/docs/guides/update-profile-preferences.md index 2c32b653d..115e51717 100644 --- a/docs/guides/update-profile-preferences.md +++ b/docs/guides/update-profile-preferences.md @@ -32,7 +32,7 @@ Profile preferences are for personal comfort and control: font size, navigation 3. In **Appearance Preferences**, pick **Font size** and select **Save Font Size**. {% include media.html src="guides/update-profile-preferences-step-3.png" - alt="Screenshot showing update profile preferences step 3." + alt="The profile Settings tab showing preference cards for font size, response completion audio, navigation, Latest Features visibility, tutorials, desktop notifications, conversation navigation, fact memory, microphone permission, and text-to-speech voice." title="Update profile preferences step 3" capture="Capture the update profile preferences task at this step in SimpleChat with realistic sample data and redact secrets." %} @@ -40,7 +40,7 @@ Profile preferences are for personal comfort and control: font size, navigation 5. In **Tutorial Preferences**, choose whether tutorial buttons appear and select **Save Tutorial Preferences**. {% include media.html src="guides/update-profile-preferences-step-5.png" - alt="Screenshot showing update profile preferences step 5." + alt="The Tutorial Preferences card with the switch that shows or hides the floating guided tutorial launchers on Chat and Personal Workspace, and its Save Tutorial Preference button." title="Update profile preferences step 5" capture="Capture the update profile preferences task at this step in SimpleChat with realistic sample data and redact secrets." %} diff --git a/docs/guides/use-deep-research.md b/docs/guides/use-deep-research.md index 7c159f758..f9d8818fc 100644 --- a/docs/guides/use-deep-research.md +++ b/docs/guides/use-deep-research.md @@ -32,8 +32,8 @@ Use Deep Research when the answer depends on evidence review rather than a quick 3. Include exact URLs when specific web pages should be reviewed. {% include media.html src="guides/use-deep-research-step-3.png" - alt="Screenshot showing use deep research step 3." - title="Use deep research step 3" + alt="The chat composer with Web and Research both active, a question containing a URL typed in the message box, and the web search data notice above it." + title="A Deep Research question with a source URL" capture="Capture the use deep research task at this step in SimpleChat with realistic sample data and redact secrets." %} 4. Select **Research**; its tooltip is **Deep Research**. diff --git a/docs/guides/use-public-workspaces.md b/docs/guides/use-public-workspaces.md index 7db2f7621..2d17dda3e 100644 --- a/docs/guides/use-public-workspaces.md +++ b/docs/guides/use-public-workspaces.md @@ -32,7 +32,7 @@ Use public workspaces for curated materials intended for a broad audience, such 3. Review the role indicator. {% include media.html src="guides/use-public-workspaces-step-3.png" - alt="Screenshot showing use public workspaces step 3." + alt="The Public Workspace Directory listing available public workspaces with per-workspace visibility and Chat buttons, plus controls for saving and loading curated visibility lists." title="Use public workspaces step 3" capture="Capture the use public workspaces task at this step in SimpleChat with realistic sample data and redact secrets." %} @@ -40,7 +40,7 @@ Use public workspaces for curated materials intended for a broad audience, such 5. Switch between **List**, **Cards**, **Folders**, and **Folders + Cards** views as needed. {% include media.html src="guides/use-public-workspaces-step-5.png" - alt="Screenshot showing use public workspaces step 5." + alt="A public workspace in Cards view, showing the List, Cards, Folders and Folders + Cards view switcher above document cards that each carry status, version, page count, tags, and Chat and Edit actions." title="Use public workspaces step 5" capture="Capture the use public workspaces task at this step in SimpleChat with realistic sample data and redact secrets." %} diff --git a/docs/guides/use-web-search.md b/docs/guides/use-web-search.md index 29cda26d8..5e6998e49 100644 --- a/docs/guides/use-web-search.md +++ b/docs/guides/use-web-search.md @@ -1,64 +1,106 @@ --- layout: page title: "Use web search" -description: "Send the current chat message to Bing web search when fresh web information is needed." +description: "Ground a chat answer in current public web results, and understand exactly what leaves SimpleChat when you do." section: "Guides" audience: user --- ## What this does -**Web** turns on Bing web search for the current chat message. When the user notice is enabled, SimpleChat explains that only the current message is sent for web search. +**Web** grounds a single chat message in current public web results. When you turn it on and send a message, SimpleChat hands that message to an Azure AI Foundry agent your administrator configured. That agent uses the Grounding with Bing Search service to run the search and returns summarized results together with the source links. Those results are added to the context for your answer, so the model can respond with information published after its training cutoff, and you get citations you can click and verify. -{% include media.html type="video" - title="Use web search walkthrough" - poster="video-posters/guide-use-web-search.png" - capture="Recording planned. Show use web search end to end and explain why this task helps a user." %} +This replaced the direct Bing search integration that Microsoft retired. The agent-based path is why an administrator has to configure a Foundry project and agent before the **Web** control appears at all. + +{% include media.html src="workflow-web_search.png" + alt="Flow diagram: a prompt goes from the user through the web UI to the backend API, which decides whether web search is used. If it is, an Azure AI Foundry agent queries Bing Search and returns grounded context and citations, which are combined with workspace context in the Azure OpenAI chat completion that produces the answer." + title="How a web-search message is answered" + caption="Conversation history goes to the chat completion. Only the search query goes to the Foundry agent and on to Bing." %} + +## What leaves SimpleChat + +This is the part worth reading carefully, because web search is the one chat feature that sends your content to a service outside the Azure compliance boundary. + +**Exactly one thing is sent to the search boundary: the message you just typed.** SimpleChat derives the search query from the current user message alone, trimmed of surrounding whitespace. It is not rewritten using earlier turns, not summarized from the conversation, and not expanded with anything the model already knows about your session. + +The following are **never** sent for web search: + +- Earlier messages in the conversation, from you or the assistant. +- Documents in your personal, group, or public workspaces. +- The contents of files you attached to the conversation. +- System prompts, agent instructions, or agent action configuration. +- Workspace names, document titles, tags, or classification labels. + +The practical consequence is simple and worth internalizing: **the message you type is the disclosure decision.** If you would not paste that sentence into a public search engine, do not send it with **Web** turned on. Nothing else in the conversation goes with it, and nothing you said earlier gets pulled along behind you. + +Everything else behaves normally. Conversation history and any workspace results are still sent to Azure OpenAI to compose the answer, exactly as they are for a message without web search. The narrow boundary described above is specifically the external search hop. + +### Deep Research sends more queries, but still no history + +[Deep Research]({{ '/guides/use-deep-research/' | relative_url }}) builds on this same search path. Instead of a single query, it plans several related queries and runs each one through the same Foundry agent. + +Those additional queries are all derived from your current message. Turning on Deep Research increases how many searches leave SimpleChat; it does not widen what they are derived from, and it does not start sending conversation history. + +### Compliance boundary + +An administrator had to accept this notice before web search could be enabled: + +> When you use Grounding with Bing Search, your customer data is transferred outside of the Azure compliance boundary to the Grounding with Bing Search service. Grounding with Bing Search is not subject to the same data processing terms (including location of processing) and does not have the same compliance standards and certifications as the Azure AI Agent Service, as described in the Grounding with Bing Search TOU. + +If your organization has rules about what may be sent to consumer search services, those rules apply to the text you type into a web-search message. ## Why you would use this -Use web search when an answer depends on current public information rather than workspace documents or model memory. It replaces searching the web yourself and pasting snippets; it is wrong for confidential prompts or answers that must come only from approved internal files. +Use web search when the answer depends on current public information rather than on your workspace documents or the model's training data. Product releases, current prices, recent news, changed public documentation, and "what is the latest version of X" all qualify. + +It is the wrong tool when the authoritative answer lives in your own approved files, when the prompt itself is confidential, or when you need a reproducible answer, since public sources change underneath you. ## Before you start -- Admins must enable `enable_web_search` and complete consent/configuration; see [Search and Extract]({{ '/admin/knowledge/' | relative_url }}). -- `enable_web_search_user_notice` may show a notice while web search is active. -- Do not include sensitive content in a web-search prompt. +- An administrator must enable `enable_web_search` **and** accept the data-handling consent. Both are required; the toggle alone does nothing until consent is recorded. See [Search and Extract]({{ '/admin/knowledge/' | relative_url }}). +- An administrator must configure a Foundry project endpoint and an agent ID. If the agent is missing, SimpleChat tells you web search is unavailable rather than quietly answering from training data. +- If your tenant enables the user notice, a banner appears above the composer while **Web** is active. ## Steps 1. Open **Chat**. -2. Write a question that needs current public information. +2. Write a question that needs current public information. Write it as a self-contained question, because the rest of the conversation is not sent with it. "What changed in the latest release of X" works; "what about the newest one" does not, since the search never sees what "one" referred to. 3. Select **Web**. {% include media.html src="guides/use-web-search-step-3.png" - alt="Screenshot showing use web search step 3." - title="Use web search step 3" - capture="Capture the use web search task at this step in SimpleChat with realistic sample data and redact secrets." %} + alt="The chat composer with the Web control switched on and the data notice banner visible above the message box." + title="Turning on Web for a message" + capture="Show the chat composer with Web enabled and the web search notice banner visible above it. Use a neutral sample question." %} -4. Read and dismiss the web search notice if it appears. +4. Read the notice if it appears. Dismissing it hides it for the rest of the browser session; it does not turn web search off. 5. Select **Send Message**. {% include media.html src="guides/use-web-search-step-5.png" - alt="Screenshot showing use web search step 5." - title="Use web search step 5" - capture="Capture the use web search task at this step in SimpleChat with realistic sample data and redact secrets." %} + alt="A chat answer grounded in web search, with source links listed beneath the response." + title="A grounded answer with its sources" + capture="Show a completed web-search answer with the source citations visible beneath it. Use a neutral public topic and redact any tenant identifiers." %} -6. Turn **Web** off for later messages that should not use public search. +6. Turn **Web** off for later messages that should not go to public search. It stays on until you turn it off. ## Verify it worked -The answer should use web search when relevant. The notice appears only while web search is active and the tenant settings allow it. +A grounded answer arrives with source links attached, the same way [Deep Research]({{ '/guides/use-deep-research/' | relative_url }}) presents its sources. Open one and confirm it supports the claim you care about. + +If the search could not run, the assistant says so explicitly. It is instructed not to fall back to training data and present it as current, so "I could not complete the web search" is the correct, working behavior rather than a failure to answer. ## Troubleshooting | Symptom | Likely cause | Fix | | --- | --- | --- | -| **Web** is missing | Web search is disabled or consent is not accepted | Ask an admin to review `enable_web_search`. | -| Web turns off in **Image** mode | Image generation disables source controls | Turn off **Image** first. | +| **Web** is missing from the composer | Web search is disabled, or consent was never accepted | Ask an admin to review `enable_web_search` and the consent step. | +| The assistant says web search is unavailable | No Foundry agent ID is configured | Ask an admin to finish the Foundry agent configuration and use the built-in test button. | +| The assistant says the search failed | The Foundry agent call errored | Retry. If it persists, ask an admin to check the agent's credentials and role assignments. | +| The answer ignores current information | **Web** was off when the message was sent | Turn **Web** on and resend. It applies per message. | +| **Web** turns off in **Image** mode | Image generation disables source controls | Turn off **Image** first. | +| The notice stopped appearing | You dismissed it earlier in this browser session | It returns in a new session. Web search is unaffected either way. | ## Related -- [Review pasted URLs]({{ '/guides/review-pasted-urls/' | relative_url }}) - [Use deep research]({{ '/guides/use-deep-research/' | relative_url }}) +- [Review pasted URLs]({{ '/guides/review-pasted-urls/' | relative_url }}) - [Search and Extract]({{ '/admin/knowledge/' | relative_url }}) diff --git a/docs/images/admin/backup-recovery-overview.png b/docs/images/admin/backup-recovery-overview.png new file mode 100644 index 000000000..10933f027 Binary files /dev/null and b/docs/images/admin/backup-recovery-overview.png differ diff --git a/docs/images/admin/data-lifecycle-overview.png b/docs/images/admin/data-lifecycle-overview.png new file mode 100644 index 000000000..65a3f39c5 Binary files /dev/null and b/docs/images/admin/data-lifecycle-overview.png differ diff --git a/docs/images/admin/governance-overview.png b/docs/images/admin/governance-overview.png new file mode 100644 index 000000000..757957acd Binary files /dev/null and b/docs/images/admin/governance-overview.png differ diff --git a/docs/images/admin/workflow-overview.png b/docs/images/admin/workflow-overview.png new file mode 100644 index 000000000..529d71801 Binary files /dev/null and b/docs/images/admin/workflow-overview.png differ diff --git a/docs/images/guides/admin-enable-a-capability-dependencies.png b/docs/images/guides/admin-enable-a-capability-dependencies.png new file mode 100644 index 000000000..e123377c1 Binary files /dev/null and b/docs/images/guides/admin-enable-a-capability-dependencies.png differ diff --git a/docs/images/guides/admin-enable-a-capability-guardrails.png b/docs/images/guides/admin-enable-a-capability-guardrails.png new file mode 100644 index 000000000..aa99375bf Binary files /dev/null and b/docs/images/guides/admin-enable-a-capability-guardrails.png differ diff --git a/docs/images/guides/admin-first-configuration-general.png b/docs/images/guides/admin-first-configuration-general.png new file mode 100644 index 000000000..65a76d3ab Binary files /dev/null and b/docs/images/guides/admin-first-configuration-general.png differ diff --git a/docs/images/guides/admin-first-configuration-models.png b/docs/images/guides/admin-first-configuration-models.png new file mode 100644 index 000000000..481e58efe Binary files /dev/null and b/docs/images/guides/admin-first-configuration-models.png differ diff --git a/docs/images/guides/admin-first-configuration-workspaces.png b/docs/images/guides/admin-first-configuration-workspaces.png new file mode 100644 index 000000000..9f7187b01 Binary files /dev/null and b/docs/images/guides/admin-first-configuration-workspaces.png differ diff --git a/docs/images/guides/create-a-file-sync-step-3.png b/docs/images/guides/create-a-file-sync-step-3.png new file mode 100644 index 000000000..eba5f0317 Binary files /dev/null and b/docs/images/guides/create-a-file-sync-step-3.png differ diff --git a/docs/images/guides/create-a-file-sync-step-9.png b/docs/images/guides/create-a-file-sync-step-9.png new file mode 100644 index 000000000..92b257a34 Binary files /dev/null and b/docs/images/guides/create-a-file-sync-step-9.png differ diff --git a/docs/images/guides/create-a-workflow-step-3.png b/docs/images/guides/create-a-workflow-step-3.png new file mode 100644 index 000000000..5b7991c58 Binary files /dev/null and b/docs/images/guides/create-a-workflow-step-3.png differ diff --git a/docs/images/guides/create-an-action-step-3.png b/docs/images/guides/create-an-action-step-3.png new file mode 100644 index 000000000..67701bdda Binary files /dev/null and b/docs/images/guides/create-an-action-step-3.png differ diff --git a/docs/images/guides/create-an-action-step-6.png b/docs/images/guides/create-an-action-step-6.png new file mode 100644 index 000000000..8f5d3a369 Binary files /dev/null and b/docs/images/guides/create-an-action-step-6.png differ diff --git a/docs/images/guides/create-an-agent-step-3.png b/docs/images/guides/create-an-agent-step-3.png new file mode 100644 index 000000000..7b3ad74a5 Binary files /dev/null and b/docs/images/guides/create-an-agent-step-3.png differ diff --git a/docs/images/guides/create-an-agent-step-8.png b/docs/images/guides/create-an-agent-step-8.png new file mode 100644 index 000000000..63600c922 Binary files /dev/null and b/docs/images/guides/create-an-agent-step-8.png differ diff --git a/docs/images/guides/create-an-agent-with-actions-step-3.png b/docs/images/guides/create-an-agent-with-actions-step-3.png new file mode 100644 index 000000000..3ae0a0fe9 Binary files /dev/null and b/docs/images/guides/create-an-agent-with-actions-step-3.png differ diff --git a/docs/images/guides/create-an-agent-with-actions-step-6.png b/docs/images/guides/create-an-agent-with-actions-step-6.png new file mode 100644 index 000000000..c3f9c6eb7 Binary files /dev/null and b/docs/images/guides/create-an-agent-with-actions-step-6.png differ diff --git a/docs/images/guides/create-and-manage-tags-step-3.png b/docs/images/guides/create-and-manage-tags-step-3.png new file mode 100644 index 000000000..2d53f7c9b Binary files /dev/null and b/docs/images/guides/create-and-manage-tags-step-3.png differ diff --git a/docs/images/guides/create-and-manage-tags-step-7.png b/docs/images/guides/create-and-manage-tags-step-7.png new file mode 100644 index 000000000..21e782815 Binary files /dev/null and b/docs/images/guides/create-and-manage-tags-step-7.png differ diff --git a/docs/images/guides/generate-images-step-3.png b/docs/images/guides/generate-images-step-3.png new file mode 100644 index 000000000..3e76eab28 Binary files /dev/null and b/docs/images/guides/generate-images-step-3.png differ diff --git a/docs/images/guides/lock-workspace-scope-step-3.png b/docs/images/guides/lock-workspace-scope-step-3.png new file mode 100644 index 000000000..3657d0c31 Binary files /dev/null and b/docs/images/guides/lock-workspace-scope-step-3.png differ diff --git a/docs/images/guides/manage-group-workspaces-step-3.png b/docs/images/guides/manage-group-workspaces-step-3.png new file mode 100644 index 000000000..452bbfcc5 Binary files /dev/null and b/docs/images/guides/manage-group-workspaces-step-3.png differ diff --git a/docs/images/guides/manage-group-workspaces-step-5.png b/docs/images/guides/manage-group-workspaces-step-5.png new file mode 100644 index 000000000..8bbf114fa Binary files /dev/null and b/docs/images/guides/manage-group-workspaces-step-5.png differ diff --git a/docs/images/guides/manage-notifications-step-3.png b/docs/images/guides/manage-notifications-step-3.png new file mode 100644 index 000000000..52afaee6e Binary files /dev/null and b/docs/images/guides/manage-notifications-step-3.png differ diff --git a/docs/images/guides/review-approval-requests-step-3.png b/docs/images/guides/review-approval-requests-step-3.png new file mode 100644 index 000000000..ee295fc01 Binary files /dev/null and b/docs/images/guides/review-approval-requests-step-3.png differ diff --git a/docs/images/guides/review-pasted-urls-step-3.png b/docs/images/guides/review-pasted-urls-step-3.png new file mode 100644 index 000000000..a97963938 Binary files /dev/null and b/docs/images/guides/review-pasted-urls-step-3.png differ diff --git a/docs/images/guides/send-feedback-step-3.png b/docs/images/guides/send-feedback-step-3.png new file mode 100644 index 000000000..67be641ed Binary files /dev/null and b/docs/images/guides/send-feedback-step-3.png differ diff --git a/docs/images/guides/send-feedback-step-6.png b/docs/images/guides/send-feedback-step-6.png new file mode 100644 index 000000000..9595df85e Binary files /dev/null and b/docs/images/guides/send-feedback-step-6.png differ diff --git a/docs/images/guides/trigger-a-workflow-step-3.png b/docs/images/guides/trigger-a-workflow-step-3.png new file mode 100644 index 000000000..1c549eaca Binary files /dev/null and b/docs/images/guides/trigger-a-workflow-step-3.png differ diff --git a/docs/images/guides/update-profile-preferences-step-3.png b/docs/images/guides/update-profile-preferences-step-3.png new file mode 100644 index 000000000..7b85fda53 Binary files /dev/null and b/docs/images/guides/update-profile-preferences-step-3.png differ diff --git a/docs/images/guides/update-profile-preferences-step-5.png b/docs/images/guides/update-profile-preferences-step-5.png new file mode 100644 index 000000000..00675da56 Binary files /dev/null and b/docs/images/guides/update-profile-preferences-step-5.png differ diff --git a/docs/images/guides/use-deep-research-step-3.png b/docs/images/guides/use-deep-research-step-3.png new file mode 100644 index 000000000..8188756cd Binary files /dev/null and b/docs/images/guides/use-deep-research-step-3.png differ diff --git a/docs/images/guides/use-public-workspaces-step-3.png b/docs/images/guides/use-public-workspaces-step-3.png new file mode 100644 index 000000000..afeab11d7 Binary files /dev/null and b/docs/images/guides/use-public-workspaces-step-3.png differ diff --git a/docs/images/guides/use-public-workspaces-step-5.png b/docs/images/guides/use-public-workspaces-step-5.png new file mode 100644 index 000000000..15be2dfa9 Binary files /dev/null and b/docs/images/guides/use-public-workspaces-step-5.png differ diff --git a/docs/images/guides/use-web-search-step-3.png b/docs/images/guides/use-web-search-step-3.png new file mode 100644 index 000000000..46f134513 Binary files /dev/null and b/docs/images/guides/use-web-search-step-3.png differ diff --git a/docs/images/reference/actions-azure-maps-openlayers-configuration.png b/docs/images/reference/actions-azure-maps-openlayers-configuration.png new file mode 100644 index 000000000..8f5d3a369 Binary files /dev/null and b/docs/images/reference/actions-azure-maps-openlayers-configuration.png differ diff --git a/docs/images/reference/actions-blob-storage-configuration.png b/docs/images/reference/actions-blob-storage-configuration.png new file mode 100644 index 000000000..cd0d05492 Binary files /dev/null and b/docs/images/reference/actions-blob-storage-configuration.png differ diff --git a/docs/images/reference/actions-chart-configuration.png b/docs/images/reference/actions-chart-configuration.png new file mode 100644 index 000000000..e59a1f853 Binary files /dev/null and b/docs/images/reference/actions-chart-configuration.png differ diff --git a/docs/images/reference/actions-cosmos-query-configuration.png b/docs/images/reference/actions-cosmos-query-configuration.png new file mode 100644 index 000000000..a08ec16af Binary files /dev/null and b/docs/images/reference/actions-cosmos-query-configuration.png differ diff --git a/docs/images/reference/actions-databricks-configuration.png b/docs/images/reference/actions-databricks-configuration.png new file mode 100644 index 000000000..d93d9b3d4 Binary files /dev/null and b/docs/images/reference/actions-databricks-configuration.png differ diff --git a/docs/images/reference/actions-document-search-configuration.png b/docs/images/reference/actions-document-search-configuration.png new file mode 100644 index 000000000..5501debe4 Binary files /dev/null and b/docs/images/reference/actions-document-search-configuration.png differ diff --git a/docs/images/reference/actions-log-analytics-configuration.png b/docs/images/reference/actions-log-analytics-configuration.png new file mode 100644 index 000000000..bd84b7b48 Binary files /dev/null and b/docs/images/reference/actions-log-analytics-configuration.png differ diff --git a/docs/images/reference/actions-mcp-configuration.png b/docs/images/reference/actions-mcp-configuration.png new file mode 100644 index 000000000..afbebfb3d Binary files /dev/null and b/docs/images/reference/actions-mcp-configuration.png differ diff --git a/docs/images/reference/actions-msgraph-configuration.png b/docs/images/reference/actions-msgraph-configuration.png new file mode 100644 index 000000000..64b021de5 Binary files /dev/null and b/docs/images/reference/actions-msgraph-configuration.png differ diff --git a/docs/images/reference/actions-openapi-configuration.png b/docs/images/reference/actions-openapi-configuration.png new file mode 100644 index 000000000..ce68e7ac2 Binary files /dev/null and b/docs/images/reference/actions-openapi-configuration.png differ diff --git a/docs/images/reference/actions-rocksdb-configuration.png b/docs/images/reference/actions-rocksdb-configuration.png new file mode 100644 index 000000000..cb2bacce8 Binary files /dev/null and b/docs/images/reference/actions-rocksdb-configuration.png differ diff --git a/docs/images/reference/actions-simplechat-configuration.png b/docs/images/reference/actions-simplechat-configuration.png new file mode 100644 index 000000000..b3f472a08 Binary files /dev/null and b/docs/images/reference/actions-simplechat-configuration.png differ diff --git a/docs/images/reference/chat-controls-composer-tools.png b/docs/images/reference/chat-controls-composer-tools.png new file mode 100644 index 000000000..a656484b0 Binary files /dev/null and b/docs/images/reference/chat-controls-composer-tools.png differ diff --git a/docs/images/reference/chat-controls-conversation-header.png b/docs/images/reference/chat-controls-conversation-header.png new file mode 100644 index 000000000..02229b555 Binary files /dev/null and b/docs/images/reference/chat-controls-conversation-header.png differ diff --git a/docs/images/reference/chat-controls-conversation-list.png b/docs/images/reference/chat-controls-conversation-list.png new file mode 100644 index 000000000..583a51db1 Binary files /dev/null and b/docs/images/reference/chat-controls-conversation-list.png differ diff --git a/docs/images/reference/chat-controls-conversation-search.png b/docs/images/reference/chat-controls-conversation-search.png new file mode 100644 index 000000000..f3af89fd8 Binary files /dev/null and b/docs/images/reference/chat-controls-conversation-search.png differ diff --git a/docs/images/reference/chat-controls-grounded-search.png b/docs/images/reference/chat-controls-grounded-search.png new file mode 100644 index 000000000..3657d0c31 Binary files /dev/null and b/docs/images/reference/chat-controls-grounded-search.png differ diff --git a/docs/images/reference/chat-controls-selectors.png b/docs/images/reference/chat-controls-selectors.png new file mode 100644 index 000000000..ae76b3c28 Binary files /dev/null and b/docs/images/reference/chat-controls-selectors.png differ diff --git a/docs/reference/actions/azure-maps-openlayers.md b/docs/reference/actions/azure-maps-openlayers.md index 4beb5b684..3395d3c3d 100644 --- a/docs/reference/actions/azure-maps-openlayers.md +++ b/docs/reference/actions/azure-maps-openlayers.md @@ -8,7 +8,7 @@ audience: user -{% include media.html src="reference/actions-azure-maps-openlayers-configuration.png" alt="Azure Maps OpenLayers action setup or assignment UI." title="Azure Maps OpenLayers action" capture="Capture the Azure Maps OpenLayers action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} +{% include media.html src="reference/actions-azure-maps-openlayers-configuration.png" alt="The Configuration step of the Add Action wizard for Azure Maps, showing the built-in action notice, the Azure Maps subscription key field, and a Test Connection button." title="Azure Maps OpenLayers action configuration" capture="Capture the Azure Maps OpenLayers action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} ## What this action does diff --git a/docs/reference/actions/blob-storage.md b/docs/reference/actions/blob-storage.md index bc515aa9a..4927aa7d9 100644 --- a/docs/reference/actions/blob-storage.md +++ b/docs/reference/actions/blob-storage.md @@ -8,7 +8,7 @@ audience: user -{% include media.html src="reference/actions-blob-storage-configuration.png" alt="Blob Storage action setup or assignment UI." title="Blob Storage action" capture="Capture the Blob Storage action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} +{% include media.html src="reference/actions-blob-storage-configuration.png" alt="The Blob Storage configuration pane showing the container-scoped notice, authentication type, connection string, container name and blob prefix fields, and the default capability toggles for listing and reading blobs." title="Blob Storage action configuration" capture="Capture the Blob Storage action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} ## What this action does diff --git a/docs/reference/actions/chart.md b/docs/reference/actions/chart.md index 81eaf3ef0..a8b6aa317 100644 --- a/docs/reference/actions/chart.md +++ b/docs/reference/actions/chart.md @@ -8,7 +8,7 @@ audience: user -{% include media.html src="reference/actions-chart-configuration.png" alt="Chart action setup or assignment UI." title="Chart action" capture="Capture the Chart action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} +{% include media.html src="reference/actions-chart-configuration.png" alt="The Chart configuration pane noting charts render with the internal Chart.js bundle, above toggles for the default chart types including line, bar, pie, doughnut, scatter, area, bubble, radar, and stacked bar." title="Chart action configuration" capture="Capture the Chart action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} ## What this action does diff --git a/docs/reference/actions/cosmos-query.md b/docs/reference/actions/cosmos-query.md index f1ada56e5..ffbcea765 100644 --- a/docs/reference/actions/cosmos-query.md +++ b/docs/reference/actions/cosmos-query.md @@ -8,7 +8,7 @@ audience: user -{% include media.html src="reference/actions-cosmos-query-configuration.png" alt="Cosmos Query action setup or assignment UI." title="Cosmos Query action" capture="Capture the Cosmos Query action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} +{% include media.html src="reference/actions-cosmos-query-configuration.png" alt="The Cosmos configuration pane showing account endpoint, database, container and partition key path fields, with Managed Identity selected as the authentication method." title="Cosmos Query action configuration" capture="Capture the Cosmos Query action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} ## What this action does diff --git a/docs/reference/actions/databricks.md b/docs/reference/actions/databricks.md index 7f54c5d2a..030d2eaa9 100644 --- a/docs/reference/actions/databricks.md +++ b/docs/reference/actions/databricks.md @@ -8,7 +8,7 @@ audience: user -{% include media.html src="reference/actions-databricks-configuration.png" alt="Databricks action configuration UI." title="Databricks configuration" capture="Capture Workspace and Warehouse, Authentication, Execution Limits, and Test Connection. Redact tokens and IDs if needed." %} +{% include media.html src="reference/actions-databricks-configuration.png" alt="The Databricks configuration pane showing workspace URL, cloud, SQL warehouse ID, default catalog and schema, personal access token authentication, and execution limits." title="Databricks action configuration" capture="Capture Workspace and Warehouse, Authentication, Execution Limits, and Test Connection. Redact tokens and IDs if needed." %} ## What this action does diff --git a/docs/reference/actions/document-search.md b/docs/reference/actions/document-search.md index 4695211ed..d7a4324e2 100644 --- a/docs/reference/actions/document-search.md +++ b/docs/reference/actions/document-search.md @@ -8,7 +8,7 @@ audience: user -{% include media.html src="reference/actions-document-search-configuration.png" alt="Document Search action setup or assignment UI." title="Document Search action" capture="Capture the Document Search action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} +{% include media.html src="reference/actions-document-search-configuration.png" alt="The Document Search configuration pane noting that the action uses internal search and the current user's access, with default scope, result limit, windowing, and summary settings." title="Document Search action configuration" capture="Capture the Document Search action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} ## What this action does diff --git a/docs/reference/actions/log-analytics.md b/docs/reference/actions/log-analytics.md index b7decd5b6..de850e269 100644 --- a/docs/reference/actions/log-analytics.md +++ b/docs/reference/actions/log-analytics.md @@ -8,7 +8,7 @@ audience: user -{% include media.html src="reference/actions-log-analytics-configuration.png" alt="Log Analytics action setup or assignment UI." title="Log Analytics action" capture="Capture the Log Analytics action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} +{% include media.html src="reference/actions-log-analytics-configuration.png" alt="The Log Analytics configuration pane showing workspace ID, cloud and API endpoint fields, Managed Identity authentication with a note about the Log Analytics Reader role, and a Test Connection button." title="Log Analytics action configuration" capture="Capture the Log Analytics action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} ## What this action does diff --git a/docs/reference/actions/mcp.md b/docs/reference/actions/mcp.md index 8687bfd29..d54ec7699 100644 --- a/docs/reference/actions/mcp.md +++ b/docs/reference/actions/mcp.md @@ -8,7 +8,7 @@ audience: user -{% include media.html src="reference/actions-mcp-configuration.png" alt="MCP action configuration UI." title="MCP configuration" capture="Capture MCP Server, Authentication, Tool Exposure, Timeouts and Retries, Discover Tools, and Test Connection. Redact secrets." %} +{% include media.html src="reference/actions-mcp-configuration.png" alt="The MCP Server configuration pane showing the preconfigured server template selector, server preset, transport and endpoint fields, the authentication method, and a custom headers JSON box noting header values are treated as secrets." title="MCP action configuration" capture="Capture MCP Server, Authentication, Tool Exposure, Timeouts and Retries, Discover Tools, and Test Connection. Redact secrets." %} ## What this action does diff --git a/docs/reference/actions/msgraph.md b/docs/reference/actions/msgraph.md index 936a84ef3..f314e956e 100644 --- a/docs/reference/actions/msgraph.md +++ b/docs/reference/actions/msgraph.md @@ -8,7 +8,7 @@ audience: user -{% include media.html src="reference/actions-msgraph-configuration.png" alt="Microsoft Graph action configuration UI." title="Microsoft Graph configuration" capture="Capture Default Microsoft Graph Capabilities and mail/calendar delivery settings. Redact user identifiers." %} +{% include media.html src="reference/actions-msgraph-configuration.png" alt="The Microsoft Graph configuration pane noting the action uses the signed-in user's delegated permissions, above capability toggles for reading profile, mailbox timezone, calendar events, and mail, and for creating calendar invites and sending mail with their delivery mode selectors." title="Microsoft Graph action configuration" capture="Capture Default Microsoft Graph Capabilities and mail/calendar delivery settings. Redact user identifiers." %} ## What this action does diff --git a/docs/reference/actions/openapi.md b/docs/reference/actions/openapi.md index 4f5090ecb..866974d86 100644 --- a/docs/reference/actions/openapi.md +++ b/docs/reference/actions/openapi.md @@ -8,7 +8,7 @@ audience: user -{% include media.html src="reference/actions-openapi-configuration.png" alt="OpenAPI action configuration UI." title="OpenAPI configuration" capture="Capture OpenAPI Configuration, Authentication Configuration, API Information, and Test Connection. Redact secrets." %} +{% include media.html src="reference/actions-openapi-configuration.png" alt="The API configuration pane showing the OpenAPI specification file picker, the base URL field with a note that it is auto-populated from the spec, the authentication type selector, and a Test Connection button." title="OpenAPI action configuration" capture="Capture OpenAPI Configuration, Authentication Configuration, API Information, and Test Connection. Redact secrets." %} ## What this action does diff --git a/docs/reference/actions/rocksdb.md b/docs/reference/actions/rocksdb.md index 45e14943e..52d07c0d0 100644 --- a/docs/reference/actions/rocksdb.md +++ b/docs/reference/actions/rocksdb.md @@ -8,7 +8,7 @@ audience: user -{% include media.html src="reference/actions-rocksdb-configuration.png" alt="RocksDB action setup or assignment UI." title="RocksDB action" capture="Capture the RocksDB action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} +{% include media.html src="reference/actions-rocksdb-configuration.png" alt="The RocksDB configuration pane showing the service base URL and authentication scheme, and data handling options for column family, read-only mode, key and value encoding, and key prefix hints." title="RocksDB action configuration" capture="Capture the RocksDB action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} ## What this action does diff --git a/docs/reference/actions/simplechat.md b/docs/reference/actions/simplechat.md index dc569d80e..10b79ce8e 100644 --- a/docs/reference/actions/simplechat.md +++ b/docs/reference/actions/simplechat.md @@ -8,7 +8,7 @@ audience: user -{% include media.html src="reference/actions-simplechat-configuration.png" alt="SimpleChat action setup or assignment UI." title="SimpleChat action" capture="Capture the SimpleChat action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} +{% include media.html src="reference/actions-simplechat-configuration.png" alt="The SimpleChat configuration pane noting the action needs no URL or external credentials, above capability toggles for creating groups, adding users, creating conversations and workflows, and uploading Markdown documents." title="SimpleChat action configuration" capture="Capture the SimpleChat action setup or assignment UI with relevant fields visible. Redact secrets and user identifiers." %} ## What this action does diff --git a/docs/reference/chat-controls.md b/docs/reference/chat-controls.md index 9f1cf5fbc..20a48d3a4 100644 --- a/docs/reference/chat-controls.md +++ b/docs/reference/chat-controls.md @@ -45,7 +45,7 @@ Use this page when you can see a control in Chat but are not sure what it does o | `search-documents-btn` | Opens the grounded search panel for searching workspace documents from chat. | Use it when the answer should come from personal or group workspace content instead of general model knowledge. | [`enable_group_workspaces`]({{ '/admin/workspaces/' | relative_url }})
[`enable_user_workspace`]({{ '/admin/workspaces/' | relative_url }}) | | `choose-file-btn` | Lets you select a supported local file and starts chat upload processing for the conversation. | Use it when the file is the immediate subject of the conversation and you do not want to visit Workspace first. | [`enable_chat_file_uploads`]({{ '/admin/workspaces/' | relative_url }}) | | `upload-btn` | Adds the selected upload to the chat after file selection. | Use it to confirm an upload before asking questions about that file. | [`enable_web_search`]({{ '/admin/knowledge/' | relative_url }}) | -| `search-web-btn` | Allows the chat to search the web using the configured Bing/Foundry web-search path. | Use it for current events, public facts, or external pages that are not in your workspaces. | [`enable_web_search`]({{ '/admin/knowledge/' | relative_url }}) | +| `search-web-btn` | Sends the current message to an admin-configured Azure AI Foundry agent, which searches the public web through Grounding with Bing Search and returns results with citations. | Use it for current events, public facts, or external pages that are not in your workspaces. Only the message you type is sent externally, never conversation history or workspace content. | [`enable_web_search`]({{ '/admin/knowledge/' | relative_url }}) | | `url-access-btn` | Opens review for URLs pasted into the message so they can be inspected by the chat flow. | Use it when pasted links should be fetched or reasoned over instead of treated as plain text. | [`enable_url_access`]({{ '/admin/knowledge/' | relative_url }}) | | `source-review-btn` | Starts Deep Research so SimpleChat can inspect search results and linked source pages within configured crawl limits. | Use it for research tasks where source review and evidence collection matter more than a quick answer. | [`enable_source_review`]({{ '/admin/knowledge/' | relative_url }}) | | `send-btn` | Sends the current composer message to the selected model or agent. | Use it once the prompt, files, scope, and optional tools are ready. | Always available | diff --git a/functional_tests/test_docs_link_integrity.py b/functional_tests/test_docs_link_integrity.py new file mode 100644 index 000000000..71e1a35e0 --- /dev/null +++ b/functional_tests/test_docs_link_integrity.py @@ -0,0 +1,434 @@ +#!/usr/bin/env python3 +""" +Functional test for documentation link integrity and media slot coverage. +Version: 0.261.003 +Implemented in: 0.261.003 + +The documentation site was reorganized: pages that used to live at +docs/how-to/.md moved to docs/guides/.md. Jekyll +redirects kept the published URLs alive, but repository-relative markdown links +in README.md and the deployer READMEs kept pointing at the old file paths. +Those links resolve to 404 on GitHub, where Jekyll redirects do not apply, and +nothing caught it. Forty-six such links had accumulated. + +This test ensures that: + + - Every relative markdown link in README.md, docs/, and deployers/ points at + a file that exists. + - Every Jekyll `relative_url` page link resolves to a real page, honoring + permalink and redirect_from front matter. + - Every page URL declared in docs/_data/features.yml resolves. + - Every `{% include media.html id="..." %}` names a slot that exists in + docs/_data/media.yml, so the site never renders an "Unknown media slot" + error card. + +Media coverage itself is reported but never fails the run. Missing screenshots +are tracked at /contributing/media-status/ and deliberately do not block a +change. See .github/instructions/docs_coverage.instructions.md. +""" + +import io +import os +import re +import sys +from collections import defaultdict +from pathlib import Path + +sys.path.append(os.path.dirname(os.path.abspath(__file__))) + +import yaml + +from test_support.versioning import assert_app_version_at_least + +REPO_ROOT = Path(__file__).resolve().parents[1] +DOCS_ROOT = REPO_ROOT / "docs" +IMAGES_ROOT = DOCS_ROOT / "images" +DEPLOYERS_ROOT = REPO_ROOT / "deployers" +MEDIA_FILE = DOCS_ROOT / "_data" / "media.yml" +FEATURES_DATA_FILE = DOCS_ROOT / "_data" / "features.yml" + +# Trees Jekyll never builds. Their pages stay readable on GitHub, so their +# markdown links still matter, but their site-relative links never render. +UNPUBLISHED_DOC_PATHS = ( + "explanation/features", + "explanation/fixes", + "explanation/release_notes.md", +) + +# Template directories hold Liquid, not pages. +TEMPLATE_DIRS = ("_includes", "_layouts", "_sass") + +ASSET_SUFFIXES = ( + ".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp", ".ico", + ".css", ".js", ".json", ".xml", ".yml", ".yaml", ".txt", + ".pdf", ".zip", ".csv", ".woff", ".woff2", +) + +MARKDOWN_LINK_RE = re.compile(r"\[([^\]\n]*)\]\(([^)\s]+)(?:\s+\"[^\"]*\")?\)") +RELATIVE_URL_RE = re.compile(r"\{\{\s*'([^']+)'\s*\|\s*relative_url\s*\}\}") +MEDIA_INCLUDE_RE = re.compile(r"\{%\s*include\s+media\.html(.*?)%\}", re.DOTALL) +MEDIA_ATTR_RE = re.compile(r'(\w+)\s*=\s*"([^"]*)"') +FENCED_CODE_RE = re.compile(r"^(```|~~~).*?^\1", re.MULTILINE | re.DOTALL) +FRONT_MATTER_RE = re.compile(r"\A---\r?\n(.*?)\r?\n---\r?\n", re.DOTALL) + + +def read_text(path): + """Read a file, tolerating encoding damage rather than aborting the run.""" + return io.open(path, encoding="utf-8", errors="ignore").read() + + +def strip_code_blocks(text): + """Blank out fenced code blocks so documented examples are not treated as links.""" + return FENCED_CODE_RE.sub(lambda match: "\n" * match.group(0).count("\n"), text) + + +def is_generated_build_output(path): + """True for anything inside a built site tree.""" + return "_site" in path.parts + + +def is_unpublished(path): + """True when Jekyll excludes the page from the built site.""" + try: + relative = path.relative_to(DOCS_ROOT).as_posix() + except ValueError: + return True + return any( + relative == entry or relative.startswith(entry.rstrip("/") + "/") + for entry in UNPUBLISHED_DOC_PATHS + ) + + +def is_template(path): + """True for Liquid templates rather than authored pages.""" + try: + parts = path.relative_to(DOCS_ROOT).parts + except ValueError: + return False + return bool(parts) and parts[0] in TEMPLATE_DIRS + + +def normalize_url(url): + """Reduce a site URL to a comparable /path/ form, or None if not site-internal.""" + candidate = str(url or "").split("#")[0].split("?")[0].strip() + if not candidate.startswith("/"): + return None + trimmed = candidate.strip("/") + return "/" if not trimmed else f"/{trimmed}/" + + +def parse_front_matter(text): + """Return the front matter mapping for a page, or an empty mapping.""" + match = FRONT_MATTER_RE.match(text) + if not match: + return {} + try: + loaded = yaml.safe_load(match.group(1)) + except yaml.YAMLError: + return {} + return loaded if isinstance(loaded, dict) else {} + + +def page_url_from_path(path): + """Derive the default site URL Jekyll would give a source page.""" + relative = path.relative_to(DOCS_ROOT).as_posix() + stem = relative.rsplit(".", 1)[0] + if stem == "index": + return "/" + if stem.endswith("/index"): + stem = stem[: -len("/index")] + return f"/{stem}/" + + +def iter_source_pages(): + """Yield every authored documentation page, excluding build output.""" + for suffix in ("*.md", "*.html"): + for path in DOCS_ROOT.rglob(suffix): + if is_generated_build_output(path) or is_template(path): + continue + yield path + + +def collect_known_urls(): + """Build the set of URLs the built site actually serves.""" + known = set() + for path in iter_source_pages(): + text = read_text(path) + front_matter = parse_front_matter(text) + + if is_unpublished(path): + continue + + permalink = front_matter.get("permalink") + if permalink: + known.add(normalize_url(permalink)) + else: + known.add(page_url_from_path(path)) + + redirects = front_matter.get("redirect_from") or [] + if isinstance(redirects, str): + redirects = [redirects] + for redirect in redirects: + normalized = normalize_url(redirect) + if normalized: + known.add(normalized) + + # The features collection is generated from _features/ with a permalink + # pattern, so those pages have no source file under a matching path. + for path in (DOCS_ROOT / "_features").glob("*.md"): + known.add(f"/features/{path.stem}/") + + known.discard(None) + return known + + +def iter_markdown_sources(): + """Yield every markdown file whose relative links are browsed on GitHub.""" + # Glob is case-insensitive on Windows and case-sensitive elsewhere, so + # collect into a set rather than scanning ReadMe.md twice on one platform. + seen = set() + readme = REPO_ROOT / "README.md" + if readme.exists(): + seen.add(readme) + for path in DOCS_ROOT.rglob("*.md"): + if not is_generated_build_output(path): + seen.add(path) + for pattern in ("*.md", "*.MD"): + seen.update(DEPLOYERS_ROOT.rglob(pattern)) + return sorted(seen) + + +def test_relative_markdown_links_resolve(): + """Relative markdown links must point at files that exist.""" + print("Checking relative markdown links resolve...") + + checked = 0 + broken = defaultdict(list) + + for path in iter_markdown_sources(): + text = strip_code_blocks(read_text(path)) + for match in MARKDOWN_LINK_RE.finditer(text): + label, target = match.group(1), match.group(2) + if target.startswith(("http://", "https://", "mailto:", "tel:", "#")): + continue + if "{{" in target or "{%" in target: + continue + file_part = target.split("#")[0] + if not file_part.lower().endswith(".md"): + continue + checked += 1 + if not (path.parent / file_part).resolve().exists(): + broken[path.relative_to(REPO_ROOT).as_posix()].append((label, target)) + + if broken: + total = sum(len(items) for items in broken.values()) + print(f" {total} of {checked} relative markdown links are broken:") + for source in sorted(broken): + print(f" {source}") + for label, target in broken[source]: + print(f" [{label}] -> {target}") + print(" Pages moved from docs/how-to/.md to " + "docs/guides/.md. Repoint the link, or drop the link " + "and keep the prose when the target no longer exists.") + return False + + print(f" All {checked} relative markdown links resolve.") + return True + + +def test_site_page_links_resolve(): + """Jekyll relative_url page links must resolve to real pages.""" + print("Checking site page links resolve...") + + known = collect_known_urls() + checked = 0 + broken = defaultdict(set) + + for path in iter_source_pages(): + if is_unpublished(path): + continue + text = strip_code_blocks(read_text(path)) + for match in RELATIVE_URL_RE.finditer(text): + target = match.group(1) + if target.lower().endswith(ASSET_SUFFIXES): + continue + normalized = normalize_url(target) + if normalized is None: + continue + checked += 1 + if normalized not in known: + broken[path.relative_to(DOCS_ROOT).as_posix()].add(target) + + if broken: + total = sum(len(items) for items in broken.values()) + print(f" {total} of {checked} site page links do not resolve:") + for source in sorted(broken): + print(f" {source}") + for target in sorted(broken[source]): + print(f" -> {target}") + print(" Repoint the link, or add a redirect_from entry on the page " + "that replaced the old URL.") + return False + + print(f" All {checked} site page links resolve.") + return True + + +def test_features_data_links_resolve(): + """Page URLs declared in features.yml must resolve.""" + print("Checking docs/_data/features.yml links resolve...") + + if not FEATURES_DATA_FILE.exists(): + print(" Skipped: features.yml not found.") + return True + + known = collect_known_urls() + data = yaml.safe_load(read_text(FEATURES_DATA_FILE)) or {} + + found = [] + + def walk(node, trail): + if isinstance(node, dict): + for key, value in node.items(): + if key == "url" and isinstance(value, str): + found.append((" > ".join(trail) or "(root)", value)) + else: + walk(value, trail + [str(key)]) + elif isinstance(node, list): + for index, value in enumerate(node): + walk(value, trail + [str(index)]) + + walk(data, []) + + checked = 0 + broken = [] + for trail, url in found: + if url.lower().endswith(ASSET_SUFFIXES) or not url.startswith("/"): + continue + checked += 1 + if normalize_url(url) not in known: + broken.append((trail, url)) + + if broken: + print(f" {len(broken)} of {checked} features.yml links do not resolve:") + for trail, url in broken: + print(f" {url} ({trail})") + return False + + print(f" All {checked} features.yml links resolve.") + return True + + +def load_media_registry(): + """Load the media slot registry.""" + if not MEDIA_FILE.exists(): + return {} + data = yaml.safe_load(read_text(MEDIA_FILE)) or {} + return data if isinstance(data, dict) else {} + + +def iter_media_slots(): + """Yield (page, attributes) for every media include across the site.""" + for path in iter_source_pages(): + text = strip_code_blocks(read_text(path)) + for match in MEDIA_INCLUDE_RE.finditer(text): + yield path, dict(MEDIA_ATTR_RE.findall(match.group(1))) + + +def test_media_slot_ids_are_known(): + """A media include by id must name a registered slot.""" + print("Checking media slot ids are registered...") + + registry = load_media_registry() + unknown = [] + checked = 0 + + for path, attrs in iter_media_slots(): + slot_id = attrs.get("id") + if not slot_id: + continue + checked += 1 + if slot_id not in registry: + unknown.append((path.relative_to(DOCS_ROOT).as_posix(), slot_id)) + + if unknown: + print(f" {len(unknown)} media include(s) name an unregistered slot:") + for source, slot_id in unknown: + print(f" {source} -> {slot_id}") + print(" These render a visible 'Unknown media slot' error card. Add the " + "entry to docs/_data/media.yml or correct the id.") + return False + + print(f" All {checked} media includes by id name a registered slot.") + return True + + +def report_media_coverage(): + """Report outstanding screenshots and videos without failing the run.""" + print("Reporting media coverage...") + + filled_images = 0 + missing_images = defaultdict(list) + filled_posters = 0 + missing_posters = 0 + registry = load_media_registry() + + for path, attrs in iter_media_slots(): + page = path.relative_to(DOCS_ROOT).as_posix() + entry = registry.get(attrs.get("id"), {}) if attrs.get("id") else {} + media_type = attrs.get("type") or entry.get("type") or "image" + + if media_type == "video": + poster = attrs.get("poster") or entry.get("poster") + if not poster: + continue + if (IMAGES_ROOT / poster).exists(): + filled_posters += 1 + else: + missing_posters += 1 + continue + + source = attrs.get("src") or entry.get("file") + if not source: + continue + if (IMAGES_ROOT / source).exists(): + filled_images += 1 + else: + missing_images[page.split("/")[0]].append(source) + + outstanding = sum(len(items) for items in missing_images.values()) + total_images = filled_images + outstanding + + print(f" Screenshots: {filled_images}/{total_images} filled, {outstanding} outstanding.") + for group in sorted(missing_images, key=lambda key: -len(missing_images[key])): + print(f" {group}: {len(missing_images[group])} outstanding") + print(f" Video posters: {filled_posters} filled, {missing_posters} outstanding.") + print(" Outstanding media never fails this test. Track it at " + "/contributing/media-status/.") + return True + + +if __name__ == "__main__": + assert_app_version_at_least("0.261.003") + + tests = [ + test_relative_markdown_links_resolve, + test_site_page_links_resolve, + test_features_data_links_resolve, + test_media_slot_ids_are_known, + report_media_coverage, + ] + + results = [] + for test in tests: + print(f"\nRunning {test.__name__}...") + try: + results.append(test()) + except Exception as error: # noqa: BLE001 - report and continue + print(f"Test raised an exception: {error}") + import traceback + traceback.print_exc() + results.append(False) + + print(f"\nResults: {sum(1 for r in results if r)}/{len(results)} checks passed") + sys.exit(0 if all(results) else 1) diff --git a/functional_tests/test_docs_release_notes_integrity.py b/functional_tests/test_docs_release_notes_integrity.py new file mode 100644 index 000000000..9b352985b --- /dev/null +++ b/functional_tests/test_docs_release_notes_integrity.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +""" +Functional test for release notes source and generated page parity. +Version: 0.261.003 +Implemented in: 0.261.003 + +docs/explanation/release_notes.md is the source of truth, and the pages under +docs/explanation/release-notes/ are generated from it by +scripts/build_release_notes_pages.py. + +That arrangement hid a data loss. The source was truncated from 46 version +sections to 19, dropping every v0.260 entry and v0.250.229 through v0.250.231, +but the generated pages were not rebuilt. The site kept serving the missing +history, so nothing looked wrong, and the repository sat one routine +regeneration away from erasing roughly 2,400 lines of release notes with no +visible cause. + +This test ensures that: + + - Every version documented on a generated page still exists in the source, + so a truncated source is caught immediately instead of at the next build. + - Every version in the source appears on a generated page, so stale pages + are caught before they can mask a later edit. +""" + +import io +import os +import re +import sys +from pathlib import Path + +sys.path.append(os.path.dirname(os.path.abspath(__file__))) + +from test_support.versioning import assert_app_version_at_least + +REPO_ROOT = Path(__file__).resolve().parents[1] +EXPLANATION_ROOT = REPO_ROOT / "docs" / "explanation" +SOURCE_FILE = EXPLANATION_ROOT / "release_notes.md" +GENERATED_DIR = EXPLANATION_ROOT / "release-notes" + +VERSION_HEADING_RE = re.compile(r"^### \*\*\((v[\d.]+)\)\*\*", re.MULTILINE) + + +def read_text(path): + """Read a release notes file.""" + return io.open(path, encoding="utf-8", errors="ignore").read() + + +def versions_in(path): + """Return the set of release versions documented in a file.""" + return set(VERSION_HEADING_RE.findall(read_text(path))) + + +def generated_versions(): + """Return every release version documented across the generated pages.""" + found = set() + for path in sorted(GENERATED_DIR.glob("*.md")): + found |= versions_in(path) + return found + + +def test_generated_pages_match_source(): + """The source file and the generated pages must document the same releases.""" + print("Checking release notes source and generated pages agree...") + + if not SOURCE_FILE.exists(): + print(f" Missing {SOURCE_FILE.relative_to(REPO_ROOT).as_posix()}.") + return False + + source = versions_in(SOURCE_FILE) + generated = generated_versions() + + missing_from_source = sorted(generated - source, reverse=True) + missing_from_pages = sorted(source - generated, reverse=True) + + if missing_from_source: + print(f" {len(missing_from_source)} release(s) are published but no longer " + f"in the source file:") + for version in missing_from_source[:30]: + print(f" {version}") + if len(missing_from_source) > 30: + print(f" ... and {len(missing_from_source) - 30} more") + print(" Regenerating would delete these from the site. Restore the " + "sections in docs/explanation/release_notes.md, then run " + "scripts/build_release_notes_pages.py.") + return False + + if missing_from_pages: + print(f" {len(missing_from_pages)} release(s) are in the source but not " + f"on any generated page:") + for version in missing_from_pages[:30]: + print(f" {version}") + if len(missing_from_pages) > 30: + print(f" ... and {len(missing_from_pages) - 30} more") + print(" The generated pages are stale. Run " + "scripts/build_release_notes_pages.py and commit the result.") + return False + + print(f" {len(source)} releases documented in both the source and the " + f"generated pages.") + return True + + +if __name__ == "__main__": + assert_app_version_at_least("0.261.003") + + tests = [test_generated_pages_match_source] + + results = [] + for test in tests: + print(f"\nRunning {test.__name__}...") + try: + results.append(test()) + except Exception as error: # noqa: BLE001 - report and continue + print(f"Test raised an exception: {error}") + import traceback + traceback.print_exc() + results.append(False) + + print(f"\nResults: {sum(1 for r in results if r)}/{len(results)} checks passed") + sys.exit(0 if all(results) else 1) diff --git a/functional_tests/test_docs_web_search_accuracy.py b/functional_tests/test_docs_web_search_accuracy.py new file mode 100644 index 000000000..8fd66e7de --- /dev/null +++ b/functional_tests/test_docs_web_search_accuracy.py @@ -0,0 +1,212 @@ +#!/usr/bin/env python3 +""" +Functional test for web search documentation accuracy. +Version: 0.261.003 +Implemented in: 0.261.003 + +The web search documentation described a direct Bing Web Search API +integration that was removed in v0.229.001. The implemented path is an Azure +AI Foundry agent carrying the Grounding with Bing Search tool. + +The documentation also understated the egress boundary that v0.241.022 +deliberately hardened: only the user's current chat message is sent to the +external search service. That is a privacy claim readers act on, so this test +ties it to the implementation. If build_web_search_query_text ever starts +folding in conversation history again, this test fails and forces the +documentation to be corrected with it, rather than leaving a false assurance +published. + +This test ensures that: + + - The web search guide states the egress boundary explicitly. + - The guide and its companion summaries describe the Foundry agent path. + - No documentation page still claims web search calls Bing directly. + - The query builder in the application still sends only the current message. +""" + +import io +import os +import re +import sys +from pathlib import Path + +sys.path.append(os.path.dirname(os.path.abspath(__file__))) + +from test_support.versioning import assert_app_version_at_least + +REPO_ROOT = Path(__file__).resolve().parents[1] +DOCS_ROOT = REPO_ROOT / "docs" +GUIDE = DOCS_ROOT / "guides" / "use-web-search.md" +CHAT_ROUTES = REPO_ROOT / "application" / "single_app" / "route_backend_chats.py" + +COMPANION_PAGES = ( + DOCS_ROOT / "guides" / "index.md", + DOCS_ROOT / "features.md", + DOCS_ROOT / "reference" / "chat-controls.md", + DOCS_ROOT / "admin" / "knowledge.md", +) + +# Wording that describes the retired direct-API integration rather than the +# Foundry agent that actually runs the search. +STALE_PHRASES = ( + "turns on Bing web search", + "Bing Web Search API", + "Bing-backed web search", + "sent to Bing web search", +) + +# Names that would indicate history leaking back into the outbound query. +HISTORY_IDENTIFIERS = ( + "conversation", + "history", + "messages", + "summary", + "summarize", + "context", + "previous", + "prior", +) + + +def read_text(path): + """Read a documentation or source file.""" + return io.open(path, encoding="utf-8", errors="ignore").read() + + +def test_guide_documents_egress_boundary(): + """The guide must state what does and does not leave the application.""" + print("Checking the web search guide documents the egress boundary...") + + text = read_text(GUIDE) + problems = [] + + if "## What leaves SimpleChat" not in text: + problems.append("no 'What leaves SimpleChat' section") + + if not re.search(r"only the (current )?message you just typed|current user message alone", + text, re.IGNORECASE): + problems.append("does not state that only the current message is sent") + + # The value of the section is the explicit exclusion list, not the summary. + for excluded in ("Earlier messages", "workspaces", "attached", "System prompts"): + if excluded.lower() not in text.lower(): + problems.append(f"exclusion list does not mention {excluded!r}") + + if "compliance boundary" not in text.lower(): + problems.append("does not carry the Grounding with Bing Search compliance notice") + + if "Deep Research" not in text: + problems.append("does not explain the Deep Research multi-query nuance") + + if problems: + print(f" {GUIDE.relative_to(REPO_ROOT).as_posix()} has {len(problems)} problem(s):") + for problem in problems: + print(f" {problem}") + return False + + print(" The guide documents the egress boundary, exclusions, and compliance notice.") + return True + + +def test_documentation_describes_foundry_agent_path(): + """Documentation must describe the Foundry agent rather than a direct Bing call.""" + print("Checking documentation describes the Foundry agent path...") + + guide_text = read_text(GUIDE) + problems = [] + + if "Azure AI Foundry" not in guide_text: + problems.append(f"{GUIDE.name}: does not name Azure AI Foundry") + if "Grounding with Bing Search" not in guide_text: + problems.append(f"{GUIDE.name}: does not name Grounding with Bing Search") + + for page in (GUIDE,) + COMPANION_PAGES: + if not page.exists(): + continue + text = read_text(page) + for phrase in STALE_PHRASES: + if phrase.lower() in text.lower(): + relative = page.relative_to(REPO_ROOT).as_posix() + problems.append(f"{relative}: still says {phrase!r}") + + if problems: + print(f" {len(problems)} problem(s):") + for problem in problems: + print(f" {problem}") + print(" The direct Bing Web Search API was removed in v0.229.001. Web " + "search runs through a configured Azure AI Foundry agent.") + return False + + print(" Guide and companion pages describe the Foundry agent path.") + return True + + +def test_query_builder_sends_only_current_message(): + """The outbound query must still be derived from the current message alone.""" + print("Checking the web search query builder still sends only the current message...") + + source = read_text(CHAT_ROUTES) + match = re.search( + r"^def build_web_search_query_text\(([^)]*)\):\n(.*?)(?=^\S)", + source, + re.MULTILINE | re.DOTALL, + ) + + if not match: + print(" Could not find build_web_search_query_text in route_backend_chats.py.") + print(" The documented egress boundary can no longer be verified.") + return False + + parameters = [item.strip() for item in match.group(1).split(",") if item.strip()] + body = match.group(2) + # The docstring describes the boundary in prose; only executable lines matter. + code = re.sub(r'""".*?"""', "", body, flags=re.DOTALL) + + problems = [] + + if parameters != ["user_message"]: + problems.append( + f"takes {parameters} instead of only 'user_message', so it can now " + "see more than the current message" + ) + + for identifier in HISTORY_IDENTIFIERS: + if re.search(rf"\b{identifier}\w*", code, re.IGNORECASE): + problems.append(f"body references {identifier!r}") + + if problems: + print(f" {len(problems)} problem(s) in build_web_search_query_text:") + for problem in problems: + print(f" {problem}") + print(" docs/guides/use-web-search.md promises readers that only the " + "current message leaves the application. Either restore that " + "behavior or update the guide, the chat control reference, and " + "the admin notice copy together.") + return False + + print(" build_web_search_query_text still derives the query from the current message alone.") + return True + + +if __name__ == "__main__": + assert_app_version_at_least("0.261.003") + + tests = [ + test_guide_documents_egress_boundary, + test_documentation_describes_foundry_agent_path, + test_query_builder_sends_only_current_message, + ] + + results = [] + for test in tests: + print(f"\nRunning {test.__name__}...") + try: + results.append(test()) + except Exception as error: # noqa: BLE001 - report and continue + print(f"Test raised an exception: {error}") + import traceback + traceback.print_exc() + results.append(False) + + print(f"\nResults: {sum(1 for r in results if r)}/{len(results)} checks passed") + sys.exit(0 if all(results) else 1)