@danhachuel/thunderbolt 0.4.29 → 0.4.30

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.
Files changed (2) hide show
  1. package/app/main.py +49 -5
  2. package/package.json +1 -1
package/app/main.py CHANGED
@@ -6135,6 +6135,25 @@ def _persist_media_cards(settings: dict[str, Any], cards: list[dict[str, Any]],
6135
6135
  return updated
6136
6136
 
6137
6137
 
6138
+ def _fetch_media_models(card: dict[str, Any]) -> list[str]:
6139
+ """Consultar modelos do provider, incluindo o catálogo nativo Gemini."""
6140
+ provider = str(card.get("provider") or "").strip().lower()
6141
+ if provider == "nano_banana":
6142
+ base_url = str(card.get("base_url") or "https://generativelanguage.googleapis.com/v1beta").rstrip("/")
6143
+ response = requests.get(
6144
+ f"{base_url}/models",
6145
+ params={"key": str(card.get("api_key") or "").strip()},
6146
+ headers={"Accept": "application/json"},
6147
+ timeout=12,
6148
+ )
6149
+ response.raise_for_status()
6150
+ payload = response.json()
6151
+ models = payload.get("models") if isinstance(payload, dict) else []
6152
+ return sorted({str(item.get("name", "")).removeprefix("models/") for item in models if isinstance(item, dict) and item.get("name")}, key=str.casefold)
6153
+ from integrations.openai_model_discovery import fetch_openai_compatible_models
6154
+ return fetch_openai_compatible_models(str(card.get("api_key") or ""), str(card.get("base_url") or ""))
6155
+
6156
+
6138
6157
  def _render_media_provider_card(settings: dict[str, Any], cards: list[dict[str, Any]], index: int, *, embedded: bool = False) -> None:
6139
6158
  card = normalize_media_card(cards[index], index)
6140
6159
  cards[index] = card
@@ -6160,7 +6179,23 @@ def _render_media_provider_card(settings: dict[str, Any], cards: list[dict[str,
6160
6179
  st.caption("Este provider não exige API key.")
6161
6180
  api_key = ""
6162
6181
  with model_col:
6163
- model = st.text_input("Modelo", value=str(card.get("model") or ""), help="ID do modelo ou rota usada pelo provider.", key=f"media_card_{card_id}_model")
6182
+ model_catalog = st.session_state.get(f"media_model_catalog_{card_id}", [])
6183
+ if not isinstance(model_catalog, list):
6184
+ model_catalog = []
6185
+ current_model = str(card.get("model") or "").strip()
6186
+ discovered_models = [str(item).strip() for item in model_catalog if str(item).strip()]
6187
+ options = ["__select_model__", *list(dict.fromkeys(discovered_models))]
6188
+ if current_model and current_model not in options:
6189
+ options.insert(1, current_model)
6190
+ selected_model = st.selectbox(
6191
+ "Modelo",
6192
+ options,
6193
+ index=options.index(current_model) if current_model in options else 0,
6194
+ format_func=lambda value: "Seleccione um modelo" if value == "__select_model__" else value,
6195
+ help="Consulte o catálogo do provider e seleccione um modelo disponível.",
6196
+ key=f"media_card_{card_id}_model_select",
6197
+ )
6198
+ model = "" if selected_model == "__select_model__" else selected_model
6164
6199
  base_url = st.text_input("Base URL", value=str(card.get("base_url") or definition.default_base_url), key=f"media_card_{card_id}_base_url")
6165
6200
  extra_values: dict[str, str] = {}
6166
6201
  if definition.extra_fields:
@@ -6177,17 +6212,26 @@ def _render_media_provider_card(settings: dict[str, Any], cards: list[dict[str,
6177
6212
  supports_video = st.checkbox("Pool Vídeo", value=bool(card.get("supports_video", definition.supports_video)), key=f"media_card_{card_id}_video")
6178
6213
  with status_cols[3]:
6179
6214
  priority = st.number_input("Prioridade", min_value=0, max_value=999, value=int(card.get("priority", index)), step=1, key=f"media_card_{card_id}_priority")
6180
- action_cols = st.columns(3)
6215
+ action_cols = st.columns(4)
6181
6216
  with action_cols[0]:
6182
- test_clicked = st.form_submit_button("Testar Chamada API", use_container_width=True, key=f"media_card_{card_id}_test")
6217
+ refresh_clicked = st.form_submit_button("Consultar Modelos", use_container_width=True, key=f"media_card_{card_id}_refresh")
6183
6218
  with action_cols[1]:
6184
- save_clicked = st.form_submit_button("Salvar", type="primary", use_container_width=True, key=f"media_card_{card_id}_save")
6219
+ test_clicked = st.form_submit_button("Testar Chamada API", use_container_width=True, key=f"media_card_{card_id}_test")
6185
6220
  with action_cols[2]:
6221
+ save_clicked = st.form_submit_button("Salvar", type="primary", use_container_width=True, key=f"media_card_{card_id}_save")
6222
+ with action_cols[3]:
6186
6223
  remove_clicked = st.form_submit_button("Remover provider", use_container_width=True, key=f"media_card_{card_id}_remove")
6187
6224
  edited = dict(card)
6188
6225
  edited.update({"api_key": str(api_key or "").strip(), "model": str(model or "").strip(), "base_url": str(base_url or "").strip(), "enabled": bool(enabled), "supports_image": bool(supports_image), "supports_video": bool(supports_video), "priority": int(priority), **extra_values})
6189
6226
  cards[index] = edited
6190
- if test_clicked:
6227
+ if refresh_clicked:
6228
+ try:
6229
+ discovered = _fetch_media_models(edited)
6230
+ st.session_state[f"media_model_catalog_{card_id}"] = discovered
6231
+ st.success(f"{len(discovered)} modelo(s) disponíveis neste endpoint.")
6232
+ except Exception:
6233
+ st.error("Não foi possível consultar os modelos deste provider. Confirme a API key e a Base URL.")
6234
+ elif test_clicked:
6191
6235
  result = test_media_provider_card(edited)
6192
6236
  edited["test_result"] = stamp_test_result(result)
6193
6237
  _persist_media_cards(settings, cards, str(settings.get(MEDIA_IMAGE_ACTIVE_CARD_KEY) or ""), str(settings.get(MEDIA_VIDEO_ACTIVE_CARD_KEY) or ""))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.4.29",
3
+ "version": "0.4.30",
4
4
  "description": "Thunderbolt — interface local para operação de canais faceless e motor MoneyPrinterTurbo",
5
5
  "license": "MIT",
6
6
  "main": "scripts/cli.mjs",