DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

dsh-web-search-diy

Web Search Diy

按供应商 × 协议选择的 DSH Web 搜索提供商:支持带内置搜索工具的 Chat Completions、Responses 和 Anthropic Messages,以及 DeepSeek、Kimi 和 Zhipu 的独立搜索 API;四个自定义目标覆盖网关;界面文案遵循应用语言(zh、en、ja、es、fr、de、ru、pt)。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add dsh-web-search-diy@2.1.0
README兼容性版本

兼容性与来源证明

Web Search Diy 以 dsh-web-search-diy 发布,当前版本为 2.1.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/10/31

版本

2.1.0stable
2026/10/31
2.0.5stable
2026/10/29
2.0.4stable
2026/10/28
查看其余 13 个版本收起版本
2.0.3stable
2026/10/27
2.0.2stable
2026/10/20
2.0.1stable
2026/10/18
2.0.0stable
2026/10/17
1.1.1stable
2026/10/15
1.1.0stable
2026/10/13
1.0.2stable
2026/10/12
1.0.1stable
2026/10/8
1.0.0stable
2026/9/24
0.2.2stable
2026/9/22
0.2.1stable
2026/9/18
0.2.0stable
2026/9/7
0.1.4stable
2026/9/6

相关插件

正在加载相关插件…

最新版
2.1.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
566.6 kB
文件数
16
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 5
周下载
0
最近提交
2026/10/31
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 search-research 分类下经过校验的插件。

Free Searchdsh-free-searchDeepSeek Harness 的免费网页搜索:27 个引擎(Bing/DuckDuckGo/AnySearch/SearXNG/Exa/Tavily/Keenable/Firecrawl/Parallel/You.com 无需密钥;通过 MCP 支持 Zhihu 全局/站内搜索,以及 Perplexity/SerpBase/DeepSeek(官方 + 原生工具/搜索)/Baidu/Kimi/Aliyun/Douba)Ab Wechat Scrapedsh-ab-wechat-scrape--- description: "树外 wechat_scrape 工具:获取微信公众号文章,过滤推广区块,并将每篇文章保存为 Markdown 文件,供此机器的 dsh 配置文件维护者使用。" kind: "package-reference" ---Arisdsh-arisARIS research-workflow 技能作为 DeepSeek Harness 捆绑包:包含 82 项技能,以及通过 Codex 进行的跨模型对抗性审查。Ab Market Researchdsh-ab-market-research一个树外 DeepSeek Harness 插件:将 trade_search 工具(多轮扩展方面的查询规划、出版商级别排序、来源多样性、JSON 快照)及其浏览器卡片集成在一个包中。

README

dsh-web-search-diy

English · 简体中文

A web search provider plugin for the DeepSeek Harness (DSH). It supplies the built-in web_search tool per vendor × protocol: three in-protocol shapes (Chat Completions / Responses / Anthropic Messages) plus standalone search, covering DeepSeek, Kimi, Zhipu, Qwen, OpenAI, Anthropic, OpenRouter, and four custom targets. Results are normalized into structured citation sources for the calling model to ground its answer on. The plugin also ships an observability page that records every search and can backfill history from older session logs.

Capabilities

  • 🧭 Vendor × protocol matrix — 17 official targets (13 full + 4 degraded) and 4 custom targets. Only combinations that really search appear in the vendor list; the rest live in a collapsed section with a reason.
  • 🎛️ Three-layer configuration page — search kind → protocol → vendor. Fields come from the catalog served by the host; a blank value means the combination's default.
  • 🧩 Custom targets — a template picker performs a one-shot fill (selection resets, nothing is saved); endpoint, path, request field names, and response field names are all editable.
  • 🧪 Test connection — runs one real search with the staged draft (nothing saved to the configuration) and grades the result by source quality.
  • 🔐 Write-only credentials — API keys are stored through the credentials service, never in the configuration file; each vendor offers its reference chain.
  • 🗂️ Configuration v3 — one bucket per vendor/protocol; v1/v2 files migrate on read and the old file is backed up as .v2.bak before the first save.
  • 🪜 Thinking-effort fallback — a rejected reasoning.effort / output_config / thinking is dropped one at a time and retried.
  • 📦 Dispatcher-proof decoding — bodies are read as bytes and inflated by magic number, independent of dsh's global undici dispatcher.
  • 📄 Long bodies become source summaries — standalone search writes its long body into source.summary (capped at 2,000 characters) and skips it when the original body equals snippet; snippets are capped the same way. The model reads the summary before falling back to the snippet.
  • 🚦 No credential, no tool — when the selected target cannot resolve a credential, web_search is no longer offered to the model instead of failing after invocation.
  • 📊 Built-in observability page — a first-level "Config / Observability" tab. The overview shows searches, success rate, P50/P95, average sources, summary coverage, a target ranking, success-rate/P95 trends and recent records; the records view filters by status and query, expands source details, and copies a record as JSON.
  • 🗄️ Local observation store and historical import — node:sqlite with WAL, 0600 permissions, transactional writes and a 50,000-row retention cap. Importing scans $DSH_HOME/sessions for older web_search calls and is idempotent; JSONL/CSV export and a typed-DELETE clear are available.
  • 🧱 Failure classes and request timeout — HTTP statuses, network failures and local timeouts map to stable error codes; requestTimeoutMs defaults to 25 s (60 s for test connections), and caller cancellation stays distinct from a timeout.
  • 📅 Calendar ranges and page-number pagination — presets plus a month calendar for start/end dates, independently for queries and imports; records page by page number with 10/20/50/100 rows and jump-to-page.

