Skip to content

Switch support agent to mqtt #7090

Merged
cstns merged 74 commits into
mainfrom
expert/switch-insights-to-mqtt
May 6, 2026
Merged

Switch support agent to mqtt #7090
cstns merged 74 commits into
mainfrom
expert/switch-insights-to-mqtt

Conversation

@cstns
Copy link
Copy Markdown
Contributor

@cstns cstns commented Apr 16, 2026

Description

This PR switches the Expert assistant's communication layer from HTTP to MQTT for real-time bidirectional messaging, gated behind a PostHog feature flag (isExpertCommsBetaEnabled). It also introduces admin UI for managing Expert agent MQTT broker credentials, improves contextual awareness across the app, and refactors several UI components.

MQTT Communication Layer

  • New MqttExpertTopicHelper composable: builds and parses structured MQTT topic paths (ff/v1/expert/<userId>/<sessionId>/<entityType>/<entityId>/<agentChannel>/<topicType>/<topicAction>) with full entity type resolution (application, instance, device, team).
  • Enhanced MqttService: adds disconnect, end, reconnect, packetsend, packetreceive, and outgoingEmpty event handlers; introduces reconnectGeneration to prevent stale reconnect timers from firing; adds _killStaleClient for forceful cleanup of zombie MQTT clients; fixes reconnect guard to skip when already connected/connecting; adds connectHandlerPromise to serialize connect handler work and prevent publish before subscribe races; switches internal _ helpers to private; sets keepalive: 45; adds normalized reconnect policy defaults.
  • Categorized MQTT error codes: exported sets for FATAL_ERROR_CODES, TRANSIENT_ERROR_CODES, THROTTLED_ERROR_CODES, PROTOCOL_BUG_ERROR_CODES, and ERRORS_WITHOUT_CODES to drive user facing error messaging with context appropriate language.

Expert Store (product-expert.js)

  • Dual transport (sendQuery): routes through sendMqttQuery or sendHttpQuery based on the feature flag.
  • MQTT lifecycle management: establishMqttComms creates a keyed MQTT client with dynamic credentials from userApi.initiateExpertChat; topic subscriptions happen in _onMqttConnect using wildcard patterns; _onMqttMessage dispatches to handleMessageResponse (chat replies) or handleInFlightRequest (tool call in flight requests).
  • In flight request tracking: tracks pending MQTT requests per agent store; handles expert:status-message (acks) and automation:* (proxied to Node RED via invokeActionAwaitResponse) in flight request types.
  • Error handling with personality: randomized, user friendly error and reconnection messages with duplicate error suppression based on recent error codes.
  • stopInflightChat: clears in flight requests and updates when the user cancels mid flight.
  • inFlightUpdates: surfaces real time tool call status/tool name updates to the loading indicator.

Product Assistant Store

  • invokeActionAwaitResponse: new method that sends a postMessage to the immersive editor iframe and returns a promise that resolves when the correlated response arrives (or rejects after timeout); uses pendingRequests map keyed by composite sessionId:chatTransactionId:transactionId.
  • isImmersiveInstance / isImmersiveDevice getters: replace the old immersiveInstance/immersiveDevice getters to require both entity presence and immersive mode, fixing false positive immersive detection.
  • targetOrigin fix: uses contextStore directly instead of the old getters for postMessage target origin.

Context Store & Mixins

  • isImmersive flag: added to the context store, set/cleared by Instance and Device editors on mount/unmount.
  • application in context: new setApplication action; Application mixin now writes the contextual application into the store (and clears on unmount).
  • Device/Instance mixins: set contextual entities on mount/watch and clear on unmount for consistent contextual awareness.

Admin UI: Expert Agent Credentials

  • Generate/delete MQTT broker credentials for the Expert agent in Admin > Settings > General (only visible when isExpertCommsBetaEnabled flag is active).
  • New API functions: adminApi.generateExpertAgentCreds() / adminApi.deleteExpertAgentCreds() and userApi.initiateExpertChat().

Infrastructure

  • projectCount cast to integer in ProjectTemplate DB views to fix data type inconsistency.

