103 lines
3.1 KiB
TypeScript
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:
|
|
}
|
|
} |