feat(orchestrator): durcir le rendez-vous inter-agents + backstop no-reply (Finding A)
Corrige le wedge survenant lorsqu'un agent délégué ne rappelle pas idea_reply :
le rendez-vous ask_agent ne reste plus bloqué indéfiniment.
Lot 1 — durcissement du préambule de délégation :
- input/mod.rs : delegation_preamble renforcé (obligation explicite idea_reply).
- agent/lifecycle.rs : préambule injecté conditionné à mcp_enabled.
Lot 2 — peuplement du prompt_ready_pattern :
- agent/catalogue.rs : .with_prompt_ready_pattern("? for shortcuts") sur le
profil Claude + tests de seed, pour calibrer la détection de grâce.
Lot 3 — backstop timeout serveur :
- mcp/jsonrpc.rs : code d'erreur typé RENDEZVOUS_NO_REPLY (-32001).
- mcp/server.rs : mapping timeout → erreur typée, with_ask_rendezvous_timeout
promu + resolve_ask_rendezvous_timeout (configurable).
- app-tauri/state.rs : lecture env IDEA_ASK_RENDEZVOUS_TIMEOUT_MS.
- tests/mcp_server.rs mis à jour, fix d'un test input flaky.
Propagation overlay (référence des profils) :
- agent/catalogue.rs : overlay_reference_defaults + reference_index + tests.
- store/profile.rs : ReferenceBackfillProfileStore + tests.
- app-tauri/state.rs : wrap au composition root.
- exports mod.rs / lib.rs (application + infrastructure).
Tests réels verts : application 494, app-tauri 235, infrastructure 248,
mcp_server 22/22, 0 échec. Validation e2e LIVE (rebuild AppImage) en attente
avant merge vers develop.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -1247,11 +1247,25 @@ async fn ask_agent_rendezvous_times_out_with_a_jsonrpc_error() {
|
||||
.expect("reply owed");
|
||||
|
||||
let error = response.error.expect("a JSON-RPC error on timeout");
|
||||
assert_eq!(error.code, error_codes::INTERNAL_ERROR, "got {error:?}");
|
||||
assert!(
|
||||
error.message.contains("timeout"),
|
||||
"explicit timeout message, got {error:?}"
|
||||
// Filet serveur : code DISTINCT de l'INTERNAL_ERROR opaque, sémantique typée et
|
||||
// retryable (miroir de `AppError::TargetReturnedNoReply`).
|
||||
assert_eq!(
|
||||
error.code,
|
||||
error_codes::RENDEZVOUS_NO_REPLY,
|
||||
"rendezvous timeout maps to the distinct typed code, got {error:?}"
|
||||
);
|
||||
assert_ne!(
|
||||
error.code,
|
||||
error_codes::INTERNAL_ERROR,
|
||||
"must NOT be the opaque internal error"
|
||||
);
|
||||
assert!(
|
||||
error.message.contains("idea_reply"),
|
||||
"message must steer the caller back to idea_reply, got {error:?}"
|
||||
);
|
||||
let data = error.data.expect("typed data on the rendezvous error");
|
||||
assert_eq!(data["code"], "TARGET_RETURNED_NO_REPLY", "got {data:?}");
|
||||
assert_eq!(data["retryable"], true, "got {data:?}");
|
||||
assert!(response.result.is_none(), "error responses carry no result");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user