Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

810: Session vs non-session routes #811

Merged
merged 5 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Always use LF for line endings
* text eol=lf
# Apart from font files
# Apart from font files and images
*.[ot]tf binary
*.png -text
1 change: 1 addition & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
OPENAI_API_KEY=YOUR_API_KEY
SESSION_SECRET=YOUR_SESSION_SECRET
CORS_ALLOW_ORIGIN=http://localhost:5173
2 changes: 1 addition & 1 deletion backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ RUN npm ci
COPY . .
EXPOSE 3001
RUN npm run build
CMD ["node", "--import=tsx/esm", "./build/server.js"]
CMD ["node", "--import=tsx", "./src/server.ts"]
4 changes: 3 additions & 1 deletion backend/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
services:
prompt-injection-api:
environment:
NODE_ENV: development
NODE_ENV: ${NODE_ENV:-development}
OPENAI_API_KEY: ${OPENAI_API_KEY}
SESSION_SECRET: ${SESSION_SECRET}
CORS_ALLOW_ORIGIN: '${CORS_ALLOW_ORIGIN:-*}'
PORT: 3001
build: .
image: 'scottlogic/prompt-injection-api'
Expand Down
28 changes: 3 additions & 25 deletions backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"type": "module",
"scripts": {
"build": "tsc",
"build": "tsc --noEmit",
"dev": "tsx watch -r dotenv/config src/server.ts",
"start": "tsx -r dotenv/config src/server.ts",
"docker:start": "docker compose up -d",
Expand All @@ -23,8 +23,7 @@
"memorystore": "^1.6.7",
"openai": "^4.19.0",
"openai-chat-tokens": "^0.2.8",
"pdf-parse": "^1.1.1",
"react": "^18.2.0"
chriswilty marked this conversation as resolved.
Show resolved Hide resolved
"pdf-parse": "^1.1.1"
},
"devDependencies": {
"@jest/globals": "^29.7.0",
Expand Down
80 changes: 11 additions & 69 deletions backend/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,74 +1,16 @@
import cors from 'cors';
import dotenv from 'dotenv';
import express from 'express';
import session from 'express-session';
import memoryStoreFactory from 'memorystore';
import { fileURLToPath } from 'node:url';

import { importMetaUrl } from './importMetaUtils';
import { ChatModel, defaultChatModel } from './models/chat';
import { LevelState, getInitialLevelStates } from './models/level';
import { router } from './router';
import nonSessionRoutes from './nonSessionRoutes';
import sessionRoutes from './sessionRoutes';

dotenv.config();

declare module 'express-session' {
chriswilty marked this conversation as resolved.
Show resolved Hide resolved
interface Session {
initialised: boolean;
chatModel: ChatModel;
levelState: LevelState[];
}
}

const app = express();
const isProd = app.get('env') === 'production';

// for parsing application/json
app.use(express.json());

// use session storage - currently in-memory, but in future use Redis in prod builds
const maxAge = 60 * 60 * 1000 * (isProd ? 1 : 8); //1 hour in prod, 8hrs in dev
const sessionOpts: session.SessionOptions = {
store: new (memoryStoreFactory(session))({
checkPeriod: maxAge,
}),
secret: process.env.SESSION_SECRET ?? 'secret',
name: 'prompt-injection.sid',
resave: false,
saveUninitialized: true,
cookie: {
secure: isProd,
maxAge,
},
};

app.use(session(sessionOpts));

app.use(
cors({
credentials: true,
origin: true,
})
);

app.use((req, _res, next) => {
// initialise session variables first time
if (!req.session.initialised) {
req.session.chatModel = defaultChatModel;
req.session.levelState = getInitialLevelStates();
req.session.initialised = true;
}
next();
});

app.use('/', router);

// serve the documents folder
app.use(
'/documents',
express.static(
fileURLToPath(new URL('../resources/documents', importMetaUrl()))
export default express()
.use(express.json())
.use(
cors({
origin: process.env.CORS_ALLOW_ORIGIN,
credentials: true,
})
)
);

export default app;
.use('/', nonSessionRoutes)
.use('/', sessionRoutes);
3 changes: 2 additions & 1 deletion backend/src/document.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as fs from 'fs';
import { CSVLoader } from 'langchain/document_loaders/fs/csv';
import { DirectoryLoader } from 'langchain/document_loaders/fs/directory';
import { PDFLoader } from 'langchain/document_loaders/fs/pdf';
import { TextLoader } from 'langchain/document_loaders/fs/text';
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
import * as fs from 'node:fs';

import { DocumentMeta } from './models/document';
import { LEVEL_NAMES } from './models/level';
Expand All @@ -28,6 +28,7 @@ async function getDocuments(filePath: string) {
'.csv': (path: string) => new CSVLoader(path),
});
const docs = await loader.load();
console.debug(`${docs.length} documents found`);

Copy link
Member Author

@chriswilty chriswilty Feb 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the line that exposed we weren't stubbing the loader to return anything. So I simply added that in my test changes. I'm happy for this line to be removed if you wish, it's not all that important any longer.

// split the documents into chunks
const textSplitter = new RecursiveCharacterTextSplitter({
Expand Down
5 changes: 3 additions & 2 deletions backend/src/langchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ import {

// store vectorised documents for each level as array
const vectorisedDocuments = (() => {
let docs: DocumentsVector[] = [];
const docs: DocumentsVector[] = [];
return {
get: () => docs,
set: (newDocs: DocumentsVector[]) => {
docs = newDocs;
while (docs.length > 0) docs.pop();
docs.push(...newDocs);
chriswilty marked this conversation as resolved.
Show resolved Hide resolved
},
};
})();
Expand Down
13 changes: 4 additions & 9 deletions backend/src/models/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,21 +149,16 @@ export type {
ChatDefenceReport,
ChatGptReply,
ChatMalicious,
ChatModel,
ChatModelConfiguration,
chriswilty marked this conversation as resolved.
Show resolved Hide resolved
ChatResponse,
LevelHandlerResponse,
ChatHttpResponse,
ChatHistoryMessage,
SingleDefenceReport,
TransformedChatMessage,
FunctionCallResponse,
ToolCallResponse,
MessageTransformation,
};
export {
CHAT_MODELS,
CHAT_MESSAGE_TYPE,
MODEL_CONFIG,
ChatModel,
ChatModelConfiguration,
defaultChatModel,
SingleDefenceReport,
};
export { CHAT_MODELS, CHAT_MESSAGE_TYPE, MODEL_CONFIG, defaultChatModel };
21 changes: 21 additions & 0 deletions backend/src/nonSessionRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import express from 'express';
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();

router.use(
'/documents',
express.static(
fileURLToPath(new URL('../resources/documents', importMetaUrl()))
)
);
router.get('/documents', handleGetDocuments);
router.get('/health', handleHealthCheck);
router.get('/systemRoles', handleGetSystemRoles);
chriswilty marked this conversation as resolved.
Show resolved Hide resolved

export default router;
2 changes: 1 addition & 1 deletion backend/src/openai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const getOpenAIKey = (() => {
openAIKey = process.env.OPENAI_API_KEY;
if (!openAIKey) {
throw new Error(
'OpenAI API key not found in environment vars - cannot continue!'
'OPENAI_API_KEY not found in environment vars, cannot continue!'
);
}
}
Expand Down
68 changes: 0 additions & 68 deletions backend/src/router.ts

This file was deleted.

Loading
Loading