Skip to content

add engine cloud service #35

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 21, 2025
Merged

add engine cloud service #35

merged 3 commits into from
May 21, 2025

Conversation

cjber
Copy link
Contributor

@cjber cjber commented May 21, 2025

Summary by CodeRabbit

  • New Features

    • Introduced the EngineCloud service for cloud-based engine operations, including server wallet creation with KMS, contract interactions, transaction management, balance queries, and transaction searches.
  • Documentation

    • Updated READMEs to detail EngineCloud usage, configuration, and capabilities.
    • Added new CLI options and environment variables for EngineCloud integration.

Copy link

coderabbitai bot commented May 21, 2025

Walkthrough

The changes introduce a new EngineCloud service for interacting with the Thirdweb Engine Cloud API, including methods for wallet creation, contract execution, transaction handling, and querying. Documentation is updated to reflect this addition. Public APIs are clarified in relevant __init__.py files, and a new adapter module is added for Google ADK tools. Minor improvements are made to the Google ADK adapter to avoid mutating schema data.

Changes

File(s) Change Summary
python/thirdweb-ai/README.md Updated documentation to include the new EngineCloud service, its usage, initialization, and description in the available services section.
python/thirdweb-mcp/README.md Updated documentation to introduce and configure the new EngineCloud service for the MCP server, including new CLI options and environment variables.
python/thirdweb-mcp/src/mcp.py Added EngineCloud integration with new CLI options --engine-cloud-url and --vault-access-token; updated main function signature and service registration to include EngineCloud.
python/thirdweb-ai/src/thirdweb_ai/adapters/google_adk/init.py Introduced a new module that imports and publicly exports the get_google_adk_tools function, defining the public API for the adapter.
python/thirdweb-ai/src/thirdweb_ai/adapters/google_adk/google_adk.py Modified _get_declaration method to deep copy and recursively clean "additionalProperties" from schema parameters to avoid mutating original data.
python/thirdweb-ai/src/thirdweb_ai/services/init.py Added a new __init__.py that imports and publicly exports six service classes (Engine, EngineCloud, Insight, Nebula, Service, Storage) to define the package's public API.
python/thirdweb-ai/src/thirdweb_ai/services/engine_cloud.py Introduced the EngineCloud class, extending Service, providing methods for server wallet creation, contract execution, transaction sending, contract reading, balance retrieval, and transaction searching, all interfacing with the Engine Cloud API. Each method is type-annotated and includes descriptive metadata for parameters.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant EngineCloud
    participant EngineCloudAPI

    User->>EngineCloud: Initialize (secret_key, vault_access_token)
    User->>EngineCloud: create_server_wallet(label)
    EngineCloud->>EngineCloudAPI: POST /server-wallets {label}
    EngineCloudAPI-->>EngineCloud: Response (wallet info)
    EngineCloud-->>User: Wallet info

    User->>EngineCloud: write_contract(from_address, chain_id, method, params, contract_address, abi, value)
    EngineCloud->>EngineCloudAPI: POST /contract/write {params}
    EngineCloudAPI-->>EngineCloud: Response (tx result)
    EngineCloud-->>User: Tx result

    User->>EngineCloud: send_transaction(from_address, chain_id, to_address, data, value)
    EngineCloud->>EngineCloudAPI: POST /transaction/send {params}
    EngineCloudAPI-->>EngineCloud: Response (tx result)
    EngineCloud-->>User: Tx result

    User->>EngineCloud: read_contract(multicall_address, chain_id, from_address, method, params, contract_address, abi)
    EngineCloud->>EngineCloudAPI: POST /contract/read {params}
    EngineCloudAPI-->>EngineCloud: Response (read result)
    EngineCloud-->>User: Read result

    User->>EngineCloud: get_native_balance(chain_id, address)
    EngineCloud->>EngineCloudAPI: POST /balance/native {params}
    EngineCloudAPI-->>EngineCloud: Response (balance)
    EngineCloud-->>User: Balance

    User->>EngineCloud: search_transactions(filters, filters_operation, page, limit, sort_by, sort_direction)
    EngineCloud->>EngineCloudAPI: POST /transactions/search {params}
    EngineCloudAPI-->>EngineCloud: Response (transactions)
    EngineCloud-->>User: Transactions
