# SWITCHER Feature - Response Format Modifiers ## Overview Add a switcher interface that allows users to toggle response modifiers that influence how the AI generates responses. Unlike suggestions (which are one-time actions), switchers are persistent toggles that remain active until deactivated. ## Location `botui/ui/suite/chat/` - alongside existing suggestion buttons ## Syntax ### Standard Switcher (predefined prompt) ``` ADD SWITCHER "tables" AS "Tabelas" ``` ### Custom Switcher (with custom prompt) ``` ADD SWITCHER "sempre mostrar 10 perguntas" AS "Mostrar Perguntas" ``` ## What Switcher Does The switcher: 1. **Injects the prompt** into every LLM request 2. **The prompt** can be: - **Standard**: References a predefined prompt by ID (`"tables"`, `"cards"`, etc.) - **Custom**: Any custom instruction string (`"sempre mostrar 10 perguntas"`) 3. **Influences** the AI response format 4. **Persists** until toggled OFF ## Available Standard Switchers | ID | Label | Color | Description | |----|--------|--------|-------------| | tables | Tabelas | #4CAF50 | Format responses as tables | | infographic | Infográfico | #2196F3 | Visual, graphical representations | | cards | Cards | #FF9800 | Card-based layout | | list | Lista | #9C27B0 | Bulleted lists | | comparison | Comparação | #E91E63 | Side-by-side comparisons | | timeline | Timeline | #00BCD4 | Chronological ordering | | markdown | Markdown | #607D8B | Standard markdown | | chart | Gráfico | #F44336 | Charts and diagrams | ## Predefined Prompts (Backend) Each standard ID maps to a predefined prompt in the backend: ``` ID: tables Prompt: "REGRAS DE FORMATO: SEMPRE retorne suas respostas em formato de tabela HTML usando , , , ,
, . Cada dado deve ser uma célula. Use cabeçalhos claros na primeira linha. Se houver dados numéricos, alinhe à direita. Se houver texto, alinhe à esquerda. Use cores sutis em linhas alternadas (nth-child). NÃO use markdown tables, use HTML puro." ID: infographic Prompt: "REGRAS DE FORMATO: Crie representações visuais HTML usando SVG, progress bars, stat cards, e elementos gráficos. Use elementos como: para gráficos,
para barras de progresso, ícones emoji, badges coloridos. Organize informações visualmente com grids, flexbox, e espaçamento. Inclua legendas e rótulos visuais claros." ID: cards Prompt: "REGRAS DE FORMATO: Retorne informações em formato de cards HTML. Cada card deve ter:
. Dentro do card use: título em

ou , subtítulo em

