Dear friends,
These days I am testing using ollama from Harbour. It is working fine using hbcurl.lib.
Now the challenge is to implement HB_CURLOPT_WRITEFUNCTION in hbcurl.lib so every generated AI token is visible as its gets generated so the user does not have to wait until the end to see them.
Viktor comments about it:
/* These are hidden on the Harbour level: */
/* HB_CURLOPT_WRITEFUNCTION */
With a few little changes I have been able to implement it, though I have found that CURLOPT_WRITEFUNCTION is already being used from hbcurl.lib core.c
from: HB_CURLOPT_DL_FILE_SETUP, HB_CURLOPT_DL_FHANDLE_SETUP and HB_CURLOPT_DL_BUFF_SETUP. In my tested code I don't need those options, so I don't have any conflicts with them.
Basically I have added a new struct member PHB_ITEM pWriteFunctionCallback; to HB_CURL. And then from static void PHB_CURL_free( PHB_CURL hb_curl, HB_BOOL bFree ):
if( hb_curl->pProgressCallback )
{
hb_itemRelease( hb_curl->pProgressCallback );
hb_curl->pProgressCallback = NULL;
}
also from static HB_GARBAGE_FUNC( PHB_CURL_mark ):
if( hb_curl->pProgressCallback )
hb_gcMark( hb_curl->pProgressCallback );
also:
size_t static hb_curl_writefunction_callback( void *buffer, size_t size, size_t nmemb, void *Cargo )
{
PHB_CURL hb_curl = ( PHB_CURL ) Cargo;
if( hb_curl->pWriteFunctionCallback && hb_vmRequestReenter() )
{
hb_vmPushEvalSym();
hb_vmPush( hb_curl->pWriteFunctionCallback );
hb_vmPushString( buffer, size * nmemb );
hb_vmSend( 1 );
hb_vmRequestRestore();
return size * nmemb;
}
return 0;
}
and
case HB_CURLOPT_WRITEFUNCTION:
{
PHB_ITEM pWriteFunctionCallback = hb_param( 3, HB_IT_BLOCK | HB_IT_SYMBOL );
if( hb_curl->pWriteFunctionCallback )
{
curl_easy_setopt( hb_curl->curl, CURLOPT_WRITEFUNCTION, NULL );
hb_itemRelease( hb_curl->pWriteFunctionCallback );
hb_curl->pWriteFunctionCallback = NULL;
}
if( pWriteFunctionCallback )
{
hb_curl->pWriteFunctionCallback = hb_itemNew( pWriteFunctionCallback );
/* unlock the item so GC will not mark them as used */
hb_gcUnlock( hb_curl->pWriteFunctionCallback );
curl_easy_setopt( hb_curl->curl, CURLOPT_WRITEFUNCTION, hb_curl_writefunction_callback );
res = curl_easy_setopt( hb_curl->curl, CURLOPT_WRITEDATA, hb_curl );
}
}
break;
Basically thats all is needed and in my tests here is working fine. Now I can see ollama AI tokens as they get generated.
I do appreciate your feedback and comments before considering adding these changes to Harbour.
many thanks