News:

Welcome to RetroCoders Community

Main Menu

Recent posts

#1
FreeBasic / Hebrew in freeBASIC
Last post by ron77 - Today at 10:07 AM
1. hebrew in freebasic GFX screen you need to load a .CPI hebrew font like so...

file "LoadFont.bas"

type fbGfxFONT
  as long w,h
  as ubyte ptr pData
  bData(16*256-1) as ubyte
end type  
extern as any ptr __fb_gfx alias "__fb_gfx"
static shared as fbGfxFONT g_MyFont = type(8,16)
static shared as fbGfxFONT ptr g_pOrgFont
static shared as fbGfxFONT ptr ptr g_pptfbGfxFont

sub LoadFontEgaCPI( sFontFile as string )
  
  g_pptfbGfxFont = cptr(fbGfxFONT ptr ptr,__fb_gfx+52+9*sizeof(any ptr)-4)  
  if g_pOrgFont = 0 then g_pOrgFont = *g_pptfbGfxFont
  *g_pptfbGfxFont = @g_MyFont  
  
  var f = freefile()
  if open(sFontFile for binary access read as #f) then exit sub
  get #f,66,g_MyFont.bData(): close #f
  for N as long = 0 to 255*16
    g_MyFont.bData(N) = ((g_MyFont.bData(N) * &h80200802ULL) and &h0884422110ULL) * &h0101010101ULL shr 32
  next N
    
  g_MyFont.pData = @(g_MyFont.bData(0))  
  
end sub
#define EnableFont() *g_pptfbGfxFont = @g_MyFont  
#define RestoreFont() *g_pptfbGfxFont = g_pOrgFont

'~ screenres 640,480

'~ width 640\8,480\16 'must be 8x16
'~ LoadFontEgaCPI("hebega.cpi")

'~ for I as long = 0 to 1
  '~ for N as long = 0 to 255
    '~ locate 1+N\16, I*40+1+(N mod 16)*2
    '~ if (N >=7 and N<=10) or N=13 then print "?";: continue for
    '~ print chr(N);    
  '~ next N  
  '~ RestoreFont()
'~ next I

'~ sleep : end

You cannot view this attachment.

Plus you need to use IBM OEM 862 encoding instead UTF-8

Here is a function that converts UTF-8 to IBM OEM 862 encoding plus a "PrintRight" Function:

function Utf8ToOEM862( sInput as string ) as string
  dim as string sOutput = space(len(sInput))
  dim as long iOut
  for N as long = 0 to len(sInput)-1
    if sInput[N]=&hD7 then
      if sInput[N+1]>=&h90 andalso sInput[N+1]<=&hAA then
        sOutput[iOut] = sInput[N+1]-&h10         
        iOut += 1 : N += 1 :  :continue for
      end if
    end if
    #if __FB_DEBUG__    
      if sInput[N]>&h7F then puts("Warning: utf-8 char not converted!")
    #endif
    sOutput[iOut] = sInput[N] : iOut += 1
  next N
  return left(sOutput,iOut)
end function


sub PrintRight( sText as string )
  var sInvert = sText, iLen = len(sInvert)-1  
  for N as long = 0 to iLen\2
    swap SInvert[N],sInvert[iLen-N]
  next N
  var iLin = csrlin(), iCol = pos()
  if (iCol-(iLen+1)) < 1 then 
    print : iLin = csrlin() : iCol = loword(width())
  end if
  locate iLin,iCol-iLen
  print sInvert;
  locate iLin,iCol-(iLen+1)
end sub

and here is a function that converts UTF-8 to ANSI 1255 (good for GUI window9.bi)

function utf8toansi1255( sInput as string ) as string
  dim as string sOutput = space(len(sInput))
  dim as long iOut
  for N as long = 0 to len(sInput)-1
    if sInput[N]=&hD7 then
      if sInput[N+1]>=&h90 andalso sInput[N+1]<=&hAA then
        sOutput[iOut] = sInput[N+1]+(&hE0-&h90)
        iOut += 1 : N += 1 :  :continue for
      end if
    end if
    #if __FB_DEBUG__    
      if sInput[N]>&h7F then puts("Warning: utf-8 char not converted!")
    #endif
    sOutput[iOut] = sInput[N] : iOut += 1
  next N
  return left(sOutput,iOut)
end function
#2
C / C++ / Re: chatbot Danny in C
Last post by ron77 - Sep 04, 2024, 05:17 PM
Okay, I made some final adjustments to the chatbot. First, let me clear that this chatbot is not politically correct. It is an offensive chatbot that is not suitable for minors under 18 years old, and also, I do not take on any responsibility for your usage of it. So here are the final elements of almost the final diversion of the chatbot in C programming Language.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <stdbool.h>
#include <unistd.h>

#define MAX_STRING_LENGTH 1000
#define MAX_ARRAY_SIZE 1000
#define MAX_KEYWORDS 20
#define MAX_REPLIES 50
#define MAX_MATCHES 10
#define MAX_SWAP_WORDS 100
#define MAX_MEMORY 15

char wordIn[MAX_SWAP_WORDS][MAX_STRING_LENGTH];
char wordOut[MAX_SWAP_WORDS][MAX_STRING_LENGTH];
int wCnt = 0;

char memory[MAX_MEMORY][MAX_STRING_LENGTH];
int memoryCount = 0;

typedef struct {
    char keywords[MAX_KEYWORDS][MAX_STRING_LENGTH];
    char replies[MAX_REPLIES][MAX_STRING_LENGTH];
    int keywordCount;
    int replyCount;
} ArraySet;

ArraySet g_Key_Reply[MAX_ARRAY_SIZE];
int g_Key_ReplyCount = 0;

char default_replies[MAX_ARRAY_SIZE][MAX_STRING_LENGTH];
int default_reply_count = 0;

char* safe_strdup(const char* s) {
    if (!s) return NULL;
    char* result = strdup(s);
    if (!result) {
        fprintf(stderr, "Memory allocation failed in safe_strdup\n");
        exit(1);
    }
    return result;
}

char* isolatePunctuation(const char* s) {
    char* b = malloc(strlen(s) * 3 + 1);
    if (!b) return NULL;
    
    int j = 0;
    for (int i = 0; s[i]; i++) {
        if (strchr("?!,.:;<>(){}[]", s[i])) {
            b[j++] = ' ';
            b[j++] = s[i];
            b[j++] = ' ';
        } else {
            b[j++] = s[i];
        }
    }
    b[j] = '\0';
    return b;
}

void loadArrays(const char* filename) {
    FILE* file = fopen(filename, "r");
    if (!file) {
        printf("Error opening file: %s\n", filename);
        return;
    }

    char line[MAX_STRING_LENGTH];
    int currentSet = -1;
    
    while (fgets(line, sizeof(line), file)) {
        line[strcspn(line, "\n")] = 0;  // Remove newline

        if (strncmp(line, "d1:", 3) == 0) {
            strcpy(default_replies[default_reply_count++], line + 3);
        }
    
        if (line[0] == 'k' && line[1] == ':') {
            if (currentSet == -1 || g_Key_Reply[currentSet].replyCount > 0) {
                currentSet++;
            }
            strcpy(g_Key_Reply[currentSet].keywords[g_Key_Reply[currentSet].keywordCount], line + 2);
            g_Key_Reply[currentSet].keywordCount++;
            g_Key_ReplyCount = currentSet + 1;
        } else if (line[0] == 'r' && line[1] == ':') {
            strcpy(g_Key_Reply[currentSet].replies[g_Key_Reply[currentSet].replyCount], line + 2);
            g_Key_Reply[currentSet].replyCount++;
        }
    }

    fclose(file);
	printf("number of keywords-replies pair groups %d\n", currentSet);
}

void loadSwapWords(const char* filename) {
    FILE* file = fopen(filename, "r");
    if (!file) {
        printf("Error opening swap words file: %s\n", filename);
        return;
    }

    char line[MAX_STRING_LENGTH];
    while (fgets(line, sizeof(line), file) && wCnt < MAX_SWAP_WORDS) {
        line[strcspn(line, "\n")] = 0;  // Remove newline
        if (line[0] == 's' && line[1] == ':') {
            char* delimiter = strchr(line + 2, '>');
            if (delimiter) {
                *delimiter = '\0';
                strcpy(wordIn[wCnt], line + 2);
                strcpy(wordOut[wCnt], delimiter + 1);
                wCnt++;
            }
        }
    }

    fclose(file);
}

char* swapWords(const char* input) {
    if (!input) return NULL;
    char* result = safe_strdup(input);
    char* temp = malloc(strlen(input) * 2 + 1); // Allocate more space for worst-case scenario
    if (!temp) {
        free(result);
        return NULL;
    }

    char* word = strtok(result, " ");
    temp[0] = '\0';

    while (word != NULL) {
        bool swapped = false;
        for (int i = 0; i < wCnt; i++) {
            if (strcmp(word, wordIn[i]) == 0) {
                strcat(temp, wordOut[i]);
                strcat(temp, " ");
                swapped = true;
                break;
            }
        }
        if (!swapped) {
            strcat(temp, word);
            strcat(temp, " ");
        }
        word = strtok(NULL, " ");
    }

    // Remove trailing space
    int len = strlen(temp);
    if (len > 0 && temp[len - 1] == ' ') {
        temp[len - 1] = '\0';
    }

    free(result);
    return temp;
}

char* processReply(const char* reply, const char* userInput) {
    if (!reply || !userInput) return NULL;
    char* processedReply = safe_strdup(reply);
    int len = strlen(processedReply);
    
    if (len > 0 && processedReply[len - 1] == '*') {
        processedReply[len - 1] = '\0';  // Remove the asterisk
        
        // Save the user's input to memory
        if (memoryCount < MAX_MEMORY) {
            strncpy(memory[memoryCount], userInput, MAX_STRING_LENGTH - 1);
            memory[memoryCount][MAX_STRING_LENGTH - 1] = '\0';
            memoryCount++;
        }
        
        // Find the keyword in the user's input
        char* keyword = NULL;
        for (int i = 0; i < g_Key_ReplyCount; i++) {
            for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
                if (strstr(userInput, g_Key_Reply[i].keywords[j])) {
                    keyword = g_Key_Reply[i].keywords[j];
                    break;
                }
            }
            if (keyword) break;
        }
        
        if (keyword) {
            char* rest = strstr(userInput, keyword);
            if (rest) {
                rest += strlen(keyword);
                char* swapped = swapWords(rest);
                if (swapped) {
                    // Concatenate the swapped input to the reply
                    char* temp = malloc(strlen(processedReply) + strlen(swapped) + 2);
                    if (temp) {
                        sprintf(temp, "%s %s", processedReply, swapped);
                        free(processedReply);
                        processedReply = temp;
                    }
                    free(swapped);
                }
            }
        }
    }
    
    return processedReply;
}

