diff --git a/backend/src/controller/modelController.ts b/backend/src/controller/modelController.ts index dafb6716a..08301113d 100644 --- a/backend/src/controller/modelController.ts +++ b/backend/src/controller/modelController.ts @@ -1,10 +1,9 @@ -import { Request, Response } from 'express'; +import { Response } from 'express'; import { OpenAIGetModelRequest } from '@src/models/api/OpenAIGetModelRequest'; import { OpenAiConfigureModelRequest } from '@src/models/api/OpenAiConfigureModelRequest'; import { OpenAiSetModelRequest } from '@src/models/api/OpenAiSetModelRequest'; import { MODEL_CONFIG } from '@src/models/chat'; -import { getValidOpenAIModelsList } from '@src/openai'; function handleSetModel(req: OpenAiSetModelRequest, res: Response) { const { model } = req.body; @@ -37,14 +36,4 @@ function handleGetModel(req: OpenAIGetModelRequest, res: Response) { res.send(req.session.chatModel); } -function handleGetValidModels(_: Request, res: Response) { - const models = getValidOpenAIModelsList(); - res.send({ models }); -} - -export { - handleSetModel, - handleConfigureModel, - handleGetModel, - handleGetValidModels, -}; +export { handleSetModel, handleConfigureModel, handleGetModel }; diff --git a/backend/src/controller/startController.ts b/backend/src/controller/startController.ts new file mode 100644 index 000000000..676c92686 --- /dev/null +++ b/backend/src/controller/startController.ts @@ -0,0 +1,30 @@ +import { Response } from 'express'; + +import { GetStartRequest } from '@src/models/api/getStartRequest'; +import { LEVEL_NAMES } from '@src/models/level'; +import { getValidOpenAIModels } from '@src/openai'; +import { + systemRoleLevel1, + systemRoleLevel2, + systemRoleLevel3, +} from '@src/promptTemplates'; + +function handleStart(req: GetStartRequest, res: Response) { + const { level } = req.query; + + const systemRoles = [ + { level: LEVEL_NAMES.LEVEL_1, systemRole: systemRoleLevel1 }, + { level: LEVEL_NAMES.LEVEL_2, systemRole: systemRoleLevel2 }, + { level: LEVEL_NAMES.LEVEL_3, systemRole: systemRoleLevel3 }, + ]; + + res.send({ + emails: req.session.levelState[level].sentEmails, + chatHistory: req.session.levelState[level].chatHistory, + defences: req.session.levelState[level].defences, + availableModels: getValidOpenAIModels(), + systemRoles, + }); +} + +export { handleStart }; diff --git a/backend/src/controller/systemRoleController.ts b/backend/src/controller/systemRoleController.ts deleted file mode 100644 index 432d5c6d1..000000000 --- a/backend/src/controller/systemRoleController.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Request, Response } from 'express'; - -import { LEVEL_NAMES } from '@src/models/level'; -import { - systemRoleLevel1, - systemRoleLevel2, - systemRoleLevel3, -} from '@src/promptTemplates'; - -function handleGetSystemRoles(_: Request, res: Response) { - const systemRoles = [ - { level: LEVEL_NAMES.LEVEL_1, systemRole: systemRoleLevel1 }, - { level: LEVEL_NAMES.LEVEL_2, systemRole: systemRoleLevel2 }, - { level: LEVEL_NAMES.LEVEL_3, systemRole: systemRoleLevel3 }, - ]; - res.send(systemRoles); -} - -export { handleGetSystemRoles }; diff --git a/backend/src/defence.ts b/backend/src/defence.ts index f067c5371..54a320e29 100644 --- a/backend/src/defence.ts +++ b/backend/src/defence.ts @@ -256,7 +256,7 @@ function transformMessage( : undefined; if (!transformedMessage) { - console.debug('No defences applied. Message unchanged.'); + console.debug('No transformation applied. Message unchanged.'); return; } diff --git a/backend/src/langchain.ts b/backend/src/langchain.ts index 8341e07dc..2e487e780 100644 --- a/backend/src/langchain.ts +++ b/backend/src/langchain.ts @@ -7,7 +7,7 @@ import { getDocumentVectors } from './document'; import { CHAT_MODELS } from './models/chat'; import { PromptEvaluationChainReply, QaChainReply } from './models/langchain'; import { LEVEL_NAMES } from './models/level'; -import { getOpenAIKey, getValidOpenAIModelsList } from './openai'; +import { getOpenAIKey, getValidOpenAIModels } from './openai'; import { promptEvalPrompt, promptEvalContextTemplate, @@ -31,7 +31,7 @@ function makePromptTemplate( } function getChatModel() { - return getValidOpenAIModelsList().includes(CHAT_MODELS.GPT_4) + return getValidOpenAIModels().includes(CHAT_MODELS.GPT_4) ? CHAT_MODELS.GPT_4 : CHAT_MODELS.GPT_3_5_TURBO; } diff --git a/backend/src/models/api/getStartRequest.ts b/backend/src/models/api/getStartRequest.ts new file mode 100644 index 000000000..86d8c9dd2 --- /dev/null +++ b/backend/src/models/api/getStartRequest.ts @@ -0,0 +1,21 @@ +import { Request } from 'express'; + +import { ChatMessage } from '@src/models/chatMessage'; +import { Defence } from '@src/models/defence'; +import { EmailInfo } from '@src/models/email'; +import { LEVEL_NAMES } from '@src/models/level'; + +export type GetStartRequest = Request< + never, + { + emails: EmailInfo[]; + chatHistory: ChatMessage[]; + defences: Defence[]; + availableModels: string[]; + systemRoles: string[]; + }, + never, + { + level: LEVEL_NAMES; + } +>; diff --git a/backend/src/nonSessionRoutes.ts b/backend/src/nonSessionRoutes.ts index cae39c5ee..2497bfa47 100644 --- a/backend/src/nonSessionRoutes.ts +++ b/backend/src/nonSessionRoutes.ts @@ -3,7 +3,6 @@ import { fileURLToPath } from 'node:url'; import { handleGetDocuments } from './controller/documentController'; import { handleHealthCheck } from './controller/healthController'; -import { handleGetSystemRoles } from './controller/systemRoleController'; import { importMetaUrl } from './importMetaUtils'; const router = express.Router(); @@ -16,6 +15,5 @@ router.use( ); router.get('/documents', handleGetDocuments); router.get('/health', handleHealthCheck); -router.get('/systemRoles', handleGetSystemRoles); export default router; diff --git a/backend/src/openai.ts b/backend/src/openai.ts index 553dd0883..a4a5433c2 100644 --- a/backend/src/openai.ts +++ b/backend/src/openai.ts @@ -439,7 +439,7 @@ async function chatGptSendMessage( }; } -export const getValidOpenAIModelsList = validOpenAiModels.get; +export const getValidOpenAIModels = validOpenAiModels.get; export { chatGptTools, chatGptSendMessage, diff --git a/backend/src/sessionRoutes.ts b/backend/src/sessionRoutes.ts index d9a19660e..3b8ff3240 100644 --- a/backend/src/sessionRoutes.ts +++ b/backend/src/sessionRoutes.ts @@ -23,10 +23,10 @@ import { import { handleConfigureModel, handleGetModel, - handleGetValidModels, handleSetModel, } from './controller/modelController'; import { handleResetProgress } from './controller/resetController'; +import { handleStart } from './controller/startController'; import { handleTest } from './controller/testController'; import { ChatModel, defaultChatModel } from './models/chat'; import { LevelState, getInitialLevelStates } from './models/level'; @@ -94,6 +94,9 @@ router.use((req, _res, next) => { next(); }); +// handshake +router.get('/start', handleStart); + // defences router.get('/defence/status', handleGetDefenceStatus); router.post('/defence/activate', handleDefenceActivation); @@ -112,7 +115,6 @@ router.post('/openai/addInfoToHistory', handleAddInfoToChatHistory); router.post('/openai/clear', handleClearChatHistory); // model configurations -router.get('/openai/validModels', handleGetValidModels); router.get('/openai/model', handleGetModel); router.post('/openai/model', handleSetModel); router.post('/openai/model/configure', handleConfigureModel); diff --git a/backend/test/unit/controller/systemRoleController.test.ts b/backend/test/unit/controller/systemRoleController.test.ts deleted file mode 100644 index 5413eb532..000000000 --- a/backend/test/unit/controller/systemRoleController.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { expect, test, jest, describe } from '@jest/globals'; -import { Request, Response } from 'express'; - -import { handleGetSystemRoles } from '@src/controller/systemRoleController'; -import { LEVEL_NAMES } from '@src/models/level'; -import { - systemRoleLevel1, - systemRoleLevel2, - systemRoleLevel3, -} from '@src/promptTemplates'; - -describe('systemRoleController unit tests', () => { - function responseMock() { - return { - send: jest.fn(), - status: jest.fn(), - } as unknown as Response; - } - - test('GIVEN a request THEN the systemRoleController should return a list of system roles', () => { - const expectedSystemRoles = [ - { level: LEVEL_NAMES.LEVEL_1, systemRole: systemRoleLevel1 }, - { level: LEVEL_NAMES.LEVEL_2, systemRole: systemRoleLevel2 }, - { level: LEVEL_NAMES.LEVEL_3, systemRole: systemRoleLevel3 }, - ]; - - const res = responseMock(); - handleGetSystemRoles({} as Request, res); - - expect(res.send).toHaveBeenCalledWith(expectedSystemRoles); - }); -}); diff --git a/backend/test/unit/langchain.ts/initialisePromptEvaluationModel.test.ts b/backend/test/unit/langchain.ts/initialisePromptEvaluationModel.test.ts index 07fc9f8cd..055cd4547 100644 --- a/backend/test/unit/langchain.ts/initialisePromptEvaluationModel.test.ts +++ b/backend/test/unit/langchain.ts/initialisePromptEvaluationModel.test.ts @@ -32,7 +32,7 @@ jest.mock('@src/openai', () => { jest.requireActual('@src/openai'); return { ...originalModule, - getValidOpenAIModelsList: jest.fn(() => mockValidModels), + getValidOpenAIModels: jest.fn(() => mockValidModels), }; }); diff --git a/backend/test/unit/langchain.ts/initialiseQAModel.test.ts b/backend/test/unit/langchain.ts/initialiseQAModel.test.ts index 1c27c1b47..12ad68f84 100644 --- a/backend/test/unit/langchain.ts/initialiseQAModel.test.ts +++ b/backend/test/unit/langchain.ts/initialiseQAModel.test.ts @@ -56,7 +56,7 @@ jest.mock('@src/openai', () => { jest.requireActual('@src/openai'); // can we remove this return { ...originalModule, - getValidOpenAIModelsList: jest.fn(() => mockValidModels), + getValidOpenAIModels: jest.fn(() => mockValidModels), }; }); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 02e97530f..eade00131 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,14 +1,13 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import DocumentViewBox from './components/DocumentViewer/DocumentViewBox'; -import HandbookOverlay from './components/HandbookOverlay/HandbookOverlay'; import MainComponent from './components/MainComponent/MainComponent'; import LevelsComplete from './components/Overlay/LevelsComplete'; import MissionInformation from './components/Overlay/MissionInformation'; import OverlayWelcome from './components/Overlay/OverlayWelcome'; import ResetProgressOverlay from './components/Overlay/ResetProgress'; -import { LEVEL_NAMES, LevelSystemRole } from './models/level'; -import { chatService, levelService, systemRoleService } from './service'; +import { LEVEL_NAMES } from './models/level'; +import { levelService } from './service'; import './App.css'; import './Theme.css'; @@ -28,8 +27,6 @@ function App() { null ); - const [chatModels, setChatModels] = useState([]); - const [systemRoles, setSystemRoles] = useState([]); const [mainComponentKey, setMainComponentKey] = useState(0); function loadIsNewUser() { @@ -72,21 +69,6 @@ function App() { setNumCompletedLevels(Math.max(numCompletedLevels, completedLevel + 1)); } - // fetch constants from the backend on app mount - async function loadBackendData() { - try { - console.log("Initializing app's backend data"); - const [models, roles] = await Promise.all([ - chatService.getValidModels(), - systemRoleService.getSystemRoles(), - ]); - setChatModels(models); - setSystemRoles(roles); - } catch (err) { - console.log(err); - } - } - useEffect(() => { // save number of completed levels to local storage localStorage.setItem('numCompletedLevels', numCompletedLevels.toString()); @@ -116,11 +98,6 @@ function App() { } }, [isNewUser]); - // load the system constants from backend on app mount - useEffect(() => { - void loadBackendData(); - }, []); - useEffect(() => { // must re-bind event listener after changing overlay type setTimeout(() => { @@ -177,16 +154,7 @@ function App() { /> ); } - function openHandbook() { - openOverlay( - - ); - } + function openInformationOverlay() { openOverlay( { // get user-friendly defence name - const defenceName = ALL_DEFENCES.find((defence) => { + const defenceName = DEFAULT_DEFENCES.find((defence) => { return defence.id === triggeredDefence; })?.name.toLowerCase(); if (defenceName) { @@ -131,7 +131,7 @@ function ChatBox({ // add triggered defences to the chat response.defenceReport.triggeredDefences.forEach((triggeredDefence) => { // get user-friendly defence name - const defenceName = ALL_DEFENCES.find((defence) => { + const defenceName = DEFAULT_DEFENCES.find((defence) => { return defence.id === triggeredDefence; })?.name.toLowerCase(); if (defenceName) { diff --git a/frontend/src/components/ControlPanel/ControlPanel.tsx b/frontend/src/components/ControlPanel/ControlPanel.tsx index d1c9ef608..3a165192d 100644 --- a/frontend/src/components/ControlPanel/ControlPanel.tsx +++ b/frontend/src/components/ControlPanel/ControlPanel.tsx @@ -1,4 +1,4 @@ -import { MODEL_DEFENCES } from '@src/Defences'; +import { DEFENCES_HIDDEN_LEVEL3_IDS, MODEL_DEFENCES } from '@src/Defences'; import DefenceBox from '@src/components/DefenceBox/DefenceBox'; import DocumentViewButton from '@src/components/DocumentViewer/DocumentViewButton'; import ModelBox from '@src/components/ModelBox/ModelBox'; @@ -29,12 +29,21 @@ function ControlPanel({ openDocumentViewer: () => void; addInfoMessage: (message: string) => void; }) { - const configurableDefences = defences.filter( - (defence) => !MODEL_DEFENCES.some((id) => id === defence.id) + const configurableDefences = + currentLevel === LEVEL_NAMES.SANDBOX + ? defences + : currentLevel === LEVEL_NAMES.LEVEL_3 + ? defences.filter( + (defence) => !DEFENCES_HIDDEN_LEVEL3_IDS.includes(defence.id) + ) + : []; + + const nonModelDefences = configurableDefences.filter( + (defence) => !MODEL_DEFENCES.includes(defence.id) ); - const modelDefences = defences.filter((defence) => - MODEL_DEFENCES.some((id) => id === defence.id) + const modelDefences = configurableDefences.filter((defence) => + MODEL_DEFENCES.includes(defence.id) ); // only allow configuration in sandbox @@ -53,7 +62,7 @@ function ControlPanel({ void; updateNumCompletedLevels: (level: number) => void; openDocumentViewer: () => void; - openHandbook: () => void; openInformationOverlay: () => void; openLevelsCompleteOverlay: () => void; openOverlay: (overlayComponent: JSX.Element) => void; @@ -50,27 +47,53 @@ function MainComponent({ setCurrentLevel: (newLevel: LEVEL_NAMES) => void; }) { const [MainBodyKey, setMainBodyKey] = useState(0); - const [defencesToShow, setDefencesToShow] = useState(ALL_DEFENCES); - const [emails, setEmails] = useState([]); + const [defences, setDefences] = useState(DEFAULT_DEFENCES); const [messages, setMessages] = useState([]); + const [emails, setEmails] = useState([]); + const [chatModels, setChatModels] = useState([]); + const [systemRoles, setSystemRoles] = useState([]); + + const isFirstRender = useRef(true); - // called on mount + // facilitate refresh / first render useEffect(() => { - // perform backend health check - healthService.healthCheck().catch(() => { - // addErrorMessage('Failed to reach the server. Please try again later.'); + console.log( + 'Loading initial backend data plus data for level', + currentLevel + ); + void loadBackendData(); + }, []); + + // facilitate level change + useEffect(() => { + console.log( + 'useEffect currentLevel. isFirstRender.current:', + isFirstRender.current + ); + if (!isFirstRender.current) { + console.log('Loading backend data for level', currentLevel); + void setNewLevel(currentLevel); + } + isFirstRender.current = false; + }, [currentLevel]); + + async function loadBackendData() { + try { + const { availableModels, defences, emails, history, systemRoles } = + await startService.start(currentLevel); + setChatModels(availableModels); + setSystemRoles(systemRoles); + processBackendLevelData(currentLevel, emails, history, defences); + } catch (err) { + console.warn(err); setMessages([ { message: 'Failed to reach the server. Please try again later.', type: 'ERROR_MSG', }, ]); - }); - }, []); - - useEffect(() => { - void setNewLevel(currentLevel); - }, [currentLevel]); + } + } function openResetLevelOverlay() { openOverlay( @@ -85,6 +108,17 @@ function MainComponent({ ); } + function openHandbook() { + openOverlay( + + ); + } + // methods to modify messages function addChatMessage(message: ChatMessage) { setMessages((messages: ChatMessage[]) => [...messages, message]); @@ -116,41 +150,26 @@ function MainComponent({ // for going switching level without clearing progress async function setNewLevel(newLevel: LEVEL_NAMES) { - // get emails for new level from the backend - setEmails(await emailService.getSentEmails(newLevel)); + const emails = await emailService.getSentEmails(newLevel); + const chatHistory = await chatService.getChatHistory(newLevel); + const defences = await defenceService.getDefences(newLevel); + processBackendLevelData(newLevel, emails, chatHistory, defences); + } - // get chat history for new level from the backend - const retrievedMessages = await chatService.getChatHistory(newLevel); + function processBackendLevelData( + level: LEVEL_NAMES, + emails: EmailInfo[], + chatHistory: ChatMessage[], + defences: Defence[] + ) { + setEmails(emails); // add welcome message for levels only - newLevel !== LEVEL_NAMES.SANDBOX - ? setMessagesWithWelcome(retrievedMessages) - : setMessages(retrievedMessages); + level !== LEVEL_NAMES.SANDBOX + ? setMessagesWithWelcome(chatHistory) + : setMessages(chatHistory); - const defences = - newLevel === LEVEL_NAMES.LEVEL_3 ? DEFENCES_SHOWN_LEVEL3 : ALL_DEFENCES; - // fetch defences from backend - const remoteDefences = await defenceService.getDefences(newLevel); - defences.map((localDefence) => { - const matchingRemoteDefence = remoteDefences.find((remoteDefence) => { - return localDefence.id === remoteDefence.id; - }); - if (matchingRemoteDefence) { - localDefence.isActive = matchingRemoteDefence.isActive; - // set each config value - matchingRemoteDefence.config.forEach((configEntry) => { - // get the matching config in the local defence - const matchingConfig = localDefence.config.find((config) => { - return config.id === configEntry.id; - }); - if (matchingConfig) { - matchingConfig.value = configEntry.value; - } - }); - } - return localDefence; - }); - setDefencesToShow(defences); + setDefences(defences); setMainBodyKey(MainBodyKey + 1); } @@ -182,7 +201,7 @@ function MainComponent({ ); addConfigUpdateToChat(defenceId, 'reset'); // update state - const newDefences = defencesToShow.map((defence) => { + const newDefences = defences.map((defence) => { if (defence.id === defenceId) { defence.config.forEach((config) => { if (config.id === configId) { @@ -192,7 +211,7 @@ function MainComponent({ } return defence; }); - setDefencesToShow(newDefences); + setDefences(newDefences); } async function setDefenceToggle(defence: Defence) { @@ -202,7 +221,7 @@ function MainComponent({ currentLevel ); - const newDefenceDetails = defencesToShow.map((defenceDetail) => { + const newDefenceDetails = defences.map((defenceDetail) => { if (defenceDetail.id === defence.id) { defenceDetail.isActive = !defence.isActive; const action = defenceDetail.isActive ? 'activated' : 'deactivated'; @@ -212,7 +231,7 @@ function MainComponent({ return defenceDetail; }); - setDefencesToShow(newDefenceDetails); + setDefences(newDefenceDetails); } async function setDefenceConfiguration( @@ -227,13 +246,13 @@ function MainComponent({ if (success) { addConfigUpdateToChat(defenceId, 'updated'); // update state - const newDefences = defencesToShow.map((defence) => { + const newDefences = defences.map((defence) => { if (defence.id === defenceId) { defence.config = config; } return defence; }); - setDefencesToShow(newDefences); + setDefences(newDefences); } return success; } @@ -286,7 +305,7 @@ function MainComponent({ { }); const chatMessageDTOs = (await response.json()) as ChatMessageDTO[]; + return getChatMessagesFromDTOResponse(chatMessageDTOs); +} + +function getChatMessagesFromDTOResponse(chatMessageDTOs: ChatMessageDTO[]) { return chatMessageDTOs .filter(chatMessageDTOIsConvertible) .map(makeChatMessageFromDTO); @@ -97,14 +101,6 @@ async function getGptModel(): Promise { return (await response.json()) as ChatModel; } -async function getValidModels(): Promise { - const response = await sendRequest(`${PATH}validModels`, { method: 'GET' }); - const data = (await response.json()) as { - models: string[]; - }; - return data.models; -} - async function addInfoMessageToChatHistory( message: string, chatMessageType: CHAT_MESSAGE_TYPE, @@ -128,7 +124,7 @@ export { configureGptModel, getGptModel, setGptModel, - getValidModels, getChatHistory, addInfoMessageToChatHistory, + getChatMessagesFromDTOResponse, }; diff --git a/frontend/src/service/defenceService.ts b/frontend/src/service/defenceService.ts index 3edf83d4f..460a8a8f6 100644 --- a/frontend/src/service/defenceService.ts +++ b/frontend/src/service/defenceService.ts @@ -1,8 +1,9 @@ +import { DEFAULT_DEFENCES } from '@src/Defences'; import { DEFENCE_ID, DefenceConfigItem, - Defence, DefenceResetResponse, + DefenceDTO, } from '@src/models/defence'; import { sendRequest } from './backendService'; @@ -13,7 +14,30 @@ async function getDefences(level: number) { const response = await sendRequest(`${PATH}status?level=${level}`, { method: 'GET', }); - return (await response.json()) as Defence[]; + const defenceDTOs = (await response.json()) as DefenceDTO[]; + return getDefencesFromDTOs(defenceDTOs); +} + +function getDefencesFromDTOs(defenceDTOs: DefenceDTO[]) { + return DEFAULT_DEFENCES.map((defence) => { + const defenceDTO = defenceDTOs.find( + (defenceDTO) => defence.id === defenceDTO.id + ); + return defenceDTO + ? { + ...defence, + isActive: defenceDTO.isActive, + config: defence.config.map((config) => { + const matchingConfigItemDTO = defenceDTO.config.find( + (configItemDTO) => config.id === configItemDTO.id + ); + return matchingConfigItemDTO + ? { ...config, value: matchingConfigItemDTO.value } + : config; + }), + } + : defence; + }); } async function toggleDefence( @@ -103,4 +127,5 @@ export { configureDefence, resetDefenceConfig, validateDefence, + getDefencesFromDTOs, }; diff --git a/frontend/src/service/healthService.ts b/frontend/src/service/healthService.ts deleted file mode 100644 index 52b37e713..000000000 --- a/frontend/src/service/healthService.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { sendRequest } from './backendService'; - -const PATH = 'health/'; - -async function healthCheck() { - const response = await sendRequest(PATH, { method: 'GET' }); - return response.status === 200; -} - -export { healthCheck }; diff --git a/frontend/src/service/index.ts b/frontend/src/service/index.ts index 5d611c740..eb03f0626 100644 --- a/frontend/src/service/index.ts +++ b/frontend/src/service/index.ts @@ -2,16 +2,14 @@ import * as chatService from './chatService'; import * as defenceService from './defenceService'; import * as documentService from './documentService'; import * as emailService from './emailService'; -import * as healthService from './healthService'; import * as levelService from './levelService'; -import * as systemRoleService from './systemRoleService'; +import * as startService from './startService'; export { chatService, defenceService, documentService, emailService, - healthService, levelService, - systemRoleService, + startService, }; diff --git a/frontend/src/service/startService.ts b/frontend/src/service/startService.ts new file mode 100644 index 000000000..d1315dbfc --- /dev/null +++ b/frontend/src/service/startService.ts @@ -0,0 +1,25 @@ +import { StartReponse } from '@src/models/combined'; + +import { sendRequest } from './backendService'; +import { getChatMessagesFromDTOResponse } from './chatService'; +import { getDefencesFromDTOs } from './defenceService'; + +const PATH = 'start/'; + +async function start(level: number) { + const response = await sendRequest(`${PATH}?level=${level}`, { + method: 'GET', + }); + const { availableModels, defences, emails, chatHistory, systemRoles } = + (await response.json()) as StartReponse; + + return { + emails, + history: getChatMessagesFromDTOResponse(chatHistory), + defences: getDefencesFromDTOs(defences), + availableModels, + systemRoles, + }; +} + +export { start }; diff --git a/frontend/src/service/systemRoleService.ts b/frontend/src/service/systemRoleService.ts deleted file mode 100644 index 4d501b397..000000000 --- a/frontend/src/service/systemRoleService.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { LevelSystemRole } from '@src/models/level'; - -import { sendRequest } from './backendService'; - -const PATH = 'systemRoles/'; - -// get the system roles for all levels -async function getSystemRoles(): Promise { - const response = await sendRequest(PATH, { method: 'GET' }); - return (await response.json()) as LevelSystemRole[]; -} - -export { getSystemRoles };