File size: 5,173 Bytes
27127dd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import React from 'react';
import { ChatHistoryProps } from '@/lib/types';
import TypingIndicator from './TypingIndicator';
import { useScrollToBottom } from '@/lib/hooks';
import { AlertTriangle } from 'lucide-react';

const ChatHistory: React.FC<ChatHistoryProps> = ({ 
  messages, 
  isLoading,
  currentModel = 'openai'
}) => {
  const scrollRef = useScrollToBottom([messages, isLoading]);
  
  // Check if we're in fallback mode by looking at the model or fallback indicator in messages
  const isFallbackMode = currentModel === 'qwen' ||
    messages.some(message => 
      message.role === 'assistant' && 
      message.content.includes('fallback mode')
    );

  return (
    <div 
      ref={scrollRef}
      className="chat-container overflow-y-auto pb-4 px-2"
      style={{ height: 'calc(100vh - 180px)' }}
    >
      {/* Fallback mode indicator */}
      {isFallbackMode && (
        <div className="bg-amber-50 border-l-4 border-amber-400 p-4 mb-4 rounded-md">
          <div className="flex items-center">
            <div className="flex-shrink-0">
              <AlertTriangle className="h-5 w-5 text-amber-400" />
            </div>
            <div className="ml-3">
              <p className="text-sm text-amber-700">
                <strong>Qwen Fallback Mode Active:</strong> The OpenAI API is currently unavailable.
                Responses are being generated by the Qwen model instead.
              </p>
            </div>
          </div>
        </div>
      )}

      {messages.map((message, index) => {
        // Check if this is a fallback message directly from the content
        const isMessageFallback = message.role === 'assistant' && 
          (message.content.includes('fallback mode') || 
           message.content.includes('Qwen model'));
        
        // Determine if this message appears to be a fallback response
        const isAssistantFallbackMessage = message.role === 'assistant' && 
          (currentModel === 'qwen' || isMessageFallback);
        
        // Clean up fallback message for display
        let displayContent = isAssistantFallbackMessage 
          ? message.content.replace(/\n\n\(Note: I'm currently operating in fallback mode.*\)$/, '') 
          : message.content;
          
        // Remove any thinking process sections for Qwen responses
        if (isAssistantFallbackMessage) {
          // Remove <think> tags and their content
          displayContent = displayContent.replace(/<think>[\s\S]*?<\/think>/g, '');
          
          // Remove any other XML-like tags
          displayContent = displayContent.replace(/<[^>]*>/g, '');
          
          // Clean up any excessive whitespace
          displayContent = displayContent.replace(/^\s+|\s+$/g, '');
          displayContent = displayContent.replace(/\n{3,}/g, '\n\n');
        }
          
        return (
          <div 
            key={index}
            className={`flex items-start ${message.role === 'user' ? 'justify-end' : ''} mb-4`}
          >
            {message.role !== 'user' && (
              <div className="flex-shrink-0 mr-3">
                <div className={`h-8 w-8 rounded-full ${
                  isAssistantFallbackMessage ? 'bg-amber-500' : 'bg-primary'
                } flex items-center justify-center text-white`}>
                  <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
                    <path d="M2 5a2 2 0 012-2h7a2 2 0 012 2v4a2 2 0 01-2 2H9l-3 3v-3H4a2 2 0 01-2-2V5z" />
                    <path d="M15 7v2a4 4 0 01-4 4H9.828l-1.766 1.767c.28.149.599.233.938.233h2l3 3v-3h2a2 2 0 002-2V9a2 2 0 00-2-2h-1z" />
                  </svg>
                </div>
              </div>
            )}
            
            <div 
              className={`${
                message.role === 'user' 
                  ? 'bg-primary text-white' 
                  : isAssistantFallbackMessage 
                    ? 'bg-amber-50 border border-amber-200 text-gray-800' 
                    : 'bg-white text-gray-800'
              } rounded-lg p-4 shadow-sm max-w-[85%]`}
            >
              <p className="whitespace-pre-wrap">{displayContent}</p>
              
              {isAssistantFallbackMessage && isMessageFallback && (
                <p className="mt-2 text-xs text-amber-600 italic">
                  (This response was generated using the Qwen fallback model)
                </p>
              )}
            </div>
            
            {message.role === 'user' && (
              <div className="flex-shrink-0 ml-3">
                <div className="h-8 w-8 rounded-full bg-gray-300 flex items-center justify-center text-gray-600">
                  <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
                    <path fillRule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clipRule="evenodd" />
                  </svg>
                </div>
              </div>
            )}
          </div>
        );
      })}
      
      <TypingIndicator isVisible={isLoading} />
    </div>
  );
};

export default ChatHistory;