/** * Observability SQLite bootstrap. * * Opens (or creates) `~/.crewly/observability.db` and applies the * idempotent migration for `agent_behavior_log`. The schema is a * single append-only table that backs Crewly's minimal internal * metrics (delegate-first rate, escalation patterns, slack-delivery * failure counters, prompt-size trends). * * This module mirrors the lazy `better-sqlite3` loader pattern from * `services/chat-v2/sqlite/chat-db.ts` so the native module never * loads at import time — only when an opener is first called. * * @module services/observability/observability-db */ import { type ComponentLogger } from '../core/logger.service.js'; /** Type alias for a `better-sqlite3` Database instance. */ export type ObservabilityDatabase = import('better-sqlite3').Database; /** * Idempotent base DDL for the observability database. * * Single table strategy: every behavior event lives in * `agent_behavior_log`, discriminated by `event_type`. Per-event-type * payload variation is captured in the optional `subject`, `task_id`, * `reason`, `amount`, and `details_json` columns. This keeps the * schema small while supporting later additive event types without * migrations. * * Indexes are scoped to the most common query shapes for the weekly * digest (per-agent, per-event-type, per-time-window). */ export declare const OBSERVABILITY_MIGRATION_SQL = "\nCREATE TABLE IF NOT EXISTS agent_behavior_log (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n ts INTEGER NOT NULL,\n event_type TEXT NOT NULL,\n agent TEXT NOT NULL DEFAULT '',\n subject TEXT NOT NULL DEFAULT '',\n task_id TEXT NOT NULL DEFAULT '',\n reason TEXT NOT NULL DEFAULT '',\n amount INTEGER NOT NULL DEFAULT 0,\n details_json TEXT NOT NULL DEFAULT '{}'\n);\n\nCREATE INDEX IF NOT EXISTS ix_behavior_log_ts\n ON agent_behavior_log(ts);\n\nCREATE INDEX IF NOT EXISTS ix_behavior_log_event_ts\n ON agent_behavior_log(event_type, ts);\n\nCREATE INDEX IF NOT EXISTS ix_behavior_log_agent_event_ts\n ON agent_behavior_log(agent, event_type, ts);\n"; /** * Default on-disk path for the observability database. * * Lives next to the chat database under `~/.crewly/` so operators have a * single directory to back up / inspect. * * @returns Absolute path to `~/.crewly/observability.db` */ export declare function defaultObservabilityDbPath(): string; /** * Options accepted by `openObservabilityDatabase`. */ export interface OpenObservabilityDatabaseOptions { /** * Absolute path to the SQLite file. Parent directories are created * as needed. Defaults to `defaultObservabilityDbPath()`. */ dbPath?: string; /** * When true, uses SQLite `:memory:` regardless of `dbPath`. Intended * for unit tests. Defaults to false. */ inMemory?: boolean; /** * When true, suppress the integrity-check warning on open. Tests use * this to avoid noisy logs. Defaults to false. */ skipIntegrityCheck?: boolean; /** Optional logger override — defaults to `LoggerService`. */ logger?: ComponentLogger; } /** * Open (or create) the observability database, apply PRAGMAs, run the * idempotent migration, and run a boot-time integrity check. * * Safe to call multiple times during a single process lifetime — each * call returns a fresh `Database` handle the caller is responsible for * closing. In production, code should hold a single shared handle and * close it during graceful shutdown. * * @param options - Opener options * @returns A ready-to-use better-sqlite3 Database handle * * @example * ```ts * const db = openObservabilityDatabase(); * // ... use db ... * db.close(); * ``` */ export declare function openObservabilityDatabase(options?: OpenObservabilityDatabaseOptions): ObservabilityDatabase; //# sourceMappingURL=observability-db.d.ts.map