feat: add chatbot module and service
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
import { Body, Controller, Post } from '@nestjs/common';
|
||||
import { ChatbotService } from './providers/chatbot.service';
|
||||
import { Public } from '../auth/decorators/public.decorator';
|
||||
|
||||
@Controller('chatbot')
|
||||
export class ChatbotController {
|
||||
constructor(
|
||||
/**
|
||||
* Inject Chatbot Service
|
||||
*/
|
||||
private readonly chatbotService: ChatbotService,
|
||||
) {}
|
||||
|
||||
@Post('chat')
|
||||
// TEMP:
|
||||
@Public()
|
||||
public async chat(@Body('message') message: string) {
|
||||
return this.chatbotService.chat(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ChatbotController } from './chatbot.controller';
|
||||
import { ChatbotService } from './providers/chatbot.service';
|
||||
|
||||
@Module({
|
||||
controllers: [ChatbotController],
|
||||
providers: [ChatbotService],
|
||||
})
|
||||
export class ChatbotModule {}
|
||||
@@ -0,0 +1,7 @@
|
||||
POST {{baseUrl}}/chatbot/chat
|
||||
Content-Type: application/json
|
||||
# Authorization: Bearer {{$global.accessToken}}
|
||||
|
||||
{
|
||||
"message": "چطوری بفهمم به HPV مبتلا هستم یا خیر؟"
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
@Injectable()
|
||||
export class ChatbotService {
|
||||
private openRouter: any;
|
||||
|
||||
constructor(
|
||||
/**
|
||||
* Inject Config Service
|
||||
*/
|
||||
private readonly configService: ConfigService,
|
||||
) {}
|
||||
|
||||
private async getOpenRouter() {
|
||||
if (!this.openRouter) {
|
||||
const { OpenRouter } = await import('@openrouter/sdk');
|
||||
|
||||
this.openRouter = new OpenRouter({
|
||||
apiKey: this.configService.get<string>('openRouter.apiKey'),
|
||||
});
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||
return this.openRouter;
|
||||
}
|
||||
|
||||
public async chat(message: string) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const openRouter = await this.getOpenRouter();
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
||||
const response = await openRouter.chat.send({
|
||||
chatRequest: {
|
||||
model: this.configService.get<string>('openRouter.model'),
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: `
|
||||
You are a medical AI assistant named Heala (Or in persian: هیلا).
|
||||
|
||||
Your role is to provide general medical information
|
||||
and health education.
|
||||
|
||||
- Do not provide definitive diagnoses.
|
||||
- Do not prescribe medications or dosages.
|
||||
- Do not fabricate medical information.
|
||||
- If symptoms may indicate an emergency, recommend
|
||||
seeking urgent medical care.
|
||||
- Clearly communicate uncertainty when appropriate.
|
||||
- Answer in Persian when the user asks in Persian.
|
||||
`.trim(),
|
||||
},
|
||||
{
|
||||
role: 'user',
|
||||
content: message,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
if (response instanceof ReadableStream) {
|
||||
throw new Error('Expected non-streaming response');
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
||||
const content = response.choices[0]?.message?.content;
|
||||
|
||||
if (typeof content !== 'string') {
|
||||
throw new Error('OpenRouter returned an unexpected response');
|
||||
}
|
||||
|
||||
return {
|
||||
message: content,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user