fix: expose the rotation grace deadline and encode agent ids in paths

Add previous_token_grace_until to RotateApiTokenResponse and
percent-encode the agent id path segment in both clients.

Claude-Session: https://claude.ai/code/session_01Agoc9bRVE9KL7mmWtey9Vq
This commit is contained in:
雷电芽衣 committed 2026-09-03 20:12:50 -04:00
1 parent 7b3ea2922c
commit 11a152bab8
3 files changed
+15 -12

No files matched your search

+7 -6
View File
@@ -3,6 +3,7 @@
from __future__ import annotations
import warnings
from urllib.parse import quote
from typing import Any, Dict, List, Optional, Union
import aiohttp
@@ -212,19 +213,19 @@ class AsyncElydoraClient:
return await self._request("POST", "/v1/agents/register", json_body=request)
async def get_agent(self, agent_id: str) -> GetAgentResponse:
return await self._request("GET", f"/v1/agents/{agent_id}")
return await self._request("GET", f"/v1/agents/{quote(agent_id, safe='')}")
async def list_agents(self) -> ListAgentsResponse:
return await self._request("GET", "/v1/agents")
async def freeze_agent(self, agent_id: str, reason: str) -> FreezeAgentResponse:
return await self._request(
"POST", f"/v1/agents/{agent_id}/freeze", json_body={"reason": reason}
"POST", f"/v1/agents/{quote(agent_id, safe='')}/freeze", json_body={"reason": reason}
)
async def unfreeze_agent(self, agent_id: str, reason: str) -> UnfreezeAgentResponse:
return await self._request(
"POST", f"/v1/agents/{agent_id}/unfreeze", json_body={"reason": reason}
"POST", f"/v1/agents/{quote(agent_id, safe='')}/unfreeze", json_body={"reason": reason}
)
async def update_agent(
@@ -232,15 +233,15 @@ class AsyncElydoraClient:
) -> UpdateAgentResponse:
require_integration_type(integration_type)
return await self._request(
"PATCH", f"/v1/agents/{agent_id}", json_body={"integration_type": integration_type}
"PATCH", f"/v1/agents/{quote(agent_id, safe='')}", json_body={"integration_type": integration_type}
)
async def delete_agent(self, agent_id: str) -> DeleteAgentResponse:
return await self._request("DELETE", f"/v1/agents/{agent_id}")
return await self._request("DELETE", f"/v1/agents/{quote(agent_id, safe='')}")
async def revoke_key(self, agent_id: str, kid: str, reason: str) -> None:
await self._request(
"POST", f"/v1/agents/{agent_id}/revoke", json_body={"kid": kid, "reason": reason}
"POST", f"/v1/agents/{quote(agent_id, safe='')}/revoke", json_body={"kid": kid, "reason": reason}
)
def create_operation(
+7 -6
View File
@@ -3,6 +3,7 @@
from __future__ import annotations
import warnings
from urllib.parse import quote
from typing import Any, Dict, List, Optional, Union
import requests
@@ -198,29 +199,29 @@ class ElydoraClient:
return self._request("POST", "/v1/agents/register", json_body=request)
def get_agent(self, agent_id: str) -> GetAgentResponse:
return self._request("GET", f"/v1/agents/{agent_id}")
return self._request("GET", f"/v1/agents/{quote(agent_id, safe='')}")
def list_agents(self) -> ListAgentsResponse:
return self._request("GET", "/v1/agents")
def freeze_agent(self, agent_id: str, reason: str) -> FreezeAgentResponse:
return self._request("POST", f"/v1/agents/{agent_id}/freeze", json_body={"reason": reason})
return self._request("POST", f"/v1/agents/{quote(agent_id, safe='')}/freeze", json_body={"reason": reason})
def unfreeze_agent(self, agent_id: str, reason: str) -> UnfreezeAgentResponse:
return self._request("POST", f"/v1/agents/{agent_id}/unfreeze", json_body={"reason": reason})
return self._request("POST", f"/v1/agents/{quote(agent_id, safe='')}/unfreeze", json_body={"reason": reason})
def update_agent(self, agent_id: str, integration_type: IntegrationType) -> UpdateAgentResponse:
require_integration_type(integration_type)
return self._request(
"PATCH", f"/v1/agents/{agent_id}", json_body={"integration_type": integration_type}
"PATCH", f"/v1/agents/{quote(agent_id, safe='')}", json_body={"integration_type": integration_type}
)
def delete_agent(self, agent_id: str) -> DeleteAgentResponse:
return self._request("DELETE", f"/v1/agents/{agent_id}")
return self._request("DELETE", f"/v1/agents/{quote(agent_id, safe='')}")
def revoke_key(self, agent_id: str, kid: str, reason: str) -> None:
self._request(
"POST", f"/v1/agents/{agent_id}/revoke", json_body={"kid": kid, "reason": reason}
"POST", f"/v1/agents/{quote(agent_id, safe='')}/revoke", json_body={"kid": kid, "reason": reason}
)
def create_operation(
+1
View File
@@ -359,6 +359,7 @@ class RotateApiTokenResponse(TypedDict):
token: str
expires_at: Optional[int]
token_id: str
previous_token_grace_until: int
class HealthResponse(TypedDict):