@danhachuel/thunderbolt 0.6.87 → 0.6.88

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 CHANGED
@@ -77,7 +77,7 @@ def display_version(version: str) -> str:
77
77
 
78
78
  APP_VERSION_LABEL = display_version(APP_VERSION)
79
79
 
80
- from hermes_ui.domain import STAGES, create_batch, create_channel, create_tasks_for_batch, delete_channel, delete_task, pipeline_summary, remake_video_task, retry_task_with_current_settings, set_channel_defaults, stop_task_by_user, transition_task, update_channel, update_channel_video
80
+ from hermes_ui.domain import STAGES, composio_connected_account_id_from_channel_name, create_batch, create_channel, create_tasks_for_batch, delete_channel, delete_task, pipeline_summary, remake_video_task, retry_task_with_current_settings, set_channel_defaults, stop_task_by_user, transition_task, update_channel, update_channel_video
81
81
  from hermes_ui.channel_import import build_channel_template_xlsx, channel_is_duplicate, find_duplicate_channel, parse_channel_workbook, resolve_blueprint, resolve_google_account, resolve_voice
82
82
  from hermes_ui.drafts import list_drafts, save_draft
83
83
  from hermes_ui.automation_worker import load_worker_status
@@ -1399,6 +1399,7 @@ def render_channel_audio_subtitle_defaults(channel: dict) -> None:
1399
1399
  def render_channel_edit_form(channel: dict, youtube_account_ids: list[str], youtube_account_labels: dict[str, str], youtube_accounts_by_id: dict[str, dict[str, Any]]) -> None:
1400
1400
  channel_id = str(channel["id"])
1401
1401
  blueprint_ids, blueprint_labels, current_blueprint, voice_options, current_voice = channel_default_options(channel)
1402
+ current_composio_account_id = str(channel.get("composio_connected_account_id") or composio_connected_account_id_from_channel_name(channel.get("name") or ""))
1402
1403
  account_ids = list(youtube_account_ids)
1403
1404
  current_account = str(channel.get("google_account_id") or "")
1404
1405
  if current_account and current_account not in account_ids:
@@ -1423,6 +1424,7 @@ def render_channel_edit_form(channel: dict, youtube_account_ids: list[str], yout
1423
1424
  edited_blueprint = st.selectbox("Blueprint Padrão", blueprint_ids, index=blueprint_ids.index(current_blueprint) if current_blueprint in blueprint_ids else 0, format_func=lambda item: blueprint_labels.get(item, item or "Sem Blueprint padrão"))
1424
1425
  edited_voice = st.selectbox("Narrador/Voz Padrão", voice_options, index=voice_options.index(current_voice) if current_voice in voice_options else 0, format_func=lambda item: item or "Sem voz padrão")
1425
1426
  edited_account = st.selectbox("Conta Google para Upload directo", account_ids, index=account_ids.index(current_account) if current_account in account_ids else 0, format_func=lambda item: youtube_account_labels.get(item, item or "Sem conta Google associada"))
1427
+ edited_composio_account_id = st.text_input("Connected account ID do Composio", value=current_composio_account_id, help="Gerado automaticamente a partir do nome do canal no formato Nome-Do-Canal. Pode editar este valor para coincidir com o alias ligado no Composio.")
1426
1428
  edited_description = st.text_area("Descrição", value=str(channel.get("description") or ""), height=100)
1427
1429
  edited_automation = st.toggle("Automação ON", value=bool(channel.get("automation_on", False)), key=f"edit_automation_{channel_id}")
1428
1430
  edited_time = st.text_input("Horário diário (HH:MM)", value=str(channel.get("automation_time") or "00:00"))
@@ -1444,6 +1446,7 @@ def render_channel_edit_form(channel: dict, youtube_account_ids: list[str], yout
1444
1446
  "default_blueprint_id": edited_blueprint.strip(), "blueprint_id": edited_blueprint.strip(),
1445
1447
  "default_voice": edited_voice.strip(), "voice": edited_voice.strip(),
1446
1448
  "google_account_id": edited_account.strip(), "google_account_email": str(youtube_accounts_by_id.get(edited_account, {}).get("email", "")),
1449
+ "composio_connected_account_id": edited_composio_account_id.strip() or composio_connected_account_id_from_channel_name(edited_name),
1447
1450
  "description": edited_description.strip(), "automation_on": bool(edited_automation), "automation_time": edited_time.strip(),
1448
1451
  "subscriber_count": _channel_count_value(edited_subscribers) or None, "video_count": _channel_count_value(edited_videos) or None, "view_count": _channel_count_value(edited_views) or None,
1449
1452
  })
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import re
4
+ import unicodedata
4
5
  import uuid
5
6
  from typing import Any
6
7
 
@@ -21,6 +22,13 @@ def slugify(value: str) -> str:
21
22
  return value or "item"
22
23
 
23
24
 
25
+ def composio_connected_account_id_from_channel_name(name: str) -> str:
26
+ """Create the editable Composio account alias used by a YouTube channel."""
27
+ normalized = unicodedata.normalize("NFKD", str(name or "")).encode("ascii", "ignore").decode("ascii")
28
+ words = re.findall(r"[A-Za-z0-9]+", normalized)
29
+ return "-".join(word[:1].upper() + word[1:] for word in words)
30
+
31
+
24
32
  def make_id(prefix: str) -> str:
25
33
  return f"{prefix}_{uuid.uuid4().hex[:10]}"
26
34
 
@@ -31,6 +39,7 @@ def create_channel(name: str, url: str = "", metadata: dict[str, Any] | None = N
31
39
  "youtube_channel_id": "",
32
40
  "google_account_id": "",
33
41
  "google_account_email": "",
42
+ "composio_connected_account_id": composio_connected_account_id_from_channel_name(name),
34
43
  "name": name.strip(),
35
44
  "url": url.strip(),
36
45
  "platform": "youtube",
@@ -20,6 +20,7 @@ from integrations.youtube_direct_credentials import document_status
20
20
  from integrations.youtube_direct_upload import YouTubeDirectUploader
21
21
  from integrations.youtube_session_manager import renew_account_session
22
22
  from integrations.composio_upload import ComposioUploadError, execute_upload, resolve_tool_slug
23
+ from hermes_ui.domain import composio_connected_account_id_from_channel_name
23
24
  from hermes_ui.storage import read_json, write_json
24
25
  from hermes_ui.languages import language_locale
25
26
 
@@ -338,7 +339,7 @@ def _composio_upload(settings: dict[str, Any], *, channel: dict[str, Any], **kwa
338
339
  str(kwargs.get("video_path") or ""),
339
340
  file_field,
340
341
  json.dumps(parsed_arguments, ensure_ascii=False),
341
- str(settings.get("composio_connected_account_id") or channel.get("composio_connected_account_id") or "").strip(),
342
+ str(channel.get("composio_connected_account_id") or composio_connected_account_id_from_channel_name(channel.get("name") or "") or settings.get("composio_connected_account_id") or "").strip(),
342
343
  )
343
344
  except ComposioUploadError as exc:
344
345
  return IntegrationResult(False, str(exc), {})
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.6.87",
3
+ "version": "0.6.88",
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",