File size: 4,300 Bytes
6534ea1 8f13b2c 6534ea1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { v4 as uuidv4 } from 'uuid';
export interface ChatMessage {
id?: number;
text: string;
sender: 'user' | 'bot';
timestamp: Date;
isTyping?: boolean;
rawData?: any;
}
export interface SearchResponse {
success: boolean;
matched_question?: string;
answer?: string;
sno?: number;
audio_url?: string;
video_url?: string;
story_url?: string;
detail_url?: string;
example_url?: string;
confidence_score?: number;
user_question?: string;
message?: string;
suggestion?: string;
sample_questions?: string[];
total_questions_available?: number;
matching_method?: string;
is_follow_up?: boolean;
enhanced_question?: string;
scenario?: string;
context_info?: {
current_topic: string | null;
current_intent: string | null;
has_context: boolean;
history_length: number;
};
}
export interface Question {
sno: number;
question: string;
}
@Injectable({
providedIn: 'root'
})
export class ChatService {
private readonly apiBase =
location.hostname.endsWith('hf.space')
? 'https://pykara-py-learn-backend.hf.space/staticchat'
: 'http://localhost:5000/staticchat';
// =====================================================
// Static user_id: generated once per browser session.
// Persists across page navigations within the same tab,
// but resets when the tab/browser is closed.
//
// Options:
// sessionStorage — resets when tab closes (recommended)
// localStorage — persists even after browser restart
// =====================================================
private userId: string;
constructor(private http: HttpClient) {
// Try to restore existing session ID
const stored = sessionStorage.getItem('chat_user_id');
if (stored) {
this.userId = stored;
} else {
// Generate a new one for this session
this.userId = uuidv4();
sessionStorage.setItem('chat_user_id', this.userId);
}
console.log('Chat session user_id:', this.userId);
}
/**
* Get the current user ID (useful for context endpoints)
*/
getUserId(): string {
return this.userId;
}
/**
* Reset the session — clears context on backend and generates a new user_id
*/
resetSession(): Observable<{ success: boolean; message: string }> {
const oldUserId = this.userId;
// Generate new user_id
this.userId = uuidv4();
sessionStorage.setItem('chat_user_id', this.userId);
console.log('Session reset. New user_id:', this.userId);
// Clear old context on the backend
return this.http.post<{ success: boolean; message: string }>(
`${this.apiBase}/context/${oldUserId}/clear`, {}
);
}
/**
* Search — sends user_id with every request for context carry-forward
*/
searchQuestion(question: string): Observable<SearchResponse> {
return this.http.post<SearchResponse>(
`${this.apiBase}/search`,
{
question,
user_id: this.userId // <-- This is the key fix
}
);
}
/**
* Get all questions for reference / autocomplete
*/
getAllQuestions(): Observable<{ success: boolean; questions: Question[]; count: number }> {
return this.http.get<{ success: boolean; questions: Question[]; count: number }>(
`${this.apiBase}/questions`
);
}
/**
* Get random suggestions
*/
getRandomSuggestions(count: number = 5): Observable<{ success: boolean; suggestions: string[] }> {
return this.http.get<{ success: boolean; suggestions: string[] }>(
`${this.apiBase}/suggestions`,
{ params: { count: count.toString() } }
);
}
/**
* Get context-aware follow-up suggestions based on conversation history
*/
getContextSuggestions(): Observable<{ success: boolean; suggestions: string[]; current_topic: string | null }> {
return this.http.get<{ success: boolean; suggestions: string[]; current_topic: string | null }>(
`${this.apiBase}/context/suggestions/${this.userId}`
);
}
/**
* Get current conversation context (for debugging or UI display)
*/
getContext(): Observable<any> {
return this.http.get(`${this.apiBase}/context/${this.userId}`);
}
}
|