@konbakuyomu/smart-search-linux-x64 0.0.0 → 0.1.26

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 (81) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +18 -3
  3. package/runtime/smart-search/_internal/base_library.zip +0 -0
  4. package/runtime/smart-search/_internal/certifi/cacert.pem +3959 -0
  5. package/runtime/smart-search/_internal/certifi/py.typed +0 -0
  6. package/runtime/smart-search/_internal/libpython3.13.so.1.0 +0 -0
  7. package/runtime/smart-search/_internal/prompt_toolkit-3.0.53.dist-info/INSTALLER +1 -0
  8. package/runtime/smart-search/_internal/prompt_toolkit-3.0.53.dist-info/METADATA +171 -0
  9. package/runtime/smart-search/_internal/prompt_toolkit-3.0.53.dist-info/RECORD +298 -0
  10. package/runtime/smart-search/_internal/prompt_toolkit-3.0.53.dist-info/WHEEL +5 -0
  11. package/runtime/smart-search/_internal/prompt_toolkit-3.0.53.dist-info/licenses/AUTHORS.rst +11 -0
  12. package/runtime/smart-search/_internal/prompt_toolkit-3.0.53.dist-info/licenses/LICENSE +27 -0
  13. package/runtime/smart-search/_internal/prompt_toolkit-3.0.53.dist-info/top_level.txt +1 -0
  14. package/runtime/smart-search/_internal/smart_search/__init__.py +1 -0
  15. package/runtime/smart-search/_internal/smart_search/activity.py +279 -0
  16. package/runtime/smart-search/_internal/smart_search/assets/i18n/messages.json +17858 -0
  17. package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/SKILL.md +69 -0
  18. package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/agents/openai.yaml +3 -0
  19. package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/references/cli-contract.md +21 -0
  20. package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/references/cli-core.md +99 -0
  21. package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/references/command-patterns.md +166 -0
  22. package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/references/deep-research-mode.md +204 -0
  23. package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/references/provider-routing.md +178 -0
  24. package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/references/regression-release.md +46 -0
  25. package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/references/setup-config.md +133 -0
  26. package/runtime/smart-search/_internal/smart_search/assets/ui/index.html +955 -0
  27. package/runtime/smart-search/_internal/smart_search/cli.py +3651 -0
  28. package/runtime/smart-search/_internal/smart_search/config.py +1302 -0
  29. package/runtime/smart-search/_internal/smart_search/desktop_backend.py +709 -0
  30. package/runtime/smart-search/_internal/smart_search/desktop_catalog.py +166 -0
  31. package/runtime/smart-search/_internal/smart_search/desktop_cli.py +209 -0
  32. package/runtime/smart-search/_internal/smart_search/desktop_entry.py +19 -0
  33. package/runtime/smart-search/_internal/smart_search/desktop_environment.py +629 -0
  34. package/runtime/smart-search/_internal/smart_search/desktop_skills.py +129 -0
  35. package/runtime/smart-search/_internal/smart_search/desktop_updates.py +160 -0
  36. package/runtime/smart-search/_internal/smart_search/desktop_worker.py +117 -0
  37. package/runtime/smart-search/_internal/smart_search/i18n.py +135 -0
  38. package/runtime/smart-search/_internal/smart_search/intent_router.py +253 -0
  39. package/runtime/smart-search/_internal/smart_search/jev.py +473 -0
  40. package/runtime/smart-search/_internal/smart_search/jev_search.py +719 -0
  41. package/runtime/smart-search/_internal/smart_search/logger.py +43 -0
  42. package/runtime/smart-search/_internal/smart_search/provider_descriptions.py +140 -0
  43. package/runtime/smart-search/_internal/smart_search/provider_errors.py +137 -0
  44. package/runtime/smart-search/_internal/smart_search/provider_health.py +277 -0
  45. package/runtime/smart-search/_internal/smart_search/providers/__init__.py +27 -0
  46. package/runtime/smart-search/_internal/smart_search/providers/anysearch.py +336 -0
  47. package/runtime/smart-search/_internal/smart_search/providers/base.py +41 -0
  48. package/runtime/smart-search/_internal/smart_search/providers/context7.py +153 -0
  49. package/runtime/smart-search/_internal/smart_search/providers/exa.py +191 -0
  50. package/runtime/smart-search/_internal/smart_search/providers/jina.py +124 -0
  51. package/runtime/smart-search/_internal/smart_search/providers/openai_compatible.py +977 -0
  52. package/runtime/smart-search/_internal/smart_search/providers/sciverse.py +351 -0
  53. package/runtime/smart-search/_internal/smart_search/providers/tinyfish.py +213 -0
  54. package/runtime/smart-search/_internal/smart_search/providers/xai_responses.py +242 -0
  55. package/runtime/smart-search/_internal/smart_search/providers/zhipu.py +172 -0
  56. package/runtime/smart-search/_internal/smart_search/providers/zhipu_mcp.py +287 -0
  57. package/runtime/smart-search/_internal/smart_search/sciverse_schema.py +437 -0
  58. package/runtime/smart-search/_internal/smart_search/service.py +4302 -0
  59. package/runtime/smart-search/_internal/smart_search/skill_installer.py +549 -0
  60. package/runtime/smart-search/_internal/smart_search/skill_maintenance.py +181 -0
  61. package/runtime/smart-search/_internal/smart_search/sources.py +429 -0
  62. package/runtime/smart-search/_internal/smart_search/state_files.py +53 -0
  63. package/runtime/smart-search/_internal/smart_search/ui_api.py +246 -0
  64. package/runtime/smart-search/_internal/smart_search/ui_metadata.py +698 -0
  65. package/runtime/smart-search/_internal/smart_search/ui_server.py +506 -0
  66. package/runtime/smart-search/_internal/smart_search/utils.py +220 -0
  67. package/runtime/smart-search/_internal/smart_search-0.1.26.dist-info/INSTALLER +1 -0
  68. package/runtime/smart-search/_internal/smart_search-0.1.26.dist-info/METADATA +97 -0
  69. package/runtime/smart-search/_internal/smart_search-0.1.26.dist-info/RECORD +105 -0
  70. package/runtime/smart-search/_internal/smart_search-0.1.26.dist-info/REQUESTED +0 -0
  71. package/runtime/smart-search/_internal/smart_search-0.1.26.dist-info/WHEEL +5 -0
  72. package/runtime/smart-search/_internal/smart_search-0.1.26.dist-info/direct_url.json +1 -0
  73. package/runtime/smart-search/_internal/smart_search-0.1.26.dist-info/entry_points.txt +2 -0
  74. package/runtime/smart-search/_internal/smart_search-0.1.26.dist-info/licenses/LICENSE +21 -0
  75. package/runtime/smart-search/_internal/smart_search-0.1.26.dist-info/top_level.txt +1 -0
  76. package/runtime/smart-search/_internal/wcwidth/_wcwidth_c.abi3.so +0 -0
  77. package/runtime/smart-search/_internal/wcwidth/_wcwidth_c.pyi +77 -0
  78. package/runtime/smart-search/_internal/wcwidth/py.typed +0 -0
  79. package/runtime/smart-search/package.json +49 -0
  80. package/runtime/smart-search/smart-search +0 -0
  81. package/README.md +0 -3