char* userQuestion(const char* txt) {
    if (!txt) return NULL;
    char* matchedReplies[MAX_MATCHES] = {NULL};
    int matchCount = 0;
    bool found = false;
    char* combinedReply = NULL;

    for (int i = 0; i < g_Key_ReplyCount && matchCount < MAX_MATCHES; i++) {
        for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
            if (strstr(txt, g_Key_Reply[i].keywords[j])) {
                int replyIndex = rand() % g_Key_Reply[i].replyCount;
                matchedReplies[matchCount] = safe_strdup(g_Key_Reply[i].replies[replyIndex]);
                matchCount++;
                found = true;
                break;
            }
        }
    }

    if (matchCount > 0) {
        size_t totalLength = 1;  // Start with 1 for the null terminator
        for (int i = 0; i < matchCount; i++) {
            char* processedReply = processReply(matchedReplies[i], txt);
            if (processedReply) {
                totalLength += strlen(processedReply) + 1;  // +1 for newline
                free(matchedReplies[i]);
                matchedReplies[i] = processedReply;
            }
        }

        combinedReply = malloc(totalLength);
        if (combinedReply) {
            combinedReply[0] = '\0';
            for (int i = 0; i < matchCount; i++) {
                if (matchedReplies[i]) {
                    strcat(combinedReply, matchedReplies[i]);
                    strcat(combinedReply, "\n");
                    free(matchedReplies[i]);
                }
            }
        }
    } else if (!found) {
        if (default_reply_count > 0) {
            int defaultIndex = rand() % default_reply_count;
            combinedReply = safe_strdup(default_replies[defaultIndex]);
        }
    }
    
    return combinedReply ? combinedReply : safe_strdup("I don't understand. Can you rephrase that?");
}

