see also:
procedure RunPerplexity(systemprompt, userprompt, model:String; var MemoResponse:TMemo);
var
zURL, response: String;
zJsonStreamIn, zJsonStreamOut: TStringStream;
NetHTTPClient: TNetHTTPClient;
NetHTTPRequest: TNetHTTPRequest;
i:Integer;
begin
zURL := 'https://api.perplexity.ai/chat/completions';
API_Key := 'MyAPIKey';
// Create a JSON object from the string
//perplexity request format: {"model":"mistral-7b-instruct","messages":[{"content":"string","role":"system"}],"max_tokens":0,"temperature":0.2,"top_p":0.9,"top_k":0,"stream":false,"presence_penalty":0,"frequency_penalty":1}
zJsonStreamIn := TStringStream.Create('{"model":"'+model+'","messages":[{"role":"system","content":"' + SystemPrompt + '"},{"role":"user","content":"' + UserPrompt + '"}]}');
try
zJsonStreamOut := TStringStream.Create;
try
NetHTTPClient := TNetHTTPClient.Create(nil);
try
NetHTTPRequest := TNetHTTPRequest.Create(nil);
try
MemoResponse.Lines.Clear;
application.ProcessMessages;
NetHTTPRequest.Client := NetHTTPClient;
NetHTTPRequest.URL := zURL;
NetHTTPRequest.MethodString := 'POST /chat/completions HTTP/1.1';
NetHTTPRequest.CustomHeaders['Authorization'] := 'Bearer ' + API_Key;
// Make the POST request and capture the response
NetHTTPRequest.Post(zURL, zJsonStreamIn, zJsonStreamOut);
// Display the response in a TMemo component:
try
// Extract the LLM response text from the response JSON object stream
response := ExtractContentFromJSON(zJsonStreamOut.DataString);
//now need to format the embedded line breaks:
i := pos(#$A, response); // #$A is = /n
try
MemoResponse.Lines.BeginUpdate; //prevent control visually updating each line add
while i > 0 do //create new lines for line breaks
begin
MemoResponse.Lines.Add(Copy(response,0,i-1));
response := Copy(response,i+1,length(response)-1);
i := pos(#$A, response);
end;
MemoResponse.Lines.Add(response);
//now scroll to top of memo:
MemoResponse.SelStart := 0;
MemoResponse.SelLength := 0;
MemoResponse.Perform(EM_SCROLLCARET, 0, 0);
finally
MemoResponse.Lines.EndUpdate;
end;
Except on E:exception do
begin
MemoResponse.Lines.Add('Error: '+#13+zJsonStreamOut.DataString);
end;
end;
finally
NetHTTPRequest.Free;
end;
finally
NetHTTPClient.Free;
end;
finally
zJsonStreamOut.Free;
end;
finally
zJsonStreamIn.Free;
end;
{
In this code:
- `TNetHTTPClient` is used to manage the HTTP requests.
- `TNetHTTPRequest` is used to configure and execute the specific POST request.
- The `CustomHeaders` property of `TNetHTTPRequest` is used to set the 'Authorization' header.
- The `Post` method of `TNetHTTPRequest` is used to send the request and receive the response.
Make sure to add `System.Net.HttpClient`, `System.Net.URLClient`, `System.Classes`, and `System.SysUtils` to the uses clause of your unit.
}
end;
function ExtractContentFromJSON(const AJSONText: string):String;
var
JSONValue, ChoicesArrayValue, ChoiceValue, MessageValue: TJSONValue;
JSONObj: TJSONObject;
JSONArray: TJSONArray;
begin
// Parse the JSON string into a JSONValue
JSONValue := TJSONObject.ParseJSONValue(AJSONText);
if JSONValue = nil then
raise Exception.Create('Invalid JSON string');
try
// Cast the JSONValue to a JSONObject
JSONObj := JSONValue as TJSONObject;
// Get the 'choices' array from the JSON object
ChoicesArrayValue := JSONObj.Values['choices'];
if ChoicesArrayValue = nil then
raise Exception.Create('Choices array not found');
// Cast the ChoicesArrayValue to a JSONArray
JSONArray := ChoicesArrayValue as TJSONArray;
// Get the first object from the 'choices' array
ChoiceValue := JSONArray.Items[0];
if ChoiceValue = nil then
raise Exception.Create('Choice object not found');
// Cast the ChoiceValue to a JSONObject
JSONObj := ChoiceValue as TJSONObject;
// Get the 'message' object from the choice
MessageValue := JSONObj.Values['message'];
if MessageValue = nil then
raise Exception.Create('Message object not found');
// Cast the MessageValue to a JSONObject
JSONObj := MessageValue as TJSONObject;
// Get the 'content' string from the 'message' object
result := JSONObj.Values['content'].Value;
finally
JSONValue.Free;
end;
end;