style="color:#666", ícone emoji ou ícone SVG no topo, badges de status. Organize cards em grid usando display:grid ou flex-wrap." ID: list Prompt: "REGRAS DE FORMATO: Use apenas listas HTML:

    para bullets e
      para números numerados. Cada item em
    1. . Use sublistas aninhadas quando apropriado. NÃO use parágrafos de texto, converta tudo em itens de lista. Adicione ícones emoji no início de cada
    2. quando possível. Use classes CSS para estilização: .list-item, .sub-list." ID: comparison Prompt: "REGRAS DE FORMATO: Crie comparações lado a lado em HTML. Use grid de 2 colunas:
      . Cada lado em uma
      com borda colorida distinta. Use headers claros para cada lado. Adicione seção de "Diferenças Chave" com bullet points. Use cores contrastantes para cada lado (ex: azul vs laranja). Inclua tabela de comparação resumida no final." ID: timeline Prompt: "REGRAS DE FORMATO: Organize eventos cronologicamente em formato de timeline HTML. Use
      com border-left vertical. Cada evento em
      com: data em , título em

      , descrição em

      . Adicione círculo indicador na timeline line. Ordene do mais antigo para o mais recente. Use espaçamento claro entre eventos." ID: markdown Prompt: "REGRAS DE FORMATO: Use exclusivamente formato Markdown padrão. Sintaxe permitida: **negrito**, *itálico*, `inline code`, ```bloco de código```, # cabeçalhos, - bullets, 1. números, [links](url), ![alt](url), | tabela | markdown |. NÃO use HTML tags exceto para blocos de código. Siga estritamente a sintaxe CommonMark." ID: chart Prompt: "REGRAS DE FORMATO: Crie gráficos e diagramas em HTML SVG. Use elementos SVG: , para gráficos de linha, para gráficos de barra, para gráficos de pizza, para gráficos de área. Inclua eixos com labels, grid lines, legendas. Use cores distintas para cada série de dados (ex: vermelho, azul, verde). Adicione tooltips com valores ao hover. Se o usuário pedir gráfico de pizza com "pizza vermelha", use fill="#FF0000" no SVG." ``` ## UI Design ### HTML Structure ```html

      Formato:
      ``` ### Placement Position the switchers container **above** the suggestions container: ```html
      ``` ### CSS Styling #### Container ```css .switchers-container { display: flex; align-items: center; gap: 12px; padding: 8px 16px; flex-wrap: wrap; background: rgba(0, 0, 0, 0.02); border-top: 1px solid rgba(0, 0, 0, 0.05); } .switchers-label { font-size: 13px; font-weight: 600; color: #666; text-transform: uppercase; letter-spacing: 0.5px; } ``` #### Switcher Chips (Toggle Buttons) ```css .switchers-chips { display: flex; gap: 8px; flex-wrap: wrap; } .switcher-chip { display: flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 20px; border: 2px solid transparent; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; background: rgba(0, 0, 0, 0.05); color: #666; user-select: none; } .switcher-chip:hover { background: rgba(0, 0, 0, 0.08); transform: translateY(-1px); } .switcher-chip.active { border-color: currentColor; background: currentColor; color: white; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); } .switcher-chip-icon { font-size: 14px; } ``` ## JavaScript Implementation ### State Management ```javascript // Track active switchers var activeSwitchers = new Set(); // Switcher definitions (from ADD SWITCHER commands in start.bas) var switcherDefinitions = [ { id: 'tables', label: 'Tabelas', icon: '📊', color: '#4CAF50' }, { id: 'infographic', label: 'Infográfico', icon: '📈', color: '#2196F3' }, { id: 'cards', label: 'Cards', icon: '🃏', color: '#FF9800' }, { id: 'list', label: 'Lista', icon: '📋', color: '#9C27B0' }, { id: 'comparison', label: 'Comparação', icon: '⚖️', color: '#E91E63' }, { id: 'timeline', label: 'Timeline', icon: '📅', color: '#00BCD4' }, { id: 'markdown', label: 'Markdown', icon: '📝', color: '#607D8B' }, { id: 'chart', label: 'Gráfico', icon: '📉', color: '#F44336' } ]; ``` ### Render Switchers ```javascript function renderSwitchers() { var container = document.getElementById("switcherChips"); if (!container) return; container.innerHTML = switcherDefinitions.map(function(sw) { var isActive = activeSwitchers.has(sw.id); return ( '
      ' + '' + sw.icon + '' + '' + sw.label + '' + '
      ' ); }).join(''); // Add click handlers container.querySelectorAll('.switcher-chip').forEach(function(chip) { chip.addEventListener('click', function() { toggleSwitcher(this.getAttribute('data-switch-id')); }); }); } ``` ### Toggle Handler ```javascript function toggleSwitcher(switcherId) { if (activeSwitchers.has(switcherId)) { activeSwitchers.delete(switcherId); } else { activeSwitchers.add(switcherId); } renderSwitchers(); } ``` ### Message Enhancement When sending a user message, prepend active switcher prompts: ```javascript function sendMessage(messageContent) { // ... existing code ... var content = messageContent || input.value.trim(); if (!content) return; // Prepend active switcher prompts var enhancedContent = content; if (activeSwitchers.size > 0) { // Get prompts for active switchers from backend var activePrompts = []; activeSwitchers.forEach(function(id) { // Backend has predefined prompts for each ID activePrompts.push(getSwitcherPrompt(id)); }); // Inject prompts before user message if (activePrompts.length > 0) { enhancedContent = activePrompts.join('\n\n') + '\n\n---\n\n' + content; } } // Send enhanced content addMessage("user", content); if (ws && ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ bot_id: currentBotId, user_id: currentUserId, session_id: currentSessionId, channel: "web", content: enhancedContent, message_type: MessageType.USER, timestamp: new Date().toISOString(), })); } } function getSwitcherPrompt(switcherId) { // Get predefined prompt from backend or API // For example, tables ID maps to: // "REGRAS DE FORMATO: SEMPRE retorne suas respostas em formato de tabela HTML..." var switcher = switcherDefinitions.find(function(s) { return s.id === switcherId; }); if (!switcher) return ""; // This could be fetched from backend or stored locally return SWITCHER_PROMPTS[switcherId] || ""; } ``` ## Bot Integration (start.bas) The bot receives the switcher prompt injected into the user message and simply passes it to the LLM. ### Example in start.bas ```basic REM Switcher prompts are automatically injected by frontend REM Just pass user_input to LLM - no parsing needed! REM If user types: "mostra os cursos" REM And "Tabelas" switcher is active REM Frontend sends: "REGRAS DE FORMATO: SEMPRE retorne suas respostas em formato de tabela HTML... --- mostra os cursos" REM Bot passes directly to LLM: response$ = CALL_LLM(user_input) REM The LLM will follow the REGRAS DE FORMATO instructions ``` ### Multiple Active Switchers When multiple switchers are active, all prompts are injected: ```basic REM Frontend injects multiple REGRAS DE FORMATO blocks REM Example with "Tabelas" and "Gráfico" active: REM REM "REGRAS DE FORMATO: SEMPRE retorne suas respostas em formato de tabela HTML... REM REGRAS DE FORMATO: Crie gráficos e diagramas em HTML SVG... REM --- REM mostra os dados de vendas" REM Bot passes to LLM: response$ = CALL_LLM(user_input) ``` ## Implementation Steps 1. ✅ Create prompts/switcher.md (this file) 2. ⬜ Define predefined prompts in backend (map IDs to prompt strings) 3. ⬜ Add HTML structure to chat.html (switchers container) 4. ⬜ Add CSS styles to chat.css (switcher chip styles) 5. ⬜ Add switcher definitions to chat.js 6. ⬜ Implement renderSwitchers() function 7. ⬜ Implement toggleSwitcher() function 8. ⬜ Modify sendMessage() to prepend switcher prompts 9. ⬜ Update salesianos bot start.bas to use ADD SWITCHER commands 10. ⬜ Test locally with all switcher options 11. ⬜ Verify multiple switchers can be active simultaneously 12. ⬜ Test persistence across page refreshes (optional - localStorage) ## Testing Checklist - [ ] Switchers appear above suggestions - [ ] Switchers are colorful and match their defined colors - [ ] Clicking a switcher toggles it on/off - [ ] Multiple switchers can be active simultaneously - [ ] Active switchers have distinct visual state (border, background, shadow) - [ ] Formatted responses match the selected format - [ ] Toggling off removes the format modifier - [ ] Works with empty active switchers (normal response) - [ ] Works in combination with suggestions - [ ] Responsive design on mobile devices ## Files to Modify 1. `botui/ui/suite/chat/chat.html` - Add switcher container HTML 2. `botui/ui/suite/chat/chat.css` - Add switcher styles 3. `botui/ui/suite/chat/chat.js` - Add switcher logic 4. `botserver/bots/salesianos/start.bas` - Add ADD SWITCHER commands ## Example start.bas ```basic USE_WEBSITE("https://salesianos.br", "30d") USE KB "carta" USE KB "proc" USE TOOL "inscricao" USE TOOL "consultar_inscricao" USE TOOL "agendamento_visita" USE TOOL "informacoes_curso" USE TOOL "documentos_necessarios" USE TOOL "contato_secretaria" USE TOOL "calendario_letivo" ADD_SUGGESTION_TOOL "inscricao" AS "Fazer Inscrição" ADD_SUGGESTION_TOOL "consultar_inscricao" AS "Consultar Inscrição" ADD_SUGGESTION_TOOL "agendamento_visita" AS "Agendar Visita" ADD_SUGGESTION_TOOL "informacoes_curso" AS "Informações de Cursos" ADD_SUGGESTION_TOOL "documentos_necessarios" AS "Documentos Necessários" ADD_SUGGESTION_TOOL "contato_secretaria" AS "Falar com Secretaria" ADD_SUGGESTION_TOOL "segunda_via" AS "Segunda Via de Boleto" ADD_SUGGESTION_TOOL "calendario_letivo" AS "Calendário Letivo" ADD_SUGGESTION_TOOL "outros" AS "Outros" ADD SWITCHER "tables" AS "Tabelas" ADD SWITCHER "infographic" AS "Infográfico" ADD SWITCHER "cards" AS "Cards" ADD SWITCHER "list" AS "Lista" ADD SWITCHER "comparison" AS "Comparação" ADD SWITCHER "timeline" AS "Timeline" ADD SWITCHER "markdown" AS "Markdown" ADD SWITCHER "chart" AS "Gráfico" TALK "Olá! Sou o assistente virtual da Escola Salesiana. Como posso ajudá-lo hoje com inscrições, visitas, informações sobre cursos, documentos ou calendário letivo? Você pode também escolher formatos de resposta acima da caixa de mensagem." ``` ## Notes - Switchers are **persistent** until deactivated - Multiple switchers can be active at once - Switcher prompts are prepended to user messages with "---" separator - The backend (LLM) should follow these format instructions - UI should provide clear visual feedback for active switchers - Color coding helps users quickly identify active formats - Standard switchers use predefined prompts in backend - Custom switchers allow any prompt string to be injected