add experimental action
publish release / release (push) Failing after 3m38s

apply formatting
This commit is contained in:
2026-05-08 22:30:11 +02:00
parent 51b1123cf9
commit d9ade649d3
17 changed files with 242 additions and 143 deletions
+53 -31
View File
@@ -1,13 +1,13 @@
use crate::mcp::MCPClient;
use ollama_rs::error::OllamaError;
use ollama_rs::generation::chat::request::ChatMessageRequest;
use ollama_rs::generation::chat::ChatMessage;
use ollama_rs::generation::tools::ToolInfo;
use ollama_rs::Ollama;
use rmcp::model::{CallToolRequestParams, CallToolResult};
use ollama_rs::error::OllamaError;
use ollama_rs::generation::chat::ChatMessage;
use ollama_rs::generation::chat::request::ChatMessageRequest;
use ollama_rs::generation::tools::ToolInfo;
use rmcp::ServiceError;
use std::collections::HashMap;
use rmcp::model::{CallToolRequestParams, CallToolResult};
use serde::Deserialize;
use std::collections::HashMap;
use thiserror::Error;
#[derive(Debug, Copy, Clone, Default, Deserialize, PartialEq)]
@@ -164,21 +164,29 @@ impl AgentChat {
/// * `name`: must be in the format "mcp_server_name:tool_or_resource_name".
///
/// returns: Option<&RestrictedTool>
pub fn get_tool(
mpc_server_data: &MCPServerData,
name: String,
) -> Option<&RestrictedTool> {
pub fn get_tool(mpc_server_data: &MCPServerData, name: String) -> Option<&RestrictedTool> {
mpc_server_data
.translated_tools
.iter()
.find(|tool| tool.tool_info.function.name == name)
}
pub fn set_permission(&mut self, full_tool_name: String, permission: ToolPermission) -> Result<(), ChatError> {
pub fn set_permission(
&mut self,
full_tool_name: String,
permission: ToolPermission,
) -> Result<(), ChatError> {
let (mcp_server_name, tool_name) = Self::parse_tool_name(full_tool_name.clone())?;
let mcp_server_data: &mut MCPServerData = self.mcp_servers.get_mut(&mcp_server_name.clone()).ok_or(ChatError::ServiceNotFoundError(mcp_server_name.clone()))?;
let tool_index = mcp_server_data.translated_tools.iter().position(|tool| tool.tool_info.function.name == full_tool_name).ok_or(ChatError::ToolNotFoundError(tool_name))?;
let mcp_server_data: &mut MCPServerData = self
.mcp_servers
.get_mut(&mcp_server_name.clone())
.ok_or(ChatError::ServiceNotFoundError(mcp_server_name.clone()))?;
let tool_index = mcp_server_data
.translated_tools
.iter()
.position(|tool| tool.tool_info.function.name == full_tool_name)
.ok_or(ChatError::ToolNotFoundError(tool_name))?;
mcp_server_data.translated_tools[tool_index].permission = permission;
Ok(())
}
@@ -187,12 +195,12 @@ impl AgentChat {
&mut self,
user_message: String,
mut permission_request_callback: impl FnMut(String, String) -> C,
) -> Result<ChatMessage, ChatError>
{
) -> Result<ChatMessage, ChatError> {
let all_tools: Vec<ToolInfo> = self
.get_all_tools()
.filter_map(|restricted_tool|{
if restricted_tool.permission == ToolPermission::Denied { // filters denied tools to save tokens
.filter_map(|restricted_tool| {
if restricted_tool.permission == ToolPermission::Denied {
// filters denied tools to save tokens
None
} else {
Some(restricted_tool.tool_info.clone())
@@ -219,16 +227,22 @@ impl AgentChat {
for tool_call in &response.message.tool_calls {
log::debug!("calling tool {}", tool_call.function.name);
let result = self.call_tool(tool_call, &mut permission_request_callback).await?;
let result = self
.call_tool(tool_call, &mut permission_request_callback)
.await?;
// serialize structured content if it exists
if let Some(structured_content) = result.clone().and_then(|result|result.structured_content) {
if let Some(structured_content) =
result.clone().and_then(|result| result.structured_content)
{
log::debug!("structured content: {structured_content:#?}");
self.message_history.push(ChatMessage::tool(structured_content.to_string()));
self.message_history
.push(ChatMessage::tool(structured_content.to_string()));
} else {
let contents = match result {
Some(result) => result.content
Some(result) => result
.content
.iter()
.filter_map(|content| content.as_text())
.map(|text_content| text_content.text.clone())
@@ -270,7 +284,7 @@ impl AgentChat {
&self,
tool_call: &ollama_rs::generation::tools::ToolCall,
permission_request_callback: &mut impl FnMut(String, String) -> C,
) -> Result<Option<CallToolResult>, ChatError> {
) -> Result<Option<CallToolResult>, ChatError> {
let arguments_json_object = tool_call
.function
.arguments
@@ -286,10 +300,10 @@ impl AgentChat {
let mcp_server_data = self
.get_mcp_server_by_name(mcp_server_name.clone())
.ok_or(ChatError::ServiceNotFoundError(mcp_server_name.clone()))?;
let restricted_tool = AgentChat::get_tool(&mcp_server_data, full_unparsed_tool_name.clone())
.ok_or(ChatError::ToolNotFoundError(
full_unparsed_tool_name.clone(),
))?;
let restricted_tool =
AgentChat::get_tool(&mcp_server_data, full_unparsed_tool_name.clone()).ok_or(
ChatError::ToolNotFoundError(full_unparsed_tool_name.clone()),
)?;
match restricted_tool.permission {
ToolPermission::Allowed => {
@@ -301,7 +315,8 @@ impl AgentChat {
}
ToolPermission::Ask => {
log::trace!("ask restricted tool: {:?}", restricted_tool);
let response = permission_request_callback(mcp_server_name, tool_name.clone()).await;
let response =
permission_request_callback(mcp_server_name, tool_name.clone()).await;
match response {
PermissionAnswer::Granted => {
log::trace!("granted restricted tool: {:?}", restricted_tool);
@@ -323,7 +338,9 @@ impl AgentChat {
request_params
);
Ok(Some(mcp_server_data.client.call_tool(request_params).await?))
Ok(Some(
mcp_server_data.client.call_tool(request_params).await?,
))
}
}
@@ -356,16 +373,21 @@ mod tests {
MCP_TEST_SERVER_URL,
None::<String>,
Implementation::new("test", env!("CARGO_PKG_VERSION")),
).await.unwrap(),
)
.await
.unwrap(),
)]);
let mut chat = AgentChat::new(ollama, "lfm2.5-thinking:1.2b".to_string(), mcp_clients).await.unwrap();
let mut chat = AgentChat::new(ollama, "lfm2.5-thinking:1.2b".to_string(), mcp_clients)
.await
.unwrap();
let tools: Vec<RestrictedTool> = chat.get_all_tools().cloned().collect();
assert_eq!(tools.len(), 1);
assert_eq!(tools[0].permission, ToolPermission::Ask);
chat.set_permission("test:echo".to_string(), ToolPermission::Allowed).unwrap();
chat.set_permission("test:echo".to_string(), ToolPermission::Allowed)
.unwrap();
let tools: Vec<RestrictedTool> = chat.get_all_tools().cloned().collect();
assert_eq!(tools[0].permission, ToolPermission::Allowed);