Skip to content

Commit

Permalink
Merge pull request #5 from ls1intum/only-send-last-five-messages
Browse files Browse the repository at this point in the history
Disable sending when answer is generating, try to get new token if re…
  • Loading branch information
ninori9 authored Nov 5, 2024
2 parents 3871b35 + 29ed147 commit 99a8357
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 16 deletions.
3 changes: 3 additions & 0 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,8 @@
}
}
}
},
"cli": {
"analytics": false
}
}
13 changes: 8 additions & 5 deletions src/app/chat/chat.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ <h2>CIT Chatbot</h2>
</div>

<div class="study-program-dropdown">
<label for="studyProgramSelect" class="dropdown-label">Select Study Program:</label>
<label for="studyProgramSelect" class="dropdown-label">{{ dropdownLabel }}</label>
<ng-select class="select" [items]="studyPrograms" bindLabel="label" bindValue="value"
[formControl]="studyProgramControl" placeholder="Select your study program">
</ng-select>
Expand Down Expand Up @@ -45,10 +45,13 @@ <h2>CIT Chatbot</h2>
(keydown)="onKeyDown($event)"
[placeholder]="placeholderText"
rows="1"></textarea>
<button (click)="sendMessage()">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
<path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
</svg>
<button
(click)="sendMessage()"
[disabled]="disableSending"
[ngClass]="{ 'disabled': disableSending }">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
<path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
</svg>
</button>
</div>
</div>
6 changes: 6 additions & 0 deletions src/app/chat/chat.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ $logo-size: 40px;
&:hover {
background-color: $primary-color;
}

&.disabled {
background-color: $border-color;
color: #aaa;
cursor: not-allowed;
}

