@konbakuyomu/smart-search-linux-x64 0.1.25 → 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.
- package/package.json +1 -1
- package/runtime/smart-search/_internal/base_library.zip +0 -0
- package/runtime/smart-search/_internal/smart_search/activity.py +1 -1
- package/runtime/smart-search/_internal/smart_search/assets/i18n/messages.json +183 -19
- package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/SKILL.md +6 -6
- package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/references/cli-core.md +5 -5
- package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/references/command-patterns.md +12 -22
- package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/references/deep-research-mode.md +8 -8
- package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/references/provider-routing.md +33 -62
- package/runtime/smart-search/_internal/smart_search/assets/skills/smart-search-cli/references/setup-config.md +21 -13
- package/runtime/smart-search/_internal/smart_search/assets/ui/index.html +41 -15
- package/runtime/smart-search/_internal/smart_search/cli.py +118 -401
- package/runtime/smart-search/_internal/smart_search/config.py +34 -69
- package/runtime/smart-search/_internal/smart_search/desktop_catalog.py +13 -13
- package/runtime/smart-search/_internal/smart_search/desktop_worker.py +2 -1
- package/runtime/smart-search/_internal/smart_search/intent_router.py +6 -550
- package/runtime/smart-search/_internal/smart_search/jev.py +37 -5
- package/runtime/smart-search/_internal/smart_search/jev_search.py +336 -192
- package/runtime/smart-search/_internal/smart_search/provider_descriptions.py +140 -0
- package/runtime/smart-search/_internal/smart_search/providers/context7.py +8 -1
- package/runtime/smart-search/_internal/smart_search/providers/openai_compatible.py +19 -2
- package/runtime/smart-search/_internal/smart_search/providers/xai_responses.py +30 -4
- package/runtime/smart-search/_internal/smart_search/service.py +241 -2030
- package/runtime/smart-search/_internal/smart_search/ui_metadata.py +61 -80
- package/runtime/smart-search/_internal/{smart_search-0.1.25.dist-info → smart_search-0.1.26.dist-info}/METADATA +2 -1
- package/runtime/smart-search/_internal/{smart_search-0.1.25.dist-info → smart_search-0.1.26.dist-info}/RECORD +32 -32
- package/runtime/smart-search/_internal/wcwidth/_wcwidth_c.abi3.so +0 -0
- package/runtime/smart-search/_internal/wcwidth/_wcwidth_c.pyi +77 -0
- package/runtime/smart-search/package.json +7 -7
- package/runtime/smart-search/smart-search +0 -0
- package/runtime/smart-search/_internal/smart_search/embedding_presets.py +0 -40
- /package/runtime/smart-search/_internal/{smart_search-0.1.25.dist-info → smart_search-0.1.26.dist-info}/INSTALLER +0 -0
- /package/runtime/smart-search/_internal/{smart_search-0.1.25.dist-info → smart_search-0.1.26.dist-info}/REQUESTED +0 -0
- /package/runtime/smart-search/_internal/{smart_search-0.1.25.dist-info → smart_search-0.1.26.dist-info}/WHEEL +0 -0
- /package/runtime/smart-search/_internal/{smart_search-0.1.25.dist-info → smart_search-0.1.26.dist-info}/direct_url.json +0 -0
- /package/runtime/smart-search/_internal/{smart_search-0.1.25.dist-info → smart_search-0.1.26.dist-info}/entry_points.txt +0 -0
- /package/runtime/smart-search/_internal/{smart_search-0.1.25.dist-info → smart_search-0.1.26.dist-info}/licenses/LICENSE +0 -0
- /package/runtime/smart-search/_internal/{smart_search-0.1.25.dist-info → smart_search-0.1.26.dist-info}/top_level.txt +0 -0
|
@@ -1,84 +1,52 @@
|
|
|
1
1
|
# Provider Routing
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Intent Routing Diagnostics
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- Intent routing diagnostics
|
|
7
|
-
- Provider boundaries
|
|
8
|
-
- Provider output details
|
|
9
|
-
- Routing heuristics
|
|
10
|
-
- Maintenance guardrails
|
|
5
|
+
`search` and `research` are the two live search modes. Both share the configured channel catalog, execution, deadlines, and evidence records.
|
|
11
6
|
|
|
12
|
-
|
|
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`.
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
- `extra_sources`: parallel Tavily / Firecrawl candidates from `--extra-sources`; these are not automatic evidence for the generated `content`.
|
|
16
|
-
- `sources`: backward-compatible merged list from `primary_sources + extra_sources`, deduped by URL.
|
|
17
|
-
- `source_warning`: non-empty when extra source candidates were appended.
|
|
18
|
-
- `extra_sources` are retrieved in parallel and are not automatically used by the primary model to verify its answer.
|
|
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.
|
|
19
12
|
|
|
20
|
-
|
|
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.
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Intent router rules:
|
|
27
|
-
|
|
28
|
-
- `SMART_SEARCH_INTENT_ROUTER=hybrid|rules|off|jev`, default `hybrid`. `SMART_SEARCH_INTENT_ROUTER` accepts `hybrid`, `rules`, `off`, and `jev`.
|
|
29
|
-
- Jev is the recommended optional mode; users opt in with `TYPESAFE_API_KEY` and at least one configured retrieval channel. It selects allowed operations using capabilities and existing provider preferences, then judges evidence before a new query, another engine, or page reading. Missing/unavailable judgments use explicit fixed-capability fallback when allowed, without the legacy remote classifier. `SMART_SEARCH_RESEARCH_DISABLED_PROVIDERS` and `--providers` restrict its candidates; Sciverse remains explicit-only.
|
|
30
|
-
- `SMART_SEARCH_JEV_FILTER_RESULTS=true` enables conservative binary passage filtering after retrieval. Failures retain original evidence; changed content is reassessed before claiming sufficiency. `SMART_SEARCH_JEV_SYNTHESIZE=false` is the default: no mandatory main-model synthesis. `SMART_SEARCH_JEV_MAX_ROUNDS=3` and `SMART_SEARCH_JEV_MAX_CHANNELS=3` bound execution within `--timeout`.
|
|
31
|
-
- `SMART_SEARCH_JEV_SYNTHESIZE` accepts `true`, `false`, and `auto`. Auto asks Jev after optional filtering whether the retained evidence benefits from main-model synthesis. No allowed main model or a failed judgment returns evidence directly. `synthesis` reports the mode, decision probability, execution status and skip reason.
|
|
32
|
-
- In Jev mode `search` and `research` return evidence with assessment/filter/usage telemetry. Research retains its offline plan, budget tiers, reports, and fetched/read-only citations. `route --router-mode jev` lists local candidates without TypeSafe; `--remote` explicitly enables a potentially billable judgment. `deep` stays an offline planner.
|
|
33
|
-
- Optional semantic routing uses `INTENT_EMBEDDING_API_URL`, `INTENT_EMBEDDING_API_KEY`, `INTENT_EMBEDDING_MODEL`, `INTENT_EMBEDDING_THRESHOLD`, and `INTENT_EMBEDDING_MARGIN`.
|
|
34
|
-
- Normal users should use the Qwen3-Embedding-8B preset: SiliconFlow endpoint `https://api.siliconflow.cn/v1/embeddings`, model `Qwen/Qwen3-Embedding-8B`, threshold `0.475`, and margin `0.053`.
|
|
35
|
-
- `smart-search setup` auto-fills threshold/margin when Qwen3-Embedding-8B is selected and no explicit values are already configured.
|
|
36
|
-
- Embedding thresholds are model-specific. Run `smart-search route-calibrate --models "Qwen/Qwen3-Embedding-8B" --format json` after changing model/endpoint or refreshing the real-query calibration set; use semantic-only Macro-F1 as the primary selector and full-route Macro-F1 as validation.
|
|
37
|
-
- Optional model classification uses `INTENT_CLASSIFIER_API_URL`, `INTENT_CLASSIFIER_API_KEY`, and `INTENT_CLASSIFIER_MODEL`.
|
|
38
|
-
- `INTENT_ROUTER_TIMEOUT_SECONDS` defaults to `8`.
|
|
39
|
-
- Missing or failing embeddings/classifier degrade to rules and should not fail ordinary `search`.
|
|
40
|
-
- Semantic matches add a capability only when the top score reaches `INTENT_EMBEDDING_THRESHOLD` and the top-vs-second gap reaches `INTENT_EMBEDDING_MARGIN`; ambiguous semantic matches are recorded as signals only.
|
|
41
|
-
- The router returns capabilities only: `docs_search`, `web_search`, `web_fetch`, and `vertical_search`.
|
|
42
|
-
- Classifier output cannot select providers. Unknown capability names and provider names are ignored.
|
|
43
|
-
- `search` and `research` use the unified router. `deep` remains an offline planner and must not call embeddings or classifier components.
|
|
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.
|
|
44
20
|
|
|
45
21
|
## Provider Boundaries
|
|
46
22
|
|
|
47
|
-
- `search` builds `main_search` from configured peer providers: `XAI_API_KEY` for xAI Responses and `OPENAI_COMPATIBLE_API_URL` + `OPENAI_COMPATIBLE_API_KEY` for an OpenAI-compatible route.
|
|
48
|
-
- `search` uses unified `IntentRouter` output to populate `required_capabilities` and `supplemental_paths`; provider execution still follows capability-first fallback.
|
|
49
|
-
- `research` reuses the same `IntentRouter` before provider-advantage ordering.
|
|
50
23
|
- `deep` uses offline rules/local signals only and must not call remote embeddings or classifier components.
|
|
51
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.
|
|
52
|
-
- `
|
|
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.
|
|
53
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.
|
|
54
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.
|
|
55
29
|
- Neither OpenAI-compatible API mode sends xAI `web_search` / `x_search` tools or legacy `search_parameters`; xAI Chat Completions Live Search is deprecated.
|
|
56
|
-
- The standard minimum profile requires one configured provider in each of `main_search`, `docs_search`, and fetch capability. Missing required capabilities should be treated as a hard configuration failure.
|
|
57
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.
|
|
58
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.
|
|
59
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.
|
|
60
|
-
- Same-capability fallback is allowed;
|
|
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.
|
|
61
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.
|
|
62
|
-
-
|
|
63
|
-
- `
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
- Fetch capability: Tavily first, then Jina Reader with `JINA_API_KEY`, then Zhipu Coding Plan MCP `webReader`, then Firecrawl, then TinyFish.
|
|
67
|
-
- `search` calls Tavily and/or Firecrawl only when `--extra-sources N` is greater than 0.
|
|
68
|
-
- With both Tavily and Firecrawl configured, `search --extra-sources N` splits extra sources between them, with Tavily receiving about 60% and Firecrawl the rest.
|
|
69
|
-
- `fetch` and known-URL `search "https://..."` use the same fetch fallback chain.
|
|
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.
|
|
70
39
|
- `fetch` tries Tavily first, then Jina with `JINA_API_KEY`, then Zhipu Coding Plan MCP Reader, then Firecrawl, then TinyFish.
|
|
71
40
|
|
|
72
41
|
TinyFish:
|
|
73
42
|
|
|
74
|
-
- `TINYFISH_API_KEY` is optional and registers TinyFish for both `web_search` and `web_fetch`. It never satisfies `main_search` or `docs_search
|
|
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.
|
|
75
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"}`.
|
|
76
45
|
- Both endpoints send `X-API-Key`, not `Authorization: Bearer`. Never log or echo the key.
|
|
77
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.
|
|
78
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`.
|
|
79
48
|
- Challenge pages such as `Checking if the site connection is secure` are reported as `quality_error` so same-capability fallback can continue.
|
|
80
49
|
- `401`/403 map to `auth_error`, `408` to `timeout`, `429` to `rate_limited`, `5xx` to `network_error`, and `400`/422 to `parameter_error`.
|
|
81
|
-
- `--extra-sources N` reaches TinyFish only when neither Tavily nor Firecrawl is configured; with Tavily or Firecrawl present, TinyFish stays in the web_search fallback chain instead of splitting the extra-source budget.
|
|
82
50
|
- `map` currently uses Tavily only.
|
|
83
51
|
- `exa-search` and `exa-similar` use Exa only.
|
|
84
52
|
- `context7-library` and `context7-docs` use Context7 only.
|
|
@@ -109,7 +77,7 @@ Zhipu Coding Plan Remote MCP:
|
|
|
109
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.
|
|
110
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.
|
|
111
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.
|
|
112
|
-
- Provider failures must appear in `provider_attempts` and fallback must remain same-capability.
|
|
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.
|
|
113
81
|
- `doctor` should report configured/not-configured, auth, rate-limit, provider, timeout, and network status without exposing the MCP token.
|
|
114
82
|
|
|
115
83
|
Jina Reader:
|
|
@@ -154,13 +122,13 @@ OpenAI-compatible streaming:
|
|
|
154
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`.
|
|
155
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.
|
|
156
124
|
- `OPENAI_COMPATIBLE_STREAM` defaults to `false` and accepts `true`, `1`, or `yes` as true.
|
|
157
|
-
- `search --stream` means "prefer stream first"; stream empty/timeout/retryable protocol failures fall back to the same provider/model with `stream=false`.
|
|
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`.
|
|
158
126
|
- `search --no-stream` forces `stream=false` for the current invocation.
|
|
159
|
-
- `SMART_SEARCH_TIMEOUT_SECONDS` defines one 300-second default monotonic `search` budget
|
|
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.
|
|
160
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.
|
|
161
|
-
- `timeout_phase`, `phase_attempts`, elapsed/remaining deadline values, and `partial_success`
|
|
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.
|
|
162
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`.
|
|
163
|
-
- Streaming applies
|
|
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`.
|
|
164
132
|
|
|
165
133
|
Exa domain filters:
|
|
166
134
|
|
|
@@ -171,7 +139,7 @@ Exa domain filters:
|
|
|
171
139
|
## Provider Failure Cooldown
|
|
172
140
|
|
|
173
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.
|
|
174
|
-
- 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
|
|
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.
|
|
175
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.
|
|
176
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.
|
|
177
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.
|
|
@@ -191,17 +159,20 @@ Exa domain filters:
|
|
|
191
159
|
- Use `zhipu-search` for Chinese, domestic, current, or domain-filtered source discovery when Zhipu is configured.
|
|
192
160
|
- Use `exa-search --start-published-date` for recency-constrained source discovery.
|
|
193
161
|
- Use `exa-similar` when a known good page is available and adjacent sources are needed.
|
|
194
|
-
- Use `search --format content` when a human wants
|
|
162
|
+
- Use `search --format content` when a human wants the selected channel output.
|
|
195
163
|
- Use `fetch --format markdown` or `fetch --format content` for user-supplied URLs or when exact page text matters.
|
|
196
164
|
- Use `map` before fetching many pages from a documentation site.
|
|
197
165
|
- Keep `search --extra-sources` small (`1` to `3`) unless broad coverage is requested.
|
|
198
|
-
- For current news or high-risk claims, prefer source discovery plus `fetch`; do not treat broad `search.content` plus
|
|
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.
|
|
199
167
|
|
|
200
168
|
## Maintenance Guardrails
|
|
201
169
|
|
|
202
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.
|
|
203
|
-
- Register providers by capability first, then route by intent. Fallback is allowed only within the same capability.
|
|
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.
|
|
204
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.
|
|
205
173
|
- Do not use Context7 for broad news or generic web facts; do not use Tavily or Firecrawl as documentation semantic-search replacements.
|
|
206
|
-
- Standard installs must fail closed unless `main_search`, `docs_search`, and fetch capability each have at least one configured provider.
|
|
207
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.
|
|
@@ -28,26 +28,26 @@
|
|
|
28
28
|
|
|
29
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
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,
|
|
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
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
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
34
|
|
|
35
35
|
## Setup Workflow
|
|
36
36
|
|
|
37
|
-
- Interactive `smart-search setup` is a language-selecting grouped wizard with arrow-key / Space / Enter provider selection. It
|
|
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
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
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
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;
|
|
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
42
|
- `--non-interactive` keeps script behavior and only saves values passed as flags.
|
|
43
|
-
-
|
|
43
|
+
- Provider groups are optional choices: configure at least one usable retrieval channel, then add Jev and research page reading as needed.
|
|
44
44
|
- Unchecking a configured provider must not delete existing config values; use `smart-search config unset KEY` for deletion.
|
|
45
45
|
- Interactive output should summarize `minimum_profile_ok`, missing required capabilities, and next-step commands.
|
|
46
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
47
|
|
|
48
48
|
## Browser Config UI
|
|
49
49
|
|
|
50
|
-
- `smart-search ui` opens a temporary local config page
|
|
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
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
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
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.
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
|
|
77
77
|
- Setup and config output should include `ok` and `config_file`. Saved API keys must be masked in command output.
|
|
78
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
|
|
79
|
+
- Interactive setup asks for Zhipu API key, API URL, and search service when the user selects Zhipu in the provider wizard.
|
|
80
80
|
- `config set ZHIPU_SEARCH_ENGINE VALUE` must remain free-form so newly added official services do not require a CLI release.
|
|
81
81
|
- `ZHIPU_API_URL` defaults to `https://open.bigmodel.cn/api`.
|
|
82
82
|
- `ZHIPU_SEARCH_ENGINE` defaults to `search_std`.
|
|
@@ -95,14 +95,14 @@
|
|
|
95
95
|
- `ANYSEARCH_API_URL` defaults to `https://api.anysearch.com/mcp`; `ANYSEARCH_TIMEOUT_SECONDS` defaults to `30`.
|
|
96
96
|
- `SCIVERSE_API_URL` defaults to `https://api.sciverse.space`; `SCIVERSE_TIMEOUT_SECONDS` defaults to `30`.
|
|
97
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
|
|
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
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
100
|
- `TINYFISH_TIMEOUT_SECONDS` defaults to `60` and covers both TinyFish search and fetch reads.
|
|
101
101
|
|
|
102
102
|
## Provider Failure Cooldown
|
|
103
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.
|
|
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
|
|
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
106
|
- An empty result set is not a failure and never opens a cooldown.
|
|
107
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
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.
|
|
@@ -112,14 +112,22 @@
|
|
|
112
112
|
|
|
113
113
|
## Intent Router Setup
|
|
114
114
|
|
|
115
|
-
- Interactive setup asks for `SMART_SEARCH_INTENT_ROUTER`, `INTENT_EMBEDDING_*`, `INTENT_CLASSIFIER_*`, and `INTENT_ROUTER_TIMEOUT_SECONDS` when optional smart intent routing is selected. Keep examples official or neutral and keep keys masked.
|
|
116
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.
|
|
117
|
-
- Default guided setup can configure `SMART_SEARCH_INTENT_ROUTER`, `INTENT_EMBEDDING_*`, `INTENT_CLASSIFIER_*`, and `INTENT_ROUTER_TIMEOUT_SECONDS` without `--advanced`.
|
|
118
|
-
- Default guided setup recommends SiliconFlow + `Qwen/Qwen3-Embedding-8B` for embeddings and auto-fills threshold `0.475` plus margin `0.053` when no explicit threshold/margin exists.
|
|
119
|
-
- Existing mismatched threshold/margin values should produce a warning rather than being silently overwritten.
|
|
120
116
|
|
|
121
117
|
## Language and complete handbook
|
|
122
118
|
|
|
123
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.
|
|
124
120
|
|
|
125
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.
|
|
@@ -49,6 +49,10 @@ h2 { font-size: 20px; margin: 0 0 6px; }
|
|
|
49
49
|
}
|
|
50
50
|
.card h3 { margin: 0 0 2px; font-size: 15px; display: flex; align-items: center; gap: 8px; }
|
|
51
51
|
.card .note { color: var(--muted); font-size: 13px; margin: 0 0 12px; }
|
|
52
|
+
.card .provider-guidance {
|
|
53
|
+
color: var(--muted); font-size: 12px; margin: 0 0 12px; padding: 8px 10px;
|
|
54
|
+
border-left: 2px solid var(--accent); background: var(--bg); border-radius: 4px;
|
|
55
|
+
}
|
|
52
56
|
.banner { border-left: 3px solid var(--accent); }
|
|
53
57
|
.banner.ok { border-left-color: var(--ok); }
|
|
54
58
|
.banner.bad { border-left-color: var(--bad); }
|
|
@@ -188,19 +192,19 @@ details.more[open] > summary::before { content: "▾ "; }
|
|
|
188
192
|
confirmAll: "这会对所有已配置的数据源各发一次真实请求,继续?",
|
|
189
193
|
skills: "已安装", skillsNot: "未安装", refresh: "刷新",
|
|
190
194
|
skillsCurrent: "已是当前版本", skillsStale: "可更新", skillsExtra: "已安装(含额外文件)",
|
|
191
|
-
required: "必需", optional: "可选",
|
|
195
|
+
required: "必需", optional: "可选", routingConnection: "路由与连接", jevMode: "Jev 自动选路", localMode: "本地选路",
|
|
192
196
|
missingOne: "缺", optionalOne: "未配置", more: "更多设置",
|
|
193
197
|
save: "保存", discard: "放弃修改", clear: "清除", saved: "已保存",
|
|
194
198
|
unsaved: "有 {n} 处未保存", envHint: "想改的话先在终端执行",
|
|
195
199
|
keepSecret: "留空表示不改动", getKey: "去申请 key", readDocs: "文档",
|
|
196
|
-
stepMain: "
|
|
197
|
-
stepDocs: "
|
|
198
|
-
pickOne: "
|
|
200
|
+
stepMain: "模型联网检索",
|
|
201
|
+
stepDocs: "文档与网页检索", stepFetch: "网页读取(深入搜索推荐)",
|
|
202
|
+
pickOne: "按用途选择渠道,不要求三类全部配置。", installSkill: "安装 / 更新",
|
|
199
203
|
runRoute: "看它走哪些能力(免费)", runSearch: "跑一次真实搜索",
|
|
200
204
|
queryPlaceholder: "比如:React useEffect 清理函数怎么写",
|
|
201
|
-
running: "运行中…", searchCost: "
|
|
205
|
+
running: "运行中…", searchCost: "真实搜索会调用选中的检索渠道,配置 Jev 时还会进行一次选路判断,可能计费。确定继续?",
|
|
202
206
|
needQuery: "先输入一个问题。", result: "结果", chain: "兜底顺序",
|
|
203
|
-
chainNote: "
|
|
207
|
+
chainNote: "Jev 按问题选择渠道;这里列出各类能力的本地回退顺序,绿色表示已配置。",
|
|
204
208
|
},
|
|
205
209
|
en: {
|
|
206
210
|
sub: "local config", ready: "Minimum profile met", notReady: "Minimum profile not met",
|
|
@@ -216,19 +220,19 @@ details.more[open] > summary::before { content: "▾ "; }
|
|
|
216
220
|
confirmAll: "This makes one real request to every configured provider. Continue?",
|
|
217
221
|
skills: "installed", skillsNot: "not installed", refresh: "Refresh",
|
|
218
222
|
skillsCurrent: "up to date", skillsStale: "update available", skillsExtra: "installed (extra files)",
|
|
219
|
-
required: "required", optional: "optional",
|
|
223
|
+
required: "required", optional: "optional", routingConnection: "Routing and connection", jevMode: "Jev routing", localMode: "Local routing",
|
|
220
224
|
missingOne: "missing", optionalOne: "not set", more: "More settings",
|
|
221
225
|
save: "Save", discard: "Discard", clear: "Clear", saved: "Saved",
|
|
222
226
|
unsaved: "{n} unsaved change(s)", envHint: "To change it, first run",
|
|
223
227
|
keepSecret: "Leave empty to keep the current value", getKey: "Get a key", readDocs: "Docs",
|
|
224
|
-
stepMain: "
|
|
225
|
-
stepDocs: "
|
|
226
|
-
pickOne: "
|
|
228
|
+
stepMain: "Model-backed retrieval",
|
|
229
|
+
stepDocs: "Documentation and web retrieval", stepFetch: "Page reading (recommended for research)",
|
|
230
|
+
pickOne: "Choose channels for your task; all three groups are not required.", installSkill: "Install / update",
|
|
227
231
|
runRoute: "Show which capabilities (free)", runSearch: "Run a real search",
|
|
228
232
|
queryPlaceholder: "e.g. how do I write a React useEffect cleanup function",
|
|
229
|
-
running: "Running…", searchCost: "A real search calls the
|
|
233
|
+
running: "Running…", searchCost: "A real search calls the selected channel and, when configured, Jev once for routing. Charges may apply. Continue?",
|
|
230
234
|
needQuery: "Type a question first.", result: "Result", chain: "Fallback order",
|
|
231
|
-
chainNote: "
|
|
235
|
+
chainNote: "Jev selects for the question. These are local fallback orders; green channels are configured.",
|
|
232
236
|
}
|
|
233
237
|
};
|
|
234
238
|
function t(key) { return T[lang][key] || key; }
|
|
@@ -419,6 +423,18 @@ details.more[open] > summary::before { content: "▾ "; }
|
|
|
419
423
|
el("span", { class: "pill", id: "res-" + provider, text: "" })
|
|
420
424
|
])
|
|
421
425
|
];
|
|
426
|
+
var profile = (state.provider_profiles || {})[provider] || {};
|
|
427
|
+
var descriptions = profile.descriptions || {};
|
|
428
|
+
function localizedDescriptions(prefix) {
|
|
429
|
+
return ["search", "fetch", "site_map", "synthesis"].map(function (operation) {
|
|
430
|
+
var translations = descriptions[operation] || {};
|
|
431
|
+
return translations[prefix + lang] || translations[prefix + "en"] || "";
|
|
432
|
+
}).filter(Boolean).join(" ");
|
|
433
|
+
}
|
|
434
|
+
var intro = localizedDescriptions("");
|
|
435
|
+
var guidance = localizedDescriptions("guidance_");
|
|
436
|
+
if (intro) kids.push(el("p", { class: "note", text: intro }));
|
|
437
|
+
if (guidance) kids.push(el("p", { class: "provider-guidance", text: guidance }));
|
|
422
438
|
var upfront = fields.filter(function (f) { return f.tier !== "advanced"; });
|
|
423
439
|
var advanced = fields.filter(function (f) { return f.tier === "advanced"; });
|
|
424
440
|
if (!upfront.length) { upfront = advanced; advanced = []; }
|
|
@@ -533,10 +549,14 @@ details.more[open] > summary::before { content: "▾ "; }
|
|
|
533
549
|
var select = el("select", locked ? { disabled: "disabled" } : {});
|
|
534
550
|
select.appendChild(el("option", { value: "", text: "(" + t("def") + (field.default ? " " + field.default : "") + ")" }));
|
|
535
551
|
options.forEach(function (option) {
|
|
536
|
-
|
|
552
|
+
var label = field.key === "SMART_SEARCH_INTENT_ROUTER" ? t(option === "jev" ? "jevMode" : "localMode") : option;
|
|
553
|
+
select.appendChild(el("option", { value: option, text: label }));
|
|
537
554
|
});
|
|
538
555
|
select.value = value;
|
|
539
|
-
if (!locked) select.addEventListener("change", function () {
|
|
556
|
+
if (!locked) select.addEventListener("change", function () {
|
|
557
|
+
markDirty(field, select, select.value);
|
|
558
|
+
if (field.key === "SMART_SEARCH_INTENT_ROUTER") render();
|
|
559
|
+
});
|
|
540
560
|
if (pending.hasOwnProperty(field.key)) select.className = "dirty";
|
|
541
561
|
return select;
|
|
542
562
|
}
|
|
@@ -585,6 +605,7 @@ details.more[open] > summary::before { content: "▾ "; }
|
|
|
585
605
|
var saved = (state.values || {})[field.key] || "";
|
|
586
606
|
var locked = source === "environment";
|
|
587
607
|
var input = fieldInput(field);
|
|
608
|
+
input.setAttribute("aria-label", L(field, "label"));
|
|
588
609
|
var side = [el("span", { class: "pill", text: sourceLabel(source) })];
|
|
589
610
|
if (locked) side.push(el("span", { class: "pill warn", text: t("envLocked") }));
|
|
590
611
|
else if (saved) side.push(el("button", {
|
|
@@ -727,10 +748,15 @@ details.more[open] > summary::before { content: "▾ "; }
|
|
|
727
748
|
main.appendChild(el("h2", { text: L(section, "label") }));
|
|
728
749
|
main.appendChild(el("p", { class: "blurb", text: L(section, "blurb") }));
|
|
729
750
|
var fields = state.metadata.fields.filter(function (field) { return field.section === id; });
|
|
751
|
+
if (id === "routing" && effectiveValues().SMART_SEARCH_INTENT_ROUTER === "local") {
|
|
752
|
+
fields = fields.filter(function (field) {
|
|
753
|
+
return field.key.indexOf("TYPESAFE_") !== 0 && field.key.indexOf("SMART_SEARCH_JEV_") !== 0;
|
|
754
|
+
});
|
|
755
|
+
}
|
|
730
756
|
var essential = fields.filter(function (f) { return f.tier === "essential"; });
|
|
731
757
|
var rest = fields.filter(function (f) { return f.tier !== "essential"; });
|
|
732
758
|
if (essential.length) {
|
|
733
|
-
main.appendChild(el("div", { class: "card" }, [el("h3", { text: t("required") })].concat(
|
|
759
|
+
main.appendChild(el("div", { class: "card" }, [el("h3", { text: t(id === "routing" ? "routingConnection" : "required") })].concat(
|
|
734
760
|
essential.map(editableRow))));
|
|
735
761
|
}
|
|
736
762
|
if (rest.length) {
|