@danhachuel/thunderbolt 0.6.86 → 0.6.87

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
@@ -6363,6 +6363,7 @@ def render_upload_composio():
6363
6363
  settings = read_json("settings.json", {})
6364
6364
  api_key = str(settings.get("composio_api_key") or "").strip()
6365
6365
  user_id = str(settings.get("composio_user_id") or "").strip()
6366
+ connected_account_id = str(settings.get("composio_connected_account_id") or "").strip()
6366
6367
  if not settings.get("composio_enabled", False) or not api_key:
6367
6368
  st.warning("Composio está desactivado ou sem API key. Configure-o em Configuração API > API Keys Upload > Composio.")
6368
6369
  return
@@ -6414,7 +6415,7 @@ def render_upload_composio():
6414
6415
  if st.button("Enviar vídeo via Composio", type="primary", key=f"composio_upload_send_{selected_task_id}", use_container_width=True):
6415
6416
  try:
6416
6417
  parse_arguments(arguments_json)
6417
- result = execute_upload(api_key, user_id, selected_slug, video_path, file_field, arguments_json)
6418
+ result = execute_upload(api_key, user_id, selected_slug, video_path, file_field, arguments_json, connected_account_id)
6418
6419
  record = {"id": uuid.uuid4().hex, "task_id": task.get("id"), "destination": "Composio", "target": {"toolkit": selected_tool.get("toolkit"), "slug": selected_slug, "file_field": file_field}, "status": "published" if result.get("successful") else "failed", "message": result.get("error") or "Upload Composio concluído.", "data": result.get("data") or {}, "log_id": result.get("log_id") or "", "created_at": now()}
6419
6420
  uploads = read_json("uploads.json", [])
6420
6421
  uploads.append(record)
@@ -112,28 +112,34 @@ def _client(api_key: str, *, upload_dir: Path | None = None):
112
112
 
113
113
 
114
114
  def _connected_account_id(client: Any, user_id: str, toolkit: str, selector: str) -> str:
115
- """Resolve a connected-account ID from an ID or UI alias."""
115
+ """Resolve a connected-account ID from an ID, alias, or sole active account."""
116
116
  value = str(selector or "").strip()
117
- if not value:
118
- return ""
119
117
  try:
120
118
  response = client.connected_accounts.list(user_ids=[_require_user_id(user_id)], statuses=["ACTIVE"])
121
119
  raw = _safe_value(response)
122
120
  items = raw.get("items", []) if isinstance(raw, dict) else raw
123
121
  if not isinstance(items, list):
124
122
  items = []
125
- wanted = value.casefold()
123
+ matching_items = []
126
124
  for item in items:
127
125
  if not isinstance(item, dict):
128
126
  continue
129
127
  toolkit_value = item.get("toolkit")
130
128
  if isinstance(toolkit_value, dict):
131
129
  toolkit_value = toolkit_value.get("slug") or toolkit_value.get("name")
132
- candidates = [item.get("id"), item.get("nanoid"), item.get("alias"), item.get("name")]
133
130
  if str(toolkit or "").strip() and toolkit.casefold() not in str(toolkit_value or "").casefold():
134
131
  continue
135
- if any(str(candidate or "").strip().casefold() == wanted for candidate in candidates):
136
- return str(item.get("id") or item.get("nanoid") or value).strip()
132
+ matching_items.append(item)
133
+ if value:
134
+ wanted = value.casefold()
135
+ for item in matching_items:
136
+ candidates = [item.get("id"), item.get("nanoid"), item.get("alias"), item.get("name")]
137
+ if any(str(candidate or "").strip().casefold() == wanted for candidate in candidates):
138
+ return str(item.get("id") or item.get("nanoid") or value).strip()
139
+ return value
140
+ if len(matching_items) == 1:
141
+ item = matching_items[0]
142
+ return str(item.get("id") or item.get("nanoid") or "").strip()
137
143
  except Exception:
138
144
  # Preserve the original selector so Composio returns its actionable error.
139
145
  return value
@@ -237,8 +243,12 @@ def execute_upload(api_key: str, user_id: str, slug: str, video_path: str, file_
237
243
  "dangerously_skip_version_check": True,
238
244
  }
239
245
  selected_account = _connected_account_id(client, user_id, "youtube", connected_account_id)
240
- if selected_account:
241
- execute_kwargs["connected_account_id"] = selected_account
246
+ if not selected_account:
247
+ raise ComposioUploadError(
248
+ f"Nenhuma conta YouTube activa está ligada ao Composio user ID `{_require_user_id(user_id)}`. "
249
+ "Use `Autorizar toolkit no Composio` ou configure o Connected account ID correcto."
250
+ )
251
+ execute_kwargs["connected_account_id"] = selected_account
242
252
  result = client.tools.execute(slug, **execute_kwargs)
243
253
  response = _response(result)
244
254
  if not response["successful"] and not response["error"]:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.6.86",
3
+ "version": "0.6.87",
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",