196 lines
5.0 KiB
Plaintext
196 lines
5.0 KiB
Plaintext
unit uChatAPI;
|
||
|
||
interface
|
||
|
||
uses
|
||
Classes, SysUtils, IdHTTP, System.JSON, IdSSLOpenSSL, IdGlobal;
|
||
|
||
type
|
||
TMessage = procedure(s: string) of object;
|
||
|
||
type
|
||
TChatAPI = class(TObject)
|
||
protected
|
||
FToken_api: string;
|
||
FPrefix: string;
|
||
FOnError: TMessage;
|
||
function GetOtvetFromJson(jsonString: string; isOllama: boolean = false)
|
||
: string; virtual;
|
||
function CreateHTTPRequest(const url: string; const params: TStringStream;
|
||
isOllama: boolean = false): string;
|
||
|
||
public
|
||
constructor Create(Sender: TObject; aToken: string;
|
||
aprefix: string = ''); virtual;
|
||
destructor Destroy; override;
|
||
function GetGPTRequest(url: string; model: string; q: string;
|
||
isOllama: boolean = false): string;
|
||
property OnError: TMessage read FOnError write FOnError;
|
||
end;
|
||
|
||
implementation
|
||
|
||
{ TChatAPI }
|
||
|
||
constructor TChatAPI.Create(Sender: TObject; aToken: string;
|
||
aprefix: string = '');
|
||
begin
|
||
FPrefix := aprefix;
|
||
FToken_api := aToken;
|
||
end;
|
||
|
||
function TChatAPI.CreateHTTPRequest(const url: string;
|
||
const params: TStringStream; isOllama: boolean = false): string;
|
||
var
|
||
http: TIdHTTP;
|
||
ssl: TIdSSLIOHandlerSocketOpenSSL;
|
||
otv: string;
|
||
begin
|
||
http := TIdHTTP.Create(nil);
|
||
ssl := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
|
||
try
|
||
http.IOHandler := ssl;
|
||
ssl.SSLOptions.method := sslvSSLv23;
|
||
http.Request.UserAgent :=
|
||
'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
|
||
http.Request.CustomHeaders.Clear;
|
||
// http.Request.CustomHeaders.Add('Content-Type: application/json; charset=utf-8');
|
||
http.Request.ContentType := 'application/json; charset=utf-8';
|
||
|
||
if FToken_api <> '' then
|
||
http.Request.CustomHeaders.Add('Authorization: Bearer ' + FToken_api);
|
||
http.Request.Accept := 'application/json; charset=utf-8';
|
||
http.Request.CharSet := 'utf-8';
|
||
http.Response.CharSet := 'utf-8';
|
||
// http.Request.CustomHeaders.Add('Accept: application/json; charset=utf-8');
|
||
http.Response.ContentEncoding := 'utf-8';
|
||
http.IOHandler.DefStringEncoding := IndyTextEncoding_UTF8;
|
||
http.Request.ContentEncoding := 'utf-8';
|
||
|
||
try
|
||
otv := http.Post(url, params);
|
||
Result := GetOtvetFromJson(otv, isOllama);
|
||
except
|
||
on E: Exception do
|
||
if Assigned(OnError) then
|
||
OnError(E.Message);
|
||
end;
|
||
finally
|
||
params.Free;
|
||
http.Free;
|
||
ssl.Free;
|
||
end;
|
||
end;
|
||
|
||
destructor TChatAPI.Destroy;
|
||
begin
|
||
inherited;
|
||
end;
|
||
|
||
function ReplaceDelphiHexCodes(const InputStr: string): string;
|
||
var
|
||
I, Start, HexVal: Integer;
|
||
HexStr: string;
|
||
begin
|
||
Result := '';
|
||
I := 1;
|
||
while I <= Length(InputStr) do
|
||
begin
|
||
if (I <= Length(InputStr) - 5) and (InputStr[I] = '#') and
|
||
(InputStr[I + 1] = '$') then
|
||
begin
|
||
HexStr := Copy(InputStr, I + 2, 4);
|
||
if TryStrToInt('$' + HexStr, HexVal) then
|
||
begin
|
||
Result := Result + WideChar(HexVal);
|
||
Inc(I, 6); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> #$XXXX
|
||
Continue;
|
||
end;
|
||
end;
|
||
Result := Result + InputStr[I];
|
||
Inc(I);
|
||
end;
|
||
end;
|
||
|
||
function ConvertAnsiToUtf8(const AStr: string): string;
|
||
var
|
||
AnsiBytes: TBytes;
|
||
begin
|
||
AnsiBytes := TEncoding.ANSI.GetBytes(AStr);
|
||
Result := TEncoding.UTF8.GetString(AnsiBytes);
|
||
end;
|
||
|
||
function TChatAPI.GetOtvetFromJson(jsonString: string;
|
||
isOllama: boolean = false): string;
|
||
var
|
||
JSON: TJSONObject;
|
||
dataArray: TJSONArray;
|
||
JSONValue: TJSONValue;
|
||
JsonParts: TStringList;
|
||
I: Integer;
|
||
CleanedJson: string;
|
||
JsonObj: TJSONObject;
|
||
ResponseStr, FullResponse: string;
|
||
begin
|
||
|
||
Result := '<27><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!';
|
||
if isOllama then
|
||
begin
|
||
JSON := TJSONObject.ParseJSONValue(jsonString) as TJSONObject;
|
||
try
|
||
if Assigned(JSON) then
|
||
begin
|
||
JSONValue := TJSONObject(JSON);
|
||
if JSONValue.TryGetValue('response', JSONValue) then
|
||
Result := JSONValue.Value;
|
||
end;
|
||
finally
|
||
JSON.Free;
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
JSON := TJSONObject.ParseJSONValue(jsonString) as TJSONObject;
|
||
try
|
||
if Assigned(JSON) then
|
||
begin
|
||
if JSON.TryGetValue('messages', JSONValue) then
|
||
begin
|
||
dataArray := JSONValue as TJSONArray;
|
||
if Assigned(dataArray) and (dataArray.Count > 0) then
|
||
Result := dataArray.Items[0].GetValue<string>('content');
|
||
end;
|
||
end;
|
||
finally
|
||
JSON.Free;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
function TChatAPI.GetGPTRequest(url: string; model: string; q: string;
|
||
isOllama: boolean = false): string;
|
||
var
|
||
params: TStringStream;
|
||
r: string;
|
||
begin
|
||
|
||
q := StringReplace(q, '"', '''', [rfReplaceAll]);
|
||
if isOllama then
|
||
params := TStringStream.Create('{ "model": "' + model + '", "prompt": "' +
|
||
FPrefix + q + '", "stream": false }', TEncoding.UTF8)
|
||
else
|
||
params := TStringStream.Create('{ "model": "' + model +
|
||
'", "messages": [{ "role": "user", "content": "' + FPrefix + q +
|
||
'" }], "stream": false }', CP_UTF8);
|
||
|
||
try
|
||
r := CreateHTTPRequest(url, params, isOllama);
|
||
finally
|
||
// params.Free;
|
||
end;
|
||
Result := r;
|
||
|
||
end;
|
||
|
||
end.
|