1- import ModelClient from "@azure-rest/ai-inference" ;
2- import { AzureKeyCredential } from "@azure/core-auth" ;
3-
41export class AIService {
5- private client : any = null ;
6- private readonly endpoint = "https://models.inference.ai.azure.com" ;
2+ private readonly endpoint = "https://models.inference.ai.azure.com/chat/completions" ;
73 private readonly token : string ;
84
95 constructor ( ) {
106 this . token = process . env . GITHUB_AI_TOKEN || "" ;
11- }
12-
13- private getClient ( ) {
14- if ( ! this . client && this . token ) {
15- try {
16- this . client = ModelClient ( this . endpoint , new AzureKeyCredential ( this . token ) ) ;
17- } catch ( e : any ) {
18- console . error ( `[AIService] Erro ao inicializar cliente: ${ e . message } ` ) ;
19- return null ;
20- }
21- }
22- return this . client ;
7+ if ( ! this . token ) console . warn ( "[AIService] ⚠️ Token GITHUB_AI_TOKEN não encontrado!" ) ;
238 }
249
2510 async analyzeFailure ( errorMessage : string , domSnapshot : string ) : Promise < string > {
26- if ( ! this . token ) return "IA desativada: Token não configurado." ;
11+ console . log ( "[AIService] 🚀 Iniciando análise via Fetch Nativo..." ) ;
12+
13+ if ( ! this . token ) return "IA desativada: Token ausente." ;
2714
28- const client = this . getClient ( ) ;
29- if ( ! client ) return "IA indisponível: Falha na inicialização." ;
30-
31- // 🎯 PROMPT BLINDADO: Exige formato estrito
3215 const systemPrompt = `
33- Você é um especialista em Auto-Healing para Playwright (QA).
34- Analise o erro e o DOM fornecido.
35-
36- SEU OBJETIVO: Encontrar o seletor CSS correto para corrigir o teste.
16+ Você é uma IA de Self-Healing para automação de testes (Playwright).
17+ Objetivo: Consertar seletores quebrados.
3718
38- REGRAS CRÍTICAS DE RESPOSTA :
39- 1. Se encontrar o elemento, responda APENAS o seletor dentro de crases. Exemplo: \`#login-button\`
40- 2. NÃO explique nada. NÃO dê contexto. APENAS O SELETOR.
41- 3. Se não encontrar , responda: \` null\`
19+ Regra :
20+ 1. Analise o erro e o DOM.
21+ 2. Retorne APENAS o seletor CSS corrigido dentro de crases. Ex: \`#novo-id\`
22+ 3. Se não achar , responda: null
4223 ` ;
4324
4425 try {
45- // Cortamos o DOM para não estourar o limite de tokens e focar no essencial
46- const truncatedDom = domSnapshot . slice ( 0 , 15000 ) ;
26+ const truncatedDom = domSnapshot . slice ( 0 , 10000 ) ;
4727
48- const response = await client . path ( "/chat/completions" ) . post ( {
49- body : {
28+ console . log ( `[AIService] 📤 Enviando requisição para gpt-4o-mini...` ) ;
29+
30+ // ⚡ REQUISIÇÃO NATIVA (Sem SDK pesado)
31+ const response = await fetch ( this . endpoint , {
32+ method : "POST" ,
33+ headers : {
34+ "Content-Type" : "application/json" ,
35+ "Authorization" : `Bearer ${ this . token } `
36+ } ,
37+ body : JSON . stringify ( {
5038 messages : [
5139 { role : "system" , content : systemPrompt } ,
5240 { role : "user" , content : `Erro: ${ errorMessage } \n\nDOM:\n${ truncatedDom } ` }
5341 ] ,
54- model : "gpt-4o" ,
55- temperature : 0.1 // Temperatura baixa = Mais precisão, menos criatividade
56- }
42+ model : "gpt-4o-mini" , // Modelo mais rápido e leve
43+ temperature : 0.1 ,
44+ max_tokens : 100 // Limita resposta para ser veloz
45+ } )
5746 } ) ;
5847
59- if ( response . status !== "200" ) {
60- console . error ( `[AIService] Erro na API: ${ response . status } ` ) ;
48+ if ( ! response . ok ) {
49+ console . error ( `[AIService] ❌ Erro API: ${ response . status } - ${ response . statusText } ` ) ;
50+ const errorText = await response . text ( ) ;
51+ console . error ( `[AIService] Detalhe: ${ errorText } ` ) ;
6152 return "Erro na API da IA" ;
6253 }
6354
64- const data = response . body as any ;
65- return data . choices ?. [ 0 ] ?. message ?. content || "Sem resposta." ;
55+ const data = await response . json ( ) as any ;
56+ const content = data . choices ?. [ 0 ] ?. message ?. content ;
57+
58+ console . log ( `[AIService] 📥 Resposta recebida: ${ content } ` ) ;
59+ return content || "Sem resposta." ;
6660
6761 } catch ( error : any ) {
68- console . error ( `[AIService] Exception: ${ error . message } ` ) ;
69- return "Erro interno no serviço de IA." ;
62+ console . error ( `[AIService] 💥 Exception: ${ error . message } ` ) ;
63+ // Se for erro de certificado (comum em empresa), avisa
64+ if ( error . cause ) console . error ( `[AIService] Causa: ${ error . cause } ` ) ;
65+ return `Erro interno: ${ error . message } ` ;
7066 }
7167 }
7268}
0 commit comments