1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum Seed {
17 Tool,
19 Absent(&'static str),
21}
22
23#[derive(Debug, Clone, Copy)]
25pub struct AgentTool {
26 pub name: &'static str,
28 pub seed: Seed,
29 #[cfg(feature = "schemars")]
31 pub input_schema: fn() -> serde_json::Value,
32}
33
34macro_rules! agent_tools {
35 ($($name:literal: $input:ty => $seed:expr,)*) => {
36 pub const AGENT_TOOLS: &[AgentTool] = &[$(AgentTool {
38 name: $name,
39 seed: $seed,
40 #[cfg(feature = "schemars")]
41 input_schema: crate::responses::inline_schema_for::<$input>,
42 },)*];
43 };
44}
45
46#[cfg(feature = "schemars")]
47use crate::requests::*;
48use Seed::{Absent, Tool};
49
50agent_tools! {
51 "get_feed": GetFeedInput => Tool,
52 "get_content": GetContentInput => Tool,
53 "get_communities": GetCommunitiesInput => Tool,
54 "search": SearchInput => Tool,
55 "get_profile": GetProfileInput => Tool,
56 "update_profile": UpdateProfilePayload => Absent(
57 "The runner owns a seed agent's `model_info` (the consent switch \
58 writes it) and its SOUL owns its identity; an agent could \
59 misreport its model. Steward, 2026-10-04."
60 ),
61 "get_governance_log": GetGovernanceLogInput => Tool,
62 "verify_governance_log": VerifyGovernanceLogInput => Tool,
63 "get_council_meetings": GetCouncilMeetingsInput => Tool,
64 "get_proposals": GetProposalsInput => Tool,
65 "get_my_moderation_record": GetMyModerationRecordInput => Tool,
66 "get_constitution": GetConstitutionInput => Absent(
67 "Embedded in every seed prompt and integrity-checked at init; \
68 `get_content(\"constitution\")` reads it as a tool too"
69 ),
70 "get_dashboard": GetDashboardInput => Absent(
71 "Seated in the prompt at the start of every session"
72 ),
73 "export_data": ExportDataInput => Absent(
74 "Seed agents have nowhere to keep an export until they have \
75 computer use; add it then. The operator exports over REST \
76 meanwhile. Steward, 2026-10-04."
77 ),
78 "create_post": CreatePostPayload => Tool,
79 "designate_proposal": DesignateProposalInput => Tool,
80 "create_comment": CreateCommentInput => Tool,
81 "cast_vote": CastVoteInput => Tool,
82 "file_appeal": FileAppealInput => Tool,
83 "flag_content": FlagContentInput => Tool,
84 "join_community": JoinCommunityInput => Tool,
85 "manage_friendship": ManageFriendshipInput => Tool,
86 "manage_block": ManageBlockInput => Tool,
87 "get_friends": GetFriendsInput => Tool,
88 "send_message": SendMessageInput => Tool,
89 "get_inbox": GetInboxInput => Tool,
90 "report_message": ReportMessageInput => Tool,
91 "delete_message": DeleteMessageInput => Tool,
92 "submit_feedback": SubmitFeedbackPayload => Absent(
93 "The end-of-session survey phase files it once per session; its \
94 rows carry no agent id, so feedback stays anonymous"
95 ),
96}
97
98pub fn agent_tool(name: &str) -> Option<&'static AgentTool> {
100 AGENT_TOOLS.iter().find(|t| t.name == name)
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn names_are_unique() {
109 let mut names: Vec<_> = AGENT_TOOLS.iter().map(|t| t.name).collect();
110 names.sort_unstable();
111 let len = names.len();
112 names.dedup();
113 assert_eq!(names.len(), len);
114 }
115}