@danhachuel/thunderbolt 0.5.30 → 0.5.33
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 +39 -3
- package/hermes_ui/api_key_tests.py +2 -2
- package/package.json +1 -1
package/app/main.py
CHANGED
|
@@ -656,6 +656,19 @@ def render_channel_thumbnail_blueprint_panel(channel: dict, *, compact: bool = F
|
|
|
656
656
|
st.info(f"**Thumbnail Blueprint utilizado pelo canal:** {name} · apenas leitura")
|
|
657
657
|
|
|
658
658
|
|
|
659
|
+
def render_tiktok_prompt_master_panel(channel: dict, *, compact: bool = False) -> None:
|
|
660
|
+
"""Mostrar a configuração editorial TikTok sem exigir um Blueprint YouTube."""
|
|
661
|
+
prompt_id = str(channel.get("default_prompt_master") or channel.get("prompt_master") or "").strip()
|
|
662
|
+
_prompt_ids, prompt_labels = _tiktok_prompt_options()
|
|
663
|
+
prompt_name = prompt_labels.get(prompt_id, prompt_id)
|
|
664
|
+
if not prompt_id:
|
|
665
|
+
st.warning("**SEM PROMPT MASTER CONFIGURADO** · configure um Prompt Master padrão na aba Canais Tiktok.")
|
|
666
|
+
elif compact:
|
|
667
|
+
st.caption(f"**Prompt Master TikTok:** {prompt_name}")
|
|
668
|
+
else:
|
|
669
|
+
st.info(f"**Prompt Master utilizado pelo canal TikTok:** {prompt_name} · `{prompt_id}`")
|
|
670
|
+
|
|
671
|
+
|
|
659
672
|
def creative_payload_from_result(channel: dict, topic: str, creative: dict, topic_source: str = "manual") -> dict[str, Any]:
|
|
660
673
|
variant = creative.get("thumbnail_variant") or {}
|
|
661
674
|
return {
|
|
@@ -3039,9 +3052,12 @@ def render_new_video(page_title: str = "Criação de Vídeos", prefix: str = "ne
|
|
|
3039
3052
|
else:
|
|
3040
3053
|
selected_one = st.selectbox("Canal", active_channels, format_func=lambda c: c["name"], key=f"{prefix}_channel")
|
|
3041
3054
|
selected = [selected_one["id"]]
|
|
3042
|
-
#
|
|
3043
|
-
|
|
3044
|
-
|
|
3055
|
+
# YouTube uses Blueprints; TikTok Shorts use the channel Prompt Master.
|
|
3056
|
+
if channel_platform == "tiktok":
|
|
3057
|
+
render_tiktok_prompt_master_panel(selected_one)
|
|
3058
|
+
else:
|
|
3059
|
+
render_channel_blueprint_panel(selected_one)
|
|
3060
|
+
render_channel_thumbnail_blueprint_panel(selected_one)
|
|
3045
3061
|
generation_settings = render_video_generation_settings(
|
|
3046
3062
|
prefix,
|
|
3047
3063
|
current_language=str(st.session_state.get("video_language") or ""),
|
|
@@ -7089,6 +7105,26 @@ def _fetch_media_models(card: dict[str, Any]) -> list[str]:
|
|
|
7089
7105
|
provider = str(card.get("provider") or "").strip().lower()
|
|
7090
7106
|
if provider == "kie_ai":
|
|
7091
7107
|
return list(KIE_MEDIA_MODEL_CATALOG)
|
|
7108
|
+
if provider == "fal_ai":
|
|
7109
|
+
api_key = str(card.get("api_key") or "").strip()
|
|
7110
|
+
if not api_key:
|
|
7111
|
+
raise ValueError("Introduza a API key FAL AI antes de consultar os modelos.")
|
|
7112
|
+
response = requests.get(
|
|
7113
|
+
"https://api.fal.ai/v1/models",
|
|
7114
|
+
headers={"Accept": "application/json", "Authorization": f"Key {api_key}"},
|
|
7115
|
+
timeout=12,
|
|
7116
|
+
)
|
|
7117
|
+
response.raise_for_status()
|
|
7118
|
+
payload = response.json()
|
|
7119
|
+
entries = payload.get("models") if isinstance(payload, dict) else []
|
|
7120
|
+
models = {
|
|
7121
|
+
str(item.get("endpoint_id") or "").strip()
|
|
7122
|
+
for item in entries
|
|
7123
|
+
if isinstance(item, dict) and str(item.get("endpoint_id") or "").strip()
|
|
7124
|
+
}
|
|
7125
|
+
if not models:
|
|
7126
|
+
raise ValueError("A FAL AI não devolveu modelos disponíveis.")
|
|
7127
|
+
return sorted(models, key=str.casefold)
|
|
7092
7128
|
if provider == "openrouter":
|
|
7093
7129
|
base_url = str(card.get("base_url") or "https://openrouter.ai/api/v1").rstrip("/")
|
|
7094
7130
|
headers = {"Accept": "application/json", "Authorization": f"Bearer {str(card.get('api_key') or '').strip()}"}
|
|
@@ -177,6 +177,8 @@ def test_media_provider_card(card: Mapping[str, Any]) -> dict[str, Any]:
|
|
|
177
177
|
return _get(f"{base_url}/v3/users/me", headers={"X-Api-Key": api_key})
|
|
178
178
|
if provider == "kie_ai":
|
|
179
179
|
return _get(f"{base_url}/chat/credit", headers={"Authorization": f"Bearer {api_key}"})
|
|
180
|
+
if provider == "fal_ai":
|
|
181
|
+
return _get("https://api.fal.ai/v1/models", headers={"Authorization": f"Key {api_key}"})
|
|
180
182
|
if not model and provider not in {"inferenceport", "cloudflare_workers_ai", "heygen"}:
|
|
181
183
|
return _result("missing", "Complete o modelo antes de testar.")
|
|
182
184
|
if provider == "openrouter":
|
|
@@ -194,8 +196,6 @@ def test_media_provider_card(card: Mapping[str, Any]) -> dict[str, Any]:
|
|
|
194
196
|
return _get(endpoint, headers=headers, params={"search": model or "stable-diffusion"})
|
|
195
197
|
if api_style in {"openai_compatible", "huggingface", "agnes", "kie"} or provider in {"pollinations", "huggingface", "agnes", "inferenceport"}:
|
|
196
198
|
endpoint = _models_endpoint(base_url)
|
|
197
|
-
elif provider == "fal_ai":
|
|
198
|
-
endpoint = f"{base_url}/models" if base_url.endswith("/v1") else base_url
|
|
199
199
|
else:
|
|
200
200
|
endpoint = base_url
|
|
201
201
|
return _get(endpoint, headers=headers)
|
package/package.json
CHANGED