package ai import ( "context" "encoding/json" "fmt" "strings" "time" ) // OphionCopilot é o assistente de IA para troubleshooting type OphionCopilot struct { engine *AIEngine contextStore map[string]*ConversationContext } // ConversationContext contexto da conversa type ConversationContext struct { SessionID string UserID string Messages []CopilotMessage CurrentHost string CurrentIssue string StartedAt time.Time } // CopilotMessage mensagem do copilot type CopilotMessage struct { Role string `json:"role"` // user, assistant Content string `json:"content"` Timestamp time.Time `json:"timestamp"` Metadata map[string]interface{} `json:"metadata,omitempty"` } // CopilotResponse resposta do copilot type CopilotResponse struct { Message string `json:"message"` Actions []SuggestedAction `json:"actions,omitempty"` Queries []SuggestedQuery `json:"queries,omitempty"` RelatedDocs []string `json:"related_docs,omitempty"` Confidence float64 `json:"confidence"` NeedsHuman bool `json:"needs_human"` } // SuggestedAction ação sugerida pelo copilot type SuggestedAction struct { Type string `json:"type"` // command, script, config_change, scale, restart Description string `json:"description"` Command string `json:"command,omitempty"` Risk string `json:"risk"` // low, medium, high AutoExecute bool `json:"auto_execute"` } // SuggestedQuery query sugerida para investigação type SuggestedQuery struct { Type string `json:"type"` // metrics, logs, traces Query string `json:"query"` Description string `json:"description"` } // NewOphionCopilot cria nova instância do Copilot func NewOphionCopilot(engine *AIEngine) *OphionCopilot { return &OphionCopilot{ engine: engine, contextStore: make(map[string]*ConversationContext), } } // Chat processa uma mensagem do usuário func (c *OphionCopilot) Chat(ctx context.Context, sessionID, userMessage string, systemContext SystemContext) (*CopilotResponse, error) { // Obter ou criar contexto da conversa convCtx := c.getOrCreateContext(sessionID) // Adicionar mensagem do usuário convCtx.Messages = append(convCtx.Messages, CopilotMessage{ Role: "user", Content: userMessage, Timestamp: time.Now(), }) // Construir prompt com contexto completo prompt := c.buildPrompt(userMessage, convCtx, systemContext) // Chamar IA response, err := c.engine.chat(ctx, prompt) if err != nil { return nil, err } // Parsear resposta var result CopilotResponse if err := json.Unmarshal([]byte(response), &result); err != nil { // Se não for JSON válido, retornar como mensagem simples result = CopilotResponse{ Message: response, Confidence: 0.7, } } // Adicionar resposta ao contexto convCtx.Messages = append(convCtx.Messages, CopilotMessage{ Role: "assistant", Content: result.Message, Timestamp: time.Now(), Metadata: map[string]interface{}{ "confidence": result.Confidence, "actions": len(result.Actions), }, }) return &result, nil } // buildPrompt constrói o prompt completo func (c *OphionCopilot) buildPrompt(userMessage string, convCtx *ConversationContext, sysCtx SystemContext) string { var sb strings.Builder sb.WriteString(`Você é o OPHION Copilot, um assistente especialista em observabilidade e troubleshooting de infraestrutura. SUAS CAPACIDADES: - Analisar métricas, logs e traces - Identificar causas raiz de problemas - Sugerir comandos e ações de correção - Explicar conceitos de forma clara - Correlacionar eventos de diferentes fontes CONTEXTO DO SISTEMA: `) // Adicionar contexto do sistema sb.WriteString(fmt.Sprintf(` Hosts monitorados: %d Alertas ativos: %d Incidentes abertos: %d Último deploy: %s `, sysCtx.TotalHosts, sysCtx.ActiveAlerts, sysCtx.OpenIncidents, sysCtx.LastDeploy)) // Métricas atuais if len(sysCtx.CurrentMetrics) > 0 { sb.WriteString("\nMÉTRICAS ATUAIS:\n") for host, metrics := range sysCtx.CurrentMetrics { sb.WriteString(fmt.Sprintf("- %s: CPU=%.1f%%, MEM=%.1f%%, Disco=%.1f%%\n", host, metrics.CPU, metrics.Memory, metrics.Disk)) } } // Alertas recentes if len(sysCtx.RecentAlerts) > 0 { sb.WriteString("\nALERTAS RECENTES:\n") for _, alert := range sysCtx.RecentAlerts { sb.WriteString(fmt.Sprintf("- [%s] %s: %s\n", alert.Severity, alert.Host, alert.Message)) } } // Histórico da conversa if len(convCtx.Messages) > 1 { sb.WriteString("\nHISTÓRICO DA CONVERSA:\n") for _, msg := range convCtx.Messages[max(0, len(convCtx.Messages)-6):] { sb.WriteString(fmt.Sprintf("%s: %s\n", msg.Role, msg.Content)) } } // Pergunta atual sb.WriteString(fmt.Sprintf(` PERGUNTA DO USUÁRIO: %s INSTRUÇÕES DE RESPOSTA: 1. Seja direto e prático 2. Se sugerir comandos, explique o que fazem 3. Indique o nível de risco das ações 4. Se não tiver certeza, diga e sugira investigações adicionais Responda em JSON: { "message": "sua resposta detalhada", "actions": [ { "type": "command|script|config_change|scale|restart", "description": "o que faz", "command": "comando se aplicável", "risk": "low|medium|high", "auto_execute": false } ], "queries": [ { "type": "metrics|logs|traces", "query": "query para investigar", "description": "o que vai mostrar" } ], "confidence": 0.0-1.0, "needs_human": false }`, userMessage)) return sb.String() } func (c *OphionCopilot) getOrCreateContext(sessionID string) *ConversationContext { if ctx, exists := c.contextStore[sessionID]; exists { return ctx } ctx := &ConversationContext{ SessionID: sessionID, Messages: []CopilotMessage{}, StartedAt: time.Now(), } c.contextStore[sessionID] = ctx return ctx } // SystemContext contexto do sistema para o copilot type SystemContext struct { TotalHosts int ActiveAlerts int OpenIncidents int LastDeploy string CurrentMetrics map[string]HostMetrics RecentAlerts []AlertInfo RecentLogs []string } // HostMetrics métricas de um host type HostMetrics struct { CPU float64 Memory float64 Disk float64 } // AlertInfo informação de alerta type AlertInfo struct { Severity string Host string Message string Time time.Time } func max(a, b int) int { if a > b { return a } return b }