1pub mod decision;
2pub mod handoff;
3pub mod multi_round;
4pub mod passthrough;
5pub mod proposal;
6pub mod quorum;
7pub mod task;
8pub mod util;
9
10use macp_core::error::MacpError;
11use macp_core::session::Session;
12use macp_pb::pb::{Envelope, ModeDescriptor};
13use std::collections::HashMap;
14
15pub const STANDARD_MODE_NAMES: &[&str] = &[
17 "macp.mode.decision.v1",
18 "macp.mode.proposal.v1",
19 "macp.mode.task.v1",
20 "macp.mode.handoff.v1",
21 "macp.mode.quorum.v1",
22];
23
24pub const EXTENSION_MODE_NAMES: &[&str] = &["ext.multi_round.v1"];
26
27pub use macp_core::mode::ModeResponse;
31
32pub trait Mode: Send + Sync {
36 fn on_session_start(
37 &self,
38 session: &Session,
39 env: &Envelope,
40 ) -> Result<ModeResponse, MacpError>;
41
42 fn on_message(&self, session: &Session, env: &Envelope) -> Result<ModeResponse, MacpError>;
43
44 fn authorize_sender(&self, session: &Session, env: &Envelope) -> Result<(), MacpError> {
47 if !session.participants.is_empty() && !session.participants.contains(&env.sender) {
48 return Err(MacpError::Forbidden);
49 }
50 Ok(())
51 }
52}
53
54pub fn standard_mode_names() -> &'static [&'static str] {
55 STANDARD_MODE_NAMES
56}
57
58pub fn extension_mode_names() -> &'static [&'static str] {
59 EXTENSION_MODE_NAMES
60}
61
62fn schema_map(path: &str) -> HashMap<String, String> {
63 HashMap::from([("protobuf".to_string(), path.to_string())])
64}
65
66pub fn standard_mode_descriptors() -> Vec<ModeDescriptor> {
67 vec![
68 ModeDescriptor {
69 mode: "macp.mode.decision.v1".into(),
70 mode_version: "1.0.0".into(),
71 title: "Decision Mode".into(),
72 description: "Structured decision making with proposals, evaluations, objections, votes, and a terminal Commitment.".into(),
73 determinism_class: "semantic-deterministic".into(),
74 participant_model: "declared".into(),
75 message_types: vec![
76 "SessionStart".into(),
77 "Proposal".into(),
78 "Evaluation".into(),
79 "Objection".into(),
80 "Vote".into(),
81 "Commitment".into(),
82 ],
83 terminal_message_types: vec!["Commitment".into()],
84 schema_uris: schema_map("buf.build/multiagentcoordinationprotocol/macp"),
85 },
86 ModeDescriptor {
87 mode: "macp.mode.proposal.v1".into(),
88 mode_version: "1.0.0".into(),
89 title: "Proposal Mode".into(),
90 description: "Negotiation with proposals, counterproposals, accepts, rejects, withdrawals, and a terminal Commitment.".into(),
91 determinism_class: "semantic-deterministic".into(),
92 participant_model: "peer".into(),
93 message_types: vec![
94 "SessionStart".into(),
95 "Proposal".into(),
96 "CounterProposal".into(),
97 "Accept".into(),
98 "Reject".into(),
99 "Withdraw".into(),
100 "Commitment".into(),
101 ],
102 terminal_message_types: vec!["Commitment".into()],
103 schema_uris: schema_map("buf.build/multiagentcoordinationprotocol/macp"),
104 },
105 ModeDescriptor {
106 mode: "macp.mode.task.v1".into(),
107 mode_version: "1.0.0".into(),
108 title: "Task Mode".into(),
109 description: "One bounded delegated task with assignee responses, progress, completion/failure reports, and a terminal Commitment.".into(),
110 determinism_class: "structural-only".into(),
111 participant_model: "orchestrated".into(),
112 message_types: vec![
113 "SessionStart".into(),
114 "TaskRequest".into(),
115 "TaskAccept".into(),
116 "TaskReject".into(),
117 "TaskUpdate".into(),
118 "TaskComplete".into(),
119 "TaskFail".into(),
120 "Commitment".into(),
121 ],
122 terminal_message_types: vec!["Commitment".into()],
123 schema_uris: schema_map("buf.build/multiagentcoordinationprotocol/macp"),
124 },
125 ModeDescriptor {
126 mode: "macp.mode.handoff.v1".into(),
127 mode_version: "1.0.0".into(),
128 title: "Handoff Mode".into(),
129 description: "Scoped responsibility transfer with handoff offers, context, target responses, and a terminal Commitment.".into(),
130 determinism_class: "context-frozen".into(),
131 participant_model: "delegated".into(),
132 message_types: vec![
133 "SessionStart".into(),
134 "HandoffOffer".into(),
135 "HandoffContext".into(),
136 "HandoffAccept".into(),
137 "HandoffDecline".into(),
138 "Commitment".into(),
139 ],
140 terminal_message_types: vec!["Commitment".into()],
141 schema_uris: schema_map("buf.build/multiagentcoordinationprotocol/macp"),
142 },
143 ModeDescriptor {
144 mode: "macp.mode.quorum.v1".into(),
145 mode_version: "1.0.0".into(),
146 title: "Quorum Mode".into(),
147 description: "Threshold approval with one approval request, participant ballots, and a terminal Commitment.".into(),
148 determinism_class: "semantic-deterministic".into(),
149 participant_model: "quorum".into(),
150 message_types: vec![
151 "SessionStart".into(),
152 "ApprovalRequest".into(),
153 "Approve".into(),
154 "Reject".into(),
155 "Abstain".into(),
156 "Commitment".into(),
157 ],
158 terminal_message_types: vec!["Commitment".into()],
159 schema_uris: schema_map("buf.build/multiagentcoordinationprotocol/macp"),
160 },
161 ]
162}
163
164pub fn extension_mode_descriptors() -> Vec<ModeDescriptor> {
165 vec![ModeDescriptor {
166 mode: "ext.multi_round.v1".into(),
167 mode_version: "1.0.0".into(),
168 title: "Multi-Round Mode".into(),
169 description: "Iterative convergence through multiple contribution rounds until all participants agree, with a terminal Commitment.".into(),
170 determinism_class: "semantic-deterministic".into(),
171 participant_model: "peer".into(),
172 message_types: vec![
173 "SessionStart".into(),
174 "Contribute".into(),
175 "Commitment".into(),
176 ],
177 terminal_message_types: vec!["Commitment".into()],
178 schema_uris: schema_map("buf.build/multiagentcoordinationprotocol/macp"),
179 }]
180}
181
182pub fn all_mode_descriptors() -> Vec<ModeDescriptor> {
183 let mut all = standard_mode_descriptors();
184 all.extend(extension_mode_descriptors());
185 all
186}