autoGPT for OpenAI

User avatar
Antonio Linares
Site Admin
Posts: 42393
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 9 times
Been thanked: 41 times
Contact:

autoGPT for OpenAI

Post by Antonio Linares »

Based on the excellent work of Carlos Gallego:
https://fivetechsupport.com/forums/view ... 75&start=0

and after seeking advice from ChatGPT, I have managed to implement "context" for it.
For example, if you first tell it "tell me a joke" and then say "tell me another," it knows what you mean :-)

The goal is to provide different "prompts," make it work automatically, be able to remove previous steps, etc.

It's a work in progress and still has bugs. Here it is if you'd like to give it a try:

autogpt.prg

Code: Select all | Expand

#include "FiveWin.ch"

function Main()

   local oDlg, oGet1, cVar1 := Space( 100 )
   local oGet2, cVar2 := Space( 2048 )
   local oFont, oBtn1, oSay1, oSay2
   local nChars := 2048
   local oOpenAI := TOPenAI()
   local oGetContext, cContext
   
   oOpenAI:cKey = "sk-yours..."

   TBtnBmp():lLegacyLookLeftRight := .T.
   
   DEFINE FONT oFont NAME "Verdana" SIZE 0, -16

   DEFINE DIALOG oDlg FROM 0, 0 TO 39, 150 TRUEPIXEL TITLE "autoGPT with OpenAI"
   
   @ 24, 370 SAY "Question" OF oDlg FONT oFont SIZE 75, 15 PIXEL

   @ 28, 1040 SAY oSay1 VAR "Chars: 0 / " + cValToChar( nChars ) OF oDlg PIXEL ;
      SIZE 120, 15 UPDATE CENTER

   @ 45, 370 GET oGet1 VAR cVar1 OF oDlg PIXEL SIZE 800,200 MEMO FONT oFont 
   
   oGet1:bGotfocus := {|| oGet1:SetSel( 0, 0 ) }

   @ 250, 590 BTNBMP PROMPT "Clean context" OF oDlg PIXEL SIZE 150, 45 ;
      ACTION oOpenAI:Clean() NOBORDER 2007

   @ 250, 755 BTNBMP PROMPT "Submit" OF oDlg PIXEL SIZE 150, 45 ;
      ACTION ( oGet2:SetText( oOpenAI:Ask( AllTrim( cVar1 ) ) ), oGetContext:SetText( oOpenAI:cContext ) ) ;
      NOBORDER 2007

   @ 296, 370 SAY "Result" OF oDlg FONT oFont SIZE 70,15 PIXEL

   @ 317, 370 GET oGet2 VAR cVar2 OF oDlg PIXEL SIZE 800, 200 MEMO FONT oFont
   
   oGet2:bGotfocus := {|| oGet2:SetSel( 0, 0 ) }

   @ 24, 15 SAY "Context" OF oDlg FONT oFont SIZE 75, 15 PIXEL

   @ 45, 15 GET oGetContext VAR cContext PIXEL SIZE 340, 473 MEMO FONT oFont 

   @ 535, 900 BTNBMP PROMPT "Close" OF oDlg PIXEL ACTION oDlg:End() SIZE 150,45;
      NOBORDER 2007
   
   ACTIVATE DIALOG oDlg CENTERED ON PAINT oGet1:SetPos( 0 )
   
return nil

//------------------------------------------------------------//

CLASS TOpenAI

   DATA   cKey
   DATA   cContext INIT ""
   DATA   cAnswer

   METHOD Ask( cQuestion )
   METHOD Clean() INLINE ::cContext := ""

ENDCLASS   

//------------------------------------------------------------//

METHOD Ask( cQuestion ) CLASS TOpenAI

   ::cContext += "User: " + cQuestion
   ::cAnswer = OpenAICall( ::cContext, ::cKey )
   if ! Empty( ::cAnswer )
      ::cContext += ". chatGPT: " + StrTran( ::cAnswer, CRLF, "\r\n" )
   endif   

return ::cAnswer   

//------------------------------------------------------------//

function OpenAICall( cPrompt, cKey )

   local cUrl  := "https://api.openai.com/v1/engines/text-davinci-003/completions"
   local cJSon, hAnswer := {=>}, cAnswer := ""
   
   static oSoap

   if oSoap == nil 
      oSoap = CreateObject( "MSXML2.ServerXMLHTTP.6.0" )
   endif   

   TEXT INTO cJson
   {
      "prompt": "cPrompt_empty",
      "temperature": 0,
      "max_tokens": 2048
   }
   ENDTEXT
   
   cPrompt = AllTrim( cPrompt )
   cJson = StrTran( cJson, "cPrompt_empty", cPrompt )
   cJson = StrTran( cJson, CRLF, "\r\n" )

   oSoap:Open( "POST", cUrl, .F. )
   oSoap:SetRequestHeader( "Content-Type", "application/json; charset=utf-8" )
   oSoap:setRequestHeader( "Authorization", "Bearer " + cKey )
   oSoap:Send( cJson )

   hb_jsondecode( Alltrim( oSoap:responseText ), @hAnswer )

   if hb_hHasKey( hAnswer, "error" )
      if Empty( hAnswer[ "error" ][ "param" ] )
         hAnswer[ "error" ][ "param" ] = ""
      endif   
      if Empty( hAnswer[ "error" ][ "code" ] )
         hAnswer[ "error" ][ "code" ] = ""
      endif   
      MsgAlert( hAnswer[ "error" ][ "message" ] + CRLF + CRLF + ;
                "Param: " + hAnswer[ "error" ][ "param" ] + CRLF + CRLF + ;
                "Code: " + hAnswer[ "error" ][ "code" ] + CRLF + CRLF, ;
                hAnswer[ "error" ][ "type" ] )
   else
      cAnswer = hAnswer[ "choices" ][ 1 ][ "text" ]
      cAnswer = AllTrim( StrTran( cAnswer, Chr( 10 ), CRLF ) )
      cAnswer = StrTran( cAnswer, '"', "'" )
   endif
   
