omp packages

pi-deepseek-search-tools0.1.1

DeepSeek Search & Fetch for Pi: deepseek_search for live web results via the official POST /v1/tools/search API and deepseek_fetch for full-page Markdown via POST /v1/tools/fetch. Requires a DeepSeek API key (DEEPSEEK_API_KEY or /deepseek-setup).

ethan_szu Published 7 days ago MIT ~535 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-deepseek-search-tools

pi-deepseek-search-tools is a Pi Coding Agent extension with two direct tools backed by the official DeepSeek Search & Fetch API:

POST https://api.deepseek.com/v1/tools/search   (structured web results)
POST https://api.deepseek.com/v1/tools/fetch    (full-page Markdown)
  • deepseek_search — one query per call, returning ranked titles, exact URLs, per-item site/date/authority/rerank metadata, and bounded snippets/summaries.
  • deepseek_fetch — one HTTP/HTTPS URL per call, returning the page title and clean Markdown.

Use it proactively when an answer depends on current or externally verifiable information: documentation, news, prices, products, papers, comparisons, fact-checking. It is not a replacement for Pi's local file or shell tools.

中文说明:这是一个面向 Pi Coding Agent 的 DeepSeek 联网搜索扩展,只使用官方 Search/Fetch API(POST /v1/tools/search 与 POST /v1/tools/fetch)。必须配置 DeepSeek API key(无匿名模式):export DEEPSEEK_API_KEY=sk-... 或在 Pi 内运行 /deepseek-setup。

Core capabilities

  • General web search as bounded Markdown (≤12,000 chars per call; snippets ≤500 chars, summaries ≤1,000 chars, optional content ≤2,000 chars per result — use deepseek_fetch for full pages).
  • Only the official Search request fields are exposed: query, count (1–50, default 10), ori_question, localization, need_content. There are no domain/sub_domain/batch parameters — they do not exist in the DeepSeek Search API.
  • DeepSeek query operators pass through in query: site:/-site:, leading -, "quoted phrases", lang:xx,yy, after:/before: (year or full date).
  • Result metadata (site_name, date, authority 0–4, rerank_score 0–3) is rendered per item so the model can weigh source quality; URL-less items are never given a fabricated citation.
  • Duplicate results are removed before rendering (normalized URL match, or near-identical title via character-bigram similarity ≥0.85).
  • deepseek_fetch returns **Source** + title + Markdown body, capped at 50,000 characters. The vendor's backslash-escaped ASCII punctuation (\#, \., \[, \|…) is unescaped back to real Markdown.
  • Local bounded reading for fetched pages: offset/limit/find_text/refresh over a five-minute in-memory session cache (16 entries, ~1M chars). These parameters never leave the plugin.
  • Compact Pi TUI rendering (collapsed by default, expandable).

Requirements

A DeepSeek API key is required — the API has no anonymous mode and returns HTTP 401 without one.

Installation

From a checkout of this repository:

# Load the extension for the current Pi invocation only
pi -e .

# Install the local directory as a Pi package
pi install .

API key configuration

Configuration priority is:

DEEPSEEK_API_KEY environment variable
> <agent dir>/deepseek.json    (deepseekApiKey | deepseek_api_key | apiKey)
> <agent dir>/settings.json    (deepseekApiKey | deepseek_api_key)
> <agent dir>/auth.json        (deepseek.key when type is "api_key")

Set the environment variable in your shell or CI environment:

export DEEPSEEK_API_KEY="sk-..."

Or create ~/.pi/agent/deepseek.json:

{
  "deepseekApiKey": "sk-..."
}

~/.pi/agent is Pi's default agent directory. If PI_CODING_AGENT_DIR is set, the extension reads the config files from that directory instead. Config files are only read — except deepseek.json, which /deepseek-setup writes with your confirmation.

Pi commands

/deepseek-setup

Opens an interactive prompt and saves the key to <agent dir>/deepseek.json. The new key is used by subsequent calls without restarting Pi, unless a non-empty DEEPSEEK_API_KEY remains set; the environment variable always takes precedence.

/deepseek-status

Shows the configuration path and reports only 已配置 (configured) or 未配置 (not configured). It does not display the key or a key prefix.

postinstall behavior

The npm package includes a postinstall script:

  • In an interactive terminal, it may ask for an API key when none is configured. Press Enter to skip.
  • In a non-interactive installation, it prints setup guidance; installation still succeeds.
  • If npm lifecycle scripts are disabled (npm install --ignore-scripts), the script does not run.

Tool reference

deepseek_search

