Jump to content

Recommended Posts

Posted

I'm using this to generate Lua documentation from the existing C++ content. Here is a simple example to use the API.

#ifdef _WIN32
    #define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
    #include <windows.h>
#endif

#include <string>
#include <curl/curl.h>
#include "json.hpp"

std::string APIKEY = "";
std::string logtext;

#ifndef _DEBUG
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        curl_global_init(0);
        break;
    case DLL_PROCESS_DETACH:
        curl_global_cleanup();
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}
#endif

void Print(const std::string& s)
{
    OutputDebugStringA(s.c_str());
    printf((s + std::string("\n")).c_str());
    if (not logtext.empty()) logtext += "\n";
    logtext += s;
}

size_t WriteCallback(char* contents, size_t size, size_t nmemb, void* userp)
{
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

// trim from start (in place)
static inline void ltrim(std::string& s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
        return !std::isspace(ch);
        }));
}

// trim from end (in place)
static inline void rtrim(std::string& s) {
    s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
        return !std::isspace(ch);
        }).base(), s.end());
}

// trim from both ends (in place)
static inline void trim(std::string& s) {
    rtrim(s);
    ltrim(s);
}

std::string Chat(const std::string prompt, const std::string& APIKEY)
{
    std::string response;
    bool success = false;

    std::string imageurl;

    if (APIKEY.empty()) return 0;

    std::string url = "https://api.openai.com/v1/chat/completions";
    std::string readBuffer;
    std::string bearerTokenHeader = "Authorization: Bearer " + APIKEY;
    std::string contentType = "Content-Type: application/json";

    auto curl = curl_easy_init();

    struct curl_slist* headers = NULL;
    headers = curl_slist_append(headers, bearerTokenHeader.c_str());
    headers = curl_slist_append(headers, contentType.c_str());

    nlohmann::json j3, msg;
    j3["model"] = "gpt-3.5-turbo";
    j3["messages"] = {};

    msg["role"] = "user";
    msg["content"] = prompt;
    j3["messages"].push_back(msg);

    std::string postfields = j3.dump();

    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postfields.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);

    auto errcode = curl_easy_perform(curl);
    if (errcode == CURLE_OK)
    {
        //OutputDebugStringA(readBuffer.c_str());
        trim(readBuffer);
        if (readBuffer.size() > 1 and readBuffer[0] == '{' and readBuffer[readBuffer.size() - 1] == '}')
        {
            j3 = nlohmann::json::parse(readBuffer);
            if (j3.is_object())
            {
                if (j3["error"].is_object())
                {
                    if (j3["error"]["message"].is_string())
                    {
                        std::string msg = j3["error"]["message"];
                        msg = "Error: " + msg;
                        Print(msg.c_str());
                    }
                    else
                    {
                        Print("Error: Unknown error.");
                    }
                }
                else
                {
                    if (j3["data"].is_array() or j3["data"].size() == 0)
                    {
                        if (j3["choices"].is_array() and not j3["choices"].empty())
                        {
                            std::string s = j3["choices"][0]["message"]["content"];
                            response = s;
                            success = true;
                        }
                    }
                }
            }
            else
            {
                Print("Error: Response is not a valid JSON object.");
                Print(readBuffer);
            }
        }
        else
        {
            Print("Error: Response is not a valid JSON object.");
            Print(readBuffer);
        }
    }
    else
    {
        Print("Error: Request failed.");
    }

    curl_easy_cleanup(curl);
    return response;
}

int main(int argc, char* argv[])
{
    std::string key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    std::string prompt = "What is 2 plus 3?";
    std::string response = Chat(prompt, key);
    printf(response.c_str());
    return 0;
}

 

  • Like 1

My job is to make tools you love, with the features you want, and performance you can't live without.

  • 2 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...