return cAnswer

//------------------------------------------------------------//
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 42393
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 9 times
Been thanked: 41 times
Contact:

Re: autoGPT for OpenAI

Post by Antonio Linares »

Enhanced version:

Code: Select all | Expand

#include "FiveWin.ch"

function Main()

   local oDlg, oGet1, cVar1 := Space( 100 )
   local oGet2, cVar2 := Space( 2048 )
   local oFont, oBtn1, oSay1, oSay2
   local nChars := 2048
   local oOpenAI := TOPenAI()
   local oGetContext, cContext
   
   oOpenAI:cKey = "sk-yours..."

   TBtnBmp():lLegacyLookLeftRight := .T.
   
   DEFINE FONT oFont NAME "Verdana" SIZE 0, -16

   DEFINE DIALOG oDlg FROM 0, 0 TO 39, 150 TRUEPIXEL TITLE "autoGPT with OpenAI"
   
   @ 24, 370 SAY "Question" OF oDlg FONT oFont SIZE 75, 15 PIXEL

   @ 28, 1040 SAY oSay1 VAR "Chars: 0 / " + cValToChar( nChars ) OF oDlg PIXEL ;
      SIZE 120, 15 UPDATE CENTER

   @ 45, 370 GET oGet1 VAR cVar1 OF oDlg PIXEL SIZE 800,200 MEMO FONT oFont 
   
   oGet1:bGotfocus := {|| oGet1:SetSel( 0, 0 ) }

   @ 250, 590 BTNBMP PROMPT "Clean context" OF oDlg PIXEL SIZE 150, 45 ;
      ACTION ( oOpenAI:Clean(), oGetContext:SetText( "" ) ) NOBORDER 2007

   @ 250, 755 BTNBMP PROMPT "Submit" OF oDlg PIXEL SIZE 150, 45 ;
      ACTION ( oGet2:SetText( oOpenAI:Ask( AllTrim( cVar1 ) ) ),;
               oGetContext:SetText( oOpenAI:GetContext() ) ) ;
      NOBORDER 2007

   @ 296, 370 SAY "Result" OF oDlg FONT oFont SIZE 70,15 PIXEL

   @ 317, 370 GET oGet2 VAR cVar2 OF oDlg PIXEL SIZE 800, 200 MEMO FONT oFont
   
   oGet2:bGotfocus := {|| oGet2:SetSel( 0, 0 ) }

   @ 24, 15 SAY "Context" OF oDlg FONT oFont SIZE 75, 15 PIXEL

   @ 45, 15 GET oGetContext VAR cContext PIXEL SIZE 340, 473 MEMO FONT oFont 

   @ 535, 900 BTNBMP PROMPT "Close" OF oDlg PIXEL ACTION oDlg:End() SIZE 150,45;
      NOBORDER 2007
   
   ACTIVATE DIALOG oDlg CENTERED ON PAINT oGet1:SetPos( 0 )
   
return nil

//------------------------------------------------------------//

CLASS TOpenAI

   DATA   cKey
   DATA   cContext INIT ""
   DATA   cAnswer

   METHOD Ask( cQuestion )
   METHOD Clean() INLINE ::cContext := ""
   METHOD GetContext() INLINE StrTran( ::cContext, "\r\n", CRLF )

ENDCLASS   

//------------------------------------------------------------//

METHOD Ask( cQuestion ) CLASS TOpenAI

   ::cContext += "\r\nUser: " + cQuestion
   ::cAnswer = OpenAICall( ::cContext, ::cKey )
   if ! Empty( ::cAnswer )
      ::cContext += "\r\nchatGPT: " + StrTran( ::cAnswer, CRLF, "\r\n" )
   endif   

return ::cAnswer   

//------------------------------------------------------------//

function OpenAICall( cPrompt, cKey )

   local cUrl  := "https://api.openai.com/v1/engines/text-davinci-003/completions"
   local cJSon, hAnswer := {=>}, cAnswer := ""
   
   static oSoap

   if oSoap == nil 
      oSoap = CreateObject( "MSXML2.ServerXMLHTTP.6.0" )
   endif   

   TEXT INTO cJson
   {
      "prompt": "cPrompt_empty",
      "temperature": 0,
      "max_tokens": 2048
   }
   ENDTEXT
   
   cPrompt = AllTrim( cPrompt )
   cJson = StrTran( cJson, "cPrompt_empty", cPrompt )
   cJson = StrTran( cJson, CRLF, "\r\n" )

   oSoap:Open( "POST", cUrl, .F. )
   oSoap:SetRequestHeader( "Content-Type", "application/json; charset=utf-8" )
   oSoap:setRequestHeader( "Authorization", "Bearer " + cKey )
   oSoap:Send( cJson )

   hb_jsondecode( Alltrim( oSoap:responseText ), @hAnswer )

   if hb_hHasKey( hAnswer, "error" )
      if Empty( hAnswer[ "error" ][ "param" ] )
         hAnswer[ "error" ][ "param" ] = ""
      endif   
      if Empty( hAnswer[ "error" ][ "code" ] )
         hAnswer[ "error" ][ "code" ] = ""
      endif   
      MsgAlert( hAnswer[ "error" ][ "message" ] + CRLF + CRLF + ;
                "Param: " + hAnswer[ "error" ][ "param" ] + CRLF + CRLF + ;
                "Code: " + hAnswer[ "error" ][ "code" ] + CRLF + CRLF, ;
                hAnswer[ "error" ][ "type" ] )
   else
      cAnswer = hAnswer[ "choices" ][ 1 ][ "text" ]
      cAnswer = AllTrim( StrTran( cAnswer, Chr( 10 ), CRLF ) )
      cAnswer = StrTran( cAnswer, '"', "'" )
   endif
   
return cAnswer

