* feat(i18n): key translation pairing records by heading section Replace the whole-file blob hashes in *.i18n.yaml with one entry per heading section that still holds language-specific content, keyed by the English heading-slug path. Blocks identical across the pair (generated table rows, code blocks, shared regions) stay out of the hash, so edits to different sections and identical regenerations merge with Git's default text merge, including on GitHub. Remove the dsh-translation-pairing merge driver, its resolver command and installer wiring; gen-translation-brief recovers last-confirmed text from commit history. Migrate all active records, archive the superseded Agent Note, and record the replayed conflict reduction in the new one. * test(i18n): refresh translation prompt snapshot for the terminology note * feat(i18n): exclude only code blocks and generated regions from pairing records Replace byte-equality masking with an explicit rule: a record hash skips fenced code blocks and BEGIN/END GENERATED regions, the two kinds of content the pairing gate already requires to be identical on both sides. Move generated data into regions written into both pages: gen-config-catalog renders both languages and the record with per-package regions labelled by code identifiers; gen-module-graph keeps its table in a region; gen-doc-graphs splices the event matrix regions into the Chinese page. Add a generic region splice beside the region grammar.
description, kind
| description | kind |
|---|---|
| The Perplexity-backed search provider for ctx.web: how deployments mount OpenAI-compatible Perplexity search with generated answers and citations. | package-reference |
@deepseek-ai/dsh-web-search-perplexity
English | 中文
Summary
With dsh-web-search-perplexity, the harness searches the web through Perplexity and gets a model-generated answer plus citeable sources in one call. Choose it when a deployment has a Perplexity API key and wants a generated answer. Perplexity has no result-count control, so the returned sources are truncated to the requested bound after the fact. When Perplexity omits structured result metadata, sources fall back to URL-only citations. The model-facing web_search tool lives in dsh-tool-web.
Table of Contents
- Use this package
- Understand the implementation
- Further Exploration
- Model Experience
- Known Limitations and Deferred Work
- Dev Note
Use this package
Mount the provider in a composition that already loads the web service; it registers as the perplexity search provider, so ctx.web.search() resolves it automatically when it is the only usable search backend — or pin it with searchProvider: perplexity.
When to choose it
Choose this backend when a deployment holds a Perplexity API key and wants a model-generated answer plus citeable sources in one search. The provider is unavailable — and every search call fails with a structured error — when the key is empty or the endpoint base does not parse.
Minimal configuration
Load the web service and the provider; the API key falls back to $PERPLEXITY_API_KEY from the launch environment, and all other settings have safe defaults.
- name: '@deepseek-ai/dsh-web'
- name: '@deepseek-ai/dsh-web-search-perplexity'
config:
apiKey: !!js process.env.PERPLEXITY_API_KEY
| Field | Default | Meaning |
|---|---|---|
apiKey |
$PERPLEXITY_API_KEY |
Perplexity API key; empty or absent makes the provider unavailable |
baseURL |
https://api.perplexity.ai |
Endpoint base; /chat/completions is appended. An unparseable value makes the provider unavailable |
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 |
The generated configuration catalog is the exhaustive source for every accepted field and its JSDoc.
What a search returns
content carries Perplexity's generated answer. sources[] prefers the structured search_results[] (url, title, snippet, publishedAt from date) and falls back to the URL-only citations[] array only when search_results is absent — which is why title/snippet/publishedAt are optional on the service. Perplexity exposes no result-count control, so the service enforces maxResults by truncating and flagging.
Failures and recovery
Provider failures — HTTP errors, network failures, unparseable or wrong-shape bodies — surface as WebError WEB_PROVIDER_ERROR; an aborted request surfaces as WEB_ABORTED. HTTP redirects are rejected before the Location target is contacted and surface as WEB_PROVIDER_ERROR. Callers route on the code; the model-facing web_search tool surfaces failures to the model under its own error wrapper.
Understand the implementation
Implementation internals — click to expand
This section explains the design decisions behind the provider; the observable behavior is fully covered in Use this package.
Design philosophy
The provider is a thin adapter over Perplexity's chat-completions endpoint with two deliberate rules:
- The generated answer is trusted as
content. Unlike the other search backends, Perplexity returns a model-generated answer, and this provider passes it through as the normalizedcontentfield. - Structured sources win; URL-only citations are the fallback.
search_results[]carries the portable fields;citations[]carries only URLs, and the service vocabulary makes those fields optional precisely for this case.
Source map
| File | Role |
|---|---|
src/index.ts |
Plugin entry: config schema, environment fallback, provider registration |
src/provider.ts |
The PerplexitySearchProvider: request dispatch, abort classification, answer and source mapping |
src/types.ts |
Perplexity wire types for the chat-completions response |
| — | No runtime invariant companion is published; this package exposes no independent event sequence or mutable data relation beyond contracts enforced at its owning seam. |
Request and mapping flow
search() posts the query with the model, token cap, and optional recency filter to {baseURL}/chat/completions with redirect: 'error'. The response's content becomes content; search_results[] becomes sources[] when present, otherwise each citations[] entry becomes a URL-only source; and the service applies the final maxResults bound on the way back. An abort — a DOMException named AbortError — becomes WEB_ABORTED; anything else becomes WEB_PROVIDER_ERROR.
Further Exploration
Read these pages when the package-level contract is not enough. They move from the shared vocabulary to the service, the model-facing tools, and the design rationale.
- Web subsystem — the exhaustive search request/result vocabulary and error codes.
- Web package map — the six-package family and each role.
- dsh-web — the web service this provider registers into.
- dsh-tool-web — the model-facing
web_searchtool that renders this provider's sources. - Generated configuration catalog — every accepted config field and its source declaration.
- Web capability seam decision — why search and fetch share one provider-selection service.
Model Experience
Auxiliary Perplexity request
What the model sees
A separate Perplexity model receives <query> verbatim as its sole user message through the chat-completions endpoint. This request is not part of the conversation model's context.
Token effect
Separate provider tokens are incurred per search; maxTokens caps the generated answer.
KV Cache effect
Independent of the conversation request cache. An identical query under the same model route may reuse provider cache; a changed query or route establishes a different prefix.
Conversation tool result, indirectly
What the model sees
Through dsh-tool-web, the conversation model sees the generated answer plus structured result metadata or URL-only citations. This provider's exact failures are Perplexity search aborted, Perplexity search request failed: <error>, and Perplexity returned an unprocessable response body: <error>; HTTP failures preserve the provider message. The consumer owns the error wrapper.
Token effect
Zero direct conversation tokens from registration. Answer and source tokens are data-dependent, source count is service-bounded, and the retained result or error is resent until compaction.
KV Cache effect
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
Known Limitations and Deferred Work
These limits define when the provider is a poor fit. They are current package constraints.
- Citation-fallback sources are URL-only — when Perplexity omits structured
search_results[], sources carry notitle/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,
maxResultsis enforced only post-hoc by service truncation. - Only
model/maxTokens/searchRecencyare exposed — Perplexity's other search controls (domain filters,web_search_optionscontext size, images) wait on provider-neutral service fields (seam Agent Note). - Abort classification is error-shape-based — only a
DOMExceptionnamedAbortErrormaps toWEB_ABORTED; an abort carrying a custom reason (such asdsh-timeout'sTimeoutReason) surfaces asWEB_PROVIDER_ERROR.
Dev Note
Working context for maintainers — click to expand
This Dev Note is working context for maintainers: open questions and undecided directions. It is explicitly non-authoritative — shipped behavior, limits, and rationale live in the sections above and the linked Agent Notes.
Future: wider Perplexity control surface
Perplexity's domain filters, web_search_options context size, and image support stay unexposed. Exposing them needs provider-neutral service fields first, so the family adds one coordinated control rather than a vendor-specific argument.