Class: Bddgenx::IA::ChatGptCliente

Inherits:
Object
  • Object
show all
Defined in:
lib/bddgenx/ia/chatgtp_cliente.rb

Overview

Cliente para interação com a API do ChatGPT da OpenAI para gerar cenários BDD no formato Gherkin, com suporte a fallback para Gemini.

Constant Summary collapse

CHATGPT_API_URL =
'https://api.openai.com/v1/chat/completions'.freeze
MODEL =
'gpt-4o'

Class Method Summary collapse

Class Method Details

.detecta_idioma_arquivo(caminho_arquivo) ⇒ String

Detecta o idioma de um arquivo de feature pela linha “# language:”.



134
135
136
137
138
139
140
141
142
143
144
# File 'lib/bddgenx/ia/chatgtp_cliente.rb', line 134

def self.detecta_idioma_arquivo(caminho_arquivo)
  return 'pt' unless File.exist?(caminho_arquivo)

  File.foreach(caminho_arquivo) do |linha|
    if linha =~ /^#\s*language:\s*(\w{2})/i
      return $1.downcase
    end
  end

  'pt'
end

.fallback_com_gemini(historia, idioma) ⇒ String

Método de fallback que chama o GeminiCliente para gerar cenários, usado quando a API do ChatGPT não está disponível ou ocorre erro.



123
124
125
126
# File 'lib/bddgenx/ia/chatgtp_cliente.rb', line 123

def self.fallback_com_gemini(historia, idioma)
  warn "🔁 Tentando gerar com Gemini como fallback..."
  GeminiCliente.gerar_cenarios(historia, idioma)
end

.gerar_cenarios(historia, idioma = 'pt') ⇒ String

Gera cenários BDD a partir de uma história fornecida, solicitando à API do ChatGPT a criação dos cenários em formato Gherkin. Se a API key não estiver configurada ou houver erro na requisição, utiliza fallback com o GeminiCliente.



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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/bddgenx/ia/chatgtp_cliente.rb', line 23

def self.gerar_cenarios(historia, idioma = 'pt')
  api_key = Bddgenx.configuration.openai_api_key  # para ChatGPT


  unless api_key
    warn "❌ API Key do ChatGPT não encontrada no .env (OPENAI_API_KEY)"
    return fallback_com_gemini(historia, idioma)
  end

  # Palavras-chave Gherkin para português e inglês

  keywords_pt = {
    feature: "Funcionalidade",
    scenario: "Cenário",
    scenario_outline: "Esquema do Cenário",
    examples: "Exemplos",
    given: "Dado",
    when: "Quando",
    then: "Então",
    and: "E"
  }

  keywords_en = {
    feature: "Feature",
    scenario: "Scenario",
    scenario_outline: "Scenario Outline",
    examples: "Examples",
    given: "Given",
    when: "When",
    then: "Then",
    and: "And"
  }

  keywords = idioma == 'en' ? keywords_en : keywords_pt

  # Prompt base enviado ao ChatGPT, instruindo a saída no formato correto

  prompt_base = "    Gere cen\u00E1rios BDD no formato Gherkin, usando as palavras-chave de estrutura no idioma \\\"\#{idioma}\\\":\n      Feature: \#{keywords[:feature]}\n      Scenario: \#{keywords[:scenario]}\n      Scenario Outline: \#{keywords[:scenario_outline]}\n      Examples: \#{keywords[:examples]}\n      Given: \#{keywords[:given]}\n      When: \#{keywords[:when]}\n      Then: \#{keywords[:then]}\n      And: \#{keywords[:and]}\n\n    Aten\u00E7\u00E3o: Os textos e descri\u00E7\u00F5es dos cen\u00E1rios e passos devem ser escritos em portugu\u00EAs, mesmo que as palavras-chave estejam em ingl\u00EAs.\n\n    Hist\u00F3ria:\n    \#{historia}\n  PROMPT\n\n  uri = URI(CHATGPT_API_URL)\n  request_body = {\n    model: MODEL,\n    messages: [\n      {\n        role: \"user\",\n        content: prompt_base\n      }\n    ]\n  }\n\n  headers = {\n    \"Content-Type\" => \"application/json\",\n    \"Authorization\" => \"Bearer \#{api_key}\"\n  }\n\n  response = Net::HTTP.post(uri, request_body.to_json, headers)\n\n  if response.is_a?(Net::HTTPSuccess)\n    json = JSON.parse(response.body)\n    texto_ia = json.dig(\"choices\", 0, \"message\", \"content\")\n\n    if texto_ia\n      texto_limpo = Bddgenx::GherkinCleaner.limpar(texto_ia)\n      Utils::StepCleaner.remover_steps_duplicados(texto_ia, idioma)\n\n      # Ajusta a linha de idioma no arquivo gerado\n      texto_limpo.sub!(/^# language: .*/, \"# language: \#{idioma}\")\n      texto_limpo.prepend(\"# language: \#{idioma}\\n\") unless texto_limpo.start_with?(\"# language:\")\n      return texto_limpo\n    else\n      warn \"\u274C Resposta da IA sem conte\u00FAdo de texto\"\n      warn JSON.pretty_generate(json)\n      return fallback_com_gemini(historia, idioma)\n    end\n  else\n    warn \"\u274C Erro ao chamar ChatGPT: \#{response.code} - \#{response.body}\"\n    return fallback_com_gemini(historia, idioma)\n  end\nend\n"