//------------------------------------------------------------//
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Jimmy
Posts: 1734
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: autoGPT for OpenAI

Post by Jimmy »

hi,

it seem that you need a ABO Account for own Apps
Image

"free" Account still work when use Online Webpage
greeting,
Jimmy
User avatar
Antonio Linares
Site Admin
Posts: 42393
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 9 times
Been thanked: 41 times
Contact:

Re: autoGPT for OpenAI

Post by Antonio Linares »

Dear Jimmy,

Yes, you have to subscribe to it but it is very cheap :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 42393
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 9 times
Been thanked: 41 times
Contact:

Re: autoGPT for OpenAI

Post by Antonio Linares »

Enhanced version:

autogpt.prg

Code: Select all | Expand

#include "FiveWin.ch"

function Main()

   local oDlg, oGet1, cVar1 := Space( 100 )
   local oGet2, cVar2 := Space( 2048 )
   local oFont, oBtn1, oSay1, oSay2
   local nChars := 2048
   local oOpenAI := TOPenAI()
   local oGetContext, cContext
   
   oOpenAI:cKey = "sk-yours..."
   oOpenAI:AddRule( "don't include 'Bot:', 'chatGPT:', 'User:' in your answer" )

   TBtnBmp():lLegacyLookLeftRight := .T.
   
   DEFINE FONT oFont NAME "Verdana" SIZE 0, -16

   DEFINE DIALOG oDlg FROM 0, 0 TO 39, 150 TRUEPIXEL TITLE "autoGPT with OpenAI"
   
   @ 24, 370 SAY "Question" OF oDlg FONT oFont SIZE 75, 15 PIXEL

   @ 28, 1040 SAY oSay1 VAR "Chars: 0 / " + cValToChar( nChars ) OF oDlg PIXEL ;
      SIZE 120, 15 UPDATE CENTER

   @ 45, 370 GET oGet1 VAR cVar1 OF oDlg PIXEL SIZE 800,200 MEMO FONT oFont 
   
   oGet1:bGotfocus := {|| oGet1:SetSel( 0, 0 ) }

   @ 250, 590 BTNBMP PROMPT "Clean context" OF oDlg PIXEL SIZE 150, 45 ;
      ACTION ( oOpenAI:Clean(), oGetContext:SetText( "" ) ) NOBORDER 2007

   @ 250, 755 BTNBMP PROMPT "Submit" OF oDlg PIXEL SIZE 150, 45 ;
      ACTION ( oGet2:SetText( oOpenAI:Ask( AllTrim( cVar1 ) ) ),;
               oGetContext:SetText( oOpenAI:GetContext() ) ) ;
      NOBORDER 2007

   @ 296, 370 SAY "Result" OF oDlg FONT oFont SIZE 70,15 PIXEL

   @ 317, 370 GET oGet2 VAR cVar2 OF oDlg PIXEL SIZE 800, 200 MEMO FONT oFont
   
   oGet2:bGotfocus := {|| oGet2:SetSel( 0, 0 ) }

   @ 24, 15 SAY "Context" OF oDlg FONT oFont SIZE 75, 15 PIXEL

   @ 45, 15 GET oGetContext VAR cContext PIXEL SIZE 340, 473 MEMO FONT oFont 

   @ 535, 900 BTNBMP PROMPT "Close" OF oDlg PIXEL ACTION oDlg:End() SIZE 150,45;
      NOBORDER 2007
   
   ACTIVATE DIALOG oDlg CENTERED ON PAINT oGet1:SetPos( 0 )
   
return nil

//------------------------------------------------------------//

CLASS TOpenAI

   DATA   cKey
   DATA   cContext INIT ""
   DATA   cAnswer
   DATA   aRules INIT {}

   METHOD Ask( cQuestion )
   METHOD Clean() INLINE ::cContext := ""
   METHOD GetContext() INLINE StrTran( ::cContext, "\r\n", CRLF )
   METHOD AddRule( cRule ) INLINE AAdd( ::aRules, cRule )

ENDCLASS   

//------------------------------------------------------------//

METHOD Ask( cQuestion ) CLASS TOpenAI

   local cRule

   ::cContext += "\r\nUser: " + cQuestion
   if ! Empty( ::aRules )
      for each cRule in ::aRules
         ::cContext += "\r\n" + cRule
      next
   endif      
   ::cAnswer = OpenAICall( ::cContext, ::cKey )
   if ! Empty( ::cAnswer )
      ::cContext += "\r\nchatGPT: " + StrTran( ::cAnswer, CRLF, "\r\n" )
   endif   

return ::cAnswer   

//------------------------------------------------------------//

function OpenAICall( cPrompt, cKey )

   local cUrl  := "https://api.openai.com/v1/engines/text-davinci-003/completions"
   local cJSon, hAnswer := {=>}, cAnswer := ""
   
   static oSoap

   if oSoap == nil 
      oSoap = CreateObject( "MSXML2.ServerXMLHTTP.6.0" )
   endif   

   TEXT INTO cJson
   {
      "prompt": "cPrompt_empty",
      "temperature": 0,
      "max_tokens": 2048
   }
   ENDTEXT
   
   cPrompt = AllTrim( cPrompt )
   cJson   = StrTran( cJson, "cPrompt_empty", cPrompt )
   cJson   = StrTran( cJson, CRLF, "\r\n" )
   cJson   = StrTran( cJson, Chr( 13 ), "" )

   oSoap:Open( "POST", cUrl, .F. )
   oSoap:SetRequestHeader( "Content-Type", "application/json; charset=utf-8" )
   oSoap:setRequestHeader( "Authorization", "Bearer " + cKey )
   oSoap:Send( cJson )

   hb_jsondecode( Alltrim( oSoap:responseText ), @hAnswer )

   if hb_hHasKey( hAnswer, "error" )
      if Empty( hAnswer[ "error" ][ "param" ] )
         hAnswer[ "error" ][ "param" ] = ""
      endif   
      if Empty( hAnswer[ "error" ][ "code" ] )
         hAnswer[ "error" ][ "code" ] = ""
      endif   
      MsgAlert( hAnswer[ "error" ][ "message" ] + CRLF + CRLF + ;
                "Param: " + hAnswer[ "error" ][ "param" ] + CRLF + CRLF + ;
                "Code: " + hAnswer[ "error" ][ "code" ] + CRLF + CRLF, ;
                hAnswer[ "error" ][ "type" ] )
      fw_memoEdit( cJson )          
   else
      cAnswer = hAnswer[ "choices" ][ 1 ][ "text" ]
      cAnswer = AllTrim( StrTran( cAnswer, Chr( 10 ), CRLF ) )
      cAnswer = StrTran( cAnswer, '"', "'" )
   endif
   
