mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-18 20:57:05 +02:00
Lot 36 : appels d'outils MCP du tour de la façade par son pool
Quand la façade tient les serveurs MCP (LOKI_MCP=rust), un appel mcp__* d'un de ses tours partait au Go (/internal/v1/tool/exec), qui le renvoyait aussitôt à la façade (/internal/facade/v1/mcp/call) : deux allers-retours pour revenir au même pool. Le Go n'ajoute rien au résultat d'un outil MCP. ChatShared porte désormais le pool (le même que celui des routes, créé une fois) ; GoTurnHost::exec_tool l'appelle directement — même résultat que la route interne, reconnexion comprise. Une reconnexion annonce la version du Go (/internal/v1/auth), lue une fois et retenue. Sans pool tenu, rien ne change. Le Go garde la route interne pour les tours qu'il exécute encore. Test : un tour de la façade contre un faux serveur MCP stdio — rien par le Go, résultats tels que le modèle les reçoit, erreur après reconnexion, version du Go annoncée. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
This commit is contained in:
8 files changed
+223
-11
No files matched your search
@@ -1303,6 +1303,8 @@ impl ChatShared {
|
||||
patterns: super::stream::RetryPatterns::builtin(),
|
||||
tpl: std::sync::Arc::new(super::tplprobe::TplProbe::new()),
|
||||
prewarm: Default::default(),
|
||||
mcp: None,
|
||||
go_version: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,8 @@
|
||||
//! - envoi au moteur par [`EngineHttp`] (clé de CET endpoint), pannes
|
||||
//! classées et formulées comme `friendlyLLMError` ;
|
||||
//! - outils fichiers et shell exécutés ici ([`crate::tools`], état partagé
|
||||
//! tenu par le Go) ; les autres par le Go (`/internal/v1/tool/exec`), avec
|
||||
//! tenu par le Go), outils MCP par le pool de la façade quand elle le tient
|
||||
//! (lot 36) ; les autres par le Go (`/internal/v1/tool/exec`), avec
|
||||
//! ce qu'il tire du résultat (capture de la bulle, aperçu du navigateur,
|
||||
//! image relayée) ;
|
||||
//! - résultats complets (« voir plus ») confiés à l'écrivain des discussions ;
|
||||
@@ -330,6 +331,32 @@ pub struct ChatShared {
|
||||
pub tpl: Arc<super::tplprobe::TplProbe>,
|
||||
/// Préchauffage (PREWARM) : celui en vol, capacités des discussions.
|
||||
pub prewarm: super::prewarm::Prewarm,
|
||||
/// Le pool MCP, quand la façade le tient (LOKI_MCP=rust) : les appels
|
||||
/// `mcp__*` du tour y vont directement (lot 36).
|
||||
pub mcp: Option<Arc<crate::mcp::Mcp>>,
|
||||
/// La version du Go, annoncée aux serveurs MCP à une reconnexion ; lue
|
||||
/// une fois.
|
||||
pub go_version: tokio::sync::OnceCell<String>,
|
||||
}
|
||||
|
||||
impl ChatShared {
|
||||
/// [`Self::go_version`] : `/internal/v1/auth`, retenue une fois lue.
|
||||
pub async fn go_version(&self) -> String {
|
||||
if let Some(v) = self.go_version.get() {
|
||||
return v.clone();
|
||||
}
|
||||
let v = self
|
||||
.store
|
||||
.internal_json(hyper::Method::GET, "/internal/v1/auth", None)
|
||||
.await
|
||||
.ok()
|
||||
.and_then(|v| v.get("version").and_then(Value::as_str).map(str::to_string))
|
||||
.unwrap_or_default();
|
||||
if !v.is_empty() {
|
||||
let _ = self.go_version.set(v.clone());
|
||||
}
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
/// Ce que la compaction sait du tour.
|
||||
@@ -615,6 +642,18 @@ impl TurnHost for GoTurnHost {
|
||||
}
|
||||
|
||||
async fn exec_tool(&self, name: &str, args: &Map<String, Value>, label: &str) -> ToolOutcome {
|
||||
// Outils MCP, quand la façade tient le pool : ce que ferait le Go
|
||||
// (`mcpCall` → /internal/facade/v1/mcp/call), sans ses deux
|
||||
// allers-retours. Le Go n'en tire rien d'autre que le texte.
|
||||
if crate::mcp::config::is_mcp_tool(name)
|
||||
&& let Some(mcp) = &self.shared.mcp
|
||||
{
|
||||
let version = self.shared.go_version().await;
|
||||
return ToolOutcome {
|
||||
result: mcp.call(&self.shared.store, name, args, &version).await,
|
||||
..Default::default()
|
||||
};
|
||||
}
|
||||
// Outils fichiers et shell : ici (lot 7), l'état partagé restant au Go.
|
||||
if crate::tools::is_local(name) {
|
||||
let st = crate::tools::GoToolState {
|
||||
|
||||
Reference in new issue
Block a user