WinGPT, um assistente de IA para Windows 3.1
(dialup.net)- WinGPT é um projeto que tenta executar um chatbot baseado na API da OpenAI até no Windows 3.1, com foco em chamar serviços modernos de IA a partir de PCs antigos como um 386
- A implementação é baseada em C e na API padrão do Windows, e graças ao Open Watcom v2 é possível gerar builds para Windows de 16 bits até mesmo no Windows 11
- Ele se conecta diretamente ao servidor da API da OpenAI com TLS 1.3, sem proxy, mas deixa explícito que essa implementação de TLS não é segura
- Como os controles básicos de UI do Windows 3.1 são limitados, elementos como a barra de status precisaram ser implementados manualmente ou adaptados de código antigo em domínio público
- Por causa das restrições de memória, ele pede respostas curtas e não envia os turnos anteriores da conversa, então não consegue manter contexto de conversa
Um experimento para chamar a API da OpenAI no Windows 3.1
- WinGPT é um assistente de IA para Windows 3.1 que se apresenta como útil para perguntas e respostas, piadas e rascunhos de documentos e planilhas via API da OpenAI
- Em uma nota de rodapé, o autor esclarece que essa descrição é satírica e diz para não depender dele, já que ele não consegue realizar essas funções com confiabilidade
- A implementação é baseada em C e na API padrão do Windows
- O compilador usado é o Open Watcom v2
- O Open Watcom v2 consegue fazer cross-compilation para Windows de 16 bits até mesmo no Windows 11
- Ele se conecta diretamente ao servidor da API da OpenAI com TLS 1.3
- Não é necessário um proxy para terminar o TLS em uma máquina moderna
- Em “Modern TLS on 16-bit Windows”, o autor aborda a implementação e as dificuldades, deixando claro que essa implementação de TLS não é segura
Dificuldades de UI causadas pela antiga API do Windows
- No Windows 3.1, usando apenas a API padrão do Windows, os recursos de construção de UI são muito limitados
- A maior parte da UI foi criada manualmente em código C, e também foi preciso escrever lógica de redimensionamento para que cada componente mantivesse o tamanho correto quando a janela mudasse de tamanho
- Os controles padrão se limitam basicamente a push button, check box, radio button e edit box
- As limitações do Windows 3.1 ficam especialmente evidentes na implementação da barra de status
- O File Manager e o Control Panel têm barras de status, mas a Microsoft não as disponibilizou amplamente para desenvolvedores de apps comuns até o Windows 95
- Ao perguntar ao ChatGPT como usar uma barra de status, ele sugeriu arquivos de cabeçalho que só existem em versões posteriores do Windows e, quando perguntado de novo, inventou o nome de uma biblioteca de UI que aparentemente não existe
- No fim, o autor usou a implementação de barra de status de Philip J. Erdelsky, de 1997, e a modificou para ficar mais parecida, até no nível de pixels, com a barra de status dos programas da Microsoft
- Os ícones foram criados com o Borland Image Editor
- Os ícones de programa do Windows 3.1 são 32x32 e aparecem no Program Manager e no alternador de tarefas
- Também foram criados separadamente ícones 16x16 para exibição em versões posteriores do Windows
Restrições de memória e condições de execução
- Por causa das restrições de memória das máquinas com Windows 3.1, foi necessário reduzir o uso de memória no processamento de requisições e respostas da API
- As respostas JSON das APIs modernas não são otimizadas para tamanho, e a API da OpenAI não é exceção
- Para manter as respostas pequenas, o modelo é instruído a responder de forma curta
- Como o texto dos turnos anteriores da conversa não é incluído na chamada da API, não é possível aproveitar o contexto anterior
- O WinGPT usa licença GNU GPL v2
- Funciona em versões de Windows de 16 ou 32 bits posteriores ao Windows 3.1
- Requer uma implementação de Winsock, e foi testado no Windows 3.11 for Workgroups com Microsoft TCP/IP-32 3.11b instalado e no Windows 2000 padrão
- Não funciona no Windows de 64 bits, mas pode ser executado no Wine
- Para se comunicar com a OpenAI, é necessária uma chave da API da OpenAI, inserida em
File | Options...após a execução - Download: Binaries for 16-bit and 32-bit Windows
- O código-fonte está incluído em modified WolfSSL source code, no caminho
watcom16/wingpt
2 comentários
kkkkkkkkkkkkkkkkkkkkkkkk
Opiniões no Hacker News
Acho que ficaria bom incluir isso na versão do MS Office daquela época
Dava até para transformar materiais de escritório reais da época em personagens antropomórficos, no estilo esqueumórfico; por exemplo, um elástico… ou… algo como um clipe de papel…
Há uma parte separada sobre fazer TLS 1.2 e 1.3 funcionarem no Windows 3.1 para que o WinGPT se conecte diretamente aos servidores da OpenAI sem depender da terminação TLS em uma máquina moderna: https://www.dialup.net/wingpt/tls.html
Vale muito a leitura. Em ambientes embarcados profundos, como IoT, e até em CPUs de 8 bits que usam bank switching, muitas vezes há suporte a TLS 1.2, então é um pouco surpreendente que tenha sido difícil colocar uma implementação de TLS dentro de 64 KB de código e dados
É triste quando sistemas operacionais um pouco antigos têm dificuldade para acessar a internet
Sinto muita saudade da era Windows 3.1, 95 e 98. Parece que a interface só piorou desde então
Toda vez que ligo um 386 ou um Pentium, fico surpreso com o quanto a GUI era limpa e pouco estressante. Estou realmente cansado do inferno de pop-ups de baixo contraste no estilo Apple/Google
Hoje, ao localizar, aparece um rótulo tipo "Tap to...." em metade da UI. Muitas vezes, ferramentas de UI modernas incríveis e os desenvolvedores estrela que as usam não conseguem nem fazer uma barra lateral arrastável
Se quiser trocar espaço por tempo de CPU, dá para usar parsing no estilo SAX
O parsing no estilo SAX percorre a árvore de cima para baixo e dispara eventos ao visitar cada nó. Em comparação com fazer o parsing completo do JSON, a memória necessária é desprezível, e não deve ser tão difícil escrever um parser JSON customizado no estilo SAX. Também há parsers JSON no estilo SAX já existentes que podem servir de referência
[1]: https://en.wikipedia.org/wiki/Simple_API_for_XML
[2]: https://rapidjson.org/md_doc_sax.html
Exato. Estou usando JSMN(https://github.com/zserge/jsmn), que é um parser de streaming que visita cada token sequencialmente, então só existe uma cópia da resposta JSON na memória
Também evito ao máximo novas alocações intermediárias. Por exemplo, ao remover escapes de barra invertida de uma string JSON, uso um loop destrutivo que move os caracteres que não são barras invertidas para a frente da memória e move o terminador nulo mais para a frente para cortar a string. É algo que quase ninguém faria em ambientes atuais, mas, como você disse, dá para gastar tempo de CPU e economizar um pouco de espaço :)
void DestructivelyUnescapeStr(LPSTR lpInput) {
int offset = 0;
int i = 0;
while (lpInput[i] != '\0') {
if (lpInput[i] == '\') {
offset++;
} else {
lpInput[i - offset] = lpInput[i];
}
i++;
}
lpInput[i - offset] = '\0';
}
É bem provável que a infraestrutura de suporte do controle de caixa de texto em que estou digitando agora consuma mais recursos do sistema do que o WinGPT inteiro
Isso mostra que, para aumentar um pouco a produtividade do desenvolvedor, desperdiçamos memória literalmente em várias ordens de grandeza. Programação com controles puros do Windows é difícil? Claro que é, mas também dá para argumentar que Delphi ou VB no Win95 eram muito mais produtivos do que toolkits de UI modernos, e os aplicativos resultantes usavam muito menos recursos. O que faltava de essencial era basicamente suporte a mobile e consciência de DPI
Acho que "pequeno ganho de produtividade do desenvolvedor" é, sinceramente, subestimar a questão
Coisas que eu sofria para fazer em código nativo quando era criança hoje viraram algo que praticamente qualquer pessoa consegue fazer com bibliotecas e ferramentas prontas voltadas para o navegador web. Isso, por si só, é uma conquista impressionante e não é algo ruim. O que mais lamento é que o navegador, ao se tornar a opção "melhor" no geral, esteja matando os aplicativos nativos
Hoje, empresas de software consideram óbvio que precisam oferecer acesso web a seus serviços de rede, então constroem primeiro para a web. Depois tentam dar suporte a iPhone, Windows, Android, macOS e Linux. Há opções que cobrem mais ou menos cada plataforma, mas, a essa altura, já existe pelo menos uma prova de conceito no navegador, e com uma instalação via NPM dá para colocar aquilo em uma janela separada, anexar um instalador e um sistema de distribuição e enviar. Não é excelente, mas é possível
Se existisse um framework GUI nativo, eficiente e com qualidade de produção que mirasse de forma eficiente o DOM e as UIs nativas de Windows, macOS, Android e iPhone, e que ainda desse suporte a entrada de texto nativa com IME e semântica própria da plataforma, acessibilidade integrada a leitores de tela, mudanças responsivas de UI para vários tamanhos de tela e elementos visuais independentes de DPI, robustos e rápidos, lidando corretamente com escalas fracionárias, o problema seria menor. Deve ser fácil, né?
Mas isso não existe. Eu gosto do Delphi VCL e do Win32 puro, mas eles também não atendem à maior parte disso. Dar suporte a todas essas plataformas é muito difícil. O navegador faz esse trabalho muito bem e também é uma das melhores fontes de código de exemplo para consultar ao escrever código profundamente específico de plataforma. Além disso, como a maior parte mira a web de qualquer forma, e o motor do navegador também é "código nativo", é muito mais fácil distribuir junto um navegador, ou pelo menos um motor JS, em uma plataforma que já executa código nativo do que criar uma solução de código nativo isomórfica que também rode no ambiente do navegador.
Você pode explicar melhor a parte de que "também dava para dizer que era muito mais produtivo"?
A produtividade precisa incluir também o conceito de distribuição. Pelos padrões da época, Delphi/VB ignoravam completamente essa questão.
Se fosse um utilitário simples de zip, bastava copiar um único EXE para algum compartilhamento de rede na LAN atrás do firewall. O Windows colocava dentro do binário uma espécie de pseudo-sistema de arquivos que fazia algo como carregar ícones e strings, e isso era suficiente. Se fosse um app mais complexo, que precisasse de DLLs e entradas no registro, você tinha que pagar centenas de dólares pelo InstallShield e aprender InstallScript. Até surgirem MSI e WiX, não havia meio-termo; e, até meados dos anos 1990, a Microsoft ainda via a internet como uma moda exótica e achava que distribuir software pela rede não era prático por causa da baixa largura de banda. Software era para CD-ROM, e "shipping" era literalmente colocar em um navio.
O problema é que as pessoas passaram a valorizar a velocidade de iteração quase acima de tudo, mais até do que a produtividade pura. O mundo mudou mais rápido que o Delphi. A Borland poderia ter percebido que a tendência de forçar o navegador a ser usado como se fosse um app representava uma necessidade fundamental não verbalizada, e poderia ter criado algo como um interpretador de Object Pascal. Por exemplo, se tivesse criado algo como um "Delphi Browser", ele teria sido adotado, mas a base de código era fundamentalmente voltada à produção de apps nativos para Windows, então essa transição teria sido difícil. Além disso, a Borland era mais como uma convidada na plataforma Windows e tendia a seguir a direção da Microsoft. A Microsoft promoveu o ActiveX como forma de ligar a web ao mundo Windows, e a Borland percebeu tarde demais que o ActiveX não atenderia às necessidades das pessoas. No começo, ela não via a web como concorrente; depois, passou a vê-la como um simples meio de transporte para apps Delphi; mais tarde ainda, tentou empurrar o uso do Delphi para escrever servidores web, mas seus pontos fortes não se encaixavam nisso.
A lição aqui é sobre preferências não verbalizadas, que você aprende observando o que as pessoas realmente fazem, não o que elas dizem, e sobre a importância esmagadora da distribuição. Distribuição continua sendo um ponto cego para a maioria dos concorrentes da web hoje. Até o ano passado, quase não havia plataformas parecidas com Delphi com distribuição no estilo web, em que tudo é atualizado a cada execução do app. Até o Electron oferece apenas atualizações no estilo desktop, totalmente assíncronas. Eu administro uma pequena empresa que cria um produto para consertar a distribuição de apps desktop dentro das limitações das plataformas nativas, e adicionei um modo de distribuição no estilo web chamado aggressive updates (https://hydraulic.dev/). Nesse modo, ele verifica atualizações a cada execução; então, se você consegue fazer o usuário reiniciar o app de vez em quando, ou forçar a reinicialização no momento adequado, dá para iterar muito rapidamente. Não é diferente de pedir que o usuário feche a aba e recarregue em uma SPA.
Por isso, não concordo que o ponto central que faltava fosse mobile e DPI. Delphi, VB, GTK, Cocoa etc. já tinham perdido o desktop antes de os smartphones se tornarem importantes. Eles não tinham bons sistemas de distribuição e atualização, e a capacidade de enviar correções e mudanças imediatamente era mais importante do que todos os outros recursos somados.
Parece que a velocidade do progresso tecnológico ficou rápida demais, a ponto de começarmos a sofrer um choque cultural vindo da nossa própria cultura, isto é, um choque do futuro. Essa velocidade vai aumentar ainda mais durante nossas vidas.
É bom rever software do Windows 3.1. Deixo isto também para os entusiastas de retrocomputação: https://www.xfce-look.org/p/1016410
TLS nativo é a parte mais impressionante.
Lembro de ter ouvido que a criptografia moderna não poderia ser usada em CPUs antigas por causa da quantidade de cálculos numéricos difíceis de otimizar. Algo como algumas etapas do algoritmo de troca de chaves demorarem tanto que o servidor poderia expirar a conexão. Mas, pelo visto, em um 386 antigo e lento isso não é um problema?
Talvez isso se aplique a sistemas sem casos de uso embarcados, como criptografia de vídeo em tempo real, mas nem todo mundo se conecta à internet usando o iPhone mais recente.
Muito legal. Acho que vou tentar em uma das minhas máquinas reais com Windows 3.1 :)
Como sugestão, seria bom permitir customizar o prompt do sistema na caixa de diálogo Options. O cenário de 1992 é divertido, mas um tanto limitado. Se você estiver tentando resolver um problema em um computador retrô, talvez faça algum sentido usar isso em vez de pegar um computador moderno ou um smartphone.
No Windows 3.1, se você usar Win32s, não precisa se preocupar com o modelo de memória segmentada, e ele também pode funcionar no Windows de 64 bits.