Se você tem acompanhado a evolução do Rad IA — nosso plugin open-source de assistência de IA integrado nativamente à IDE do Delphi (Alexandria, Athens e Florence) —, sabe que nosso compromisso vai muito além de “envelopar APIs de IA”. Buscamos trazer produtividade real para o desenvolvedor Object Pascal sob as regras mais rígidas de Clean Code, SOLID e segurança em runtime.
Na recém-lançada versão v0.0.26, demos um salto gigantesco. Redesenhamos a experiência visual do chat para torná-la mais orgânica e premium, e realizamos uma profunda reforma estrutural de engenharia de software na base de código do plugin.
Neste artigo, convido você a dar uma olhada nos bastidores do que mudou no Rad IA, nas decisões de arquitetura que tomamos e em como blindamos o plugin contra travamentos e concorrência no Delphi.
Identidade Visual Premium: Logos SVG Oficiais e Dropdown Customizado
A primeira grande mudança é altamente visual. Até a versão anterior, o painel do chat lateral utilizava o logotipo clássico do robô do Rad IA para todas as respostas e um componente <select> nativo e sem estilo para alternar entre as IAs.
Na versão v0.0.26, elevamos o nível estético:
- Biblioteca de Ícones SVG Incorporada: Adicionamos caminhos vetoriais de alta fidelidade e gradientes oficiais extraídos diretamente da biblioteca de ícones
@lobehub/icons-static-svg(Lobe Icons). Cada marca agora brilha com suas cores exatas (o gradiente azul-roxo-rosa do Gemini, o verde#10A37Fda OpenAI, o laranja Anthropic do Claude, a baleia estilizada do DeepSeek, etc.). - Dropdown Customizado na Barra Inferior: Substituímos o seletor nativo por um componente visual HTML/JS responsivo e moderno no WebView2. O dropdown exibe o logotipo vetorial e o nome do provedor de forma elegante, mantendo a IDE fluida e adaptando-se instantaneamente aos temas Light e Dark do Delphi.
- Avatares Dinâmicos de Mensagens: Quando você conversa no chat, cada bolha de resposta do assistente assume dinamicamente o logotipo colorido correspondente à IA que gerou aquele conteúdo (ex: logo do Claude para respostas do Claude 3.5 Sonnet).
- Melhorias na forma de mostrar o consumo de tokens: Adicionamos a barra inferior melhores informarções de como os tokens estão sendo consumidos e gastos a cada prompt e resposta.
A Grande Reforma Interna: Inversão de Controle (IoC) e Desacoplamento de IDE
Se por fora o Rad IA está mais bonito, por dentro ele passou por uma reengenharia completa baseada no Princípio de Inversão de Dependência (DIP) do SOLID.
1. Injeção de Dependências com IoC Container Thread-Safe
Anteriormente, os nossos apresentadores (Presenters do MVP) e ganchos do editor dependiam de instâncias concretas e singletons estáticos. Isso dificultava a modularidade e tornava impossível isolar o código de UI para testes unitários offline.
Introduzimos a unit RadIA.Core.Container.pas, que implementa um container IoC genérico (TRadIAContainer). Por rodar dentro do processo principal da IDE (bds.exe), o container foi blindado contra race conditions concorrentes de leitura e escrita em background threads utilizando sincronização estrutural com TMonitor (TMonitor.Enter / TMonitor.Exit), eliminando o risco latente de Access Violations de memória compartilhada.
O boot do container e o registro de serviços ocorrem de forma centralizada na inicialização do plugin (RadIA.OTA.Register.pas):
TRadIAContainer.Register<IRadIAService, TRadIAService>;
TRadIAContainer.Register<IRadIAConfig, TRadIAConfig>;
TRadIAContainer.Register<IRadIAHttpClient, TRadIAConcreteHttpClient>;
TRadIAContainer.Register<IRadIAErrorDecoder, TRadIAErrorDecoder>;
TRadIAContainer.Register<IRadIALocalizer, TRadIALocalizer>;
2. Desacoplamento da Open Tools API com IRadIAIDEAdapter
Interagir com as APIs nativas do Delphi (como BorlandIDEServices e IOTAEditorServices) exige dependências físicas diretas do uses de units da IDE. Isso impedia que compilássemos e rodássemos testes unitários fora da IDE.
Para sanar isso, abstraímos todo o comportamento da IDE na interface IRadIAIDEAdapter. Em produção, o container resolve a classe concreta TRadIAConcreteIDEAdapter que conversa com a OTA. Nos testes unitários de regressão, injetamos o mock TMockIDEAdapter, permitindo que toda a inteligência do orquestrador de serviços do Rad IA seja testada em consoles puros offline!
3. Composition Root Físico (RadIA.Providers.Link.pas)
Limpamos o uses do orquestrador central TRadIAService. Ele não conhece mais nenhuma classe concreta de provedor de IA (Gemini, OpenAI, Claude, Bedrock). Criamos a unit RadIA.Providers.Link.pas (Composition Root), que liga fisicamente as units dos provedores de IA no pacote BPL principal e executa o auto-registro (initialization) dinamicamente. O serviço central agora opera exclusivamente com metadados e abstrações de interfaces!
Serviços de Infraestrutura Altamente Especializados (SRP)
Aplicamos o Princípio de Responsabilidade Única (SRP) para fatiar infraestruturas genéricas em unidades desacopladas:
- Conectividade Unificada (
IRadIAHttpClient): Extraímos toda a lógica de tratamento de time-outs, sockets e decodificação incremental de pacotes Server-Sent Events (SSE) de dentro dos conectores de IAs para uma classe especializada. - Central de Erros de APIs (
IRadIAErrorDecoder): Um parser robusto que analisa retornos de falha HTTP (como 401, 403, 429 ou 500) e decodifica as estruturas JSON dinâmicas de erro de múltiplos gateways de IA, transformando alertas crípticos em diagnósticos didáticos e amigáveis para o usuário. - Internacionalização Pronta (
IRadIALocalizer): Dicionário de localização em memória que já nasceu dando suporte nativo a múltiplos idiomas (pt-BReen).
Testes Unitários de Regressão e Segurança de I/O de Dados
Uma das maiores preocupações de quem desenvolve plugins de IDE é a segurança de dados locais. Durante o ciclo de testes, as units de persistência precisam ser testadas exaustivamente.
Nesta versão, parametrizamos todos os construtores de templates (TPromptTemplateManager), históricos e gerenciador de sessões (TRadIASessionManager) com injeção de diretório base (ADataDir).
Durante a execução da suíte de testes unitários com o DUnitX, geramos subdiretórios temporários dinâmicos baseados em GUIDs (dentro de TPath.GetTempPath) na fase de Setup e realizamos a varredura completa de exclusão no TearDown. Isso isola e blinda absolutamente os arquivos reais de produção e chats do desenvolvedor local, que antes eram acidentalmente apagados pelos testes automatizados.
Resultados da Validação da Matriz
Otimizamos a unit RadIA.Tests.ProvidersEx.pas aplicando o princípio DRY para condensar rotinas repetitivas de streaming SSE em helpers parametrizados, reduzindo o arquivo de teste em mais de 500 linhas de redundâncias de asserção.
A suíte agora conta com 177 testes unitários offline concluídos com 100% de sucesso e 0 vazamentos de memória (Memory Leaks) na matriz Delphi 11 Alexandria, Delphi 12 Athens e Delphi 13 Florence.
Conclusão e Download
A versão v0.0.26 do Rad IA é um marco de maturidade técnica do projeto. Ela consolida uma interface extremamente agradável e refinada com a solidez de uma arquitetura limpa, pronta para receber novas automações inteligentes e refatorações complexas de código legado nas próximas etapas do nosso roadmap.
Gostou das novidades e quer contribuir ou usar no seu dia a dia? O Rad IA é totalmente open-source. Acesse o repositório, faça o download e confira as instruções de instalação:
GitHub – Rad IA Plugin (regyssilveira/RadIA-Plugin)
Deixe sua estrela no repositório, compartilhe suas ideias no canal de Issues e bons códigos Delphi!
Descubra mais sobre Régys Borges da Silveira
Assine para receber nossas notícias mais recentes por e-mail.
Dê-nos sua opinião, seu comentário ajuda o site a crescer e melhorar a qualidade dos artigos.