← Back to PRs

#19722: feat(chat): add search functionality for chat history

by aleiby open 2026-02-18 03:50 View on GitHub →
app: web-ui gateway size: M
## Summary Closes #19725 Add text search across chat session transcripts: - **New `chat.search` gateway method** — search within a session's message history with case-insensitive matching, snippet extraction, and configurable result limits - **Extended `sessions.list` search** — new optional `searchContent` boolean parameter to scan transcript content in addition to session metadata (displayName, label, subject, key) - **UI controller wiring** — `searchChatHistory()` function in chat controller, `sessionsSearch` state in sessions controller ## Changes ### Backend - `ChatSearchParamsSchema` (sessionKey, query, limit) in protocol schema - `searchSessionTranscript()` helper in `session-utils.fs.ts` — reads JSONL transcripts, extracts text from string/array content, returns matches with snippets - `chat.search` handler in chat server methods, registered in gateway method list - `searchContent` param in `SessionsListParamsSchema` — when true, `sessions.list` also scans transcript content for the search term ### Frontend - `ChatSearchResult`, `ChatSearchMatch` types and `searchChatHistory()` in chat controller - `sessionsSearch` state property added to sessions controller, app state, and view state - `loadSessions()` now passes `search` and `searchContent` params ### Tests - 10 tests across `session-utils.fs.test.ts` and `session-utils.test.ts` covering: string/array content matching, empty queries, missing sessions, limit, case-insensitivity, message indexing, malformed JSON, and cross-session content filtering integration ## Existing limitation (unchanged) The `searchContent` option in `sessions.list` scans transcript files synchronously within the existing session filter loop. This is O(N) in session count, consistent with the existing synchronous I/O patterns used by `readSessionMessages`, `readSessionTitleFieldsFromTranscript`, etc. For large deployments with many sessions, a future improvement could add an inverted index or async streaming to avoid blocking the event loop. For now, using `limit` alongside `searchContent` is recommended. ## Test plan - [x] `pnpm test -- --run src/gateway/session-utils.fs.test.ts` — 51 tests pass - [x] `pnpm test -- --run src/gateway/session-utils.test.ts` — 37 tests pass - [x] `npx tsc --noEmit` — clean type check - [ ] CI checks on upstream ## AI-assisted This PR was developed with AI assistance (Claude Opus 4.6). All changes have been reviewed and tested. --- 🤖 [Tackled](https://github.com/aleiby/claude-skills/tree/main/tackle) with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h3>Greptile Summary</h3> Adds text search functionality for chat session transcripts via a new `chat.search` gateway method and a `searchContent` option on `sessions.list`. The backend reads JSONL transcript files, extracts text from string/array content formats, and returns matches with context snippets. The frontend adds corresponding types and controller functions. Good test coverage with 10 new tests. Two issues found: - **Message index mismatch**: `searchSessionTranscript` counts only `parsed?.message` lines for its `messageIndex`, but `readSessionMessages` (used by `chat.history`) also includes compaction entries in its output array. This causes the search result `index` to be off when a session has compaction entries, which would cause the UI to scroll to or highlight the wrong message. - **Missing transcript resolution params**: The `searchContent` path in `listSessionsFromStore` calls `searchSessionTranscriptFs` without passing `sessionFile` or `agentId`, unlike the comparable `readSessionTitleFieldsFromTranscript` call. This means transcript content search will silently fail for sessions stored in agent-specific directories. <h3>Confidence Score: 3/5</h3> - Two logic bugs should be fixed before merging: index mismatch with compaction entries and missing transcript resolution parameters for agent sessions. - The overall structure and patterns are solid and well-tested, but two logic bugs would cause incorrect behavior in production: (1) search result indices won't match chat history array positions when compaction entries exist, and (2) searchContent in sessions.list will silently miss transcripts for agent-specific sessions due to missing sessionFile/agentId parameters. - `src/gateway/session-utils.fs.ts` (messageIndex drift with compaction entries), `src/gateway/session-utils.ts` (missing sessionFile/agentId in searchContent call) <sub>Last reviewed commit: 9d3d8f8</sub> <!-- greptile_other_comments_section --> <sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub> <!-- /greptile_comment -->

Most Similar PRs