From 26d5d6d6a2cfa67b5844b8ec647240826bc40641 Mon Sep 17 00:00:00 2001 From: Ilango Date: Thu, 15 Feb 2024 15:13:47 +0530 Subject: [PATCH] Save feedback id to message and update feedback --- packages/server/src/Interface.ts | 2 +- .../src/database/entities/ChatMessage.ts | 8 ++- .../database/entities/ChatMessageFeedback.ts | 3 -- .../sqlite/1707213619308-AddFeedback.ts | 2 +- .../1707986407818-AddFeedbackToChatMessage.ts | 20 +++++++ .../src/database/migrations/sqlite/index.ts | 4 +- packages/server/src/index.ts | 52 +++++++++++++++---- 7 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 packages/server/src/database/migrations/sqlite/1707986407818-AddFeedbackToChatMessage.ts diff --git a/packages/server/src/Interface.ts b/packages/server/src/Interface.ts index aa5852b2..c705cf79 100644 --- a/packages/server/src/Interface.ts +++ b/packages/server/src/Interface.ts @@ -41,6 +41,7 @@ export interface IChatMessage { memoryType?: string sessionId?: string createdDate: Date + feedbackId?: string } export interface IChatMessageFeedback { @@ -48,7 +49,6 @@ export interface IChatMessageFeedback { content?: string chatflowid: string chatId: string - messageId: string rating: ChatMessageRatingType createdDate: Date } diff --git a/packages/server/src/database/entities/ChatMessage.ts b/packages/server/src/database/entities/ChatMessage.ts index f25f893c..55a1c0e5 100644 --- a/packages/server/src/database/entities/ChatMessage.ts +++ b/packages/server/src/database/entities/ChatMessage.ts @@ -1,7 +1,6 @@ /* eslint-disable */ -import { Entity, Column, CreateDateColumn, PrimaryGeneratedColumn, Index, OneToOne, JoinColumn } from 'typeorm' +import { Entity, Column, CreateDateColumn, PrimaryGeneratedColumn, Index } from 'typeorm' import { IChatMessage, MessageType } from '../../Interface' -import { ChatMessageFeedback } from './ChatMessageFeedback' @Entity() export class ChatMessage implements IChatMessage { @@ -42,7 +41,6 @@ export class ChatMessage implements IChatMessage { @CreateDateColumn() createdDate: Date - @OneToOne(() => ChatMessageFeedback) - @JoinColumn() - feedback?: ChatMessageFeedback + @Column({ nullable: true }) + feedbackId?: string } diff --git a/packages/server/src/database/entities/ChatMessageFeedback.ts b/packages/server/src/database/entities/ChatMessageFeedback.ts index 4011972d..972994f9 100644 --- a/packages/server/src/database/entities/ChatMessageFeedback.ts +++ b/packages/server/src/database/entities/ChatMessageFeedback.ts @@ -17,9 +17,6 @@ export class ChatMessageFeedback implements IChatMessageFeedback { @Column() chatId: string - @Column() - messageId: string - @Column() rating: ChatMessageRatingType diff --git a/packages/server/src/database/migrations/sqlite/1707213619308-AddFeedback.ts b/packages/server/src/database/migrations/sqlite/1707213619308-AddFeedback.ts index b240ec1b..29ac76bc 100644 --- a/packages/server/src/database/migrations/sqlite/1707213619308-AddFeedback.ts +++ b/packages/server/src/database/migrations/sqlite/1707213619308-AddFeedback.ts @@ -3,7 +3,7 @@ import { MigrationInterface, QueryRunner } from 'typeorm' export class AddFeedback1707213619308 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { await queryRunner.query( - `CREATE TABLE IF NOT EXISTS "chat_message_feedback" ("id" varchar PRIMARY KEY NOT NULL, "chatflowid" varchar NOT NULL, "content" text, "chatId" varchar NOT NULL, "messageId" varchar NOT NULL, "rating" varchar NOT NULL, "createdDate" datetime NOT NULL DEFAULT (datetime('now')));` + `CREATE TABLE IF NOT EXISTS "chat_message_feedback" ("id" varchar PRIMARY KEY NOT NULL, "chatflowid" varchar NOT NULL, "content" text, "chatId" varchar NOT NULL, "rating" varchar NOT NULL, "createdDate" datetime NOT NULL DEFAULT (datetime('now')));` ) } diff --git a/packages/server/src/database/migrations/sqlite/1707986407818-AddFeedbackToChatMessage.ts b/packages/server/src/database/migrations/sqlite/1707986407818-AddFeedbackToChatMessage.ts new file mode 100644 index 00000000..24af4ada --- /dev/null +++ b/packages/server/src/database/migrations/sqlite/1707986407818-AddFeedbackToChatMessage.ts @@ -0,0 +1,20 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class AddFeedbackToChatMessage1707986407818 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "temp_chat_message" ("id" varchar PRIMARY KEY NOT NULL, "role" varchar NOT NULL, "chatflowid" varchar NOT NULL, "content" text NOT NULL, "sourceDocuments" text, "usedTools" text, "fileAnnotations" text, "createdDate" datetime NOT NULL DEFAULT (datetime('now')), "chatType" VARCHAR NOT NULL DEFAULT 'INTERNAL', "chatId" VARCHAR NOT NULL, "memoryType" VARCHAR, "sessionId" VARCHAR, "feedbackId" varchar);` + ) + await queryRunner.query( + `INSERT INTO "temp_chat_message" ("id", "role", "chatflowid", "content", "sourceDocuments", "usedTools", "fileAnnotations", "createdDate", "chatType", "chatId", "memoryType", "sessionId") SELECT "id", "role", "chatflowid", "content", "sourceDocuments", "usedTools", "fileAnnotations", "createdDate", "chatType", "chatId", "memoryType", "sessionId" FROM "chat_message";` + ) + await queryRunner.query(`DROP TABLE "chat_message";`) + await queryRunner.query(`ALTER TABLE "temp_chat_message" RENAME TO "chat_message";`) + await queryRunner.query(`CREATE INDEX "IDX_e574527322272fd838f4f0f3d3" ON "chat_message" ("chatflowid") ;`) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE IF EXISTS "temp_chat_message";`) + await queryRunner.query(`ALTER TABLE "chat_message" DROP COLUMN "feedbackId";`) + } +} diff --git a/packages/server/src/database/migrations/sqlite/index.ts b/packages/server/src/database/migrations/sqlite/index.ts index 4e6dc72c..5a54a5cd 100644 --- a/packages/server/src/database/migrations/sqlite/index.ts +++ b/packages/server/src/database/migrations/sqlite/index.ts @@ -12,6 +12,7 @@ import { AddCategoryToChatFlow1699900910291 } from './1699900910291-AddCategoryT import { AddFileAnnotationsToChatMessage1700271021237 } from './1700271021237-AddFileAnnotationsToChatMessage' import { AddVariableEntity1699325775451 } from './1702200925471-AddVariableEntity' import { AddFeedback1707213619308 } from './1707213619308-AddFeedback' +import { AddFeedbackToChatMessage1707986407818 } from './1707986407818-AddFeedbackToChatMessage' export const sqliteMigrations = [ Init1693835579790, @@ -27,5 +28,6 @@ export const sqliteMigrations = [ AddCategoryToChatFlow1699900910291, AddFileAnnotationsToChatMessage1700271021237, AddVariableEntity1699325775451, - AddFeedback1707213619308 + AddFeedback1707213619308, + AddFeedbackToChatMessage1707986407818 ] diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index d63b82a9..331b4fd0 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -10,7 +10,7 @@ import logger from './utils/logger' import { expressRequestLogger } from './utils/logger' import { v4 as uuidv4 } from 'uuid' import OpenAI from 'openai' -import { Between, IsNull, FindOptionsWhere, createQueryBuilder } from 'typeorm' +import { Between, IsNull, FindOptionsWhere } from 'typeorm' import { IChatFlow, IncomingInput, @@ -606,18 +606,31 @@ export class App { // ---------------------------------------- // Chat Message Feedback // ---------------------------------------- - this.app.get('/api/v1/feedback/:id', async (req: Request, res: Response) => {}) + // Create new feedback this.app.post('/api/v1/feedback/:id', async (req: Request, res: Response) => { const body = req.body const results = await this.addChatMessageFeedback(body) return res.json(results) }) + // Update feedback this.app.put('/api/v1/feedback/:id', async (req: Request, res: Response) => { - const chatflowid = req.params.id const body = req.body - const results = await this.addChatMessageFeedback(body) + const chatMessageFeedback = await this.AppDataSource.getRepository(ChatMessageFeedback).findOneBy({ + id: req.params.id + }) + + if (!chatMessageFeedback) { + res.status(404).send(`Feedback ${req.params.id} not found`) + return + } + + const newChatMessageFeedback = new ChatMessageFeedback() + Object.assign(newChatMessageFeedback, body) + + this.AppDataSource.getRepository(ChatMessageFeedback).merge(chatMessageFeedback, newChatMessageFeedback) + const results = await this.AppDataSource.getRepository(ChatMessageFeedback).save(chatMessageFeedback) return res.json(results) }) @@ -1476,9 +1489,6 @@ export class App { }, order: { createdDate: sortOrder === 'DESC' ? 'DESC' : 'ASC' - }, - relations: { - feedback } }) } @@ -1495,18 +1505,40 @@ export class App { return await this.AppDataSource.getRepository(ChatMessage).save(chatmessage) } + async updateChatMessage(id: string, update: Partial) { + const chatMessage = await this.AppDataSource.getRepository(ChatMessage).findOneBy({ + id + }) + + if (!chatMessage) return + + const newChatMessage = new ChatMessage() + Object.assign(newChatMessage, update) + + this.AppDataSource.getRepository(ChatMessage).merge(chatMessage, newChatMessage) + return await this.AppDataSource.getRepository(ChatMessage).save(chatMessage) + } + /** - * Method that adds feedback for a chat message. + * Method that adds feedback for a chat message and updates the chat message with the feedback id. * @param {Partial} chatMessageFeedback */ - async addChatMessageFeedback(chatMessageFeedback: Partial): Promise { + async addChatMessageFeedback(chatMessageFeedback: Partial & { messageId: string }): Promise { + const messageId = chatMessageFeedback.messageId const newFeedback = new ChatMessageFeedback() Object.assign(newFeedback, chatMessageFeedback) const feedback = this.AppDataSource.getRepository(ChatMessageFeedback).create(newFeedback) - return await this.AppDataSource.getRepository(ChatMessageFeedback).save(feedback) + const results = await this.AppDataSource.getRepository(ChatMessageFeedback).save(feedback) + + // use the message id to update the chat message with feedback id + await this.updateChatMessage(messageId, { feedbackId: results.id }) + + return results } + async updateChatMessageFeedback(id: string, update: Partial) {} + async upsertVector(req: Request, res: Response, isInternal: boolean = false) { try { const chatflowid = req.params.id