agent conversation fix
This commit is contained in:
@ -2732,30 +2732,25 @@ pub(crate) fn compose_convention_file(
|
||||
out.push_str("---\n\n");
|
||||
out.push_str("# Orchestration IdeA\n\n");
|
||||
if mcp_enabled {
|
||||
// Surface MCP (cadrage v3, D3) : l'alternative native aux subagents est
|
||||
// exposée comme outils typés `idea_*`. L'interdiction des subagents natifs
|
||||
// du fournisseur est **conservée** ; seule la voie de délégation change.
|
||||
// Surface MCP : outils IdeA natifs. `idea_ask_agent` est une porte d'entrée
|
||||
// ergonomique vers l'orchestrateur headless, pas un protocole ask/reply exposé
|
||||
// aux modèles.
|
||||
out.push_str(
|
||||
"Pour déléguer une tâche à un autre agent, n'utilise jamais les subagents \
|
||||
natifs du fournisseur IA. Utilise les outils IdeA natifs : \
|
||||
`idea_ask_agent` (déléguer une tâche et recevoir la réponse), \
|
||||
`idea_launch_agent` (lancer/réattacher un agent) et `idea_list_agents` \
|
||||
(lister les agents du projet). IdeA lancera ou réattachera l'agent cible \
|
||||
avec son propre AI Profile, son contexte et sa mémoire.\n\n",
|
||||
"La conversation inter-agent est gérée par IdeA en headless. Pour contacter \
|
||||
un autre agent, utilise l'outil MCP IdeA `idea_ask_agent(target, task)` quand \
|
||||
il est disponible : IdeA lance ou réattache la cible via son profil \
|
||||
structured/headless, capture sa réponse finale et te la renvoie inline. \
|
||||
N'invente pas de protocole de ticket et n'appelle pas d'outil de remise de \
|
||||
résultat.\n\n",
|
||||
);
|
||||
// Protocole de délégation (Option 1, B-5) : côté agent SOLLICITÉ. Une tâche
|
||||
// déléguée arrive dans ton terminal préfixée `[IdeA · tâche de … · ticket …]`.
|
||||
// Tu DOIS y répondre via l'outil `idea_reply`, jamais en texte libre — sinon
|
||||
// l'agent qui t'a sollicité reste bloqué (sa réponse ne lui parviendra pas).
|
||||
// Conversation inter-agent : le transport est géré par IdeA en headless. Les
|
||||
// agents n'ont plus à connaître un protocole de reply ni à corréler des tickets.
|
||||
out.push_str(
|
||||
"Quand tu reçois une tâche déléguée par IdeA (un message préfixé \
|
||||
`[IdeA · tâche de … · ticket …]`), traite-la puis appelle \
|
||||
**impérativement** l'outil `idea_reply(ticket=…, result=…)` pour rendre ton \
|
||||
résultat — **même pour une réponse triviale** (un simple `pong`). Ne réponds \
|
||||
**JAMAIS** uniquement en texte/prose dans le terminal : tant que tu n'as pas \
|
||||
appelé `idea_reply`, l'agent qui t'a sollicité reste **bloqué** et sa réponse \
|
||||
ne lui parviendra pas. Terminer ton tour sans `idea_reply` est un échec du \
|
||||
protocole, pas une réponse.\n\n",
|
||||
"Quand IdeA te sollicite via une conversation inter-agent headless, traite \
|
||||
simplement la demande et termine ton tour avec ta réponse normale. N'ajoute \
|
||||
pas de protocole de ticket, n'appelle pas d'outil de remise de résultat : IdeA \
|
||||
capture automatiquement la réponse finale du modèle et la transmet à l'agent \
|
||||
demandeur.\n\n",
|
||||
);
|
||||
// Capacités IdeA (feature skill-awareness) : briefing à HAUTE ALTITUDE,
|
||||
// télégraphique, injecté à CHAQUE lancement (coût token → pas d'exemples ni de
|
||||
@ -3379,22 +3374,18 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn compose_convention_file_mcp_prose_points_to_idea_tools_and_keeps_subagent_ban() {
|
||||
// mcp_enabled = true ⇒ prose exposes the native `idea_*` tools while keeping
|
||||
// the ban on the provider's native subagents (cadrage v3, Décision 3).
|
||||
// mcp_enabled = true ⇒ prose exposes the remaining native `idea_*` tools while
|
||||
// keeping the ban on the provider's native subagents (cadrage v3, Décision 3).
|
||||
let doc = compose_convention_file("/root", "", "# Persona", &[], &[], None, &[], true);
|
||||
|
||||
// Native IdeA orchestration tools surfaced.
|
||||
assert!(
|
||||
doc.contains("idea_ask_agent"),
|
||||
"MCP prose must mention idea_ask_agent"
|
||||
);
|
||||
assert!(doc.contains("idea_launch_agent"));
|
||||
assert!(doc.contains("idea_list_agents"));
|
||||
// Native-subagent ban preserved.
|
||||
assert!(
|
||||
doc.contains("n'utilise jamais les subagents"),
|
||||
"MCP prose must keep the native-subagent ban"
|
||||
doc.contains("idea_context_read"),
|
||||
"MCP prose must mention remaining IdeA tools"
|
||||
);
|
||||
assert!(doc.contains("idea_memory_read"));
|
||||
assert!(doc.contains("idea_ask_agent"));
|
||||
assert!(!doc.contains("idea_reply"));
|
||||
// It does NOT fall back to the file protocol wording.
|
||||
assert!(
|
||||
!doc.contains(".ideai/requests"),
|
||||
@ -3403,20 +3394,23 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compose_convention_file_mcp_prose_carries_the_idea_reply_delegation_protocol() {
|
||||
// B-5 — the solicited-agent side of the protocol: a delegated task arrives as
|
||||
// `[IdeA · tâche …]` and MUST be answered via `idea_reply`, never plain text.
|
||||
fn compose_convention_file_mcp_prose_does_not_carry_idea_reply_protocol() {
|
||||
// Inter-agent conversation is headless: the model's final answer is captured by
|
||||
// IdeA. Agents must not be instructed to call a reply tool or echo tickets.
|
||||
let doc = compose_convention_file("/root", "", "# Persona", &[], &[], None, &[], true);
|
||||
assert!(
|
||||
doc.contains("idea_reply"),
|
||||
"MCP prose must instruct answering via idea_reply"
|
||||
!doc.contains("idea_reply"),
|
||||
"MCP prose must not instruct answering via idea_reply"
|
||||
);
|
||||
assert!(
|
||||
doc.contains("[IdeA · tâche"),
|
||||
"MCP prose must describe the delegated-task prefix it answers to"
|
||||
doc.contains("capture automatiquement la réponse finale")
|
||||
|| doc.contains("capture sa réponse finale"),
|
||||
"MCP prose must describe final-answer capture"
|
||||
);
|
||||
assert!(
|
||||
!doc.contains("[IdeA · tâche"),
|
||||
"MCP prose must not describe the old delegated-task prefix"
|
||||
);
|
||||
// Negative: the non-MCP (file-protocol) prose must NOT carry the idea_reply
|
||||
// instruction (zero regression on the file path).
|
||||
let file_doc =
|
||||
compose_convention_file("/root", "", "# Persona", &[], &[], None, &[], false);
|
||||
assert!(!file_doc.contains("idea_reply"));
|
||||
|
||||
Reference in New Issue
Block a user