char* commands(char* txt) {
    char* isolated = isolatePunctuation(txt);
    for (int i = 0; isolated[i]; i++) {
        isolated[i] = tolower(isolated[i]);
    }
    
    char* response = userQuestion(isolated);
    
    free(isolated);
    return response;
}

void speak(const char* text) {
    char command[MAX_STRING_LENGTH * 2];
    snprintf(command, sizeof(command), "voice -r -1 -n \"Microsoft David Desktop\" \"%s\"", text);
    system(command);
}

int main() {
    srand(time(NULL));
    
    loadArrays("database.txt");
    loadSwapWords("swapwords.txt");
    
	printf("CHATBOT DANNY IN C PROGRAMMING LANGUAGE VERSION 1.1.6.5 (C) RON77\n");
	
    char input[MAX_STRING_LENGTH];
    char* response;
    
    while (1) {
        printf("> ");
        if (fgets(input, sizeof(input), stdin) == NULL) {
            break;
        }
        input[strcspn(input, "\n")] = 0;  // Remove newline
        
        if (strcmp(input, "quit") == 0) break;
        
        response = commands(input);
        
        if (response) {
            // Split the response into separate lines and speak each one
            char* line = strtok(response, "\n");
            while (line != NULL) {
                printf("%s\n", line);
                speak(line);
                line = strtok(NULL, "\n");
            }
            
            free(response);
        } else {
            printf("An error occurred while processing your input.\n");
        }
    }
    
    return 0;
}

You cannot view this attachment.

You cannot view this attachment.

this chatbot used 'voice.exe' TTS cli engine wrapper on windows...

https://elifulkerson.com/projects/commandline-text-to-speech.php
#3
C / C++ / chatbot Danny in C
Last post by ron77 - Sep 04, 2024, 09:40 AM
ok just a basic version of fb_chatbot_danny converted to C...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <stdbool.h>
#include <unistd.h>

#define MAX_STRING_LENGTH 1000
#define MAX_ARRAY_SIZE 1000
#define MAX_KEYWORDS 20
#define MAX_REPLIES 50
#define MAX_MATCHES 5
#define MAX_SWAP_WORDS 100
#define MAX_MEMORY 10

char wordIn[MAX_SWAP_WORDS][MAX_STRING_LENGTH];
char wordOut[MAX_SWAP_WORDS][MAX_STRING_LENGTH];
int wCnt = 0;

char memory[MAX_MEMORY][MAX_STRING_LENGTH];
int memoryCount = 0;

typedef struct {
    char keywords[MAX_KEYWORDS][MAX_STRING_LENGTH];
    char replies[MAX_REPLIES][MAX_STRING_LENGTH];
    int keywordCount;
    int replyCount;
} ArraySet;

ArraySet g_Key_Reply[MAX_ARRAY_SIZE];
int g_Key_ReplyCount = 0;

char default_replies[MAX_ARRAY_SIZE][MAX_STRING_LENGTH];
int default_reply_count = 0;

char* safe_strdup(const char* s) {
    if (!s) return NULL;
    char* result = strdup(s);
    if (!result) {
        fprintf(stderr, "Memory allocation failed in safe_strdup\n");
        exit(1);
    }
    return result;
}

char* isolatePunctuation(const char* s) {
    char* b = malloc(strlen(s) * 3 + 1);
    if (!b) return NULL;
    
    int j = 0;
    for (int i = 0; s[i]; i++) {
        if (strchr("?!,.:;<>(){}[]", s[i])) {
            b[j++] = ' ';
            b[j++] = s[i];
            b[j++] = ' ';
        } else {
            b[j++] = s[i];
        }
    }
    b[j] = '\0';
    return b;
}

void loadArrays(const char* filename) {
    FILE* file = fopen(filename, "r");
    if (!file) {
        printf("Error opening file: %s\n", filename);
        return;
    }

    char line[MAX_STRING_LENGTH];
    int currentSet = -1;
    
    while (fgets(line, sizeof(line), file)) {
        line[strcspn(line, "\n")] = 0;  // Remove newline

        if (strncmp(line, "d1:", 3) == 0) {
            strcpy(default_replies[default_reply_count++], line + 3);
        }
    
        if (line[0] == 'k' && line[1] == ':') {
            if (currentSet == -1 || g_Key_Reply[currentSet].replyCount > 0) {
                currentSet++;
            }
            strcpy(g_Key_Reply[currentSet].keywords[g_Key_Reply[currentSet].keywordCount], line + 2);
            g_Key_Reply[currentSet].keywordCount++;
            g_Key_ReplyCount = currentSet + 1;
        } else if (line[0] == 'r' && line[1] == ':') {
            strcpy(g_Key_Reply[currentSet].replies[g_Key_Reply[currentSet].replyCount], line + 2);
            g_Key_Reply[currentSet].replyCount++;
        }
    }

    fclose(file);
}

void loadSwapWords(const char* filename) {
    FILE* file = fopen(filename, "r");
    if (!file) {
        printf("Error opening swap words file: %s\n", filename);
        return;
    }

    char line[MAX_STRING_LENGTH];
    while (fgets(line, sizeof(line), file) && wCnt < MAX_SWAP_WORDS) {
        line[strcspn(line, "\n")] = 0;  // Remove newline
        if (line[0] == 's' && line[1] == ':') {
            char* delimiter = strchr(line + 2, '>');
            if (delimiter) {
                *delimiter = '\0';
                strcpy(wordIn[wCnt], line + 2);
                strcpy(wordOut[wCnt], delimiter + 1);
                wCnt++;
            }
        }
    }

    fclose(file);
}

char* swapWords(const char* input) {
    if (!input) return NULL;
    char* result = safe_strdup(input);
    char* temp = malloc(strlen(input) * 2 + 1); // Allocate more space for worst-case scenario
    if (!temp) {
        free(result);
        return NULL;
    }

    char* word = strtok(result, " ");
    temp[0] = '\0';

    while (word != NULL) {
        bool swapped = false;
        for (int i = 0; i < wCnt; i++) {
            if (strcmp(word, wordIn[i]) == 0) {
                strcat(temp, wordOut[i]);
                strcat(temp, " ");
                swapped = true;
                break;
            }
        }
        if (!swapped) {
            strcat(temp, word);
            strcat(temp, " ");
        }
        word = strtok(NULL, " ");
    }

    // Remove trailing space
    int len = strlen(temp);
    if (len > 0 && temp[len - 1] == ' ') {
        temp[len - 1] = '\0';
    }

    free(result);
    return temp;
}

