Repository navigation
Live support chat with AI triage for Cloud and dedicated instances - #1155
Merged
Merged
Conversation
Cloud and our dedicated enterprise instances load a Libredesk chat widget for signed-in users. The backend signs an HS256 identity carrying a workspace snapshot (plan, trial end, connectors, last-24h connector errors, redacted), so agents and the triage see the context. A signed webhook triages new conversations: category, priority, team, segment tags and a private note with a reply draft. Nothing is sent to the customer automatically. The module loads only when SUPPORT_CHAT_* or LIBREDESK_* are set, so self-hosted installations are unaffected.
With LIBREDESK_AI_ASSISTANT_USER_ID set, the triage assigns live chats in categories the assistant can handle (connector setup and errors, connector requests, account, other) to the Libredesk AI assistant after the team, so it answers from the knowledge base and hands back to the Support team when it cannot help. Billing, bugs, feature requests, sales, email conversations and enterprise customers still go straight to a person.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This adds a live support chat for the instances we run: AnythingMCP Cloud and the dedicated instances of enterprise customers. The goal is to help people during the trial when a connector won't set up, without anyone having to ask for their workspace details first. The desk is our own Libredesk (AGPL, self-hosted, unmodified) at support.anythingmcp.com.
The widget's identity is signed by the backend and carries a snapshot of the workspace: plan, trial end, connectors, and the connector errors of the last 24 hours with credentials redacted. Every new conversation then goes through an AI triage that sets the category, priority, team and segment tags, and adds a private note with a summary and a reply draft. Nothing is sent to the customer automatically; a person reviews the draft.
Changes
ee/support/(new, AnythingMCP Commercial License):GET /api/support/widget(JWT auth): returns the widget settings plus an HS256 user JWT (external_user_id = <instance host>:<user id>, contact attributes). The snapshot is cached for 5 minutes, and every query is filtered byorganizationId.POST /api/support/webhook: accepts Libredeskconversation.created. It checks theX-Libredesk-SignatureHMAC on the raw body, refuses deliveries older than 10 minutes, answers right away and runs the triage in the background.knowledge-graph/llm-client(on Cloud: Anthropicclaude-haiku-4-5). Customer text is passed throughredactPiiandredactSecretsbefore it reaches the LLM. Billing and enterprise conversations are always High. Without an LLM it falls back to tags and priority only.SUPPORT_CHAT_*(widget) orLIBREDESK_*(triage) are set.LIBREDESK_AI_ASSISTANT_USER_ID): after setting the team, the triage assigns live chats inconnector-setup,connector-error,new-connector-request,accountandotherto the Libredesk AI assistant, which answers from the knowledge base and hands back to the Support team when it can't help. Billing, bugs, feature requests, sales, email conversations and enterprise customers always go to a person. The team is set before the user because Libredesk clears the user assignee whenever the team changes.main.ts: the JSON parser keeps the raw body, but only for/api/support/webhook.email-verified.guard.ts:/api/support/widgetadded to the allowlist, so people whose verification code never arrived can still reach us.SupportChatis mounted inProviders. It renders nothing, loadswidget.jsonly when the backend returns a session, refreshes the identity when the token changes and logs the widget out when the user signs out.docker-compose.cloud.yml: passes the seven new variables through.Cloud and self-hosted
SUPPORT_CHAT_*. Contacts are taggedself-hostedandenterpriseand routed to the Enterprise team with High priority./api/support/widgetreturns 404. The frontend makes one request at sign-in, gets the 404 and loads nothing else. No third-party script.Type
Testing
src/ee/support/*.spec.ts. They cover JWT claims and verification, per-instance external id, org-scoped queries, redaction, cache, the 404 gates, signature and staleness checks, the triage flow, routing to Enterprise, the no-LLM fallback, idempotency and partial failure.SupportIdentityService;auth/exchangecreated a verified contact with all attributes.SupportTriageServiceagainst it with Haiku.connector-setup, cloud, trial, ai-triaged, priority High, Support team, and a private note with the right diagnosis (Etsy redirect URI mismatch, taken from the connector-issues snapshot) and an Italian reply draft.cloud.anythingmcp.comorigin: no console errors, user recognised, previous conversation listed.Commands and results:
packages/backend:npx tsc --noEmit -p tsconfig.json→ clean.packages/backend:npx eslinton the changed files → 0 errors. The fullnpm run lintalso reports only existing warnings; the--fixrewrites it made in two unrelated spec files were reverted.packages/backend:npx jest→ 682 suites passed, 1 failed (connectors/parsers/curl.parser.spec.ts). That suite passes when run alone (43/43); this branch doesn't touch it, so it fails only in the full parallel run.packages/frontend:npx tsc --noEmit -p tsconfig.jsonandnpx eslinton the changed files → clean.Checklist
npm test): see the note oncurl.parser.spec.tsaboveRelated Issues
None. There is no schema change.
Live check of the assistant path: a conversation with a
needs_reauthGoogle Calendar connector was triaged asconnector-error, assigned to the assistant, and got a correct answer (re-authorize; publish the OAuth app if it is in Testing) about 3 s after the triage.