Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   consultar a API ChatGPT con REST en C++ Builder Rad Studio 12 (https://www.clubdelphi.com/foros/showthread.php?t=96631)

navbuoy 06-03-2024 12:01:47

consultar a API ChatGPT con REST en C++ Builder Rad Studio 12
 
Buenos dias a todos

me gustaria si alguien me pudiese ayudar en este asunto que me trae de cabeza ya

Estoy intentando hacer una consulta a CHATGPT mediante los componentes RESTClient RESTRequest y RESTResponse de C++ Builder Rad Studio 12
tengo esta funcion y aunque lo he intentado de multiples maneras, siempre me tira este error que lo que deduzco es que no logra autentificarse bien en el API de entrada

Código:

{"error":{"message":"You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY), or as the password field (with blank username) if you're accessing the API from your browser and are prompted for a username and password. You can obtain an API key from https:\/\/platform.openai.com\/account\/api-keys.","type":"invalid_request_error","param":null,"code":null}}
y el codigo fuente en C++ Builder que estoy usando con esos componentes REST es este:
he de aclarar que el codigo compila sin errores ninguno y funciona y en la ejecucion es cuando falla al intentar la Authorization

Código:

// Set REST Client

 Memo1->Clear();

 RESTClient1->BaseURL = "https://api.openai.com/v1/chat/completions";

RESTClient1->Params->AddHeader( "content", "Content-Type: application/json");
  RESTClient1->Params->AddHeader( "Authorization",  "Authorization: Bearer AQUI_PONGO_EL_API_KEY_QUE_TENGO_CREADO");


 // Set REST Request
 RESTRequest1->Method  = TRESTRequestMethod::rmPOST;
 RESTRequest1->Response = RESTResponse1;
 RESTRequest1->Response->ContentType = "application/json";
 RESTRequest1->Response->ContentEncoding="UTF-8";

 RESTRequest1->ClearBody();
 RESTRequest1->Body->Add("{ \"prompt\": \"it was a rainy day for\",  \"max_tokens\": 150 }", Rest::Types::TRESTContentType::ctNotLeadChar);
 RESTRequest1->Execute();

 // Get REST Response
 TJSONValue *jValue = RESTResponse1->JSONValue;

 // Print REST Response
 Memo1->Lines->Add(jValue->ToString());

he probado incluso a meter los Params de RESTClient de forma manual desde el IDE y en la propiedad Kind he probado con varios tipos "pkCOOKIE, pkHTTPSHEADERS, pkGetorPost, pkQUERY etc" y no parece ir ninguna aunque creo que la correcta es pkHTTPSHEADERS

si alguien me pudiese ayudar lo agradeceria enormemente

Neftali [Germán.Estévez] 06-03-2024 12:19:03

¿Has probado con el RESTDebugger o con PostMan/Insomnia?

Neftali [Germán.Estévez] 06-03-2024 12:50:18

Prueba a añadir el parámetro de esta manera:

Código Delphi [-]
RESTRequest1.AddParameter('Authorization','Bearer ' + 'MY-API-KAY',TRESTRequestParameterKind.pkHTTPHEADER,[poDoNotEncode]);

navbuoy 06-03-2024 13:03:56

pues no Neftali, no tengo esos programas, intente bajarme el REST Debugger pero estos tios de Embarcadero tienen un formulario enorme pa esa jodida descarga y la verdad que ni lo rellene

tampoco funciona el codigo ese, lo acepta y compila asi como lo he adaptado, no lo he metido como me has puesto porque el parametro PoDoNotEncode no lo acepta
lo he adaptado a C++ builder de esta manera pero me sigue dando el error de "Unauthorized" diciendo que no le estoy dando la API KEY

Código:


  RESTRequest1->AddParameter("Authorization","Authorization: Bearer API_KEY", pkHTTPHEADER);
  RESTRequest1->AddParameter( "Content-Type", "application/json");

he probado tambien asi:

Código:


  RESTRequest1->AddParameter("Authorization","Bearer API_KEY", pkHTTPHEADER);
  RESTRequest1->AddParameter( "Content-Type", "application/json");

los tios de TMS componentes tienen un componente para eso segun este codigo, se llama TMSCloudBase o algo asi pero no se donde esta, tengo los UI Pack pero no lo veo que lo tenga en la paleta

el codigo que ellos dan para lo de CHAT GPT con su componente es este:

Código:

uses 
  System.JSON, VCL.TMSFNCCloudBase; 
 
function AskChatGPT(AQuestion: string): string; 
var 
  LCb: TTMSFNCCloudBase; 
  LPostdata: string; 
  LJsonValue: TJsonValue; 
  LJsonArray: TJsonArray; 
  LJSonString: TJsonString; 
begin 
  Result := ''; 
 
  LPostData := '{' + 
    '"model": "text-davinci-003",'+ 
    '"prompt": "' + AQuestion + '",'+ 
    '"max_tokens": 2048,'+ 
    '"temperature": 0'+ 
    '}'; 
 
  // create instance of TMS FNC Cloud Base class 
  LCb := TTMSFNCCloudBase.Create; 
 
  try 
    // Use JSON for the REST API calls and set API KEY via Authorization header 
    LCb.Request.AddHeader('Authorization','Bearer ' + CHATGPT_APIKEY); 
    LCb.Request.AddHeader('Content-Type','application/json'); 
 
    // Select HTTPS POST method, set POST data and specify endpoint URL 
    LCb.Request.Method := rmPOST; 
    LCb.Request.PostData := LPostData; 
    LCb.Request.Host := 'http__s://api.openai.com'; 
    LCb.Request.Path := 'v1/completions'; 
 
    // Execute the HTTPS POST request synchronously (last param Async = false) 
    LCb.ExecuteRequest(nil,nil,false); 
 
    // Process returned JSON when request was successful 
    if Lcb.RequestResult.Success then 
    begin 
      LJsonValue := TJSonObject.ParseJSONValue(Lcb.RequestResult.ResultString); 
      LJsonValue := LJsonValue.GetValue<TJSonValue>('choices'); 
      if LJsonValue is TJSonArray then 
      begin 
        LJSonArray := LJsonValue as TJSonArray; 
        LJSonString := LJSonArray.Items[0].GetValue<TJSONString>('text'); 
        Result := LJSonString.Value; 
      end 
      else 
    end 
    else 
      raise Exception.Create('HTTP response code: ' + LCb.RequestResult.ResponseCode.ToString); 
  finally 
    LCb.Free; 
  end; 
end;


Neftali [Germán.Estévez] 06-03-2024 13:17:06

Cita:

Empezado por navbuoy (Mensaje 554776)
pues no Neftali, no tengo esos programas, intente bajarme el REST Debugger pero estos tios de Embarcadero tienen un formulario enorme pa esa jodida descarga y la verdad que ni lo rellene

Sólo como información, el RESTDebugger viene con Delphi (en el directorio bin), al menos con la versión que yo tengo.
Revisalo, tal vez con las básicas o la community no viene, esto ya no lo puedo asegurar.

A mi, esta me funciona en RADStudio 12:
Código Delphi [-]
RESTRequest1.AddParameter('Authorization','Bearer ' + 'MY-API-KAY',TRESTRequestParameterKind.pkHTTPHEADER,[poDoNotEncode]);

Lo que pasa que en mi caso, me dice que ya he excedido la cuota, pero creo que si llega a ese punto es que ya ha pasado la autentificación.

navbuoy 06-03-2024 13:20:11

podrias darmela en formato C++ Builder?? yo es que pascal no lo controlo muy bien, se sustituir los . por -> y las comillas simples por dobles pero no mucho mas
y creo que si le meto los 4 parametros el de DoNotEncode dice que no corresponde con la estructura de la funcion

me molesta que no funcione porque este codigo PHP lo tengo en mi hosting y funciona perfecto con mi api key y tal para consultar CHATGPT desde la pagina web
pero aunque miro que lo envio con el Method POST y como lo compone el codigo este de PHP, no se lo traga no se porque

mira, el codigo php es este y te aseguro que funciona perfecto ya luego en la app C++ Builder mirare como componer el prompt bien pero la cuestion es que no pasa el Login del Authorization

Código:

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Verificar si se recibió la pregunta del chat
    if (isset($_POST['mensaje'])) {
        // Obtener la pregunta del chat
        $pregunta = $_POST['mensaje'];

        $api_key = "AQUI PONGO MI API KEY SOLAMENTE sk-taltal";

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'http__s://api.openai.com/v1/chat/completions');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $api_key,
        ]);

        $data = [
            'model' => 'gpt-3.5-turbo',
            'messages' => [],
        ];

        $data['messages'][] = ['role' => 'system', 'content' => 'Actua como un experto '];
        $data['messages'][] = ['role' => 'user', 'content' => $pregunta];

        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));


        $response = curl_exec($ch);
        $respuesta = '';
        $decoded_response = json_decode($response, true);

        if (isset($decoded_response['choices'][0]['message']['content'])) {
            $respuesta = $decoded_response['choices'][0]['message']['content'];
        }

        curl_close($ch);

        echo $respuesta;
    }
}

