mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-24 15:38:12 +02:00
Cache : la ligne MCP du préambule ne manque plus au premier tour après un démarrage
Le préambule système était bâti (InjectSkills → baseSystemPrompt) AVANT que runChat n'appelle EnabledTools, donc avant que mcpTools n'ouvre les connexions. mcpPromptLine lisait le pool encore vide : le premier tour après un démarrage partait sans la ligne MCP, le second avec — tout le prompt à recalculer pour une ligne. Elle comptait en plus les outils masqués par l'utilisateur, et s'affichait pour le planner, qui ne reçoit aucun outil MCP. - prepareTurn calcule les outils UNE fois par tour, puis le préambule à partir d'eux ; runChatTools les reprend tels quels (pas de second passage par mcpEnsureAll, qui retentait deux fois un serveur en panne). - mcpPromptLine se déduit de cette tranche : seuls les outils réellement envoyés sont comptés, et rien n'est annoncé sans outil MCP. - trackerList départage les égalités d'horodatage par nom puis slug : la liste part dans le contexte, un ordre tiré au sort changeait le prompt. - Le commentaire de tasks_run.go ne prétend plus que le préfixe d'une tâche égale celui du chat (dossier de travail et taskCaps diffèrent). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9263df404d
commit
7dd319a058
12 files changed
+202
-34
No files matched your search
+32
-12
@@ -449,22 +449,42 @@ func flattenMCPContent(res *mcpsdk.CallToolResult) string {
|
||||
return text
|
||||
}
|
||||
|
||||
// mcpPromptLine renvoie une ligne système listant les serveurs MCP connectés et
|
||||
// leur nombre d'outils, pour situer le modèle. Ne force PAS de connexion : lit
|
||||
// seulement l'état déjà établi par mcpTools() (appelé par EnabledTools sur le
|
||||
// même tour), pour ne pas payer deux fois le handshake.
|
||||
func mcpPromptLine() string {
|
||||
mcpMgr.mu.Lock()
|
||||
defer mcpMgr.mu.Unlock()
|
||||
var names []string
|
||||
for name, s := range mcpMgr.sessions {
|
||||
if s.sess != nil && len(s.tools) > 0 {
|
||||
names = append(names, fmt.Sprintf("%s (%d)", name, len(s.tools)))
|
||||
// mcpPromptLine renvoie une ligne système listant les serveurs MCP annoncés et
|
||||
// leur nombre d'outils, pour situer le modèle. Elle se DÉDUIT des outils
|
||||
// réellement envoyés ce tour-ci (EnabledTools), pas de l'état du pool.
|
||||
//
|
||||
// Lue dans le pool, elle arrivait en retard d'un tour : le préambule est bâti
|
||||
// avant que mcpTools n'ouvre les connexions, si bien que le premier tour après
|
||||
// un démarrage partait sans la ligne et le second avec — tout le prompt à
|
||||
// recalculer pour une ligne. Elle comptait aussi les outils masqués par
|
||||
// l'utilisateur, et s'affichait pour un rôle (planner…) qui ne reçoit aucun
|
||||
// outil MCP. Tirée de la même tranche que les schémas, elle ne peut plus les
|
||||
// contredire.
|
||||
func mcpPromptLine(tools []Tool) string {
|
||||
counts := map[string]int{}
|
||||
for _, t := range tools {
|
||||
if !strings.HasPrefix(t.Function.Name, "mcp__") {
|
||||
continue
|
||||
}
|
||||
// mcpTools préfixe chaque description par « [MCP: <serveur>] » : le nom
|
||||
// d'origine du serveur, que le nom d'outil (assaini) ne garde pas.
|
||||
rest, ok := strings.CutPrefix(t.Function.Description, "[MCP: ")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
server, _, ok := strings.Cut(rest, "] ")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
counts[server]++
|
||||
}
|
||||
if len(names) == 0 {
|
||||
if len(counts) == 0 {
|
||||
return ""
|
||||
}
|
||||
names := make([]string, 0, len(counts))
|
||||
for name, n := range counts {
|
||||
names = append(names, fmt.Sprintf("%s (%d)", name, n))
|
||||
}
|
||||
sort.Strings(names)
|
||||
return "\n\nMCP servers connected (their tools are prefixed mcp__<server>__<tool>): " + strings.Join(names, ", ") + "."
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user