UNPKG

@agentdao/core

Version:

Core functionality, skills, and ready-made UI components for AgentDAO - Web3 subscriptions, content generation, social media, help support, live chat, RSS fetching, web search, and agent pricing integration

473 lines (431 loc) 18.7 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.A2AProtocolWidget = A2AProtocolWidget; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); function A2AProtocolWidget({ config, className, style }) { const [agents, setAgents] = (0, react_1.useState)([]); const [selectedAgent, setSelectedAgent] = (0, react_1.useState)(null); const [taskDescription, setTaskDescription] = (0, react_1.useState)(''); const [taskType, setTaskType] = (0, react_1.useState)('delegate'); const [isLoading, setIsLoading] = (0, react_1.useState)(false); const [messages, setMessages] = (0, react_1.useState)([]); const [activeStreams, setActiveStreams] = (0, react_1.useState)(new Map()); // Discover agents on component mount (0, react_1.useEffect)(() => { discoverAgents(); }, []); const discoverAgents = async () => { try { setIsLoading(true); const response = await fetch('/api/a2a/agents'); const data = await response.json(); setAgents(data.agents || []); } catch (error) { console.error('Failed to discover agents:', error); } finally { setIsLoading(false); } }; const delegateTask = async () => { if (!selectedAgent || !taskDescription.trim()) { alert('Please select an agent and enter a task description'); return; } try { setIsLoading(true); const task = { type: taskType, description: taskDescription, input: { description: taskDescription }, priority: 'medium', timeout: 30000 }; const message = { id: `msg_${Date.now()}`, fromAgent: config.agentId, toAgent: selectedAgent.id, task: { ...task, id: `task_${Date.now()}` }, timestamp: new Date(), status: 'pending' }; // Add to messages setMessages(prev => [...prev, message]); // Send task const response = await fetch('/api/a2a/tasks', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(message) }); const result = await response.json(); // Update message status setMessages(prev => prev.map(msg => msg.id === message.id ? { ...msg, status: 'completed', result: result.result } : msg)); // Clear form setTaskDescription(''); setSelectedAgent(null); } catch (error) { console.error('Failed to delegate task:', error); alert('Failed to delegate task'); } finally { setIsLoading(false); } }; const startStreamingTask = async () => { if (!selectedAgent || !taskDescription.trim()) { alert('Please select an agent and enter a task description'); return; } try { setIsLoading(true); const task = { type: 'stream', description: taskDescription, input: { description: taskDescription }, priority: 'medium', timeout: 60000 }; const message = { id: `msg_${Date.now()}`, fromAgent: config.agentId, toAgent: selectedAgent.id, task: { ...task, id: `task_${Date.now()}` }, timestamp: new Date(), status: 'pending' }; // Add to messages setMessages(prev => [...prev, message]); // Create stream const response = await fetch('/api/a2a/stream', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(message) }); const result = await response.json(); if (result.success) { // Start listening to stream listenToStream(result.streamId, message.id); } } catch (error) { console.error('Failed to start streaming task:', error); alert('Failed to start streaming task'); } finally { setIsLoading(false); } }; const listenToStream = (streamId, messageId) => { const eventSource = new EventSource(`/api/a2a/stream?streamId=${streamId}`); eventSource.onmessage = (event) => { const chunk = JSON.parse(event.data); if (chunk.type === 'connection') { console.log('Stream connected:', streamId); } else if (chunk.type === 'complete') { console.log('Stream completed:', streamId); eventSource.close(); // Update message status setMessages(prev => prev.map(msg => msg.id === messageId ? { ...msg, status: 'completed' } : msg)); } else { // Handle data chunk setActiveStreams(prev => { const newStreams = new Map(prev); const stream = newStreams.get(streamId) || { chunks: [] }; stream.chunks.push(chunk); newStreams.set(streamId, stream); return newStreams; }); } }; eventSource.onerror = (error) => { console.error('Stream error:', error); eventSource.close(); }; }; const collaborateWithMultipleAgents = async () => { const selectedAgents = agents.filter(agent => agent.capabilities.some(cap => ['collaboration', 'teamwork', 'coordination'].includes(cap.toLowerCase()))).slice(0, 3); // Limit to 3 agents if (selectedAgents.length === 0) { alert('No suitable agents found for collaboration'); return; } try { setIsLoading(true); const task = { type: 'collaborate', description: taskDescription, input: { description: taskDescription, participants: selectedAgents.map(a => a.id) }, priority: 'high', timeout: 60000 }; // Send to each agent const promises = selectedAgents.map(agent => { const message = { id: `msg_${Date.now()}_${agent.id}`, fromAgent: config.agentId, toAgent: agent.id, task: { ...task, id: `task_${Date.now()}_${agent.id}` }, timestamp: new Date(), status: 'pending' }; setMessages(prev => [...prev, message]); return fetch('/api/a2a/tasks', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(message) }); }); const results = await Promise.all(promises); // Update message statuses results.forEach((result, index) => { const messageId = `msg_${Date.now()}_${selectedAgents[index].id}`; setMessages(prev => prev.map(msg => msg.id === messageId ? { ...msg, status: 'completed' } : msg)); }); } catch (error) { console.error('Failed to collaborate:', error); alert('Failed to start collaboration'); } finally { setIsLoading(false); } }; return ((0, jsx_runtime_1.jsxs)("div", { className: `a2a-protocol-widget ${className || ''}`, style: style, children: [(0, jsx_runtime_1.jsxs)("div", { className: "a2a-header", children: [(0, jsx_runtime_1.jsx)("h3", { children: "A2A Protocol - Agent Collaboration" }), (0, jsx_runtime_1.jsx)("button", { onClick: discoverAgents, disabled: isLoading, className: "a2a-refresh-btn", children: isLoading ? 'Discovering...' : 'Refresh Agents' })] }), (0, jsx_runtime_1.jsxs)("div", { className: "a2a-content", children: [(0, jsx_runtime_1.jsxs)("div", { className: "a2a-section", children: [(0, jsx_runtime_1.jsxs)("h4", { children: ["Available Agents (", agents.length, ")"] }), (0, jsx_runtime_1.jsx)("div", { className: "a2a-agents-list", children: agents.map(agent => ((0, jsx_runtime_1.jsx)("div", { className: `a2a-agent ${selectedAgent?.id === agent.id ? 'selected' : ''}`, onClick: () => setSelectedAgent(agent), children: (0, jsx_runtime_1.jsxs)("div", { className: "agent-info", children: [(0, jsx_runtime_1.jsx)("strong", { children: agent.name }), (0, jsx_runtime_1.jsx)("p", { children: agent.description }), (0, jsx_runtime_1.jsx)("div", { className: "agent-capabilities", children: agent.capabilities.map(cap => ((0, jsx_runtime_1.jsx)("span", { className: "capability-tag", children: cap }, cap))) })] }) }, agent.id))) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "a2a-section", children: [(0, jsx_runtime_1.jsx)("h4", { children: "Task Configuration" }), (0, jsx_runtime_1.jsxs)("div", { className: "a2a-task-form", children: [(0, jsx_runtime_1.jsxs)("select", { value: taskType, onChange: (e) => setTaskType(e.target.value), className: "a2a-select", children: [(0, jsx_runtime_1.jsx)("option", { value: "delegate", children: "Delegate Task" }), (0, jsx_runtime_1.jsx)("option", { value: "collaborate", children: "Collaborate" }), (0, jsx_runtime_1.jsx)("option", { value: "query", children: "Query" }), (0, jsx_runtime_1.jsx)("option", { value: "stream", children: "Stream" })] }), (0, jsx_runtime_1.jsx)("textarea", { value: taskDescription, onChange: (e) => setTaskDescription(e.target.value), placeholder: "Describe the task you want to delegate...", className: "a2a-textarea", rows: 3 }), (0, jsx_runtime_1.jsxs)("div", { className: "a2a-actions", children: [(0, jsx_runtime_1.jsx)("button", { onClick: delegateTask, disabled: !selectedAgent || !taskDescription.trim() || isLoading, className: "a2a-btn primary", children: isLoading ? 'Processing...' : 'Delegate Task' }), taskType === 'stream' && ((0, jsx_runtime_1.jsx)("button", { onClick: startStreamingTask, disabled: !selectedAgent || !taskDescription.trim() || isLoading, className: "a2a-btn secondary", children: "Start Streaming" })), (0, jsx_runtime_1.jsx)("button", { onClick: collaborateWithMultipleAgents, disabled: !taskDescription.trim() || isLoading, className: "a2a-btn tertiary", children: "Collaborate with Multiple Agents" })] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "a2a-section", children: [(0, jsx_runtime_1.jsx)("h4", { children: "Message History" }), (0, jsx_runtime_1.jsx)("div", { className: "a2a-messages", children: messages.map(message => ((0, jsx_runtime_1.jsxs)("div", { className: `a2a-message ${message.status}`, children: [(0, jsx_runtime_1.jsxs)("div", { className: "message-header", children: [(0, jsx_runtime_1.jsx)("span", { className: "message-type", children: message.task.type }), (0, jsx_runtime_1.jsx)("span", { className: "message-status", children: message.status }), (0, jsx_runtime_1.jsx)("span", { className: "message-time", children: message.timestamp.toLocaleTimeString() })] }), (0, jsx_runtime_1.jsxs)("div", { className: "message-content", children: [(0, jsx_runtime_1.jsxs)("p", { children: [(0, jsx_runtime_1.jsx)("strong", { children: "To:" }), " ", message.toAgent] }), (0, jsx_runtime_1.jsxs)("p", { children: [(0, jsx_runtime_1.jsx)("strong", { children: "Task:" }), " ", message.task.description] }), message.result && ((0, jsx_runtime_1.jsxs)("div", { className: "message-result", children: [(0, jsx_runtime_1.jsx)("strong", { children: "Result:" }), (0, jsx_runtime_1.jsx)("pre", { children: JSON.stringify(message.result, null, 2) })] }))] })] }, message.id))) })] }), activeStreams.size > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "a2a-section", children: [(0, jsx_runtime_1.jsx)("h4", { children: "Active Streams" }), (0, jsx_runtime_1.jsx)("div", { className: "a2a-streams", children: Array.from(activeStreams.entries()).map(([streamId, stream]) => ((0, jsx_runtime_1.jsxs)("div", { className: "a2a-stream", children: [(0, jsx_runtime_1.jsxs)("h5", { children: ["Stream: ", streamId] }), (0, jsx_runtime_1.jsx)("div", { className: "stream-chunks", children: stream.chunks.map((chunk, index) => ((0, jsx_runtime_1.jsxs)("div", { className: "stream-chunk", children: [(0, jsx_runtime_1.jsx)("span", { className: "chunk-data", children: chunk.chunk.data }), (0, jsx_runtime_1.jsxs)("span", { className: "chunk-progress", children: [chunk.chunk.progress, "%"] })] }, index))) })] }, streamId))) })] }))] }), (0, jsx_runtime_1.jsx)("style", { children: ` .a2a-protocol-widget { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; border: 1px solid #e1e5e9; border-radius: 8px; background: white; max-width: 800px; margin: 0 auto; } .a2a-header { display: flex; justify-content: space-between; align-items: center; padding: 16px; border-bottom: 1px solid #e1e5e9; background: #f8f9fa; } .a2a-header h3 { margin: 0; color: #2c3e50; } .a2a-refresh-btn { padding: 8px 16px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; } .a2a-refresh-btn:disabled { background: #6c757d; cursor: not-allowed; } .a2a-content { padding: 16px; } .a2a-section { margin-bottom: 24px; } .a2a-section h4 { margin: 0 0 12px 0; color: #2c3e50; } .a2a-agents-list { display: grid; gap: 12px; max-height: 200px; overflow-y: auto; } .a2a-agent { padding: 12px; border: 1px solid #e1e5e9; border-radius: 6px; cursor: pointer; transition: all 0.2s; } .a2a-agent:hover { border-color: #007bff; background: #f8f9fa; } .a2a-agent.selected { border-color: #007bff; background: #e3f2fd; } .agent-info strong { display: block; margin-bottom: 4px; } .agent-info p { margin: 4px 0; color: #6c757d; font-size: 14px; } .agent-capabilities { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; } .capability-tag { background: #e9ecef; color: #495057; padding: 2px 8px; border-radius: 12px; font-size: 12px; } .a2a-task-form { display: flex; flex-direction: column; gap: 12px; } .a2a-select, .a2a-textarea { padding: 8px 12px; border: 1px solid #e1e5e9; border-radius: 4px; font-size: 14px; } .a2a-textarea { resize: vertical; min-height: 80px; } .a2a-actions { display: flex; gap: 8px; flex-wrap: wrap; } .a2a-btn { padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; transition: all 0.2s; } .a2a-btn:disabled { opacity: 0.6; cursor: not-allowed; } .a2a-btn.primary { background: #007bff; color: white; } .a2a-btn.secondary { background: #6c757d; color: white; } .a2a-btn.tertiary { background: #28a745; color: white; } .a2a-messages { max-height: 300px; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; } .a2a-message { padding: 12px; border: 1px solid #e1e5e9; border-radius: 6px; background: #f8f9fa; } .a2a-message.completed { border-color: #28a745; background: #d4edda; } .a2a-message.failed { border-color: #dc3545; background: #f8d7da; } .message-header { display: flex; gap: 12px; margin-bottom: 8px; font-size: 12px; } .message-type { background: #007bff; color: white; padding: 2px 8px; border-radius: 12px; } .message-status { background: #6c757d; color: white; padding: 2px 8px; border-radius: 12px; } .message-time { color: #6c757d; } .message-content p { margin: 4px 0; font-size: 14px; } .message-result { margin-top: 8px; padding: 8px; background: white; border-radius: 4px; } .message-result pre { margin: 4px 0; font-size: 12px; white-space: pre-wrap; } .a2a-streams { display: flex; flex-direction: column; gap: 12px; } .a2a-stream { padding: 12px; border: 1px solid #e1e5e9; border-radius: 6px; background: #f8f9fa; } .a2a-stream h5 { margin: 0 0 8px 0; color: #2c3e50; } .stream-chunks { display: flex; flex-direction: column; gap: 4px; } .stream-chunk { display: flex; justify-content: space-between; align-items: center; padding: 4px 8px; background: white; border-radius: 4px; font-size: 12px; } .chunk-progress { background: #007bff; color: white; padding: 2px 6px; border-radius: 12px; } ` })] })); }