Skip to content

Commit 2db94a9

Browse files
committed
Made the ai continuation work. Need to add a way to ignore failures
1 parent 1c53509 commit 2db94a9

File tree

2 files changed

+42
-16
lines changed

2 files changed

+42
-16
lines changed

ai.go

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1870,7 +1870,6 @@ func GetActionAIResponse(ctx context.Context, resp http.ResponseWriter, user Use
18701870

18711871
apiKey := os.Getenv("AI_API_KEY")
18721872
if apiKey == "" {
1873-
fmt.Println("[WARNING] AI_API_KEY not found, failing over to OPENAI_API_KEY...")
18741873
apiKey = os.Getenv("OPENAI_API_KEY")
18751874
}
18761875

@@ -5197,7 +5196,6 @@ func ValidateLabelAvailability(category string, availableLabels []string) {
51975196
*/
51985197
apiKey := os.Getenv("AI_API_KEY")
51995198
if apiKey == "" {
5200-
fmt.Println("[WARNING] AI_API_KEY not found, failing over to OPENAI_API_KEY...")
52015199
apiKey = os.Getenv("OPENAI_API_KEY")
52025200
}
52035201

@@ -5404,7 +5402,6 @@ func runAtomicChatRequest(ctx context.Context, user User, input QueryInput) (str
54045402

54055403
apiKey := os.Getenv("AI_API_KEY")
54065404
if apiKey == "" {
5407-
log.Println("[WARNING] AI_API_KEY not found, failing over to OPENAI_API_KEY...")
54085405
apiKey = os.Getenv("OPENAI_API_KEY")
54095406
}
54105407

@@ -6413,7 +6410,6 @@ func runSupportRequest(ctx context.Context, input QueryInput) string {
64136410

64146411
supportModel := os.Getenv("AI_SUPPORT_MODEL")
64156412
if supportModel == "" {
6416-
fmt.Println("[WARNING] AI_SUPPORT_MODEL not found, failing over to OPENAI_SUPPORT_MODEL...")
64176413
supportModel = os.Getenv("OPENAI_SUPPORT_MODEL")
64186414
}
64196415

@@ -6437,6 +6433,7 @@ func runSupportRequest(ctx context.Context, input QueryInput) string {
64376433
// createNextActions = true => mid-agent to decide next steps
64386434
func HandleAiAgentExecutionStart(execution WorkflowExecution, startNode Action, createNextActions bool) (Action, error) {
64396435

6436+
aiStarttime := time.Now().Unix()
64406437
// A handler to ensure we ALWAYS focus on next actions if a node starts late
64416438
// or is missing context, but has previous decisions
64426439
for _, result := range execution.Results {
@@ -6463,7 +6460,7 @@ func HandleAiAgentExecutionStart(execution WorkflowExecution, startNode Action,
64636460

64646461
// Create the OpenAI body struct
64656462
systemMessage := `INTRODUCTION:
6466-
You are a general AI agent which makes decisions based on user input. You should output a list of decisions based on the same input. Available actions within categories you can choose from are below. Only use the built-in actions 'answer' (ai analysis) or 'ask' (human analysis) if it fits 100%, is not the last action AND it can't be done with an API. These actions are a last resort. Do NOT ask about networking or authentication unless explicitly specified.
6463+
You are a general AI agent which makes decisions based on user input. You should output a list of decisions based on the same input. Available actions within categories you can choose from are below. Only use the built-in actions 'answer' (ai analysis) or 'ask' (human analysis) if it fits 100%, is not the last action AND it can't be done with an API. These actions are a last resort. Use Markdown with focus on human readability. Do NOT ask about networking or authentication unless explicitly specified.
64676464
64686465
END INTRODUCTION
64696466
---
@@ -6577,7 +6574,7 @@ SINGUL ACTIONS:
65776574
_ = oldActionResult
65786575
oldAgentOutput := AgentOutput{}
65796576
if createNextActions == true {
6580-
extraString = "This is a continuation of a previous execution. ONLY output decisions that fit AFTER the last FINISHED decision. DO NOT repeat previous decisions, and make sure your indexing is on point. Output as an array of decisions.\n\nIF you don't want to add any new decision, add AT LEAST one decision saying why it is finished, summarising EXACTLY what the user wants in a user-friendly Markdown format, OR the format the user asked for. Make the action and category 'finish', and put the reason in the 'reason' field. Do NOT summarize, explain or say things like 'user said'. JUST give exactly the final answer and nothing more."
6577+
extraString = "This is a continuation of a previous execution. ONLY output decisions that fit AFTER the last FINISHED decision. DO NOT repeat previous decisions, and make sure your indexing is on point. Output as an array of decisions.\n\nIF you don't want to add any new decision, add AT LEAST one decision saying why it is finished, summarising EXACTLY what the user wants in a user-friendly Markdown format, OR the format the user asked for. Make the action and category 'finish', and put the reason in the 'reason' field. Do NOT summarize, explain or say things like 'user said'. JUST give exactly the final answer and nothing more, in past tense. If any action failed, make sure to mention why"
65816578

65826579
userMessageChanged := false
65836580

@@ -6852,6 +6849,7 @@ RULES:
68526849
* NEVER ask the user for clarification, confirmations, or extra details unless it is absolutely unavoidable.
68536850
* If realtime data is required, ALWAYS use an Singul APIs to get it.
68546851
* ALWAYS output the same language as the original question.
6852+
* ALWAYS format questions using Markdown formatting, with a focus on human readability.
68556853
68566854
2. Action & Decision Rules
68576855
@@ -6864,7 +6862,7 @@ RULES:
68646862
* Fields can reference previous action outputs using {{action_name}}. Example: {"body": "{{previous_action.field}}"}.
68656863
* If questions are absolutely required, combine all into one "ask" action with multiple "question" fields. Do NOT create multiple separate decisions.
68666864
* Retry actions if the result was irrelevant. After three retries of a failed decision, add the finish decision.
6867-
* If any decision has failed, add the finish decision.
6865+
* If any decision has failed, add the finish decision with details about the failure.
68686866
* If a formatting is specified for the output, use it exactly how explained for the finish decision.
68696867
68706868
END RULES
@@ -7424,7 +7422,7 @@ FINALISING:
74247422
// A self-corrective measure for last-finished index
74257423
if decision.Action == "finish" || decision.Category == "finish" {
74267424
log.Printf("[INFO][%s] Decision %d is a finish decision. Marking the agent as finished...", execution.ExecutionId, decision.I)
7427-
agentOutput.Decisions[decisionIndex].RunDetails.StartedAt = time.Now().Unix()
7425+
agentOutput.Decisions[decisionIndex].RunDetails.StartedAt = aiStarttime
74287426
agentOutput.Decisions[decisionIndex].RunDetails.CompletedAt = time.Now().Unix()
74297427
agentOutput.Decisions[decisionIndex].RunDetails.Status = "FINISHED"
74307428

@@ -7546,7 +7544,7 @@ FINALISING:
75467544
// These aren't properly being updated in the db, so
75477545
// we need additional logic here to ensure it is being
75487546
// set/started
7549-
if nextActionType == "ask" || nextActionType == "finish" || nextActionType == "answer" {
7547+
if nextActionType == "ask" || nextActionType == "question" || nextActionType == "finish" || nextActionType == "answer" {
75507548
// Ensure we update all of it
75517549
for resultIndex, result := range execution.Results {
75527550
if result.Action.ID != startNode.ID {
@@ -7971,22 +7969,18 @@ func RunAiQuery(systemMessage, userMessage string, incomingRequest ...openai.Cha
79717969
orgId := os.Getenv("AI_API_ORG")
79727970

79737971
if len(apiKey) == 0 {
7974-
log.Println("[WARNING] AI_API_KEY not found, failing over to OPENAI_API_KEY...")
79757972
apiKey = os.Getenv("OPENAI_API_KEY")
79767973
}
79777974

79787975
if len(aiRequestUrl) == 0 {
7979-
log.Println("[WARNING] AI_API_URL not found, failing over to OPENAI_API_URL...")
79807976
aiRequestUrl = os.Getenv("OPENAI_API_URL")
79817977
}
79827978

79837979
if len(aiApiVersion) == 0 {
7984-
log.Println("[WARNING] AI_API_VERSION not found, failing over to OPENAI_API_VERSION...")
79857980
aiApiVersion = os.Getenv("OPENAI_API_VERSION")
79867981
}
79877982

79887983
if len(orgId) == 0 {
7989-
log.Println("[WARNING] AI_API_ORG not found, failing over to OPENAI_API_ORG...")
79907984
orgId = os.Getenv("OPENAI_API_ORG")
79917985
}
79927986

@@ -10514,12 +10508,10 @@ func HandleEditWorkflowWithLLM(resp http.ResponseWriter, request *http.Request)
1051410508
aiModel := os.Getenv("AI_MODEL")
1051510509

1051610510
if len(aiRequestUrl) == 0 {
10517-
log.Println("[WARNING] AI_API_URL not found, failing over to OPENAI_API_URL...")
1051810511
aiRequestUrl = os.Getenv("OPENAI_API_URL")
1051910512
}
1052010513

1052110514
if len(aiModel) == 0 {
10522-
log.Println("[WARNING] AI_MODEL not found, failing over to OPENAI_MODEL...")
1052310515
aiModel = os.Getenv("OPENAI_MODEL")
1052410516
}
1052510517

shared.go

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23801,15 +23801,49 @@ func PrepareWorkflowExecution(ctx context.Context, workflow Workflow, request *h
2380123801
continue
2380223802
}
2380323803

23804+
findContinue := false
23805+
if decision.Action == "finish" {
23806+
findContinue = true
23807+
}
23808+
23809+
log.Printf("[INFO][%s] Found the decision inside the agentic workflow to update: %s", execArg, decisionId)
23810+
2380423811
mappedArgument := map[string]string{}
2380523812
err = json.Unmarshal([]byte(execArg), &mappedArgument)
2380623813
if err != nil {
2380723814
log.Printf("[ERROR][%s] Failed unmarshalling execution argument during agentic decision handling: %s", execArg, err)
2380823815
break
2380923816
}
2381023817

23818+
log.Printf("Found mapped argument: %#v", mappedArgument)
23819+
2381123820
handledNumber := []string{}
2381223821
for key, value := range mappedArgument {
23822+
// Handles special case for Continuing an existing Agent run by modifying the "finish" action
23823+
if findContinue {
23824+
// The only key we care about in this case
23825+
if key == "continue" {
23826+
// Overwrite everything
23827+
decision.Fields = []Valuereplace{
23828+
Valuereplace{
23829+
Key: "continue",
23830+
Value: "How do you want to continue?",
23831+
Answer: value,
23832+
},
23833+
}
23834+
23835+
decision.Action = "ask"
23836+
decision.Tool = "ask"
23837+
decision.Category = "standalone"
23838+
decision.Reason = "Continued by adding task details"
23839+
23840+
fieldsChanged = true
23841+
break
23842+
}
23843+
23844+
continue
23845+
}
23846+
2381323847
if ArrayContains(handledNumber, key) {
2381423848
continue
2381523849
}
@@ -23855,7 +23889,7 @@ func PrepareWorkflowExecution(ctx context.Context, workflow Workflow, request *h
2385523889
}
2385623890

2385723891
if !fieldsChanged {
23858-
return workflowExecution, ExecInfo{}, fmt.Sprintf("Did not find the decision inside the agentic workflow to update %s", decisionId), errors.New("Did not find the decision to update")
23892+
return workflowExecution, ExecInfo{}, fmt.Sprintf("Could not find decision '%s' inside the agentic workflow", decisionId), errors.New(fmt.Sprintf("Could not find decision '%s'", decisionId))
2385923893
}
2386023894

2386123895
log.Printf("[INFO][%s] Found the decision inside the agentic workflow to update: %s", execArg, decisionId)

0 commit comments

Comments
 (0)