/** * Trajectory Collector - message write trajectory recording * * Fallback trajectory collection when llm_output is blocked by missing * allowConversationAccess. before_message_write is NOT in * CONVERSATION_HOOK_NAMES so OpenClaw always delivers it. * * SQLite writes are enqueued to an async queue because before_message_write is * a SYNCHRONOUS OpenClaw hook — the handler must return immediately. better-sqlite3 * is synchronous, so calling it directly would block the message-write main path. * Trade-off: in degradation mode the last few queued writes may be lost on * process exit; this is acceptable because degradation mode is already caused * by a config problem (missing allowConversationAccess), and the primary * llm_output path is authoritative when authorized. * * JSONL writing was removed (no consumers — verified zero readers across the * codebase; PRI-347 already removed tool_call/llm_output JSONL writers). * * ERR-002: fallback errors are logged, never silent. * ERR-001/005: content is sanitized before persisting. */ import type { PluginHookAgentContext, PluginHookBeforeMessageWriteEvent } from '../openclaw-sdk.js'; /** * PRI-346: Message write hook with SQLite fallback trajectory recording. * * When allowConversationAccess is NOT set (unauthorized), llm_output is silently * blocked by OpenClaw and trajectory.db has no data. This hook is NOT in * CONVERSATION_HOOK_NAMES, so it always fires — making it the natural fallback. * * De-duplication: only writes to SQLite when llm_output is blocked (unauthorized). * When llm_output is working (authorized), this hook is a no-op. * * SQLite writes are async-queued (see file header) to avoid blocking the sync hook. * * ERR-002: structured observability when fallback fires. * ERR-001/005: content is sanitized before persisting. */ export declare function handleBeforeMessageWrite(event: PluginHookBeforeMessageWriteEvent, ctx: PluginHookAgentContext & { workspaceDir?: string; pluginConfig?: unknown; }): void;