opencode-search-plugin 3.2.0 → 3.3.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/README.md +147 -128
- package/README.zh-CN.md +154 -135
- package/index.ts +3 -1
- package/package.json +3 -2
- package/plugins/zhipu-search.ts +426 -0
package/README.zh-CN.md
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
[English](README.md) · **简体中文**
|
|
2
|
-
|
|
3
1
|
# opencode-search-plugin
|
|
4
2
|
|
|
3
|
+
[English](README.md) · **简体中文**
|
|
4
|
+
|
|
5
5
|
[](https://www.npmjs.com/package/opencode-search-plugin)
|
|
6
6
|
[](https://www.npmjs.com/package/opencode-search-plugin)
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
**无需 API key,开箱即用的 OpenCode 网页搜索插件。**
|
|
10
10
|
|
|
11
|
-
AnySearch 和 Keenable
|
|
11
|
+
AnySearch 和 Keenable 支持免配置直接使用。其余 provider 仅在配置对应 API key 后才会激活,避免产生意外账单。
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
在 OpenCode 的 `random` 模式下,当某个 provider 遇到 HTTP 429 限流时,系统会自动切换至下一个可用服务。未配置 key 的 provider 不会进入候选池,避免请求发送至未配置的服务。
|
|
14
14
|
|
|
15
15
|
```sh
|
|
16
16
|
opencode plugin add opencode-search-plugin
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
安装完成后,直接向 OpenCode 提问即可进行联网检索。
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## 跳过 provider 选择提示
|
|
22
22
|
|
|
23
|
-
初次搜索时,OpenCode
|
|
23
|
+
初次搜索时,OpenCode 默认会提示选择搜索服务。在配置中设置 `websearch.provider` 即可跳过此提示:
|
|
24
24
|
|
|
25
25
|
```jsonc
|
|
26
26
|
{
|
|
@@ -29,37 +29,37 @@ opencode plugin add opencode-search-plugin
|
|
|
29
29
|
}
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
`"random"`
|
|
32
|
+
`"random"` 会在单个会话中固定使用一个 provider,遇到限流时自动回退至其他可用服务。也可以填写具体 ID(如 `"osp-brave"`)指定固定 provider,或设为 `false` 完全禁用联网搜索。
|
|
33
33
|
|
|
34
34
|
<!-- TODO: 录一段 10 秒 GIF:
|
|
35
35
|
配置 websearch.provider -> 提问 -> provider 正常应答带引用 -->
|
|
36
36
|
|
|
37
|
-
##
|
|
37
|
+
## 支持的 Provider
|
|
38
38
|
|
|
39
|
-
[AnySearch](https://www.anysearch.com/) · [Bocha](https://bocha.ai/) · [Brave Search](https://brave.com/search/api/) · [DeepSeek](https://api-docs.deepseek.com/guides/search/) · [Jina](https://jina.ai/) · [Keenable](https://keenable.ai/) · [Linkup](https://www.linkup.so/) · [Metaso](https://metaso.cn/) · [Ollama](https://ollama.com/) · [Perplexity](https://www.perplexity.ai/) · [Querit](https://querit.ai/) · [SerpApi](https://serpapi.com/) · [Serper](https://serper.dev/) · [You.com](https://you.com/)
|
|
39
|
+
[AnySearch](https://www.anysearch.com/) · [Bocha](https://bocha.ai/) · [Brave Search](https://brave.com/search/api/) · [DeepSeek](https://api-docs.deepseek.com/guides/search/) · [Jina](https://jina.ai/) · [Keenable](https://keenable.ai/) · [Linkup](https://www.linkup.so/) · [Metaso](https://metaso.cn/) · [Ollama](https://ollama.com/) · [Perplexity](https://www.perplexity.ai/) · [Querit](https://querit.ai/) · [SerpApi](https://serpapi.com/) · [Serper](https://serper.dev/) · [You.com](https://you.com/) · [Zhipu](https://bigmodel.cn/)
|
|
40
40
|
|
|
41
41
|
## 为什么做这个插件
|
|
42
42
|
|
|
43
|
-
OpenCode v2
|
|
43
|
+
OpenCode v2 内置了部分搜索服务:`exa`、`firecrawl`、`parallel`、`tavily` 与 `tinyfish`。此外,市面上许多外部搜索 API 同样提供免费层级或充足的免费调用额度。
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
本插件将这些搜索服务接入 OpenCode:
|
|
46
46
|
|
|
47
|
-
- AnySearch 和 Keenable
|
|
48
|
-
-
|
|
49
|
-
- 扩充 OpenCode `random`
|
|
47
|
+
- AnySearch 和 Keenable 无需 API key 或注册账号即可直接使用。
|
|
48
|
+
- 多家服务提供免费额度,便于搭建低成本的备用搜索池。
|
|
49
|
+
- 扩充 OpenCode 的 `random` 模式候选池:单家服务返回 HTTP 429 时,OpenCode 会自动使用其他 provider 重试,保障搜索连续性。
|
|
50
50
|
|
|
51
51
|
## 安装
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
请根据使用需求选择安装方式。**推荐使用 npm**:发布的版本具有不可变性,使用 `@<version>` 锁定版本可确保构建始终一致。
|
|
54
54
|
|
|
55
55
|
### 1. 从 npm 安装(推荐)
|
|
56
56
|
|
|
57
57
|
```sh
|
|
58
|
-
# 追加 @<version>
|
|
58
|
+
# 追加 @<version> 可固定到指定版本
|
|
59
59
|
opencode plugin add opencode-search-plugin
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
或在 `opencode.json(c)` 中声明:
|
|
63
63
|
|
|
64
64
|
```jsonc
|
|
65
65
|
{
|
|
@@ -71,11 +71,11 @@ opencode plugin add opencode-search-plugin
|
|
|
71
71
|
### 2. 从 GitHub 安装
|
|
72
72
|
|
|
73
73
|
```sh
|
|
74
|
-
# 追加 #v<version>
|
|
74
|
+
# 追加 #v<version> 可固定到指定 tag
|
|
75
75
|
opencode plugin add github:guotree/opencode-search-plugin
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
或在 `opencode.json(c)` 中声明:
|
|
79
79
|
|
|
80
80
|
```jsonc
|
|
81
81
|
{
|
|
@@ -86,24 +86,24 @@ opencode plugin add github:guotree/opencode-search-plugin
|
|
|
86
86
|
|
|
87
87
|
### 3. 本地复制文件
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
每个 provider 插件均为独立的单个 `.ts` 文件,无相对导入且无需构建步骤。将其放置于 OpenCode 自动发现插件的目录即可:
|
|
90
90
|
|
|
91
91
|
```text
|
|
92
92
|
~/.config/opencode/plugins/ # 全局
|
|
93
|
-
<project>/.opencode/plugins/ #
|
|
93
|
+
<project>/.opencode/plugins/ # 项目级别
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
若放置于非自动发现目录,需在配置中显式指定文件路径:
|
|
97
97
|
|
|
98
98
|
```jsonc
|
|
99
99
|
{ "plugins": ["./plugins/brave-search.ts"] }
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
>
|
|
102
|
+
> 请勿同时安装 npm 包并复制单独的插件文件。两者注册的是同一批 provider ID,会导致搜索池中出现重复服务。
|
|
103
103
|
|
|
104
|
-
###
|
|
104
|
+
### 过滤不需要的 Provider
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
安装插件包后会注册所有 provider,但未配置 API key 的 provider 会保持未激活状态(参见[密钥](#密钥))。如需完全排除或限定特定 provider,可使用 `disable` 或 `enable` 配置项:
|
|
107
107
|
|
|
108
108
|
```jsonc
|
|
109
109
|
{
|
|
@@ -116,200 +116,205 @@ opencode plugin add github:guotree/opencode-search-plugin
|
|
|
116
116
|
}
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
- `disable
|
|
120
|
-
- `enable
|
|
119
|
+
- `disable`:Provider ID 黑名单(参见下表)。由于 AnySearch 和 Keenable 无需 key 即可使用,`disable` 是将其移出搜索池的唯一方式。
|
|
120
|
+
- `enable`:Provider ID 白名单。仅注册指定的 ID,例如 `"enable": ["osp-brave", "osp-jina"]` 仅激活这两项。
|
|
121
121
|
|
|
122
|
-
|
|
122
|
+
若同时配置两者,**重叠项以 `disable` 为准**:
|
|
123
123
|
|
|
124
124
|
```jsonc
|
|
125
125
|
{
|
|
126
126
|
"options": {
|
|
127
127
|
"enable": ["osp-brave", "osp-jina", "osp-serper"],
|
|
128
128
|
"disable": ["osp-serper", "osp-youcom"]
|
|
129
|
-
// osp-serper
|
|
130
|
-
// osp-youcom
|
|
129
|
+
// osp-serper 会被排除:disable 优先级高于 enable。
|
|
130
|
+
// osp-youcom 本身不在 enable 中,会被安全忽略。
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
```
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
生效集合为 `enable - disable`。重叠项会被自动剔除;若包含无效或未识别的 ID,插件会在日志中输出警告,而非静默失败。
|
|
136
136
|
|
|
137
137
|
## 升级
|
|
138
138
|
|
|
139
139
|
```sh
|
|
140
|
-
# 从 npm
|
|
140
|
+
# 从 npm 安装
|
|
141
141
|
opencode plugin update opencode-search-plugin
|
|
142
|
-
# 从 GitHub
|
|
142
|
+
# 从 GitHub 安装
|
|
143
143
|
opencode plugin update github:guotree/opencode-search-plugin
|
|
144
144
|
# 更新所有过期插件
|
|
145
145
|
opencode plugin update
|
|
146
146
|
```
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
更新时需使用安装时配置的插件标识符(specifier):
|
|
149
|
+
- 从 npm 安装的,使用包名(`opencode-search-plugin`)。
|
|
150
|
+
- 从 GitHub 安装的,需使用完整的 `github:` 格式(若仅指定裸包名会提示 `Plugin is not configured`)。
|
|
151
|
+
|
|
152
|
+
运行 `opencode plugin check` 可先查看有哪些插件需要更新。未锁定版本的安装会更新至最新版本;锁定版本的安装(npm 为 `@<version>`,GitHub 为 `#v<version>`)会保持在指定版本,直至修改 `opencode.json(c)` 或使用新版本重新执行 `plugin add`。本地复制的文件直接用新版本覆盖旧文件即可。
|
|
149
153
|
|
|
150
154
|
## 卸载
|
|
151
155
|
|
|
152
156
|
```sh
|
|
153
|
-
# 从 npm
|
|
157
|
+
# 从 npm 安装
|
|
154
158
|
opencode plugin remove opencode-search-plugin
|
|
155
|
-
# 从 GitHub
|
|
159
|
+
# 从 GitHub 安装
|
|
156
160
|
opencode plugin remove github:guotree/opencode-search-plugin
|
|
157
161
|
```
|
|
158
162
|
|
|
159
|
-
|
|
163
|
+
卸载时同样需要传入安装时使用的插件标识符。该命令会更新全局配置。如果插件是在 `opencode.json(c)` 的 `plugins` 条目中声明或作为本地文件复制的,直接删除配置项或删除复制的 `.ts` 文件即可。`/connect` 中保存的凭据不会被清除,重新安装后可自动识别。若仅需关闭部分 provider 而非整个插件,请使用上文介绍的 `enable` / `disable` 配置项。
|
|
160
164
|
|
|
161
165
|
## 密钥
|
|
162
166
|
|
|
163
|
-
除 AnySearch 和 Keenable
|
|
167
|
+
除 AnySearch 和 Keenable 外,其余 provider 均需要 API key。可通过以下两种方式之一提供凭据:
|
|
164
168
|
|
|
165
|
-
- **OpenCode 内的 `/connect`**:按 provider
|
|
166
|
-
-
|
|
169
|
+
- **OpenCode 内的 `/connect`**:按 provider 存储,支持无需重启即时轮换,且不受环境变量变动影响。
|
|
170
|
+
- **环境变量**:作为兜底读取,适用于无界面、自动化或 CI 环境。
|
|
167
171
|
|
|
168
|
-
|
|
172
|
+
环境变量使用 `OSP_<PROVIDER>_API_KEY` 命名空间前缀(例如 `OSP_BRAVE_API_KEY`),避免与其他工具导出的同厂商变量名发生命名冲突。`/connect` 中配置的凭据始终优先于环境变量。
|
|
169
173
|
|
|
170
|
-
|
|
174
|
+
未配置 key 的 provider 会保持未绑定状态:它不会进入搜索池,确保 `"provider": "random"` 绝不会将查询路由至注定失败的服务。
|
|
171
175
|
|
|
172
|
-
AnySearch 和 Keenable
|
|
176
|
+
AnySearch 和 Keenable 是例外情况。两者均包含匿名层级并默认注册,仅在配置 key 时附带认证凭据头。对于 Keenable,两种层级使用独立额度:配置 key 每月享有 100,000 次免费请求;免 key 请求改走 `/public` 端点,受速率限制(单个 IP 每小时 1,000 次、每秒 10 次,且与同一出口 IP 的其他用户共享)。配置 API key 可消除对共享 IP 限流的依赖。
|
|
173
177
|
|
|
174
|
-
|
|
178
|
+
配置好密钥后,由 `websearch.provider` 控制路由方式:`"random"` 会将查询分散至所有已绑定的 provider(参见[跳过 provider 选择提示](#跳过-provider-选择提示));填写具体 ID(如 `"osp-brave"`)则固定使用该 provider;设为 `false` 则完全关闭网页搜索。
|
|
175
179
|
|
|
176
|
-
##
|
|
180
|
+
## Provider 列表
|
|
177
181
|
|
|
178
|
-
下表中的 ID 均带有 `osp-` 前缀,用以避免与 OpenCode 内置渠道或官方插件命名冲突(它们使用的是 `exa`、`tavily`
|
|
182
|
+
下表中的 ID 均带有 `osp-` 前缀,用以避免与 OpenCode 内置渠道或官方插件命名冲突(它们使用的是 `exa`、`tavily` 这类直接名称)。在 `websearch.provider` 和 `enable` / `disable` 中请使用带前缀的完整 ID。
|
|
179
183
|
|
|
180
|
-
在 OpenCode 的 `/connect` 界面中,本插件的条目会带有 `(osp)` 后缀(如 `DeepSeek (osp)
|
|
184
|
+
在 OpenCode 的 `/connect` 界面中,本插件的条目会带有 `(osp)` 后缀(如 `DeepSeek (osp)`),方便与内置同名服务区分。搜索池内部仍会显示无后缀的干净名称。
|
|
181
185
|
|
|
182
|
-
|
|
|
186
|
+
| Provider | ID | 密钥(环境变量 / `/connect`) | 匿名可用 | 说明 |
|
|
183
187
|
| --- | --- | --- | --- | --- |
|
|
184
|
-
| AnySearch | `osp-anysearch` | `OSP_ANYSEARCH_API_KEY` | 是 | 按 IP
|
|
185
|
-
| Bocha | `osp-bocha` | `OSP_BOCHA_API_KEY` | 否 | 结果格式兼容 Bing
|
|
188
|
+
| AnySearch | `osp-anysearch` | `OSP_ANYSEARCH_API_KEY` | 是 | 按 IP 提供免费额度;意图路由,`cn` / `intl` 分区 |
|
|
189
|
+
| Bocha | `osp-bocha` | `OSP_BOCHA_API_KEY` | 否 | 结果格式兼容 Bing;按搜索次数计费,请求摘要时另按 token 计费 |
|
|
186
190
|
| Brave Search | `osp-brave` | `OSP_BRAVE_API_KEY` | 否 | 独立索引,最多 20 条结果 |
|
|
187
191
|
| DeepSeek | `osp-deepseek` | `OSP_DEEPSEEK_API_KEY` | 否 | 自研搜索引擎;每千次成功请求 5 元;限速 5 QPS |
|
|
188
|
-
| Jina | `osp-jina` | `OSP_JINA_API_KEY` | 否 | 页面正文按 token
|
|
189
|
-
| Keenable | `osp-keenable` | `OSP_KEENABLE_API_KEY` | 是 |
|
|
190
|
-
| Linkup | `osp-linkup` | `OSP_LINKUP_API_KEY` | 否 |
|
|
191
|
-
| Metaso | `osp-metaso` | `OSP_METASO_API_KEY` | 否 |
|
|
192
|
-
| Ollama | `osp-ollama` | `OSP_OLLAMA_API_KEY` | 否 |
|
|
193
|
-
| Perplexity | `osp-perplexity` | `OSP_PERPLEXITY_API_KEY` | 否 | Search API
|
|
194
|
-
| Querit | `osp-querit` | `OSP_QUERIT_API_KEY` | 否 |
|
|
195
|
-
| SerpApi | `osp-serpapi` | `OSP_SERPAPI_API_KEY` | 否 | 经 SerpApi 调用 Google
|
|
192
|
+
| Jina | `osp-jina` | `OSP_JINA_API_KEY` | 否 | 页面正文按 token 计费,因此默认不获取 |
|
|
193
|
+
| Keenable | `osp-keenable` | `OSP_KEENABLE_API_KEY` | 是 | 配置 key 每月享有 100,000 次免费请求;免 key 层级按 IP 限速 |
|
|
194
|
+
| Linkup | `osp-linkup` | `OSP_LINKUP_API_KEY` | 否 | 四档推理深度:`flash`、`fast`、`standard`、`deep` |
|
|
195
|
+
| Metaso | `osp-metaso` | `OSP_METASO_API_KEY` | 否 | 按次搜索计费,不按结果条数计费 |
|
|
196
|
+
| Ollama | `osp-ollama` | `OSP_OLLAMA_API_KEY` | 否 | 个人档免费;每条结果包含整页 markdown,上下文偏重;上限 10 条,且不带发布日期 |
|
|
197
|
+
| Perplexity | `osp-perplexity` | `OSP_PERPLEXITY_API_KEY` | 否 | Search API 直接返回搜索结果,不包含生成的问答正文;按请求计费,每千次 5 美元,使用 `fast` 则为 1 美元 |
|
|
198
|
+
| Querit | `osp-querit` | `OSP_QUERIT_API_KEY` | 否 | 摘要缺失时回退至句子级匹配 |
|
|
199
|
+
| SerpApi | `osp-serpapi` | `OSP_SERPAPI_API_KEY` | 否 | 经 SerpApi 调用 Google;包含 SerpApi 自带的免费 1 小时服务端缓存 |
|
|
196
200
|
| Serper | `osp-serper` | `OSP_SERPER_API_KEY` | 否 | 经 Serper 调用 Google;按查询消耗积分计费 |
|
|
197
|
-
| You.com | `osp-youcom` | `OSP_YDC_API_KEY` | 否 |
|
|
201
|
+
| You.com | `osp-youcom` | `OSP_YDC_API_KEY` | 否 | 网页与新闻结果合并;提供多种正文抽取模式 |
|
|
202
|
+
| Zhipu | `osp-zhipu` | `OSP_ZHIPU_API_KEY` | 否 | 独立搜索接口,不经过模型调用;按次计费,Search-Std 每次 0.01 元起,无免费额度;四款引擎(含搜狗、夸克);支持 `cn` / `intl` 两站点 |
|
|
198
203
|
|
|
199
204
|
## 配置
|
|
200
205
|
|
|
201
|
-
|
|
206
|
+
配置项以环境变量形式在启动时加载。如修改了变量,需重启 OpenCode 方可生效。默认值均对齐上游 API 文档推荐。
|
|
202
207
|
|
|
203
|
-
###
|
|
208
|
+
### 通用配置(所有 Provider)
|
|
204
209
|
|
|
205
|
-
| 变量 | 默认值 |
|
|
210
|
+
| 变量 | 默认值 | 说明 |
|
|
206
211
|
| --- | --- | --- |
|
|
207
|
-
| `<PROVIDER>_CACHE_TTL` | `600000` |
|
|
208
|
-
| `<PROVIDER>_TIMEOUT` | `25000` |
|
|
212
|
+
| `<PROVIDER>_CACHE_TTL` | `600000` | 相同归一化查询复用缓存响应的毫秒数(`0` 表示禁用缓存) |
|
|
213
|
+
| `<PROVIDER>_TIMEOUT` | `25000` | 单次请求的超时毫秒数(`0` 表示取消超时限制,但保留取消信号) |
|
|
209
214
|
|
|
210
215
|
### AnySearch
|
|
211
216
|
|
|
212
|
-
| 变量 | 默认值 |
|
|
217
|
+
| 变量 | 默认值 | 说明 |
|
|
213
218
|
| --- | --- | --- |
|
|
214
219
|
| `ANYSEARCH_MAX_RESULTS` | `10` | 每次搜索的结果数,限制在 API 允许的 1–10 |
|
|
215
|
-
| `ANYSEARCH_TAG` | — |
|
|
216
|
-
| `ANYSEARCH_ZONE` | — |
|
|
220
|
+
| `ANYSEARCH_TAG` | — | 固定意图路由的子领域,例如 `code.doc` |
|
|
221
|
+
| `ANYSEARCH_ZONE` | — | 区域分区:`cn` 或 `intl` |
|
|
217
222
|
| `ANYSEARCH_LANGUAGE` | — | 首选结果语言,例如 `zh-CN` |
|
|
218
|
-
| `ANYSEARCH_FORMAT` | `markdown` | content
|
|
219
|
-
| `OSP_ANYSEARCH_API_KEY` | — |
|
|
223
|
+
| `ANYSEARCH_FORMAT` | `markdown` | `content` 字段格式:`markdown` 或 `json` |
|
|
224
|
+
| `OSP_ANYSEARCH_API_KEY` | — | 可选;未配置时使用免 key 匿名访问 |
|
|
220
225
|
|
|
221
226
|
### Bocha
|
|
222
227
|
|
|
223
|
-
| 变量 | 默认值 |
|
|
228
|
+
| 变量 | 默认值 | 说明 |
|
|
224
229
|
| --- | --- | --- |
|
|
225
|
-
| `BOCHA_COUNT` | `10` | 每次搜索的结果数,限制在 1–50
|
|
226
|
-
| `BOCHA_FRESHNESS` | — |
|
|
227
|
-
| `BOCHA_SUMMARY` | 关 | `true`
|
|
230
|
+
| `BOCHA_COUNT` | `10` | 每次搜索的结果数,限制在 1–50(博查上限) |
|
|
231
|
+
| `BOCHA_FRESHNESS` | — | 时间筛选:`noLimit`、`oneDay`、`oneWeek`、`oneMonth`、`oneYear`、`YYYY-MM-DD` 或 `YYYY-MM-DD..YYYY-MM-DD`。官方文档建议不设此参数:博查会自行改写时间范围,固定区间可能导致检索结果为空 |
|
|
232
|
+
| `BOCHA_SUMMARY` | 关 | `true` 表示用生成的摘要替换 snippet(提供更多上下文,但单次调用成本更高) |
|
|
228
233
|
|
|
229
234
|
### Brave Search
|
|
230
235
|
|
|
231
|
-
| 变量 | 默认值 |
|
|
236
|
+
| 变量 | 默认值 | 说明 |
|
|
232
237
|
| --- | --- | --- |
|
|
233
|
-
| `BRAVE_NUM` | `8` | 每次搜索的结果数,限制在 1–20(Brave
|
|
238
|
+
| `BRAVE_NUM` | `8` | 每次搜索的结果数,限制在 1–20(Brave 上限) |
|
|
234
239
|
| `BRAVE_COUNTRY` | — | 两位国家代码,或 `ALL` |
|
|
235
|
-
| `BRAVE_LANG` | — |
|
|
236
|
-
| `BRAVE_FRESHNESS` | — |
|
|
240
|
+
| `BRAVE_LANG` | — | 结果语言代码,例如 `en`、`zh-hans`、`pt-br` |
|
|
241
|
+
| `BRAVE_FRESHNESS` | — | 时间筛选:`pd`(24 小时)、`pw`(7 天)、`pm`(31 天)、`py`(365 天)或 `YYYY-MM-DDtoYYYY-MM-DD` |
|
|
237
242
|
|
|
238
243
|
### DeepSeek
|
|
239
244
|
|
|
240
|
-
| 变量 | 默认值 |
|
|
245
|
+
| 变量 | 默认值 | 说明 |
|
|
241
246
|
| --- | --- | --- |
|
|
242
|
-
| `DEEPSEEK_COUNT` | `10` | 每次搜索的结果数,限制在 1–50(DeepSeek
|
|
247
|
+
| `DEEPSEEK_COUNT` | `10` | 每次搜索的结果数,限制在 1–50(DeepSeek 上限)。按请求计费,增加结果条数不产生额外费用 |
|
|
243
248
|
|
|
244
249
|
### Jina
|
|
245
250
|
|
|
246
|
-
| 变量 | 默认值 |
|
|
251
|
+
| 变量 | 默认值 | 说明 |
|
|
247
252
|
| --- | --- | --- |
|
|
248
|
-
| `JINA_NUM` | `0` |
|
|
249
|
-
| `JINA_INCLUDE_CONTENT` | 关 | `true`
|
|
253
|
+
| `JINA_NUM` | `0` | 每次搜索的结果数(1–100)。`0` 表示不传递该参数,以保留 Jina 更快且类型更全的结果 |
|
|
254
|
+
| `JINA_INCLUDE_CONTENT` | 关 | `true` 表示返回每条结果的整页 markdown,大幅增加上下文与计费 token |
|
|
250
255
|
| `JINA_GL` / `JINA_HL` | — | 国家 / 语言代码 |
|
|
251
|
-
| `JINA_LOCATION` | — |
|
|
252
|
-
| `JINA_TIMEOUT` | `25000
|
|
256
|
+
| `JINA_LOCATION` | — | 模拟的城市级地理位置,例如 `Berlin` |
|
|
257
|
+
| `JINA_TIMEOUT` | `25000`(开启 `JINA_INCLUDE_CONTENT` 时为 `60000`) | 请求超时毫秒数;整页抓取模式下使用更长的默认超时时间 |
|
|
253
258
|
|
|
254
259
|
### Keenable
|
|
255
260
|
|
|
256
|
-
| 变量 | 默认值 |
|
|
261
|
+
| 变量 | 默认值 | 说明 |
|
|
257
262
|
| --- | --- | --- |
|
|
258
263
|
| `KEENABLE_MAX_RESULTS` | `10` | 每次搜索的结果数,限制在 1–50 |
|
|
259
|
-
| `KEENABLE_MODE` | — |
|
|
260
|
-
| `KEENABLE_TITLE` | `opencode-search-plugin` | 作为 `X-Keenable-Title`
|
|
261
|
-
| `OSP_KEENABLE_API_KEY` | — |
|
|
264
|
+
| `KEENABLE_MODE` | — | 检索模式:`pro`(深度检索)或 `realtime`(快速检索);未设置则使用 Keenable 默认值 |
|
|
265
|
+
| `KEENABLE_TITLE` | `opencode-search-plugin` | 作为 `X-Keenable-Title` 发送的应用标识,无 key 端点依赖此标识统计调用 |
|
|
266
|
+
| `OSP_KEENABLE_API_KEY` | — | 可选;未配置时使用免 key 匿名访问 |
|
|
262
267
|
|
|
263
268
|
### Linkup
|
|
264
269
|
|
|
265
|
-
| 变量 | 默认值 |
|
|
270
|
+
| 变量 | 默认值 | 说明 |
|
|
266
271
|
| --- | --- | --- |
|
|
267
|
-
| `LINKUP_DEPTH` | `fast` |
|
|
272
|
+
| `LINKUP_DEPTH` | `fast` | 推理深度:`flash`、`fast`、`standard` 或 `deep` |
|
|
268
273
|
| `LINKUP_MAX_RESULTS` | `10` | 每次搜索的结果数,限制在 1–100 |
|
|
269
274
|
|
|
270
275
|
### Metaso
|
|
271
276
|
|
|
272
|
-
| 变量 | 默认值 |
|
|
277
|
+
| 变量 | 默认值 | 说明 |
|
|
273
278
|
| --- | --- | --- |
|
|
274
279
|
| `METASO_SEARCH_SIZE` | `20` | 每次搜索的结果数,限制在 1–100 |
|
|
275
|
-
| `METASO_INCLUDE_RAW_CONTENT` | 关 | `true`
|
|
280
|
+
| `METASO_INCLUDE_RAW_CONTENT` | 关 | `true` 表示返回每条结果的完整原文;搜索费用不变,但会大幅消耗上下文 token |
|
|
276
281
|
|
|
277
282
|
### Ollama
|
|
278
283
|
|
|
279
|
-
| 变量 | 默认值 |
|
|
284
|
+
| 变量 | 默认值 | 说明 |
|
|
280
285
|
| --- | --- | --- |
|
|
281
|
-
| `OLLAMA_MAX_RESULTS` | `5` | 每次搜索的结果数,限制在 1–10(API
|
|
286
|
+
| `OLLAMA_MAX_RESULTS` | `5` | 每次搜索的结果数,限制在 1–10(API 上限)。每条结果均包含整页 markdown 正文而非摘要,默认 5 条即可提供丰富的上下文 |
|
|
282
287
|
|
|
283
288
|
### Perplexity
|
|
284
289
|
|
|
285
|
-
| 变量 | 默认值 |
|
|
290
|
+
| 变量 | 默认值 | 说明 |
|
|
286
291
|
| --- | --- | --- |
|
|
287
|
-
| `PERPLEXITY_MAX_RESULTS` | `10` | 每次搜索的结果数,限制在 1–20
|
|
288
|
-
| `PERPLEXITY_SEARCH_TYPE` | — |
|
|
289
|
-
| `PERPLEXITY_RECENCY` | — |
|
|
292
|
+
| `PERPLEXITY_MAX_RESULTS` | `10` | 每次搜索的结果数,限制在 1–20(网页搜索上限为 20 条;`search_type=people` 支持至多 50 条) |
|
|
293
|
+
| `PERPLEXITY_SEARCH_TYPE` | — | 搜索类型:`web`(API 默认值,每千次 5 美元)、`fast`(每千次 1 美元,延迟更低)或 `people`;未设置则不传递该字段 |
|
|
294
|
+
| `PERPLEXITY_RECENCY` | — | 时效筛选:`hour`、`day`、`week`、`month` 或 `year` |
|
|
290
295
|
| `PERPLEXITY_COUNTRY` | — | 两位 ISO 3166-1 国家代码,例如 `US` |
|
|
291
|
-
| `PERPLEXITY_LANGUAGE` | — | ISO 639-1
|
|
296
|
+
| `PERPLEXITY_LANGUAGE` | — | 逗号分隔的 ISO 639-1 语言代码,例如 `en,zh`(至多发送 10 个,按快速上手文档中更严格的限制执行) |
|
|
292
297
|
|
|
293
|
-
|
|
298
|
+
此 Provider 未提供域名或信源过滤配置项:Perplexity API 未设置独立的新闻、Reddit 或学术垂直领域开关,其官方文档推荐在单次查询中通过 `search_domain_filter` 白名单进行过滤,而非作为全局配置项。
|
|
294
299
|
|
|
295
300
|
### Querit
|
|
296
301
|
|
|
297
|
-
| 变量 | 默认值 |
|
|
302
|
+
| 变量 | 默认值 | 说明 |
|
|
298
303
|
| --- | --- | --- |
|
|
299
304
|
| `QUERIT_COUNT` | `8` | 每次搜索的结果数 |
|
|
300
305
|
|
|
301
306
|
### SerpApi
|
|
302
307
|
|
|
303
|
-
| 变量 | 默认值 |
|
|
308
|
+
| 变量 | 默认值 | 说明 |
|
|
304
309
|
| --- | --- | --- |
|
|
305
310
|
| `SERPAPI_GL` / `SERPAPI_HL` | — | 国家 / 语言代码 |
|
|
306
|
-
| `SERPAPI_TBS` | — |
|
|
311
|
+
| `SERPAPI_TBS` | — | 高级筛选参数,例如 `qdr:d`(一天内)、`qdr:y`(一年内) |
|
|
307
312
|
|
|
308
|
-
|
|
313
|
+
此 Provider 未提供结果条数配置项:由于 Google 已废弃 `num` 参数,SerpApi 无法支持自定义返回条数。
|
|
309
314
|
|
|
310
315
|
### Serper
|
|
311
316
|
|
|
312
|
-
| 变量 | 默认值 |
|
|
317
|
+
| 变量 | 默认值 | 说明 |
|
|
313
318
|
| --- | --- | --- |
|
|
314
319
|
| `SERPER_NUM` | `10` | 每次搜索的结果数,限制在 1–100 |
|
|
315
320
|
| `SERPER_GL` / `SERPER_HL` | — | 国家 / 语言代码 |
|
|
@@ -317,48 +322,62 @@ AnySearch 和 Keenable 是例外。两家都有匿名层级,因此始终注册
|
|
|
317
322
|
|
|
318
323
|
### You.com
|
|
319
324
|
|
|
320
|
-
| 变量 | 默认值 |
|
|
325
|
+
| 变量 | 默认值 | 说明 |
|
|
321
326
|
| --- | --- | --- |
|
|
322
327
|
| `YOUCOM_COUNT` | `10` | 每个分区(网页、新闻各自)的结果数,限制在 1–100 |
|
|
323
|
-
| `YOUCOM_EXTRACTION` | `highlights` |
|
|
324
|
-
| `YOUCOM_LANGUAGE` / `YOUCOM_COUNTRY` | — |
|
|
325
|
-
| `YOUCOM_FRESHNESS` | — |
|
|
328
|
+
| `YOUCOM_EXTRACTION` | `highlights` | 正文抽取模式:`highlights` 返回解答性段落,`none` 仅返回原始摘要,`full_page` 抓取完整页面并按抓取页数计费 |
|
|
329
|
+
| `YOUCOM_LANGUAGE` / `YOUCOM_COUNTRY` | — | 语言 / 国家代码,例如 `EN` / `US` |
|
|
330
|
+
| `YOUCOM_FRESHNESS` | — | 时效筛选:`day`、`week`、`month`、`year` 或 `YYYY-MM-DDtoYYYY-MM-DD` |
|
|
331
|
+
|
|
332
|
+
### Zhipu
|
|
333
|
+
|
|
334
|
+
| 变量 | 默认值 | 说明 |
|
|
335
|
+
| --- | --- | --- |
|
|
336
|
+
| `ZHIPU_COUNT` | `10` | 每次搜索的结果数,限制在 1–50(Zhipu 的上限) |
|
|
337
|
+
| `ZHIPU_ENGINE` | `search_std` | 搜索引擎:`search_std`(0.01 元/次)、`search_pro`(0.03 元/次,召回更高)、`search_pro_sogou` / `search_pro_quark`(0.05 元/次)。`ZHIPU_SITE=intl` 时文档仅接受 `search-prime`(0.01 美元/次),并以其为默认值 |
|
|
338
|
+
| `ZHIPU_RECENCY` | — | 时间筛选:`oneDay`、`oneWeek`、`oneMonth`、`oneYear` 或 `noLimit`。不设置时保留 API 的 `noLimit` 默认行为 |
|
|
339
|
+
| `ZHIPU_CONTENT_SIZE` | — | 摘要长度:`medium`(API 默认)或 `high`,在同样按次计费下返回更完整的摘要 |
|
|
340
|
+
| `ZHIPU_SITE` | `cn` | 接口站点:`cn` 为 `open.bigmodel.cn`,`intl` 为 `api.z.ai`。两者是相互独立的账号体系,密钥、引擎与价格均不通用 |
|
|
341
|
+
|
|
342
|
+
默认引擎 `search_std` 是价格最低的一档;`search_pro` 价格为其三倍,召回更高;搜狗 / 夸克引擎则以更高单价换取各自的信源池(搜狗覆盖腾讯生态与知乎内容,夸克偏重时效)。每次调用均计费——没有免费额度——因此重复查询由共享缓存承接。请求发出前会截断至 API `search_query` 的 70 字符上限;`count` 在 `search_pro_quark` 引擎上不发送(其文档未列出该字段),在 `search_pro_sogou` 上则取整到 10/20/30/40/50 之一。
|
|
326
343
|
|
|
327
344
|
## 查询处理流程
|
|
328
345
|
|
|
329
|
-
1. OpenCode 向当前分配的 provider
|
|
330
|
-
2.
|
|
346
|
+
1. OpenCode 向当前分配的 provider 发起搜索请求。
|
|
347
|
+
2. 归一化后的搜索词(去除首尾空白并合并多余空格)优先匹配内存缓存。命中缓存时直接返回结果,不发起外部 API 请求。
|
|
331
348
|
3. 未命中缓存时,重新解析 API key,确保在 `/connect` 中轮换的密钥即时生效。
|
|
332
|
-
4.
|
|
333
|
-
5. 返回的数据经过 schema 校验,映射为 `{ url, title, content, time }`
|
|
349
|
+
4. 请求发出时附带超时限制(`<PROVIDER>_TIMEOUT`,默认 25s),防止无响应的上游服务阻塞会话。
|
|
350
|
+
5. 返回的数据经过 schema 校验,映射为 `{ url, title, content, time }` 并写入缓存供后续相同查询复用。
|
|
334
351
|
|
|
335
|
-
时间解析支持相对时间(`3 hours ago`、`3小时前`)、绝对格式(`Sep 30, 2026`、`31 Mar 2026`)和 ISO 8601
|
|
352
|
+
时间解析支持相对时间(`3 hours ago`、`3小时前`)、绝对格式(`Sep 30, 2026`、`31 Mar 2026`)和 ISO 8601 时间戳。不完整的日期文本(如缺少年份的 `Nov 1`)会被直接忽略,避免宽容解析器推导出错误的年份。
|
|
336
353
|
|
|
337
354
|
## 排错
|
|
338
355
|
|
|
339
356
|
```sh
|
|
340
|
-
#
|
|
357
|
+
# 查看插件是否已加载及加载状态
|
|
341
358
|
opencode plugin list
|
|
342
359
|
|
|
343
|
-
#
|
|
344
|
-
#
|
|
345
|
-
# AnySearch 和 Keenable
|
|
360
|
+
# 查看当前搜索池中包含的 provider
|
|
361
|
+
# 若某 provider 未出现在列表中,说明其未配置 key,或被 enable/disable 规则排除
|
|
362
|
+
# AnySearch 和 Keenable 无需 key,始终处于列表中
|
|
346
363
|
opencode api get "/api/websearch/provider"
|
|
347
364
|
```
|
|
348
365
|
|
|
349
|
-
|
|
366
|
+
常见排查项:
|
|
350
367
|
|
|
351
|
-
-
|
|
352
|
-
-
|
|
353
|
-
-
|
|
354
|
-
-
|
|
355
|
-
-
|
|
356
|
-
-
|
|
357
|
-
-
|
|
358
|
-
-
|
|
359
|
-
-
|
|
368
|
+
- **Provider 未出现在搜索池中**:该 provider 未配置 API key,或被 `disable` 排除(或未包含在 `enable` 列表中)。可在 `/connect` 中配置密钥或设置对应环境变量后重启 OpenCode(在 `/connect` 中更新的凭据无需重启即可即时生效)。若已配置但仍未出现,请检查拼写:插件日志会在启动时对无法识别的 ID 以及 `enable` / `disable` 的冲突项输出警告。
|
|
369
|
+
- **搜索报错 `Keenable rate limited the request (HTTP 429)`**:免 key 匿名层级限制为单 IP 每小时 1,000 次、每秒 10 次,且与同一出口 IP 的其他用户共享。设置 `OSP_KEENABLE_API_KEY` 可使用独立的专属免费配额。
|
|
370
|
+
- **搜索报错 `Ollama API error 401`**:`OSP_OLLAMA_API_KEY` 必须是来自 [ollama.com/settings/keys](https://ollama.com/settings/keys) 的账户 API key。若环境变量中已配置用于 Ollama 兼容代理的 Bearer token,可在 `/connect` 中为 **Ollama Search (osp)** 配置专门的 API key,`/connect` 凭据优先级高于环境变量。
|
|
371
|
+
- **搜索报错 `Bocha balance is exhausted (HTTP 403)`**:账户余额已耗尽,可前往 [open.bocha.cn](https://open.bocha.cn) 充值。错误信息包含博查返回的 `message` 文本与 `log_id`,联系客服时可作为凭证。
|
|
372
|
+
- **搜索报错 `Bocha rate limited the request (HTTP 429)`**:博查单账户请求上限与累计充值金额相关。若博查返回了 `Retry-After` 响应头,错误信息中会包含 `retry after Ns` 提示。
|
|
373
|
+
- **搜索报错 `Zhipu rejected the API key (HTTP 401)`**:key 很可能来自另一个站点。`cn` 站点([open.bigmodel.cn](https://open.bigmodel.cn),`ZHIPU_SITE=cn`)与 `intl` 站点([api.z.ai](https://api.z.ai),`ZHIPU_SITE=intl`)是相互独立的账号体系,密钥不通用。请将 `ZHIPU_SITE` 设置为签发 key 的站点,或前往 [bigmodel.cn](https://bigmodel.cn/usercenter/proj-mgmt/apikeys) 获取密钥。
|
|
374
|
+
- **搜索报错 `Zhipu rate limited the request (HTTP 429)`**:智谱按账户限制并发搜索数,对应 API 错误码 1701。若错误信息中附带 `retry after Ns` 提示,等待该时间或减少并发搜索即可恢复。
|
|
375
|
+
- **搜索报错 `Connect X in /connect, or set OSP_X_API_KEY`**:凭据在 provider 注册与实际调用之间失效或丢失。请重新在 `/connect` 中配置或重新导出环境变量。
|
|
376
|
+
- **搜索报错 `X search timed out after 25000ms`**:上游服务在超时时限内未完成响应。通常重试即可恢复;若特定 provider 响应较慢,可提高对应的 `<PROVIDER>_TIMEOUT`。此限制是为防止无响应的上游服务导致整个会话永久阻塞(OpenCode 自身不对搜索设置超时限制)。
|
|
377
|
+
- **搜索延迟高或配额消耗过快**:建议保留 `*_CACHE_TTL` 的默认值。在缓存窗口内的重复查询将直接由内存提供响应,不产生外部网络请求或费用。
|
|
378
|
+
- **修改本地插件文件后未生效**:OpenCode 会监视插件文件并自动重载。若未自动重载,可执行 `opencode service restart` 重启服务。
|
|
360
379
|
|
|
361
|
-
|
|
380
|
+
日志位于 `~/.local/share/opencode/log/opencode.log`;过滤 `loading plugin` 可查看 OpenCode 解析的所有插件及其入口文件。本插件关于 `enable` / `disable` 配置的警告信息同样记录在该文件中,带有 `[opencode-search-plugin]` 前缀。
|
|
362
381
|
|
|
363
382
|
## 开发
|
|
364
383
|
|
|
@@ -367,12 +386,12 @@ npm install
|
|
|
367
386
|
npm run check # 类型检查 + 测试
|
|
368
387
|
```
|
|
369
388
|
|
|
370
|
-
- `npm run typecheck
|
|
371
|
-
- `npm test
|
|
389
|
+
- `npm run typecheck`:对所有插件和测试执行严格的 TypeScript 类型检查。
|
|
390
|
+
- `npm test`:运行通用 provider 契约、单 provider 行为、日期解析、聚合注册以及仓库结构守卫测试。
|
|
372
391
|
|
|
373
|
-
`@opencode/plugin` 和 `effect` 声明为 **devDependencies
|
|
392
|
+
`@opencode/plugin` 和 `effect` 声明为 **devDependencies**,而非 `dependencies`。这两个模块由 OpenCode 在运行时提供,这也是单个 `.ts` 文件可以直接在 `~/.config/opencode/plugins/` 中运行且完全无需 `node_modules` 的原因。若声明为运行时依赖,`opencode plugin add` 将为了 100 KB 的插件源码下载 127 MB 的依赖树(仅 `effect` 就占 47 MB,`@opencode/plugin` 还会引入 `@aws-sdk`、`google-auth-library` 与 `@opentelemetry`);声明为 devDependencies 则既能满足开发时的类型检查与测试需求,又避免了为最终使用者引入多余依赖。
|
|
374
393
|
|
|
375
|
-
|
|
394
|
+
结构测试用于确保每个插件文件保持独立可复制性:若插件引入了同级模块依赖、共享代码块未保持逐字一致,或 provider ID 定义出现漂移,测试均会失败。详见 [CONTRIBUTING.md](CONTRIBUTING.md)。
|
|
376
395
|
|
|
377
396
|
## 许可证
|
|
378
397
|
|
package/index.ts
CHANGED
|
@@ -16,11 +16,12 @@ import { effect as querit } from "./plugins/querit-search"
|
|
|
16
16
|
import { effect as serpapi } from "./plugins/serpapi-search"
|
|
17
17
|
import { effect as serper } from "./plugins/serper-search"
|
|
18
18
|
import { effect as youcom } from "./plugins/youcom-search"
|
|
19
|
+
import { effect as zhipu } from "./plugins/zhipu-search"
|
|
19
20
|
|
|
20
21
|
type ProviderEffect = (ctx: Plugin.Context) => Effect.Effect<void, never, Scope.Scope>
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
|
-
* The
|
|
24
|
+
* The fifteen providers this package registers, in alphabetical order. Each entry
|
|
24
25
|
* is the same effect its standalone file uses as a default export, so a file
|
|
25
26
|
* copied out of this repository behaves exactly as it does here.
|
|
26
27
|
*
|
|
@@ -44,6 +45,7 @@ const PROVIDERS: ReadonlyArray<readonly [id: string, run: ProviderEffect]> = [
|
|
|
44
45
|
["osp-serpapi", serpapi],
|
|
45
46
|
["osp-serper", serper],
|
|
46
47
|
["osp-youcom", youcom],
|
|
48
|
+
["osp-zhipu", zhipu],
|
|
47
49
|
]
|
|
48
50
|
|
|
49
51
|
/** Every ID this package registers, so a typo in an option can be named. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-search-plugin",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.3.0",
|
|
4
|
+
"description": "Fifteen self-contained websearch provider plugins for OpenCode v2: AnySearch, Bocha, Brave, DeepSeek, Jina, Keenable, Linkup, Metaso, Ollama, Perplexity, Querit, SerpApi, Serper, You.com and Zhipu.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"./serpapi-search": "./plugins/serpapi-search.ts",
|
|
37
37
|
"./serper-search": "./plugins/serper-search.ts",
|
|
38
38
|
"./youcom-search": "./plugins/youcom-search.ts",
|
|
39
|
+
"./zhipu-search": "./plugins/zhipu-search.ts",
|
|
39
40
|
"./package.json": "./package.json"
|
|
40
41
|
},
|
|
41
42
|
"files": [
|