Files
deepseek-harness/packages/web/web-search-perplexity
Tianyi Cui ecb8aa5b8e Add a gated Known Limitations and Deferred Work section to every package README
Every packages/*/* README now carries a canonical '## Known Limitations and
Deferred Work' section: condensed, evidence-backed bullets for consumer-visible
gaps (unimplemented features, platform caveats, MVP cuts) and consciously
postponed work (TODO/FIXME/XXX markers, RFC deferrals still open). The ten
pre-existing ad-hoc variants ('What is NOT here (TODO)', 'Deferred',
'Limitations (MVP)', 'Known limitations (tracked TODOs)', ...) are normalized
into the canonical heading.

A new doc-sync gate, scripts/verify-readme-limitations.ts, enforces the shape:
exactly one limitations-like heading per package README, byte-equal to the
canonical h2, with at least one bullet; near-miss headings fail so variants
cannot creep back. Packages with genuinely nothing to declare (dsh-brand,
dsh-timeout, dsh-subagent-mock, dsh-app-boot) are whitelisted in the script and
must NOT carry the section; whitelist entries are validated against the scanned
package set so a rename fails loud.

Wired into the doc-sync chain (package.json) and the run-gates doc-sync leaf
set; the standing rule lands in packages/AGENTS.md and the adding-a-package
cookbook; decision record in
docs/rfc/implemented/process/2026-07-10-readme-known-limitations-gate.md
(RFC index regenerated).

Also fixes two stale '(deferred)' markers claiming dsh-compact-basic is
unimplemented (the dsh-compact seam README's package table and the seam's
module doc comment).
2026-07-12 01:46:34 +08:00
..
2026-07-05 15:31:50 +08:00

@deepseek-ai/dsh-web-search-perplexity

A Perplexity-backed WebSearchProvider for the harness web capability seam (ctx.web). It calls Perplexity's OpenAI-compatible POST /chat/completions endpoint and maps the generated answer plus citations into the seam's normalized WebSearchResult.

This is an implementation package: it registers a provider into ctx.web, it does not own the key and it does not register a model-facing tool. Like @deepseek-ai/dsh-llm-deepseek, it is a function/namespace plugin (inject: ['web']). The OpenAI-compatible wire shape is a provider-private detail — it does not make this provider depend on ctx.llm.

Config

Key Default Meaning
apiKey $PERPLEXITY_API_KEY Perplexity API key. Empty/absent → provider status() reports missing-credential.
baseURL https://api.perplexity.ai Endpoint base; /chat/completions is appended. An unparseable value makes status() report misconfigured.
model sonar Search model name.
maxTokens 1024 Upper bound on generated answer tokens (max_tokens). Must be a positive integer.
searchRecency (unset) Recency window sent as search_recency_filter: day, week, month, or year. Unset sends no filter.
- id: web-search-perplexity
  name: '@deepseek-ai/dsh-web-search-perplexity'
  config:
    apiKey: !!js process.env.PERPLEXITY_API_KEY

Mapping

contentchoices[0].message.content (the generated answer). sources[] prefers the structured search_results[] (url, title, snippet, publishedAtdate), falling back to the URL-only citations[] array only when search_results is absent — those sources carry just a url, which is why title/snippet/publishedAt are optional on the seam. Provider failures surface as WebError WEB_PROVIDER_ERROR; an aborted request surfaces as WEB_ABORTED. Perplexity has no result-count control, so maxResults is enforced by the seam (truncating sources[] and setting truncated).

Known Limitations and Deferred Work

  • Citation-fallback sources are URL-only — when Perplexity omits structured search_results[], sources carry no title/snippet/publishedAt, so the tool renders bare hostname labels.
  • Over-returned sources still cost tokens and latency — with no result-count control on the wire, maxResults is enforced only post-hoc by seam truncation.
  • Only model/maxTokens/searchRecency are exposed — Perplexity's other search controls (domain filters, web_search_options context size, images) wait on provider-neutral seam fields (seam RFC).
  • Abort classification is error-shape-based — only a DOMException named AbortError maps to WEB_ABORTED; an abort carrying a custom reason (e.g. dsh-timeout's TimeoutReason) surfaces as WEB_PROVIDER_ERROR.