deepseek-web-retrieval 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +96 -230
- package/README.md +53 -25
- package/dist/cli.js +1358 -617
- package/docs/agents/codex.md +32 -11
- package/docs/agents/opencode-v2.md +5 -5
- package/docs/agents/pi.md +92 -90
- package/docs/design/installer-design.md +72 -9
- package/docs/hosts.jsonc +2 -2
- package/docs/integration.md +14 -9
- package/docs/research/control-matrix.md +48 -13
- package/docs/research/mcp-compatibility.md +9 -4
- package/docs/research/search-api-defaults.md +309 -0
- package/examples/pi.settings.jsonc +17 -0
- package/index.ts +2 -2
- package/package.json +35 -4
- package/src/core/auth.ts +4 -6
- package/src/core/client.ts +65 -53
- package/src/core/constants.ts +30 -24
- package/src/core/descriptions.ts +30 -6
- package/src/core/domains.ts +56 -67
- package/src/core/env.ts +112 -0
- package/src/core/format.ts +53 -50
- package/src/core/index.ts +9 -9
- package/src/core/jsonc.ts +6 -6
- package/src/core/object.ts +4 -0
- package/src/core/options.ts +21 -26
- package/src/core/search.ts +45 -44
- package/src/core/transport.ts +109 -113
- package/src/core/types.ts +47 -47
- package/src/core/url.ts +20 -20
- package/src/installer/apply.ts +256 -81
- package/src/installer/cli.ts +135 -104
- package/src/installer/detect.ts +46 -31
- package/src/installer/formats/index.ts +26 -28
- package/src/installer/formats/json.ts +81 -77
- package/src/installer/formats/rules.ts +55 -28
- package/src/installer/formats/toml.ts +88 -81
- package/src/installer/formats/value.ts +34 -30
- package/src/installer/hosts/codex.ts +100 -54
- package/src/installer/hosts/index.ts +126 -41
- package/src/installer/hosts/opencode.ts +70 -51
- package/src/installer/hosts/pi.ts +269 -75
- package/src/installer/hosts/shared.ts +19 -14
- package/src/installer/operation-lock.ts +54 -0
- package/src/installer/ownership.ts +129 -0
- package/src/installer/paths.ts +7 -5
- package/src/installer/persistence.ts +66 -0
- package/src/installer/render.ts +29 -29
- package/src/installer/revert.ts +33 -29
- package/src/installer/rulesContent.ts +24 -13
- package/src/installer/state.ts +116 -31
- package/src/installer/types.ts +74 -56
- package/src/installer/uninstall.ts +40 -17
- package/src/mcp/auth.ts +7 -8
- package/src/mcp/cli.ts +38 -20
- package/src/mcp/client.ts +35 -0
- package/src/mcp/server.ts +68 -97
- package/src/opencode/auth.ts +24 -26
- package/src/opencode/plugin.ts +99 -87
- package/src/pi/extension.ts +164 -0
- package/src/pi/settings.ts +49 -0
- package/src/mcp/config.ts +0 -124
|
@@ -79,14 +79,19 @@ paths imply the available scopes; keys locked to a single scope are enumerated i
|
|
|
79
79
|
|
|
80
80
|
- **Positioning** — VSCode-extension agent with an experimental lightweight CLI (`clite`,
|
|
81
81
|
built on the Cline SDKs). Apache-2.0. MCP plus CLI/SDK custom tools; neither replaces the
|
|
82
|
-
built-in `fetch_web_content`.
|
|
83
|
-
|
|
82
|
+
built-in `fetch_web_content`. `@cline/cli` is frozen at 0.0.13 (last publish 2026-05-11);
|
|
83
|
+
the next day the unscoped `cline` package superseded it (3.0.0 on 2026-05-12; 3.0.73 at
|
|
84
|
+
2026-10-21; binary renamed `clite` → `cline`), and docs.cline.bot now describes only the
|
|
85
|
+
`cline` binary (re-verified 2026-10-21). The lock stays 0.0.13 `clite` and everything
|
|
86
|
+
here is verified against that binary; adopting 3.x means re-verifying this whole row.
|
|
84
87
|
- **Built-in web tools** — `fetch_web_content` (fetch a URL and analyze it with a prompt);
|
|
85
88
|
no built-in web search (the binary's `web_search` strings are Bedrock provider tool
|
|
86
89
|
versions). Kill switch: `"disabledTools": ["fetch_web_content"]` in
|
|
87
90
|
`~/.cline/data/settings/global-settings.json` (path overridable via
|
|
88
91
|
`CLINE_GLOBAL_SETTINGS_PATH`); a disabled tool is dropped from the available set.
|
|
89
|
-
`--yolo` mode also deactivates web fetch.
|
|
92
|
+
`--yolo` mode also deactivates web fetch. Current docs.cline.bot documents the SDK's
|
|
93
|
+
`toolPolicies: { enabled: false }` as the disable mechanism and no longer mentions the
|
|
94
|
+
`disabledTools` key, which still exists in the settings file (re-verified 2026-10-21).
|
|
90
95
|
- **MCP registration** — `~/.cline/settings/cline_mcp_settings.json`
|
|
91
96
|
(`CLINE_MCP_SETTINGS_PATH`), written by the `clite mcp` wizard in a nested form:
|
|
92
97
|
`mcpServers.<name>.transport` with `type` (`stdio` | `sse` | `streamableHttp`) plus
|
|
@@ -108,11 +113,25 @@ paths imply the available scopes; keys locked to a single scope are enumerated i
|
|
|
108
113
|
<bool>` form parses but discards the value at 0.163.0 — a silent no-op
|
|
109
114
|
([config source at rust-v0.163.0](https://github.com/openai/codex/blob/rust-v0.163.0/codex-rs/config/src/config_toml.rs)).
|
|
110
115
|
- **MCP registration** — `~/.codex/config.toml` `[mcp_servers.<name>]`: stdio
|
|
111
|
-
`command`/`args`/`env`/`env_vars`; `startup_timeout_sec` (
|
|
112
|
-
(
|
|
116
|
+
`command`/`args`/`env`/`env_vars`; `startup_timeout_sec` (30 s) and `tool_timeout_sec`
|
|
117
|
+
(300 s) defaults — the `DEFAULT_STARTUP_TIMEOUT`/`DEFAULT_TOOL_TIMEOUT` constants
|
|
118
|
+
([rmcp_client.rs at rust-v0.163.0](https://github.com/openai/codex/blob/rust-v0.163.0/codex-rs/codex-mcp/src/rmcp_client.rs));
|
|
119
|
+
`enabled_tools`/`disabled_tools` (verbatim raw tool-name match, filtered before
|
|
120
|
+
registration so the model never sees a disabled tool; an empty `enabled_tools` allow-list
|
|
121
|
+
exposes nothing), per-tool approval modes, and output limits.
|
|
113
122
|
stdio children do not inherit the parent environment (only `HOME`, `PATH`, and explicit
|
|
114
123
|
`env`), so `DEEPSEEK_API_KEY` must be passed explicitly. When a tool result has
|
|
115
124
|
`structuredContent`, Codex replaces the content blocks with the serialized JSON. No SSE.
|
|
125
|
+
Codex identifies itself in the initialize handshake as clientInfo name `codex-mcp-client`
|
|
126
|
+
with title `Codex`
|
|
127
|
+
([rmcp_client.rs at rust-v0.163.0](https://github.com/openai/codex/blob/rust-v0.163.0/codex-rs/codex-mcp/src/rmcp_client.rs)).
|
|
128
|
+
The official docs moved to learn.chatgpt.com
|
|
129
|
+
([MCP](https://learn.chatgpt.com/docs/extend/mcp),
|
|
130
|
+
[config reference](https://learn.chatgpt.com/docs/config-file/config-reference); the old
|
|
131
|
+
developers.openai.com URLs 308-redirect there) and now document every key above — but
|
|
132
|
+
state 10 s/60 s timeout defaults, which describe an older release line; the 30 s/300 s
|
|
133
|
+
constants above are the facts at the locked 0.163.0 (docs discrepancy re-verified
|
|
134
|
+
2026-10-21).
|
|
116
135
|
- **Rules** — `~/.codex/AGENTS.md` (with `AGENTS.override.md` preferred) at user scope;
|
|
117
136
|
every `AGENTS.md` from the project root down to the cwd, concatenated root→cwd.
|
|
118
137
|
Extensible via `project_doc_fallback_filenames` and `developer_instructions`
|
|
@@ -136,12 +155,25 @@ paths imply the available scopes; keys locked to a single scope are enumerated i
|
|
|
136
155
|
|
|
137
156
|
### Pi
|
|
138
157
|
|
|
139
|
-
- **Positioning** — minimal, fully customizable agent (earendil-works). MIT.
|
|
140
|
-
|
|
158
|
+
- **Positioning** — minimal, fully customizable agent (earendil-works). MIT. A TypeScript
|
|
159
|
+
extension API plus MCP. See [Pi](../agents/pi.md); the shipped adapter is the native
|
|
160
|
+
extension (`src/pi/`), with the MCP server as the fallback path.
|
|
141
161
|
- **Built-in web tools** — none at 1.3.0. The built-in set is exactly `bash, edit, find,
|
|
142
162
|
grep, ls, powershell, read, write` (default-active: `read, bash, edit, write`); web
|
|
143
163
|
search/fetch arrive via MCP or extensions
|
|
144
164
|
([tools index at v1.3.0](https://github.com/earendil-works/pi/blob/v1.3.0/packages/coding-agent/src/core/tools/index.ts)).
|
|
165
|
+
- **Extension registration** — `packages` in settings.json (`~/.pi/agent/settings.json` or
|
|
166
|
+
`.pi/settings.json`): source strings (`npm:<pkg>`, `git:…`, local paths) resolved at
|
|
167
|
+
session start; `pi install <source>` appends them, and a package's `pi` manifest field
|
|
168
|
+
names its entry files (loaded via jiti, TypeScript directly). Extension tools default to
|
|
169
|
+
`exposure: "direct"` — no codemode trap — and run in-process: the key is read from
|
|
170
|
+
`process.env` (no forwarding), and results bypass the MCP layer entirely, so neither the
|
|
171
|
+
20 KB truncation nor the 60 s request timeout applies. There is no per-extension options
|
|
172
|
+
channel: the runtime config surface is the `DEEPSEEK_*` environment (the same pipeline as
|
|
173
|
+
the MCP server) plus a `deepseekWebRetrieval` settings namespace the installer writes for
|
|
174
|
+
the off tier — Pi preserves unknown settings keys on read and on its own rewrites
|
|
175
|
+
(`pi install`), verified at 1.3.0. Action methods such as `getSettings()` cannot be
|
|
176
|
+
called during extension loading, so the adapter reads the settings files itself.
|
|
145
177
|
- **MCP registration** — `~/.pi/agent/mcp.json` or `.pi/mcp.json`: stdio
|
|
146
178
|
`command`/`args`/`env`/`cwd`, HTTP `url`/`headers`, plus `timeout`, `enabled`,
|
|
147
179
|
`exposure`. MCP tools are hidden from the model by default
|
|
@@ -237,7 +269,9 @@ paths imply the available scopes; keys locked to a single scope are enumerated i
|
|
|
237
269
|
- **Rules** — `~/.copilot/copilot-instructions.md` (user),
|
|
238
270
|
`.github/copilot-instructions.md` (repo) and `.github/instructions/**/*.instructions.md`
|
|
239
271
|
(path-scoped via `applyTo` globs); `AGENTS.md`/`CLAUDE.md` discovery (changelog-dated
|
|
240
|
-
≤1.0.86; `GEMINI.md`
|
|
272
|
+
≤1.0.86); `GEMINI.md` is never named in the changelog but the official docs have listed
|
|
273
|
+
it since the page's creation on 2026-02-16 (docs-history-dated, 0.0.41x era — comfortably
|
|
274
|
+
≤1.0.98; re-verified 2026-10-21); `.claude/rules` support is changelog-dated 1.0.89;
|
|
241
275
|
`COPILOT_CUSTOM_INSTRUCTIONS_DIRS` adds directories
|
|
242
276
|
([custom instructions](https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-custom-instructions)).
|
|
243
277
|
|
|
@@ -250,8 +284,9 @@ paths imply the available scopes; keys locked to a single scope are enumerated i
|
|
|
250
284
|
- **Replacement is exclusive to native extension points** — only OpenCode. Exclusion is
|
|
251
285
|
the general forced path on MCP hosts. The two structural limits: OpenCode search has no
|
|
252
286
|
middle tier, and Cursor search cannot be forced at all.
|
|
253
|
-
- **Version drift to re-verify on the next baseline pass:** Cline's
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
287
|
+
- **Version drift to re-verify on the next baseline pass:** Cline's `cline` 3.x package
|
|
288
|
+
(3.0.73 at 2026-10-21) has superseded the locked 0.0.13 `clite`; adopting it means
|
|
289
|
+
re-verifying that host's whole row (the documented kill switch already differs: SDK
|
|
290
|
+
`toolPolicies`). Codex's docs location and Copilot's `GEMINI.md` dating were re-verified
|
|
291
|
+
2026-10-21 and are settled in their sections above. Protocol-revision evidence for every
|
|
292
|
+
host lives in [mcp-compatibility.md](mcp-compatibility.md).
|
|
@@ -107,12 +107,17 @@ differences:
|
|
|
107
107
|
capability; do not rely on resources, prompts, sampling, elicitation, or roots — the
|
|
108
108
|
hosts' client capabilities are inconsistent (Codex has elicitation only; Pi serves
|
|
109
109
|
roots). Always return readable
|
|
110
|
-
text in `content` blocks, and mirror the same data in `structuredContent`
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
text in `content` blocks, and mirror the same data in `structuredContent` — the
|
|
111
|
+
spec's own backwards-compat SHOULD — except for clients that would replace the text
|
|
112
|
+
with its serialized JSON: Codex *replaces* content with `structuredContent` when
|
|
113
|
+
present, so the shipped server detects its `codex-mcp-client` identity (the
|
|
114
|
+
initialize `clientInfo` on handshake-era connections, the per-request envelope on
|
|
115
|
+
`2026-07-28`) and omits the mirror for it. Cline reads
|
|
113
116
|
text content only; Pi is
|
|
114
117
|
content-first, falling back to `structuredContent` only when a result has no content
|
|
115
|
-
blocks (verified in `tools.ts` at v1.3.0).
|
|
118
|
+
blocks (verified in `tools.ts` at v1.3.0). No `outputSchema` is declared: the SDK
|
|
119
|
+
rejects text-only results for a tool with a declared schema, and no host in the
|
|
120
|
+
matrix validates the schema anyway.
|
|
116
121
|
2. **stdio is the universal transport.** Every host in the matrix launches stdio servers
|
|
117
122
|
with the same conceptual JSON (`mcpServers` → `command`/`args`/`env`), differing only in
|
|
118
123
|
file location and cosmetic field names. stdio needs no OAuth and no URL config, and the
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# Search and fetch API defaults across vendors
|
|
2
|
+
|
|
3
|
+
This note answers one question: what are the **factory defaults** — the values applied when a
|
|
4
|
+
caller passes nothing — of the mature AI-native web-search and web-fetch APIs? It exists
|
|
5
|
+
because this repo layers its own client-side defaults on top of the DeepSeek Search/Fetch API,
|
|
6
|
+
and the original values (`maxResults=5` on an API `count` of 10, `minRerank=1.5`,
|
|
7
|
+
`minAuthority=2`, `allowUnknownAuthority=false`, `maxRetries=0`, `timeout=30s`, fetch
|
|
8
|
+
truncation at 16,000 characters, summary truncation at 1,200, response-body cap 5 MiB) were
|
|
9
|
+
challenged as arbitrary. The pages below are the benchmark against which the repo's defaults
|
|
10
|
+
are grounded; based on this survey the search-side defaults were changed on 2026-10-21 to
|
|
11
|
+
`maxResults=10`, `minRerank=0`, `minAuthority=0`, `allowUnknownAuthority=true` (filters stay
|
|
12
|
+
available as opt-ins). It records facts only; the closing section lines the repo's values up
|
|
13
|
+
against them without recommending changes.
|
|
14
|
+
|
|
15
|
+
**Research baseline:** 2026-10-21. Claims are cited to primary sources only: official vendor
|
|
16
|
+
documentation and official SDK source (GitHub repos and published npm/PyPI packages). Secondhand
|
|
17
|
+
blogs and tutorials are excluded. "Default" means the value in force when the parameter is
|
|
18
|
+
omitted — not the allowed range, and not an example value. Where no default is published, that
|
|
19
|
+
is stated as such rather than guessed.
|
|
20
|
+
|
|
21
|
+
The five questions asked of every product:
|
|
22
|
+
|
|
23
|
+
1. Search-result count default (the analogue of this repo's `maxResults`/API `count`).
|
|
24
|
+
2. Any **client-side relevance/authority filtering** default (the analogue of
|
|
25
|
+
`minRerank`/`minAuthority`/`allowUnknownAuthority`) — in particular, does anyone drop
|
|
26
|
+
results by authority in the client?
|
|
27
|
+
3. HTTP retry default at the SDK layer.
|
|
28
|
+
4. Request timeout default (SDK and API layer).
|
|
29
|
+
5. Fetched-content truncation default (character limits, byte caps).
|
|
30
|
+
|
|
31
|
+
## Tavily
|
|
32
|
+
|
|
33
|
+
API defaults from the official OpenAPI reference for `POST /search`
|
|
34
|
+
([docs](https://docs.tavily.com/documentation/api-reference/endpoint/search)):
|
|
35
|
+
|
|
36
|
+
| Parameter | Default when omitted | Source |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| `max_results` | **10** (min 0, max 20) | [API reference](https://docs.tavily.com/documentation/api-reference/endpoint/search) |
|
|
39
|
+
| `search_depth` | **`basic`** (vs `advanced`/`fast`/`ultra-fast`) | same |
|
|
40
|
+
| `chunks_per_source` | **3** (chunks of ~500 chars `basic`/`fast`, ~800 `advanced`) | same |
|
|
41
|
+
| `topic` | **`general`** | same |
|
|
42
|
+
| `include_answer` / `include_raw_content` / `include_images` | **false** | same |
|
|
43
|
+
| `auto_parameters` | **false** | same |
|
|
44
|
+
| `include_domains` / `exclude_domains` | **empty** | same |
|
|
45
|
+
| `include_domains_mode` | **`restrict`** ("`include_domains` acts as a hard filter unless set to `prefer`") | same |
|
|
46
|
+
|
|
47
|
+
No relevance score, authority tier, or any other per-result quality signal is returned or
|
|
48
|
+
filterable in the client — ranking is server-side and opaque.
|
|
49
|
+
|
|
50
|
+
SDK layer ([tavily-python, master](https://github.com/tavily-ai/tavily-python/blob/master/tavily/tavily.py)):
|
|
51
|
+
`max_results` and `search_depth` default to `None` (so the API defaults above apply); `search`
|
|
52
|
+
has `timeout: float = 60` clamped to `min(timeout, 120)` seconds; `extract` defaults to 30 s and
|
|
53
|
+
`crawl` to 150 s. The client posts through a plain `requests.Session` with no retry adapter —
|
|
54
|
+
the only retry-related code parses a `retry_after_seconds` field out of error payloads.
|
|
55
|
+
|
|
56
|
+
## Exa
|
|
57
|
+
|
|
58
|
+
API defaults from the official OpenAPI spec
|
|
59
|
+
([reference](https://exa.ai/docs/reference/search)):
|
|
60
|
+
|
|
61
|
+
| Parameter | Default when omitted | Source |
|
|
62
|
+
| --- | --- | --- |
|
|
63
|
+
| `numResults` | **10** (max 100) | [reference](https://exa.ai/docs/reference/search); the [search quickstart](https://exa.ai/docs/search/quickstart) states it in prose: "Search returns up to 10 results by default" |
|
|
64
|
+
| `type` | **`auto`** | [reference](https://exa.ai/docs/reference/search) |
|
|
65
|
+
| `contents.text` (boolean form) | **false** — "If true, returns full page text with default settings. If false, disables text return." | same |
|
|
66
|
+
| `contents.text.verbosity` | **`compact`** | same |
|
|
67
|
+
| `contents.highlights` (boolean form) | **false** | same |
|
|
68
|
+
| `moderation` | **false** | same |
|
|
69
|
+
| `contents.livecrawlTimeout` | **10000 ms** | same |
|
|
70
|
+
| `contents.text.maxCharacters` | **no published default** (max 1,000,000); the [contents quickstart](https://exa.ai/docs/contents/quickstart) frames it as opt-in: "Full pages can be large, so use `maxCharacters` when you need a limit" | both |
|
|
71
|
+
|
|
72
|
+
Like Tavily, Exa exposes no per-result authority/score field and no client filter for one;
|
|
73
|
+
`moderation` (off by default) is content-moderation, not authority.
|
|
74
|
+
|
|
75
|
+
## Perplexity
|
|
76
|
+
|
|
77
|
+
The Sonar chat-completions API was retired on 2026-09-27; the live products are the Search API
|
|
78
|
+
and the Agent API ([migration guide](https://docs.perplexity.ai/docs/agent-api/migrate-from-sonar/overview)).
|
|
79
|
+
|
|
80
|
+
Search API (`POST /search`,
|
|
81
|
+
[reference](https://docs.perplexity.ai/api-reference/search-post); the
|
|
82
|
+
[quickstart](https://docs.perplexity.ai/docs/search/quickstart) restates it):
|
|
83
|
+
|
|
84
|
+
| Parameter | Default when omitted | Source |
|
|
85
|
+
| --- | --- | --- |
|
|
86
|
+
| `max_results` | **10** (1–20) | [quickstart](https://docs.perplexity.ai/docs/search/quickstart): "`max_results` accepts values from 1 to 20 and defaults to 10" |
|
|
87
|
+
| `search_type` | **`web`** | [reference](https://docs.perplexity.ai/api-reference/search-post) |
|
|
88
|
+
|
|
89
|
+
Agent API `web_search` tool ([tool guide](https://docs.perplexity.ai/docs/agent-api/tools/web-search),
|
|
90
|
+
[schema](https://docs.perplexity.ai/api-reference/agent-post)): `max_results` accepts 1–50 and
|
|
91
|
+
`max_tokens`/`max_tokens_per_page` cap search context, but none of the three publishes a numeric
|
|
92
|
+
default — "When omitted, the default budget applies" is all the docs say. The one published
|
|
93
|
+
tool-count default in the same schema is `image_search.max_results`: **5** (1–30)
|
|
94
|
+
([reference](https://docs.perplexity.ai/api-reference/agent-post)). The retired Sonar
|
|
95
|
+
`web_search_options.search_context_size` has no named-size successor; the
|
|
96
|
+
[migration table](https://docs.perplexity.ai/docs/agent-api/migrate-from-sonar/how-to) maps it
|
|
97
|
+
to the token budgets above, and the current docs no longer state its old default. No
|
|
98
|
+
authority/score filtering exists on any of these surfaces.
|
|
99
|
+
|
|
100
|
+
## Firecrawl
|
|
101
|
+
|
|
102
|
+
API defaults from the official OpenAPI references
|
|
103
|
+
([search](https://docs.firecrawl.dev/api-reference/endpoint/search),
|
|
104
|
+
[scrape](https://docs.firecrawl.dev/api-reference/endpoint/scrape)):
|
|
105
|
+
|
|
106
|
+
| Parameter | Default when omitted | Source |
|
|
107
|
+
| --- | --- | --- |
|
|
108
|
+
| search `limit` | **10** (1–100; per source type when multiple `sources`) | [search reference](https://docs.firecrawl.dev/api-reference/endpoint/search) |
|
|
109
|
+
| search `sources` | **`["web"]`** | same |
|
|
110
|
+
| search `timeout` | **60000 ms** | same |
|
|
111
|
+
| search `highlights` | **true** | same |
|
|
112
|
+
| scrape `timeout` | **60000 ms** (min 1 s, max 300 s) | [scrape reference](https://docs.firecrawl.dev/api-reference/endpoint/scrape) |
|
|
113
|
+
| scrape `onlyMainContent` | **true** | same |
|
|
114
|
+
| scrape `maxAge` (cache freshness window) | **172800000 ms (2 days)** | same |
|
|
115
|
+
|
|
116
|
+
No character or byte truncation default is published for scraped content. No authority/score
|
|
117
|
+
filter exists.
|
|
118
|
+
|
|
119
|
+
SDK layer (`@mendable/firecrawl-js` 4.50.0, npm tarball with registry provenance;
|
|
120
|
+
[source](https://www.npmjs.com/package/@mendable/firecrawl-js)): `maxRetries` defaults to
|
|
121
|
+
**3** (`options.maxRetries ?? 3`), retrying **only HTTP 502** with exponential backoff
|
|
122
|
+
(`backoffFactor` 0.5 s × 2^attempt); `timeoutMs` defaults to **300000 ms (5 min)**.
|
|
123
|
+
|
|
124
|
+
## Jina Reader (r.jina.ai / s.jina.ai)
|
|
125
|
+
|
|
126
|
+
Official product page ([jina.ai/reader](https://jina.ai/reader/)) and official repo
|
|
127
|
+
([jina-ai/reader](https://github.com/jina-ai/reader)):
|
|
128
|
+
|
|
129
|
+
| Behavior | Default | Source |
|
|
130
|
+
| --- | --- | --- |
|
|
131
|
+
| Search-mode result count (`s.jina.ai`) | **fixed 5** — "Reader searches the web, fetches the top 5 results, visits each URL, and applies `r.jina.ai` to it"; no count parameter is exposed | [repo README](https://github.com/jina-ai/reader/blob/main/README.md); the [product page](https://jina.ai/reader/) likewise: "it returns a list of five entries" |
|
|
132
|
+
| `x-timeout` | **no default set** — optional header, integer seconds, max 180; when absent the option stays `null` (no client-side deadline) | [README](https://github.com/jina-ai/reader/blob/main/README.md) and [`crawler-options.ts`](https://github.com/jina-ai/reader/blob/main/src/dto/crawler-options.ts) (`instance.timeout ??= null`) |
|
|
133
|
+
| `x-token-budget` | **no default** (parsed only when sent) | [`crawler-options.ts`](https://github.com/jina-ai/reader/blob/main/src/dto/crawler-options.ts) |
|
|
134
|
+
| Content truncation | none published | — |
|
|
135
|
+
|
|
136
|
+
No relevance/authority filter; no retry logic documented.
|
|
137
|
+
|
|
138
|
+
## Anthropic web_search / web_fetch server tools
|
|
139
|
+
|
|
140
|
+
Current docs live at
|
|
141
|
+
[web search tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool),
|
|
142
|
+
[web fetch tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool),
|
|
143
|
+
and the [server tools guide](https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools).
|
|
144
|
+
|
|
145
|
+
| Parameter | Default when omitted | Source |
|
|
146
|
+
| --- | --- | --- |
|
|
147
|
+
| `web_search.max_uses` | optional; no numeric default published ("limits the number of searches performed"; guidance: "Simple factual queries typically use 1–3 searches") | [web search tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool) |
|
|
148
|
+
| `web_fetch.max_uses` | optional; **"There is currently no default limit."** | [web fetch tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool) |
|
|
149
|
+
| `web_fetch.max_content_tokens` | optional token cap; **no default value published** (doc example: 100000) — "If the fetched content exceeds this limit, the tool truncates it … applies to text content, not to binary content such as PDFs" | [web fetch tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool) |
|
|
150
|
+
| `web_fetch` URL length | hard max **250 characters** | same (error `url_too_long`) |
|
|
151
|
+
| `web_fetch` content types | text, HTML, PDF only; `robots.txt` and private addresses respected server-side | same |
|
|
152
|
+
| `web_fetch.use_cache` | **true** | same |
|
|
153
|
+
| `web_fetch.citations` | **disabled by default** | same |
|
|
154
|
+
| `response_inclusion` (both tools) | **`"full"`** | both |
|
|
155
|
+
| Result count / authority filter | **neither exists** — the model decides how many searches to run; no score or authority field is returned | both |
|
|
156
|
+
|
|
157
|
+
A widely repeated pair of numbers — "truncate to 20,000 characters" and "5 MiB" — is **not in
|
|
158
|
+
the current official docs** (checked 2026-10-21), nor in the November 2025 snapshot of the same
|
|
159
|
+
page on the Internet Archive; the published truncation mechanism is the token-based
|
|
160
|
+
`max_content_tokens` parameter above, with no published default.
|
|
161
|
+
|
|
162
|
+
SDK layer (official repos, default branch):
|
|
163
|
+
|
|
164
|
+
| SDK | Default timeout | Default max retries | Source |
|
|
165
|
+
| --- | --- | --- | --- |
|
|
166
|
+
| anthropic-sdk-typescript | **10 minutes** (`options.timeout ?? BaseAnthropic.DEFAULT_TIMEOUT`) | **2** (`options.maxRetries ?? 2`) | [`client.ts`](https://github.com/anthropics/anthropic-sdk-typescript/blob/main/src/client.ts) |
|
|
167
|
+
| anthropic-sdk-python | **600 s total, 5 s connect** (`httpx.Timeout(timeout=10 * 60, connect=5.0)`) | **2** (`DEFAULT_MAX_RETRIES = 2`) | [`_constants.py`](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_constants.py) |
|
|
168
|
+
|
|
169
|
+
## OpenAI Responses web_search
|
|
170
|
+
|
|
171
|
+
From the official guide
|
|
172
|
+
([Web search tool](https://platform.openai.com/docs/guides/tools-web-search)):
|
|
173
|
+
|
|
174
|
+
| Parameter | Default when omitted | Source |
|
|
175
|
+
| --- | --- | --- |
|
|
176
|
+
| Result count | **not exposed** — no count parameter; the docs note the size setting "does not set an exact token count or guarantee a specific number of sources or citations" | [guide](https://platform.openai.com/docs/guides/tools-web-search) |
|
|
177
|
+
| `search_context_size` | **`medium`** — "Use `low` for simple lookups, `medium` for a balanced default, and `high` …" | [guide](https://platform.openai.com/docs/guides/tools-web-search) |
|
|
178
|
+
| `external_web_access` | **true** (live access) | [guide](https://platform.openai.com/docs/guides/tools-web-search) |
|
|
179
|
+
| `return_token_budget` | **`default`** — "Uses the standard returned-token budget … the same behavior as omitting `return_token_budget`" (numeric value unpublished) | [guide](https://platform.openai.com/docs/guides/tools-web-search) |
|
|
180
|
+
|
|
181
|
+
No relevance/authority score or filter is exposed on any web-search surface.
|
|
182
|
+
|
|
183
|
+
SDK layer (official repos, default branch):
|
|
184
|
+
|
|
185
|
+
| SDK | Default timeout | Default max retries | Source |
|
|
186
|
+
| --- | --- | --- | --- |
|
|
187
|
+
| openai-node | **600000 ms (10 min)** (`OpenAI.DEFAULT_TIMEOUT = 600000`) | **2** (`@param {number} [opts.maxRetries=2]`) | [`client.ts`](https://github.com/openai/openai-node/blob/master/src/client.ts) |
|
|
188
|
+
| openai-python | **600 s total, 5 s connect** (`httpx.Timeout(timeout=600, connect=5.0)`) | **2** (`DEFAULT_MAX_RETRIES = 2`); initial retry delay 0.5 s, max 8 s | [`_constants.py`](https://github.com/openai/openai-python/blob/main/src/openai/_constants.py) |
|
|
189
|
+
|
|
190
|
+
## Brave Search API
|
|
191
|
+
|
|
192
|
+
From the official Web Search API query documentation
|
|
193
|
+
([docs](https://api-dashboard.search.brave.com/app/documentation/web-search/query)):
|
|
194
|
+
|
|
195
|
+
| Parameter | Default when omitted | Source |
|
|
196
|
+
| --- | --- | --- |
|
|
197
|
+
| `count` | **20** — "Maximum number of results per page (max 20, default 20). The actual number of results returned may be less than count." | [docs](https://api-dashboard.search.brave.com/app/documentation/web-search/query) |
|
|
198
|
+
| `offset` | 0 (0-based, max 9) | same |
|
|
199
|
+
|
|
200
|
+
No relevance/authority filter beyond `safesearch`-style content controls; ranking is
|
|
201
|
+
server-side.
|
|
202
|
+
|
|
203
|
+
## Linkup
|
|
204
|
+
|
|
205
|
+
From the official OpenAPI reference
|
|
206
|
+
([search reference](https://docs.linkup.so/pages/documentation/endpoints/search/reference))
|
|
207
|
+
and the official Python SDK source
|
|
208
|
+
([linkup-python-sdk](https://github.com/LinkupPlatform/linkup-python-sdk/blob/main/src/linkup/_client.py)):
|
|
209
|
+
|
|
210
|
+
| Parameter | Default when omitted | Source |
|
|
211
|
+
| --- | --- | --- |
|
|
212
|
+
| `depth` | **no published default** — enum `flash`/`fast`/`standard`/`deep`; the spec's prose calls `fast` "the recommended default for most agentic applications" without declaring an omission default. The SDK makes `depth` a required argument | [reference](https://docs.linkup.so/pages/documentation/endpoints/search/reference), [`_client.py`](https://github.com/LinkupPlatform/linkup-python-sdk/blob/main/src/linkup/_client.py) |
|
|
213
|
+
| `maxResults` | **no published default** (min 1; schema example: 5) | [reference](https://docs.linkup.so/pages/documentation/endpoints/search/reference) |
|
|
214
|
+
| `includeImages` / `includeInlineCitations` / `includeSources` | **false** | same |
|
|
215
|
+
| SDK `timeout` | **None — "the request will have no timeout"** | [`_client.py`](https://github.com/LinkupPlatform/linkup-python-sdk/blob/main/src/linkup/_client.py) |
|
|
216
|
+
|
|
217
|
+
The SDK has no retry loop for transient failures (its one retry path is the x402 payment
|
|
218
|
+
handshake). No relevance/authority filter exists.
|
|
219
|
+
|
|
220
|
+
## You.com
|
|
221
|
+
|
|
222
|
+
The API documentation is still public at
|
|
223
|
+
[you.com/docs](https://you.com/docs/api-reference/search/v1-search). Defaults for
|
|
224
|
+
`POST /v1/search` ([reference](https://you.com/docs/api-reference/search/v1-search)):
|
|
225
|
+
|
|
226
|
+
| Parameter | Default when omitted | Source |
|
|
227
|
+
| --- | --- | --- |
|
|
228
|
+
| `count` | **10** — per section (`web` and `news`) | [reference](https://you.com/docs/api-reference/search/v1-search) |
|
|
229
|
+
| `safesearch` | **`moderate`** | same |
|
|
230
|
+
| `crawl_timeout` | **10 s** (1–60) | same |
|
|
231
|
+
| `livecrawl_formats` (deprecated) | **`["html"]`** | same |
|
|
232
|
+
| `extraction.highlights.total_max_tokens` | **8192 tokens** (range 1024–8192; "Omit it to get the default budget of 8192") | same |
|
|
233
|
+
| `extraction.full_page.extraction_formats` | **`["markdown"]`** | same |
|
|
234
|
+
| Result content | **snippets by default**; highlights/full-page are opt-in via `extraction` | same |
|
|
235
|
+
|
|
236
|
+
`moderate` safesearch is a content-moderation filter, not an authority filter; no
|
|
237
|
+
relevance/authority score is exposed.
|
|
238
|
+
|
|
239
|
+
## What DeepSeek itself claims
|
|
240
|
+
|
|
241
|
+
The challenge quote attributed to the DeepSeek docs — an "AI 原生的通用搜索引擎" that
|
|
242
|
+
"通过严格的识别机制进行过滤,确保向用户与 LLM 呈现权威可信的信息" — is **not present** on
|
|
243
|
+
<https://api-docs.deepseek.com/guides/search> (checked 2026-10-21, English and 中文 pages).
|
|
244
|
+
The closest positioning sentences actually on the page:
|
|
245
|
+
|
|
246
|
+
- EN: "It is powered by DeepSeek's in-house search engine."
|
|
247
|
+
([guide](https://api-docs.deepseek.com/guides/search))
|
|
248
|
+
- ZH: "该接口由 DeepSeek 自研搜索引擎提供支持。"
|
|
249
|
+
([指南](https://api-docs.deepseek.com/zh-cn/guides/search))
|
|
250
|
+
|
|
251
|
+
So the official docs claim an in-house engine but make **no published claim of server-side
|
|
252
|
+
quality filtering**. What they do publish, verbatim
|
|
253
|
+
([指南](https://api-docs.deepseek.com/zh-cn/guides/search)):
|
|
254
|
+
|
|
255
|
+
- `rerank_score`: "排序分数,0~3 分,综合考虑相关性、权威性、时效性等维度,**大于等于 1.5 分为优质结果**。"
|
|
256
|
+
- `authority`: "网页权威性,0~4(**-1 表示未知**),**大于等于 3 为极权威结果**。"
|
|
257
|
+
- Request defaults: `count` "否 / 默认值 10 / 返回条数,1~50"; `need_content` "否 / false";
|
|
258
|
+
`localization` "否 / 空"; `ori_question` optional.
|
|
259
|
+
- Response sizing: `snippet` "短摘要 … 通常为 100~200 字符"; `summary` "长摘要 … 通常为 600~800 字符".
|
|
260
|
+
|
|
261
|
+
## What this means for this repo's defaults
|
|
262
|
+
|
|
263
|
+
Fact-by-fact alignment of the repo's client-side defaults
|
|
264
|
+
(`src/core/constants.ts`) against the surveyed factory defaults. No recommendation is made
|
|
265
|
+
here; the table only lines up what the industry ships.
|
|
266
|
+
|
|
267
|
+
| Repo default | Industry factory defaults observed above |
|
|
268
|
+
| --- | --- |
|
|
269
|
+
| API `count=10`, client `maxResults=10` (post-dedup cap; `5` before 2026-10-21) | API-level count defaults: Tavily 10, Exa 10, Perplexity Search API 10, Firecrawl 10, You.com 10 (per section), Brave 20. Post-filter caps are uncommon; a fixed 5 exists at Jina (`s.jina.ai` top 5, not configurable) and Perplexity's `image_search` tool (default 5). Linkup's schema example is 5 but no default is published. OpenAI and Anthropic expose no count at all |
|
|
270
|
+
| `minRerank=0`, `minAuthority=0`, `allowUnknownAuthority=true` — no client-side filtering (previously `1.5`/`2`/`false`) | **No surveyed product filters search results client-side by relevance score or authority.** The only published thresholds for DeepSeek's own fields are the docs' quality labels (≥1.5 "优质", ≥3 "极权威") — labels, not filters. The closest shipped analogues are domain allow/block lists (Tavily, Exa, Perplexity, You.com, Anthropic, Brave) and You.com's `safesearch: moderate` default, which is content moderation, not authority |
|
|
271
|
+
| `maxRetries=0` | Official model-API SDKs: OpenAI 2, Anthropic 2 (both languages). Search-API SDKs: firecrawl-js 3 (502 only), tavily-python 0, Linkup SDK 0 |
|
|
272
|
+
| `timeout=30s` (search and fetch, 1–120 s range, covers body read) | Search/scrape API timeouts: Firecrawl 60 s (scrape max 300 s), Tavily SDK search 60 s (cap 120 s) / extract 30 s, You.com `crawl_timeout` 10 s, Linkup SDK no timeout, Jina `x-timeout` unset by default (max 180 s). Model-API SDKs: OpenAI and Anthropic 10 minutes |
|
|
273
|
+
| Fetch truncation 16,000 chars | Exa: page text **off** by default (`contents.text: false`), opt-in `maxCharacters` with no published default; DeepSeek itself: `need_content: false` by default; Anthropic `web_fetch`: token-based `max_content_tokens`, no published default (example 100000), no char/MiB figure in current docs; You.com highlights budget 8192 tokens; Firecrawl and Jina publish no truncation default |
|
|
274
|
+
| Summary truncation 1,200 chars | DeepSeek's own field doc says `summary` is "通常为 600~800 字符"; no surveyed vendor ships a client-side summary cap (they return snippets/highlights sized server-side: Exa verbosity `compact`, You.com highlights budget) |
|
|
275
|
+
| Response body cap 5 MiB | No surveyed product publishes a response-body byte cap; the only published byte-adjacent limits are Anthropic's URL length (250 chars) and content-type whitelist, and Exa's `maxCharacters` ceiling of 1,000,000 characters |
|
|
276
|
+
| Filter markers (`minRerank`/`minAuthority` matching) | Nothing to compare: no surveyed vendor returns a per-result authority tier at all — DeepSeek's `rerank_score`/`authority` response fields are the outlier, which is what makes client-side thresholds possible here and nowhere else in this survey |
|
|
277
|
+
|
|
278
|
+
## Sources
|
|
279
|
+
|
|
280
|
+
- DeepSeek: [Search & Fetch guide (EN)](https://api-docs.deepseek.com/guides/search) ·
|
|
281
|
+
[网页搜索与抓取 (ZH)](https://api-docs.deepseek.com/zh-cn/guides/search)
|
|
282
|
+
- Tavily: [search API reference](https://docs.tavily.com/documentation/api-reference/endpoint/search) ·
|
|
283
|
+
[tavily-python source](https://github.com/tavily-ai/tavily-python/blob/master/tavily/tavily.py)
|
|
284
|
+
- Exa: [search reference (OpenAPI)](https://exa.ai/docs/reference/search) ·
|
|
285
|
+
[search quickstart](https://exa.ai/docs/search/quickstart) ·
|
|
286
|
+
[contents quickstart](https://exa.ai/docs/contents/quickstart)
|
|
287
|
+
- Perplexity: [Search API quickstart](https://docs.perplexity.ai/docs/search/quickstart) ·
|
|
288
|
+
[Search API reference](https://docs.perplexity.ai/api-reference/search-post) ·
|
|
289
|
+
[Agent API web_search tool](https://docs.perplexity.ai/docs/agent-api/tools/web-search) ·
|
|
290
|
+
[Agent API schema](https://docs.perplexity.ai/api-reference/agent-post) ·
|
|
291
|
+
[Sonar migration guide](https://docs.perplexity.ai/docs/agent-api/migrate-from-sonar/how-to)
|
|
292
|
+
- Firecrawl: [search reference](https://docs.firecrawl.dev/api-reference/endpoint/search) ·
|
|
293
|
+
[scrape reference](https://docs.firecrawl.dev/api-reference/endpoint/scrape) ·
|
|
294
|
+
[npm @mendable/firecrawl-js](https://www.npmjs.com/package/@mendable/firecrawl-js)
|
|
295
|
+
- Jina: [reader product page](https://jina.ai/reader/) ·
|
|
296
|
+
[jina-ai/reader README](https://github.com/jina-ai/reader/blob/main/README.md) ·
|
|
297
|
+
[crawler-options.ts](https://github.com/jina-ai/reader/blob/main/src/dto/crawler-options.ts)
|
|
298
|
+
- Anthropic: [web search tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-search-tool) ·
|
|
299
|
+
[web fetch tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/web-fetch-tool) ·
|
|
300
|
+
[server tools](https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools) ·
|
|
301
|
+
[anthropic-sdk-typescript client.ts](https://github.com/anthropics/anthropic-sdk-typescript/blob/main/src/client.ts) ·
|
|
302
|
+
[anthropic-sdk-python _constants.py](https://github.com/anthropics/anthropic-sdk-python/blob/main/src/anthropic/_constants.py)
|
|
303
|
+
- OpenAI: [web search tool guide](https://platform.openai.com/docs/guides/tools-web-search) ·
|
|
304
|
+
[openai-node client.ts](https://github.com/openai/openai-node/blob/master/src/client.ts) ·
|
|
305
|
+
[openai-python _constants.py](https://github.com/openai/openai-python/blob/main/src/openai/_constants.py)
|
|
306
|
+
- Brave: [Web Search API query docs](https://api-dashboard.search.brave.com/app/documentation/web-search/query)
|
|
307
|
+
- Linkup: [search reference (OpenAPI)](https://docs.linkup.so/pages/documentation/endpoints/search/reference) ·
|
|
308
|
+
[linkup-python-sdk _client.py](https://github.com/LinkupPlatform/linkup-python-sdk/blob/main/src/linkup/_client.py)
|
|
309
|
+
- You.com: [POST /v1/search reference](https://you.com/docs/api-reference/search/v1-search)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Pi extension config: ~/.pi/agent/settings.json (user) or .pi/settings.json (project).
|
|
3
|
+
// "packages" sources resolve at session start; the first launch fetches
|
|
4
|
+
// npm:deepseek-web-retrieval from the registry (pi update --extensions refreshes it).
|
|
5
|
+
// The key never enters this file: the extension reads DEEPSEEK_API_KEY from the
|
|
6
|
+
// environment of the Pi process itself.
|
|
7
|
+
"packages": [
|
|
8
|
+
"npm:deepseek-web-retrieval"
|
|
9
|
+
],
|
|
10
|
+
// Optional: the off switches the installer writes; they outrank the
|
|
11
|
+
// DEEPSEEK_ENABLE_* environment variables. Pi preserves unknown keys like
|
|
12
|
+
// this namespace on read and on its own rewrites.
|
|
13
|
+
"deepseekWebRetrieval": {
|
|
14
|
+
// "enableSearch": false,
|
|
15
|
+
// "enableFetch": false
|
|
16
|
+
}
|
|
17
|
+
}
|
package/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
1
|
+
export * from "./src/core/index";
|
|
2
|
+
export { default } from "./src/opencode/plugin";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "deepseek-web-retrieval",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"description": "Token-efficient DeepSeek Search and Fetch for coding agents, starting with OpenCode v2.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
"keywords": [
|
|
15
15
|
"opencode",
|
|
16
16
|
"opencode-plugin",
|
|
17
|
+
"pi",
|
|
18
|
+
"pi-extension",
|
|
17
19
|
"deepseek",
|
|
18
20
|
"websearch",
|
|
19
21
|
"webfetch",
|
|
@@ -23,7 +25,13 @@
|
|
|
23
25
|
"exports": {
|
|
24
26
|
".": "./index.ts",
|
|
25
27
|
"./core": "./src/core/index.ts",
|
|
26
|
-
"./mcp": "./src/mcp/server.ts"
|
|
28
|
+
"./mcp": "./src/mcp/server.ts",
|
|
29
|
+
"./pi": "./src/pi/extension.ts"
|
|
30
|
+
},
|
|
31
|
+
"pi": {
|
|
32
|
+
"extensions": [
|
|
33
|
+
"./src/pi/extension.ts"
|
|
34
|
+
]
|
|
27
35
|
},
|
|
28
36
|
"bin": {
|
|
29
37
|
"deepseek-web-retrieval": "dist/cli.js"
|
|
@@ -39,19 +47,42 @@
|
|
|
39
47
|
"examples"
|
|
40
48
|
],
|
|
41
49
|
"scripts": {
|
|
50
|
+
"lint": "biome check --error-on-warnings .",
|
|
51
|
+
"lint:ci": "biome ci --error-on-warnings .",
|
|
52
|
+
"lint:fix": "biome check --write --error-on-warnings .",
|
|
53
|
+
"format": "biome format --write .",
|
|
42
54
|
"typecheck": "tsc --noEmit",
|
|
43
55
|
"build": "bun build src/mcp/cli.ts --target=node --format=esm --outdir=dist --external @modelcontextprotocol/server --external @modelcontextprotocol/server/stdio --external zod --external zod/v4",
|
|
44
|
-
"prepublishOnly": "bun run
|
|
56
|
+
"prepublishOnly": "bun run check:release",
|
|
45
57
|
"test": "bun test",
|
|
58
|
+
"test:package": "node scripts/test-package.mjs",
|
|
59
|
+
"test:e2e:keyless": "bun run test:e2e pi pi-extension installer reinit upgrade pkg capability-off",
|
|
60
|
+
"check:release": "bun run check && bun run test:package && bun run test:e2e:keyless",
|
|
46
61
|
"test:e2e": "bun run test/e2e/run.ts",
|
|
47
62
|
"docs:matrix": "bun run scripts/render-matrix.ts",
|
|
48
63
|
"test:coverage": "bun test --coverage",
|
|
49
|
-
"check": "bun run typecheck && bun run docs:matrix --check && bun run build && bun test"
|
|
64
|
+
"check": "bun run lint && bun run typecheck && bun run docs:matrix --check && bun run build && bun test"
|
|
50
65
|
},
|
|
51
66
|
"peerDependencies": {
|
|
67
|
+
"@earendil-works/pi-ai": "^1.3.0",
|
|
68
|
+
"@earendil-works/pi-coding-agent": "^1.3.0",
|
|
52
69
|
"@opencode/plugin": "^2.0.32"
|
|
53
70
|
},
|
|
71
|
+
"peerDependenciesMeta": {
|
|
72
|
+
"@earendil-works/pi-ai": {
|
|
73
|
+
"optional": true
|
|
74
|
+
},
|
|
75
|
+
"@earendil-works/pi-coding-agent": {
|
|
76
|
+
"optional": true
|
|
77
|
+
},
|
|
78
|
+
"@opencode/plugin": {
|
|
79
|
+
"optional": true
|
|
80
|
+
}
|
|
81
|
+
},
|
|
54
82
|
"devDependencies": {
|
|
83
|
+
"@biomejs/biome": "2.5.15",
|
|
84
|
+
"@earendil-works/pi-ai": "1.3.0",
|
|
85
|
+
"@earendil-works/pi-coding-agent": "1.3.0",
|
|
55
86
|
"@modelcontextprotocol/client": "^2.3.1",
|
|
56
87
|
"@opencode/plugin": "2.0.32",
|
|
57
88
|
"@types/bun": "1.4.0",
|
package/src/core/auth.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { API_KEY_ENV } from "./constants"
|
|
1
|
+
import { API_KEY_ENV } from "./constants";
|
|
2
2
|
|
|
3
|
-
export function apiKeyFromEnv(
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const key = env[API_KEY_ENV]?.trim()
|
|
7
|
-
return key ? key : undefined
|
|
3
|
+
export function apiKeyFromEnv(env: Readonly<Record<string, string | undefined>> = process.env): string | undefined {
|
|
4
|
+
const key = env[API_KEY_ENV]?.trim();
|
|
5
|
+
return key ? key : undefined;
|
|
8
6
|
}
|