char* processReply(const char* reply, const char* userInput) {
    if (!reply || !userInput) return NULL;
    char* processedReply = safe_strdup(reply);
    int len = strlen(processedReply);
    
    if (len > 0 && processedReply[len - 1] == '*') {
        processedReply[len - 1] = '\0';  // Remove the asterisk
        
        // Save the user's input to memory
        if (memoryCount < MAX_MEMORY) {
            strncpy(memory[memoryCount], userInput, MAX_STRING_LENGTH - 1);
            memory[memoryCount][MAX_STRING_LENGTH - 1] = '\0';
            memoryCount++;
        }
        
        // Find the keyword in the user's input
        char* keyword = NULL;
        for (int i = 0; i < g_Key_ReplyCount; i++) {
            for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
                if (strstr(userInput, g_Key_Reply[i].keywords[j])) {
                    keyword = g_Key_Reply[i].keywords[j];
                    break;
                }
            }
            if (keyword) break;
        }
        
        if (keyword) {
            char* rest = strstr(userInput, keyword);
            if (rest) {
                rest += strlen(keyword);
                char* swapped = swapWords(rest);
                if (swapped) {
                    // Concatenate the swapped input to the reply
                    char* temp = malloc(strlen(processedReply) + strlen(swapped) + 2);
                    if (temp) {
                        sprintf(temp, "%s %s", processedReply, swapped);
                        free(processedReply);
                        processedReply = temp;
                    }
                    free(swapped);
                }
            }
        }
    }
    
    return processedReply;
}

char* userQuestion(const char* txt) {
    if (!txt) return NULL;
    char* matchedReplies[MAX_MATCHES] = {NULL};
    int matchCount = 0;
    bool found = false;
    char* combinedReply = NULL;

    for (int i = 0; i < g_Key_ReplyCount && matchCount < MAX_MATCHES; i++) {
        for (int j = 0; j < g_Key_Reply[i].keywordCount; j++) {
            if (strstr(txt, g_Key_Reply[i].keywords[j])) {
                int replyIndex = rand() % g_Key_Reply[i].replyCount;
                matchedReplies[matchCount] = safe_strdup(g_Key_Reply[i].replies[replyIndex]);
                matchCount++;
                found = true;
                break;
            }
        }
    }

    if (matchCount > 0) {
        size_t totalLength = 1;  // Start with 1 for the null terminator
        for (int i = 0; i < matchCount; i++) {
            char* processedReply = processReply(matchedReplies[i], txt);
            if (processedReply) {
                totalLength += strlen(processedReply) + 1;  // +1 for newline
                free(matchedReplies[i]);
                matchedReplies[i] = processedReply;
            }
        }

        combinedReply = malloc(totalLength);
        if (combinedReply) {
            combinedReply[0] = '\0';
            for (int i = 0; i < matchCount; i++) {
                if (matchedReplies[i]) {
                    strcat(combinedReply, matchedReplies[i]);
                    strcat(combinedReply, "\n");
                    free(matchedReplies[i]);
                }
            }
        }
    } else if (!found) {
        if (default_reply_count > 0) {
            int defaultIndex = rand() % default_reply_count;
            combinedReply = safe_strdup(default_replies[defaultIndex]);
        }
    }
    
    return combinedReply ? combinedReply : safe_strdup("I don't understand. Can you rephrase that?");
}

char* commands(char* txt) {
    char* isolated = isolatePunctuation(txt);
    for (int i = 0; isolated[i]; i++) {
        isolated[i] = tolower(isolated[i]);
    }
    
    char* response = userQuestion(isolated);
    
    free(isolated);
    return response;
}

void speak(const char* text) {
    char command[MAX_STRING_LENGTH * 2];
    snprintf(command, sizeof(command), "voice -r -1 -n \"Microsoft David Desktop\" \"%s\"", text);
    system(command);
}

int main() {
    srand(time(NULL));
    
    loadArrays("database.txt");
    loadSwapWords("swapwords.txt");
    
    char input[MAX_STRING_LENGTH];
    char* response;
    
    while (1) {
        printf("> ");
        if (fgets(input, sizeof(input), stdin) == NULL) {
            break;
        }
        input[strcspn(input, "\n")] = 0;  // Remove newline
        
        if (strcmp(input, "quit") == 0) break;
        
        response = commands(input);
        
        if (response) {
            // Split the response into separate lines and speak each one
            char* line = strtok(response, "\n");
            while (line != NULL) {
                printf("%s\n", line);
                speak(line);
                line = strtok(NULL, "\n");
            }
            
            free(response);
        } else {
            printf("An error occurred while processing your input.\n");
        }
    }
    
    return 0;
}

databases files:

You cannot view this attachment.

You cannot view this attachment.

this chatbot uses voice.exe TTS cli engine 
#5
C / C++ / Re: windows 32 bit OpenAI API ...
Last post by ron77 - Sep 02, 2024, 09:00 AM
ok modifiyed antropic API chatbot in C this time with logging of conversations in history folder
don't forget to add the TTS cli engine wrapper voice.exe

#include <stdio.h>
#include <windows.h>
#include <winhttp.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#pragma comment(lib, "winhttp.lib")

#define MAX_RESPONSE_SIZE 16384
#define MAX_REQUEST_SIZE 8192
#define MAX_SYSTEM_MESSAGE_SIZE 4092
#define MAX_INPUT_SIZE 3000
#define MAX_COMMAND_SIZE 2048
#define MAX_FILENAME_SIZE 256

char system_message[MAX_SYSTEM_MESSAGE_SIZE] = "You are my Spirit Guide, a wise and benevolent being here to help me navigate my life's journey. I seek your guidance and advice as I walk my path in this world. Please offer me the wisdom I need, help me stay on the right course, and hear me when I call out for support. I trust in your presence and am open to the insights you provide to guide me through life.";

