Информация Chat GPT in SA:MP

Sanurial

Участник
Автор темы
80
12
Из-за того что в этой теме: https://www.blast.hk/threads/171743/#post-1287059 код не совсем работает, а некоторым не хватит ума понять в чём дело, покажу готовый и рабочий код.

Рабочий код:
require 'lib.moonloader'
effil = require"effil"
local ffi = require('ffi')
local imgui = require 'mimgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local new = imgui.new

local renderWindow = new.bool(true)
local input_news_buf = ffi.new('char[1024]')


imgui.OnInitialize(function()
    imgui.GetIO().IniFilename = nil
end)

local newFrame = imgui.OnFrame(
    function() return renderWindow[0] end,
    function(player)
        local resX, resY = getScreenResolution()
        local sizeX, sizeY = 300, 300
        imgui.SetNextWindowPos(imgui.ImVec2(resX / 2, resY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(sizeX, sizeY), imgui.Cond.FirstUseEver)
        imgui.Begin('Main Window', renderWindow)
        imgui.InputTextMultiline(u8 "##138", input_news_buf, ffi.sizeof(input_news_buf), imgui.ImVec2(785, 175))
        if imgui.Button(u8'A12', imgui.ImVec2(40, 24)) then
            local input_text = u8:decode(ffi.string(input_news_buf))
            onSendChat(input_text)
        end   
        imgui.End()
    end
)

function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand('mimgui', function()
        renderWindow[0] = not renderWindow[0]
    end)
    while true do
        wait(0)
    
    end
end

function onSendChat(message)
    OpenAI_Generate(message, false, function(responseText)
        sampAddChatMessage("Ответ GPT-3.5: " .. responseText, 0xFFFFFF)
    end)
end

function OpenAI_Generate(prompt, dontFreeze, customCallback)
    asyncHttpRequest('POST', 'https://api.openai.com/v1/chat/completions', {
            headers = {
                ['Authorization'] = 'Bearer ' .. 'ВАШ API CHATGPT',
                ['Content-Type'] = 'application/json'
            },
            data = u8(encodeJson({
                ["model"] = "gpt-3.5-turbo",
                ["messages"] = {
                    {
                        ["role"] = "system",
                        ["content"] = "You are a helpful assistant."
                    },
                    {
                        ["role"] = "user",
                        ["content"] = prompt
                    }
                },
                ["temperature"] = 0.5,
                ["max_tokens"] = 50,
                ["top_p"] = 1,
                ["frequency_penalty"] = 0,
                ["presence_penalty"] = 0,
                ["stop"] = {"You:"}
            }))
        },
        function(response)
            if response.status_code == 200 then
                local RESULT = decodeJson(response.text)
                if RESULT.choices and #RESULT.choices > 0 then
                    local text = RESULT.choices[1].message.content
                    if text ~= nil then
                        text = u8:decode(text)
                        if customCallback then
                            customCallback(text)
                        else
                            sendChatMessage("GPT-3.5 ответ: " .. text)
                        end
                    else
                        print("Ошибка: текст ответа равен nil")
                    end
                else
                    print("Ошибка: сервер не вернул ни одного варианта ответа")
                end
            else
                print("Ошибка: HTTP код: " .. response.status_code)
                print("Текст ошибки: " .. response.text)
            end
        end,
        function(err)
            print("Ошибка: " .. err)
        end
    )
end

function asyncHttpRequest(method, url, args, resolve, reject)
    local request_thread = effil.thread(function (method, url, args)
        local requests = require 'requests'
        local result, response = pcall(requests.request, method, url, args)
        if result then
            response.json, response.xml = nil, nil
            return true, response
        else
            return false, response
        end
    end)(method, url, args)
    -- Если запрос без функций обработки ответа и ошибок.
    if not resolve then resolve = function() end end
    if not reject then reject = function() end end
    -- Проверка выполнения потока
    lua_thread.create(function()
        local runner = request_thread
        while true do
            local status, err = runner:status()
            if not err then
                if status == 'completed' then
                    local result, response = runner:get()
                    if result then
                        resolve(response)
                    else
                        reject(response)
                    end
                    return
                elseif status == 'canceled' then
                    return reject(status)
                end
            else
                return reject(err)
            end
            wait(0)
        end
    end)
end

Указывайте пожалуйста какие библиотеки нужно использовать и как записывать переменные...
Я с буфером input_news_buf долго е**лся, пока не догнал написать local input_news_buf = ffi.new('char[1024]')

Версия с ответами в обычный чат(сообщение переносится): спасибо автору этого скрипта - https://www.blast.hk/threads/69714/
В обычный чат ответы:
require 'lib.moonloader'
effil = require"effil"
local ffi = require('ffi')
local imgui = require 'mimgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local new = imgui.new

local renderWindow = new.bool(true)
local input_news_buf = ffi.new('char[1024]')

bi = false

imgui.OnInitialize(function()
    imgui.GetIO().IniFilename = nil
end)

local newFrame = imgui.OnFrame(
    function() return renderWindow[0] end,
    function(player)
        local resX, resY = getScreenResolution()
        local sizeX, sizeY = 300, 300
        imgui.SetNextWindowPos(imgui.ImVec2(resX / 2, resY / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        imgui.SetNextWindowSize(imgui.ImVec2(sizeX, sizeY), imgui.Cond.FirstUseEver)
        imgui.Begin('Main Window', renderWindow)
        imgui.InputTextMultiline(u8 "##138", input_news_buf, ffi.sizeof(input_news_buf), imgui.ImVec2(785, 175))
        if imgui.Button(u8'A12', imgui.ImVec2(40, 24)) then
            local input_text = u8:decode(ffi.string(input_news_buf))
            onSendChat(input_text)
        end    
        imgui.End()
    end
)

function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand('mimgui', function()
        renderWindow[0] = not renderWindow[0]
    end)
    while true do
        wait(0)
     
    end
end

function onSendChat(msg)
    OpenAI_Generate(msg, false, function(responseText)
        local newMsg = responseText
        local chunks = divide(newMsg, "", "", 50) - - через какое количество символов (включая пробелы) разделять сообщение
        lua_thread.create(function()
            for _, chunk in ipairs(chunks) do
                sampSendChat(chunk)
                wait(500) -- задержка отправки сообщений в мс
            end
        end)
    end)
end

function divide(msg, beginning, ending, limit)
    local chunks = {}
    if msg == nil then
        return chunks
    end
    for i = 1, #msg, limit do
        table.insert(chunks, beginning .. msg:sub(i, i+limit-1) .. ending)
    end
    return


function OpenAI_Generate(prompt, dontFreeze, customCallback)
    asyncHttpRequest('POST', 'https://api.openai.com/v1/chat/completions', {
            headers = {
                ['Authorization'] = 'Bearer ' .. 'ВАШ API CHATGPT',
                ['Content-Type'] = 'application/json'
            },
            data = u8(encodeJson({
                ["model"] = "gpt-3.5-turbo",
                ["messages"] = {
                    {
                        ["role"] = "system",
                        ["content"] = "You are a helpful assistant."
                    },
                    {
                        ["role"] = "user",
                        ["content"] = prompt
                    }
                },
                ["temperature"] = 0.5,
                ["max_tokens"] = 50,
                ["top_p"] = 1,
                ["frequency_penalty"] = 0,
                ["presence_penalty"] = 0,
                ["stop"] = {"You:"}
            }))
        },
        function(response)
            if response.status_code == 200 then
                local RESULT = decodeJson(response.text)
                if RESULT.choices and #RESULT.choices > 0 then
                    local text = RESULT.choices[1].message.content
                    if text ~= nil then
                        text = u8:decode(text)
                        if customCallback then
                            customCallback(text)
                        else
                            sendChatMessage("GPT-3.5 ответ: " .. text)
                        end
                    else
                        print("Ошибка: текст ответа равен nil")
                    end
                else
                    print("Ошибка: сервер не вернул ни одного варианта ответа")
                end
            else
                print("Ошибка: HTTP код: " .. response.status_code)
                print("Текст ошибки: " .. response.text)
            end
        end,
        function(err)
            print("Ошибка: " .. err)
        end
    )
end

function asyncHttpRequest(method, url, args, resolve, reject)
    local request_thread = effil.thread(function (method, url, args)
        local requests = require 'requests'
        local result, response = pcall(requests.request, method, url, args)
        if result then
            response.json, response.xml = nil, nil
            return true, response
        else
            return false, response
        end
    end)(method, url, args)
    -- Если запрос без функций обработки ответа и ошибок.
    if not resolve then resolve = function() end end
    if not reject then reject = function() end end
    -- Проверка выполнения потока
    lua_thread.create(function()
        local runner = request_thread
        while true do
            local status, err = runner:status()
            if not err then
                if status == 'completed' then
                    local result, response = runner:get()
                    if result then
                        resolve(response)
                    else
                        reject(response)
                    end
                    return
                elseif status == 'canceled' then
                    return reject(status)
                end
            else
                return reject(err)
            end
            wait(0)
        end
    end)
end
 
Последнее редактирование:
  • Влюблен
Реакции: kuzheren

Sanurial

Участник
Автор темы
80
12
так была же тема на 3.5 турбо, https://www.blast.hk/threads/171743/
Проблема в том, что если взять готовый код оттуда, не выйдет его запустить с первого раза, тут же у меня уже всё подключено и объявлено, потому игрокам достаточно просто вставить свой API чтобы заработало всё
 

JasonEllison

Известный
5
5
Я с буфером input_news_buf долго е**лся, пока не догнал написать local input_news_buf = ffi.new('char[1024]')
Ну извини :D
Цель была выложить только основу для подключения) А с такими нюансами, думал сами разберутся :D