@ -261,6 +261,13 @@ func checkout(w http.ResponseWriter, req *http.Request) {
}
}
func completion ( w http . ResponseWriter , req * http . Request ) {
func completion ( w http . ResponseWriter , req * http . Request ) {
logStr := "" // print all the logs at once, to make it so the printed output as multiple completions are happening at once, is coherent
defer func ( ) {
if len ( logStr ) > 0 {
log . Println ( logStr )
}
} ( )
req . Body = http . MaxBytesReader ( w , req . Body , 1024 * 1024 ) // no sending huge files to crash the server
req . Body = http . MaxBytesReader ( w , req . Body , 1024 * 1024 ) // no sending huge files to crash the server
if doCors {
if doCors {
w . Header ( ) . Set ( "Access-Control-Allow-Origin" , "*" )
w . Header ( ) . Set ( "Access-Control-Allow-Origin" , "*" )
@ -268,7 +275,7 @@ func completion(w http.ResponseWriter, req *http.Request) {
bodyBytes , err := io . ReadAll ( req . Body )
bodyBytes , err := io . ReadAll ( req . Body )
if err != nil {
if err != nil {
w . WriteHeader ( http . StatusBadRequest )
w . WriteHeader ( http . StatusBadRequest )
log . Println ( "Bad error: " , err )
log Str += fmt . Sprintf ( "Bad error: " , err ) + "\n"
return
return
} else {
} else {
bodyString := string ( bodyBytes )
bodyString := string ( bodyBytes )
@ -276,7 +283,7 @@ func completion(w http.ResponseWriter, req *http.Request) {
if len ( splitBody ) != 2 {
if len ( splitBody ) != 2 {
w . WriteHeader ( http . StatusBadRequest )
w . WriteHeader ( http . StatusBadRequest )
log . P rintf( "Weird body length %d not 2\n" , len ( splitBody ) )
log Str += fmt . Sp rintf( "Weird body length %d not 2\n" , len ( splitBody ) )
return
return
}
}
var promptString string = splitBody [ 1 ]
var promptString string = splitBody [ 1 ]
@ -286,7 +293,7 @@ func completion(w http.ResponseWriter, req *http.Request) {
rejected := false
rejected := false
cleanTimedOut ( )
cleanTimedOut ( )
if len ( stripe . Key ) == 0 {
if len ( stripe . Key ) == 0 {
log . P rintf( "Stripe capabilities are disabled, so automatically allowing completion" )
log Str += fmt . Sp rintf( "Stripe capabilities are disabled, so automatically allowing completion" )
} else {
} else {
if len ( userToken ) != 4 {
if len ( userToken ) != 4 {
// where I do the IP rate limiting
// where I do the IP rate limiting
@ -310,32 +317,32 @@ func completion(w http.ResponseWriter, req *http.Request) {
var thisUser User
var thisUser User
thisUserCode , err := codes . ParseUserCode ( userToken )
thisUserCode , err := codes . ParseUserCode ( userToken )
if err != nil {
if err != nil {
log . P rintf( "Error: Failed to parse user token %s\n" , userToken )
log Str += fmt . Sp rintf( "Error: Failed to parse user token %s\n" , userToken )
rejected = true
rejected = true
} else {
} else {
err := db . First ( & thisUser , thisUserCode ) . Error
err := db . First ( & thisUser , thisUserCode ) . Error
if err != nil {
if err != nil {
log . P rintf( "User code %d string %s couldn't be found in the database: %s\n" , thisUserCode , userToken , err )
log Str += fmt . Sp rintf( "User code %d string %s couldn't be found in the database: %s\n" , thisUserCode , userToken , err )
rejected = true
rejected = true
} else {
} else {
if isUserOld ( thisUser ) {
if isUserOld ( thisUser ) {
log . Println ( "User code " + userToken + " is old, not valid" )
log Str += fmt . Sprintf ( "User code " + userToken + " is old, not valid" ) + "\n"
db . Delete ( & thisUser )
db . Delete ( & thisUser )
rejected = true
rejected = true
} else {
} else {
// now have valid user, in the database, to be rate limit checked
// now have valid user, in the database, to be rate limit checked
// rate limiting based on user token
// rate limiting based on user token
if ! thisUser . IsFulfilled {
if ! thisUser . IsFulfilled {
log . Println ( "Unfulfilled user trying to play, might've been unresponded to event. Retrieving backlog of unfulfilled events...\n" )
log Str += fmt . Sprintf ( "Unfulfilled user trying to play, might've been unresponded to event. Retrieving backlog of unfulfilled events...\n" ) + "\n"
params := & stripe . EventListParams { }
params := & stripe . EventListParams { }
params . Filters . AddFilter ( "delivery_success" , "" , "false" )
params . Filters . AddFilter ( "delivery_success" , "" , "false" )
i := event . List ( params )
i := event . List ( params )
for i . Next ( ) {
for i . Next ( ) {
e := i . Event ( )
e := i . Event ( )
log . Println ( "Unfulfilled event! Of type %s. Handling...\n" , e . Type )
log Str += fmt . Sprintf ( "Unfulfilled event! Of type %s. Handling...\n" , e . Type ) + "\n"
err := handleEvent ( * e )
err := handleEvent ( * e )
if err != nil {
if err != nil {
log . Println ( "Failed to fulfill unfulfilled event: %s\n" , err )
log Str += fmt . Sprintf ( "Failed to fulfill unfulfilled event: %s\n" , err ) + "\n"
}
}
}
}
}
}
@ -348,7 +355,7 @@ func completion(w http.ResponseWriter, req *http.Request) {
daypassTimedOut [ thisUserCode ] = currentTime ( )
daypassTimedOut [ thisUserCode ] = currentTime ( )
}
}
} else {
} else {
log . Println ( "User with code and existing entry in database was not fulfilled, and wanted to play... Very bad. Usercode: %s\n" , thisUserCode )
log Str += fmt . Sprintf ( "User with code and existing entry in database was not fulfilled, and wanted to play... Very bad. Usercode: %s\n" , thisUserCode ) + "\n"
}
}
}
}
}
}
@ -361,7 +368,7 @@ func completion(w http.ResponseWriter, req *http.Request) {
}
}
if logResponses {
if logResponses {
log . Println ( "Println line prompt string: " , promptString )
log Str += fmt . Sprintf ( "Println line prompt string: " , promptString ) + "\n"
}
}
ctx := context . Background ( )
ctx := context . Background ( )
@ -380,7 +387,7 @@ func completion(w http.ResponseWriter, req *http.Request) {
}
}
resp , err := c . CreateCompletion ( ctx , req )
resp , err := c . CreateCompletion ( ctx , req )
if err != nil {
if err != nil {
log . Println ( "Error Failed to generate, failed to create completion: " , err )
log Str += fmt . Sprintf ( "Error Failed to generate, failed to create completion: " , err ) + "\n"
w . WriteHeader ( http . StatusInternalServerError )
w . WriteHeader ( http . StatusInternalServerError )
return
return
}
}
@ -388,24 +395,24 @@ func completion(w http.ResponseWriter, req *http.Request) {
} else {
} else {
// parse the json walter
// parse the json walter
var parsed [ ] ChatGPTElem
var parsed [ ] ChatGPTElem
log . Printf ( "----------------------------------------------------------" )
logStr += fmt . Sprintf ( "----------------------------------------------------------" )
defer log . Printf ( "----------------------------------------------------------" )
logStr += fmt . Sprintf ( "Parsing prompt string `%s`\n\n\n" , promptString )
log . Printf ( "Parsing prompt string `%s`\n\n\n" , promptString )
err = json . Unmarshal ( [ ] byte ( promptString ) , & parsed )
err = json . Unmarshal ( [ ] byte ( promptString ) , & parsed )
if err != nil {
if err != nil {
log . Println ( "Error bad json given for prompt: " , err )
log Str += fmt . Sprintf ( "Error bad json given for prompt: " , err ) + "\n"
w . WriteHeader ( http . StatusBadRequest )
w . WriteHeader ( http . StatusBadRequest )
return
return
}
}
messages := make ( [ ] openai . ChatCompletionMessage , 0 )
messages := make ( [ ] openai . ChatCompletionMessage , 0 )
for _ , elem := range parsed {
for _ , elem := range parsed {
log . P rintf( "Making message with role %s and Content `%s`...\n" , elem . ElemType , elem . Content )
log Str += fmt . Sp rintf( "Making message with role %s and Content `%s`...\n" , elem . ElemType , elem . Content )
messages = append ( messages , openai . ChatCompletionMessage {
messages = append ( messages , openai . ChatCompletionMessage {
Role : elem . ElemType ,
Role : elem . ElemType ,
Content : elem . Content ,
Content : elem . Content ,
} )
} )
}
}
logStr += fmt . Sprintf ( "----------------------------------------------------------" )
if false { // temporary testing AI
if false { // temporary testing AI
response = "ACT_holo \"Garbage\""
response = "ACT_holo \"Garbage\""
@ -420,19 +427,19 @@ func completion(w http.ResponseWriter, req *http.Request) {
} ,
} ,
)
)
if err != nil {
if err != nil {
log . Println ( "Error Failed to generate: " , err )
log Str += fmt . Sprintf ( "Error Failed to generate: " , err ) + "\n"
w . WriteHeader ( http . StatusInternalServerError )
w . WriteHeader ( http . StatusInternalServerError )
return
return
}
}
log . P rintf( "Full response: \n````\n%s\n````\n" , resp )
log Str += fmt . Sp rintf( "Full response: \n````\n%s\n````\n" , resp )
response = resp . Choices [ 0 ] . Message . Content
response = resp . Choices [ 0 ] . Message . Content
}
}
/ *
/ *
with_action := strings . SplitAfter ( response , "ACT_" )
with_action := strings . SplitAfter ( response , "ACT_" )
if len ( with_action ) != 2 {
if len ( with_action ) != 2 {
log . P rintf( "Could not find action in response string `%s`\n" , response )
log Str += fmt . Sp rintf( "Could not find action in response string `%s`\n" , response )
w . WriteHeader ( http . StatusInternalServerError ) // game should send a new retry request after this
w . WriteHeader ( http . StatusInternalServerError ) // game should send a new retry request after this
return
return
}
}
@ -444,7 +451,7 @@ func completion(w http.ResponseWriter, req *http.Request) {
between_quotes := strings . Split ( response , "\"" )
between_quotes := strings . Split ( response , "\"" )
// [action] " [stuff] " [anything extra]
// [action] " [stuff] " [anything extra]
if len ( between_quotes ) < 2 {
if len ( between_quotes ) < 2 {
log . P rintf( "Could not find enough quotes in response string `%s`\n" , response )
log Str += fmt . Sp rintf( "Could not find enough quotes in response string `%s`\n" , response )
w . WriteHeader ( http . StatusInternalServerError )
w . WriteHeader ( http . StatusInternalServerError )
return
return
}
}
@ -452,8 +459,8 @@ func completion(w http.ResponseWriter, req *http.Request) {
* /
* /
}
}
if logResponses {
if logResponses {
log . Println ( "Println response: `" , response + "`" )
log Str += fmt . Sprintf ( "Println response: `" , response + "`" ) + "\n"
log . Println ( )
log Str += "\n"
}
}
fmt . Fprintf ( w , "1%s" , response + "\n" )
fmt . Fprintf ( w , "1%s" , response + "\n" )
}
}