return cAnswer

//------------------------------------------------------------//
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 42393
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 9 times
Been thanked: 41 times
Contact:

Re: autoGPT for OpenAI

Post by Antonio Linares »

Enhanced version:

autogpt.prg

Code: Select all | Expand

#include "FiveWin.ch"

function Main()

   local oDlg, oGetQuestion, cQuestion := Space( 100 )
   local oGet2, cVar2 := Space( 2048 )
   local oFont, oBtn1, oSay1, oSay2
   local nChars := 0
   local oOpenAI := TOPenAI()
   local oGetContext, cContext, oBtnContinue, oBtnSubmit
   
   oOpenAI:cKey = "sk-yours..."
   oOpenAI:AddRule( "don't include the words 'Bot:' 'chatGPT:' 'User:' in your answer" )

   DEFINE FONT oFont NAME "Verdana" SIZE 0, -16

   DEFINE DIALOG oDlg FROM 0, 0 TO 39, 150 TRUEPIXEL TITLE "autoGPT with OpenAI"
   
   @ 24, 370 SAY "Question" OF oDlg FONT oFont SIZE 75, 15 PIXEL

   @ 24, 1040 SAY oSay1 VAR "Chars: " + cValToChar( nChars ) OF oDlg PIXEL ;
      SIZE 170, 15 UPDATE CENTER FONT oFont

   @ 45, 370 GET oGetQuestion VAR cQuestion OF oDlg PIXEL SIZE 800,200 MEMO FONT oFont UPDATE

   oGetQuestion:bChange = { || nChars := Len( AllTrim( oGetQuestion:GetText() ) ), oSay1:Refresh() }
   oGetQuestion:bGotfocus = {|| oGetQuestion:SetSel( 0, 0 ) }

   @ 255, 677 BUTTON "Clean context" OF oDlg PIXEL SIZE 150, 45 ;
      FONT oFont ACTION ( oOpenAI:Clean(), oGetQuestion:SetText( "" ), ;
                          cQuestion := "", oGetQuestion:VarPut( "" ),;
                          oGetContext:SetText( "" ), oGet2:SetText( "" ) )

   @ 255, 849 BUTTON oBtnSubmit PROMPT "Submit" OF oDlg PIXEL SIZE 150, 45 ;
      FONT oFont ACTION ( oBtnSubmit:Disable(), oGet2:SetText( oOpenAI:Ask( AllTrim( cQuestion ) ) ),;
                          oGetContext:SetText( oOpenAI:GetContext() ), oBtnSubmit:Enable() ) 

   @ 255, 755 + 200 + 64 BUTTON oBtnContinue PROMPT "Continue" OF oDlg PIXEL SIZE 150, 45 ;
      FONT oFont ;
      ACTION ( oBtnContinue:Disable(),;
               oGetQuestion:VarPut( "continue" ), oGetQuestion:SetText( "continue" ), SysRefresh(),;
               oBtnSubmit:Click(), oBtnContinue:Enable() )

   @ 296, 370 SAY "Result" OF oDlg FONT oFont SIZE 70,15 PIXEL

   @ 317, 370 GET oGet2 VAR cVar2 OF oDlg PIXEL SIZE 800, 200 MEMO FONT oFont
   
   oGet2:bGotfocus := {|| oGet2:SetSel( 0, 0 ) }

   @ 24, 15 SAY "Context" OF oDlg FONT oFont SIZE 75, 15 PIXEL

   @ 45, 15 GET oGetContext VAR cContext PIXEL SIZE 340, 473 MEMO FONT oFont 

   @ 531, 1020 BUTTON "Close" OF oDlg PIXEL FONT oFont ACTION oDlg:End() SIZE 150, 45
   
   ACTIVATE DIALOG oDlg CENTERED ON PAINT oGetQuestion:SetPos( 0 )
   
return nil

//------------------------------------------------------------//

CLASS TOpenAI

   DATA   cKey
   DATA   cContext INIT ""
   DATA   cAnswer
   DATA   aRules INIT {}

   METHOD Ask( cQuestion )
   METHOD Clean() INLINE ( ::cContext := "", ::cAnswer := "" )
   METHOD GetContext() INLINE StrTran( ::cContext, "\r\n", CRLF )
   METHOD AddRule( cRule ) INLINE AAdd( ::aRules, cRule )

ENDCLASS   

//------------------------------------------------------------//

METHOD Ask( cQuestion ) CLASS TOpenAI

   local cRule

   ::cContext += If( ! Empty( ::cContext ), "\r\n", "" ) + "User: " + cQuestion
   if ! Empty( ::aRules )
      for each cRule in ::aRules
         ::cContext += "\r\n" + cRule
      next
   endif      
   ::cAnswer = OpenAICall( ::cContext, ::cKey )
   if ! Empty( ::cAnswer )
      ::cContext += "\r\nchatGPT: " + StrTran( ::cAnswer, CRLF, "\r\n" )
   endif   

return ::cAnswer   

//------------------------------------------------------------//

