Na nota de agosto, escrevemos uma frase: o assistente não seria aberto nesta versão.
Não foi preguiça. Naquela época, o Agent de primeira geração já conseguia conversar, buscar faixas e gerar prévias na página de Organização; o que realmente travou foi a base. Empilhar mais funções em cima disso equivaleria a soldar a orquestração, a sessão, a chave e o write-back no mesmo processo. O segundo produto teria que ser feito novamente. Escolhemos desmontar o conjunto que já rodava e trocar por um runtime que pudesse ser incorporado, auditado e que isolasse falhas.
Essa troca foi muito mais difícil do que escrever uma caixa de chat do zero.
🛠 A primeira geração já funcionava, e aí começou o problema
O conjunto de julho não era um protótipo. Era um assistente completo embutido no processo do PureLab: fluxo de múltiplos turnos, sessões gravadas no banco de dados, cancelamento e bloqueio serial, chave de modelo fornecida pelo usuário, busca na biblioteca e prévias de tags. O write-back continuava passando pelo próprio portão de confirmação do produto. A segurança de domínio era um ponto forte — o modelo não podia editar arquivos diretamente, os caminhos eram ofuscados e o controle do plano não podia ser contornado apenas por passar pelo chat.
O problema não era «se conseguia conversar», o problema era o formato.
Orquestração, canal de eventos, tabela de sessões, descriptografia de chaves, chamadas de ferramentas, tudo estava dentro do processo do produto. A interface só reconhecia esse único fluxo de eventos. Se trocasse a biblioteca, mudasse a barra ou gerasse um conflito, a máquina de estados teria que ser escrita novamente no frontend e no backend. Pior ainda: se o próximo produto para desktop também quisesse um assistente, isso significaria copiar outro Host inteiro. Isso não é incorporar, é cada App criar o seu próprio Agent.
Não é que não tenhamos tentado «manter o antigo e plugar um novo».
🚧 O desvio mais árduo: mantivemos dois motores para comparar resultados, mas o design de quatro mil linhas foi descartado
No início de agosto, havia um caminho que parecia mais seguro: a barra lateral direita abrigaria simultaneamente a «IA Clássica» e o «Assistente Inteligente». Inicialmente, a ideia de manter o núcleo antigo era apenas para ter uma base de comparação ao conectar a nova base. Esperávamos que, enquanto o novo processo isolado lentamente alcançasse a compatibilidade com o Windows, o empacotamento e o canal de chaves, pudéssemos validar a qualidade das saídas do modelo através do motor antigo.
No papel, isso se chamava transição suave, mas ao ser implementado no design, tornou-se um desastre.
Para manter essa “comparação”, os dois conjuntos de comandos de conversa não podiam se misturar, as duas sessões não podiam ser reconciliadas, mas a mesma chave precisava ser alimentada tanto na orquestração dentro do processo quanto no processo isolado. E o pior: a chave não podia ser gravada em variáveis de ambiente, nem em arquivos de configuração. Prévia, confirmação, write-back e reversão precisavam continuar seguindo a cadeia de segurança do produto, enquanto o novo núcleo não podia ter permissão arbitrária sobre os arquivos. O Windows, na época, fechou explicitamente o processo isolado; a entrada ainda tinha que estar lá, o texto tinha que ser compreensível, e não podia ficar em branco nem dar crash.
Aquele design de dupla entrada, feito apenas para “comparar resultados”, forçou mais de trinta decisões rígidas e o texto ultrapassou as quatro mil linhas. Antes mesmo de começarmos a implementá-lo, já sabíamos: aquilo não era uma comparação, era criar simultaneamente dois assistentes, duas bases de dados e dois domínios de falha. Qualquer pensamento de «compatibilizar a sessão antiga» trancaria os dois lados.
No dia 13 de agosto, todo o documento foi descartado.
O novo contrato tem apenas algumas frases, mas cada uma custa caro: o Kit é totalmente composto por código novo, comandos novos e canal de eventos novo. Nenhuma compatibilidade com o caminho antigo, nenhuma reconciliação, nenhuma migração de histórico, nenhuma tabela compartilhada. A “missão de comparação” do Agent antigo foi diretamente encerrada. Ao apagar, removemos apenas a entrada antiga do produto, sem alterar o novo contrato.
Isso significa que o usuário não verá a opção de «recuperar o histórico de conversas anterior». Não foi um esquecimento, foi intencional. Migrar a sessão antiga para o novo runtime parece ser cuidadoso, mas, na verdade, amarra para sempre os ciclos de vida de ambos. Não podemos pagar esses juros.
⛰️ As montanhas que tiveram de ser removidas para trocar a base
O descarte foi apenas a permissão. O verdadeiro esforço foi separar «a função de chat do produto» em três camadas, e ainda conectá-la ao PureLab em um mês.
- 📦 A primeira montanha é o processo: O loop do modelo não pode mais disputar o mesmo domínio de falha com a página de organização, o write-back e a análise. A conversa roda em um processo isolado; o produto apenas inicia, supervisiona e, em caso de falha, retira. Se o processo isolado falhar, a biblioteca e o pipeline de tags devem continuar lá. Por outro lado, o produto também nunca deve passar um terminal genérico, um sistema de arquivos arbitrário ou ferramentas externas para o modelo; a permissão de escrita da biblioteca de música não pertence ao assistente.
- 🔌 A segunda montanha é o protocolo: A interface não deve falar sobre o protocolo de sessão subjacente, nem o produto deve criar manualmente um ciclo de «enviar prompt, ouvir evento, construir o histórico». No meio, deve haver uma camada de protocolo de produto estável: enviar, parar, listar sessões, restaurar, canal de configurações. O transporte pode ser por comandos de desktop, mas o protocolo em si não pertence a um aplicativo específico. O que o segundo produto fará é pendurar um painel, fornecer a identidade da biblioteca atual e registrar as capacidades do domínio, não implementar o Host novamente.
- 🔑 A terceira montanha é a chave: A Key do modelo do usuário continua selada no produto. Essa Key não deve aparecer no disco nem nas variáveis de ambiente do processo isolado. A requisição retorna do processo isolado para a máquina local (loopback), é brevemente descompactada pelo processo do produto, transferida para a interface preenchida pelo usuário e, em seguida, descartada. Copiar o arquivo do banco de dados ainda pode permitir a recuperação do texto cifrado; esse é um risco conhecido, e não fingimos já tê-lo resolvido com as chaves de sistema.
- 🛠 A quarta montanha são as ferramentas de domínio: O assistente pode buscar na biblioteca autorizada no momento, ler faixas, visualizar renomeações e patches de tags, e também gerar rascunhos. Mas não pode iniciar o write-back, não pode iniciar a renomeação, não pode iniciar o pipeline e nem fazer a análise. O fluxo de trabalho deve ser: primeiro visualizar de 1 a 5 faixas; se a amostra estiver certa, gerar no máximo 50 rascunhos; a bancada exibe a caixa de write-back e os arquivos só são alterados se você clicar em Apply. O modelo não tem permissão para inventar caminhos, exigir identificadores internos da biblioteca, nem afirmar que «os arquivos já foram alterados».
- 🚀 A quinta montanha é o empacotamento multiplataforma: Com o mesmo contrato, o macOS precisa passar por uma assinatura de sandbox; no Windows, o processo isolado ficou indisponível por um tempo, e só conseguíamos exibir a mensagem «indisponível no sistema atual». Somente em setembro o Windows alinhou o diretório principal do processo isolado, as opções de capacidade e o diretório de depuração/lançamento. Em um Agent de software para desktop, metade do trabalho não está na conversa, mas em garantir que «ele seja instalável, executável e não quebre o programa principal».
Essas cinco montanhas tinham que ser movidas juntas. Fazer primeiro a conversa e depois a segurança, ou primeiro a segurança e depois o Windows, faria com que a entrada antiga retornasse durante o período de comparação. E nós já havíamos removido a opção de trazer a entrada antiga de volta.
⚙️ Onde esse mês realmente foi gasto
Do meio de agosto até o dia 10 de setembro, o calendário marcava «integração». Mas os dias foram uma sucessão de tratamentos de limites problemáticos:
- O emaranhado do canal com a máquina de estado: Nas Configurações, tinha que haver uma entrada para o «Assistente de IA» que as pessoas pudessem encontrar. Sem configurações, o painel não podia ser exibido como se estivesse pronto; a barra de diálogo devia ficar vazia (em inglês) por padrão e o produto então injetaria um «Ir para configurações», levando a pessoa até a página de ajustes; os códigos de erro internos não podiam ser jogados na interface de qualquer jeito. Ao alterar o endereço da interface, chegou a ser obrigatório reenviar a Key, mas depois permitimos algo que uma pessoa faria, como «a Key ainda está lá, mude apenas o endereço ou o modelo». Esses não eram problemas de texto, era a máquina de estados do canal amarrada ao descompactamento da chave.
- Gerenciamento de sessão mais difícil que uma caixa de chat: A criação de uma nova sessão não podia ser sobrescrita por uma «restauração do último não vazio». Ao mudar para outra biblioteca, a lista de sessões tinha que mudar junto, não podia misturar; se fechasse a barra lateral direita e a abrisse novamente, na mesma execução deveria repor a tela e não reproduzir a conversa como uma máquina de escrever; a restauração completa só deveria acontecer ao fechar o software e abri-lo novamente. Quando mudávamos de aba e voltávamos, o histórico até chegou a ser perdido, mas depois consertamos para que fosse lembrado por sessão através dos eventos já projetados. Excluir uma sessão tinha que encerrar a sessão subjacente e limpar o diretório do disco, e também não podia permitir cliques acidentais durante a geração.
- O mecanismo de write-back extremamente desgastante: O portão de confirmação do Agent antigo estava correto; a nova base não podia ser mais flexível apenas por ter mudado o transporte. No chat, não seria mais perguntado se «permite esta ferramenta» — consultas já aprovadas são liberadas pelo host. Somente no início de setembro é que transformamos a etapa de «preencher parâmetros → pré-visualizar pequena amostra → gerar rascunho → clicar em Apply» num evento do produto, onde a confirmação para alterar o arquivo ainda ocorre na caixa de write-back, e não num popup de chat. Renomeações não têm patch, então foi preciso primeiro mostrar um mapeamento de caminho para você conferir na área de operações antes de aplicar. Qualquer frase que dissesse «o assistente já alterou o arquivo para você» nesse contrato é um bug.
- A independência e o compromisso da integração do painel: O painel precisava parecer uma bancada, e não uma demonstração. O Markdown foi usado apenas para títulos e listas, sem realce de sintaxe de código; a saída por fluxo (stream), as falhas e os cancelamentos compartilhavam o mesmo sistema de renderização. O interior do painel é codificado de forma rígida em inglês; o produto só consegue alterar a frase de entrada das configurações — esse é um dos preços de embutir três repositórios. Ele foi inserido no lado direito da página de organização, mas recentemente foi movido para o fundo, para não disputar a visão com as ações de extração, substituição e pipeline.
Nenhuma dessas coisas pôde ser lançada de forma independente. Uma mudança no protocolo exigia mexer no host, no painel e no adaptador do produto simultaneamente. Se esquecêssemos de mexer em um deles, o resultado seria: «às vezes conversa, às vezes perde o histórico, às vezes a chave vai para o lugar errado».
👀 O que você verá agora na bancada
O produto foi atualizado para a versão 6.0. No lado direito da página de Organização, a entrada de IA está fixa no fundo da barra de atividades. Ao abrir, há uma bancada de conversas completa: com suporte a várias sessões, recuperável e passível de interrupção a qualquer momento. Em relação à nota de agosto sobre a 5.0, a entrada agora é permanente; não afirmaremos neste texto que a versão já foi lançada nas lojas.
- Configuração flexível: Vá em Configurações e preencha sua própria interface, modelo e chave. Não amarramos a conversa a uma nuvem específica e, quando não há configurações, não recorremos furtivamente a um modelo embutido.
- Capacidades de domínio restritas: Depois de configurar, você pode falar com a biblioteca atualmente aberta. Por exemplo, visualizar renomeações de artista e álbum, ou dar uma olhada num pequeno lote de rascunhos de tags. O assistente pode buscar, visualizar e gerar propostas, mas se o arquivo vai ser alterado ou não, quem decide é você, na caixa de write-back ou na tela de comparação de renomeações. O pipeline de tags lançado em agosto continua lá; o assistente não apertará o botão de «Iniciar» por você.
- Fronteiras inegociáveis: Análises, capas, letras, complemento de metadados via rede — tudo isso continua indisponível para ele nesta rodada. Não é que não tenhamos pensado nisso, mas os limites devem estar muito bem fixados antes de discutirmos como ele fará mais.
💡 O custo que estávamos dispostos a pagar e as contas que ainda não fechamos
O custo mais alto da troca de base não foi escrever o código novo, mas admitir que a primeira geração já funcionava e que os dois motores mantidos para comparação pareciam muito estáveis — e, mesmo assim, decidir descartar todo o design com firmeza. Não migrar o histórico é uma atitude irresponsável com as antigas conversas; mas migrar é irresponsável com o novo contrato. Escolhemos a segunda opção e apagamos qualquer rastro da antiga entrada do produto, evitando que dois assistentes coexistam numa comparação sem fim.
As dívidas que ainda não pagamos também devem ficar claras. Mudar o canal para o nosso próprio relay, substituir os arquivos encriptados no banco de dados pelos chaveiros do sistema e fazer com que a distribuição no Windows seja tão simples quanto no macOS — essas coisas ainda estão a caminho. O assistente é atualmente um projeto piloto na bancada, não deve ser tratado como o slogan de marketing «O Assistente Inteligente foi lançado oficialmente».
Em agosto, reunimos a organização das tags numa única linha (pipeline), pois trabalhos repetitivos não devem depender da alternância manual de guias. Neste mês, retiramos o assistente do processo do produto, porque conversas, chaves e write-backs não devem compartilhar o mesmo domínio de falha. As duas linhas trabalham no mesmo sentido: permitir que a estação de organização local de bibliotecas se atreva a automatizar, mas também tenha a audácia de parar antes que os arquivos sejam efetivamente alterados.
Só depois de trocar a base é que podemos falar em realmente ajudá-lo a se organizar.