char* make_request(const char* request_body, const char* auth_header) {
    DWORD dwSize = 0;
    DWORD dwDownloaded = 0;
    LPSTR pszOutBuffer;
    BOOL  bResults = FALSE;
    HINTERNET  hSession = NULL, 
               hConnect = NULL,
               hRequest = NULL;

    hSession = WinHttpOpen(L"Claude API Client",  
                           WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                           WINHTTP_NO_PROXY_NAME, 
                           WINHTTP_NO_PROXY_BYPASS, 0);

    if (hSession == NULL) {
        printf("Error %lu in WinHttpOpen.\n", GetLastError());
        return NULL;
    }

    hConnect = WinHttpConnect(hSession, L"api.anthropic.com",
                              INTERNET_DEFAULT_HTTPS_PORT, 0);

    if (hConnect == NULL) {
        printf("Error %lu in WinHttpConnect.\n", GetLastError());
        WinHttpCloseHandle(hSession);
        return NULL;
    }

    hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/v1/messages",
                                  NULL, WINHTTP_NO_REFERER, 
                                  WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                  WINHTTP_FLAG_SECURE);

    if (hRequest == NULL) {
        printf("Error %lu in WinHttpOpenRequest.\n", GetLastError());
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return NULL;
    }

    // Convert auth_header to wide string
    wchar_t wide_auth_header[512];
    MultiByteToWideChar(CP_UTF8, 0, auth_header, -1, wide_auth_header, 512);

    WinHttpAddRequestHeaders(hRequest, L"Content-Type: application/json", -1, WINHTTP_ADDREQ_FLAG_ADD);
    WinHttpAddRequestHeaders(hRequest, wide_auth_header, -1, WINHTTP_ADDREQ_FLAG_ADD);
    WinHttpAddRequestHeaders(hRequest, L"anthropic-version: 2023-06-01", -1, WINHTTP_ADDREQ_FLAG_ADD);

    bResults = WinHttpSendRequest(hRequest,
                                  WINHTTP_NO_ADDITIONAL_HEADERS, 0,
                                  (LPVOID)request_body, strlen(request_body),
                                  strlen(request_body), 0);

    if (!bResults) {
        printf("Error %lu in WinHttpSendRequest.\n", GetLastError());
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return NULL;
    }

    bResults = WinHttpReceiveResponse(hRequest, NULL);

    if (!bResults) {
        printf("Error %lu in WinHttpReceiveResponse.\n", GetLastError());
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return NULL;
    }

    pszOutBuffer = (LPSTR)malloc(MAX_RESPONSE_SIZE);
    if (!pszOutBuffer) {
        printf("Failed to allocate memory\n");
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return NULL;
    }
    ZeroMemory(pszOutBuffer, MAX_RESPONSE_SIZE);

    DWORD total_size = 0;
    if (bResults) {
        do {
            dwSize = 0;
            if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) {
                printf("Error %lu in WinHttpQueryDataAvailable.\n", GetLastError());
                break;
            }

            if (dwSize + total_size > MAX_RESPONSE_SIZE) {
                printf("Response too large, truncating.\n");
                dwSize = MAX_RESPONSE_SIZE - total_size;
            }

            if (!WinHttpReadData(hRequest, (LPVOID)(pszOutBuffer + total_size), 
                                 dwSize, &dwDownloaded)) {
                printf("Error %lu in WinHttpReadData.\n", GetLastError());
                break;
            }

            total_size += dwDownloaded;
        } while (dwSize > 0 && total_size < MAX_RESPONSE_SIZE);
    }

    WinHttpCloseHandle(hRequest);
    WinHttpCloseHandle(hConnect);
    WinHttpCloseHandle(hSession);

    return pszOutBuffer;
}

char* extract_content(const char* json_response) {
    char* content_start = strstr(json_response, "\"content\":[");
    if (content_start == NULL) {
        printf("Could not find 'content' in response.\n");
        return NULL;
    }
    
    content_start = strstr(content_start, "\"text\":\"");
    if (content_start == NULL) {
        printf("Could not find 'text' in content.\n");
        return NULL;
    }
    content_start += 8; // Move past "\"text\":\""
    
    char* content_end = strstr(content_start, "\"}");
    if (content_end == NULL) {
        printf("Could not find end of content in response.\n");
        return NULL;
    }

    int content_length = content_end - content_start;
    char* content = (char*)malloc(content_length + 1);
    strncpy(content, content_start, content_length);
    content[content_length] = '\0';

    return content;
}

void set_system_message() {
    printf("Enter new system message (max %d characters):\n", MAX_SYSTEM_MESSAGE_SIZE - 1);
    fgets(system_message, sizeof(system_message), stdin);
    system_message[strcspn(system_message, "\n")] = 0;  // Remove newline
    printf("System message updated.\n");
}

