UNPKG

tlnt

Version:

TLNT - HMS-Powered Multi-Agent Platform with Government Agency Analysis, Deep Research, and Enterprise-Ready Deployment. Self-optimizing multi-domain AI agent with continuous learning and enterprise-grade performance monitoring.

313 lines 9.1 kB
import React, { useState, useEffect, useCallback } from 'react'; import { render, Box, Text, useInput, useApp } from 'ink'; import TextInput from 'ink-text-input'; import { eventBus } from '../core/eventBus.js'; function App({ agentHub, hubAdapter }) { const [messages, setMessages] = useState([ { role: 'system', content: '🦾 tlnt ready - Type your message below (F2: settings, F3: tasks, Ctrl+C: quit)', timestamp: Date.now() } ]); const [input, setInput] = useState(''); const [isLoading, setIsLoading] = useState(false); const [showSettings, setShowSettings] = useState(false); const [showTasks, setShowTasks] = useState(false); const [connectionStatus, setConnectionStatus] = useState('disconnected'); const { exit } = useApp(); // Handle keyboard shortcuts useInput((input, key) => { if (key.ctrl && input === 'c') { exit(); } else if (key.f2) { setShowSettings(!showSettings); } else if (key.f3) { setShowTasks(!showTasks); } }); // Monitor hub connection status useEffect(() => { const updateStatus = () => { setConnectionStatus(hubAdapter.isConnected() ? 'connected' : 'disconnected'); }; hubAdapter.on('connected', updateStatus); hubAdapter.on('disconnected', updateStatus); updateStatus(); return () => { hubAdapter.off('connected', updateStatus); hubAdapter.off('disconnected', updateStatus); }; }, [hubAdapter]); // Listen to hub events useEffect(() => { const subscription = eventBus.subscribeToAgentEvents().subscribe(event => { setMessages(prev => [...prev, { role: 'system', content: `[${event.type}] ${JSON.stringify(event.data)}`, timestamp: event.timestamp }]); }); return () => subscription.unsubscribe(); }, []); const handleSubmit = useCallback(async () => { if (!input.trim() || isLoading) return; const userMessage = { role: 'user', content: input.trim(), timestamp: Date.now() }; setMessages(prev => [...prev, userMessage]); setInput(''); setIsLoading(true); try { const result = await agentHub.execute('chat', { sessionId: `tui-${Date.now()}`, userId: 'tui-user', workspacePath: process.cwd(), environment: 'development', capabilities: ['chat'], metadata: {} }, { prompt: input.trim() }); const assistantMessage = { role: 'assistant', content: result.success ? String(result.data) : `Error: ${result.error?.message}`, timestamp: Date.now() }; setMessages(prev => [...prev, assistantMessage]); } catch (error) { const errorMessage = { role: 'system', content: `Error: ${error instanceof Error ? error.message : String(error)}`, timestamp: Date.now() }; setMessages(prev => [...prev, errorMessage]); } finally { setIsLoading(false); } }, [input, isLoading, agentHub]); if (showSettings) { return onBack; { () => setShowSettings(false); } hubAdapter = { hubAdapter } / > ; } if (showTasks) { return onBack; { () => setShowTasks(false); } hubAdapter = { hubAdapter } / > ; } return flexDirection = "column"; height = "100%" > { /* Header */} < Box; borderStyle = "single"; borderColor = "gray"; paddingX = { 1: } > tlnt - Terminal; Agent | Status; color; { connectionStatus === 'connected' ? 'green' : 'red'; } > { connectionStatus } < /Text> |; F2: Settings | F3; Tasks | Ctrl + C; Quit < /Text> < /Box>; { /* Chat Messages */ } flexDirection; "column"; flexGrow = { 1: }; paddingX = { 1: }; paddingY = { 1: } > { messages, : .map((message, index) => key = { index }, marginBottom = { 1: } > color, { message, : .role === 'user' ? 'cyan' : message.role === 'assistant' ? 'green' : 'gray' } > [{ message, : .role }], { message, : .content } < /Text> < /Box>) }; { isLoading && color; "yellow" > ; Thinking; /Text> < /Box>; } /Box>; { /* Input Area */ } borderStyle; "single"; borderColor = "gray"; paddingX = { 1: } > color; "cyan" > & gt; /Text> < TextInput; value = { input }; onChange = { setInput }; onSubmit = { handleSubmit }; placeholder = "Type your message here..." / > /Box> < /Box>; ; } function SettingsView({ onBack, hubAdapter }) { useInput((input, key) => { if (key.escape || key.f2) { onBack(); } }); const status = hubAdapter.getConnectionStatus(); return flexDirection = "column"; padding = { 2: } > marginBottom; { 2; } > bold; color = "cyan" > Settings(Press, ESC, or, F2, to, go, back) < /Text> < /Box> < Box; flexDirection = "column"; gap = { 1: } > Hub; URL: { status.url; } /Text> < Text > Connected; { status.connected ? 'Yes' : 'No'; } /Text> < Text > Reconnect; Attempts: { status.reconnectAttempts; } /Text> < Text > Environment; { process.env.NODE_ENV || 'development'; } /Text> < Text > Working; Directory: { process.cwd(); } /Text> < /Box> < /Box>; ; } function TasksView({ onBack, hubAdapter }) { const [agents, setAgents] = useState([]); const [deals, setDeals] = useState([]); const [loading, setLoading] = useState(true); useInput((input, key) => { if (key.escape || key.f3) { onBack(); } }); useEffect(() => { async function loadData() { try { if (hubAdapter.isConnected()) { const [agentsData, dealsData] = await Promise.all([ hubAdapter.listAgents().catch(() => []), hubAdapter.listDeals().catch(() => []) ]); setAgents(agentsData); setDeals(dealsData); } } finally { setLoading(false); } } loadData(); }, [hubAdapter]); return flexDirection = "column"; padding = { 2: } > marginBottom; { 2; } > bold; color = "cyan" > Tasks & Agents(Press, ESC, or, F3, to, go, back) < /Text> < /Box>; { loading ? Loading : ; /Text>; flexDirection = "column"; gap = { 1: } > bold > Active; Agents({ agents, : .length }) < /Text>; { agents.length === 0 ? color = "gray" > No : ; agents; available < /Text>; (agents.map((agent, index) => key = { index } > , { agent, : .name }({ agent, : .status }) < /Text>)); } bold; marginTop = { 1: } > Active; Deals({ deals, : .length }) < /Text>; { deals.length === 0 ? color = "gray" > No : ; deals; available < /Text>; (deals.map((deal, index) => key = { index } > , { deal, : .name }({ deal, : .status }) - { deal, : .participants.length }, participants < /Text>)); } /Box>; } /Box>; ; } export class TUI { agentHub; hubAdapter; constructor(agentHub, hubAdapter) { this.agentHub = agentHub; this.hubAdapter = hubAdapter; } async start() { // Clear screen and set up terminal process.stdout.write('\x1Bc'); // Clear screen process.stdout.write('\x1b[?1049h'); // Use alternate screen buffer // Handle cleanup on exit process.on('SIGINT', this.cleanup); process.on('SIGTERM', this.cleanup); process.on('exit', this.cleanup); // Render the React app render(React.createElement(App, { agentHub: this.agentHub, hubAdapter: this.hubAdapter })); } cleanup = () => { // Restore terminal process.stdout.write('\x1b[?1049l'); // Exit alternate screen buffer this.hubAdapter.disconnect(); }; } //# sourceMappingURL=tui.js.map