
    i;                      d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	m
Z
mZmZ ddlmZ ddlmZ ddlmZmZ dd	lmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0 dd
l1m2Z2m3Z3 ddlm
Z
  e	ddg          Z4 ej5        e6          Z7h dZ8 e            Z9dddddZ:ddZ;ddd Z<dd$Z=dd%Z;dd+Z>dd.Z?dd1Z@dd3ZAdd5ZBdd8ZCdd9ZDdd:ZEdd;ZFdd=ZGdd?ZHdd@ZIddDZJddEZKddHZLddLZMddMZNddOZOddRZPddTZQddVZRddXZSe4T                    dYdZe[          dd^            ZUe4T                    d_d`e%[          ddc            ZVe4T                    dddedfdgeh          g fddo            ZWe4T                    dpdqe![          ddt            ZXe4T                    dudve$[          ddy            ZYe4T                    dzd{e*[          dd~            ZZe4T                    dde([          dd            Z[e4T                    dde.[          dd            Z\e4T                    dde0[          dd            Z]e4T                    ddddeh          dd            Z^dS )u  
Nom du fichier : issues.py
Chemin : /var/www/html/gitlab-bridge/app/api/v1/issues.py
Description : Endpoint API de création d'issue GitLab compatible OpenWebUI.
              Cette version utilise un payload simple sans bloc "auth" afin de
              permettre l'import OpenAPI et l'appel réel depuis OpenWebUI.
              L'appel à GitLab est effectué via le token technique du bridge.
Options éventuelles :
    - POST /api/v1/issues/create
Exemples d'utilisation :
    - Appel OpenWebUI via serveur d'outils OpenAPI
    - Appel curl :
      curl -X POST "https://gitlab-bridge.tarbouriech.tech/api/v1/issues/create"         -H "Content-Type: application/json"         -d '{
              "project_path": "si/intelligence-artificielle/serveur-ia-interne",
              "title": "Test OpenWebUI",
              "description": "Issue de test",
              "labels": ["test", "ia"]
            }'
Prérequis :
    - Variables d'environnement :
        GITLAB_BASE_URL
        GITLAB_API_TOKEN
        GITLAB_TIMEOUT (optionnel)
    - Schémas :
        app.schemas.issues.IssueCreateResponse
        app.schemas.issues.IssuePayload
Auteur : Sylvain SCATTOLINI
Date de création : 2026-03-25
Date de modification : 2026-03-25
Version : 1.3
    )annotationsN)	AnnotatedAny)	APIRouterBodyHTTPExceptionstatus)GitLabClient)GitLabApiError)normalize_textcompute_similarity_score)BatchIssueResult IssueAssistantBatchCreateRequest!IssueAssistantBatchCreateResponseIssueAssistantCreateRequestIssueAssistantListRequestIssueAssistantListResponseIssueCreateResponseIssueListItemIssuePayloadIssueAssistantCloseRequestIssueAssistantCloseResponseIssueCandidateItemIssueAssistantReopenRequestIssueAssistantReopenResponseIssueAssistantCreateResponseIssueDuplicateItemIssueAssistantAddLabelRequestIssueAssistantAddLabelResponseIssueAssistantListLabelsRequest IssueAssistantListLabelsResponse	LabelItemBulkIssueResultItem!IssueAssistantAddLabelBulkRequest"IssueAssistantAddLabelBulkResponse IssueAssistantAddLabelAllRequest!IssueAssistantAddLabelAllResponse)MilestoneCandidateItemMilestoneItem)r   z/api/v1/issuesissues)prefixtags>   alaucededuenetlaleunauxcesdeslessurunedansmisepourcreerfaireplacemettreajoutercreation
configurerimplementerconfigurationimplementation)query_paramspayloadmethodstrendpointrK   dict[str, Any] | NonerL   returnr   c                   	 t                               | |||          S # t          $ r%}|j        pd}t	          ||j                  |d}~ww xY w)uU   Adaptateur vers GitLabClient — remplace urllib, bénéficie du pooling et du retry.)params	json_body  status_codedetailN)
_gl_client_requestr   http_statusr   message)rM   rO   rK   rL   excr[   s         0/var/www/html/gitlab-bridge/app/api/v1/issues.py_gitlab_requestr_   w   sl    R""68LT["\\\ R R Ro,CKHHHcQRs     
A A

Aproject_pathdict[str, Any]c                J    t          | d          }t          dd|           S )uH   
    Résout un projet GitLab à partir de son path_with_namespace.
     safeGET
/projects/)quoter_   )r`   encoded_project_paths     r^   _get_project_by_pathrj      s8     !B777+)++      rc   project_hint	root_hintc                J   t          dd| ddd          }t          |t                    sg S g }|D ]}t          |t                    st	          |                    dd                    }|r0t          |                              t          |                    smt          t          | t	          |                    d	d                              t          | |                    }|d
k     r|
                    ||f           |                    dd            |S )Nrf   z	/projectsT2   )searchsimpleper_pagerK   path_with_namespacerc   name(   c                    | d         S Nr    items    r^   <lambda>z&_search_best_project.<locals>.<lambda>   
    47 rk   reversekey)r_   
