enhancement: automatically update MCP tool list UI on server change (#4940)

* enhancement: automatically update MCP tool list UI on server change

* enhancement: tool call block fit content
This commit is contained in:
Louis 2025-04-24 16:47:13 +07:00
parent 946e8dda65
commit 5c88cedaf0
No known key found for this signature in database
GPG Key ID: 44FA9F4D33C37DE2
4 changed files with 19 additions and 11 deletions

View File

@ -2,7 +2,7 @@ use std::{collections::HashMap, sync::Arc};
use rmcp::{service::RunningService, transport::TokioChildProcess, RoleClient, ServiceExt};
use serde_json::Value;
use tauri::{AppHandle, State};
use tauri::{AppHandle, Emitter, State};
use tokio::{process::Command, sync::Mutex};
use super::{cmd::get_jan_data_folder_path, state::AppState};
@ -24,7 +24,6 @@ pub async fn run_mcp_commands(
"Load MCP configs from {}",
app_path.clone() + "/mcp_config.json"
);
// let mut client_list = HashMap::new();
let config_content = std::fs::read_to_string(app_path.clone() + "/mcp_config.json")
.map_err(|e| format!("Failed to read config file: {}", e))?;
@ -81,10 +80,7 @@ fn extract_command_args(
}
#[tauri::command]
pub async fn restart_mcp_servers(
app: AppHandle,
state: State<'_, AppState>,
) -> Result<(), String> {
pub async fn restart_mcp_servers(app: AppHandle, state: State<'_, AppState>) -> Result<(), String> {
let app_path = get_jan_data_folder_path(app.clone());
let app_path_str = app_path.to_str().unwrap().to_string();
let servers = state.mcp_servers.clone();
@ -92,7 +88,10 @@ pub async fn restart_mcp_servers(
stop_mcp_servers(state.mcp_servers.clone()).await?;
// Restart the servers
run_mcp_commands(app_path_str, servers).await
run_mcp_commands(app_path_str, servers).await?;
app.emit("mcp-update", "MCP servers updated")
.map_err(|e| format!("Failed to emit event: {}", e))
}
pub async fn stop_mcp_servers(

View File

@ -6,7 +6,7 @@ use std::{
sync::{Arc, Mutex},
};
use tar::Archive;
use tauri::{App, Listener, Manager};
use tauri::{App, Emitter, Listener, Manager};
use tauri_plugin_shell::process::CommandEvent;
use tauri_plugin_shell::ShellExt;
use tauri_plugin_store::StoreExt;
@ -185,10 +185,12 @@ pub fn setup_mcp(app: &App) {
let state = app.state::<AppState>().inner();
let app_path_str = app_path.to_str().unwrap().to_string();
let servers = state.mcp_servers.clone();
let app_handle = app.handle().clone();
tauri::async_runtime::spawn(async move {
if let Err(e) = run_mcp_commands(app_path_str, servers).await {
log::error!("Failed to run mcp commands: {}", e);
}
app_handle.emit("mcp-update", "MCP servers updated").unwrap();
});
}

View File

@ -13,6 +13,7 @@ import {
Modal,
Switch,
} from '@janhq/joi'
import { listen } from '@tauri-apps/api/event'
import { useAtom, useAtomValue } from 'jotai'
import {
FileTextIcon,
@ -117,6 +118,12 @@ const ChatInput = () => {
window.core?.api?.getTools().then((data: ModelTool[]) => {
setTools(data)
})
listen('mcp-update', (event) => {
window.core?.api?.getTools().then((data: ModelTool[]) => {
setTools(data)
})
})
}, [])
const onStopInferenceClick = async () => {

View File

@ -49,11 +49,11 @@ const ToolCallBlock = ({ id, name, result, loading, onExpand }: Props) => {
<ScrollArea
className={twMerge(
'w-full overflow-hidden transition-all duration-300',
isExpanded ? 'max-h-96' : 'max-h-0'
'h-fit w-full overflow-auto transition-all duration-300',
isExpanded ? 'max-h-44' : 'max-h-0 overflow-hidden'
)}
>
<div className="mt-2 overflow-x-hidden pl-6 text-[hsla(var(--text-secondary))]">
<div className="mt-2 inline-block overflow-x-hidden pl-6 text-[hsla(var(--text-secondary))]">
<span>{result ?? ''} </span>
</div>
</ScrollArea>