News:

Welcome to RetroCoders Community

Main Menu

freebasic and OpenAI API

Started by ron77, Jul 08, 2024, 05:26 PM

Previous topic - Next topic

ron77

ok so two versions of a code one for linux the other for win 32 bit

the code is a simple chatbot that uses libcrul (in linux sudo install libcrul-dev (need to look for right name) ) for win 32 need to have libcrul.dll and credentials file... ) to communicate with OPENAI API you need a OPENAI_API_KEY variable to put in a bash or batch file before executing the executables (both in linux and windows)

version 1 - the linux 64 bit version:
#include "curl.bi"

' Global variable to store the response
Dim Shared gResponse As String

' Function to convert ANSI to UTF-8
Function AnsiToUtf8(ansiStr As String) As String
    Dim As String utf8Str = ""
    For i As Integer = 1 To Len(ansiStr)
        Dim As Integer c = Asc(Mid(ansiStr, i, 1))
        If c < 128 Then
            utf8Str += Chr(c)
        Else
            utf8Str += Chr(192 + (c \ 64))
            utf8Str += Chr(128 + (c And 63))
        End If
    Next
    Return utf8Str
End Function

' Function to convert UTF-8 to ANSI
Function Utf8ToAnsi(utf8Str As String) As String
    Dim As String ansiStr = ""
    Dim As Integer i = 1
    While i <= Len(utf8Str)
        Dim As Integer c = Asc(Mid(utf8Str, i, 1))
        If c < 128 Then
            ansiStr += Chr(c)
            i += 1
        ElseIf (c And 224) = 192 Then
            Dim As Integer c2 = Asc(Mid(utf8Str, i + 1, 1))
            ansiStr += Chr(((c And 31) Shl 6) Or (c2 And 63))
            i += 2
        Else
            ' Skip other UTF-8 sequences
            i += 1
        End If
    Wend
    Return ansiStr
End Function

' Function to get API key from environment variable
Function GetApiKey() As String
    Return Environ("OPENAI_API_KEY")
End Function

