@danhachuel/thunderbolt 0.3.54 → 0.3.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MANUAL-INSTALACAO.md +6 -6
- package/README.md +4 -4
- package/app/influencers_ui.py +35 -10
- package/app/main.py +7 -4
- package/package.json +1 -1
package/MANUAL-INSTALACAO.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Este manual descreve a instalação local da UI Thunderbolt, baseada no MoneyPrinterTurbo, utilizando o pacote npm `@danhachuel/thunderbolt`. O fluxo recomendado instala automaticamente o ambiente Python, as dependências da aplicação, as dependências do MoneyPrinterTurbo, o Streamlit e o suporte FFmpeg através de `imageio-ffmpeg`.
|
|
4
4
|
|
|
5
|
-
> **Versão deste manual:** 0.3.
|
|
5
|
+
> **Versão deste manual:** 0.3.56
|
|
6
6
|
> **Pacote npm:** `@danhachuel/thunderbolt`
|
|
7
7
|
> **Porta padrão da UI:** `localhost:3030`
|
|
8
8
|
> **Repositório:** [github.com/DanHachuel/thunderbolt](https://github.com/DanHachuel/thunderbolt)
|
|
@@ -29,7 +29,7 @@ O MoneyPrinterTurbo declara Python 3.11 ou superior como requisito e documenta a
|
|
|
29
29
|
|
|
30
30
|
## AI Influencers — configuração e utilização
|
|
31
31
|
|
|
32
|
-
A área **AI Influencers > Personagens** permite criar personagens com nome, biografia, idioma, Instagram Business ID opcional, várias imagens de referência e ficheiros `.md`/`.json`. No uploader, seleccione vários ficheiros de uma vez; cada imagem pode ser pré-visualizada e cada documento é validado como UTF-8, Markdown ou JSON válido. Os assets são deduplicados por SHA-256 e não são gravados como base64 dentro das tabelas.
|
|
32
|
+
A área **AI Influencers > Personagens** permite criar personagens com nome, biografia, idioma, Instagram Business ID opcional, várias imagens de referência e ficheiros `.md`/`.json`. O campo **Idioma** é um selector e reutiliza exactamente a mesma lista, os códigos e os labels visuais de **Pipeline Vídeos > Criação de Vídeos**. No uploader, seleccione vários ficheiros de uma vez; cada imagem pode ser pré-visualizada e cada documento é validado como UTF-8, Markdown ou JSON válido. Os assets são deduplicados por SHA-256 e não são gravados como base64 dentro das tabelas.
|
|
33
33
|
|
|
34
34
|
O backend local predefinido é **SQLite**, pelo que Personagens e Geração de Conteúdo IA podem ser usados sem credenciais externas. Abra **Configurações > Configuração API > API Keys > Banco de Dados Influencers** para confirmar **SQLite** ou seleccionar **Supabase**. Se seleccionar Supabase, preencha **Supabase Project URL**, **Supabase API key** e **Supabase Storage bucket**, clique em **Testar ligação do backend**, aplique primeiro `seed/references/ai_influencers_schema.sql` no SQL Editor do projecto, exponha as quatro tabelas na Data API e configure permissões/RLS adequadas. O bucket deve existir com o nome configurado, por defeito `ai-influencers`.
|
|
35
35
|
|
|
@@ -114,13 +114,13 @@ Execute:
|
|
|
114
114
|
Windows PowerShell ou MobaXterm:
|
|
115
115
|
|
|
116
116
|
```powershell
|
|
117
|
-
npx.cmd --yes --prefer-online @danhachuel/thunderbolt@0.3.
|
|
117
|
+
npx.cmd --yes --prefer-online @danhachuel/thunderbolt@0.3.56 install
|
|
118
118
|
```
|
|
119
119
|
|
|
120
120
|
Linux/macOS:
|
|
121
121
|
|
|
122
122
|
```bash
|
|
123
|
-
npx --yes --prefer-online @danhachuel/thunderbolt@0.3.
|
|
123
|
+
npx --yes --prefer-online @danhachuel/thunderbolt@0.3.56 install
|
|
124
124
|
```
|
|
125
125
|
|
|
126
126
|
A instalação normal é **segura para actualizações**: preserva `storage`, Blueprints, Brandings, configurações e artefactos do utilizador. Remove apenas `.venv`, o clone técnico do MoneyPrinterTurbo e dependências que serão recriadas. Uma pasta antiga sem dados do utilizador, como `C:\Users\<utilizador>\AppData\Local\hermes` da tentativa incompleta, pode ser removida; uma pasta antiga que contenha Blueprints, Brandings ou storage é preservada e apenas avisada no terminal. Feche processos Python, Node, Streamlit e MobaXterm que estejam a usar as pastas antes de executar.
|
|
@@ -128,7 +128,7 @@ A instalação normal é **segura para actualizações**: preserva `storage`, Bl
|
|
|
128
128
|
Se quiser apagar absolutamente tudo de forma intencional, use o comando destrutivo separado:
|
|
129
129
|
|
|
130
130
|
```powershell
|
|
131
|
-
npx.cmd --yes --prefer-online @danhachuel/thunderbolt@0.3.
|
|
131
|
+
npx.cmd --yes --prefer-online @danhachuel/thunderbolt@0.3.56 install --purge-data
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
O parâmetro `--purge-data` apaga Blueprints, Brandings, configurações, storage e artefactos locais. Não o use numa actualização normal.
|
|
@@ -542,7 +542,7 @@ Ao abrir a página, o Thunderbolt não prepara dados públicos, não descarrega
|
|
|
542
542
|
|
|
543
543
|
Os parâmetros da UI são número de clusters entre 2 e 10, suporte mínimo entre 0,01 e 0,50, país, engagement, intervalo de datas e tags, todos dentro da área principal da aba. O núcleo normaliza os dados, calcula engagement, aplica filtros, faz transformação logarítmica e standardização, executa K-Means e calcula itemsets/regras com FP-Growth. Não são apresentados resultados até ao primeiro clique em **Analisar Nichos**; o mesmo botão aplica alterações posteriores aos filtros. Os resultados são DataFrames de clusters, itemsets frequentes, regras de associação e dados analisados; o gráfico de dispersão é criado nativamente com Plotly.
|
|
544
544
|
|
|
545
|
-
As dependências adicionais — `scikit-learn`, `mlxtend`, `plotly`, `seaborn`, `matplotlib` e `kagglehub` — são instaladas pelo procedimento normal de `npx`. Em instalações existentes, execute novamente `npx.cmd --yes --prefer-online @danhachuel/thunderbolt@0.3.
|
|
545
|
+
As dependências adicionais — `scikit-learn`, `mlxtend`, `plotly`, `seaborn`, `matplotlib` e `kagglehub` — são instaladas pelo procedimento normal de `npx`. Em instalações existentes, execute novamente `npx.cmd --yes --prefer-online @danhachuel/thunderbolt@0.3.56 install`; o instalador detecta e reutiliza o que já estiver válido.
|
|
546
546
|
|
|
547
547
|
### Niche Finder Apify
|
|
548
548
|
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ A primeira versão implementa a camada UI independente com:
|
|
|
20
20
|
| Criação de Vídeos / Criação de Músicas | Subabas Criar vídeo e Vídeos; idiomas históricos preservados e dez códigos MoneyPrinterTurbo com bandeiras; Pexels/Pixabay, full IA com Estilo IA e Apenas Música com agente musical; a segunda página reutiliza o mesmo fluxo com título próprio |
|
|
21
21
|
| Upload Música | Subabas **JewelMusic**, **Pushtunes** e **ytmusicapi** para upload de ficheiros, sincronização de bibliotecas e envio autenticado para YouTube Music; credenciais locais e histórico em `uploads.json` |
|
|
22
22
|
| Automação | Menu expansível com a subaba **Automação Youtube**, onde ficam os vídeos e canais, selectores editáveis de Blueprint/voz padrão, Automação ON, horário diário HH:MM e worker local baseado no relógio do computador |
|
|
23
|
-
| AI Influencers | Menu expansível com Personagens, Geração de Conteúdo IA,
|
|
23
|
+
| AI Influencers | Menu expansível com Personagens, Geração de Conteúdo IA, Redes Sociais, Tutorial Meta e Tutorial Supabase; Personagens aceita múltiplas imagens e documentos `.md`/`.json`, e Geração de Conteúdo IA separa Imagens, Vídeos e Motion Control |
|
|
24
24
|
| Niche Finder | Menu expansível com duas alternativas independentes: Niche Finder Kaggle e Niche Finder Apify, com parâmetros, execução e resultados separados |
|
|
25
25
|
| Edição | Menu expansível abaixo de Automação com Limpador de Metadados, Clip Generator local em Cortes e Editor Python inspirado no PYEdit para vídeos e scripts locais |
|
|
26
26
|
| Upload | YouTube via `youtube-automation-agent` adaptado internamente, fallback ordenado API Oficial → Upload directo → Postiz, upload de MP4 para Postiz via API key/MCP configurável, TikTok, Instagram e Facebook Pages no front end |
|
|
@@ -30,7 +30,7 @@ A primeira versão implementa a camada UI independente com:
|
|
|
30
30
|
|
|
31
31
|
## AI Influencers — personagens e geração de conteúdo
|
|
32
32
|
|
|
33
|
-
A área **AI Influencers > Personagens** permite guardar um personagem com nome, biografia, idioma, Instagram Business ID opcional, várias imagens de referência e documentos `.md` ou `.json`. Cada asset é validado, sanitizado, deduplicado por SHA-256 e guardado separado do perfil; imagens têm pré-visualização e documentos são mostrados como Markdown ou JSON estruturado.
|
|
33
|
+
A área **AI Influencers > Personagens** permite guardar um personagem com nome, biografia, idioma, Instagram Business ID opcional, várias imagens de referência e documentos `.md` ou `.json`. O campo **Idioma** é um selector que reutiliza exactamente a lista, os códigos e os labels visuais de **Pipeline Vídeos > Criação de Vídeos**. Cada asset é validado, sanitizado, deduplicado por SHA-256 e guardado separado do perfil; imagens têm pré-visualização e documentos são mostrados como Markdown ou JSON estruturado.
|
|
34
34
|
|
|
35
35
|
O backend local predefinido é **SQLite**, por isso Personagens e Geração de Conteúdo IA funcionam imediatamente sem credenciais externas. Em **Configurações > Configuração API > API Keys > Banco de Dados Influencers**, pode manter **SQLite** ou seleccionar **Supabase** quando quiser uma base remota; nesse caso, configure o **Supabase Project URL**, a **Supabase API key** e o bucket de Storage, aplique `seed/references/ai_influencers_schema.sql` no SQL Editor e confirme Data API/RLS. SQLite cria localmente `storage/state/ai_influencers.db` e `storage/influencers/`; apenas um backend fica activo de cada vez. O botão **Testar ligação do backend** é read-only e não bloqueia a utilização local.
|
|
36
36
|
|
|
@@ -79,9 +79,9 @@ No topo da área principal da aplicação existe o menu nativo de idioma no padr
|
|
|
79
79
|
|
|
80
80
|
A UI suporta os temas **Dark** e **Light** através do menu nativo de três pontos do Streamlit, no local original do toolbar. Não existe um selector Theme adicional dentro da página. A configuração distribuída em `.streamlit/config.toml` disponibiliza as variantes nomeadas **Dark** e **Light**, e o menu nativo continua responsável por alternar entre os modos, seguindo o padrão do [MoneyPrinterTurbo](https://github.com/harry0703/MoneyPrinterTurbo). O CSS próprio do Thunderbolt usa cores semânticas, `currentColor` e `color-mix` para acompanhar o tema activo, sem alterar a posição nem a funcionalidade do toolbar, do botão Deploy e do menu principal.
|
|
81
81
|
|
|
82
|
-
## Navegação da UI 0.3.
|
|
82
|
+
## Navegação da UI 0.3.56
|
|
83
83
|
|
|
84
|
-
A barra lateral mantém os níveis principais, nesta ordem: **Início**, **Niche Finder**, **Pipeline**, **Pipeline TikTok**, **Automação**, **Edição**, **AI Influencers** e **Configurações**. **Pipeline Vídeos** é expansível e contém **Criação de Vídeos**, **Backlog Vídeos**, **Roteiros**, **Thumbnails** e **Upload**. **Pipeline Música** é expansível e contém **Criação de Músicas** e **Upload Música**. **Automação** também é expansível e contém **Automação Youtube**. **Edição** é expansível e contém **Limpador de Metadados**, **Cortes**, **Editor Python** e **Download Mídia**, nessa ordem. **AI Influencers** é expansível e contém **Personagens**, **Geração de Conteúdo IA**, **
|
|
84
|
+
A barra lateral mantém os níveis principais, nesta ordem: **Início**, **Niche Finder**, **Pipeline**, **Pipeline TikTok**, **Automação**, **Edição**, **AI Influencers** e **Configurações**. **Pipeline Vídeos** é expansível e contém **Criação de Vídeos**, **Backlog Vídeos**, **Roteiros**, **Thumbnails** e **Upload**. **Pipeline Música** é expansível e contém **Criação de Músicas** e **Upload Música**. **Automação** também é expansível e contém **Automação Youtube**. **Edição** é expansível e contém **Limpador de Metadados**, **Cortes**, **Editor Python** e **Download Mídia**, nessa ordem. **AI Influencers** é expansível e contém **Personagens**, **Geração de Conteúdo IA**, **Redes Sociais**, **Tutorial Meta** e **Tutorial Supabase**, nessa ordem. A página Geração de Conteúdo IA divide-se em **Imagens**, **Vídeos** e **Motion Control**; a subaba Motion Control permanece vazia nesta release.
|
|
85
85
|
**Niche Finder** é expansível e contém **Niche Finder Kaggle** e **Niche Finder Apify**. **Configurações** é expansível e contém **Canais Youtube**, **Blueprints Youtube**, **MCP**, **Contas Google**, **Notificações**, **Logs** e **Configuração API**, nessa ordem. O Início reúne o dashboard e as filas do Pipeline, sem botões de acções rápidas.
|
|
86
86
|
|
|
87
87
|
A subaba **Tutorial Supabase** apresenta o guia de criação das tabelas `plans` e `posts` e do bucket `instagram-images`, com ligação para a fonte original no GitHub. As duas frases promocionais da comunidade foram omitidas. Todas as subabas internas também são localizadas pelo helper nativo de tabs:
|
package/app/influencers_ui.py
CHANGED
|
@@ -127,20 +127,45 @@ def render_ai_influencers_api_status(settings: dict[str, Any]) -> None:
|
|
|
127
127
|
st.error(result.get("message") or "O backend não está disponível.")
|
|
128
128
|
|
|
129
129
|
|
|
130
|
-
def render_ai_influencer_characters(
|
|
130
|
+
def render_ai_influencer_characters(
|
|
131
|
+
settings: dict[str, Any],
|
|
132
|
+
*,
|
|
133
|
+
language_options: list[str] | None = None,
|
|
134
|
+
language_formatter: Any = None,
|
|
135
|
+
language_normalizer: Any = None,
|
|
136
|
+
) -> None:
|
|
131
137
|
st.title("Personagens")
|
|
138
|
+
language_options = list(language_options or ["pt"])
|
|
139
|
+
language_formatter = language_formatter or (lambda value: value)
|
|
140
|
+
language_normalizer = language_normalizer or (lambda value, default="pt": str(value or default))
|
|
141
|
+
|
|
142
|
+
def language_index(value: Any) -> int:
|
|
143
|
+
try:
|
|
144
|
+
normalized = language_normalizer(value, default="pt")
|
|
145
|
+
except TypeError:
|
|
146
|
+
normalized = language_normalizer(value)
|
|
147
|
+
if normalized in language_options:
|
|
148
|
+
return language_options.index(normalized)
|
|
149
|
+
return language_options.index("pt") if "pt" in language_options else 0
|
|
150
|
+
|
|
132
151
|
st.caption("Crie personagens virtuais com várias imagens de referência e documentos Markdown/JSON. Os assets ficam associados ao personagem e não são enviados para IA sem uma acção de geração.")
|
|
133
152
|
repository = _repository(settings)
|
|
134
153
|
if repository is None:
|
|
135
154
|
return
|
|
136
155
|
|
|
137
|
-
with st.form("influencer_create_form", clear_on_submit=
|
|
156
|
+
with st.form("influencer_create_form", clear_on_submit=True):
|
|
138
157
|
st.subheader("Novo personagem")
|
|
139
158
|
cols = st.columns(3)
|
|
140
159
|
with cols[0]:
|
|
141
160
|
name = st.text_input("Nome do personagem", key="influencer_new_name")
|
|
142
161
|
with cols[1]:
|
|
143
|
-
language = st.
|
|
162
|
+
language = st.selectbox(
|
|
163
|
+
"Idioma",
|
|
164
|
+
language_options,
|
|
165
|
+
index=language_index(st.session_state.get("influencer_new_language", "pt")),
|
|
166
|
+
format_func=language_formatter,
|
|
167
|
+
key="influencer_new_language",
|
|
168
|
+
)
|
|
144
169
|
with cols[2]:
|
|
145
170
|
instagram_id = st.text_input("Instagram Business ID (opcional)", key="influencer_new_instagram_id")
|
|
146
171
|
bio = st.text_area("Biografia e instruções", height=130, key="influencer_new_bio")
|
|
@@ -184,7 +209,13 @@ def render_ai_influencer_characters(settings: dict[str, Any]) -> None:
|
|
|
184
209
|
with st.expander("Editar perfil", expanded=False):
|
|
185
210
|
with st.form(f"influencer_edit_form_{selected_id}"):
|
|
186
211
|
edit_name = st.text_input("Nome", value=str(selected.get("name") or ""), key=f"influencer_edit_name_{selected_id}")
|
|
187
|
-
edit_language = st.
|
|
212
|
+
edit_language = st.selectbox(
|
|
213
|
+
"Idioma",
|
|
214
|
+
language_options,
|
|
215
|
+
index=language_index(selected.get("language") or "pt"),
|
|
216
|
+
format_func=language_formatter,
|
|
217
|
+
key=f"influencer_edit_language_{selected_id}",
|
|
218
|
+
)
|
|
188
219
|
edit_instagram = st.text_input("Instagram Business ID", value=str(selected.get("instagram_business_id") or ""), key=f"influencer_edit_instagram_{selected_id}")
|
|
189
220
|
edit_bio = st.text_area("Biografia e instruções", value=str(selected.get("bio") or ""), height=130, key=f"influencer_edit_bio_{selected_id}")
|
|
190
221
|
save_edit = st.form_submit_button("Guardar alterações", type="primary")
|
|
@@ -387,14 +418,8 @@ def render_ai_influencer_content(settings: dict[str, Any]) -> None:
|
|
|
387
418
|
st.info("A subaba Motion Control foi preparada para a próxima evolução. Nenhuma operação é executada nesta versão.")
|
|
388
419
|
|
|
389
420
|
|
|
390
|
-
def render_ai_influencer_motion_control() -> None:
|
|
391
|
-
st.title("Motion Control")
|
|
392
|
-
st.info("A área Motion Control está reservada para desenvolvimento futuro e permanece vazia nesta versão.")
|
|
393
|
-
|
|
394
|
-
|
|
395
421
|
__all__ = [
|
|
396
422
|
"render_ai_influencer_characters",
|
|
397
423
|
"render_ai_influencer_content",
|
|
398
|
-
"render_ai_influencer_motion_control",
|
|
399
424
|
"render_ai_influencers_api_status",
|
|
400
425
|
]
|
package/app/main.py
CHANGED
|
@@ -31,7 +31,7 @@ from app.modules.niche_finder.apify import ApifyError, DEFAULT_ACTOR_ID, abort_a
|
|
|
31
31
|
from app.modules.niche_finder.core import NicheAnalysisError, run_niche_analysis
|
|
32
32
|
from app.modules.niche_finder.data_loader import DatasetError, download_kaggle_dataset
|
|
33
33
|
from app.modules.niche_finder.summarizer import summarize_items
|
|
34
|
-
from app.influencers_ui import render_ai_influencer_characters, render_ai_influencer_content,
|
|
34
|
+
from app.influencers_ui import render_ai_influencer_characters, render_ai_influencer_content, render_ai_influencers_api_status
|
|
35
35
|
from hermes_ui.blueprints import create_blueprint_from_link, list_branding_files, save_generated_blueprint
|
|
36
36
|
from hermes_ui.metadata_cleaner import build_description, clean_video_metadata, list_edit_records, metadata_manifest, normalize_tags, save_edit_record, store_external_video
|
|
37
37
|
from hermes_ui.python_editor import AUDIO_EXTENSIONS, VIDEO_EXTENSIONS, PythonEditorError, change_speed, editor_manifest, extract_audio, list_edit_records as list_python_editor_records, list_generated_videos, list_scripts, list_video_files, read_script, remove_audio, replace_audio, resize_video, save_edit_record as save_python_editor_record, save_script, store_uploaded_asset, trim_video
|
|
@@ -6236,7 +6236,6 @@ def main():
|
|
|
6236
6236
|
models_ai_items = [
|
|
6237
6237
|
("Personagens", ":material/person:", "Personagens"),
|
|
6238
6238
|
("Geração de Conteúdo IA", ":material/auto_awesome:", "Geração de Conteúdo IA"),
|
|
6239
|
-
("Motion Control", ":material/motion_mode:", "Motion Control"),
|
|
6240
6239
|
("UGC Products", ":material/shopping_bag:", "UGC Products"),
|
|
6241
6240
|
("Redes Sociais", ":material/share:", "Redes Sociais"),
|
|
6242
6241
|
]
|
|
@@ -6371,9 +6370,13 @@ def main():
|
|
|
6371
6370
|
"Editor Python": render_python_editor,
|
|
6372
6371
|
"Download Mídia": render_media_download,
|
|
6373
6372
|
"AI Influencers": lambda: render_edit_placeholder("AI Influencers", "Seleccione uma das abas AI Influencers no menu expansível."),
|
|
6374
|
-
"Personagens": lambda: render_ai_influencer_characters(
|
|
6373
|
+
"Personagens": lambda: render_ai_influencer_characters(
|
|
6374
|
+
read_json("settings.json", {}),
|
|
6375
|
+
language_options=VIDEO_LANGUAGE_SELECTION_OPTIONS,
|
|
6376
|
+
language_formatter=video_language_label,
|
|
6377
|
+
language_normalizer=normalize_video_language,
|
|
6378
|
+
),
|
|
6375
6379
|
"Geração de Conteúdo IA": lambda: render_ai_influencer_content(read_json("settings.json", {})),
|
|
6376
|
-
"Motion Control": render_ai_influencer_motion_control,
|
|
6377
6380
|
"UGC Products": lambda: render_edit_placeholder("UGC Products", ""),
|
|
6378
6381
|
"Redes Sociais": lambda: render_edit_placeholder("Redes Sociais", "Área reservada para a futura funcionalidade de redes sociais."),
|
|
6379
6382
|
"Analista Growth Youtube": lambda: render_edit_placeholder("Analista Growth Youtube", ""),
|
package/package.json
CHANGED