38060-vm/frontend/src/stores/openAiSlice.ts
2026-02-01 12:51:34 +00:00

152 lines
4.8 KiB
TypeScript

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import axios from 'axios';
interface MainState {
isFetchingQuery: boolean;
errorMessage: string;
smartWidgets: any[];
gptResponse: string | null;
aiResponse: any | null;
isAskingQuestion: boolean;
isAskingResponse: boolean;
notify: {
showNotification: boolean;
textNotification: string;
typeNotification: string;
};
}
const initialState: MainState = {
isFetchingQuery: false,
errorMessage: '',
smartWidgets: [],
gptResponse: null,
aiResponse: null,
isAskingQuestion: false,
isAskingResponse: false,
notify: {
showNotification: false,
textNotification: '',
typeNotification: 'warn',
},
};
const fulfilledNotify = (state, msg, type?: string) => {
state.notify.textNotification = msg;
state.notify.typeNotification = type || 'success';
state.notify.showNotification = true;
};
export const aiPrompt = createAsyncThunk(
'openai/aiPrompt',
async (data: any, { rejectWithValue }) => {
try {
return await axios.post('/openai/create_widget', data);
} catch (error) {
if (!error.response) {
throw error;
}
return rejectWithValue(error.response.data);
}
},
);
export const askGpt = createAsyncThunk(
'openai/askGpt',
async (prompt: string, { rejectWithValue }) => {
try {
const response = await axios.post('/openai/ask-gpt', { prompt });
return response.data;
} catch (error) {
if (!error.response) {
throw error;
}
return rejectWithValue(error.response.data);
}
},
);
export const aiResponse = createAsyncThunk(
'openai/aiResponse',
async (payload: { input: Array<{ role: string; content: string }>; options?: Record<string, any> }, { rejectWithValue }) => {
try {
const response = await axios.post('/ai/response', payload);
return response.data;
} catch (error) {
if (!error.response) {
throw error;
}
return rejectWithValue(error.response.data);
}
},
);
export const openAiSlice = createSlice({
name: 'openAiSlice',
initialState,
reducers: {
resetNotify: (state) => {
state.notify.showNotification = false;
state.notify.typeNotification = '';
state.notify.textNotification = '';
},
setErrorNotification: (state, action) => {
fulfilledNotify(state, action.payload, 'error');
},
},
extraReducers: (builder) => {
builder.addCase(aiPrompt.pending, (state) => {
state.isFetchingQuery = true;
});
builder.addCase(aiPrompt.fulfilled, (state, action: Record<any, any>) => {
state.isFetchingQuery = false;
state.errorMessage = '';
state.smartWidgets.unshift(action.payload.data);
});
builder.addCase(aiPrompt.rejected, (state) => {
state.errorMessage = 'Something was wrong. Try again';
state.isFetchingQuery = false;
state.smartWidgets = null;
});
builder.addCase(askGpt.pending, (state) => {
state.isAskingQuestion = true;
state.gptResponse = null;
state.errorMessage = '';
});
builder.addCase(askGpt.fulfilled, (state, action) => {
state.isAskingQuestion = false;
state.gptResponse = action.payload.data;
state.errorMessage = '';
});
builder.addCase(askGpt.rejected, (state) => {
state.isAskingQuestion = false;
state.gptResponse = null;
state.errorMessage = 'Failed to get response from ChatGPT. Please try again.';
fulfilledNotify(state, 'Failed to get response from ChatGPT', 'error');
});
builder.addCase(aiResponse.pending, (state) => {
state.isAskingResponse = true;
state.aiResponse = null;
state.errorMessage = '';
});
builder.addCase(aiResponse.fulfilled, (state, action) => {
state.isAskingResponse = false;
state.aiResponse = action.payload;
state.errorMessage = '';
});
builder.addCase(aiResponse.rejected, (state) => {
state.isAskingResponse = false;
state.aiResponse = null;
state.errorMessage = 'Failed to get response from AI proxy. Please try again.';
fulfilledNotify(state, 'Failed to get response from AI proxy', 'error');
});
},
});
// Action creators are generated for each case reducer function
export const { resetNotify, setErrorNotification } = openAiSlice.actions;
export default openAiSlice.reducer;