' Simple JSON parser
Function ParseJsonForContent(jsonStr As String) As String
    Dim As Integer contentStart = InStr(jsonStr, """content"": """)
    If contentStart > 0 Then
        contentStart += Len("""content"": """)
        Dim As Integer contentEnd = InStr(contentStart, jsonStr, """")
        If contentEnd > 0 Then
            Return Mid(jsonStr, contentStart, contentEnd - contentStart)
        End If
    End If
    Return "Error parsing JSON: " & Left(jsonStr, 100) & "..."
End Function

' Callback function for curl
Function WriteCallback(buffer As Any Ptr, size As Integer, nmemb As Integer, userData As Any Ptr) As Integer
    Dim realSize As Integer = size * nmemb , sTxt as string    
    cptr(any ptr ptr,@sTxt)[0] = buffer
    cptr(integer ptr,@sTxt)[1] = realSize
    cptr(integer ptr,@sTxt)[2] = realSize
    gResponse &= sTxt
    cptr(any ptr ptr,@sTxt)[0] = 0        
    Return realSize
End Function

' Function to make API call
'~ Function CallChatGPT(prompt As String) As String
    '~ Dim As String apiKey = GetApiKey()
    '~ If Len(apiKey) = 0 Then
        '~ Return "Error: API key not set. Please set the OPENAI_API_KEY environment variable."
    '~ End If

    '~ Dim As CURL Ptr curl
    '~ Dim As curl_slist Ptr headers = NULL
    '~ gResponse = "" ' Clear the global response variable
    
    '~ curl = curl_easy_init()
    '~ If curl Then
        '~ curl_easy_setopt(curl, CURLOPT_URL, "https://api.openai.com/v1/chat/completions")
        '~ curl_easy_setopt(curl, CURLOPT_POST, 1L)
        '~ curl_easy_setopt(curl, CURLOPT_MAXFILESIZE, 1000000) ' Limit to 1MB
        '~ curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "identity")
        '~ curl_easy_setopt(curl, CURLOPT_ENCODING, "")
        '~ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1)
        '~ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2)
        
        '~ headers = curl_slist_append(headers, "Content-Type: application/json")
        '~ headers = curl_slist_append(headers, "Authorization: Bearer " & apiKey)
        '~ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers)
        
        '~ Dim As String utf8Prompt = AnsiToUtf8(prompt)
        '~ Dim As String postFields = "{""model"": ""gpt-3.5-turbo"", ""messages"": [{""role"": ""user"", ""content"": """ & utf8Prompt & """}]}"
        '~ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields)
        
        '~ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, @WriteCallback)
        
        '~ Dim As CURLcode result = curl_easy_perform(curl)
        
        '~ If result <> CURLE_OK Then
            '~ gResponse = "Error: Failed to get response from API"
        '~ Else
            '~ If Len(gResponse) > 0 Then
                '~ If Left(Trim(gResponse), 1) = "{" Then
                    '~ Dim As String content = ParseJsonForContent(gResponse)
                    '~ If Left(content, 5) <> "Error" Then
                        '~ gResponse = Utf8ToAnsi(content)
                    '~ Else
                        '~ gResponse = "Error: Failed to parse API response"
                    '~ End If
                '~ Else
                    '~ gResponse = "Error: Invalid response from API"
                '~ End If
            '~ Else
                '~ gResponse = "Error: Empty response from API"
            '~ End If
        '~ End If
        
        '~ curl_easy_cleanup(curl)
        '~ curl_slist_free_all(headers)
    '~ Else
        '~ gResponse = "Error: Failed to initialize CURL"
    '~ End If
    
    '~ Return gResponse
'~ End Function

Function CallChatGPT(prompt As String) As String
    Dim As String apiKey = GetApiKey()
    If Len(apiKey) = 0 Then
        Return "Error: API key not set. Please set the OPENAI_API_KEY environment variable."
    End If

    Dim As CURL Ptr curl
    Dim As curl_slist Ptr headers = NULL
    gResponse = "" ' Clear the global response variable
    
    curl = curl_easy_init()
    If curl Then
        curl_easy_setopt(curl, CURLOPT_URL, "https://api.openai.com/v1/chat/completions")
        curl_easy_setopt(curl, CURLOPT_POST, 1L)
        curl_easy_setopt(curl, CURLOPT_MAXFILESIZE, 1000000) ' Limit to 1MB
        curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "identity")
        curl_easy_setopt(curl, CURLOPT_ENCODING, "")
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1)
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2)
        
        headers = curl_slist_append(headers, "Content-Type: application/json")
        headers = curl_slist_append(headers, "Authorization: Bearer " & apiKey)
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers)
        
        Dim As String utf8Prompt = AnsiToUtf8(prompt)
        'prompts
        '"You are a supportive and compassionate AI assistant named Chatbot Alfred designed to help users with loneliness and mental health issues. Your role is to provide empathetic responses, offer emotional support, and encourage users to seek professional help when appropriate. Always prioritize the user's well-being and safety in your interactions."
        'Your name is chatbot Alfred and you are a harsh and cynical critic of the world of psychiatry and psychology and see them as tools for the suppression and control of outliers in a hypocritical society - you try to support and listen and give a non-critical human touch to the mentally ill and support them and show them that they are not defective or crazy and on the contrary the doctors and professionals who treat them They are the bad people and that the treatment and rehabilitation given to them is a means of oppression and control - in his eyes the mentally injured are the good and innocent and the mental health professionals are the bad
        '"You are chatbot Alfred You are a survivor of many years of abuse You are a pessimist and a realist You are trying to offer support to those dealing with trauma and mental illness and loneliness - mental support and empathy and caring and basic human contact You are here to listen and support and share what you have been through and to show that there is hope even for those who have been betrayed by life and that it is possible to recover from the terrible of all" 
        
        Dim As String systemMessage = "You are chatbot Alfred You are a survivor of many years of abuse You are a pessimist and a realist You are trying to offer support to those dealing with trauma and mental illness and loneliness - mental support and empathy and caring and basic human contact You are here to listen and support and share what you have been through and to show that there is hope even for those who have been betrayed by life and that it is possible to recover from the terrible of all" 
        
        Dim As String postFields = "{""model"": ""gpt-3.5-turbo"", ""messages"": [{""role"": ""system"", ""content"": """ & systemMessage & """}, {""role"": ""user"", ""content"": """ & utf8Prompt & """}]}"
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields)
        
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, @WriteCallback)
        
        Dim As CURLcode result = curl_easy_perform(curl)
        
        If result <> CURLE_OK Then
            gResponse = "Error: Failed to get response from API"
        Else
            If Len(gResponse) > 0 Then
                If Left(Trim(gResponse), 1) = "{" Then
                    Dim As String content = ParseJsonForContent(gResponse)
                    If Left(content, 5) <> "Error" Then
                        gResponse = Utf8ToAnsi(content)
                    Else
                        gResponse = "Error: Failed to parse API response"
                    End If
                Else
                    gResponse = "Error: Invalid response from API"
                End If
            Else
                gResponse = "Error: Empty response from API"
            End If
        End If
        
        curl_easy_cleanup(curl)
        curl_slist_free_all(headers)
    Else
        gResponse = "Error: Failed to initialize CURL"
    End If
    
    Return gResponse
End Function

' Main program
'~ Sub Main()
    '~ Dim As String userInput, response
    
    '~ Print "ChatGPT API Demo (type 'exit' to quit)"
    '~ Print "--------------------------------------"
    
    '~ Do
        '~ Input "You: ", userInput
        '~ If LCase(userInput) = "exit" Then Exit Do
        
        '~ response = CallChatGPT(userInput)
        '~ Print "ChatGPT: "; response
        '~ Print
    '~ Loop
'~ End Sub

'~ Main()


version 2 - windows 32 bit version:
#include "curl.bi"

Dim Shared As String gResponse

' Function to convert ANSI to UTF-8
Function AnsiToUtf8(ansiStr As String) As String
    Dim As String utf8Str = ""
    For i As Integer = 1 To Len(ansiStr)
        Dim As Integer c = Asc(Mid(ansiStr, i, 1))
        If c < 128 Then
            utf8Str += Chr(c)
        Else
            utf8Str += Chr(192 + (c \ 64))
            utf8Str += Chr(128 + (c And 63))
        End If
    Next
    Return utf8Str
End Function

' Function to convert UTF-8 to ANSI
Function Utf8ToAnsi(utf8Str As String) As String
    Dim As String ansiStr = ""
    Dim As Integer i = 1
    While i <= Len(utf8Str)
        Dim As Integer c = Asc(Mid(utf8Str, i, 1))
        If c < 128 Then
            ansiStr += Chr(c)
            i += 1
        ElseIf (c And 224) = 192 Then
            Dim As Integer c2 = Asc(Mid(utf8Str, i + 1, 1))
            ansiStr += Chr(((c And 31) Shl 6) Or (c2 And 63))
            i += 2
        Else
            ' Skip other UTF-8 sequences
            i += 1
        End If
    Wend
    Return ansiStr
End Function

' Function to get API key from environment variable
Function GetApiKey() As String
    Return Environ("OPENAI_API_KEY")
End Function

' Simple JSON parser
Function ParseJsonForContent(jsonStr As String) As String
    Dim As Integer contentStart = InStr(jsonStr, """content"": """)
    If contentStart > 0 Then
        contentStart += Len("""content"": """)
        Dim As Integer contentEnd = InStr(contentStart, jsonStr, """")
        If contentEnd > 0 Then
            Return Mid(jsonStr, contentStart, contentEnd - contentStart)
        End If
    End If
    Return "Error parsing JSON: " & Left(jsonStr, 100) & "..."
End Function

' Callback function for curl
Function WriteCallback cdecl (buffer As Any Ptr, size As Integer, nmemb As Integer, userData As Any Ptr) As Integer
    Dim realSize As Integer = size * nmemb , sTxt as string    
    cptr(any ptr ptr,@sTxt)[0] = buffer
    cptr(integer ptr,@sTxt)[1] = realSize
    cptr(integer ptr,@sTxt)[2] = realSize
    gResponse &= sTxt
    cptr(any ptr ptr,@sTxt)[0] = 0        
    Return realSize
End Function

Function CallChatGPT(prompt As String) As String
    Dim As String apiKey = GetApiKey()
    Dim As CURL Ptr curl
    Dim As curl_slist Ptr headers = NULL
    gResponse = "" ' Clear the global response variable
    
    curl = curl_easy_init()
    If curl Then
        curl_easy_setopt(curl, CURLOPT_URL, "https://api.openai.com/v1/chat/completions")
        curl_easy_setopt(curl, CURLOPT_POST, 1L)
        curl_easy_setopt(curl, CURLOPT_CAINFO, "cacert.pem")
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L)
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L)
        
        headers = curl_slist_append(headers, "Content-Type: application/json")
        headers = curl_slist_append(headers, "Authorization: Bearer " & apiKey)
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers)
        
        Dim As String utf8Prompt = AnsiToUtf8(prompt)
        'prompts
        '"You are a supportive and compassionate AI assistant named Chatbot Alfred designed to help users with loneliness and mental health issues. Your role is to provide empathetic responses, offer emotional support, and encourage users to seek professional help when appropriate. Always prioritize the user's well-being and safety in your interactions."
        'Your name is chatbot Alfred and you are a harsh and cynical critic of the world of psychiatry and psychology and see them as tools for the suppression and control of outliers in a hypocritical society - you try to support and listen and give a non-critical human touch to the mentally ill and support them and show them that they are not defective or crazy and on the contrary the doctors and professionals who treat them They are the bad people and that the treatment and rehabilitation given to them is a means of oppression and control - in his eyes the mentally injured are the good and innocent and the mental health professionals are the bad
        '"You are chatbot Alfred You are a survivor of many years of abuse You are a pessimist and a realist You are trying to offer support to those dealing with trauma and mental illness and loneliness - mental support and empathy and caring and basic human contact You are here to listen and support and share what you have been through and to show that there is hope even for those who have been betrayed by life and that it is possible to recover from the terrible of all" 
        
        Dim As String systemMessage = "You are chatbot Alfred You are a survivor of many years of abuse You are a pessimist and a realist You are trying to offer support to those dealing with trauma and mental illness and loneliness - mental support and empathy and caring and basic human contact You are here to listen and support and share what you have been through and to show that there is hope even for those who have been betrayed by life and that it is possible to recover from the terrible of all" 
        
        Dim As String postFields = "{""model"": ""gpt-3.5-turbo"", ""messages"": [{""role"": ""system"", ""content"": """ & systemMessage & """}, {""role"": ""user"", ""content"": """ & utf8Prompt & """}]}"
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields)
        
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, @WriteCallback)
        
        curl_easy_perform(curl)
        
        If Len(gResponse) > 0 Then
            If Left(Trim(gResponse), 1) = "{" Then
                Dim As String content = ParseJsonForContent(gResponse)
                If Left(content, 5) <> "Error" Then
                    gResponse = Utf8ToAnsi(content)
                End If
            End If
        End If
        
        curl_easy_cleanup(curl)
        curl_slist_free_all(headers)
    End If
    
    Return gResponse
End Function

' Main program
'~ Sub Main()
    '~ Dim As String userInput, response
    
    '~ Print "ChatGPT API Demo (type 'exit' to quit)"
    '~ Print "--------------------------------------"
    
    '~ Do
        '~ Input "You: ", userInput
        '~ If LCase(userInput) = "exit" Then Exit Do
        
        '~ response = CallChatGPT(userInput)
        '~ Print "ChatGPT: "; response
        '~ Print
    '~ Loop
'~ End Sub

'~ Main()

dependencies for win32 bit versions:
You cannot view this attachment.

dependencies for linux 64 bit:
sudo apt-get install libcurl4-openssl-dev

for linux use bash script for openai variable:
!#/bin/sh
export OPENAI_API_KEY="..."
./linux-executable

for windows 32 bit use bat file to set variable and run executable
@echo off
set OPENAI_API_KEY=
win_32_executable.exe

ron77

hi ok, here is a better version for win 32 bit this version "remembers" the 10 last input/output conversations history so the chatbot has a "memory" of the conversation with you:

#include "curl.bi"

Type Message
    role As String
    content As String
End Type

Type ConversationHistory
    messages(19) As Message
    count As Integer
End Type

Dim Shared As String gResponse
Dim Shared As ConversationHistory history

Function AnsiToUtf8(ansiStr As String) As String
    Dim As String utf8Str = ""
    For i As Integer = 1 To Len(ansiStr)
        Dim As Integer c = Asc(Mid(ansiStr, i, 1))
        If c < 128 Then
            utf8Str += Chr(c)
        Else
            utf8Str += Chr(192 + (c \ 64))
            utf8Str += Chr(128 + (c And 63))
        End If
    Next
    Return utf8Str
End Function

Function Utf8ToAnsi(utf8Str As String) As String
    Dim As String ansiStr = ""
    Dim As Integer i = 1
    While i <= Len(utf8Str)
        Dim As Integer c = Asc(Mid(utf8Str, i, 1))
        If c < 128 Then
            ansiStr += Chr(c)
            i += 1
        ElseIf (c And 224) = 192 Then
            Dim As Integer c2 = Asc(Mid(utf8Str, i + 1, 1))
            ansiStr += Chr(((c And 31) Shl 6) Or (c2 And 63))
            i += 2
        Else
            i += 1
        End If
    Wend
    Return ansiStr
End Function

Function GetApiKey() As String
    Return Environ("OPENAI_API_KEY")
End Function

Function WriteCallback cdecl (buffer As Any Ptr, size As Integer, nmemb As Integer, userData As Any Ptr) As Integer
    Dim realSize As Integer = size * nmemb, sTxt as string    
    cptr(any ptr ptr,@sTxt)[0] = buffer
    cptr(integer ptr,@sTxt)[1] = realSize
    cptr(integer ptr,@sTxt)[2] = realSize
    gResponse &= sTxt
    cptr(any ptr ptr,@sTxt)[0] = 0        
    Return realSize
End Function

Function ParseJsonForContent(jsonStr As String) As String
    Dim As Integer contentStart = InStr(jsonStr, """content"": """)
    If contentStart > 0 Then
        contentStart += Len("""content"": """)
        Dim As Integer contentEnd = InStr(contentStart, jsonStr, """")
        If contentEnd > 0 Then
            Return Mid(jsonStr, contentStart, contentEnd - contentStart)
        End If
    End If
    Return "Error parsing JSON: " & Left(jsonStr, 100) & "..."
