@@ -93,12 +93,37 @@ def rotate_identity_keys(self, agent_id: str) -> OneclawResponse[Any]:
9393 return self ._http .request ("POST" , f"/v1/agents/{ agent_id } /rotate-identity-keys" )
9494
9595 def enroll (
96- self , name : str , human_email : str , description : str = ""
96+ self ,
97+ name : str ,
98+ human_email : str | None = None ,
99+ description : str = "" ,
100+ public_key : str | None = None ,
97101 ) -> OneclawResponse [Any ]:
98- """Self-enroll an agent (no auth required). Credentials emailed to the human."""
102+ """Self-enroll an agent (no auth required).
103+
104+ With ``human_email`` the approval link is emailed; without it the response
105+ carries ``approval_url`` for the human to open while signed in. With
106+ ``public_key`` (``ssh-ed25519 AAAA…`` or base64 of the raw 32-byte key) a
107+ pairing is opened: the response also carries ``pairing_id``, ``fingerprint``
108+ (show it to the human — they verify it on the approval page) and
109+ ``poll_token`` for :meth:`enrollment_status`.
110+ """
111+ body : dict [str , Any ] = {"name" : name , "description" : description }
112+ if human_email :
113+ body ["human_email" ] = human_email
114+ if public_key :
115+ body ["public_key" ] = public_key
116+ return self ._http .request (
117+ "POST" , "/v1/agents/enroll" , body = body , skip_auth = True ,
118+ )
119+
120+ def enrollment_status (self , pairing_id : str , poll_token : str ) -> OneclawResponse [Any ]:
121+ """Pairing status (no auth). ``status`` is pending/approved/denied/expired; on the
122+ first approved response ``api_key`` is present, once."""
99123 return self ._http .request (
100- "POST" , "/v1/agents/enroll" ,
101- body = {"name" : name , "human_email" : human_email , "description" : description },
124+ "GET" ,
125+ f"/v1/agents/enroll/{ pairing_id } /status" ,
126+ query = {"poll" : poll_token },
102127 skip_auth = True ,
103128 )
104129
0 commit comments