File size: 3,274 Bytes
ff6ab6d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4413b85
ff6ab6d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { useState, useRef } from 'preact/hooks';

async function waitForConfig() {
    return new Promise((resolve) => {
        const check = () => {
            if (window.ChatbotConfig) resolve(window.ChatbotConfig);
            else setTimeout(check, 50);
        };
        check();
    });
}

export function useChat() {
    const [messages, setMessages] = useState([]);
    const [isTyping, setIsTyping] = useState(false);
    const sessionId = useRef(null);
    const config = useRef(null);

    async function getConfig() {
        if (!config.current) {
            config.current = await waitForConfig();
        }
        return config.current;
    }

    async function initialize() {
        await getConfig();
        setMessages([{
            id: Date.now(),
            sender: 'bot',
            text: 'Hello! How can I help you today? \u60A8\u597D\uFF01\u4ECA\u5929\u6211\u80FD\u4E3A\u60A8\u505A\u4E9B\u4EC0\u4E48\uFF1F',
        }]);
    }

    async function sendMessage(text) {
        if (isTyping || !text.trim()) return;

        const cfg = await getConfig();

        setMessages(prev => [...prev, { id: Date.now(), sender: 'user', text }]);
        setIsTyping(true);

        try {
            const body = { message: text };
            if (sessionId.current) body.session_id = sessionId.current;

            const controller = new AbortController();
            const timeout = setTimeout(() => controller.abort(), cfg.REQUEST_TIMEOUT_MS);

            const thinkingStart = Date.now();
            const res = await fetch(`${cfg.API_URL}/chat`, {
                method: 'POST',
                headers: { 'X-API-Key': cfg.API_KEY, 'Content-Type': 'application/json' },
                body: JSON.stringify(body),
                signal: controller.signal,
            });
            clearTimeout(timeout);
            if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);
            const data = await res.json();
            const thinkingDuration = data.thinking
                ? ((Date.now() - thinkingStart) / 1000).toFixed(1)
                : null;

            sessionId.current = data.session_id;

            let debugInfo = null;
            if (cfg.SHOW_DEBUG_INFO) {
                debugInfo = {
                    intent: data.intent,
                    confidence: data.confidence?.toFixed(2),
                    entities: data.entities,
                    language: data.debug_info?.language,
                    environment: data.debug_info?.environment,
                };
            }

            setMessages(prev => [...prev, {
                id: Date.now(),
                sender: 'bot',
                text: data.response,
                thinking: data.thinking || null,
                thinkingDuration,
                debugInfo,
            }]);
        } catch (err) {
            const cfg = config.current;
            const errMsg = cfg?.DEBUG
                ? `Error: ${err.message}`
                : 'Sorry, I encountered an error. Please try again.';
            setMessages(prev => [...prev, { id: Date.now(), sender: 'bot', text: errMsg }]);
        } finally {
            setIsTyping(false);
        }
    }

    return { messages, isTyping, initialize, sendMessage };
}