wangzhibo
6 天以前 7bd866831780abcf5a59c4cbb7d1be456eea7c99
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
import { module } from '/@/cool';
import { useBase } from '/$/base';
 
export function useAi() {
    const { api } = module.config('helper');
    const { user } = useBase();
 
    // 调用流程
    async function invokeFlow(
        label: string,
        params: any,
        streamCb?: ({ isEnd, content }: { isEnd: boolean; content: string }) => void
    ): Promise<any> {
        const stream = !!streamCb;
 
        let cacheText = '';
 
        return new Promise((resolve, reject) => {
            fetch(api + '/open/code/gen/data', {
                method: 'POST',
                headers: {
                    Authorization: user.token,
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    params,
                    label,
                    stream
                })
            })
                .then(res => {
                    if (res.body) {
                        if (stream) {
                            const reader = res.body.getReader();
                            const decoder = new TextDecoder('utf-8');
                            const stream = new ReadableStream({
                                start(controller) {
                                    function push() {
                                        reader.read().then(({ done, value }) => {
                                            if (done) {
                                                controller.close();
                                                return;
                                            }
 
                                            let text = decoder.decode(value, { stream: true });
 
                                            if (streamCb) {
                                                if (cacheText) {
                                                    text = cacheText + text;
                                                }
 
                                                if (text.indexOf('data:') == 0) {
                                                    text = '\n\n' + text;
                                                }
 
                                                try {
                                                    const arr = text
                                                        .split(/\n\ndata:/g)
                                                        .filter(Boolean)
                                                        .map(e => JSON.parse(e));
 
                                                    arr.forEach(streamCb);
 
                                                    cacheText = '';
                                                } catch (err) {
                                                    cacheText = text;
                                                }
                                            }
 
                                            controller.enqueue(text);
                                            push();
                                        });
                                    }
                                    push();
                                }
                            });
 
                            return new Response(stream);
                        } else {
                            return res.json();
                        }
                    }
                })
                .then(res => {
                    if (stream) {
                        return res;
                    }
 
                    if (res.code == 1000) {
                        resolve(res.data.result);
                    } else {
                        reject(res);
                    }
                })
                .catch(reject);
        });
    }
 
    return {
        invokeFlow
    };
}