File size: 4,490 Bytes
20ec4ad
969b550
 
 
20ec4ad
8a0e39e
20ec4ad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
969b550
 
20ec4ad
 
 
969b550
 
 
 
 
 
20ec4ad
 
 
 
 
969b550
 
 
 
 
 
20ec4ad
 
 
8a0e39e
 
 
 
 
 
 
 
 
 
 
 
 
20ec4ad
 
 
 
969b550
 
 
20ec4ad
969b550
20ec4ad
 
 
 
 
 
 
969b550
 
20ec4ad
969b550
 
 
20ec4ad
969b550
 
20ec4ad
 
 
 
 
969b550
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20ec4ad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import React from 'react';
import { FaRobot } from 'react-icons/fa';
import { FiUser, FiCpu, FiAlertTriangle, FiTerminal, FiInfo } from 'react-icons/fi';
import ReactMarkdown from 'react-markdown';

export type MessageType = 'user' | 'agent' | 'log' | 'error' | 'info';

export interface ChatMessage {
  id: string;
  type: MessageType;
  content: string;
  agentId?: string;
  timestamp: Date;
}

interface ChatMessageProps {
  message: ChatMessage;
}

// Componente para exibir uma única mensagem do chat
const ChatMessageComponent: React.FC<ChatMessageProps> = ({ message }) => {
  // Renderiza logs de forma diferente
  if (message.type === 'log') {
    // Extrai informações do log no formato [Agent:agentId] message
    const logMatch = message.content.match(/\[Agent:([^\]]+)\] (.*)/);
    if (logMatch) {
      const [_, agentId, logContent] = logMatch;
      return (
        <div className="text-xs text-gray-500 py-1 pl-8 border-l border-gray-700 my-1">
          <span className="font-semibold text-gray-400">{agentId}:</span> {logContent}
        </div>
      );
    }
    return (
      <div className="flex items-start space-x-2 text-xs text-gray-500 py-1">
        <FiTerminal className="text-gray-500 mt-0.5 flex-shrink-0" size={12} />
        <div>{message.content}</div>
      </div>
    );
  }

  // Renderiza erros de forma destacada
  if (message.type === 'error') {
    return (
      <div className="flex items-start space-x-2 my-2 p-2 bg-red-900/20 border-l-2 border-red-500 text-red-400 rounded">
        <FiAlertTriangle className="text-red-500 mt-1 flex-shrink-0" />
        <div>
          <p className="font-semibold text-red-400">Erro:</p>
          <p className="text-gray-300">{message.content}</p>
        </div>
      </div>
    );
  }
  
  // Renderiza mensagens informativas
  if (message.type === 'info') {
    return (
      <div className="flex items-start space-x-2 my-2 p-2 bg-blue-900/20 border-l-2 border-blue-500 text-blue-400 rounded">
        <FiInfo className="text-blue-500 mt-1 flex-shrink-0" />
        <div>
          <p className="font-semibold text-blue-400">Informação:</p>
          <p className="text-gray-300 whitespace-pre-line">{message.content}</p>
        </div>
      </div>
    );
  }

  // Renderiza mensagem do usuário
  if (message.type === 'user') {
    return (
      <div className="flex items-start space-x-2 my-3">
        <div className="bg-indigo-600 text-white p-2 rounded-full flex-shrink-0">
          <FiUser />
        </div>
        <div className="bg-gray-800 p-3 rounded-lg rounded-tl-none max-w-[calc(100%-50px)] text-gray-200">
          {message.content}
        </div>
      </div>
    );
  }

  // Renderiza resposta do agente
  const agentColor = getAgentColor(message.agentId || 'default');
  
  return (
    <div className="flex items-start space-x-2 my-3">
      <div className={`${agentColor} text-white p-2 rounded-full flex-shrink-0`}>
        <FiCpu />
      </div>
      <div className="bg-gray-900 p-3 rounded-lg rounded-tl-none max-w-[calc(100%-50px)] text-gray-200 border border-gray-800">
        <MessageContent content={message.content} />
      </div>
    </div>
  );
};

// Função auxiliar para definir cores diferentes para cada agente
const getAgentColor = (agentId: string): string => {
  switch (agentId) {
    case 'orchestrator':
      return 'bg-purple-600';
    case 'mike':
      return 'bg-blue-600';
    case 'alex':
      return 'bg-green-600';
    case 'david':
      return 'bg-amber-600';
    default:
      return 'bg-indigo-600';
  }
};

// Componente para exibir o conteúdo da mensagem com formatação markdown
const MessageContent: React.FC<{ content: string }> = ({ content }) => {
  // Verifica se o conteúdo é HTML
  if (content.includes('<html') || content.includes('<!DOCTYPE')) {
    return (
      <div>
        <div className="bg-gray-800 p-2 rounded mb-2 text-xs text-green-400">
          <FiInfo className="inline mr-1" /> HTML gerado
        </div>
        <div className="text-gray-300 max-h-80 overflow-y-auto">
          {content}
        </div>
      </div>
    );
  }

  // Tenta renderizar o conteúdo como markdown
  try {
    return (
      <div className="prose prose-invert prose-sm max-w-none">
        <ReactMarkdown>{content}</ReactMarkdown>
      </div>
    );
  } catch {
    // Se falhar, renderiza como texto normal
    return <div className="whitespace-pre-wrap">{content}</div>;
  }
};

export default ChatMessageComponent;