function OpenAICall( cPrompt, cKey )

   local cUrl  := "https://api.openai.com/v1/engines/text-davinci-003/completions"
   local cJSon, hAnswer := {=>}, cAnswer := ""
   
   static oSoap

   if oSoap == nil 
      oSoap = CreateObject( "MSXML2.ServerXMLHTTP.6.0" )
   endif   

   TEXT INTO cJson
   {
      "prompt": "cPrompt_empty",
      "temperature": 0,
      "max_tokens": 2048
   }
   ENDTEXT
   
   cPrompt = AllTrim( cPrompt )
   cJson   = StrTran( cJson, "cPrompt_empty", cPrompt )
   cJson   = StrTran( cJson, CRLF, "\r\n" )
   cJson   = StrTran( cJson, Chr( 13 ), "" )

   oSoap:Open( "POST", cUrl, .F. )
   oSoap:SetRequestHeader( "Content-Type", "application/json; charset=utf-8" )
   oSoap:setRequestHeader( "Authorization", "Bearer " + cKey )
   oSoap:Send( cJson )

   hb_jsondecode( Alltrim( oSoap:responseText ), @hAnswer )

   if hb_hHasKey( hAnswer, "error" )
      if Empty( hAnswer[ "error" ][ "param" ] )
         hAnswer[ "error" ][ "param" ] = ""
      endif   
      if Empty( hAnswer[ "error" ][ "code" ] )
         hAnswer[ "error" ][ "code" ] = ""
      endif   
      MsgAlert( hAnswer[ "error" ][ "message" ] + CRLF + CRLF + ;
                "Param: " + hAnswer[ "error" ][ "param" ] + CRLF + CRLF + ;
                "Code: " + hAnswer[ "error" ][ "code" ] + CRLF + CRLF, ;
                hAnswer[ "error" ][ "type" ] )
      fw_memoEdit( cJson )          
   else
      cAnswer = hAnswer[ "choices" ][ 1 ][ "text" ]
      cAnswer = AllTrim( StrTran( cAnswer, Chr( 10 ), CRLF ) )
      cAnswer = StrTran( cAnswer, '"', "'" )
   endif
   
return cAnswer

//------------------------------------------------------------//
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Otto
Posts: 6396
Joined: Fri Oct 07, 2005 7:07 pm
Has thanked: 8 times
Been thanked: 1 time
Contact:

Re: autoGPT for OpenAI

Post by Otto »

Dear Antonio,

many, many thanks for your tireless research work.
So great that we can now access AI from Fivewin.
It opens up so many possibilities.

I am also already in the process of creating a small utility.
You can choose standard tasks from a task box to set ChatGPT.

Thanks again
Otto


Image
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Antonio Linares
Site Admin
Posts: 42393
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 9 times
Been thanked: 41 times
Contact:

Re: autoGPT for OpenAI

Post by Antonio Linares »

Dear Otto,

yes, thats the idea :-)

To have a collection of tasks and also a collection of different prompts and rules
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
reinaldocrespo
Posts: 979
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Re: autoGPT for OpenAI

Post by reinaldocrespo »

Hello Antonio;

I think I have a very good use case for this class. I have been testing the idea using Chat.openai.com manually. I feed the document's text with a very technical question and so far the answers are better than what my most seasoned and technical users have been coming up with.

A typical document is 166 tokens. OpenAI answers are about 16 tokens at most for each document that is fed.

#1 -- When you limit tokens, does that limit the answer or does that includes question and answer?
#2 -- I noticed you are using SOAP. Will it work with hbCurl.lib? Doesn't it make more sense to use hbCurl.lib that is MS independent?

I noticed their samples are Python samples. Are there c samples anywhere or can you help with a TOpenAI class sample using hbcurl?

Thank you,

Reinaldo.
User avatar
Antonio Linares
Site Admin
Posts: 42393
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 9 times
Been thanked: 41 times
Contact:

Re: autoGPT for OpenAI

Post by Antonio Linares »

Dear Reinaldo,

In the source code, originally developed by Carlos Gallego, you find this:

Code: Select all | Expand

   TEXT INTO cJson
   {
      "prompt": "cPrompt_empty",
      "temperature": 0,
      "max_tokens": 2048
   }
   ENDTEXT
Not sure if modifying the max_tokens value may help. Maybe we need to contact OpenAI tech support.

Regarding the use of SOAP I don't see any issue with that as we build Windows apps mostly. If a Linux or Mac user wants to use it, then it may get converted into curl.

I am mostly focused on finding a good way to manage the context (deleting, modifying or redoing a previous step), manage different prompts and rules. It seems as the combination of context use, the right prompt and certain rules is the way to get the best from the OpenAI engine.

I do appreciate your feedback about this, hopefully more users provide feedback too, so we can enhance this new Class TOpenAI to be used from our apps the best way
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Otto
Posts: 6396
Joined: Fri Oct 07, 2005 7:07 pm
Has thanked: 8 times
Been thanked: 1 time
Contact:

Re: autoGPT for OpenAI

Post by Otto »

Hello friends,

I am thinking of creating an offline tool to submit text to ChatGPT.
Requiring customers to have an API key with variable cost billing can be cumbersome.
Here, I will simply enter the text into a textbox and then select the task from a combobox.
Then, I will use a copy command to transfer the text to the clipboard.

Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Antonio Linares
Site Admin
Posts: 42393
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 9 times
Been thanked: 41 times
Contact:

Re: autoGPT for OpenAI

Post by Antonio Linares »

Dear Otto,

Who will pay for the OpenAI services ?

Could you please explain your point of view and how will it work ?

many thanks
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Otto
Posts: 6396
Joined: Fri Oct 07, 2005 7:07 pm
Has thanked: 8 times
Been thanked: 1 time
Contact:

Re: autoGPT for OpenAI

Post by Otto »

Dear Antonio,
I have the ChatGPT Pro plan and pay $24 per month. However, if I want to use the OpenAI API, I need another plan that is billed per token.
I hope my information is right.
Best regards,
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Antonio Linares
Site Admin
Posts: 42393
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 9 times
Been thanked: 41 times
Contact:

