@mini-z/dsh-search-providers 0.1.2
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 +188 -0
- package/cordis.patch.yml +9 -0
- package/dsh/client.js +7 -0
- package/dsh/client.js.map +1 -0
- package/dsh/index.js +1211 -0
- package/dsh/index.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# dsh-search-providers
|
|
2
|
+
|
|
3
|
+
A modular [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/dsh) plugin that takes over `web_search` and `read_page` with an extensible provider registry and automatic failover.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Takes over native `web_search`**: registers as the DSH web seam search provider.
|
|
8
|
+
- **Adds/replaces `read_page`**: fetches clean page content through the active provider.
|
|
9
|
+
- **Multi-provider failover + cooldown**: automatic fallback; providers that fail are temporarily skipped to avoid repeated timeouts.
|
|
10
|
+
- **Modular providers**: add more by implementing `SearchProvider`.
|
|
11
|
+
- **Standard DSH configuration**: secrets via `~/.dsh/.env`, cordis config via `~/.dsh/profiles/<profile>/cordis.patch.yml`.
|
|
12
|
+
- **Demo mode**: test wiring without any API key.
|
|
13
|
+
|
|
14
|
+
## Supported providers
|
|
15
|
+
|
|
16
|
+
| Provider | Search | Fetch | Requires API key |
|
|
17
|
+
|----------|--------|-------|------------------|
|
|
18
|
+
| TinyFish | ✅ | ✅ | Yes |
|
|
19
|
+
| Tavily | ✅ | ❌ | Yes |
|
|
20
|
+
| Exa | ✅ | ✅ | Yes |
|
|
21
|
+
| Firecrawl| ✅ | ✅ | Yes |
|
|
22
|
+
| Codex | ✅ | ❌ | Static credential file in `~/.dsh` |
|
|
23
|
+
| Demo | ✅ | ✅ | No |
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
### Option 1: Install from npm (when published)
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npx -y @deepseek-ai/dsh plugin --profile web add @mini-z/dsh-search-providers
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Option 2: Local / migrate from another machine
|
|
34
|
+
|
|
35
|
+
1. Copy the project folder (or the migration zip) to the target machine.
|
|
36
|
+
2. Install dependencies:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
cd dsh-search-providers
|
|
40
|
+
bun install --frozen-lockfile
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
3. Configure API keys in `~/.dsh/.env` (see [Configuration](#configuration)).
|
|
44
|
+
|
|
45
|
+
4. Link the plugin into your DSH profile:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cd ~/.dsh/profiles/<your-profile>
|
|
49
|
+
npx -y @deepseek-ai/dsh plugin add /path/to/dsh-search-providers
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
> The built plugin artifacts are already included in `dsh/`, so you do not need to run `bun run build` unless you modify the source.
|
|
53
|
+
|
|
54
|
+
### Option 3: Development install
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
git clone <repo-url>
|
|
58
|
+
cd dsh-search-providers
|
|
59
|
+
bun install
|
|
60
|
+
bun run build
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Configuration
|
|
64
|
+
|
|
65
|
+
This plugin follows DSH conventions: secrets go in `~/.dsh/.env`, and cordis-level config goes in the profile patch file.
|
|
66
|
+
|
|
67
|
+
### Environment variables
|
|
68
|
+
|
|
69
|
+
Put one or more of these in `~/.dsh/.env`:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
TINYFISH_API_KEY=...
|
|
73
|
+
TAVILY_API_KEY=...
|
|
74
|
+
EXA_API_KEY=...
|
|
75
|
+
FIRECRAWL_API_KEY=...
|
|
76
|
+
CODEX_CREDENTIAL_FILE=C:/Users/you/.dsh/some-codex-auth.json
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
DSH loads this file automatically when the profile starts. Providers are tried in this default priority order:
|
|
80
|
+
|
|
81
|
+
1. Codex
|
|
82
|
+
2. TinyFish
|
|
83
|
+
3. Tavily
|
|
84
|
+
4. Exa
|
|
85
|
+
5. Firecrawl
|
|
86
|
+
|
|
87
|
+
API-key providers are attempted only when their key is configured. Codex is attempted only when `CODEX_CREDENTIAL_FILE` points to a usable static credential file. Missing or malformed configuration is silently skipped. Confirmed authentication failures disable that provider until DSH restarts; ordinary HTTP 403 responses do not. Rate limits use a 5-minute cooldown, network/timeouts 30 seconds, and other failures 10 seconds. Transient cooldowns are isolated between search and page fetching, and caller cancellation never cools a provider. Successful fallback responses identify cooling and disabled providers explicitly.
|
|
88
|
+
|
|
89
|
+
### Codex credential file
|
|
90
|
+
|
|
91
|
+
Codex is fully independent of login or model plugins. Set `CODEX_CREDENTIAL_FILE` to any specific JSON credential file. When the variable is absent, the Codex provider is disabled. The minimal JSON shape is:
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"access_token": "eyJ...",
|
|
96
|
+
"account_id": "account-id"
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The reader explicitly supports top-level fields plus `credential` and `tokens` wrappers. Access-token fields may be named `access_token` or `access`; account fields may be named `account_id` or `accountId`. When the account field is absent, the standard `chatgpt_account_id` JWT claim is used. Extra fields—including `refresh_token`, `expired`, `expires_at`, and `expires`—are ignored.
|
|
101
|
+
|
|
102
|
+
This plugin only reads the file. It never starts a login, refreshes a token, checks local timestamps, or writes credential data. A missing or malformed credential makes Codex unavailable and is skipped. If Codex rejects the credential with HTTP 401/403, Codex is disabled until restart and the normal fallback chain continues. Restrict the file's filesystem permissions to the owning user.
|
|
103
|
+
|
|
104
|
+
Codex does not implement `read_page`, and its standalone endpoint ignores this plugin's recency, domain, location, language, and maximum-result filters.
|
|
105
|
+
|
|
106
|
+
### Override the active provider or fallback order
|
|
107
|
+
|
|
108
|
+
The active `provider` is always tried first. `fallbackChain` lists the providers to try afterward, is de-duplicated in order, and may be an empty array to disable fallback.
|
|
109
|
+
|
|
110
|
+
Edit `~/.dsh/profiles/<profile>/cordis.patch.yml`:
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
- id: search-providers
|
|
114
|
+
config:
|
|
115
|
+
provider: exa
|
|
116
|
+
fallbackChain: [codex, tinyfish, tavily, firecrawl]
|
|
117
|
+
providers:
|
|
118
|
+
exa:
|
|
119
|
+
timeoutMs: 55000
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Usage
|
|
123
|
+
|
|
124
|
+
Once the plugin is loaded by DSH, the model can use the native `web_search` and `read_page` tools. No extra configuration is needed.
|
|
125
|
+
|
|
126
|
+
### web_search
|
|
127
|
+
|
|
128
|
+
Ask the model to search the web:
|
|
129
|
+
|
|
130
|
+
```text
|
|
131
|
+
Search the web for "latest Rust memory safety features".
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The plugin will use the active provider and automatically fall back to the next available provider if the first one fails. Every successful result starts with `[Search provider: ...]`, naming the provider that actually returned it.
|
|
135
|
+
|
|
136
|
+
### read_page
|
|
137
|
+
|
|
138
|
+
Give the model a URL to read:
|
|
139
|
+
|
|
140
|
+
```text
|
|
141
|
+
Read this page: https://example.com/article
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The plugin will fetch the page content through the active provider (or the first available fetch-capable provider in the fallback chain).
|
|
145
|
+
|
|
146
|
+
> Note: Tavily and Codex support search only, so they are skipped for `read_page`.
|
|
147
|
+
|
|
148
|
+
## Demo mode (test without API key)
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
SEARCH_PROVIDERS_DEMO=1 npx -y @deepseek-ai/dsh --profile web --no-open --port 9876
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Then ask the model to run `web_search` or `read_page`; it will receive canned demo results.
|
|
155
|
+
|
|
156
|
+
## Development
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
bun install
|
|
160
|
+
bun run typecheck
|
|
161
|
+
bun run test
|
|
162
|
+
bun run build
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Architecture
|
|
166
|
+
|
|
167
|
+
- `src/providers/types.ts` — `SearchProvider` interface.
|
|
168
|
+
- `src/providers/registry.ts` — provider registry and active-provider selection.
|
|
169
|
+
- `src/providers/cooldown.ts` — failure tracking and cooldown logic.
|
|
170
|
+
- `src/providers/tinyfish.ts`, `tavily.ts`, `exa.ts`, `firecrawl.ts`, `codex.ts` — provider implementations.
|
|
171
|
+
- `src/providers/demo.ts` — canned demo provider for testing.
|
|
172
|
+
- `src/tools/web-search.ts` — registers the plugin as `ctx.web.registerSearchProvider` with failover.
|
|
173
|
+
- `src/tools/read-page.ts` — registers the `read_page` tool with failover.
|
|
174
|
+
- `src/index.ts` — DSH plugin entry (`apply`).
|
|
175
|
+
|
|
176
|
+
## Adding a provider
|
|
177
|
+
|
|
178
|
+
Implement the `SearchProvider` interface, register it in `src/index.ts`, and add its config resolution.
|
|
179
|
+
|
|
180
|
+
## Publishing
|
|
181
|
+
|
|
182
|
+
1. Bump the version in `package.json`.
|
|
183
|
+
2. `npm login`
|
|
184
|
+
3. `bun publish --access public`
|
|
185
|
+
|
|
186
|
+
## License
|
|
187
|
+
|
|
188
|
+
MIT. The Codex interoperability implementation was developed with reference to [dsh-codex-connect](https://github.com/franksong2702/dsh-codex-connect) (Apache-2.0); no runtime dependency on that package is required.
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# dsh bundle patch: mount the search-providers plugin and route the web seam
|
|
2
|
+
# search capability through it. This replaces the default search provider.
|
|
3
|
+
- id: web
|
|
4
|
+
config:
|
|
5
|
+
searchProvider: search-providers
|
|
6
|
+
|
|
7
|
+
- insert:
|
|
8
|
+
- id: search-providers
|
|
9
|
+
name: '@mini-z/dsh-search-providers'
|
package/dsh/client.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sources":["../src/client.ts"],"sourcesContent":["// Browser-side companion for dsh web settings card.\n// Currently a no-op stub; Phase 6 can add a configuration UI here.\nexport function init() {\n console.log('[search-providers] client stub loaded');\n}\n"],"names":[],"mappings":"AAEO,SAAS,OAAO;AACrB,UAAQ,IAAI,uCAAuC;AACrD;"}
|