Skip to content

Commit

Permalink
Merge pull request #4 from fenrir-devops/feature-005/add-trial
Browse files Browse the repository at this point in the history
feat:add-trial-done
  • Loading branch information
dev-y8nh2 authored Aug 4, 2023
2 parents 8c68eea + b2f5cee commit 381846d
Show file tree
Hide file tree
Showing 15 changed files with 362 additions and 43 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# .env
.env

# compiled output
/dist
/node_modules
Expand Down
43 changes: 43 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/jwt": "^10.1.0",
"@nestjs/mongoose": "^10.0.1",
Expand Down
23 changes: 17 additions & 6 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,32 @@ import { UsersModule } from './users/users.module';
import { AuthMiddleware } from './common/auth.middleware';
import { BabblesController } from './babbles/babbles.controller';
import { JwtService } from '@nestjs/jwt';
import { ConfigModule, ConfigService } from '@nestjs/config';


import { TrialsModule } from './trials/trials.module';

@Module({
imports: [
MongooseModule.forRoot(
'',
),
ConfigModule.forRoot(),
MongooseModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (config: ConfigService) => {
console.log(config.get<string>('MONGO_DB_URI'));
return ({

uri: config.get<string>('MONGO_DB_URI'), // Loaded from .ENV
})}
}),
BabblesModule,
UsersModule,
TrialsModule
],
providers : [JwtService]
providers: [JwtService],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(AuthMiddleware).forRoutes(BabblesController);
consumer.apply(AuthMiddleware).forRoutes(BabblesController);
}

}
1 change: 1 addition & 0 deletions src/babbles/babbles.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export class BabblesController {
await this.babblesService.validateBabbles(id, user);

const data = await this.babblesService.getHistoryById(id);
data.messages.shift();
console.log(data);
return res.status(200).json(data);
}
Expand Down
2 changes: 1 addition & 1 deletion src/babbles/babbles.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class BabblesService {
messages: [
{
role: 'system',
content: `너는 ${createBabbleDto.personality} 역할이야. 답변은 말하듯 짧게 1~3 문장으로 해줘. 잘 부탁해.`,
content: `너는 ${createBabbleDto.personality} 역할이야. 답변은 말하듯 짧게 1~3 문장으로 해줘. 너무 길면 불편하거든. 잘 부탁해.`,
},
],
};
Expand Down
12 changes: 0 additions & 12 deletions src/babbles/interfaces/message.interface.ts

This file was deleted.

15 changes: 8 additions & 7 deletions src/common/openai.service.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import { Injectable } from '@nestjs/common';

import { ConfigService } from '@nestjs/config/dist';
import {
ChatCompletionRequestMessage,
ChatCompletionResponseMessage,
Configuration,
OpenAIApi,
} from 'openai';

const configuration = new Configuration({
organization: 'org-jPO32mgFLsFXUbX0VhM5CsXo',
apiKey: '',
});
const openai = new OpenAIApi(configuration);

