dsh-web-search-pro 0.2.0 → 0.2.3

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.
Files changed (266) hide show
  1. package/CHANGELOG.md +179 -0
  2. package/README.md +197 -32
  3. package/assets/skills/dsh-web-search-pro/SKILL.md +14 -13
  4. package/assets/skills/dsh-web-search-pro/references/config.md +36 -0
  5. package/assets/skills/dsh-web-search-pro/references/sources.md +19 -4
  6. package/assets/skills/dsh-web-search-pro/references/troubleshooting.md +3 -1
  7. package/catalog/sources.v1.json +22 -12
  8. package/lib/actions/approval.js +50 -1
  9. package/lib/actions/approval.js.map +1 -1
  10. package/lib/actions/config.js +274 -0
  11. package/lib/actions/config.js.map +1 -0
  12. package/lib/actions/errors.js +8 -1
  13. package/lib/actions/errors.js.map +1 -1
  14. package/lib/actions/format.js +10 -0
  15. package/lib/actions/format.js.map +1 -1
  16. package/lib/actions/index-view.js +2 -2
  17. package/lib/actions/index-view.js.map +1 -1
  18. package/lib/actions/read.js +7 -3
  19. package/lib/actions/read.js.map +1 -1
  20. package/lib/actions/registry.js +3 -1
  21. package/lib/actions/registry.js.map +1 -1
  22. package/lib/actions/run.js +2 -2
  23. package/lib/actions/run.js.map +1 -1
  24. package/lib/actions/schema.js +18 -0
  25. package/lib/actions/schema.js.map +1 -1
  26. package/lib/actions/search.js +12 -6
  27. package/lib/actions/search.js.map +1 -1
  28. package/lib/actions/sources.js +116 -41
  29. package/lib/actions/sources.js.map +1 -1
  30. package/lib/actions/types.js +19 -1
  31. package/lib/actions/types.js.map +1 -1
  32. package/lib/browser-access.js +25 -0
  33. package/lib/browser-access.js.map +1 -1
  34. package/lib/catalog/recommend.js +11 -3
  35. package/lib/catalog/recommend.js.map +1 -1
  36. package/lib/catalog/schema.js +3 -1
  37. package/lib/catalog/schema.js.map +1 -1
  38. package/lib/cli/builtin-specs.js +341 -0
  39. package/lib/cli/builtin-specs.js.map +1 -0
  40. package/lib/cli/chain.js +193 -0
  41. package/lib/cli/chain.js.map +1 -0
  42. package/lib/cli/chains-spec.js +118 -0
  43. package/lib/cli/chains-spec.js.map +1 -0
  44. package/lib/cli/engine.js +99 -0
  45. package/lib/cli/engine.js.map +1 -0
  46. package/lib/cli/opencli-sites.js +83 -0
  47. package/lib/cli/opencli-sites.js.map +1 -0
  48. package/lib/cli/opencli.js +153 -0
  49. package/lib/cli/opencli.js.map +1 -0
  50. package/lib/cli/probe.js +128 -0
  51. package/lib/cli/probe.js.map +1 -0
  52. package/lib/cli/runner.js +564 -0
  53. package/lib/cli/runner.js.map +1 -0
  54. package/lib/cli/spec.js +496 -0
  55. package/lib/cli/spec.js.map +1 -0
  56. package/lib/cli/time-text.js +79 -0
  57. package/lib/cli/time-text.js.map +1 -0
  58. package/lib/cli/trial.js +57 -0
  59. package/lib/cli/trial.js.map +1 -0
  60. package/lib/client/SettingsCard.js +14 -32
  61. package/lib/client/SettingsCard.js.map +1 -1
  62. package/lib/client/agent-mark.js +27 -0
  63. package/lib/client/agent-mark.js.map +1 -0
  64. package/lib/client/card-frame.js +118 -0
  65. package/lib/client/card-frame.js.map +1 -0
  66. package/lib/client/cli-form.js +257 -0
  67. package/lib/client/cli-form.js.map +1 -0
  68. package/lib/client/field-docs.js +130 -0
  69. package/lib/client/field-docs.js.map +1 -0
  70. package/lib/client/field-keys.js +81 -0
  71. package/lib/client/field-keys.js.map +1 -0
  72. package/lib/client/field-rows.js +71 -0
  73. package/lib/client/field-rows.js.map +1 -0
  74. package/lib/client/fill.js +3 -0
  75. package/lib/client/fill.js.map +1 -0
  76. package/lib/client/form-specs.js +15 -1
  77. package/lib/client/form-specs.js.map +1 -1
  78. package/lib/client/form.js +296 -27
  79. package/lib/client/form.js.map +1 -1
  80. package/lib/client/group-advanced.js +23 -0
  81. package/lib/client/group-advanced.js.map +1 -0
  82. package/lib/client/group-agent.js +28 -0
  83. package/lib/client/group-agent.js.map +1 -0
  84. package/lib/client/group-cli.js +136 -0
  85. package/lib/client/group-cli.js.map +1 -0
  86. package/lib/client/group-common.js +29 -0
  87. package/lib/client/group-common.js.map +1 -0
  88. package/lib/client/group-judge.js +67 -0
  89. package/lib/client/group-judge.js.map +1 -0
  90. package/lib/client/group-order.js +201 -0
  91. package/lib/client/group-order.js.map +1 -0
  92. package/lib/client/group-runtime.js +33 -0
  93. package/lib/client/group-runtime.js.map +1 -0
  94. package/lib/client/group-sources.js +83 -0
  95. package/lib/client/group-sources.js.map +1 -0
  96. package/lib/client/groups-basic.js +36 -0
  97. package/lib/client/groups-basic.js.map +1 -0
  98. package/lib/client/index.js.map +1 -1
  99. package/lib/client/json-list.js +50 -0
  100. package/lib/client/json-list.js.map +1 -0
  101. package/lib/client/locales.js +666 -215
  102. package/lib/client/locales.js.map +1 -1
  103. package/lib/client/order.js +192 -0
  104. package/lib/client/order.js.map +1 -0
  105. package/lib/client/overlay-ops.js +46 -0
  106. package/lib/client/overlay-ops.js.map +1 -0
  107. package/lib/client/sources-table.js +1 -0
  108. package/lib/client/sources-table.js.map +1 -1
  109. package/lib/client/styles.js +74 -47
  110. package/lib/client/styles.js.map +1 -1
  111. package/lib/client/text-view.js +98 -0
  112. package/lib/client/text-view.js.map +1 -0
  113. package/lib/client/ui-kit.js +120 -0
  114. package/lib/client/ui-kit.js.map +1 -0
  115. package/lib/client/validators.js +22 -0
  116. package/lib/client/validators.js.map +1 -1
  117. package/lib/client.js +9151 -1987
  118. package/lib/client.js.map +1 -1
  119. package/lib/config-fillers.js +53 -0
  120. package/lib/config-fillers.js.map +1 -0
  121. package/lib/config-groups.js +49 -0
  122. package/lib/config-groups.js.map +1 -0
  123. package/lib/config.js +87 -107
  124. package/lib/config.js.map +1 -1
  125. package/lib/default-chain.js +66 -0
  126. package/lib/default-chain.js.map +1 -0
  127. package/lib/deps.js +109 -102
  128. package/lib/deps.js.map +1 -1
  129. package/lib/engine-error.js +19 -0
  130. package/lib/engine-error.js.map +1 -0
  131. package/lib/engines.js +32 -115
  132. package/lib/engines.js.map +1 -1
  133. package/lib/fetch.js +23 -4
  134. package/lib/fetch.js.map +1 -1
  135. package/lib/index.js +30 -5
  136. package/lib/index.js.map +1 -1
  137. package/lib/overlay-types.js +88 -0
  138. package/lib/overlay-types.js.map +1 -0
  139. package/lib/overlay.js +683 -0
  140. package/lib/overlay.js.map +1 -0
  141. package/lib/pipeline/candidates.js +27 -1
  142. package/lib/pipeline/candidates.js.map +1 -1
  143. package/lib/pipeline/compile.js +63 -0
  144. package/lib/pipeline/compile.js.map +1 -1
  145. package/lib/pipeline/confidence.js +64 -0
  146. package/lib/pipeline/confidence.js.map +1 -0
  147. package/lib/pipeline/fusion.js +50 -3
  148. package/lib/pipeline/fusion.js.map +1 -1
  149. package/lib/pipeline/plan.js +2 -2
  150. package/lib/pipeline/plan.js.map +1 -1
  151. package/lib/pipeline/render.js +20 -2
  152. package/lib/pipeline/render.js.map +1 -1
  153. package/lib/pipeline/run.js +21 -7
  154. package/lib/pipeline/run.js.map +1 -1
  155. package/lib/pipeline/sources-spec.js +19 -3
  156. package/lib/pipeline/sources-spec.js.map +1 -1
  157. package/lib/providers/builtin.js +13 -14
  158. package/lib/providers/builtin.js.map +1 -1
  159. package/lib/providers/deepseek.js +348 -0
  160. package/lib/providers/deepseek.js.map +1 -0
  161. package/lib/providers/http.js.map +1 -1
  162. package/lib/providers/keyed-meta.js +7 -0
  163. package/lib/providers/keyed-meta.js.map +1 -1
  164. package/lib/providers/platforms.js +118 -58
  165. package/lib/providers/platforms.js.map +1 -1
  166. package/lib/providers/registry.js.map +1 -1
  167. package/lib/restart.js +47 -0
  168. package/lib/restart.js.map +1 -0
  169. package/lib/router.js +203 -27
  170. package/lib/router.js.map +1 -1
  171. package/lib/rpc-types.js +15 -0
  172. package/lib/rpc-types.js.map +1 -0
  173. package/lib/rpc.js +85 -0
  174. package/lib/rpc.js.map +1 -0
  175. package/lib/tools.js +10 -4
  176. package/lib/tools.js.map +1 -1
  177. package/lib/types/actions/approval.d.ts +11 -0
  178. package/lib/types/actions/config.d.ts +54 -0
  179. package/lib/types/actions/format.d.ts +9 -2
  180. package/lib/types/actions/run.d.ts +1 -0
  181. package/lib/types/actions/schema.d.ts +7 -1
  182. package/lib/types/actions/sources.d.ts +29 -3
  183. package/lib/types/actions/types.d.ts +28 -2
  184. package/lib/types/browser-access.d.ts +17 -0
  185. package/lib/types/catalog/recommend.d.ts +4 -0
  186. package/lib/types/catalog/schema.d.ts +2 -0
  187. package/lib/types/cli/builtin-specs.d.ts +38 -0
  188. package/lib/types/cli/chain.d.ts +83 -0
  189. package/lib/types/cli/chains-spec.d.ts +48 -0
  190. package/lib/types/cli/engine.d.ts +50 -0
  191. package/lib/types/cli/opencli-sites.d.ts +24 -0
  192. package/lib/types/cli/opencli.d.ts +77 -0
  193. package/lib/types/cli/probe.d.ts +53 -0
  194. package/lib/types/cli/runner.d.ts +126 -0
  195. package/lib/types/cli/spec.d.ts +269 -0
  196. package/lib/types/cli/time-text.d.ts +12 -0
  197. package/lib/types/cli/trial.d.ts +19 -0
  198. package/lib/types/client/SettingsCard.d.ts +17 -1
  199. package/lib/types/client/agent-mark.d.ts +22 -0
  200. package/lib/types/client/card-frame.d.ts +35 -0
  201. package/lib/types/client/cli-form.d.ts +97 -0
  202. package/lib/types/client/field-docs.d.ts +15 -0
  203. package/lib/types/client/field-keys.d.ts +41 -0
  204. package/lib/types/client/field-rows.d.ts +70 -0
  205. package/lib/types/client/fill.d.ts +2 -0
  206. package/lib/types/client/form-specs.d.ts +12 -3
  207. package/lib/types/client/form.d.ts +79 -1
  208. package/lib/types/client/group-advanced.d.ts +9 -0
  209. package/lib/types/client/group-agent.d.ts +20 -0
  210. package/lib/types/client/group-cli.d.ts +52 -0
  211. package/lib/types/client/group-common.d.ts +12 -0
  212. package/lib/types/client/group-judge.d.ts +17 -0
  213. package/lib/types/client/group-order.d.ts +26 -0
  214. package/lib/types/client/group-runtime.d.ts +15 -0
  215. package/lib/types/client/group-sources.d.ts +46 -0
  216. package/lib/types/client/groups-basic.d.ts +18 -0
  217. package/lib/types/client/index.d.ts +8 -0
  218. package/lib/types/client/json-list.d.ts +21 -0
  219. package/lib/types/client/locales.d.ts +1079 -196
  220. package/lib/types/client/order.d.ts +102 -0
  221. package/lib/types/client/overlay-ops.d.ts +37 -0
  222. package/lib/types/client/styles.d.ts +56 -41
  223. package/lib/types/client/text-view.d.ts +22 -0
  224. package/lib/types/client/ui-kit.d.ts +200 -0
  225. package/lib/types/client/validators.d.ts +6 -0
  226. package/lib/types/config-fillers.d.ts +9 -0
  227. package/lib/types/config-groups.d.ts +23 -0
  228. package/lib/types/config.d.ts +265 -216
  229. package/lib/types/default-chain.d.ts +63 -0
  230. package/lib/types/deps.d.ts +25 -23
  231. package/lib/types/engine-error.d.ts +12 -0
  232. package/lib/types/engines.d.ts +45 -10
  233. package/lib/types/fetch.d.ts +12 -3
  234. package/lib/types/index.d.ts +164 -146
  235. package/lib/types/overlay-types.d.ts +98 -0
  236. package/lib/types/overlay.d.ts +141 -0
  237. package/lib/types/pipeline/candidates.d.ts +19 -0
  238. package/lib/types/pipeline/compile.d.ts +11 -0
  239. package/lib/types/pipeline/confidence.d.ts +35 -0
  240. package/lib/types/pipeline/fusion.d.ts +23 -1
  241. package/lib/types/pipeline/render.d.ts +16 -0
  242. package/lib/types/pipeline/run.d.ts +3 -1
  243. package/lib/types/pipeline/sources-spec.d.ts +5 -2
  244. package/lib/types/pipeline/types.d.ts +37 -0
  245. package/lib/types/providers/deepseek.d.ts +130 -0
  246. package/lib/types/providers/http.d.ts +2 -1
  247. package/lib/types/providers/keyed-meta.d.ts +5 -0
  248. package/lib/types/providers/platforms.d.ts +15 -3
  249. package/lib/types/providers/registry.d.ts +10 -0
  250. package/lib/types/restart.d.ts +52 -0
  251. package/lib/types/router.d.ts +69 -9
  252. package/lib/types/rpc-types.d.ts +79 -0
  253. package/lib/types/rpc.d.ts +41 -0
  254. package/lib/types/tools.d.ts +6 -0
  255. package/lib/types/util.d.ts +16 -1
  256. package/lib/util.js +17 -4
  257. package/lib/util.js.map +1 -1
  258. package/package.json +51 -43
  259. package/scripts/check-client-bundle.mjs +1 -1
  260. package/scripts/cli-login-check.mjs +214 -0
  261. package/lib/client/RubricEditor.js +0 -47
  262. package/lib/client/RubricEditor.js.map +0 -1
  263. package/lib/client/fields.js +0 -31
  264. package/lib/client/fields.js.map +0 -1
  265. package/lib/types/client/RubricEditor.d.ts +0 -6
  266. package/lib/types/client/fields.d.ts +0 -65
