diff --git a/packages/frontend/@n8n/i18n/src/locales/en.json b/packages/frontend/@n8n/i18n/src/locales/en.json index 6a4ae038db2..03e22d32ee0 100644 --- a/packages/frontend/@n8n/i18n/src/locales/en.json +++ b/packages/frontend/@n8n/i18n/src/locales/en.json @@ -1325,10 +1325,10 @@ "experiments.instanceAiWorkflowPreviewSuggestions.suggestions.scoreMyLeads.prompt": "When a new lead is created in my CRM, enrich it with Lemlist, score it based on fit, then update the lead if qualified and notify the sales team on Slack.", "experiments.instanceAiWorkflowPreviewSuggestions.suggestions.processInvoices.label": "Process invoices", "experiments.instanceAiWorkflowPreviewSuggestions.suggestions.processInvoices.prompt": "Every morning, scan Gmail for new invoices, use Claude to extract details and cross-check them against purchase orders in Google Sheets, flag any discrepancies for review, and add all payment due dates to Google Calendar automatically.", - "experiments.instanceAiWorkflowPreviewSuggestions.suggestions.whatsappSupport.label": "WhatsApp support agent", - "experiments.instanceAiWorkflowPreviewSuggestions.suggestions.whatsappSupport.prompt": "When a customer sends a WhatsApp message, use Gemini to match their question against our FAQ in Google Sheets and reply instantly. If it cannot resolve it, create a support ticket in Notion and alert the team on Slack.", "experiments.instanceAiWorkflowPreviewSuggestions.suggestions.scheduleSocialPosts.label": "Schedule social posts", "experiments.instanceAiWorkflowPreviewSuggestions.suggestions.scheduleSocialPosts.prompt": "Every Monday, read this week's content ideas from a Google Sheet, use Gemini to write tailored content then schedule them to post throughout the week.", + "experiments.instanceAiWorkflowPreviewSuggestions.suggestions.telegramAgent.label": "Telegram support agent", + "experiments.instanceAiWorkflowPreviewSuggestions.suggestions.telegramAgent.prompt": "Create a Telegram agent that answers customer questions using Claude, looks up order details in Gmail and our FAQ in Google Sheets, and escalates to a human when it is unsure.", "experiments.instanceAiWorkflowPreviewSuggestions.suggestions.seeAll": "See all", "experiments.personalizedTemplatesV3.browseAllTemplates": "Browse our template library", "experiments.personalizedTemplatesV3.couldntFind": "Need something different?", diff --git a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewCanvas.test.ts b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewCanvas.test.ts index d3af8af500a..95df94f8a67 100644 --- a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewCanvas.test.ts +++ b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewCanvas.test.ts @@ -84,3 +84,45 @@ describe('WorkflowPreviewCanvas renderScale', () => { expect(style).toContain('scale(1)'); }); }); + +describe('WorkflowPreviewCanvas full-canvas visualization', () => { + const fullCanvasWorkflow: PreviewWorkflow = { + nodes: [], + connections: [], + fullCanvasVisualization: { type: 'agent-builder' }, + }; + + function mountFullCanvas(animating: boolean) { + vi.mocked(useElementSize).mockReturnValue({ + width: ref(1600), + height: ref(420), + } as unknown as ReturnType); + + return mount(WorkflowPreviewCanvas, { + props: { workflow: fullCanvasWorkflow, animating }, + global: { stubs: { WorkflowPreviewNode: true, AgentBuilderVisualization: true } }, + }); + } + + it('renders the full-canvas visualization component', () => { + const wrapper = mountFullCanvas(false); + const viz = wrapper.findComponent({ name: 'AgentBuilderVisualization' }); + expect(viz.exists()).toBe(true); + expect(viz.props('active')).toBe(false); + }); + + it('activates the visualization when animating', async () => { + const wrapper = mountFullCanvas(true); + await wrapper.vm.$nextTick(); + const viz = wrapper.findComponent({ name: 'AgentBuilderVisualization' }); + expect(viz.props('active')).toBe(true); + }); + + it('stays active after the visualization completes', async () => { + const wrapper = mountFullCanvas(true); + const viz = wrapper.findComponent({ name: 'AgentBuilderVisualization' }); + viz.vm.$emit('complete'); + await wrapper.vm.$nextTick(); + expect(wrapper.findComponent({ name: 'AgentBuilderVisualization' }).props('active')).toBe(true); + }); +}); diff --git a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewCanvas.vue b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewCanvas.vue index c8bd869e41d..36368ec0bfd 100644 --- a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewCanvas.vue +++ b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/WorkflowPreviewCanvas.vue @@ -11,7 +11,7 @@ import WorkflowPreviewNode from './WorkflowPreviewNode.vue'; import SlackMessageVisualization from './visualizations/SlackMessageVisualization.vue'; import SalesforceCardVisualization from './visualizations/SalesforceCardVisualization.vue'; import InvoiceSpreadsheetVisualization from './visualizations/InvoiceSpreadsheetVisualization.vue'; -import WhatsAppChatVisualization from './visualizations/WhatsAppChatVisualization.vue'; +import AgentBuilderVisualization from './visualizations/AgentBuilderVisualization.vue'; const NODE_HALF_WIDTH = 48; const EDGE_CURVE_OFFSET = 60; @@ -28,7 +28,7 @@ const visualizationComponents: Record = { 'slack-message': SlackMessageVisualization, 'salesforce-card': SalesforceCardVisualization, 'invoice-spreadsheet': InvoiceSpreadsheetVisualization, - 'whatsapp-chat': WhatsAppChatVisualization, + 'agent-builder': AgentBuilderVisualization, }; const props = withDefaults( @@ -40,13 +40,20 @@ const props = withDefaults( ); const canvasRef = ref(null); -const { width: canvasRenderedWidth } = useElementSize(canvasRef); +const { width: canvasRenderedWidth, height: canvasRenderedHeight } = useElementSize(canvasRef); const animationPhase = ref('idle'); const nodeStates = reactive>({}); const hasInputViz = computed(() => !!props.workflow.inputVisualization); const hasOutputViz = computed(() => !!props.workflow.outputVisualization); +const hasFullCanvasViz = computed(() => !!props.workflow.fullCanvasVisualization); + +const fullCanvasVizComponent = computed(() => + props.workflow.fullCanvasVisualization + ? visualizationComponents[props.workflow.fullCanvasVisualization.type] + : undefined, +); const outputVizItems = computed((): PreviewOutputVisualization[] => { const viz = props.workflow.outputVisualization; @@ -147,7 +154,7 @@ async function runNodeAnimation() { function startAnimation() { stopped = false; resetStates(); - if (hasInputViz.value) { + if (hasFullCanvasViz.value || hasInputViz.value) { animationPhase.value = 'input'; } else { animationPhase.value = 'nodes'; @@ -169,6 +176,11 @@ function handleInputComplete() { void runNodeAnimation(); } +function handleFullCanvasComplete() { + if (stopped) return; + animationPhase.value = 'done'; +} + function handleOutputComplete() { if (stopped) return; outputCompletedCount++; @@ -291,7 +303,9 @@ const renderScale = computed(() => const contentStyle = computed(() => { const rs = renderScale.value; - const verticalOffset = (CANVAS_HEIGHT * (1 - rs)) / 2; + const renderedHeight = + canvasRenderedHeight.value > 0 ? canvasRenderedHeight.value : CANVAS_HEIGHT; + const verticalOffset = Math.max(0, (renderedHeight - CANVAS_HEIGHT * rs) / 2); return { width: `${CANVAS_WIDTH}px`, height: `${CANVAS_HEIGHT}px`, @@ -436,6 +450,15 @@ function isEdgeSuccess(connection: PreviewWorkflowConnection): boolean { +
+ +
+
({ matches })), + }); +} + +describe('AgentBuilderVisualization', () => { + beforeEach(() => { + vi.useFakeTimers(); + setPrefersReducedMotion(false); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it('emits complete after the animation sequence finishes', async () => { + const wrapper = mount(AgentBuilderVisualization, { + props: { active: true }, + }); + + await vi.advanceTimersByTimeAsync(20000); + + expect(wrapper.emitted('complete')).toHaveLength(1); + }); + + it('fills in the builder sections as the animation progresses', async () => { + const wrapper = mount(AgentBuilderVisualization, { + props: { active: true }, + }); + + expect(wrapper.text()).not.toContain('Gmail'); + + await vi.advanceTimersByTimeAsync(20000); + + const text = wrapper.text(); + expect(text).toContain('Gmail'); + expect(text).toContain('Google Sheets'); + expect(text).toContain('Summarize conversations'); + // The agent is not scheduled — the Schedules section stays empty. + expect(text).toContain('Add schedule'); + expect(text).not.toContain('Daily digest'); + expect(text).toContain('Claude Opus 5'); + expect(text).toContain('escalate to a human'); + }); + + it('stops and resets when deactivated', async () => { + const wrapper = mount(AgentBuilderVisualization, { + props: { active: true }, + }); + + await vi.advanceTimersByTimeAsync(2000); + await wrapper.setProps({ active: false }); + await vi.advanceTimersByTimeAsync(20000); + + expect(wrapper.emitted('complete')).toBeUndefined(); + expect(wrapper.text()).not.toContain('Gmail'); + }); + + it('does not emit complete when never activated', async () => { + const wrapper = mount(AgentBuilderVisualization, { + props: { active: false }, + }); + + await vi.advanceTimersByTimeAsync(20000); + + expect(wrapper.emitted('complete')).toBeUndefined(); + }); + + it('renders the publish button and flips it to Published after typing finishes', async () => { + const wrapper = mount(AgentBuilderVisualization, { + props: { active: true }, + }); + + await vi.advanceTimersByTimeAsync(2000); + const button = wrapper.find('[data-testid="publish-agent-button"]'); + expect(button.exists()).toBe(true); + expect(button.text()).toBe('Publish'); + + await vi.advanceTimersByTimeAsync(18000); + expect(wrapper.find('[data-testid="publish-agent-button"]').text()).toBe('Published'); + }); + + it('plays the Telegram chat first, then the builder, and emits complete at the end', async () => { + const wrapper = mount(AgentBuilderVisualization, { + props: { active: true }, + }); + + // Chat phase: conversation is playing, builder sections untouched. + await vi.advanceTimersByTimeAsync(2000); + expect(wrapper.text()).toContain('order #4712'); + expect(wrapper.text()).not.toContain('Claude Opus 5'); + expect(wrapper.emitted('complete')).toBeUndefined(); + + // Builder phase: sections are being filled in. + await vi.advanceTimersByTimeAsync(14000); + expect(wrapper.text()).toContain('Claude Opus 5'); + expect(wrapper.emitted('complete')).toBeUndefined(); + + await vi.advanceTimersByTimeAsync(6000); + expect(wrapper.text()).toContain('Published'); + expect(wrapper.emitted('complete')).toHaveLength(1); + }); + + it('shows the final state and completes promptly with reduced motion', async () => { + setPrefersReducedMotion(true); + const wrapper = mount(AgentBuilderVisualization, { + props: { active: true }, + }); + + await vi.advanceTimersByTimeAsync(3000); + + const text = wrapper.text(); + expect(text).toContain('Claude Opus 5'); + expect(text).toContain('Published'); + // The chat phase is skipped in the reduced-motion end state. + expect(text).not.toContain('order #4712'); + expect(wrapper.emitted('complete')).toHaveLength(1); + }); +}); diff --git a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/visualizations/AgentBuilderVisualization.vue b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/visualizations/AgentBuilderVisualization.vue new file mode 100644 index 00000000000..ed991df3f45 --- /dev/null +++ b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/visualizations/AgentBuilderVisualization.vue @@ -0,0 +1,875 @@ + + + + + diff --git a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/visualizations/TelegramChatVisualization.vue b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/visualizations/TelegramChatVisualization.vue new file mode 100644 index 00000000000..a0ddbee1e24 --- /dev/null +++ b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/visualizations/TelegramChatVisualization.vue @@ -0,0 +1,412 @@ + + + + + diff --git a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/visualizations/WhatsAppChatVisualization.vue b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/visualizations/WhatsAppChatVisualization.vue deleted file mode 100644 index 0bb2f88ce19..00000000000 --- a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/components/visualizations/WhatsAppChatVisualization.vue +++ /dev/null @@ -1,230 +0,0 @@ - - - - - diff --git a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/suggestions.ts b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/suggestions.ts index bdb1efc2a0c..f5e0115a13f 100644 --- a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/suggestions.ts +++ b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/suggestions.ts @@ -29,16 +29,6 @@ export const INSTANCE_AI_WORKFLOW_PREVIEW_SUGGESTIONS: readonly WorkflowPreviewS 'experiments.instanceAiWorkflowPreviewSuggestions.suggestions.processInvoices.prompt' as BaseTextKey, workflowFile: 'process-invoices', }, - { - type: 'prompt', - id: 'whatsapp-support', - icon: 'message-circle' as IconName, - labelKey: - 'experiments.instanceAiWorkflowPreviewSuggestions.suggestions.whatsappSupport.label' as BaseTextKey, - promptKey: - 'experiments.instanceAiWorkflowPreviewSuggestions.suggestions.whatsappSupport.prompt' as BaseTextKey, - workflowFile: 'whatsapp-support', - }, { type: 'prompt', id: 'schedule-social-posts', @@ -49,4 +39,14 @@ export const INSTANCE_AI_WORKFLOW_PREVIEW_SUGGESTIONS: readonly WorkflowPreviewS 'experiments.instanceAiWorkflowPreviewSuggestions.suggestions.scheduleSocialPosts.prompt' as BaseTextKey, workflowFile: 'schedule-social-posts', }, + { + type: 'prompt', + id: 'telegram-agent', + icon: 'bot' as IconName, + labelKey: + 'experiments.instanceAiWorkflowPreviewSuggestions.suggestions.telegramAgent.label' as BaseTextKey, + promptKey: + 'experiments.instanceAiWorkflowPreviewSuggestions.suggestions.telegramAgent.prompt' as BaseTextKey, + workflowFile: 'telegram-agent', + }, ]; diff --git a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/index.ts b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/index.ts index 7ee1b3c6fa0..3a27e7be9c6 100644 --- a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/index.ts +++ b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/index.ts @@ -1,8 +1,8 @@ import type { PreviewWorkflow } from './types'; import { scoreMyLeadsWorkflow } from './score-my-leads'; import { processInvoicesWorkflow } from './process-invoices'; -import { whatsappSupportWorkflow } from './whatsapp-support'; import { scheduleSocialPostsWorkflow } from './schedule-social-posts'; +import { telegramAgentWorkflow } from './telegram-agent'; export type { PreviewWorkflow, @@ -18,8 +18,8 @@ export type { const workflowRegistry: Record = { 'score-my-leads': scoreMyLeadsWorkflow, 'process-invoices': processInvoicesWorkflow, - 'whatsapp-support': whatsappSupportWorkflow, 'schedule-social-posts': scheduleSocialPostsWorkflow, + 'telegram-agent': telegramAgentWorkflow, }; export function getPreviewWorkflow(workflowFile: string): PreviewWorkflow | undefined { diff --git a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/process-invoices.ts b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/process-invoices.ts index bf8d113d4fa..7540d2a157e 100644 --- a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/process-invoices.ts +++ b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/process-invoices.ts @@ -1,12 +1,12 @@ import type { PreviewWorkflow } from './types'; -const GMAIL_ICON_SVG = +export const GMAIL_ICON_SVG = 'data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%22256%22%20height=%22193%22%20preserveAspectRatio=%22xMidYMid%22%3E%3Cpath%20fill=%22%234285F4%22%20d=%22M58.182%20192.05V93.14L27.507%2065.077%200%2049.504v125.091c0%209.658%207.825%2017.455%2017.455%2017.455z%22/%3E%3Cpath%20fill=%22%2334A853%22%20d=%22M197.818%20192.05h40.727c9.659%200%2017.455-7.826%2017.455-17.455V49.505l-31.156%2017.837-27.026%2025.798z%22/%3E%3Cpath%20fill=%22%23EA4335%22%20d=%22m58.182%2093.14-4.174-38.647%204.174-36.989L128%2069.868l69.818-52.364%204.67%2034.992-4.67%2040.644L128%20145.504z%22/%3E%3Cpath%20fill=%22%23FBBC04%22%20d=%22M197.818%2017.504V93.14L256%2049.504V26.231c0-21.585-24.64-33.89-41.89-20.945z%22/%3E%3Cpath%20fill=%22%23C5221F%22%20d=%22m0%2049.504%2026.759%2020.07L58.182%2093.14V17.504L41.89%205.286C24.61-7.66%200%204.646%200%2026.23z%22/%3E%3C/svg%3E'; -const ANTHROPIC_ICON_SVG = +export const ANTHROPIC_ICON_SVG = 'data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2246%22%20height=%2232%22%20fill=%22none%22%3E%3Cpath%20fill=%22%237D7D87%22%20d=%22M32.73%200h-6.945L38.45%2032h6.945zM12.665%200%200%2032h7.082l2.59-6.72h13.25l2.59%206.72h7.082L19.929%200zm-.702%2019.337%204.334-11.246%204.334%2011.246z%22/%3E%3C/svg%3E'; -const GOOGLE_SHEETS_ICON_SVG = +export const GOOGLE_SHEETS_ICON_SVG = 'data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2260%22%20height=%2260%22%3E%3Cg%20fill=%22none%22%20fill-rule=%22evenodd%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpath%20fill=%22%2328B446%22%20d=%22M35.69%201%2052%2017.225v39.087a3.67%203.67%200%200%201-1.084%202.61A3.7%203.7%200%200%201%2048.293%2060H12.707a3.7%203.7%200%200%201-2.623-1.078A3.67%203.67%200%200%201%209%2056.312V4.688a3.67%203.67%200%200%201%201.084-2.61A3.7%203.7%200%200%201%2012.707%201z%22/%3E%3Cpath%20fill=%22%236ACE7C%22%20d=%22M35.69%201%2052%2017.225H39.397c-2.054%200-3.707-1.829-3.707-3.872z%22/%3E%3Cpath%20fill=%22%23219B38%22%20d=%22M39.211%2017.225%2052%2022.48v-5.255z%22/%3E%3Cpath%20fill=%22%23FFF%22%20d=%22M20.12%2031.975c0-.817.662-1.475%201.483-1.475h17.794c.821%200%201.482.658%201.482%201.475v15.487c0%20.818-.661%201.475-1.482%201.475H21.603a1.476%201.476%200%200%201-1.482-1.474V31.974zm2.225%201.475h6.672v2.212h-6.672zm0%205.162h6.672v2.213h-6.672zm0%205.163h6.672v2.212h-6.672zm9.638-10.325h6.672v2.212h-6.672zm0%205.162h6.672v2.213h-6.672zm0%205.163h6.672v2.212h-6.672z%22/%3E%3Cpath%20fill=%22%2328B446%22%20d=%22M34.69%200%2051%2016.225v39.087a3.67%203.67%200%200%201-1.084%202.61A3.7%203.7%200%200%201%2047.293%2059H11.707a3.7%203.7%200%200%201-2.623-1.078A3.67%203.67%200%200%201%208%2055.312V3.688a3.67%203.67%200%200%201%201.084-2.61A3.7%203.7%200%200%201%2011.707%200z%22/%3E%3Cpath%20fill=%22%236ACE7C%22%20d=%22M34.69%200%2051%2016.225H38.397c-2.054%200-3.707-1.829-3.707-3.872z%22/%3E%3Cpath%20fill=%22%23219B38%22%20d=%22M38.211%2016.225%2051%2021.48v-5.255z%22/%3E%3Cpath%20fill=%22%23FFF%22%20d=%22M19.12%2030.975c0-.817.662-1.475%201.483-1.475h17.794c.821%200%201.482.658%201.482%201.475v15.487c0%20.818-.661%201.475-1.482%201.475H20.603a1.476%201.476%200%200%201-1.482-1.474V30.974zm2.225%201.475h6.672v2.212h-6.672zm0%205.162h6.672v2.213h-6.672zm0%205.163h6.672v2.212h-6.672zm9.638-10.325h6.672v2.212h-6.672zm0%205.162h6.672v2.213h-6.672zm0%205.163h6.672v2.212h-6.672z%22/%3E%3C/g%3E%3C/svg%3E'; const GOOGLE_CALENDAR_ICON_SVG = diff --git a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/telegram-agent.ts b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/telegram-agent.ts new file mode 100644 index 00000000000..223ddb19428 --- /dev/null +++ b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/telegram-agent.ts @@ -0,0 +1,9 @@ +import type { PreviewWorkflow } from './types'; + +export const telegramAgentWorkflow: PreviewWorkflow = { + nodes: [], + connections: [], + fullCanvasVisualization: { + type: 'agent-builder', + }, +}; diff --git a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/types.ts b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/types.ts index c8205ac09c0..dec4ba697ef 100644 --- a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/types.ts +++ b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/types.ts @@ -22,7 +22,7 @@ export type PreviewVisualizationType = | 'slack-message' | 'salesforce-card' | 'invoice-spreadsheet' - | 'whatsapp-chat'; + | 'agent-builder'; export interface PreviewVisualization { type: PreviewVisualizationType; @@ -51,5 +51,6 @@ export interface PreviewWorkflow { connections: PreviewWorkflowConnection[]; inputVisualization?: PreviewVisualization; outputVisualization?: PreviewVisualization | PreviewOutputVisualization[]; + fullCanvasVisualization?: PreviewVisualization; crmCycle?: CrmCycleConfig; } diff --git a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/whatsapp-support.ts b/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/whatsapp-support.ts deleted file mode 100644 index e1aca663bc8..00000000000 --- a/packages/frontend/editor-ui/src/experiments/instanceAiWorkflowPreviewSuggestions/workflows/whatsapp-support.ts +++ /dev/null @@ -1,91 +0,0 @@ -import type { PreviewWorkflow } from './types'; - -const WHATSAPP_ICON_SVG = - 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2260%22%20height%3D%2260%22%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20viewBox%3D%220%200%2048%2048%22%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22m4.868%2043.303%202.694-9.835a18.94%2018.94%200%200%201-2.535-9.489C5.032%2013.514%2013.548%205%2024.014%205a18.87%2018.87%200%200%201%2013.43%205.566A18.87%2018.87%200%200%201%2043%2023.994c-.004%2010.465-8.522%2018.98-18.986%2018.98h-.008a19%2019%200%200%201-9.073-2.311z%22/%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22M4.868%2043.803a.5.5%200%200%201-.482-.631l2.639-9.636a19.5%2019.5%200%200%201-2.497-9.556C4.532%2013.238%2013.273%204.5%2024.014%204.5a19.37%2019.37%200%200%201%2013.784%205.713A19.36%2019.36%200%200%201%2043.5%2023.994c-.004%2010.741-8.746%2019.48-19.486%2019.48a19.54%2019.54%200%200%201-9.144-2.277l-9.875%202.589a.5.5%200%200%201-.127.017%22/%3E%3Cpath%20fill%3D%22%23cfd8dc%22%20d%3D%22M24.014%205a18.87%2018.87%200%200%201%2013.43%205.566A18.87%2018.87%200%200%201%2043%2023.994c-.004%2010.465-8.522%2018.98-18.986%2018.98h-.008a19%2019%200%200%201-9.073-2.311l-10.065%202.64%202.694-9.835a18.94%2018.94%200%200%201-2.535-9.489C5.032%2013.514%2013.548%205%2024.014%205m0-1C12.998%204%204.032%2012.962%204.027%2023.979a20%2020%200%200%200%202.461%209.622L3.903%2043.04a.998.998%200%200%200%201.219%201.231l9.687-2.54a20%2020%200%200%200%209.197%202.244c11.024%200%2019.99-8.963%2019.995-19.98A19.86%2019.86%200%200%200%2038.153%209.86%2019.87%2019.87%200%200%200%2024.014%204%22/%3E%3Cpath%20fill%3D%22%2340c351%22%20d%3D%22M35.176%2012.832a15.67%2015.67%200%200%200-11.157-4.626c-8.704%200-15.783%207.076-15.787%2015.774a15.74%2015.74%200%200%200%202.413%208.396l.376.597-1.595%205.821%205.973-1.566.577.342a15.75%2015.75%200%200%200%208.032%202.199h.006c8.698%200%2015.777-7.077%2015.78-15.776a15.68%2015.68%200%200%200-4.618-11.161%22/%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22M19.268%2016.045c-.355-.79-.729-.806-1.068-.82-.277-.012-.593-.011-.909-.011s-.83.119-1.265.594-1.661%201.622-1.661%203.956%201.7%204.59%201.937%204.906%203.282%205.259%208.104%207.161c4.007%201.58%204.823%201.266%205.693%201.187s2.807-1.147%203.202-2.255.395-2.057.277-2.255c-.119-.198-.435-.316-.909-.554s-2.807-1.385-3.242-1.543-.751-.237-1.068.238c-.316.474-1.225%201.543-1.502%201.859s-.554.357-1.028.119-2.002-.738-3.815-2.354c-1.41-1.257-2.362-2.81-2.639-3.285-.277-.474-.03-.731.208-.968.213-.213.474-.554.712-.831.237-.277.316-.475.474-.791s.079-.594-.04-.831c-.117-.238-1.039-2.584-1.461-3.522%22/%3E%3C/svg%3E'; - -const GEMINI_ICON_SVG = - 'data:image/svg+xml,%3Csvg%20class%3D%22_footerSpark_98udt_151%22%20width%3D%2264%22%20height%3D%2264%22%20viewBox%3D%220%200%2064%2064%22%20fill%3D%22none%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%3Cpath%20d%3D%22M57.0667%2028.6103C52.1359%2026.4878%2047.8217%2023.576%2044.1223%2019.8784C40.4247%2016.1808%2037.5128%2011.8649%2035.3902%206.9342C34.5754%205.04449%2033.9206%203.10204%2033.4186%201.11049C33.2549%200.459368%2032.6711%200.0010376%2032%200.0010376C31.3288%200.0010376%2030.745%200.459368%2030.5813%201.11049C30.0793%203.10204%2029.4246%205.04267%2028.6097%206.9342C26.4872%2011.8649%2023.5753%2016.1808%2019.8777%2019.8784C16.18%2023.576%2011.864%2026.4878%206.93327%2028.6103C5.04353%2029.4251%203.10105%2030.0799%201.10947%2030.5819C0.458338%2030.7456%200%2031.3294%200%2032.0005C0%2032.6716%200.458338%2033.2555%201.10947%2033.4191C3.10105%2033.9211%205.04172%2034.5759%206.93327%2035.3907C11.864%2037.5132%2016.1782%2040.4251%2019.8777%2044.1226C23.5771%2047.8202%2026.4872%2052.1361%2028.6097%2057.0668C29.4246%2058.9565%2030.0793%2060.899%2030.5813%2062.8905C30.745%2063.5416%2031.3288%2064%2032%2064C32.6711%2064%2033.2549%2063.5416%2033.4186%2062.8905C33.9206%2060.899%2034.5754%2058.9583%2035.3902%2057.0668C37.5128%2052.1361%2040.4247%2047.822%2044.1223%2044.1226C47.8199%2040.4251%2052.1359%2037.5132%2057.0667%2035.3907C58.9564%2034.5759%2060.8989%2033.9211%2062.8905%2033.4191C63.5416%2033.2555%2064%2032.6716%2064%2032.0005C64%2031.3294%2063.5416%2030.7456%2062.8905%2030.5819C60.8989%2030.0799%2058.9582%2029.4251%2057.0667%2028.6103Z%22%20fill%3D%22white%22%3E%3C/path%3E%3Cmask%20id%3D%22mask0_10859_4894%22%20style%3D%22mask-type%3Aalpha%22%20maskUnits%3D%22userSpaceOnUse%22%20x%3D%220%22%20y%3D%220%22%20width%3D%2264%22%20height%3D%2264%22%3E%3Cpath%20d%3D%22M32%200C32.6711%201.144e-05%2033.2553%200.458263%2033.4189%201.10938C33.9209%203.10093%2034.5758%205.04389%2035.3906%206.93359C37.5131%2011.8639%2040.4247%2016.1796%2044.1221%2019.877C47.8215%2023.5745%2052.1357%2026.4869%2057.0664%2028.6094C58.958%2029.4242%2060.899%2030.0791%2062.8906%2030.5811C63.5415%2030.7448%2063.9998%2031.3281%2064%2031.999C64%2032.6701%2063.5417%2033.2542%2062.8906%2033.418C60.899%2033.9199%2058.9561%2034.5748%2057.0664%2035.3896C52.1358%2037.5121%2047.8196%2040.4237%2044.1221%2044.1211C40.4246%2047.8204%2037.5131%2052.1349%2035.3906%2057.0654C34.5758%2058.957%2033.9209%2060.8981%2033.4189%2062.8896C33.2552%2063.5407%2032.6711%2063.999%2032%2063.999C31.3289%2063.999%2030.7448%2063.5407%2030.5811%2062.8896C30.0791%2060.8981%2029.4242%2058.9551%2028.6094%2057.0654C26.4869%2052.1349%2023.5773%2047.8186%2019.8779%2044.1211C16.1786%2040.4237%2011.8642%2037.5121%206.93359%2035.3896C5.04204%2034.5748%203.10096%2033.9199%201.10938%2033.418C0.458309%2033.2542%200%2032.6701%200%2031.999C0.000201548%2031.3281%200.458463%2030.7448%201.10938%2030.5811C3.10096%2030.0791%205.04386%2029.4242%206.93359%2028.6094C11.8643%2026.4869%2016.1804%2023.5745%2019.8779%2019.877C23.5753%2016.1796%2026.4869%2011.8639%2028.6094%206.93359C29.4242%205.04207%2030.0791%203.10093%2030.5811%201.10938C30.7448%200.45826%2031.3289%200%2032%200Z%22%20fill%3D%22black%22%3E%3C/path%3E%3Cpath%20d%3D%22M32%200C32.6711%201.144e-05%2033.2553%200.458263%2033.4189%201.10938C33.9209%203.10093%2034.5758%205.04389%2035.3906%206.93359C37.5131%2011.8639%2040.4247%2016.1796%2044.1221%2019.877C47.8215%2023.5745%2052.1357%2026.4869%2057.0664%2028.6094C58.958%2029.4242%2060.899%2030.0791%2062.8906%2030.5811C63.5415%2030.7448%2063.9998%2031.3281%2064%2031.999C64%2032.6701%2063.5417%2033.2542%2062.8906%2033.418C60.899%2033.9199%2058.9561%2034.5748%2057.0664%2035.3896C52.1358%2037.5121%2047.8196%2040.4237%2044.1221%2044.1211C40.4246%2047.8204%2037.5131%2052.1349%2035.3906%2057.0654C34.5758%2058.957%2033.9209%2060.8981%2033.4189%2062.8896C33.2552%2063.5407%2032.6711%2063.999%2032%2063.999C31.3289%2063.999%2030.7448%2063.5407%2030.5811%2062.8896C30.0791%2060.8981%2029.4242%2058.9551%2028.6094%2057.0654C26.4869%2052.1349%2023.5773%2047.8186%2019.8779%2044.1211C16.1786%2040.4237%2011.8642%2037.5121%206.93359%2035.3896C5.04204%2034.5748%203.10096%2033.9199%201.10938%2033.418C0.458309%2033.2542%200%2032.6701%200%2031.999C0.000201548%2031.3281%200.458463%2030.7448%201.10938%2030.5811C3.10096%2030.0791%205.04386%2029.4242%206.93359%2028.6094C11.8643%2026.4869%2016.1804%2023.5745%2019.8779%2019.877C23.5753%2016.1796%2026.4869%2011.8639%2028.6094%206.93359C29.4242%205.04207%2030.0791%203.10093%2030.5811%201.10938C30.7448%200.45826%2031.3289%200%2032%200Z%22%20fill%3D%22url%28%23paint0_linear_10859_4894%29%22%3E%3C/path%3E%3C/mask%3E%3Cg%20mask%3D%22url%28%23mask0_10859_4894%29%22%3E%3Cg%20filter%3D%22url%28%23filter0_f_10859_4894%29%22%3E%3Cellipse%20cx%3D%2214.2084%22%20cy%3D%2216.7164%22%20rx%3D%2214.2084%22%20ry%3D%2216.7164%22%20transform%3D%22matrix%280.942343%200.334649%20-0.334656%200.94234%20-7.979%2013.7735%29%22%20fill%3D%22%23FFE432%22%3E%3C/ellipse%3E%3C/g%3E%3Cg%20filter%3D%22url%28%23filter1_f_10859_4894%29%22%3E%3Cellipse%20cx%3D%2227.0543%22%20cy%3D%222.55114%22%20rx%3D%2218.3944%22%20ry%3D%2218.7985%22%20fill%3D%22%23FC413D%22%3E%3C/ellipse%3E%3C/g%3E%3Cg%20filter%3D%22url%28%23filter2_f_10859_4894%29%22%3E%3Cellipse%20cx%3D%2219.2245%22%20cy%3D%2224.9042%22%20rx%3D%2219.2245%22%20ry%3D%2224.9042%22%20transform%3D%22matrix%280.998807%20-0.0488254%200.0488266%200.998807%20-1.72778%2032.6573%29%22%20fill%3D%22%2300B95C%22%3E%3C/ellipse%3E%3C/g%3E%3Cg%20filter%3D%22url%28%23filter3_f_10859_4894%29%22%3E%3Cellipse%20cx%3D%2219.2245%22%20cy%3D%2224.9042%22%20rx%3D%2219.2245%22%20ry%3D%2224.9042%22%20transform%3D%22matrix%280.998807%20-0.0488254%200.0488266%200.998807%20-1.72778%2032.6573%29%22%20fill%3D%22%2300B95C%22%3E%3C/ellipse%3E%3C/g%3E%3Cg%20filter%3D%22url%28%23filter4_f_10859_4894%29%22%3E%3Cellipse%20cx%3D%2218.8429%22%20cy%3D%2220.7441%22%20rx%3D%2218.8429%22%20ry%3D%2220.7441%22%20transform%3D%22matrix%280.854301%20-0.519779%200.51979%200.854294%20-7.13574%2047.5078%29%22%20fill%3D%22%2300B95C%22%3E%3C/ellipse%3E%3C/g%3E%3Cg%20filter%3D%22url%28%23filter5_f_10859_4894%29%22%3E%3Cellipse%20cx%3D%2266.4617%22%20cy%3D%2224.977%22%20rx%3D%2218.0933%22%20ry%3D%2217.4229%22%20fill%3D%22%233186FF%22%3E%3C/ellipse%3E%3C/g%3E%3Cg%20filter%3D%22url%28%23filter6_f_10859_4894%29%22%3E%3Cellipse%20cx%3D%2220.9292%22%20cy%3D%2222.0752%22%20rx%3D%2220.9292%22%20ry%3D%2222.0752%22%20transform%3D%22matrix%280.79599%200.60531%20-0.60532%200.795982%20-2.81885%20-7.43323%29%22%20fill%3D%22%23FBBC04%22%3E%3C/ellipse%3E%3C/g%3E%3Cg%20filter%3D%22url%28%23filter7_f_10859_4894%29%22%3E%3Cellipse%20cx%3D%2224.1311%22%20cy%3D%2222.2919%22%20rx%3D%2224.1311%22%20ry%3D%2222.2919%22%20transform%3D%22matrix%280.824037%200.566536%20-0.566546%200.82403%2039.6338%200.310608%29%22%20fill%3D%22%233186FF%22%3E%3C/ellipse%3E%3C/g%3E%3Cg%20filter%3D%22url%28%23filter8_f_10859_4894%29%22%3E%3Cpath%20d%3D%22M54.2255%20-2.30403C57.0195%201.49462%2053.4294%208.8804%2046.2068%2014.1926C38.9842%2019.5048%2030.8642%2020.7318%2028.0702%2016.9331C25.2762%2013.1345%2028.8663%205.74867%2036.0889%200.436486C43.3115%20-4.8757%2051.4315%20-6.10267%2054.2255%20-2.30403Z%22%20fill%3D%22%23749BFF%22%3E%3C/path%3E%3C/g%3E%3Cg%20filter%3D%22url%28%23filter9_f_10859_4894%29%22%3E%3Cellipse%20cx%3D%2227.5853%22%20cy%3D%2217.1478%22%20rx%3D%2227.5853%22%20ry%3D%2217.1478%22%20transform%3D%22matrix%280.733166%20-0.680049%200.680061%200.733155%20-12.2583%209.49695%29%22%20fill%3D%22%23FC413D%22%3E%3C/ellipse%3E%3C/g%3E%3Cg%20filter%3D%22url%28%23filter10_f_10859_4894%29%22%3E%3Cellipse%20cx%3D%2214.7819%22%20cy%3D%228.59637%22%20rx%3D%2214.7819%22%20ry%3D%228.59637%22%20transform%3D%22matrix%280.813186%200.582004%20-0.582016%200.813177%206.37842%2030.511%29%22%20fill%3D%22%23FFEE48%22%3E%3C/ellipse%3E%3C/g%3E%3C/g%3E%3Cdefs%3E%3Cfilter%20id%3D%22filter0_f_10859_4894%22%20x%3D%22-19.618%22%20y%3D%2212.9027%22%20width%3D%2238.8681%22%20height%3D%2242.7562%22%20filterUnits%3D%22userSpaceOnUse%22%20color-interpolation-filters%3D%22sRGB%22%3E%3CfeFlood%20flood-opacity%3D%220%22%20result%3D%22BackgroundImageFix%22%3E%3C/feFlood%3E%3CfeBlend%20mode%3D%22normal%22%20in%3D%22SourceGraphic%22%20in2%3D%22BackgroundImageFix%22%20result%3D%22shape%22%3E%3C/feBlend%3E%3CfeGaussianBlur%20stdDeviation%3D%222.45965%22%20result%3D%22effect1_foregroundBlur_10859_4894%22%3E%3C/feGaussianBlur%3E%3C/filter%3E%3Cfilter%20id%3D%22filter1_f_10859_4894%22%20x%3D%22-15.1223%22%20y%3D%22-40.0296%22%20width%3D%2284.3533%22%20height%3D%2285.1615%22%20filterUnits%3D%22userSpaceOnUse%22%20color-interpolation-filters%3D%22sRGB%22%3E%3CfeFlood%20flood-opacity%3D%220%22%20result%3D%22BackgroundImageFix%22%3E%3C/feFlood%3E%3CfeBlend%20mode%3D%22normal%22%20in%3D%22SourceGraphic%22%20in2%3D%22BackgroundImageFix%22%20result%3D%22shape%22%3E%3C/feBlend%3E%3CfeGaussianBlur%20stdDeviation%3D%2211.8911%22%20result%3D%22effect1_foregroundBlur_10859_4894%22%3E%3C/feGaussianBlur%3E%3C/filter%3E%3Cfilter%20id%3D%22filter2_f_10859_4894%22%20x%3D%22-20.7682%22%20y%3D%2211.4835%22%20width%3D%2278.9161%22%20height%3D%2290.2196%22%20filterUnits%3D%22userSpaceOnUse%22%20color-interpolation-filters%3D%22sRGB%22%3E%3CfeFlood%20flood-opacity%3D%220%22%20result%3D%22BackgroundImageFix%22%3E%3C/feFlood%3E%3CfeBlend%20mode%3D%22normal%22%20in%3D%22SourceGraphic%22%20in2%3D%22BackgroundImageFix%22%20result%3D%22shape%22%3E%3C/feBlend%3E%3CfeGaussianBlur%20stdDeviation%3D%2210.1086%22%20result%3D%22effect1_foregroundBlur_10859_4894%22%3E%3C/feGaussianBlur%3E%3C/filter%3E%3Cfilter%20id%3D%22filter3_f_10859_4894%22%20x%3D%22-20.7682%22%20y%3D%2211.4835%22%20width%3D%2278.9161%22%20height%3D%2290.2196%22%20filterUnits%3D%22userSpaceOnUse%22%20color-interpolation-filters%3D%22sRGB%22%3E%3CfeFlood%20flood-opacity%3D%220%22%20result%3D%22BackgroundImageFix%22%3E%3C/feFlood%3E%3CfeBlend%20mode%3D%22normal%22%20in%3D%22SourceGraphic%22%20in2%3D%22BackgroundImageFix%22%20result%3D%22shape%22%3E%3C/feBlend%3E%3CfeGaussianBlur%20stdDeviation%3D%2210.1086%22%20result%3D%22effect1_foregroundBlur_10859_4894%22%3E%3C/feGaussianBlur%3E%3C/filter%3E%3Cfilter%20id%3D%22filter4_f_10859_4894%22%20x%3D%22-19.85%22%20y%3D%2214.9664%22%20width%3D%2279.1886%22%20height%3D%2280.9378%22%20filterUnits%3D%22userSpaceOnUse%22%20color-interpolation-filters%3D%22sRGB%22%3E%3CfeFlood%20flood-opacity%3D%220%22%20result%3D%22BackgroundImageFix%22%3E%3C/feFlood%3E%3CfeBlend%20mode%3D%22normal%22%20in%3D%22SourceGraphic%22%20in2%3D%22BackgroundImageFix%22%20result%3D%22shape%22%3E%3C/feBlend%3E%3CfeGaussianBlur%20stdDeviation%3D%2210.1086%22%20result%3D%22effect1_foregroundBlur_10859_4894%22%3E%3C/feGaussianBlur%3E%3C/filter%3E%3Cfilter%20id%3D%22filter5_f_10859_4894%22%20x%3D%2229.1561%22%20y%3D%22-11.6582%22%20width%3D%2274.6111%22%20height%3D%2273.2703%22%20filterUnits%3D%22userSpaceOnUse%22%20color-interpolation-filters%3D%22sRGB%22%3E%3CfeFlood%20flood-opacity%3D%220%22%20result%3D%22BackgroundImageFix%22%3E%3C/feFlood%3E%3CfeBlend%20mode%3D%22normal%22%20in%3D%22SourceGraphic%22%20in2%3D%22BackgroundImageFix%22%20result%3D%22shape%22%3E%3C/feBlend%3E%3CfeGaussianBlur%20stdDeviation%3D%229.60613%22%20result%3D%22effect1_foregroundBlur_10859_4894%22%3E%3C/feGaussianBlur%3E%3C/filter%3E%3Cfilter%20id%3D%22filter6_f_10859_4894%22%20x%3D%22-38.291%22%20y%3D%22-16.2687%22%20width%3D%2277.538%22%20height%3D%2278.1513%22%20filterUnits%3D%22userSpaceOnUse%22%20color-interpolation-filters%3D%22sRGB%22%3E%3CfeFlood%20flood-opacity%3D%220%22%20result%3D%22BackgroundImageFix%22%3E%3C/feFlood%3E%3CfeBlend%20mode%3D%22normal%22%20in%3D%22SourceGraphic%22%20in2%3D%22BackgroundImageFix%22%20result%3D%22shape%22%3E%3C/feBlend%3E%3CfeGaussianBlur%20stdDeviation%3D%228.70591%22%20result%3D%22effect1_foregroundBlur_10859_4894%22%3E%3C/feGaussianBlur%3E%3C/filter%3E%3Cfilter%20id%3D%22filter7_f_10859_4894%22%20x%3D%227.78038%22%20y%3D%22-6.0981%22%20width%3D%2278.2181%22%20height%3D%2276.8982%22%20filterUnits%3D%22userSpaceOnUse%22%20color-interpolation-filters%3D%22sRGB%22%3E%3CfeFlood%20flood-opacity%3D%220%22%20result%3D%22BackgroundImageFix%22%3E%3C/feFlood%3E%3CfeBlend%20mode%3D%22normal%22%20in%3D%22SourceGraphic%22%20in2%3D%22BackgroundImageFix%22%20result%3D%22shape%22%3E%3C/feBlend%3E%3CfeGaussianBlur%20stdDeviation%3D%227.77473%22%20result%3D%22effect1_foregroundBlur_10859_4894%22%3E%3C/feGaussianBlur%3E%3C/filter%3E%3Cfilter%20id%3D%22filter8_f_10859_4894%22%20x%3D%2213.2082%22%20y%3D%22-18.425%22%20width%3D%2255.8793%22%20height%3D%2251.4791%22%20filterUnits%3D%22userSpaceOnUse%22%20color-interpolation-filters%3D%22sRGB%22%3E%3CfeFlood%20flood-opacity%3D%220%22%20result%3D%22BackgroundImageFix%22%3E%3C/feFlood%3E%3CfeBlend%20mode%3D%22normal%22%20in%3D%22SourceGraphic%22%20in2%3D%22BackgroundImageFix%22%20result%3D%22shape%22%3E%3C/feBlend%3E%3CfeGaussianBlur%20stdDeviation%3D%226.95694%22%20result%3D%22effect1_foregroundBlur_10859_4894%22%3E%3C/feGaussianBlur%3E%3C/filter%3E%3Cfilter%20id%3D%22filter9_f_10859_4894%22%20x%3D%22-15.4739%22%20y%3D%22-31.0272%22%20width%3D%2270.2034%22%20height%3D%2268.6735%22%20filterUnits%3D%22userSpaceOnUse%22%20color-interpolation-filters%3D%22sRGB%22%3E%3CfeFlood%20flood-opacity%3D%220%22%20result%3D%22BackgroundImageFix%22%3E%3C/feFlood%3E%3CfeBlend%20mode%3D%22normal%22%20in%3D%22SourceGraphic%22%20in2%3D%22BackgroundImageFix%22%20result%3D%22shape%22%3E%3C/feBlend%3E%3CfeGaussianBlur%20stdDeviation%3D%225.87598%22%20result%3D%22effect1_foregroundBlur_10859_4894%22%3E%3C/feGaussianBlur%3E%3C/filter%3E%3Cfilter%20id%3D%22filter10_f_10859_4894%22%20x%3D%22-14.173%22%20y%3D%2220.474%22%20width%3D%2255.1373%22%20height%3D%2251.261%22%20filterUnits%3D%22userSpaceOnUse%22%20color-interpolation-filters%3D%22sRGB%22%3E%3CfeFlood%20flood-opacity%3D%220%22%20result%3D%22BackgroundImageFix%22%3E%3C/feFlood%3E%3CfeBlend%20mode%3D%22normal%22%20in%3D%22SourceGraphic%22%20in2%3D%22BackgroundImageFix%22%20result%3D%22shape%22%3E%3C/feBlend%3E%3CfeGaussianBlur%20stdDeviation%3D%227.27253%22%20result%3D%22effect1_foregroundBlur_10859_4894%22%3E%3C/feGaussianBlur%3E%3C/filter%3E%3ClinearGradient%20id%3D%22paint0_linear_10859_4894%22%20x1%3D%2218.1931%22%20y1%3D%2242.821%22%20x2%3D%2251.4335%22%20y2%3D%2214.7959%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20stop-color%3D%22%234893FC%22%3E%3C/stop%3E%3Cstop%20offset%3D%220.27%22%20stop-color%3D%22%234893FC%22%3E%3C/stop%3E%3Cstop%20offset%3D%220.776981%22%20stop-color%3D%22%23969DFF%22%3E%3C/stop%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23BD99FE%22%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3C/svg%3E%0A'; - -const GOOGLE_SHEETS_ICON_SVG = - 'data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2260%22%20height=%2260%22%3E%3Cg%20fill=%22none%22%20fill-rule=%22evenodd%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpath%20fill=%22%2328B446%22%20d=%22M35.69%201%2052%2017.225v39.087a3.67%203.67%200%200%201-1.084%202.61A3.7%203.7%200%200%201%2048.293%2060H12.707a3.7%203.7%200%200%201-2.623-1.078A3.67%203.67%200%200%201%209%2056.312V4.688a3.67%203.67%200%200%201%201.084-2.61A3.7%203.7%200%200%201%2012.707%201z%22/%3E%3Cpath%20fill=%22%236ACE7C%22%20d=%22M35.69%201%2052%2017.225H39.397c-2.054%200-3.707-1.829-3.707-3.872z%22/%3E%3Cpath%20fill=%22%23219B38%22%20d=%22M39.211%2017.225%2052%2022.48v-5.255z%22/%3E%3Cpath%20fill=%22%23FFF%22%20d=%22M20.12%2031.975c0-.817.662-1.475%201.483-1.475h17.794c.821%200%201.482.658%201.482%201.475v15.487c0%20.818-.661%201.475-1.482%201.475H21.603a1.476%201.476%200%200%201-1.482-1.474V31.974zm2.225%201.475h6.672v2.212h-6.672zm0%205.162h6.672v2.213h-6.672zm0%205.163h6.672v2.212h-6.672zm9.638-10.325h6.672v2.212h-6.672zm0%205.162h6.672v2.213h-6.672zm0%205.163h6.672v2.212h-6.672z%22/%3E%3Cpath%20fill=%22%2328B446%22%20d=%22M34.69%200%2051%2016.225v39.087a3.67%203.67%200%200%201-1.084%202.61A3.7%203.7%200%200%201%2047.293%2059H11.707a3.7%203.7%200%200%201-2.623-1.078A3.67%203.67%200%200%201%208%2055.312V3.688a3.67%203.67%200%200%201%201.084-2.61A3.7%203.7%200%200%201%2011.707%200z%22/%3E%3Cpath%20fill=%22%236ACE7C%22%20d=%22M34.69%200%2051%2016.225H38.397c-2.054%200-3.707-1.829-3.707-3.872z%22/%3E%3Cpath%20fill=%22%23219B38%22%20d=%22M38.211%2016.225%2051%2021.48v-5.255z%22/%3E%3Cpath%20fill=%22%23FFF%22%20d=%22M19.12%2030.975c0-.817.662-1.475%201.483-1.475h17.794c.821%200%201.482.658%201.482%201.475v15.487c0%20.818-.661%201.475-1.482%201.475H20.603a1.476%201.476%200%200%201-1.482-1.474V30.974zm2.225%201.475h6.672v2.212h-6.672zm0%205.162h6.672v2.213h-6.672zm0%205.163h6.672v2.212h-6.672zm9.638-10.325h6.672v2.212h-6.672zm0%205.162h6.672v2.213h-6.672zm0%205.163h6.672v2.212h-6.672z%22/%3E%3C/g%3E%3C/svg%3E'; - -const NOTION_ICON_SVG = - 'data:image/svg+xml,%3Csvg%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%220%200%2040%2040%22%20fill%3D%22none%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M7.58276%206.97679C8.82047%207.98238%209.28479%207.90566%2011.6091%207.75057L33.5206%206.43488C33.9853%206.43488%2033.5989%205.97127%2033.4439%205.89423L29.8049%203.26348C29.1076%202.72213%2028.1786%202.10217%2026.3982%202.25726L5.18115%203.80476C4.40736%203.88148%204.25282%204.26837%204.56096%204.57847L7.58276%206.97679ZM8.89829%2012.0833V35.1381C8.89829%2036.3771%209.51746%2036.8407%2010.911%2036.764L34.9919%2035.3706C36.3862%2035.2939%2036.5415%2034.4417%2036.5415%2033.4352V10.5351C36.5415%209.53019%2036.1549%208.98829%2035.3014%209.06564L10.1367%2010.5351C9.20799%2010.6131%208.89821%2011.0777%208.89821%2012.0833H8.89829ZM32.6708%2013.32C32.8252%2014.017%2032.6708%2014.7133%2031.9725%2014.7917L30.8123%2015.0229V32.0434C29.8049%2032.5848%2028.8759%2032.8944%2028.1018%2032.8944C26.8625%2032.8944%2026.5521%2032.5072%2025.6237%2031.3474L18.0343%2019.4329V30.9605L20.4359%2031.5024C20.4359%2031.5024%2020.4359%2032.8944%2018.4983%2032.8944L13.1568%2033.2042C13.0016%2032.8944%2013.1568%2032.1214%2013.6986%2031.9665L15.0925%2031.5802V16.3385L13.1572%2016.1834C13.0019%2015.4864%2013.3885%2014.4814%2014.4733%2014.4035L20.2035%2014.0172L28.1018%2026.0868V15.4097L26.0881%2015.1786C25.9335%2014.3265%2026.5521%2013.7078%2027.3265%2013.6311L32.6708%2013.32ZM3.39973%201.71598L25.4688%200.0907457C28.179%20-0.141688%2028.8763%200.0140245%2030.5796%201.25135L37.6243%206.20276C38.7867%207.05421%2039.1742%207.28602%2039.1742%208.21419V35.3706C39.1742%2037.0726%2038.5542%2038.0791%2036.3865%2038.2331L10.7577%2039.7807C9.13049%2039.8583%208.35607%2039.6264%207.50392%2038.5426L2.31608%2031.8117C1.38658%2030.5726%201%2029.6457%201%2028.5613V4.42283C1%203.03105%201.62019%201.87005%203.39973%201.71598V1.71598Z%22%20fill%3D%22white%22/%3E%0A%3C/svg%3E%0A'; - -export const whatsappSupportWorkflow: PreviewWorkflow = { - nodes: [ - { - id: 'whatsapp-trigger', - label: 'Message received', - icon: { type: 'file', src: WHATSAPP_ICON_SVG }, - position: { x: 0, y: 120 }, - }, - { - id: 'lookup-faq', - label: 'Lookup FAQ', - icon: { type: 'file', src: GOOGLE_SHEETS_ICON_SVG }, - position: { x: 220, y: 120 }, - }, - { - id: 'claude', - label: 'Generate reply', - icon: { type: 'file', src: GEMINI_ICON_SVG }, - position: { x: 440, y: 120 }, - }, - { - id: 'if-resolved', - label: 'Resolved?', - icon: { type: 'icon', name: 'node:if' }, - iconColor: 'green', - position: { x: 660, y: 120 }, - }, - { - id: 'whatsapp-reply', - label: 'Send reply', - icon: { type: 'file', src: WHATSAPP_ICON_SVG }, - position: { x: 880, y: 0 }, - }, - { - id: 'notion-ticket', - label: 'Create ticket', - icon: { type: 'file', src: NOTION_ICON_SVG, lightInvert: true }, - position: { x: 880, y: 240 }, - }, - ], - connections: [ - { source: 'whatsapp-trigger', target: 'lookup-faq' }, - { source: 'lookup-faq', target: 'claude' }, - { source: 'claude', target: 'if-resolved' }, - { source: 'if-resolved', target: 'whatsapp-reply' }, - { source: 'if-resolved', target: 'notion-ticket' }, - ], - inputVisualization: { - type: 'whatsapp-chat', - props: { - sender: 'Customer', - message: 'How do I reset my password?', - slideFrom: 'left', - }, - }, - outputVisualization: [ - { - type: 'whatsapp-chat', - targetNodeId: 'whatsapp-reply', - props: { - sender: 'Support Bot', - message: 'Go to Settings → Security → Reset Password ✓', - isOutgoing: true, - }, - }, - { - type: 'salesforce-card', - targetNodeId: 'notion-ticket', - props: { - icon: NOTION_ICON_SVG, - title: 'Ticket created', - subtitle: 'Password reset · Unresolved', - lightInvert: true, - }, - }, - ], -}; diff --git a/packages/frontend/editor-ui/src/features/ai/instanceAi/InstanceAiEmptyView.vue b/packages/frontend/editor-ui/src/features/ai/instanceAi/InstanceAiEmptyView.vue index f36934040f9..5456a569782 100644 --- a/packages/frontend/editor-ui/src/features/ai/instanceAi/InstanceAiEmptyView.vue +++ b/packages/frontend/editor-ui/src/features/ai/instanceAi/InstanceAiEmptyView.vue @@ -431,8 +431,9 @@ const CANVAS_NATURAL_HEIGHT_PX = 420; const PREVIEW_MIN_SCALE = 0.3; const previewScale = ref(1); +const previewRemainingSpace = ref(CANVAS_NATURAL_HEIGHT_PX); -useResizeObserver(emptyLayoutRef, () => { +function updatePreviewScale() { if (!emptyLayoutRef.value || !centeredInputRef.value) return; const containerRect = emptyLayoutRef.value.getBoundingClientRect(); const inputRect = centeredInputRef.value.getBoundingClientRect(); @@ -440,15 +441,20 @@ useResizeObserver(emptyLayoutRef, () => { const bottomPadding = parseFloat(layoutStyles.paddingBottom); const gap = parseFloat(layoutStyles.gap) || 0; const remainingSpace = containerRect.bottom - inputRect.bottom - bottomPadding - gap; + previewRemainingSpace.value = Math.max(0, remainingSpace); previewScale.value = Math.max(0, Math.min(1, remainingSpace / CANVAS_NATURAL_HEIGHT_PX)); -}); +} + +useResizeObserver(emptyLayoutRef, updatePreviewScale); +useResizeObserver(centeredInputRef, updatePreviewScale); const hasSpaceForPreview = computed(() => previewScale.value >= PREVIEW_MIN_SCALE); const workflowPreviewWrapperStyle = computed(() => ({ transform: `scale(${previewScale.value})`, transformOrigin: 'top center', - height: `${CANVAS_NATURAL_HEIGHT_PX * previewScale.value}px`, + height: `${previewRemainingSpace.value}px`, + '--workflow-preview-canvas-height': `${Math.max(CANVAS_NATURAL_HEIGHT_PX, previewRemainingSpace.value)}px`, })); useChatInputAutoFocus(chatInputRef, { disabled: isStartingThread });