diff --git a/gigachat/api.lua b/gigachat/api.lua index 528393f..77e8365 100644 --- a/gigachat/api.lua +++ b/gigachat/api.lua @@ -11,9 +11,37 @@ if not db.token then db:save() end +local types = { --Разрешенные типы файлов для загрузки в модель + txt = {mime = 'text/plain', size = 40}, + doc = {mime = 'application/msword', size = 40}, + docx = {mime = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', size = 40}, + pdf = {mime = 'application/pdf', size = 40}, + epub = {mime = 'application/epub+zip', size = 40}, + ppt = {mime = 'application/vnd.ms-powerpoint', size = 40}, + pptx = {mime = 'application/vnd.openxmlformats-officedocument.presentationml.presentation', size = 40}, + jpeg = {mime = 'image/jpeg', size = 15}, + png = {mime = 'image/png', size = 15}, + tiff = {mime = 'image/tiff', size = 15}, + bmp = {mime = 'image/bmp', size = 15}, + mp4 = {mime = 'video/mp4', size = 35}, + mp3 = {mime = 'audio/mpeg', size = 35}, + m4a = {mime = 'audio/x-m4a', size = 35}, + wav = {mime = 'audio/x-wav', size = 35}, + weba = {mime = 'audio/webm', size = 35}, + ogg = {mime = 'audio/ogg', size = 35}, + opus = {mime = 'audio/opus', size = 35} +} + local _M = {} +local mt = {__index = _M} + _M.chat = {} +_M.files = setmetatable({}, mt) + +function mt.__call(self,...) + return _M.files.list(...) +end log.outfile = config.logs_path..'gigachat_'..os.date('%Y-%m-%d')..'.log' log.level = 'trace' @@ -53,6 +81,8 @@ function _M.token() post = true, postfields = poster({scope=config.scope}), httpheader = headers, + ssl_verifypeer = false, + ssl_verifyhost = false, writefunction = function(st) str = str..st collectgarbage("collect") @@ -87,6 +117,8 @@ local function get(endpoint) local c = cURL.easy{ url = url, httpheader = headers, + ssl_verifypeer = false, + ssl_verifyhost = false, writefunction = function(st) str = str..st collectgarbage("collect") @@ -118,6 +150,8 @@ local function post(endpoint,data) url = url, httpheader = headers, post = true, + ssl_verifypeer = false, + ssl_verifyhost = false, postfields = json.encode(data), writefunction = function(st) str = str..st @@ -138,6 +172,58 @@ local function post(endpoint,data) return res,err end +local function upload(endpoint,file) + local str = '' + local ok, err = true + local url = config.base_url..endpoint + local headers = { + 'Content-type: multipart/form-data', + 'Accept: application/json', + 'Authorization: Bearer '.._M.token() + } + local c = cURL.easy{ + url = url, + httpheader = headers, + ssl_verifypeer = false, + ssl_verifyhost = false, + post = true, + writefunction = function(st) + str = str..st + collectgarbage("collect") + return #st + end + } + local form = cURL.form() + local typ = file:match('^.+%.(.+)$') or '' + if not types[typ] then return nil, json.encode({status = 400, message = 'Тип файла не поддерживается'}) end + local file_test = io.open(file, 'rb') + if not file_test then return nil,'Файл '..file..' не найден' end + local size = file_test:seek('end') + file_test:close() + if size > types[typ].size*1024*1024 then return nil, json.encode({status = 400, message = 'Превышен максимальный размер файла типа '..typ..' - '..types[typ].size..' Мб'}) end + ok, err = form:add_file('file',file,types[typ].mime) + if not ok then + form:free() + return nil, err + end + ok,err = c:setopt_postfields(form:get()) + if not ok then + form:free() + return nil, err + end + ok, err = c:perform() + local code = c:getinfo_response_code() + c:close() + if not ok then return nil, err end + if code ~= 200 then + log.error(str) + return nil,str + end + local res,err = get_result(str) + if res then return res end + return res,err +end + -- Получение списка доступных моделей function _M.models() @@ -150,7 +236,7 @@ end function _M.chat.completions(messages,model,max_tokens,repetition_penalty,stream,update_interval,temperature,top_p,function_call,functions) if type(messages) == 'string' then messages = {{role='user',content=messages}} end - if temperature and top_p then return nil, 'Одновременно указаны top_p и температура выборки' end + if temperature and top_p then return nil, json.encode({status = 400, message = 'Одновременно указаны top_p и температура выборки'}) end return post('chat/completions',{ model = model or 'GigaChat-2', stream = stream or false, @@ -169,4 +255,16 @@ function _M.embeddings(model) }) end +-- Загрузка файлов + +function _M.files.add(file) + return upload('files',file) +end + +-- Получение списка файлов + +function _M.files.list() + +end + return _M