From fb11cc482e6bc8fe744dee2c9dc972c16c23ba17 Mon Sep 17 00:00:00 2001 From: Rob Hough Date: Tue, 6 Oct 2026 12:58:33 +0000 Subject: [PATCH] refactor(editor): Improve agent message queue and steering controls (#40287) Co-authored-by: Bob Hough <15361982+heymynameisrob@users.noreply.github.com> Co-authored-by: linear-code[bot] <222613912+linear-code[bot]@users.noreply.github.com> --- .../design-system/src/css/mixins/mixins.scss | 12 - .../frontend/@n8n/i18n/src/locales/en.json | 8 +- .../agents/__tests__/AgentChatPanel.test.ts | 469 ++++++++------- .../features/agents/agents-design-language.md | 15 +- .../agents/components/AgentChatPanel.vue | 544 +++++------------- .../agents/composables/useAgentChatStream.ts | 8 +- .../ai/shared/components/ChatInputBase.vue | 1 + .../components/ChatMessageQueue.test.ts | 196 +++++++ .../ai/shared/components/ChatMessageQueue.vue | 460 +++++++++++++++ .../components/chatMessageQueue.types.ts | 21 + 10 files changed, 1117 insertions(+), 617 deletions(-) create mode 100644 packages/frontend/editor-ui/src/features/ai/shared/components/ChatMessageQueue.test.ts create mode 100644 packages/frontend/editor-ui/src/features/ai/shared/components/ChatMessageQueue.vue create mode 100644 packages/frontend/editor-ui/src/features/ai/shared/components/chatMessageQueue.types.ts diff --git a/packages/frontend/@n8n/design-system/src/css/mixins/mixins.scss b/packages/frontend/@n8n/design-system/src/css/mixins/mixins.scss index 1e4f6c6caf5..1ccbe4c8fed 100644 --- a/packages/frontend/@n8n/design-system/src/css/mixins/mixins.scss +++ b/packages/frontend/@n8n/design-system/src/css/mixins/mixins.scss @@ -57,20 +57,8 @@ $E: null; @include scroll-bar; scrollbar-color: transparent transparent; - &::-webkit-scrollbar-thumb { - background-color: transparent; - } - &:hover { scrollbar-color: var.$scrollbar-background-color transparent; - - &::-webkit-scrollbar-thumb { - background-color: var.$scrollbar-background-color; - - &:hover { - background-color: var.$scrollbar-hover-background-color; - } - } } } diff --git a/packages/frontend/@n8n/i18n/src/locales/en.json b/packages/frontend/@n8n/i18n/src/locales/en.json index b170e8f8689..a8ddca8bea2 100644 --- a/packages/frontend/@n8n/i18n/src/locales/en.json +++ b/packages/frontend/@n8n/i18n/src/locales/en.json @@ -8067,7 +8067,7 @@ "agents.chat.loadHistory.error": "Could not load chat history", "agents.chat.clearHistory.error": "Could not clear chat history", "agents.chat.stop.error": "Couldn't stop the agent. Try again.", - "agents.chat.queue.title": "{count} message up next | {count} messages up next", + "chat.messageQueue.title": "{count} queued message | {count} queued messages", "agents.chat.queue.steer": "Steer", "agents.chat.queue.steerTooltip": "Send to current execution", "agents.chat.queue.steering": "Waiting for the next step", @@ -8079,8 +8079,8 @@ "agents.chat.queue.editSteeringUnavailable": "This message is waiting for the next step. Your changes weren't applied.", "agents.chat.queue.editError": "Couldn't save your changes. Try again.", "agents.chat.queue.remove": "Remove queued message", - "agents.chat.queue.reorder": "Reorder queued message {position} of {count}", - "agents.chat.queue.reorderTooltip": "Drag to reorder. Use the Up and Down arrow keys to move the message.", + "chat.messageQueue.reorder": "Reorder queued message {position} of {count}", + "chat.messageQueue.reorderTooltip": "Drag to reorder", "agents.chat.queue.reorderUnavailable": "The queue changed. Review the updated order and try again.", "agents.chat.queue.reorderError": "Couldn't change the queue order. Try again.", "agents.chat.queue.loadError": "Couldn't load queued messages. Reopen the chat to try again.", @@ -8120,6 +8120,8 @@ "agents.chat.clearHistory": "Clear chat history", "agents.chat.input.placeholder": "Type a message...", "agents.chat.input.placeholder.withAgent": "Message {agentName}…", + "agents.chat.input.placeholder.withQueue.mac": "Press Option + ↑ to edit the last queued message", + "agents.chat.input.placeholder.withQueue.other": "Press Alt + ↑ to edit the last queued message", "agents.chat.attachments.tooLarge": "{fileName} exceeds the {limit} MB attachment limit", "agents.chat.attachments.tooMany": "You can attach up to {limit} files per message", "agents.chat.attachments.unavailable": "No longer available", diff --git a/packages/frontend/editor-ui/src/features/agents/__tests__/AgentChatPanel.test.ts b/packages/frontend/editor-ui/src/features/agents/__tests__/AgentChatPanel.test.ts index 587d7e9e205..5fd76c4e4bc 100644 --- a/packages/frontend/editor-ui/src/features/agents/__tests__/AgentChatPanel.test.ts +++ b/packages/frontend/editor-ui/src/features/agents/__tests__/AgentChatPanel.test.ts @@ -19,6 +19,10 @@ import AgentChatPlan from '../components/AgentChatPlan.vue'; import { planMessage, planView } from './fixtures/agent-plan'; type PanelVm = { sendMessageFromOutside: (message: string, files?: File[]) => void }; +const isMacOsMock = ref(false); +vi.mock('@n8n/composables/useDeviceSupport', () => ({ + useDeviceSupport: () => ({ isMacOs: isMacOsMock.value }), +})); const sendMessageMock = vi.fn(); const stopGeneratingMock = vi.fn(); @@ -47,7 +51,6 @@ const trackSubmittedMessageMock = vi.fn(); const trackSentMessageToN8nChatAgentMock = vi.fn(); const queuedMessagesMock = ref([]); const removeQueuedMessageMock = vi.fn(); -const updateQueuedMessageMock = vi.fn(); const reorderQueuedMessageMock = vi.fn(); const isReorderingQueueMock = ref(false); const steerQueuedMessageMock = vi.fn(); @@ -80,6 +83,10 @@ const defaultAgentConfig: AgentJsonConfig = { instructions: 'Help.', }; +vi.mock('@n8n/stores/useRootStore', () => ({ + useRootStore: () => ({ restApiContext: { baseUrl: '/rest' } }), +})); + vi.mock('@n8n/i18n', () => { const baseText = ( key: string, @@ -87,7 +94,7 @@ vi.mock('@n8n/i18n', () => { ) => { const translations: Record = { 'agents.chat.input.placeholder.withAgent': `Message ${options?.interpolate?.agentName}…`, - 'agents.chat.queue.title': `${options?.interpolate?.count} ${options?.adjustToNumber === 1 ? 'message' : 'messages'} up next`, + 'chat.messageQueue.title': `${options?.interpolate?.count} ${options?.adjustToNumber === 1 ? 'message' : 'messages'} up next`, 'agents.chat.misconfigured.issuesPrefix': 'Check:', 'agents.chat.misconfigured.missing.tools': 'Tool configuration', 'agents.chat.misconfigured.missing.mcpServers': 'MCP server', @@ -140,12 +147,14 @@ vi.mock('@n8n/design-system', async (importOriginal) => ({ N8nCallout: { template: '
' }, N8nCard: { template: '
' }, N8nDropdownMenu: { template: '
' }, + N8nHoverCard: { template: '
' }, N8nHeading: { template: '
' }, N8nIcon: { name: 'N8nIcon', props: ['icon', 'spin'], template: '' }, N8nIconButton: { emits: ['click'], template: '