( query: string, mcpResources: Record<string, ServerResource[]>, agents: AgentDefinition[], showOnEmpty = false, )
| 109 | } |
| 110 | |
| 111 | export async function generateUnifiedSuggestions( |
| 112 | query: string, |
| 113 | mcpResources: Record<string, ServerResource[]>, |
| 114 | agents: AgentDefinition[], |
| 115 | showOnEmpty = false, |
| 116 | ): Promise<SuggestionItem[]> { |
| 117 | if (!query && !showOnEmpty) { |
| 118 | return [] |
| 119 | } |
| 120 | |
| 121 | const [fileSuggestions, agentSources] = await Promise.all([ |
| 122 | generateFileSuggestions(query, showOnEmpty), |
| 123 | Promise.resolve(generateAgentSuggestions(agents, query, showOnEmpty)), |
| 124 | ]) |
| 125 | |
| 126 | const fileSources: FileSuggestionSource[] = fileSuggestions.map( |
| 127 | suggestion => ({ |
| 128 | type: 'file' as const, |
| 129 | displayText: suggestion.displayText, |
| 130 | description: suggestion.description, |
| 131 | path: suggestion.displayText, // Use displayText as path for files |
| 132 | filename: basename(suggestion.displayText), |
| 133 | score: (suggestion.metadata as { score?: number } | undefined)?.score, |
| 134 | }), |
| 135 | ) |
| 136 | |
| 137 | const mcpSources: McpResourceSuggestionSource[] = Object.values(mcpResources) |
| 138 | .flat() |
| 139 | .map(resource => ({ |
| 140 | type: 'mcp_resource' as const, |
| 141 | displayText: `${resource.server}:${resource.uri}`, |
| 142 | description: truncateDescription( |
| 143 | resource.description || resource.name || resource.uri, |
| 144 | ), |
| 145 | server: resource.server, |
| 146 | uri: resource.uri, |
| 147 | name: resource.name || resource.uri, |
| 148 | })) |
| 149 | |
| 150 | if (!query) { |
| 151 | const allSources = [...fileSources, ...mcpSources, ...agentSources] |
| 152 | return allSources |
| 153 | .slice(0, MAX_UNIFIED_SUGGESTIONS) |
| 154 | .map(createSuggestionFromSource) |
| 155 | } |
| 156 | |
| 157 | const nonFileSources: SuggestionSource[] = [...mcpSources, ...agentSources] |
| 158 | |
| 159 | // Score non-file sources with Fuse.js |
| 160 | // File sources are already scored by Rust/nucleo |
| 161 | type ScoredSource = { source: SuggestionSource; score: number } |
| 162 | const scoredResults: ScoredSource[] = [] |
| 163 | |
| 164 | // Add file sources with their nucleo scores (already 0-1, lower is better) |
| 165 | for (const fileSource of fileSources) { |
| 166 | scoredResults.push({ |
| 167 | source: fileSource, |
| 168 | score: fileSource.score ?? 0.5, // Default to middle score if missing |
no test coverage detected