@Injectable()
export class OpenAIService {
async createAIbabble(
messages?: ChatCompletionRequestMessage[] | any,
): Promise<ChatCompletionResponseMessage> {
const configuration = new Configuration({
organization: 'org-jPO32mgFLsFXUbX0VhM5CsXo',
apiKey: process.env.OPEN_AI_KEY,
});

const openai = new OpenAIApi(configuration);

const response = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: messages,
Expand Down
14 changes: 14 additions & 0 deletions src/trials/dto/create-trial.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { IsNotEmpty } from "class-validator";
import { ApiProperty } from '@nestjs/swagger';

export class CreateTrialDto {

@ApiProperty()
@IsNotEmpty()
readonly deviceId: string;

@ApiProperty()
@IsNotEmpty()
readonly personality : string;

}
8 changes: 8 additions & 0 deletions src/trials/dto/make-trial-message.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { IsNotEmpty } from "class-validator";
import { ApiProperty } from '@nestjs/swagger';

export class MakeTrialMessageDTO {
@IsNotEmpty()
@ApiProperty()
readonly content : string;
}
29 changes: 29 additions & 0 deletions src/trials/interfaces/trials.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import mongoose from 'mongoose';

class Message {
@Prop()
role : string;
@Prop()
content : string;
}

@Schema()
export class Trial {
@Prop({ default: new mongoose.Types.ObjectId })
_id: string;

@Prop()
talker: string;
@Prop()
created: Date;
@Prop()
modified: Date;
@Prop()
personality: string;

@Prop()
messages: Message[];
}

export const TrialSchema = SchemaFactory.createForClass(Trial);
103 changes: 103 additions & 0 deletions src/trials/trials.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { Body, Controller, Res, Req, Get, Post, Param } from '@nestjs/common';
import { TrialsService } from './trials.service';
import { CreateTrialDto } from './dto/create-trial.dto';
import { MakeTrialMessageDTO } from './dto/make-trial-message.dto';
import { OpenAIService } from 'src/common/openai.service';
import { Response } from 'express';

import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';

@Controller('api/trials')
@ApiTags('[체험판 관련]')
export class TrialsController {
constructor(
private readonly trialsService: TrialsService,
private readonly openaiService: OpenAIService,
) {}

@Post()
@ApiOperation({
summary: '체험판 생성',
description:
'부여된 성격으로 대화 상대를 설정 하여 방을 생성.(deviceId 필요)',
})
@ApiResponse({
status: 201,
description: '대화방 생성 성공시 대화방의 id = (deviceId) 가 반환.',
})
@ApiResponse({
status: 400,
description: '이미 체험판을 이용한적이 있다면 에러응답.',
})
async handleTrialRequest(
@Body() createTrialDto: CreateTrialDto,
@Res() res: Response,
) {
const created = await this.trialsService.create(createTrialDto);
return res
.status(201)
.json({ message: 'success', trialId: createTrialDto.deviceId });
}


@Get(':deviceId')
@ApiOperation({
summary: '체험판 기록 확인하기',
description: '특정 디바이스의 체험판 기록을 응답으로 반환.',
})
@ApiResponse({
status: 400,
description:
'체험판 신청한적이 없다면 에러 응답 반환.',
})
async handleTrialHistoryRequest(
@Res() res: Response,
@Param('deviceId') deviceId: string,
) {
await this.trialsService.validateTrials(deviceId);

const log = await this.trialsService.getHistoryByDeviceId(deviceId);
log.messages.shift();
return res.status(200).json(log);
}


@Post(':deviceId')
@ApiOperation({
summary: '체험판 대화하기',
description: '요청자의 메세지를 처리하여 AI의 메세지를 응답으로 반환.',
})
@ApiResponse({
status: 200,
description: '{role:string , content : string } 형태의 객체로 응답 반환',
})
@ApiResponse({
status: 400,
description:
'체험판 ID가 잘못되었거나, 이미 3번 이상 사용했을때 에러 응답 반환.',
})
async handleTrialConversationRequest(
@Res() res: Response,
@Param('deviceId') deviceId: string,
@Body() makeTrialMessageDto: MakeTrialMessageDTO,
) {
await this.trialsService.validateTrials(deviceId);

const updated = await this.trialsService.pushMessage(
deviceId,
'user',
makeTrialMessageDto.content,
);

// console.log(updated);
const ais = await this.openaiService.createAIbabble(
updated.messages.map((one) => ({ role: one.role, content: one.content })),
);

await this.trialsService.pushMessage(deviceId, 'assistant', ais.content);

return res.status(200).json(ais);
}


}
16 changes: 16 additions & 0 deletions src/trials/trials.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Module } from '@nestjs/common';
import { TrialsController } from './trials.controller';
import { TrialsService } from './trials.service';
import { OpenAIService } from 'src/common/openai.service';

import { MongooseModule } from '@nestjs/mongoose';
import { TrialSchema } from './interfaces/trials.interface';

@Module({
imports: [
MongooseModule.forFeature([{ name: 'Trial', schema: TrialSchema }]),
],
controllers: [TrialsController],
providers: [TrialsService, OpenAIService],
})
export class TrialsModule {}
Loading

0 comments on commit 381846d

Please sign in to comment.