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