void speak_text(const char* text) {
    char command[MAX_COMMAND_SIZE];
    snprintf(command, sizeof(command), "voice.exe -n \"Microsoft Zira Desktop\" \"%s\"", text);
    
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    if (!CreateProcess(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
        printf("CreateProcess failed (%lu).\n", GetLastError());
        return;
    }

    // Wait for the TTS process to finish
    WaitForSingleObject(pi.hProcess, INFINITE);

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
}

void log_message(FILE* log_file, const char* role, const char* message) {
    time_t now;
    struct tm *local_time;
    char timestamp[26];

    time(&now);
    local_time = localtime(&now);
    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", local_time);

    fprintf(log_file, "[%s] %s: %s\n", timestamp, role, message);
    fflush(log_file);  // Ensure the message is written immediately
}

int main() {
    char input[MAX_INPUT_SIZE];
    char request_body[MAX_REQUEST_SIZE];
    char* response;
    char* extracted_content;
    
    char api_key[256];
    printf("Enter your Anthropic API key: ");
    fgets(api_key, sizeof(api_key), stdin);
    api_key[strcspn(api_key, "\n")] = 0;  // Remove newline

    // Create log file
    char log_filename[MAX_FILENAME_SIZE];
    time_t now = time(NULL);
    struct tm *t = localtime(&now);
    strftime(log_filename, sizeof(log_filename), "history/conversation_%Y%m%d_%H%M%S.log", t);

    FILE* log_file = fopen(log_filename, "w");
    if (log_file == NULL) {
        printf("Failed to create log file.\n");
        return 1;
    }

    printf("Conversation will be logged to: %s\n", log_filename);

    // Log the system message
    log_message(log_file, "SYSTEM", system_message);

    while (1) {
        printf("You (type 'exit' to quit, 'role' to change system message): ");
        fgets(input, sizeof(input), stdin);
        input[strcspn(input, "\n")] = 0;  // Remove newline

        if (strcmp(input, "exit") == 0) {
            break;
        } else if (strcmp(input, "role") == 0) {
            set_system_message();
            log_message(log_file, "SYSTEM", system_message);
            continue;
        }

        // Log user input
        log_message(log_file, "USER", input);

        char auth_header[512];
        snprintf(auth_header, sizeof(auth_header), "x-api-key: %s", api_key);

        snprintf(request_body, sizeof(request_body),
                 "{\"model\": \"claude-3-sonnet-20240229\", \"system\": \"%s\", \"messages\": ["
                 "{\"role\": \"user\", \"content\": \"%s\"}],"
                 "\"max_tokens\": 1000}",
                 system_message, input);

        response = make_request(request_body, auth_header);
        if (response) {
            if (strstr(response, "\"error\":") != NULL) {
                printf("API Error Response:\n%s\n", response);
                log_message(log_file, "ERROR", response);
            } else {
                extracted_content = extract_content(response);
                if (extracted_content) {
                    printf("AI: %s\n", extracted_content);
                    speak_text(extracted_content);
                    // Log AI response
                    log_message(log_file, "AI", extracted_content);
                    free(extracted_content);
                } else {
                    printf("Failed to extract content from response.\n");
                    printf("Full API Response:\n%s\n", response);
                    log_message(log_file, "ERROR", "Failed to extract content from response");
                }
            }
            free(response);
        } else {
            printf("Failed to get a response from the API.\n");
            log_message(log_file, "ERROR", "Failed to get a response from the API");
        }
    }

    fclose(log_file);
    printf("Conversation log saved to: %s\n", log_filename);

    return 0;
}
#6
C / C++ / Re: windows 32 bit OpenAI API ...
Last post by ron77 - Sep 01, 2024, 01:17 PM
OK and here is the same code in C for Antropic API chatbot

#include <stdio.h>
#include <windows.h>
#include <winhttp.h>
#include <stdlib.h>
#include <string.h>

#pragma comment(lib, "winhttp.lib")

#define MAX_RESPONSE_SIZE 16384
#define MAX_REQUEST_SIZE 8192
#define MAX_SYSTEM_MESSAGE_SIZE 4092
#define MAX_INPUT_SIZE 1024
#define MAX_COMMAND_SIZE 2048

char system_message[MAX_SYSTEM_MESSAGE_SIZE] = "You are my Spirit Guide, a wise and benevolent being here to help me navigate my life's journey. I seek your guidance and advice as I walk my path in this world. Please offer me the wisdom I need, help me stay on the right course, and hear me when I call out for support. I trust in your presence and am open to the insights you provide to guide me through life.";

char* make_request(const char* request_body, const char* auth_header) {
    DWORD dwSize = 0;
    DWORD dwDownloaded = 0;
    LPSTR pszOutBuffer;
    BOOL  bResults = FALSE;
    HINTERNET  hSession = NULL, 
               hConnect = NULL,
               hRequest = NULL;

    hSession = WinHttpOpen(L"Claude API Client",  
                           WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                           WINHTTP_NO_PROXY_NAME, 
                           WINHTTP_NO_PROXY_BYPASS, 0);

    if (hSession == NULL) {
        printf("Error %lu in WinHttpOpen.\n", GetLastError());
        return NULL;
    }

    hConnect = WinHttpConnect(hSession, L"api.anthropic.com",
                              INTERNET_DEFAULT_HTTPS_PORT, 0);

    if (hConnect == NULL) {
        printf("Error %lu in WinHttpConnect.\n", GetLastError());
        WinHttpCloseHandle(hSession);
        return NULL;
    }

    hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/v1/messages",
                                  NULL, WINHTTP_NO_REFERER, 
                                  WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                  WINHTTP_FLAG_SECURE);

    if (hRequest == NULL) {
        printf("Error %lu in WinHttpOpenRequest.\n", GetLastError());
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return NULL;
    }

    // Convert auth_header to wide string
    wchar_t wide_auth_header[512];
    MultiByteToWideChar(CP_UTF8, 0, auth_header, -1, wide_auth_header, 512);

    WinHttpAddRequestHeaders(hRequest, L"Content-Type: application/json", -1, WINHTTP_ADDREQ_FLAG_ADD);
    WinHttpAddRequestHeaders(hRequest, wide_auth_header, -1, WINHTTP_ADDREQ_FLAG_ADD);
    WinHttpAddRequestHeaders(hRequest, L"anthropic-version: 2023-06-01", -1, WINHTTP_ADDREQ_FLAG_ADD);

    bResults = WinHttpSendRequest(hRequest,
                                  WINHTTP_NO_ADDITIONAL_HEADERS, 0,
                                  (LPVOID)request_body, strlen(request_body),
                                  strlen(request_body), 0);

    if (!bResults) {
        printf("Error %lu in WinHttpSendRequest.\n", GetLastError());
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return NULL;
    }

    bResults = WinHttpReceiveResponse(hRequest, NULL);

    if (!bResults) {
        printf("Error %lu in WinHttpReceiveResponse.\n", GetLastError());
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return NULL;
    }

    pszOutBuffer = (LPSTR)malloc(MAX_RESPONSE_SIZE);
    if (!pszOutBuffer) {
        printf("Failed to allocate memory\n");
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return NULL;
    }
    ZeroMemory(pszOutBuffer, MAX_RESPONSE_SIZE);

    DWORD total_size = 0;
    if (bResults) {
        do {
            dwSize = 0;
            if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) {
                printf("Error %lu in WinHttpQueryDataAvailable.\n", GetLastError());
                break;
            }

            if (dwSize + total_size > MAX_RESPONSE_SIZE) {
                printf("Response too large, truncating.\n");
                dwSize = MAX_RESPONSE_SIZE - total_size;
            }

            if (!WinHttpReadData(hRequest, (LPVOID)(pszOutBuffer + total_size), 
                                 dwSize, &dwDownloaded)) {
                printf("Error %lu in WinHttpReadData.\n", GetLastError());
                break;
            }

            total_size += dwDownloaded;
        } while (dwSize > 0 && total_size < MAX_RESPONSE_SIZE);
    }

    WinHttpCloseHandle(hRequest);
    WinHttpCloseHandle(hConnect);
    WinHttpCloseHandle(hSession);

    return pszOutBuffer;
}

