Skip to content

Commit 5d4cc75

Browse files
committed
Found a clear bug with auth mapping for single app execs & body field in Singul
1 parent 43e2aa2 commit 5d4cc75

File tree

3 files changed

+84
-44
lines changed

3 files changed

+84
-44
lines changed

ai.go

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -374,19 +374,21 @@ func FindHttpBody(fullBody []byte) (HTTPOutput, []byte, error) {
374374
return *httpOutput, []byte{}, err
375375
}
376376

377+
marshalledBody, err := json.Marshal(httpOutput.Body)
378+
if err != nil {
379+
log.Printf("[ERROR] Failed to marshal Schemaless HTTP Body response body back to byte: %s", err)
380+
return *httpOutput, []byte{}, err
381+
}
382+
383+
// FIXME: Why 404 excluded? Weird.
377384
if httpOutput.Status >= 300 && httpOutput.Status != 404 {
378385
if debug {
379-
log.Printf("[DEBUG] Translated action failed with status: %d. Rerun Autocorrecting feature!", httpOutput.Status)
386+
log.Printf("[INFO] Translated action failed with status: %d. Rerun Autocorrecting feature!. Body: %s", httpOutput.Status, string(marshalledBody))
380387
}
381388

382389
return *httpOutput, []byte{}, errors.New(fmt.Sprintf("Status: %d", httpOutput.Status))
383390
}
384391

385-
marshalledBody, err := json.Marshal(httpOutput.Body)
386-
if err != nil {
387-
log.Printf("[ERROR] Failed to marshal Schemaless HTTP Body response body back to byte: %s", err)
388-
return *httpOutput, []byte{}, err
389-
}
390392

391393
return *httpOutput, marshalledBody, nil
392394
}
@@ -688,6 +690,18 @@ func RunSelfCorrectingRequest(action Action, status int, additionalInfo, outputB
688690
inputBody += "\n}"
689691
}
690692

693+
// Check if the amount of {} in inputBody is the same
694+
if strings.Count(inputBody, "{") != strings.Count(inputBody, "}") {
695+
log.Printf("[ERROR] Input body has mismatched curly braces. Fixing it. InputBody: %s", inputBody)
696+
697+
// FIXME: Doesn't take into account key vs value, as it shouldn't change the value.
698+
if strings.Count(inputBody, "{") > strings.Count(inputBody, "}") {
699+
for i := 0; i < (strings.Count(inputBody, "{") - strings.Count(inputBody, "}")); i++ {
700+
inputBody += "}"
701+
}
702+
}
703+
}
704+
691705
// Append previous problems too
692706
//log.Printf("[Critical] InputBody generated here: %s", inputBody)
693707
//log.Printf("[Critical] OutputBodies generated here: %s", outputBodies)
@@ -899,10 +913,14 @@ func getBadOutputString(action Action, appname, inputdata, outputBody string, st
899913
}
900914

901915
if len(param.Value) > 0 {
902-
outputParams += fmt.Sprintf("\"%s\": \"%s\"", param.Name, param.Value)
916+
outputParams += fmt.Sprintf("\"%s\": \"%s\", ", param.Name, param.Value)
903917
}
904918
}
905919

920+
if len(outputParams) > 2 {
921+
outputParams = outputParams[:len(outputParams)-2]
922+
}
923+
906924
outputData := fmt.Sprintf("Fields: %s\n\nHTTP Status: %d\nHTTP error: %s", outputParams, status, outputBody)
907925

