From 02063a73b2b8edbc98039e5c8463108466e6e389 Mon Sep 17 00:00:00 2001 From: Pim Hutting Date: Thu, 22 Jan 2026 11:15:13 +0100 Subject: [PATCH] feat: added recursive mapping ref: N25B-400 --- .../visual_emotion_recognition_agent.py | 4 +--- .../user_interrupt/user_interrupt_agent.py | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/control_backend/agents/perception/visual_emotion_recognition_agent/visual_emotion_recognition_agent.py b/src/control_backend/agents/perception/visual_emotion_recognition_agent/visual_emotion_recognition_agent.py index 5344b9b..7f21d21 100644 --- a/src/control_backend/agents/perception/visual_emotion_recognition_agent/visual_emotion_recognition_agent.py +++ b/src/control_backend/agents/perception/visual_emotion_recognition_agent/visual_emotion_recognition_agent.py @@ -7,7 +7,6 @@ import numpy as np import zmq import zmq.asyncio as azmq from pydantic_core import ValidationError -import struct from control_backend.agents import BaseAgent from control_backend.agents.perception.visual_emotion_recognition_agent.visual_emotion_recognizer import ( # noqa @@ -89,7 +88,7 @@ class VisualEmotionRecognitionAgent(BaseAgent): while self._running: try: frame_bytes = await self.video_in_socket.recv() - + # Convert bytes to a numpy buffer nparr = np.frombuffer(frame_bytes, np.uint8) @@ -126,7 +125,6 @@ class VisualEmotionRecognitionAgent(BaseAgent): except zmq.Again: self.logger.warning("No video frame received within timeout.") - async def update_emotions(self, prev_emotions: set[str], emotions: set[str]): """ Compare emotions from previous window and current emotions, diff --git a/src/control_backend/agents/user_interrupt/user_interrupt_agent.py b/src/control_backend/agents/user_interrupt/user_interrupt_agent.py index 7320896..8bf5b77 100644 --- a/src/control_backend/agents/user_interrupt/user_interrupt_agent.py +++ b/src/control_backend/agents/user_interrupt/user_interrupt_agent.py @@ -9,7 +9,7 @@ from control_backend.agents.bdi.agentspeak_generator import AgentSpeakGenerator from control_backend.core.agent_system import InternalMessage from control_backend.core.config import settings from control_backend.schemas.belief_message import Belief, BeliefMessage -from control_backend.schemas.program import ConditionalNorm, Program +from control_backend.schemas.program import ConditionalNorm, Goal, Program from control_backend.schemas.ri_message import ( GestureCommand, PauseCommand, @@ -250,6 +250,18 @@ class UserInterruptAgent(BaseAgent): self._cond_norm_map = {} self._cond_norm_reverse_map = {} + def _register_goal(goal: Goal): + """Recursively register goals and their subgoals.""" + slug = AgentSpeakGenerator.slugify(goal) + self._goal_map[str(goal.id)] = slug + self._goal_reverse_map[slug] = str(goal.id) + + # Recursively check steps for subgoals + if goal.plan and goal.plan.steps: + for step in goal.plan.steps: + if isinstance(step, Goal): + _register_goal(step) + for phase in program.phases: for trigger in phase.triggers: slug = AgentSpeakGenerator.slugify(trigger) @@ -257,8 +269,7 @@ class UserInterruptAgent(BaseAgent): self._trigger_reverse_map[slug] = str(trigger.id) for goal in phase.goals: - self._goal_map[str(goal.id)] = AgentSpeakGenerator.slugify(goal) - self._goal_reverse_map[AgentSpeakGenerator.slugify(goal)] = str(goal.id) + _register_goal(goal) for goal, id in self._goal_reverse_map.items(): self.logger.debug(f"Goal mapping: UI ID {goal} -> {id}")