DelphiOpenAI

repository·main·Indexed 43 days ago

https://github.com/hemulgm/delphiopenai

An unofficial Delphi implementation of the OpenAI public API. It enables Delphi developers to integrate AI capabilities including Chat, Completions, Image generation (DALL-E), and Function Calling into their applications using the TOpenAI class or TOpenAIComponent.

Tokens
2.8K
Snippets
12
Records
12
Agent score
6%

What's inside DelphiOpenAI

  1. Implement Function Calling

    main

    Function calling allows the model to output JSON arguments for specific functions you define.

    1. Define your functions as a TArray<IChatFunction>.
    2. Pass them to Params.Functions and set Params.FunctionCall(TFunctionCall.Auto).
    3. Check the FinishReason in the response. If it is TFinishReason.FunctionCall, execute your local function using the provided FunctionCall object.
    4. To continue the conversation, send the function result back to the model by adding the assistant's function call and the function's result to the message history.
    // 1. Request function call
    var Chat := OpenAI.Chat.Create(
      procedure(Params: TChatParams)
      begin
        Params.Functions(Funcs); 
        Params.FunctionCall(TFunctionCall.Auto);
        Params.Messages([TChatMessageBuild.User(Text)]);
        Params.MaxTokens(1024);
      end);
    
    // 2. Handle response
    try
      for var Choice in Chat.Choices do
        if Choice.FinishReason = TFinishReason.FunctionCall then
          ProcFunction(Choice.Message.FunctionCall)
        else
          MemoChat.Lines.Add(Choice.Message.Content);
    finally
      Chat.Free;
    end;
    
    // 3. Send result back to continue conversation
    procedure ProcFunction(Func: TChatFunctionCall);
    begin
      var FuncResult := Execute(Func.Name, Func.Arguments);
      var Chat := OpenAI.Chat.Create(
        procedure(Params: TChatParams)
        begin
          Params.Functions(Funcs);
          Params.FunctionCall(TFunctionCall.Auto);
          Params.Messages([
             TChatMessageBuild.User(Text), 
             TChatMessageBuild.NewAsistantFunc(Func.Name, Func.Arguments), 
             TChatMessageBuild.Func(FuncResult, Func.Name)]);
          Params.MaxTokens(1024);
        end);
      // ... handle response ...
    end;
  2. Use the Preparing Mechanism for Third-Party APIs

    main

    If you are using a compatible third-party API (like GigaChat) that requires specific authentication steps or headers before making a request, implement the IAPIPrepare interface and assign it to the Prepare property of your client instance.

    var client := TOpenAI.Create('https://gigachat.devices.sberbank.ru/api/v1', '');
    client.Prepare := TApiPrepareGigaChat.Create(
      '<client_id>',
      '<auth_key>');
    var response := client.Chat.Create(...);
  3. Install DelphiOpenAI

    main

    You can install the library using one of two methods:

    1. GetIt: Install directly from the IDE using the GetIt package manager.
    2. Manual: Add the root folder of the repository to your IDE library path or your project's source path.
    # No specific CLI command, use GetIt in Delphi IDE
  4. Initialize the OpenAI API instance

    main

    To use the library, you must first obtain an API token from your OpenAI organization. The TOpenAI class (or TOpenAIComponent) serves as the entry point. Configuration is handled via anonymous functions to manage the various optional parameters.

    Note: You can use either the component-based approach or the interface-based approach.

    uses OpenAI;
    
    // Component approach
    var OpenAI := TOpenAIComponent.Create(Self, API_TOKEN);
    
    // Interface approach
    var OpenAI: IOpenAI := TOpenAI.Create(API_TOKEN);
  5. Stream Chat Completions

    main

    To receive responses in real-time as they are generated, use Chat.CreateStream. This method accepts two anonymous functions: one for configuring the request and one for handling the incoming stream of data (chunks).

    OpenAI.Chat.CreateStream(
      procedure(Params: TChatParams)
      begin
        Params.Messages([TchatMessageBuild.User(Buf.Text)]);
        Params.MaxTokens(1024);
        Params.Stream;
      end,
      procedure(Chat: TChat; IsDone: Boolean; var Cancel: Boolean)
      begin
        if (not IsDone) and Assigned(Chat) then
          Writeln(Chat.Choices[0].Delta.Content)
        else if IsDone then
          Writeln('DONE!');
        Writeln('-------');
        Sleep(100);
      end);
  6. Generate Images with DALL-E

    main

    Use Image.Create to generate images from a text prompt. You can specify the ResponseFormat (e.g., 'url').

    var Images := OpenAI.Image.Create(
      procedure(Params: TImageCreateParams)
      begin
        Params.Prompt(MemoPrompt.Text);
        Params.ResponseFormat('url');
      end);
    try
      for var Image in Images.Data do
        Image1.Bitmap.LoadFromUrl(Image.Url);
    finally
      Images.Free;
    end;
  7. Create text completions

    main

    The Completion.Create method allows you to generate text completions based on a prompt. Parameters like Prompt and MaxTokens are configured within an anonymous function.

    var Completions := OpenAI.Completion.Create(
      procedure(Params: TCompletionParams)
      begin
        Params.Prompt(MemoPrompt.Text);
        Params.MaxTokens(2048);
      end);
    try
      for var Choice in Completions.Choices do
        MemoChat.Lines.Add(Choice.Index.ToString + ' ' + Choice.Text);
    finally
      Completions.Free;
    end;
  8. List available models

    main

    Use the Model.List() method to retrieve a list of available models from the API. Remember to free the returned object to prevent memory leaks.

    var Models := OpenAI.Model.List();
    try
      for var Model in Models.Data do
        MemoChat.Lines.Add(Model.Id);
    finally
      Models.Free;
    end;
  9. Configure Proxy Settings

    main

    If you need to route your API requests through a proxy, configure the OpenAI.API.ProxySettings property using a TProxySettings instance.

    OpenAI.API.ProxySettings := TProxySettings.Create(
        ProxyHost,
        ProxyPort,
        ProxyUserName,
        ProxyPassword);
  10. Use Chat Vision (Image Input)

    main

    For models supporting vision (e.g., gpt-4-vision-preview), you can pass a combination of text and images in the messages. Use TMessageContent.CreateText and TMessageContent.CreateImage (which accepts a Base64 string) to build the content array.

    var Chat := OpenAI.Chat.Create(
      procedure(Params: TChatParams)
      begin
        Params.Model('gpt-4-vision-preview');
    
        var Content: TArray<TMessageContent>;
        Content := Content + [TMessageContent.CreateText(Text)];
        Content := Content + [TMessageContent.CreateImage(FileToBase64('file path'))];
    
        Params.Messages([TChatMessageBuild.User(Content)]);
        Params.MaxTokens(1024);
      end);
    try
      for var Choice in Chat.Choices do
        MemoChat.Lines.Add(Choice.Message.Content);
    finally
      Chat.Free;
    end;
  11. Use Chat Completions

    main

    The Chat.Create method is used for conversational models (like GPT-3.5/4). You define the conversation history using Messages and set parameters like MaxTokens via an anonymous function.

    var Chat := OpenAI.Chat.Create(
      procedure(Params: TChatParams)
      begin
        Params.Messages([TChatMessageBuild.Create(TMessageRole.User, Text)]);
        Params.MaxTokens(1024);
      end);
    try
      for var Choice in Chat.Choices do
        MemoChat.Lines.Add(Choice.Message.Content);
    finally
      Chat.Free;
    end;
  12. Handle OpenAI Errors and Exceptions

    main

    The library uses a hierarchy of exceptions to handle API errors. You should wrap your requests in try...except blocks to catch specific error types like rate limits or authentication issues.

    Common Exception Types:

    • OpenAIException (Base class)
    • OpenAIExceptionAPI (Wrapper errors)
    • OpenAIExceptionInvalidRequestError
    • OpenAIExceptionRateLimitError
    • OpenAIExceptionAuthenticationError
    • OpenAIExceptionPermissionError
    • OpenAIExceptionTryAgain
    • OpenAIExceptionInvalidResponse (Parse errors)
    try
      var Images := OpenAI.Image.Create(...);
    except
      on E: OpenAIExceptionRateLimitError do
        ShowError('OpenAI Limit Error: ' + E.Message);
      on E: OpenAIException do
        ShowError('OpenAI Error: ' + E.Message);  
    end;