mirror of
https://github.com/infinilabs/coco-app.git
synced 2025-12-16 03:27:43 +01:00
fix: show only enabled datasource & MCP list (#523)
* fix: show only enabled datasource & MCP list * docs: update notes * fix: show only enabled datasource & MCP list
This commit is contained in:
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@@ -13,6 +13,7 @@
|
||||
"elif",
|
||||
"errmsg",
|
||||
"fullscreen",
|
||||
"fulltext",
|
||||
"headlessui",
|
||||
"Icdbb",
|
||||
"icns",
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ pub async fn get_response_body_text(response: Response) -> Result<String, String
|
||||
.await
|
||||
.map_err(|e| format!("Failed to read response body: {}, code: {}", e, status))?;
|
||||
|
||||
log::debug!("Response status: {}, body: {}", status, &body);
|
||||
//log::debug!("Response status: {}, body: {}", status, &body);
|
||||
|
||||
if status < 200 || status >= 400 {
|
||||
// Try to parse the error body
|
||||
|
||||
@@ -210,7 +210,7 @@ pub fn run() {
|
||||
})
|
||||
.on_window_event(|window, event| match event {
|
||||
WindowEvent::CloseRequested { api, .. } => {
|
||||
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<R: Runtime>(app: AppHandle<R>) {
|
||||
}
|
||||
|
||||
fn move_window_to_active_monitor<R: Runtime>(window: &Window<R>) {
|
||||
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,
|
||||
|
||||
@@ -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<u32>,
|
||||
pub size: Option<u32>,
|
||||
pub query: Option<String>,
|
||||
pub query: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
@@ -100,31 +101,14 @@ pub async fn datasource_search(
|
||||
) -> Result<Vec<DataSource>, 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
|
||||
@@ -139,7 +123,7 @@ pub async fn datasource_search(
|
||||
|
||||
// Parse the search results from the response
|
||||
let datasources: Vec<DataSource> = 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<GetDatasourcesByServerOptions>,
|
||||
from: u32,
|
||||
size: u32,
|
||||
query: Option<HashMap<String, Value>>,
|
||||
) -> Result<Vec<DataSource>, 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) = query {
|
||||
body["query"] = serde_json::to_value(q).map_err(|e| e.to_string())?;
|
||||
}
|
||||
|
||||
// Perform the async HTTP request outside the cache lock
|
||||
@@ -195,7 +161,7 @@ pub async fn mcp_server_search(
|
||||
|
||||
// Parse the search results from the response
|
||||
let mcp_server: Vec<DataSource> = parse_search_results(resp).await.map_err(|e| {
|
||||
dbg!("Error parsing search results: {}", &e);
|
||||
//dbg!("Error parsing search results: {}", &e);
|
||||
e.to_string()
|
||||
})?;
|
||||
|
||||
|
||||
@@ -44,28 +44,28 @@ impl HttpClient {
|
||||
headers: Option<HashMap<String, String>>,
|
||||
body: Option<reqwest::Body>,
|
||||
) -> Result<reqwest::Response, String> {
|
||||
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 {
|
||||
|
||||
@@ -82,14 +82,12 @@ export function AssistantList({ assistantIDs = [] }: AssistantListProps) {
|
||||
size,
|
||||
};
|
||||
|
||||
if (debounceKeyword || assistantIDs.length > 0) {
|
||||
body.query = {
|
||||
bool: {
|
||||
must: [
|
||||
{term: {"enabled": true}}
|
||||
],
|
||||
must: [{ term: { enabled: true } }],
|
||||
},
|
||||
};
|
||||
|
||||
if (debounceKeyword) {
|
||||
body.query.bool.must.push({
|
||||
query_string: {
|
||||
@@ -110,7 +108,6 @@ export function AssistantList({ assistantIDs = [] }: AssistantListProps) {
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (isTauri) {
|
||||
if (!currentServiceId) {
|
||||
|
||||
@@ -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<string, any> = {
|
||||
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<string, any> = {
|
||||
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 [];
|
||||
|
||||
Reference in New Issue
Block a user