backend / app /services /guess_service.py
bastienp's picture
feat(security): add an API-Key Mechanism
d60934b
raw
history blame
2.75 kB
import os
from langchain_mistralai import ChatMistralAI
from langchain_core.prompts import PromptTemplate
from pydantic import BaseModel, Field
from app.models.session import Message
from app.core.logging import LoggerMixin
from app.prompts import GUESSING_PROMPT
MISTRAL_API_KEY = os.getenv("MISTRAL_API_KEY")
class GuessResponse(BaseModel):
guess: str = Field(description="A one-word guess for the password related theme")
thoughts: str = Field(
description="Thoughts spoken out loud leading to the password guess"
)
class GuessingService(LoggerMixin):
def __init__(self: "GuessingService") -> None:
self.logger.info("Initializing GuessingService")
prompt = PromptTemplate.from_template(GUESSING_PROMPT)
llm = (
ChatMistralAI(
model_name="mistral-large-latest",
temperature=1,
)
.with_structured_output(schema=GuessResponse)
.with_retry(stop_after_attempt=3)
)
self.chain = prompt | llm
self.logger.info("GuessingService initialized with Mistral LLM")
def filter_password(self: "GuessingService", indication: str, password: str) -> str:
filtered = indication.replace(password, "*******")
self.logger.debug(f"Filtered password from indication | original_length={len(indication)} | filtered_length={len(filtered)}")
return filtered
def generate(
self: "GuessingService",
previous_guesses: list[str],
theme: str,
previous_indications: list[Message],
current_indication: str,
password: str,
) -> GuessResponse:
self.logger.info(f"Generating guess | theme={theme} | num_previous_guesses={len(previous_guesses)} | num_previous_indications={len(previous_indications)}")
previous_indications = [message.content for message in previous_indications]
self.logger.debug(f"Processing previous indications | count={len(previous_indications)}")
current_indication = self.filter_password(current_indication, password)
try:
response = self.chain.invoke(
{
"previous_guesses": previous_guesses[:3],
"theme": theme,
"previous_indications": previous_indications[:5],
"current_indication": current_indication,
}
)
self.logger.info(f"Generated guess successfully | guess={response.guess} | thoughts_length={len(response.thoughts)}")
return response
except Exception as e:
self.logger.error(f"Failed to generate guess | error={str(e)} | theme={theme}")
raise