feat: add chat history and session
This commit is contained in:
25
src/pages/ai-chat/store/ai-history.ts
Normal file
25
src/pages/ai-chat/store/ai-history.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { StateCreator } from 'zustand';
|
||||
import { AiStore } from './ai-store';
|
||||
import { query } from '@/modules';
|
||||
export type AiHistoryStore = {
|
||||
list: any[];
|
||||
getList: () => Promise<any>;
|
||||
};
|
||||
export const createAiHistoryStore: StateCreator<AiStore, [], [], AiHistoryStore> = (set, get, store) => {
|
||||
return {
|
||||
list: [],
|
||||
getList: async () => {
|
||||
const { key } = get();
|
||||
set({ loading: true });
|
||||
const res = await query.post({
|
||||
path: 'chat-session',
|
||||
key: 'list-history',
|
||||
data: { key },
|
||||
});
|
||||
if (res.success) {
|
||||
set({ list: res.data });
|
||||
}
|
||||
console.log('res', res);
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -1,6 +1,8 @@
|
||||
import { query } from '@/modules';
|
||||
import { message } from 'antd';
|
||||
import { produce } from 'immer';
|
||||
import { create } from 'zustand';
|
||||
import { AiHistoryStore, createAiHistoryStore } from './ai-history';
|
||||
type ResData = {
|
||||
created_at: string;
|
||||
done?: boolean;
|
||||
@@ -14,48 +16,87 @@ type ResData = {
|
||||
prompt_eval_duration?: number;
|
||||
total_duration?: number;
|
||||
};
|
||||
|
||||
type MessageData = {
|
||||
chatId: string;
|
||||
chatPromptId: string;
|
||||
role: string;
|
||||
root: boolean;
|
||||
show: boolean;
|
||||
data: {
|
||||
message: string;
|
||||
};
|
||||
};
|
||||
export type AiStore = {
|
||||
/** 打开侧边栏 */
|
||||
open: boolean;
|
||||
setOpen: (open: boolean) => void;
|
||||
showEdit: boolean;
|
||||
setShowEdit: (showEdit: boolean) => void;
|
||||
loading: boolean;
|
||||
setLoading: (loading: boolean) => void;
|
||||
type?: string;
|
||||
/** 当前app执行的key */
|
||||
key: string;
|
||||
setKey: (key: string) => void;
|
||||
setType?: (type: string) => void;
|
||||
sendMsg: (msg: string) => void;
|
||||
formData: any;
|
||||
setFormData: (data: any) => void;
|
||||
data: any;
|
||||
setData: (data: any) => void;
|
||||
runAi: () => any;
|
||||
title: string;
|
||||
title: string; // AI Module的标题
|
||||
setTitle: (title: string) => void;
|
||||
messages: { role: string; content: string }[];
|
||||
setMessage: (message: { role: string; content: string }[]) => void;
|
||||
};
|
||||
getPrompt: (key?: string) => any;
|
||||
// 设置预设数据,只有是root的情况下才成立
|
||||
presetData?: any;
|
||||
setPresetData: (data: any) => void;
|
||||
/** 是否是第一条消息 */
|
||||
root: boolean;
|
||||
setRoot: (root: boolean) => void;
|
||||
onMessage: (data: MessageData) => void;
|
||||
} & AiHistoryStore;
|
||||
|
||||
export const useAiStore = create<AiStore>((set, get) => {
|
||||
export const useAiStore = create<AiStore>((set, get, store) => {
|
||||
return {
|
||||
open: false,
|
||||
setOpen: (open) => set({ open }),
|
||||
setOpen: (open) => set({ open, root: true }),
|
||||
loading: false,
|
||||
setLoading: (loading) => set({ loading }),
|
||||
key: '',
|
||||
setKey: (key) => set({ key }),
|
||||
sendMsg: (msg) => {
|
||||
console.log(msg);
|
||||
setKey: (key) => {
|
||||
const { getPrompt } = get();
|
||||
if (key) {
|
||||
getPrompt(key);
|
||||
}
|
||||
set({ key });
|
||||
},
|
||||
formData: {},
|
||||
setFormData: (data) => set({ formData: data }),
|
||||
data: {},
|
||||
setData: (data) => {
|
||||
const { key, presetData = {} } = data;
|
||||
console.log('key', presetData, data);
|
||||
if (!key) {
|
||||
console.error('key is required');
|
||||
return;
|
||||
title: '',
|
||||
setTitle: (title) => set({ title }),
|
||||
messages: [],
|
||||
setMessage: (messages) => set({ messages }),
|
||||
getPrompt: async (key) => {
|
||||
const state = get();
|
||||
const res = await query.post({
|
||||
path: 'chat-prompt',
|
||||
key: 'getByKey',
|
||||
data: {
|
||||
key: key || state.key,
|
||||
},
|
||||
});
|
||||
if (res.code === 200) {
|
||||
const { prompt } = res.data;
|
||||
const { presetData } = prompt;
|
||||
console.log(res.data);
|
||||
state.setPresetData(presetData);
|
||||
set({ root: true });
|
||||
}
|
||||
const { inputs = [] } = presetData.data || {};
|
||||
},
|
||||
presetData: {},
|
||||
setPresetData: (data) => {
|
||||
set({ presetData: data });
|
||||
const { inputs = [] } = data?.data || {};
|
||||
const formData = {
|
||||
key,
|
||||
inputs: inputs.map((input) => {
|
||||
return {
|
||||
key: input.key,
|
||||
@@ -65,40 +106,23 @@ export const useAiStore = create<AiStore>((set, get) => {
|
||||
}),
|
||||
messages: [],
|
||||
};
|
||||
console.log('formData', formData);
|
||||
set({ key, data, formData });
|
||||
set({ formData });
|
||||
},
|
||||
runAi: async () => {
|
||||
const { formData, messages } = get();
|
||||
const loading = message.loading('loading');
|
||||
const res = await query.post({
|
||||
path: 'ai',
|
||||
key: 'run',
|
||||
data: {
|
||||
key: formData.key,
|
||||
inputs: [
|
||||
// {
|
||||
// key: 'title',
|
||||
// value: '根据描述生成代码',
|
||||
// },
|
||||
// {
|
||||
// key: 'description',
|
||||
// value: '我想获取一个card, 包含标题和内容,标题是evision,内容是这是一个测试',
|
||||
// },
|
||||
...formData.inputs,
|
||||
],
|
||||
},
|
||||
});
|
||||
loading();
|
||||
if (res.code === 200) {
|
||||
console.log(res.data);
|
||||
message.success('Success');
|
||||
set({ messages: [...messages, res.data.message] });
|
||||
}
|
||||
root: false,
|
||||
setRoot: (root) => set({ root }),
|
||||
onMessage: (data) => {
|
||||
const state = get();
|
||||
if (state.root) set({ root: false });
|
||||
const { message } = data.data;
|
||||
const role = data.role;
|
||||
set(
|
||||
produce((state) => {
|
||||
state.messages.push({ role, content: message });
|
||||
}),
|
||||
);
|
||||
},
|
||||
title: '',
|
||||
setTitle: (title) => set({ title }),
|
||||
messages: [],
|
||||
setMessage: (messages) => set({ messages }),
|
||||
showEdit: false,
|
||||
setShowEdit: (showEdit) => set({ showEdit }),
|
||||
...createAiHistoryStore(set, get, store),
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user