Files
pepperplus-ui/src/pages/VisProgPage/visualProgrammingUI/components/Plan.tsx
2026-01-07 15:44:56 +01:00

103 lines
3.1 KiB
TypeScript

export type Plan = {
name: string,
id: string,
steps: PlanElement[],
}
export type PlanElement = Goal | Action
export type PlanElementTypes = ActionTypes | "goal"
export type Goal = {
id: string,
name: string,
plan: Plan,
can_fail: boolean,
type: "goal"
}
// Actions
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"
// Extract the wanted information from a plan within the reducing of nodes
export function PlanReduce(plan?: Plan) {
if (!plan) return ""
return {
name: plan.name,
id: plan.id,
steps: plan.steps.map((x) => StepReduce(x))
}
}
// Extract the wanted information from a plan element.
function StepReduce(planElement: PlanElement) {
// We have different types of plan elements, requiring differnt types of output
switch (planElement.type) {
case ("speech"):
return {
id: planElement.id,
text: planElement.text,
}
case ("gesture"):
return {
id: planElement.id,
gesture: {
type: planElement.isTag ? "tag" : "single",
name: planElement.gesture
},
}
case ("llm"):
return {
id: planElement.id,
goal: planElement.goal,
}
case ("goal"):
return {
id: planElement.id,
plan: planElement.plan,
can_fail: planElement.can_fail,
};
default:
}
}
/**
* Finds out whether the plan can iterate multiple times, or always stops after one action.
* This comes down to checking if the plan only has speech/ gesture actions, or others as well.
* @param plan: the plan to check
* @returns: a boolean
*/
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);
}
/**
* Returns the value of the action.
* Since typescript can't polymorphicly access the value field,
* we need to switch over the types and return the correct field.
* @param action: action to retrieve the value from
* @returns string | undefined
*/
export function GetActionValue(action: Action) {
let returnAction;
switch (action.type) {
case "gesture":
returnAction = action as GestureAction
return returnAction.gesture;
case "speech":
returnAction = action as SpeechAction
return returnAction.text;
case "llm":
returnAction = action as LLMAction
return returnAction.goal;
default:
}
}