diff --git a/.vscode/settings.json b/.vscode/settings.json index fa31a480..c2bbe744 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,6 +13,7 @@ "elif", "errmsg", "fullscreen", + "fulltext", "headlessui", "Icdbb", "icns", diff --git a/docs/content.en/docs/release-notes/_index.md b/docs/content.en/docs/release-notes/_index.md index 24b20e9f..51ce4ce1 100644 --- a/docs/content.en/docs/release-notes/_index.md +++ b/docs/content.en/docs/release-notes/_index.md @@ -32,6 +32,7 @@ Information about release notes of Coco Server is provided here. - fix: fixed the newly created session has no title when it is deleted #511 - fix: loading chat history for potential empty attachments - fix: datasource & MCP list synchronization update #521 +- fix: show only enabled datasource & MCP list ### ✈️ Improvements diff --git a/src-tauri/src/common/http.rs b/src-tauri/src/common/http.rs index f1250255..a3831854 100644 --- a/src-tauri/src/common/http.rs +++ b/src-tauri/src/common/http.rs @@ -26,7 +26,7 @@ pub async fn get_response_body_text(response: Response) -> Result= 400 { // Try to parse the error body @@ -49,4 +49,4 @@ pub async fn get_response_body_text(response: Response) -> Result { - dbg!("Close requested event received"); + //dbg!("Close requested event received"); window.hide().unwrap(); api.prevent_close(); } @@ -225,10 +225,10 @@ pub fn run() { has_visible_windows, .. } => { - dbg!( - "Reopen event received: has_visible_windows = {}", - has_visible_windows - ); + // dbg!( + // "Reopen event received: has_visible_windows = {}", + // has_visible_windows + // ); if has_visible_windows { return; } @@ -289,7 +289,7 @@ async fn hide_coco(app: AppHandle) { } fn move_window_to_active_monitor(window: &Window) { - dbg!("Moving window to active monitor"); + //dbg!("Moving window to active monitor"); // Try to get the available monitors, handle failure gracefully let available_monitors = match window.available_monitors() { Ok(monitors) => monitors, diff --git a/src-tauri/src/server/datasource.rs b/src-tauri/src/server/datasource.rs index 75598356..29c5fda3 100644 --- a/src-tauri/src/server/datasource.rs +++ b/src-tauri/src/server/datasource.rs @@ -4,6 +4,7 @@ use crate::server::connector::get_connector_by_id; use crate::server::http_client::HttpClient; use crate::server::servers::get_all_servers; use lazy_static::lazy_static; +use serde_json::Value; use std::collections::HashMap; use std::sync::{Arc, RwLock}; use tauri::{AppHandle, Runtime}; @@ -12,7 +13,7 @@ use tauri::{AppHandle, Runtime}; pub struct GetDatasourcesByServerOptions { pub from: Option, pub size: Option, - pub query: Option, + pub query: Option, } lazy_static! { @@ -32,7 +33,7 @@ pub fn save_datasource_to_cache(server_id: &str, datasources: Vec) { #[allow(dead_code)] pub fn get_datasources_from_cache(server_id: &str) -> Option> { let cache = DATASOURCE_CACHE.read().unwrap(); // Acquire read lock - // dbg!("cache: {:?}", &cache); + // dbg!("cache: {:?}", &cache); let server_cache = cache.get(server_id)?; // Get the server's cache Some(server_cache.clone()) } @@ -100,31 +101,14 @@ pub async fn datasource_search( ) -> Result, String> { let from = options.as_ref().and_then(|opt| opt.from).unwrap_or(0); let size = options.as_ref().and_then(|opt| opt.size).unwrap_or(10000); - let query = options - .and_then(|opt| opt.query) - .unwrap_or(String::default()); let mut body = serde_json::json!({ "from": from, "size": size, }); - if !query.is_empty() { - body["query"] = serde_json::json!({ - "bool": { - "must": [{ - "query_string": { - "fields": ["combined_fulltext"], - "query": query, - "fuzziness": "AUTO", - "fuzzy_prefix_length": 2, - "fuzzy_max_expansions": 10, - "fuzzy_transpositions": true, - "allow_leading_wildcard": false - } - }] - } - }); + if let Some(q) = options.unwrap().query { + body["query"] = q; } // Perform the async HTTP request outside the cache lock @@ -134,12 +118,12 @@ pub async fn datasource_search( None, Some(reqwest::Body::from(body.to_string())), ) - .await - .map_err(|e| format!("Error fetching datasource: {}", e))?; + .await + .map_err(|e| format!("Error fetching datasource: {}", e))?; // Parse the search results from the response let datasources: Vec = parse_search_results(resp).await.map_err(|e| { - dbg!("Error parsing search results: {}", &e); + //dbg!("Error parsing search results: {}", &e); e.to_string() })?; @@ -152,35 +136,17 @@ pub async fn datasource_search( #[tauri::command] pub async fn mcp_server_search( id: &str, - options: Option, + from: u32, + size: u32, + query: Option>, ) -> Result, String> { - let from = options.as_ref().and_then(|opt| opt.from).unwrap_or(0); - let size = options.as_ref().and_then(|opt| opt.size).unwrap_or(10000); - let query = options - .and_then(|opt| opt.query) - .unwrap_or(String::default()); - let mut body = serde_json::json!({ - "from": from, - "size": size, + "from": from, + "size": size, }); - if !query.is_empty() { - body["query"] = serde_json::json!({ - "bool": { - "must": [{ - "query_string": { - "fields": ["combined_fulltext"], - "query": query, - "fuzziness": "AUTO", - "fuzzy_prefix_length": 2, - "fuzzy_max_expansions": 10, - "fuzzy_transpositions": true, - "allow_leading_wildcard": false - } - }] - } - }); + if let Some(q) = query { + body["query"] = serde_json::to_value(q).map_err(|e| e.to_string())?; } // Perform the async HTTP request outside the cache lock @@ -190,12 +156,12 @@ pub async fn mcp_server_search( None, Some(reqwest::Body::from(body.to_string())), ) - .await - .map_err(|e| format!("Error fetching datasource: {}", e))?; + .await + .map_err(|e| format!("Error fetching datasource: {}", e))?; // Parse the search results from the response let mcp_server: Vec = parse_search_results(resp).await.map_err(|e| { - dbg!("Error parsing search results: {}", &e); + //dbg!("Error parsing search results: {}", &e); e.to_string() })?; diff --git a/src-tauri/src/server/http_client.rs b/src-tauri/src/server/http_client.rs index 55f1224e..708ee8d0 100644 --- a/src-tauri/src/server/http_client.rs +++ b/src-tauri/src/server/http_client.rs @@ -44,28 +44,28 @@ impl HttpClient { headers: Option>, body: Option, ) -> Result { - log::debug!( - "Sending Request: {}, query_params: {:?}, header: {:?}, body: {:?}", - &url, - &query_params, - &headers, - &body - ); + // log::debug!( + // "Sending Request: {}, query_params: {:?}, header: {:?}, body: {:?}", + // &url, + // &query_params, + // &headers, + // &body + // ); let request_builder = Self::get_request_builder(method, url, headers, query_params, body).await; let response = request_builder.send().await.map_err(|e| { - dbg!("Failed to send request: {}", &e); + //dbg!("Failed to send request: {}", &e); format!("Failed to send request: {}", e) })?; - log::debug!( - "Request: {}, Response status: {:?}, header: {:?}", - &url, - &response.status(), - &response.headers() - ); + // log::debug!( + // "Request: {}, Response status: {:?}, header: {:?}", + // &url, + // &response.status(), + // &response.headers() + // ); Ok(response) } @@ -165,12 +165,12 @@ impl HttpClient { headers.insert("X-API-TOKEN".to_string(), t); } - log::debug!( - "Sending request to server: {}, url: {}, headers: {:?}", - &server_id, - &url, - &headers - ); + // log::debug!( + // "Sending request to server: {}, url: {}, headers: {:?}", + // &server_id, + // &url, + // &headers + // ); Self::send_raw_request(method, &url, query_params, Some(headers), body).await } else { diff --git a/src/components/Assistant/AssistantList.tsx b/src/components/Assistant/AssistantList.tsx index 884d2e5b..c7aa98b6 100644 --- a/src/components/Assistant/AssistantList.tsx +++ b/src/components/Assistant/AssistantList.tsx @@ -82,34 +82,31 @@ export function AssistantList({ assistantIDs = [] }: AssistantListProps) { size, }; - if (debounceKeyword || assistantIDs.length > 0) { - body.query = { - bool: { - must: [ - {term: {"enabled": true}} - ], + body.query = { + bool: { + must: [{ term: { enabled: true } }], + }, + }; + + if (debounceKeyword) { + body.query.bool.must.push({ + query_string: { + fields: ["combined_fulltext"], + query: debounceKeyword, + fuzziness: "AUTO", + fuzzy_prefix_length: 2, + fuzzy_max_expansions: 10, + fuzzy_transpositions: true, + allow_leading_wildcard: false, }, - }; - if (debounceKeyword) { - body.query.bool.must.push({ - query_string: { - fields: ["combined_fulltext"], - query: debounceKeyword, - fuzziness: "AUTO", - fuzzy_prefix_length: 2, - fuzzy_max_expansions: 10, - fuzzy_transpositions: true, - allow_leading_wildcard: false, - }, - }); - } - if (assistantIDs.length > 0) { - body.query.bool.must.push({ - terms: { - id: assistantIDs.map((id) => id), - }, - }); - } + }); + } + if (assistantIDs.length > 0) { + body.query.bool.must.push({ + terms: { + id: assistantIDs.map((id) => id), + }, + }); } if (isTauri) { diff --git a/src/components/SearchChat/index.tsx b/src/components/SearchChat/index.tsx index 93184e3e..fe1cdb2e 100644 --- a/src/components/SearchChat/index.tsx +++ b/src/components/SearchChat/index.tsx @@ -23,7 +23,7 @@ import platformAdapter from "@/utils/platformAdapter"; import { useStartupStore } from "@/stores/startupStore"; import { DataSource } from "@/types/commands"; import { useThemeStore } from "@/stores/themeStore"; -import { Get } from "@/api/axiosRequest"; +import { Post } from "@/api/axiosRequest"; import { useConnectStore } from "@/stores/connectStore"; import { useAppearanceStore } from "@/stores/appearanceStore"; @@ -217,14 +217,41 @@ function SearchChat({ ) { return []; } + + const body: Record = { + id: serverId, + from: options?.from || 0, + size: options?.size || 1000, + }; + + body.query = { + bool: { + must: [{ term: { enabled: true } }], + }, + }; + + if (options?.query) { + body.query.bool.must.push({ + query_string: { + fields: ["combined_fulltext"], + query: options?.query, + fuzziness: "AUTO", + fuzzy_prefix_length: 2, + fuzzy_max_expansions: 10, + fuzzy_transpositions: true, + allow_leading_wildcard: false, + }, + }); + } + let response: any; if (isTauri) { response = await platformAdapter.invokeBackend("datasource_search", { id: serverId, - options, + options: body, }); } else { - const [error, res]: any = await Get("/datasource/_search"); + const [error, res]: any = await Post("/datasource/_search", body); if (error) { console.error("_search", error); return []; @@ -258,14 +285,39 @@ function SearchChat({ if (!(assistantConfig.mcpEnabled && assistantConfig.mcpVisible)) { return []; } + const body: Record = { + id: serverId, + from: options?.from || 0, + size: options?.size || 1000, + }; + body.query = { + bool: { + must: [{ term: { enabled: true } }], + }, + }; + + if (options?.query) { + body.query.bool.must.push({ + query_string: { + fields: ["combined_fulltext"], + query: options?.query, + fuzziness: "AUTO", + fuzzy_prefix_length: 2, + fuzzy_max_expansions: 10, + fuzzy_transpositions: true, + allow_leading_wildcard: false, + }, + }); + } + let response: any; if (isTauri) { - response = await platformAdapter.invokeBackend("mcp_server_search", { - id: serverId, - options, - }); + response = await platformAdapter.invokeBackend( + "mcp_server_search", + body + ); } else { - const [error, res]: any = await Get("/mcp_server/_search"); + const [error, res]: any = await Post("/mcp_server/_search", body); if (error) { console.error("_search", error); return [];