PLG-CAL-002: Implement calendar scheduler for agent slot wakeup
- Add CalendarScheduler class to manage periodic heartbeat and slot execution - Implement agent wakeup logic when Idle and slots are pending - Handle slot status transitions (attended, ongoing, deferred) - Support both real and virtual slot materialization - Add task context building for different event types (job, system, entertainment) - Integrate scheduler into main plugin index.ts - Add new plugin tools: harborforge_calendar_status, complete, abort
This commit is contained in:
184
plugin/calendar/scheduler.d.ts
vendored
Normal file
184
plugin/calendar/scheduler.d.ts
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* HarborForge Calendar Scheduler
|
||||
*
|
||||
* PLG-CAL-002: Plugin-side handling for pending slot execution.
|
||||
*
|
||||
* Responsibilities:
|
||||
* - Run calendar heartbeat every minute
|
||||
* - Detect when agent is Idle and slots are pending
|
||||
* - Wake agent with task context
|
||||
* - Handle slot status transitions (attended, ongoing, deferred)
|
||||
* - Manage agent status transitions (idle → busy/on_call)
|
||||
*
|
||||
* Design reference: NEXT_WAVE_DEV_DIRECTION.md §6 (Agent wakeup mechanism)
|
||||
*/
|
||||
import { CalendarBridgeClient } from './calendar-bridge';
|
||||
import { CalendarSlotResponse, AgentStatusValue } from './types';
|
||||
export interface CalendarSchedulerConfig {
|
||||
/** Calendar bridge client for backend communication */
|
||||
bridge: CalendarBridgeClient;
|
||||
/** Function to get current agent status from backend */
|
||||
getAgentStatus: () => Promise<AgentStatusValue | null>;
|
||||
/** Function to wake/spawn agent with task context */
|
||||
wakeAgent: (context: AgentWakeContext) => Promise<boolean>;
|
||||
/** Logger instance */
|
||||
logger: {
|
||||
info: (...args: any[]) => void;
|
||||
error: (...args: any[]) => void;
|
||||
debug: (...args: any[]) => void;
|
||||
warn: (...args: any[]) => void;
|
||||
};
|
||||
/** Heartbeat interval in milliseconds (default: 60000) */
|
||||
heartbeatIntervalMs?: number;
|
||||
/** Enable verbose debug logging */
|
||||
debug?: boolean;
|
||||
}
|
||||
/**
|
||||
* Context passed to agent when waking for slot execution.
|
||||
* This is the payload the agent receives to understand what to do.
|
||||
*/
|
||||
export interface AgentWakeContext {
|
||||
/** The slot to execute */
|
||||
slot: CalendarSlotResponse;
|
||||
/** Human-readable task description */
|
||||
taskDescription: string;
|
||||
/** Prompt/instructions for the agent */
|
||||
prompt: string;
|
||||
/** Whether this is a virtual slot (needs materialization) */
|
||||
isVirtual: boolean;
|
||||
}
|
||||
/**
|
||||
* Current execution state tracked by the scheduler.
|
||||
*/
|
||||
interface SchedulerState {
|
||||
/** Whether scheduler is currently running */
|
||||
isRunning: boolean;
|
||||
/** Currently executing slot (null if idle) */
|
||||
currentSlot: CalendarSlotResponse | null;
|
||||
/** Last heartbeat timestamp */
|
||||
lastHeartbeatAt: Date | null;
|
||||
/** Interval handle for cleanup */
|
||||
intervalHandle: ReturnType<typeof setInterval> | null;
|
||||
/** Set of slot IDs that have been deferred in current session */
|
||||
deferredSlotIds: Set<string>;
|
||||
/** Whether agent is currently processing a slot */
|
||||
isProcessing: boolean;
|
||||
}
|
||||
/**
|
||||
* CalendarScheduler manages the periodic heartbeat and slot execution lifecycle.
|
||||
*/
|
||||
export declare class CalendarScheduler {
|
||||
private config;
|
||||
private state;
|
||||
constructor(config: CalendarSchedulerConfig);
|
||||
/**
|
||||
* Start the calendar scheduler.
|
||||
* Begins periodic heartbeat to check for pending slots.
|
||||
*/
|
||||
start(): void;
|
||||
/**
|
||||
* Stop the calendar scheduler.
|
||||
* Cleans up intervals and resets state.
|
||||
*/
|
||||
stop(): void;
|
||||
/**
|
||||
* Execute a single heartbeat cycle.
|
||||
* Fetches pending slots and handles execution logic.
|
||||
*/
|
||||
runHeartbeat(): Promise<void>;
|
||||
/**
|
||||
* Handle slots when agent is not idle.
|
||||
* Defer all pending slots with priority boost.
|
||||
*/
|
||||
private handleNonIdleAgent;
|
||||
/**
|
||||
* Handle slots when agent is idle.
|
||||
* Select highest priority slot and wake agent.
|
||||
*/
|
||||
private handleIdleAgent;
|
||||
/**
|
||||
* Execute a slot by waking the agent.
|
||||
*/
|
||||
private executeSlot;
|
||||
/**
|
||||
* Build the wake context for an agent based on slot details.
|
||||
*/
|
||||
private buildWakeContext;
|
||||
/**
|
||||
* Build prompt for job-type slots.
|
||||
*/
|
||||
private buildJobPrompt;
|
||||
/**
|
||||
* Build prompt for system event slots.
|
||||
*/
|
||||
private buildSystemPrompt;
|
||||
/**
|
||||
* Build prompt for entertainment slots.
|
||||
*/
|
||||
private buildEntertainmentPrompt;
|
||||
/**
|
||||
* Build generic prompt for slots without specific event data.
|
||||
*/
|
||||
private buildGenericPrompt;
|
||||
/**
|
||||
* Mark a slot as deferred with priority boost.
|
||||
*/
|
||||
private deferSlot;
|
||||
/**
|
||||
* Revert a slot to not_started status after failed execution attempt.
|
||||
*/
|
||||
private revertSlot;
|
||||
/**
|
||||
* Complete the current slot execution.
|
||||
* Call this when the agent finishes the task.
|
||||
*/
|
||||
completeCurrentSlot(actualDurationMinutes: number): Promise<void>;
|
||||
/**
|
||||
* Abort the current slot execution.
|
||||
* Call this when the agent cannot complete the task.
|
||||
*/
|
||||
abortCurrentSlot(reason?: string): Promise<void>;
|
||||
/**
|
||||
* Pause the current slot execution.
|
||||
* Call this when the agent needs to temporarily pause.
|
||||
*/
|
||||
pauseCurrentSlot(): Promise<void>;
|
||||
/**
|
||||
* Resume a paused slot.
|
||||
*/
|
||||
resumeCurrentSlot(): Promise<void>;
|
||||
/**
|
||||
* Get a stable ID for a slot (real or virtual).
|
||||
*/
|
||||
private getSlotId;
|
||||
/**
|
||||
* Format a Date as ISO time string (HH:MM:SS).
|
||||
*/
|
||||
private formatTime;
|
||||
/**
|
||||
* Debug logging helper.
|
||||
*/
|
||||
private logDebug;
|
||||
/**
|
||||
* Get current scheduler state (for introspection).
|
||||
*/
|
||||
getState(): Readonly<SchedulerState>;
|
||||
/**
|
||||
* Check if scheduler is running.
|
||||
*/
|
||||
isRunning(): boolean;
|
||||
/**
|
||||
* Check if currently processing a slot.
|
||||
*/
|
||||
isProcessing(): boolean;
|
||||
/**
|
||||
* Get the current slot being executed (if any).
|
||||
*/
|
||||
getCurrentSlot(): CalendarSlotResponse | null;
|
||||
}
|
||||
/**
|
||||
* Factory function to create a CalendarScheduler from plugin context.
|
||||
*/
|
||||
export declare function createCalendarScheduler(config: CalendarSchedulerConfig): CalendarScheduler;
|
||||
export {};
|
||||
//# sourceMappingURL=scheduler.d.ts.map
|
||||
Reference in New Issue
Block a user