Loading
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
python/thirdweb-ai/src/thirdweb_ai/services/__init__.py (1)

1-8: Well-structured module exports.

The file properly imports and explicitly exports the service classes, making the API surface clear and well-defined. The inclusion of EngineCloud alongside the other services integrates it nicely into the package.

Add a newline at the end of the file to fix the static analysis warning:

 __all__ = ["Engine", "EngineCloud", "Insight", "Nebula", "Service", "Storage"]
+
🧰 Tools
🪛 Ruff (0.11.9)

8-8: No newline at end of file

Add trailing newline

(W292)

python/thirdweb-ai/src/thirdweb_ai/services/engine_cloud.py (1)

168-214: Consider simplifying the complex type annotation.

The filters parameter has a complex type annotation that might be difficult to maintain. Consider defining a dedicated type alias or class to improve readability.

+# At the top of the file, add:
+from typing import TypedDict, Union, Literal
+
+class FilterField(TypedDict):
+    field: Literal["id", "batchIndex", "from", "signerAddress", "smartAccountAddress", "chainId"]
+
+class FilterValues(TypedDict):
+    values: list[int]
+
+class FilterOperator(TypedDict):
+    operator: Literal["AND", "OR"]
+
+FilterCondition = Union[FilterField, FilterValues, FilterOperator]
+
 @tool(
     description="Search for transactions with flexible filtering options. Retrieve transaction history with customizable filters for addresses, chains, statuses, and more."
 )
 def search_transactions(
     self,
     filters: Annotated[
-        list[
-            dict[
-                Literal["field"],
-                Literal["id", "batchIndex", "from", "signerAddress", "smartAccountAddress", "chainId"],
-            ]
-            | dict[Literal["values"], list[int]]
-            | dict[Literal["operator"], Literal["AND", "OR"]]
-        ],
+        list[FilterCondition],
         "List of filter conditions to apply",
     ],
     # Rest of the method remains unchanged
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9fe000a and 12d90ab.

📒 Files selected for processing (4)
  • python/thirdweb-ai/README.md (3 hunks)
  • python/thirdweb-ai/src/thirdweb_ai/adapters/google_adk/__init__.py (1 hunks)
  • python/thirdweb-ai/src/thirdweb_ai/services/__init__.py (1 hunks)
  • python/thirdweb-ai/src/thirdweb_ai/services/engine_cloud.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
python/thirdweb-ai/src/thirdweb_ai/adapters/google_adk/__init__.py (1)
python/thirdweb-ai/src/thirdweb_ai/adapters/google_adk/google_adk.py (1)
  • get_google_adk_tools (64-73)
🪛 Ruff (0.11.9)
python/thirdweb-ai/src/thirdweb_ai/services/__init__.py

8-8: No newline at end of file

Add trailing newline

(W292)

🔇 Additional comments (12)
python/thirdweb-ai/src/thirdweb_ai/adapters/google_adk/__init__.py (1)

1-3: Well-structured module initialization.

Clean implementation that clearly defines the module's public API by importing and explicitly exporting the get_google_adk_tools function. This follows Python best practices for package structure.

python/thirdweb-ai/README.md (4)

52-53: Good addition of the new service to the import statement.

The addition of EngineCloud to the import statement clearly shows users how to access the new service.


58-59: Clear documentation for authentication requirements.

The note about vault_access_token being required for server wallet operations provides important information for users to properly initialize the service.


68-69: Good inclusion of Engine Cloud tools with helpful comment.

The addition of engine_cloud.get_tools() with a descriptive comment helps users understand when to use this service.


74-83: Well-structured documentation of available services.

The new "Available Services" section provides a clear and concise overview of all the core services, including the new EngineCloud service. The description effectively communicates the purpose and capabilities of each service.

python/thirdweb-ai/src/thirdweb_ai/services/engine_cloud.py (7)

7-21: Well-implemented authentication handling.

The class properly extends the base Service class and implements custom header handling for the vault access token. The implementation follows the Open/Closed principle by extending the parent class's behavior rather than modifying it.


22-34: Good implementation of server wallet creation.

The create_server_wallet method is well-documented and properly implements the API endpoint for creating a new server wallet with KMS integration.


35-70: Well-documented contract interaction method.

The write_contract method is thoroughly documented with clear parameter annotations explaining each field's purpose. The payload construction is properly structured for the API endpoint.


71-109: Well-implemented transaction sending method.

The send_transaction method handles low-level transactions with appropriate parameter validation and documentation. The payload structure follows the API requirements.


110-149: Comprehensive contract reading implementation.

The read_contract method provides a flexible interface for read-only contract calls with support for multicall batching. All parameters are well-documented with clear type annotations.


150-167: Simple and effective balance query method.

The get_native_balance method provides a straightforward way to query native cryptocurrency balances with minimal required parameters.


1-214:

❌ Incorrect review comment

Consider adding error handling for API responses.

While the implementation is solid, there's no explicit error handling for the API responses. Consider adding try/except blocks or documenting the error handling approach.

You could add a helper method to handle errors consistently:

def _handle_api_response(self, response: dict[str, Any]) -> dict[str, Any]:
    """Process API response and handle errors consistently."""
    if "error" in response:
        # Extract error details and raise appropriate exception
        error_message = response.get("error", {}).get("message", "Unknown error")
        error_code = response.get("error", {}).get("code", "unknown")
        raise ValueError(f"API Error ({error_code}): {error_message}")
    return response

Then update your methods to use this helper:

def create_server_wallet(self, label: Annotated[str, "A human-readable label to identify this wallet."]) -> dict[str, Any]:
    payload = {"label": label}
    response = self._post("accounts", payload)
    return self._handle_api_response(response)

🏁 Script executed:

#!/bin/bash
# Look for error handling in the parent Service class
echo "Checking for error handling in Service class"
rg -A 5 "_post" | grep -A 10 "def _post"

Length of output: 1763


🏁 Script executed:

#!/bin/bash
# Display the full implementation of Service._post to check for built-in error handling
rg -A 50 "def _post" python/thirdweb-ai/src/thirdweb_ai/services/service.py

Length of output: 845


Service._post already handles HTTP errors
The Service._post implementation invokes response.raise_for_status(), so any non-2xx response will raise an HTTPError before you call response.json(). You’ll get built-in error handling for HTTP failures. If you need to standardize or enrich error messages (e.g. wrap HTTPError or inspect JSON error bodies on 2xx), you could extend or wrap _post, but the basic error-raising is already in place.

Likely an incorrect or invalid review comment.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
python/thirdweb-ai/src/thirdweb_ai/adapters/google_adk/google_adk.py (1)

43-65: Good fix: Prevent schema mutation with deep copy and recursive cleaning.

The changes correctly fix potential side effects by:

  1. Deep copying the parameters to avoid modifying the original schema
  2. Implementing a recursive helper to clean nested dictionaries

This is a much safer approach than modifying the original schema.

I suggest some style improvements to make the code cleaner:

-        # Deep copy the parameters to avoid modifying the original
+        # Deep copy the parameters to avoid modifying the original schema
         import copy
         parameters = copy.deepcopy(self.tool.schema["parameters"])
-        
         if "additionalProperties" in parameters:
-            del parameters["additionalProperties"]
+            parameters.pop("additionalProperties")
-        
         def remove_additional_properties(obj: dict[str, Any]):
             if "additionalProperties" in obj:
-                del obj["additionalProperties"]
+                obj.pop("additionalProperties")
-                
             if "items" in obj and isinstance(obj["items"], dict):
                 remove_additional_properties(obj["items"])
-            
             if "properties" in obj and isinstance(obj["properties"], dict):
                 for prop in obj["properties"].values():
                     if isinstance(prop, dict):
                         remove_additional_properties(prop)
-        
         if "properties" in parameters:
             for prop in parameters["properties"].values():
                 remove_additional_properties(prop)
-        
🧰 Tools
🪛 Ruff (0.11.9)

46-46: Blank line contains whitespace

Remove whitespace from blank line

(W293)


49-49: Blank line contains whitespace

Remove whitespace from blank line

(W293)


52-52: Use pop instead of key in dict followed by del dict[key]

Replace if statement with .pop(..., None)

(RUF051)


53-53: Blank line contains whitespace

Remove whitespace from blank line

(W293)


56-56: Blank line contains whitespace

Remove whitespace from blank line

(W293)


61-61: Blank line contains whitespace

Remove whitespace from blank line

(W293)


65-65: Blank line contains whitespace

Remove whitespace from blank line

(W293)

python/thirdweb-mcp/README.md (1)

83-84: Fix URL formatting in documentation.

The environment variables section has been properly updated, but there's a markdown formatting issue with the bare URL.

-- `THIRDWEB_ENGINE_CLOUD_URL`: URL endpoint for EngineCloud service (defaults to https://engine.thirdweb.com/v1)
+- `THIRDWEB_ENGINE_CLOUD_URL`: URL endpoint for EngineCloud service (defaults to `https://engine.thirdweb.com/v1`)
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

83-83: Bare URL used
null

(MD034, no-bare-urls)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 12d90ab and 1c4d403.

📒 Files selected for processing (5)
  • README.md (6 hunks)
  • python/thirdweb-ai/src/thirdweb_ai/adapters/google_adk/google_adk.py (1 hunks)
  • python/thirdweb-ai/src/thirdweb_ai/services/engine_cloud.py (1 hunks)
  • python/thirdweb-mcp/README.md (7 hunks)
  • python/thirdweb-mcp/src/mcp.py (5 hunks)
✅ Files skipped from review due to trivial changes (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • python/thirdweb-ai/src/thirdweb_ai/services/engine_cloud.py
🧰 Additional context used
🪛 Ruff (0.11.9)
python/thirdweb-ai/src/thirdweb_ai/adapters/google_adk/google_adk.py

46-46: Blank line contains whitespace

Remove whitespace from blank line

(W293)


49-49: Blank line contains whitespace

Remove whitespace from blank line

(W293)


52-52: Use pop instead of key in dict followed by del dict[key]

Replace if statement with .pop(..., None)

(RUF051)


53-53: Blank line contains whitespace

Remove whitespace from blank line

(W293)


56-56: Blank line contains whitespace

Remove whitespace from blank line

(W293)


61-61: Blank line contains whitespace

Remove whitespace from blank line

(W293)


65-65: Blank line contains whitespace

Remove whitespace from blank line

(W293)

🪛 markdownlint-cli2 (0.17.2)
python/thirdweb-mcp/README.md

83-83: Bare URL used
null

(MD034, no-bare-urls)

🔇 Additional comments (10)
python/thirdweb-mcp/src/mcp.py (5)

4-4: LGTM: Import statement properly updated.

The import statement has been correctly updated to include the new EngineCloud service alongside other existing services.


57-68: CLI options well-defined for EngineCloud configuration.

The added CLI options follow the established pattern in the codebase:

  • --engine-cloud-url with a sensible default URL
  • --vault-access-token for authentication

Both options properly fall back to environment variables, maintaining consistency with other service configurations.


77-78: LGTM: Function signature properly extended.

The main function signature has been correctly updated to include the new parameters, using appropriate typing with str and str | None.


87-87: LGTM: Service registration properly updated.

The engine_cloud service is correctly added to the list of enabled services when a secret key is provided, following the pattern used for other services.


119-126: LGTM: EngineCloud service correctly initialized and registered.

The EngineCloud service initialization follows the established pattern:

  1. Check if the service is enabled
  2. Create an instance with the appropriate configuration
  3. Register the service tools with the MCP server

The implementation is clean and consistent with how other services are handled.

python/thirdweb-mcp/README.md (5)

12-12: LGTM: EngineCloud added to overview.

The EngineCloud service is properly added to the overview section with a clear, concise description of its capabilities.


49-52: LGTM: Configuration requirements updated.

Configuration requirements have been properly updated to include EngineCloud with the required thirdweb Secret Key and Vault Access Token.


71-72: LGTM: Command-line example updated.

The command-line example has been extended to include the new vault-access-token parameter, maintaining the established format.


108-109: LGTM: Claude Desktop integration instructions updated.

The Claude Desktop integration instructions have been properly updated to include the new vault access token environment variable.


151-158: LGTM: EngineCloud service documentation added.

A comprehensive section has been added for the EngineCloud service, clearly describing its capabilities:

  • Server wallet management with KMS integration
  • Smart contract interactions
  • Transaction management
  • Native token balance checks

The documentation is concise and consistent with other service descriptions.

@cjber cjber merged commit a41112d into main May 21, 2025
3 checks passed
@cjber cjber deleted the cb/engine-cloud branch May 21, 2025 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant