| 95 | } |
| 96 | |
| 97 | QFuture<LLMQore::ToolResult> ProjectSearchTool::executeAsync(const QJsonObject &input) |
| 98 | { |
| 99 | return QtConcurrent::run([this, input]() -> LLMQore::ToolResult { |
| 100 | QString query = input["query"].toString().trimmed(); |
| 101 | if (query.isEmpty()) { |
| 102 | throw LLMQore::ToolInvalidArgument("Query parameter is required"); |
| 103 | } |
| 104 | |
| 105 | QString searchTypeStr = input["search_type"].toString(); |
| 106 | if (searchTypeStr != "text" && searchTypeStr != "symbol") { |
| 107 | throw LLMQore::ToolInvalidArgument("search_type must be 'text' or 'symbol'"); |
| 108 | } |
| 109 | |
| 110 | SearchType searchType = (searchTypeStr == "symbol") ? SearchType::Symbol : SearchType::Text; |
| 111 | QList<SearchResult> results; |
| 112 | |
| 113 | if (searchType == SearchType::Text) { |
| 114 | bool caseSensitive = input["case_sensitive"].toBool(false); |
| 115 | bool useRegex = input["use_regex"].toBool(false); |
| 116 | bool wholeWords = input["whole_words"].toBool(false); |
| 117 | QString filePattern = input["file_pattern"].toString(); |
| 118 | |
| 119 | results = searchText(query, caseSensitive, useRegex, wholeWords, filePattern); |
| 120 | } else { |
| 121 | SymbolType symbolType = parseSymbolType(input["symbol_type"].toString()); |
| 122 | bool caseSensitive = input["case_sensitive"].toBool(false); |
| 123 | bool useRegex = input["use_regex"].toBool(false); |
| 124 | |
| 125 | results = searchSymbols(query, symbolType, caseSensitive, useRegex); |
| 126 | } |
| 127 | |
| 128 | if (results.isEmpty()) { |
| 129 | return LLMQore::ToolResult::text(QString("No matches found for '%1'").arg(query)); |
| 130 | } |
| 131 | |
| 132 | return LLMQore::ToolResult::text(formatResults(results, query)); |
| 133 | }); |
| 134 | } |
| 135 | |
| 136 | QList<ProjectSearchTool::SearchResult> ProjectSearchTool::searchText( |
| 137 | const QString &query, |
nothing calls this directly
no test coverage detected