fix: default behavior and end phase

ref: N25B-448
This commit is contained in:
2026-01-14 11:24:19 +01:00
parent 43ac8ad69f
commit ff24ab7a27
4 changed files with 52 additions and 18 deletions

View File

@@ -7,6 +7,7 @@ from control_backend.agents.bdi.agentspeak_ast import (
AstBinaryOp, AstBinaryOp,
AstExpression, AstExpression,
AstLiteral, AstLiteral,
AstNumber,
AstPlan, AstPlan,
AstProgram, AstProgram,
AstRule, AstRule,
@@ -44,7 +45,11 @@ class AgentSpeakGenerator:
def generate(self, program: Program) -> str: def generate(self, program: Program) -> str:
self._asp = AstProgram() self._asp = AstProgram()
self._asp.rules.append(AstRule(self._astify(program.phases[0]))) if program.phases:
self._asp.rules.append(AstRule(self._astify(program.phases[0])))
else:
self._asp.rules.append(AstRule(AstLiteral("phase", [AstString("end")])))
self._add_keyword_inference() self._add_keyword_inference()
self._add_default_plans() self._add_default_plans()
@@ -72,6 +77,7 @@ class AgentSpeakGenerator:
self._add_reply_with_goal_plan() self._add_reply_with_goal_plan()
self._add_say_plan() self._add_say_plan()
self._add_reply_plan() self._add_reply_plan()
self._add_notify_cycle_plan()
def _add_reply_with_goal_plan(self): def _add_reply_with_goal_plan(self):
self._asp.plans.append( self._asp.plans.append(
@@ -134,6 +140,19 @@ class AgentSpeakGenerator:
) )
) )
def _add_notify_cycle_plan(self):
self._asp.plans.append(
AstPlan(
TriggerType.ADDED_GOAL,
AstLiteral("notify_cycle"),
[],
[
AstStatement(StatementType.DO_ACTION, AstLiteral("notify_ui")),
AstStatement(StatementType.DO_ACTION, AstLiteral("wait", [AstNumber(1)])),
],
)
)
def _process_phases(self, phases: list[Phase]) -> None: def _process_phases(self, phases: list[Phase]) -> None:
for curr_phase, next_phase in zip([None] + phases, phases + [None], strict=True): for curr_phase, next_phase in zip([None] + phases, phases + [None], strict=True):
if curr_phase: if curr_phase:
@@ -148,7 +167,9 @@ class AgentSpeakGenerator:
trigger_literal=AstLiteral("user_said", [AstVar("Message")]), trigger_literal=AstLiteral("user_said", [AstVar("Message")]),
context=[AstLiteral("phase", [AstString("end")])], context=[AstLiteral("phase", [AstString("end")])],
body=[ body=[
AstStatement(StatementType.DO_ACTION, AstLiteral("notify_user_said")), AstStatement(
StatementType.DO_ACTION, AstLiteral("notify_user_said", [AstVar("Message")])
),
AstStatement(StatementType.ACHIEVE_GOAL, AstLiteral("reply")), AstStatement(StatementType.ACHIEVE_GOAL, AstLiteral("reply")),
], ],
) )

View File

@@ -342,14 +342,11 @@ class BDICoreAgent(BaseAgent):
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=norms, body=str(norms),
) )
self.add_behavior(self.send(norm_update_message)) self.add_behavior(self.send(norm_update_message))
self.logger.debug("Norms: %s", norms)
self.logger.debug("User text: %s", message_text)
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
@@ -369,13 +366,6 @@ class BDICoreAgent(BaseAgent):
) )
self.add_behavior(self.send(norm_update_message)) self.add_behavior(self.send(norm_update_message))
self.logger.debug(
'"reply_with_goal" action called with message=%s, norms=%s, goal=%s',
message_text,
norms,
goal,
)
self.add_behavior(self._send_to_llm(str(message_text), str(norms), str(goal))) self.add_behavior(self._send_to_llm(str(message_text), str(norms), str(goal)))
yield yield

View File

@@ -279,8 +279,10 @@ class BDIProgramManager(BaseAgent):
Initialize the agent. Initialize the agent.
Connects the internal ZMQ SUB socket and subscribes to the 'program' topic. Connects the internal ZMQ SUB socket and subscribes to the 'program' topic.
Starts the background behavior to receive programs. Starts the background behavior to receive programs. Initializes a default program.
""" """
await self._create_agentspeak_and_send_to_bdi(Program(phases=[]))
context = Context.instance() context = Context.instance()
self.sub_socket = context.socket(zmq.SUB) self.sub_socket = context.socket(zmq.SUB)

View File

@@ -1,13 +1,34 @@
norm("Be friendly"). phase("end").
keyword_said(Keyword) :- (user_said(Message) & .substring(Keyword, Message, Pos)) & (Pos >= 0).
+!reply_with_goal(Goal)
: user_said(Message)
<- +responded_this_turn;
.findall(Norm, norm(Norm), Norms);
.reply_with_goal(Message, Norms, Goal).
+!say(Text)
<- +responded_this_turn;
.say(Text).
+!reply +!reply
: user_said(Message) : user_said(Message)
<- .findall(Norm, norm(Norm), Norms); <- +responded_this_turn;
.findall(Norm, norm(Norm), Norms);
.reply(Message, Norms). .reply(Message, Norms).
+!notify_cycle
<- .notify_ui;
.wait(1).
+user_said(Message) +user_said(Message)
: phase("end")
<- .notify_user_said(Message); <- .notify_user_said(Message);
!reply. !reply.
+!transition_phase <- true. +!check_triggers
+!check_triggers <- true. <- true.
+!transition_phase
<- true.