Capability matrix

Legend: ✅ full (in-protocol search + citable sources); ◐ degraded (searches, but sources or model are limited); ✗ unsupported; ⚙ custom.

VendorChat CompletionsResponsesAnthropic MessagesStandalone search
DeepSeek✗◐ deepseek-v4-pro only; sources from open_page✅✅ /v1/tools/search
Kimi✗ built-in $web_search retired✅ web_search + include✗ no server tool in the schema✅ /v1/tools/search
Zhipu✅ web_search tool✅ web_search + results[]✗ accepts but does not run it✅ /paas/v4/web_search
Qwen◐ enable_search, no sources✅ action.sources (url only)✅ needs the billing header✗ no standalone REST
OpenAI◐ gpt-5-search-api only✅ full filters / include✗ no such endpoint✗
Anthropic✗✗✅ native web_search✗
OpenRouter✅ openrouter:web_search✅ same server tool◐ alias, untested✗
Custom⚙ template + 4 variants⚙ template + toolType⚙ template + toolType⚙ template + 8 mapping fields

13 full, 4 degraded (OpenRouter Anthropic is pending), 4 custom. Eight unsupported entries exist only for the collapsed section and never create a configuration bucket.

Install

Published on npm:

dsh plugin --profile web add dsh-web-search-diy

The bundle patch performs the wiring, so no manual cordis.patch.yml edits are required:

  • inserts the web-search-diy loader entry;
  • overrides the shared web row's searchProvider to diy-search and restates fetchProvider: http (a patch replaces the whole row config);
  • disables the shipped web-search-deepseek provider.

For local development, install the checkout as a link:

dsh plugin --profile web add link:./dsh-web-search-diy

