feat: destacado no deploy o resumo que será gravado na mensagem do

- destacado no deploy o resumo que será gravado na mensagem do commit

Resumo:
- 8 arquivos alterados
- 1 novos
- 7 modificados
- 0 removidos

 7 files changed, 143 insertions(+), 11 deletions(-)

Arquivos:
  - .jhonny/analises.db
  - admin/deploy.command
  - code/engine/executar_scanner.py
  - code/engine/integracoes/midia/__init__.py
  - code/engine/integracoes/visual/apple_vision.py
  - code/engine/scanner/configuracao_visual.py
  - code/engine/scanner/visual.py
  - code/engine/integracoes/midia/compactador_de_proxy.py
This commit is contained in:
João Henrique
2026-09-08 18:40:52 -04:00
parent 5cc50f00a4
commit 400c3c93dd
8 changed files with 313 additions and 11 deletions
+32 -3
View File
@@ -143,17 +143,25 @@ class AnalisadorAppleVisionNativo(AnalisadorDeFrame):
def __init__(self, recursos: tuple[str, ...] = RECURSOS_PADRAO,
interpretar_com_apple_intelligence: bool = True,
executor: ExecutorDoRunnerApple | None = None,
timeout_em_segundos: float = 90.0) -> None:
timeout_em_segundos: float = 90.0,
maximo_de_frames_interpretados: int | None = None) -> None:
self.recursos = recursos
self.interpretar_com_apple_intelligence = interpretar_com_apple_intelligence
self.executor = executor or ExecutorDoRunnerApple()
self.timeout_em_segundos = timeout_em_segundos
# Limita quantos frames por clipe fazem a interpretação editorial (Apple
# Intelligence / Foundation Models), que é a parte mais cara. Os demais
# frames continuam com a análise visual completa. None = interpreta todos.
self.maximo_de_frames_interpretados = maximo_de_frames_interpretados
def analisar(self, quadro: QuadroDeVideo) -> list[EvidenciaVisual]:
def analisar(self, quadro: QuadroDeVideo, interpretar: bool | None = None) -> list[EvidenciaVisual]:
if quadro.caminho is None:
raise ValueError("Apple Vision requer que o frame tenha caminho persistido em disco.")
if self._indices_para_interpretar and quadro.indice not in self._indices_para_interpretar:
interpretar = False
deve_interpretar = interpretar if interpretar is not None else self.interpretar_com_apple_intelligence
dados = self.executor.executar({"frame": str(quadro.caminho), "recursos": list(self.recursos),
"resumir": self.interpretar_com_apple_intelligence},
"resumir": deve_interpretar},
self.timeout_em_segundos)
evidencias = [self._converter(item, quadro) for item in dados.get("evidencias", [])]
avisos = dados.get("avisos", [])
@@ -162,6 +170,27 @@ class AnalisadorAppleVisionNativo(AnalisadorDeFrame):
{"avisos": avisos, "recursos_solicitados": list(self.recursos)}, provider=self.nome))
return evidencias
def preparar_interpretacao_por_clipe(self, quantidade_de_frames: int) -> None:
"""Marca os índices de frames que receberão a interpretação editorial.
Distribui a interpretação ao longo do clipe (início, pontos médios e fim)
em vez de aplicar a todos os frames, mantendo a cobertura de cena com
custo muito menor. Quando não há limite (None), interpreta todos.
"""
if self.maximo_de_frames_interpretados is None or quantidade_de_frames <= 0:
self._indices_para_interpretar = set(range(quantidade_de_frames))
return
quantidade = min(quantidade_de_frames, max(1, self.maximo_de_frames_interpretados))
indices = set()
if quantidade_de_frames == 1:
indices.add(0)
else:
passo = max(1, quantidade_de_frames // quantidade)
indices = set(range(0, quantidade_de_frames, passo)) | {quantidade_de_frames - 1}
self._indices_para_interpretar = {i for i in indices if i < quantidade_de_frames}
_indices_para_interpretar: set[int] = set()
def _converter(self, item: dict[str, Any], quadro: QuadroDeVideo) -> EvidenciaVisual:
return EvidenciaVisual(item["tipo"], quadro.timestamp, quadro.timestamp, item["valor"],
confianca=item.get("confianca"), provider=self.nome,