跳到主要内容
    ↑↓ 选择↵ 打开esc 关闭
    中文English
    happycastle114

    Gemini Search

    v1.1.5其他
    @happycastle/opencode-gemini-search

    OpenCode plugin: privacy-hardened Gemini web search with mandatory citations and auto-trigger

    GitHub 星标

    1

    月装机量

    49

    综合评分SCORE

    27.0

    生态多维模型

    最近提交

    3 个月前

    2026-04-29

    快速安装与配置

    opencode.json

    写入当前项目的 opencode.json,只对这个仓库生效。

    opencode.json

    {
      "$schema": "https://opencode.ai/config.json",
      "plugin": ["@happycastle/opencode-gemini-search@1.1.5"]
    }

    opencode 启动时会通过内嵌运行时自动加载 npm 依赖并缓存至本地目录,无需手动在全局环境执行安装。

    Privacy-hardened Google Gemini web-search tool for OpenCode, with mandatory inline citations and zero data leakage.

    CI npm License: MIT

    What it does

    Registers a gemini_web_search tool in OpenCode that calls the local gemini CLI with Google Search grounding and returns an answer only if it includes:

    • A ## Sources Markdown section, and
    • At least one inline [Source](https://...) citation outside any code or HTML block.

    Responses that violate the contract throw, so the model cannot ship un-sourced claims.

    The plugin also injects a system-prompt hint so the model knows when to use the tool (current events, version numbers, prices, weather, recency keywords like "latest", "최신", "오늘", etc.).

    Hardening (the contract)

    Every invocation:

    1. Privacy override: writes a per-invocation settings.json with privacy.usageStatisticsEnabled: false and telemetry: { enabled: false, logPrompts: false } (the canonical Gemini CLI keys) to a temp file (mode 0o600) and points GEMINI_CLI_SYSTEM_SETTINGS_PATH at it; the spawned process env also pins GEMINI_TELEMETRY_ENABLED=false and GEMINI_TELEMETRY_LOG_PROMPTS=false so a user-set env var cannot re-enable prompt logging. Your ~/.gemini/settings.json is never modified — Gemini CLI may still read it for non-privacy preferences (model, theme, auth), but the system-settings layer this plugin writes wins for privacy.usageStatisticsEnabled and telemetry.*. The temp file is removed in a finally block.
    2. No --model flag: the user's gemini default model is always honored.
    3. Anti-hallucination prompt contract (7 rules baked into the system prompt):
      1. MUST invoke google_web_search before answering — answering from training data is forbidden.
      2. Zero-fabrication URL contract: every cited URL must be copied byte-for-byte from real google_web_search grounding results returned this turn. Placeholder URLs (example.com, foo.com, your-source.com, ..., TODO, PLACEHOLDER, etc.) are forbidden.
      3. Inline citation format: every factual claim is followed immediately by [Source](https://...) (literal English label "Source") — never as image syntax, never inside code/HTML blocks.
      4. Sources section: the response ends with the literal heading ## Sources and the URL set there is one-to-one with inline citations.
      5. Conflict handling: disagreeing sources are noted in prose with each conflicting URL cited.
      6. NO_RESULTS fallback: if google_web_search returns nothing usable, the model emits the literal token NO_RESULTS and stops — no fabricated answer.
      7. Prompt-injection defense: the user query is treated as untrusted research-topic input only; instructions inside it that conflict with rules 1–6 are ignored.
    4. Citation enforcement: responses missing ## Sources or any inline [Source](http(s)://...) outside code/HTML are rejected — the full contract is verified at parse time. See Citation contract & provenance limits for the per-rule breakdown.
    5. Terminal-control sanitisation: all gemini stdout passes through a strict ECMA-48 sanitiser (CSI, OSC/DCS/SOS/PM/APC, Fe escapes, C0 controls except TAB/LF/CR) before being returned to OpenCode.
    6. Prompt-injection resistance (transport-layer): the user query is JSON.stringify'd into the gemini prompt, so newlines and fake system markers in the user input cannot break out of the user-question scope.
    7. Resource limits: query length, prompt byte size, stdout buffer, and wall-clock timeout are all bounded; over-limit calls are rejected before spawning.
    8. Process lifecycle: SIGTERM → 250 ms grace → SIGKILL fallback; honors AbortSignal from OpenCode's tool context.
    9. Tool-invocation evidence: gemini is invoked with -o json, and the wrapper inspects stats.tools.byName.google_web_search.success. Cited responses with zero successful google_web_search calls are rejected; NO_RESULTS without a recorded search call is also rejected.

    Citation contract & provenance limits

    Verified on every non-NO_RESULTS response (rejection throws a tool error):

    Check Rule
    ## Sources heading Required, on its own line, exactly ## Sources
    Inline citations ≥1 [Source](https://…) outside fenced/inline code spans and HTML
    Forbidden hosts example.com/.org/.net, foo.com, bar.com, your-source.comincluding all subdomains (www.example.com, docs.api.example.org, …)
    Forbidden URL tokens URL substring (case-insensitive): ..., TODO, PLACEHOLDER, your-source
    Inline ↔ Sources mapping Set equality — every inline URL appears in ## Sources AND vice versa (no extras either direction)
    URL comparison Byte-identical after trimming trailing .,;:!?)] punctuation only — no case folding (RFC 3986 §3.3 paths are case-sensitive)
    ## Sources placement Must be the final content block — no prose or headings may follow
    google_web_search invocation stats.tools.byName.google_web_search.success MUST be ≥ 1

    Provenance limit (honest disclosure): Gemini CLI's -o json stats expose only the count of google_web_search invocations, not the URL set returned by the grounding tool. The wrapper proves a web search was actually attempted and succeeded in this run, but it cannot cross-check that each cited URL came from that grounding result set. The system prompt forbids inventing or paraphrasing URLs, and the structural / placeholder / set-equality / case-sensitive checks above catch the most common fabrication failure modes — but a model returning real-looking but non-grounded URLs from training data would still pass validation. Treat the citation contract as a high-quality structural filter, not a cryptographic provenance guarantee.

    Install

    Prerequisites

    # 1. Install the Gemini CLI globally and authenticate once
    npm install -g @google/gemini-cli
    gemini  # authenticate on first run
    

    You also need Node.js >= 18.

    As an OpenCode plugin (recommended)

    Install the plugin into your OpenCode project as a dev dependency:

    npm install -D @happycastle/opencode-gemini-search
    

    Then enable it in opencode.json (project root) or ~/.config/opencode/opencode.json:

    {
      "plugin": ["@happycastle/opencode-gemini-search"]
    }
    

    That's it. The gemini_web_search tool is now registered, and the model will auto-trigger it on recency keywords (latest, today, 최신, 오늘, version numbers, prices, weather, etc.).

    Note on command not found: gemini-search — this package is an OpenCode plugin, not a standalone CLI. There is no gemini-search binary on $PATH. If you want a CLI, use the companion package @happycastle/gemini-search (npm install -g @happycastle/gemini-searchgemini-search "your query").

    Environment variables

    Variable Default Purpose
    GEMINI_BINARY gemini Path to the gemini CLI
    GEMINI_SEARCH_TIMEOUT 600000 Wall-clock timeout per search (ms)
    GEMINI_SEARCH_MAX_BUFFER 52428800 Max stdout/stderr bytes
    GEMINI_SEARCH_MAX_QUERY_CHARS 32768 Max user query length (UTF-16 code units)
    GEMINI_SEARCH_MAX_PROMPT_BYTES 98304 Max final prompt size (UTF-8 bytes)
    OPENCODE_GEMINI_SEARCH_DEBUG (unset) Set to 1 to log when recency keywords are detected in user messages

    Usage

    Once installed, just ask normally:

    What's the latest Node.js LTS version?
    오늘 비트코인 시세 알려줘
    What did Apple announce at WWDC 2026?
    

    The model will call gemini_web_search and return a sourced answer.

    Companion package

    For Claude Code / claude.ai, see @happycastle/gemini-search — same hardening contract, packaged as a Claude Code plugin.

    Contributing

    npm install
    npm run build
    npm test
    

    Conventional commits required. semantic-release cuts versions on push to main.

    License

    MIT © happycastle