Run Mode
The RunMode
provides autonomous operation capabilities for the Penguin AI assistant, allowing it to switch from interactive conversation to task-driven execution mode.
Overview
Run Mode enables Penguin to:
- Execute specific tasks with defined goals
- Run continuously to process multiple tasks
- Maintain workspace state across tasks
- Operate with time limits and graceful shutdowns
Task Execution Flow (_execute_task
)
The core logic for executing a task within RunMode
resides in the _execute_task
method.
- Check for Engine: It first checks if the
PenguinCore
instance has an initializedEngine
. - Delegate to Engine (Preferred): If the
Engine
exists,_execute_task
delegates the entire multi-step reasoning and action loop toEngine.run_task(task_prompt_full, max_iterations=self.max_iterations)
. TheEngine
handles the iterations, LLM calls, action execution, and stop conditions. - Legacy Fallback: If the
Engine
is not available (e.g., failed initialization),_execute_task
falls back to its internal legacy loop:- It prepares the initial task prompt and adds it to the conversation.
- It iterates up to
max_iterations
:- Calls
PenguinCore.get_response()
to get the next LLM response and potential actions based on the current conversation state. - Displays assistant output and action results.
- Checks for completion or stop phrases in the response.
- Continues the loop, building upon the conversation history.
- Calls
- Handle Completion/Error: Returns the final status (completed, interrupted, error) and message.
Continuous Mode Operation
Initialization
def __init__(
self,
core,
max_iterations: int = MAX_TASK_ITERATIONS,
time_limit: Optional[int] = None,
):
Parameters:
core
:PenguinCore
instance to use for operations.RunMode
will usecore.engine
if available.max_iterations
: Maximum iterations per task (used primarily in legacy fallback loop). Default from config.time_limit
: Optional time limit in minutes for continuous mode.
Key Methods
Start Single Task
async def start(
self,
name: str,
description: Optional[str] = None,
context: Optional[Dict[str, Any]] = None,
) -> None
Starts autonomous execution for a specific task by calling _execute_task
.
Start Continuous Mode
async def start_continuous(self, specified_task_name: Optional[str] = None, task_description: Optional[str] = None) -> None:
Starts continuous operation mode that processes tasks sequentially, calling _execute_task
for each task.
Task Execution (_execute_task
)
async def _execute_task(
self,
name: str,
description: Optional[str] = None,
context: Optional[Dict[str, Any]] = None,
) -> Dict[str, Any]
Executes a task. Crucially, this method now attempts to delegate the entire execution loop to PenguinCore.engine.run_task
if the Engine
is available. If not, it falls back to its internal iterative loop using PenguinCore.get_response
. Returns a dictionary with the task status and final message.
Task Completion & Control Phrases
RunMode uses special phrases, typically checked within the Engine
loop or the legacy fallback loop, to manage task flow:
TASK_COMPLETION_PHRASE
(e.g., "TASK_COMPLETED"): Signals that a specific task's objective has been met.CONTINUOUS_COMPLETION_PHRASE
(e.g., "CONTINUOUS_MODE_COMPLETE"): Signals the end of the entire continuous mode session (not just one task).NEED_USER_CLARIFICATION_PHRASE
(e.g., "NEED_USER_CLARIFICATION"): Indicates the AI needs more input from the user to proceed with the current task. This typically pauses the continuous mode.EMERGENCY_STOP_PHRASE
: Signals immediate termination of operations.
Task Flow Summary
When running a task (start
or within start_continuous
), RunMode
primarily:
- Retrieves or prepares task details (name, description, context).
- Calls
_execute_task
. _execute_task
checks forcore.engine
.- If Engine exists: Delegates to
Engine.run_task
to handle the multi-step process until completion, stop condition, or error. - If Engine doesn't exist: Initiates its own loop, calling
core.get_response
iteratively, checking for completion phrases itself. - Handles the result (success, error, interruption, clarification needed).
- In continuous mode, loops to get the next task.
Continuous Mode
In continuous mode, RunMode:
- Initializes with a time limit if specified
- Enters a loop that:
- Gets the next highest priority task from project manager
- Executes the task
- Marks task as complete when finished
- Performs health checks periodically
- Handles interruptions gracefully
- Monitors for shutdown requests
- Performs graceful shutdown when time limit is reached or shutdown requested
Health Monitoring
RunMode periodically checks system health:
async def _health_check(self) -> None
This monitors memory usage, CPU usage, and other diagnostic metrics to ensure stable operation.
Graceful Shutdown
async def _graceful_shutdown(self) -> None
Ensures clean shutdown by:
- Completing current task if possible
- Saving state information
- Cleaning up resources
- Logging shutdown information
Example Usage
# Create a RunMode instance
run_mode = RunMode(core, time_limit=60) # 60 minute limit
# Run a specific task
await run_mode.start(
name="build_data_parser",
description="Create a parser for CSV data files"
)
# Run in continuous mode to process tasks automatically
await run_mode.start_continuous()
Command Line Usage
RunMode is activated through slash commands inside the Penguin CLI:
penguin # start the CLI
/run task build_data_parser "Create a parser for CSV files"
# Start continuous mode for 2 hours
/run --247 --time 120
Integration with Task Manager
RunMode integrates with the ProjectManager
to:
- Retrieve task details by name
- Mark tasks as complete when finished
- Get the next highest priority task in continuous mode
- Track metadata for completed tasks
This allows for a seamless workflow where tasks can be created interactively and then executed autonomously.