Files
pepperplus-cb/src/control_backend/schemas/program.py
2026-01-19 12:10:58 +01:00

243 lines
5.7 KiB
Python

from enum import Enum
from typing import Literal
from pydantic import UUID4, BaseModel
class ProgramElement(BaseModel):
"""
Represents a basic element of our behavior program.
:ivar name: The researcher-assigned name of the element.
:ivar id: Unique identifier.
"""
name: str
id: UUID4
# To make program elements hashable
model_config = {"frozen": True}
class LogicalOperator(Enum):
"""
Logical operators for combining beliefs.
"""
AND = "AND"
OR = "OR"
type Belief = KeywordBelief | SemanticBelief | InferredBelief | EmotionBelief
type BasicBelief = KeywordBelief | SemanticBelief | EmotionBelief
class KeywordBelief(ProgramElement):
"""
Represents a belief that is activated when a specific keyword is detected in the user's speech.
:ivar keyword: The string to look for in the transcription.
"""
name: str = ""
keyword: str
class SemanticBelief(ProgramElement):
"""
Represents a belief whose truth value is determined by an LLM analyzing the conversation
context.
:ivar description: A natural language description of what this belief represents,
used as a prompt for the LLM.
"""
description: str
class InferredBelief(ProgramElement):
"""
Represents a belief derived from other beliefs using logical operators.
:ivar operator: The :class:`LogicalOperator` (AND/OR) to apply.
:ivar left: The left operand (another belief).
:ivar right: The right operand (another belief).
"""
name: str = ""
operator: LogicalOperator
left: Belief
right: Belief
class EmotionBelief(ProgramElement):
"""
Represents a belief that is set when a certain emotion is detected.
:ivar emotion: The emotion on which this belief gets set.
"""
name: str = ""
emotion: str
class Norm(ProgramElement):
"""
Base class for behavioral norms that guide the robot's interactions.
:ivar norm: The textual description of the norm.
:ivar critical: Whether this norm is considered critical and should be strictly enforced.
"""
name: str = ""
norm: str
critical: bool = False
class BasicNorm(Norm):
"""
A simple behavioral norm that is always considered for activation when its phase is active.
"""
pass
class ConditionalNorm(Norm):
"""
A behavioral norm that is only active when a specific condition (belief) is met.
:ivar condition: The :class:`Belief` that must hold for this norm to be active.
"""
condition: Belief
type PlanElement = Goal | Action
class Plan(ProgramElement):
"""
Represents a list of steps to execute. Each of these steps can be a goal (with its own plan)
or a simple action.
:ivar steps: The actions or subgoals to execute, in order.
"""
name: str = ""
steps: list[PlanElement]
class BaseGoal(ProgramElement):
"""
Represents an objective to be achieved. This base version does not include a plan to achieve
this goal, and is used in semantic belief extraction.
:ivar description: A description of the goal, used to determine if it has been achieved.
:ivar can_fail: Whether we can fail to achieve the goal after executing the plan.
"""
description: str = ""
can_fail: bool = True
class Goal(BaseGoal):
"""
Represents an objective to be achieved. To reach the goal, we should execute the corresponding
plan. It inherits from the BaseGoal a variable `can_fail`, which if true will cause the
completion to be determined based on the conversation.
Instances of this goal are not hashable because a plan is not hashable.
:ivar plan: The plan to execute.
"""
plan: Plan
type Action = SpeechAction | GestureAction | LLMAction
class SpeechAction(ProgramElement):
"""
An action where the robot speaks a predefined literal text.
:ivar text: The text content to be spoken.
"""
name: str = ""
text: str
class Gesture(BaseModel):
"""
Defines a physical gesture for the robot to perform.
:ivar type: Whether to use a specific "single" gesture or a random one from a "tag" category.
:ivar name: The identifier for the gesture or tag.
"""
type: Literal["tag", "single"]
name: str
class GestureAction(ProgramElement):
"""
An action where the robot performs a physical gesture.
:ivar gesture: The :class:`Gesture` definition.
"""
name: str = ""
gesture: Gesture
class LLMAction(ProgramElement):
"""
An action that triggers an LLM-generated conversational response.
:ivar goal: A temporary conversational goal to guide the LLM's response generation.
"""
name: str = ""
goal: str
class Trigger(ProgramElement):
"""
Defines a reactive behavior: when the condition (belief) is met, the plan is executed.
:ivar condition: The :class:`Belief` that triggers this behavior.
:ivar plan: The :class:`Plan` to execute upon activation.
"""
condition: Belief
plan: Plan
class Phase(ProgramElement):
"""
A logical stage in the interaction program, grouping norms, goals, and triggers.
:ivar norms: List of norms active during this phase.
:ivar goals: List of goals the robot pursues in this phase.
:ivar triggers: List of reactive behaviors defined for this phase.
"""
name: str = ""
norms: list[BasicNorm | ConditionalNorm]
goals: list[Goal]
triggers: list[Trigger]
class Program(BaseModel):
"""
The top-level container for a complete robot behavior definition.
:ivar phases: An ordered list of :class:`Phase` objects defining the interaction flow.
"""
phases: list[Phase]
if __name__ == "__main__":
input = input("Enter program JSON: ")
program = Program.model_validate_json(input)
print(program)