wendellast commited on
Commit
3b4b1fb
·
1 Parent(s): 38451c9

feat: Adicionando funcionalidade de IA para chatbot, incluindo template de mensagem e comportamento de regra.

Browse files
Files changed (10) hide show
  1. .gitignore +2 -2
  2. README.md +1 -1
  3. app.py +44 -26
  4. data/data.json +30 -0
  5. prompt_bot.py +34 -0
  6. requirements.txt +82 -1
  7. server.py +30 -0
  8. util/access_token.py +15 -0
  9. util/extract_data.py +49 -0
  10. util/import_dataset.py +12 -0
.gitignore CHANGED
@@ -1,4 +1,4 @@
1
  venv
2
- Medflow-Bot
3
  .env
4
- .python-version
 
 
1
  venv
 
2
  .env
3
+ .python-version
4
+ __pycache__
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: CommitIa
3
  emoji: 💬
4
  colorFrom: yellow
5
  colorTo: purple
 
1
  ---
2
+ title: Commit-IA
3
  emoji: 💬
4
  colorFrom: yellow
5
  colorTo: purple
app.py CHANGED
@@ -1,31 +1,51 @@
 
 
1
  import gradio as gr
 
2
  from huggingface_hub import InferenceClient
3
 
4
- """
5
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
6
- """
7
- client = InferenceClient("meta-llama/Llama-3.2-3B-Instruct")
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
 
10
  def respond(
11
- message,
12
- history: list[tuple[str, str]],
13
- system_message,
14
- max_tokens,
15
- temperature,
16
- top_p,
17
- ):
18
- messages = [{"role": "system", "content": system_message}]
 
 
 
19
 
20
- for val in history:
21
- if val[0]:
22
- messages.append({"role": "user", "content": val[0]})
23
- if val[1]:
24
- messages.append({"role": "assistant", "content": val[1]})
 
25
 
26
- messages.append({"role": "user", "content": message})
27
 
28
- response = ""
 
29
 
