feat(mcp): enforce spec-compliant tool registry

- Reject dotted tool identifiers during registration and remove alias-backed lookups.
- Drop web.search compatibility, normalize all code/tests around the canonical web_search name, and update consent/session logic.
- Harden CLI toggles to manage the spec-compliant identifier and ensure MCP configs shed non-compliant entries automatically.

Acceptance Criteria:
- Tool registry denies invalid identifiers by default and no alias codepaths remain.

Test Notes:
- cargo check -p owlen-core (tests unavailable in sandbox).
This commit is contained in:
2025-10-25 04:48:17 +02:00
parent 6a94373c4f
commit c3a92a092b
13 changed files with 284 additions and 105 deletions

View File

@@ -2,6 +2,7 @@ use std::{any::Any, collections::HashMap, sync::Arc};
use async_trait::async_trait;
use futures::StreamExt;
use owlen_core::tools::{WEB_SEARCH_TOOL_NAME, tool_name_matches};
use owlen_core::{
Config, Error, Mode, Provider,
config::McpMode,
@@ -88,7 +89,7 @@ impl Provider for StreamingToolProvider {
fn tool_descriptor() -> McpToolDescriptor {
McpToolDescriptor {
name: "web_search".to_string(),
name: WEB_SEARCH_TOOL_NAME.to_string(),
description: "search".to_string(),
input_schema: serde_json::json!({"type": "object"}),
requires_network: true,
@@ -123,7 +124,7 @@ impl CachedResponseClient {
metadata.insert("cached".to_string(), "true".to_string());
let response = McpToolResponse {
name: "web_search".to_string(),
name: WEB_SEARCH_TOOL_NAME.to_string(),
success: true,
output: serde_json::json!({
"query": "rust",
@@ -286,13 +287,13 @@ async fn web_tool_timeout_fails_over_to_cached_result() {
]);
let call = McpToolCall {
name: "web_search".to_string(),
name: WEB_SEARCH_TOOL_NAME.to_string(),
arguments: serde_json::json!({ "query": "rust", "max_results": 3 }),
};
let response = client.call_tool(call.clone()).await.expect("fallback");
assert_eq!(response.name, "web_search");
assert!(tool_name_matches(&response.name, WEB_SEARCH_TOOL_NAME));
assert_eq!(
response.metadata.get("source").map(String::as_str),
Some("cache")