fix: sync issues

ref: N25B-447
This commit is contained in:
2026-01-14 15:28:29 +01:00
parent 8f6662e64a
commit 39e1bb1ead
5 changed files with 47 additions and 22 deletions

View File

@@ -50,6 +50,8 @@ class AgentSpeakGenerator:
else: else:
self._asp.rules.append(AstRule(AstLiteral("phase", [AstString("end")]))) self._asp.rules.append(AstRule(AstLiteral("phase", [AstString("end")])))
self._asp.rules.append(AstRule(AstLiteral("!notify_cycle")))
self._add_keyword_inference() self._add_keyword_inference()
self._add_default_plans() self._add_default_plans()
@@ -147,8 +149,18 @@ class AgentSpeakGenerator:
AstLiteral("notify_cycle"), AstLiteral("notify_cycle"),
[], [],
[ [
AstStatement(StatementType.DO_ACTION, AstLiteral("notify_ui")), AstStatement(
AstStatement(StatementType.DO_ACTION, AstLiteral("wait", [AstNumber(1)])), StatementType.DO_ACTION,
AstLiteral(
"findall",
[AstVar("Norm"), AstLiteral("norm", [AstVar("Norm")]), AstVar("Norms")],
),
),
AstStatement(
StatementType.DO_ACTION, AstLiteral("notify_norms", [AstVar("Norms")])
),
AstStatement(StatementType.DO_ACTION, AstLiteral("wait", [AstNumber(100)])),
AstStatement(StatementType.ACHIEVE_GOAL, AstLiteral("notify_cycle")),
], ],
) )
) )
@@ -365,6 +377,10 @@ class AgentSpeakGenerator:
if isinstance(step, Goal): if isinstance(step, Goal):
step.can_fail = False # triggers are continuous sequence step.can_fail = False # triggers are continuous sequence
subgoals.append(step) subgoals.append(step)
# Arbitrary wait for UI to display nicely
body.append(AstStatement(StatementType.DO_ACTION, AstLiteral("wait", [AstNumber(2000)])))
body.append( body.append(
AstStatement( AstStatement(
StatementType.DO_ACTION, StatementType.DO_ACTION,

View File

@@ -107,7 +107,6 @@ class BDICoreAgent(BaseAgent):
if not maybe_more_work: if not maybe_more_work:
deadline = self.bdi_agent.shortest_deadline() deadline = self.bdi_agent.shortest_deadline()
if deadline: if deadline:
self.logger.debug("Sleeping until %s", deadline)
await asyncio.sleep(deadline - time.time()) await asyncio.sleep(deadline - time.time())
maybe_more_work = True maybe_more_work = True
else: else:
@@ -335,14 +334,6 @@ class BDICoreAgent(BaseAgent):
message_text = agentspeak.grounded(term.args[0], intention.scope) message_text = agentspeak.grounded(term.args[0], intention.scope)
norms = agentspeak.grounded(term.args[1], intention.scope) norms = agentspeak.grounded(term.args[1], intention.scope)
norm_update_message = InternalMessage(
to=settings.agent_settings.user_interrupt_name,
thread="active_norms_update",
body=str(norms),
)
self.add_behavior(self.send(norm_update_message))
self.add_behavior(self._send_to_llm(str(message_text), str(norms), "")) self.add_behavior(self._send_to_llm(str(message_text), str(norms), ""))
yield yield
@@ -355,14 +346,20 @@ class BDICoreAgent(BaseAgent):
message_text = agentspeak.grounded(term.args[0], intention.scope) message_text = agentspeak.grounded(term.args[0], intention.scope)
norms = agentspeak.grounded(term.args[1], intention.scope) norms = agentspeak.grounded(term.args[1], intention.scope)
goal = agentspeak.grounded(term.args[2], intention.scope) goal = agentspeak.grounded(term.args[2], intention.scope)
self.add_behavior(self._send_to_llm(str(message_text), str(norms), str(goal)))
yield
@self.actions.add(".notify_norms", 1)
def _notify_norms(agent, term, intention):
norms = agentspeak.grounded(term.args[0], intention.scope)
norm_update_message = InternalMessage( norm_update_message = InternalMessage(
to=settings.agent_settings.user_interrupt_name, to=settings.agent_settings.user_interrupt_name,
thread="active_norms_update", thread="active_norms_update",
body=str(norms), body=str(norms),
) )
self.add_behavior(self.send(norm_update_message)) self.add_behavior(self.send(norm_update_message, should_log=False))
self.add_behavior(self._send_to_llm(str(message_text), str(norms), str(goal)))
yield yield
@self.actions.add(".say", 1) @self.actions.add(".say", 1)
@@ -473,7 +470,6 @@ class BDICoreAgent(BaseAgent):
body=str(trigger_name), body=str(trigger_name),
) )
# TODO: check with Pim
self.add_behavior(self.send(msg)) self.add_behavior(self.send(msg))
yield yield

View File

@@ -97,6 +97,15 @@ class BDIProgramManager(BaseAgent):
if new == "end": if new == "end":
self._phase = None self._phase = None
# Notify user interaction agent
msg = InternalMessage(
to=settings.agent_settings.user_interrupt_name,
thread="transition_phase",
body="end",
)
self.logger.info("Transitioned to end phase, notifying UserInterruptAgent.")
self.add_behavior(self.send(msg))
return return
for phase in self._program.phases: for phase in self._program.phases:

View File

@@ -214,8 +214,8 @@ class UserInterruptAgent(BaseAgent):
payload = {"type": "cond_norms_state_update", "norms": updates} payload = {"type": "cond_norms_state_update", "norms": updates}
await self._send_experiment_update(payload) await self._send_experiment_update(payload, should_log=False)
self.logger.debug(f"Broadcasted state for {len(updates)} conditional norms.") # self.logger.debug(f"Broadcasted state for {len(updates)} conditional norms.")
def _create_mapping(self, program_json: str): def _create_mapping(self, program_json: str):
""" """
@@ -259,7 +259,7 @@ class UserInterruptAgent(BaseAgent):
except Exception as e: except Exception as e:
self.logger.error(f"Mapping failed: {e}") self.logger.error(f"Mapping failed: {e}")
async def _send_experiment_update(self, data): async def _send_experiment_update(self, data, should_log: bool = True):
""" """
Sends an update to the 'experiment' topic. Sends an update to the 'experiment' topic.
The SSE endpoint will pick this up and push it to the UI. The SSE endpoint will pick this up and push it to the UI.
@@ -268,6 +268,7 @@ class UserInterruptAgent(BaseAgent):
topic = b"experiment" topic = b"experiment"
body = json.dumps(data).encode("utf-8") body = json.dumps(data).encode("utf-8")
await self.pub_socket.send_multipart([topic, body]) await self.pub_socket.send_multipart([topic, body])
if should_log:
self.logger.debug(f"Sent experiment update: {data}") self.logger.debug(f"Sent experiment update: {data}")
async def _send_to_speech_agent(self, text_to_say: str): async def _send_to_speech_agent(self, text_to_say: str):

View File

@@ -120,7 +120,7 @@ class BaseAgent(ABC):
task.cancel() task.cancel()
self.logger.info(f"Agent {self.name} stopped") self.logger.info(f"Agent {self.name} stopped")
async def send(self, message: InternalMessage): async def send(self, message: InternalMessage, should_log: bool = True):
""" """
Send a message to another agent. Send a message to another agent.
@@ -142,12 +142,16 @@ class BaseAgent(ABC):
if target: if target:
await target.inbox.put(message) await target.inbox.put(message)
self.logger.debug(f"Sent message {message.body} to {message.to} via regular inbox.") if should_log:
self.logger.debug(
f"Sent message {message.body} to {message.to} via regular inbox."
)
else: else:
# Apparently target agent is on a different process, send via ZMQ # Apparently target agent is on a different process, send via ZMQ
topic = f"internal/{receiver}".encode() topic = f"internal/{receiver}".encode()
body = message.model_dump_json().encode() body = message.model_dump_json().encode()
await self._internal_pub_socket.send_multipart([topic, body]) await self._internal_pub_socket.send_multipart([topic, body])
if should_log:
self.logger.debug(f"Sent message {message.body} to {message.to} via ZMQ.") self.logger.debug(f"Sent message {message.body} to {message.to} via ZMQ.")
async def _process_inbox(self): async def _process_inbox(self):
@@ -158,7 +162,6 @@ class BaseAgent(ABC):
""" """
while self._running: while self._running:
msg = await self.inbox.get() msg = await self.inbox.get()
self.logger.debug(f"Received message from {msg.sender}.")
await self.handle_message(msg) await self.handle_message(msg)
async def _receive_internal_zmq_loop(self): async def _receive_internal_zmq_loop(self):