Skill: lion504/gemini-deep-research-1-0-0 (version 1.0.0)

--- name: gemini-deep-research description: Perform complex, long-running research tasks using Gemini Deep Research Agent. Use when asked to research topics requiring multi-source synthesis, competitive analysis, market research, or comprehensive technical investigations that benefit from systematic web search and analysis. metadata: {"clawdbot":{"emoji":"🔬","requires":{"env":["GEMINI_API_KEY"]},"primaryEnv":"GEMINI_API_KEY"}} --- # Gemini Deep Research Use Gemini's Deep Research Agent to perform complex, long-running context gathering and synthesis tasks. ## Prerequisites - `GEMINI_API_KEY` environment variable (from Google AI Studio) - **Note**: This does NOT work with Antigravity OAuth tokens. Requires a direct Gemini API key. ## How It Works Deep Research is an agent that: 1. Breaks down complex queries into sub-questions 2. Searches the web systematically 3. Synthesizes findings into comprehensive reports 4. Provides streaming progress updates ## Usage ### Basic Research ```bash scripts/deep_research.py --query "Research the history of Google TPUs" ``` ### Custom Output Format ```bash scripts/deep_research.py --query "Research the competitive landscape of EV batteries" \ --format "1. Executive Summary\n2. Key Players (include data table)\n3. Supply Chain Risks" ``` ### With File Search (optional) ```bash scripts/deep_research.py --query "Compare our 2025 fiscal year report against current public web news" \ --file-search-store "fileSearchStores/my-store-name" ``` ### Stream Progress ```bash scripts/deep_research.py --query "Your research topic" --stream ``` ## Output The script saves results to timestamped files: - `deep-research-YYYY-MM-DD-HH-MM-SS.md` - Final report in markdown - `deep-research-YYYY-MM-DD-HH-MM-SS.json` - Full interaction metadata ## API Details - **Endpoint**: `https://generativelanguage.googleapis.com/v1beta/interactions` - **Agent**: [REDACTED_SECRET] - **Auth**: `x-goog-api-key` header (NOT OAuth Bearer token) ## Limitations - Requires Gemini API key (get from [Google AI Studio](https://aistudio.google.com/apikey)) - Does NOT work with Antigravity OAuth authentication - Long-running tasks (minutes to hours depending on complexity) - May incur API costs depending on your quota

path: _meta.json
content: ownerId: kn7azq5e6sw0fbwwzdpcwvvjzd7z0x4z
slug: gemini-deep-research
version: 1.0.0
publishedAt: 1768845281114

path: scripts/deep_research.py
content: #!/usr/bin/env python3
"""
Gemini Deep Research API client
Performs complex, long-running research tasks via Gemini's Deep Research Agent
"""

import argparse
import json
import os
import sys
import time
from datetime import datetime
from pathlib import Path
import requests

API_BASE = "https://generativelanguage.googleapis.com/v1beta"
AGENT_MODEL = "deep-research-pro-preview-12-2025"


def create_interaction(api_key, query, output_format=None, file_search_store=None):
    """Start a new deep research interaction"""
    headers = {
        "Content-Type": "application/json",
        "x-goog-api-key": api_key
    }
    
    payload = {
        "input": query,
        "agent": AGENT_MODEL,
        "background": True
    }
    
    if output_format:
        payload["input"] = f"{query}\n\nFormat the output as follows:\n{output_format}"
    
    if file_search_store:
        payload["tools"] = [{
            "type": "file_search",
            "file_search_store_names": [file_search_store]
        }]
    
    response = requests.post(
        f"{API_BASE}/interactions",
        headers=headers,
        json=payload
    )
    
    if response.status_code != 200:
        print(f"Error creating interaction: {response.status_code}", file=sys.stderr)
        print(response.text, file=sys.stderr)
        sys.exit(1)
    
    return response.json()


def poll_interaction(api_key, interaction_id, stream=False):
    """Poll for interaction updates"""
    headers = {
        "x-goog-api-key": api_key
    }
    
    while True:
        response = requests.get(
            f"{API_BASE}/interactions/{interaction_id}",
            headers=headers
        )
        
        if response.status_code != 200:
            print(f"Error polling interaction: {response.status_code}", file=sys.stderr)
            print(response.text, file=sys.stderr)
            sys.exit(1)
        
        data = response.json()
        status = data.get("status", "UNKNOWN")
        
        if stream:
            # Show progress updates
            if "statusMessage" in data:
                print(f"[{status}] {data['statusMessage']}", file=sys.stderr)
        
        if status == "completed":
            return data
        elif status == "failed":
            print(f"Research failed: {data.get('error', 'Unknown error')}", file=sys.stderr)
            sys.exit(1)
        
        time.sleep(10)  # Poll every 10 seconds


def extract_report(interaction_data):
    """Extract the final report from interaction data"""
    if "output" in interaction_data:
        output = interaction_data["output"]
        if isinstance(output, dict) and "text" in output:
            return output["text"]
        elif isinstance(output, str):
            return output
    
    # Fallback: look in messages
    messages = interaction_data.get("messages", [])
    for msg in reversed(messages):
        if msg.get("role") == "model" and "parts" in msg:
            for part in msg["parts"]:
                if "text" in part:
                    return part["text"]
    
    return None


def main():
    parser = argparse.ArgumentParser(description="Gemini Deep Research API Client")
    parser.add_argument("--query", required=True, help="Research query")
    parser.add_argument("--format", help="Custom output format instructions")
    parser.add_argument("--file-search-store", help="File search store name (optional)")
    parser.add_argument("--stream", action="store_true", help="Show streaming progress updates")
    parser.add_argument("--output-dir", default=".", help="Output directory for results")
    parser.add_argument("--api-key", help="Gemini API key (overrides GEMINI_API_KEY env var)")
    
    args = parser.parse_args()
    
    # Get API key
    [REDACTED_SECRET] or os.environ.get("GEMINI_API_KEY")
    if not [REDACTED_SECRET]"Error: No API key provided.", file=sys.stderr)
        print("Please either:", file=sys.stderr)
        print("  1. Provide --api-key argument", file=sys.stderr)
        print("  2. Set GEMINI_API_KEY environment variable", file=sys.stderr)
        sys.exit(1)
    
    # Start research
    print(f"Starting deep research: {args.query}", file=sys.stderr)
    interaction = create_interaction(
        api_key,
        args.query,
        output_format=args.format,
        file_search_store=args.file_search_store
    )
    
    interaction_id = interaction.get("id")
    if not interaction_id:
        print(f"Error: No interaction ID in response: {interaction}", file=sys.stderr)
        sys.exit(1)
    print(f"Interaction started: {interaction_id}", file=sys.stderr)
    
    # Poll for completion
    print("Polling for results (this may take several minutes)...", file=sys.stderr)
    result = poll_interaction(api_key, interaction_id, stream=args.stream)
    
    # Extract report
    report = extract_report(result)
    
    if not report:
        print("Warning: Could not extract report text from response", file=sys.stderr)
        report = json.dumps(result, indent=2)
    
    # Save results
    timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
    output_dir = Path(args.output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)
    
    md_path = output_dir / f"deep-research-{timestamp}.md"
    json_path = output_dir / f"deep-research-{timestamp}.json"
    
    md_path.write_text(report)
    json_path.write_text(json.dumps(result, indent=2))
    
    print(f"\nResearch complete!", file=sys.stderr)
    print(f"Report saved: {md_path}", file=sys.stderr)
    print(f"Full data saved: {json_path}", file=sys.stderr)
    
    # Print report to stdout
    print(report)


if __name__ == "__main__":
    main()


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)