@@ -0,0 +1,178 @@
1
+ # Provider Routing
2
+
3
+ ## Intent Routing Diagnostics
4
+
5
+ `search` and `research` are the two live search modes. Both share the configured channel catalog, execution, deadlines, and evidence records.
6
+
7
+ - `search`: one routing decision, using Jev or local rules, selects one suitable channel, then returns results and sources. Necessary dependent requests (such as Context7 library resolution followed by docs) and same-capability failure fallback remain; model answers and web search are mutual fallbacks in ordinary search. It never runs evidence assessment, follow-up search, filtering, or synthesis. `--extra-sources N` limits results from that channel (up to 20), not the number of channels. `evidence_assessment.status=not_evaluated`; success is retrieval success, not factual verification. `--validation strict` requires source evidence and can return partial content with an evidence error.
8
+ - `research`: the shared loop selects complementary actions in parallel, reads discovered pages, assesses evidence gaps, and continues while useful and within budget. Jev or local rules choose from program-built original/subquestion/gap query candidates; Jev does not generate arbitrary queries or tool calls. Only fetched/read content enters `citations`. Optional filtering and `SMART_SEARCH_JEV_SYNTHESIZE=false|auto|true` apply only here.
9
+ - `deep` remains an offline planner. Its `steps[].command` entries are suggestions for manual/AI orchestration; `research` records its actual actions separately in `routing_decision.rounds` and `stage_results`.
10
+
11
+ The default is `SMART_SEARCH_INTENT_ROUTER=jev`. In Jev mode, ordinary search makes at most one logical Jev judgment; without a TypeSafe key or a valid judgment, `--fallback auto` uses local capability rules and reports degradation, while `--fallback off` fails clearly. Explicit `local` needs no TypeSafe key and never calls Jev. Legacy `hybrid` maps to `jev`; `rules` and `off` map to `local`. Old embedding/classifier keys remain stored but unused. `route-calibrate` is a retired, non-network compatibility command.
12
+
13
+ `route` previews local capabilities without calling a model or retrieval provider. Add `--remote` only for an explicit, potentially billable Jev diagnostic. Direct provider commands keep their explicit behavior.
14
+
15
+ Only configured, enabled, allowed channels outside cooldown can run. `--providers`, provider enable switches, `SMART_SEARCH_RESEARCH_DISABLED_PROVIDERS`, and explicit-only boundaries are enforced before selection and dispatch. A failed ordinary channel can try another provider of the same capability, with model answers and web search treated as mutual fallbacks; it cannot turn into a research loop. User preferences do not bypass these boundaries.
16
+
17
+ The shared total timeout defaults to 300 seconds (`SMART_SEARCH_TIMEOUT_SECONDS`, overridden by `search --timeout`). Research quick/standard/deep ceilings are 2/3/10 rounds, 1/2/10 channels per round, 3/5/20 results per channel, and 45/120/configured seconds, further limited by the configured Jev budgets. Sufficient evidence, exhaustion, no progress, or deadline stops the loop. Completed results survive optional judgment/filter/synthesis failure.
18
+
19
+ For research, `SMART_SEARCH_JEV_SYNTHESIZE` accepts `true`, `false`, and `auto`. Final synthesis uses only the dedicated `SMART_SEARCH_JEV_SYNTHESIS_API_URL`, `_API_KEY`, and `_MODEL` configuration; `_API_MODE` selects `chat-completions` (default) or `responses`. It never uses the main-search model or `--model`. Auto asks Jev after optional filtering whether the retained evidence benefits from synthesis. No allowed dedicated model or a failed judgment returns evidence directly. `synthesis` reports the mode, decision probability, execution status and skip reason. With an explicit `--providers` filter, include `jev-synthesis` to permit the synthesis call.
20
+
21
+ ## Provider Boundaries
22
+
23
+ - `deep` uses offline rules/local signals only and must not call remote embeddings or classifier components.
24
+ - Official xAI uses `/responses` through `XAI_*`. OpenAI-compatible relays default to `/chat/completions`; `OPENAI_COMPATIBLE_API_MODE=responses` explicitly selects `/responses` for a relay that supports the documented subset.
25
+ - `search --stream` sets `stream=true` for xAI Responses and OpenAI-compatible search, including Grok search selected by Jev. `--no-stream` disables streaming for that request. `OPENAI_COMPATIBLE_STREAM=true` remains the default switch for OpenAI-compatible search and provider-side fetch.
26
+ - Legacy `SMART_SEARCH_API_URL`, `SMART_SEARCH_API_KEY`, `SMART_SEARCH_API_MODE`, `SMART_SEARCH_MODEL`, and `SMART_SEARCH_XAI_TOOLS` are unsupported config keys.
27
+ - xAI Responses mode may use only `XAI_TOOLS=web_search,x_search` and a subset of those tools.
28
+ - `XAI_REASONING_EFFORT` accepts `low`, `medium`, or `high` (case-insensitive, stored lowercase). Optional; when set, sends reasoning.effort in xAI Responses requests; omitted by default. This also applies to Grok search selected by Jev. Unsupported reasoning values reported by the upstream API remain errors; the field is not silently removed and retried.
29
+ - Neither OpenAI-compatible API mode sends xAI `web_search` / `x_search` tools or legacy `search_parameters`; xAI Chat Completions Live Search is deprecated.
30
+ - AnySearch is reported only as optional experimental `vertical_search`; it is not part of the `web_search` fallback and is not required by the `standard` minimum profile.
31
+ - Sciverse is reported only as optional experimental explicit-only `vertical_search`; it is not `docs_search`, not part of default `search` / `research` fallback, and not required by the `standard` minimum profile.
32
+ - Jina Reader is `web_fetch` only, not a general search provider. `JINA_API_KEY` is required before Jina satisfies the standard minimum profile; anonymous `r.jina.ai` is explicit/experimental fetch behavior.
33
+ - Same-capability fallback is allowed; model answers and web search are mutual fallbacks in ordinary search. Context7 is not used for unrelated broad web queries, and page extraction providers are not used as docs search providers.
34
+ - `TAVILY_ENABLED=false` removes Tavily from registered `web_search` and `web_fetch` routes even when its key is present. Direct Tavily search/extract calls, `map`, `doctor`, and smoke must make no Tavily network request; `map` reports a local configuration error. Firecrawl remains independently configured and all fallback stays within its capability.
35
+ - In Jev mode, Jev chooses among allowed capabilities and providers for the question; there is no mandatory main-model call or fixed global provider order. Local routing prioritizes suitable capabilities and configured preferences.
36
+ - `main_search` contains xAI Responses and OpenAI-compatible model channels; `web_search` contains Zhipu REST/MCP, Tavily, Firecrawl and TinyFish; `docs_search` contains Context7 and Exa. Failure fallback stays within the selected capability family; model answers and web search are mutual fallbacks in ordinary search.
37
+ - Ordinary Context7 uses the first library in Context7's ranked candidates, without a second Jev call. Research may use Jev to select the matching library, using the first candidate if Jev fails or no score reaches its threshold. Empty results may fall through to same-capability Exa; explicit Context7 commands remain unchanged.
38
+ - `--extra-sources N` controls the selected channel's result count. It does not add channels, split a budget between providers, or make Tavily/Firecrawl a required extra stage. A known-URL search follows the configured Jev/local routing; local routing prefers page reading.
39
+ - `fetch` tries Tavily first, then Jina with `JINA_API_KEY`, then Zhipu Coding Plan MCP Reader, then Firecrawl, then TinyFish.
40
+
41
+ TinyFish:
42
+
43
+ - `TINYFISH_API_KEY` is optional and registers TinyFish for both `web_search` and `web_fetch`. It never satisfies `main_search` or `docs_search`. Jev may select it directly; the direct `fetch` fallback order remains as listed above.
44
+ - `TINYFISH_SEARCH_API_URL` defaults to `https://api.search.tinyfish.ai` and is called as `GET ?query=...`; `TINYFISH_FETCH_API_URL` defaults to `https://api.fetch.tinyfish.ai` and is called as `POST` with `{"urls": [url], "format": "markdown"}`.
45
+ - Both endpoints send `X-API-Key`, not `Authorization: Bearer`. Never log or echo the key.
46
+ - Search results normalize `snippet` to `description`, `site_name` to `source`, and `date` to `published_date`. An empty result set is a successful empty response, not a failure.
47
+ - Fetch reads `results[0].text`; `errors[]` entries are surfaced as `provider_error` with the upstream message. A payload with neither results nor errors is `provider_error`, and a non-object payload is `parse_error`.
48
+ - Challenge pages such as `Checking if the site connection is secure` are reported as `quality_error` so same-capability fallback can continue.
49
+ - `401`/403 map to `auth_error`, `408` to `timeout`, `429` to `rate_limited`, `5xx` to `network_error`, and `400`/422 to `parameter_error`.
50
+ - `map` currently uses Tavily only.
51
+ - `exa-search` and `exa-similar` use Exa only.
52
+ - `context7-library` and `context7-docs` use Context7 only.
53
+ - `anysearch-domains`, `anysearch-search`, `anysearch-extract`, and `anysearch-batch` use AnySearch only. Treat results as acceptance evidence until the target vertical domain is reviewed.
54
+ - `sciverse-catalog`, `sciverse-search`, `sciverse-semantic`, `sciverse-read`, and `sciverse-relations` use Sciverse only. They are explicit academic commands and must not be inserted into default provider fallback.
55
+ - `zhipu-search` uses Zhipu only.
56
+ - `zhipu-mcp-search`, `zhipu-mcp-reader`, and `zhipu-mcp-*` zread commands use Zhipu Coding Plan Remote MCP only.
57
+ - Runtime config priority is environment variables first, then local config file, then defaults.
58
+ - `setup` and `config` read/write the local Smart Search config file and do not call providers.
59
+ - `model current` reports explicit provider model settings. `model set` is retained only as a parameter-error migration guard; use `config set XAI_MODEL ...` or `config set OPENAI_COMPATIBLE_MODEL ...` to change models.
60
+
61
+ Provider attempt errors:
62
+
63
+ - Provider exceptions must be visible as `provider_attempts[].status="error"`, never silently converted to empty output. Use the stable taxonomy: HTTP `400`/`422` is `parameter_error`, `401`/`403` is `auth_error`, timeout is `timeout`, `429` is `rate_limited`, `5xx` or request failure is `network_error`, invalid response decoding is `parse_error`, and explicit upstream tool failures are `provider_error`.
64
+ - A successfully decoded response with no normalized candidates or content is `status="empty"`, so same-capability fallback can continue without misreporting a provider failure.
65
+
66
+ Zhipu Web Search API:
67
+
68
+ - `zhipu-search` corresponds to the official Zhipu Web Search API route, using `ZHIPU_API_URL` plus `ZHIPU_SEARCH_ENGINE`; it is not Zhipu Chat Completions `tools=[web_search]`, not Search Agent, and not the MCP Server.
69
+ - `ZHIPU_SEARCH_ENGINE` defaults to `search_std`. Official Web Search API service values include `search_std`, `search_pro`, `search_pro_sogou`, and `search_pro_quark`; keep custom values possible because official services may change.
70
+ - `TAVILY_API_URL` only affects Tavily REST calls and does not proxy Zhipu.
71
+
72
+ Zhipu Coding Plan Remote MCP:
73
+
74
+ - `ZHIPU_MCP_API_KEY` configures the Coding Plan MCP auth token and must be sent as `Authorization: Bearer ...`; it must never be logged unmasked.
75
+ - `ZHIPU_MCP_SEARCH_API_URL` defaults to `https://open.bigmodel.cn/api/mcp/web_search_prime/mcp` and calls `web_search_prime` for `web_search`.
76
+ - `ZHIPU_MCP_READER_API_URL` defaults to `https://open.bigmodel.cn/api/mcp/web_reader/mcp` and calls `webReader` for `web_fetch`.
77
+ - `ZHIPU_MCP_ZREAD_API_URL` defaults to `https://open.bigmodel.cn/api/mcp/zread/mcp` and calls `search_doc`, `get_repo_structure`, and `read_file` through explicit repo/docs commands.
78
+ - Zhipu Coding Plan MCP must be implemented as a separate Remote MCP-over-HTTP provider layer. Do not route it through the existing `/paas/v4/web_search` Zhipu REST provider.
79
+ - A normal Zhipu Web Search API key is not sufficient evidence of Coding Plan entitlement. If `ZHIPU_MCP_API_KEY` is missing or returns auth/provider errors, MCP providers are skipped or fall through within the same capability; zread remains explicit and does not affect the standard minimum profile.
80
+ - Provider failures must appear in `provider_attempts` and fallback must remain same-capability, with model answers and web search treated as mutual fallbacks in ordinary search.
81
+ - `doctor` should report configured/not-configured, auth, rate-limit, provider, timeout, and network status without exposing the MCP token.
82
+
83
+ Jina Reader:
84
+
85
+ - `JINA_READER_API_URL` defaults to `https://r.jina.ai`.
86
+ - `JINA_API_KEY` is required before Jina satisfies `SMART_SEARCH_MINIMUM_PROFILE=standard`.
87
+ - Anonymous Jina Reader calls may be used only as explicit/experimental degraded fetch behavior; they must not make standard setup pass.
88
+ - `JINA_RESPOND_WITH=readerlm-v2` requires `JINA_API_KEY` and should report a configuration error without a network request when the key is missing.
89
+ - Jina Reader is `web_fetch` only, not `web_search`.
90
+ - Jina 401/403, 422, 429, timeout, network errors, and low-quality challenge pages such as `Title: Just a moment...` must be reported as failed provider attempts and allow same-capability fallback.
91
+
92
+ AnySearch:
93
+
94
+ - AnySearch uses JSON-RPC 2.0 `tools/call` at `ANYSEARCH_API_URL`, default `https://api.anysearch.com/mcp`.
95
+ - `ANYSEARCH_API_KEY` is optional. If configured, requests include `Authorization: Bearer ...`; if missing, anonymous requests are allowed.
96
+ - `ANYSEARCH_TIMEOUT_SECONDS` defaults to `30`.
97
+ - Live MCP tools are `search`, `batch_search`, `extract`, and `get_sub_domains`. `anysearch-domains` maps to `get_sub_domains` (not the removed `list_domains` tool).
98
+ - `anysearch-domains DOMAIN` calls the live `get_sub_domains` tool; without `DOMAIN`, it reads the `tools/list` schema for the available domains.
99
+ - HTTP 200 responses with `result.isError=true` must return `ok=false`, `error_type=provider_error`, and no successful source results.
100
+ - Markdown URL/title/snippet candidates should be parsed into `results`, while raw text remains in `content` and `raw_content`.
101
+ - Structured results without URLs must be preserved as raw/structured evidence, not dropped.
102
+ - Dotted vertical domain shorthand such as `code.doc` is allowed for simple subdomains and must be normalized to `domain=code` plus `sub_domain=doc`; parameterized subdomains parse `--sub-domain-params` JSON first, then repeatable `--param KEY=VALUE` entries override matching keys. Invalid JSON, non-object JSON, a missing `=`, or an empty key fails before the network request.
103
+ - `anysearch-extract --max-length` sends only `url` to the live tool. A positive value truncates successful top-level and result text fields locally; zero or negative values preserve the normalized payload.
104
+ - `anysearch-batch` accepts at most 5 CLI query strings and returns `error_type=parameter_error` without sending a request when the limit is exceeded.
105
+
106
+ Sciverse:
107
+
108
+ - `SCIVERSE_API_URL` defaults to `https://api.sciverse.space`; `SCIVERSE_TIMEOUT_SECONDS` defaults to `30`.
109
+ - `SCIVERSE_API_TOKEN` is required. Missing token returns `error_type=config_error` without a network request; configured requests send `Authorization: Bearer ...` and must never expose the token.
110
+ - Commands map directly to Sciverse OpenAPI: catalog -> `GET /meta-catalog`, search -> `POST /meta-search`, semantic -> `POST /agentic-search`, read -> `GET /content`, relations -> `POST /meta-paper-relations`.
111
+ - Current `meta-catalog` and `meta-search` schemas have no `collection` selector. Legacy `--collection papers` is accepted without being sent upstream; `authors` and `sources` return `parameter_error` before a request. `meta-search` sends only `query`, `filters`, `sort`, `freshness_boost`, `page`, and `page_size`. `--title-contains` / `--abstract-contains` fold into `query`; author, journal, subject, and year conveniences become current filter items.
112
+ - Advanced filters and sorts are structured local contracts: filters require `field` and `value` with a current `operator` such as `FILTER_OP_GTE`; legacy `op` is accepted only when it maps unambiguously. Sort items require `field` and normalize `order` to `SORT_ORDER_ASC` or `SORT_ORDER_DESC`. Full-text `query` and any `sort` conflict, so `--sort-by-year` defaults to `none` and sorting is filter-only.
113
+ - `sciverse-semantic --retrieval hybrid|milvus|es` is the current semantic contract. Deprecated `--mode fast|balanced|quality` maps to `retrieval=hybrid` with a warning; it conflicts with explicit `milvus` or `es`. Semantic `--source-types` accepts only `web,pdf`.
114
+ - `sciverse-read` uses `doc_id`; `sciverse-relations` uses `unique_id`.
115
+ - Relation direction must stay explicit: `CITATIONS` means papers citing the target paper, `REFERENCES` means papers cited by the target paper, and `RELATED_WORKS` means related work suggestions.
116
+ - Sciverse's documented HTTP `504` deadline response is `timeout`; other `5xx` responses remain `network_error`.
117
+ - Local limits reject before network: search `page_size <= 200` and `page * page_size <= 10000`, semantic `top_k <= 100`, read `limit <= 16384`, relations `page_size <= 200`.
118
+ - `--filters-advanced` and `--sort-advanced` must be JSON arrays of valid objects and fail with `parameter_error` before service/provider calls when malformed.
119
+
120
+ OpenAI-compatible streaming:
121
+
122
+ - `OPENAI_COMPATIBLE_API_MODE` defaults to `chat-completions` and accepts only `chat-completions` or `responses`. The selected protocol applies consistently to `search()`, provider-side `fetch()`, `describe_url()`, `rank_sources()`, `doctor`, and `diagnose openai-compatible`.
123
+ - Responses mode handles the official `model` + `instructions`/`input` subset, heterogeneous `output` text parts, URL citations, typed stream deltas, and terminal failures. It does not promise `/responses` support from every relay marketed as OpenAI-compatible; accept each named relay with both diagnose stream probes.
124
+ - `OPENAI_COMPATIBLE_STREAM` defaults to `false` and accepts `true`, `1`, or `yes` as true.
125
+ - For OpenAI-compatible search, `search --stream` means "prefer stream first"; stream empty/timeout/retryable protocol failures fall back to the same provider/model with `stream=false`.
126
+ - `search --no-stream` forces `stream=false` for the current invocation.
127
+ - `SMART_SEARCH_TIMEOUT_SECONDS` defines one 300-second default monotonic `search` budget. Jev selection, channel dependencies and failure fallback share its remaining time; no budget is reserved for a mandatory main model. `search --timeout` overrides the saved value for one invocation. Research uses the same deadline with its configured budget ceilings.
128
+ - `OPENAI_COMPATIBLE_FALLBACK_MODELS` is an optional comma-separated ordered list. It is fail-over after a hard primary-model failure, not a time slice. The current candidate keeps the remaining shared main-search budget; extra fallback models must not shrink that budget. `--fallback off` or `--model MODEL` disables this model fallback for the invocation.
129
+ - `timeout_phase`, `phase_attempts`, elapsed/remaining deadline values, and `partial_success` report execution progress. Research judgment/filter/synthesis failures preserve completed evidence; ordinary search has no extra/supplemental phase. Strict validation still reports an evidence error when its source requirements are not met.
130
+ - OpenAI-compatible attempts may include `model`, `transport`, `fallback_from_transport`, `fallback_from_model`, and `breaker_state`. `transport_fallback_used` records stream-to-non-stream recovery separately from provider/model `fallback_used`.
131
+ - Streaming applies to xAI Responses `search()` and OpenAI-compatible `search()` and provider-side `fetch()` calls. `describe_url()` and `rank_sources()` stay non-streaming. xAI Responses uses the shared Responses SSE parser and does not retry with `stream=false`.
132
+
133
+ Exa domain filters:
134
+
135
+ - `--include-domains` and `--exclude-domains` accept comma-separated or whitespace-separated domains.
136
+ - Both `--include-domains docs.python.org,developer.mozilla.org` and `--include-domains docs.python.org developer.mozilla.org` normalize to the same Exa domain list.
137
+ - This normalization is intentional for Windows PowerShell, where an unquoted comma expression can be forwarded through `.ps1` wrappers as a space-separated value.
138
+
139
+ ## Provider Failure Cooldown
140
+
141
+ - Same-capability fallback assumes a failing provider is worth retrying. A provider whose key is revoked, quota is exhausted, or endpoint is down is not, so its failures are persisted in `provider_health.json` and the provider is skipped for `SMART_SEARCH_PROVIDER_COOLDOWN_SECONDS` instead of being called again on every invocation.
142
+ - Hard failures (`auth_error`, `config_error`) open the cooldown immediately for four cooldown windows and are not probed. Soft failures need `SMART_SEARCH_PROVIDER_FAILURE_THRESHOLD` consecutive failures within one window, and automatic search respects cooldown until expiry or an explicit reset. Direct fetch retains its bounded recovery probe.
143
+ - A skipped provider appears in `provider_attempts` with `status=skipped`, the remembered `error_type`, and a `provider_health` block. It is not a silent drop, and it does not change same-capability fallback order.
144
+ - Zhipu reports several failures inside an HTTP `200` body. Those payloads are classified (`auth_error`, `rate_limited`, `provider_error`) instead of being reported as an empty result set, so a dead Zhipu channel is diagnosable and coolable.
145
+ - Recovery paths: `smart-search providers reset PROVIDER`, a credential change through `smart-search config set`, a successful `smart-search doctor` probe, or waiting out the cooldown.
146
+
147
+ ## Provider Output Details
148
+
149
+ - Exa HTTP `400` or `422` failures are returned as `ok=false` with `error_type=parameter_error`; use this to distinguish bad CLI/domain/date/category arguments from upstream network failures.
150
+ - AnySearch experimental output should preserve structured results without URLs as raw/structured evidence.
151
+ - Sciverse experimental output should preserve raw response data under `raw` while exposing normalized `fields`, `results`, `hits`, `text`, or `items` depending on the command.
152
+ - Diagnostic output should report Firecrawl status as whether `FIRECRAWL_API_KEY` is configured; it is not currently a live Firecrawl request.
153
+
154
+ ## Routing Heuristics
155
+
156
+ - Use `smart-search route "query" --format markdown` when you need to explain why a query maps to `docs_search`, `web_search`, `web_fetch`, or `vertical_search` without executing providers.
157
+ - Use `exa-search --include-domains` when official documentation domains are known.
158
+ - Use `context7-library` / `context7-docs` for docs/API/SDK/library/framework intent when Context7 is configured.
159
+ - Use `zhipu-search` for Chinese, domestic, current, or domain-filtered source discovery when Zhipu is configured.
160
+ - Use `exa-search --start-published-date` for recency-constrained source discovery.
161
+ - Use `exa-similar` when a known good page is available and adjacent sources are needed.
162
+ - Use `search --format content` when a human wants the selected channel output.
163
+ - Use `fetch --format markdown` or `fetch --format content` for user-supplied URLs or when exact page text matters.
164
+ - Use `map` before fetching many pages from a documentation site.
165
+ - Keep `search --extra-sources` small (`1` to `3`) unless broad coverage is requested.
166
+ - For current news or high-risk claims, prefer source discovery plus `fetch`; do not treat broad `search.content` plus source metadata as claim-level verification.
167
+
168
+ ## Maintenance Guardrails
169
+
170
+ - Provider architecture changes must be verified as distributable CLI behavior, not as behavior that only works because one developer machine has a specific wrapper, shell profile, or local config file.
171
+ - Register providers by capability first, then route by intent. Fallback is allowed only within the same capability family; model answers and web search are mutual fallbacks in ordinary search.
172
+ - Keep xAI Responses and OpenAI-compatible as peer `main_search` providers. A failed xAI Responses request may fall back to OpenAI-compatible only when `OPENAI_COMPATIBLE_API_URL` and `OPENAI_COMPATIBLE_API_KEY` are separately configured.
173
+ - Do not use Context7 for broad news or generic web facts; do not use Tavily or Firecrawl as documentation semantic-search replacements.
174
+ - After provider-routing changes, run source-checkout regression plus `smart-search smoke --mock --format json`. If live keys were used, run a targeted secret scan for exact key substrings before committing.
175
+
176
+ `primary_sources` preserves citations from a selected model channel; these are discovery candidates until read. `sources` contains returned source metadata; `extra_sources` is retained as an empty compatibility list.
177
+
178
+ Explicit cancellation returns `error_type=cancelled` with completed evidence and `partial_success`; do not treat the interrupted request as complete. App cancellation retains the same result and research artifacts.
@@ -0,0 +1,46 @@
1
+ # Regression And Release
2
+
3
+ ## Table of Contents
4
+
5
+ - Regression
6
+ - Smoke matrix
7
+ - Release lanes
8
+ - Release closeout lessons
9
+
10
+ ## Regression
11
+
12
+ Run `smart-search regression` before considering CLI or skill changes complete.
13
+
14
+ - In a source checkout, it runs offline pytest coverage for CLI, service, smoke, provider, and skill contract behavior.
15
+ - In npm / mise packaged installs, repository test files are not bundled; since v0.1.8 it falls back to built-in mock smoke regression so users can still verify installed CLI health.
16
+ - For release validation, use a source checkout for full pytest-backed regression and use packaged-install regression only as an install-health check.
17
+ - Provider architecture changes must be verified as distributable CLI behavior, not as behavior that only works because one developer machine has a specific wrapper, shell profile, or local config file.
18
+ - After provider-routing changes, run source-checkout regression plus `smart-search smoke --mock --format json`. If live keys were used, run a targeted secret scan for exact key substrings before committing.
19
+ - Read-only CI must cover Ubuntu Node 18/Python 3.10, Ubuntu Node 24/Python 3.12, and Windows Node 22/Python 3.12. It must never publish; it checks source regression, mock smoke, skill parity, pack dry-run, a fresh temporary-prefix tarball install, and committed diff whitespace with `git diff --check HEAD^1 HEAD` (or `git diff-tree --check --root -r --no-commit-id HEAD` for a root commit). A bare `git diff --check` after checkout only sees an empty worktree.
20
+
21
+ ## Smoke Matrix
22
+
23
+ - Deep Research smoke coverage is mock-full plus live-limited.
24
+ - Mock-full coverage should cover trigger phrases, normal search requests that should not trigger Deep Research, required `research_plan` fields, allowed tool whitelist, `fetch_before_claim`, evidence paths, capability boundaries, `intent_signals`, `capability_plan`, `gap_check`, simple current prompts such as `深度搜索一下最近的比特币行情`, docs/API prompts, claim-verification prompts, user-provided URL fetch-first flows, missing-provider failure guidance, research provider advantage routing, same-capability research fallback, and the rule that fixed topic recipe ids are not required schema.
25
+ - Live-limited coverage should run `doctor`, one broad `search`, one `exa-search`, and one `fetch` when real keys are available and live checks are expected; add one small `research` smoke when configured keys make it stable.
26
+ - If a smoke issue is found, fix the affected docs/code/tests and rerun the affected smoke until it passes or is proven to be an external provider blocker.
27
+
28
+ ## Release Lanes
29
+
30
+ - Stable releases are pushed as `vX.Y.Z` Git tags and publish npm `X.Y.Z` with dist-tag `latest`.
31
+ - Test releases are pushed from `main` and publish `<package.json version>-beta.N` with dist-tag `next`. The beta counter resets per base version, so `0.1.9-beta.1` and `0.1.10-beta.1` are separate sequences.
32
+ - Stable bump commits should use `chore(release): bump version to X.Y.Z`, but the workflow detects a stable bump by comparing the current stable package version with the first parent. This also skips beta publication for merge and squash release commits; the subject check remains a compatibility fallback.
33
+ - Stable GitHub release notes should be stored as `.github/releases/vX.Y.Z.md` before tagging. The publish workflow appends npm package, dist-tag, and workflow-run metadata to that body automatically.
34
+ - Historical test builds can be backfilled through GitHub Actions `workflow_dispatch` by supplying an explicit `target_ref`, exact `version`, and a non-`latest` npm tag such as `backfill`.
35
+ - npm versions are immutable. Old `*-dev.*` packages cannot be renamed in place; publish replacement `*-beta.N` packages and optionally deprecate the old names when npm owner credentials are available.
36
+ - npm publish runs use a repository-scoped concurrency group and must serialize rather than cancel an in-progress release.
37
+
38
+ ## Release Closeout Lessons
39
+
40
+ - Always read back npm before and after publishing with `npm view @konbakuyomu/smart-search versions --json` and `npm view @konbakuyomu/smart-search dist-tags --json`. A test release must leave `latest` on the stable version and move only `next` or the explicitly supplied non-`latest` tag.
41
+ - Backfill jobs can publish npm successfully even if GitHub release creation fails because the workflow token cannot access the release API. In that case, leave npm intact and create the missing GitHub prerelease with authenticated local `gh release create ... --prerelease --latest=false`.
42
+ - If concurrent backfill jobs hit npm `E409`, re-dispatch only the affected versions serially after checking whether the version already appeared in the registry.
43
+ - Finish with a diff-style gap check: expected beta version list minus npm versions equals empty, and expected `vX.Y.Z-beta.N` list minus GitHub prereleases equals empty.
44
+ - Local verification after a test release must use an exact install target, such as `mise use -g "npm:@konbakuyomu/smart-search@0.1.10-beta.3" -y --pin`, followed by `mise reshim`, `where.exe smart-search`, `smart-search --version`, packaged `smart-search regression`, and `smart-search smoke --mock --format json`.
45
+ - Also pipe a non-ASCII JSON command such as `smart-search deep "深度搜索一下最近的比特币行情" --format json | ConvertFrom-Json` to verify the Windows npm/mise wrapper is emitting UTF-8 JSON, not locale-encoded bytes.
46
+ - Before any remote release action, run the local temporary-prefix tarball smoke so a package from `npm pack` proves its wrapper, packaged regression fallback, and mock smoke without touching a global install.
@@ -0,0 +1,133 @@
1
+ # Setup And Config
2
+
3
+ ## Table of Contents
4
+
5
+ - Config storage
6
+ - Doctor and diagnostics
7
+ - Setup workflow
8
+ - Browser config UI
9
+ - Skill installation sync
10
+ - Provider endpoint setup
11
+ - Intent router setup
12
+
13
+ ## Config Storage
14
+
15
+ - Prefer the CLI's local config file managed by `smart-search setup` / `smart-search config`.
16
+ - Environment variables remain supported for CI and advanced users, and override the local config file.
17
+ - `SMART_SEARCH_TIMEOUT_SECONDS` persists the total monotonic `search` budget and defaults to `300`; explicit `search --timeout SECONDS` overrides environment, config, and default for one invocation. The budget is also the main-search read ceiling, so slow reasoning models are no longer cut off by a separate fixed provider read timeout.
18
+ - `SMART_SEARCH_PROVIDER_COOLDOWN_SECONDS` defaults to `900` and `SMART_SEARCH_PROVIDER_FAILURE_THRESHOLD` defaults to `2`. They control how long a repeatedly failing optional provider is skipped; `SMART_SEARCH_PROVIDER_COOLDOWN_SECONDS=0` disables the cooldown entirely.
19
+ - Do not ask users to set Windows global API-key environment variables by default.
20
+ - If keys are changed with `smart-search config set`, rerun the CLI; no Codex restart is needed.
21
+ - If PATH is changed, a new terminal or Codex restart may be needed.
22
+ - On Windows, the default local config file is `%LOCALAPPDATA%\smart-search\config.json`. Linux/macOS default to `~/.config/smart-search/config.json`.
23
+ - In sandboxed runtimes where the default config directory is not writable or must be pinned, set `SMART_SEARCH_CONFIG_DIR` to an absolute writable path. The CLI uses it for both config and relative logs and skips default-directory selection.
24
+ - Earlier Windows source defaults used `~\.config\smart-search\config.json`, while some installs were already pinned to `%LOCALAPPDATA%\smart-search` through `SMART_SEARCH_CONFIG_DIR`. If the new default file is missing but the old file exists, `doctor` reports `legacy_windows_home` as the active source so upgrades do not silently lose configuration.
25
+ - When a Windows user reports different config paths, diagnose in this order: `config_dir_source`, `config_dir_override_value`, `config_dir_override_matches_default`, then `legacy_windows_config_exists`. Do not delete either config file or the user-level override until the upgraded CLI has been verified with `config path`, `doctor`, and smoke/regression checks.
26
+
27
+ ## Doctor And Diagnostics
28
+
29
+ - Use `smart-search doctor --format json` for agent/script parsing and `smart-search doctor --format markdown` when a human wants a detailed diagnostic report.
30
+ - If `smart-search doctor --format json` returns `ok: false`, follow the `error` field's guidance (`smart-search setup` or `smart-search config set KEY VALUE`); do not silently fall back to native web search.
31
+ - `doctor --format markdown` must render a detailed diagnostic report with overall status, active/default/legacy config paths, log path resolution, file-logging status, masked config values with sources, minimum profile, capability status, providers currently on failure cooldown, main-search provider checks, provider connectivity checks, Jev/local router status, model metadata, and full long error/message detail.
32
+ - Use `smart-search diagnose openai-compatible --format markdown` when `doctor` succeeds but OpenAI-compatible `search` appears to hang, returns a timeout, or differs between `--stream` and `--no-stream`. It is the beginner-facing one-command report for upstream/relay compatibility.
33
+ - `diagnose openai-compatible --format markdown` must render a short copy-pasteable troubleshooting report with masked config, the selected API mode and endpoint, a quick selected-endpoint check, real search-shape `stream=false` and `stream=true` checks, fallback-model inventory against `/models`, the remaining-budget timeout policy, a plain-language summary, and a next command.
34
+
35
+ ## Setup Workflow
36
+
37
+ - Interactive `smart-search setup` is a language-selecting grouped wizard with arrow-key / Space / Enter provider selection. It groups optional providers by capability; configure one retrieval channel, then add Jev or page reading as needed.
38
+ - Default `smart-search setup` shows a Smart Search ASCII banner, asks for `zh` or `en`, offers user-level `smart-search-cli` skill installation, then shows a grouped provider wizard.
39
+ - The grouped wizard should use an arrow-key / Space / Enter selector when packaged TUI dependencies are available, with a text fallback for non-TTY and tests.
40
+ - Use `smart-search setup --lang en` for an English wizard.
41
+ - Use `smart-search setup --advanced` only when low-level config keys must be shown one by one; Jev/local routing is available in the default wizard. `--advanced` does not show the skill prompt unless `--install-skills` is explicit.
42
+ - `--non-interactive` keeps script behavior and only saves values passed as flags.
43
+ - Provider groups are optional choices: configure at least one usable retrieval channel, then add Jev and research page reading as needed.
44
+ - Unchecking a configured provider must not delete existing config values; use `smart-search config unset KEY` for deletion.
45
+ - Interactive output should summarize `minimum_profile_ok`, missing required capabilities, and next-step commands.
46
+ - Beginner filling examples for official-service and relay/pooled-endpoint minimum profiles must appear in the grouped wizard on stderr, not stdout. They must cover `main_search`, `docs_search`, and `web_fetch`.
47
+
48
+ ## Browser Config UI
49
+
50
+ - `smart-search ui` opens a temporary local config page for users who prefer forms to the terminal wizard. Its test page supports offline route preview and ordinary single-pass search; start research from the App or CLI.
51
+ - It binds `127.0.0.1` on a random port, prints a URL carrying a one-time token, and exits once the browser tab stops sending heartbeats. It is not a daemon and needs no extra install: stdlib `http.server` plus one bundled HTML file.
52
+ - Flags: `--no-browser` (print the URL only), `--port N`, `--idle-timeout SEC` (default `900`, `0` disables), `--lang zh|en`, `--check` (verify the bundled page resolves, then exit), plus the usual `--format`.
53
+ - On a headless host, SSH session, or container the browser is deliberately not opened; the URL is printed and a `ssh -L` forwarding recipe is shown. Use `--port` to pin the port for forwarding.
54
+ - The page never receives unmasked secrets. Keys supplied through environment variables render as locked, because environment variables override `config.json` on every read; the page names the `unset` to run.
55
+ - Per-provider Test buttons call `smart-search providers test PROVIDER` equivalents. Each one is a real, possibly billable API request, so nothing is probed until the user clicks.
56
+ - Do not recommend the UI for scripted or non-interactive work; `smart-search setup --non-interactive` and `smart-search config set` remain the automation path.
57
+
58
+ ## Skill Installation Sync
59
+
60
+ - Skill installation installs the bundled `smart-search-cli` skill into selected AI-tool skill directories and must not run `trellis init`, create hooks, create agents, create commands, or modify other skills.
61
+ - Targets are user-level/global directories under the current user's home directory, for example Codex `~/.agents/skills/`, Claude Code `~/.claude/skills/`, Cursor `~/.cursor/skills/`, OpenCode `~/.config/opencode/skills/`, GitHub Copilot `~/.copilot/skills/`, and Hermes Agent `~/.hermes/skills/`.
62
+ - Skill targets are `codex`, `claude`, `cursor`, `opencode`, `copilot`, `gemini`, `kiro`, `qoder`, `codebuddy`, `droid`, `pi`, `kilo`, `antigravity`, `windsurf`, and `hermes`.
63
+ - OpenCode's canonical global skill directory is `~/.config/opencode/skills/smart-search-cli`. `skills status` reports a discovered legacy `~/.opencode/skills/smart-search-cli` directory as read-only `legacy_locations` metadata; it never migrates or deletes that tree.
64
+ - `--skip-skills` disables skill installation.
65
+ - `--install-skills codex,claude,cursor,hermes` selects targets explicitly.
66
+ - `--skills-root PATH` is an advanced synthetic home-root override used in portable installs or tests. For OpenCode, `--skills-root T` writes to `T/.config/opencode/skills/smart-search-cli`. Normal users should omit it.
67
+ - `smart-search agent-guide [relative-path]` reads current instructions directly from the installed CLI. A Skill's local invocation prefix also applies to this command.
68
+ - `smart-search skills remove --targets codex --format json` moves selected Skill files into a backup folder and disconnects automatic maintenance. It does not uninstall the CLI or remove configuration.
69
+ - CLI-owned automatic maintenance affects only explicitly connected targets bound to this installation. It preserves personal edits, missing files, extra files and each target's configuration directory. Version/capability probes and `skills status` never perform maintenance.
70
+ - `smart-search skills status --targets codex,claude,cursor,hermes --format json` compares bundled skill files with installed user-level skill directories. Status values are `missing`, `up_to_date`, `stale`, `extra_files`, and `error`. It reports target paths, bundled file count, installed file count, hashes, hash match flags, missing files, stale files, and extra files. OpenCode also reports discovered legacy locations. Status must not write or delete files.
71
+ - `smart-search skills update --targets codex,claude,cursor,hermes --format json` overwrites the managed bundled `smart-search-cli` files for selected targets. For OpenCode, setup and update write managed files only to the canonical config path; legacy trees and user extra files remain untouched. `smart-search skills update --all --format json` selects every target id.
72
+ - This daily sync path must not change provider keys, run setup prompts, create Trellis files, create hooks, create agents, create commands, or delete leftover files. Extra installed files are only reported by `skills status`.
73
+ - `smart-search setup --non-interactive --install-skills codex` remains the first-time setup compatibility path. Prefer `skills status` and `skills update` for routine global skill synchronization after CLI upgrades.
74
+
75
+ ## Provider Endpoint Setup
76
+
77
+ - Setup and config output should include `ok` and `config_file`. Saved API keys must be masked in command output.
78
+ - Use `smart-search setup --non-interactive --zhipu-api-url "https://open.bigmodel.cn/api" --zhipu-search-engine "search_std"` to save Zhipu Web Search API endpoint and search service without prompts.
79
+ - Interactive setup asks for Zhipu API key, API URL, and search service when the user selects Zhipu in the provider wizard.
80
+ - `config set ZHIPU_SEARCH_ENGINE VALUE` must remain free-form so newly added official services do not require a CLI release.
81
+ - `ZHIPU_API_URL` defaults to `https://open.bigmodel.cn/api`.
82
+ - `ZHIPU_SEARCH_ENGINE` defaults to `search_std`.
83
+ - Official Web Search API service values include `search_std`, `search_pro`, `search_pro_sogou`, and `search_pro_quark`.
84
+ - Use `smart-search setup --non-interactive --jina-key "key"` to let Jina satisfy `web_fetch`; `JINA_RESPOND_WITH=readerlm-v2` also requires `JINA_API_KEY`.
85
+ - Use `smart-search setup --non-interactive --zhipu-mcp-key "key"` only when the user explicitly wants Coding Plan Remote MCP quota.
86
+ - Use `smart-search setup --non-interactive --openai-compatible-api-mode responses` only when a named relay requires `/responses`. The default is `chat-completions` and uses `/chat/completions`; invalid modes fail before setup saves any field.
87
+ - Use `smart-search setup --non-interactive --openai-compatible-stream true` only when an OpenAI-compatible relay benefits from SSE streaming for long requests. Default remains false.
88
+ - Use `smart-search setup --non-interactive --openai-compatible-fallback-models "model-a,model-b"` to save ordered OpenAI-compatible backup models for primary model hard failure. These models do not receive a reserved time slice; the primary model keeps the remaining shared main-search budget. `--fallback off` and `search --model MODEL` disable this model fallback for one invocation.
89
+ - Use `smart-search setup --non-interactive --search-timeout 300` or `smart-search config set SMART_SEARCH_TIMEOUT_SECONDS 300` to persist the normal search budget. Invalid non-positive values fail before provider work.
90
+ - Use `smart-search setup --non-interactive --anysearch-api-url "https://api.anysearch.com/mcp" --anysearch-key "key"` only for experimental AnySearch acceptance; do not add it to the normal minimum-profile setup.
91
+ - Use `smart-search setup --non-interactive --sciverse-token "key" --sciverse-api-url "https://api.sciverse.space"` only for explicit experimental Sciverse academic commands; do not add it to the normal minimum-profile setup.
92
+ - `TAVILY_API_URL` defaults to `https://api.tavily.com` and only affects Tavily REST calls. It does not proxy Zhipu.
93
+ - Use `TAVILY_API_URL=https://<host>/api/tavily` for Tavily Hikari / pooled endpoints. Root host and `/mcp` inputs are normalized by setup; `/mcp` itself is not the REST base Smart Search should call.
94
+ - `TAVILY_TIMEOUT_SECONDS` controls the Tavily `doctor` connectivity timeout and defaults to `30`. Raise it for slower pooled/community Tavily endpoints before judging the provider unhealthy.
95
+ - `ANYSEARCH_API_URL` defaults to `https://api.anysearch.com/mcp`; `ANYSEARCH_TIMEOUT_SECONDS` defaults to `30`.
96
+ - `SCIVERSE_API_URL` defaults to `https://api.sciverse.space`; `SCIVERSE_TIMEOUT_SECONDS` defaults to `30`.
97
+ - `FIRECRAWL_API_URL` defaults to `https://api.firecrawl.dev/v2`. Use it only for a Firecrawl-compatible REST base.
98
+ - Use `smart-search setup --non-interactive --tinyfish-key "key"` to add TinyFish to `web_search` and `web_fetch`. It never satisfies `main_search` or `docs_search`; Jev can select it among the allowed channels.
99
+ - `TINYFISH_SEARCH_API_URL` defaults to `https://api.search.tinyfish.ai`, and `TINYFISH_FETCH_API_URL` defaults to `https://api.fetch.tinyfish.ai`. Both authenticate with the `X-API-Key` header, not a bearer token.
100
+ - `TINYFISH_TIMEOUT_SECONDS` defaults to `60` and covers both TinyFish search and fetch reads.
101
+
102
+ ## Provider Failure Cooldown
103
+
104
+ - Optional providers (`web_search`, `docs_search`, `web_fetch`, `vertical_search`) are additive. When one keeps failing, Smart Search records it in `provider_health.json` next to `config.json` and skips it instead of re-calling it on every invocation. Search-model channels also respect the shared health gate.
105
+ - A hard failure (`auth_error`, `config_error`) opens the cooldown on the first occurrence and is never probed, because a bad key does not heal itself. Soft failures (timeout, `5xx`, rate limit) need `SMART_SEARCH_PROVIDER_FAILURE_THRESHOLD` consecutive failures and automatic search waits until cooldown expiry or an explicit reset.
106
+ - An empty result set is not a failure and never opens a cooldown.
107
+ - The record is keyed to a fingerprint of the provider's credentials, so re-keying a provider with `smart-search config set` clears its cooldown automatically. A successful `smart-search doctor` probe also clears it.
108
+ - `smart-search providers test PROVIDER [PROVIDER...]` checks whether saved credentials still work for one provider at a time, instead of `doctor`'s all-at-once fan-out. Each run is a real API request. `--timeout` caps each probe. A passing test clears that provider's cooldown, the same way a `doctor` probe does. Firecrawl reports `probe: presence` because only key presence can be checked.
109
+ - Use `smart-search providers status --format json` to see which providers are cooling and why, and `smart-search providers reset PROVIDER` to retry one immediately. `smart-search providers reset` with no argument clears every cooldown.
110
+ - Use `smart-search setup --non-interactive --provider-cooldown 600 --provider-failure-threshold 3`, or `smart-search config set SMART_SEARCH_PROVIDER_COOLDOWN_SECONDS VALUE`, to persist the cooldown policy. A negative or non-numeric cooldown and a non-positive threshold fail before setup saves any field.
111
+ - A skipped provider is still reported: the attempt has `status=skipped` with the remembered `error_type`, and `provider_notices` carries one deduplicated entry per degraded provider.
112
+
113
+ ## Intent Router Setup
114
+
115
+ - `--search-timeout` (also `--search-timeout-seconds`) is the non-interactive setup flag for the total search budget; it does not change individual provider endpoint timeouts.
116
+
117
+ ## Language and complete handbook
118
+
119
+ From v0.1.21, Smart Search supports `smart-search --lang en --help`, `smart-search search QUERY --lang zh`, and saved `SMART_SEARCH_LANGUAGE=auto|zh|en` through `config set`. Priority is per-call flag, dedicated environment variable, saved configuration, then system locale. Command/JSON identifiers and source content stay unchanged. App language is independent.
120
+
121
+ The [bilingual handbook](https://github.com/konbakuyomu/smartsearch/tree/main/docs/guide) contains the [complete command reference](https://github.com/konbakuyomu/smartsearch/blob/main/docs/guide/en/cli-reference.md) and [all saved configuration keys](https://github.com/konbakuyomu/smartsearch/blob/main/docs/guide/en/configuration-reference.md).
122
+
123
+ ## Current routing configuration
124
+
125
+ `SMART_SEARCH_INTENT_ROUTER=jev|local` defaults to `jev`. `hybrid` maps to `jev`; `rules`/`off` map to `local`. Retired `INTENT_EMBEDDING_*`, `INTENT_CLASSIFIER_*`, and `INTENT_ROUTER_TIMEOUT_SECONDS` keys stay stored, without remote calls or preset changes.
126
+
127
+ ```powershell
128
+ smart-search config set TYPESAFE_API_KEY "your-key"
129
+ smart-search config set SMART_SEARCH_INTENT_ROUTER jev
130
+ smart-search route "React docs" --format json
131
+ ```
132
+
133
+ `TYPESAFE_API_KEY` is optional with `--fallback auto`; local routing needs no router credentials. See `references/provider-routing.md` for the two-mode execution contract.