2026-06-16 11:27:41 +02:00
#spec.py
from pydantic import BaseModel , Field , model_validator
from typing import List , Optional , Literal
2026-06-12 18:16:58 +02:00
2026-06-16 11:27:41 +02:00
class InputOutputConfig ( BaseModel ) :
has_inputs : bool = Field ( default = False , description = " Le script prend-il des éléments en entrée ? " )
input_type : Optional [ Literal [ " file " , " directory " , " api " , " database " , " none " ] ] = Field ( None , description = " Type d ' entrée principale " )
input_paths_or_sources : List [ str ] = Field ( default_factory = list , description = " Chemins, tables ou endpoints sources " )
has_outputs : bool = Field ( default = False , description = " Le script génère-t-style des éléments en sortie ? " )
output_type : Optional [ Literal [ " file " , " directory " , " database " , " api_response " , " log_only " ] ] = Field ( None , description = " Type de sortie principale " )
output_formats : List [ str ] = Field ( default_factory = list , description = " Formats attendus (ex: CSV, JSON, XLSX) " )
class AuthenticationConfig ( BaseModel ) :
requires_auth : bool = Field ( default = False , description = " Le script nécessite-t-il des accès sécurisés ? " )
auth_method : Optional [ Literal [ " env_variables " , " service_account_json " , " oauth2 " , " api_key " , " none " ] ] = Field ( None , description = " Méthode d ' authentification " )
target_tools_and_apis : List [ str ] = Field ( default_factory = list , description = " Logiciels ou API avec lesquels interagir (ex: Sharepoint, JIRA) " )
class EnvironmentConfig ( BaseModel ) :
target_os : Literal [ " linux " , " windows " , " macos " , " cross_platform " ] = Field ( default = " cross_platform " , description = " Système d ' exploitation cible " )
language_version : str = Field ( default = " ^3.11 " , description = " Contrainte de version du langage " )
critical_dependencies : List [ str ] = Field ( default_factory = list , description = " Librairies tierces indispensables " )
2026-06-12 18:16:58 +02:00
class ProjectSpec ( BaseModel ) :
2026-06-16 11:27:41 +02:00
title : Optional [ str ] = Field ( None , description = " Nom clair et concis du script " )
description : Optional [ str ] = Field ( None , description = " Description macro de l ' objectif du script " )
requirements : List [ str ] = Field ( default_factory = list , description = " Liste des fonctionnalités pas-à-pas attendues " )
constraints : List [ str ] = Field ( default_factory = list , description = " Normes, formats de code et conventions de nommage imposés " )
language : str = Field ( default = " Python " , description = " Langage de programmation principal " )
target_stack : str = Field ( None , description = " Stack technique ou framework attendu (ex: Pandas, FastAPI, Flask, Django, etc.) " )
# Sous-configurations détaillées (permettent la détection des champs manquants)
io_config : InputOutputConfig = Field ( default_factory = InputOutputConfig )
auth_config : AuthenticationConfig = Field ( default_factory = AuthenticationConfig )
env_config : EnvironmentConfig = Field ( default_factory = EnvironmentConfig )
error_handling_strategy : Literal [ " abort_on_error " , " log_and_continue " , " retry_policy " ] = Field (
default = " log_and_continue " ,
description = " Comportement du script face à une anomalie "
)
is_complete : bool = Field ( default = False , description = " Passez à True UNIQUEMENT si vous avez TOUTES les infos pour coder (titre, desc, reqs, io_config, auth_config si besoin). " )
clarifying_question : Optional [ str ] = Field ( None , description = " Si is_complete est False, écrivez ici une question claire et polie pour Chainlit pour demander les détails manquants. " )
@model_validator ( mode = " after " )
def validate_conditional_fields ( self ) - > ' ProjectSpec ' :
""" Validation des dépendances logiques pour marquer le cahier des charges comme valide. """
# Si les champs majeurs sont remplis, on valide la cohérence interne
if self . title and self . description and len ( self . requirements ) > 0 :
if self . io_config . has_inputs and not self . io_config . input_type :
raise ValueError ( " input_type manquant alors que has_inputs est True " )
if self . io_config . has_outputs and not self . io_config . output_type :
raise ValueError ( " output_type manquant alors que has_outputs est True " )
if self . auth_config . requires_auth and ( not self . auth_config . auth_method or self . auth_config . auth_method == " none " ) :
raise ValueError ( " auth_method manquante alors que requires_auth est True " )
return self