Neftali: una cosa que podria servirme es si con esa funcion solo hago un echo en PHP para mostrar la respuesta, pudiese capturar esa respuesta por ejemplo con un componente NetHTTPClient..... tu sabrias darme algo de codigo para capturar esa respuesta haciendo un GET desde NetHTTPClient?? porque eso podria valerme de modo chapucero claro

Neftali [Germán.Estévez] 06-03-2024 13:26:10

Yo estoy igual que tú, pero al revés.
de todas formas la función con los 4 parámetros rtambién está en C++ Builder:
http://docwiki.embarcadero.com/Libra...t.AddParameter

Debería ser algo así:
Código Delphi [-]

RESTRequest1->AddParameter("Authorization","Bearer  " + "API_KEY", pkHTTPHEADER, [poDoNotEncode]);
// o esta, dependiendo de cual te acepte 
// OJO que al final de la palabra bearer hay un espacio, para separarlo del valor de la API_KEY
RESTRequest1->AddParameter("Authorization","Bearer  " + "API_KEY",TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);

chenech 06-03-2024 15:00:35

Yo uso este actualmente en C++ Builder 11 y funciona bien:
https://www.clubdelphi.com/foros/sho...hlight=chatgpt

navbuoy 06-03-2024 17:18:47

Hola Casimiro, pues mira, compilar compila sin errores y se ejecuta pero en esta linea:

Código:

TJSONArray *a = (TJSONArray*) o->Get("choices")->JsonValue;
me casca con un feo error de patinazo de memoria:

Código:

First chance exception at $00A4B668. Exception class $C0000005 with message 'access violation at 0x00a4b668: read of address 0x0000000c'. Process Promto.exe (12412)
sabrias como arreglarlo?

navbuoy 06-03-2024 18:14:43

bueno he estado toqueteando y añadiendo unas cosas y de momento me funciona aunque lo que no tengo terminado es el formateado de la respuesta (ya que le he puesto un RETURN antes de llegar a la parte esa del final ..... pero le he preguntado "que es un terabyte" y me ha dado la respuesta asi:

Código:

{
  "id": "chatcmpl-8zp2KRCrbycZgIpcsr5D6xgbDp3y1",
  "object": "chat.completion",
  "created": 1709744884,
  "model": "gpt-3.5-turbo-0125",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Un terabyte es una unidad de almacenamiento de información equivalente a 1 billón de bytes, o 1,000 gigabytes. Es una medida de capacidad de almacenamiento de datos utilizada comúnmente en la informática y la tecnologÃ*a de la información. Un terabyte es una cantidad muy grande de almacenamiento y es comúnmente utilizado para almacenar grandes cantidades de datos como archivos multimedia, bases de datos o copias de seguridad."
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 12,
    "completion_tokens": 94,
    "total_tokens": 106
  },
  "system_fingerprint": "fp_b9d4cef803"
}


Asi que aqui os dejo el codigo que me funciona en Rad Studio C++ Builder 12 Architect por si os pudiese servir

Código:

