By default, Somnia Agents uses Majority consensus — the request finalizes when a threshold of validators return byte-identical results. This works well for deterministic agents (math, API lookups with exact values, etc.) but breaks down when each validator is expected to return a different value.
Threshold consensus solves this. Instead of requiring matching results, it finalizes as soon as the threshold number of validators respond successfully — regardless of whether their results agree. Your callback receives all individual results, and you aggregate them however you like.
Consensus Types
Type
Finalization Condition
responses[] in Callback
Majority (0)
threshold validators return the same result
Responds with all responses; at least threshold will match on the same .result value
Threshold (1)
threshold validators return any successful result
All responses (check .status to filter successful ones)
Using Threshold Consensus
Call createAdvancedRequest instead of createRequest:
platform.createAdvancedRequest{value: deposit}( agentId,address(this),this.handleResponse.selector, payload,5,// subcommitteeSize3,// threshold — finalize after 3 of 5 respond ConsensusType.Threshold,// don't require matching results1minutes// timeout);
The threshold parameter controls how many successful responses are needed before finalization. A typical choice is 3 of 5 — this tolerates up to 2 validator failures while still collecting enough data points for meaningful aggregation.
Example: Price Oracle (Median)
Each validator fetches a price independently. Results may differ slightly. Your contract takes the median to filter outliers.
Taking the median of independent price observations naturally filters outliers and manipulation — with 3 of 5 results, the median remains accurate even if one validator returns a garbage value.
Example: Random Oracle (XOR)
Each validator returns a random uint256. Your contract XORs all values together to produce a combined random number. This is secure as long as at least one responding validator provides a truly random value — even if the others are compromised or predictable, the XOR output remains unpredictable.
When to Use Which
Use Case
Consensus
Why
Deterministic computation (math, hashing)
Majority
All validators should return the exact same result
API lookups with exact values
Majority
Same endpoint, same response
Deterministic LLM inference
Majority
Fixed seed + temperature 0 produces identical outputs across validators
Price feeds / continuous values
Threshold
Slight differences expected; median filters outliers
Random number generation
Threshold
Values must differ; XOR combines them securely
Weather data / sensor readings
Threshold
Approximate values; average or median for accuracy
Non-deterministic LLM inference
Threshold
Natural variance in outputs; application decides how to reconcile
Threshold Tips
A threshold of 3 out of 5 is a good default — it tolerates up to 2 failures while still collecting enough data for aggregation.
Higher thresholds (e.g., 4 of 5) give more data points but are more likely to time out if a validator fails.
Avoid setting threshold = subcommitteeSize — a single validator failure would prevent finalization entirely.
The responses[] array in your callback contains all validator responses — check each responses[i].status to filter for successful ones.
getAdvancedRequestDeposit(subSize) returns the operations-reserve floor (minPerAgentDeposit × subSize). That's the minimum msg.value the contract will accept, and it only covers gas/callback/upkeep — the agent pot is msg.value − floor. Deposit more than the floor to actually pay runners for execution work. See Gas Fees for the full fund-flow model.
Unused funds are rebated to the requester after finalisation.