Skip to content

Feature/support menu#824

Merged
paullizer merged 7 commits intoDevelopmentfrom
feature/support-menu
Apr 7, 2026
Merged

Feature/support menu#824
paullizer merged 7 commits intoDevelopmentfrom
feature/support-menu

Conversation

@paullizer
Copy link
Copy Markdown
Contributor

@paullizer paullizer commented Apr 7, 2026

  • Support Menu and User-Facing Latest Features

    • Added a configurable Support menu for signed-in app users so teams can expose Latest Features and Send Feedback directly in everyday navigation.
    • Admins can rename the Support menu, control the internal feedback-recipient email address, and choose exactly which latest-feature cards are shared with end users from the General tab.
    • The user-facing Latest Features page now mirrors the available admin screenshots more closely, includes clearer guidance about why each feature matters, and adds direct links into Chat, Personal Workspace, or Support destinations where users can try the feature.
    • The Admin Settings Latest Features tab now also calls out the General-tab User-Facing Latest Features checklist so admins can see where feature sharing is configured.
    • (Ref: support_menu_config.py, route_frontend_support.py, latest_features.html, support_send_feedback.html, admin_settings.html, test_support_menu_user_feature.py, support menu configuration and user-facing latest features)
  • Streaming Chat Post-Finalization JSON Sanitization

    • Fixed a repeatable late-stream failure where assistant responses could appear nearly complete and then end with a Stream interrupted warning during final persistence.
    • Normalized non-finite numeric values from citation payloads before assistant messages, assistant artifacts, and terminal chat payloads are written, preventing Cosmos DB from rejecting invalid JSON.
    • This improves reliability for streaming chat, compatibility streaming, and the standard JSON response path when tool or search citations include sparse or tabular numeric values.
    • (Ref: functions_message_artifacts.py, route_backend_chats.py, test_chat_post_stream_json_sanitization.py, post-stream citation sanitization)

@paullizer paullizer requested a review from Copilot April 7, 2026 18:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR introduces a configurable Support menu (Latest Features + Send Feedback) for signed-in users and hardens the chat finalization pipeline by sanitizing non-finite numeric values (NaN/±Infinity) before persistence/response emission to avoid Cosmos DB invalid-JSON failures.

Changes:

  • Added Support menu configuration, templates, JS, routes, and functional/UI coverage for sidebar/top-nav visibility and latest-features image modal previews.
  • Centralized post-stream JSON sanitization via make_json_serializable() and applied it across chat finalization, artifacts, and terminal SSE/JSON payloads.
  • Updated versioning and added fix/feature documentation for Support menu and chat post-stream sanitization.

Reviewed changes

Copilot reviewed 29 out of 45 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
ui_tests/test_support_menu_sidebar_visibility.py Adds UI regression test for Support section visibility in left sidebar when enabled.
ui_tests/test_support_latest_features_image_modal.py Adds UI regression test for Latest Features image modal behavior.
ui_tests/test_single_app_template_json_bootstrap_render.py Extends bootstrap render test to assert new Latest Features selectors on admin settings page.
functional_tests/test_support_menu_user_feature.py Adds functional “marker” tests to validate Support menu plumbing across templates/routes/config.
functional_tests/test_chat_post_stream_json_sanitization.py Adds regression tests ensuring non-finite values are sanitized pre-persistence/response.
functional_tests/test_admin_latest_features_tab.py Updates expected Latest Features tab markers and assets for new cards/screenshots.
docs/explanation/fixes/SUPPORT_MENU_SIDEBAR_VISIBILITY_FIX.md Documents Support menu sidebar visibility fix and validation.
docs/explanation/fixes/SUPPORT_LATEST_FEATURE_IMAGES_FIX.md Documents user Latest Features image modal parity and catalog/image updates.
docs/explanation/fixes/CHAT_STREAM_POST_FINALIZATION_JSON_SANITIZATION_FIX.md Documents the NaN/Infinity sanitization fix and impact.
docs/explanation/features/LATEST_FEATURES_ADMIN_TAB.md Updates admin Latest Features documentation for new cards/screenshots.
application/single_app/templates/support_send_feedback.html Adds user-facing Send Feedback page/template.
application/single_app/templates/latest_features.html Adds user-facing Latest Features page with gallery + modal + inline styling.
application/single_app/templates/admin_settings.html Adds Support menu admin configuration UI + expands Latest Features tab content.
application/single_app/templates/_top_nav.html Adds Support dropdown to top navigation when enabled and destinations available.
application/single_app/templates/_sidebar_short_nav.html Adds Support section to compact sidebar and collapsible behavior.
application/single_app/templates/_sidebar_nav.html Adds Support section to left sidebar and expands Latest Features nav entries.
application/single_app/support_menu_config.py Introduces shared Support latest-features catalog + visibility normalization helpers.
application/single_app/static/js/support/support_feedback.js Adds client logic to request server draft metadata + open mailto.
application/single_app/static/js/support/latest_features.js Adds Bootstrap modal wiring for user Latest Features thumbnails.
application/single_app/static/js/admin/admin_settings.js Adds admin-side DOM toggling for Support menu settings sections.
application/single_app/route_frontend_support.py Adds frontend routes for Support destinations (Latest Features, Send Feedback).
application/single_app/route_frontend_admin_settings.py Persists/normalizes Support settings and passes catalog to template.
application/single_app/route_backend_settings.py Adds backend endpoint to log/prepare support feedback email draft metadata.
application/single_app/route_backend_chats.py Replaces local serializers with shared make_json_serializable() and sanitizes outputs.
application/single_app/functions_settings.py Adds Support defaults + sanitizes user-visible settings payload (hiding recipient email).
application/single_app/functions_message_artifacts.py Adds NaN/Infinity normalization + strict JSON dump for artifact payloads.
application/single_app/functions_activity_logging.py Adds activity logging for user-initiated support feedback mailto drafts.
application/single_app/config.py Bumps app VERSION to 0.240.063.
application/single_app/app.py Registers new Support frontend routes.
Comments suppressed due to low confidence (1)

