Skip to content

Commit

Permalink
actors to the stage
Browse files Browse the repository at this point in the history
  • Loading branch information
seanchatmangpt committed Feb 7, 2024
1 parent c3e73ac commit 09b3589
Show file tree
Hide file tree
Showing 14 changed files with 480 additions and 4 deletions.
Empty file added experiments/__init__.py
Empty file.
Empty file added experiments/actor/__init__.py
Empty file.
50 changes: 50 additions & 0 deletions experiments/actor/hoare.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from rdddy.actor import Actor
from rdddy.actor_system import ActorSystem
from experiments.actor.messages import *


class InitiationActor(Actor):
async def handle_start_phase_command(self, message: StartPhaseCommand):
print(f"Starting phase: {message.phase_name}")
# Simulate checking a condition to decide if we proceed
if message.phase_name == "Hello":
# Emit an event to indicate the precondition is evaluated and successful
await self.publish(PreconditionEvaluatedEvent(phase_name=message.phase_name, result=True))
else:
await self.publish(PhaseErrorEvent(phase_name=message.phase_name, error_message="Precondition failed"))

async def handle_evaluate_precondition_query(self, message: EvaluatePreconditionQuery):
# Directly using the message content to decide success or failure here for simplicity
if message.phase_name == "Hello":
await self.publish(PreconditionEvaluatedEvent(phase_name=message.phase_name, result=True))
else:
await self.publish(PhaseErrorEvent(phase_name=message.phase_name, error_message="Precondition failed"))

class CompletionActor(Actor):
async def handle_evaluate_postcondition_query(self, message: EvaluatePostconditionQuery):
# If message is "Hello", the postcondition check passes
if message.phase_name == "Hello":
await self.publish(PostconditionEvaluatedEvent(phase_name=message.phase_name, result=True))
await self.publish(PhaseCompletedEvent(phase_name=message.phase_name))
# If message is "Goodbye", the postcondition check fails
elif message.phase_name == "Goodbye":
await self.publish(PhaseErrorEvent(phase_name=message.phase_name, error_message="Postcondition failed"))

# Setup and usage within an ActorSystem context
async def setup_and_run():
actor_system = ActorSystem()
initiation_actor = await actor_system.actor_of(InitiationActor)
completion_actor = await actor_system.actor_of(CompletionActor)

await actor_system.publish(StartPhaseCommand(phase_name="Hello"))
await actor_system.publish(StartPhaseCommand(phase_name="Goodbye"))

import asyncio


async def main():
await setup_and_run()


if __name__ == '__main__':
asyncio.run(main())
56 changes: 56 additions & 0 deletions experiments/actor/hoare2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from rdddy.actor import Actor
from rdddy.actor_system import ActorSystem
from experiments.actor.messages import *


class InitiationActor(Actor):
async def handle_start_phase_command(self, message: StartPhaseCommand):
print(f"Initiating phase: {message.phase_name}")
# Trigger precondition evaluation
await self.publish(EvaluatePreconditionQuery(phase_name=message.phase_name))


class ProcessingActor(Actor):
async def handle_precondition_evaluated_event(self, message: PreconditionEvaluatedEvent):
if message.result:
print(f"Preconditions met for phase: {message.phase_name}, processing...")
# Simulate phase processing and then evaluate postconditions
await self.publish(ProcessPhaseCommand(phase_name=message.phase_name))
else:
print(f"Preconditions not met for phase: {message.phase_name}, aborting...")
await self.publish(PhaseErrorEvent(phase_name=message.phase_name, error_message="Precondition failed"))

async def handle_process_phase_command(self, message: ProcessPhaseCommand):
# Simulate phase processing logic here
print(f"Processing phase: {message.phase_name}")
# After processing, evaluate postconditions
await self.publish(EvaluatePostconditionQuery(phase_name=message.phase_name))


class CompletionActor(Actor):
async def handle_postcondition_evaluated_event(self, message: PostconditionEvaluatedEvent):
if message.result:
print(f"Phase {message.phase_name} completed successfully.")
await self.publish(PhaseCompletedEvent(phase_name=message.phase_name))
else:
print(f"Postconditions not met for phase: {message.phase_name}.")
await self.publish(PhaseErrorEvent(phase_name=message.phase_name, error_message="Postcondition failed"))

# Setup the actor system and actors
async def setup_and_run():
actor_system = ActorSystem()
initiation_actor = await actor_system.actor_of(InitiationActor)
processing_actor = await actor_system.actor_of(ProcessingActor)
completion_actor = await actor_system.actor_of(CompletionActor)

# Start the workflow by initiating a phase
for i in range(5):
await initiation_actor.publish(StartPhaseCommand(phase_name=f"Phase {i}"))

import asyncio

async def main():
await setup_and_run()

if __name__ == '__main__':
asyncio.run(main())
35 changes: 35 additions & 0 deletions experiments/actor/messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from rdddy.messages import *


class StartPhaseCommand(Command):
phase_name: str

class PhaseStartedEvent(Event):
phase_name: str

class EvaluatePreconditionQuery(Query):
phase_name: str

class PreconditionEvaluatedEvent(Event):
phase_name: str
result: bool

class ProcessPhaseCommand(Command):
phase_name: str

class PhaseProcessedEvent(Event):
phase_name: str

class EvaluatePostconditionQuery(Query):
phase_name: str

class PostconditionEvaluatedEvent(Event):
phase_name: str
result: bool

class PhaseCompletedEvent(Event):
phase_name: str

class PhaseErrorEvent(Event):
phase_name: str
error_message: str
134 changes: 134 additions & 0 deletions experiments/actor/software.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import asyncio