UI Improvements

  • ToolCallItem extracted into its own Vue component from ToolCalls, with collapsed list limited to 2 items and scrollable/expandable tool list (max 5 collapsed, 15 expanded).
  • Tool call duration moved into the tool call title row; status prioritized over tool name.
  • Code block styling: removed border/padding from agent response code blocks; improved markdown table styling.
  • Chat input overflow fix: prevents context selection pills from overflowing the input area.
  • Download chat messages: hidden Shift+Alt+D keyboard shortcut to download expert messages as JSON.
  • Simplified hydrateMessages: cleaner switch based logic since tool calls aren't received when ingesting website context.
  • StreamableContent: rendering support for streamable content blocks.

Caution

Changes made in .github/workflows/branch-deploy.yaml and ci/ci-values.yaml files are exclusive to this pull request and should be reverted before merge.

Related Issue(s)

closes #6972

Checklist

  • I have read the contribution guidelines
  • Suitable unit/system level tests have been added and they pass
  • Documentation has been updated
    • Upgrade instructions
    • Configuration details
    • Concepts
  • Changes flowforge.yml?
    • Issue/PR raised on FlowFuse/helm to update ConfigMap Template
    • Issue/PR raised on FlowFuse/CloudProject to update values for Staging/Production
  • Link to Changelog Entry PR, or note why one is not needed.

Labels

  • Includes a DB migration? -> add the area:migration label

- alter the way we deduce immersive entities in such a way that we have full contextual awareness throughout the app
- rough mqtt implementation
@cstns cstns self-assigned this Apr 16, 2026
@cstns cstns marked this pull request as draft April 16, 2026 13:56
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 16, 2026

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.59%. Comparing base (b3a1c78) to head (617bb17).
⚠️ Report is 29 commits behind head on main.

Files with missing lines Patch % Lines
forge/db/views/ProjectTemplate.js 0.00% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7090   +/-   ##
=======================================
  Coverage   76.58%   76.59%           
=======================================
  Files         405      405           
  Lines       20580    20579    -1     
  Branches     4974     4975    +1     
=======================================
  Hits        15762    15762           
+ Misses       4818     4817    -1     
Flag Coverage Δ
backend 76.59% <0.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…cher to unsubscribe from stale topics and re-subscription
@cstns cstns linked an issue Apr 17, 2026 that may be closed by this pull request
cstns added 2 commits April 17, 2026 14:11
…ding messages and tool calls, handle assistant replies based on toolCall
…ig asterisk when re-creating the mqtt client and fixes to the topic builder
Base automatically changed from expert-agent-creds-fe to main May 4, 2026 11:30
@cstns cstns requested a review from Steve-Mcl May 5, 2026 10:05
@cstns
Copy link
Copy Markdown
Contributor Author

cstns commented May 5, 2026

ready for review, leaving it as draft for the time being because we still need to remove the ci bits that enabled testing on pre-staging

Copy link
Copy Markdown
Contributor

@Steve-Mcl Steve-Mcl left a comment

Choose a reason for hiding this comment

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

Acknowledging this is a large PR (unavoidable mostly) but also acknowledging it has been dogfooded by 3 team members over last week it is good to go AFTER CI stuff is deleted.

const { correlationId } = payloadData
const inflight = this.pendingRequests.get(correlationId)
if (inflight) {
// console.debug('Received response for in-flight request:', { correlationId, originalRequest: inflight.postMessagePayload, response: payloadData })
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.

Suggested change
// console.debug('Received response for in-flight request:', { correlationId, originalRequest: inflight.postMessagePayload, response: payloadData })

Comment thread .github/workflows/branch-deploy.yaml Outdated
Comment thread ci/ci-values.yaml Outdated
Comment thread ci/ci-values.yaml Outdated
@cstns cstns marked this pull request as ready for review May 6, 2026 10:47
@cstns cstns merged commit c3c8f6f into main May 6, 2026
29 checks passed
@cstns cstns deleted the expert/switch-insights-to-mqtt branch May 6, 2026 10:57
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.

alter message publishing & handling

4 participants