Spaces:
Sleeping
Sleeping
File size: 3,876 Bytes
01543cd f09f2a0 333cede 01543cd e866313 333cede 01543cd 333cede 6e2e53b d604f12 333cede 28408e1 6e2e53b 333cede 6e2e53b 01543cd 6e2e53b df0f53d 6e2e53b 333cede 01543cd df0f53d 01543cd 333cede 28408e1 333cede d641174 6e2e53b 725d55d 6e2e53b 333cede 01543cd 333cede 8555bb7 01543cd 8555bb7 | 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 | """Pydantic models for API requests and responses."""
from dataclasses import dataclass
from typing import Optional
from pydantic import BaseModel, Field, ConfigDict
class QuestionInput(BaseModel):
"""Input model for a user question."""
question: str = Field(..., min_length=1, max_length=500, description="Free-text question")
similarity_threshold: Optional[float] = Field(
None,
ge=0.0,
le=1.0,
description="Desired cosine similarity threshold between 0.0 and 1.0.",
)
top_k: Optional[int] = None
cross_encodeur_gap_threshold: Optional[float] = None
cross_encodeur_confidence_threshold: Optional[float] = None
model_config = ConfigDict(
json_schema_extra={
"example": {
"question": "Comment je deviens membre ?",
"threshold": 0.85
}
}
)
@dataclass(slots=True)
class SemanticSearchCandidate:
"""Candidate produced by semantic search."""
formulation: str
theme: str
response: str
similarity_score: float
cross_encoder_logit: float | None = None
cross_encoder_score: float | None = None
class AnswerOutput(BaseModel):
"""Output model for a FAQ answer."""
question: str = Field(..., description="User question")
formulation: str = Field(..., description="FAQ formulation matched in the knowledge base")
answer: str = Field(..., description="Answer found in the FAQ knowledge base")
theme: str = Field(..., description="Answer theme or category")
similarity_score: float = Field(..., ge=0.0, le=1.0, description="Cosine similarity score in [0, 1]")
cross_encoder_logit: Optional[float] = Field(None, description="Cross-encoder logit score")
cross_encoder_score: Optional[float] = Field(None, description="Cross-encoder score")
confidence: bool = Field(..., description="True if the score meets the confidence threshold, otherwise False")
list_candidates: Optional[list[SemanticSearchCandidate]] = Field(None, description="List of semantic search candidates")
model_config = ConfigDict(
json_schema_extra={
"example": {
"question": "Comment je deviens membre ?",
"formulation": "Comment devenir membre de GOT ?",
"answer": "Tu peux soit 'tinscrire, soit commencer ta candidature depuis le bouton « Inscription » du site. Tu renseigneras ton profil, tes compétences et les domaines qui t’intéressent afin que l’équipe puisse étudier ta candidature.",
"theme": "comment_rejoindre_guild_open_tech",
"similarity_score": 0.889,
"cross_encoder_logit": 2.5,
"cross_encoder_score": 0.95,
"confidence": True,
"list_candidates": []
}
}
)
class HealthResponse(BaseModel):
"""Health-check response model."""
status: str = Field(..., description="Service status")
faq_count: int = Field(..., description="Number of FAQ entries in the knowledge base")
model_config = ConfigDict(
json_schema_extra={
"example": {
"status": "ok",
"faq_count": 3
}
}
)
class ConfigResponse(BaseModel):
"""Configuration response model."""
embeddings_model_name: str = Field(..., description="Name of the embedding model used")
cross_encoder_model_name: str = Field(..., description="Name of the cross-encoder model used")
model_config = ConfigDict(
json_schema_extra={
"example": {
"embeddings_model_name": "intfloat/multilingual-e5-small",
"cross_encoder_model_name": "cross-encoder/ms-marco-MiniLM-L6-v2",
}
}
) |