TOpenCode (OpenCode Zen)
Fonte: source/classes/topencode.prg
TOpenCode usa a API de chat OpenCode Zen
(https://opencode.ai/zen/v1/chat/completions) com
Authorization: Bearer public. Sem chave API. Modelos gratuitos
(mimo-v2.6-flash-free, space-bunny-free,
big-pickle, beam-free, glm-5.3-flash-free,
deepseek-v4.1-flash-free; verificado em 2026-10-17).
SendAsync exige a VM Harbour MT
(build_new.bat <sample> hb32 mt).
Transporte: hbcurl sobre um libcurl estático
(Schannel): não é preciso distribuir o libcurl.dll. Os
fontes do curl e os scripts de build estão em 3rdparty/
(saídas: lib/libcurl_static*.{lib,a} para
bcc32/bcc64/msvc32/msvc64/gcc).
Métodos
| Método | Descrição |
|---|---|
New( cModel ) | Um handle curl por instância (vários agentes em paralelo). |
Send( cPrompt ) / SendWithSystem() | Síncrono; em rate limit tenta outro modelo free. |
SendAsync() / SendWithSystemAsync() | Retorna já. Consultar IsRunning(); se a thread terminar sem resultado retorna .F. e GetValue() informa o erro. |
GetValue() | Texto do assistente (UTF-8 → ACP). |
lVerifySSL | Verifica o certificado do servidor (padrão .T.). Deixe ativado. |
SetServer( cBaseUrl [, cProviderID [, cModel ]] ) | Usa um servidor local opencode serve em vez do Zen (URL vazia = voltar ao Zen). |
SessionStart() / SessionEnd() | Gerencia a sessão do servidor manualmente (automático em Send() / End()). |
SetTimeout( nMs ) | Timeout de cada requisição em milissegundos (nTimeout, padrão 90000). |
ClearMessages() | Esquece a conversa; no modo servidor o próximo Send() abre uma sessão nova. |
Async grava oc_<ms>_<seq>.json via .part
+ rename: três SendAsync() no mesmo tick não colidem.
Melhor esforço: o nível gratuito do OpenCode Zen só responde a pedidos que parecem vir do cliente OpenCode, e o TOpenCode envia os cabeçalhos e a lista de ferramentas que esse nível espera. O Zen pode mudar isso, ou a lista de modelos gratuitos, a qualquer momento; se um modelo deixar de responder, use SetModel() com outro modelo gratuito.
Modo servidor local (opencode serve)
Com SetServer() a classe fala com um
opencode serve local
(padrão http://127.0.0.1:4096) em vez do OpenCode Zen. Ela
mantém uma sessão persistente (POST /session), então o
servidor lembra de toda a conversa, e qualquer provedor/modelo configurado
no opencode pode ser usado (cProviderID +
cModel; vazios = modelo padrão do servidor). Se a sessão se
perde (HTTP 404), ela é recriada uma vez automaticamente, e
End() a apaga (DELETE /session/{id}). Suporta
autenticação básica com cServerUser / cServerPass
(OPENCODE_SERVER_PASSWORD). Nesse modo o
SendAsync() funciona de forma síncrona. Este backend segue a
abordagem da classe TOpenCode de Charly 9000 (licença MIT).
o := TOpenCode():New()
o:SetServer( "http://127.0.0.1:4096" )
o:Send( "Olá" )
o:Send( "O que eu acabei de dizer?" ) // o servidor lembra
o:End()
Histórico de conversa
Por padrão (lHistory := .T.) cada
Send()/SendWithSystem() bem-sucedido adiciona o
turno a aMessages e a próxima requisição leva toda a conversa:
o modelo tem memória. ClearMessages() começa uma conversa
nova; lHistory := .F. volta a requisições sem estado.
Samples
samples/ai/opencode1.prg— 3 agentes concorrentes.samples/ai/opencode2.prg+opencode2.html— TWebView2 estilo WhatsApp: agentes à esquerda, chat à direita, papéis.
cd samples\ai
build_new.bat opencode2 hb32 mt
Executar a partir de samples\ai para achar libcurl.dll.