Page 1 of 1

AI: Using free ollama from Harbour using curl

Posted: Wed Sep 11, 2024 10:11 am
by Antonio Linares
Thanks to Kwon Oh Chul:

Code: Select all | Expand

//EEVE-Korean-10.8B:latest
#include "hbclass.ch"

#define HB_CURLOPT_URL                        2
#define HB_CURLOPT_POST                       47
#define HB_CURLOPT_POSTFIELDS                 15
#define HB_CURLOPT_HTTPHEADER                 23
#define HB_CURLOPT_WRITEFUNCTION              11
#define HB_CURLINFO_RESPONSE_CODE             2
#define HB_CURLOPT_DL_BUFF_SETUP              1008


FUNCTION MAIN()
    LOCAL oPost
    LOCAL cUrl := "http://192.168.2.236:11434/api/chat"
    LOCAL hPost := { "model" => "llama3.1:8b", "messages" => { { "role" => "user", "content" => "" } }, "stream" => .F., "temperature"=>0, "format" => "json" }
    
    hPost["messages"][1]["content"] := getText()
    hPost["model"] := "llama3.1:8b"
    
 //   hPost["model"] := "llama3"
    
    oPost := TDrCURLPost():New( cUrl, hPost )
    
    

    
    IF oPost:Execute()
        ? '<meta charset="utf-8">'
        ? "Response Code: ", oPost:GetHttpCode()
        ? "Response: ", oPost:GetResponse()
    ELSE
        ? "Error: ", oPost:GetError()
    ENDIF
    
    oPost:Destroy()
    
RETURN NIL    

FUNCTION getText()
    LOCAL cText
    
TEXT INTO cText
What is harbour project for xBase?
ENDTEXT
    
RETURN cText


CLASS TDrCURLPost

    DATA hCurl
    DATA cUrl
    DATA hPost
    DATA cResponse
    DATA nHttpCode
    DATA cError

    METHOD New(cUrl, hPost)
    METHOD Execute()
    METHOD GetResponse()
    METHOD GetHttpCode()
    METHOD GetError()
    METHOD Destroy()
    METHOD BuildPostFields()

ENDCLASS

METHOD New( cUrl, hPost ) CLASS TDrCURLPost

    ::cUrl := cUrl
    ::hPost := hPost
    ::hCurl := curl_easy_init()
    
RETURN Self

METHOD Execute() CLASS TDrCURLPost
    LOCAL nError
    LOCAL aHeaders
    LOCAL cPostFields

    IF ::hCurl == NIL
        ::cError := "Failed to initialize cURL"
        RETURN .F.
    ENDIF

    cPostFields := ::BuildPostFields()

    curl_easy_setopt(::hCurl, HB_CURLOPT_URL, ::cUrl)

    aHeaders := { "Content-Type: application/json" }
                  
    curl_easy_setopt(::hCurl, HB_CURLOPT_HTTPHEADER, aHeaders)

    curl_easy_setopt(::hCurl, HB_CURLOPT_POST, .T.)
    curl_easy_setopt(::hCurl, HB_CURLOPT_POSTFIELDS, cPostFields)

    curl_easy_setopt(::hCurl, HB_CURLOPT_WRITEFUNCTION, NIL)
    curl_easy_setopt(::hCurl, HB_CURLOPT_DL_BUFF_SETUP)

    nError := curl_easy_perform(::hCurl)

    IF nError == 0
       curl_easy_getinfo(::hCurl, HB_CURLINFO_RESPONSE_CODE, @::nHttpCode)
       ::cResponse := curl_easy_dl_buff_get(::hCurl)
       RETURN .T.
    ELSE
       ::cError := "cURL error: " + hb_ntos(nError)
       RETURN .F.
    ENDIF
    
RETURN NIL

METHOD GetResponse() CLASS TDrCURLPost
RETURN ::cResponse

METHOD GetHttpCode() CLASS TDrCURLPost
RETURN ::nHttpCode

METHOD GetError() CLASS TDrCURLPost
RETURN ::cError

