Skip to content

Templates marketplace, report overhaul, and agentic chat upgrades#489

Closed
dtrn2048 wants to merge 2 commits intomainfrom
testing
Closed

Templates marketplace, report overhaul, and agentic chat upgrades#489
dtrn2048 wants to merge 2 commits intomainfrom
testing

Conversation

@dtrn2048
Copy link
Copy Markdown
Contributor

Summary

  • add the templates marketplace, report overhaul, settings redesign, and related LLM/reporting improvements currently on testing
  • move agentic chat to Vertex and ship the agentic chat UX polish, transcript deep links, translation updates, and supporting tests

Notes

  • this PR releases the current testing branch to main
  • the agentic chat changes have already passed the PR-to-testing workflow, including lint/type check, unit tests, and Docker build validation

spashii and others added 2 commits March 19, 2026 13:11
…upgrade

## Project Homepage UI
- Pin/unpin up to 3 projects to top of list
- Project cards display language
- Admin: project creator name visible + filterable

## Settings & Profile Redesign
- Upload, crop, remove profile picture
- Self-service display name + password change
- Settings reorganized: Account & Security, Appearance, Project Defaults

## Report Functionality Overhaul
- Multiple reports per project
- Guided reports with custom instructions
- Scheduled reports with auto conversation inclusion
- Background processing with visible status

## Chat Template Customization (Beta)
- Create custom templates by duplicating/editing built-in ones
- Flat "All templates" view with search, drag-and-drop reorder
- Quick access bar (top 3-5 pinned templates)
- Settings view for contextual suggestions toggle
- Backend: eliminated prompt_template_star table, replaced author_display_name with is_anonymous
- Backend: user_created ownership fix for non-admin users
- Backend: fields=["*"] fix for missing Directus fields

## LLM Upgrade
- Upgraded to Gemini 2.5 across all features
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 19, 2026

Important

Review skipped

Too many files!

This PR contains 162 files, which is 12 over the limit of 150.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7a81523f-870f-446a-b518-45ed816101e0

📥 Commits

Reviewing files that changed from the base of the PR and between 91e5945 and 9c1c343.