svg {
fill: white;
Expand Down
22 changes: 16 additions & 6 deletions src/app/chat/chat.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export const MESSAGES = {
If you'd like program-specific advice, please select your study program from the dropdown menu at the top, and I'll provide you with the most relevant information.
`,
errorMessage: `Sorry, but I am currently unable to answer your questions. Please try again at a later time.`,
placeholder: `Type your message here...`
placeholder: `Type your message here...`,
dropdownLabel: `Select Study Program:`
},
de: {
welcomeMessage: `
Expand All @@ -32,7 +33,8 @@ export const MESSAGES = {
Wenn Sie studiengangspezifische Ratschläge benötigen, wählen Sie bitte Ihr Studienprogramm aus dem Dropdown-Menü oben, und ich werde Ihnen die relevantesten Informationen bereitstellen.
`,
errorMessage: `Entschuldigung, aber ich kann Ihre Fragen derzeit nicht beantworten. Bitte versuchen Sie es später erneut.`,
placeholder: `Geben Sie hier Ihre Nachricht ein...`
placeholder: `Geben Sie hier Ihre Nachricht ein...`,
dropdownLabel: `Studiengang auswählen:`
}
};

Expand All @@ -54,13 +56,15 @@ export class ChatComponent implements OnInit, AfterViewChecked {
placeholderText: string = '';
welcomeMessage: string = '';
errorMessage: string = '';
dropdownLabel: string = '';

// FormControl for the study program dropdown
studyProgramControl = new FormControl('');
studyPrograms = studyPrograms;

language: 'en' | 'de' = 'en'; // Default language is English
private needScrollToBottom: boolean = false;
disableSending: boolean = false;

constructor(private chatbotService: ChatbotService, private route: ActivatedRoute) { }

Expand All @@ -84,6 +88,7 @@ export class ChatComponent implements OnInit, AfterViewChecked {
this.welcomeMessage = MESSAGES[this.language].welcomeMessage;
this.errorMessage = MESSAGES[this.language].errorMessage;
this.placeholderText = MESSAGES[this.language].placeholder;
this.dropdownLabel = MESSAGES[this.language].dropdownLabel;
}

onKeyDown(event: KeyboardEvent): void {
Expand All @@ -92,7 +97,8 @@ export class ChatComponent implements OnInit, AfterViewChecked {
!event.shiftKey &&
!event.ctrlKey &&
!event.altKey &&
!event.metaKey
!event.metaKey &&
!this.disableSending
) {
event.preventDefault(); // Prevents the default action of adding a newline
this.sendMessage();
Expand All @@ -102,6 +108,7 @@ export class ChatComponent implements OnInit, AfterViewChecked {
sendMessage() {
if (this.userMessage.trim()) {
// Add the user's message to the messages array
this.disableSending = true;
this.messages.push({ message: this.userMessage, type: 'user' });
this.userMessage = '';
this.resetTextAreaHeight();
Expand All @@ -113,9 +120,10 @@ export class ChatComponent implements OnInit, AfterViewChecked {
const loadingMessage: ChatMessage = { message: '', type: 'loading' };
this.messages.push(loadingMessage);
this.needScrollToBottom = true;

// Prepare the messages to send to the bot, excluding the loading message
const messagesToSend = this.messages.filter(msg => msg.type !== 'loading');

const nonLoadingMessages = this.messages.filter(msg => msg.type !== 'loading');
// Keep only the last 5 messages, if there are 5 or more
const messagesToSend = nonLoadingMessages.slice(-5);

// Call the bot service with the filtered messages
this.chatbotService.getBotResponse(messagesToSend, selectedProgram).subscribe({
Expand All @@ -126,6 +134,7 @@ export class ChatComponent implements OnInit, AfterViewChecked {
const formattedResponse = this.formatResponseText(response.answer);
this.messages.push({ message: formattedResponse, type: 'system' });
this.needScrollToBottom = true;
this.disableSending = false;
},
error: (error) => {
console.error('Error fetching response:', error);
Expand All @@ -137,6 +146,7 @@ export class ChatComponent implements OnInit, AfterViewChecked {
type: 'system'
});
this.needScrollToBottom = true;
this.disableSending = false;
}
});
}
Expand Down
48 changes: 43 additions & 5 deletions src/app/services/chatbot.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ChatMessage } from '../chat/chat.component';
import { Observable, switchMap } from 'rxjs';
import { catchError, Observable, switchMap, throwError } from 'rxjs';
import { environment } from '../../environments/environment';
import { AuthService } from './auth.service';

Expand All @@ -22,14 +22,52 @@ export class ChatbotService {

getBotResponse(chatHistory: ChatMessage[], study_program: string): Observable<any> {
const token = this.authService.getToken();

const makeRequest = (authToken: string): Observable<any> => {
return this.sendBotRequest(authToken, chatHistory, study_program);
};

if (token) {
return this.sendBotRequest(token, chatHistory, study_program);
return makeRequest(token).pipe(
catchError((error: HttpErrorResponse) => {
if (error.status === 401 || error.status === 403) {
// Token might have expired, try to re-authenticate
return this.authService.login().pipe(
switchMap(() => {
const newToken = this.authService.getToken();
if (newToken) {
return makeRequest(newToken);
} else {
// Login failed to return a token
return throwError(() => new Error('Failed to obtain new token after re-authentication.'));
}
}),
catchError(loginError => {
// Handle login failure
return throwError(() => loginError);
})
);
} else {
// Other errors
return throwError(() => error);
}
})
);
} else {
// Login if no token is stored, then proceed with the bot request
// No token available, attempt to login
return this.authService.login().pipe(
switchMap(() => {
const newToken = this.authService.getToken();
return this.sendBotRequest(newToken, chatHistory, study_program);
if (newToken) {
return makeRequest(newToken);
} else {
// Login failed to return a token
return throwError(() => new Error('Failed to obtain token after login.'));
}
}),
catchError(loginError => {
// Handle login failure
return throwError(() => loginError);
})
);
}
Expand Down

0 comments on commit 99a8357

Please sign in to comment.