The plugin declares the @deepseek-ai/* hooks as peerDependencies. Run pnpm install once in the plugin directory before linking; the harness provides the peers at runtime.

Configuration

Configuration page

Location: Plugins → Installed plugins → the dsh-web-search-diy card (clicking the card opens this plugin's configuration page). Copy follows Settings → Language (zh, en, ja, es, fr, de, ru, pt).

  • Search kind: In-protocol search or Standalone search. Standalone has no model turn, so model and output-budget fields are hidden.
  • Protocol: one of Chat Completions / Responses / Anthropic Messages in-protocol; standalone is fixed to search.
  • Vendor: only vendors available under that protocol; degraded combinations show their reason on the card; unsupported ones are collapsed for the current shape.
  • Fields: blank means the catalog default (shown as the placeholder). Saving a blank deletes the key.
  • Endpoint override (Anthropic protocol): the launching environment variable DEEPSEEK_SEARCH_BASE_URL overrides the endpoint; an explicitly saved Endpoint wins over it.
  • Template (custom only): a one-shot picker. The selection resets immediately, the placeholder names the last template, and the template itself is never saved. If the target already has a saved configuration, switching templates first asks for confirmation and offers Reset to saved configuration.
  • Save: switching vendor/protocol counts as a pending change; saving takes effect immediately (the host re-reads the file on every search).
  • API key: written through the credentials service only; blank keeps the current key.

Configuration file (v3)

$DSH_HOME/dsh-web-search-diy.json, written by the configuration page:

{
  "version": 3,
  "vendor": "qwen",
  "protocol": "responses",
  "targets": {
    "qwen/responses": {
      "baseURL": "https://maas.qianwenaiapi.com/compatible-mode/v1",
      "apiKeyEnv": "QWEN_TOKEN_PLAN_API_KEY",
      "model": "qwen3.8-flash",
      "maxOutputTokens": 4096,
      "toolType": "web_search",
      "includeSources": true
    },
    "custom/search": {
      "baseURL": "https://search-gateway.example.com",
      "path": "/v1/tools/search",
      "apiKeyEnv": "SEARCH_GATEWAY_API_KEY",
      "queryField": "q",
      "countField": "size",
      "resultsPath": "data.items",
      "urlField": "link",
      "titleField": "name",
      "snippetField": "desc",
      "count": 10
    }
  }
}
  • The top level stores only the current vendor and protocol; each target bucket stores only the keys declared in its fields.
  • A blank value deletes the key and restores the catalog default.
  • template is a fill action, not configuration; submitting it is rejected.
  • API keys never appear in this file.

Migrating from 1.x

v2 modev3 target
responsesqwen/responses
anthropic-messagesdeepseek/anthropic-messages
zhipu-web-searchzhipu/search
zhipu-chat-searchzhipu/chat-completions
  • A v1 flat object is first projected onto its mode, then migrated by the table above.
  • Migration happens in memory on read; the first save writes v3 and backs the original up as dsh-web-search-diy.json.v2.bak (once, for rollback).
  • Old key names: responsesToolType → toolType, responsesIncludeSources → includeSources, responsesReasoningEffort → reasoningEffort, anthropicThinking → thinking, anthropicEffort → effort; apiVersion is dropped (fixed at 2023-06-01).
  • 2.0 registers no settings section; configuration comes from the file and the credential surface only.

Field reference

Protocol / vendorFields
CommonbaseURL, apiKeyEnv, model, maxOutputTokens (the last two are hidden for standalone)
Responses · OpenAItoolType, includeSources, reasoningEffort, searchContextSize, allowedDomains, blockedDomains, userLocation, externalWebAccess, returnTokenBudget, searchContentTypes, imageMaxResults, imageCaption
Responses · KimitoolType, includeSources, allowedDomains (blockedDomains / search_context_size return 400)
Responses · Zhipu / QwentoolType, includeSources, reasoningEffort
Responses · DeepSeektoolType; the model is locked to deepseek-v4-pro and include is not sent
Responses · OpenRoutertoolType, includeSources, engine, mode, maxResults, maxUses, maxTotalResults, searchContextSize, maxCharacters, userLocation, allowedDomains, excludedDomains, xSearch
Anthropic MessagestoolType, maxUses, thinking, effort, allowedDomains, blockedDomains, userLocation, responseInclusion
Chat · ZhipusearchEngine, count, searchRecencyFilter, contentSize, searchDomainFilter, requireSearch, searchPrompt, reasoningEffort
Chat · QwensearchStrategy, forcedSearch, freshness, assignedSiteList, ,

oriQuestion sends the human prompt that triggered the search as DeepSeek's ori_question: whitespace collapsed, cut to 128 characters, read from the initiating Session and omitted outside one. It shares the source used by the official web-deepseek-api provider (sendOriginalQuestion).

Result count and digest size are independent: count / limit drive the request and the number of sources (1–50 for Zhipu/DeepSeek, 1–20 for Kimi); digestEntries (default 8) and digestSnippetChars (default 200) only shape the content digest returned to the caller and never trim sources.

Custom targets

  • Templates: in-protocol targets list the vendors available under that protocol; standalone lists DeepSeek / Kimi / Zhipu. Picking a template performs a one-shot fill of endpoint, credential, model, and search parameters; everything remains editable.
  • Chat variants: decided by the template (Zhipu answer augmentation / Qwen web search / OpenRouter server tool / OpenAI search model), not exposed as a separate field; fields are filtered per variant.
  • Standalone mapping: queryField, countField, resultsPath, urlField, titleField, snippetField, dateField, contentField are authoritative; the template only fills them and acts as a blank fallback. Simple dot paths (data.items) are supported; full JSONPath is not.
  • Body field: contentField names each result's long body. It becomes the source's summary (capped at 2,000 characters), backs the content digest when snippet is empty, and is skipped when the original body equals snippet — the check runs before the cap, so a long Zhipu content is not stored twice. snippet is capped at 2,000 characters too. The DeepSeek template defaults to content (the need_content body); a saved summary keeps working through the fallback.
  • Search engine: free input with common candidates (Zhipu / OpenRouter / self-hosted). On the Zhipu template a blank falls back to search_std (the API requires it).
  • Required: Chat needs a variant (the template fills it); Responses / Anthropic need toolType; standalone needs path.

Target reference (default endpoint / model / credential)

targetSupportDefault endpointDefault modelCredential reference
deepseek/anthropic-messages✅https://api.deepseek.com/anthropicdeepseek-flashDEEPSEEK_API_KEY
deepseek/responses◐https://api.deepseek.comdeepseek-v4-proDEEPSEEK_API_KEY
deepseek/search✅https://api.deepseek.com—DEEPSEEK_API_KEY
kimi/responses✅https://api.moonshot.cn/v1kimi-k2.6MOONSHOT_API_KEY → KIMI_API_KEY
kimi/search✅https://api.moonshot.cn—same
zhipu/chat-completions✅https://open.bigmodel.cn/api/paas/v4glm-5.3-flashZAI_CODING_CN_API_KEY → ZHIPU_API_KEY
zhipu/responses✅https://open.bigmodel.cn/api/v1glm-5.3same
zhipu/search✅https://open.bigmodel.cn/api/paas/v4—same
qwen/chat-completions◐https://maas.qianwenaiapi.com/compatible-mode/v1qwen3.8-flashQWEN_TOKEN_PLAN_API_KEY → QWEN_TOKEN_PLAN_CN_API_KEY → DASHSCOPE_API_KEY
qwen/responses✅sameqwen3.8-flashsame
qwen/anthropic-messages✅https://maas.qianwenaiapi.com/apps/anthropicqwen3.8-maxsame

Default models are current examples, not a long-term promise; an explicit user value always wins.

Test connection

The page's Test connection button runs one real search with the staged draft, without persisting the draft (the observation store records one test row, excluded from statistics by default):

  • query fixed to OpenAI, maxResults = 3, timeout 60 s;
  • in-protocol: Responses / Anthropic send Perform a web search for the query: OpenAI; Chat sends OpenAI directly;
  • standalone: sends search_query / query / text_query plus the matching count;
  • response: { ok, sourceCount, sourceQuality, degraded, latencyMs, contentPreview?, error? };
  • the save-side required-field checks (for example, a standalone custom target must declare path) run first, so a missing value returns 400 without sending a request;
  • with zero sources the message is graded by the combination's expected source quality: by design / may not have run / check the tool name and endpoint.

How it works

you ──> chat LLM ──> web_search tool (model-independent)
                        │ ctx.web seam ──> diy-search provider
                        ▼
   ├─ Responses:          POST {baseURL}/responses   tools: [{ type, ... }]
   ├─ Anthropic Messages: POST {baseURL}/messages    tools: [{ type: web_search_*, max_uses }]
   ├─ Chat Completions:   POST {baseURL}/chat/completions  (four variants)
   └─ Standalone:         POST {baseURL}{path}       (no model turn)
                        │
                        ▼
                  chat LLM answers from the sources
  • Responses: action.sources[], open_page / find_in_page action.url, results[] metadata, and url_citation annotations all normalize into deduplicated sources; the answer prefers phase: "final_answer". A reply with no search evidence fails explicitly, and a 404 points out the missing /responses path.
  • Anthropic Messages: web_search_tool_result → sources[], citations[].cited_text → snippet, page_age → ISO date; allowed_domains and blocked_domains are mutually exclusive (allowed wins); tool types other than 20250305 also send allowed_callers: ["direct"].
  • Chat Completions: Zhipu web_search tool, Qwen enable_search, OpenRouter server tool, OpenAI search model; sources come from message.web_search[] or annotations[].
  • Standalone: structured results become sources[], the contentField long body becomes source.summary, and the first few snippets form content; there is no model turn.
  • Effort fallback: drop one knob at a time in the order reasoning.effort → output_config → thinking → reasoning_effort and retry.
  • Decoding: read as bytes and inflate by gzip/zlib magic, capped at 8 MiB on the wire and 16 MiB decoded.

Observability and historical import

  • Capture: the provider reports one outcome per real search and per test connection, for both success and failure: target/vendor/protocol, session id, query, duration, error code and source counts. The sink wraps its own writes, so a storage failure logs one diagnostic and never changes the search result.
  • Storage: node:sqlite writes $DSH_HOME/web-search-diy/observations.db with WAL, busy_timeout and foreign keys; the directory and files are tightened to 0700/0600. A record and its source rows commit in one transaction. On open, PRAGMA user_version drives schema migrations and only the latest 50,000 rows are retained (never time-based, so imported history is not pruned). When node:sqlite is unavailable, the directory is unwritable, or the database is corrupt, observability is disabled and search keeps working.
  • Failure classes: 401/403 → WEB_PROVIDER_AUTH; 408/504 and local timeouts → WEB_PROVIDER_TIMEOUT; 429 → WEB_PROVIDER_RATE_LIMIT; 5xx → WEB_PROVIDER_SERVER; other 4xx (except 400) → WEB_PROVIDER_REQUEST; 400 and unparseable bodies → WEB_PROVIDER_ERROR; transport failures → WEB_PROVIDER_NETWORK; caller cancellation → WEB_ABORTED.
  • Queries and pagination: GET /api/web-search-diy/observability/summary|records|export, DELETE .../records, POST .../import. P50/P95 are computed in the application layer by sorting duration_ms and interpolating, avoiding a dependency on SQLite window functions. Records are read by page/limit and return the filtered total; out-of-range pages clamp to the last page.
  • Time ranges: since accepts relative presets or ISO timestamps, until accepts ISO timestamps; a custom end day includes the whole local day up to 23:59:59.999. Presets and "until now" send no until, and the default range is the last 24 hours. Query and import ranges are independent.
  • Historical import: scans session logs for tool/call (web_search) events and their results, uses deterministic history:<sessionId>:<seq> ids and only adds what is missing. All protocols in this release write a web/deepseek-search-llm-request event with the target id between the call and its result; events without a target fall back to matching the catalog default endpoint, and calls with neither are marked (shown as "History"). Imports accept / and also backfill the target of an existing history row.

Live verification

Real credentials, 2026-10-17 / 2026-10-18:

targetSourcesNotes
qwen/responses6sources carry url only
qwen/anthropic-messages9billing header attached automatically
deepseek/anthropic-messages10—
deepseek/search3blank localization is not sent
zhipu/chat-completions8—
zhipu/responses5sources + results merged
zhipu/search1digest cap applied
kimi/responses6kimi-k2.6
kimi/search3maxResults=30 clamped to limit=20
custom/search1custom mapping and digest cap applied
qwen/chat-completions0degraded as expected (no sources)
deepseek/responses0degraded as expected (open_page only)
custom/chat / responses / anthropic8 / 5 / 10verified on 2026-10-17

Re-checked with a real DeepSeek key on 2026-10-29: deepseek/search returned 5 sources with 1,790–2,000-character source.summary values (the need_content body is used when “include content” is on); deepseek/anthropic-messages returned 10 sources plus a 4,336-character answer.

OpenAI, Anthropic, and OpenRouter are not verified yet; results for these endpoints are welcome under Feedback.

Known limitations

  • Kimi Chat is not wired in: the in-protocol $web_search retires on 2026-10-20, and the api.kimi.com/coding endpoint is not wired either. Kimi keeps Responses and standalone search (/v1/tools/search; the Pro endpoint can be reached by overriding path on a custom target).
  • Zhipu's Anthropic surface accepts but never runs the tool (web_search_requests: 0), so it is marked unsupported.
  • DeepSeek Responses only works with deepseek-v4-pro and returns no action.sources; sources come from open_page only.
  • Qwen Chat returns no sources; Qwen is wired to the Qwen AI Platform only (maas.qianwenaiapi.com), not Alibaba Cloud Model Studio.
  • OpenAI Chat only works with gpt-5-search-api; ordinary models ignore the tool.
  • OpenRouter Anthropic accepts the web_search_20250305 alias per its docs, but it is not verified yet.
  • Kimi Responses rejects search_context_size / blocked_domains (400).
  • Standalone search has no model turn; its output cap is digestEntries / digestSnippetChars, not a model token budget.
  • Standalone source text is capped at 2,000 characters for both snippet and summary, without splitting surrogate pairs; dsh-tool-web then trims summary to 800 by default before the model reads it.
  • Test connection uses a fixed query (OpenAI) and only proves connectivity, not search quality.
  • Observability requires node:sqlite — when the module is missing, the directory is unwritable, or the database is corrupt, the whole observability layer is disabled with one diagnostic; search is unaffected.
  • The observation store keeps the latest 50,000 rows — retention is not time-based, and imported history shares the same cap.
  • Historical import can only recover calls present in session logs — an older session with neither a request event nor an endpoint matching a catalog default keeps the historical target; re-running the import does not change it.
  • Test and compare records are excluded by default — enable "Include test connections" in the toolbar to count them. Test connections always use the fixed query.

Feedback

If you hit an unsupported vendor or gateway, a protocol difference, or a field-mapping problem, open an issue with the endpoint type, request shape, and error message. PRs with new live-verification results are welcome.

Credentials

Store keys in the Web Models page / credentials service ($DSH_HOME/.credentials.yaml) or export them in the launching environment. The plugin resolves them per search, never retains them on the provider, and never writes them to the configuration file. While the selected target cannot resolve a credential, web_search is not offered to the model at all.

Default chains per vendor: DeepSeek DEEPSEEK_API_KEY; Kimi MOONSHOT_API_KEY → KIMI_API_KEY → KIMI_CODING_API_KEY; Zhipu ZAI_CODING_CN_API_KEY → ZHIPU_API_KEY; Qwen QWEN_TOKEN_PLAN_API_KEY → QWEN_TOKEN_PLAN_CN_API_KEY → DASHSCOPE_API_KEY; one each for OpenAI / Anthropic / OpenRouter. Custom targets use a user-supplied reference.

A reference name must be a valid environment-variable name (letter/underscore start, then letters, digits, underscores). Saving rejects anything else, and an invalid reference left in a hand-edited file is skipped in favor of the next candidate.

Development

Host and Client both live in src/; built artifacts are committed:

src/
  index.ts        # apply: registers the provider, config/test and observability endpoints
  catalog.ts      # capability matrix, defaults, fields, templates
  config.ts       # v3 read/write, v1/v2 migration, field validation
  endpoint.ts     # GET/POST /api/web-search-diy/config and /test
  options.ts      # catalog defaults + file overrides
  provider.ts     # available / ready / dispatch by protocol
  transport.ts    # fetch, decoding, reasoning fallback, failure classes
  protocols/      # responses / anthropic / chat / search
  mappers/        # source normalization
  observability/  # store, aggregation, historical import, export, endpoints
  client/         # browser half, bundled into one lib/client.js
    index.tsx     # apply: card registration, stylesheet and dictionaries
    page.tsx      # config page: shape → protocol → vendor, field form, test/save
    fields.tsx    # field controls
    field-meta.ts # enum/boolean/numeric sets, chat variants, advanced section
    draft.ts      # draft normalization, template fill, number coercion
    labels.ts     # protocol/vendor/support copy
    styles.ts     # card stylesheet
    locale.ts     # zh/en dictionaries plus the shared ALL_LOCALES map
    locales/      # ja / es / fr / de / ru / pt dictionaries
    obs/          # observability page: overview, records, calendar range, charts
    consts.ts     # loader id and endpoints
    types.ts      # draft and field-prop types
pnpm install
pnpm run build       # Host ESM + Client CJS
pnpm run typecheck
pnpm test            # host tests (180)
pnpm run test:client # rebuild and verify the client contract

lib/index.js and lib/client.js are committed; source maps are not.

License

MIT — see LICENSE. Copyright (c) 2026 aaronlei.

searchExtension
promptIntervene
Chat · OpenRouterengine, mode, maxResults, maxUses, maxTotalResults, searchContextSize, maxCharacters, userLocation, allowedDomains, excludedDomains, xSearch
Chat · OpenAIno search parameters; the model is locked to gpt-5-search-api
Standalonecount, includeContent, searchEngine / contentSize / searchRecencyFilter / searchDomainFilter (Zhipu), oriQuestion / localization (DeepSeek), timeoutSeconds (Kimi), digestEntries, digestSnippetChars; custom adds path and the 8 mapping fields
openai/chat-completions◐https://api.openai.com/v1gpt-5-search-apiOPENAI_API_KEY
openai/responses✅https://api.openai.com/v1gpt-5.5OPENAI_API_KEY
anthropic/anthropic-messages✅https://api.anthropic.comclaude-opus-5-5ANTHROPIC_API_KEY
openrouter/chat-completions✅https://openrouter.ai/api/v1user-suppliedOPENROUTER_API_KEY
openrouter/responses✅https://openrouter.ai/api/v1user-suppliedOPENROUTER_API_KEY
openrouter/anthropic-messages◐https://openrouter.ai/apiuser-suppliedOPENROUTER_API_KEY
custom/chat-completions⚙template prefilltemplate / useruser
custom/responses⚙template prefilltemplate / useruser
custom/anthropic-messages⚙template prefilltemplate / useruser
custom/search⚙template prefill—user
historical
since
until
OpenAI
  • Time ranges follow the browser's local day — a custom end day includes the whole day, so boundaries shift with the viewer's time zone.