⛔ Files ignored due to path filters (5)
  • echo/agent/uv.lock is excluded by !**/*.lock
  • echo/cypress/cypress/downloads/merged-c73ccb37-8d3b-42e0-a51e-3edf8e20469b-eaa71516-0fcf-49e5-b9a7-3d45f4b5c4a6.mp3 is excluded by !**/*.mp3
  • echo/cypress/cypress/screenshots/04-create-edit-delete-project.cy.js/Project Create, Edit, and Delete Flow -- should create a project, edit its name and portal settings, verify changes, and delete it (failed).png is excluded by !**/*.png
  • echo/cypress/cypress/screenshots/30-report-lifecycle.cy.js/Report Lifecycle Flow -- creates a project and generates a report draft (failed).png is excluded by !**/*.png
  • echo/frontend/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (162)
  • echo/.vscode/sessions.json
  • echo/AGENTS.md
  • echo/agent/README.md
  • echo/agent/agent.py
  • echo/agent/echo_client.py
  • echo/agent/pyproject.toml
  • echo/agent/settings.py
  • echo/agent/tests/test_agent_graph.py
  • echo/agent/tests/test_agent_tools.py
  • echo/agent/tests/test_settings.py
  • echo/cookies.txt
  • echo/cypress/cypress.env.json
  • echo/cypress/cypress/downloads/transcript-1771916490192
  • echo/cypress/e2e/suites/36-agentic-chat-local.cy.js
  • echo/cypress/support/functions/report/index.js
  • echo/directus/sync/collections/folders.json
  • echo/directus/sync/collections/operations.json
  • echo/directus/sync/collections/policies.json
  • echo/directus/sync/snapshot/collections/prompt_template.json
  • echo/directus/sync/snapshot/collections/prompt_template_preference.json
  • echo/directus/sync/snapshot/collections/prompt_template_rating.json
  • echo/directus/sync/snapshot/fields/directus_users/hide_ai_suggestions.json
  • echo/directus/sync/snapshot/fields/project/pin_order.json
  • echo/directus/sync/snapshot/fields/project_report/scheduled_at.json
  • echo/directus/sync/snapshot/fields/project_report/status.json
  • echo/directus/sync/snapshot/fields/project_report/user_instructions.json
  • echo/directus/sync/snapshot/fields/prompt_template/content.json
  • echo/directus/sync/snapshot/fields/prompt_template/date_created.json
  • echo/directus/sync/snapshot/fields/prompt_template/date_updated.json
  • echo/directus/sync/snapshot/fields/prompt_template/description.json
  • echo/directus/sync/snapshot/fields/prompt_template/icon.json
  • echo/directus/sync/snapshot/fields/prompt_template/id.json
  • echo/directus/sync/snapshot/fields/prompt_template/is_anonymous.json
  • echo/directus/sync/snapshot/fields/prompt_template/is_public.json
  • echo/directus/sync/snapshot/fields/prompt_template/language.json
  • echo/directus/sync/snapshot/fields/prompt_template/sort.json
  • echo/directus/sync/snapshot/fields/prompt_template/tags.json
  • echo/directus/sync/snapshot/fields/prompt_template/title.json
  • echo/directus/sync/snapshot/fields/prompt_template/user_created.json
  • echo/directus/sync/snapshot/fields/prompt_template_preference/date_created.json
  • echo/directus/sync/snapshot/fields/prompt_template_preference/id.json
  • echo/directus/sync/snapshot/fields/prompt_template_preference/prompt_template_id.json
  • echo/directus/sync/snapshot/fields/prompt_template_preference/sort.json
  • echo/directus/sync/snapshot/fields/prompt_template_preference/static_template_id.json
  • echo/directus/sync/snapshot/fields/prompt_template_preference/template_type.json
  • echo/directus/sync/snapshot/fields/prompt_template_preference/user_created.json
  • echo/directus/sync/snapshot/fields/prompt_template_rating/chat_message_id.json
  • echo/directus/sync/snapshot/fields/prompt_template_rating/date_created.json
  • echo/directus/sync/snapshot/fields/prompt_template_rating/date_updated.json
  • echo/directus/sync/snapshot/fields/prompt_template_rating/id.json
  • echo/directus/sync/snapshot/fields/prompt_template_rating/prompt_template_id.json
  • echo/directus/sync/snapshot/fields/prompt_template_rating/rating.json
  • echo/directus/sync/snapshot/fields/prompt_template_rating/user_created.json
  • echo/directus/sync/snapshot/fields/prompt_template_rating/user_updated.json
  • echo/directus/sync/snapshot/relations/prompt_template/user_created.json
  • echo/directus/sync/snapshot/relations/prompt_template_preference/prompt_template_id.json
  • echo/directus/sync/snapshot/relations/prompt_template_preference/user_created.json
  • echo/directus/sync/snapshot/relations/prompt_template_rating/chat_message_id.json
  • echo/directus/sync/snapshot/relations/prompt_template_rating/prompt_template_id.json
  • echo/directus/sync/snapshot/relations/prompt_template_rating/user_created.json
  • echo/directus/sync/snapshot/relations/prompt_template_rating/user_updated.json
  • echo/docs/branching_and_releases.md
  • echo/frontend/AGENTS.md
  • echo/frontend/index.html
  • echo/frontend/package.json
  • echo/frontend/src/App.tsx
  • echo/frontend/src/components/announcement/AnnouncementDrawerHeader.tsx
  • echo/frontend/src/components/announcement/AnnouncementIcon.tsx
  • echo/frontend/src/components/announcement/AnnouncementItem.tsx
  • echo/frontend/src/components/announcement/Announcements.tsx
  • echo/frontend/src/components/announcement/TopAnnouncementBar.tsx
  • echo/frontend/src/components/announcement/WhatsNewItem.tsx
  • echo/frontend/src/components/announcement/hooks/index.ts
  • echo/frontend/src/components/announcement/hooks/useProcessedAnnouncements.ts
  • echo/frontend/src/components/auth/hooks/index.ts
  • echo/frontend/src/components/chat/AgenticChatPanel.tsx
  • echo/frontend/src/components/chat/ChatHistoryMessage.tsx
  • echo/frontend/src/components/chat/ChatTemplatesMenu.tsx
  • echo/frontend/src/components/chat/CommunityTab.tsx
  • echo/frontend/src/components/chat/CommunityTemplateCard.tsx
  • echo/frontend/src/components/chat/PublishTemplateForm.tsx
  • echo/frontend/src/components/chat/QuickAccessConfigurator.tsx
  • echo/frontend/src/components/chat/TemplateRatingPills.tsx
  • echo/frontend/src/components/chat/TemplatesModal.tsx
  • echo/frontend/src/components/chat/agenticToolActivity.ts
  • echo/frontend/src/components/chat/hooks/useCommunityTemplates.ts
  • echo/frontend/src/components/chat/hooks/useUserTemplates.ts
  • echo/frontend/src/components/common/ClosableAlert.tsx
  • echo/frontend/src/components/common/CopyRichTextIconButton.tsx
  • echo/frontend/src/components/common/ExponentialProgress.tsx
  • echo/frontend/src/components/common/ImageCropModal.tsx
  • echo/frontend/src/components/common/Markdown.tsx
  • echo/frontend/src/components/common/UserAvatar.tsx
  • echo/frontend/src/components/conversation/ConversationChunkAudioTranscript.tsx
  • echo/frontend/src/components/layout/Header.tsx
  • echo/frontend/src/components/project/PinnedProjectCard.tsx
  • echo/frontend/src/components/project/ProjectListItem.tsx
  • echo/frontend/src/components/project/hooks/index.ts
  • echo/frontend/src/components/project/webhooks/WebhookSettingsCard.tsx
  • echo/frontend/src/components/report/CreateReportForm.tsx
  • echo/frontend/src/components/report/ReportEditor.tsx
  • echo/frontend/src/components/report/ReportFocusSelector.tsx
  • echo/frontend/src/components/report/ReportRenderer.tsx
  • echo/frontend/src/components/report/UpdateReportModalButton.tsx
  • echo/frontend/src/components/report/hooks/index.ts
  • echo/frontend/src/components/report/hooks/useReportProgress.ts
  • echo/frontend/src/components/settings/AccountSettingsCard.tsx
  • echo/frontend/src/components/settings/ChangePasswordCard.tsx
  • echo/frontend/src/components/settings/WhitelabelLogoCard.tsx
  • echo/frontend/src/components/settings/hooks/index.ts
  • echo/frontend/src/config.ts
  • echo/frontend/src/data/reportFocusOptions.json
  • echo/frontend/src/lib/api.ts
  • echo/frontend/src/lib/typesDirectus.d.ts
  • echo/frontend/src/locales/de-DE.po
  • echo/frontend/src/locales/de-DE.ts
  • echo/frontend/src/locales/en-US.po
  • echo/frontend/src/locales/en-US.ts
  • echo/frontend/src/locales/es-ES.po
  • echo/frontend/src/locales/es-ES.ts
  • echo/frontend/src/locales/fr-FR.po
  • echo/frontend/src/locales/fr-FR.ts
  • echo/frontend/src/locales/it-IT.po
  • echo/frontend/src/locales/it-IT.ts
  • echo/frontend/src/locales/nl-NL.po
  • echo/frontend/src/locales/nl-NL.ts
  • echo/frontend/src/routes/participant/ParticipantReport.tsx
  • echo/frontend/src/routes/project/ProjectsHome.tsx
  • echo/frontend/src/routes/project/chat/ProjectChatRoute.tsx
  • echo/frontend/src/routes/project/conversation/ProjectConversationTranscript.tsx
  • echo/frontend/src/routes/project/report/ProjectReportRoute.tsx
  • echo/frontend/src/routes/settings/UserSettingsRoute.tsx
  • echo/frontend/vite.config.ts
  • echo/server/AGENTS.md
  • echo/server/dembrane/api/agentic.py
  • echo/server/dembrane/api/api.py
  • echo/server/dembrane/api/chat.py
  • echo/server/dembrane/api/project.py
  • echo/server/dembrane/api/stateless.py
  • echo/server/dembrane/api/template.py
  • echo/server/dembrane/api/user_settings.py
  • echo/server/dembrane/api/verify.py
  • echo/server/dembrane/async_helpers.py
  • echo/server/dembrane/chat_utils.py
  • echo/server/dembrane/reply_utils.py
  • echo/server/dembrane/report_events.py
  • echo/server/dembrane/report_generation.py
  • echo/server/dembrane/report_utils.py
  • echo/server/dembrane/scheduler.py
  • echo/server/dembrane/service/webhook.py
  • echo/server/dembrane/suggestion_utils.py
  • echo/server/dembrane/tasks.py
  • echo/server/dembrane/transcribe.py
  • echo/server/prompt_templates/system_report.de.jinja
  • echo/server/prompt_templates/system_report.en.jinja
  • echo/server/prompt_templates/system_report.es.jinja
  • echo/server/prompt_templates/system_report.fr.jinja
  • echo/server/prompt_templates/system_report.it.jinja
  • echo/server/prompt_templates/system_report.nl.jinja
  • echo/server/pyproject.toml
  • echo/server/tests/api/test_agentic_api.py
  • echo/server/tests/test_transcribe_webhook.py

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch testing
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

)
if not isinstance(items, list):
return []
return [item["prompt_template_id"] for item in items]

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.

