33from fastapi import FastAPI
44from fastapi .responses import JSONResponse
55from helpers import save_document
6- from request_models import CreateSessionRequest , PromptRequest , SummaryRequest , QuizRequest , FlashcardRequest
6+ from request_models import LoadDocumentRequest , PromptRequest , SummaryRequest , QuizRequest , FlashcardRequest
77from llm import StudyLLM
88from prometheus_fastapi_instrumentator import Instrumentator
99
1212logger = logging .getLogger (__name__ )
1313
1414
15- llm_instances : dict [ str , StudyLLM ] = {}
15+ llm_instance : StudyLLM = StudyLLM ()
1616
1717@asynccontextmanager
1818async def lifespan (_ ):
1919 yield
2020 # Shutdown: cleanup
21- for llm in llm_instances .values ():
22- llm .cleanup ()
21+ llm_instance .cleanup ()
2322
2423app = FastAPI (
2524 title = "tutor" ,
@@ -48,8 +47,8 @@ async def lifespan(_):
4847 ).instrument (app ).expose (app )
4948
5049
51- # llm_instances[" dummy"] = StudyLLM( "./documents/example/W07_Microservices_and_Scalable_Architectures.pdf ") # TODO: remove
52- # llm_instances["dummy2"] = StudyLLM("./documents/example/dummy_knowledge.txt ") # TODO: remove
50+ # StudyLLM(user_id=' dummy', doc_path= "./documents/example/dummy_knowledge.txt ") # TODO: remove
51+ # llm_instances["dummy2"] = StudyLLM(user_id='dummy', doc_path= "./documents/example/W07_Microservices_and_Scalable_Architectures.pdf ") # TODO: remove
5352
5453# Auxiliary Endpoints
5554@app .get ("/health" )
@@ -62,44 +61,34 @@ async def health_check():
6261
6362
6463# AI Tasks Endpoints
65- @app .post ("/session/load " )
66- async def load_session (data : CreateSessionRequest ):
64+ @app .post ("/document " )
65+ async def load_document (data : LoadDocumentRequest ):
6766 """
68- Create a new session with the LLM for a given document URL .
67+ Load a new document in the LLM instance .
6968 """
7069 try :
71- if data .session_id in llm_instances :
72- logger .info (f"Session { data .session_id } already exists" )
73- return {"message" : "Session already loaded." }
74-
75- logger .info (f"Creating new session { data .session_id } for document { data .document_name } " )
76- doc_name = f"{ data .session_id } _{ data .document_name } "
70+ logger .info (f"Loading new document { data .document_name } for user { data .user_id } " )
71+ doc_name = f"{ data .user_id } _{ data .document_name } "
7772 path = save_document (doc_name , data .document_base64 )
78- llm_instances [ data . session_id ] = StudyLLM ( path )
79- logger .info (f"Session { data . session_id } created successfully" )
80- return {"message" : "Session created successfully." }
73+ await llm_instance . load_document ( doc_name , path , data . user_id )
74+ logger .info (f"Document { doc_name } created successfully" )
75+ return {"message" : "Document loaded successfully." }
8176 except Exception as e :
82- error_msg = f"Failed to create session { data . session_id } : { str (e )} "
77+ error_msg = f"Failed to load document { doc_name } : { str (e )} "
8378 logger .error (error_msg )
8479 return {"error" : error_msg }
8580
86-
8781@app .post ("/chat" )
8882async def receive_prompt (data : PromptRequest ):
8983 """
9084 Receive a prompt and return a response from the LLM.
9185 """
9286 try :
93- if data .session_id not in llm_instances :
94- error_msg = f"Session { data .session_id } not found. Please ensure the document was processed successfully."
95- logger .error (error_msg )
96- return JSONResponse (status_code = 404 , content = {"response" : f"ERROR: { error_msg } " })
97-
98- logger .info (f"Processing chat request for session { data .session_id } " )
99- response = await llm_instances [data .session_id ].prompt (data .message )
87+ logger .info (f"Processing chat request for user { data .user_id } " )
88+ response = await llm_instance .prompt (data .message , data .user_id )
10089 return {"response" : response }
10190 except Exception as e :
102- error_msg = f"Chat error for session { data .session_id } : { str (e )} "
91+ error_msg = f"Chat error for user { data .user_id } : { str (e )} "
10392 logger .error (error_msg )
10493 return {"response" : f"ERROR: { error_msg } " }
10594
@@ -109,16 +98,11 @@ async def generate_summary(data: SummaryRequest):
10998 Receive a summary request and return a summary from the LLM.
11099 """
111100 try :
112- if data .session_id not in llm_instances :
113- error_msg = f"Session { data .session_id } not found. Please ensure the document was processed successfully."
114- logger .error (error_msg )
115- return {"response" : f"ERROR: { error_msg } " }
116-
117- logger .info (f"Generating summary for session { data .session_id } " )
118- response = await llm_instances [data .session_id ].summarize ()
101+ logger .info (f"Generating summary for user { data .user_id } , document { data .document_name } " )
102+ response = await llm_instance .summarize (data .document_name , data .user_id )
119103 return {"response" : response }
120104 except Exception as e :
121- error_msg = f"Summary generation error for session { data .session_id } : { str (e )} "
105+ error_msg = f"Summary generation error for user { data .user_id } : { str (e )} "
122106 logger .error (error_msg )
123107 return {"response" : f"ERROR: { error_msg } " }
124108
@@ -128,17 +112,12 @@ async def generate_flashcards(data: FlashcardRequest):
128112 Receive a flashcard request and return flashcard objects from the LLM.
129113 """
130114 try :
131- if data .session_id not in llm_instances :
132- error_msg = f"Session { data .session_id } not found. Please ensure the document was processed successfully."
133- logger .error (error_msg )
134- return {"response" : {"flashcards" : [], "error" : error_msg }}
135-
136- logger .info (f"Generating flashcards for session { data .session_id } " )
137- response = await llm_instances [data .session_id ].generate_flashcards ()
138- logger .info (f"Flashcards generated successfully for session { data .session_id } " )
115+ logger .info (f"Generating flashcards for user { data .user_id } , document { data .document_name } " )
116+ response = await llm_instance .generate_flashcards (data .document_name , data .user_id )
117+ logger .info (f"Flashcards generated successfully for user { data .user_id } " )
139118 return {"response" : response }
140119 except Exception as e :
141- error_msg = f"Flashcard generation error for session { data .session_id } : { str (e )} "
120+ error_msg = f"Flashcard generation error for user { data .user_id } : { str (e )} "
142121 logger .error (error_msg )
143122 return {"response" : {"flashcards" : [], "error" : error_msg }}
144123
@@ -148,44 +127,11 @@ async def generate_quiz(data: QuizRequest):
148127 Receive a quiz request and return a quiz object from the LLM.
149128 """
150129 try :
151- if data .session_id not in llm_instances :
152- error_msg = f"Session { data .session_id } not found. Please ensure the document was processed successfully."
153- logger .error (error_msg )
154- return {"response" : {"questions" : [], "error" : error_msg }}
155-
156- logger .info (f"Generating quiz for session { data .session_id } " )
157- response = await llm_instances [data .session_id ].generate_quiz ()
158- logger .info (f"Quiz generated successfully for session { data .session_id } " )
130+ logger .info (f"Generating quiz for user { data .user_id } , document { data .document_name } " )
131+ response = await llm_instance .generate_quiz (data .document_name , data .user_id )
132+ logger .info (f"Quiz generated successfully for user { data .user_id } " )
159133 return {"response" : response }
160134 except Exception as e :
161- error_msg = f"Quiz generation error for session { data .session_id } : { str (e )} "
135+ error_msg = f"Quiz generation error for user { data .user_id } : { str (e )} "
162136 logger .error (error_msg )
163137 return {"response" : {"questions" : [], "error" : error_msg }}
164-
165- @app .post ("/process" )
166- async def process_document (data : SummaryRequest ):
167- """Compatibility endpoint for Kotlin genai-service (/process).
168- It creates a session (if not present) and immediately returns QUEUED.
169- (Actual processing e.g. summary generation can be triggered asynchronously.)"""
170- try :
171- session_id = data .session_id or data .document_id
172- if session_id not in llm_instances :
173- logger .info (f"/process received – creating session { session_id } " )
174- # save document and create LLM instance
175- doc_name = f"{ session_id } _{ data .document_name or 'doc.pdf' } "
176- path = save_document (doc_name , data .document_base64 or "" )
177- llm_instances [session_id ] = StudyLLM (path )
178- return {
179- "requestId" : session_id ,
180- "status" : "QUEUED" ,
181- "message" : "Document queued for processing" ,
182- "estimatedTime" : None
183- }
184- except Exception as e :
185- logger .error (f"/process error: { str (e )} " )
186- return {
187- "requestId" : None ,
188- "status" : "FAILED" ,
189- "message" : f"Failed to process document: { str (e )} " ,
190- "estimatedTime" : None
191- }
0 commit comments