try
{
  TNetHeaders AuthHeader;
  AuthHeader.Length = 2;
  AuthHeader[0] = TNameValuePair("Authorization", "Bearer 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");
  AuthHeader[1] = TNameValuePair("Content-Type", "application/json");
  TMemoryStream *salida = new TMemoryStream();
  TMemoryStream *entrada = new TMemoryStream();
  TMemo *memo = new TMemo(Form6);
  memo->Parent = Form6;
  memo->Visible = false;
  memo->Lines->Clear();
  String  ASAux = EPregunta->Text;
  char dest[200];
  UnicodeToUtf8(dest, 200, EPregunta->Text.c_str(), 200);
  ASAux = dest;
 
  TJSONObject *inputObject = new TJSONObject();
                inputObject->AddPair("model", "gpt-3.5-turbo");

  // Construir el array de mensajes
                TJSONArray *messagesArray = new TJSONArray();

  TJSONObject *messageObject = new TJSONObject();
                        messageObject->AddPair("role", "system");
                        messageObject->AddPair("content", "You are a helpful assistant.");
                        messageObject->AddPair("role", "user");
                        messageObject->AddPair("content", "que es un terabyte");

  messagesArray->Add(messageObject);

  // Agregar el array de mensajes al objeto de entrada
                inputObject->AddPair("messages", messagesArray);

  memo->Lines->Add(inputObject->ToString());

  memo->Lines->SaveToStream(salida);
  salida->Position = soFromBeginning;
  NetHTTPC1->Post("h_t_t_p_s://api.openai.com/v1/chat/completions", salida, entrada, AuthHeader);
  memo->Lines->Clear();
  memo->Lines->LoadFromStream(entrada);
 
  delete salida;
  delete entrada;

  TJSONObject *o = (TJSONObject*) TJSONObject::ParseJSONValue(TEncoding::ANSI->GetBytes(memo->Lines->Text), 0);
  Memo1->Lines->Add(memo->Lines->Text);
  return;


  //Tened en cuenta que esta es la parte que he "cropeado" y aun no he ajustado para que salga pre-formateado
  TJSONArray *a = (TJSONArray*) o->GetValue("choices");
  TJSONObject *book = (TJSONObject*) a->Items[0];
  Memo1->Lines->Clear();
  ASAux = book->Pairs[0]->JsonValue->ToString();
  ASAux = StringReplace(ASAux, "\\n\\n", sLineBreak, TReplaceFlags() << rfReplaceAll);
  ASAux = StringReplace(ASAux, "\\n", sLineBreak, TReplaceFlags() << rfReplaceAll);
  Memo1->Lines->Add(ASAux);
  o->Free();
  memo->Free();
}
catch (...)
{
  ShowMessage("Error accediendo a los servicios IA de HFocused");
}

Muchas Gracias por vuestra ayuda chicos, le decia yo a un amigo mio ayer .... voy a pedirles ayuda a los de Club Delphi que son unos cracks ....
porque llevamos intentando integrar esto de las preguntas a GPTChat en la app varios dias y pffff..... no teneis ni idea del tute de probar mil cosas que llevo

navbuoy 07-03-2024 20:17:25

Codigo Final de la funcion Consulta a ChatGPT
 
Os dejo aqui el codigo como lo he dejado al final en Rad Studio 12

tened en cuenta a la hora de adaptarlo para vuestra app, que uso un EditBox llamado EPregunta, un Memo llamado Memo1 (para las respuestas) y mi formulario es el Form6
y tened en cuenta que aunque yo uso AddText en el memo, es porque en realidad es un TMSRichEditor ... en un Memo standard seria Memo->Lines->Add("el texto que sea");

y el uso de la funcion Utf8ToAnsi al enviar el query....es debido a que si no, el ChatGPT como le pongas una Ñ o algun caracter especial que no entienda bien, cascara con un error en el envio de la consulta
y de la misma manera el uso de Utf8ToAnsi en la respuesta, hace que convierta los caracteres especiales a nuestra codepage local, (acentos, eñes etc)

Código:


/// Recordad los include de cabecera
////////////////////////////////////////////////////
#include <vcl.h>
#include <System.Classes.hpp>
#include <System.Net.URLClient.hpp>
#include <windows.h>
#include <System.JSON.hpp>
#include <System.SysUtils.hpp>

/// Y esto en el onclick del boton que por ejemplo usemos para enviar la consulta
//////////////////////////////////////////////////////////////////////////////////////////////////////

