Repository navigation
Add an alert investigation example with VirusTotal MCP - #1426
bernardoquintero wants to merge 3 commits into
Conversation
|
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a comprehensive example for performing security alert investigations using the Gemini API's Antigravity managed agent and VirusTotal MCP. The provided notebook showcases best practices for interacting with remote tools, managing background interactions, and validating model-generated claims against raw tool output. It emphasizes secure handling of credentials and lifecycle management for sandbox environments. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request adds a new Jupyter notebook, Alert_investigation_with_VirusTotal_MCP.ipynb, demonstrating how to use the Gemini API's Antigravity managed agent to investigate security alerts via a remote VirusTotal MCP server, and registers it in the examples README. Feedback recommends installing the SDK using the -U flag and >= operator to align with the repository style guide, and refactoring the custom SingleCreateClient to prevent bypassing the SDK's built-in error handling and prematurely blocking retries on transient failures.
| }, | ||
| "outputs": [], | ||
| "source": [ | ||
| "%pip install -q \"google-genai==2.30.1\"" |
There was a problem hiding this comment.
According to the repository style guide (line 25), the correct way to install the SDK is using >= with -U to specify the minimum required version rather than pinning a specific version with ==. This ensures users receive subsequent bug fixes and updates of the SDK while maintaining compatibility.
%pip install -U -q "google-genai>=2.30.1"References
- The correct and most recent SDK is the Python genai one. '%pip install -U -q 'google-genai>=2.9.0'' is the right way to install the SDK. The version indicated should reflect the minimum version needed to use the features used in the notebook. (link)
| "class RequestFailed(RuntimeError):\n", | ||
| "\n", | ||
| " def __init__(self, status_code):\n", | ||
| " self.status_code = status_code\n", | ||
| " super().__init__(f\"HTTP {status_code}; request not retried.\")\n", | ||
| "\n", | ||
| "\n", | ||
| "class SingleCreateClient(httpx.Client):\n", | ||
| " create_sent = False\n", | ||
| "\n", | ||
| " def send(self, request, **kwargs):\n", | ||
| " if request.method == \"POST\" and request.url.path.endswith(\"/interactions\"):\n", | ||
| " if self.create_sent:\n", | ||
| " raise RuntimeError(\"Create already attempted; recover by interaction ID.\")\n", | ||
| " self.create_sent = True\n", | ||
| " response = super().send(request, **kwargs)\n", | ||
| " if response.is_error:\n", | ||
| " status_code = response.status_code\n", | ||
| " response.close()\n", | ||
| " raise RequestFailed(status_code)\n", | ||
| " return response\n", |
There was a problem hiding this comment.
By raising RequestFailed and closing the response on any HTTP error, the custom client bypasses the google-genai SDK's built-in error handling and parsing. This hides the detailed error payload returned by the Gemini API (such as invalid API key, quota exceeded, or bad request details), making debugging extremely difficult.
Additionally, setting create_sent = True before the request is sent means that if the request fails (e.g., due to a transient network issue or configuration error), the user is permanently blocked from retrying without restarting the kernel or re-running the client definition cell.
We can simplify the client to only mark create_sent = True upon a successful POST response, and let the SDK handle error responses normally so that detailed API error messages are preserved:
class SingleCreateClient(httpx.Client):
create_sent = False
def send(self, request, **kwargs):
if request.method == "POST" and request.url.path.endswith("/interactions"):
if self.create_sent:
raise RuntimeError("Create already attempted; recover by interaction ID.")
response = super().send(request, **kwargs)
if request.method == "POST" and request.url.path.endswith("/interactions") and response.is_success:
self.create_sent = True
return responseNote that the RequestFailed class can be completely removed with this approach.
Demonstrates alert investigation with the Antigravity managed agent, the Interactions API and VirusTotal MCP. The example restricts access to one domain-report tool, checks generated evidence against the actual tool result, and separates facts, inference and unresolved questions.
It uses Colab Secrets, records the interaction ID for recovery, prevents duplicate creation, and cleans up its own sandbox. It also documents credential revocation and clearing outputs before sharing, and adds the notebook to the examples index.
Validation:
The Colab install reported a dependency conflict: google-colab pins google-auth 2.49.0, while google-genai 2.30.1 requires >=2.56.0,<3.0.0. The tested Colab Secrets and notebook flow completed with google-auth 2.62.0; other Colab features were not tested.
Run the tested notebook in Colab.
Related to #1404.