fix: real per-agent slot handle for multi-agent calendar tools #7
Reference in New Issue
Block a user
Delete Branch "fix/multi-agent-scheduler-handle"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
In multi-agent sync mode every
harborforge_calendar_*tool was returningcalendarScheduler.<method> is not a function. After PR #6 wired the multi-agent path,index.tsreplaced the typedcalendarScheduler: CalendarScheduler | nullwith a{ stop() }stub right after starting the runSync/runCheck intervals. Every other method on the slot —isRunning,getCurrentSlot,complete/abort/pause/resumeCurrentSlot,getState,isRestartPending,getStateFilePath— blew up at call time.What this PR does
Replaces the stub with a
MultiAgentSchedulerHandlethat:wakeAgent)getStatus / complete / abort / pause / resumetaking the callingagentIdnot_started/deferred/ongoingslots so a tool called between sync windows still finds something sensibleCalendarBridgeClient.updateSlotAs(agentId, …)so audit headers reflect the real caller (the bridge constructoragentIdis'unused'in multi-agent mode)isRunning/isProcessing/getState/...so the single-agent fallback (CalendarScheduler) keeps working unchangedEach calendar tool factory now takes
OpenClawPluginToolContext, readsctx.agentId, and dispatches through the handle. Single-agent branches are preserved behindinstanceofchecks.Drops the dead
trackSessionCompletionpoll loop (only definition, no caller) which referenced the removedcompleteCurrentSlot. Bumpspackage.json0.2.0 → 0.3.2.Verified in sim
harborforge_*call returnednot a functionnpm run buildcleanrecruiteragainst task SIM-T2 should seeharborforge_calendar_statusreturn a real slot, andharborforge_calendar_completeactually transition the slot tofinished🤖 Generated with Claude Code
In multi-agent sync mode every harborforge_calendar_* tool was returning `calendarScheduler.<method> is not a function`. The cause: index.ts replaced `calendarScheduler` (typed `CalendarScheduler | null`) with a `{ stop() }` stub right after wiring the runSync/runCheck intervals, so `isRunning()`, `getCurrentSlot()`, `completeCurrentSlot()`, `abortCurrentSlot()`, `pauseCurrentSlot()`, `resumeCurrentSlot()`, `getState()`, `isRestartPending()` and `getStateFilePath()` all blew up at call time. Replaces the stub with a `MultiAgentSchedulerHandle` that: - tracks the last slot dispatched per agent (recorded by `wakeAgent`) - exposes status/complete/abort/pause/resume taking the calling agentId - resolves the implicit "current slot" via woken-cursor first then a cache scan over not_started/deferred/ongoing slots - PATCHes via `bridge.updateSlotAs(agentId, …)` so audit headers reflect the real caller (bridge constructor agentId is 'unused' in multi-agent) - mirrors the legacy `isRunning/isProcessing/getState/...` surface so the single-agent fallback (`CalendarScheduler`) keeps working unchanged Each calendar tool factory now takes `OpenClawPluginToolContext`, reads `ctx.agentId`, and dispatches through the handle. Single-agent path (when `calendarScheduler` is a real `CalendarScheduler`) is preserved behind `instanceof` checks. Drops the dead `trackSessionCompletion` poll loop (only definition, no caller) which referenced the removed `completeCurrentSlot`. Bumps plugin version 0.2.0 → 0.3.2. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>