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 on_message_at(
51 &self,
52 session: &Session,
53 env: &Envelope,
54 ctx: &macp_core::mode::MessageContext,
55 ) -> Result<ModeResponse, MacpError> {
56 let _ = ctx;
57 self.on_message(session, env)
58 }
59
60 fn authorize_sender(&self, session: &Session, env: &Envelope) -> Result<(), MacpError> {
63 if !session.participants.is_empty() && !session.participants.contains(&env.sender) {
64 return Err(MacpError::Forbidden);
65 }
66 Ok(())
67 }
68}
69
70pub fn standard_mode_names() -> &'static [&'static str] {
71 STANDARD_MODE_NAMES
72}
73
74pub fn extension_mode_names() -> &'static [&'static str] {
75 EXTENSION_MODE_NAMES
76}
77
78fn schema_map(path: &str) -> HashMap<String, String> {
79 HashMap::from([("protobuf".to_string(), path.to_string())])
80}
81
82pub fn standard_mode_descriptors() -> Vec<ModeDescriptor> {
83 vec![
84 ModeDescriptor {
85 mode: "macp.mode.decision.v1".into(),
86 mode_version: "1.0.0".into(),
87 title: "Decision Mode".into(),
88 description: "Structured decision making with proposals, evaluations, objections, votes, and a terminal Commitment.".into(),
89 determinism_class: "semantic-deterministic".into(),
90 participant_model: "declared".into(),
91 message_types: vec![
92 "SessionStart".into(),
93 "Proposal".into(),
94 "Evaluation".into(),
95 "Objection".into(),
96 "Vote".into(),
97 "Commitment".into(),
98 ],
99 terminal_message_types: vec!["Commitment".into()],
100 schema_uris: schema_map("buf.build/multiagentcoordinationprotocol/macp"),
101 },
102 ModeDescriptor {
103 mode: "macp.mode.proposal.v1".into(),
104 mode_version: "1.0.0".into(),
105 title: "Proposal Mode".into(),
106 description: "Negotiation with proposals, counterproposals, accepts, rejects, withdrawals, and a terminal Commitment.".into(),
107 determinism_class: "semantic-deterministic".into(),
108 participant_model: "peer".into(),
109 message_types: vec![
110 "SessionStart".into(),
111 "Proposal".into(),
112 "CounterProposal".into(),
113 "Accept".into(),
114 "Reject".into(),
115 "Withdraw".into(),
116 "Commitment".into(),
117 ],
118 terminal_message_types: vec!["Commitment".into()],
119 schema_uris: schema_map("buf.build/multiagentcoordinationprotocol/macp"),
120 },
121 ModeDescriptor {
122 mode: "macp.mode.task.v1".into(),
123 mode_version: "1.0.0".into(),
124 title: "Task Mode".into(),
125 description: "One bounded delegated task with assignee responses, progress, completion/failure reports, and a terminal Commitment.".into(),
126 determinism_class: "structural-only".into(),
127 participant_model: "orchestrated".into(),
128 message_types: vec![
129 "SessionStart".into(),
130 "TaskRequest".into(),
131 "TaskAccept".into(),
132 "TaskReject".into(),
133 "TaskUpdate".into(),
134 "TaskComplete".into(),
135 "TaskFail".into(),
136 "Commitment".into(),
137 ],
138 terminal_message_types: vec!["Commitment".into()],
139 schema_uris: schema_map("buf.build/multiagentcoordinationprotocol/macp"),
140 },
141 ModeDescriptor {
142 mode: "macp.mode.handoff.v1".into(),
143 mode_version: "1.0.0".into(),
144 title: "Handoff Mode".into(),
145 description: "Scoped responsibility transfer with handoff offers, context, target responses, and a terminal Commitment.".into(),
146 determinism_class: "context-frozen".into(),
147 participant_model: "delegated".into(),
148 message_types: vec![
149 "SessionStart".into(),
150 "HandoffOffer".into(),
151 "HandoffContext".into(),
152 "HandoffAccept".into(),
153 "HandoffDecline".into(),
154 "Commitment".into(),
155 ],
156 terminal_message_types: vec!["Commitment".into()],
157 schema_uris: schema_map("buf.build/multiagentcoordinationprotocol/macp"),
158 },
159 ModeDescriptor {
160 mode: "macp.mode.quorum.v1".into(),
161 mode_version: "1.0.0".into(),
162 title: "Quorum Mode".into(),
163 description: "Threshold approval with one approval request, participant ballots, and a terminal Commitment.".into(),
164 determinism_class: "semantic-deterministic".into(),
165 participant_model: "quorum".into(),
166 message_types: vec![
167 "SessionStart".into(),
168 "ApprovalRequest".into(),
169 "Approve".into(),
170 "Reject".into(),
171 "Abstain".into(),
172 "Commitment".into(),
173 ],
174 terminal_message_types: vec!["Commitment".into()],
175 schema_uris: schema_map("buf.build/multiagentcoordinationprotocol/macp"),
176 },
177 ]
178}
179
180pub fn extension_mode_descriptors() -> Vec<ModeDescriptor> {
181 vec![ModeDescriptor {
182 mode: "ext.multi_round.v1".into(),
183 mode_version: "1.0.0".into(),
184 title: "Multi-Round Mode".into(),
185 description: "Iterative convergence through multiple contribution rounds until all participants agree, with a terminal Commitment.".into(),
186 determinism_class: "semantic-deterministic".into(),
187 participant_model: "peer".into(),
188 message_types: vec![
189 "SessionStart".into(),
190 "Contribute".into(),
191 "Commitment".into(),
192 ],
193 terminal_message_types: vec!["Commitment".into()],
194 schema_uris: schema_map("buf.build/multiagentcoordinationprotocol/macp"),
195 }]
196}
197
198pub fn all_mode_descriptors() -> Vec<ModeDescriptor> {
199 let mut all = standard_mode_descriptors();
200 all.extend(extension_mode_descriptors());
201 all
202}