char* extract_content(const char* json_response) {
    char* content_start = strstr(json_response, "\"content\":[");
    if (content_start == NULL) {
        printf("Could not find 'content' in response.\n");
        return NULL;
    }
    
    content_start = strstr(content_start, "\"text\":\"");
    if (content_start == NULL) {
        printf("Could not find 'text' in content.\n");
        return NULL;
    }
    content_start += 8; // Move past "\"text\":\""
    
    char* content_end = strstr(content_start, "\"}");
    if (content_end == NULL) {
        printf("Could not find end of content in response.\n");
        return NULL;
    }

    int content_length = content_end - content_start;
    char* content = (char*)malloc(content_length + 1);
    strncpy(content, content_start, content_length);
    content[content_length] = '\0';

    return content;
}

void set_system_message() {
    printf("Enter new system message (max %d characters):\n", MAX_SYSTEM_MESSAGE_SIZE - 1);
    fgets(system_message, sizeof(system_message), stdin);
    system_message[strcspn(system_message, "\n")] = 0;  // Remove newline
    printf("System message updated.\n");
}

void speak_text(const char* text) {
    char command[MAX_COMMAND_SIZE];
    snprintf(command, sizeof(command), "voice.exe -n \"Microsoft Zira Desktop\" \"%s\"", text);
    
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    if (!CreateProcess(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
        printf("CreateProcess failed (%lu).\n", GetLastError());
        return;
    }

    // Wait for the TTS process to finish
    WaitForSingleObject(pi.hProcess, INFINITE);

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
}

int main() {
    char input[MAX_INPUT_SIZE];
    char request_body[MAX_REQUEST_SIZE];
    char* response;
    char* extracted_content;
    
    char api_key[256];
    printf("Enter your Anthropic API key: ");
    fgets(api_key, sizeof(api_key), stdin);
    api_key[strcspn(api_key, "\n")] = 0;  // Remove newline

    while (1) {
        printf("You (type 'exit' to quit, 'role' to change system message): ");
        fgets(input, sizeof(input), stdin);
        input[strcspn(input, "\n")] = 0;  // Remove newline

        if (strcmp(input, "exit") == 0) {
            break;
        } else if (strcmp(input, "role") == 0) {
            set_system_message();
            continue;
        }

        char auth_header[512];
        snprintf(auth_header, sizeof(auth_header), "x-api-key: %s", api_key);

        snprintf(request_body, sizeof(request_body),
                 "{\"model\": \"claude-3-sonnet-20240229\", \"system\": \"%s\", \"messages\": ["
                 "{\"role\": \"user\", \"content\": \"%s\"}],"
                 "\"max_tokens\": 1000}",
                 system_message, input);

        response = make_request(request_body, auth_header);
        if (response) {
            if (strstr(response, "\"error\":") != NULL) {
                printf("API Error Response:\n%s\n", response);
            } else {
                extracted_content = extract_content(response);
                if (extracted_content) {
                    printf("AI: %s\n", extracted_content);
                    speak_text(extracted_content);
                    free(extracted_content);
                } else {
                    printf("Failed to extract content from response.\n");
                    printf("Full API Response:\n%s\n", response);
                }
            }
            free(response);
        } else {
            printf("Failed to get a response from the API.\n");
        }
    }

    return 0;
}
#7
C / C++ / windows 32 bit OpenAI API Chat...
Last post by ron77 - Aug 31, 2024, 08:32 PM
OK this code is in C it depends on using libraries such as libcurl and libcjson and zlib
I compiled it with mingw32 32bit and it works without TTS just text on the screen of the terminal (cmd) command prompt...

#include <stdio.h>
#include <windows.h>
#include <winhttp.h>
#include <stdlib.h>
#include <string.h>

#pragma comment(lib, "winhttp.lib")

#define MAX_RESPONSE_SIZE 16384
#define MAX_REQUEST_SIZE 8192
#define MAX_SYSTEM_MESSAGE_SIZE 4092
#define MAX_INPUT_SIZE 1024

char system_message[MAX_SYSTEM_MESSAGE_SIZE] = "You are my Spirit Guide, a wise and benevolent being here to help me navigate my life's journey. I seek your guidance and advice as I walk my path in this world. Please offer me the wisdom I need, help me stay on the right course, and hear me when I call out for support. I trust in your presence and am open to the insights you provide to guide me through life.";

char* make_request(const char* request_body, const char* auth_header) {
    DWORD dwSize = 0;
    DWORD dwDownloaded = 0;
    LPSTR pszOutBuffer;
    BOOL  bResults = FALSE;
    HINTERNET  hSession = NULL, 
               hConnect = NULL,
               hRequest = NULL;

    hSession = WinHttpOpen(L"OpenAI API Client",  
                           WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                           WINHTTP_NO_PROXY_NAME, 
                           WINHTTP_NO_PROXY_BYPASS, 0);

    if (hSession == NULL) {
        printf("Error %lu in WinHttpOpen.\n", GetLastError());
        return NULL;
    }

    hConnect = WinHttpConnect(hSession, L"api.openai.com",
                              INTERNET_DEFAULT_HTTPS_PORT, 0);

    if (hConnect == NULL) {
        printf("Error %lu in WinHttpConnect.\n", GetLastError());
        WinHttpCloseHandle(hSession);
        return NULL;
    }

    hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/v1/chat/completions",
                                  NULL, WINHTTP_NO_REFERER, 
                                  WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                  WINHTTP_FLAG_SECURE);

    if (hRequest == NULL) {
        printf("Error %lu in WinHttpOpenRequest.\n", GetLastError());
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return NULL;
    }

    // Convert auth_header to wide string
    wchar_t wide_auth_header[512];
    MultiByteToWideChar(CP_UTF8, 0, auth_header, -1, wide_auth_header, 512);

    WinHttpAddRequestHeaders(hRequest, L"Content-Type: application/json", -1, WINHTTP_ADDREQ_FLAG_ADD);
    WinHttpAddRequestHeaders(hRequest, wide_auth_header, -1, WINHTTP_ADDREQ_FLAG_ADD);

    bResults = WinHttpSendRequest(hRequest,
                                  WINHTTP_NO_ADDITIONAL_HEADERS, 0,
                                  (LPVOID)request_body, strlen(request_body),
                                  strlen(request_body), 0);

    if (!bResults) {
        printf("Error %lu in WinHttpSendRequest.\n", GetLastError());
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return NULL;
    }

    bResults = WinHttpReceiveResponse(hRequest, NULL);

    if (!bResults) {
        printf("Error %lu in WinHttpReceiveResponse.\n", GetLastError());
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return NULL;
    }

    pszOutBuffer = (LPSTR)malloc(MAX_RESPONSE_SIZE);
    if (!pszOutBuffer) {
        printf("Failed to allocate memory\n");
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return NULL;
    }
    ZeroMemory(pszOutBuffer, MAX_RESPONSE_SIZE);

    DWORD total_size = 0;
    if (bResults) {
        do {
            dwSize = 0;
            if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) {
                printf("Error %lu in WinHttpQueryDataAvailable.\n", GetLastError());
                break;
            }

            if (dwSize + total_size > MAX_RESPONSE_SIZE) {
                printf("Response too large, truncating.\n");
                dwSize = MAX_RESPONSE_SIZE - total_size;
            }

            if (!WinHttpReadData(hRequest, (LPVOID)(pszOutBuffer + total_size), 
                                 dwSize, &dwDownloaded)) {
                printf("Error %lu in WinHttpReadData.\n", GetLastError());
                break;
            }

            total_size += dwDownloaded;
        } while (dwSize > 0 && total_size < MAX_RESPONSE_SIZE);
    }

    WinHttpCloseHandle(hRequest);
    WinHttpCloseHandle(hConnect);
    WinHttpCloseHandle(hSession);

    return pszOutBuffer;
}