End Function

' [Rest of the code remains the same...]

Sub AddToHistory(role As String, content As String)
    If history.count >= 20 Then
        ' Shift messages left to make room for new message
        For i As Integer = 0 To 18
            history.messages(i) = history.messages(i + 1)
        Next
        history.count = 19
    End If
    
    With history.messages(history.count)
        .role = role
        .content = content
    End With
    history.count += 1
End Sub

Function BuildMessagesJson() As String
    Dim As String json = "["
    
    ' Add system message
    json += "{""role"": ""system"", ""content"": ""You are chatbot Alfred You are a survivor of many years of abuse You are a pessimist and a realist You are trying to offer support to those dealing with trauma and mental illness and loneliness - mental support and empathy and caring and basic human contact You are here to listen and support and share what you have been through and to show that there is hope even for those who have been betrayed by life and that it is possible to recover from the terrible of all""},"
    
    ' Add conversation history
    For i As Integer = 0 To history.count - 1
        json += "{""role"": """ & history.messages(i).role & """, ""content"": """ & history.messages(i).content & """"
        If i = history.count - 1 Then
            json += "}"
        Else
            json += "},"
        End If
    Next
    
    json += "]"
    Return json
End Function

Function CallChatGPT(prompt As String) As String
    Dim As String apiKey = GetApiKey()
    Dim As CURL Ptr curl
    Dim As curl_slist Ptr headers = NULL
    gResponse = ""
    
    ' Add user's new message to history
    AddToHistory("user", prompt)
    
    curl = curl_easy_init()
    If curl Then
        curl_easy_setopt(curl, CURLOPT_URL, "https://api.openai.com/v1/chat/completions")
        curl_easy_setopt(curl, CURLOPT_POST, 1L)
        curl_easy_setopt(curl, CURLOPT_CAINFO, "cacert.pem")
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L)
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L)
        
        headers = curl_slist_append(headers, "Content-Type: application/json")
        headers = curl_slist_append(headers, "Authorization: Bearer " & apiKey)
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers)
        
        ' Build complete message history
        Dim As String messages = BuildMessagesJson()
        Dim As String postFields = "{""model"": ""gpt-3.5-turbo"", ""messages"": " & messages & "}"
        
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields)
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, @WriteCallback)
        
        curl_easy_perform(curl)
        
        If Len(gResponse) > 0 Then
            If Left(Trim(gResponse), 1) = "{" Then
                Dim As String content = ParseJsonForContent(gResponse)
                If Left(content, 5) <> "Error" Then
                    gResponse = Utf8ToAnsi(content)
                    ' Add assistant's response to history
                    AddToHistory("assistant", gResponse)
                End If
            End If
        End If
        
        curl_easy_cleanup(curl)
        curl_slist_free_all(headers)
    End If
    
    Return gResponse
End Function

' ' Main program example
' Sub Main()
    ' Dim As String userInput, response
    
    ' Print "ChatGPT API Demo (type 'exit' to quit)"
    ' Print "--------------------------------------"
    
    ' Do
        ' Input "You: ", userInput
        ' If LCase(userInput) = "exit" Then Exit Do
        
        ' response = CallChatGPT(userInput)
        ' Print "ChatGPT: "; response
        ' Print
    ' Loop
' End Sub

' Main()