Parameter Type Required Description
query string Yes One search intent, 1–128 characters, not all whitespace. Query operators pass through: site:, -site:, -term, -"phrase", "phrase", lang:, after:, before:.
count integer No Results to return, 1–50; the API default is 10.
ori_question string No The user's original question (1–128 chars) to improve query understanding.
localization string No An IP address used to localize results.
need_content boolean No Return each result's page content (bounded to 2,000 chars/item locally). Default false.
{"query": "DeepSeek V4 release notes", "count": 5}
{"query": "DeepSeek site:github.com OR site:huggingface.co lang:en after:2026", "count": 10}

deepseek_fetch

Parameter Type Required Description
url string Yes http:// or https:// URL with a host, no embedded username/password, at most 8,192 characters.

Optional local reading parameters (never sent to the DeepSeek API):

Parameter Description
offset Non-negative UTF-16 code-unit position in the complete fetched text, including Source/title.
limit Fragment size, 1–50,000 characters; default 6,000 for enhanced reads.
find_text First exact, case-sensitive literal match with nearby context. Cannot be combined with offset.
refresh Fetch again instead of reusing the five-minute session cache.
{"url": "https://example.com/article", "find_text": "Attention", "limit": 4000}

Enhanced results report source URL, fetch time, cache hit, original-text range, next offset, and explicit no_match/end_of_text status.

Returned results

Search returns ## Search Results (n results) followed by numbered items carrying the exact title/url pair, a **Meta** line (site_name · date · authority · rerank score), and the summary (falling back to snippet). With need_content: true, a bounded **Content** block is appended per item. A search with no matches returns (0 results).

Fetch returns **Source**: <url> followed by ## <title> and the page content as Markdown.

Each tool result carries structured details: isError, auth mode (configured/unconfigured), requestId when upstream provides one, and fetch reading metadata. Details never contain the API key.

Errors propagate as tool errors: DeepSeek API error <status>: <message> parsed from the OpenAI-compatible error envelope, with credential-shaped strings redacted. Per the official guide, HTTP 408/429/5xx responses and connection-level transport failures are retried once after a 300 ms backoff (honoring Retry-After up to 2 s); other 4xx responses are never retried. Cancellations and timeouts propagate via AbortSignal.

Security

  • Never commit API keys to Git, source files, examples, or issue reports.
  • Error text is sanitized before surfacing: sk-… tokens and Bearer headers are redacted, and HTTP 402 balance errors are replaced with a fixed message instead of echoing upstream text.
  • The fetch URL contract is enforced locally before any network call: http/https only, a host is required, embedded credentials are rejected, and the 8,192-character limit applies. Fetch requests go only to https://api.deepseek.com — target content is fetched server-side by DeepSeek.
  • The configuration file stores the key locally as plain JSON; protect access to your Pi agent directory.
  • Pi extensions execute with the user's permissions. Review the source before installation.
  • This extension makes network requests to https://api.deepseek.com/v1/tools/search and https://api.deepseek.com/v1/tools/fetch only when one of the tools is called. It does not make a network request merely by loading the extension.

Coexisting with pi-anysearch

This package registers only deepseek_search and deepseek_fetch, so it does not collide with anysearch/anysearch_extract or other search tools. Use deepseek_search when you want DeepSeek's in-house index (notably strong Chinese-language coverage); keep anysearch for anonymous fallback and vertical domains.

Development and verification

npm install --ignore-scripts
npm test
DEEPSEEK_API_KEY=sk-... npm run test:e2e   # real endpoints; key required
# Preserve previous evidence: choose a directory that does not exist
DEEPSEEK_E2E_OUTPUT_DIR=.evidence/e2e-NEW npm run test:e2e

npm test runs the deterministic mocked-fetch suite; real network checks are explicit so credentials, balance, and connectivity cannot make the default test command flaky:

  • test/deepseek.test.ts — mocked-fetch coverage for tool registration and schema surface (official fields only), request assembly, response field parsing, bounded Markdown rendering, deduplication, error-envelope propagation with credential redaction, retry classification (transport codes, 408/429/5xx, Retry-After), URL validation, Markdown unescaping, fetch-reader cache/paging/find behavior, and the key-resolution order.
  • test/e2e.test.ts — real-endpoint checks for a stable-fact search, tool-level execution, example.com fetch with unescaped-Markdown verification, fetch-reader caching, fault injection (one synthetic transport failure retried against the live service), and a deliberately invalid key proving 401 surfaces as a failure rather than a skip. Each passing scenario stores redacted raw evidence under .evidence/; unreachable networks are skipped with an explicit reason — credential and HTTP business errors always fail.

For a temporary local Pi run:

pi -e .

Links

License

MIT, as declared in package.json.