908926
if debug {
@@ -950,7 +968,9 @@ func UpdateActionBody(action WorkflowAppAction) (string, error) {
950968
systemMessage := fmt.Sprintf("Output a valid HTTP body to %s in %s. Only add required fields. Output ONLY JSON without explainers.", newName, action.AppName)
951969
userMessage := ""
952970

953-
log.Printf("\n\nBODY CREATE SYSTEM MESSAGE: %s\n\n", systemMessage)
971+
if debug {
972+
log.Printf("\n\n[DEBUG] BODY CREATE SYSTEM MESSAGE: %s\n\n", systemMessage)
973+
}
954974

955975
contentOutput, err := RunAiQuery(systemMessage, userMessage)
956976
if err != nil {
@@ -1269,8 +1289,8 @@ func AutofixAppLabels(app WorkflowApp, label string, keys []string) (WorkflowApp
12691289
return app, WorkflowAppAction{}
12701290
}
12711291

1272-
if strings.TrimSpace(strings.ToLower(label)) == "api" || label == "custom_action" {
1273-
log.Printf("[INFO] Skipping label '%s' in AutofixAppLabels for app %s (%s) as it's too generic", label, app.Name, app.ID)
1292+
if strings.TrimSpace(strings.ToLower(label)) == "api" || label == "custom_action" || len(label) < 5 {
1293+
//log.Printf("[INFO] Skipping label '%s' in AutofixAppLabels for app %s (%s) as it's too generic", label, app.Name, app.ID)
12741294
return app, WorkflowAppAction{}
12751295
}
12761296

@@ -6427,8 +6447,6 @@ func HandleAiAgentExecutionStart(execution WorkflowExecution, startNode Action)
64276447
continue
64286448
}
64296449

6430-
//lowerName := strings.ToLower(auth.App.Name)
6431-
log.Printf("APP CATEGORIES: %s\n", auth.App.Categories)
64326450
if len(auth.App.Categories) > 0 {
64336451
found := false
64346452
for _, preApp := range preferredApps {

cloudSync.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2043,7 +2043,7 @@ func HandleSuborgScheduleRun(request *http.Request, workflow *Workflow) {
20432043
// As AI Agents can have multiple types of runs, this could change every time.
20442044
func RunAgentDecisionSingulActionHandler(execution WorkflowExecution, decision AgentDecision) ([]byte, string, error) {
20452045
debugUrl := ""
2046-
log.Printf("[DEBUG][%s] Running agent decision action %s with tool %s", execution.ExecutionId, decision.Action, decision.Tool)
2046+
log.Printf("[INFO][%s] Running agent decision action '%s' with app '%s'. This is ran with Singul.", execution.ExecutionId, decision.Action, decision.Tool)
20472047

20482048
baseUrl := "https://shuffler.io"
20492049
if os.Getenv("BASE_URL") != "" {
@@ -2070,6 +2070,10 @@ func RunAgentDecisionSingulActionHandler(execution WorkflowExecution, decision A
20702070
SkipWorkflow: true,
20712071
}
20722072

2073+
if strings.ToLower(decision.Action) == "api" {
2074+
parsedAction.Action = "custom_action"
2075+
}
2076+
20732077
marshalledAction, err := json.Marshal(parsedAction)
20742078
if err != nil {
20752079
log.Printf("[ERROR][%s] Failed marshalling action in agent decision: %s", execution.ExecutionId, err)

shared.go

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18208,8 +18208,11 @@ func HandleKeyEncryption(data []byte, passphrase string) ([]byte, error) {
1820818208
}
1820918209

1821018210
func HandleKeyDecryption(data []byte, passphrase string) ([]byte, error) {
18211-
//log.Printf("[DEBUG] Passphrase: %s", passphrase)
18212-
//log.Printf("Decrypting key: %s", data)
18211+
//if debug {
18212+
// log.Printf("[DEBUG] Passphrase: %s", passphrase)
18213+
// log.Printf("Decrypting key: %s", data)
18214+
//}
18215+
1821318216
key, err := create32Hash(passphrase)
1821418217
if err != nil {
1821518218
log.Printf("[ERROR] Failed hashing in decrypt: %s", err)
@@ -18237,7 +18240,11 @@ func HandleKeyDecryption(data []byte, passphrase string) ([]byte, error) {
1823718240

1823818241
nonceSize := gcm.NonceSize()
1823918242
if nonceSize > len(parsedData) {
18240-
log.Printf("[ERROR] Nonce size is larger than parsed data. Returning as if this is valid.")
18243+
//log.Printf("[ERROR] Nonce size is larger than parsed data in decryption. Returning as if this is valid. This should _never_ happen, but typically only happens IF the source data is invalid (e.g. 1/20 keys)")
18244+
//if debug {
18245+
// log.Printf("Returned: '%s'. Len %d vs %d", string(parsedData), nonceSize, len(parsedData))
18246+
//}
18247+
1824118248
return data, nil
1824218249
}
1824318250

@@ -19831,9 +19838,12 @@ func PrepareSingleAction(ctx context.Context, user User, appId string, body []by
1983119838
}
1983219839

1983319840
// This is NOT a good solution, but a good bypass
19834-
if app.Authentication.Required {
19841+
if app.Authentication.Required || len(action.AuthenticationId) > 0 {
19842+
1983519843
if len(action.AuthenticationId) > 0 {
19836-
//log.Printf("\n\n[INFO] Found auth ID for single action: %s\n\n", action.AuthenticationId)
19844+
if debug {
19845+
log.Printf("[INFO][%s] Found auth ID for single action: %s", workflowExecution.ExecutionId, action.AuthenticationId)
19846+
}
1983719847

1983819848
// FIXME: How do we decide what fields to replace?
1983919849
// The problem now is that some auth fields are being set and others maybe are not
@@ -19911,7 +19921,7 @@ func PrepareSingleAction(ctx context.Context, user User, appId string, body []by
1991119921
}
1991219922

1991319923
if runValidationAction {
19914-
log.Printf("[INFO] Running validation action for %s for org %s (%s)", app.Name, user.ActiveOrg.Name, user.ActiveOrg.Id)
19924+
log.Printf("\n\n[INFO] SHOULD BE Running validation action for %s for org %s (%s)\n\n", app.Name, user.ActiveOrg.Name, user.ActiveOrg.Id)
1991519925

1991619926
// Find the action tagged to be used for validation:
1991719927
// 1. Find the action in the app
@@ -19925,10 +19935,9 @@ func PrepareSingleAction(ctx context.Context, user User, appId string, body []by
1992519935
//}
1992619936
}
1992719937

19928-
newParams := []WorkflowAppActionParameter{}
1992919938

1993019939
// Auth is handled in PrepareWorkflowExec, so this may not be needed
19931-
19940+
newParams := []WorkflowAppActionParameter{}
1993219941
originalUrl := ""
1993319942
for _, param := range action.Parameters {
1993419943
newName := GetValidParameters([]string{param.Name})
@@ -24732,35 +24741,35 @@ func PrepareWorkflowExecution(ctx context.Context, workflow Workflow, request *h
2473224741
}
2473324742

2473424743
// Special Action cleanup in case authentication etc has gone wrong
24735-
// FIXME: Focused on URL field for now
24744+
// FIXME: Focused on URL field primarily
2473624745
for actionIndex, _ := range workflowExecution.Workflow.Actions {
2473724746
found := []string{}
2473824747

2473924748
newparams := []WorkflowAppActionParameter{}
2474024749
for paramIndex, _ := range workflowExecution.Workflow.Actions[actionIndex].Parameters {
24741-
2474224750
param := workflowExecution.Workflow.Actions[actionIndex].Parameters[paramIndex]
24743-
if ArrayContains(found, param.Name) {
2474424751

24745-
// Replaces the field
24746-
for existingParamIndex, _ := range newparams {
24747-
if param.Name != newparams[existingParamIndex].Name {
24752+
if !ArrayContains(found, param.Name) {
24753+
newparams = append(newparams, param)
24754+
found = append(found, param.Name)
24755+
continue
24756+
}
2474824757

24749-
// Special for urls
24750-
if param.Name == "url" && strings.Contains(param.Value, "http") && !strings.Contains(newparams[existingParamIndex].Value, "http") {
24751-
newparams[existingParamIndex] = param
24752-
}
24758+
// Replaces the field
24759+
for existingParamIndex, _ := range newparams {
24760+
if param.Name != newparams[existingParamIndex].Name {
24761+
continue
24762+
}
2475324763

24754-
break
24755-
}
24764+
// Special for urls
24765+
if param.Name == "url" && strings.Contains(param.Value, "http") && !strings.Contains(newparams[existingParamIndex].Value, "http") {
24766+
newparams[existingParamIndex] = param
2475624767
}
2475724768

24758-
log.Printf("[ERROR][%s] Duplicate Field in Action: %#v", workflowExecution.ExecutionId, param.Name)
24759-
continue
24769+
break
2476024770
}
2476124771

24762-
newparams = append(newparams, param)
24763-
found = append(found, param.Name)
24772+
log.Printf("[ERROR][%s] Duplicate Field in Action: %#v", workflowExecution.ExecutionId, param.Name)
2476424773
}
2476524774

2476624775
workflowExecution.Workflow.Actions[actionIndex].Parameters = newparams
@@ -24879,9 +24888,10 @@ func GetAuthentication(ctx context.Context, workflowExecution WorkflowExecution,
2487924888
newValue, err := HandleKeyDecryption([]byte(field.Value), parsedKey)
2488024889
if err != nil {
2488124890
if field.Key != "access_token" {
24882-
log.Printf("[ERROR] Failed decryption (3) in auth org %s for %s: %s. Auth label: %s", curAuth.OrgId, field.Key, err, curAuth.Label)
24891+
log.Printf("[ERROR][%s] Failed decryption (3) in auth org %s for %s: %s. Auth label: %s", workflowExecution.ExecutionId, curAuth.OrgId, field.Key, err, curAuth.Label)
2488324892
setField = false
2488424893
//fieldLength = 0
24894+
2488524895
break
2488624896
} else {
2488724897
continue
@@ -24895,8 +24905,6 @@ func GetAuthentication(ctx context.Context, workflowExecution WorkflowExecution,
2489524905
if strings.HasSuffix(string(newValue), "/") {
2489624906
newValue = []byte(string(newValue)[0 : len(newValue)-1])
2489724907
}
24898-
24899-
//log.Printf("Value2 (%s): %s", field.Key, string(newValue))
2490024908
}
2490124909

2490224910
fieldLength += len(newValue)
@@ -25050,7 +25058,9 @@ func GetAuthentication(ctx context.Context, workflowExecution WorkflowExecution,
2505025058
}
2505125059
}
2505225060
} else if strings.ToLower(curAuth.Type) == "oauth2" {
25053-
//log.Printf("[DEBUG] Should replace auth parameters (Oauth2)")
25061+
if debug {
25062+
log.Printf("[DEBUG][%s] Should replace auth parameters (Oauth2)", workflowExecution.ExecutionId)
25063+
}
2505425064

2505525065
runRefresh := false
2505625066
refreshUrl := ""
@@ -25075,7 +25085,10 @@ func GetAuthentication(ctx context.Context, workflowExecution WorkflowExecution,
2507525085
}
2507625086

2507725087
if param.Key != "url" && param.Key != "access_token" {
25078-
//log.Printf("Skipping key %s", param.Key)
25088+
//if debug {
25089+
// log.Printf("[DEBUG][%s] Skipping key %s in auth %s (%s)", workflowExecution.ExecutionId, param.Key, curAuth.Label, curAuth.Id)
25090+
//}
25091+
2507925092
continue
2508025093
}
2508125094

@@ -25085,6 +25098,8 @@ func GetAuthentication(ctx context.Context, workflowExecution WorkflowExecution,
2508525098
})
2508625099
}
2508725100

25101+
// FIXME: Refresh isn't required ALL the time
25102+
// but we currently are doing it.
2508825103
runRefresh = true
2508925104
if runRefresh {
2509025105
user := User{
@@ -25097,7 +25112,9 @@ func GetAuthentication(ctx context.Context, workflowExecution WorkflowExecution,
2509725112
if len(refreshUrl) == 0 {
2509825113
log.Printf("[ERROR] No Oauth2 request to run, as no refresh url is set!")
2509925114
} else {
25100-
//log.Printf("[INFO] Running Oauth2 request with URL %s", refreshUrl)
25115+
if debug {
25116+
log.Printf("[INFO][%s] Running Oauth2 request with URL %s", workflowExecution.ExecutionId, refreshUrl)
25117+
}
2510125118

2510225119
newAuth, err := RunOauth2Request(ctx, user, curAuth, true)
2510325120
if err != nil {
@@ -25130,7 +25147,7 @@ func GetAuthentication(ctx context.Context, workflowExecution WorkflowExecution,
2513025147
}
2513125148

2513225149
// FIXME: There used to be code here to stop the app, but for now we just continue with the old tokens
25133-
}
25150+
}
2513425151

2513525152
allAuths[authIndex] = newAuth
2513625153

@@ -25145,6 +25162,7 @@ func GetAuthentication(ctx context.Context, workflowExecution WorkflowExecution,
2514525162
newParams = append(newParams, WorkflowAppActionParameter{
2514625163
Name: param.Key,
2514725164
Value: param.Value,
25165+
Configuration: true,
2514825166
})
2514925167
}
2515025168
}

0 commit comments

Comments
 (0)