The Big One #43

Merged
k.marinus merged 93 commits from feat/reset-experiment-and-phase into dev 2026-01-26 19:20:45 +00:00
Showing only changes of commit bab4800698 - Show all commits

View File

@@ -23,6 +23,7 @@ from control_backend.schemas.program import (
ProgramElement, ProgramElement,
SemanticBelief, SemanticBelief,
SpeechAction, SpeechAction,
Trigger,
) )
test_program = Program( test_program = Program(
@@ -47,22 +48,30 @@ test_program = Program(
), ),
], ],
triggers=[ triggers=[
# Trigger( Trigger(
# condition=InferredBelief( condition=InferredBelief(
# left=KeywordBelief(keyword="key"), left=KeywordBelief(keyword="key"),
# right=InferredBelief( right=InferredBelief(
# left=KeywordBelief(keyword="key2"), left=KeywordBelief(keyword="key2"),
# right=SemanticBelief( right=SemanticBelief(
# description="Decode this", name="semantic belief 2" description="Decode this", name="semantic belief 2"
# ), ),
# operator=LogicalOperator.OR, operator=LogicalOperator.OR,
# name="test trigger inferred inner", name="test trigger inferred inner",
# ), ),
# operator=LogicalOperator.OR, operator=LogicalOperator.OR,
# name="test trigger inferred outer", name="test trigger inferred outer",
# ), ),
# plan=Plan(steps=[]), plan=Plan(
# ) steps=[
SpeechAction(text="Testing trigger"),
Goal(
name="Testing trigger",
plan=Plan(steps=[LLMAction(goal="Do something")]),
),
]
),
)
], ],
goals=[ goals=[
Goal( Goal(
@@ -93,6 +102,10 @@ test_program = Program(
) )
def do_things():
print(AgentSpeakGenerator().generate(test_program))
class AgentSpeakGenerator: class AgentSpeakGenerator:
""" """
Converts Pydantic representation of behavior programs into AgentSpeak(L) code string. Converts Pydantic representation of behavior programs into AgentSpeak(L) code string.
@@ -186,13 +199,13 @@ class AgentSpeakGenerator:
for phase in program.phases: for phase in program.phases:
previous_goal: Goal | None = None previous_goal: Goal | None = None
for goal in phase.goals: for goal in phase.goals:
lines += self._generate_plan_recursive(goal, phase, previous_goal) lines += self._generate_goal_plan_recursive(goal, phase, previous_goal)
previous_goal = goal previous_goal = goal
lines += ["", ""] lines += ["", ""]
return lines return lines
def _generate_plan_recursive( def _generate_goal_plan_recursive(
self, goal: Goal, phase: Phase, previous_goal: Goal | None = None self, goal: Goal, phase: Phase, previous_goal: Goal | None = None
) -> list[str]: ) -> list[str]:
lines = [] lines = []
@@ -210,6 +223,11 @@ class AgentSpeakGenerator:
extra_goals_to_generate = [] extra_goals_to_generate = []
steps = goal.plan.steps steps = goal.plan.steps
if len(steps) == 0:
lines.append(f"{' ' * 2}<-{' ' * 2}true.")
return lines
first_step = steps[0] first_step = steps[0]
lines.append( lines.append(
f"{' ' * 2}<-{' ' * 2}{self._slugify(first_step, include_prefix=True)}" f"{' ' * 2}<-{' ' * 2}{self._slugify(first_step, include_prefix=True)}"
@@ -239,7 +257,7 @@ class AgentSpeakGenerator:
extra_previous_goal: Goal | None = None extra_previous_goal: Goal | None = None
for extra_goal in extra_goals_to_generate: for extra_goal in extra_goals_to_generate:
lines += self._generate_plan_recursive(extra_goal, phase, extra_previous_goal) lines += self._generate_goal_plan_recursive(extra_goal, phase, extra_previous_goal)
extra_previous_goal = extra_goal extra_previous_goal = extra_goal
return lines return lines
@@ -248,9 +266,57 @@ class AgentSpeakGenerator:
lines = [] lines = []
lines.append("// --- Triggers ---") lines.append("// --- Triggers ---")
for phase in program.phases:
for trigger in phase.triggers:
lines += self._generate_trigger_plan(trigger, phase)
lines += ["", ""] lines += ["", ""]
return lines return lines
def _generate_trigger_plan(self, trigger: Trigger, phase: Phase) -> list[str]:
lines = []
belief_name = self._slugify(trigger.condition)
lines.append(f"+{belief_name}")
lines.append(f"{' ' * 2}:{' ' * 3}phase({phase.id})")
extra_goals_to_generate = []
steps = trigger.plan.steps
if len(steps) == 0:
lines.append(f"{' ' * 2}<-{' ' * 2}true.")
return lines
first_step = steps[0]
lines.append(
f"{' ' * 2}<-{' ' * 2}{self._slugify(first_step, include_prefix=True)}"
f"{'.' if len(steps) == 1 else ';'}"
)
if isinstance(first_step, Goal):
extra_goals_to_generate.append(first_step)
for step in steps[1:-1]:
lines.append(f"{' ' * 6}{self._slugify(step, include_prefix=True)};")
if isinstance(step, Goal):
extra_goals_to_generate.append(step)
if len(steps) > 1:
last_step = steps[-1]
lines.append(f"{' ' * 6}{self._slugify(last_step, include_prefix=True)}.")
if isinstance(last_step, Goal):
extra_goals_to_generate.append(last_step)
lines.append("")
extra_previous_goal: Goal | None = None
for extra_goal in extra_goals_to_generate:
lines += self._generate_goal_plan_recursive(extra_goal, phase, extra_previous_goal)
extra_previous_goal = extra_goal
return lines
def _slugify(self, element: ProgramElement, include_prefix: bool = False) -> str: def _slugify(self, element: ProgramElement, include_prefix: bool = False) -> str:
def base_slugify_call(text: str): def base_slugify_call(text: str):
return slugify(text, separator="_", stopwords=["a", "the"]) return slugify(text, separator="_", stopwords=["a", "the"])