Skip to content

Commit

Permalink
Phase switching (#122)
Browse files Browse the repository at this point in the history
* WIP: Phase rework

* Phase syncing between frontend and backend

* Better backend phase transitions
  • Loading branch information
gsproston-scottlogic authored Aug 11, 2023
1 parent 90397ce commit 5d2a1ed
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 273 deletions.
5 changes: 2 additions & 3 deletions backend/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const cors = require("cors");
const session = require("express-session");
const { setOpenAiApiKey } = require("./openai");
const { getInitialDefences } = require("./defence");
const { getPhases } = require("./phase");

dotenv.config();

Expand Down Expand Up @@ -61,8 +60,8 @@ app.use(function (req, res, next) {
if (!req.session.gptModel) {
req.session.gptModel = defaultModel;
}
if (!req.session.phases) {
req.session.phases = getPhases();
if (!req.session.numPhasesCompleted) {
req.session.numPhasesCompleted = 0;
}
next();
});
Expand Down
71 changes: 0 additions & 71 deletions backend/src/phase.js

This file was deleted.

54 changes: 20 additions & 34 deletions backend/src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ const {
setOpenAiApiKey,
setGptModel,
} = require("./openai");
const {
getCurrentPhase,
switchCurrentPhase,
getCompletedPhases,
setPhaseCompleted,
} = require("./phase");
const router = express.Router();

// Activate a defence
Expand Down Expand Up @@ -84,6 +78,11 @@ router.post("/openai/chat", async (req, res, next) => {
let transformedMessage = "";
// parse out the message
const message = req.body?.message;
const currentPhase = req.body?.currentPhase;

// TODO remove, this is just for demonstration purposes
console.log("Current phase " + currentPhase);

if (message) {
transformedMessage = message;
// see if this message triggers any defences
Expand Down Expand Up @@ -126,8 +125,21 @@ router.post("/openai/chat", async (req, res, next) => {
reply = "Missing message";
console.error(reply);
}

// TODO remove, this is just for demonstration purposes
let numPhasesCompleted = req.session.numPhasesCompleted;
if (numPhasesCompleted < 3 && currentPhase === numPhasesCompleted) {
numPhasesCompleted = currentPhase + 1;
req.session.numPhasesCompleted = numPhasesCompleted;
}

// construct response
const response = { reply, defenceInfo, transformedMessage };
const response = {
reply,
defenceInfo,
transformedMessage,
numPhasesCompleted,
};
// log and send the reply with defence info
console.log(response);
res.send(response);
Expand Down Expand Up @@ -174,34 +186,8 @@ router.get("/openai/model", (req, res, next) => {
res.send(req.session.gptModel);
});

router.post("/phase/current", (req, res, next) => {
const phase = req.body?.phase;
if (phase) {
req.session.phases = switchCurrentPhase(req.session, phase);
res.status(200).send("Phase set to " + req.session.phases);
} else {
res.status(400).send("Missing phase");
}
});

router.get("/phase/current", (req, res, next) => {
res.send(getCurrentPhase(req.session));
});

router.get("/phase/completed", (req, res, next) => {
res.send(getCompletedPhases(req.session));
});

router.post("/phase/completed", (req, res, next) => {
const phase = req.body?.phase;
if (phase) {
req.session.phases = setPhaseCompleted(req.session, phase);
res.send("Phase complete status set");
} else {
res.statusCode = 400;
res.send("Missing phase");
}
res.send(req.session.numPhasesCompleted.toString());
});

// Importing the router
module.exports = router;
22 changes: 20 additions & 2 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React, { useEffect } from "react";
import "./App.css";
import AttackBox from "./components/AttackBox/AttackBox";
import ChatBox from "./components/ChatBox/ChatBox";
Expand All @@ -10,19 +10,31 @@ import Header from "./components/Header";
import ModelSelectionBox from "./components/ModelSelectionBox/ModelSelectionBox";
import { useState } from "react";
import { EmailInfo } from "./models/email";
import { getCompletedPhases } from "./service/phaseService";

function App() {
const [defenceBoxKey, setDefenceBoxKey] = useState<number>(0);
const [emails, setEmails] = useState<EmailInfo[]>([]);
const [triggeredDefences, setTriggeredDefences] = useState<string[]>([]);

// start on sandbox mode
const [currentPhase, setCurrentPhase] = useState<number>(0);
const [numCompletedPhases, setNumCompletedPhases] = useState<number>(0);

const updateTriggeredDefences = (defenceDetails: string[]) => {
// set the new triggered defences
setTriggeredDefences(defenceDetails);
// update the key of the defence box to force a re-render
setDefenceBoxKey(defenceBoxKey + 1);
};

// called on mount
useEffect(() => {
getCompletedPhases().then((numCompletedPhases) => {
setNumCompletedPhases(numCompletedPhases);
});
}, []);

return (
<span id="main-area">
<div className="side-bar">
Expand All @@ -39,13 +51,19 @@ function App() {
<div id="centre-area">
<Header />
<ChatBox
currentPhase={currentPhase}
setNumCompletedPhases={setNumCompletedPhases}
setEmails={setEmails}
updateTriggeredDefences={updateTriggeredDefences}
/>
</div>
<div className="side-bar">
<div className="side-bar-header">phases</div>
<PhaseSelectionBox />
<PhaseSelectionBox
currentPhase={currentPhase}
numCompletedPhases={numCompletedPhases}
setCurrentPhase={setCurrentPhase}
/>
<div className="side-bar-header">sent emails</div>
<EmailBox emails={emails} />
</div>
Expand Down
74 changes: 29 additions & 45 deletions frontend/src/Phases.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,34 @@
import { Phase, PHASE_NAMES } from "./models/phase";

const DEFAULT_SANDBOX_PHASE: Phase = new Phase(
PHASE_NAMES.SANDBOX,
3,
"app sandbox. ask the model questions and try get sensitive information",
"preamble",
"path_to_documents",
false,
true
);

const PHASES: Phase[] = [
new Phase(
PHASE_NAMES.PHASE_0,
0,
"easy phase to see how to ask the model question and get answers",
"preamble",
"path_to_documents",
false,
false
),
new Phase(
PHASE_NAMES.PHASE_1,
1,
"harder prompt to try and trick the model into telling you the secret",
"preamble",
"path_to_documents",
false,
false
),
new Phase(
PHASE_NAMES.PHASE_2,
2,
"even harder and you can use any feature on the app to try and trick the model into telling you the secret",
"preamble",
"path_to_documents",
false,
false
),
DEFAULT_SANDBOX_PHASE,
{
id: PHASE_NAMES.PHASE_0,
name: "phase 0",
preamble: "preamble",
isComplete: false,
isCurrent: false,
},
{
id: PHASE_NAMES.PHASE_1,
name: "phase 1",
preamble: "preamble",
isComplete: false,
isCurrent: false,
},
{
id: PHASE_NAMES.PHASE_2,
name: "phase 2",
preamble: "preamble",
isComplete: false,
isCurrent: false,
},
{
id: PHASE_NAMES.SANDBOX,
name: "sandbox",
preamble: "preamble",
isComplete: false,
isCurrent: false,
},
];

function getPhaseByName(phaseName: string): Phase {
return (
PHASES.find((phase) => phase.name === phaseName) || DEFAULT_SANDBOX_PHASE
);
}

export { PHASES, getPhaseByName };
export { PHASES };
7 changes: 6 additions & 1 deletion frontend/src/components/ChatBox/ChatBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ import { EmailInfo } from "../../models/email";
function ChatBox(
this: any,
{
currentPhase,
setNumCompletedPhases,
setEmails,
updateTriggeredDefences,
}: {
currentPhase: number;
setNumCompletedPhases: (numCompletedPhases: number) => void;
setEmails: (emails: EmailInfo[]) => void;
updateTriggeredDefences: (defences: string[]) => void;
}
Expand Down Expand Up @@ -52,7 +56,8 @@ function ChatBox(
// clear the input
event.currentTarget.value = "";

const response: ChatResponse = await sendMessage(message);
const response: ChatResponse = await sendMessage(message, currentPhase);
setNumCompletedPhases(response.numPhasesCompleted);
const transformedMessage = response.transformedMessage;
const isTransformed = transformedMessage !== message;
// add the transformed message to the chat box if it is different from the original message
Expand Down
Loading

0 comments on commit 5d2a1ed

Please sign in to comment.