Skip to content

Feature/support menu - #824

Merged
Paul Lizer (paullizer) merged 7 commits into
Developmentfrom
feature/support-menu
Apr 7, 2026
Merged

Feature/support menu#824
Paul Lizer (paullizer) merged 7 commits into
Developmentfrom
feature/support-menu

Conversation

@paullizer

@paullizerPaul Lizer (paullizer) commented Apr 7, 2026

Copy link
Copy Markdown
Contributor
  • 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)

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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

Comment threadapplication/single_app/route_frontend_support.py
Comment threadapplication/single_app/route_backend_settings.py
Comment threadapplication/single_app/templates/_top_nav.html
Comment threadapplication/single_app/templates/admin_settings.html
Comment threadapplication/single_app/static/js/support/support_feedback.js Outdated
Comment threadapplication/single_app/route_backend_settings.py
Comment threadapplication/single_app/functions_message_artifacts.py
Comment threadapplication/single_app/config.py Outdated
CopilotAI review requested due to automatic review settings April 7, 2026 18:55
@paullizer
Paul Lizer (paullizer) merged commit 108b6a1 into DevelopmentApr 7, 2026
6 checks passed
@paullizer
Paul Lizer (paullizer) deleted the feature/support-menu branch April 7, 2026 18:56

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

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

CopilotAIApr 7, 2026

Copy link

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.');
}

CopilotAIApr 7, 2026

Copy link

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
constresult=awaitresponse.json();
if(!response.ok){
thrownewError(result.error||'Unable to prepare the feedback email draft.');
}
constcontentType=response.headers.get('content-type')||'';
constisJsonResponse=contentType.includes('application/json');
letresult=null;
letresponseText='';
if(isJsonResponse){
result=awaitresponse.json();
}else{
responseText=awaitresponse.text();
}
if(!response.ok){
thrownewError(
result?.error||
responseText||
'Unable to prepare the feedback email draft.'
);
}
if(!result){
thrownewError('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)}

CopilotAIApr 7, 2026

Copy link

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

@paullizer