feat(mcp): synchronise les permissions MCP avec les tools réellement exposés

Les permissions déclarées ne reflétaient pas toujours les tools
effectivement exposés aux agents (contexte requester/projet lié après
coup). Ajoute ToolInvoker::tools_for_bound_context/tools_for_context
pour exposer la liste effective au moment de l'injection dans une
requête OpenAI-compatible, et propage le calcul dans la policy MCP,
le serveur, la factory de session et l'adapter openai_compat.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-29 15:57:45 +02:00
parent 5955ea37a2
commit 21a84ab8f2
8 changed files with 462 additions and 223 deletions

View File

@ -281,7 +281,7 @@ impl OpenAiCompatibleSession {
send_tap(&tap, &ReplyEvent::Heartbeat);
for iteration in 0..=self.config.effective_max_tool_iterations() {
let transcript = self.transcript.lock().expect("mutex sain").clone();
let tools = self.effective_tools();
let tools = self.effective_tools().await?;
let response = self.post_chat(&transcript, &tools, true).await;
let response = match response {
Ok(response) => response,
@ -330,13 +330,17 @@ impl OpenAiCompatibleSession {
unreachable!("loop returns at max_tool_iterations");
}
fn effective_tools(&self) -> Vec<ToolSpec> {
async fn effective_tools(&self) -> Result<Vec<ToolSpec>, AgentSessionError> {
if *self.tools_disabled.lock().expect("mutex sain") {
return Vec::new();
return Ok(Vec::new());
}
match &self.tool_invoker {
Some(invoker) => invoker
.tools_for_bound_context()
.await
.map_err(|e| AgentSessionError::Start(format!("résolution tools: {e}"))),
None => Ok(Vec::new()),
}
self.tool_invoker
.as_ref()
.map_or_else(Vec::new, |invoker| invoker.tools())
}
async fn post_chat(