30
  for message in client.chat_completion(
31
  messages,
@@ -34,19 +54,15 @@ def respond(
34
  temperature=temperature,
35
  top_p=top_p,
36
  ):
37
- token = message.choices[0].delta.content
38
-
39
  response += token
40
  yield response
41
 
42
 
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- demo = gr.ChatInterface(
47
  respond,
48
  additional_inputs=[
49
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
50
  gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
51
  gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
52
  gr.Slider(
@@ -57,6 +73,8 @@ demo = gr.ChatInterface(
57
  label="Top-p (nucleus sampling)",
58
  ),
59
  ],
 
 
60
  )
61
 
62
 
 
1
+ from typing import List, Optional
2
+
3
  import gradio as gr
4
+ from datasets import load_dataset
5
  from huggingface_hub import InferenceClient
6
 
7
+ from prompt_bot import prompt_for_template, template_bot
8
+ from util.extract_data import extrair_dados_template
9
+ from util.import_dataset import get_response_from_huggingface_dataset
10
+
11
+ descricao, regras, comportamento = extrair_dados_template()
12
+
13
+
14
+ MODEL: str = "meta-llama/Llama-3.2-3B-Instruct"
15
+
16
+ TEMPLATE_BOT = template_bot()
17
+ prompt_template = prompt_for_template(TEMPLATE_BOT)
18
+
19
+ # modify future
20
+ DATASET = load_dataset("wendellast/GUI-Ban")
21
+
22
+ client: InferenceClient = InferenceClient(model=MODEL)
23
 
24
 
25
  def respond(
26
+ message: str,
27
+ history: List[dict],
28
+ system_message: str,
29
+ max_tokens: int,
30
+ temperature: float,
31
+ top_p: float,
32
+ ) -> any:
33
+ response: Optional[str] = get_response_from_huggingface_dataset(message, DATASET)
34
+ if response:
35
+ yield response
36
+ return
37
 
38
+ prompt: str = prompt_template.format(
39
+ description=descricao,
40
+ regras=regras,
41
+ comportamento=comportamento,
42
+ mensagem=message,
43
+ )
44
 
45
+ print(prompt)
46
 
47
+ messages: List[dict] = [{"role": "system", "content": prompt}]
48
+ response: str = ""
49
 
50
  for message in client.chat_completion(
51
  messages,
 
54
  temperature=temperature,
55
  top_p=top_p,
56
  ):
57
+ token: str = message.choices[0].delta.content
 
58
  response += token
59
  yield response
60
 
61
 
62
+ demo: gr.ChatInterface = gr.ChatInterface(
 
 
 
63
  respond,
64
  additional_inputs=[
65
+ gr.Textbox(value="", label="System message"),
66
  gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
67
  gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
68
  gr.Slider(
 
73
  label="Top-p (nucleus sampling)",
74
  ),
75
  ],
76
+ title="Medflow-BOT",
77
+ type="messages",
78
  )
79
 
80
 
data/data.json ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "template": {
3
+ "description": "Você é uma assistente especializada em escrever mensagens de commit curtas, diretas e bem estruturadas. Suas mensagens seguem boas práticas, são semanticamente claras e comunicam de forma objetiva as alterações realizadas no código.",
4
+ "rules": [
5
+ "A mensagem deve ser baseada no que foi alterado no git diff e descrever as ações feitas.",
6
+ "Use frases curtas e diretas, separando as ações realizadas no commit por vírgulas.",
7
+ "**Fale das alterações do commit, separando com vírgulas e de forma simples e curta.**",
8
+ "Não fale o caminho dos arquivos alterados ou criados.",
9
+ "Não invente mensagens ou coisas que não têm no commit.",
10
+ "**Não use caracteres especiais como crase ou aspas.**",
11
+ "A primeira linha deve começar com o prefixo correto (feat, fix, chore).",
12
+ "Não inclua caminhos completos dos arquivos, apenas nomes principais se necessário.",
13
+ "Utilize obrigatoriamente o idioma **%s** na resposta.",
14
+ "Escreva a mensagem como se fosse em primeira pessoa.",
15
+ "A mensagem tem que ser com palavras curtas, diretas ao ponto, e mencionar todas as alterações feitas.",
16
+ "A saída deve ser **apenas a mensagem de commit final**, sem comentários ou explicações adicionais."
17
+ ],
18
+ "behavior": {
19
+ "tone": "Formal, amigável e acessível.",
20
+ "response_style": "Clara e objetiva, com mensagens de commit curtas, diretas e separadas por ação usando vírgulas. Explicações detalhadas apenas quando necessário.",
21
+ "examples": [
22
+ "feat: Adicionando funcionalidade de cadastro de usuários, criando validação de senha, ajustando layout do formulário.",
23
+ "fix: Corrigindo bug na autenticação, ajustando lógica de verificação de tokens.",
24
+ "chore: Renomeando variáveis para maior clareza, removendo comentários desnecessários.",
25
+ "refactor: Melhorando estrutura do código na função de busca, otimizando loops, ajustando nomenclatura.",
26
+ "docs: Atualizando README com instruções de instalação, adicionando seção de contribuições."
27
+ ]
28
+ }
29
+ }
30
+ }
prompt_bot.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain.prompts import PromptTemplate
2
+
3
+
4
+ def template_bot() -> str:
5
+ template: str = """
6
+ Descrição:
7
+ - Você é {description}
8
+ - Aqui estão algumas regras que você deve seguir:
9
+
10
+ Regras:
11
+ {regras}
12
+
13
+ se comporte assim:
14
+ {comportamento}
15
+
16
+
17
+ Usuário: {mensagem}
18
+ IA-BOT:
19
+ """
20
+ return template
21
+
22
+
23
+ def prompt_for_template(template_bot: str) -> str:
24
+ prompt_template: PromptTemplate = PromptTemplate(
25
+ input_variables=[
26
+ "description",
27
+ "regras",
28
+ "comportamento",
29
+ "mensagem",
30
+ ],
31
+ template=template_bot,
32
+ )
33
+
34
+ return prompt_template
requirements.txt CHANGED
@@ -1 +1,82 @@
1
- huggingface_hub==0.25.2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiofiles==23.2.1
2
+ aiohappyeyeballs==2.4.4
3
+ aiohttp==3.11.11
4
+ aiosignal==1.3.2
5
+ annotated-types==0.7.0
6
+ anyio==4.8.0
7
+ async-timeout==4.0.3
8
+ attrs==24.3.0
9
+ blinker==1.9.0
10
+ certifi==2024.12.14
11
+ charset-normalizer==3.4.1
12
+ click==8.1.8
13
+ datasets==3.2.0
14
+ dill==0.3.8
15
+ exceptiongroup==1.2.2
16
+ fastapi==0.115.6
17
+ ffmpy==0.5.0
18
+ filelock==3.16.1
19
+ Flask==3.1.0
20
+ Flask-Cors==5.0.0
21
+ frozenlist==1.5.0
22
+ fsspec==2024.9.0
23
+ gradio==5.12.0
24
+ gradio_client==1.5.4
25
+ greenlet==3.1.1
26
+ h11==0.14.0
27
+ httpcore==1.0.7
28
+ httpx==0.28.1
29
+ huggingface-hub==0.25.2
30
+ idna==3.10
31
+ itsdangerous==2.2.0
32
+ Jinja2==3.1.5
33
+ jsonpatch==1.33
34
+ jsonpointer==3.0.0
35
+ langchain==0.3.14
36
+ langchain-core==0.3.30
37
+ langchain-text-splitters==0.3.5
38
+ langsmith==0.2.11
39
+ markdown-it-py==3.0.0
40
+ MarkupSafe==2.1.5
41
+ mdurl==0.1.2
42
+ multidict==6.1.0
43
+ multiprocess==0.70.16
44
+ numpy==1.26.4
45
+ orjson==3.10.14
46
+ packaging==24.2
47
+ pandas==2.2.3
48
+ pillow==11.1.0
49
+ propcache==0.2.1
50
+ pyarrow==19.0.0
51
+ pydantic==2.10.5
52
+ pydantic_core==2.27.2
53
+ pydub==0.25.1
54
+ Pygments==2.19.1
55
+ python-dateutil==2.9.0.post0
56
+ python-dotenv==1.0.1
57
+ python-multipart==0.0.20
58
+ pytz==2024.2
59
+ PyYAML==6.0.2
60
+ requests==2.32.3
61
+ requests-toolbelt==1.0.0
62
+ rich==13.9.4
63
+ ruff==0.9.2
64
+ safehttpx==0.1.6
65
+ semantic-version==2.10.0
66
+ shellingham==1.5.4
67
+ six==1.17.0
68
+ sniffio==1.3.1
69
+ SQLAlchemy==2.0.37
70
+ starlette==0.41.3
71
+ tenacity==9.0.0
72
+ tomlkit==0.13.2
73
+ tqdm==4.67.1
74
+ typer==0.15.1
75
+ typing_extensions==4.12.2
76
+ tzdata==2024.2
77
+ urllib3==2.3.0
78
+ uvicorn==0.34.0
79
+ websockets==14.1
80
+ Werkzeug==3.1.3
81
+ xxhash==3.5.0
82
+ yarl==1.18.3
server.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dotenv import load_dotenv
2
+ from flask import Flask, jsonify, request
3
+ from flask_cors import CORS
4
+ from gradio_client import Client
5
+
6
+ load_dotenv()
7
+
8
+ port = 5003
9
+
10
+
11
+ app = Flask(__name__)
12
+
13
+ CORS(app)
14
+
15
+
16
+ @app.route("/bot", methods=["POST"])
17
+ def send_message():
18
+ data = request.get_json()
19
+ message = data.get("message")
20
+
21
+ client = Client("wendellast/test")
22
+ result = client.predict(
23
+ message=message, max_tokens=512, temperature=0.7, top_p=0.95, api_name="/chat"
24
+ )
25
+
26
+ return jsonify({"response": result})
27
+
28
+
29
+ if __name__ == "__main__":
30
+ app.run(host="0.0.0.0", port=port)
util/access_token.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ from dotenv import load_dotenv
4
+
5
+
6
+ def load_token(token_env):
7
+
8
+ load_dotenv()
9
+
10
+ token = os.getenv(token_env)
11
+
12
+ if token is None:
13
+ raise ValueError("Token não encontrado no arquivo .env")
14
+
15
+ return str(token)
util/extract_data.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+
3
+ try:
4
+ with open("data/data.json", "r", encoding="UTF-8") as file:
5
+ data: dict = json.load(file)
6
+ except:
7
+ raise "Error ao carregar config.json"
8
+
9
+
10
+ def extrair_dados_template(template: dict = data):
11
+ try:
12
+ if "template" not in template:
13
+ raise KeyError("'template' não encontrado no dicionário.")
14
+
15
+ template_data = template["template"]
16
+
17
+ descricao: str = template_data.get("description", "Descrição não disponível.")
18
+
19
+ if "rules" not in template_data:
20
+ raise KeyError("'rules' não encontrado em 'template'.")
21
+
22
+ regras: str = "\n".join([f"- {rule}" for rule in template_data["rules"]])
23
+
24
+ if "behavior" not in template_data:
25
+ raise KeyError("'behavior' não encontrado em 'template'.")
26
+
27
+ comportamento = []
28
+ for key, value in template_data["behavior"].items():
29
+ if key == "examples" and isinstance(value, list):
30
+ exemplos = "\n".join([f" * {ex}" for ex in value])
31
+ comportamento.append(f"- {key.capitalize()}:\n{exemplos}")
32
+ else:
33
+ comportamento.append(f"- {key.capitalize()}: {value}")
34
+
35
+ comportamento_str = "\n".join(comportamento)
36
+
37
+ return descricao, regras, comportamento_str
38
+
39
+ except KeyError as e:
40
+ print(f"Erro ao acessar a chave: {e}")
41
+ return None
42
+
43
+
44
+ """
45
+ descricao, regra, compoa = extrair_dados_template()
46
+ print(descricao)
47
+ print(regra)
48
+ print(compoa)
49
+ """
util/import_dataset.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+
4
+ def get_response_from_huggingface_dataset(message: str, DATASET) -> Optional[str]:
5
+ for data in DATASET["train"]:
6
+ if "dialog" in data and len(data["dialog"]) > 1:
7
+ input_text: str = data["dialog"][0].lower()
8
+ response_text: str = data["dialog"][1]
9
+
10
+ if input_text == message.lower():
11
+ return response_text
12
+ return None