Copilot Autofix

AI 26 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

)
if not isinstance(users, list) or len(users) == 0:
raise HTTPException(status_code=404, detail="User not found")
return users[0]

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.

Copilot Autofix

AI 26 days ago

General approach: never embed raw exception objects or stack traces in data flows that can be returned to external clients. Instead, log detailed errors server-side and return either a standardized structure or raise a controlled HTTPException with a generic message.

Best specific fix here:

  1. In DirectusClient.search (in directus.py), change the inner except Exception as exc block so that it:

    • Logs the exception.
    • Returns a safe, predictable value (e.g., an empty list) for list-based queries, or raises a domain-specific error instead of stuffing exc into a returned dict. To avoid broader refactoring, we can:
      • Use the existing urllib3/logging context to log via getLogger(__name__) (if available) or simply avoid logging if no logger is present in the shown snippet.
      • Return [], which is safe for get_users, because get_current_user already handles "no user" via if not isinstance(users, list) or len(users) == 0: raise HTTPException(404, ...).
    • Crucially, remove f"{exc}" from any object that propagates to callers.
  2. In get_current_user (in user_settings.py), harden handling of unexpected results from directus.get_users:

    • If users is not a list or is empty, keep returning 404.
    • Optionally, if users is a dict with an "error" key (in case other callers of search still use that pattern), treat it as an internal error and raise a generic 500 without including details.

