dsh-web-search-pro 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +164 -0
- package/README.md +154 -58
- package/assets/skills/dsh-web-search-pro/SKILL.md +13 -12
- package/assets/skills/dsh-web-search-pro/references/config.md +36 -0
- package/assets/skills/dsh-web-search-pro/references/sources.md +13 -7
- package/assets/skills/dsh-web-search-pro/references/troubleshooting.md +3 -1
- package/catalog/sources.v1.json +16 -14
- package/lib/actions/approval.js +50 -1
- package/lib/actions/approval.js.map +1 -1
- package/lib/actions/config.js +274 -0
- package/lib/actions/config.js.map +1 -0
- package/lib/actions/errors.js +8 -1
- package/lib/actions/errors.js.map +1 -1
- package/lib/actions/format.js +10 -0
- package/lib/actions/format.js.map +1 -1
- package/lib/actions/index-view.js +2 -2
- package/lib/actions/index-view.js.map +1 -1
- package/lib/actions/read.js +7 -3
- package/lib/actions/read.js.map +1 -1
- package/lib/actions/registry.js +3 -1
- package/lib/actions/registry.js.map +1 -1
- package/lib/actions/run.js +2 -2
- package/lib/actions/run.js.map +1 -1
- package/lib/actions/schema.js +18 -0
- package/lib/actions/schema.js.map +1 -1
- package/lib/actions/search.js +7 -2
- package/lib/actions/search.js.map +1 -1
- package/lib/actions/sources.js +76 -18
- package/lib/actions/sources.js.map +1 -1
- package/lib/actions/types.js +19 -1
- package/lib/actions/types.js.map +1 -1
- package/lib/browser-access.js +25 -0
- package/lib/browser-access.js.map +1 -1
- package/lib/catalog/recommend.js +11 -3
- package/lib/catalog/recommend.js.map +1 -1
- package/lib/catalog/schema.js +3 -1
- package/lib/catalog/schema.js.map +1 -1
- package/lib/cli/builtin-specs.js +57 -22
- package/lib/cli/builtin-specs.js.map +1 -1
- package/lib/cli/chain.js +13 -12
- package/lib/cli/chain.js.map +1 -1
- package/lib/cli/chains-spec.js +31 -11
- package/lib/cli/chains-spec.js.map +1 -1
- package/lib/cli/engine.js +19 -3
- package/lib/cli/engine.js.map +1 -1
- package/lib/cli/opencli-sites.js +83 -0
- package/lib/cli/opencli-sites.js.map +1 -0
- package/lib/cli/opencli.js +65 -17
- package/lib/cli/opencli.js.map +1 -1
- package/lib/cli/probe.js +1 -1
- package/lib/cli/probe.js.map +1 -1
- package/lib/cli/runner.js +217 -27
- package/lib/cli/runner.js.map +1 -1
- package/lib/cli/spec.js +100 -20
- package/lib/cli/spec.js.map +1 -1
- package/lib/cli/time-text.js +79 -0
- package/lib/cli/time-text.js.map +1 -0
- package/lib/cli/trial.js +57 -0
- package/lib/cli/trial.js.map +1 -0
- package/lib/client/SettingsCard.js +14 -32
- package/lib/client/SettingsCard.js.map +1 -1
- package/lib/client/agent-mark.js +27 -0
- package/lib/client/agent-mark.js.map +1 -0
- package/lib/client/card-frame.js +118 -0
- package/lib/client/card-frame.js.map +1 -0
- package/lib/client/cli-form.js +257 -0
- package/lib/client/cli-form.js.map +1 -0
- package/lib/client/field-docs.js +130 -0
- package/lib/client/field-docs.js.map +1 -0
- package/lib/client/field-keys.js +81 -0
- package/lib/client/field-keys.js.map +1 -0
- package/lib/client/field-rows.js +71 -0
- package/lib/client/field-rows.js.map +1 -0
- package/lib/client/fill.js +3 -0
- package/lib/client/fill.js.map +1 -0
- package/lib/client/form-specs.js +13 -1
- package/lib/client/form-specs.js.map +1 -1
- package/lib/client/form.js +282 -24
- package/lib/client/form.js.map +1 -1
- package/lib/client/group-advanced.js +23 -0
- package/lib/client/group-advanced.js.map +1 -0
- package/lib/client/group-agent.js +28 -0
- package/lib/client/group-agent.js.map +1 -0
- package/lib/client/group-cli.js +136 -0
- package/lib/client/group-cli.js.map +1 -0
- package/lib/client/group-common.js +29 -0
- package/lib/client/group-common.js.map +1 -0
- package/lib/client/group-judge.js +67 -0
- package/lib/client/group-judge.js.map +1 -0
- package/lib/client/group-order.js +201 -0
- package/lib/client/group-order.js.map +1 -0
- package/lib/client/group-runtime.js +33 -0
- package/lib/client/group-runtime.js.map +1 -0
- package/lib/client/group-sources.js +83 -0
- package/lib/client/group-sources.js.map +1 -0
- package/lib/client/groups-basic.js +36 -0
- package/lib/client/groups-basic.js.map +1 -0
- package/lib/client/index.js.map +1 -1
- package/lib/client/json-list.js +50 -0
- package/lib/client/json-list.js.map +1 -0
- package/lib/client/locales.js +666 -219
- package/lib/client/locales.js.map +1 -1
- package/lib/client/order.js +192 -0
- package/lib/client/order.js.map +1 -0
- package/lib/client/overlay-ops.js +46 -0
- package/lib/client/overlay-ops.js.map +1 -0
- package/lib/client/sources-table.js +1 -0
- package/lib/client/sources-table.js.map +1 -1
- package/lib/client/styles.js +74 -47
- package/lib/client/styles.js.map +1 -1
- package/lib/client/text-view.js +98 -0
- package/lib/client/text-view.js.map +1 -0
- package/lib/client/ui-kit.js +120 -0
- package/lib/client/ui-kit.js.map +1 -0
- package/lib/client/validators.js +8 -1
- package/lib/client/validators.js.map +1 -1
- package/lib/client.js +7313 -1571
- package/lib/client.js.map +1 -1
- package/lib/config-fillers.js +53 -0
- package/lib/config-fillers.js.map +1 -0
- package/lib/config-groups.js +49 -0
- package/lib/config-groups.js.map +1 -0
- package/lib/config.js +84 -108
- package/lib/config.js.map +1 -1
- package/lib/default-chain.js +66 -0
- package/lib/default-chain.js.map +1 -0
- package/lib/deps.js +1 -1
- package/lib/deps.js.map +1 -1
- package/lib/engines.js +3 -3
- package/lib/engines.js.map +1 -1
- package/lib/fetch.js +23 -4
- package/lib/fetch.js.map +1 -1
- package/lib/index.js +30 -5
- package/lib/index.js.map +1 -1
- package/lib/overlay-types.js +88 -0
- package/lib/overlay-types.js.map +1 -0
- package/lib/overlay.js +683 -0
- package/lib/overlay.js.map +1 -0
- package/lib/pipeline/candidates.js +27 -1
- package/lib/pipeline/candidates.js.map +1 -1
- package/lib/pipeline/compile.js +63 -0
- package/lib/pipeline/compile.js.map +1 -1
- package/lib/pipeline/confidence.js +64 -0
- package/lib/pipeline/confidence.js.map +1 -0
- package/lib/pipeline/fusion.js +50 -3
- package/lib/pipeline/fusion.js.map +1 -1
- package/lib/pipeline/plan.js +2 -2
- package/lib/pipeline/plan.js.map +1 -1
- package/lib/pipeline/render.js +20 -2
- package/lib/pipeline/render.js.map +1 -1
- package/lib/pipeline/run.js +17 -5
- package/lib/pipeline/run.js.map +1 -1
- package/lib/pipeline/sources-spec.js +19 -3
- package/lib/pipeline/sources-spec.js.map +1 -1
- package/lib/providers/builtin.js +3 -0
- package/lib/providers/builtin.js.map +1 -1
- package/lib/providers/deepseek.js +348 -0
- package/lib/providers/deepseek.js.map +1 -0
- package/lib/providers/http.js.map +1 -1
- package/lib/providers/keyed-meta.js +7 -0
- package/lib/providers/keyed-meta.js.map +1 -1
- package/lib/providers/platforms.js +18 -17
- package/lib/providers/platforms.js.map +1 -1
- package/lib/providers/registry.js.map +1 -1
- package/lib/restart.js +47 -0
- package/lib/restart.js.map +1 -0
- package/lib/router.js +145 -26
- package/lib/router.js.map +1 -1
- package/lib/rpc-types.js +15 -0
- package/lib/rpc-types.js.map +1 -0
- package/lib/rpc.js +85 -0
- package/lib/rpc.js.map +1 -0
- package/lib/tools.js +10 -4
- package/lib/tools.js.map +1 -1
- package/lib/types/actions/approval.d.ts +11 -0
- package/lib/types/actions/config.d.ts +54 -0
- package/lib/types/actions/format.d.ts +9 -2
- package/lib/types/actions/run.d.ts +1 -0
- package/lib/types/actions/schema.d.ts +7 -1
- package/lib/types/actions/sources.d.ts +29 -3
- package/lib/types/actions/types.d.ts +28 -2
- package/lib/types/browser-access.d.ts +17 -0
- package/lib/types/catalog/recommend.d.ts +4 -0
- package/lib/types/catalog/schema.d.ts +2 -0
- package/lib/types/cli/builtin-specs.d.ts +11 -3
- package/lib/types/cli/chains-spec.d.ts +12 -3
- package/lib/types/cli/engine.d.ts +10 -3
- package/lib/types/cli/opencli-sites.d.ts +24 -0
- package/lib/types/cli/opencli.d.ts +42 -3
- package/lib/types/cli/runner.d.ts +47 -8
- package/lib/types/cli/spec.d.ts +101 -8
- package/lib/types/cli/time-text.d.ts +12 -0
- package/lib/types/cli/trial.d.ts +19 -0
- package/lib/types/client/SettingsCard.d.ts +17 -1
- package/lib/types/client/agent-mark.d.ts +22 -0
- package/lib/types/client/card-frame.d.ts +35 -0
- package/lib/types/client/cli-form.d.ts +97 -0
- package/lib/types/client/field-docs.d.ts +15 -0
- package/lib/types/client/field-keys.d.ts +41 -0
- package/lib/types/client/field-rows.d.ts +70 -0
- package/lib/types/client/fill.d.ts +2 -0
- package/lib/types/client/form-specs.d.ts +12 -3
- package/lib/types/client/form.d.ts +79 -1
- package/lib/types/client/group-advanced.d.ts +9 -0
- package/lib/types/client/group-agent.d.ts +20 -0
- package/lib/types/client/group-cli.d.ts +52 -0
- package/lib/types/client/group-common.d.ts +12 -0
- package/lib/types/client/group-judge.d.ts +17 -0
- package/lib/types/client/group-order.d.ts +26 -0
- package/lib/types/client/group-runtime.d.ts +15 -0
- package/lib/types/client/group-sources.d.ts +46 -0
- package/lib/types/client/groups-basic.d.ts +18 -0
- package/lib/types/client/index.d.ts +8 -0
- package/lib/types/client/json-list.d.ts +21 -0
- package/lib/types/client/locales.d.ts +1079 -200
- package/lib/types/client/order.d.ts +102 -0
- package/lib/types/client/overlay-ops.d.ts +37 -0
- package/lib/types/client/styles.d.ts +56 -41
- package/lib/types/client/text-view.d.ts +22 -0
- package/lib/types/client/ui-kit.d.ts +200 -0
- package/lib/types/config-fillers.d.ts +9 -0
- package/lib/types/config-groups.d.ts +23 -0
- package/lib/types/config.d.ts +263 -225
- package/lib/types/default-chain.d.ts +63 -0
- package/lib/types/engines.d.ts +29 -1
- package/lib/types/fetch.d.ts +12 -3
- package/lib/types/index.d.ts +164 -150
- package/lib/types/overlay-types.d.ts +98 -0
- package/lib/types/overlay.d.ts +141 -0
- package/lib/types/pipeline/candidates.d.ts +17 -0
- package/lib/types/pipeline/compile.d.ts +11 -0
- package/lib/types/pipeline/confidence.d.ts +35 -0
- package/lib/types/pipeline/fusion.d.ts +23 -1
- package/lib/types/pipeline/render.d.ts +16 -0
- package/lib/types/pipeline/run.d.ts +2 -1
- package/lib/types/pipeline/sources-spec.d.ts +5 -2
- package/lib/types/pipeline/types.d.ts +37 -0
- package/lib/types/providers/deepseek.d.ts +130 -0
- package/lib/types/providers/http.d.ts +2 -1
- package/lib/types/providers/keyed-meta.d.ts +5 -0
- package/lib/types/providers/registry.d.ts +7 -0
- package/lib/types/restart.d.ts +52 -0
- package/lib/types/router.d.ts +57 -10
- package/lib/types/rpc-types.d.ts +79 -0
- package/lib/types/rpc.d.ts +41 -0
- package/lib/types/tools.d.ts +6 -0
- package/lib/types/util.d.ts +10 -0
- package/lib/util.js +10 -1
- package/lib/util.js.map +1 -1
- package/package.json +50 -42
- package/scripts/check-client-bundle.mjs +1 -1
- package/scripts/cli-login-check.mjs +214 -0
- package/lib/client/RubricEditor.js +0 -47
- package/lib/client/RubricEditor.js.map +0 -1
- package/lib/client/fields.js +0 -31
- package/lib/client/fields.js.map +0 -1
- package/lib/types/client/RubricEditor.d.ts +0 -6
- package/lib/types/client/fields.d.ts +0 -65
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agent overlay, pure half: the shapes the overlay file, the `config.*` actions and the settings card's RPC channel carry, and
|
|
3
|
+
* the small helpers that name an overlay entry. The store that reads and writes the file is overlay.ts (Node); the card bundle
|
|
4
|
+
* includes only this file. No imports.
|
|
5
|
+
*
|
|
6
|
+
* The overlay is a small managed file next to the plugin's database. It sits on top of the configuration the user owns (the
|
|
7
|
+
* profile) and can hold only the settings an agent may change at run time: the engine order, the source priority and disabled
|
|
8
|
+
* lists, the confidence of a source, the backend chain of a platform, and custom CLI adapter specs. Everything else stays
|
|
9
|
+
* the user's: an agent cannot reach a key, a path, a switch or a budget through it.
|
|
10
|
+
* @module web-search-pro/overlay-types
|
|
11
|
+
*/
|
|
12
|
+
export declare const OVERLAY_VERSION = 1;
|
|
13
|
+
export declare const OVERLAY_FILE = "overlay.json";
|
|
14
|
+
/** The audit trail is cut to the newest entries, so the file stays small however long it lives. */
|
|
15
|
+
export declare const MAX_AUDIT_ENTRIES = 50;
|
|
16
|
+
export declare const MIN_REASON = 3;
|
|
17
|
+
export declare const MAX_REASON = 300;
|
|
18
|
+
/** What `config.reset` can drop. */
|
|
19
|
+
export declare const RESET_SCOPES: readonly ["all", "order", "confidence", "cli", "platform"];
|
|
20
|
+
export type ResetScope = typeof RESET_SCOPES[number];
|
|
21
|
+
/** The overlaid values, in the shape of the configuration fields they sit on. Absent = the baseline applies. */
|
|
22
|
+
export interface OverlayValues {
|
|
23
|
+
/** The whole `engines` list. */
|
|
24
|
+
engines?: string[];
|
|
25
|
+
sources?: {
|
|
26
|
+
priority?: string[];
|
|
27
|
+
disabled?: string[];
|
|
28
|
+
/** Per source or backend id. */
|
|
29
|
+
confidence?: Record<string, number>;
|
|
30
|
+
};
|
|
31
|
+
/** Per platform, the whole backend chain. */
|
|
32
|
+
platformBackends?: Record<string, string[]>;
|
|
33
|
+
/** Per id, the whole adapter spec (without its `id`, which is the key). */
|
|
34
|
+
cliAdapters?: Record<string, Record<string, unknown>>;
|
|
35
|
+
}
|
|
36
|
+
/** One line of the audit trail: what a key was before and after, as short text. */
|
|
37
|
+
export interface AuditChange {
|
|
38
|
+
key: string;
|
|
39
|
+
before: string;
|
|
40
|
+
after: string;
|
|
41
|
+
}
|
|
42
|
+
export interface AuditEntry {
|
|
43
|
+
/** The revision this change produced. */
|
|
44
|
+
revision: number;
|
|
45
|
+
at: string;
|
|
46
|
+
/** `agent`: a `config.*` action. `user`: the settings card. */
|
|
47
|
+
actor: 'agent' | 'user';
|
|
48
|
+
action: string;
|
|
49
|
+
sessionId?: string;
|
|
50
|
+
reason: string;
|
|
51
|
+
changes: AuditChange[];
|
|
52
|
+
}
|
|
53
|
+
export type OverlayItemKind = 'engines' | 'priority' | 'disabled' | 'confidence' | 'platform' | 'cli';
|
|
54
|
+
/** One overridden key, for the card and `config.inspect`. */
|
|
55
|
+
export interface OverlayItem {
|
|
56
|
+
/** `engines`, `sources.priority`, `sources.disabled`, `sources.confidence.<id>`, `platformBackends.<platform>`, `cliAdapters.<id>`. */
|
|
57
|
+
key: string;
|
|
58
|
+
kind: OverlayItemKind;
|
|
59
|
+
/** The id, platform or adapter id the key is about. */
|
|
60
|
+
target?: string;
|
|
61
|
+
/** The overlaid value. */
|
|
62
|
+
value: unknown;
|
|
63
|
+
/** Short text of the overlaid value. */
|
|
64
|
+
summary: string;
|
|
65
|
+
/** Short text of what the baseline holds there, for the card. */
|
|
66
|
+
baseline: string;
|
|
67
|
+
/** The newest audit entry that touched this key (absent when it has rotated out of the trail). */
|
|
68
|
+
at?: string;
|
|
69
|
+
reason?: string;
|
|
70
|
+
actor?: AuditEntry['actor'];
|
|
71
|
+
sessionId?: string;
|
|
72
|
+
}
|
|
73
|
+
/** What the card reads over RPC (`overlay` endpoint) and `config.inspect` extends. */
|
|
74
|
+
export interface OverlayView {
|
|
75
|
+
file: string;
|
|
76
|
+
revision: number;
|
|
77
|
+
updatedAt: string;
|
|
78
|
+
/** The overlay file loads and agrees with the baseline; false = it is being ignored as a whole. */
|
|
79
|
+
valid: boolean;
|
|
80
|
+
problem?: string;
|
|
81
|
+
items: OverlayItem[];
|
|
82
|
+
audit: AuditEntry[];
|
|
83
|
+
}
|
|
84
|
+
/** The keys an overlay holds, in a stable order. */
|
|
85
|
+
export declare function overlayKeys(values: OverlayValues): string[];
|
|
86
|
+
/** Kind and target of an overlay key; undefined for a name that is not one. */
|
|
87
|
+
export declare function describeKey(key: string): {
|
|
88
|
+
kind: OverlayItemKind;
|
|
89
|
+
target?: string;
|
|
90
|
+
} | undefined;
|
|
91
|
+
export declare function clipText(text: string, max: number): string;
|
|
92
|
+
/**
|
|
93
|
+
* Short text of a value for the audit trail and the card: a list is its items joined with `>` (order matters), a number is itself,
|
|
94
|
+
* a CLI spec is its command and search arguments (what the program is and what it is asked), nothing is `(none)`.
|
|
95
|
+
*/
|
|
96
|
+
export declare function summarizeValue(key: string, value: unknown, max?: number): string;
|
|
97
|
+
/** `<bins[0]> <search.argv...>`: the command a custom CLI spec would run for a search, with the placeholders as written. */
|
|
98
|
+
export declare function cliCommandLine(spec: Record<string, unknown>): string;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The agent overlay: the settings an agent may change at run time without hand-editing the configuration.
|
|
3
|
+
*
|
|
4
|
+
* The profile configuration stays the user's baseline. The overlay is a small managed file next to the plugin's database
|
|
5
|
+
* (`$DSH_HOME/data/web-search-pro/overlay.json`, or beside `dbPath` when the user moved it) that `dynamic()` merges on top of the
|
|
6
|
+
* baseline on every read, so every consumer sees the change at once, with no watcher and no restart. It holds only what
|
|
7
|
+
* overlay-types.ts lists (engine order, source priority / disabled, confidence, platform backend chains, custom CLI specs),
|
|
8
|
+
* carries a revision for optimistic locking, a checksum, and an audit trail cut to {@link MAX_AUDIT_ENTRIES} entries.
|
|
9
|
+
*
|
|
10
|
+
* The same functions validate a change before it is written and the whole file when it is loaded: a file that does not parse,
|
|
11
|
+
* fails its checksum, holds a value the validators refuse, or no longer agrees with the baseline (a chain naming a CLI the user
|
|
12
|
+
* removed) is ignored as a whole and reported, never half applied. Validation reuses the functions the settings card and
|
|
13
|
+
* `sources.status` use (`cliIssues`, `sourcesIssues`, the CLI spec validator, the source id rules).
|
|
14
|
+
*
|
|
15
|
+
* Adding or replacing only: the overlay never deletes a baseline entry. Taking a baseline CLI out of service is
|
|
16
|
+
* `sources.disabled`; removing a CLI the overlay added is `config.remove_cli`.
|
|
17
|
+
* @module web-search-pro/overlay
|
|
18
|
+
*/
|
|
19
|
+
import type { ResolvedConfig } from './config.ts';
|
|
20
|
+
import { MAX_AUDIT_ENTRIES, OVERLAY_FILE, OVERLAY_VERSION, type AuditChange, type AuditEntry, type OverlayItem, type OverlayValues, type OverlayView, type ResetScope } from './overlay-types.ts';
|
|
21
|
+
export { MAX_AUDIT_ENTRIES, OVERLAY_FILE, OVERLAY_VERSION };
|
|
22
|
+
export interface Overlay {
|
|
23
|
+
version: 1;
|
|
24
|
+
revision: number;
|
|
25
|
+
updatedAt: string;
|
|
26
|
+
values: OverlayValues;
|
|
27
|
+
audit: AuditEntry[];
|
|
28
|
+
}
|
|
29
|
+
export declare function emptyOverlay(): Overlay;
|
|
30
|
+
export declare function checksumOf(overlay: Pick<Overlay, 'version' | 'revision' | 'updatedAt' | 'values' | 'audit'>): string;
|
|
31
|
+
/** `<dir of dbPath>/overlay.json`: the overlay sits beside the database, wherever the user put it. */
|
|
32
|
+
export declare function overlayFileFor(dbPath: string): string;
|
|
33
|
+
/** The baseline with the overlay merged on top. Never mutates its inputs. */
|
|
34
|
+
export declare function mergeOverlay(base: ResolvedConfig, values: OverlayValues): ResolvedConfig;
|
|
35
|
+
/** Where the effective value of an overlay key comes from, and what it is. */
|
|
36
|
+
export declare function effectiveValueOf(config: ResolvedConfig, key: string): unknown;
|
|
37
|
+
/** The id rules of the sources the baseline knows; supplied by the router (`registry.routeId(id) !== undefined`). */
|
|
38
|
+
export type KnownSource = (id: string) => boolean;
|
|
39
|
+
/** Problems the overlay values add to what the baseline already has (the user's own mistakes are not the overlay's to answer for). */
|
|
40
|
+
export declare function overlayErrors(base: ResolvedConfig, values: OverlayValues, known: KnownSource): string[];
|
|
41
|
+
/**
|
|
42
|
+
* Every problem with the `id` / `spec` of a `config.upsert_cli` call, one message each ([] when the call is valid). The single
|
|
43
|
+
* source of these rules: {@link OverlayStore.apply} refuses a change that has any, and the action's `precheck` asks it before the
|
|
44
|
+
* user is, so an unusable spec never reaches an approval prompt. It reads no state, so it never depends on the overlay file.
|
|
45
|
+
*/
|
|
46
|
+
export declare function cliSpecProblems(id: unknown, spec: unknown): string[];
|
|
47
|
+
/** Reason rule shared by every write: a real sentence, not a placeholder. */
|
|
48
|
+
export declare function checkReason(reason: unknown): string;
|
|
49
|
+
export type OverlayChange = {
|
|
50
|
+
kind: 'order';
|
|
51
|
+
engines?: unknown;
|
|
52
|
+
priority?: unknown;
|
|
53
|
+
disabled?: unknown;
|
|
54
|
+
platform?: unknown;
|
|
55
|
+
backends?: unknown;
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'confidence';
|
|
58
|
+
id: unknown;
|
|
59
|
+
value: unknown;
|
|
60
|
+
} | {
|
|
61
|
+
kind: 'upsertCli';
|
|
62
|
+
id: unknown;
|
|
63
|
+
spec: unknown;
|
|
64
|
+
} | {
|
|
65
|
+
kind: 'removeCli';
|
|
66
|
+
id: unknown;
|
|
67
|
+
} | {
|
|
68
|
+
kind: 'reset';
|
|
69
|
+
scope: ResetScope;
|
|
70
|
+
id?: unknown;
|
|
71
|
+
}
|
|
72
|
+
/** The settings card: drop these keys (one or several), or everything when `keys` is `'all'`. */
|
|
73
|
+
| {
|
|
74
|
+
kind: 'revoke';
|
|
75
|
+
keys: readonly string[] | 'all';
|
|
76
|
+
};
|
|
77
|
+
export interface ChangeMeta {
|
|
78
|
+
actor: 'agent' | 'user';
|
|
79
|
+
/** The action name (`config.set_order`) or the card's button. */
|
|
80
|
+
action: string;
|
|
81
|
+
reason: string;
|
|
82
|
+
sessionId?: string;
|
|
83
|
+
/** When given, the change only applies if the overlay is still at this revision. */
|
|
84
|
+
expectedRevision?: number;
|
|
85
|
+
}
|
|
86
|
+
export interface AppliedChange {
|
|
87
|
+
/** False when the change left the overlay as it was (nothing was written, the revision is unchanged). */
|
|
88
|
+
changed: boolean;
|
|
89
|
+
revision: number;
|
|
90
|
+
keys: string[];
|
|
91
|
+
changes: AuditChange[];
|
|
92
|
+
audit?: AuditEntry;
|
|
93
|
+
}
|
|
94
|
+
export interface OverlayStoreOptions {
|
|
95
|
+
file: string;
|
|
96
|
+
/** The configuration the user owns (the profile), re-read on every call. */
|
|
97
|
+
baseline: () => ResolvedConfig;
|
|
98
|
+
known: KnownSource;
|
|
99
|
+
/** Changes whenever the answer of `known` can have changed (the router's registry revision), so a cached verdict is not kept past it. */
|
|
100
|
+
knownSignature?: () => string;
|
|
101
|
+
now?: () => Date;
|
|
102
|
+
}
|
|
103
|
+
export declare class OverlayStore {
|
|
104
|
+
private readonly options;
|
|
105
|
+
private overlay;
|
|
106
|
+
private signature;
|
|
107
|
+
private loadProblem;
|
|
108
|
+
private compat;
|
|
109
|
+
constructor(options: OverlayStoreOptions);
|
|
110
|
+
get file(): string;
|
|
111
|
+
private stat;
|
|
112
|
+
/** Re-read the file when its mtime or size changed. No watcher: every read of the effective config asks. */
|
|
113
|
+
private refresh;
|
|
114
|
+
private reload;
|
|
115
|
+
private readFile;
|
|
116
|
+
/** Strict parse: unknown keys, wrong types, a failed checksum or any value the validators refuse reject the whole file. */
|
|
117
|
+
private parse;
|
|
118
|
+
/** Why the overlay is being ignored, if it is: a broken file, or values that no longer agree with the baseline. */
|
|
119
|
+
get problem(): string | undefined;
|
|
120
|
+
private incompatibility;
|
|
121
|
+
/** The loaded overlay (an empty one while the file is missing or ignored). */
|
|
122
|
+
current(): Overlay;
|
|
123
|
+
/** The configuration as the plugin runs it: the baseline with the overlay on top, or the baseline alone while the overlay is ignored. */
|
|
124
|
+
effective(): ResolvedConfig;
|
|
125
|
+
baselineConfig(): ResolvedConfig;
|
|
126
|
+
/** The overlaid keys with the newest audit entry that touched each, for the card and `config.inspect`. */
|
|
127
|
+
items(): OverlayItem[];
|
|
128
|
+
view(limit?: number): OverlayView;
|
|
129
|
+
/** Compute the values a change leads to without writing anything. Throws {@link ActionArgError} for an invalid change. */
|
|
130
|
+
private plan;
|
|
131
|
+
/** Drop empty containers, and entries equal to the baseline (an override that changes nothing is not one). */
|
|
132
|
+
private normalize;
|
|
133
|
+
/**
|
|
134
|
+
* Plan, validate and write a change: re-reads the file first, checks the revision, validates the merged result with the
|
|
135
|
+
* server's own functions, writes atomically (0600) and appends the audit entry. A failed change leaves the file as it was.
|
|
136
|
+
*/
|
|
137
|
+
apply(change: OverlayChange, meta: ChangeMeta): AppliedChange;
|
|
138
|
+
private write;
|
|
139
|
+
/** Move an unreadable file aside (kept for inspection) so a fresh overlay can start. */
|
|
140
|
+
private quarantine;
|
|
141
|
+
}
|
|
@@ -13,6 +13,13 @@ export interface ProviderSource {
|
|
|
13
13
|
title?: string | null;
|
|
14
14
|
snippet?: string | null;
|
|
15
15
|
publishedAt?: string | null;
|
|
16
|
+
rerankScore?: number | null;
|
|
17
|
+
authority?: number | null;
|
|
18
|
+
/** The user-defined CLI that returned the row (`custom-cli:echo`) and the label it carries. */
|
|
19
|
+
via?: string | null;
|
|
20
|
+
tag?: string | null;
|
|
21
|
+
/** The source's confidence (0..1) when it is below 1 (see confidence.ts). */
|
|
22
|
+
confidence?: number | null;
|
|
16
23
|
}
|
|
17
24
|
/** One provider's ordered result list for one query (index 0 = rank 1). */
|
|
18
25
|
export interface ProviderOutput {
|
|
@@ -29,6 +36,16 @@ export interface MergeOptions {
|
|
|
29
36
|
export declare function candidateIdOf(canonical: string): string;
|
|
30
37
|
/** Fold snippet `next` into `current`: drop repeats, keep the longer of near-duplicates, join complements within `cap`. */
|
|
31
38
|
export declare function mergeSnippets(current: string, next: string | null | undefined, cap?: number): string;
|
|
39
|
+
/**
|
|
40
|
+
* What a result says about where it came from, for the exit: the custom CLIs that returned it (`via`) with their honest label (`tag`),
|
|
41
|
+
* and `confidence` = the best confidence among the providers that returned it, only when it is below 1 (a URL a full-confidence
|
|
42
|
+
* source also returned is as sure as that source). Empty for a result of built-in sources only.
|
|
43
|
+
*/
|
|
44
|
+
export declare function provenanceOf(candidate: Pick<Candidate, 'contributions' | 'origin'>): {
|
|
45
|
+
via?: string;
|
|
46
|
+
tag?: string;
|
|
47
|
+
confidence?: number;
|
|
48
|
+
};
|
|
32
49
|
/**
|
|
33
50
|
* Merge provider outputs into candidates keyed by canonical URL, in first-seen
|
|
34
51
|
* order (outputs in the given order, sources by rank). Sources without a URL
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
* - keyed sources (dev-plan M7c): Tavily / Linkup / Baidu Qianfan / Zhipu take domain lists (`options.sites`, capped at what
|
|
16
16
|
* each documents) and a date lower bound (`options.since`); Brave / Serper (Google) take `site:` / `-site:` / `-term`
|
|
17
17
|
* operators in the query; whatever a source does not document stays for local verification;
|
|
18
|
+
* - deepseek (DeepSeek Search API): `site:a OR site:b` / `-site:` / `-term` for HARD site / exclude_site / exclude_term and
|
|
19
|
+
* `after:YYYY-MM-DD` for a HARD time_window whose lower bound is understood, all in the query text (the API documents them as
|
|
20
|
+
* query operators); `originalQuestion` carries the task goal (or the first critical need) for the API's `ori_question`;
|
|
18
21
|
* - github*: the natural-language query returns nothing on repository search
|
|
19
22
|
* (E1: 0 of 20), so it is replaced by a short keyword query;
|
|
20
23
|
* - everything else: the plain query.
|
|
@@ -52,6 +55,7 @@ export interface CompiledQuery {
|
|
|
52
55
|
since?: string;
|
|
53
56
|
lang?: 'zh' | 'en';
|
|
54
57
|
sites?: CompiledSites;
|
|
58
|
+
originalQuestion?: string;
|
|
55
59
|
};
|
|
56
60
|
/** Broader variants to try, in order, when the provider answers ENGINE_EMPTY for `query` (GitHub: fewer keywords). */
|
|
57
61
|
fallbacks?: string[];
|
|
@@ -103,6 +107,13 @@ export declare function hardWindows(task: TaskLike, now: Date): {
|
|
|
103
107
|
* sources get `site:` / `-site:` / `-term` in the query. Soft constraints are never pushed down.
|
|
104
108
|
*/
|
|
105
109
|
export declare function compileKeyed(task: TaskLike, providerId: string, now: Date, caps: KeyedCaps): CompiledQuery;
|
|
110
|
+
/**
|
|
111
|
+
* DeepSeek Search takes `site:` (several joined by `OR`), `-site:`, `-term`, `"phrase"`, `lang:`, `after:` and `before:` inside
|
|
112
|
+
* the query. Hard constraints become those operators (the engine keeps them whole when it has to cut a long query). An operator the
|
|
113
|
+
* query already spells is not repeated; a hard site when the query already restricts to other sites stays local (two `site:`
|
|
114
|
+
* restrictions would AND into nothing).
|
|
115
|
+
*/
|
|
116
|
+
export declare function compileDeepSeek(task: TaskLike, providerId: string, now: Date): CompiledQuery;
|
|
106
117
|
export declare const GITHUB_MAX_TERMS = 5;
|
|
107
118
|
/**
|
|
108
119
|
* Short keyword query for repository search: entities, then must_terms, then a
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source confidence (0..1): how far the user trusts what one source returns. It is an input of rank fusion and a label on results,
|
|
3
|
+
* nothing else: it never removes a result, never changes what a source is asked, and every built-in source has confidence 1, so
|
|
4
|
+
* with the defaults the fused order is exactly what it was before confidence existed.
|
|
5
|
+
*
|
|
6
|
+
* factor(c) = 1 - STRENGTH · (1 - c) c in [0, 1]; undefined = 1; the factor is always in [1 - STRENGTH, 1]
|
|
7
|
+
* rrf(d) = Σ_provider factor(c_provider) / (k + bestRank_provider(d)) (fusion.ts)
|
|
8
|
+
* bonus(d) = bonus(d) · max_provider factor(c_provider) a URL only a doubted source returned earns less of the tie-break bonuses
|
|
9
|
+
*
|
|
10
|
+
* A source of confidence c therefore ranks as if its list began ((k + 1) / factor - (k + 1)) positions lower: at k = 60 about 7
|
|
11
|
+
* positions for c = 0.5 and about 16 for c = 0. Results several sources agree on lose almost nothing, a result only a doubted
|
|
12
|
+
* source has sinks towards the tail, and {@link guaranteeSeats} makes sure its best one is still within the list that is shown.
|
|
13
|
+
* Pure and free of imports: the settings card and the tests read it too.
|
|
14
|
+
* @module web-search-pro/pipeline/confidence
|
|
15
|
+
*/
|
|
16
|
+
/** How much confidence 0 takes off the contribution of a source (0.2 = a fifth). */
|
|
17
|
+
export declare const CONFIDENCE_STRENGTH = 0.2;
|
|
18
|
+
/** Confidence of a source nothing is known about: the built-in ones. */
|
|
19
|
+
export declare const FULL_CONFIDENCE = 1;
|
|
20
|
+
/** A confidence as a number in [0, 1]; anything else (missing, NaN) is full confidence. */
|
|
21
|
+
export declare function clampConfidence(value: number | undefined): number;
|
|
22
|
+
/** The multiplier of a source's rank-fusion contribution, in [1 - STRENGTH, 1]; exactly 1 for confidence 1 or none. */
|
|
23
|
+
export declare function confidenceFactor(confidence: number | undefined): number;
|
|
24
|
+
/** A contribution of one provider to a candidate; `confidence` is present only when it is below 1. */
|
|
25
|
+
export interface WeightedContribution {
|
|
26
|
+
providerId: string;
|
|
27
|
+
confidence?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Keep the best result of every doubted source within the first `size` results. A source whose confidence is below 1 and which
|
|
31
|
+
* answered, but has none of its results in the window, gets its best-ranked result moved to the end of the window (at most
|
|
32
|
+
* `size - 1` such seats, so the window never consists of nothing else). The order of everything else is kept. With no confidence
|
|
33
|
+
* below 1 anywhere the list comes back unchanged.
|
|
34
|
+
*/
|
|
35
|
+
export declare function guaranteeSeats<T>(ranked: readonly T[], size: number, contributions: (item: T) => readonly WeightedContribution[]): T[];
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* rrf(d) = Σ_provider 1 / (k + bestRank_provider(d)) one term per provider
|
|
5
5
|
* norm(d) = rrf(d) / (nProviders / (k + 1)) in [0, 1]; 1 = rank 1 everywhere
|
|
6
6
|
* score(d) = norm(d) + bonus(d) bonus added ONCE per URL
|
|
7
|
-
* bonus(d) = (freshnessBoost·fresh(d) + authorityBoost·authority(d)) · unit
|
|
7
|
+
* bonus(d) = (freshnessBoost·fresh(d) + authorityBoost·authority(d) + signalBoost·signal(d)) · unit
|
|
8
8
|
* unit = 1 / (nProviders · (k + 2)) one top-rank step of one provider, on the normalised scale
|
|
9
9
|
*
|
|
10
10
|
* `freshnessBoost` / `authorityBoost` (config, 0..1) are therefore FRACTIONS OF
|
|
@@ -13,10 +13,25 @@
|
|
|
13
13
|
* positions. They break ties and near-ties; they cannot lift a rank-10 result
|
|
14
14
|
* over a rank-1 result of the same provider. A URL returned by several
|
|
15
15
|
* providers gets one bonus, not one per hit.
|
|
16
|
+
*
|
|
17
|
+
* `signal(d)` is the provider's OWN quality grade when it gives one (DeepSeek Search: `rerank_score` 0..3, which already folds
|
|
18
|
+
* relevance, authority and freshness together, and `authority` 0..4): 0.7·rerank/3 + 0.3·authority/4 over whichever of the two
|
|
19
|
+
* the URL has (the best seen over providers, see candidates.ts), 0 for a URL no provider graded. `signalBoost` (default
|
|
20
|
+
* {@link PROVIDER_SIGNAL_BOOST}) is, like the others, a fraction of ONE top-rank step: with the default boosts the three
|
|
21
|
+
* bonuses together can never reach one rank position (0.2 + 0.25 + 0.3 = 0.75). A provider that grades its own results already
|
|
22
|
+
* orders them, so the signal mostly arbitrates between providers; it never lifts a rank-10 result over a rank-1 one.
|
|
23
|
+
*
|
|
24
|
+
* Source confidence (confidence.ts) scales each provider's RRF term by `factor(c)` in [0.8, 1] and the bonus of a URL by the best factor
|
|
25
|
+
* among the providers that returned it; a provider without a confidence, which is every built-in source, has factor exactly 1 and the
|
|
26
|
+
* scores are what they were without it.
|
|
16
27
|
* @module web-search-pro/pipeline/fusion
|
|
17
28
|
*/
|
|
18
29
|
import type { Candidate } from './types.ts';
|
|
19
30
|
export declare const AUTHORITY_DOMAINS_BUILTIN: readonly string[];
|
|
31
|
+
/** Default weight of the provider's own quality signal (fraction of one top-rank step); see the module comment. */
|
|
32
|
+
export declare const PROVIDER_SIGNAL_BOOST = 0.3;
|
|
33
|
+
/** Share of the provider signal that comes from `rerank_score` (the rest is `authority`, when the URL has one). */
|
|
34
|
+
export declare const RERANK_SIGNAL_WEIGHT = 0.7;
|
|
20
35
|
export interface FusionOptions {
|
|
21
36
|
/** RRF smoothing constant (config rrfConstant). */
|
|
22
37
|
k: number;
|
|
@@ -26,6 +41,8 @@ export interface FusionOptions {
|
|
|
26
41
|
freshnessDays: number;
|
|
27
42
|
/** Fraction of one top-rank step for an authority host (0..1). */
|
|
28
43
|
authorityBoost: number;
|
|
44
|
+
/** Fraction of one top-rank step for a result the provider itself graded best (0..1; default {@link PROVIDER_SIGNAL_BOOST}); 0 turns the signal off. */
|
|
45
|
+
signalBoost?: number;
|
|
29
46
|
/** Extra authority domains; the built-in list and .edu/.gov/.org always apply. */
|
|
30
47
|
authorityDomains: readonly string[];
|
|
31
48
|
/** Providers that took part (answered, even with few results). Defaults to the distinct providers in the candidates. */
|
|
@@ -42,6 +59,11 @@ export interface RankedCandidate {
|
|
|
42
59
|
normalized: number;
|
|
43
60
|
bonus: number;
|
|
44
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* The provider's own quality grade of a candidate in 0..1: `rerank_score` / 3 weighted 0.7 and `authority` / 4 weighted 0.3; with
|
|
64
|
+
* only one of them present that one alone; 0 when the candidate has none. Out-of-range values are clamped.
|
|
65
|
+
*/
|
|
66
|
+
export declare function providerSignal(candidate: Pick<Candidate, 'signals'>): number;
|
|
45
67
|
/** Best (lowest) rank per provider: one RRF term per provider per URL. */
|
|
46
68
|
export declare function bestRanks(candidate: Pick<Candidate, 'contributions'>): Map<string, number>;
|
|
47
69
|
export declare function isAuthorityHost(host: string, extraDomains?: readonly string[]): boolean;
|
|
@@ -10,8 +10,24 @@ export interface RenderSource {
|
|
|
10
10
|
title?: string;
|
|
11
11
|
snippet?: string;
|
|
12
12
|
publishedAt?: string;
|
|
13
|
+
rerankScore?: number;
|
|
14
|
+
authority?: number;
|
|
13
15
|
lowConfidence?: boolean;
|
|
16
|
+
via?: string;
|
|
17
|
+
confidence?: number;
|
|
18
|
+
tag?: string;
|
|
14
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* `[rerank 2.4/3, authority 3/4]`: the provider's own grades of a source (DeepSeek Search); for a custom CLI or a source the user gave a
|
|
22
|
+
* confidence below 1 also `via custom-cli:echo, confidence 0.5` and the honest label (user-defined, not verified). Empty when there is none of it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function qualityTag(s: {
|
|
25
|
+
rerankScore?: number;
|
|
26
|
+
authority?: number;
|
|
27
|
+
via?: string;
|
|
28
|
+
confidence?: number;
|
|
29
|
+
tag?: string;
|
|
30
|
+
}): string;
|
|
15
31
|
/** Marker for a source / excerpt whose page only passed the S4 floor, not the relevance gate (dev-plan §3.1). */
|
|
16
32
|
export declare const LOW_RELEVANCE = " (low relevance)";
|
|
17
33
|
/** One line under the header (dev-plan M3b): "covered" is a lexical judgement, and a missing passage proves nothing. */
|
|
@@ -44,7 +44,8 @@ export interface ProviderCall {
|
|
|
44
44
|
export type ProviderOutcome = {
|
|
45
45
|
state: 'ok';
|
|
46
46
|
sources: readonly ProviderSource[]; /** The backend of a platform chain that answered. */
|
|
47
|
-
backend?: string;
|
|
47
|
+
backend?: string; /** The engine's own remarks (a query it had to cut, results it dropped); they reach the pack notes. */
|
|
48
|
+
notes?: readonly string[];
|
|
48
49
|
}
|
|
49
50
|
/** `detail` carries the provider's own explanation of an empty answer (e.g. a login hint), when it gave one. */
|
|
50
51
|
| {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Validation of the user's source preferences (`sources.priority`, `sources.disabled`, `sources.budget`), with no Node
|
|
2
|
+
* Validation of the user's source preferences (`sources.priority`, `sources.disabled`, `sources.budget`, `sources.confidence`), with no Node
|
|
3
3
|
* imports so the settings panel validates them with the code the server uses; the request counters live in ./ledger.ts.
|
|
4
4
|
* @module web-search-pro/pipeline/sources-spec
|
|
5
5
|
*/
|
|
@@ -13,11 +13,14 @@ export interface SourcesInput {
|
|
|
13
13
|
priority?: readonly string[];
|
|
14
14
|
disabled?: readonly string[];
|
|
15
15
|
budget?: Record<string, SourceBudgetInput>;
|
|
16
|
+
/** Confidence (0..1) per source or platform-backend id; absent = 1 for a built-in source, the spec's own for a custom CLI. */
|
|
17
|
+
confidence?: Record<string, number>;
|
|
16
18
|
}
|
|
17
19
|
export interface SourcesResolved {
|
|
18
20
|
priority: string[];
|
|
19
21
|
disabled: string[];
|
|
20
22
|
budget: Record<string, SourceBudgetInput>;
|
|
23
|
+
confidence: Record<string, number>;
|
|
21
24
|
/** Entries ignored, each saying why (surfaced by `sources.status` and the settings card). */
|
|
22
25
|
diagnostics: string[];
|
|
23
26
|
}
|
|
@@ -25,4 +28,4 @@ export interface SourcesResolved {
|
|
|
25
28
|
* Validate the preferences; invalid entries are dropped and reported, never thrown. `known` (optional) tells whether an
|
|
26
29
|
* id is a registered provider: unknown ids are reported and dropped, so a typo cannot silently disable nothing.
|
|
27
30
|
*/
|
|
28
|
-
export declare function resolveSources(input: SourcesInput | undefined, known?: (id: string) => boolean): SourcesResolved;
|
|
31
|
+
export declare function resolveSources(input: SourcesInput | undefined, known?: (id: string) => boolean, knownBackend?: (id: string) => boolean): SourcesResolved;
|
|
@@ -43,12 +43,27 @@ export interface TaskSpec {
|
|
|
43
43
|
constraints: Constraint[];
|
|
44
44
|
budget: BudgetProfile;
|
|
45
45
|
}
|
|
46
|
+
export interface CandidateSignals {
|
|
47
|
+
/** Provider relevance / authority / freshness rank score, 0..3. */
|
|
48
|
+
rerankScore?: number;
|
|
49
|
+
/** Provider source-authority grade, 0..4. */
|
|
50
|
+
authority?: number;
|
|
51
|
+
}
|
|
46
52
|
/** One provider hit for a candidate. `rank` is 1-based within that provider's result list. */
|
|
47
53
|
export interface Contribution {
|
|
48
54
|
providerId: string;
|
|
49
55
|
rank: number;
|
|
50
56
|
/** The exact query sent to the provider (may be a compiled variant). */
|
|
51
57
|
query: string;
|
|
58
|
+
/** The source's confidence (0..1), present only when it is below 1: a custom CLI, or a source the user set `sources.confidence` for. */
|
|
59
|
+
confidence?: number;
|
|
60
|
+
}
|
|
61
|
+
/** Where a result of a user-defined source came from: shown with the result and never merged away. */
|
|
62
|
+
export interface CandidateOrigin {
|
|
63
|
+
/** Ids of the custom CLIs that returned the URL (`custom-cli:echo`). */
|
|
64
|
+
via: string[];
|
|
65
|
+
/** The honest label of these sources: user-defined, not verified by the plugin. */
|
|
66
|
+
tag: string;
|
|
52
67
|
}
|
|
53
68
|
export type Satisfied = 'yes' | 'no' | 'unknown';
|
|
54
69
|
export interface ConstraintCheck {
|
|
@@ -81,8 +96,15 @@ export interface Candidate {
|
|
|
81
96
|
title: string;
|
|
82
97
|
snippet: string;
|
|
83
98
|
publishedAt?: string;
|
|
99
|
+
/**
|
|
100
|
+
* The providers' own quality signals for this URL (best seen over all providers that gave one): DeepSeek Search's `rerank_score`
|
|
101
|
+
* (0..3) and `authority` (0..4). Source metadata, and one small fusion signal (fusion.ts); absent for providers that give none.
|
|
102
|
+
*/
|
|
103
|
+
signals?: CandidateSignals;
|
|
84
104
|
/** Every (provider, rank, query) that returned this URL. */
|
|
85
105
|
contributions: Contribution[];
|
|
106
|
+
/** Set when a user-defined CLI returned the URL. */
|
|
107
|
+
origin?: CandidateOrigin;
|
|
86
108
|
checks?: ConstraintCheck[];
|
|
87
109
|
gate?: GateVerdict;
|
|
88
110
|
}
|
|
@@ -110,6 +132,12 @@ export interface PageBlock {
|
|
|
110
132
|
providers: string[];
|
|
111
133
|
/** The candidate only passed the S4 floor, not the relevance gate. */
|
|
112
134
|
lowConfidence?: true;
|
|
135
|
+
/** Custom CLI that returned the page's URL, the label it carries, and the best confidence among the sources that returned it (below 1 only). */
|
|
136
|
+
origin?: {
|
|
137
|
+
via?: string;
|
|
138
|
+
tag?: string;
|
|
139
|
+
confidence?: number;
|
|
140
|
+
};
|
|
113
141
|
block: Block;
|
|
114
142
|
}
|
|
115
143
|
/** `grade` is 0..3 (rule: integer buckets; Jev: the level expectation). `rank` is a finer tie-breaker. */
|
|
@@ -138,6 +166,10 @@ export interface EvidenceItem {
|
|
|
138
166
|
source: string;
|
|
139
167
|
/** The page's candidate failed the relevance gate and was kept only by the floor. */
|
|
140
168
|
lowConfidence?: true;
|
|
169
|
+
/** The custom CLI(s) that returned the page, the best confidence among its sources (below 1 only) and the honest label. */
|
|
170
|
+
via?: string;
|
|
171
|
+
confidence?: number;
|
|
172
|
+
tag?: string;
|
|
141
173
|
}
|
|
142
174
|
export type GapReason = 'no_candidates' | 'no_page_content' | 'weak_support' | 'budget';
|
|
143
175
|
export interface Gap {
|
|
@@ -230,7 +262,12 @@ export interface EvidencePack {
|
|
|
230
262
|
title?: string;
|
|
231
263
|
snippet?: string;
|
|
232
264
|
publishedAt?: string;
|
|
265
|
+
rerankScore?: number;
|
|
266
|
+
authority?: number;
|
|
233
267
|
lowConfidence?: true;
|
|
268
|
+
via?: string;
|
|
269
|
+
confidence?: number;
|
|
270
|
+
tag?: string;
|
|
234
271
|
}[];
|
|
235
272
|
engine: string;
|
|
236
273
|
enginesTried: string[];
|