diff --git a/plugin/hooks/gateway-start.ts b/plugin/hooks/gateway-start.ts index de3f6ab..26aee53 100644 --- a/plugin/hooks/gateway-start.ts +++ b/plugin/hooks/gateway-start.ts @@ -7,20 +7,10 @@ export function registerGatewayStartHook(api: any, deps: { pushMetaToMonitor: () => Promise; startCalendarScheduler: () => void; setMetaPushInterval: (handle: ReturnType) => void; - onCronServiceAvailable?: (cron: any) => void; }) { const { logger, pushMetaToMonitor, startCalendarScheduler, setMetaPushInterval } = deps; - api.on('gateway_start', (event?: any) => { - // Extract cron service from gateway startup event (same as memory-core dreaming) - if (event && deps.onCronServiceAvailable) { - const context = event?.context; - const cron = context?.cron ?? context?.deps?.cron; - if (cron && typeof cron.add === 'function') { - deps.onCronServiceAvailable(cron); - logger.info('HarborForge: cron service acquired from gateway_start'); - } - } + api.on('gateway_start', () => { logger.info('HarborForge plugin active'); const live = getPluginConfig(api); diff --git a/plugin/index.ts b/plugin/index.ts index 48be1fd..fce6156 100644 --- a/plugin/index.ts +++ b/plugin/index.ts @@ -187,46 +187,49 @@ export default { return null; } - // Cron service reference, acquired from gateway_start event - let cronService: any = null; - /** - * Wake agent via cron service — same mechanism used by dreaming/memory-core. - * Creates a one-shot cron job with wakeMode: "now" and deleteAfterRun: true. + * Wake agent via dispatchInboundMessage — same mechanism used by Discord plugin. + * Direct in-process call, no WebSocket or CLI needed. */ async function wakeAgent(context: AgentWakeContext): Promise { logger.info(`Waking agent for slot: ${context.taskDescription}`); - if (!cronService) { - logger.error('Cron service not available — cannot wake agent'); - return false; - } - const agentId = process.env.AGENT_ID || 'unknown'; const slotId = context.slot.id ?? context.slot.virtual_id ?? 'unknown'; + const sessionKey = `agent:${agentId}:hf-calendar:slot-${slotId}`; try { - await cronService.add({ - name: `hf-calendar-slot-${slotId}`, - description: `[managed-by=harbor-forge.calendar] Slot ${slotId}: ${context.taskDescription}`, - deleteAfterRun: true, - wakeMode: 'now', - agentId, - payload: { - kind: 'agentTurn', - message: context.prompt, - timeoutSeconds: context.slot.estimated_duration * 60, + const { dispatchInboundMessageWithDispatcher } = await import( + 'openclaw/plugin-sdk/reply-dispatch-runtime' + ); + + const cfg = api.runtime?.config?.loadConfig?.(); + if (!cfg) { + logger.error('Cannot load OpenClaw config for dispatch'); + return false; + } + + const result = await dispatchInboundMessageWithDispatcher({ + ctx: { + Body: context.prompt, + SessionKey: sessionKey, + From: 'harborforge-calendar', + Provider: 'harborforge', }, - delivery: { - mode: 'none', + cfg, + dispatcherOptions: { + deliver: async (payload: any) => { + // No delivery — agent works silently + logger.info(`Agent reply for slot ${slotId}: ${(payload.text || '').slice(0, 100)}`); + }, }, }); - logger.info(`Agent wake cron job created for slot ${slotId}`); + logger.info(`Agent dispatched for slot ${slotId}: ${result?.status || 'ok'}`); return true; } catch (err) { - logger.error('Failed to create wake cron job:', err); + logger.error('Failed to dispatch agent for slot:', err); return false; } } @@ -309,9 +312,6 @@ export default { setMetaPushInterval(handle) { metaPushInterval = handle; }, - onCronServiceAvailable(cron) { - cronService = cron; - }, }); registerGatewayStopHook(api, {