Task 45 — Fan-out / fan-in
Phase: 4
Initiative: 18
Status: done
Owner: —
Slug: fan-out-in
Goal
Запрос уходит нескольким применимым агентам под строгим concurrency и budget. Ответы schema-validated, выбираются детерминированно, голосованием или опциональным judge.
Acceptance criteria
Sub-tasks
src/agent/Mesh/Router/FanOutOptions.cs— config:MaxConcurrency,BudgetCeilingUsd,DefaultTimeoutMs,Strategy(Deterministic/Voting/LlmJudge),MinResponsesForVoting,VotingThreshold,EnableSchemaValidationsrc/agent/Mesh/Router/IFanOutOrchestrator.cs— interface:OrchestrateFanOutAsync(envelope, responseSchema, strategy, budget, ct) → AggregationResultsrc/agent/Mesh/Router/FanOutOrchestrator.cs— full implementation: queryIMeshRouter→ parallel fan-out viaITransportrespectingMaxConcurrency+BudgetCeilingUsd+ per-callDeadline; per-peerTimeoutMs; schema validation viaResponseAggregatorsrc/agent/Mesh/Aggregation/AggregationResult.cs— result model:Winner,AllResponses,SelectionMethod,Duration,JudgeRationale,SchemaViolationssrc/agent/Mesh/Aggregation/ResponseAggregator.cs— aggregation engine:ValidateSchema(response, schema),AggregateDeterministic(responses, criterion),AggregateVoting(responses, threshold),AggregateWithLlmJudge(envelope, responses)Config/AppConfig.cs— addFanOutOrchestratorOptions FanOuttoMeshConfigMeshServiceExtensions.cs— wireIFanOutOrchestrator,ResponseAggregatorinto DItests/Phase4Tests/FanOutTests.cs— unit tests: schema validation, deterministic selection (first/highest-conf/latest), voting, LLM-judge fallback, concurrency limiting, budget exceeding, timeout handling, empty responsesdotnet build src/agent/Hercules.csproj— 0 errorsdotnet test Phase4— all Phase 4 tests pass
Implementation notes
2026-08-13
src/agent/Mesh/Router/FanOutOptions.cs — configuration:
FanOutSelectionStrategyenum:Deterministic = 0,Voting = 1,LlmJudge = 2DeterministicCriterionenum:FirstSuccess,HighestConfidence,LatestFanOutOptions:Enabled,MaxConcurrency(default 5),BudgetCeilingUsd(1.00m),DefaultTimeoutMs(30s),Strategy,DeterministicCriterion,MinResponsesForVoting(3),VotingThreshold(0.51),EnableSchemaValidation(true),EnableLlmJudgeFallback(true),MinPeersForFanOut(2)
src/agent/Mesh/Router/IFanOutOrchestrator.cs — interface:
OrchestrateFanOutAsync(envelope, responseSchema, strategy, budgetUsd, ct) → AggregationResult
src/agent/Mesh/Router/FanOutOrchestrator.cs — full implementation:
- Queries
IMeshRouterfor ranked peers filtered by budget - Single-peer fallback when
peers.Count < MinPeersForFanOut - Parallel fan-out via
SemaphoreSlim-limited concurrency - Per-peer timeout via linked
CancellationTokenSource - Schema validation via
ResponseAggregator - Selection via
ResponseAggregator.AggregateAsync()
src/agent/Mesh/Aggregation/AggregationResult.cs — result model:
- Factories:
Local(),SinglePeer(),NoPeers() - Fields:
Winner,AllResponses,ValidResponses,SelectionMethod,Duration,JudgeRationale,SchemaViolations,PeersContacted,SuccessCount,HasWinner
src/agent/Mesh/Aggregation/ResponseAggregator.cs — aggregation engine:
ValidateSchema(response, schema): JSON validity check + type/required-property structural validation (no external lib)AggregateDeterministic(): FirstSuccess / HighestConfidence / Latest by configuredDeterministicCriterionAggregateVoting(): text normalization → group by normalized result → majority check vsVotingThreshold→ fallback to deterministicAggregateWithLlmJudgeAsync(): builds prompt with all responses → callsILLMClient.CompleteAsync()→ parses JSONbest_index+rationale→ fallback on exception or parse error
Config/AppConfig.cs — MeshConfig.FanOut { get; set; } = new().
MeshServiceExtensions.cs — DI: FanOutOptions, ResponseAggregator, IFanOutOrchestrator → FanOutOrchestrator.
tests/Phase4Tests/FanOutTests.cs — 29 unit tests:
- FanOutOptions defaults, schema validation (JSON validity, type mismatch, missing required, disabled validation), deterministic selection (highest-confidence, first-success, latest), no-valid-responses, failed-excluded, voting majority, voting no-majority fallback, voting below-min-responses fallback, LLM-judge no-client fallback, AggregationResult factories, orchestrator (disabled, no-peers, single-peer, fan-out, budget, schema violations, strategy override)
Validation:
dotnet build src/agent/Hercules.csproj -c Release— 0 errors (19 pre-existing warnings only)dotnet test Phase4— 131/131 passeddotnet test Phase3— 297/297 passed
Scope / Likely files
src/agent/Mesh/Router/FanOut.cs, src/agent/Mesh/Aggregation/
Dependencies
- блокирует / опирается на: task_043 — mesh-router
- блокирует / опирается на: task_044 — complexity-router
Risks / Rollback
Стоимость fan-out; строгие per-request лимиты.
Links
- Backlog: ../backlog.md
- Roadmap (EN): ../../ROADMAP-EN.md
- Roadmap (RU): ../../ROADMAP-RU.md