Lot 47 : outil subagent du mode Code exécuté par la façade

Le builder délègue à un rôle en lecture seule (explorer, code-reviewer,
planner) sans passer par /tool/exec : src/chat/subagent.rs porte
toolSubagent. Mêmes refus avant tout appel au moteur (rôle inconnu,
verifier compris, tâche vide, récursion), contexte isolé servi par le Go
(POST /internal/v1/turn/subagent : prompt du rôle + briefing machine,
outils, capacités ; subagentView et subagentFraming partagés), tour
imbriqué run_turn avec l'endpoint, le raisonnement, l'écho et l'arrêt du
tour qui délègue, température 0,6, travail annexe (second slot, effacé à
la fin), télémétrie à part. Seul le texte écrit après le dernier outil
revient, rogné, préfixé du rôle, tronqué à 6000 runes.

Le tour du rôle est porté par SubHost, qui délègue tout à son GoTurnHost
sauf un nouvel appel à subagent ; les outils de la façade passent dans
GoTurnHost::exec_tool_base, que seul le tour principal complète de
subagent (le type du tour imbriqué ne se contient pas lui-même).

Parité : journal tiré du Go contre un faux moteur scripté
(parity_subagent_test.go → tests/parity_subagent/subagent.json : refus,
réponse directe, rapport après deux outils, texte vide relancé, rapport
tronqué, cadrage du planner, moteur qui refuse ; requêtes du rôle),
rejoué par un tour complet de la façade (tests/lot6.rs) ;
TestSubagentVueInterne côté Go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
This commit is contained in:
Claude committed 2026-10-16 07:12:29 +00:00
1 parent 92e9adee7d
commit ded1c97c17
16 files changed
+1846 -73

No files matched your search

+22
View File
@@ -137,6 +137,28 @@ func handleInternalTurnVerifier(w http.ResponseWriter, r *http.Request) {
})
}
// handleInternalTurnSubagent : le contexte isolé d'un rôle délégué par
// l'outil subagent de la façade (lot 47) — prompt système, outils et
// capacités du rôle ; la tâche et son cadrage restent chez elle.
func handleInternalTurnSubagent(w http.ResponseWriter, r *http.Request) {
var in struct {
Role string `json:"role"`
}
if !readInternalJSON(w, r, &in) {
return
}
if !isSubagentRole(in.Role) {
sendJSON(w, http.StatusBadRequest, map[string]any{"error": "rôle inconnu : " + in.Role})
return
}
caps, system := subagentView(in.Role)
sendJSON(w, http.StatusOK, map[string]any{
"system": system,
"tools": EnabledTools(caps),
"caps": caps,
})
}
// handleInternalProjectActivate : setActiveProject pour la façade (projet
// rangé en base, cache de ceux qui le lisent ici — mémoire, trackers, outils).
func handleInternalProjectActivate(w http.ResponseWriter, r *http.Request) {