Re: autoGPT for OpenAI

Post by Antonio Linares »

Dear Otto,

yes, I think so

This is our more recent version:
https://github.com/FiveTechSoft/screens ... g?raw=true
Image
autogpt.prg

Code: Select all | Expand

#include "FiveWin.ch"

function Main()

   local oDlg, oGetQuestion, cQuestion := Space( 100 )
   local oGet2, cVar2 := Space( 2048 )
   local oFont, oBtn1, oSay1, oSay2
   local nChars := 0
   local oOpenAI := TOPenAI()
   local oBrwContext, aContext, oBtnContinue, oBtnSubmit
   
   oOpenAI:cKey = "sk-yours..."
   oOpenAI:AddRule( "don't include the words 'Bot:' 'chatGPT:' 'User:' in your answer" )

   DEFINE FONT oFont NAME "Verdana" SIZE 0, -16

   DEFINE DIALOG oDlg FROM 0, 0 TO 39, 150 TRUEPIXEL TITLE "autoGPT with OpenAI"
   
   @ 24, 370 SAY "Question" OF oDlg FONT oFont SIZE 75, 15 PIXEL

   @ 24, 1040 SAY oSay1 VAR "Chars: " + cValToChar( nChars ) OF oDlg PIXEL ;
      SIZE 170, 15 UPDATE CENTER FONT oFont

   @ 45, 370 GET oGetQuestion VAR cQuestion OF oDlg PIXEL SIZE 800,200 MEMO FONT oFont UPDATE

   oGetQuestion:bChange = { || nChars := Len( AllTrim( oGetQuestion:GetText() ) ), oSay1:Refresh() }
   oGetQuestion:bGotfocus = {|| oGetQuestion:SetSel( 0, 0 ) }

   @ 255, 677 BUTTON "Clean context" OF oDlg PIXEL SIZE 150, 45 ;
      FONT oFont ACTION ( oOpenAI:Clean(), oOpenAI:Clean(), oBrwContext:Refresh(),;
                          oGetQuestion:SetText( "" ), cQuestion := "", oGetQuestion:VarPut( "" ) )

   @ 255, 849 BUTTON oBtnSubmit PROMPT "Submit" OF oDlg PIXEL SIZE 150, 45 ;
      FONT oFont ACTION ( oBtnSubmit:Disable(), oGet2:SetText( oOpenAI:Ask( AllTrim( cQuestion ) ) ),;
                          oBrwContext:Refresh(), oBtnSubmit:Enable() ) 

   @ 255, 755 + 200 + 64 BUTTON oBtnContinue PROMPT "Continue" OF oDlg PIXEL SIZE 150, 45 ;
      FONT oFont ;
      ACTION ( oBtnContinue:Disable(),;
               oGetQuestion:VarPut( "continue" ), oGetQuestion:SetText( "continue" ), SysRefresh(),;
               oBtnSubmit:Click(), oBtnContinue:Enable() )

   @ 296, 370 SAY "Result" OF oDlg FONT oFont SIZE 70,15 PIXEL

   @ 317, 370 GET oGet2 VAR cVar2 OF oDlg PIXEL SIZE 800, 200 MEMO FONT oFont
   
   oGet2:bGotfocus := {|| oGet2:SetSel( 0, 0 ) }

   @ 24, 15 SAY "Context" OF oDlg FONT oFont SIZE 75, 15 PIXEL

   @ 45, 15 XBROWSE oBrwContext SIZE 340, 473 PIXEL OF oDlg ;
      DATASOURCE oOpenAI:aContext AUTOCOLS HEADERS "Context" FONT oFont // NOBORDER

   WITH OBJECT oBrwContext
      :nRowHeight       = 90
      :lAllowRowSizing  = .T.
      :nRowDividerStyle = 2
      :nStretchCol = 1  
      :lHScroll = .F. 
      :aCols[ 1 ]:bStrData := { |x,o| If( oBrwContext:KeyNo % 2 == 1, "User", "chatGPT" ) + ":" + CRLF + IfNil( o:Value, "" ) }
      :bClrStd  = { || If( oBrwContext:KeyNo % 2 == 0, { CLR_BLACK, CLR_HGREEN }, { CLR_BLACK, CLR_HCYAN } ) }
      :lHeader  = .F.
      :lRecordSelector = .F.  
      :CreateFromCode()
   END

   @ 531, 1020 BUTTON "Close" OF oDlg PIXEL FONT oFont ACTION oDlg:End() SIZE 150, 45
   
   ACTIVATE DIALOG oDlg CENTERED ON PAINT oGetQuestion:SetPos( 0 )
   
return nil

//------------------------------------------------------------//

CLASS TOpenAI

   DATA   cKey
   DATA   aContext INIT {}
   DATA   cAnswer
   DATA   aRules INIT {}

   METHOD Ask( cQuestion )
   METHOD Clean() INLINE ( ::cAnswer := "", ASize( ::aContext, 0 ) )
   // METHOD GetContext() INLINE StrTran( ::cContext, "\r\n", CRLF )
   METHOD AddRule( cRule ) INLINE AAdd( ::aRules, cRule )

ENDCLASS   

//------------------------------------------------------------//

METHOD Ask( cQuestion ) CLASS TOpenAI

   local cRule, cContext := "", cLine

   AAdd( ::aContext, cQuestion )
   if ! Empty( ::aRules )
      for each cRule in ::aRules
         cContext += "\r\n" + cRule
      next
   endif      
   for each cLine in ::aContext 
      cContext += cLine 
   next   
   ::cAnswer = OemToAnsi( OpenAICall( cContext, ::cKey ) )
   if ! Empty( ::cAnswer )
      if Left( ::cAnswer, 4 ) == "Bot:"
         ::cAnswer = SubStr( ::cAnswer, 6 )
      endif   
      if Left( ::cAnswer, 11 ) == "onechatGPT:"
         ::cAnswer = SubStr( ::cAnswer, 13 )
      endif   
      AAdd( ::aContext, StrTran( ::cAnswer, CRLF, "\r\n" ) )
   endif   

