refactor(mcp): centralize meta-function prefix predicates and fix list_tools pagination
Implements T1 of plans/mcp-resources-prompts-design.md (§4.1, §4.6): - Replace list_tools(None) with cursor-following list_all_tools() at the three call sites (start_server catalog build, catalog_items, describe) so paginating servers no longer silently lose tools past page one. - Add MCP_READ/MCP_PROMPT prefix constants (declared nowhere yet; wired in T4/T7) plus centralized helpers MCP_META_FUNCTION_PREFIXES, is_mcp_meta_function, and mcp_meta_function_names. - Mechanically replace every hand-rolled 3-prefix starts_with triple (partition in eval_tool_calls, 3 exclusion triples in select_enabled_functions, 3 inclusion triples + per-server name construction in select_enabled_mcp_servers) with the helpers, preserving the existing lax starts_with matching semantics and the mcp_invoke_* enablement sentinel (sentinel moves to search in T5). - Behavior-neutral: dispatch chains keep their 3 arms, emission stays at exactly 3 meta-functions per server, existing tests unmodified. - Add unit tests: helper classification, prefix-soundness property, lax-matching pin, ordered candidate-name construction.
This commit is contained in:
+9
-9
@@ -16,7 +16,7 @@ use crate::config::ensure_parent_exists;
|
||||
use crate::config::paths;
|
||||
use crate::mcp::{
|
||||
MCP_DESCRIBE_META_FUNCTION_NAME_PREFIX, MCP_INVOKE_META_FUNCTION_NAME_PREFIX,
|
||||
MCP_SEARCH_META_FUNCTION_NAME_PREFIX, McpServersConfig,
|
||||
MCP_SEARCH_META_FUNCTION_NAME_PREFIX, McpServersConfig, is_mcp_meta_function,
|
||||
};
|
||||
use crate::parsers::{bash, python, typescript};
|
||||
use anyhow::{Context, Result, anyhow, bail};
|
||||
@@ -284,14 +284,9 @@ pub async fn eval_tool_calls(
|
||||
}
|
||||
}
|
||||
|
||||
let (mcp_calls, sequential_calls): (Vec<_>, Vec<_>) =
|
||||
to_execute.into_iter().partition(|(_, call)| {
|
||||
call.name.starts_with(MCP_INVOKE_META_FUNCTION_NAME_PREFIX)
|
||||
|| call.name.starts_with(MCP_SEARCH_META_FUNCTION_NAME_PREFIX)
|
||||
|| call
|
||||
.name
|
||||
.starts_with(MCP_DESCRIBE_META_FUNCTION_NAME_PREFIX)
|
||||
});
|
||||
let (mcp_calls, sequential_calls): (Vec<_>, Vec<_>) = to_execute
|
||||
.into_iter()
|
||||
.partition(|(_, call)| is_mcp_meta_function(&call.name));
|
||||
|
||||
if !mcp_calls.is_empty() {
|
||||
let ctx_ref: &RequestContext = ctx;
|
||||
@@ -2128,6 +2123,11 @@ mod tests {
|
||||
assert_eq!(MCP_INVOKE_META_FUNCTION_NAME_PREFIX, "mcp_invoke");
|
||||
assert_eq!(MCP_SEARCH_META_FUNCTION_NAME_PREFIX, "mcp_search");
|
||||
assert_eq!(MCP_DESCRIBE_META_FUNCTION_NAME_PREFIX, "mcp_describe");
|
||||
assert_eq!(crate::mcp::MCP_READ_META_FUNCTION_NAME_PREFIX, "mcp_read");
|
||||
assert_eq!(
|
||||
crate::mcp::MCP_PROMPT_META_FUNCTION_NAME_PREFIX,
|
||||
"mcp_prompt"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user