diff --git a/plugin/index.ts b/plugin/index.ts index 3fe19f4..c1cc19a 100644 --- a/plugin/index.ts +++ b/plugin/index.ts @@ -396,6 +396,36 @@ function register(api: PluginAPI): void { } } + // Cross-plugin exposure: agent status lookup for other plugins + // (currently Fabric.OpenclawPlugin uses this to skip delivering + // `announce` channel messages to busy agents — see DIALECTIC-V2 + // design doc, Phase 1). Backed by calendarBridge.getAgentStatus + // with a small TTL cache to avoid hammering the HF backend. + type HfStatus = 'idle' | 'on_call' | 'busy' | 'exhausted' | 'offline'; + const HF_STATUS_CACHE_TTL_MS = 30_000; + const hfStatusCache = new Map(); + const _G = globalThis as Record; + _G['__hfAgentStatus'] = { + async get(agentId: string): Promise { + if (!agentId) return undefined; + const cached = hfStatusCache.get(agentId); + if (cached && Date.now() - cached.at < HF_STATUS_CACHE_TTL_MS) { + return cached.status; + } + try { + const status = await calendarBridge.getAgentStatus(agentId); + if (status) { + const typed = status as HfStatus; + hfStatusCache.set(agentId, { status: typed, at: Date.now() }); + return typed; + } + } catch { + /* fall through to cached-or-undefined */ + } + return cached?.status; + }, + }; + // Track wakes already dispatched for a slot in the current sync // window — the simplified inline scheduler does not PATCH slot // status server-side, so without dedupe the check loop re-wakes