try
{
  TNetHeaders AuthHeader;
  AuthHeader.Length = 2;
  AuthHeader[0] = TNameValuePair("Authorization", "Bearer TU_API_KEY");
  AuthHeader[1] = TNameValuePair("Content-Type", "application/json");
  TMemoryStream *salida = new TMemoryStream();
  TMemoryStream *entrada = new TMemoryStream();
  TMemo *memo = new TMemo(Form6);
  memo->Parent = Form6;
  memo->Visible = false;
  memo->Lines->Clear();
  String  ASAux = EPregunta->Text;
  char dest[200];
  UnicodeToUtf8(dest, 200, EPregunta->Text.c_str(), 200);
  ASAux = dest;

  TJSONObject *inputObject = new TJSONObject();
                inputObject->AddPair("model", "gpt-3.5-turbo");

  // Construir el array de mensajes
                TJSONArray *messagesArray = new TJSONArray();

  TJSONObject *messageObject = new TJSONObject();
                        messageObject->AddPair("role", "system");
                        messageObject->AddPair("content", "You are a helpful assistant.");
                        messageObject->AddPair("role", "user");
                        messageObject->AddPair("content", Utf8ToAnsi(EPregunta->Text));

  messagesArray->Add(messageObject);

  // Agregar el array de mensajes al objeto de entrada
                inputObject->AddPair("messages", messagesArray);

  memo->Lines->Add(inputObject->ToString());

  memo->Lines->SaveToStream(salida);
  salida->Position = soFromBeginning;
  NetHTTPC1->Post("h_t_t_p_s://api.openai.com/v1/chat/completions", salida, entrada, AuthHeader);
  memo->Lines->Clear();
  memo->Lines->LoadFromStream(entrada);
  delete salida;
  delete entrada;
  TJSONObject *o = (TJSONObject*) TJSONObject::ParseJSONValue(TEncoding::ANSI->GetBytes(memo->Lines->Text), 0);


 //Como soy muy ceporro y no me aclaro de como extraer el content de los Json, lo he apañado asi :D
 //////////////////////////////////////////////////////////////////////////////////////////////////
  AnsiString A,B, respuesta;
  int i;
  A=memo->Lines->Text;
        i=A.AnsiPos("content");
        B=A.SubString(i+10,A.Length());

        i=B.AnsiPos("}");
        respuesta = B.SubString(0, i-1);

  respuesta = StringReplace(respuesta, "\\n\\n", sLineBreak, TReplaceFlags() << rfReplaceAll);
  respuesta = StringReplace(respuesta, "\\n", sLineBreak, TReplaceFlags() << rfReplaceAll);

  ////////////////////////////////////////////////////////////////////////////////////////////////

  Memo1->AddText("\r\n \r\n");
  Memo1->AddText(Utf8ToAnsi(respuesta));

        return;

  o->Free();
  memo->Free();
}
catch (...)
{
  ShowMessage("Error accediendo a los servicios IA de HFocused");
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


navbuoy 08-03-2024 23:55:34

si alguien pudiese ayudarme con el tema de extraer el content de la respuesta del ChatGPT del JSON, porque yo es que esos malditos JSON me vuelven medio loco

y ya de paso, el otro problema es el siguiente, el RichEdit donde lo muestro resulta que los caracteres de \r y \n no los reconoce como saltos de linea etc y me veo en la texitura de tener que analizar la cadena para cuando encuentre esos caracteres ejecute la funcion de linebreak desde el codigo (que se cual es) pero ando un poco espesito a la hora de codificar esa funcion

navbuoy 13-03-2024 23:23:00

formateando la respuesta de ChatGPT en nuestra funcion de consulta a ChatGPT
 
Me las he ingeniado para crear la funcion que formatea los saltos de linea y las comillas en la respuesta de ChatGPT

Tened en cuenta que esto afecta a cuando nos da codigo fuente de ejemplo porque podria ser que el codigo ponga algo asi como "printf("numero %d\n <---esto!!!", variable);"
y en el mensaje que nos muestra en el RichEdit haria el salto de linea (esta es una particularidad que estoy mirando como hacer para discernir cuando ChatGPT me envia codigo fuente de ejemplo y de esa manera diferenciarlo

pero bueno, os paso el codigo de como ha quedado la funcion que tengo para lo de Consulta a ChatGPT
recordad que el Memo1 es en realidad un TMSRichEdit y el "c+1" que hace con la cadena cuando empieza el bucle, es porque si empezamos por 0 en la posicion del AnsiString da "Range Error"

Código:

try
{
  TNetHeaders AuthHeader;
  AuthHeader.Length = 2;
  AuthHeader[0] = TNameValuePair("Authorization", "Bearer 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");
  AuthHeader[1] = TNameValuePair("Content-Type", "application/json");
  TMemoryStream *salida = new TMemoryStream();
  TMemoryStream *entrada = new TMemoryStream();
  TMemo *memo = new TMemo(Form6);
  memo->Parent = Form6;
  memo->Visible = false;
  memo->Lines->Clear();
  String  ASAux = EPregunta->Text;
  char dest[200];
  UnicodeToUtf8(dest, 200, EPregunta->Text.c_str(), 200);
  ASAux = dest;
  //memo->Lines->Add("{\"model\": \"gpt-3.5-turbo\", \"Messages\": \"role\": \"system\" \"content\": \"Actua como un Experto\" \"role\": \"user\" \"content\": \"" + ASAux + "\", \"temperature\": 0, \"max_tokens\": 1000}");
  TJSONObject *inputObject = new TJSONObject();
                inputObject->AddPair("model", "gpt-3.5-turbo");

  // Construir el array de mensajes
                TJSONArray *messagesArray = new TJSONArray();

  TJSONObject *messageObject = new TJSONObject();
                        messageObject->AddPair("role", "system");
                        messageObject->AddPair("content", "You are a helpful assistant.");
                        messageObject->AddPair("role", "user");
                        messageObject->AddPair("content", Utf8ToAnsi(EPregunta->Text));

  messagesArray->Add(messageObject);

  // Agregar el array de mensajes al objeto de entrada
                inputObject->AddPair("messages", messagesArray);

  memo->Lines->Add(inputObject->ToString());

  memo->Lines->SaveToStream(salida);
  salida->Position = soFromBeginning;
  NetHTTPC1->Post("https://api.openai.com/v1/chat/completions", salida, entrada, AuthHeader);
  memo->Lines->Clear();
  memo->Lines->LoadFromStream(entrada);
  delete salida;
  delete entrada;
  TJSONObject *o = (TJSONObject*) TJSONObject::ParseJSONValue(TEncoding::ANSI->GetBytes(memo->Lines->Text), 0);


 //Como soy muy ceporro y no me aclaro de como extraer el content de los Json, lo he apañado asi :D
 //////////////////////////////////////////////////////////////////////////////////////////////////
  AnsiString A,B, respuesta;
  int i, f;
  A=memo->Lines->Text;
        i=A.AnsiPos("content");
        B=A.SubString(i+10,A.Length());

        i=B.AnsiPos("}");
        respuesta = B.SubString(0, i-3);

  //////////////////////////////////////////////////////////////////////////////////////////////////////////


//////// Y aqui formateamos la respuesta para hacer que los saltos de linea salgan en el TMSRichEdit
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  AnsiString respuesta_formateada = " - ";

  Memo1->AddLineBreak();  Memo1->AddLineBreak();

  Memo1->AddImage("gpt_icon.png" , 40, 40);  //Esto es un iconcito de chatGPT para darle mejor aspecto a lo que imprime



///// Imprimimos la pregunta para saber a que se refiere la respuesta
/////////////////////////////////////////////////////////////////////////////////////////////////////////////

  Memo1->AddText(Utf8ToAnsi(EPregunta->Text), clGreen, clBlack);
  Memo1->AddLineBreak();  Memo1->AddLineBreak();

  for(int c=0; c < respuesta.Length(); ++c)
  {
        if(respuesta[c+1] == '\\')
        {
          if(respuesta[c+2] == 'n' || respuesta[c+2] == 'r' )
          {
                // Imprimimos el texto precedente y el salto de linea en el RichEdit
               
                Memo1->AddText(Utf8ToAnsi(respuesta_formateada));
                Memo1->AddLineBreak();
                respuesta_formateada = "";
                c = c+3;
          }

          if(respuesta[c+2] == '"')
          {
                respuesta_formateada = respuesta_formateada + respuesta[c+2];
        respuesta_formateada = respuesta_formateada + " ";
                c = c+1;
          }
        }


        else {
                        //Seguimos almacenando la respuesta
                        respuesta_formateada = respuesta_formateada + respuesta[c+1];
                  }

  }


  //Imprimimos lo restante de la respuesta
  Memo1->AddText(Utf8ToAnsi(respuesta_formateada));


  o->Free();
  memo->Free();
}
catch (...)
{
  ShowMessage("Error accediendo a los servicios IA de HFocused");
}



La franja horaria es GMT +2. Ahora son las 12:39:36.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi