feat: more robust belief management
ref: N25B-316
This commit is contained in:
@@ -8,7 +8,7 @@ formatters:
|
||||
# Console output
|
||||
colored:
|
||||
(): "colorlog.ColoredFormatter"
|
||||
format: "{log_color}{asctime} | {levelname:11} | {name:70} | {message}"
|
||||
format: "{log_color}{asctime}.{msecs:03.0f} | {levelname:11} | {name:70} | {message}"
|
||||
style: "{"
|
||||
datefmt: "%H:%M:%S"
|
||||
|
||||
|
||||
@@ -13,11 +13,12 @@ from control_backend.schemas.ri_message import SpeechCommand
|
||||
|
||||
|
||||
class BDICoreAgent(BaseAgent):
|
||||
bdi_agent: agentspeak.runtime.Agent
|
||||
|
||||
def __init__(self, name: str, asl: str):
|
||||
super().__init__(name)
|
||||
self.asl_file = asl
|
||||
self.env = agentspeak.runtime.Environment()
|
||||
self.bdi_agent = None
|
||||
self.actions = agentspeak.stdlib.actions
|
||||
|
||||
async def setup(self) -> None:
|
||||
@@ -42,7 +43,6 @@ class BDICoreAgent(BaseAgent):
|
||||
async def _bdi_loop(self):
|
||||
"""Runs the AgentSpeak BDI loop."""
|
||||
while self._running:
|
||||
assert self.bdi_agent is not None
|
||||
self.bdi_agent.step()
|
||||
await asyncio.sleep(0.01)
|
||||
|
||||
@@ -74,30 +74,72 @@ class BDICoreAgent(BaseAgent):
|
||||
)
|
||||
await self.send(out_msg)
|
||||
|
||||
# TODO: test way of adding beliefs
|
||||
def _add_beliefs(self, beliefs: dict[str, list[str]]):
|
||||
if not beliefs:
|
||||
return
|
||||
|
||||
for belief_name, args in beliefs.items():
|
||||
self._add_belief(belief_name, args)
|
||||
for name, args in beliefs.items():
|
||||
self._add_belief(name, args)
|
||||
|
||||
if belief_name == "user_said":
|
||||
self._add_belief("new_message")
|
||||
|
||||
def _add_belief(self, belief_name: str, arguments: Iterable[str] = []):
|
||||
args = (agentspeak.Literal(arg) for arg in arguments)
|
||||
literal_belief = agentspeak.Literal(belief_name, args)
|
||||
def _add_belief(self, name: str, args: Iterable[str] = []):
|
||||
new_args = (agentspeak.Literal(arg) for arg in args)
|
||||
term = agentspeak.Literal(name, new_args)
|
||||
|
||||
assert self.bdi_agent is not None
|
||||
|
||||
self.bdi_agent.call(
|
||||
agentspeak.Trigger.addition,
|
||||
agentspeak.GoalType.belief,
|
||||
literal_belief,
|
||||
term,
|
||||
agentspeak.runtime.Intention(),
|
||||
)
|
||||
self.logger.debug(f"Added belief {belief_name}({','.join(arguments)})")
|
||||
self.logger.debug(f"Added belief {self.format_belief_string(name, args)}")
|
||||
|
||||
def _remove_belief(self, name: str, args: Iterable[str]):
|
||||
"""
|
||||
Removes a specific belief (with arguments), if it exists.
|
||||
"""
|
||||
new_args = (agentspeak.Literal(arg) for arg in args)
|
||||
term = agentspeak.Literal(name, new_args)
|
||||
|
||||
assert self.bdi_agent is not None
|
||||
|
||||
result = self.bdi_agent.call(
|
||||
agentspeak.Trigger.removal,
|
||||
agentspeak.GoalType.belief,
|
||||
term,
|
||||
agentspeak.runtime.Intention(),
|
||||
)
|
||||
|
||||
if result:
|
||||
self.logger.debug(f"Removed belief {self.format_belief_string(name, args)}")
|
||||
else:
|
||||
self.logger.debug("Failed to remove belief (it was not in the belief base).")
|
||||
|
||||
# TODO: decide if this is needed
|
||||
def _remove_all_with_name(self, name: str):
|
||||
"""
|
||||
Removes all beliefs that match the given `name`.
|
||||
"""
|
||||
assert self.bdi_agent is not None
|
||||
|
||||
relevant_groups = []
|
||||
for key in self.bdi_agent.beliefs:
|
||||
if key[0] == name:
|
||||
relevant_groups.append(key)
|
||||
|
||||
removed_count = 0
|
||||
for group in relevant_groups:
|
||||
for belief in self.bdi_agent.beliefs[group]:
|
||||
self.bdi_agent.call(
|
||||
agentspeak.Trigger.removal,
|
||||
agentspeak.GoalType.belief,
|
||||
belief,
|
||||
agentspeak.runtime.Intention(),
|
||||
)
|
||||
removed_count += 1
|
||||
|
||||
self.logger.debug(f"Removed {removed_count} beliefs.")
|
||||
|
||||
def _add_custom_actions(self) -> None:
|
||||
"""Add any custom actions here."""
|
||||
@@ -119,3 +161,10 @@ class BDICoreAgent(BaseAgent):
|
||||
msg = InternalMessage(to=settings.agent_settings.llm_name, sender=self.name, body=text)
|
||||
await self.send(msg)
|
||||
self.logger.info("Message sent to LLM agent: %s", text)
|
||||
|
||||
@staticmethod
|
||||
def format_belief_string(name: str, args: Iterable[str] = []):
|
||||
"""
|
||||
Given a belief's name and its args, return a string of the form "name(*args)"
|
||||
"""
|
||||
return f"{name}{'(' if args else ''}{','.join(args)}{')' if args else ''}"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
+new_message : user_said(Message) <-
|
||||
-new_message;
|
||||
.reply(Message).
|
||||
+user_said(NewMessage) <-
|
||||
-user_said(NewMessage);
|
||||
.reply(NewMessage).
|
||||
|
||||
@@ -67,7 +67,7 @@ class VADAgent(BaseAgent):
|
||||
self.model = None
|
||||
|
||||
async def setup(self):
|
||||
self.logger.info("Setting up %s", self.jid)
|
||||
self.logger.info("Setting up %s", self.name)
|
||||
|
||||
self._connect_audio_in_socket()
|
||||
|
||||
@@ -99,7 +99,7 @@ class VADAgent(BaseAgent):
|
||||
transcriber = TranscriptionAgent(audio_out_address)
|
||||
await transcriber.start()
|
||||
|
||||
self.logger.info("Finished setting up %s", self.jid)
|
||||
self.logger.info("Finished setting up %s", self.name)
|
||||
|
||||
async def stop(self):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user