Image Link #19
Replies: 4 comments
-
Hey @jarroddavis68 thanks I didn't work on the reply part of it, been very busy lately. Please do let me know if you are working on this. Thanks |
Beta Was this translation helpful? Give feedback.
-
Greetings, As I use Delphi, my initial objective entailed the conversion of the entire project into Delphi. This conversion was necessary to facilitate a more streamlined and convenient workflow for my programming tasks. ✔️ { TBardApiConversationEvent }
TBardApiConversationEvent = procedure(const AConversationTitle, AConversationID, AResponseID, AChoiceID: string) of object;
{ TBardApi }
TBardApi = class
private
FApiKey: string;
FProxy: TProxySettings;
FSession: THttpClient;
FConversationID: string;
FResponseID: string;
FChoiceID: string;
FReqID: Integer;
FSNlM0e: string;
FSessionFilename: string;
FSuccess: Boolean;
FLastConversationID: string;
FConversationTitle: string;
FSetSessionFlag: Boolean;
FOnNewConversation: TBardApiConversationEvent;
FOnSetConversation: TBardApiConversationEvent;
FImages: TBardApiImageList;
FCodes: TBardApiCodeList;
procedure SetApiKey(const AValue: string);
function GetSNlM0e: string;
procedure DoNewConversation;
procedure DoSetConversation;
public
property ApiKey: string read FApiKey write SetApiKey;
property ConversationID: string read FConversationID;
property ResponseID: string read FResponseID;
property ChoiceID: string read FChoiceID;
property Success: Boolean read FSuccess;
property Images: TApiImageList read FImages;
property Codes: TApiCodeList read FCodes;
property OnNewConversation: TApiConversationEvent read FOnNewConversation write FOnNewConversation;
property OnSetConversation: TApiConversationEvent read FOnSetConversation write FOnSetConversation;
constructor Create; virtual;
destructor Destroy; override;
procedure SetProxy(const aHost: string; aPort: Integer; const aUserName: string = ''; const aPassword: string = ''; const AScheme: string = '');
function GetAnswerAsJson(const AInputText: string): string;
function GetAnswer(const AInputText: string): string;
function SaveConversation(const aFilename: string=''): Boolean;
function LoadConversation(const aFilename: string=''): Boolean;
procedure ClearConversation;
procedure SetConversation(const AConversationID, AResponseID, AChoiceID, AConversationTitle: string);
end; Next, extract the image links. ✔️ type
{ TBardApiImageItem }
TBardApiImageItem = record
ImageUrl: string;
RefUrl: string;
end;
{ TBardApiImageList }
TBardApiImageList = TArray<TBardApiImageItem>;
function GetImages(const AJsonArray: TJsonArray; out AImageList: TBardApiImageList): Boolean;
var
LJson: TJsonArray;
LText: string;
I: Integer;
LList: TBardApiImageList;
function CleanImageUrl(const URL: string): string;
begin
Result := URL;
Delete(Result, URL.IndexOf('?'), Length(URL));
end;
begin
Result := False;
LList := nil;
LText := AJsonArray.P['[4][0][4]'].ToString;
if LText = 'null' then Exit;
LJson := TJSONArray.ParseJSONValue(LText) as TJSONArray;
try
SetLength(LList, LJson.Count);
for I := 0 to LJson.Count-1 do
begin
LList[I].ImageUrl := CleanImageUrl(LJson.A[I].P['[0][0]'].A[0].Value); // image link
LList[I].RefUrl := LJson.A[I].P['[1][0]'].A[0].Value; // url ref link
end;
finally
LJson.Free;
end;
AImageList := LList;
if Assigned(LList) then
Result := True;
end; Then, I figured I could get the code fragments out too. It will even grab the language label if found ✔️ type
{ TBardApiCodeItem }
TBardApiCodeItem = record
Language: string;
Code: string;
end;
function GetCode(const AText: string; out ACodeList: TArray<TBardApiCodeItem>): Boolean;
const
CodeMarker = '```';
var
StartIndex, EndIndex: Integer;
StartPos, EndPos, CodeBlockCount: Integer;
CodeItem: TBardApiCodeItem;
CodeBlock: string;
begin
Result := False;
SetLength(ACodeList, 0);
// Find the first starting code marker
StartIndex := Pos(CodeMarker, AText);
if StartIndex = 0 then
Exit;
CodeBlockCount := 0;
StartPos := StartIndex + Length(CodeMarker);
repeat
// Find the ending code marker
EndIndex := PosEx(CodeMarker, AText, StartPos);
if EndIndex = 0 then
Break;
// Extract the code block
CodeBlock := Trim(Copy(AText, StartPos, EndIndex - StartPos));
// Determine if language is present
if (StartPos < Length(AText)) and (AText[StartPos] <> #10) then
begin
// Extract the language
EndPos := Pos(#10, CodeBlock);
if EndPos > 0 then
begin
CodeItem.Language := Trim(Copy(CodeBlock, 1, EndPos - 1));
CodeBlock := Trim(Copy(CodeBlock, EndPos + 1, Length(CodeBlock) - EndPos));
end
else
begin
CodeItem.Language := ''; // No language specified
end;
end
else
begin
CodeItem.Language := ''; // No language specified
end;
Inc(CodeBlockCount);
SetLength(ACodeList, CodeBlockCount);
CodeItem.Code := CodeBlock;
ACodeList[CodeBlockCount - 1] := ApiCodeItem;
// Find the next starting code marker
StartIndex := PosEx(CodeMarker, AText, EndIndex + Length(CodeMarker));
if StartIndex = 0 then
Break;
StartPos := StartIndex + Length(CodeMarker);
until False;
Result := CodeBlockCount > 0;
end; In summary, the conversion process took a few days to complete and ensures full functionality. The images will be stored within the [4][0][4] array section, while the code blocks can be extracted by parsing the text enclosed within "```" in the [0][0] array. Thank you again for your work. Here is a video of me having a contextual conversation with Bard from Delphi: AskBard.Contexual.Conversation.mp4 |
Beta Was this translation helpful? Give feedback.
-
Looks great, good job on image extraction and codemarkers. I've never used Delphi before. Are you gonna open source it or is it for just personal use? |
Beta Was this translation helpful? Give feedback.
-
Thanks. Personal for now. Trying to see if the method continues to work or will they change things and suddenly stop working, sigh. Hope not, because it's been a blast working with Bard. We'll see. |
Beta Was this translation helpful? Give feedback.
-
Hi, this is wonderful. I've been having fun with it, many thanks.
How can the image links be parsed out and returned also?
Thanks
Beta Was this translation helpful? Give feedback.
All reactions