@danhachuel/thunderbolt 0.3.69 → 0.3.70
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 +10 -8
- package/README.md +5 -5
- package/app/influencers_ui.py +2 -2
- package/app/main.py +30 -29
- package/hermes_ui/languages.py +4 -1
- 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.70
|
|
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)
|
|
@@ -128,13 +128,13 @@ Execute:
|
|
|
128
128
|
Windows PowerShell ou MobaXterm:
|
|
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.70 install
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
Linux/macOS:
|
|
135
135
|
|
|
136
136
|
```bash
|
|
137
|
-
npx --yes --prefer-online @danhachuel/thunderbolt@0.3.
|
|
137
|
+
npx --yes --prefer-online @danhachuel/thunderbolt@0.3.70 install
|
|
138
138
|
```
|
|
139
139
|
|
|
140
140
|
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.
|
|
@@ -142,7 +142,7 @@ A instalação normal é **segura para actualizações**: preserva `storage`, Bl
|
|
|
142
142
|
Se quiser apagar absolutamente tudo de forma intencional, use o comando destrutivo separado:
|
|
143
143
|
|
|
144
144
|
```powershell
|
|
145
|
-
npx.cmd --yes --prefer-online @danhachuel/thunderbolt@0.3.
|
|
145
|
+
npx.cmd --yes --prefer-online @danhachuel/thunderbolt@0.3.70 install --purge-data
|
|
146
146
|
```
|
|
147
147
|
|
|
148
148
|
O parâmetro `--purge-data` apaga Blueprints, Brandings, configurações, storage e artefactos locais. Não o use numa actualização normal.
|
|
@@ -391,15 +391,17 @@ Em **Configuração API > API Keys**, o expander **LLM — providers e modelos**
|
|
|
391
391
|
|
|
392
392
|
Dentro do expander **LLM — providers e modelos**, acima dos cartões de providers, está o card **Limite LLM NVIDIA NIM**. Ele permite ligar **Activar limitador NVIDIA NIM — 40 RPM**. O valor padrão é 40 pedidos numa janela de 60 segundos. O contador é persistido localmente por cartão/chave e aplica-se à criação manual, aos workers e às automações. A opção vem desligada para não alterar instalações existentes; ligue-a quando o endpoint activo for NVIDIA NIM e a sua conta tiver esse limite.
|
|
393
393
|
|
|
394
|
-
O expander **Imagem e Video
|
|
394
|
+
O expander **Imagem e Video Montagem/MoviePy** aparece primeiro dentro de **Configuração API > API Keys**. Ele reúne as fontes usadas pela montagem local de vídeo com MoviePy/FFmpeg, incluindo os cartões de Pexels, Pixabay, Coverr, WaveSpeed AI, LoomLoom, TwelveLabs e ficheiro local. Pode manter várias API keys do mesmo provedor, seleccionar a fonte activa e testar cada fonte remota; a opção local não apresenta um diagnóstico remoto artificial.
|
|
395
|
+
|
|
396
|
+
Logo abaixo fica o expander **Imagem e Video IA**, que substitui o antigo bloco isolado da Nano Banana. Os cartões disponíveis são **Nano Banana**, **Pollinations.ai**, **Agnes AI**, **Hugging Face Inference API**, **Cloudflare Workers AI**, **InferencePort Proxy**, **阿里云 (Alibaba Cloud Model Studio)**, **KIE AI** e **FAL AI**. Em cada cartão, configure a API key/token, o modelo, a Base URL, o estado **Provider activo**, a participação no **Pool Imagem**, a participação no **Pool Vídeo** e a prioridade. **Image Size** e **Aspect Ratio** não aparecem nos cartões e não são editáveis: são defaults internos aplicados automaticamente no prompt da geração. O botão **Testar Chamada API** faz apenas uma verificação read-only; não inicia geração de imagem ou vídeo.
|
|
395
397
|
|
|
396
398
|
A área **Voz, TTS e música — Azure Speech, restantes serviços e Suno** está dividida em cartões independentes para **Azure Speech**, **ElevenLabs**, **SiliconFlow**, **MiniMax TTS**, **Chatterbox**, **Sonilo** e **Suno**. Cada cartão agrupa apenas as credenciais, parâmetros e diagnóstico do serviço correspondente. O Suno aparece num cartão próprio porque é uma integração de criação musical, enquanto os restantes providers são serviços de voz/TTS.
|
|
397
399
|
|
|
398
|
-
|
|
400
|
+
No expander **Imagem e Video IA**, a lista **Provider de media** inclui **FAL AI, KIE AI, Agnes AI, Nano Banana, Replicate AI, Pollinations.ai, Hugging Face Inference API, InferencePort Proxy e HeyGen** para a rota Full IA. O cartão **HeyGen** pede a API key, o **Avatar ID** e, opcionalmente, o **Voice ID**; a opção **Provider activo**, **Pool Vídeo**, **Prioridade** e **Testar Chamada API** funcionam como nos restantes cartões. O teste HeyGen usa apenas `GET /v3/users/me` e não consome uma geração. Nano Banana e Hugging Face podem permanecer no catálogo sem serem seleccionados para vídeo quando o cartão não declara capacidade de vídeo.
|
|
399
401
|
|
|
400
402
|
### API Tiktok — várias aplicações
|
|
401
403
|
|
|
402
|
-
Em **Configuração API > API Tiktok**, situada entre **Contas Google** e **
|
|
404
|
+
Em **Configuração API > API Tiktok**, situada entre **Contas Google** e **AI Influencers**, cada aplicação TikTok é configurada num card independente. O card contém exclusivamente **TikTok Client ID** e **TikTok Client Secret** e apresenta os botões **Testar chamada API**, **Guardar card** e **Apagar card**. Use **Adicionar nova API** no final da lista para criar outra aplicação sem substituir as anteriores.
|
|
403
405
|
|
|
404
406
|
O botão de teste é read-only. Sem um token OAuth TikTok já autorizado, o Thunderbolt informa que é necessário concluir o Playground/autorização do TikTok for Developers, sem inventar um resultado nem enviar credenciais. O token e a autorização não são campos dos cards. Instalações que ainda tenham `tiktok_client_key` e `tiktok_client_secret` são migradas automaticamente para o primeiro card; o adapter usa o primeiro card completo e mantém fallback para os campos antigos.
|
|
405
407
|
|
|
@@ -568,7 +570,7 @@ Ao abrir a página, o Thunderbolt não prepara dados públicos, não descarrega
|
|
|
568
570
|
|
|
569
571
|
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.
|
|
570
572
|
|
|
571
|
-
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.
|
|
573
|
+
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.70 install`; o instalador detecta e reutiliza o que já estiver válido.
|
|
572
574
|
|
|
573
575
|
### Niche Finder Apify
|
|
574
576
|
|
package/README.md
CHANGED
|
@@ -104,19 +104,19 @@ A subaba **Tutorial Supabase** apresenta o guia de criação das tabelas `plans`
|
|
|
104
104
|
|
|
105
105
|
O conteúdo interno das páginas também é localizado, não apenas a navegação: títulos, subtítulos, descrições, labels de campos, placeholders, opções de selectores, botões, avisos, mensagens de sucesso/erro, estados vazios, métricas, expanderes e blocos Markdown/HTML são traduzidos no idioma seleccionado através da camada global de conteúdo. Valores técnicos, chaves de estado, IDs de formulários, nomes de ficheiros, URLs e dados introduzidos pelo utilizador permanecem inalterados.
|
|
106
106
|
|
|
107
|
-
Todas as subabas internas também são localizadas pelo helper nativo de tabs: **Blueprints/Brandings**, **Pesquisa pública/Cadastro manual/Contas cadastradas**, **Upload/Biblioteca**, **Importar do YouTube/Canais em lote gmail/Cadastro manual**, **Criar vídeo/Vídeos**, **Novo roteiro/letra/Histórico guardado**, as três abas de análise de clusters, as quatro abas de cortes, **Vídeos/Código Python**, as quatro opções de Upload, **JewelMusic/Pushtunes/ytmusicapi**, **API Keys/Teste de vozes**, **
|
|
107
|
+
Todas as subabas internas também são localizadas pelo helper nativo de tabs: **Blueprints/Brandings**, **Pesquisa pública/Cadastro manual/Contas cadastradas**, **Upload/Biblioteca**, **Importar do YouTube/Canais em lote gmail/Cadastro manual**, **Criar vídeo/Vídeos**, **Novo roteiro/letra/Histórico guardado**, as três abas de análise de clusters, as quatro abas de cortes, **Vídeos/Código Python**, as quatro opções de Upload, **JewelMusic/Pushtunes/ytmusicapi**, **API Keys/Teste de vozes**, os expanders **Imagem e Video Montagem/MoviePy** e **Imagem e Video IA**, **Client MCP/Servidor MCP/Skill** e **Notificações/Geral/Telegram**. As chaves técnicas e a ordem funcional permanecem inalteradas.
|
|
108
108
|
|
|
109
|
-
Dentro de **Configurações > Contas Google**, a UI contém os cartões expansíveis de contas Google/YouTube, `sessionInfo` por conta, documentos de Upload directo, o formulário **Adicionar outra conta Gmail**, o bloco global de `INNERTUBE_API_KEY` e a configuração global do YouTube (OAuth Client ID, OAuth Client Secret e YouTube Data API Key). A página **Configuração API** contém as restantes credenciais, providers, modelos, serviços, **Imagem e Video**, TikTok e Postiz.
|
|
109
|
+
Dentro de **Configurações > Contas Google**, a UI contém os cartões expansíveis de contas Google/YouTube, `sessionInfo` por conta, documentos de Upload directo, o formulário **Adicionar outra conta Gmail**, o bloco global de `INNERTUBE_API_KEY` e a configuração global do YouTube (OAuth Client ID, OAuth Client Secret e YouTube Data API Key). A página **Configuração API** contém as restantes credenciais, providers, modelos, serviços, os expanders **Imagem e Video Montagem/MoviePy** e **Imagem e Video IA**, TikTok e Postiz.
|
|
110
110
|
|
|
111
|
-
Em **Configuração API > API Keys**,
|
|
111
|
+
Em **Configuração API > API Keys**, o expander **Imagem e Video Montagem/MoviePy** segue o padrão do MoneyPrinterTurbo: seleccione uma fonte — **Pexels**, **Pixabay**, **Coverr**, **WaveSpeed AI**, **LoomLoom**, **TwelveLabs** ou **Ficheiros locais** — e introduza as API keys dessa fonte. **Adicionar outra chave** cria outra linha para a mesma fonte; as listas são guardadas separadamente por fonte, deduplicadas e exportadas para o `config.toml` do motor como arrays para rotação. O expander não expõe endpoint, proxy, qualidade, codec, FFmpeg, Whisper, directório ou filtros técnicos: esses valores permanecem internalizados e a fonte local não requer credencial. Ele aparece acima do expander **Imagem e Video IA**.
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
O expander **Imagem e Video IA** mantém as credenciais dos providers de geração que não são fontes de montagem. A chave `gemini_image_api_key` da Nano Banana continua separada de `gemini_api_key` do LLM textual. `INNERTUBE_API_KEY` permanece exclusivamente em **Configurações > Contas Google**, no bloco de configuração global fora dos cartões, e não é duplicada em API Keys.
|
|
114
114
|
|
|
115
115
|
A área expansível **Voz, TTS e música — Azure Speech, restantes serviços e Suno** está organizada em cartões independentes para **Azure Speech**, **ElevenLabs**, **SiliconFlow**, **MiniMax TTS**, **Chatterbox**, **Sonilo** e **Suno**. Cada cartão contém apenas os campos do respectivo serviço e o seu próprio botão de diagnóstico; o Suno fica visualmente separado por ser um agente de criação musical, não um provider TTS. Em **Pipeline Vídeos > Criação de Vídeos > Configurações de áudio**, o modo **Upload** disponibiliza um uploader de narração, botão para guardar o ficheiro, pré-visualização e validação antes da criação. O caminho é passado ao MoneyPrinterTurbo através de `--custom-audio-file`, conforme o fluxo oficial documentado no [MoneyPrinterTurbo](https://github.com/harry0703/MoneyPrinterTurbo).
|
|
116
116
|
|
|
117
117
|
Nos cartões de **LLM — providers e modelos**, o campo **Prioridade** define a ordem de tentativa do pool textual. O valor **1** é usado primeiro; em quota, timeout, erro de transporte ou falha transitória, o router tenta a prioridade **2**, depois **3** e assim sucessivamente. O checkbox antigo **LLM principal** deixou de existir. O card **Limite LLM NVIDIA NIM** fica dentro deste mesmo expander, acima dos cartões de providers, e os seus controlos continuam partilhados pela UI, pipeline e automações. Quando **LLM Telegram** está marcado, o cartão fica reservado exclusivamente às notificações Telegram: o campo Prioridade é desactivado e o cartão é excluído do pool textual normal. A chave interna de cartão activo continua apenas como espelho de compatibilidade para instalações antigas.
|
|
118
118
|
|
|
119
|
-
O expander **Imagem e Video** reúne cartões independentes para **Nano Banana**, **Pollinations.ai**, **Agnes AI**, **Hugging Face Inference API**, **Cloudflare Workers AI**, **InferencePort Proxy**, **阿里云 (Alibaba Cloud Model Studio)**, **KIE AI** e **FAL AI**. Cada cartão permite configurar API key/token quando necessário, modelo, Base URL, activar o provider, escolher participação no **Pool Imagem** e/ou **Pool Vídeo**, definir prioridade e executar **Testar Chamada API**. Os parâmetros técnicos de composição, como **Image Size** e **Aspect Ratio**, não são apresentados nem editáveis nos cartões: ficam como defaults internos e são acrescentados automaticamente ao prompt da geração de imagem e/ou vídeo. O InferencePort usa por defeito `http://localhost:8080/v1` e não exige chave; o Cloudflare requer Account ID; os restantes providers devem ser preenchidos de acordo com a conta e endpoint disponibilizados pelo serviço.
|
|
119
|
+
O expander **Imagem e Video IA** reúne cartões independentes para **Nano Banana**, **Pollinations.ai**, **Agnes AI**, **Hugging Face Inference API**, **Cloudflare Workers AI**, **InferencePort Proxy**, **阿里云 (Alibaba Cloud Model Studio)**, **KIE AI** e **FAL AI**. Cada cartão permite configurar API key/token quando necessário, modelo, Base URL, activar o provider, escolher participação no **Pool Imagem** e/ou **Pool Vídeo**, definir prioridade e executar **Testar Chamada API**. Os parâmetros técnicos de composição, como **Image Size** e **Aspect Ratio**, não são apresentados nem editáveis nos cartões: ficam como defaults internos e são acrescentados automaticamente ao prompt da geração de imagem e/ou vídeo. O InferencePort usa por defeito `http://localhost:8080/v1` e não exige chave; o Cloudflare requer Account ID; os restantes providers devem ser preenchidos de acordo com a conta e endpoint disponibilizados pelo serviço.
|
|
120
120
|
|
|
121
121
|
O router mantém três pools independentes: **LLM textual**, **imagem** e **vídeo**. O failover só passa ao cartão seguinte em quota, timeout, erro de transporte ou HTTP transitório; erros de credencial, endpoint/modelo inexistente ou payload inválido ficam registados e não são mascarados por um provider diferente. O pool de vídeo externo é opcional: quando desligado, o worker continua a usar o motor local MoneyPrinterTurbo; quando ligado, usa apenas os cartões marcados para Pool Vídeo.
|
|
122
122
|
|
package/app/influencers_ui.py
CHANGED
|
@@ -323,7 +323,7 @@ def render_ai_influencer_content(settings: dict[str, Any]) -> None:
|
|
|
323
323
|
current = str(st.session_state.get("influencer_selected_id") or options[0])
|
|
324
324
|
cards, provider_options = _provider_options(settings, "image")
|
|
325
325
|
if not cards:
|
|
326
|
-
st.warning("Não existem providers activos no pool de imagem. Configure um provider em Configuração API > API Keys > Imagem e Video.")
|
|
326
|
+
st.warning("Não existem providers activos no pool de imagem. Configure um provider em Configuração API > API Keys > Imagem e Video IA.")
|
|
327
327
|
with st.form("influencer_image_content_form"):
|
|
328
328
|
influencer_id = st.selectbox("Personagem", options, index=options.index(current) if current in options else 0, format_func=lambda value: _influencer_label(influencers, value), key="content_image_influencer")
|
|
329
329
|
assets = repository.list_assets(influencer_id)
|
|
@@ -371,7 +371,7 @@ def render_ai_influencer_content(settings: dict[str, Any]) -> None:
|
|
|
371
371
|
current = str(st.session_state.get("influencer_selected_id") or options[0])
|
|
372
372
|
cards, provider_options = _provider_options(settings, "video")
|
|
373
373
|
if not cards:
|
|
374
|
-
st.warning("Não existem providers activos no pool de vídeo. Configure KIE AI, Replicate, FAL AI ou outro provider compatível em Configuração API > API Keys > Imagem e Video.")
|
|
374
|
+
st.warning("Não existem providers activos no pool de vídeo. Configure KIE AI, Replicate, FAL AI ou outro provider compatível em Configuração API > API Keys > Imagem e Video IA.")
|
|
375
375
|
with st.form("influencer_video_content_form"):
|
|
376
376
|
influencer_id = st.selectbox("Personagem", options, index=options.index(current) if current in options else 0, format_func=lambda value: _influencer_label(influencers, value), key="content_video_influencer")
|
|
377
377
|
assets = repository.list_assets(influencer_id)
|
package/app/main.py
CHANGED
|
@@ -5039,7 +5039,7 @@ def _material_source_card_definition(provider: str) -> dict[str, str]:
|
|
|
5039
5039
|
}
|
|
5040
5040
|
|
|
5041
5041
|
|
|
5042
|
-
def _render_material_source_card(settings: dict[str, Any], cards: list[dict[str, Any]], index: int) -> None:
|
|
5042
|
+
def _render_material_source_card(settings: dict[str, Any], cards: list[dict[str, Any]], index: int, *, embedded: bool = False) -> None:
|
|
5043
5043
|
card = normalize_material_card(cards[index], index)
|
|
5044
5044
|
cards[index] = card
|
|
5045
5045
|
card_id = str(card["id"])
|
|
@@ -5054,7 +5054,8 @@ def _render_material_source_card(settings: dict[str, Any], cards: list[dict[str,
|
|
|
5054
5054
|
st.caption(definition["description"])
|
|
5055
5055
|
with header_cols[1]:
|
|
5056
5056
|
_render_credential_status("" if is_local else card.get("api_key"), local=is_local, required=not is_local)
|
|
5057
|
-
|
|
5057
|
+
card_form = nullcontext() if embedded else st.form(f"material_source_card_form_{card_id}")
|
|
5058
|
+
with card_form:
|
|
5058
5059
|
content_cols = st.columns(2)
|
|
5059
5060
|
with content_cols[0]:
|
|
5060
5061
|
if is_local:
|
|
@@ -5085,29 +5086,30 @@ def _render_material_source_card(settings: dict[str, Any], cards: list[dict[str,
|
|
|
5085
5086
|
st.rerun()
|
|
5086
5087
|
|
|
5087
5088
|
|
|
5088
|
-
def render_material_source_api_keys(settings: dict[str, Any]) -> None:
|
|
5089
|
-
st.
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5089
|
+
def render_material_source_api_keys(settings: dict[str, Any], *, embedded: bool = False) -> None:
|
|
5090
|
+
with st.expander("Imagem e Video Montagem/MoviePy", expanded=False):
|
|
5091
|
+
st.caption("Configure as fontes usadas pela montagem de vídeo com MoviePy/FFmpeg num cartão independente. Pode repetir o mesmo provedor para guardar várias API keys; a fonte seleccionada será usada pela pipeline.")
|
|
5092
|
+
migrated, changed = ensure_material_source_cards(settings)
|
|
5093
|
+
cards = [dict(item) for item in migrated.get("material_source_cards", [])]
|
|
5094
|
+
if changed:
|
|
5095
|
+
write_json("settings.json", settings)
|
|
5096
|
+
for index in range(len(cards)):
|
|
5097
|
+
_render_material_source_card(settings, cards, index, embedded=embedded)
|
|
5097
5098
|
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5099
|
+
st.divider()
|
|
5100
|
+
st.markdown("**Adicionar fonte de materiais**")
|
|
5101
|
+
provider_codes = [item["code"] for item in material_source_catalog()] + ["local"]
|
|
5102
|
+
provider_to_add = st.selectbox(
|
|
5103
|
+
"Provedor de materiais",
|
|
5104
|
+
provider_codes,
|
|
5105
|
+
format_func=lambda value: _material_source_card_definition(value)["label"],
|
|
5106
|
+
key="material_new_provider_choice",
|
|
5107
|
+
)
|
|
5108
|
+
add_source_clicked = st.form_submit_button("Configurar Nova Fonte de Materiais", type="primary", use_container_width=True, key="add_material_source_card") if embedded else st.button("Configurar Nova Fonte de Materiais", type="primary", use_container_width=True, key="add_material_source_card")
|
|
5109
|
+
if add_source_clicked:
|
|
5110
|
+
cards.append(new_material_card(provider_to_add, card_id=f"material-{provider_to_add}-{uuid.uuid4().hex[:8]}"))
|
|
5111
|
+
_persist_material_source_cards(settings, cards, str(settings.get("material_active_card_id") or ""))
|
|
5112
|
+
st.rerun()
|
|
5111
5113
|
|
|
5112
5114
|
|
|
5113
5115
|
def _api_status_badge(label: str, kind: str = "missing") -> None:
|
|
@@ -5490,7 +5492,7 @@ def render_media_provider_cards(settings: dict[str, Any], *, embedded: bool = Fa
|
|
|
5490
5492
|
if changed:
|
|
5491
5493
|
settings.update(migrated)
|
|
5492
5494
|
write_json("settings.json", settings)
|
|
5493
|
-
with st.expander("Imagem e Video", expanded=False):
|
|
5495
|
+
with st.expander("Imagem e Video IA", expanded=False):
|
|
5494
5496
|
full_ia_labels = ", ".join(media_provider_definition(code).label for code in FULL_IA_VIDEO_PROVIDER_CODES)
|
|
5495
5497
|
st.caption(f"Configure providers de imagem e vídeo em cartões independentes. O router usa apenas o pool correspondente e faz failover entre providers activos. Pool Full IA: {full_ia_labels}.")
|
|
5496
5498
|
image_cards = [card for card in cards if card.get("supports_image")]
|
|
@@ -5537,7 +5539,7 @@ def render_settings():
|
|
|
5537
5539
|
key=f"settings_{key}",
|
|
5538
5540
|
)
|
|
5539
5541
|
|
|
5540
|
-
api_keys_tab, google_accounts_tab, tiktok_api_tab,
|
|
5542
|
+
api_keys_tab, google_accounts_tab, tiktok_api_tab, ai_influencers_tab, voice_test_tab = render_localized_tabs(["API Keys", "Contas Google", "API Tiktok", "AI Influencers", "Teste de Voz"])
|
|
5541
5543
|
|
|
5542
5544
|
with api_keys_tab:
|
|
5543
5545
|
with st.container(border=True):
|
|
@@ -5586,6 +5588,8 @@ def render_settings():
|
|
|
5586
5588
|
llm_rpm_limit = int(llm_rpm_settings["llm_rpm_limit"])
|
|
5587
5589
|
llm_rpm_window_seconds = int(llm_rpm_settings["llm_rpm_window_seconds"])
|
|
5588
5590
|
|
|
5591
|
+
render_material_source_api_keys(settings, embedded=True)
|
|
5592
|
+
|
|
5589
5593
|
render_media_provider_cards(settings, embedded=True)
|
|
5590
5594
|
|
|
5591
5595
|
with st.expander("Voz, TTS e música — Azure Speech, restantes serviços e Suno", expanded=False):
|
|
@@ -5758,9 +5762,6 @@ def render_settings():
|
|
|
5758
5762
|
with tiktok_api_tab:
|
|
5759
5763
|
render_tiktok_api_cards(settings)
|
|
5760
5764
|
|
|
5761
|
-
with material_sources_tab:
|
|
5762
|
-
render_material_source_api_keys(settings)
|
|
5763
|
-
|
|
5764
5765
|
with ai_influencers_tab:
|
|
5765
5766
|
st.subheader("AI Influencers")
|
|
5766
5767
|
st.caption("Estado do backend usado por Personagens e Geração de Conteúdo IA. O selector e as credenciais são editados nesta aba, em Banco de Dados Influencers.")
|
package/hermes_ui/languages.py
CHANGED
|
@@ -242,6 +242,8 @@ for _language_code, _api_key_values in _API_KEY_EXPANDER_TRANSLATIONS.items():
|
|
|
242
242
|
# provider cards themselves expose their capability labels in the current UI.
|
|
243
243
|
for _language_code in UI_TRANSLATIONS:
|
|
244
244
|
UI_TRANSLATIONS[_language_code].setdefault("Imagem e Video", "Imagem e Video")
|
|
245
|
+
UI_TRANSLATIONS[_language_code].setdefault("Imagem e Video IA", "Imagem e Video IA")
|
|
246
|
+
UI_TRANSLATIONS[_language_code].setdefault("Imagem e Video Montagem/MoviePy", "Imagem e Video Montagem/MoviePy")
|
|
245
247
|
|
|
246
248
|
|
|
247
249
|
# Labels introduced by the reorganised sidebar.
|
|
@@ -982,7 +984,8 @@ _CONTENT_TRANSLATION_ROWS = (
|
|
|
982
984
|
("Niche Finder — execução remota no Kaggle", "Niche Finder — execução remota no Kaggle", "Niche Finder — remote execution on Kaggle", "Niche Finder — Kaggle 远程执行", "Niche Finder — Remoteausführung auf Kaggle", "Niche Finder — chạy từ xa trên Kaggle", "Niche Finder — Kaggle'da uzaktan çalıştırma", "Niche Finder — удалённый запуск на Kaggle", "Niche Finder — ejecución remota en Kaggle", "Niche Finder — eksekusi jarak jauh di Kaggle", "Niche Finder — esecuzione remota su Kaggle"),
|
|
983
985
|
("O dataset permanece no Kaggle. O Thunderbolt usa estas credenciais apenas para publicar/executar a kernel e obter os resultados pequenos da análise.", "O dataset permanece no Kaggle. O Thunderbolt usa estas credenciais apenas para publicar/executar a kernel e obter os resultados pequenos da análise.", "The dataset remains on Kaggle. Thunderbolt uses these credentials only to publish/run the kernel and retrieve small analysis results.", "数据集保留在 Kaggle。Thunderbolt 仅使用这些凭证发布/运行 kernel 并获取小型分析结果。", "Der Datensatz bleibt auf Kaggle. Thunderbolt verwendet diese Zugangsdaten nur zum Veröffentlichen/Ausführen des Kernels und zum Abrufen kleiner Analyseergebnisse.", "Dataset vẫn ở Kaggle. Thunderbolt chỉ dùng thông tin xác thực để xuất bản/chạy kernel và lấy kết quả phân tích nhỏ.", "Veri kümesi Kaggle'da kalır. Thunderbolt bu kimlik bilgilerini yalnızca kernel'ı yayınlamak/çalıştırmak ve küçük analiz sonuçlarını almak için kullanır.", "Датасет остаётся на Kaggle. Thunderbolt использует эти данные только для публикации/запуска kernel и получения небольших результатов анализа.", "El dataset permanece en Kaggle. Thunderbolt usa estas credenciales solo para publicar/ejecutar el kernel y obtener pequeños resultados del análisis.", "Dataset tetap di Kaggle. Thunderbolt menggunakan kredensial ini hanya untuk menerbitkan/menjalankan kernel dan mengambil hasil analisis kecil.", "Il dataset resta su Kaggle. Thunderbolt usa queste credenziali solo per pubblicare/eseguire il kernel e ottenere piccoli risultati dell'analisi."),
|
|
984
986
|
("Niche Finder — execução através da Apify", "Niche Finder — execução através da Apify", "Niche Finder — execution through Apify", "Niche Finder — 通过 Apify 执行", "Niche Finder — Ausführung über Apify", "Niche Finder — chạy qua Apify", "Niche Finder — Apify üzerinden çalıştırma", "Niche Finder — запуск через Apify", "Niche Finder — ejecución mediante Apify", "Niche Finder — eksekusi melalui Apify", "Niche Finder — esecuzione tramite Apify"),
|
|
985
|
-
("Imagem e Video", "Imagem e Video", "Image and Video", "图像和视频", "Bild und Video", "Hình ảnh và video", "Görüntü ve Video", "
|
|
987
|
+
("Imagem e Video IA", "Imagem e Video IA", "AI Image and Video", "图像和视频 AI", "KI-Bild und -Video", "Hình ảnh và video AI", "Yapay Zekâ Görüntü ve Video", "ИИ: изображения и видео", "Imagen y vídeo con IA", "Gambar dan Video AI", "Immagini e video IA"),
|
|
988
|
+
("Imagem e Video Montagem/MoviePy", "Imagem e Video Montagem/MoviePy", "Image and Video Assembly/MoviePy", "图像和视频拼装/MoviePy", "Bild- und Videomontage/MoviePy", "Lắp ráp hình ảnh và video/MoviePy", "Görüntü ve Video Montajı/MoviePy", "Сборка изображения и видео/MoviePy", "Montaje de imagen y vídeo/MoviePy", "Perakitan Gambar dan Video/MoviePy", "Montaggio immagini e video/MoviePy"),
|
|
986
989
|
("A Nano Banana gera a imagem final das thumbnails a partir da variante escolhida. A chave é guardada apenas no storage local e é distinta da chave do Gemini usado como LLM textual.", "A Nano Banana gera a imagem final das thumbnails a partir da variante escolhida. A chave é guardada apenas no storage local e é distinta da chave do Gemini usado como LLM textual.", "Nano Banana generates the final thumbnail image from the selected variant. The key is stored locally and is separate from the Gemini key used as a text LLM.", "Nano Banana 根据所选变体生成最终缩略图。密钥仅保存在本地存储中,与用于文本 LLM 的 Gemini 密钥分开。", "Nano Banana erzeugt das endgültige Thumbnail aus der ausgewählten Variante. Der Schlüssel wird nur lokal gespeichert und ist vom Gemini-Schlüssel für das Text-LLM getrennt.", "Nano Banana tạo ảnh thumbnail cuối từ biến thể đã chọn. Key chỉ lưu cục bộ và tách biệt với key Gemini dùng cho LLM văn bản.", "Nano Banana, seçilen varyanttan son küçük resim görselini oluşturur. Anahtar yalnızca yerel depolamada tutulur ve metin LLM'i için kullanılan Gemini anahtarından ayrıdır.", "Nano Banana создаёт финальное изображение миниатюры из выбранного варианта. Ключ хранится локально отдельно от ключа Gemini для текстовой LLM.", "Nano Banana genera la miniatura final a partir de la variante elegida. La clave se guarda localmente y es distinta de la clave de Gemini del LLM de texto.", "Nano Banana menghasilkan gambar thumbnail akhir dari varian yang dipilih. Kunci disimpan secara lokal dan terpisah dari kunci Gemini untuk LLM teks.", "Nano Banana genera l'immagine finale della miniatura dalla variante scelta. La chiave è salvata localmente ed è separata da quella Gemini usata per l'LLM testuale."),
|
|
987
990
|
("LLM — providers e modelos", "LLM — providers e modelos", "LLM — providers and models", "LLM — 服务商和模型", "LLM — Anbieter und Modelle", "LLM — provider và mô hình", "LLM — sağlayıcılar ve modeller", "LLM — провайдеры и модели", "LLM — proveedores y modelos", "LLM — penyedia dan model", "LLM — provider e modelli"),
|
|
988
991
|
("OpenAI/ NVIDIA NIM — API key, Base URL e modelo", "OpenAI/ NVIDIA NIM — API key, Base URL e modelo", "OpenAI/NVIDIA NIM — API key, Base URL and model", "OpenAI/NVIDIA NIM — API 密钥、基础 URL 和模型", "OpenAI/NVIDIA NIM — API-Schlüssel, Basis-URL und Modell", "OpenAI/NVIDIA NIM — API key, Base URL và mô hình", "OpenAI/NVIDIA NIM — API anahtarı, Temel URL ve model", "OpenAI/NVIDIA NIM — API-ключ, базовый URL и модель", "OpenAI/NVIDIA NIM — clave API, URL base y modelo", "OpenAI/NVIDIA NIM — kunci API, URL Dasar, dan model", "OpenAI/NVIDIA NIM — API key, URL di base e modello"),
|
package/package.json
CHANGED