Skip to content

Commit e9f9b27

Browse files
authored
Migrate all doc generation to schema objects (#154)
* Copy docs over to request/notif enums * Migrate doc generation to schema objects
1 parent 8a1109f commit e9f9b27

4 files changed

Lines changed: 296 additions & 51 deletions

File tree

rust/agent.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,14 +640,90 @@ pub(crate) const SESSION_SET_MODEL_METHOD_NAME: &str = "session/set_model";
640640
#[serde(untagged)]
641641
#[schemars(extend("x-docs-ignore" = true))]
642642
pub enum ClientRequest {
643+
/// Establishes the connection with a client and negotiates protocol capabilities.
644+
///
645+
/// This method is called once at the beginning of the connection to:
646+
/// - Negotiate the protocol version to use
647+
/// - Exchange capability information between client and agent
648+
/// - Determine available authentication methods
649+
///
650+
/// The agent should respond with its supported protocol version and capabilities.
651+
///
652+
/// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
643653
InitializeRequest(InitializeRequest),
654+
/// Authenticates the client using the specified authentication method.
655+
///
656+
/// Called when the agent requires authentication before allowing session creation.
657+
/// The client provides the authentication method ID that was advertised during initialization.
658+
///
659+
/// After successful authentication, the client can proceed to create sessions with
660+
/// `new_session` without receiving an `auth_required` error.
661+
///
662+
/// See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/initialization)
644663
AuthenticateRequest(AuthenticateRequest),
664+
/// Creates a new conversation session with the agent.
665+
///
666+
/// Sessions represent independent conversation contexts with their own history and state.
667+
///
668+
/// The agent should:
669+
/// - Create a new session context
670+
/// - Connect to any specified MCP servers
671+
/// - Return a unique session ID for future requests
672+
///
673+
/// May return an `auth_required` error if the agent requires authentication.
674+
///
675+
/// See protocol docs: [Session Setup](https://agentclientprotocol.com/protocol/session-setup)
645676
NewSessionRequest(NewSessionRequest),
677+
/// Loads an existing session to resume a previous conversation.
678+
///
679+
/// This method is only available if the agent advertises the `loadSession` capability.
680+
///
681+
/// The agent should:
682+
/// - Restore the session context and conversation history
683+
/// - Connect to the specified MCP servers
684+
/// - Stream the entire conversation history back to the client via notifications
685+
///
686+
/// See protocol docs: [Loading Sessions](https://agentclientprotocol.com/protocol/session-setup#loading-sessions)
646687
LoadSessionRequest(LoadSessionRequest),
688+
/// Sets the current mode for a session.
689+
///
690+
/// Allows switching between different agent modes (e.g., "ask", "architect", "code")
691+
/// that affect system prompts, tool availability, and permission behaviors.
692+
///
693+
/// The mode must be one of the modes advertised in `availableModes` during session
694+
/// creation or loading. Agents may also change modes autonomously and notify the
695+
/// client via `current_mode_update` notifications.
696+
///
697+
/// This method can be called at any time during a session, whether the Agent is
698+
/// idle or actively generating a response.
699+
///
700+
/// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
647701
SetSessionModeRequest(SetSessionModeRequest),
702+
/// Processes a user prompt within a session.
703+
///
704+
/// This method handles the whole lifecycle of a prompt:
705+
/// - Receives user messages with optional context (files, images, etc.)
706+
/// - Processes the prompt using language models
707+
/// - Reports language model content and tool calls to the Clients
708+
/// - Requests permission to run tools
709+
/// - Executes any requested tool calls
710+
/// - Returns when the turn is complete with a stop reason
711+
///
712+
/// See protocol docs: [Prompt Turn](https://agentclientprotocol.com/protocol/prompt-turn)
648713
PromptRequest(PromptRequest),
649714
#[cfg(feature = "unstable")]
715+
/// **UNSTABLE**
716+
///
717+
/// This capability is not part of the spec yet, and may be removed or changed at any point.
718+
///
719+
/// Select a model for a given session.
650720
SetSessionModelRequest(SetSessionModelRequest),
721+
/// Handles extension method requests from the client.
722+
///
723+
/// Extension methods provide a way to add custom functionality while maintaining
724+
/// protocol compatibility.
725+
///
726+
/// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
651727
ExtMethodRequest(ExtRequest),
652728
}
653729

@@ -682,7 +758,24 @@ pub enum AgentResponse {
682758
#[serde(untagged)]
683759
#[schemars(extend("x-docs-ignore" = true))]
684760
pub enum ClientNotification {
761+
/// Cancels ongoing operations for a session.
762+
///
763+
/// This is a notification sent by the client to cancel an ongoing prompt turn.
764+
///
765+
/// Upon receiving this notification, the Agent SHOULD:
766+
/// - Stop all language model requests as soon as possible
767+
/// - Abort all tool call invocations in progress
768+
/// - Send any pending `session/update` notifications
769+
/// - Respond to the original `session/prompt` request with `StopReason::Cancelled`
770+
///
771+
/// See protocol docs: [Cancellation](https://agentclientprotocol.com/protocol/prompt-turn#cancellation)
685772
CancelNotification(CancelNotification),
773+
/// Handles extension notifications from the client.
774+
///
775+
/// Extension notifications provide a way to send one-way messages for custom functionality
776+
/// while maintaining protocol compatibility.
777+
///
778+
/// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
686779
ExtNotification(ExtNotification),
687780
}
688781

rust/bin/generate.rs

Lines changed: 88 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,14 @@ mod markdown_generator {
226226

227227
writeln!(&mut self.output, "## Agent").unwrap();
228228
writeln!(&mut self.output).unwrap();
229-
writeln!(&mut self.output, "{}", side_docs.agent_trait).unwrap();
229+
writeln!(
230+
&mut self.output,
231+
"Defines the interface that all ACP-compliant agents must implement.
232+
233+
Agents are programs that use generative AI to autonomously modify code. They handle
234+
requests from clients and execute tasks using language models and tools."
235+
)
236+
.unwrap();
230237
writeln!(&mut self.output).unwrap();
231238

232239
for (method, types) in agent_types {
@@ -235,7 +242,15 @@ mod markdown_generator {
235242

236243
writeln!(&mut self.output, "## Client").unwrap();
237244
writeln!(&mut self.output).unwrap();
238-
writeln!(&mut self.output, "{}", side_docs.client_trait).unwrap();
245+
writeln!(
246+
&mut self.output,
247+
"Defines the interface that ACP-compliant clients must implement.
248+
249+
Clients are typically code editors (IDEs, text editors) that provide the interface
250+
between users and AI agents. They manage the environment, handle user interactions,
251+
and control access to resources."
252+
)
253+
.unwrap();
239254

240255
for (method, types) in client_types {
241256
self.generate_method(&method, side_docs.client_method_doc(&method), types);
@@ -775,42 +790,44 @@ mod markdown_generator {
775790
}
776791

777792
struct SideDocs {
778-
agent_trait: String,
779793
agent_methods: HashMap<String, String>,
780-
client_trait: String,
781794
client_methods: HashMap<String, String>,
782795
}
783796

784797
impl SideDocs {
785798
fn agent_method_doc(&self, method_name: &str) -> &String {
786799
match method_name {
787-
"initialize" => self.agent_methods.get("initialize").unwrap(),
788-
"authenticate" => self.agent_methods.get("authenticate").unwrap(),
789-
"session/new" => self.agent_methods.get("new_session").unwrap(),
790-
"session/load" => self.agent_methods.get("load_session").unwrap(),
791-
"session/set_mode" => self.agent_methods.get("set_session_mode").unwrap(),
792-
"session/prompt" => self.agent_methods.get("prompt").unwrap(),
793-
"session/cancel" => self.agent_methods.get("cancel").unwrap(),
794-
"session/set_model" => self.agent_methods.get("set_session_model").unwrap(),
800+
"initialize" => self.agent_methods.get("InitializeRequest").unwrap(),
801+
"authenticate" => self.agent_methods.get("AuthenticateRequest").unwrap(),
802+
"session/new" => self.agent_methods.get("NewSessionRequest").unwrap(),
803+
"session/load" => self.agent_methods.get("LoadSessionRequest").unwrap(),
804+
"session/set_mode" => self.agent_methods.get("SetSessionModeRequest").unwrap(),
805+
"session/prompt" => self.agent_methods.get("PromptRequest").unwrap(),
806+
"session/cancel" => self.agent_methods.get("CancelNotification").unwrap(),
807+
"session/set_model" => self.agent_methods.get("SetSessionModelRequest").unwrap(),
795808
_ => panic!("Introduced a method? Add it here :)"),
796809
}
797810
}
798811

799812
fn client_method_doc(&self, method_name: &str) -> &String {
800813
match method_name {
801814
"session/request_permission" => {
802-
self.client_methods.get("request_permission").unwrap()
803-
}
804-
"fs/write_text_file" => self.client_methods.get("write_text_file").unwrap(),
805-
"fs/read_text_file" => self.client_methods.get("read_text_file").unwrap(),
806-
"session/update" => self.client_methods.get("session_notification").unwrap(),
807-
"terminal/create" => self.client_methods.get("create_terminal").unwrap(),
808-
"terminal/output" => self.client_methods.get("terminal_output").unwrap(),
809-
"terminal/release" => self.client_methods.get("release_terminal").unwrap(),
810-
"terminal/wait_for_exit" => {
811-
self.client_methods.get("wait_for_terminal_exit").unwrap()
815+
self.client_methods.get("RequestPermissionRequest").unwrap()
812816
}
813-
"terminal/kill" => self.client_methods.get("kill_terminal_command").unwrap(),
817+
"fs/write_text_file" => self.client_methods.get("WriteTextFileRequest").unwrap(),
818+
"fs/read_text_file" => self.client_methods.get("ReadTextFileRequest").unwrap(),
819+
"session/update" => self.client_methods.get("SessionNotification").unwrap(),
820+
"terminal/create" => self.client_methods.get("CreateTerminalRequest").unwrap(),
821+
"terminal/output" => self.client_methods.get("TerminalOutputRequest").unwrap(),
822+
"terminal/release" => self.client_methods.get("ReleaseTerminalRequest").unwrap(),
823+
"terminal/wait_for_exit" => self
824+
.client_methods
825+
.get("WaitForTerminalExitRequest")
826+
.unwrap(),
827+
"terminal/kill" => self
828+
.client_methods
829+
.get("KillTerminalCommandRequest")
830+
.unwrap(),
814831
_ => panic!("Introduced a method? Add it here :)"),
815832
}
816833
}
@@ -845,48 +862,68 @@ mod markdown_generator {
845862
let doc: Value = serde_json::from_str(&json_content).unwrap();
846863

847864
let mut side_docs = SideDocs {
848-
agent_trait: String::new(),
849865
agent_methods: HashMap::new(),
850-
client_trait: String::new(),
851866
client_methods: HashMap::new(),
852867
};
853868

854869
if let Some(index) = doc["index"].as_object() {
855870
for (_, item) in index {
856-
if item["name"].as_str() == Some("Agent") {
857-
if let Some(docs) = item["docs"].as_str() {
858-
side_docs.agent_trait = docs.to_string();
871+
if item["name"].as_str() == Some("ClientRequest")
872+
&& let Some(variants) = item["inner"]["enum"]["variants"].as_array()
873+
{
874+
for variant_id in variants {
875+
if let Some(variant) = doc["index"][variant_id.to_string()].as_object()
876+
&& let Some(name) = variant["name"].as_str()
877+
{
878+
side_docs.agent_methods.insert(
879+
name.to_string(),
880+
variant["docs"].as_str().unwrap_or_default().to_string(),
881+
);
882+
}
859883
}
884+
}
860885

861-
if let Some(items) = item["inner"]["trait"]["items"].as_array() {
862-
for method_id in items {
863-
if let Some(method) = doc["index"][method_id.to_string()].as_object()
864-
&& let Some(name) = method["name"].as_str()
865-
{
866-
side_docs.agent_methods.insert(
867-
name.to_string(),
868-
method["docs"].as_str().unwrap_or_default().to_string(),
869-
);
870-
}
886+
if item["name"].as_str() == Some("ClientNotification")
887+
&& let Some(variants) = item["inner"]["enum"]["variants"].as_array()
888+
{
889+
for variant_id in variants {
890+
if let Some(variant) = doc["index"][variant_id.to_string()].as_object()
891+
&& let Some(name) = variant["name"].as_str()
892+
{
893+
side_docs.agent_methods.insert(
894+
name.to_string(),
895+
variant["docs"].as_str().unwrap_or_default().to_string(),
896+
);
871897
}
872898
}
873899
}
874900

875-
if item["name"].as_str() == Some("Client") {
876-
if let Some(docs) = item["docs"].as_str() {
877-
side_docs.client_trait = docs.to_string();
901+
if item["name"].as_str() == Some("AgentRequest")
902+
&& let Some(variants) = item["inner"]["enum"]["variants"].as_array()
903+
{
904+
for variant_id in variants {
905+
if let Some(variant) = doc["index"][variant_id.to_string()].as_object()
906+
&& let Some(name) = variant["name"].as_str()
907+
{
908+
side_docs.client_methods.insert(
909+
name.to_string(),
910+
variant["docs"].as_str().unwrap_or_default().to_string(),
911+
);
912+
}
878913
}
914+
}
879915

880-
if let Some(items) = item["inner"]["trait"]["items"].as_array() {
881-
for method_id in items {
882-
if let Some(method) = doc["index"][method_id.to_string()].as_object()
883-
&& let Some(name) = method["name"].as_str()
884-
{
885-
side_docs.client_methods.insert(
886-
name.to_string(),
887-
method["docs"].as_str().unwrap_or_default().to_string(),
888-
);
889-
}
916+
if item["name"].as_str() == Some("AgentNotification")
917+
&& let Some(variants) = item["inner"]["enum"]["variants"].as_array()
918+
{
919+
for variant_id in variants {
920+
if let Some(variant) = doc["index"][variant_id.to_string()].as_object()
921+
&& let Some(name) = variant["name"].as_str()
922+
{
923+
side_docs.client_methods.insert(
924+
name.to_string(),
925+
variant["docs"].as_str().unwrap_or_default().to_string(),
926+
);
890927
}
891928
}
892929
}

0 commit comments

Comments
 (0)