From 9da9402287bbe64a9fc4204cc0e2d93f957353f1 Mon Sep 17 00:00:00 2001 From: Ruan Rabello <142259703+Ruanrabello@users.noreply.github.com> Date: Wed, 10 Dec 2025 17:18:49 -0300 Subject: [PATCH] Assitente --- .../Config/__pycache__/keys.cpython-310.pyc | Bin 0 -> 221 bytes .../Config/__pycache__/keys.cpython-313.pyc | Bin 0 -> 239 bytes .../AssistenteVirtual/Config/keys.py | 1 + .../Core/__pycache__/comandos.cpython-310.pyc | Bin 0 -> 1279 bytes .../Core/__pycache__/comandos.cpython-313.pyc | Bin 0 -> 3485 bytes .../__pycache__/historico.cpython-310.pyc | Bin 0 -> 1225 bytes .../__pycache__/historico.cpython-313.pyc | Bin 0 -> 1925 bytes .../Core/__pycache__/ia.cpython-310.pyc | Bin 0 -> 608 bytes .../Core/__pycache__/ia.cpython-313.pyc | Bin 0 -> 850 bytes .../Core/__pycache__/voz.cpython-310.pyc | Bin 0 -> 1429 bytes .../Core/__pycache__/voz.cpython-313.pyc | Bin 0 -> 2356 bytes .../AssistenteVirtual/Core/comandos.py | 87 ++++++++++++++++++ .../AssistenteVirtual/Core/historico.py | 33 +++++++ .../AssistenteVirtual/Core/ia.py | 41 +++++++++ .../AssistenteVirtual/Core/voz.py | 47 ++++++++++ .../AssistenteVirtual/data/Historico.json | 82 +++++++++++++++++ .../__pycache__/historico.cpython-313.pyc | Bin 0 -> 1918 bytes AssistenteVirtual/AssistenteVirtual/main.py | 31 +++++++ 18 files changed, 322 insertions(+) create mode 100644 AssistenteVirtual/AssistenteVirtual/Config/__pycache__/keys.cpython-310.pyc create mode 100644 AssistenteVirtual/AssistenteVirtual/Config/__pycache__/keys.cpython-313.pyc create mode 100644 AssistenteVirtual/AssistenteVirtual/Config/keys.py create mode 100644 AssistenteVirtual/AssistenteVirtual/Core/__pycache__/comandos.cpython-310.pyc create mode 100644 AssistenteVirtual/AssistenteVirtual/Core/__pycache__/comandos.cpython-313.pyc create mode 100644 AssistenteVirtual/AssistenteVirtual/Core/__pycache__/historico.cpython-310.pyc create mode 100644 AssistenteVirtual/AssistenteVirtual/Core/__pycache__/historico.cpython-313.pyc create mode 100644 AssistenteVirtual/AssistenteVirtual/Core/__pycache__/ia.cpython-310.pyc create mode 100644 AssistenteVirtual/AssistenteVirtual/Core/__pycache__/ia.cpython-313.pyc create mode 100644 AssistenteVirtual/AssistenteVirtual/Core/__pycache__/voz.cpython-310.pyc create mode 100644 AssistenteVirtual/AssistenteVirtual/Core/__pycache__/voz.cpython-313.pyc create mode 100644 AssistenteVirtual/AssistenteVirtual/Core/comandos.py create mode 100644 AssistenteVirtual/AssistenteVirtual/Core/historico.py create mode 100644 AssistenteVirtual/AssistenteVirtual/Core/ia.py create mode 100644 AssistenteVirtual/AssistenteVirtual/Core/voz.py create mode 100644 AssistenteVirtual/AssistenteVirtual/data/Historico.json create mode 100644 AssistenteVirtual/AssistenteVirtual/data/__pycache__/historico.cpython-313.pyc create mode 100644 AssistenteVirtual/AssistenteVirtual/main.py diff --git a/AssistenteVirtual/AssistenteVirtual/Config/__pycache__/keys.cpython-310.pyc b/AssistenteVirtual/AssistenteVirtual/Config/__pycache__/keys.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae0f1bf25cf158075a66b209f5e97877f2748c0e GIT binary patch literal 221 zcmd1j<>g`k0=F;bnO;EpF^Gc<7=auIATH(r5-AK(3@MDk44O<)7U{*=@dc62S)sYv zkx^czS#Ey0W+5Jd{^9N^l}W~KksgL==2-z@$yo*^X2t%={(*u1iAENMX?~iFw|Lxx z`~%}113crsT_aaA6fptK1{1%`ldWPxi&Kk=V~R=>^O9m*^2_sb@)J{vfvn`>7{}t` s%;J*Nypq%y=ls01%=DP-)XHMLg34PQHo5sJr8%i~AO{zN4CG({07Qg4XaE2J literal 0 HcmV?d00001 diff --git a/AssistenteVirtual/AssistenteVirtual/Config/__pycache__/keys.cpython-313.pyc b/AssistenteVirtual/AssistenteVirtual/Config/__pycache__/keys.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a33e744eee23a70e303e501c125638977412408 GIT binary patch literal 239 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 literal 0 HcmV?d00001 diff --git a/AssistenteVirtual/AssistenteVirtual/Core/__pycache__/historico.cpython-313.pyc b/AssistenteVirtual/AssistenteVirtual/Core/__pycache__/historico.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..917f130035db823cbf403a3f3009741cc10f5e90 GIT binary patch literal 1925 zcmb_c&2Jl35TE_9ch`xN*l|)w0K561*^0ysQk4(Ul#qfF5Q*e%P?0S~EAPf#WP8nf zPE8PsQaBWHX~c)};LaqD_J$c2h6!W%j(BzD5n8|5MEm}5fNw3zv53pNo>vpO*?{MTKuu@(g9>2#qvRTa9hE>d| zvcucd5ledcx)U@%!VFUw^h0Fpa3CqSDmN>))^4saYL&BLE$-z4rc{_Wl}hO80(e z*T&qDfYJ#a!CUXQPY=U)-P66ocDsV&c5i6(D;vtDy0!RlbXUHFId;fp!Cc-G*rqiJdncDQn~WDwYplMP1@1SagDV3ERnVggiEtP_j#e zWknUp^GxXl#$H55S%e8Ml~LWWvX))MY!T4RYjdbTA2P!wO1_(1DY#b9db6r3>L1Gr{8|FPA{cP_PdwHu+ z`Um#T;aMDCI)v=s$H##jVgRg0`+t@Pjs%cZ*P|-Am_NPSZ2>ll+_JevAj~y+nXyIy z@@oa#Sjn4Hgx$v=Ne7YPFyXkz(DE3RUt?DvLF8DJxVGaM&rKbNB(AH5(xB_+Z_;6H Ag+Fn?S}AhZCh@Yn4z{DVXmjIQ zi3i{XcqLys@d6w;0AticN1D%Lk7xYZpUvLhh@gG_^-%kakRNe!-4dJ}p}YGCl1OMt z2OJ>Aw546b6CesyB9lwtOy)9`*%#ocWN%4X{KP6!LSQG>e8O>j^5*61#qq1>ix6O)7KgUO@QiSC^jy)S7< zJ0n#aicUEvmdaT`9%UY~y46_6S-ldT@7AVUx5{hNJ4{(6eC)k4x>hdaSH(77s7yIF z>tnMn?5wo&#_HPG9CN&|%B>Ba9a68(z4=b;KCb^hs2^AFkhiPsM)arEQ*+k0Mo5QI z?W$wvun*Ev)y!B`X)#@2gdL>T3A@k&6(#NtLIDgYEg<__FbWj1Kl>>IdlOS7%*!mW zB?@Gt2z+;D`VV?JMOmDU`r9Hx-20!@HMoImp*X~++O+CPd?6RV)0m85L`Rg}`Uk5z BmN@_b literal 0 HcmV?d00001 diff --git a/AssistenteVirtual/AssistenteVirtual/Core/__pycache__/ia.cpython-313.pyc b/AssistenteVirtual/AssistenteVirtual/Core/__pycache__/ia.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e126d6809bebf62e07936945d244cb49441149a2 GIT binary patch literal 850 zcmZuv&1(}u6rb78q}enH+7BhrQbJ1(o1k7=DMG2GwJFtRi6Ab7bvvf3o1HkbRck%u zs3*M?JbLv%@ZZ=|!azas)LSI|1AJ2xXrT}0eaw6B_uiX%!)$f}0oBfygB=5*KhhYJ zHd2OnK{-JVa&Qf8V}|FYuGExmm8tW{#S6$)9d!jW%`qJPHhP7b-qOnEnFJ_fp=~ny z2BfuFf4tXRd-AAR+js`H>2-qUYjU*fD>8CKI!G1H@F%bn)WFhPMG zDjT~(JLH6w6`?U25@Gr@ib)iIxEY3C+q3Ug?%2yO>>%Q?7sU{!x9L6!MXF6W_gaKA zIa1jah93ryCp7=Si$%t#?M_JIfJPi#jCircKA?e5xG+b_EG=_&2^LAPwn!fYJfjW{V%5LzHlTIxGRA}Ot>-?Z@1l@;``lfJ9^Ez00StN~ zPXiVodLdjh;s#!&b0pHxX4_-Uz+*E22}^}|1gwktW|u zs7lfJiWv6;pF|mr@ z_7ZEZXDubxQqQU;R<*m)&*Zy1L#PO=w_7%Z)`IP0a-&3MoklN%Rt0vBGr1j1e&9u) zKM$(8 D*|o(Q literal 0 HcmV?d00001 diff --git a/AssistenteVirtual/AssistenteVirtual/Core/__pycache__/voz.cpython-310.pyc b/AssistenteVirtual/AssistenteVirtual/Core/__pycache__/voz.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f434bc32195fd0206d52221ba37a45bbbdcc1b3 GIT binary patch literal 1429 zcmYjQPmdcl6t_KpGMOaX?t)N}RxpAKIS{E*kPIkNBpP(>n;DvHLjqXopwHf)1=bNoGeMxMg@06m151%8ZOe zSbkzv!pF%(&5}%wlY)O$a;cKk>eQ&DNOhVFK}aifqIsbeE6<*v{iu3-=dPRb6%coS#(`n&2_<|<_dw9NEx8zYS6 zkfwh}Y2Js++G=2Z|8@i8GWj`0Tk+c>9VF1eBD4b*F zv*4602%Hwq$t8w!a)4@-(Wo)qz1Rg24VMqljn=+s`UP+R&Ib+<)|`8n`)dw>=dtHv zS*_I^i1$j@jNv;;`8HS_{(HcQ#NE1NB2fvj2sm{W*sDU>>s?{OXw+%+~7Kj)}z@;|c{+k4jRUwQBOO*?SZ=@g4J}c oGrrV8-Amm@^uZWjbk09?kJ-EiB0>?=8+kGG(8e*@0=?b&4~4ODwg3PC literal 0 HcmV?d00001 diff --git a/AssistenteVirtual/AssistenteVirtual/Core/__pycache__/voz.cpython-313.pyc b/AssistenteVirtual/AssistenteVirtual/Core/__pycache__/voz.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..28057b812b97afa01c27bab8f8b471e9c718134f GIT binary patch literal 2356 zcmai0O>7%Q6rSDn+UwuAagrKn>rIoku}D&dHWE!qD-#Mrh=9CuD-=uCVo#hc&aO4P zPTJ6_IkstOdI4DiL@JP4ICAPWL|l=r7&%NM6v3&th#(cU7v9)juPdlJmS^7IyqS6L zeb3$t27L&|??0Z>ZhH{=lQH%XTf|-;htTIpK??UCBF&W}e1jK=kmi$;y~SA%qwy9) z#576<9F0vKMhZU;p4lLtv?sZ*Nq5eQpt#2QrbI^1u@M#bGd7V<4^3L}v`_Lq$BUHq zDTqBe+4tZ5j(^4bG9m%R2Xipb#r=<%@iY}pwWy6#7f~(zXd6V-yR*=g7G)sE~?i_d{g9vwn6tw_NeTrE|{ z(iv|V&A4q<(rZ)BnnHHGp0V^h7B*#PS%w?*qnUP|JxGlrq;oS}wxuGZIQA;Xa|~)p z=Mr4Lwa#+0Xi|uwSuXCHUXm27&lzM`e#AmhVp;v;>s#_ULJV0oxt+1e`-!c~Uf}!Tj^pugq>4a%&riJ04^BS>AY5~Lq zrx%Q+(c)$5Z`?4`@Jd)su}GL2Ov`AiYkyh1vseknmd|bZ!>gxnoL-&0F}Wp$c6m{Z zZ%cty--_?f*sb8U)KizDRViBTtx2&47pqFKU#0$kw*5VOh-22lN_b!`v38;oI#!p4 zs?yNYT>%tN%>8iM*Jl$4(fUDO;;gWKER>iK)+a=uv!H4ZRt${-{H0NVGi^n(T~cik za-hv49nIKn0@{O<+833V!Yjfl{zb**l%dW+yMd1bL@0NsgoDoQZ0Z81xD@deuk#%@ zbf@@dOHlFXLW)nei`3qY+93PCwv-a=m)a0i4^ z?HAzW?MK7N_Rk`fUqPMt&umAOjJ-+2?g_31{+#kuL!F z3&tV_&!(jk%Usl~IVu#ePFUZHyQna)WvQr^a+*O{rl@yO{RC$g4U#ii!<1nVmMYq1 zK%htl?1?eUF39rm3Vh91&4Q!57rIGvD2Z@RV)S2z@ zfqHnL3gDdD3=drwAA6ARrCnc_*xk^KRKp|p@q>INJW>h2eO&}scYph8qsb2Kc>wcIw zT)wGp&qi->YEX!WsHb?@vdl{-X}4L#I6IeV#hg_PftrWkLYSy8X{Uk^=9juOU9(7t zk$w|fA3~xrv7jmD9frUk4n%n^*XWLo5Py&MK!%!0klvU#a-{-3LtXE9G}Ky9R+nfjWv-QMBB*7O9~l4j)}R zQA5XeyuEdAf7RQ+Hniz|b=mFc_pcqjzwd7R-tgVw8an=$+snoGqP<)<8H4lx1yhsg AtN;K2 literal 0 HcmV?d00001 diff --git a/AssistenteVirtual/AssistenteVirtual/Core/comandos.py b/AssistenteVirtual/AssistenteVirtual/Core/comandos.py new file mode 100644 index 0000000..80eaf4f --- /dev/null +++ b/AssistenteVirtual/AssistenteVirtual/Core/comandos.py @@ -0,0 +1,87 @@ +import webbrowser #? Importa o modulu que permite que o python abra urls no navegador, como youtube etc +import datetime #? módulo de data/hora +import os #? módulo do sistema operacional +from googleapiclient.discovery import build #? importa a função build da biblioteca googleapiclient. Esta função é crucial para conectar seu código à API de Dados do YouTube. + +YOUTUBE_API_KEY = "AIzaSyCPtKQkPYuKihl1RRmNsEe9HFfy-b7ZxMw" +youtube = build("youtube", "v3", developerKey=YOUTUBE_API_KEY) #? Cria um objeto chamado youtube que será usado para fazer todas as chamadas à API, meio que o telefone para ligar para o servidor + + +def abrir_youtube(): + webbrowser.open("https://www.youtube.com/") + return "Abrindo YouTube." + + +def abrir_google(): + webbrowser.open("https://www.google.com.br/index.html") + return "Abrindo Google." + + +def dizer_hora(): #? pega a hora atual e retorna uma string formatada. + agora = datetime.datetime.now().strftime("%H:%M") #? retorna um objeto datetime com data e hora atuais e converte esse objeto em uma str formatada, %H = hora com 2 dígitos, %M = minuto com 2 dígitos + return f"Agora são {agora}" + + +def abrir_programa(caminho): #? abre um programa no Windows pelo caminho completo. + try: + os.startfile(caminho) + return f"Abrindo programa em: {caminho}" + except Exception as e: + return f"Erro ao abrir o programa: {e}" + + +def buscar_video(termo): #? Busca o primeiro vídeo correspondente ao termo. + req = youtube.search().list( #? constrói a requisição para a API + q=termo, #? termo de busca + part="snippet", #! especifica que quer o trecho snippet dos resultados (título/descrição). + maxResults=1, #? pede só 1 resultado + type="video" #? restringe a busca a vídeos (não playlists ou canais) + ) + + res = req.execute() + + if not res["items"]: #? resposta da API tem uma estrutura JSON; se nada for encontrado, none em caso de erro e tals + return None + + video_id = res["items"][0]["id"]["videoId"] + return f"https://www.youtube.com/watch?v={video_id}" + + +def abrir_video(termo): + url = buscar_video(termo) #? chama a função para obter a url. 1- envia a requisição para a API do YouTube, 2- recebe a lista de resultados, 3- pega apenas o primeiro vídeo retornado, 4- extrai o videoId, 5- e monta a url(exempli: https://www.youtube.com/watch?v=VIDEO_ID_AQUI) + + if not url: + return "Não encontrei esse vídeo. Verifique o nome ou sua API KEY." + + webbrowser.open(url) + return f"Reproduzindo {termo} no YouTube." + + +def interpretar_comando(texto): + texto = texto.lower() #? Deixa tudo em minusculo + + comandos_musica = ["tocar", "ouvir", "música", "reproduzir"] #? Palavras chaves para exexutar a função + + for cmd in comandos_musica: #? Faz loop dentro da lista de palavras de ativação + if cmd in texto: #? Procura essa palavra no testo que vc falou + indice = texto.find(cmd) #? ele pega o indice aonde esta a plavra de ativação + termo_busca = texto[indice + len(cmd):].strip() #? e pega o texto a frente(exemplo: tocar ride, ele pega ride para pesquisar) + + if termo_busca: + return abrir_video(termo_busca) + else: + return "Qual música você quer ouvir?" + + # ---------------------------------- + # 📌 Comandos básicos + # ---------------------------------- + if "youtube" in texto: + return abrir_youtube() + elif "google" in texto: + return abrir_google() + elif "hora" in texto: + return dizer_hora() + elif "calculadora" in texto: + return abrir_programa("C:\\Windows\\System32\\calc.exe") + + return None diff --git a/AssistenteVirtual/AssistenteVirtual/Core/historico.py b/AssistenteVirtual/AssistenteVirtual/Core/historico.py new file mode 100644 index 0000000..e57cdcf --- /dev/null +++ b/AssistenteVirtual/AssistenteVirtual/Core/historico.py @@ -0,0 +1,33 @@ +import json # ? importa biblioteca para salvar e carregar estruturas python em JSON +import os # ? Importa funçoes relacionadas ao sistema + +CAMINHO_HISTORICO = "C:/Users/rrsilva/Downloads/Code/Assistente/data/Historico.json" + +def carregar_historico(): # ? Carrega o historico do arquivo JSON + if os.path.exists(CAMINHO_HISTORICO): # ? Verifica se o ficheiro data/historico.json existe. Se não existir, a função vai retornar uma lista vazia no final. + try: + with open(CAMINHO_HISTORICO, "r", encoding="utf-8") as f: # ? Abre o ficheiro em modo leitura ("r") com codificação UTF-8. + return json.load(f) + except json.JSONDecodeError: + return [] + return [] + + +def salvar_historico(historico): # ? recebe a lista historico e a grava no ficheiro JSON.. + with open(CAMINHO_HISTORICO, "w", encoding="utf-8") as f: # ? Abre o ficheiro em modo escrita ("w"), + json.dump(historico, f, ensure_ascii=False, indent=2) + + +def adicionar_mensagem(historico, role, content): # ? Adiciona nova mensagem ao historico. + historico.append({"role": role, "content": content}) # ? Acrescenta um dicionário com as chaves role e content à lista historico. Exemplo: {"role": "user", "content": "Olá"}. + + if len(historico) > 50: # ? Se o tamanho do histórico exceder 20 entradas, + historico.pop(0) # ? remove a primeira (mensagem mais antiga) + + salvar_historico(historico) + return historico + + +def limpar_historico(): # ? Apaga todo o historico + if os.path.exists(CAMINHO_HISTORICO): + os.remove(CAMINHO_HISTORICO) diff --git a/AssistenteVirtual/AssistenteVirtual/Core/ia.py b/AssistenteVirtual/AssistenteVirtual/Core/ia.py new file mode 100644 index 0000000..9d29bcb --- /dev/null +++ b/AssistenteVirtual/AssistenteVirtual/Core/ia.py @@ -0,0 +1,41 @@ +from groq import Groq #? 📌 Importa a classe groq que é responsável por fazer chamadas para o endpoint +from Config.keys import GROQ_API_KEY #? 📌 Esta importando a variavel/chave do arquivo ja criado da past config + +client = Groq(api_key= GROQ_API_KEY) #? 📌 Equivale a abrir a conexão para chamar a API. + +def chamar_ia(mensagem, historico=None): #? 📌 função que recebe o texto que o usuario digitou e a lista de mensagens anteriores + if historico is None: #? 📌 Se for a primeira vez chamando a função, ainda não existe histórico entap cria uma função + historico =[] + + messages = historico + [ + {"role": "user", "content": mensagem} #? 📌 Pega o histórico e adiciona a mensagem nova, cada item é um dicionário (Estrutura exigida pela api) + ] + + resposta = client.chat.completions.create( #! Chama o endpoint chat/completions + model="llama-3.1-8b-instant", #! Passa o modelo + messages=messages #! Envia as mensagens (histórico + nova) + ) + + texto = resposta.choices[0].message.content #! Pega só o texto que a IA gerou + return texto + + +''' + A resposta da Groq vem dentro de um array choices. +1-Você pega a primeira resposta (0) +2-Depois pega o atributo message +3-E por fim pega somente o texto (content) + +💡 Exemplo da estrutura real: +{ + "choices": [ + { + "message": { + "role": "assistant", + "content": "Olá! Como posso ajudar?" + } + } + ] +} +''' + \ No newline at end of file diff --git a/AssistenteVirtual/AssistenteVirtual/Core/voz.py b/AssistenteVirtual/AssistenteVirtual/Core/voz.py new file mode 100644 index 0000000..9e4fdbc --- /dev/null +++ b/AssistenteVirtual/AssistenteVirtual/Core/voz.py @@ -0,0 +1,47 @@ +import pyttsx4 #? Importa biblioteca para sintese de voz +import speech_recognition as sr #? Importa biblioteca que converte oque eu falo em texto +import time #? importa biblioteca com funcoes relacionadas ao tempo + +# Inicializadores +reconhecedor = sr.Recognizer() #! Objeto que gerencia a captura/interpretacão de áudio +sintetizador = pyttsx4.init('sapi5') #? Inicializa o engine do pyttsx4 e escolhe o driver sapi5 +sintetizador.setProperty('rate', 220) #? Ajusta a velocidade de fala (palavras por minuto). +sintetizador.setProperty('volume', 1.0) #? Define o volume da fala; 1.0 + +voices = sintetizador.getProperty('voices') #? Recupera a lista de vozes disponíveis do engine +sintetizador.setProperty('voice', voices[0].id) #? Define a voz a ser usada; aqui usa a primeira voz disponível + + +def falar_texto(texto): #? Converte texto em voz + texto = (f"Senhor, {texto}") #? (adiciona no início) a string "Senhor, " ao texto recebido + if not texto.strip(): #? Verifica se texto está vazio ou contém só espaços(strip() remover espaços em branco nas extremidades). Se estiver vazio, vai evitar tentar falar algo.) + return + try: + time.sleep(1) #? Pausa de 1 segundo antes de falar + sintetizador.say(texto) #? Faz o computador falar. + sintetizador.runAndWait() #? Bloqueante: espera terminar de falar + except Exception as e: + print(f"❌ Erro ao falar: {e}") #? Captura qualquer exceção que ocorra dentro do try (por exemplo, problema com driver de áudio) + + +def ouvir_microfone(): #? Ouvindo o microfone e retornando texto transcrito + with sr.Microphone() as mic: #? Cria um objeto que representa o dispositivo de microfone do seu computador. as mic significa: dê o nome mic a esse objeto do microfone. + print("🎤 Ouvindo...") + reconhecedor.adjust_for_ambient_noise(mic, duration=1) #? Ajusta o ruído + audio = reconhecedor.listen(mic) #? grava até detectar silêncio + + try: + texto = reconhecedor.recognize_google(audio, language="pt-BR") #? Usa o sistema de voz do Google grátis para converter áudio → texto + print(f"Você disse: {texto}") + + wake_word = "jarvis" #? palavra de ativação + + if texto.lower().startswith(wake_word): #? Verifica se o texto transcrito, em letras minúsculas, começa com a wake word + return texto[len(wake_word):].strip() #? Remove o nome antes de mandar pra IA, Retorna a parte do texto após a wake word: usa slicing para pular os primeiros caracteres + else: + print("Aguardando palavra de ativação") + return "" + except: + print("❌ Não entendi.") + return "" + diff --git a/AssistenteVirtual/AssistenteVirtual/data/Historico.json b/AssistenteVirtual/AssistenteVirtual/data/Historico.json new file mode 100644 index 0000000..fb8438c --- /dev/null +++ b/AssistenteVirtual/AssistenteVirtual/data/Historico.json @@ -0,0 +1,82 @@ +[ + { + "role": "user", + "content": "me fodendo que não funcionou" + }, + { + "role": "assistant", + "content": "Parece que estamos em um loop de expressões idiomáticas frustrantes!\n\nVou tentar mudar de assunto e criar um novo fluxo de conversa. Você está se sentindo frustrado ou estressado em algum momento da sua vida? Quer falar sobre isso?" + }, + { + "role": "user", + "content": "pode perguntar qualquer coisa" + }, + { + "role": "assistant", + "content": "Você está se sentindo um pouco como um boneco de palavras!\n\nVamos fazer algo diferente. Qual é o seu hobby favorito? É ler, jogar videogame, praticar esportes, cozinhar ou algo completamente diferente?\n\n(Vou perguntar algo que seja simples e fácil de responder!)" + }, + { + "role": "user", + "content": "cinema" + }, + { + "role": "assistant", + "content": "Parece que estamos nos afundando no cinema!\n\nVamos dar um salto e criar um novo cenário. Se você estivesse em um filme de cinema, qual seria o seu papel? Você seria um herói que salva o mundo, um vilão que busca o poder, um personagem comum que se encontra em um mundo de fantasia, ou algo completamente diferente?\n\n(Vamos criar uma nova história!)" + }, + { + "role": "user", + "content": "no Instituto res" + }, + { + "role": "assistant", + "content": "Parece que estamos em X-Men!\n\nNo Instituto Charles Xavier, você é... Magneto, o líder dos mutantes com poderes sobre a magnetização?\n\n(Vamos explorar a realidade de X-Men!)" + }, + { + "role": "user", + "content": "Instituto ha" + }, + { + "role": "assistant", + "content": "Parece que estamos em um loop de \"Instituto ha\"!\n\nVamos dar um salto e criar um novo cenário. O Instituto que você está me perguntando sobre... é o Xavier Institute para jovens superdotados em X-Men ou é outro tipo de instituição?\n\n(Vamos tentar entender o que você está perguntando!)" + }, + { + "role": "user", + "content": "conte uma piada" + }, + { + "role": "assistant", + "content": "Parece que estamos em um loop de \"conte uma piada\"!\n\nVou tentar contar uma piada:\n\nPor que o PC foi ao doutor?\n\nPorque estava com um problema de \"processamento\"!\n\n(Espere um minuto, vou tentar novamente!)\n\nPor que o homem levou um cavalo para o bar?\n\nPorque queria um sério \"tratamento\"!\n\n(Espere, vou tentar mais uma vez!)\n\nPor que o cientista abandonou a pesquisa sobre os gatos?\n\nPorque os resultados eram um \"purr-blemo\"!\n\n(Vamos ver se a próxima piada funciona!)" + }, + { + "role": "user", + "content": "Jarvis Pará" + }, + { + "role": "assistant", + "content": "Parece que estamos em um loop de \"Jarvis Pará\"!\n\nVou tentar entender... Você está se referindo a Edgar Jarvis, o assistente lógico de Tony Stark em Iron Man?\n\n Ou talvez você esteja se referindo a Pará, um estado da Amazônia brasileira?\n\n Ou talvez seja algo completamente diferente?\n\n(Vamos tentar encontrar o que você está procurando!)" + }, + { + "role": "user", + "content": "Quantos graus está fazendo hoje" + }, + { + "role": "assistant", + "content": "Parece que estamos em um loop de \"quantos graus está fazendo hoje\"!\n\nInfelizmente, eu não tenho acesso a informações em tempo real, então não posso fornecer a temperatura atual. Além disso, eu não sei onde você está, portanto, não consigo informar a temperatura local.\n\nSe você quiser saber a temperatura, eu sugiro verificar um site de notícias online, um aplicativo de clima ou um localizador de temperatura em sua região." + }, + { + "role": "user", + "content": "você tem acesso para acessar esse site e verificar informação" + }, + { + "role": "assistant", + "content": "Eu tenho acesso limitado a informações online, mas não posso acessar sites específicos nem verificar informações em tempo real da mesma forma que um navegador ou um search engine.\n\nNo entanto, posso tentar encontrar a resposta de forma indireta. Poderia você me dizer qual é a sua localização ou qual é o tipo de informação que você está procurando (por exemplo, temperatura em uma cidade específica, temperatura global, previsão do tempo, etc.)?\n\nEssa informação pode me ajudar a procurar por informações relevantes e fornecer uma resposta aproximada." + }, + { + "role": "user", + "content": "eu quero saber a temperatura do Rio de Janeiro eu moro na Taquara" + }, + { + "role": "assistant", + "content": "Entendi melhor agora!\n\nSe você está em Taquara, que é uma cidade localizada no estado do Rio de Janeiro, Brasil, eu posso tentar encontrar a temperatura atual para você.\n\nNo entanto, como eu disse anteriormente, eu não tenho acesso ao tempo real. Mas posso sugerir algumas opções para que você possa saber a temperatura atual de Taquara ou do Rio de Janeiro:\n\n1. Verifique o aplicativo do tempo no seu telefone: você pode baixar aplicativos como ClimaTem, Tempo, ou Weather Channel que fornecem previsão de tempo e temperatura atual.\n2. Visite o site do National Weather Service (NWS) da América do Norte, que fornece informações sobre temperatura e previsão de tempo para locais em todo o mundo.\n3. Verifique no Google: você pode simplesmente digitar \"temperatura atual de Taquara\" ou \"temperatura atual de Rio de Janeiro\" e o Google fornecerá a informação mais recente disponível.\n\nInfelizmente, eu não tenho acesso a essas informações em tempo real, então não posso fornecer a temperatura atual para você.\n\nMas posso sugerir que você verifique um dos métodos acima para saber a temperatura atual de Taquara ou do Rio de Janeiro!" + } +] \ No newline at end of file diff --git a/AssistenteVirtual/AssistenteVirtual/data/__pycache__/historico.cpython-313.pyc b/AssistenteVirtual/AssistenteVirtual/data/__pycache__/historico.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4840fd37d7e99e5f1bf1c5f589cdb31b394b6b20 GIT binary patch literal 1918 zcmb_c%}*Ow5TE_9ch_LRjv+0y#o?o2qk_XB;zJ23C9R-ULGlJEl`Wx_y%<-v*L}~# zrK%8V4{4FApnj-1=16+VF};=k1%bK+Z8%hFF5D2V6p3Csvv_Scs(R|Ic6Q!-GxKKW zH#5~>FaStjt&C?C8Q>3EcqG<@>SYwZ0|N}J8i|LInVNvRVZ1pv{^D^E4Z>* zHf4`|$n8R^7KHopBbV^4h6Rc!Q9p}&vDSA0;=ZOuO-zsnm#&}(qM@@7nD~>gK|-r7 zp`mHupBmDHBtiiaZnj7#-s)*KzJ0I=o?k9vzVNwHi!2HQ5X1KZyivb1jWH~XQRsyz zK6H9b>V;+DLi0Us4ga2`fQkP`7F_H_tL2)VF3&pxJN2!WmWRh53XWh;9GUX&$OMto{;shwf5SpI z*4vEPOcxwsnPc1#b*`o+lPpTo~;>Py5N9DcH^`Ax$&-Z-4_VwC> z&^MnxmmvJ6up7F5tU_zs#@us_)|LADuRndz5!r9=-)--&f}nLCgd>}?#}Z1Xd<1X( zp?!K7e(aj=k#^cO6nA<8)0dQ;L5bu`E+6iC%P;-x6OgAU6CSB3xYhX?3Rs=>vqZf* zn`%i&V85MFyk3>w4nQB=5)AAq!#^QM-AZb%rObcSQO2tV1*@UVs0$cf@Xis1p^Hwd zRp6`4S~7Vmn|1uzLK>S-ml;(wYatdy=E&*Qd=b^P20k6Q&&f+P%0i^m!A8qv6*hzs(QCgbB zGENajy;O$HbT*Z>3z*G30%T^aJnKURa?B@?ZNPyX+?OM}a^!w`w{xr_k3UlaUrcW6=wf=So5=p>IobowbD1!G zf%=+eYa`tm$bc@)>pn&%jOH+-Ve1y8<7ZahzHL1O)=zt9wU^80i~p#-i+JWHb_j)k zA0LNmfC{h@?*COCIF>-wU5~or*8JJsZVS*Ta$$2pVC0&;POK4tdNpsSS98`Bqx+~N p`5-bJCW7!3TAqUTd*tR52%X4^&~_3Lg{c!&5jv}3Q5baH{0%BcX;J_H literal 0 HcmV?d00001 diff --git a/AssistenteVirtual/AssistenteVirtual/main.py b/AssistenteVirtual/AssistenteVirtual/main.py new file mode 100644 index 0000000..0cc6e51 --- /dev/null +++ b/AssistenteVirtual/AssistenteVirtual/main.py @@ -0,0 +1,31 @@ +from Core.voz import ouvir_microfone, falar_texto +from Core.ia import chamar_ia +from Core.comandos import interpretar_comando +from Core.historico import carregar_historico, adicionar_mensagem + + +historico = carregar_historico() # ? Hisótico da conversa + +print("🤖 Assistente iniciado. Diga 'PARAR' para encerrar.") + +while True: # ? Loop infinito que mantém o assistente escutando até receber o comando de encerrar (break). + + comando = ouvir_microfone() # ? Chama a função eque pega oque vc fala e retorna o texto transcrito(string) e associa a variavel + if comando == "": # ? Se a função retorna "", então continue reinicia o loop sem processar nada. + continue + + if "parar" in comando.lower(): #? Se ele indenticar parar no que o usuario falar, ele interrompe o loop com o break e chama a função que converte texto em voz. + falar_texto("Encerrando assistente. foi um prazer auxiliá-lo SENHOR Ruan.") + break + + resposta_comando = interpretar_comando(comando) # ? Ele chama função que abre as urls e apps de acordo com a palavra chave q a gente fala, se a funçlãoindetificar a palavra chave vai abrir, exemplo o youtube + if resposta_comando: # ? e vai retornar um texto (Exemplo: ("Abrindo Youtube...")) + falar_texto(resposta_comando) + continue + # ? Se não for comando direto, enviar para a IA + resposta_ia = chamar_ia(comando, historico) # ? Vai adicionar assim no meu historico.json historico.append({"role": "user", "content": comando}), comando é oque eu falei + adicionar_mensagem(historico, "user", comando) # ? e depois vai adicionar nese formato porem a resposta da ia + adicionar_mensagem(historico, "assistant", resposta_ia) + + # ? Falar a respsota da IA + falar_texto(resposta_ia)