Class: Bddgenx::IA::GeminiCliente

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

Overview

Cliente para interação com a API Gemini do Google para geração de conteúdo, aqui usado para criar cenários BDD no formato Gherkin.

Constant Summary collapse

GEMINI_API_URL =
'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent'.freeze

Class Method Summary collapse

Class Method Details

.detecta_idioma_arquivo(caminho_arquivo) ⇒ String

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

Parameters:

  • caminho_arquivo (String)

    Caminho do arquivo para detecção do idioma.

Returns:

  • (String)

    Código do idioma detectado (ex: ‘pt’), padrão ‘pt’.



122
123
124
125
126
127
128
129
130
131
132
# File 'lib/bddgenx/ia/gemini_cliente.rb', line 122

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' # idioma padrão caso não encontre

end

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

Gera cenários BDD baseados em uma história, solicitando à API Gemini o retorno no formato Gherkin com palavras-chave no idioma desejado.

Parameters:

  • historia (String)

    Texto base da história para gerar os cenários.

  • idioma (String) (defaults to: 'pt')

    Código do idioma, ‘pt’ por padrão.

Returns:

  • (String, nil)

    Cenários no formato Gherkin, ou nil em caso de erro.



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

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


  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 que instrui a IA a gerar cenários Gherkin no idioma indicado

  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  unless api_key\n    warn \"\u274C API Key do Gemini n\u00E3o encontrada no .env (GEMINI_API_KEY)\"\n    return nil\n  end\n\n  uri = URI(\"\#{GEMINI_API_URL}?key=\#{api_key}\")\n\n  # Estrutura do corpo da requisi\u00E7\u00E3o para a API Gemini\n  request_body = {\n    contents: [\n      {\n        role: \"user\",\n        parts: [{ text: prompt_base }]\n      }\n    ]\n  }\n\n  # Executa requisi\u00E7\u00E3o POST para a API Gemini\n  response = Net::HTTP.post(uri, request_body.to_json, { \"Content-Type\" => \"application/json\" })\n\n  if response.is_a?(Net::HTTPSuccess)\n    json = JSON.parse(response.body)\n\n    unless json[\"candidates\"]&.is_a?(Array) && json[\"candidates\"].any?\n      warn \"\u274C Resposta da IA sem candidatos v\u00E1lidos:\"\n      warn JSON.pretty_generate(json)\n      return nil\n    end\n\n    texto_ia = json[\"candidates\"].first.dig(\"content\", \"parts\", 0, \"text\")\n    if texto_ia\n      # Limpeza e sanitiza\u00E7\u00E3o do texto para manter padr\u00E3o Gherkin\n      texto_limpo = Bddgenx::GherkinCleaner.limpar(texto_ia)\n      Utils::StepCleaner.remover_steps_duplicados(texto_ia, idioma)\n\n      # Ajuste da diretiva de idioma na sa\u00EDda gerada\n      texto_limpo.sub!(/^# language: .*/, \"# language: \#{idioma}\")\n      texto_limpo.prepend(\"# language: \#{idioma}\\n\") unless texto_limpo.start_with?(\"# language:\")\n\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 nil\n    end\n  else\n    warn \"\u274C Erro ao chamar Gemini: \#{response.code} - \#{response.body}\"\n    return nil\n  end\nend\n"