TOpenCode (OpenCode Zen)
Fuente: source/classes/topencode.prg
TOpenCode usa la API de chat OpenCode Zen
(https://opencode.ai/zen/v1/chat/completions) con
Authorization: Bearer public. Sin clave 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; comprobado el 2026-10-17).
SendAsync exige la VM Harbour MT
(build_new.bat <sample> hb32 mt).
Transporte: hbcurl sobre un libcurl estático
(Schannel): no hace falta distribuir libcurl.dll. Los
fuentes de curl y los scripts de build están en 3rdparty/
(salidas: lib/libcurl_static*.{lib,a} para
bcc32/bcc64/msvc32/msvc64/gcc).
Métodos
| Método | Descripción |
|---|---|
New( cModel ) | Un handle curl por instancia (varios agentes en paralelo). |
Send( cPrompt ) / SendWithSystem() | Síncrono; si hay rate limit, prueba otro modelo free. |
SendAsync() / SendWithSystemAsync() | Vuelve al momento. Consultar IsRunning(); si el hilo termina sin resultado devuelve .F. y GetValue() informa del error. |
GetValue() | Texto del asistente (UTF-8 → ACP). |
lVerifySSL | Verifica el certificado del servidor (por defecto .T.). Déjalo activado. |
SetServer( cBaseUrl [, cProviderID [, cModel ]] ) | Usa un servidor local opencode serve en lugar de Zen (URL vacía = volver a Zen). |
SessionStart() / SessionEnd() | Maneja la sesión del servidor a mano (automático en Send() / End()). |
SetTimeout( nMs ) | Timeout de cada petición en milisegundos (nTimeout, por defecto 90000). |
ClearMessages() | Olvida la conversación; en modo servidor el siguiente Send() abre una sesión nueva. |
Async escribe oc_<ms>_<seq>.json vía .part
+ rename: tres SendAsync() en el mismo tick no chocan.
Mejor esfuerzo: el nivel gratuito de OpenCode Zen solo responde a peticiones que parecen venir del cliente OpenCode, y TOpenCode envía las cabeceras y la lista de herramientas que ese nivel espera. Zen puede cambiarlo, o la lista de modelos gratuitos, en cualquier momento; si un modelo deja de responder, usa SetModel() con otro modelo gratuito.
Modo servidor local (opencode serve)
Con SetServer() la clase habla con un
opencode serve local
(por defecto http://127.0.0.1:4096) en lugar de OpenCode Zen.
Mantiene una sesión persistente (POST /session), así que el
servidor recuerda toda la conversación y se puede usar cualquier
proveedor/modelo configurado en opencode (cProviderID +
cModel; vacíos = modelo por defecto del servidor). Si la
sesión se pierde (HTTP 404) se recrea una vez automáticamente, y
End() la borra (DELETE /session/{id}). Admite
autenticación básica con cServerUser / cServerPass
(OPENCODE_SERVER_PASSWORD). En este modo
SendAsync() funciona de forma síncrona. Este backend sigue el
enfoque de la clase TOpenCode de Charly 9000 (licencia MIT).
o := TOpenCode():New()
o:SetServer( "http://127.0.0.1:4096" )
o:Send( "Hola" )
o:Send( "¿Qué te acabo de decir?" ) // el servidor lo recuerda
o:End()
Historial de conversación
Por defecto (lHistory := .T.) cada
Send()/SendWithSystem() con éxito añade el turno a
aMessages y la siguiente petición lleva toda la conversación:
el modelo tiene memoria. ClearMessages() empieza una
conversación nueva; lHistory := .F. vuelve a peticiones sin
estado.
Samples
samples/ai/opencode1.prg— 3 agentes concurrentes.samples/ai/opencode2.prg+opencode2.html— TWebView2 estilo WhatsApp: agentes a la izquierda, chat a la derecha, roles.
cd samples\ai
build_new.bat opencode2 hb32 mt
Ejecutar desde samples\ai para encontrar libcurl.dll.