@danhachuel/thunderbolt 0.2.97 → 0.2.99
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/app/main.py +19 -11
- package/package.json +1 -1
package/app/main.py
CHANGED
|
@@ -2836,7 +2836,7 @@ def render_automation():
|
|
|
2836
2836
|
st.info("Ainda não existem vídeos cadastrados.")
|
|
2837
2837
|
for task in tasks:
|
|
2838
2838
|
with st.container(border=True):
|
|
2839
|
-
task_cols = st.columns([2.
|
|
2839
|
+
task_cols = st.columns([2.45, 1.15, 1.15, 1.85])
|
|
2840
2840
|
with task_cols[0]:
|
|
2841
2841
|
st.write(f"**{task.get('topic', 'Sem tópico')}**")
|
|
2842
2842
|
st.caption(f"{task.get('channel_name', 'Canal')} · {task.get('id', '')}")
|
|
@@ -2847,8 +2847,16 @@ def render_automation():
|
|
|
2847
2847
|
st.caption("Estilo")
|
|
2848
2848
|
st.write(task.get("style_wide", "—"))
|
|
2849
2849
|
with task_cols[3]:
|
|
2850
|
-
|
|
2851
|
-
st.
|
|
2850
|
+
state = str(task.get("state") or "")
|
|
2851
|
+
start_col, stop_col = st.columns(2)
|
|
2852
|
+
with start_col:
|
|
2853
|
+
if st.button("Start", key=f"automation_start_{task['id']}", use_container_width=True, disabled=state not in {"to_do", "blocked", "failed"}):
|
|
2854
|
+
transition_task(task["id"], "doing")
|
|
2855
|
+
st.rerun()
|
|
2856
|
+
with stop_col:
|
|
2857
|
+
if st.button("Stop", key=f"automation_stop_{task['id']}", use_container_width=True, disabled=state != "doing"):
|
|
2858
|
+
transition_task(task["id"], "blocked")
|
|
2859
|
+
st.rerun()
|
|
2852
2860
|
|
|
2853
2861
|
|
|
2854
2862
|
def render_upload_direct():
|
|
@@ -3571,7 +3579,7 @@ def render_settings():
|
|
|
3571
3579
|
st.subheader("API Keys")
|
|
3572
3580
|
port = st.number_input("Porta Streamlit", 1, 65535, int(settings.get("port", 3030)))
|
|
3573
3581
|
moneyprinter_path = st.text_input("Pasta do motor de vídeo", settings.get("moneyprinter_path", ""), key="settings_moneyprinter_path")
|
|
3574
|
-
with st.expander("Niche Finder — execução remota no Kaggle", expanded=
|
|
3582
|
+
with st.expander("Niche Finder — execução remota no Kaggle", expanded=False):
|
|
3575
3583
|
st.caption("O dataset permanece no Kaggle. O Thunderbolt usa estas credenciais apenas para publicar/executar a kernel e obter os resultados pequenos da análise.")
|
|
3576
3584
|
kaggle_cols = st.columns(3)
|
|
3577
3585
|
with kaggle_cols[0]:
|
|
@@ -3581,7 +3589,7 @@ def render_settings():
|
|
|
3581
3589
|
with kaggle_cols[2]:
|
|
3582
3590
|
kaggle_kernel_slug = text_setting("Slug da kernel", "kaggle_kernel_slug", help_text="Identificador da kernel remota, por exemplo thunderbolt-niche-finder.")
|
|
3583
3591
|
|
|
3584
|
-
with st.expander("Niche Finder — execução através da Apify", expanded=
|
|
3592
|
+
with st.expander("Niche Finder — execução através da Apify", expanded=False):
|
|
3585
3593
|
st.caption("O token fica guardado apenas no storage local. A aba Niche Finder Apify só usa este serviço depois de clicar no botão de pesquisa.")
|
|
3586
3594
|
apify_cols = st.columns(4)
|
|
3587
3595
|
with apify_cols[0]:
|
|
@@ -3593,7 +3601,7 @@ def render_settings():
|
|
|
3593
3601
|
with apify_cols[3]:
|
|
3594
3602
|
apify_run_timeout = st.number_input("Limite da execução (s)", min_value=30, max_value=7200, value=int(settings.get("apify_run_timeout_seconds", 900)), step=30)
|
|
3595
3603
|
|
|
3596
|
-
with st.expander("Nano Banana — geração de thumbnails", expanded=
|
|
3604
|
+
with st.expander("Nano Banana — geração de thumbnails", expanded=False):
|
|
3597
3605
|
st.caption("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.")
|
|
3598
3606
|
nano_cols = st.columns(2)
|
|
3599
3607
|
with nano_cols[0]:
|
|
@@ -3603,7 +3611,7 @@ def render_settings():
|
|
|
3603
3611
|
gemini_image_aspect_ratio = st.selectbox("Proporção da thumbnail", ["16:9", "9:16", "1:1", "4:5"], index=["16:9", "9:16", "1:1", "4:5"].index(str(settings.get("gemini_image_aspect_ratio") or "16:9")) if str(settings.get("gemini_image_aspect_ratio") or "16:9") in {"16:9", "9:16", "1:1", "4:5"} else 0)
|
|
3604
3612
|
gemini_image_size = st.selectbox("Tamanho da imagem", ["1K", "2K", "4K"], index=["1K", "2K", "4K"].index(str(settings.get("gemini_image_size") or "1K")) if str(settings.get("gemini_image_size") or "1K") in {"1K", "2K", "4K"} else 0)
|
|
3605
3613
|
|
|
3606
|
-
with st.expander("LLM — providers e modelos", expanded=
|
|
3614
|
+
with st.expander("LLM — providers e modelos", expanded=False):
|
|
3607
3615
|
provider_options = ["openai", "moonshot", "shengsuanyun", "gemini", "deepseek", "qwen", "azure", "volcengine", "grok", "minimax", "mimo", "cloudflare", "modelscope", "aihubmix", "aimlapi", "evolink", "ollama", "oneapi", "litellm", "groq", "pollinations"]
|
|
3608
3616
|
current_llm_provider = str(settings.get("llm_provider") or DEFAULT_LLM_PROVIDER).strip().lower()
|
|
3609
3617
|
llm_provider = st.selectbox("LLM provider", provider_options, index=provider_options.index(current_llm_provider) if current_llm_provider in provider_options else 0)
|
|
@@ -3659,7 +3667,7 @@ def render_settings():
|
|
|
3659
3667
|
with cols[2]:
|
|
3660
3668
|
settings[f"{prefix}_model_name"] = text_setting("Model", f"{prefix}_model_name")
|
|
3661
3669
|
|
|
3662
|
-
with st.expander("Voz, TTS e música — Azure Speech, restantes serviços e Suno", expanded=
|
|
3670
|
+
with st.expander("Voz, TTS e música — Azure Speech, restantes serviços e Suno", expanded=False):
|
|
3663
3671
|
cols = st.columns(2)
|
|
3664
3672
|
with cols[0]:
|
|
3665
3673
|
azure_speech_key = text_setting("Azure Speech key", "azure_speech_key", secret=True)
|
|
@@ -3682,19 +3690,19 @@ def render_settings():
|
|
|
3682
3690
|
suno_api_base_url = text_setting("Suno API Base URL", "suno_api_base_url", help_text="Use o endpoint compatível fornecido pelo seu acesso Suno; não é inventado pelo Thunderbolt.")
|
|
3683
3691
|
suno_api_endpoint = text_setting("Suno API endpoint", "suno_api_endpoint", help_text="Ex.: /api/generate")
|
|
3684
3692
|
|
|
3685
|
-
with st.expander("TikTok for Developers — Client ID e Client Secret", expanded=
|
|
3693
|
+
with st.expander("TikTok for Developers — Client ID e Client Secret", expanded=False):
|
|
3686
3694
|
st.caption("Apenas as credenciais da aplicação ficam nesta UI. Redirect URI, scopes, autorização e tokens são geridos no TikTok for Developers Playground.")
|
|
3687
3695
|
tiktok_client_key = text_setting("TikTok Client ID", "tiktok_client_key", secret=True)
|
|
3688
3696
|
tiktok_client_secret = text_setting("TikTok Client Secret", "tiktok_client_secret", secret=True)
|
|
3689
3697
|
|
|
3690
|
-
with st.expander("Publicação através do Upload-Post"):
|
|
3698
|
+
with st.expander("Publicação através do Upload-Post", expanded=False):
|
|
3691
3699
|
upload_post_enabled = st.checkbox("Activar Upload-Post", bool(settings.get("upload_post_enabled", False)))
|
|
3692
3700
|
upload_post_api_key = text_setting("Upload-Post API key", "upload_post_api_key", secret=True)
|
|
3693
3701
|
upload_post_username = text_setting("Upload-Post username", "upload_post_username")
|
|
3694
3702
|
upload_post_platforms = text_setting("Plataformas Upload-Post", "upload_post_platforms")
|
|
3695
3703
|
upload_post_auto_upload = st.checkbox("Publicar automaticamente após gerar", bool(settings.get("upload_post_auto_upload", False)))
|
|
3696
3704
|
|
|
3697
|
-
with st.expander("Postiz — API key, integração e MCP", expanded=
|
|
3705
|
+
with st.expander("Postiz — API key, integração e MCP", expanded=False):
|
|
3698
3706
|
st.caption("O Thunderbolt é o cliente. A API key é enviada exclusivamente ao servidor Postiz configurado; não é colocada em URLs, logs ou repositório.")
|
|
3699
3707
|
postiz_enabled = st.checkbox("Activar Postiz como fallback final", bool(settings.get("postiz_enabled", False)))
|
|
3700
3708
|
postiz_mode = st.selectbox("Modo de ligação", ["api", "mcp"], index=0 if settings.get("postiz_mode", "api") != "mcp" else 1, help="API é o modo determinístico de upload. MCP fica disponível para uma ligação compatível com Streamable HTTP.")
|
package/package.json
CHANGED