return ::cAnswer   

//------------------------------------------------------------//

function OpenAICall( cPrompt, cKey )

   local cUrl  := "https://api.openai.com/v1/engines/text-davinci-003/completions"
   local cJSon, hAnswer := {=>}, cAnswer := ""
   
   static oSoap

   if oSoap == nil 
      oSoap = CreateObject( "MSXML2.ServerXMLHTTP.6.0" )
   endif   

   TEXT INTO cJson
   {
      "prompt": "cPrompt_empty",
      "temperature": 0,
      "max_tokens": 2048
   }
   ENDTEXT
   
   cPrompt = AllTrim( cPrompt )
   cJson   = StrTran( cJson, "cPrompt_empty", cPrompt )
   cJson   = StrTran( cJson, CRLF, "\r\n" )
   cJson   = StrTran( cJson, Chr( 13 ), "" )

   oSoap:Open( "POST", cUrl, .F. )
   oSoap:SetRequestHeader( "Content-Type", "application/json; charset=utf-8" )
   oSoap:setRequestHeader( "Authorization", "Bearer " + cKey )
   oSoap:Send( cJson )

   hb_jsondecode( Alltrim( oSoap:responseText ), @hAnswer )

   if hb_hHasKey( hAnswer, "error" )
      if Empty( hAnswer[ "error" ][ "param" ] )
         hAnswer[ "error" ][ "param" ] = ""
      endif   
      if Empty( hAnswer[ "error" ][ "code" ] )
         hAnswer[ "error" ][ "code" ] = ""
      endif   
      MsgAlert( hAnswer[ "error" ][ "message" ] + CRLF + CRLF + ;
                "Param: " + hAnswer[ "error" ][ "param" ] + CRLF + CRLF + ;
                "Code: " + hAnswer[ "error" ][ "code" ] + CRLF + CRLF, ;
                hAnswer[ "error" ][ "type" ] )
      fw_memoEdit( cJson )          
   else
      cAnswer = hAnswer[ "choices" ][ 1 ][ "text" ]
      cAnswer = AllTrim( StrTran( cAnswer, Chr( 10 ), CRLF ) )
      cAnswer = StrTran( cAnswer, '"', "'" )
   endif
   
return cAnswer

//------------------------------------------------------------//
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 42393
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Has thanked: 9 times
Been thanked: 41 times
Contact:

Re: autoGPT for OpenAI

Post by Antonio Linares »

Using "temperature:

https://github.com/FiveTechSoft/screens ... ogpt05.png
Image
autogpt.prg

Code: Select all | Expand

#include "FiveWin.ch"
#include "Slider.ch"

function Main()

   local oDlg, oGetQuestion, cQuestion := Space( 100 )
   local oGet2, cVar2 := Space( 2048 )
   local oFont, oBtn1, oSay1, oSay2
   local nChars := 0
   local oOpenAI := TOPenAI()
   local oBrwContext, aContext, oBtnContinue, oBtnSubmit, oSlide
   
   oOpenAI:cKey = "sk-yours..."
   oOpenAI:AddRule( "don't include the words 'Bot:' 'chatGPT:' 'User:' in your answer" )

   DEFINE FONT oFont NAME "Verdana" SIZE 0, -16

   DEFINE DIALOG oDlg FROM 0, 0 TO 39, 150 TRUEPIXEL TITLE "autoGPT with OpenAI"
   
   @ 24, 370 SAY "Question" OF oDlg FONT oFont SIZE 75, 15 PIXEL

   @ 24, 1040 SAY oSay1 VAR "Chars: " + cValToChar( nChars ) OF oDlg PIXEL ;
      SIZE 170, 15 UPDATE CENTER FONT oFont

   @ 45, 370 GET oGetQuestion VAR cQuestion OF oDlg PIXEL SIZE 800,200 MEMO FONT oFont UPDATE

   oGetQuestion:bChange = { || nChars := Len( AllTrim( oGetQuestion:GetText() ) ), oSay1:Refresh() }
   oGetQuestion:bGotfocus = {|| oGetQuestion:SetSel( 0, 0 ) }

   @ 255, 677 BUTTON "Clean context" OF oDlg PIXEL SIZE 150, 45 ;
      FONT oFont ACTION ( oOpenAI:Clean(), oOpenAI:Clean(), oBrwContext:Refresh(),;
                          oGetQuestion:SetText( "" ), cQuestion := "", oGetQuestion:VarPut( "" ) )

   @ 255, 849 BUTTON oBtnSubmit PROMPT "Submit" OF oDlg PIXEL SIZE 150, 45 ;
      FONT oFont ACTION ( oBtnSubmit:Disable(), oGet2:SetText( oOpenAI:Ask( AllTrim( cQuestion ) ) ),;
                          oBrwContext:Refresh(), oBrwContext:GoBottom(), oBtnSubmit:Enable() ) 

   @ 255, 755 + 200 + 64 BUTTON oBtnContinue PROMPT "Continue" OF oDlg PIXEL SIZE 150, 45 ;
      FONT oFont ;
      ACTION ( oBtnContinue:Disable(),;
               oGetQuestion:VarPut( "continue" ), oGetQuestion:SetText( "continue" ), SysRefresh(),;
               oBtnSubmit:Click(), oBtnContinue:Enable() )

   @ 296, 370 SAY "Result" OF oDlg FONT oFont SIZE 70,15 PIXEL

   @ 317, 370 GET oGet2 VAR cVar2 OF oDlg PIXEL SIZE 800, 200 MEMO FONT oFont
   
   oGet2:bGotfocus := {|| oGet2:SetSel( 0, 0 ) }

   @ 24, 15 SAY "Context" OF oDlg FONT oFont SIZE 75, 15 PIXEL

   @ 45, 15 XBROWSE oBrwContext SIZE 340, 473 PIXEL OF oDlg ;
      DATASOURCE oOpenAI:aContext AUTOCOLS HEADERS "Context" FONT oFont // NOBORDER

   WITH OBJECT oBrwContext
      :nRowHeight       = 90
      :lAllowRowSizing  = .T.
      :nRowDividerStyle = 2
      :nStretchCol = 1  
      :lHScroll = .F. 
      :aCols[ 1 ]:bStrData := { |x,o| If( oBrwContext:KeyNo % 2 == 1, "User", "chatGPT" ) + ":" + CRLF + IfNil( o:Value, "" ) }
      :bClrStd  = { || If( oBrwContext:KeyNo % 2 == 0, { CLR_BLACK, CLR_HGREEN }, { CLR_BLACK, CLR_HCYAN } ) }
      :lHeader  = .F.
      :lRecordSelector = .F.  
      :CreateFromCode()
   END

   @ 531, 1020 BUTTON "Close" OF oDlg PIXEL FONT oFont ACTION oDlg:End() SIZE 150, 45

   @ 546, 500 SAY "Strict" OF oDlg PIXEL FONT oFont

   @ 546, 800 SAY "Creative" OF oDlg PIXEL FONT oFont

   @ 541, 570 SLIDER oSlide VAR oOpenAI:nTemperature OF oDlg ;
            HORIZONTAL ;
            BOTTOM DIRECTION ;
            RANGE 0, 2 ;
            MARKS 10 ;
            EXACT ;
            SIZE 210, 33 PIXEL // ;
            // ON CHANGE Triangulo( nVar1, nVar, nVar3 ) ;
            // ON THUMBPOS Triangulo( nVar1, nVar, nVar3 )
   
   ACTIVATE DIALOG oDlg CENTERED ON PAINT oGetQuestion:SetPos( 0 )
   