@@ -0,0 +1,63 @@
1
+ /**
2
+ * The default engine order of a plain search, as a pure function: the router uses it to decide the order, and the settings
3
+ * card's status summary uses the same code to show the chain a search would try first, so the two cannot disagree.
4
+ * No imports: the client bundle includes this file.
5
+ * @module web-search-pro/default-chain
6
+ */
7
+ /** The default `engines` list. A list equal to it is "not customised": the default rule for common ("常用") sources applies to it. */
8
+ export declare const DEFAULT_ENGINES: readonly string[];
9
+ export interface ChainInput {
10
+ /** The configured `engines` (route ids). */
11
+ engines: readonly string[];
12
+ /** `sources.priority` (route ids). */
13
+ priority?: readonly string[];
14
+ /** `sources.disabled` (route ids). */
15
+ disabled?: readonly string[];
16
+ /** Common ("常用") sources whose key resolves, best first. */
17
+ commonReady?: readonly string[];
18
+ /** `evidence.sourcePolicy === 'anonymous-only'`: a paid common source is never added. */
19
+ anonymousOnly?: boolean;
20
+ }
21
+ /**
22
+ * Order of the configured chain: `sources.disabled` removed, `sources.priority` ids that are in the list first, then the common
23
+ * sources whose key resolves (only while `engines` is the default list; a list the user wrote keeps its order and the position
24
+ * it gave a common source), then the rest. Throws when everything is disabled.
25
+ */
26
+ export declare function effectiveChain(input: ChainInput): string[];
27
+ /** One reason the effective chain differs from the `engines` list as written. */
28
+ export type ChainReason =
29
+ /** `sources.disabled` removed these from the list. */
30
+ {
31
+ kind: 'disabled';
32
+ ids: string[];
33
+ }
34
+ /** `sources.priority` moved these to the front. */
35
+ | {
36
+ kind: 'priority';
37
+ ids: string[];
38
+ }
39
+ /** The default rule put these ready common ("常用") sources in front of the list. */
40
+ | {
41
+ kind: 'common';
42
+ ids: string[];
43
+ }
44
+ /** `evidence.sourcePolicy: anonymous-only` kept these ready common sources out (they need a key). */
45
+ | {
46
+ kind: 'anonymous-only';
47
+ ids: string[];
48
+ }
49
+ /** The list is the user's own, so these ready common sources are not added (they keep their place only if the list names them). */
50
+ | {
51
+ kind: 'own-list';
52
+ ids: string[];
53
+ };
54
+ export interface ChainExplanation {
55
+ /** What a plain search would try, in order ({@link effectiveChain}); undefined when everything is disabled. */
56
+ chain: string[] | undefined;
57
+ reasons: ChainReason[];
58
+ }
59
+ /**
60
+ * {@link effectiveChain} plus why it differs from the list: the preview of the settings card says it in one sentence per reason, so
61
+ * a person who sees `deepseek` first in a list that does not begin with it knows which rule did that. Same inputs, same rule.
62
+ */
63
+ export declare function explainChain(input: ChainInput): ChainExplanation;
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * External dependency detection and install for the CLI/platform backends.
3
- * Most backends shell out to tools installed outside DSH (bili, yt-dlp,
4
- * twitter, and mcporter). This module reports which are present and how to
5
- * install them; the sources.deps / sources.install actions expose it to the model. Each entry probes
6
- * the command the backend actually executes (the twitter backend runs
7
- * `twitter`, so finding `agent-reach` on PATH says nothing about it).
3
+ * Backends shell out to tools installed outside DSH: the built-in CLI adapter specs (bili, yt-dlp, twitter, xhs, zhihu,
4
+ * rdt, omnireach, gh, wx-search-cli, tanso, the standalone opencli) plus the user's own `cliAdapters`, and mcporter. This
5
+ * module reports which are present, whether the command on PATH really has the contract the adapter needs (a same-named
6
+ * program with another contract is `incompatible`, never `detected`), and how to install them; the sources.deps /
7
+ * sources.install actions expose it to the model. Probes are local, cached with a TTL, and never run a search or a login.
8
8
  *
