Conversation
- Enrich DEADLOCK_API_INFO with overview, docs links, and detailed descriptions for both Game Data and Assets APIs - Add DeadlockAPISchemaFetchTool that fetches OpenAPI specs for either the data API or assets API so the agent can answer detailed questions about available endpoints, parameters, and response formats - Register the new tool in ToolRegistry with proper lifecycle management - Update system prompt with Deadlock API section including all resource links and guidance to use the schema tool for API usage questions - Add comprehensive tests for both the info tool and schema fetch tool https://claude.ai/code/session_017pU3sCe7ku3xp7as1VXnkp
There was a problem hiding this comment.
Pull request overview
Adds a new tool for fetching Deadlock OpenAPI schemas and expands the agent’s built-in Deadlock API documentation so the assistant can answer endpoint/parameter questions from the live spec.
Changes:
- Introduces
DeadlockAPISchemaFetchToolto fetch OpenAPI JSON for the Game Data API or Assets API. - Expands
DEADLOCK_API_INFOand updates the agent knowledge base with richer Deadlock API guidance/links. - Registers/cleans up the new tool in the tool registry and adds unit tests for the new behaviors.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/tools/registry.py | Registers the new schema-fetch tool with lazy init and closes it during registry cleanup. |
| packages/tools/openapi/deadlock_api.py | Expands DEADLOCK_API_INFO, adds OPENAPI_SPEC_URLS, and implements DeadlockAPISchemaFetchTool. |
| packages/tools/openapi/openapi_test.py | Adds new unit tests for DeadlockAPIInfoTool and DeadlockAPISchemaFetchTool. |
| packages/api/patreon_test.py | Minor formatting adjustment in an existing test. |
| packages/ai_assistant/agent.py | Updates the knowledge base with Deadlock API links and guidance on when to use each tool. |
Comments suppressed due to low confidence (1)
packages/tools/openapi/deadlock_api.py:140
- The
DeadlockAPIInfoToolclass docstring is now out of date: it says it only provides URLs for the main website/assets/data/GitHub, butDEADLOCK_API_INFOnow includes anoverviewsection plus Discord/Patreon links (and docs links). Updating the docstring will prevent misleading documentation for tool consumers.
"""Tool that returns information about the Deadlock API resources.
Provides URLs and descriptions for the main website, assets API,
data API, and GitHub repository.
"""
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| async def test_run_fetches_data_api_schema(self, schema_tool: DeadlockAPISchemaFetchTool) -> None: | ||
| """Test fetching the data API schema.""" | ||
| sample_spec = { | ||
| "openapi": "3.0.0", | ||
| "info": {"title": "Deadlock API", "version": "1.0.0"}, | ||
| "paths": {"/v1/matches": {"get": {"summary": "Get matches"}}}, | ||
| } | ||
|
|
||
| mock_response = MagicMock() | ||
| mock_response.json.return_value = sample_spec | ||
| mock_response.raise_for_status = MagicMock() | ||
|
|
There was a problem hiding this comment.
Schema fetching error handling currently has coverage for HTTP and network failures, but there isn’t a test for a successful HTTP response that contains invalid/non-JSON content (i.e., response.json() raising). After adding parse-error handling in DeadlockAPISchemaFetchTool, add a unit test asserting it raises OpenAPIConnectionError (and that the SSE end event reports a useful summary).
| client = await self._get_client() | ||
| response = await client.get(spec_url) | ||
| response.raise_for_status() | ||
| return response.json() |
There was a problem hiding this comment.
DeadlockAPISchemaFetchTool._run doesn’t handle JSON decoding/parsing failures from response.json(). If the endpoint returns non-JSON (e.g., HTML error page with 200), this will raise a ValueError that bypasses the intended OpenAPIConnectionError path and results in inconsistent error reporting/retries. Consider catching JSON parse errors (or a broad Exception) around response.json() and re-raising as OpenAPIConnectionError with a helpful message (similar to OpenAPIToolGenerator.fetch_spec).
| return response.json() | |
| try: | |
| return response.json() | |
| except ValueError as e: | |
| # Handle cases where the endpoint returns non-JSON (e.g., HTML error page with 2xx status) | |
| raise OpenAPIConnectionError( | |
| f"Failed to parse {api} API schema as JSON from {spec_url}" | |
| ) from e |
| # OpenAPI spec URLs for schema fetching | ||
| OPENAPI_SPEC_URLS: dict[str, str] = { | ||
| "data": "https://api.deadlock-api.com/openapi.json", | ||
| "assets": "https://assets.deadlock-api.com/openapi.json", | ||
| } |
There was a problem hiding this comment.
DEADLOCK_API_INFO embeds the OpenAPI spec URLs as string literals while the same URLs are also defined in OPENAPI_SPEC_URLS. This duplication risks the two getting out of sync over time. Consider referencing OPENAPI_SPEC_URLS['data'] / OPENAPI_SPEC_URLS['assets'] when populating the openapi_spec fields (or building DEADLOCK_API_INFO from OPENAPI_SPEC_URLS) so there’s a single source of truth.
| async def _run(self, api: str) -> dict[str, Any]: | ||
| """Fetch the OpenAPI schema for the specified API. | ||
|
|
||
| Args: | ||
| api: Which API to fetch the schema for ('data' or 'assets') | ||
|
|
||
| Returns: | ||
| The OpenAPI specification as a dictionary | ||
|
|
||
| Raises: | ||
| ValueError: If api is not 'data' or 'assets' | ||
| OpenAPIConnectionError: If the schema cannot be fetched | ||
| """ |
There was a problem hiding this comment.
This method requires 2 positional arguments, whereas overridden BaseTool._run requires 1.
| async def _run(self, api: str) -> dict[str, Any]: | |
| """Fetch the OpenAPI schema for the specified API. | |
| Args: | |
| api: Which API to fetch the schema for ('data' or 'assets') | |
| Returns: | |
| The OpenAPI specification as a dictionary | |
| Raises: | |
| ValueError: If api is not 'data' or 'assets' | |
| OpenAPIConnectionError: If the schema cannot be fetched | |
| """ | |
| async def _run(self, *args: Any, **kwargs: Any) -> dict[str, Any]: | |
| """Fetch the OpenAPI schema for the specified API. | |
| Args: | |
| api: Which API to fetch the schema for ('data' or 'assets'). | |
| May be provided as the first positional argument or as a keyword | |
| argument named 'api'. | |
| Returns: | |
| The OpenAPI specification as a dictionary | |
| Raises: | |
| ValueError: If api is not provided or is not 'data' or 'assets' | |
| OpenAPIConnectionError: If the schema cannot be fetched | |
| """ | |
| api = args[0] if args else kwargs.get("api") | |
| if api is None: | |
| raise ValueError("Missing required 'api' argument. Must be one of: " | |
| + ", ".join(sorted(OPENAPI_SPEC_URLS))) |
Summary
This PR adds a new
DeadlockAPISchemaFetchToolthat allows the AI agent to fetch and inspect OpenAPI schemas for the Deadlock APIs, enabling it to answer detailed questions about available endpoints and parameters. It also enhances the Deadlock API documentation with comprehensive resource information and improves the API info structure.Key Changes
DeadlockAPISchemaFetchToolclass that fetches OpenAPI specifications for either the Game Data API or Assets API, with proper error handling and retry logicDEADLOCK_API_INFOdictionary with:OPENAPI_SPEC_URLSconstant for centralized management of schema endpointsdeadlock_api_schemavsdeadlock_api_infotoolsImplementation Details
OpenAPIConnectionErrorexceptionshttps://claude.ai/code/session_017pU3sCe7ku3xp7as1VXnkp