from experiments.actor.messages import PhaseErrorEvent
from rdddy.actor import Actor
from rdddy.actor_system import ActorSystem
from rdddy.messages import *


# Define the messages for each step in the scenario
class RequirementSpecificationCommand(Command):
requirements: dict[str, str]


class ModelGeneratedEvent(Event):
mdl_id: str


class ModelValidatedEvent(Event):
mdl_id: str
validation_status: bool


class ModelAdaptationCommand(Command):
mdl_id: str
external_inputs: dict[str, str]


class DecisionMadeEvent(Event):
mdl_id: str
decision_actions: list[str]


class OptimizationCompletedEvent(Event):
mdl_id: str


class DeploymentStartedCommand(Command):
mdl_id: str


class ModelDeployedEvent(Event):
mdl_id: str


class ModelMonitoringCommand(Command):
mdl_id: str


# Actors will be defined here, each handling relevant messages
# For brevity, only the structure of actors is outlined

class ProjectManagementActor(Actor):
async def handle_requirement_specification_command(self, message: RequirementSpecificationCommand):
# Log the receipt of requirements and trigger model generation
print(f"Received project requirements: {message.requirements}")
await self.publish(ModelGeneratedEvent(mdl_id="model_123"))


class ModelGenerationActor(Actor):
async def handle_model_generated_event(self, message: ModelGeneratedEvent):
# Generate model based on received event (simulate model generation)
print(f"Model {message.mdl_id} generated.")
await self.publish(ModelValidatedEvent(mdl_id=message.mdl_id, validation_status=True))


class ModelValidationActor(Actor):
async def handle_model_validated_event(self, message: ModelValidatedEvent):
# Validate the model (simulation)
print(f"Model {message.mdl_id} validation status: {message.validation_status}")
if message.validation_status:
await self.publish(DecisionMadeEvent(mdl_id=message.mdl_id, decision_actions=["proceed"]))
else:
await self.publish(PhaseErrorEvent(phase_name="Validation", error_message="Validation Failed"))


class AdaptationActor(Actor):
async def handle_model_adaptation_command(self, message: ModelAdaptationCommand):
# Adapt the model based on external inputs (simulate adaptation)
print(f"Adapting model {message.mdl_id} with inputs: {message.external_inputs}")
await self.publish(OptimizationCompletedEvent(mdl_id=message.mdl_id))


class DecisionMakingActor(Actor):
async def handle_decision_made_event(self, message: DecisionMadeEvent):
# Make decision based on DMN (simulate decision-making)
print(f"Decision for model {message.mdl_id}: {message.decision_actions}")
if "proceed" in message.decision_actions:
await self.publish(DeploymentStartedCommand(mdl_id=message.mdl_id))


class OptimizationActor(Actor):
async def handle_optimization_completed_event(self, message: OptimizationCompletedEvent):
# Optimization logic (simulation)
print(f"Optimization completed for model {message.mdl_id}.")
await self.publish(ModelDeployedEvent(mdl_id=message.mdl_id))


class DeploymentActor(Actor):
async def handle_deployment_started_command(self, message: DeploymentStartedCommand):
# Handle deployment (simulate deployment process)
print(f"Deployment started for model {message.mdl_id}.")
await self.publish(ModelMonitoringCommand(mdl_id=message.mdl_id))


class MonitoringActor(Actor):
async def handle_model_monitoring_command(self, message: ModelMonitoringCommand):
# Monitor the model (simulate monitoring)
print(f"Monitoring initiated for model {message.mdl_id}.")
# Based on monitoring, you could trigger new adaptation or optimization cycles


# Setup and execution logic for the actors and the actor system
async def setup_and_run():
actor_system = ActorSystem()
await actor_system.actors_of([ProjectManagementActor,
ModelGenerationActor,
ModelValidationActor,
AdaptationActor,
DecisionMakingActor,
OptimizationActor,
DeploymentActor,
MonitoringActor])
# Instantiate and start all actors
# Example: project_management_actor = await actor_system.actor_of(ProjectManagementActor)
# Trigger the start of the scenario by sending a RequirementSpecificationCommand
await actor_system.publish(RequirementSpecificationCommand(requirements={"model-deployment-started": "hello"}))


async def main():
await setup_and_run()


if __name__ == '__main__':
asyncio.run(main())
1 change: 0 additions & 1 deletion experiments/gen_cli_from_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from typing import List

from rdddy.generators.gen_pydantic_instance import GenPydanticInstance
from rdddy.generators.gen_python_primitive import GenPythonPrimitive


class Command(BaseModel):
Expand Down
7 changes: 7 additions & 0 deletions src/rdddy/actor_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ async def actor_of(self, actor_class, **kwargs) -> "Actor":
await actor.start(self.scheduler)
return actor

async def actors_of(self, actor_classes, **kwargs) -> list["Actor"]:
actors = []
for actor_class in actor_classes:
actor = await self.actor_of(actor_class, **kwargs)
actors.append(actor)
return actors

async def publish(self, message: "Message"):
self.event_stream.on_next(message)
actors = list(self.actors.values())
Expand Down
8 changes: 8 additions & 0 deletions src/rdddy/generators/assertion.log
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,11 @@ fields.10.default_value
fields.14.default_value
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.5/v/string_type
2024-02-05 11:15:12,713 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for GRDDDFLSSFramework

Validation error:
invalid character '∫' (U+222B) (<unknown>, line 1)
2024-02-05 11:15:15,163 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for GRDDDFLSSFramework

Validation error:
invalid character '∫' (U+222B) (<unknown>, line 1)
Loading

0 comments on commit 09b3589

Please sign in to comment.