METHOD Destroy() CLASS TDrCURLPost
    
    IF ::hCurl != NIL
        curl_easy_cleanup(::hCurl)
        ::hCurl := NIL
    ENDIF
    
RETURN NIL

METHOD BuildPostFields() CLASS TDrCURLPost
    RETURN hb_jsonEncode(::hPost)

Re: AI: Using free ollama from Harbour using curl

Posted: Wed Sep 11, 2024 10:17 am
by Antonio Linares

Re: AI: Using free ollama from Harbour using curl

Posted: Wed Sep 11, 2024 10:20 am
by Antonio Linares
Using Anthropic Claude: (not tested yet)

Code: Select all | Expand

#include "Fivewin.ch"
#include "hbcurl.ch"

FUNCTION Main()
    LOCAL oApi
    LOCAL cKey := ""  // you have to get an API key from the Anthropic platform

    oApi := TClaude_API():New(cKey)

    oApi:prompt := "What is harbour-project?"
    oApi:Send()

    ? oApi:Response()

RETURN NIL


CLASS TClaude_API

    DATA cKey AS CHARACTER INIT ""
    DATA hCurl
    DATA httpcode
    DATA nError             INIT 0
 
    DATA Response
    DATA Prompt

    // Adjusted for Claude's specific endpoint and model version
    DATA model              INIT "claude-v1"  
    DATA cUrl               INIT "https://api.anthropic.com/v1/completions"
    DATA max_tokens         INIT 2048
    DATA temperature        INIT 0
    DATA top_p              INIT 1
    DATA frequency_penalty  INIT 0.00
    DATA presence_penalty   INIT 0.00
 
    DATA cLogFile           INIT "TClaudeAPI.log"
    DATA nMaxLogSize        INIT 32768
    DATA lDebug             INIT .F.
 
    METHOD New()
    METHOD End()
    METHOD Send()
    METHOD Reset()

ENDCLASS


METHOD New(cKey) CLASS TClaude_API
    ::cKey := cKey
    ::hCurl := curl_easy_init()

RETURN Self


METHOD Send() CLASS TClaude_API
    LOCAL aheaders
    LOCAL httpcode
    LOCAL cJson
    LOCAL h := { => }
    LOCAL hMessage := { => }

    curl_easy_setopt(::hCurl, HB_CURLOPT_POST, .T.)
    curl_easy_setopt(::hCurl, HB_CURLOPT_URL, ::cUrl)
    
    aheaders := { "Content-Type: application/json", ;
                    "Authorization: Bearer " + ::cKey }

    curl_easy_setopt(::hCurl, HB_CURLOPT_HTTPHEADER, aheaders)

    curl_easy_setopt(::hCurl, HB_CURLOPT_USERNAME, '')
    curl_easy_setopt(::hCurl, HB_CURLOPT_DL_BUFF_SETUP)
    curl_easy_setopt(::hCurl, HB_CURLOPT_SSL_VERIFYPEER, .F.)

    // Create the payload for Claude API
    hb_HSet(h, "model", ::model)
    hb_HSet(hMessage, "role", "user")
    hb_HSet(hMessage, "content", ::prompt)

    h["messages"] := {hMessage}

    cJson := hb_jsonEncode(h)  
    curl_easy_setopt(::hCurl, HB_CURLOPT_POSTFIELDS, cJson)

    ::nError := curl_easy_perform(::hCurl)
    curl_easy_getinfo(::hCurl, HB_CURLINFO_RESPONSE_CODE, @httpcode)

    ::httpcode := httpcode

    IF ::nError == HB_CURLE_OK
       ::Response = curl_easy_dl_buff_get(::hCurl)
       IF ::lDebug
          // Optionally log debug information
       ENDIF
    ELSE
       // Handle the error case
    ENDIF

RETURN ::Response


METHOD Reset() CLASS TClaude_API
    curl_easy_reset(::hCurl)
    ::nError := HB_CURLE_OK
    ::Response := Nil

RETURN NIL


METHOD End() CLASS TClaude_API
    curl_easy_cleanup(::hCurl)
    ::hCurl := Nil  

RETURN NIL