isinstancelistdictrN   get_normalize_text
startswithmax_score_textappendsort)rl   rm   projects
candidatesprojectpathss          r^   _search_best_projectr      sE   "
 
  H h%% 	J ( ('4(( 	7;;4b99:: 	_T22==oi>X>XYY 	c'++fb*A*A&B&BCCd++
 

 r661g,''''OOD&:&:O;;;rk   r    list[tuple[int, dict[str, Any]]]list[dict[str, Any]]c                L   g }| d d         D ]\  }}|                     t          |d                   t          |                    dd                    t          |                    dd                    t          |                    dd                    |d           |S )N   idru   rc   rt   web_url)r   ru   rt   r   score)r   intrN   r   )r   resultsr   r   s       r^   _build_candidate_projectsr      s    $&G$RaR. 	
 	
w'$-((GKK3344'*7;;7Lb+Q+Q'R'Rw{{9b99:: 	
 	
 	
 	
 Nrk   c                    t          | d          }t          dd|           }t          |t                    rd|vrt	          dd          |S )	Nrc   rd   rf   rg   r     zProjet introuvablerV   )rh   r_   r   r   r   )r`   ri   r   s      r^   rj   rj      sd     B777e%H2F%H%HIIGgt$$ JG(;(;4HIIIINrk   
project_idr   statelimitlist[IssueListItem]c                6   |dk    rd n|}t          dd|  d|t          |d          dddd	
          }t          |t                    sg S g }|D ]}t          |t                    s|                    t          t          |d                   t          |d                   t          |	                    dd                    t          |	                    dd                    t          |	                    dd                                         |S )Nallrf   rg   /issuesd      
created_atdescr   rr   pageorder_byr   rs   r   iidtitlerc   r   r   r   r   r   r   r   )
r_   minr   r   r   r   r   r   rN   r   )r   r   r   query_stater*   r   issues          r^   _list_project_issuesr      s8   5..$$eK(Z((( E3$
 

 
 
F fd## 	#%G 
 
%&& 	uT{##e%%%))GR0011%))GR0011EIIi4455  	
 	
 	
 	
 Nrk   valueset[str]c                   t          |           }t          j        d|          }t                      }|D ]S}|t          v rt          |          dk    r|                    d          r
|d d         }|                    |           T|S )Nz	[a-z0-9]+   r   )r   refindallset
STOP_WORDSlenendswithadd)r   
normalizedtokenscleaned_tokenstokens        r^   _tokenize_meaningful_wordsr      s     ''JZj11F"uuN " "J u::>>ennS11>#2#JE5!!!!rk   
title_hintexisting_titlec                   t          |           }t          |          }t          | |          }||v s||v rt          |d          }t          |           }t          |          }|r|s|S ||z  }||z  }|r/t	          t          |          t          |          z  dz            nd}	t          |          dk    rt          |	d          }	t          |          dk    rt          |	d          }	t          ||	          S )N_   r   r   r   <      U   )r   r   r   r   r   r   )
r   r   normalized_hintnormalized_titlephrase_score
hint_wordstitle_wordscommon_wordsunion_wordsoverlap_scores
             r^   _score_issue_duplicater   
  s   %j11O&~66z>::L***.>/.Q.Q<,,+J77J,^<<K [ +L{*KIT[C\**S-=-==DEEEZ[M <AM2..
<AM2..|]+++rk   
issue_hintc           
         t          dd|  ddt          |d          dddd	
          }t          |t                    sg S g }|D ]}t          |t                    st          |                    dd                    }t          ||          }t          |          t          |          v rt          |d          }|dk     r|
                    ||f           |                    dd            |d |         S )Nrf   rg   r   openedr   r   
updated_atr   r   rs   r   rc   r   rv   Tc                    | d         S rx   ry   rz   s    r^   r|   z+_search_issues_in_project.<locals>.<lambda>J  r}   rk   r~   r_   r   r   r   r   rN   r   r   r   r   r   r   r   r   r   r*   r   r   r   r   s           r^   _search_issues_in_projectr   )  ,   (Z(((E3$
 

 
 
F fd## 	35J * *%&& 	EIIgr**++J..:&&/%*@*@@@rNNE2::5%.))))OOD&:&:O;;;fufrk   list[IssueCandidateItem]c                   g }| d d         D ]\  }}|                     t          t          |d                   t          |d                   t          |                    dd                    t          |                    dd                    t          |                    dd                    |                     |S 	Nr   r   r   r   rc   r   r   )r   r   r   r   r   r   )r   r   r   rN   r   r   r   r   r   s       r^   _build_issue_candidatesr   N  s    (*G"2A2 

 

uuT{##e%%%))GR0011%))GR0011EIIi4455  		
 		
 		
 		
 Nrk   	issue_iidr   c                   t          dd|  d| ddi          }t          |t                    st          dd	          t	          t          |d
                   t          |d                   t          |                    dd                    t          |                    dd                    t          |                    dd                              S )NPUTrg   /issues/state_eventcloserL   rU   u8   Réponse GitLab invalide lors de la clôture de l'issue.rV   r   r   r   rc   r   r   r   r_   r   r   r   r   r   rN   r   r   r   r   s      r^   _close_issuer   `  s    4Z4444(  E eT"" p4noooouT{e%))GR(())%))GR(())EIIi,,--   rk   c           
         t          dd|  ddt          |d          dddd	
          }t          |t                    sg S g }|D ]}t          |t                    st          |                    dd                    }t          ||          }t          |          t          |          v rt          |d          }|dk     r|
                    ||f           |                    dd            |d |         S )Nrf   rg   r   closedr   r   r   r   r   rs   r   rc   r   rv   Tc                    | d         S rx   ry   rz   s    r^   r|   z2_search_closed_issues_in_project.<locals>.<lambda>  r}   rk   r~   r   r   s           r^    _search_closed_issues_in_projectr   r  r   rk   c                   t          dd|  d| ddi          }t          |t                    st          dd	          t	          t          |d
                   t          |d                   t          |                    dd                    t          |                    dd                    t          |                    dd                              S )Nr   rg   r   r   reopenr   rU   u<   Réponse GitLab invalide lors de la réouverture de l'issue.rV   r   r   r   rc   r   r   r   r   r   s      r^   _reopen_issuer     s    4Z4444)  E eT"" t4rssssuT{e%))GR(())%))GR(())EIIi,,--   rk   c           
        t          dd|  ddt          |d          dddd	
          }t          |t                    sg S g }|D ]~}t          |t                    st          |                    dd                                                    }|sPt          ||          }|dk     rg|	                    ||f           |
                    dd            |d |         S )Nrf   rg   r   r   r   r   r   r   r   rs   r   rc   A   Tc                    | d         S rx   ry   rz   s    r^   r|   z5_search_duplicate_issues_in_project.<locals>.<lambda>  r}   rk   r~   )r_   r   r   r   r   rN   r   stripr   r   r   )r   r   r   r*   r   r   r   r   s           r^   #_search_duplicate_issues_in_projectr     s   
 (Z(((E3$
 

 
 
F fd## 	35J * *%&& 	EIIgr**++1133 	&z5992::5%.))))OOD&:&:O;;;fufrk   list[IssueDuplicateItem]c                   g }| d d         D ]\  }}|                     t          t          |d                   t          |d                   t          |                    dd                    t          |                    dd                    t          |                    dd                    |                     |S r   )r   r   r   rN   r   r   s       r^   _build_duplicate_issuesr     s     )+G"2A2 

 

uuT{##e%%%))GR0011%))GR0011EIIi4455  		
 		
 		
 		
 Nrk   list[LabelItem]c                   t          dd|  dt          |d          dd          }t          |t                    sg S g }|D ]0}t          |t                    s|                    t          |                    d          t          |d                   nd t          |                    d	d
                    |                    d          "t          |                    d                    nd |                    d          "t          |                    d                    nd |                    d          "t          |                    d                    nd                      2|
                    d            |S )Nrf   rg   /labelsr   r   rr   r   rs   r   ru   rc   colordescription
text_color)r   ru   r   r   r   c                4    | j                                         S N)ru   lowerrz   s    r^   r|   z&_list_project_labels.<locals>.<lambda>  s    $)//"3"3 rk   )r   )r_   r   r   r   r   r   r"   r   r   rN   r   )r   r   labelsr   labels        r^   _list_project_labelsr    s   (Z(((E3
 
  F fd## 	!G 
 
%&& 	',yy'B3uT{###62..//1671C1C1Oc%))G,,---UY=BYY}=U=U=aC		- 8 8999gk;@99\;R;R;^3uyy66777dh  	
 	
 	
 	
 LL33L444Nrk   c                    t          dd|  d|           }t          |t                    rd|vrt          dd          |S )Nrf   rg   r   r   r   zIssue introuvablerV   )r_   r   r   r   r   s      r^   _get_issue_by_iidr    s_    4Z4444 E
 eT"" Id%&7&74GHHHHLrk   
label_namecreate_if_missingboolc                   t          | d          }|D ]0}t          |j                  t          |          k    r	|j        c S 1|st          dd| d          t	          dd|  d|                                d	d
          }t          |t                    st          dd          t          |	                    d|                                                    S )Nr   r   z
Le label 'z!' est introuvable dans le projet.rV   POSTrg   r   z#428BCA)ru   r   r   rU   u7   Réponse GitLab invalide lors de la création du label.ru   )
r  r   ru   r   r_   r   r   r   rN   r   )r   r	  r
  existing_labelsr  created_labels         r^   _ensure_project_labelr    s   *:s;;O   5:&&/**E*EEE: F  
M
MMM
 
 
 	

 $(Z((($$&&
 
  M mT** o4mnnnn}  )9)9););<<===rk   c           
         t          dd|  ddt          |d          dddd	
          }t          |t                    sg S g }|D ]}t          |t                    st          |                    dd                    }t          ||          }t          |          t          |          v rt          |d          }|dk     r|
                    ||f           |                    dd            |d |         S )Nrf   rg   r   r   r   r   r   r   r   rs   r   rc   r   rv   Tc                    | d         S rx   ry   rz   s    r^   r|   z0_search_open_issues_in_project.<locals>.<lambda>O  r}   rk   r~   r   r   s           r^   _search_open_issues_in_projectr  .  r   rk   r  	list[str]c                   t          dd|  d| dd                    |          i          }t          |t                    st	          dd	          t          t          |d
                   t          |d                   t          |                    dd                    t          |                    dd                    t          |                    dd                              S )Nr   rg   r   r  ,r   rU   u<   Réponse GitLab invalide lors de la mise à jour des labels.rV   r   r   r   rc   r   r   r   )	r_   joinr   r   r   r   r   rN   r   )r   r   r  r   s       r^   _update_issue_labelsr  S  s    4Z4444chhv&&
  E eT"" t4rssssuT{e%))GR(())%))GR(())EIIi,,--   rk   issue_labels	list[Any]	new_labelc                    g }| D ]>}t          |                                          }|r||vr|                    |           ?||vr|                    |           |S r  )rN   r   r   )r  r  mergedr  	label_strs        r^   _merge_issue_labelsr  g  st    F % %JJ$$&&	 	%&00MM)$$$i   Mrk   c           
         |dk    rd n|}t          dd|  d|t          |d          dddd	
          }t          |t                    sg S d |D             S )Nr   rf   rg   r   r   r   r   r   r   rs   c                <    g | ]}t          |t                    |S ry   )r   r   ).0r   s     r^   
<listcomp>z,_list_raw_project_issues.<locals>.<listcomp>  s'    AAAeE4)@)@AEAAArk   )r_   r   r   r   )r   r   r   r   r*   s        r^   _list_raw_project_issuesr$  t  s    5..$$eK(Z((( E3$
 

 
 
F fd## 	AAvAAAArk   r   c                <   t          t          | d                   t          | d                   t          |                     dd                    t          |                     dd                    t          |                     dd                              S )Nr   r   r   rc   r   r   r   )r   r   rN   r   )r   s    r^   _issue_to_list_itemr&    s    uT{e%))GR(())%))GR(())EIIi,,--   rk   	milestoner)   c                   t          t          | d                   |                     d          "t          |                     d                    nd t          |                     dd                    |                     d          r#t          |                     dd                    nd t          |                     dd                    |                     d          r"t          |                     d                    nd |                     d          r"t          |                     d                    nd 	          S )
Nr   r   r   rc   r   r   due_dater   )r   r   r   r   r   r)  r   )r)   r   r   rN   )r'  s    r^   _milestone_to_itemr*    s   y)2u)=)=)IC	e$$%%%t)--,,--=F]]==Y=YcC	mR88999_c)--,,--3<==3L3LVY]]:..///RV1:y1I1ISIMM),,---t   rk   milestone_hintc                   t          dd|  dddd          }t          |t                    sg S g }t          |          }|D ]}t          |t                    st          |                    dd	                    }t          ||          }|t          |          v rt          |d
          }|dk     rs|	                    ||f           |
                    dd            |S )zXRecherche floue d'une milestone dans un projet (toutes les milestones actives + closed).rf   rg   z/milestonesr   r   r   rs   r   rc   r   rv   Tc                    | d         S rx   ry   rz   s    r^   r|   z/_search_milestones_in_project.<locals>.<lambda>  r}   rk   r~   )r_   r   r   r   r   rN   r   r   r   r   r   )r   r+  
milestonesr   r   msr   r   s           r^   _search_milestones_in_projectr0    s   
 !,Z,,,"%q11  J j$'' 	35J%n55O 	' 	'"d## 	BFF7B''((NE22oe4444rNNE2::5"+&&&&OOD&:&:O;;;rk   list[MilestoneCandidateItem]c                *    d | d d         D             S )Nc                8   g | ]\  }}t          t          |d                    |                    d          "t          |                    d                    ndt          |                    dd                    t          |                    dd                    |                    d          r"t          |                    d                    nd|                    d          r"t          |                    d                    nd|          S )	r   r   Nr   rc   r   r)  r   )r   r   r   r   r)  r   r   )r(   r   r   rN   )r"  r   r/  s      r^   r#  z/_build_milestone_candidates.<locals>.<listcomp>  s       E2 	2d8}}&(ffUmm&?BFF5MM"""TbffWb))**bffWb))**02z0B0BLS
++,,,.0ffY.?.?ICy))***T	
 	
 	
  rk   r   ry   )r   s    r^   _build_milestone_candidatesr4    s-      $BQB   rk   ?tuple[str, dict[str, Any] | None, list[MilestoneCandidateItem]]c                L   |                                 sddg fS t          | |          }|sddg fS t          |          dk    rd|d         d         g fS |d         d         |d         d         dz   k    rd|d         d         t          |          fS ddt          |          fS )u   
    Résout une milestone par hint flou.
    Retourne (status, milestone_dict_or_None, candidates).
    Status : "found" | "not_found" | "ambiguous"
    foundN	not_foundr   r   
   	ambiguous)r   r0  r   r4  )r   r+  r   s      r^   _resolve_milestoner;    s     !! !b  .z>JJJ %D"$$
:!
1a(",, !}Q:a=+b000
1a(*Ej*Q*QQQ9*EEEErk   z/assistant-listzAssistant liste des issues)summaryresponse_modelr   r   c                <   	 t                               dt                              |                                 d                     | j                                                                        }t          | j	                  }| j
        r| j                                        st          dd          t          | j                                                  }t          t          |d                   ||          }t          dd	d
|d          t          |d                   t!          |                    dd                    t!          |                    dd                    d|g           S t%          | j        | j                  }|st          ddd| j         dd g g           S t+          |          dk    rC|d         d         |d         d         dz
  k    r"t          dddd g t-          |                    S |d         d         }t          t          |d                   ||          }t          dd	d
|d          t          |d                   t!          |                    dd                    t!          |                    dd                    d|t-          |d d                             S # t          $ r  t.          $ r?}t                               dt!          |                     t          dd          |d }~ww xY w)Nu4   Payload reçu sur /api/v1/issues/assistant-list : %sFensure_ascii  BLe champ resolved_project_path est obligatoire quand confirm=true.rV   r   Tresolvedu   Issues récupérées pour rt   ru   rc   r   ru   rt   )successr	   r\   r   r*   candidate_projectsr8  -   Je ne trouve pas de projet correspondant à ''.r   r   r9  clarification_neededO   J’ai trouvé plusieurs projets possibles. Merci de préciser lequel utiliser.z1Erreur inattendue dans assistant_list_issues : %s  u>   Erreur interne lors de la récupération assistée des issues.)loggerinfojsondumps
model_dumpr   r   r  r   r   confirmresolved_project_pathr   rj   r   r   rN   r   r   rl   rm   r   r   	Exception	exception)rL   
safe_state
safe_limitr   r*   r   r]   s          r^   assistant_list_issuesrW    s\   MBJJw))++%J@@	
 	
 	

 ]((**0022
''
? 	06688 # #_   
 +7+H+N+N+P+PQQG)#gdm*<*<j*UUF-!UW=R5SUUgdm,,FB 7 788+.w{{;PRT/U/U+V+V 
 #%    *'*>@QRR
 	-"`H\```#%    z??Q:a=#3z!}Q7G"7L#L#L--i#<Z#H#H    Q-"%c'$-&8&8*jQQ)Q9N1OQQ'$-((GKK3344'*7;;7Lb+Q+Q'R'R 
 8BQBHH
 
 
 	
       LcRUhhWWWS
 
 
 	s,   E7K :9K 4AK 
B=K L:LLz/assistant-createu   Assistant création issuer   r   c                	   	 t                               dt                              |                                 d                     | j        r| j                                        st          dd          t          | j                                                  }t          |d                   }| j                                        | j                                        d}| j        r'd	                    d
 | j        D                       |d<   | j        dk    r
| j        |d<   t!          dd| d|          }t#          t          |d                   t          |d                   t%          |d                   t%          |d                             }| j        dk    r
d| j         nd}t'          ddd| d|j         |g g           S t)          | j        | j                  }|st'          ddd| j         dd g g           S t/          |          d k    rC|d          d         |d         d         d!z
  k    r"t'          dd"d#d t1          |          g           S |d         d          }t          |d                   }| j        }|dk    r| j                                        rt5          || j                  \  }	}
}|	d$k    rt'          dd%d&| j         d'd g g           S |	d(k    r|
rt          |
d                   }n&|	d)k    r t                               d*| j                   t9          || j        d!          }|r4|d         d         d+k    r"t'          dd,d-d g t;          |                    S | j                                        | j                                        d}| j        r'd	                    d. | j        D                       |d<   |dk    r||d<   t!          dd| d|          }t#          t          |d                   t          |d                   t%          |d                   t%          |d                             }|dk    rd| nd}t'          ddd| d|j         |t1          |d d                    g           S # t          $ r  t<          $ r?}t                               d/t%          |                     t          d0d1          |d }~ww xY w)2Nu6   Payload reçu sur /api/v1/issues/assistant-create : %sFr?  rA  rB  rV   r   r   r   r  c              3  f   K   | ],}|                                 |                                 V  -d S r  r   r"  r.   s     r^   	<genexpr>z)assistant_create_issue.<locals>.<genexpr>f  s<      3c3c!YZY`Y`YbYb3cAGGII3c3c3c3c3c3crk   r  r   milestone_idr  rg   r   r   r   r   r   r   r   r   r   u    assignée à la milestone #rc   Tcreatedu   Issue crééez : )rE  r	   r\   r   rF  duplicate_issuesproject_not_foundu/   Je ne trouve pas de projet correspondant à ‘u   ’.r   r9  project_clarification_neededrJ  r:  milestone_clarification_neededu8   J’ai trouvé plusieurs milestones correspondant à ‘u   ’. Merci de préciser.r7  r8  u(   Milestone introuvable pour hint ‘%s’P   duplicate_warninguT   Une ou plusieurs issues similaires existent déjà. Merci de confirmer la création.c              3  f   K   | ],}|                                 |                                 V  -d S r  r[  r\  s     r^   r]  z)assistant_create_issue.<locals>.<genexpr>  s<      /_/_aUVU\U\U^U^/_		/_/_/_/_/_/_rk   z2Erreur inattendue dans assistant_create_issue : %srK  u;   Erreur interne lors de la création assistée de l’issue.) rL  rM  rN  rO  rP  rQ  rR  r   r   rj   r   r   r   r  r  resolved_milestone_idr_   r   rN   r   r   rl   rm   r   r   r+  r;  warningr   r   rS  rT  )rL   r   r   create_payloadr   created_issuemilestone_noter   rh  	ms_statusms_datams_candidatesduplicate_candidatesr]   s                 r^   assistant_create_issuerq  I  s   KDJJw))++%J@@	
 	
 	

 ? &	06688 # #_   
 +7+H+N+N+P+PQQGWT]++J !,,..&288::. .N ~ d+.883c3cw~3c3c3c+c+cx(,q00181N~.#F,L,L,L,LVdeeeE(uT{##e%%%.))E),--	  M 0144 Ow/LNNN:<  0 PPP=;NPP##%!#    *'*>@QRR
 	/*d'J^ddd#%!#    z??Q:a=#3z!}Q7G"7L#L#L/5i#<Z#H#H!#    Q-"''
 !( = A%%'*@*F*F*H*H%0B:wOe0f0f-IwK''3 ;.SZSi . . . ')%'
 
 
 
 G###(+GDM(:(:%%k))I7KabbbB:w}^`aa 	$8$;A$>"$D$D/*n#%!89M!N!N    ]((**".4466
 
 > 	`'*xx/_/_7>/_/_/_'_'_N8$ 1$$-BN>*(HZ(H(H(HR`aaa$5;E%L!!eGn%%i())	
 
 
 TiklSlSlO8MOOOrt+LNLL}7JLL8BQBHH
 
 
 	
       MsSVxxXXXP
 
 
 	s:   GR! 9R! AR! (BR! .BR! >D"R! !S45:S//S4z/createcreate_issueu   Créer une issue GitLabuJ   Crée une issue GitLab à partir d'un payload simple compatible OpenWebUI.)operation_idr<  r   r=  2Annotated[str, Body(min_length=1, max_length=255)]r   r   4Annotated[str, Body(min_length=1, max_length=20000)](Annotated[list[str], Body(max_items=50)]r   c                   	 |                                  |                                 |                                 |d}t                              dt                              |d                     t          |d                   }|d         |d         d}|d	         r,d
 |d	         D             }|rd                    |          |d	<   t          dd|d          d|          }t                              d|                    d          |                    d                     t          dt          t          |d                   t          |d                   t          |d                   t          |d                                       S # t          $ r  t          $ rI}	t                              dt          |	                     t          t           j        d          |	d}	~	wt$          $ rI}	t                              dt          |	                     t          t           j        d          |	d}	~	ww xY w)uG   
    Crée une issue dans GitLab via le token technique du bridge.
    )r`   r   r   r  u,   Payload reçu sur /api/v1/issues/create : %sFr?  r`   r   r   rY  r  c                    g | ]?}t          |t                    |                                +|                                @S ry   r   rN   r   r"  r  s     r^   r#  z create_issue.<locals>.<listcomp>  sR     ! ! !eS))! /4kkmm!! ! !rk   r  r  rg   r   r   r   u>   Issue GitLab créée avec succès : project_id=%s issue_iid=%sr   Tr   r_  )rE  r   z,Champ GitLab manquant dans create_issue : %su9   Réponse GitLab incomplète lors de la création d'issue.rV   Nz(Erreur inattendue dans create_issue : %su,   Erreur interne lors de la création d'issue.)r   rL  rM  rN  rO  rj   r  r_   r   r   r   r   rN   r   KeyErrorrT  r	   HTTP_502_BAD_GATEWAYrS  HTTP_500_INTERNAL_SERVER_ERROR)
r`   r   r   r  safe_payloadr   rj  normalized_labelsr   r]   s
             r^   rr  rr    s    @(..00[[]]&,,..	
 
 	:JJ|%J88	
 	
 	

 '|N'CDD "'*'6*
 *

 ! 	G! !)(3! ! !
 ! G+.884E+F+Fx(////"
 
 
 	LKKIIe	
 	
 	
 #uT{##e%%%.))E),--	  
 
 
 	
       GSRRR3N
 
 
 	    CSXXNNN=A
 
 
 	s&   FF I.AG22I?AIIz/assistant-closeu   Assistant clôture d'issuer   r   c                   	 t                               dt                              |                                 d                     t          | j                  }| j        r| j        	                                st          dd          | j        dk    rt          dd          t          | j        	                                          }t          t          |d	                   t          | j                            }t          d
dd|j         t          |d	                   t!          |                    dd                    t!          |                    dd                    d|g g           S t%          | j        p| j        | j                  }|st          d
ddd d g g           S t-          |          dk    rD|d         d         |d         d         dz
  k    r#t          d
ddd d t/          |          g           S |d         d         }t1          t          |d	                   | j        |          }|sxt          d
dd| j         dt          |d	                   t!          |                    dd                    t!          |                    dd                    dd g g           S t-          |          dk    r|d         d         |d         d         dz
  k    r|t          d
ddt          |d	                   t!          |                    dd                    t!          |                    dd                    dd g t3          |                    S t          |d         d         d                   }t          t          |d	                   |          }t          d
dd|j         t          |d	                   t!          |                    dd                    t!          |                    dd                    d|g g           S # t          $ r  t4          $ r?}t                               dt!          |                     t          dd           |d }~ww xY w)!Nu5   Payload reçu sur /api/v1/issues/assistant-close : %sFr?  rA  rB  rV   r   ?Le champ resolved_issue_iid est obligatoire quand confirm=true.r   Tr   u   Issue clôturée : ru   rc   rt   rD  rE  r	   r\   r   r   rF  candidate_issuesrb  )Je ne trouve pas le projet correspondant.r   r9  rc  rJ  issue_not_foundu+   Je ne trouve pas d'issue correspondant à 'rH  issue_clarification_neededuQ   J’ai trouvé plusieurs issues possibles. Merci de préciser laquelle clôturer.r   z1Erreur inattendue dans assistant_close_issue : %srK  u8   Erreur interne lors de la clôture assistée de l'issue.)rL  rM  rN  rO  rP  r   r   rQ  rR  r   r   resolved_issue_iidrj   r   r   r   rN   r   r   rl   r   rm   r   r   r   r   rS  rT  )rL   rV  r   closed_issuer   issue_candidatesr   r]   s           r^   assistant_close_issuer  0  s   wCJJw))++%J@@	
 	
 	

 ''
? 	06688 # #_   
 )Q..# #\   
 +7+H+N+N+P+PQQG'GDM(:(:C@Z<[<[\\L.Bl.@BBgdm,,FB 7 788+.w{{;PRT/U/U+V+V 
 ##%!#    *'*>*T'BTV]Vghh
 		.*C#%!#    z??Q:a=#3z!}Q7G"7L#L#L.5i#<Z#H#H!#    Q-"4S5G5GI[]ghh 	.(\gFX\\\gdm,,FB 7 788+.w{{;PRT/U/U+V+V 
 #%!#      1$$)9!)<Q)?CSTUCVWXCY\^C^)^)^.3kgdm,,FB 7 788+.w{{;PRT/U/U+V+V 
 #%!89I!J!J    (+A.u566	#C$6$6	BB*>,*<>>'$-((GKK3344'*7;;7Lb+Q+Q'R'R 
 !
 
 
 	
       LcRUhhWWWM
 
 
 	:   E:P) =8P) 6AP) B0P) >B/P) .B:P) )Q<=:Q77Q<z/assistant-reopenu   Assistant réouverture d'issuer   r   c                   	 t                               dt                              |                                 d                     t          | j                  }| j        r| j        	                                st          dd          | j        dk    rt          dd          t          | j        	                                          }t          t          |d	                   t          | j                            }t          d
dd|j         t          |d	                   t!          |                    dd                    t!          |                    dd                    d|g g           S t%          | j        p| j        | j                  }|st          d
ddd d g g           S t-          |          dk    rD|d         d         |d         d         dz
  k    r#t          d
ddd d t/          |          g           S |d         d         }t1          t          |d	                   | j        |          }|sxt          d
dd| j         dt          |d	                   t!          |                    dd                    t!          |                    dd                    dd g g           S t-          |          dk    r|d         d         |d         d         dz
  k    r|t          d
ddt          |d	                   t!          |                    dd                    t!          |                    dd                    dd g t3          |                    S t          |d         d         d                   }t          t          |d	                   |          }t          d
dd|j         t          |d	                   t!          |                    dd                    t!          |                    dd                    d|g g           S # t          $ r  t4          $ r?}t                               dt!          |                     t          dd           |d }~ww xY w)!Nu6   Payload reçu sur /api/v1/issues/assistant-reopen : %sFr?  rA  rB  rV   r   r  r   Treopenedu   Issue réouverte : ru   rc   rt   rD  r  rb  r  r   r9  rc  rJ  r  u3   Je ne trouve pas d'issue fermée correspondant à 'rH  r  uZ   J’ai trouvé plusieurs issues fermées possibles. Merci de préciser laquelle réouvrir.r   z2Erreur inattendue dans assistant_reopen_issue : %srK  u<   Erreur interne lors de la réouverture assistée de l'issue.)rL  rM  rN  rO  rP  r   r   rQ  rR  r   r   r  rj   r   r   r   rN   r   r   rl   r   rm   r   r   r   r   rS  rT  )rL   rV  r   reopened_issuer   r  r   r]   s           r^   assistant_reopen_issuer    s   wDJJw))++%J@@	
 	
 	

 ''
? 	06688 # #_   
 )Q..# #\   
 +7+H+N+N+P+PQQG*3wt}+=+=s7C]?^?^__N/!Dn.BDDgdm,,FB 7 788+.w{{;PRT/U/U+V+V 
 %#%!#    *'*>*T'BTV]Vghh
 		/*C#%!#    z??Q:a=#3z!}Q7G"7L#L#L/5i#<Z#H#H!#    Q-";C<N<NPWPbdnoo 	/(dgN`dddgdm,,FB 7 788+.w{{;PRT/U/U+V+V 
 #%!#      1$$)9!)<Q)?CSTUCVWXCY\^C^)^)^/3tgdm,,FB 7 788+.w{{;PRT/U/U+V+V 
 #%!89I!J!J    (+A.u566	&s74='9'99EE+@.*>@@'$-((GKK3344'*7;;7Lb+Q+Q'R'R 
 !!
 
 
 	
       MsSVxxXXXQ
 
 
 	r  z/assistant-list-labelszAssistant liste des labelsr    r!   c                   	 t                               dt                              |                                 d                     t          | j                  }| j        r| j        	                                st          dd          t          | j        	                                          }t          t          |d                   |          }t          dd	d
|d          t          |d                   t          |                    dd                    t          |                    dd                    d|g           S t!          | j        | j                  }|st          ddd| j         dd g g           S t'          |          dk    rC|d         d         |d         d         dz
  k    r"t          dddd g t)          |                    S |d         d         }t          t          |d                   |          }t          dd	d
|d          t          |d                   t          |                    dd                    t          |                    dd                    d|t)          |d d                             S # t          $ r  t*          $ r?}t                               dt          |                     t          dd          |d }~ww xY w)Nu;   Payload reçu sur /api/v1/issues/assistant-list-labels : %sFr?  rA  rB  rV   r   TrC  u   Labels récupérés pour rt   ru   rc   rD  )rE  r	   r\   r   r  rF  r8  rG  rH  r   r   r9  rI  rJ  z1Erreur inattendue dans assistant_list_labels : %srK  u>   Erreur interne lors de la récupération assistée des labels.)rL  rM  rN  rO  rP  r   r   rQ  rR  r   r   rj   r  r!   rN   r   r   rl   rm   r   r   rS  rT  )rL   rV  r   r  r   r]   s         r^   assistant_list_labelsr  2  s9   LIJJw))++%J@@	
 	
 	

 ''
? 	06688 # #_   
 +7+H+N+N+P+PQQG)#gdm*<*<jIIF3!TG<Q4RTTgdm,,FB 7 788+.w{{;PRT/U/U+V+V 
 #%    *'*>@QRR
 	3"`H\```#%    z??Q:a=#3z!}Q7G"7L#L#L3-i#<Z#H#H    Q-"%c'$-&8&8*EE/P8M0NPP'$-((GKK3344'*7;;7Lb+Q+Q'R'R 
 8BQBHH
 
 
 	
       LcRUhhWWWS
 
 
 	s,   EJ 9J AJ B<J K./:K))K.z/assistant-add-labelu%   Assistant ajout de label à une issuer   r   c                R
   	 t                               dt                              |                                 d                     t          | j                  }| j                                        }| j	        r| j
                                        st          dd          | j        dk    rt          dd          t          | j
                                                  }t          |d	                   }t          ||| j                  }t!          |t          | j                            }d
 |                    dg           D             }|d d          }||vr|                    |           t'          |t          | j                  |          }	t)          ddd|	j         |t-          |                    dd                    t-          |                    dd                    d|	|g g           S t/          | j        p| j        | j                  }
|
st)          dddd d g g g           S t7          |
          dk    rE|
d         d         |
d         d         dz
  k    r$t)          dddd d g t9          |
          g           S |
d         d         }t          |d	                   }t;          || j        |          }|sft)          ddd| j         d|t-          |                    dd                    t-          |                    dd                    dd g g g           S t7          |          dk    r|d         d         |d         d         dz
  k    rjt)          ddd|t-          |                    dd                    t-          |                    dd                    dd g g t=          |                    S t          |d         d         d                   }t          ||| j                  }t!          ||          }d  |                    dg           D             }|d d          }||vr|                    |           t'          |||          }	t)          ddd|	j         |t-          |                    dd                    t-          |                    dd                    d|	|g g           S # t          $ r  t>          $ r?}t                                d!t-          |                     t          d"d#          |d }~ww xY w)$Nu9   Payload reçu sur /api/v1/issues/assistant-add-label : %sFr?  rA  rB  rV   r   r  r   c                ,    g | ]}t          |          S ry   rN   rz  s     r^   r#  z'assistant_add_label.<locals>.<listcomp>  s    VVVes5zzVVVrk   r  Tupdatedu   Label ajouté à l'issue : ru   rc   rt   rD  )rE  r	   r\   r   r   r  rF  r  rb  r  r   r9  rc  rJ  r  u3   Je ne trouve pas d'issue ouverte correspondant à 'rH  r  uP   J’ai trouvé plusieurs issues possibles. Merci de préciser laquelle modifier.r   c                ,    g | ]}t          |          S ry   r  rz  s     r^   r#  z'assistant_add_label.<locals>.<listcomp>
  s    RRR%3u::RRRrk   z/Erreur inattendue dans assistant_add_label : %srK  u1   Erreur interne lors de l'ajout assisté de label.)!rL  rM  rN  rO  rP  r   r   r	  r   rQ  rR  r   r  rj   r  create_label_if_missingr  r   r   r  r   r   rN   r   rl   r   rm   r   r   r  r   rS  rT  )rL   rV  safe_label_namer   r   r	  issue_beforer  merged_labelsupdated_issuer   r  r   r]   s                 r^   assistant_add_labelr    s   XGJJw))++%J@@	
 	
 	

 ''
!,2244? ,	06688 # #_   
 )Q..# #\   
 +7+H+N+N+P+PQQGWT]++J./ J -ZW=W9X9XYYLVV|7G7GRT7U7UVVVO+AAA.M..$$Z0000SA[=\=\^kllM1 Km6IKK$FB 7 788+.w{{;PRT/U/U+V+V 
 $$#%!#    *'*>*T'BTV]Vghh
 
	1*C#%!#	 	 	 	 z??Q:a=#3z!}Q7G"7L#L#L15i#<Z#H#H!#	 	 	 	 Q-"''
9*gFXZdee 	1(dgN`ddd$FB 7 788+.w{{;PRT/U/U+V+V 
 #%!#      1$$)9!)<Q)?CSTUCVWXCY\^C^)^)^13j$FB 7 788+.w{{;PRT/U/U+V+V 
 #%!89I!J!J    (+A.u566	*:Hghh
(Y??RR<3C3CHb3Q3QRRR'*]**  ,,,,ZMRR-G-2EGG GKK3344'*7;;7Lb+Q+Q'R'R 
   !
 
 
 	
       JCPSHHUUUF
 
 
 	s:   G?S 9S <AS B S 5BS C?S T&':T!!T&z/assistant-add-label-bulku,   Assistant ajout de label à plusieurs issuesr$   r%   c                   	 t                               dt                              |                                 d                     t          | j                  }| j                                        }d | j	        D             }|st          dd          | j        r%| j                                        st          dd          t          | j                                                  }t          |d	                   }t          ||| j                  }g }|D ]H}t!          |||          }	|	s-|                    t%          |d
d| dd g g                      Ct'          |	          dk    r[|	d         d         |	d         d         dz
  k    r:|                    t%          |dd| dd g t)          |	                               t          |	d         d         d                   }
t+          ||
          }t-          |                    dg           |          }t1          ||
|          }|                    t%          |dd|j         d||g                      Jt5          ddd|t7          |                    dd                    t7          |                    dd                    d||g           S t9          | j        | j                  }|st5          ddd d |g g           S t'          |          dk    rD|d         d         |d         d         dz
  k    r#t5          dd!d"d |g t?          |                    S |d         d         }t          |d	                   }t          ||| j                  }g }|D ]H}t!          |||          }	|	s-|                    t%          |d
d| dd g g                      Ct'          |	          dk    r[|	d         d         |	d         d         dz
  k    r:|                    t%          |dd| dd g t)          |	                               t          |	d         d         d                   }
t+          ||
          }t-          |                    dg           |          }t1          ||
|          }|                    t%          |dd|j         d||g                      Jt5          ddd|t7          |                    dd                    t7          |                    dd                    d||g           S # t          $ r  t@          $ r?}t           !                    d#t7          |                     t          d$d%          |d }~ww xY w)&Nu>   Payload reçu sur /api/v1/issues/assistant-add-label-bulk : %sFr?  c                    g | ]?}t          |t                    |                                +|                                @S ry   ry  )r"  r   s     r^   r#  z,assistant_add_label_bulk.<locals>.<listcomp>;  sZ     
 
 
*c**
 0:/?/?/A/A

 
 
rk   rA  zLa liste issue_hints est vide.rV   rB  r   r  zIssue introuvable pour 'rH  r   r	   r\   r   r  r  r   r   r9  r  z!Plusieurs issues possibles pour 'r   r  r     Label ajouté à 'T	processedu   Traitement des labels terminé.ru   rc   rt   rD  )rE  r	   r\   r   r	  r   rF  rb  r  rc  rJ  z4Erreur inattendue dans assistant_add_label_bulk : %srK  u:   Erreur interne lors de l'ajout assisté de label en masse.)"rL  rM  rN  rO  rP  r   r   r	  r   issue_hintsr   rQ  rR  rj   r  r  r  r   r#   r   r   r  r  r   r  r   r%   rN   r   rl   rm   r   rS  rT  )rL   rV  r  clean_issue_hintsr   r   r	  r   r   r  r   r  r  r  r   r]   s                   r^   assistant_add_label_bulkr  *  s   GLJJw))++%J@@	
 	
 	

 ''
!,2244
 
%1
 
 
 ! 	7   
 ? K	06688 # #_   
 +7+H+N+N+P+PQQGWT]++J./ J 24G/ + +
#A*jZd#e#e ' NN+'1#4$Mz$M$M$M"&#%-/  	 	 	 '((1,,1A!1DQ1GK[\]K^_`KadfKf1f1fNN+'1#?$V
$V$V$V"&#%-DEU-V-V  	 	 	  0 3A 6u =>>	0YGG 3L4D4DXr4R4RT^ _ _ 4ZM Z Z'#-( L]5H L L L+,)+  	 	 	 	 6"9$FB 7 788+.w{{;PRT/U/U+V+V 
 &#%    *'*>@QRR
 		5*C*#%    z??Q:a=#3z!}Q7G"7L#L#L55i*#<Z#H#H    Q-"''
*+
 

 .0+ +	 +	J=j*V`aa# '#-0 I: I I I"!)+  	 	 	 #$$q((-=a-@-CGWXYGZ[\G]`bGb-b-b'#-; RJ R R R"!)@AQ)R)R  	 	 	 ,Q/259::I,ZCCL/0@0@20N0NPZ[[M0YVVMNN#)$H1DHHH'(%'  	 	 	 	 25 GKK3344'*7;;7Lb+Q+Q'R'R 
 "!
 
 
 	
       OQTUXQYQYZZZO
 
 
 	s,   KT3 1T3 9AT3 G"T3 3V:VVz/assistant-add-label-allu9   Assistant ajout de label à toutes les issues d'un projetr&   r'   c                6   	 t                               dt                              |                                 d                     t          | j                  }| j                                        }| j	                                        
                                }| j        r$| j                                        st          dd          t          | j                                                  }t          |d                   }t          ||| j                  }t#          |||          }g }d}	|D ]%}
t          |
d	                   }d
 |
                    dg           D             }t'          ||          }||k    ro|                    t+          t-          |
                    dd                    dd|
                    dd           dt/          |
          |g                      t1          |||          }|	dz  }	|                    t+          t-          |
                    dd                    dd|j         d||g                      't5          ddd|t-          |                    dd                    t-          |                    dd                    d|t7          |          |	|g 	  	        S t9          | j        | j                  }|s!t5          ddd| j         dd |ddg g 	  	        S t7          |          dk    rF|d         d         |d         d         dz
  k    r%t5          ddd d |ddg t?          |          	  	        S |d         d         }t          |d                   }t          ||| j                  }t#          |||          }g }d}	|D ]%}
t          |
d	                   }d! |
                    dg           D             }t'          ||          }||k    ro|                    t+          t-          |
                    dd                    dd|
                    dd           dt/          |
          |g                      t1          |||          }|	dz  }	|                    t+          t-          |
                    dd                    dd|j         d||g                      't5          ddd|t-          |                    dd                    t-          |                    dd                    d|t7          |          |	|g 	  	        S # t          $ r  t@          $ r?}t           !                    d"t-          |                     t          d#d$          |d }~ww xY w)%Nu=   Payload reçu sur /api/v1/issues/assistant-add-label-all : %sFr?  rA  rB  rV   r   r   r   c                ,    g | ]}t          |          S ry   r  rz  s     r^   r#  z+assistant_add_label_all.<locals>.<listcomp>#  s    "S"S"S%3u::"S"S"Srk   r  r   rc   	unchangedu   Label déjà présent sur 'rH  r  r   r  r  Tr  u1   Ajout du label terminé sur les issues du projet.ru   rt   rD  )	rE  r	   r\   r   r	  total_issuesupdated_countr   rF  rb  rG  r9  rc  rJ  c                ,    g | ]}t          |          S ry   r  rz  s     r^   r#  z+assistant_add_label_all.<locals>.<listcomp>|  s    OOOes5zzOOOrk   z3Erreur inattendue dans assistant_add_label_all : %srK  zHErreur interne lors de l'ajout du label sur toutes les issues du projet.)"rL  rM  rN  rO  rP  r   r   r	  r   r   r  rQ  rR  r   rj   r  r  r$  r   r  r   r#   rN   r&  r  r   r'   r   r   rl   rm   r   rS  rT  )rL   rV  r  rU  r   r   r	  
raw_issuesr   r  r   r   r  r  r  r   r]   s                    r^   assistant_add_label_allr    s\   nKJJw))++%J@@	
 	
 	

 ''
!,2244]((**0022
? B	06688 # #_   
 +7+H+N+N+P+PQQGWT]++J./ J 2*j*UUJ13GM#  e--	"S"S599Xr;R;R"S"S"S 3OZ P P O33NN+'*599Wb+A+A'B'B#.$\%))GUWBXBX$\$\$\"5e"<"<#0-/  	 	 	  4ZM Z Z"'#&uyy"'='=#>#>( L]5H L L L+,)+  	 	 	 	 5"K$FB 7 788+.w{{;PRT/U/U+V+V 
 & __+#%     *'*>@QRR
 	4*`H\```*#%
 
 
 
 z??Q:a=#3z!}Q7G"7L#L#L45i*#<Z#H#H
 
 
 
 Q-"''
*+
 

 .j*jQQ
-/ 	 	EE%L))IOOuyy27N7NOOOO/LLM//'#&uyy"'='=#>#>* XeiiQS>T>T X X X1%88,)+  	 	 	 0YVVMQMNN#"599Wb#9#9::$H1DHHH'(%'  	 	 	 	 1G GKK3344'*7;;7Lb+Q+Q'R'R 
 "Z'!
 
 
 	
        NPSTWPXPXYYY]
 
 
 	s,   K
U <U 
AU #G!U V:VVz/assistant-batch-createassistant_batch_create_issuesu4   Créer plusieurs issues GitLab en une seule requêteuB  Crée N issues d'un seul appel dans un projet GitLab, avec assignment optionnel à une milestone. Résout automatiquement le projet et la milestone par nom partiel. En cas d'ambiguïté, retourne les candidats pour clarification. Chaque issue est créée indépendamment : une erreur sur une issue n'interrompt pas le lot.r   r   c                v   	 t                               dt          | j                  | j        | j                   | j        r| j                                        st          dd          t          | j                                                  }t          |d                   }d}| j        dk    rq	 t          dd	| d
| j                   }t          |t                    rt!          |          }n0# t          $ r# t                               d| j                   Y nw xY wg }d}d}| j        D ]}	 |j                                        |j                                        d}	|j        r+d |j        D             }
|
rd                    |
          |	d<   | j        dk    r
| j        |	d<   t          dd	| d|	          }|dz  }|                    t/          |j        dd|d          dt1          t          |d                   t          |d                   t3          |d                   t3          |d                             | j        dk                         7# t          $ rh}|dz  }t                               d|j        |j                   |                    t/          |j        dd|j                               Y d}~d}~ww xY w|t3          |                    d!d"                    t3          |                    d#d"                    d$}|rd%|j         d&nd"}t9          d'd(| d)| d*| d+|||||g g ,
  
        S t;          | j        | j                  }|st9          d'd-d.| j         d/g g g 0          S t          |          dk    rC|d         d         |d         d         d1z
  k    r"t9          d'd2d3g t?          |          g 0          S |d         d         }t          |d                   }|t3          |                    d!d"                    t3          |                    d#d"                    d$}d}d}g }| j                                        rtA          || j                  \  }}}|d4k    rt9          d'd5d6| j         d7|g g |8          S |d9k    r(t9          d'd:d;| j         d<|d#          d/|g g g 8          S |d=k    r&|r$t          |d                   }t!          |          }g }d}d}| j        D ]}	 |j                                        |j                                        d}	|j        r+d> |j        D             }
|
rd                    |
          |	d<   |dk    r||	d<   t          dd	| d|	          }|dz  }|                    t/          |j        dd|d          dt1          t          |d                   t          |d                   t3          |d                   t3          |d                             |dk                         (# t          $ rh}|dz  }t                               d|j        |j                   |                    t/          |j        dd|j                               Y d}~d}~ww xY w|rd%|j         d&nd"}t9          d'd(| d)| d*| d+|||||g g ,
  
        S # t          $ r  tB          $ r?}t           "                    d?t3          |                     t          d@dA          |d}~ww xY w)Bum  
    Endpoint batch pour Thalia / OpenWebUI.

    Flux recommandé pour l'IA :
    1. Appel initial (confirm=False) → le bridge résout projet + milestone.
       Si tout est clair → status="ready", les resolved_* sont fournis.
       Rappeler avec confirm=True et les resolved_* obtenus.
    2. Appel de confirmation (confirm=True, resolved_project_path + resolved_milestone_id) →
       toutes les issues sont créées. Jamais d'interruption partielle.

    Note : si le projet et la milestone sont non ambigus dès le premier appel,
    le bridge crée directement les issues et retourne status="completed".
    ug   Payload reçu sur /api/v1/issues/assistant-batch-create : %s issues, project_hint=%r, milestone_hint=%rrA  rB  rV   r   Nr   rf   rg   z/milestones/uG   Milestone %d introuvable — les issues seront créées sans milestone.rY  c                ^    g | ]*}|                                 |                                 +S ry   r[  r\  s     r^   r#  z1assistant_batch_create_issues.<locals>.<listcomp>  s2    '['['[aQRQXQXQZQZ'[		'['['[rk   r  r  r^  r  r   r   r   r`  zIssue #r   u	    créée.r   r   r_  )r   r	   r\   r   milestone_assignedu    Erreur création issue '%s' : %serrorz	Erreur : )r   r	   r\   ru   rc   rt   rD  z dans la milestone ''T	completedu    issue(s) créée(s)z, z erreur(s).)
rE  r	   r\   r   r'  r   created_counterror_countrF  candidate_milestonesrb  rG  rH  )rE  r	   r\   r   rF  r  r9  rc  uM   J'ai trouvé plusieurs projets possibles. Merci de préciser lequel utiliser.r:  rd  u4   J'ai trouvé plusieurs milestones correspondant à 'uM   '. Merci de préciser laquelle utiliser en fournissant resolved_milestone_id.)rE  r	   r\   r   r   rF  r  r8  milestone_not_foundu0   Je ne trouve pas de milestone correspondant à 'z' dans le projet 'r7  c                ^    g | ]*}|                                 |                                 +S ry   r[  r\  s     r^   r#  z1assistant_batch_create_issues.<locals>.<listcomp>  s-    #W#W#W!QWWYY#WAGGII#W#W#Wrk   z9Erreur inattendue dans assistant_batch_create_issues : %srK  u6   Erreur interne lors de la création en lot des issues.)#rL  rM  r   r*   rl   r+  rQ  rR  r   r   rj   r   rh  r_   r   r   r*  ri  r   r   r  r  r   r   r   rN   rX   r   r   r   rm   r   r;  rS  rT  )rL   r   r   milestone_itemrn  r   r  r  issue_inputrj  clean_labels
issue_datar]   project_dictrl  r   rh  r  rm  s                      r^   r  r    s	   :vu "		
 	
 	
 ? ]	06688 # #_   
 +7+H+N+N+P+PQQGWT]++J 48N,q00-\Z\\W=Z\\ G "'400 E);G)D)D$   NNa5     /1GMK&~ , ,+!,!2!8!8!:!:'2'>'D'D'F'F6 6N #) N'['[;;M'['['[' N7:xx7M7MN844q889@9V~6!08Z888 ." " "J "Q&MNN#3)/( F*U*; F F F*":d#344 #Ju$5 6 6"%j&9":":$'
9(=$>$>	   ,3+H1+L$ $ $     %   1$KNN:#)
  
 NN#3)/& 8CJ 8 8$ $ $         !GKK3344'*7;;7Lb+Q+Q'R'R L
 P^eKN4HKKKKceN4"(hhnhhP[hhh$(+'#%%'     *'*>@QRR
 	4*`H\```#%%'    z??Q:a=#3z!}Q7G"7L#L#L45g#<Z#H#H%'    Q-"''
FB//00#&w{{3H"'M'M#N#N
 
 !"=?!''))  	=7IG28 84Iw 4 K''8 ;ewOe e e e )'))=    K''8 0S7Ka S S+78M+NS S S )'))+    G###(+GDM(:(:%!3G!<!< "> (	 (	K'(.4466#.#:#@#@#B#B" " % J#W#W{7I#W#W#WL# J3688L3I3Ix0(1,,5JN>2,4444*  
 "/%+$Bj&7BBB&z$/00
5 122!*W"566 #Jy$9 : :	   (=q'@          !   q A;CTVYV`aaa/%+"4
44              LZaG0DGGGG_a0$dd.ddKddd $'#!!#
 
 
 	
       TVYZ]V^V^___K
 
 
 	s   B3[% 6?C6 5[% 6*D# [% "D##[% 7D1I*([% *
K4AK[% KA;[% 9[% A[% (C[% 0-[% <[% D"X?=[% ?
Z1	AZ,&[% ,Z113[% %\89:\33\8)
rM   rN   rO   rN   rK   rP   rL   rP   rQ   r   )r`   rN   rQ   ra   )rc   )rl   rN   rm   rN   )r   r   rQ   r   )r   r   r   rN   r   r   rQ   r   )r   rN   rQ   r   )r   rN   r   rN   rQ   r   )r   r   r   rN   r   r   rQ   r   )r   r   rQ   r   )r   r   r   r   rQ   r   )r   r   r   rN   r   r   rQ   r   )r   r   rQ   r   )r   r   r   r   rQ   r   )r   r   r   r   rQ   ra   )r   r   r	  rN   r
  r  rQ   rN   )r   r   r   r   r  r  rQ   r   )r  r  r  rN   rQ   r  )r   r   r   rN   r   r   rQ   r   )r   ra   rQ   r   )r'  ra   rQ   r)   )r   r   r+  rN   rQ   r   )r   r   rQ   r1  )r   r   r+  rN   rQ   r5  )rL   r   rQ   r   )rL   r   rQ   r   )
r`   rt  r   rt  r   ru  r  rv  rQ   r   )rL   r   rQ   r   )rL   r   rQ   r   )rL   r    rQ   r!   )rL   r   rQ   r   )rL   r$   rQ   r%   )rL   r&   rQ   r'   )rL   r   rQ   r   )___doc__
__future__r   loggingr   typingr   r   fastapir   r   r   r	   app.clients.gitlab_clientr
   app.core.exceptionsr   app.utils.helpersr   r   r   r   app.schemas.issuesr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   app.schemas.milestonesr(   r)   router	getLogger__name__rL  r   rY   r_   rj   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r$  r&  r*  r0  r4  r;  postrW  rq  rr  r  r  r  r  r  r  r  ry   rk   r^   <module>r     sS     D # " " " " "  				 ! ! ! ! ! ! ! ! : : : : : : : : : : : : 2 2 2 2 2 2 . . . . . . h h h h h h h h                                                       8 I H H H H H H H      	*(	<	<	<		8	$	$  
B \^^
 +/%)R R R R R R   $ $ $ $ $L   "   " " " "N   &, , , ,>" " " "J   $   $" " " "J   $& & & &R   &   B	 	 	 	> > > >8" " " "J   (   B B B B*   	 	 	 	   @   "F F F F> (-   
P P P 
Pd '/   
N N N 
N` %\&    8:	I I I I IV (.   
z z z 
zx ,/   
z z z 
zx (3   
O O O 
Ob 31   
[ [ [ 
[z :5   
J J J 
JX G4   
q q q 
qh 0B	g 5   F F F F F Frk   