#AI
zhou zhou
13 小时以前 8a3fa0452075df8290d4542e64ced002ff4b476d
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
import request from "@/utils/request";
import { PREFIX_BASE_URL, TOKEN_HEADER_NAME } from "@/config/setting";
import { getToken } from "@/utils/token-util";
 
export const getAiRuntime = async (promptCode = "home.default", sessionId = null) => {
    const res = await request.get("ai/chat/runtime", {
        params: { promptCode, sessionId },
    });
    const { code, msg, data } = res.data;
    if (code === 200) {
        return data;
    }
    throw new Error(msg || "获取 AI 运行时信息失败");
};
 
export const getAiSessions = async (promptCode = "home.default") => {
    const res = await request.get("ai/chat/sessions", {
        params: { promptCode },
    });
    const { code, msg, data } = res.data;
    if (code === 200) {
        return data || [];
    }
    throw new Error(msg || "获取 AI 会话列表失败");
};
 
export const removeAiSession = async (sessionId) => {
    const res = await request.post(`ai/chat/session/remove/${sessionId}`);
    const { code, msg, data } = res.data;
    if (code === 200) {
        return data;
    }
    throw new Error(msg || "删除 AI 会话失败");
};
 
export const streamAiChat = async (payload, { signal, onEvent } = {}) => {
    const token = getToken();
    const response = await fetch(`${PREFIX_BASE_URL}ai/chat/stream`, {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "Accept": "text/event-stream",
            ...(token ? { [TOKEN_HEADER_NAME]: token } : {}),
        },
        body: JSON.stringify(payload),
        signal,
    });
 
    if (!response.ok) {
        throw new Error(`AI 请求失败 (${response.status})`);
    }
    if (!response.body) {
        throw new Error("AI 响应流不可用");
    }
 
    const reader = response.body.getReader();
    const decoder = new TextDecoder("utf-8");
    let buffer = "";
 
    while (true) {
        const { done, value } = await reader.read();
        if (done) {
            break;
        }
        buffer += decoder.decode(value, { stream: true });
        const events = buffer.split(/\r?\n\r?\n/);
        buffer = events.pop() || "";
        events.forEach((item) => dispatchSseEvent(item, onEvent));
    }
 
    if (buffer.trim()) {
        dispatchSseEvent(buffer, onEvent);
    }
};
 
const dispatchSseEvent = (rawEvent, onEvent) => {
    const lines = rawEvent.split(/\r?\n/);
    let eventName = "message";
    const dataLines = [];
 
    lines.forEach((line) => {
        if (line.startsWith("event:")) {
            eventName = line.slice(6).trim();
        }
        if (line.startsWith("data:")) {
            dataLines.push(line.slice(5).trim());
        }
    });
 
    if (!dataLines.length) {
        return;
    }
 
    const rawData = dataLines.join("\n");
    let payload = rawData;
    try {
        payload = JSON.parse(rawData);
    } catch (error) {
    }
    if (onEvent) {
        onEvent(eventName, payload);
    }
};