zhou zhou
12 小时以前 5d16d9a0e7240ff4e6346bfee4890159da5a764e
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
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", keyword = "") => {
    const res = await request.get("ai/chat/sessions", {
        params: { promptCode, keyword },
    });
    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 renameAiSession = async (sessionId, title) => {
    const res = await request.post(`ai/chat/session/rename/${sessionId}`, { title });
    const { code, msg, data } = res.data;
    if (code === 200) {
        return data;
    }
    throw new Error(msg || "重命名 AI 会话失败");
};
 
export const pinAiSession = async (sessionId, pinned) => {
    const res = await request.post(`ai/chat/session/pin/${sessionId}`, { pinned });
    const { code, msg, data } = res.data;
    if (code === 200) {
        return data;
    }
    throw new Error(msg || "更新 AI 会话置顶状态失败");
};
 
export const clearAiSessionMemory = async (sessionId) => {
    const res = await request.post(`ai/chat/session/memory/clear/${sessionId}`);
    const { code, msg, data } = res.data;
    if (code === 200) {
        return data;
    }
    throw new Error(msg || "清空 AI 会话记忆失败");
};
 
export const retainAiSessionLatestRound = async (sessionId) => {
    const res = await request.post(`ai/chat/session/memory/retain-latest/${sessionId}`);
    const { code, msg, data } = res.data;
    if (code === 200) {
        return data;
    }
    throw new Error(msg || "仅保留当前轮记忆失败");
};
 
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);
    }
};