From 20e1c35a1e24f98158691ceec1a628c9bb1f23d8 Mon Sep 17 00:00:00 2001 From: Hari Krishna Date: Fri, 31 Jul 2026 00:36:28 +0530 Subject: [PATCH 01/11] feat: implement direct app call bypassing Singul's AI translation layer --- cloudSync.go | 226 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 220 insertions(+), 6 deletions(-) diff --git a/cloudSync.go b/cloudSync.go index 2623d526..16ea133b 100755 --- a/cloudSync.go +++ b/cloudSync.go @@ -1984,26 +1984,240 @@ func HandleSuborgScheduleRun(request *http.Request, workflow *Workflow) { } } +// runAgentDecisionDirectAppCall bypasses Singul's AI translation layer and +func runAgentDecisionDirectAppCall(execution WorkflowExecution, decision AgentDecision) (rawResult []byte, debugUrl string, appName string, categoryLabels []string, actionName string, err error) { + ctx := context.Background() + minUser := User{ + Username: execution.Workflow.Owner, + ActiveOrg: OrgMini{ + Id: execution.ExecutionOrg, + }, + } + + var ( + resolvedAppId string + resolvedAppName = decision.Tool + resolvedAuthId string + resolvedApp WorkflowApp + ) + + //startTime := time.Now() + cacheKey := fmt.Sprintf("agent_app_slug_%s_%s", execution.ExecutionOrg, strings.ToLower(decision.Tool)) + + if project.CacheDb { + if cachedId, cacheErr := GetCache(ctx, cacheKey); cacheErr == nil { + resolvedAppId = string(cachedId.([]uint8)) + if app, appErr := GetApp(ctx, resolvedAppId, minUser, false); appErr == nil { + resolvedApp = *app + resolvedAppName = app.Name + //log.Printf("[DEBUG][%s] DirectAppCall: Fast-resolved tool '%s' via cache -> ID: %s", execution.ExecutionId, decision.Tool, resolvedAppId) + } else { + resolvedAppId = "" // Cache hit but GetApp failed; fall through to full lookup + } + } + } + + if resolvedAppId == "" { + allApps, appsErr := GetPrioritizedApps(ctx, minUser) + if appsErr != nil { + //log.Printf("[WARNING][%s] DirectAppCall: Failed to list apps for name resolution: %s", execution.ExecutionId, appsErr) + } else { + toolLower := strings.ToLower(decision.Tool) + for _, app := range allApps { + if strings.ToLower(app.Name) == toolLower || + strings.ToLower(app.ID) == toolLower || + strings.ReplaceAll(strings.ToLower(app.Name), " ", "") == toolLower { + resolvedAppId = app.ID + resolvedAppName = app.Name + resolvedApp = app + //log.Printf("[DEBUG][%s] DirectAppCall: Resolved tool '%s' -> App '%s' (ID: %s)", execution.ExecutionId, decision.Tool, app.Name, app.ID) + if project.CacheDb { + SetCache(ctx, cacheKey, []byte(app.ID), 3600) + } + break + } + } + } + } + + //log.Printf("[DEBUG][%s] DirectAppCall: App resolution took %s", execution.ExecutionId, time.Since(startTime)) + + if resolvedAppId == "" { + return nil, "", decision.Tool, nil, "", fmt.Errorf("DirectAppCall: could not resolve tool '%s' to any installed app for org '%s'", decision.Tool, execution.ExecutionOrg) + } + + + authStart := time.Now() + allAuths, authErr := GetAllWorkflowAppAuth(ctx, execution.ExecutionOrg) + if authErr != nil { + log.Printf("[WARNING][%s] DirectAppCall: Failed to get app auths: %s", execution.ExecutionId, authErr) + } else { + for _, auth := range allAuths { + if auth.App.ID == resolvedAppId || strings.ToLower(auth.App.Name) == strings.ToLower(resolvedAppName) { + resolvedAuthId = auth.Id + //log.Printf("[DEBUG][%s] DirectAppCall: Found auth '%s' (defined: %v) for app '%s'", execution.ExecutionId, resolvedAuthId, auth.Defined, resolvedAppName) + if auth.Defined { + break + } + } + } + } + log.Printf("[DEBUG][%s] DirectAppCall: Auth resolution took %s", execution.ExecutionId, time.Since(authStart)) + + action := Action{ + AppID: resolvedAppId, + AppName: resolvedAppName, + Name: decision.Action, // overwritten below if schema match found + AuthenticationId: resolvedAuthId, + Parameters: []WorkflowAppActionParameter{}, + } + + decisionActionLower := strings.ToLower(decision.Action) + for _, appAction := range resolvedApp.Actions { + nameLower := strings.ToLower(appAction.Name) + labelLower := strings.ToLower(appAction.Label) + labelAsSnake := strings.ReplaceAll(labelLower, " ", "_") + + if nameLower == decisionActionLower || labelLower == decisionActionLower || labelAsSnake == decisionActionLower { + //log.Printf("[DEBUG][%s] DirectAppCall: Matched action '%s' -> schema name '%s'", execution.ExecutionId, decision.Action, appAction.Name) + for _, param := range appAction.Parameters { + action.Parameters = append(action.Parameters, param) + } + // Always use the canonical name from the schema so the backend recognises it + action.Name = appAction.Name + break + } + } + + // Overlay values the agent has explicitly provided, matching by parameter name. + for _, field := range decision.Fields { + val := field.Value + if len(field.Answer) > 0 { + val = field.Answer + } + + matched := false + for i, p := range action.Parameters { + if strings.ToLower(p.Name) == strings.ToLower(field.Key) { + action.Parameters[i].Value = val + matched = true + break + } + } + if !matched { + action.Parameters = append(action.Parameters, WorkflowAppActionParameter{ + Name: field.Key, + Value: val, + }) + } + } + + // Signal HandleRetValidation to skip the 30-second polling timeout. + action.Parameters = append(action.Parameters, WorkflowAppActionParameter{ + Name: "agent_bypass_validation", + Value: "true", + }) + + actionBytes, marshalErr := json.Marshal(action) + if marshalErr != nil { + return nil, "", resolvedAppName, nil, action.Name, fmt.Errorf("DirectAppCall: failed to marshal action: %s", marshalErr) + } + + + baseURL := os.Getenv("BASE_URL") + if len(baseURL) == 0 { + if v := os.Getenv("SHUFFLE_CLOUDRUN_URL"); len(v) > 0 { + baseURL = v + } else { + port := os.Getenv("PORT") + if len(port) == 0 { + port = "5001" + } + baseURL = fmt.Sprintf("http://localhost:%s", port) + } + } + + requestUrl := fmt.Sprintf("%s/api/v1/apps/%s/run?delete=false&execution_id=%s&authorization=%s&org_id=%s", baseURL, resolvedAppId, execution.ExecutionId, execution.Authorization, execution.ExecutionOrg) + + //log.Printf("[DEBUG][%s] DirectAppCall: Calling /run for tool '%s' action '%s' -> %s", execution.ExecutionId, resolvedAppName, action.Name, requestUrl) + + //httpStart := time.Now() + client := GetExternalClientWithTimeout(requestUrl, 0) + client.Timeout = 120 * time.Second + + req, reqErr := http.NewRequest("POST", requestUrl, bytes.NewBuffer(actionBytes)) + if reqErr != nil { + return nil, "", resolvedAppName, nil, action.Name, fmt.Errorf("DirectAppCall: failed to create request: %s", reqErr) + } + req.Header.Set("Content-Type", "application/json") + + resp, doErr := client.Do(req) + //log.Printf("[DEBUG][%s] DirectAppCall: HTTP call took %s", execution.ExecutionId, time.Since(httpStart)) + if doErr != nil { + //log.Printf("[ERROR][%s] DirectAppCall: HTTP call failed: %s", execution.ExecutionId, doErr) + return nil, "", resolvedAppName, nil, action.Name, doErr + } + defer resp.Body.Close() + + respBody, readErr := io.ReadAll(resp.Body) + if readErr != nil { + return nil, "", resolvedAppName, nil, action.Name, fmt.Errorf("DirectAppCall: failed to read response: %s", readErr) + } + + log.Printf("[INFO][%s] DirectAppCall: executeSingleAction returned status %d, body length %d", execution.ExecutionId, resp.StatusCode, len(respBody)) + + if resp.StatusCode >= 400 { + log.Printf("[ERROR][%s] DirectAppCall: executeSingleAction returned HTTP %d: %s", execution.ExecutionId, resp.StatusCode, string(respBody)) + return nil, requestUrl, resolvedAppName, nil, action.Name, fmt.Errorf("DirectAppCall: executeSingleAction returned HTTP %d", resp.StatusCode) + } + + var singleResult SingleResult + if jsonErr := json.Unmarshal(respBody, &singleResult); jsonErr == nil && len(singleResult.Result) > 0 { + status := "SUCCESS" + if !singleResult.Success { + status = "FAILURE" + } + + if status == "SUCCESS" { + var innerResult map[string]interface{} + if innerErr := json.Unmarshal([]byte(singleResult.Result), &innerResult); innerErr == nil { + if innerSuccess, ok := innerResult["success"].(bool); ok && !innerSuccess { + status = "FAILURE" + } + } + } + + log.Printf("[INFO][%s] DirectAppCall: result length %d, status %s", execution.ExecutionId, len(singleResult.Result), status) + return []byte(singleResult.Result), requestUrl, resolvedAppName, []string{}, action.Name, nil + } + + // Fallback: return raw body when the response isn't a well-formed SingleResult + return respBody, requestUrl, resolvedAppName, []string{}, action.Name, nil +} + // This is JUST for Singul actions with AI agents. // As AI Agents can have multiple types of runs, this could change every time. func RunAgentDecisionSingulActionHandler(execution WorkflowExecution, decision AgentDecision) ([]byte, string, string, []string, string, error) { debugUrl := "" - log.Printf("[INFO][%s] Running agent decision action '%s' with app '%s'. This is ran with Singul.", execution.ExecutionId, decision.Action, decision.Tool) + log.Printf("[INFO][%s] Running agent decision action '%s' with app '%s'.", execution.ExecutionId, decision.Action, decision.Tool) // Check if running in test mode if os.Getenv("AGENT_TEST_MODE") == "true" { log.Printf("[DEBUG][%s] AGENT_TEST_MODE enabled - using mock tool execution", execution.ExecutionId) - - // Call mock handler body, debugUrl, appName, err := RunAgentDecisionMockHandler(execution, decision) return body, debugUrl, appName, []string{}, "", err } - baseUrl := "https://shuffler.io" - if os.Getenv("BASE_URL") != "" { - baseUrl = os.Getenv("BASE_URL") + // AGENT_SKIP_SINGUL routes the decision directly to the app's /run endpoint, + if os.Getenv("AGENT_SKIP_SINGUL") == "true" { + //log.Printf("[INFO][%s] AGENT_SKIP_SINGUL enabled - calling app /run directly (no Singul translation)", execution.ExecutionId) + return runAgentDecisionDirectAppCall(execution, decision) } + _ = debugUrl + + baseUrl := "https://shuffler.io" + if os.Getenv("SHUFFLE_CLOUDRUN_URL") != "" { baseUrl = os.Getenv("SHUFFLE_CLOUDRUN_URL") } From bb99d9a247146d6f2f6314c759b5c465b38cc1d9 Mon Sep 17 00:00:00 2001 From: Hari Krishna Date: Fri, 31 Jul 2026 00:37:25 +0530 Subject: [PATCH 02/11] fix: update AI model to gpt-5.6-luna and add agent bypass validation parameter --- ai.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ai.go b/ai.go index 374d8828..9caa4452 100644 --- a/ai.go +++ b/ai.go @@ -8644,7 +8644,7 @@ data_filter: } // Set model based on environment - aiModel := "gpt-5-mini" + aiModel := "gpt-5.6-luna" newAiModel := os.Getenv("AI_MODEL") if newAiModel == "" { newAiModel = os.Getenv("OPENAI_MODEL") @@ -8934,6 +8934,10 @@ data_filter: Name: "headers", Value: "Content-Type: application/json\nAccept: application/json", }, + WorkflowAppActionParameter{ + Name: "agent_bypass_validation", + Value: "true", + }, } // Adding additional non-required params to make sure we get them parsed From 94ede4e42dcc8176685b34f9a7a3bca579fd6444 Mon Sep 17 00:00:00 2001 From: Hari Krishna Date: Fri, 31 Jul 2026 00:38:06 +0530 Subject: [PATCH 03/11] feat: add agent bypass validation parameter to HandleRetValidation function --- shared.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/shared.go b/shared.go index 20ae4673..b6f3ef18 100644 --- a/shared.go +++ b/shared.go @@ -23714,7 +23714,18 @@ func HandleRetValidation(ctx context.Context, workflowExecution WorkflowExecutio // FIXME: This is a custom fix for single action custom runs. // Wait for validation to have ran - if newExecution.Workflow.Validation.ValidationRan { + + agentBypass := false + if len(newExecution.Results[relevantIndex].Action.Parameters) > 0 { + for _, param := range newExecution.Results[relevantIndex].Action.Parameters { + if param.Name == "agent_bypass_validation" && param.Value == "true" { + agentBypass = true + break + } + } + } + + if newExecution.Workflow.Validation.ValidationRan || agentBypass { // FIXME: Check the return here. If there is an issue with custom_action doesn't exist, we rebuild it in realtime if strings.Contains(returnBody.Result, "custom_action doesn't exist") { From 837d9069508dc71e28fe4c60854d0b9b2680a6a9 Mon Sep 17 00:00:00 2001 From: Hari Krishna Date: Fri, 31 Jul 2026 15:08:48 +0530 Subject: [PATCH 04/11] added execution mode to the AgentOutput struct to control the tool execution --- structs.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/structs.go b/structs.go index d403e9a9..87a3e0c9 100755 --- a/structs.go +++ b/structs.go @@ -4800,6 +4800,9 @@ type AgentOutput struct { AllowedActions []string `json:"allowed_actions,omitempty" datastore:"allowed_actions"` Output string `json:"output,omitempty" datastore:"output"` + // ExecutionMode controls how tool actions are dispatched for this agent run. i.e singul or direct + ExecutionMode string `json:"execution_mode,omitempty" datastore:"execution_mode"` + // Usage tracking for guardrails LLMCallCount int `json:"llm_call_count,omitempty" datastore:"llm_call_count"` TotalTokens int64 `json:"total_tokens,omitempty" datastore:"total_tokens"` From c8e6a64a4107f0dd71a8aa9d8d260a0bd128ee48 Mon Sep 17 00:00:00 2001 From: Hari Krishna Date: Fri, 31 Jul 2026 15:09:50 +0530 Subject: [PATCH 05/11] add execution mode handling to HandleAiAgentExecutionStart function --- ai.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ai.go b/ai.go index 9caa4452..865f6963 100644 --- a/ai.go +++ b/ai.go @@ -7762,6 +7762,7 @@ func HandleAiAgentExecutionStart(execution WorkflowExecution, startNode Action, foundReasoning := "" enableQuestions := false + executionMode := "" // This is a part of making sure variables work properly, no matter where // in Shuffle we are @@ -7914,6 +7915,10 @@ func HandleAiAgentExecutionStart(execution WorkflowExecution, startNode Action, param.Name = "action" } + if param.Name == "execution_mode" { + executionMode = strings.ToLower(strings.TrimSpace(param.Value)) + } + if param.Name == "action" { param.Value = strings.ReplaceAll(param.Value, "app:undefined:api,", "") param.Value = strings.ReplaceAll(param.Value, "app:undefined:api", "") @@ -9343,12 +9348,13 @@ data_filter: Error: errorMessage, Decisions: mappedDecisions, - ExecutionId: execution.ExecutionId, - NodeId: startNode.ID, - StartedAt: time.Now().UnixMilli(), - CompletedAt: 0, + ExecutionId: execution.ExecutionId, + NodeId: startNode.ID, + StartedAt: time.Now().UnixMilli(), + CompletedAt: 0, - Memory: memorizationEngine, + Memory: memorizationEngine, + ExecutionMode: executionMode, AllowedActions: strings.Split(allowedActionString, ","), } From 3edcb485300bfe8318397a642147e96922fc61b8 Mon Sep 17 00:00:00 2001 From: Hari Krishna Date: Fri, 31 Jul 2026 15:13:20 +0530 Subject: [PATCH 06/11] add execution mode parameter to RunAgentDecisionSingulActionHandler for direct app calls --- cloudSync.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cloudSync.go b/cloudSync.go index 16ea133b..b59be204 100755 --- a/cloudSync.go +++ b/cloudSync.go @@ -2197,7 +2197,7 @@ func runAgentDecisionDirectAppCall(execution WorkflowExecution, decision AgentDe // This is JUST for Singul actions with AI agents. // As AI Agents can have multiple types of runs, this could change every time. -func RunAgentDecisionSingulActionHandler(execution WorkflowExecution, decision AgentDecision) ([]byte, string, string, []string, string, error) { +func RunAgentDecisionSingulActionHandler(execution WorkflowExecution, decision AgentDecision, executionMode string) ([]byte, string, string, []string, string, error) { debugUrl := "" log.Printf("[INFO][%s] Running agent decision action '%s' with app '%s'.", execution.ExecutionId, decision.Action, decision.Tool) @@ -2208,9 +2208,9 @@ func RunAgentDecisionSingulActionHandler(execution WorkflowExecution, decision A return body, debugUrl, appName, []string{}, "", err } - // AGENT_SKIP_SINGUL routes the decision directly to the app's /run endpoint, - if os.Getenv("AGENT_SKIP_SINGUL") == "true" { - //log.Printf("[INFO][%s] AGENT_SKIP_SINGUL enabled - calling app /run directly (no Singul translation)", execution.ExecutionId) + skipSingul := executionMode == "direct" || os.Getenv("AGENT_SKIP_SINGUL") == "true" + if skipSingul { + log.Printf("[INFO][%s] Calling app directly. ExecutionMode=%q EnvOverride=%v", execution.ExecutionId, executionMode, os.Getenv("AGENT_SKIP_SINGUL") == "true") return runAgentDecisionDirectAppCall(execution, decision) } @@ -2582,7 +2582,7 @@ func RunAgentDecisionAction(execution WorkflowExecution, agentOutput AgentOutput } } else { // Singul handler - rawResponse, debugUrl, appname, categoryLabels, actionName, err := RunAgentDecisionSingulActionHandler(execution, decision) + rawResponse, debugUrl, appname, categoryLabels, actionName, err := RunAgentDecisionSingulActionHandler(execution, decision, agentOutput.ExecutionMode) if len(appname) > 0 { decision.Tool = appname From d22f918ec02297ce4bf40c603aa80fe1ee1b88be Mon Sep 17 00:00:00 2001 From: Hari Krishna Date: Fri, 31 Jul 2026 17:18:01 +0530 Subject: [PATCH 07/11] update runAgentDecisionDirectAppCall to include timeout and debug URL in response --- cloudSync.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/cloudSync.go b/cloudSync.go index b59be204..181557fb 100755 --- a/cloudSync.go +++ b/cloudSync.go @@ -1997,7 +1997,7 @@ func runAgentDecisionDirectAppCall(execution WorkflowExecution, decision AgentDe var ( resolvedAppId string resolvedAppName = decision.Tool - resolvedAuthId string + //resolvedAuthId string resolvedApp WorkflowApp ) @@ -2047,6 +2047,7 @@ func runAgentDecisionDirectAppCall(execution WorkflowExecution, decision AgentDe } + /* authStart := time.Now() allAuths, authErr := GetAllWorkflowAppAuth(ctx, execution.ExecutionOrg) if authErr != nil { @@ -2063,12 +2064,13 @@ func runAgentDecisionDirectAppCall(execution WorkflowExecution, decision AgentDe } } log.Printf("[DEBUG][%s] DirectAppCall: Auth resolution took %s", execution.ExecutionId, time.Since(authStart)) + */ action := Action{ AppID: resolvedAppId, AppName: resolvedAppName, Name: decision.Action, // overwritten below if schema match found - AuthenticationId: resolvedAuthId, + //AuthenticationId: resolvedAuthId, Parameters: []WorkflowAppActionParameter{}, } @@ -2137,7 +2139,7 @@ func runAgentDecisionDirectAppCall(execution WorkflowExecution, decision AgentDe } } - requestUrl := fmt.Sprintf("%s/api/v1/apps/%s/run?delete=false&execution_id=%s&authorization=%s&org_id=%s", baseURL, resolvedAppId, execution.ExecutionId, execution.Authorization, execution.ExecutionOrg) + requestUrl := fmt.Sprintf("%s/api/v1/apps/%s/run?delete=false&execution_id=%s&authorization=%s&org_id=%s&timeout=115", baseURL, resolvedAppId, execution.ExecutionId, execution.Authorization, execution.ExecutionOrg) //log.Printf("[DEBUG][%s] DirectAppCall: Calling /run for tool '%s' action '%s' -> %s", execution.ExecutionId, resolvedAppName, action.Name, requestUrl) @@ -2166,9 +2168,11 @@ func runAgentDecisionDirectAppCall(execution WorkflowExecution, decision AgentDe log.Printf("[INFO][%s] DirectAppCall: executeSingleAction returned status %d, body length %d", execution.ExecutionId, resp.StatusCode, len(respBody)) + debugUrl = resp.Header.Get("X-Debug-Url") + if resp.StatusCode >= 400 { log.Printf("[ERROR][%s] DirectAppCall: executeSingleAction returned HTTP %d: %s", execution.ExecutionId, resp.StatusCode, string(respBody)) - return nil, requestUrl, resolvedAppName, nil, action.Name, fmt.Errorf("DirectAppCall: executeSingleAction returned HTTP %d", resp.StatusCode) + return nil, debugUrl, resolvedAppName, nil, action.Name, fmt.Errorf("DirectAppCall: executeSingleAction returned HTTP %d", resp.StatusCode) } var singleResult SingleResult @@ -2188,11 +2192,11 @@ func runAgentDecisionDirectAppCall(execution WorkflowExecution, decision AgentDe } log.Printf("[INFO][%s] DirectAppCall: result length %d, status %s", execution.ExecutionId, len(singleResult.Result), status) - return []byte(singleResult.Result), requestUrl, resolvedAppName, []string{}, action.Name, nil + return []byte(singleResult.Result), debugUrl, resolvedAppName, []string{}, action.Name, nil } // Fallback: return raw body when the response isn't a well-formed SingleResult - return respBody, requestUrl, resolvedAppName, []string{}, action.Name, nil + return respBody, debugUrl, resolvedAppName, []string{}, action.Name, nil } // This is JUST for Singul actions with AI agents. From e0e2f6230811f7cf240021f0a34bc66e48794ced Mon Sep 17 00:00:00 2001 From: Hari Krishna Date: Fri, 31 Jul 2026 17:24:44 +0530 Subject: [PATCH 08/11] changed model back to 5.4 mini --- ai.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ai.go b/ai.go index 865f6963..4fb174b9 100644 --- a/ai.go +++ b/ai.go @@ -8649,7 +8649,7 @@ data_filter: } // Set model based on environment - aiModel := "gpt-5.6-luna" + aiModel := "gpt-5.4-mini-2026-03-17" newAiModel := os.Getenv("AI_MODEL") if newAiModel == "" { newAiModel = os.Getenv("OPENAI_MODEL") From df007d0c0fcd3942fb13793171f042b897031176 Mon Sep 17 00:00:00 2001 From: Hari Krishna Date: Fri, 31 Jul 2026 17:25:52 +0530 Subject: [PATCH 09/11] commented-out agent_bypass_validation for now --- ai.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ai.go b/ai.go index 4fb174b9..f796f355 100644 --- a/ai.go +++ b/ai.go @@ -8939,10 +8939,10 @@ data_filter: Name: "headers", Value: "Content-Type: application/json\nAccept: application/json", }, - WorkflowAppActionParameter{ - Name: "agent_bypass_validation", - Value: "true", - }, + // WorkflowAppActionParameter{ + // Name: "agent_bypass_validation", + // Value: "true", + // }, } // Adding additional non-required params to make sure we get them parsed From 0d61d085f571ec8ee718d375f066124d92a0d0f9 Mon Sep 17 00:00:00 2001 From: Hari Krishna Date: Fri, 31 Jul 2026 17:27:11 +0530 Subject: [PATCH 10/11] fixed a comment line --- cloudSync.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudSync.go b/cloudSync.go index 181557fb..e9a3602d 100755 --- a/cloudSync.go +++ b/cloudSync.go @@ -1984,7 +1984,7 @@ func HandleSuborgScheduleRun(request *http.Request, workflow *Workflow) { } } -// runAgentDecisionDirectAppCall bypasses Singul's AI translation layer and +// runAgentDecisionDirectAppCall bypasses Singul and runs the app directly. func runAgentDecisionDirectAppCall(execution WorkflowExecution, decision AgentDecision) (rawResult []byte, debugUrl string, appName string, categoryLabels []string, actionName string, err error) { ctx := context.Background() minUser := User{ From 62dcfc709e66f9909c7584fe88131ac61f4e6ad4 Mon Sep 17 00:00:00 2001 From: Hari Krishna Date: Fri, 31 Jul 2026 17:31:59 +0530 Subject: [PATCH 11/11] added back support for BASE_URL environment variable --- cloudSync.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cloudSync.go b/cloudSync.go index e9a3602d..f6b333f7 100755 --- a/cloudSync.go +++ b/cloudSync.go @@ -2221,6 +2221,9 @@ func RunAgentDecisionSingulActionHandler(execution WorkflowExecution, decision A _ = debugUrl baseUrl := "https://shuffler.io" + if os.Getenv("BASE_URL") != "" { + baseUrl = os.Getenv("BASE_URL") + } if os.Getenv("SHUFFLE_CLOUDRUN_URL") != "" { baseUrl = os.Getenv("SHUFFLE_CLOUDRUN_URL")