Test-Apps für Gemini Api und Blockly
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
unit MainUnit;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
|
||||
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
|
||||
System.Net.HttpClient, System.Net.HttpClientComponent, System.JSON, System.Net.Mime, Vcl.AppEvnts,
|
||||
Myc.Futures, System.Generics.Collections, ApiKey;
|
||||
|
||||
type
|
||||
// NEU: Ein Record, um einen einzelnen Redebeitrag in der Konversation zu speichern
|
||||
TChatTurn = record
|
||||
Role: string; // 'user' oder 'model'
|
||||
Text: string;
|
||||
end;
|
||||
|
||||
TForm1 = class(TForm)
|
||||
AnswerMemo: TMemo;
|
||||
ExecButton: TButton;
|
||||
ApplicationEvents: TApplicationEvents;
|
||||
PromptMemo: TMemo;
|
||||
procedure ExecButtonClick(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
procedure ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
|
||||
private
|
||||
FHttpClient: TNetHTTPClient;
|
||||
FMyApiKey: string;
|
||||
FAnswer: TFuture<String>;
|
||||
FChatHistory: TList<TChatTurn>; // NEU: Liste für den Konversationsverlauf
|
||||
procedure SendPrompt;
|
||||
public
|
||||
{ Public declarations }
|
||||
end;
|
||||
|
||||
var
|
||||
Form1: TForm1;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
const
|
||||
GEMINI_MODEL = 'gemini-2.5-flash-preview-05-20';
|
||||
API_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta/models/';
|
||||
|
||||
{ TForm1 }
|
||||
|
||||
procedure TForm1.FormCreate(Sender: TObject);
|
||||
begin
|
||||
FHttpClient := TNetHTTPClient.Create(nil);
|
||||
FMyApiKey := ApiKey.Value; // Eingelesen aus ApiKey.pas
|
||||
|
||||
// NEU: Initialisiert die Liste für den Konversationsverlauf
|
||||
FChatHistory := TList<TChatTurn>.Create;
|
||||
|
||||
// Optional: Füge hier einen initialen System-Prompt hinzu, wenn gewünscht.
|
||||
// Dieser wird dann immer als erste Nachricht mitgesendet.
|
||||
// var initialTurn: TChatTurn;
|
||||
// initialTurn.Role := 'user';
|
||||
// initialTurn.Text := 'Du bist ein Delphi-Entwicklungs-Assistent...';
|
||||
// FChatHistory.Add(initialTurn);
|
||||
end;
|
||||
|
||||
procedure TForm1.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
FAnswer.WaitFor;
|
||||
FHttpClient.Free;
|
||||
FChatHistory.Free; // NEU: Gibt die Verlaufsliste frei
|
||||
end;
|
||||
|
||||
procedure TForm1.ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
|
||||
var
|
||||
answerText: string;
|
||||
modelTurn: TChatTurn;
|
||||
begin
|
||||
if FAnswer.Done.IsSet and not ExecButton.Enabled then
|
||||
begin
|
||||
answerText := FAnswer.Value;
|
||||
AnswerMemo.Lines.Add(answerText);
|
||||
|
||||
// NEU: Füge die Antwort des Modells zum Verlauf hinzu
|
||||
if not answerText.StartsWith('Fehler!') then
|
||||
begin
|
||||
modelTurn.Role := 'model';
|
||||
modelTurn.Text := answerText;
|
||||
FChatHistory.Add(modelTurn);
|
||||
end;
|
||||
|
||||
FAnswer := FAnswer.Null;
|
||||
ExecButton.Enabled := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TForm1.ExecButtonClick(Sender: TObject);
|
||||
begin
|
||||
SendPrompt;
|
||||
end;
|
||||
|
||||
procedure TForm1.SendPrompt;
|
||||
var
|
||||
userPrompt: string;
|
||||
userTurn: TChatTurn;
|
||||
begin
|
||||
if not ExecButton.Enabled then
|
||||
Exit;
|
||||
|
||||
userPrompt := PromptMemo.Lines.Text;
|
||||
if userPrompt.IsEmpty then
|
||||
begin
|
||||
ShowMessage('Bitte geben Sie einen Prompt ein.');
|
||||
Exit;
|
||||
end;
|
||||
|
||||
// NEU: Füge die aktuelle Benutzereingabe zum Verlauf hinzu
|
||||
userTurn.Role := 'user';
|
||||
userTurn.Text := userPrompt;
|
||||
FChatHistory.Add(userTurn);
|
||||
|
||||
// NEU: Leere das Eingabefeld für die nächste Nachricht
|
||||
PromptMemo.Clear;
|
||||
|
||||
ExecButton.Enabled := False;
|
||||
AnswerMemo.Lines.Add('');
|
||||
AnswerMemo.Lines.Add('--- [USER] ---');
|
||||
AnswerMemo.Lines.Add(userPrompt);
|
||||
AnswerMemo.Lines.Add('... sende Anfrage an Gemini ...');
|
||||
|
||||
FAnswer := TFuture<string>.Construct(
|
||||
function: string
|
||||
var
|
||||
jsonRequest: TJSONObject;
|
||||
jsonContents: TJSONArray;
|
||||
requestBody: TStringStream;
|
||||
response: IHTTPResponse;
|
||||
responseJson: TJSONValue;
|
||||
apiUrl: string;
|
||||
turn: TChatTurn;
|
||||
begin
|
||||
try
|
||||
// 1. JSON-Body aus dem gesamten Konversationsverlauf erstellen
|
||||
jsonRequest := TJSONObject.Create;
|
||||
try
|
||||
jsonContents := TJSONArray.Create;
|
||||
jsonRequest.AddPair('contents', jsonContents);
|
||||
|
||||
// NEU: Iteriere durch den Verlauf und baue die JSON-Struktur auf
|
||||
for turn in FChatHistory do
|
||||
begin
|
||||
var jsonTurn := TJSONObject.Create;
|
||||
jsonTurn.AddPair('role', TJSONString.Create(turn.Role));
|
||||
|
||||
var jsonParts := TJSONArray.Create;
|
||||
jsonTurn.AddPair('parts', jsonParts);
|
||||
|
||||
var jsonText := TJSONObject.Create;
|
||||
jsonText.AddPair('text', TJSONString.Create(turn.Text));
|
||||
jsonParts.Add(jsonText);
|
||||
|
||||
jsonContents.Add(jsonTurn);
|
||||
end;
|
||||
|
||||
// 2. Request senden
|
||||
requestBody := TStringStream.Create(jsonRequest.ToString, TEncoding.UTF8);
|
||||
try
|
||||
apiUrl := API_BASE_URL + GEMINI_MODEL + ':generateContent?key=' + FMyApiKey;
|
||||
response := FHttpClient.Post(apiUrl, requestBody, nil);
|
||||
|
||||
// 3. Antwort verarbeiten
|
||||
if (response.StatusCode = 200) then
|
||||
begin
|
||||
responseJson := TJSONObject.ParseJSONValue(response.ContentAsString(TEncoding.UTF8));
|
||||
try
|
||||
Result := responseJson.GetValue<TJSONArray>('candidates')
|
||||
.Items[0].GetValue<TJSONObject>('content')
|
||||
.GetValue<TJSONArray>('parts')
|
||||
.Items[0].GetValue<string>('text');
|
||||
finally
|
||||
responseJson.Free;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Result := 'Fehler! Status: ' + response.StatusCode.ToString + ' - ' + response.StatusText +
|
||||
sLineBreak + response.ContentAsString;
|
||||
end;
|
||||
finally
|
||||
requestBody.Free;
|
||||
end;
|
||||
finally
|
||||
jsonRequest.Free;
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
Result := '--- FEHLER IM TASK ---' + sLineBreak + E.Message;
|
||||
end;
|
||||
end;
|
||||
end);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user