autoGPT for OpenAI

autoGPT for OpenAI

Postby Antonio Linares » Sun Apr 23, 2023 9:52 am

Based on the excellent work of Carlos Gallego:
https://fivetechsupport.com/forums/viewtopic.php?f=6&t=42575&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 view  RUN
#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: 42122
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: autoGPT for OpenAI

Postby Antonio Linares » Sun Apr 23, 2023 10:21 am

Enhanced version:
Code: Select all  Expand view  RUN
#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
Antonio Linares
Site Admin
 
Posts: 42122
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: autoGPT for OpenAI

Postby Jimmy » Sun Apr 23, 2023 11:03 am

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
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: autoGPT for OpenAI

Postby Antonio Linares » Sun Apr 23, 2023 11:46 am

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: 42122
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: autoGPT for OpenAI

Postby Antonio Linares » Sun Apr 23, 2023 11:47 am

Enhanced version:

autogpt.prg
Code: Select all  Expand view  RUN
#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: 42122
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: autoGPT for OpenAI

Postby Antonio Linares » Sun Apr 23, 2023 4:51 pm

Enhanced version:

autogpt.prg
Code: Select all  Expand view  RUN
#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
Antonio Linares
Site Admin
 
Posts: 42122
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: autoGPT for OpenAI

Postby Otto » Wed Apr 26, 2023 10:06 am

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
Otto
 
Posts: 6346
Joined: Fri Oct 07, 2005 7:07 pm

Re: autoGPT for OpenAI

Postby Antonio Linares » Wed Apr 26, 2023 4:34 pm

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
Antonio Linares
Site Admin
 
Posts: 42122
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: autoGPT for OpenAI

Postby reinaldocrespo » Thu Apr 27, 2023 8:57 pm

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
reinaldocrespo
 
Posts: 979
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Re: autoGPT for OpenAI

Postby Antonio Linares » Fri Apr 28, 2023 8:32 am

Dear Reinaldo,

In the source code, originally developed by Carlos Gallego, you find this:
Code: Select all  Expand view  RUN
  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
Antonio Linares
Site Admin
 
Posts: 42122
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: autoGPT for OpenAI

Postby Otto » Thu May 04, 2023 6:42 am

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
Otto
 
Posts: 6346
Joined: Fri Oct 07, 2005 7:07 pm

Re: autoGPT for OpenAI

Postby Antonio Linares » Thu May 04, 2023 10:18 am

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
Antonio Linares
Site Admin
 
Posts: 42122
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: autoGPT for OpenAI

Postby Otto » Thu May 04, 2023 11:38 am

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
Otto
 
Posts: 6346
Joined: Fri Oct 07, 2005 7:07 pm

Re: autoGPT for OpenAI

Postby Antonio Linares » Thu May 04, 2023 11:54 am

Dear Otto,

yes, I think so

This is our more recent version:
https://github.com/FiveTechSoft/screenshots/blob/master/autogpt04.png?raw=true
Image
autogpt.prg
Code: Select all  Expand view  RUN
#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: 42122
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: autoGPT for OpenAI

Postby Antonio Linares » Thu May 04, 2023 12:21 pm

Using "temperature:

https://github.com/FiveTechSoft/screenshots/blob/master/autogpt05.png
Image
autogpt.prg
Code: Select all  Expand view  RUN
#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
User avatar
Antonio Linares
Site Admin
 
Posts: 42122
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Next

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 28 guests