Chat : mode agent coupé = modèle brut, vraiment

Repris d'AJEAN 0.13.12 / 0.13.13. Couper le mode agent retirait bien les
outils, la mémoire et le préambule Loki, mais laissait passer deux choses :

- Le prompt système du PRESET et le contexte du projet (description, index
  mémoire, trackers). Ils décrivent des outils et une mémoire que ce mode
  n'a pas : le modèle, persuadé de pouvoir agir, écrivait des <tool_call>
  en clair dans sa réponse. Agent off, generate n'injecte plus rien — le
  modèle reçoit les messages nus, comme un llama-server direct.
- Un tool_call que le moteur parvient à parser alors qu'aucun outil n'a été
  annoncé (agent off, ou relance sans outils après un 500). Il était exécuté,
  répondait « outil inconnu », et la boucle repartait. Il est désormais
  ignoré : le modèle répond en texte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Opus 5.5 committed 2026-10-02 23:04:51 +02:00
1 parent f117a466af
commit 4602614be0
2 files changed
+17 -4

No files matched your search

+11 -3
View File
@@ -574,9 +574,17 @@ func (c *Conversation) generate(ctx context.Context, caps Caps, temperature floa
// Contexte du projet actif (description, index mémoire, index des trackers),
// même traitement : injecté dans la vue envoyée, jamais persisté — voir
// projectSystemMessages.
final := append(projectSystemMessages(), msgs...)
if sp := readSysPrompt(); sp != "" {
final = append([]Message{{Role: "system", Content: sp}}, final...)
//
// Mode agent OFF = modèle BRUT (AJEAN 0.13.13) : ni l'un ni l'autre. Sans
// agent, on veut parler au modèle nu, comme à un llama-server direct. Le
// prompt du preset et l'index mémoire décrivent des outils que ce mode n'a
// pas : le modèle se mettait à écrire des <tool_call> en clair.
final := msgs
if caps.Agent {
final = append(projectSystemMessages(), msgs...)
if sp := readSysPrompt(); sp != "" {
final = append([]Message{{Role: "system", Content: sp}}, final...)
}
}
// newBase : vue modèle publiée par une compaction survenue PENDANT le tour.
+6 -1
View File
@@ -1094,7 +1094,12 @@ func runChat(ctx context.Context, messages []Message, temperature float64, caps
if ch.FinishReason != "" {
finishReason = ch.FinishReason
}
if len(ch.Delta.ToolCalls) > 0 {
// Un tool_call n'est retenu que si des outils ont VRAIMENT été annoncés ce
// tour-ci (même condition que le payload). Sinon — mode agent coupé, ou
// relance sans outils après un 500 — le moteur peut quand même parser un
// appel que le modèle a émis de lui-même ; l'exécuter donnait « outil
// inconnu », réinjecté puis mis en boucle. On l'ignore (AJEAN 0.13.12).
if len(tools) > 0 && !disableTools && len(ch.Delta.ToolCalls) > 0 {
// Un appel d'outil clôt le texte : on vide MAINTENANT le reliquat
// retenu par la garde « </think> » (voir plus bas). Sinon il n'était
// émis qu'en fin de flux, donc APRÈS l'événement d'outil, et l'UI