feat: automatic addition of goals to a current goal node, adding it to the plan, making sure the data stays correct. Also for the trigger nodes. :)

ref: N25B-434
This commit is contained in:
Björn Otgaar
2026-01-07 17:55:54 +01:00
parent e805c882fe
commit a4428c0d67
8 changed files with 137 additions and 66 deletions

View File

@@ -1,3 +1,6 @@
import { GoalReduce, type GoalNode } from "../nodes/GoalNode"
import { type Node } from "@xyflow/react"
export type Plan = {
name: string,
id: string,
@@ -5,13 +8,9 @@ export type Plan = {
}
export type PlanElement = Goal | Action
export type PlanElementTypes = ActionTypes | "goal"
export type Goal = {
id: string,
name: string,
plan: Plan,
can_fail: boolean,
id: string // we let the reducer figure out the rest dynamically
type: "goal"
}
@@ -20,22 +19,21 @@ export type Action = SpeechAction | GestureAction | LLMAction
export type SpeechAction = { id: string, text: string, type:"speech" }
export type GestureAction = { id: string, gesture: string, isTag: boolean, type:"gesture" }
export type LLMAction = { id: string, goal: string, type:"llm" }
export type ActionTypes = "speech" | "gesture" | "llm"
export type ActionTypes = "speech" | "gesture" | "llm";
// Extract the wanted information from a plan within the reducing of nodes
export function PlanReduce(plan?: Plan) {
export function PlanReduce(_nodes: Node[], plan?: Plan, ) {
if (!plan) return ""
return {
id: plan.id,
steps: plan.steps.map((x) => StepReduce(x))
steps: plan.steps.map((x) => StepReduce(x, _nodes))
}
}
// Extract the wanted information from a plan element.
function StepReduce(planElement: PlanElement) {
function StepReduce(planElement: PlanElement, _nodes: Node[]) : Record<string, unknown> {
// We have different types of plan elements, requiring differnt types of output
switch (planElement.type) {
case ("speech"):
@@ -57,12 +55,9 @@ function StepReduce(planElement: PlanElement) {
goal: planElement.goal,
}
case ("goal"):
return {
id: planElement.id,
plan: planElement.plan,
can_fail: planElement.can_fail,
};
default:
const nodes = _nodes
const thisNode = _nodes.find((x) => x.id === planElement.id)
return thisNode ? GoalReduce(thisNode, nodes) : {}
}
}
@@ -75,7 +70,7 @@ function StepReduce(planElement: PlanElement) {
export function DoesPlanIterate(plan?: Plan) : boolean {
// TODO: should recursively check plans that have goals (and thus more plans) in them.
if (!plan) return false
return plan.steps.filter((step) => step.type == "llm").length > 0 || (plan.steps.filter((x) => x.type == "goal").map((x) => DoesPlanIterate(x.plan))).includes(true);
return plan.steps.filter((step) => step.type == "llm").length > 0;
}
/**
@@ -99,4 +94,28 @@ export function GetActionValue(action: Action) {
return returnAction.goal;
default:
}
}
/**
* Inserts a goal into a plan
* @param plan: plan to insert goal into
* @param goalNode: the goal node to insert into the plan.
* @returns: a new plan with the goal inside.
*/
export function insertGoalInPlan(plan: Plan, goalNode: GoalNode): Plan {
const planElement : Goal = {
id: goalNode.id,
type: "goal",
}
return {
...plan,
steps: [...plan.steps, planElement],
}
}
export function deleteGoalInPlanByID(plan: Plan, goalID: string): Plan {
return {...plan,
steps: plan.steps.filter((x) => x.id !== goalID)
}
}