ui_tests/test_support_latest_features_image_modal.py:1

  • This assertion is effectively a no-op: it computes the current count and then expects the locator to have that same count. It also won’t wait for cards to appear because .count() is evaluated immediately. Make the assertion meaningful (e.g., assert count > 0, or expect(locator.first).to_be_visible(), or use a known minimum count) so the test fails when the page renders no feature cards.

Copilot AI review requested due to automatic review settings April 7, 2026 18:55
@paullizer paullizer merged commit 108b6a1 into Development Apr 7, 2026
6 checks passed
@paullizer paullizer deleted the feature/support-menu branch April 7, 2026 18:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 34 out of 50 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

functional_tests/test_chat_post_stream_json_sanitization.py:1

  • This test hard-codes the application config VERSION to 0.240.063, but application/single_app/config.py is updated to 0.240.066 in this PR. This will fail as soon as the app version moves beyond the fix version. Consider asserting only the fix doc version (since that’s what this test is about), or relaxing the config assertion (e.g., removing it, or asserting the config version is >= the fix version if you have a version-compare helper).

Comment on lines +63 to +66
{% set support_menu_role_allowed = 'Admin' in session['user']['roles'] or 'User' in session['user']['roles'] %}
{% if support_menu_role_allowed and app_settings.enable_support_menu %}
{% set show_support_latest_features = app_settings.enable_support_latest_features and app_settings.support_latest_features_has_visible_items %}
{% set show_support_send_feedback = app_settings.enable_support_send_feedback and app_settings.support_feedback_recipient_configured %}
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike the sidebar templates, this top-nav block directly indexes session['user']['roles']. On pages rendered without a populated session['user'] (or where roles is missing/non-list), Jinja will raise and break page rendering. Align this with _sidebar_nav.html / _sidebar_short_nav.html by using session.get('user'), .get('roles'), and a safe role-membership check.

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +76
const result = await response.json();
if (!response.ok) {
throw new Error(result.error || 'Unable to prepare the feedback email draft.');
}

Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling response.json() unconditionally can throw when the backend returns a non-JSON response (proxies, HTML error pages, auth middleware, etc.), which then surfaces a confusing parse error message to the user. Prefer parsing defensively (e.g., check Content-Type before .json(), or wrap JSON parsing in a try/catch and fall back to response.text() / a generic error message).

Suggested change
const result = await response.json();
if (!response.ok) {
throw new Error(result.error || 'Unable to prepare the feedback email draft.');
}
const contentType = response.headers.get('content-type') || '';
const isJsonResponse = contentType.includes('application/json');
let result = null;
let responseText = '';
if (isJsonResponse) {
result = await response.json();
} else {
responseText = await response.text();
}
if (!response.ok) {
throw new Error(
result?.error ||
responseText ||
'Unable to prepare the feedback email draft.'
);
}
if (!result) {
throw new Error('Unable to prepare the feedback email draft.');
}

Copilot uses AI. Check for mistakes.
except (TypeError, ValueError):
serializable = make_json_serializable(citation)
if not isinstance(serializable, dict):
serializable = {'value': str(citation)}
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a citation sanitizes to a non-dict (e.g., list/primitive), the code currently discards the sanitized structure and replaces it with {'value': str(citation)}. This loses potentially useful structured data even though it’s now JSON-safe. Consider preserving the sanitized value (e.g., {'value': serializable}) so downstream telemetry/debugging can still inspect the original shape.

Suggested change
serializable = {'value': str(citation)}
serializable = {'value': serializable}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants