import React, { useState, useCallback } from 'react'; import { View, Text, TextInput, ScrollView, TouchableOpacity, StyleSheet, ActivityIndicator } from 'react-native'; import { ITSM_BASE } from '../../services/api'; const AGENTS = [ { id: 'sr-manager', name: 'SR ๊ด€๋ฆฌ์ž', icon: '๐Ÿ“‹', desc: 'SR ์ ‘์ˆ˜ยท๋ถ„๋ฅ˜ยท๋ฐฐ์ • ์ž๋™ํ™”' }, { id: 'incident-responder', name: '์ธ์‹œ๋˜ํŠธ ๋Œ€์‘', icon: '๐Ÿšจ', desc: '์žฅ์•  ๊ฐ์ง€ยทRCAยท๋ณต๊ตฌ' }, { id: 'deploy-engineer', name: '๋ฐฐํฌ ์—”์ง€๋‹ˆ์–ด', icon: '๐Ÿš€', desc: 'SSH ๋ฐฐํฌยท๋กค๋ฐฑยทํ—ฌ์Šค์ฒดํฌ' }, { id: 'ai-analyst', name: 'AI ๋ถ„์„๊ฐ€', icon: '๐Ÿค–', desc: '์ด์ƒํƒ์ง€ยท์˜ˆ์ธกยท์ธ์‚ฌ์ดํŠธ' }, { id: 'csap-auditor', name: 'CSAP ๊ฐ์‚ฌ๊ด€', icon: '๐Ÿ›ก๏ธ', desc: 'CSAP ์ค€์ˆ˜์œจ ์ž๋™ ์ ๊ฒ€' }, ]; interface Message { role: 'user' | 'agent'; content: string; agent?: string; ts: string } export default function AIAgentScreen() { const [messages, setMessages] = useState([]); const [input, setInput] = useState(''); const [selectedAgent, setSelectedAgent] = useState(AGENTS[0]); const [loading, setLoading] = useState(false); const sendMessage = useCallback(async () => { if (!input.trim()) return; const userMsg: Message = { role: 'user', content: input, ts: new Date().toISOString() }; setMessages(prev => [...prev, userMsg]); setInput(''); setLoading(true); try { const r = await fetch(`${ITSM_BASE}/api/agent-collab/rooms`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ topic: input, agents: [selectedAgent.id] }), }); if (r.ok) { const room = await r.json(); const opinion = await fetch(`${ITSM_BASE}/api/agent-collab/rooms/${room.id}/ai-opinion`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ agent_id: selectedAgent.id }), }); if (opinion.ok) { const data = await opinion.json(); setMessages(prev => [...prev, { role: 'agent', content: data.opinion || data.message || '์ฒ˜๋ฆฌ ์™„๋ฃŒ', agent: selectedAgent.name, ts: new Date().toISOString(), }]); } } } catch { setMessages(prev => [...prev, { role: 'agent', content: '[Ollama ์ฒ˜๋ฆฌ ์ค‘...]', agent: selectedAgent.name, ts: new Date().toISOString() }]); } finally { setLoading(false); } }, [input, selectedAgent]); return ( AI ์—์ด์ „ํŠธ ์ฑ„ํŒ… {AGENTS.map(a => ( setSelectedAgent(a)}> {a.icon} {a.name} ))} {selectedAgent.icon} {selectedAgent.desc} {messages.map((m, i) => ( {m.role === 'agent' && {m.agent}} {m.content} {new Date(m.ts).toLocaleTimeString()} ))} {loading && } ์ „์†ก ); } const s = StyleSheet.create({ container: { flex: 1, backgroundColor: '#0A0E1A' }, title: { color: '#fff', fontSize: 18, fontWeight: '700', padding: 16, paddingBottom: 8 }, agentBar: { paddingHorizontal: 12, paddingVertical: 8, maxHeight: 80 }, agentChip: { alignItems: 'center', marginRight: 12, paddingHorizontal: 12, paddingVertical: 8, borderRadius: 20, borderWidth: 1, borderColor: '#333', backgroundColor: '#1A1F2E' }, agentActive: { borderColor: '#00A0C8', backgroundColor: '#003366' }, agentIcon: { fontSize: 18 }, agentName: { color: '#aaa', fontSize: 11, marginTop: 2 }, agentNameActive: { color: '#00A0C8' }, agentDesc: { backgroundColor: '#1A1F2E', marginHorizontal: 12, marginBottom: 4, padding: 8, borderRadius: 8 }, agentDescText: { color: '#aaa', fontSize: 12 }, chat: { flex: 1, padding: 12 }, bubble: { maxWidth: '80%', marginBottom: 12, padding: 10, borderRadius: 12 }, userBubble: { alignSelf: 'flex-end', backgroundColor: '#003366' }, agentBubble: { alignSelf: 'flex-start', backgroundColor: '#1A1F2E' }, agentLabel: { color: '#00A0C8', fontSize: 11, fontWeight: '600', marginBottom: 4 }, bubbleText: { color: '#fff', fontSize: 14, lineHeight: 20 }, ts: { color: '#555', fontSize: 10, marginTop: 4, textAlign: 'right' }, inputRow: { flexDirection: 'row', padding: 12, borderTopWidth: 1, borderTopColor: '#222' }, input: { flex: 1, backgroundColor: '#1A1F2E', color: '#fff', borderRadius: 20, paddingHorizontal: 16, marginRight: 8 }, sendBtn: { backgroundColor: '#00A0C8', borderRadius: 20, paddingHorizontal: 16, justifyContent: 'center' }, sendText: { color: '#fff', fontWeight: '700' }, });