contractNet

suspend fun <Q, B> KSLProcessBuilder.contractNet(bidders: List<AgentModel.Agent>, callForProposals: Q, deadline: Double, selectBest: (List<AgentMessage.Propose<B>>) -> AgentMessage.Propose<B>? = { it.firstOrNull() }): ContractNetOutcome<B>?(source)

Run a Contract-Net Protocol negotiation from inside the calling agent's process. The calling agent (the initiator) sends a AgentMessage.Request with payload callForProposals to every agent in bidders, waits for deadline simulated time units, then collects the AgentMessage.Propose messages that arrived with the matching conversation id. The selectBest function picks the winning proposal (default: first received).

Proposals for this conversation are captured via a mailbox reservation held for the duration of the call, so they are isolated from any other consumer on the initiator's mailbox — a statechart onMessage<Propose> handler or a concurrent receiveMessage cannot steal bids. Only proposals whose sender is an AgentModel.Agent are considered (a non-Agent ksl.modeling.entity.ProcessModel.Entity has no mailbox to notify and cannot be the winner); any others are ignored.

The winner is sent AgentMessage.Accept; every other agent that proposed is sent AgentMessage.Reject. Proposals that arrive after the reservation is released (e.g. after the deadline) are not collected and flow to the initiator's mailbox normally.

Returns the ContractNetOutcome for the winner, or null if no bidder proposed, or if selectBest returned null.

This helper must be called from inside the initiator's process { } body so it can suspend on delay and sendMessage. The initiator is taken from the calling KSLProcessBuilder.entity, which must be an AgentModel.Agent.

Type parameters: - Q the payload type of the call-for-proposals - B the payload type expected on incoming AgentMessage.Propose messages. Due to JVM type erasure this is a compile-time contract, not a runtime check; bidders that respond with a Propose<X> for some other X will still be visible to this call and the unchecked cast to Propose<B> happens internally. Keep the bid type consistent within a model.