feat: corrigido o KeyError 'totalTracks' no cliente MCP: extração

- corrigido o KeyError 'totalTracks' no cliente MCP: extração de structuredContent.data na resposta do servidor (SDK 2.0+)
- sincronizado cortes de vídeo e áudio usando razor_all_tracks em vez de split_clip por faixa, eliminando drift entre cortes
- atualizado hook para usar razor_all_tracks, isolando vídeo e áudio no mesmo instante
- adicionado simulador razor_all_tracks no dublê de teste

Resumo:
- 5 arquivos alterados
- 0 novos
- 5 modificados
- 0 removidos

 5 files changed, 264 insertions(+), 12 deletions(-)

Arquivos:
  - .jhonny/analises.db
  - code/engine/editor/aplicador_de_plano_de_edicao.py
  - code/engine/editor/escrita/escrita_no_editor.py
  - code/engine/integracoes/visual/apple_vision_runner.swift
  - code/engine/testes/duplos_de_premiere.py
This commit is contained in:
João Henrique
2026-09-10 17:31:10 -04:00
parent fc7310be39
commit 2c11ba8dda
5 changed files with 264 additions and 12 deletions
@@ -560,7 +560,64 @@ func descreverEvidencia(_ evidencia: Evidencia) -> String {
}
}
/// Classificação de ambiente extraída das evidências visuais.
/// Usado pelo Foundation Models para categorizar o cenário do frame.
struct ClassificacaoAmbiente: Encodable {
let ambiente: String
let confianca: Double
let evidencias_chave: [String]
}
/// Taxonomia de ambientes para classificação editorial.
/// Cada ambiente tem descrição de características visuais que o Foundation Models deve procurar.
enum TaxonomiaAmbientes {
static let instrucoes = """
Você identifica o ambiente de cenas de vídeo. Analise as evidências visuais fornecidas \
e classifique o ambiente segundo a taxonomia abaixo. Responda APENAS com JSON válido.
TAXONOMIA DE AMBIENTES:
- centro_cirurgico: pessoas com touca/avental/máscara/camisinha cirúrgica, cores branco/azul cirúrgico, \
mesa cirúrgica, luzes de sala de operação, monitores cardíacos, instrumentos cirúrgicos, campo estéril verde/azul.
- consultorio: mobiliário médico simples, mesa de exame, quadro na parede, equipamento clínico de escritório.
- hospital_ambiente: corredor hospitalar, leito, roupa de paciente, enfermeiros, soro, monitor.
- laboratorio: microscópio, tubos de ensaio, centroides, bancada com reagentes, jaleco branco.
- escritorio: mesa de trabalho, computador, cadeira ergonômica, estantes, iluminação artificial.
- sala_reuniao: mesa comprida, cadeiras ao redor, projetor/tela, quadro branco.
- externo_urbano: rua, edifícios, trânsito, calçada, céu aberto.
- externo_natural: árvores, gramado, água, montanha, praia, campo.
- studio: fundo neutro/escuro, iluminação profissional, equipamento de gravação.
- industria: maquinário, linha de produção, capacete, colete, ambiente fabril.
- domesticos: sala, cozinha, quarto, mobiliário residencial, iluminação caseira.
- academia: equipamentos de musculação, esteira, peso, pessoa se exercitando.
- outro: qualquer ambiente que não se encaixe nas categorias acima.
REGRAS:
1. Analise as evidências visuais (pessoas, roupas, objetos, texto OCR, categorias Vision).
2. Identifique os 2-3 indícios mais fortes para a classificação.
3. Atribua confiança de 0.0 a 1.0 baseada na força dos indícios.
4. Se houver texto OCR relevante (placas, placas de identificação), use como evidência forte.
5. Não invente informações não presentes nas evidências.
"""
static let promptClassificar = """
Classifique o ambiente deste frame de vídeo com base nas evidências visuais fornecidas.
Responda APENAS com JSON no formato: {"ambiente": "categoria", "confianca": 0.0-1.0, "evidencias_chave": ["evidência 1", "evidência 2"]}
"""
}
func interpretar(_ saida: Saida) async -> String? {
guard SystemLanguageModel.default.isAvailable else { return nil }
let fatos = saida.evidencias.map(descreverEvidencia).joined(separator: "; ")
guard !fatos.isEmpty else { return nil }
do {
let sessao = LanguageModelSession(instructions: TaxonomiaAmbientes.instrucoes)
let resposta = try await sessao.respond(to: "\(TaxonomiaAmbientes.promptClassificar)\n\nEvidências visuais: \(fatos)")
return resposta.content
} catch { return nil }
}
/// Interpretação editorial legível (frase curta) — mantida para compatibilidade.
func interpretarFrase(_ saida: Saida) async -> String? {
guard SystemLanguageModel.default.isAvailable else { return nil }
let fatos = saida.evidencias.map(descreverEvidencia).joined(separator: "; ")
guard !fatos.isEmpty else { return nil }