9
9
  * Install is intentionally a MODEL-FACING TOOL, not a browser settings button:
10
10
  * a browser button running winget/pip/npm would be arbitrary command execution
@@ -12,6 +12,9 @@
12
12
  * tool-permission/approval pipeline. The card points at this tool instead.
13
13
  * @module web-search-pro/deps
14
14
  */
15
+ import { BILI_CLI_INSTALLS, BILI_CLI_REVISION, BILI_CLI_SOURCE, BILI_CLI_VERSION, TWITTER_CLI_INSTALLS } from './cli/builtin-specs.ts';
16
+ import { type CliInstallation } from './cli/probe.ts';
17
+ export { BILI_CLI_INSTALLS, BILI_CLI_REVISION, BILI_CLI_SOURCE, BILI_CLI_VERSION, TWITTER_CLI_INSTALLS };
15
18
  export interface DepInfo {
16
19
  id: string;
17
20
  label: string;
@@ -27,6 +30,10 @@ export interface DepInfo {
27
30
  version?: string;
28
31
  /** Why a command found on PATH is not compatible. */
29
32
  diagnostic?: string;
33
+ /** `missing` (not on PATH), `detected` (present with the contract the adapter needs), `incompatible` (present, wrong contract or too old). */
34
+ installation?: CliInstallation;
35
+ /** How far the adapter was checked against the real tool: `live`, `contract-only`, `docs-only` (absent: user-defined or not a CLI adapter). */
36
+ verification?: string;
30
37
  /** No backend of this plugin executes it; it is only an install helper, so its absence is not a gap. */
31
38
  optional?: boolean;
32
39
  installs: {
@@ -34,31 +41,26 @@ export interface DepInfo {
34
41
  command: string;
35
42
  }[];
36
43
  }
37
- export declare const BILI_CLI_VERSION = "0.6.2";
38
- export declare const BILI_CLI_REVISION = "489607468f967e0e11f3cdff6efc022d011e982a";
39
- export declare const BILI_CLI_SOURCE = "git+https://github.com/public-clis/bilibili-cli@489607468f967e0e11f3cdff6efc022d011e982a";
40
- export declare const BILI_CLI_INSTALLS: {
41
- installer: string;
42
- command: string;
43
- }[];
44
- interface DepProbeResult {
44
+ interface ProbeResult {
45
45
  available: boolean;
46
46
  version?: string;
47
47
  diagnostic?: string;
48
48
  }
49
49
  /** Validate the public-clis bili command rather than trusting an ambiguous package name. */
50
- export declare function evaluateBiliCli(versionOutput: string, searchHelpOutput: string): DepProbeResult;
50
+ export declare function evaluateBiliCli(versionOutput: string, searchHelpOutput: string): ProbeResult;
51
51
  /**
52
52
  * The twitter backend runs `twitter search <query> -n N` (twitter-cli). Another program that happens to be
53
53
  * called `twitter` must not pass: require a successful `search --help` that actually describes a search command.
54
54
  */
55
- export declare function evaluateTwitterCli(searchHelpOutput: string, exitCode: number): DepProbeResult;
56
- export declare const TWITTER_CLI_INSTALLS: {
57
- installer: string;
58
- command: string;
59
- }[];
60
- /** Detect all backends. */
61
- export declare function detectDeps(): Promise<DepInfo[]>;
55
+ export declare function evaluateTwitterCli(searchHelpOutput: string, exitCode: number): ProbeResult;
56
+ export declare const DEP_IDS: readonly string[];
57
+ /** Detect every dependency: the spec-backed CLIs through their cached contract probes, the rest by presence on PATH. */
58
+ export declare function detectDeps(options?: {
59
+ config?: {
60
+ cliAdapters?: unknown;
61
+ };
62
+ force?: boolean;
63
+ }): Promise<DepInfo[]>;
62
64
  /** Run the install command for one backend + installer. */
63
65
  export declare function installDep(id: string, installer: string): Promise<{
64
66
  code: number;
@@ -66,5 +68,5 @@ export declare function installDep(id: string, installer: string): Promise<{
66
68
  stderr: string;
67
69
  timedOut: boolean;
68
70
  }>;
69
- export declare const DEP_IDS: string[];
70
- export {};
71
+ /** The installer `sources.install` uses when none is named: the first one listed for the dependency. */
72
+ export declare function defaultInstaller(id: string): string;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The error every search engine and CLI adapter throws. Leaf module (no imports), so both engines.ts and the CLI adapter
3
+ * layer can extend it without an import cycle.
4
+ * @module web-search-pro/engine-error
5
+ */
6
+ export declare class EngineError extends Error {
7
+ readonly code: string;
8
+ readonly retryable: boolean;
9
+ readonly retryAfterMs?: number | undefined;
10
+ /** `retryAfterMs`: the service's own wait hint (Retry-After); the router uses it as the cooldown. */
11
+ constructor(message: string, code: string, retryable?: boolean, retryAfterMs?: number | undefined);
12
+ }
@@ -10,18 +10,44 @@ import type { BrowserService } from './browser-service.ts';
10
10
  import { type BrowserMethod } from './browser-access.ts';
11
11
  import type { CustomPlatformSpec } from './config.ts';
12
12
  import { type ExaSearchRequest } from './exa-client.ts';
13
+ import { EngineError } from './engine-error.ts';
14
+ /**
15
+ * A source row as an engine returns it: the host's `WebSearchSource` plus the provider's own quality signals, when it has any
16
+ * (DeepSeek Search: `rerank_score` 0..3 and `authority` 0..4). They travel with the row as source metadata and are one small
17
+ * fusion signal (pipeline/fusion.ts); no engine is required to set them.
18
+ */
19
+ export interface EngineSource extends WebSearchSource {
20
+ /** The provider's relevance / authority / freshness rank score, 0..3 (higher is better). */
21
+ readonly rerankScore?: number;
22
+ /** The provider's source-authority grade, 0..4 (unknown = absent). */
23
+ readonly authority?: number;
24
+ /** The user-defined CLI that returned the row (`custom-cli:echo`): set by the adapter, shown with the result. */
25
+ readonly via?: string;
26
+ /** The honest label of a user-defined source ("user-defined, not verified by the plugin"). */
27
+ readonly tag?: string;
28
+ /** The source's confidence (0..1), below 1 only: set by the router from the spec / `sources.confidence`, never by an engine. */
29
+ readonly confidence?: number;
30
+ }
13
31
  export interface SearchOutcome {
14
32
  /** Provider-generated answer/summary text, when any. */
15
33
  content?: string;
16
- sources: WebSearchSource[];
34
+ sources: EngineSource[];
17
35
  /** Id of the concrete backend that answered (a platform provider with a fallback chain names the leg that ran). */
18
36
  via?: string;
37
+ /** The backend id of the platform chain that answered (`bili`, `browser-opencli`), for display and history. */
38
+ backend?: string;
39
+ /** Short notes for the caller: backends skipped on the way, results dropped. */
40
+ notes?: string[];
19
41
  }
20
42
  export interface Engine {
21
43
  id: string;
22
44
  label: string;
45
+ /** Backend id in a platform chain (`xhs`, `browser-opencli`); absent for plain engines. */
46
+ backend?: string;
23
47
  /** Cheap local availability check; must not do network I/O. */
24
48
  available(): boolean;
49
+ /** Why `available()` is false, when the engine knows (a platform chain quotes it in its fall-through note instead of "unavailable"). */
50
+ unavailableReason?(): string | undefined;
25
51
  /** Browser-service method this engine depends on (dsh-browser is optional). */
26
52
  needsBrowser?: BrowserMethod;
27
53
  search(query: string, count: number, signal?: AbortSignal, options?: EngineSearchOptions): Promise<SearchOutcome>;
@@ -34,6 +60,8 @@ export interface EngineSearchOptions {
34
60
  include?: string[];
35
61
  exclude?: string[];
36
62
  };
63
+ /** The caller's original question or need (DeepSeek Search `ori_question`, cut to 128 characters by the engine); absent = none sent. */
64
+ originalQuestion?: string;
37
65
  /** Lower bound of the publication date (ISO 8601), compiled from a hard time_window; the engine maps it to its native filter. */
38
66
  since?: string;
39
67
  /** Domain lists compiled from hard site / exclude_site constraints (keyed sources that take them as request fields). */
@@ -50,13 +78,7 @@ export interface EngineSearchOptions {
50
78
  /** Feed URL of the `rss` platform (it has no fixed endpoint). */
51
79
  url?: string;
52
80
  }
53
- export declare class EngineError extends Error {
54
- readonly code: string;
55
- readonly retryable: boolean;
56
- readonly retryAfterMs?: number | undefined;
57
- /** `retryAfterMs`: the service's own wait hint (Retry-After); the router uses it as the cooldown. */
58
- constructor(message: string, code: string, retryable?: boolean, retryAfterMs?: number | undefined);
59
- }
81
+ export { EngineError };
60
82
  /** One metered request of a non-model provider (Bocha search): counted in the usage ledger, tokens n/a, price unknown. */
61
83
  export interface UsageRecorder {
62
84
  record(entry: {
@@ -80,6 +102,8 @@ export interface EngineDeps {
80
102
  usage?: UsageRecorder;
81
103
  /** Test seam: replaces the global fetch of API clients that accept one. */
82
104
  fetchImpl?: typeof fetch;
105
+ /** Test seam: waits between retries of the engines that retry (DeepSeek); resolves early on abort. Default: a real timer. */
106
+ sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
83
107
  /** Test seam: replaces the DNS lookup of the SSRF check. */
84
108
  lookup?: (hostname: string) => Promise<{
85
109
  address: string;
@@ -99,6 +123,11 @@ export interface EngineDeps {
99
123
  anysearchApiKey?: string;
100
124
  /** GitHub API token (config githubToken / $GITHUB_TOKEN / $GH_TOKEN). */
101
125
  githubToken?: string;
126
+ /**
127
+ * Credential variables of the CLI adapters by the name the tool reads (`TWITTER_AUTH_TOKEN`, `TWITTER_CT0`), resolved by the router:
128
+ * config literal -> credentials ref -> process environment. Handed to a command only through its environment, never in argv.
129
+ */
130
+ cliEnv?: Readonly<Record<string, string>>;
102
131
  enableCli: boolean;
103
132
  opencliEnabled: boolean;
104
133
  agentReachEnabled: boolean;
@@ -140,13 +169,19 @@ export declare function githubEngine(deps: EngineDeps): Engine;
140
169
  export declare function githubCodeEngine(deps: EngineDeps): Engine;
141
170
  export declare function githubIssuesEngine(deps: EngineDeps): Engine;
142
171
  export declare function bilibiliEngine(deps: EngineDeps): Engine;
143
- /** Exact argv contract supported by public-clis/bilibili-cli v0.6.2+. */
172
+ /** Exact argv contract supported by public-clis/bilibili-cli v0.6.2+ (the `bili` spec). */
144
173
  export declare function biliSearchArgs(query: string, count: number): string[];
145
- /** Parse and validate bili-cli's versioned JSON envelope. */
174
+ /** Parse and validate bili-cli's versioned JSON envelope (the `bili` spec). */
146
175
  export declare function parseBilibiliSearchOutput(output: string): WebSearchSource[];
147
176
  export declare function v2exEngine(allowProxyFakeIp?: boolean): Engine;
148
177
  export declare function youtubeEngine(deps: EngineDeps, cli?: typeof runCli): Engine;
178
+ /** Platforms the dsh-browser OpenCLI bridge has a site adapter for (platform -> adapter name). */
179
+ export declare const OPENCLI_PLATFORMS: Record<string, string>;
149
180
  export declare function opencliEngine(platform: string, deps: EngineDeps): Engine;
181
+ /**
182
+ * The legacy `agentreach-twitter` engine, now a thin view of the `twitter` CLI spec (the platform chain uses the spec
183
+ * directly; this keeps the old engine id and its install message). Credentials are checked by `available()`.
184
+ */
150
185
  export declare function agentReachEngine(platform: string, deps: EngineDeps): Engine;
151
186
  export declare function arxivEngine(allowProxyFakeIp?: boolean): Engine;
152
187
  export declare function pubmedEngine(allowProxyFakeIp?: boolean): Engine;
@@ -8,7 +8,8 @@ import type { ResolvedConfig } from './config.ts';
8
8
  import type { BrowserService } from './browser-service.ts';
9
9
  import { type BrowserGetter } from './browser-access.ts';
10
10
  import type { ExtractRule } from './extract.ts';
11
- export type FetchMode = 'auto' | 'jina' | 'http' | 'playwright';
11
+ import { type DeepSeekFetchAccess } from './providers/deepseek.ts';
12
+ export type FetchMode = 'auto' | 'jina' | 'http' | 'playwright' | 'deepseek';
12
13
  export interface FetchOptions {
13
14
  mode: FetchMode;
14
15
  signal: AbortSignal | undefined;
@@ -63,7 +64,7 @@ export declare function detectShellPage(text: string): boolean;
63
64
  export type PageClass = 'content' | 'shell' | 'login_wall' | 'captcha' | 'js_shell' | 'error';
64
65
  /** One backend attempt of a fetch, in order (recorded in the result and in the stored fetch detail). */
65
66
  export interface FetchAttempt {
66
- source: 'jina' | 'http' | 'playwright';
67
+ source: 'jina' | 'http' | 'playwright' | 'deepseek';
67
68
  class: PageClass;
68
69
  chars?: number;
69
70
  detail?: string;
@@ -82,14 +83,20 @@ export declare function classifyPage(text: string, meta?: {
82
83
  export declare function normalizeUrl(raw: string): string;
83
84
  /** All rules: user (DB) first, then built-ins; user rules win on ties. */
84
85
  export declare function mergedRules(store: Store): ExtractRule[];
86
+ /**
87
+ * The DeepSeek Fetch API access for a call: key, endpoint, ledger. Resolved per call by the router (settings literal -> DSH credentials ->
88
+ * process environment); undefined = no key. Test seams (`fetchImpl`, `lookup`, `sleep`) ride along on the returned object.
89
+ */
90
+ export type DeepSeekFetchAccessProvider = () => Promise<Pick<DeepSeekFetchAccess, 'apiKey' | 'baseUrl' | 'usage' | 'fetchImpl' | 'lookup' | 'sleep' | 'allowProxyFakeIp'> | undefined>;
85
91
  export declare class FetchService {
86
92
  private readonly store;
87
93
  private readonly config;
94
+ private readonly deepseek?;
88
95
  private readonly memory;
89
96
  /** In-flight de-duplication of identical non-fresh fetches (C3). */
90
97
  private readonly flights;
91
98
  private readonly getBrowser;
92
- constructor(store: Store, config: ResolvedConfig | (() => ResolvedConfig), browser?: BrowserService | BrowserGetter);
99
+ constructor(store: Store, config: ResolvedConfig | (() => ResolvedConfig), browser?: BrowserService | BrowserGetter, deepseek?: DeepSeekFetchAccessProvider | undefined);
93
100
  private cfg;
94
101
  /** True when the optional browser can render right now (enabled in config and the service has render()). */
95
102
  private canRender;
@@ -98,5 +105,7 @@ export declare class FetchService {
98
105
  private runFetch;
99
106
  private fetchJina;
100
107
  private fetchHttp;
108
+ /** One page through the DeepSeek Fetch API. 403 / 404 are DeepSeek's own verdicts (see `DeepSeekFetchError`), never the target page's status. */
109
+ private fetchDeepSeek;
101
110
  private fetchPlaywright;
102
111
  }