holistic_search
Search across all memory layers—content, decisions, mistakes, concepts, sessions, and commits—to find relevant information in writing projects.
Instructions
Unified search across all memory layers (content, decisions, mistakes, concepts, sessions, commits)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_path | No | Path to manuscript directory (defaults to current directory) | |
| query | Yes | Search query | |
| layers | No | Memory layers to search (default: all) | |
| start_date | No | Filter results after this date (ISO format or relative) | |
| end_date | No | Filter results before this date (ISO format or relative) | |
| limit | No | Maximum results to return | |
| min_relevance | No | Minimum relevance score (0-1) |
Implementation Reference
- src/tools/WriterToolDefinitions.ts:513-536 (registration)Tool registration definition including name, description, and input schema for 'holistic_search' in the writerToolDefinitions array.{ name: "holistic_search", description: "Unified search across all memory layers (content, decisions, mistakes, concepts, sessions, commits)", inputSchema: { type: "object", properties: { project_path: { type: "string", description: "Path to manuscript directory (defaults to current directory)" }, query: { type: "string", description: "Search query" }, layers: { type: "array", items: { type: "string", enum: ["content", "decisions", "mistakes", "concepts", "sessions", "commits"], }, description: "Memory layers to search (default: all)", }, start_date: { type: "string", description: "Filter results after this date (ISO format or relative)" }, end_date: { type: "string", description: "Filter results before this date (ISO format or relative)" }, limit: { type: "number", description: "Maximum results to return", default: 20 }, min_relevance: { type: "number", description: "Minimum relevance score (0-1)", default: 0 }, }, required: ["query"], }, },
- Input schema defining parameters for the holistic_search tool: query (required), layers, dates, limit, min_relevance.inputSchema: { type: "object", properties: { project_path: { type: "string", description: "Path to manuscript directory (defaults to current directory)" }, query: { type: "string", description: "Search query" }, layers: { type: "array", items: { type: "string", enum: ["content", "decisions", "mistakes", "concepts", "sessions", "commits"], }, description: "Memory layers to search (default: all)", }, start_date: { type: "string", description: "Filter results after this date (ISO format or relative)" }, end_date: { type: "string", description: "Filter results before this date (ISO format or relative)" }, limit: { type: "number", description: "Maximum results to return", default: 20 }, min_relevance: { type: "number", description: "Minimum relevance score (0-1)", default: 0 }, }, required: ["query"],
- src/WritersAid.ts:748-768 (handler)Handler method in WritersAid class that receives tool parameters, processes dates, and delegates execution to HolisticSearcher.search method.async holisticSearch(options: { query: string; layers?: Array<"content" | "decisions" | "mistakes" | "concepts" | "sessions" | "commits">; startDate?: string; endDate?: string; limit?: number; minRelevance?: number; }) { const dateRange = { start: options.startDate ? new Date(options.startDate) : undefined, end: options.endDate ? new Date(options.endDate) : undefined, }; return this.holisticSearcher.search({ query: options.query, layers: options.layers, dateRange, limit: options.limit, minRelevance: options.minRelevance, }); }
- Core implementation of unified search in HolisticSearcher class: searches specified layers in parallel, merges results, sorts by relevance, applies filters and limit.async search(query: HolisticSearchQuery): Promise<HolisticSearchResult> { const startTime = Date.now(); const layers = query.layers || [ "content", "decisions", "mistakes", "concepts", "sessions", "commits", ]; const limit = query.limit || 20; const allResults: SearchResult[] = []; const layerStats: Record<SearchLayer, number> = { content: 0, decisions: 0, mistakes: 0, concepts: 0, sessions: 0, commits: 0, }; // Search each layer in parallel const promises = []; if (layers.includes("content")) { promises.push(this.searchContent(query)); } if (layers.includes("decisions")) { promises.push(this.searchDecisions(query)); } if (layers.includes("mistakes")) { promises.push(this.searchMistakes(query)); } if (layers.includes("concepts")) { promises.push(this.searchConcepts(query)); } if (layers.includes("sessions")) { promises.push(this.searchSessions(query)); } if (layers.includes("commits")) { promises.push(this.searchCommits(query)); } const results = await Promise.all(promises); // Merge and sort results by relevance for (const layerResults of results) { for (const result of layerResults) { allResults.push(result); layerStats[result.layer]++; } } // Sort by relevance (highest first) allResults.sort((a, b) => b.relevance - a.relevance); // Apply minimum relevance filter const minRelevance = query.minRelevance || 0; const filtered = allResults.filter((r) => r.relevance >= minRelevance); // Apply limit const limited = filtered.slice(0, limit); const executionTime = Date.now() - startTime; return { query: query.query, results: limited, totalResults: filtered.length, layerStats, searchedLayers: layers, executionTime, }; }
- src/memory/HolisticSearcher.ts:66-85 (helper)HolisticSearcher class definition and constructor that initializes dependencies for multi-layer search.export class HolisticSearcher { private db: SQLiteManager; private manuscriptSearch: ManuscriptSearch; private sessionManager: SessionManager; private conceptTracker: ConceptTracker; constructor( db: SQLiteManager, manuscriptSearch: ManuscriptSearch, sessionManager: SessionManager, _decisionExtractor: DecisionExtractor, _mistakeTracker: MistakeTracker, conceptTracker: ConceptTracker, _gitIntegrator: GitIntegrator ) { this.db = db; this.manuscriptSearch = manuscriptSearch; this.sessionManager = sessionManager; this.conceptTracker = conceptTracker; }