Allow searching persisted attached threads (#60574)

## Why

Title and content searches exclude attached threads, preventing clients from finding their saved conversations alongside ordinary threads.

## What changed

- Add `includeAttachedThreads` to `thread/list` and `thread/search`. For `thread/list`, require a non-empty `searchTerm` and preserve the usual provider and source filters.
- Expose `attachedToThreadId` on thread responses to identify the owning parent independently of fork and subagent lineage.
- Support inclusive searches through SQLite and filesystem fallback, repairing missing database entries with saved thread names during title searches.

## Testing

Add regression coverage for opt-in title and content searches, attached-parent metadata after restart, default search filters, filesystem searches without SQLite, and discovery and repair of unindexed title matches.

GitOrigin-RevId: ac12ec3c730ad7f1722bdf8e21600d17f12017f0
This commit is contained in:
Brent Traut
2026-11-10 11:17:06 +00:00
committed by copyberry
parent c82708f858
commit 77fde36ae1
56 changed files with 587 additions and 277 deletions
+2
View File
@@ -2007,6 +2007,7 @@ async fn resolve_resume_thread_id(
ClientRequest::ThreadList {
request_id: RequestId::Integer(0),
params: ThreadListParams {
include_attached_threads: false,
current_account_only: true,
excluded_thread_ids: None,
attached_to_thread_id: None,
@@ -2096,6 +2097,7 @@ async fn resolve_resume_thread_id(
ClientRequest::ThreadList {
request_id: RequestId::Integer(0),
params: ThreadListParams {
include_attached_threads: false,
current_account_only: false,
excluded_thread_ids: None,
attached_to_thread_id: None,
+2
View File
@@ -358,6 +358,7 @@ fn turn_items_for_thread_returns_matching_turn_items() {
extra: None,
session_id: "thread-1".to_string(),
forked_from_id: None,
attached_to_thread_id: None,
parent_thread_id: None,
preview: String::new(),
ephemeral: false,
@@ -871,6 +872,7 @@ fn sample_thread_start_response() -> ThreadStartResponse {
extra: None,
session_id: "67e55044-10b1-426f-9247-bb680e5fe0c7".to_string(),
forked_from_id: None,
attached_to_thread_id: None,
parent_thread_id: None,
preview: String::new(),
ephemeral: false,