Download script.js from AncViz/agentflow-studio-visual-ai-wizardry: direct link, hf CLI and curl.
- Browser
- Download file 27.9 kB
-
https://huggingface.co/spaces/AncViz/agentflow-studio-visual-ai-wizardry/resolve/main/script.js
- Command line
-
hf download hf://spaces/AncViz/agentflow-studio-visual-ai-wizardry/script.js
-
curl -L -o script.js https://huggingface.co/spaces/AncViz/agentflow-studio-visual-ai-wizardry/resolve/main/script.js
27.9 kB
| // Shared JavaScript across all pages | |
| class AgentBuilder { | |
| constructor() { | |
| this.components = []; | |
| this.connections = []; | |
| this.selectedComponent = null; | |
| this.dragging = false; | |
| this.dragOffset = { x: 0, y: 0 }; | |
| this.initializeEventListeners(); | |
| } | |
| initializeEventListeners() { | |
| const canvas = document.getElementById('canvas'); | |
| // Drag start from toolbox | |
| document.querySelectorAll('.toolbox-item').forEach(item => { | |
| item.addEventListener('dragstart', (e) => { | |
| e.dataTransfer.setData('text/plain', e.target.closest('.toolbox-item').dataset.type); | |
| }); | |
| }); | |
| // Drop on canvas | |
| canvas.addEventListener('dragover', (e) => { | |
| e.preventDefault(); | |
| canvas.classList.add('border-blue-500'); | |
| }); | |
| canvas.addEventListener('dragleave', () => { | |
| canvas.classList.remove('border-blue-500'); | |
| }); | |
| canvas.addEventListener('drop', (e) => { | |
| e.preventDefault(); | |
| canvas.classList.remove('border-blue-500'); | |
| const type = e.dataTransfer.getData('text/plain'); | |
| const rect = canvas.getBoundingClientRect(); | |
| const x = e.clientX - rect.left; | |
| const y = e.clientY - rect.top; | |
| this.addComponent(type, x, y); | |
| }); | |
| // Canvas interactions | |
| canvas.addEventListener('mousedown', (e) => { | |
| const component = e.target.closest('.canvas-component'); | |
| if (component) { | |
| this.selectComponent(component); | |
| if (e.target.classList.contains('component-handle')) { | |
| this.startDragging(component, e); | |
| } | |
| } else { | |
| this.deselectComponent(); | |
| } | |
| }); | |
| document.addEventListener('mousemove', (e) => { | |
| if (this.dragging) { | |
| this.dragComponent(e); | |
| } | |
| }); | |
| document.addEventListener('mouseup', () => { | |
| this.dragging = false; | |
| }); | |
| } | |
| addComponent(type, x, y) { | |
| const id = `comp-${Date.now()}`; | |
| const component = { | |
| id, | |
| type, | |
| x, | |
| y, | |
| properties: this.getDefaultProperties(type) | |
| }; | |
| const element = document.createElement('div'); | |
| element.className = 'canvas-component'; | |
| element.id = id; | |
| element.style.left = `${x}px`; | |
| element.style.top = `${y}px`; | |
| element.innerHTML = this.getComponentHTML(type, id); | |
| document.getElementById('canvas').appendChild(element); | |
| this.components.push(component); | |
| // Add event listeners to the new component | |
| element.addEventListener('dblclick', () => this.showProperties(component)); | |
| this.addConnectionPoints(element, id); | |
| } | |
| getComponentHTML(type, id) { | |
| const templates = { | |
| 'react-agent': ` | |
| <div class="component-handle flex items-center justify-between"> | |
| <i data-feather="cpu" class="w-4 h-4"></i> | |
| <span class="text-sm font-semibold">React Agent</span> | |
| </div> | |
| <div class="text-xs text-gray-300">Reasoning engine</div> | |
| `, | |
| 'tool': ` | |
| <div class="component-handle flex items-center justify-between"> | |
| <i data-feather="tool" class="w-4 h-4"></i> | |
| <span class="text-sm font-semibold">Tool</span> | |
| </div> | |
| <div class="text-xs text-gray-300">Function tool</div> | |
| `, | |
| 'prompt': ` | |
| <div class="component-handle flex items-center justify-between"> | |
| <i data-feather="message-square" class="w-4 h-4"></i> | |
| <span class="text-sm font-semibold">Prompt Template</span> | |
| </div> | |
| <div class="text-xs text-gray-300">Chat setup</div> | |
| `, | |
| 'memory': ` | |
| <div class="component-handle flex items-center justify-between"> | |
| <i data-feather="database" class="w-4 h-4"></i> | |
| <span class="text-sm font-semibold">Memory</span> | |
| </div> | |
| <div class="text-xs text-gray-300">State storage</div> | |
| ` | |
| }; | |
| return templates[type] || '<div>Unknown Component</div>'; | |
| } | |
| addConnectionPoints(element, id) { | |
| const inputPoint = document.createElement('div'); | |
| inputPoint.className = 'connection-point input'; | |
| inputPoint.dataset.component = id; | |
| inputPoint.dataset.type = 'input'; | |
| const outputPoint = document.createElement('div'); | |
| outputPoint.className = 'connection-point output'; | |
| outputPoint.dataset.component = id; | |
| outputPoint.dataset.type = 'output'; | |
| element.appendChild(inputPoint); | |
| element.appendChild(outputPoint); | |
| } | |
| getDefaultProperties(type) { | |
| const defaults = { | |
| 'react-agent': { | |
| name: 'react_agent', | |
| model: 'gpt-4', | |
| temperature: 0.7 | |
| }, | |
| 'tool': { | |
| name: 'custom_tool', | |
| description: 'A custom function tool', | |
| function: 'def tool_function(input):\n return "processed: " + input' | |
| }, | |
| 'prompt': { | |
| template: 'You are a helpful assistant. Answer the following question: {question}', | |
| variables: ['question'] | |
| }, | |
| 'memory': { | |
| type: 'MemorySaver', | |
| checkpoint_ttl: 3600 | |
| } | |
| }; | |
| return defaults[type] || {}; | |
| } | |
| selectComponent(componentElement) { | |
| this.deselectComponent(); | |
| componentElement.classList.add('selected'); | |
| this.selectedComponent = this.components.find(c => c.id === componentElement.id); | |
| this.showProperties(this.selectedComponent); | |
| } | |
| deselectComponent() { | |
| document.querySelectorAll('.canvas-component.selected').forEach(el => { | |
| el.classList.remove('selected'); | |
| }); | |
| this.selectedComponent = null; | |
| this.hideProperties(); | |
| } | |
| startDragging(componentElement, e) { | |
| this.dragging = true; | |
| const rect = componentElement.getBoundingClientRect(); | |
| const canvasRect = document.getElementById('canvas').getBoundingClientRect(); | |
| this.dragOffset = { | |
| x: e.clientX - rect.left + canvasRect.left, | |
| y: e.clientY - rect.top + canvasRect.top | |
| }; | |
| } | |
| dragComponent(e) { | |
| if (!this.selectedComponent) return; | |
| const canvasRect = document.getElementById('canvas').getBoundingClientRect(); | |
| const x = e.clientX - this.dragOffset.x; | |
| const y = e.clientY - this.dragOffset.y; | |
| const componentElement = document.getElementById(this.selectedComponent.id); | |
| componentElement.style.left = `${x}px`; | |
| componentElement.style.top = `${y}px`; | |
| this.selectedComponent.x = x; | |
| this.selectedComponent.y = y; | |
| } | |
| showProperties(component) { | |
| const panel = document.getElementById('properties-panel'); | |
| const content = document.getElementById('properties-content'); | |
| panel.classList.remove('hidden'); | |
| content.innerHTML = this.generatePropertiesForm(component); | |
| // Update properties on input change | |
| content.querySelectorAll('input, textarea').forEach(input => { | |
| input.addEventListener('change', (e) => { | |
| component.properties[e.target.name] = e.target.value; | |
| }); | |
| }); | |
| } | |
| hideProperties() { | |
| document.getElementById('properties-panel').classList.add('hidden'); | |
| } | |
| generatePropertiesForm(component) { | |
| const properties = component.properties; | |
| let html = `<h3 class="text-lg font-semibold mb-4 capitalize">${component.type.replace('-', ' ')} Properties</h3>`; | |
| Object.keys(properties).forEach(key => { | |
| const value = properties[key]; | |
| const isTextarea = typeof value === 'string' && value.includes('\n'); | |
| html += ` | |
| <div class="property-group"> | |
| <label class="property-label capitalize">${key.replace('_', ' ')}</label> | |
| ${isTextarea ? | |
| `<textarea name="${key}" class="property-input h-24">${value}</textarea>` : | |
| `<input type="text" name="${key}" value="${value}" class="property-input">` | |
| } | |
| </div> | |
| `; | |
| }); | |
| return html; | |
| } | |
| exportToPython() { | |
| let code = `# Generated by AgentFlow Studio\n`; | |
| code += `from langchain_core.messages import HumanMessage, ToolMessage\n`; | |
| code += `from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n`; | |
| code += `from langgraph.graph import StateGraph, END\n`; | |
| code += `from langgraph.checkpoint.memory import MemorySaver\n`; | |
| code += `from pydantic import BaseModel, Field\n`; | |
| code += `from langchain.agents import create_react_agent\n\n`; | |
| // Add component definitions | |
| this.components.forEach(comp => { | |
| code += `# ${comp.type} component\n`; | |
| switch(comp.type) { | |
| case 'react-agent': | |
| code += `agent = create_react_agent(\n`; | |
| code += ` model="${comp.properties.model}",\n`; | |
| code += ` temperature=${comp.properties.temperature}\n`; | |
| code += `)\n\n`; | |
| break; | |
| case 'tool': | |
| code += `class ${comp.properties.name.replace('_', ' ').title().replace(' ', '')}Tool(BaseModel):\n`; | |
| code += ` \"\"\"${comp.properties.description}\"\"\"\n\n`; | |
| code += ` def execute(self, input: str) -> str:\n`; | |
| code += ` ${comp.properties.function.replace('\n', '\n ')}\n\n`; | |
| break; | |
| case 'prompt': | |
| code += `prompt_template = ChatPromptTemplate.from_template(\n`; | |
| code += ` \"\"\"${comp.properties.template}\"\"\"\n`; | |
| code += `)\n\n`; | |
| break; | |
| case 'memory': | |
| code += `memory = MemorySaver()\n\n`; | |
| break; | |
| } | |
| }); | |
| // Add graph construction | |
| code += `# Build the agent graph\n`; | |
| code += `graph_builder = StateGraph()\n\n`; | |
| code += `# Export the final agent\n`; | |
| code += `def get_agent():\n`; | |
| code += ` return graph_builder.compile()\n`; | |
| return code; | |
| } | |
| } | |
| // Global functions for UI interactions | |
| function startNewProject() { | |
| const builder = new AgentBuilder(); | |
| window.agentBuilder = builder; | |
| document.getElementById('canvas').innerHTML = ''; | |
| document.getElementById('properties-panel').classList.add('hidden'); | |
| } | |
| function loadSample() { | |
| startNewProject(); | |
| // Add sample components | |
| window.agentBuilder.addComponent('react-agent', 100, 100); | |
| window.agentBuilder.addComponent('tool', 300, 100); | |
| window.agentBuilder.addComponent('prompt', 100, 200); | |
| window.agentBuilder.addComponent('memory', 300, 200); | |
| } | |
| function loadExample(exampleType) { | |
| startNewProject(); | |
| switch(exampleType) { | |
| case 'research': | |
| // Research Assistant Example | |
| const researchAgent = window.agentBuilder.addComponent('react-agent', 100, 100); | |
| const webSearchTool = window.agentBuilder.addComponent('tool', 300, 100); | |
| const researchPrompt = window.agentBuilder.addComponent('prompt', 100, 200); | |
| const researchMemory = window.agentBuilder.addComponent('memory', 300, 200); | |
| // Configure components | |
| const researchComponents = window.agentBuilder.components; | |
| researchComponents.find(c => c.id === researchAgent).properties = { | |
| name: 'research_assistant', | |
| model: 'gpt-4', | |
| temperature: 0.3, | |
| max_tokens: 2000 | |
| }; | |
| researchComponents.find(c => c.id === webSearchTool).properties = { | |
| name: 'web_search', | |
| description: 'Search the web for current information', | |
| function: 'def web_search(query):\n # Implementation for web search\n return f"Searched for: {query}"' | |
| }; | |
| researchComponents.find(c => c.id === researchPrompt).properties = { | |
| template: 'You are a research assistant. Search for information about: {topic}. Provide detailed, well-sourced answers.', | |
| variables: ['topic'] | |
| }; | |
| researchComponents.find(c => c.id === researchMemory).properties = { | |
| type: 'MemorySaver', | |
| checkpoint_ttl: 7200 | |
| }; | |
| break; | |
| case 'ecommerce': | |
| // E-commerce Assistant Example | |
| const ecomAgent = window.agentBuilder.addComponent('react-agent', 100, 100); | |
| const productSearch = window.agentBuilder.addComponent('tool', 300, 100); | |
| const priceCompare = window.agentBuilder.addComponent('tool', 500, 100); | |
| const ecomPrompt = window.agentBuilder.addComponent('prompt', 100, 200); | |
| const ecomMemory = window.agentBuilder.addComponent('memory', 300, 200); | |
| const ecomComponents = window.agentBuilder.components; | |
| ecomComponents.find(c => c.id === ecomAgent).properties = { | |
| name: 'ecommerce_assistant', | |
| model: 'gpt-4', | |
| temperature: 0.2, | |
| max_tokens: 1500 | |
| }; | |
| ecomComponents.find(c => c.id === productSearch).properties = { | |
| name: 'product_search', | |
| description: 'Search for products in the catalog', | |
| function: 'def product_search(category, keywords):\n # Search product database\n return f"Products in {category} matching {keywords}"' | |
| }; | |
| ecomComponents.find(c => c.id === priceCompare).properties = { | |
| name: 'price_comparison', | |
| description: 'Compare prices across different vendors', | |
| function: 'def price_comparison(product_id):\n # Get price comparisons\n return f"Price comparison for product {product_id}"' | |
| }; | |
| ecomComponents.find(c => c.id === ecomPrompt).properties = { | |
| template: 'You are an e-commerce assistant. Help customers find products and compare prices. Be helpful and concise.', | |
| variables: ['user_query'] | |
| }; | |
| ecomComponents.find(c => c.id === ecomMemory).properties = { | |
| type: 'MemorySaver', | |
| checkpoint_ttl: 3600 | |
| }; | |
| break; | |
| case 'code': | |
| // Code Assistant Example | |
| const codeAgent = window.agentBuilder.addComponent('react-agent', 100, 100); | |
| const codeGenerator = window.agentBuilder.addComponent('tool', 300, 100); | |
| const debuggerTool = window.agentBuilder.addComponent('tool', 500, 100); | |
| const codePrompt = window.agentBuilder.addComponent('prompt', 100, 200); | |
| const codeMemory = window.agentBuilder.addComponent('memory', 300, 200); | |
| const codeComponents = window.agentBuilder.components; | |
| codeComponents.find(c => c.id === codeAgent).properties = { | |
| name: 'code_assistant', | |
| model: 'gpt-4', | |
| temperature: 0.1, | |
| max_tokens: 3000 | |
| }; | |
| codeComponents.find(c => c.id === codeGenerator).properties = { | |
| name: 'code_generation', | |
| description: 'Generate code based on requirements', | |
| function: 'def generate_code(language, requirements):\n # Generate code implementation\n return f"Generated {language} code for: {requirements}"' | |
| }; | |
| codeComponents.find(c => c.id === debuggerTool).properties = { | |
| name: 'debug_code', | |
| description: 'Help debug and fix code issues', | |
| function: 'def debug_code(code, error):\n # Debug code implementation\n return f"Debugged code with error: {error}"' | |
| }; | |
| codeComponents.find(c => c.id === codePrompt).properties = { | |
| template: 'You are a programming assistant. Help with code generation, debugging, and explanations. Provide clear, working code examples.', | |
| variables: ['programming_task'] | |
| }; | |
| codeComponents.find(c => c.id === codeMemory).properties = { | |
| type: 'MemorySaver', | |
| checkpoint_ttl: 4800 | |
| }; | |
| break; | |
| case 'support': | |
| // Customer Support Example | |
| const supportAgent = window.agentBuilder.addComponent('react-agent', 100, 100); | |
| const faqSearch = window.agentBuilder.addComponent('tool', 300, 100); | |
| const ticketCreator = window.agentBuilder.addComponent('tool', 500, 100); | |
| const supportPrompt = window.agentBuilder.addComponent('prompt', 100, 200); | |
| const supportMemory = window.agentBuilder.addComponent('memory', 300, 200); | |
| const supportComponents = window.agentBuilder.components; | |
| supportComponents.find(c => c.id === supportAgent).properties = { | |
| name: 'support_agent', | |
| model: 'gpt-4', | |
| temperature: 0.4, | |
| max_tokens: 1200 | |
| }; | |
| supportComponents.find(c => c.id === faqSearch).properties = { | |
| name: 'faq_search', | |
| description: 'Search the FAQ database for answers', | |
| function: 'def search_faq(question):\n # Search FAQ database\n return f"FAQ results for: {question}"' | |
| }; | |
| supportComponents.find(c => c.id === ticketCreator).properties = { | |
| name: 'create_ticket', | |
| description: 'Create a support ticket for escalation', | |
| function: 'def create_ticket(issue, priority):\n # Create support ticket\n return f"Created {priority} ticket for: {issue}"' | |
| }; | |
| supportComponents.find(c => c.id === supportPrompt).properties = { | |
| template: 'You are a customer support agent. Be empathetic and helpful. Use FAQs when possible, escalate when needed.', | |
| variables: ['customer_issue'] | |
| }; | |
| supportComponents.find(c => c.id === supportMemory).properties = { | |
| type: 'MemorySaver', | |
| checkpoint_ttl: 2400 | |
| }; | |
| break; | |
| case 'analyst': | |
| // Data Analyst Example | |
| const analystAgent = window.agentBuilder.addComponent('react-agent', 100, 100); | |
| const dataProcessor = window.agentBuilder.addComponent('tool', 300, 100); | |
| const statsAnalyzer = window.agentBuilder.addComponent('tool', 500, 100); | |
| const analystPrompt = window.agentBuilder.addComponent('prompt', 100, 200); | |
| const analystMemory = window.agentBuilder.addComponent('memory', 300, 200); | |
| const analystComponents = window.agentBuilder.components; | |
| analystComponents.find(c => c.id === analystAgent).properties = { | |
| name: 'data_analyst', | |
| model: 'gpt-4', | |
| temperature: 0.2, | |
| max_tokens: 2500 | |
| }; | |
| analystComponents.find(c => c.id === dataProcessor).properties = { | |
| name: 'process_data', | |
| description: 'Process and clean datasets', | |
| function: 'def process_data(dataset, operations):\n # Process data implementation\n return f"Processed dataset with: {operations}"' | |
| }; | |
| analystComponents.find(c => c.id === statsAnalyzer).properties = { | |
| name: 'analyze_statistics', | |
| description: 'Perform statistical analysis on data', | |
| function: 'def analyze_stats(data, metrics):\n # Statistical analysis\n return f"Analysis results for metrics: {metrics}"' | |
| }; | |
| analystComponents.find(c => c.id === analystPrompt).properties = { | |
| template: 'You are a data analyst. Help analyze datasets, generate insights, and create visualizations. Be precise and data-driven.', | |
| variables: ['analysis_request'] | |
| }; | |
| analystComponents.find(c => c.id === analystMemory).properties = { | |
| type: 'MemorySaver', | |
| checkpoint_ttl: 6000 | |
| }; | |
| break; | |
| case 'translator': | |
| // Multi-language Translator Example | |
| const translatorAgent = window.agentBuilder.addComponent('react-agent', 100, 100); | |
| const translateTool = window.agentBuilder.addComponent('tool', 300, 100); | |
| const contextTool = window.agentBuilder.addComponent('tool', 500, 100); | |
| const translatorPrompt = window.agentBuilder.addComponent('prompt', 100, 200); | |
| const translatorMemory = window.agentBuilder.addComponent('memory', 300, 200); | |
| const translatorComponents = window.agentBuilder.components; | |
| translatorComponents.find(c => c.id === translatorAgent).properties = { | |
| name: 'translator', | |
| model: 'gpt-4', | |
| temperature: 0.3, | |
| max_tokens: 1800 | |
| }; | |
| translatorComponents.find(c => c.id === translateTool).properties = { | |
| name: 'translate_text', | |
| description: 'Translate text between languages', | |
| function: 'def translate(text, source_lang, target_lang):\n # Translation implementation\n return f"Translated from {source_lang} to {target_lang}: {text}"' | |
| }; | |
| translatorComponents.find(c => c.id === contextTool).properties = { | |
| name: 'preserve_context', | |
| description: 'Maintain context and cultural nuances', | |
| function: 'def preserve_context(translation, context):\n # Context preservation\n return f"Context-preserved translation: {translation}"' | |
| }; | |
| translatorComponents.find(c => c.id === translatorPrompt).properties = { | |
| template: 'You are a multilingual translator. Translate text while preserving meaning, context, and cultural nuances. Support multiple languages.', | |
| variables: ['text_to_translate', 'target_language'] | |
| }; | |
| translatorComponents.find(c => c.id === translatorMemory).properties = { | |
| type: 'MemorySaver', | |
| checkpoint_ttl: 5400 | |
| }; | |
| break; | |
| } | |
| // Update the UI to show the loaded example | |
| document.getElementById('properties-panel').classList.add('hidden'); | |
| // Show success message | |
| showNotification(`Loaded ${exampleType.replace(/_/g, ' ')} example successfully!`, 'success'); | |
| } | |
| function exportAgent() { | |
| if (!window.agentBuilder || window.agentBuilder.components.length === 0) { | |
| showNotification('Please add some components to the canvas first!', 'error'); | |
| return; | |
| } | |
| const code = window.agentBuilder.exportToPython(); | |
| showCodeModal(code); | |
| } | |
| function clearCanvas() { | |
| if (confirm('Are you sure you want to clear the canvas?')) { | |
| document.getElementById('canvas').innerHTML = ''; | |
| document.getElementById('properties-panel').classList.add('hidden'); | |
| if (window.agentBuilder) { | |
| window.agentBuilder.components = []; | |
| window.agentBuilder.connections = []; | |
| } | |
| showNotification('Canvas cleared successfully!', 'success'); | |
| } | |
| } | |
| function showCodeModal(code) { | |
| const modal = document.createElement('div'); | |
| modal.className = 'modal-overlay'; | |
| modal.innerHTML = ` | |
| <div class="modal-content"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="text-xl font-semibold">Generated Python Code</h3> | |
| <button onclick="this.closest('.modal-overlay').remove()" class="text-gray-400 hover:text-white"> | |
| <i data-feather="x"></i> | |
| </button> | |
| </div> | |
| <pre class="bg-gray-900 p-4 rounded-lg overflow-auto max-h-96"><code class="language-python">${code}</code></pre> | |
| <div class="flex gap-2 mt-4"> | |
| <button onclick="copyCode()" class="bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg flex-1"> | |
| <i data-feather="copy" class="mr-2"></i>Copy to Clipboard | |
| </button> | |
| <button onclick="downloadCode()" class="bg-green-600 hover:bg-green-700 px-4 py-2 rounded-lg flex-1"> | |
| <i data-feather="download" class="mr-2"></i>Download .py | |
| </button> | |
| </div> | |
| </div> | |
| `; | |
| document.body.appendChild(modal); | |
| feather.replace(); | |
| window.copyCode = function() { | |
| navigator.clipboard.writeText(code).then(() => { | |
| alert('Code copied to clipboard!'); | |
| }); | |
| }; | |
| window.downloadCode = function() { | |
| const blob = new Blob([code], { type: 'text/python' }); | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| a.download = 'langchain_agent.py'; | |
| a.click(); | |
| URL.revokeObjectURL(url); | |
| }; | |
| } | |
| // Notification system | |
| function showNotification(message, type = 'info') { | |
| const notification = document.createElement('div'); | |
| notification.className = `fixed top-4 right-4 z-50 p-4 rounded-lg shadow-lg transition-all duration-300 transform translate-x-full ${ | |
| type === 'success' ? 'bg-green-600' : | |
| type === 'error' ? 'bg-red-600' : | |
| 'bg-blue-600' | |
| } text-white`; | |
| notification.innerHTML = ` | |
| <div class="flex items-center gap-2"> | |
| <i data-feather="${type === 'success' ? 'check-circle' : type === 'error' ? 'alert-circle' : 'info'}"></i> | |
| <span>${message}</span> | |
| </div> | |
| `; | |
| document.body.appendChild(notification); | |
| // Animate in | |
| setTimeout(() => { | |
| notification.style.transform = 'translateX(0)'; | |
| }, 100); | |
| // Animate out and remove | |
| setTimeout(() => { | |
| notification.style.transform = 'translateX(full)'; | |
| setTimeout(() => { | |
| if (notification.parentNode) { | |
| notification.parentNode.removeChild(notification); | |
| } | |
| }, 300); | |
| }, 3000); | |
| feather.replace(); | |
| } | |
| // Initialize the app when page loads | |
| document.addEventListener('DOMContentLoaded', () => { | |
| window.agentBuilder = new AgentBuilder(); | |
| feather.replace(); | |
| // Check for example parameter in URL | |
| const urlParams = new URLSearchParams(window.location.search); | |
| const example = urlParams.get('example'); | |
| if (example && ['research', 'ecommerce', 'code', 'support', 'analyst', 'translator'].includes(example)) { | |
| // Small delay to ensure everything is loaded | |
| setTimeout(() => { | |
| loadExample(example); | |
| }, 500); | |
| } | |
| }); | |
| console.log('AgentFlow Studio loaded'); |