return nil

//------------------------------------------------------------//

CLASS TOpenAI

   DATA   cKey
   DATA   aContext INIT {}
   DATA   cAnswer
   DATA   aRules INIT {}
   DATA   nTemperature

   METHOD Ask( cQuestion )
   METHOD Clean() INLINE ( ::cAnswer := "", ASize( ::aContext, 0 ) )
   // METHOD GetContext() INLINE StrTran( ::cContext, "\r\n", CRLF )
   METHOD AddRule( cRule ) INLINE AAdd( ::aRules, cRule )

ENDCLASS   

//------------------------------------------------------------//

METHOD Ask( cQuestion ) CLASS TOpenAI

   local cRule, cContext := "", cLine

   AAdd( ::aContext, cQuestion )
   if ! Empty( ::aRules )
      for each cRule in ::aRules
         cContext += "\r\n" + cRule
      next
   endif      
   for each cLine in ::aContext 
      cContext += cLine 
   next   
   ::cAnswer = OemToAnsi( OpenAICall( cContext, ::cKey, ::nTemperature ) )
   if ! Empty( ::cAnswer )
      if Left( ::cAnswer, 4 ) == "Bot:"
         ::cAnswer = SubStr( ::cAnswer, 6 )
      endif   
      if Left( ::cAnswer, 11 ) == "onechatGPT:"
         ::cAnswer = SubStr( ::cAnswer, 13 )
      endif   
      AAdd( ::aContext, StrTran( ::cAnswer, CRLF, "\r\n" ) )
   endif   

return ::cAnswer   

//------------------------------------------------------------//

function OpenAICall( cPrompt, cKey, nTemperature )

   local cUrl  := "https://api.openai.com/v1/engines/text-davinci-003/completions"
   local cJSon, hAnswer := {=>}, cAnswer := ""
   
   static oSoap

   if oSoap == nil 
      oSoap = CreateObject( "MSXML2.ServerXMLHTTP.6.0" )
   endif   

   TEXT INTO cJson
   {
      "prompt": "cPrompt_empty",
      "temperature": nTemperature,
      "max_tokens": 2048
   }
   ENDTEXT
   
   cPrompt = AllTrim( cPrompt )
   cJson   = StrTran( cJson, "cPrompt_empty", cPrompt )
   cJson   = StrTran( cJson, CRLF, "\r\n" )
   cJson   = StrTran( cJson, Chr( 13 ), "" )
   cJson   = StrTran( cJson, "nTemperature", AllTrim( Str( nTemperature ) ) )

   oSoap:Open( "POST", cUrl, .F. )
   oSoap:SetRequestHeader( "Content-Type", "application/json; charset=utf-8" )
   oSoap:setRequestHeader( "Authorization", "Bearer " + cKey )
   oSoap:Send( cJson )

   hb_jsondecode( Alltrim( oSoap:responseText ), @hAnswer )

   if hb_hHasKey( hAnswer, "error" )
      if Empty( hAnswer[ "error" ][ "param" ] )
         hAnswer[ "error" ][ "param" ] = ""
      endif   
      if Empty( hAnswer[ "error" ][ "code" ] )
         hAnswer[ "error" ][ "code" ] = ""
      endif   
      MsgAlert( hAnswer[ "error" ][ "message" ] + CRLF + CRLF + ;
                "Param: " + hAnswer[ "error" ][ "param" ] + CRLF + CRLF + ;
                "Code: " + hAnswer[ "error" ][ "code" ] + CRLF + CRLF, ;
                hAnswer[ "error" ][ "type" ] )
      fw_memoEdit( cJson )          
   else
      cAnswer = hAnswer[ "choices" ][ 1 ][ "text" ]
      cAnswer = AllTrim( StrTran( cAnswer, Chr( 10 ), CRLF ) )
      cAnswer = StrTran( cAnswer, '"', "'" )
   endif
   
return cAnswer

//------------------------------------------------------------//
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply