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:
parent
946e8dda65
commit
5c88cedaf0
@ -2,7 +2,7 @@ use std::{collections::HashMap, sync::Arc};
|
|||||||
|
|
||||||
use rmcp::{service::RunningService, transport::TokioChildProcess, RoleClient, ServiceExt};
|
use rmcp::{service::RunningService, transport::TokioChildProcess, RoleClient, ServiceExt};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use tauri::{AppHandle, State};
|
use tauri::{AppHandle, Emitter, State};
|
||||||
use tokio::{process::Command, sync::Mutex};
|
use tokio::{process::Command, sync::Mutex};
|
||||||
|
|
||||||
use super::{cmd::get_jan_data_folder_path, state::AppState};
|
use super::{cmd::get_jan_data_folder_path, state::AppState};
|
||||||
@ -24,7 +24,6 @@ pub async fn run_mcp_commands(
|
|||||||
"Load MCP configs from {}",
|
"Load MCP configs from {}",
|
||||||
app_path.clone() + "/mcp_config.json"
|
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")
|
let config_content = std::fs::read_to_string(app_path.clone() + "/mcp_config.json")
|
||||||
.map_err(|e| format!("Failed to read config file: {}", e))?;
|
.map_err(|e| format!("Failed to read config file: {}", e))?;
|
||||||
|
|
||||||
@ -81,10 +80,7 @@ fn extract_command_args(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn restart_mcp_servers(
|
pub async fn restart_mcp_servers(app: AppHandle, state: State<'_, AppState>) -> Result<(), String> {
|
||||||
app: AppHandle,
|
|
||||||
state: State<'_, AppState>,
|
|
||||||
) -> Result<(), String> {
|
|
||||||
let app_path = get_jan_data_folder_path(app.clone());
|
let app_path = get_jan_data_folder_path(app.clone());
|
||||||
let app_path_str = app_path.to_str().unwrap().to_string();
|
let app_path_str = app_path.to_str().unwrap().to_string();
|
||||||
let servers = state.mcp_servers.clone();
|
let servers = state.mcp_servers.clone();
|
||||||
@ -92,7 +88,10 @@ pub async fn restart_mcp_servers(
|
|||||||
stop_mcp_servers(state.mcp_servers.clone()).await?;
|
stop_mcp_servers(state.mcp_servers.clone()).await?;
|
||||||
|
|
||||||
// Restart the servers
|
// 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(
|
pub async fn stop_mcp_servers(
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use std::{
|
|||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
use tar::Archive;
|
use tar::Archive;
|
||||||
use tauri::{App, Listener, Manager};
|
use tauri::{App, Emitter, Listener, Manager};
|
||||||
use tauri_plugin_shell::process::CommandEvent;
|
use tauri_plugin_shell::process::CommandEvent;
|
||||||
use tauri_plugin_shell::ShellExt;
|
use tauri_plugin_shell::ShellExt;
|
||||||
use tauri_plugin_store::StoreExt;
|
use tauri_plugin_store::StoreExt;
|
||||||
@ -185,10 +185,12 @@ pub fn setup_mcp(app: &App) {
|
|||||||
let state = app.state::<AppState>().inner();
|
let state = app.state::<AppState>().inner();
|
||||||
let app_path_str = app_path.to_str().unwrap().to_string();
|
let app_path_str = app_path.to_str().unwrap().to_string();
|
||||||
let servers = state.mcp_servers.clone();
|
let servers = state.mcp_servers.clone();
|
||||||
|
let app_handle = app.handle().clone();
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
if let Err(e) = run_mcp_commands(app_path_str, servers).await {
|
if let Err(e) = run_mcp_commands(app_path_str, servers).await {
|
||||||
log::error!("Failed to run mcp commands: {}", e);
|
log::error!("Failed to run mcp commands: {}", e);
|
||||||
}
|
}
|
||||||
|
app_handle.emit("mcp-update", "MCP servers updated").unwrap();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import {
|
|||||||
Modal,
|
Modal,
|
||||||
Switch,
|
Switch,
|
||||||
} from '@janhq/joi'
|
} from '@janhq/joi'
|
||||||
|
import { listen } from '@tauri-apps/api/event'
|
||||||
import { useAtom, useAtomValue } from 'jotai'
|
import { useAtom, useAtomValue } from 'jotai'
|
||||||
import {
|
import {
|
||||||
FileTextIcon,
|
FileTextIcon,
|
||||||
@ -117,6 +118,12 @@ const ChatInput = () => {
|
|||||||
window.core?.api?.getTools().then((data: ModelTool[]) => {
|
window.core?.api?.getTools().then((data: ModelTool[]) => {
|
||||||
setTools(data)
|
setTools(data)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
listen('mcp-update', (event) => {
|
||||||
|
window.core?.api?.getTools().then((data: ModelTool[]) => {
|
||||||
|
setTools(data)
|
||||||
|
})
|
||||||
|
})
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const onStopInferenceClick = async () => {
|
const onStopInferenceClick = async () => {
|
||||||
|
|||||||
@ -49,11 +49,11 @@ const ToolCallBlock = ({ id, name, result, loading, onExpand }: Props) => {
|
|||||||
|
|
||||||
<ScrollArea
|
<ScrollArea
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
'w-full overflow-hidden transition-all duration-300',
|
'h-fit w-full overflow-auto transition-all duration-300',
|
||||||
isExpanded ? 'max-h-96' : 'max-h-0'
|
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>
|
<span>{result ?? ''} </span>
|
||||||
</div>
|
</div>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user