Purpose
Track search effectiveness: log query → result count → top score for every brain_search call. Foundation for B2a/B2c stats.
Design
Add search_analytics table to src/schema.ts:
CREATE TABLE IF NOT EXISTS search_analytics (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL,
query TEXT NOT NULL,
result_count INTEGER NOT NULL DEFAULT 0,
top_score REAL DEFAULT 0,
content_types TEXT DEFAULT '',
duration_ms INTEGER DEFAULT 0,
helpful INTEGER, -- NULL=unreported, 0=no, 1=yes
used_results INTEGER, -- NULL=unreported, 0=no, 1=yes
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_search_analytics_session ON search_analytics(session_id, created_at);
Hook into brain_search tool execution in src/four-opencode-brain.ts:
- After search completes, INSERT a row with query, result_count, top_score, content_types, duration
- Generate UUID7 for id
- Use session-scoped session_id
Add aggregation function getSearchStats(sessionId?) returning:
- total_searches, avg_results, avg_top_score, most_common_content_type
Acceptance
search_analytics table created on schema init
- Every
brain_search call logged with full metrics
getSearchStats() returns correct aggregates
- Tests: verify table creation, search logging, aggregation
Purpose
Track search effectiveness: log query → result count → top score for every
brain_searchcall. Foundation for B2a/B2c stats.Design
Add
search_analyticstable tosrc/schema.ts:Hook into
brain_searchtool execution insrc/four-opencode-brain.ts:Add aggregation function
getSearchStats(sessionId?)returning:Acceptance
search_analyticstable created on schema initbrain_searchcall logged with full metricsgetSearchStats()returns correct aggregates