- Add plugin/calendar/types.ts: TypeScript interfaces for heartbeat request/response (CalendarHeartbeatRequest/Response, CalendarSlotResponse, SlotAgentUpdate, all enums: SlotType, SlotStatus, EventType) - Add plugin/calendar/calendar-bridge.ts: CalendarBridgeClient HTTP client with heartbeat(), updateSlot(), updateVirtualSlot(), reportAgentStatus() - Add plugin/calendar/index.ts: module entry point exporting all public types - Add docs/PLG-CAL-001-calendar-heartbeat-format.md: full specification documenting claw_identifier and agent_id determination, request/response shapes, error handling, and endpoint summary - Update plugin/openclaw.plugin.json: add calendarEnabled, calendarHeartbeatIntervalSec, calendarApiKey config options; clarify identifier description as claw_identifier Refs: HarborForge.NEXT_WAVE_DEV_DIRECTION.md §6, BE-AGT-001
124 lines
5.0 KiB
TypeScript
124 lines
5.0 KiB
TypeScript
/**
|
|
* HarborForge Calendar Bridge Client
|
|
*
|
|
* PLG-CAL-001: Handles HTTP communication between the OpenClaw plugin
|
|
* and the HarborForge backend for Calendar heartbeat and slot updates.
|
|
*
|
|
* Request authentication:
|
|
* • X-Agent-ID header — set to process.env.AGENT_ID
|
|
* • X-Claw-Identifier header — set to the server's claw_identifier
|
|
* (from plugin config or hostname fallback)
|
|
*
|
|
* Base URL:
|
|
* Derived from plugin config: backendUrl + "/calendar"
|
|
* Default backendUrl: "https://monitor.hangman-lab.top"
|
|
*
|
|
* Endpoints used:
|
|
* GET /calendar/agent/heartbeat — fetch pending slots
|
|
* PATCH /calendar/slots/{id}/agent-update — update real slot status
|
|
* PATCH /calendar/slots/virtual/{vid}/agent-update — update virtual slot status
|
|
*
|
|
* References:
|
|
* • NEXT_WAVE_DEV_DIRECTION.md §6.1 (Heartbeat flow)
|
|
* • HarborForge.Backend/app/services/agent_heartbeat.py (BE-AGT-001)
|
|
*/
|
|
import { CalendarHeartbeatResponse, CalendarSlotResponse, SlotAgentUpdate } from './types';
|
|
export interface CalendarBridgeConfig {
|
|
/** HarborForge backend base URL (e.g. "https://monitor.hangman-lab.top") */
|
|
backendUrl: string;
|
|
/** Server/claw identifier (from plugin config or hostname fallback) */
|
|
clawIdentifier: string;
|
|
/** OpenClaw agent ID ($AGENT_ID), set at agent startup */
|
|
agentId: string;
|
|
/** HTTP request timeout in milliseconds (default: 5000) */
|
|
timeoutMs?: number;
|
|
}
|
|
export declare class CalendarBridgeClient {
|
|
private baseUrl;
|
|
private config;
|
|
private timeoutMs;
|
|
constructor(config: CalendarBridgeConfig);
|
|
/**
|
|
* Fetch today's pending calendar slots for this agent.
|
|
*
|
|
* Heartbeat flow (§6.1):
|
|
* 1. Plugin sends heartbeat every minute
|
|
* 2. Backend returns slots where status is NotStarted or Deferred
|
|
* AND scheduled_at <= now
|
|
* 3. Plugin selects highest-priority slot (if any)
|
|
* 4. For remaining slots, plugin sets status = Deferred + priority += 1
|
|
*
|
|
* @returns CalendarHeartbeatResponse or null if the backend is unreachable
|
|
*/
|
|
heartbeat(): Promise<CalendarHeartbeatResponse | null>;
|
|
/**
|
|
* Update a real (materialized) slot's status after agent execution.
|
|
*
|
|
* Used by the plugin to report:
|
|
* - Slot attended (attended=true, started_at=now, status=Ongoing)
|
|
* - Slot finished (actual_duration set, status=Finished)
|
|
* - Slot deferred (status=Deferred, priority += 1)
|
|
* - Slot aborted (status=Aborted)
|
|
*
|
|
* @param slotId Real slot DB id
|
|
* @param update Status update payload
|
|
* @returns true on success, false on failure
|
|
*/
|
|
updateSlot(slotId: number, update: SlotAgentUpdate): Promise<boolean>;
|
|
/**
|
|
* Update a virtual (plan-generated) slot's status after agent execution.
|
|
*
|
|
* When updating a virtual slot, the backend first materializes it
|
|
* (creates a real TimeSlot row), then applies the update.
|
|
* The returned slot will have a real id on subsequent calls.
|
|
*
|
|
* @param virtualId Virtual slot id in format "plan-{plan_id}-{date}"
|
|
* @param update Status update payload
|
|
* @returns Updated CalendarSlotResponse on success, null on failure
|
|
*/
|
|
updateVirtualSlot(virtualId: string, update: SlotAgentUpdate): Promise<CalendarSlotResponse | null>;
|
|
/**
|
|
* Report the agent's current runtime status to HarborForge.
|
|
*
|
|
* Used to push agent status transitions:
|
|
* idle → busy / on_call (when starting a slot)
|
|
* busy / on_call → idle (when finishing a slot)
|
|
* → exhausted (on rate-limit / billing error, with recovery_at)
|
|
* → offline (after 2 min with no heartbeat)
|
|
*
|
|
* @param status New agent status
|
|
* @param recoveryAt ISO timestamp for expected Exhausted recovery (optional)
|
|
* @param exhaustReason "rate_limit" | "billing" (required if status=exhausted)
|
|
*/
|
|
reportAgentStatus(params: {
|
|
status: 'idle' | 'on_call' | 'busy' | 'exhausted' | 'offline';
|
|
recoveryAt?: string;
|
|
exhaustReason?: 'rate_limit' | 'billing';
|
|
}): Promise<boolean>;
|
|
private fetchJson;
|
|
private postBoolean;
|
|
}
|
|
export interface CalendarPluginConfig {
|
|
/** Backend URL for calendar API (overrides monitor backendUrl) */
|
|
calendarBackendUrl?: string;
|
|
/** Server identifier (overrides auto-detected hostname) */
|
|
identifier?: string;
|
|
/** Agent ID from OpenClaw ($AGENT_ID) */
|
|
agentId: string;
|
|
/** HTTP timeout for calendar API calls (default: 5000) */
|
|
timeoutMs?: number;
|
|
}
|
|
/**
|
|
* Build a CalendarBridgeClient from the OpenClaw plugin API context.
|
|
*
|
|
* @param api OpenClaw plugin API (register() receives this)
|
|
* @param fallbackUrl Fallback backend URL if not configured
|
|
* @param agentId $AGENT_ID from OpenClaw environment
|
|
*/
|
|
export declare function createCalendarBridgeClient(api: {
|
|
config?: Record<string, unknown>;
|
|
logger?: {
|
|
debug?: (...args: unknown[]) => void;
|
|
};
|
|
}, fallbackUrl: string, agentId: string): CalendarBridgeClient;
|
|
//# sourceMappingURL=calendar-bridge.d.ts.map
|