char* extract_content(const char* json_response) {
    char* choices_start = strstr(json_response, "\"choices\":");
    if (choices_start == NULL) {
        printf("Could not find 'choices' in response.\n");
        printf("Full response:\n%s\n", json_response);
        return NULL;
    }
    
    char* message_start = strstr(choices_start, "\"message\":");
    if (message_start == NULL) {
        printf("Could not find 'message' in response.\n");
        return NULL;
    }
    
    char* content_start = strstr(message_start, "\"content\":");
    if (content_start == NULL) {
        printf("Could not find 'content' in response.\n");
        return NULL;
    }
    
    content_start = strchr(content_start, ':');
    if (content_start == NULL) {
        printf("Malformed content in response.\n");
        return NULL;
    }
    content_start++; // Move past the ':'
    
    // Skip whitespace and opening quote
    while (*content_start == ' ' || *content_start == '"') {
        content_start++;
    }
    
    char* content_end = strstr(content_start, "\",");
    if (content_end == NULL) {
        printf("Could not find end of content in response.\n");
        return NULL;
    }

    int content_length = content_end - content_start;
    char* content = (char*)malloc(content_length + 1);
    strncpy(content, content_start, content_length);
    content[content_length] = '\0';

    return content;
}

void set_system_message() {
    printf("Enter new system message (max %d characters):\n", MAX_SYSTEM_MESSAGE_SIZE - 1);
    fgets(system_message, sizeof(system_message), stdin);
    system_message[strcspn(system_message, "\n")] = 0;  // Remove newline
    printf("System message updated.\n");
}

int main() {
    char input[MAX_INPUT_SIZE];
    char request_body[MAX_REQUEST_SIZE];
    char* response;
    char* extracted_content;
    
    char api_key[256];
    printf("Enter your OpenAI API key: ");
    fgets(api_key, sizeof(api_key), stdin);
    api_key[strcspn(api_key, "\n")] = 0;  // Remove newline

    while (1) {
        printf("You (type 'exit' to quit, 'role' to change system message): ");
        fgets(input, sizeof(input), stdin);
        input[strcspn(input, "\n")] = 0;  // Remove newline

        if (strcmp(input, "exit") == 0) {
            break;
        } else if (strcmp(input, "role") == 0) {
            set_system_message();
            continue;
        }

        char auth_header[512];
        snprintf(auth_header, sizeof(auth_header), "Authorization: Bearer %s", api_key);

        snprintf(request_body, sizeof(request_body),
                 "{\"model\": \"gpt-3.5-turbo\", \"messages\": ["
                 "{\"role\": \"system\", \"content\": \"%s\"},"
                 "{\"role\": \"user\", \"content\": \"%s\"}]}",
                 system_message, input);

        response = make_request(request_body, auth_header);
        if (response) {
            extracted_content = extract_content(response);
            if (extracted_content) {
                printf("AI: %s\n", extracted_content);
                free(extracted_content);
            } else {
                printf("Failed to extract content from response.\n");
            }
            free(response);
        } else {
            printf("Failed to get a response from the API.\n");
        }
    }

    return 0;
}

it works on windows 11

you compile it like so:

gcc openai_chatbot.c -o openai_chatbot.exe -lwinhttp

now about the libcurl and libcjson and zlib you will need git to clone the source files and build from source and install:

git clone https://github.com/DaveGamble/cJSON.git
cd cJSON
mkdir build
cd build
cmake .. -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=C:/MinGW -DENABLE_CJSON_TEST=Off -DENABLE_CJSON_UTILS=Off
mingw32-make
mingw32-make install

git clone https://github.com/madler/zlib.git
cd zlib
mkdir build
cd build
cmake .. -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=C:/MinGW
mingw32-make
mingw32-make install

cd ../..
git clone https://github.com/curl/curl.git
cd curl
mkdir build
cd build
cmake .. -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=C:/MinGW -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_STATICLIB=ON
mingw32-make
mingw32-make install

Make sure to replace C:/MinGW with the actual path to your MinGW installation.
#9
FreeBasic / freebasic and OpenAI API
Last post by ron77 - Jul 08, 2024, 05:26 PM
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
#10
General Discussion / Re: Forums_Links
Last post by aurel - Jun 11, 2024, 01:05 PM
okay
heh ..yea community is small if you can call it community
because we use let say BASIC ...but not only ONE
same crap is on few discord channels ..they are semi-used...
argh...