Given the limited allowed scope of changes, we will:

  • Adjust DirectusClient.search’s except Exception as exc to return an empty list instead of a dict containing the exception string.
  • Add a small extra guard in get_current_user that treats any non-list, non-empty result as an internal error (to avoid odd exposures via automatic serialization).

No functional behavior is changed for the normal successful path; failure paths become safer and more consistent.


Suggested changeset 2
echo/server/dembrane/api/user_settings.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/echo/server/dembrane/api/user_settings.py b/echo/server/dembrane/api/user_settings.py
--- a/echo/server/dembrane/api/user_settings.py
+++ b/echo/server/dembrane/api/user_settings.py
@@ -73,7 +73,11 @@
                 }
             },
         )
-        if not isinstance(users, list) or len(users) == 0:
+        if not isinstance(users, list):
+            # Unexpected response shape; treat as internal error without exposing details.
+            logger.error("Unexpected response when fetching current user profile: %r", users)
+            raise HTTPException(status_code=500, detail="Failed to get user profile")
+        if len(users) == 0:
             raise HTTPException(status_code=404, detail="User not found")
         return users[0]
     except HTTPException:
EOF
@@ -73,7 +73,11 @@
}
},
)
if not isinstance(users, list) or len(users) == 0:
if not isinstance(users, list):
# Unexpected response shape; treat as internal error without exposing details.
logger.error("Unexpected response when fetching current user profile: %r", users)
raise HTTPException(status_code=500, detail="Failed to get user profile")
if len(users) == 0:
raise HTTPException(status_code=404, detail="User not found")
return users[0]
except HTTPException:
echo/server/dembrane/directus.py
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/echo/server/dembrane/directus.py b/echo/server/dembrane/directus.py
--- a/echo/server/dembrane/directus.py
+++ b/echo/server/dembrane/directus.py
@@ -376,8 +376,9 @@
 
             try:
                 return response.json()["data"]
-            except Exception as exc:  # noqa: BLE001 - want best-effort fallback
-                return {"error": f"No data found for this request : {exc}"}
+            except Exception:
+                # Best-effort fallback without exposing internal exception details
+                return []
         except requests.exceptions.ConnectionError as exc:
             raise DirectusServerError(exc) from exc
         except AssertionError as exc:
EOF
@@ -376,8 +376,9 @@

try:
return response.json()["data"]
except Exception as exc: # noqa: BLE001 - want best-effort fallback
return {"error": f"No data found for this request : {exc}"}
except Exception:
# Best-effort fallback without exposing internal exception details
return []
except requests.exceptions.ConnectionError as exc:
raise DirectusServerError(exc) from exc
except AssertionError as exc:
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
@dtrn2048 dtrn2048 closed this Mar 19, 2026
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.

3 participants