|
|
import os |
|
|
from openai import OpenAI |
|
|
from pydantic import BaseModel, Field |
|
|
from typing import List, Optional, Any |
|
|
from app.schema.models import QuizOutput, QuizQuestion |
|
|
from app.config import settings |
|
|
from openai import AsyncOpenAI |
|
|
from typing import List |
|
|
|
|
|
client = AsyncOpenAI( |
|
|
base_url="https://api.groq.com/openai/v1", |
|
|
api_key=settings.GROQ_API_KEY |
|
|
) |
|
|
|
|
|
async def call_llm(prompt:str): |
|
|
try: |
|
|
response = await client.chat.completions.create( |
|
|
|
|
|
model="openai/gpt-oss-120b", |
|
|
messages=[ |
|
|
{"role": "user", "content": prompt} |
|
|
], |
|
|
|
|
|
response_format={"type": "json_object"}, |
|
|
temperature=0.4, |
|
|
) |
|
|
|
|
|
json_string = response.choices[0].message.content |
|
|
|
|
|
import json |
|
|
quiz_data = json.loads(json_string) |
|
|
wrapped_data = {"quiz": quiz_data} |
|
|
return QuizOutput.model_validate(wrapped_data) |
|
|
|
|
|
except Exception as e: |
|
|
print(f"Error calling LiteLLM/Gemini: {e}") |
|
|
raise e |
|
|
|
|
|
|
|
|
async def stream_chat(messages: List[dict], context: str, retrieved_docs: str | None): |
|
|
system_instruction = { |
|
|
"role": "system", |
|
|
"content": "You are a helpful AI assistant. Answer the user's question based on the provided context and retrieved documents." |
|
|
} |
|
|
|
|
|
conversation_history = [msg.copy() for msg in messages] |
|
|
|
|
|
if conversation_history and conversation_history[-1]['role'] == 'user': |
|
|
last_user_msg = conversation_history[-1] |
|
|
original_question = last_user_msg['content'] |
|
|
|
|
|
|
|
|
augmented_content = "" |
|
|
|
|
|
|
|
|
if context: |
|
|
augmented_content += ( |
|
|
f"Here is the context/notes you must use:\n" |
|
|
f"---------------------\n" |
|
|
f"{context}\n" |
|
|
f"---------------------\n\n" |
|
|
) |
|
|
|
|
|
|
|
|
if retrieved_docs: |
|
|
augmented_content += ( |
|
|
f"Here is background information/retrieved documents:\n" |
|
|
f"---------------------\n" |
|
|
f"{retrieved_docs}\n" |
|
|
f"---------------------\n\n" |
|
|
) |
|
|
|
|
|
|
|
|
augmented_content += f"User Question: {original_question}" |
|
|
|
|
|
|
|
|
last_user_msg['content'] = augmented_content |
|
|
|
|
|
else: |
|
|
|
|
|
|
|
|
combined_context = f"{context}\n\n{retrieved_docs or ''}" |
|
|
conversation_history.append({ |
|
|
"role": "user", |
|
|
"content": f"Context:\n{combined_context}\n\nPlease analyze this." |
|
|
}) |
|
|
|
|
|
|
|
|
full_history = [system_instruction] + conversation_history |
|
|
|
|
|
try: |
|
|
|
|
|
stream = await client.chat.completions.create( |
|
|
model="openai/gpt-oss-120b", |
|
|
messages=full_history, |
|
|
temperature=0.7, |
|
|
stream=True |
|
|
) |
|
|
|
|
|
async for chunk in stream: |
|
|
if chunk.choices[0].delta.content: |
|
|
yield chunk.choices[0].delta.content |
|
|
|
|
|
except Exception as e: |
|
|
print(f"Error in chat stream: {e}") |
|
|
yield f"Error: {str(e)}" |