@instruments/materialgraph 0.25.0 → 0.27.0
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/association-types.d.ts +38 -27
- package/associations-client.d.ts +4 -4
- package/associations-client.js +3 -10
- package/attribution-types.d.ts +4 -4
- package/brand-types.d.ts +14 -6
- package/brands-client.d.ts +7 -38
- package/brands-client.js +10 -40
- package/by-colour-types.d.ts +58 -31
- package/by-spec-types.d.ts +6 -73
- package/by-spec-types.js +7 -5
- package/catalog-discovery-types.d.ts +11 -26
- package/catalogue-client.d.ts +16 -35
- package/catalogue-client.js +32 -67
- package/catalogue-types.d.ts +44 -4
- package/categories-client.d.ts +63 -0
- package/categories-client.js +48 -0
- package/category-types.d.ts +114 -0
- package/citation-types.d.ts +4 -4
- package/client-config.d.ts +4 -6
- package/client-config.js +2 -4
- package/client-source-material-comments.d.ts +4 -4
- package/client-source-material-comments.js +4 -38
- package/client-vocabulary.d.ts +7 -9
- package/client-vocabulary.js +22 -30
- package/client.d.ts +110 -244
- package/client.js +217 -387
- package/codes-client.d.ts +2 -2
- package/codes-client.js +8 -8
- package/codes-types.d.ts +55 -34
- package/colour-aggregate-types.d.ts +24 -24
- package/colours-client.d.ts +6 -11
- package/colours-client.js +11 -19
- package/coordinate-client.d.ts +2 -2
- package/coordinate-client.js +1 -13
- package/corpus-scope-types.d.ts +3 -3
- package/corpus-scope-types.js +1 -25
- package/demand-batch-types.d.ts +18 -18
- package/demand-types.d.ts +24 -24
- package/errors.d.ts +13 -13
- package/errors.js +54 -52
- package/http-transport.d.ts +13 -21
- package/http-transport.js +31 -28
- package/identify-types.d.ts +54 -44
- package/identify-types.js +5 -3
- package/index.d.ts +11 -27
- package/index.js +4 -6
- package/list-variant-facets-types.d.ts +60 -0
- package/list-variants-types.d.ts +142 -0
- package/list-variants-types.js +12 -0
- package/match-stream-types.d.ts +45 -32
- package/match-stream-types.js +2 -0
- package/match-stream.d.ts +2 -2
- package/match-stream.js +67 -49
- package/match-types.d.ts +32 -8
- package/material-asset-types.d.ts +89 -69
- package/material-block-types.d.ts +8 -6
- package/material-composition-client.d.ts +21 -0
- package/material-composition-client.js +13 -0
- package/material-composition-types.d.ts +403 -0
- package/material-query-plan-types.d.ts +61 -145
- package/material-resources-client.d.ts +12 -10
- package/material-resources-client.js +27 -22
- package/material-types.d.ts +16 -24
- package/ndjson.js +16 -8
- package/operations.d.ts +6 -6
- package/operations.js +29 -156
- package/package.json +5 -1
- package/palette-search-types.d.ts +87 -52
- package/query-understanding-types.d.ts +65 -40
- package/resolve-client.d.ts +8 -12
- package/resolve-client.js +9 -13
- package/resolve-colour-types.d.ts +8 -8
- package/resolve-types.d.ts +10 -10
- package/response-schemas.d.ts +20 -0
- package/response-schemas.generated.d.ts +5 -0
- package/response-schemas.generated.js +160 -0
- package/response-schemas.js +113 -0
- package/run-types.d.ts +64 -145
- package/runs.d.ts +9 -58
- package/runs.js +60 -149
- package/samplize-catalogue-types.d.ts +18 -18
- package/samplize-colorvec.d.ts +20 -20
- package/samplize-colorvec.js +66 -42
- package/schema-resource-types.d.ts +52 -39
- package/schema-resource-types.js +5 -5
- package/search-card-types.d.ts +26 -4
- package/search-index-plan-types.d.ts +70 -0
- package/search-refinement-types.d.ts +10 -40
- package/search-refinement-types.js +1 -0
- package/search-request-types.d.ts +121 -204
- package/search-response-receipt-types.d.ts +13 -253
- package/search-response-types.d.ts +2 -2
- package/search-result-validation.d.ts +3 -19
- package/search-result-validation.js +42 -183
- package/source-material-validation.d.ts +3 -3
- package/source-material-validation.js +35 -39
- package/spec-facet-types.d.ts +11 -16
- package/spec-types.d.ts +23 -16
- package/spec-types.js +8 -7
- package/specifications.d.ts +14 -72
- package/specifications.js +39 -89
- package/sse.d.ts +2 -2
- package/sse.js +32 -16
- package/substitute-types.d.ts +22 -22
- package/suggest-types.d.ts +11 -17
- package/suggest-types.js +3 -3
- package/taxonomy-coverage-types.d.ts +8 -8
- package/types.d.ts +202 -405
- package/validation.d.ts +26 -26
- package/validation.js +97 -92
- package/webmcp.d.ts +3 -3
- package/webmcp.generated.js +10 -93
- package/brand-most-sampled-types.d.ts +0 -33
- package/browse-types.d.ts +0 -236
- package/client-browse.d.ts +0 -78
- package/client-browse.js +0 -72
- package/client-exploration.d.ts +0 -9
- package/client-exploration.js +0 -7
- package/compare-types.d.ts +0 -89
- package/composition-client.d.ts +0 -33
- package/composition-client.js +0 -27
- package/composition-types.d.ts +0 -455
- package/composition-types.js +0 -10
- package/correction-types.d.ts +0 -88
- package/exploration-types.d.ts +0 -118
- package/exploration-types.js +0 -1
- package/fan-deck-types.d.ts +0 -42
- package/fan-deck-types.js +0 -9
- package/match-rejection-types.d.ts +0 -43
- package/match-rejection-types.js +0 -7
- package/palette-completion-types.d.ts +0 -115
- package/palette-completion-types.js +0 -1
- package/project-types.d.ts +0 -79
- package/project-types.js +0 -9
- package/projects.d.ts +0 -13
- package/projects.js +0 -46
- package/render-assets-types.d.ts +0 -65
- package/render-assets-types.js +0 -1
- package/run-events.d.ts +0 -106
- package/run-events.js +0 -32
- package/schedule-reference-types.d.ts +0 -46
- package/schedule-reference-types.js +0 -1
- package/schedule-references-client.d.ts +0 -14
- package/schedule-references-client.js +0 -26
- package/schedule-types.d.ts +0 -261
- package/schedule-types.js +0 -1
- package/search-collapse-types.d.ts +0 -69
- package/search-collapse-types.js +0 -1
- package/search-mood-types.d.ts +0 -6
- package/search-mood-types.js +0 -1
- package/search-window-types.d.ts +0 -25
- package/search-window-types.js +0 -1
- package/slot-pool-types.d.ts +0 -372
- package/slot-pool-types.js +0 -1
- /package/{brand-most-sampled-types.js → category-types.js} +0 -0
- /package/{browse-types.js → list-variant-facets-types.js} +0 -0
- /package/{compare-types.js → material-composition-types.js} +0 -0
- /package/{correction-types.js → search-index-plan-types.js} +0 -0
|
@@ -1,86 +1,75 @@
|
|
|
1
|
-
/** samplizeCatalogue admits published US Samplize paint colours, regardless of stock. */
|
|
2
1
|
/**
|
|
3
2
|
* @module search-request-types
|
|
4
|
-
* The two request shapes for the `/search` surface
|
|
3
|
+
* The two request shapes for the `/search` surface: the POST JSON body and the
|
|
5
4
|
* GET query-string form. Split out of `types.ts` so neither file outgrows the
|
|
6
5
|
* repo's source-size gate; every name here is re-exported from `types.ts`, so
|
|
7
6
|
* no import path changes.
|
|
8
7
|
*/
|
|
9
8
|
import type { CorpusScope } from "./corpus-scope-types.js";
|
|
10
9
|
import type { Cursor, VariantId } from "./identifiers.js";
|
|
11
|
-
import type {
|
|
12
|
-
import type { ColourInput, OpenEnum, SearchImageInput } from "./types.js";
|
|
10
|
+
import type { OpenEnum, SearchImageInput } from "./types.js";
|
|
13
11
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
12
|
+
* One attribute filter the one search runs as a hard token set on its index
|
|
13
|
+
* (ADR 0031, MG-2158). Entries on one attribute are OR'd; entries on different
|
|
14
|
+
* attributes AND together.
|
|
15
|
+
*
|
|
16
|
+
* - `term`: the value must carry this canonical term.
|
|
17
|
+
* - `terms`: any one of these terms satisfies it.
|
|
18
|
+
* - `excludesTerm`: the value must not carry this term. A material that states
|
|
19
|
+
* nothing for the attribute passes.
|
|
20
|
+
* - `hasValue: true`: any stated value.
|
|
21
|
+
* - `min` and/or `max`: an inclusive numeric range, on a numeric attribute
|
|
22
|
+
* (`"nrc_rating"`), a dimensions lens in millimetres
|
|
23
|
+
* (`"dimensions.thickness_mm"`, `"dimensions.short_side_mm"`) or a
|
|
24
|
+
* composition share on 0 to 1 (`"composition_weighted.wool"`). It is read as
|
|
25
|
+
* the number bands wholly inside it, so a bound between two band edges is
|
|
26
|
+
* read inward; a range no band fits inside is a 400.
|
|
27
|
+
*
|
|
28
|
+
* `attributeId` is an attribute the index carries tokens for, or
|
|
29
|
+
* `"certification_programme"` for any certification programme. Terms are
|
|
30
|
+
* canonical dictionary terms, not display names. Numeric attributes take
|
|
31
|
+
* `hasValue` or a range. An attribute or term the index does not carry is a
|
|
32
|
+
* 400 naming it.
|
|
17
33
|
*/
|
|
18
|
-
export
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
* `sort`, which stays the closed relevance / colour / catalogue vocabulary.
|
|
46
|
-
*
|
|
47
|
-
* `direction` defaults to `"asc"`. Sent together with `sort`, `orderBy` wins
|
|
48
|
-
* and the response `note` says so — a UI holding both controls can send both.
|
|
49
|
-
*
|
|
50
|
-
* Ordering is DECLARED, never inferred from how a value is spelled: an
|
|
51
|
-
* attribute with no stated ladder is a 400 carrying the orderable set in
|
|
52
|
-
* `orderable_attributes`, not a quiet fall back to relevance. A material whose
|
|
53
|
-
* value is off the ladder, or which carries no value at all, sorts LAST in
|
|
54
|
-
* both directions — it is still a real material, it just has no rung.
|
|
55
|
-
*/
|
|
56
|
-
orderBy?: {
|
|
57
|
-
attributeId: string;
|
|
58
|
-
direction?: OpenEnum<"asc" | "desc">;
|
|
59
|
-
};
|
|
34
|
+
export type SearchIndexFilter = {
|
|
35
|
+
attributeId: string;
|
|
36
|
+
term: string;
|
|
37
|
+
} | {
|
|
38
|
+
attributeId: string;
|
|
39
|
+
terms: string[];
|
|
40
|
+
} | {
|
|
41
|
+
attributeId: string;
|
|
42
|
+
excludesTerm: string;
|
|
43
|
+
} | {
|
|
44
|
+
attributeId: string;
|
|
45
|
+
hasValue: true;
|
|
46
|
+
} | {
|
|
47
|
+
attributeId: string;
|
|
48
|
+
min?: number;
|
|
49
|
+
max?: number;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* The POST `/search` JSON body (ADR 0031): the words, or a look-alike seed, and
|
|
53
|
+
* the page wanted. `category`, `filters`, `corpusScope`, `colour` and `brands`
|
|
54
|
+
* become fields of the query's plan and run in the same index query. The order
|
|
55
|
+
* is the index's own, so nothing here sets weights, a blend or a sort. Send
|
|
56
|
+
* `text`, `similarTo`, `image`, `colour`, `category`, `filters` or `brands`; a
|
|
57
|
+
* corpus scope alone does not say what to find. Any other field is a 400
|
|
58
|
+
* naming it.
|
|
59
|
+
*/
|
|
60
|
+
export type SearchInput = {
|
|
60
61
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* Three response states, all different: no `attributes` key means you did not
|
|
66
|
-
* ask, a key with `null` means nothing is on record for that material, and
|
|
67
|
-
* anything else is the value. An unknown attribute id is a 400 naming it.
|
|
62
|
+
* Free text ("oak flooring", "sage green velvet", "Kvadrat wool"). Brands,
|
|
63
|
+
* categories, colours and attributes are read from the words unless
|
|
64
|
+
* `brands`, `category` or `colour` says so instead; a corrected word is
|
|
65
|
+
* reported under `correctedQuery`.
|
|
68
66
|
*/
|
|
69
|
-
|
|
67
|
+
text?: string;
|
|
68
|
+
/** A query image (URL or base64); `text`, when also given, narrows it. */
|
|
69
|
+
image?: SearchImageInput;
|
|
70
70
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* (`vector`).
|
|
74
|
-
*
|
|
75
|
-
* `materialBankId` exists so a caller already holding a SKU does not have to
|
|
76
|
-
* ask us to translate it before it can ask us anything useful — one call, not
|
|
77
|
-
* two. It resolves to the variant server-side and then behaves identically to
|
|
78
|
-
* the `{ variantId }` form, seed verdicts included. A SKU that names no
|
|
79
|
-
* variant is a 400 carrying the offending value: never an empty result set,
|
|
80
|
-
* never a silent fall back to unseeded search.
|
|
81
|
-
*
|
|
82
|
-
* The `{ vector }` form carries no seed variant, so it is the only one
|
|
83
|
-
* `verdicts` cannot diff a candidate against.
|
|
71
|
+
* Materials that LOOK like a seed: an existing variant, a Material Bank SKU
|
|
72
|
+
* (an unknown SKU is a 400 naming it), or a pre-computed image vector.
|
|
84
73
|
*/
|
|
85
74
|
similarTo?: {
|
|
86
75
|
variantId: VariantId;
|
|
@@ -90,156 +79,84 @@ export interface SearchInput {
|
|
|
90
79
|
vector: string;
|
|
91
80
|
};
|
|
92
81
|
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* Maximum 256; ids are opaque.
|
|
82
|
+
* A hard category gate: public category-group or product-type names, or
|
|
83
|
+
* taxonomy keys. It replaces the category the words were read as. An
|
|
84
|
+
* unknown value is a 400 listing every valid name.
|
|
97
85
|
*/
|
|
98
|
-
excludeVariantIds?: VariantId[];
|
|
99
|
-
image?: SearchImageInput;
|
|
100
86
|
category?: {
|
|
101
|
-
|
|
102
|
-
filter?: string[];
|
|
87
|
+
filter: string[];
|
|
103
88
|
};
|
|
89
|
+
/** Hard attribute filters, 1 to 24. See {@link SearchIndexFilter}. */
|
|
90
|
+
filters?: SearchIndexFilter[];
|
|
104
91
|
/**
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
92
|
+
* Order the page by a colour: a `hex`, or `variantId` for the colour of an
|
|
93
|
+
* existing Variant. The page is the colour's family, nearest first by OKLab
|
|
94
|
+
* distance; it replaces any colour read from `text`. A Variant with no colour
|
|
95
|
+
* on the index is a 400.
|
|
109
96
|
*/
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
lexical?: number;
|
|
115
|
-
/** Compatibility field; seeded text does not activate secondary scoring. */
|
|
116
|
-
text?: number;
|
|
97
|
+
colour?: {
|
|
98
|
+
hex: string;
|
|
99
|
+
} | {
|
|
100
|
+
variantId: VariantId;
|
|
117
101
|
};
|
|
118
|
-
filters?: SearchFilter[];
|
|
119
|
-
/**
|
|
120
|
-
* SOFT spec criteria (rank-never-exclude). Same shape as `filters`; a preference
|
|
121
|
-
* never removes a result — it adds a `preferred` cell to each hit's `verdict` and
|
|
122
|
-
* demotes a failed/missing preferred hit WITHIN its page only.
|
|
123
|
-
*/
|
|
124
|
-
preferences?: SearchFilter[];
|
|
125
|
-
/** Results per page (default 60, max 60), never a bound on the match set. */
|
|
126
|
-
limit?: number;
|
|
127
|
-
/** The previous response's `cursor`, passed back verbatim. Never synthesise one. */
|
|
128
|
-
cursor?: Cursor;
|
|
129
|
-
explain?: boolean;
|
|
130
|
-
/** Public POST defaults to distinct products; send `"none"` for individual variants. */
|
|
131
|
-
collapse?: OpenEnum<"none" | "product">;
|
|
132
102
|
/**
|
|
133
|
-
*
|
|
134
|
-
*
|
|
103
|
+
* Makers the page must come from: canonical brand ids, exact slugs
|
|
104
|
+
* ("sherwin-williams") or exact display names ("Sherwin-Williams"), up to
|
|
105
|
+
* 50. They replace the makers `text` was read as. An empty list is the
|
|
106
|
+
* same request as omitting it — every brand. An unrecognised value is a
|
|
107
|
+
* 400 naming it; a display name shared by more than one brand is a 400
|
|
108
|
+
* naming the exact slugs to choose between; a brand MaterialGraph holds no
|
|
109
|
+
* materials under is a 400 naming a populated sibling when one exists.
|
|
135
110
|
*/
|
|
136
|
-
|
|
111
|
+
brands?: string[];
|
|
137
112
|
/**
|
|
138
|
-
*
|
|
139
|
-
* `
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
113
|
+
* Attribute ids (at most 8) whose resolved value should ride each result
|
|
114
|
+
* under `attributes`, keyed by attribute id. Not a plan field: it changes
|
|
115
|
+
* no ordering and plays no part in the cursor. An attribute you did not
|
|
116
|
+
* ask for is not a key on `attributes` at all; one you asked for that a
|
|
117
|
+
* result carries no accepted value for is `null`; anything else is the
|
|
118
|
+
* value. An unknown attribute id is a 400 naming it.
|
|
143
119
|
*/
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Opaque five-minute receipt from a prior pool-derived faceted search.
|
|
147
|
-
* Resubmitting it may only narrow that exact finalized pool.
|
|
148
|
-
*/
|
|
149
|
-
refinementToken?: string;
|
|
150
|
-
/** Only return materials with at least one catalog image. Default false (full catalog). */
|
|
151
|
-
hasImages?: boolean;
|
|
152
|
-
/** Require a recorded accepted sampleable=true fact; unknown and false are excluded. */
|
|
153
|
-
sampleableOnly?: boolean;
|
|
154
|
-
/**
|
|
155
|
-
* Opt-in seed-relative verdict cells (MG-629). Only meaningful with
|
|
156
|
-
* `similarTo: { variantId }`: each hit's `verdict` gains `preferred` cells
|
|
157
|
-
* diffing its comparable attributes (numeric + a `colour` axis) against the
|
|
158
|
-
* seed's, with directional deviations. Inert on every other seed form.
|
|
159
|
-
*/
|
|
160
|
-
verdicts?: boolean;
|
|
161
|
-
/** Result projection — `"full"` (default) or the lean `"card"` grid form. */
|
|
162
|
-
view?: OpenEnum<"full" | "card">;
|
|
163
|
-
/**
|
|
164
|
-
* Budget profile for the search primitive.
|
|
165
|
-
*
|
|
166
|
-
* `"search"` (default) is the full engine. `"typeahead"` is the as-you-type
|
|
167
|
-
* profile: lexical-only with prefix match on the final token, forced
|
|
168
|
-
* `view: "card"`, `limit` capped at 24, and no mood/colour detection tiers,
|
|
169
|
-
* semantic fallback, secondary scoring, refinement suggestions,
|
|
170
|
-
* counts, or meanings. `textModes` is ignored under typeahead.
|
|
171
|
-
*/
|
|
172
|
-
intent?: OpenEnum<"search" | "typeahead">;
|
|
120
|
+
returnAttributes?: string[];
|
|
173
121
|
/**
|
|
174
|
-
* Which corpus to answer from.
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
* products DesignShop hides from browse excluded).
|
|
184
|
-
* `"materialBankNaAndCatalogue"` is a governed discovery corpus: the single
|
|
185
|
-
* producer-side union of Material Bank North America and Catalogue editorial
|
|
186
|
-
* membership. It is not a buyability claim, and a catalogue reference alone
|
|
187
|
-
* does not establish membership.
|
|
188
|
-
*
|
|
189
|
-
* `"materialBankOrderable"` is NOT one of them, despite the name. It selects
|
|
190
|
-
* materials carrying a Material Bank identity — a PROVENANCE signal, not a
|
|
191
|
-
* storefront — and admits about 98% of the graph. Use it to exclude the
|
|
192
|
-
* crawl-sourced brands that were never in the Material Bank feed; if you mean
|
|
193
|
-
* orderable, use one of the channel-backed scopes above.
|
|
194
|
-
*
|
|
195
|
-
* A scope answers membership in its named distribution or visibility
|
|
196
|
-
* surface; the token-specific description states whether that means
|
|
197
|
-
* transaction or editorial inclusion. It never answers what is SUITABLE:
|
|
198
|
-
* scope on channel, then refine on sector.
|
|
199
|
-
*
|
|
200
|
-
* The scope is applied INSIDE the query: `limit` fills with eligible rows,
|
|
201
|
-
* `counts` describe the SCOPED corpus, and the response echoes the scope.
|
|
202
|
-
* That is what post-filtering a page cannot give you — a client-side filter
|
|
203
|
-
* shortens the page exactly when the query drifts toward the corpus beyond
|
|
204
|
-
* the Material Bank feed, which is unpredictable from outside.
|
|
122
|
+
* Which corpus to answer from, applied inside the index query. ABSENT (or
|
|
123
|
+
* `"all"`) means the whole graph. `"materialBankOrderable"` is a provenance
|
|
124
|
+
* signal (a Material Bank identity), not a storefront; the channel-backed
|
|
125
|
+
* scopes (`"materialBankNaOrderable"`, `"materialBankEuOrderable"`,
|
|
126
|
+
* `"designShopOrderable"`) answer where a material can be ordered,
|
|
127
|
+
* `"materialBankNaAndCatalogue"` is a governed discovery corpus (the union
|
|
128
|
+
* of Material Bank North America and Catalogue editorial membership, not a
|
|
129
|
+
* buyability claim), and `"samplizeCatalogue"` admits published US Samplize
|
|
130
|
+
* paint colours, regardless of stock.
|
|
205
131
|
*/
|
|
206
132
|
corpusScope?: CorpusScope;
|
|
133
|
+
/** Products per page (max 60). Absent, the search's own page size. */
|
|
134
|
+
limit?: number;
|
|
207
135
|
/**
|
|
208
|
-
*
|
|
209
|
-
* (
|
|
210
|
-
* cards, which are orderable samples and never specifiable materials.
|
|
136
|
+
* The previous response's `cursor`, passed back verbatim. A cursor from
|
|
137
|
+
* another query (other words, filters or scope) is a 409.
|
|
211
138
|
*/
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
139
|
+
cursor?: Cursor;
|
|
140
|
+
/** Add `timings` and `explain.plan`, the plan the search ran on. */
|
|
141
|
+
explain?: boolean;
|
|
142
|
+
/** Result projection: `"full"` (default) or the lean `"card"` grid form. */
|
|
143
|
+
view?: OpenEnum<"full" | "card">;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Query-string params for the GET `/search` form. `category` and `filters`
|
|
147
|
+
* have no query-string form; send them through `search()`.
|
|
148
|
+
*/
|
|
149
|
+
export type SearchGetParams = {
|
|
216
150
|
q?: string;
|
|
217
|
-
|
|
218
|
-
logic?: OpenEnum<"all" | "any">;
|
|
219
|
-
mood?: string;
|
|
220
|
-
/** Governed corpus applied inside retrieval; absent means the whole graph. */
|
|
221
|
-
corpusScope?: CorpusScope;
|
|
222
|
-
sort?: OpenEnum<"relevance" | "light" | "dark" | "vivid" | "muted" | "colourful" | "name" | "name_desc" | "recent">;
|
|
223
|
-
tol?: OpenEnum<"tight" | "normal" | "loose">;
|
|
224
|
-
/** Seed the search from this variant's image. Opaque — pass it through verbatim. */
|
|
151
|
+
/** Seed the search from this variant's image. Opaque; pass it through verbatim. */
|
|
225
152
|
variantId?: VariantId;
|
|
153
|
+
/** Corpus applied inside the index query; absent means the whole graph. */
|
|
154
|
+
corpusScope?: CorpusScope;
|
|
226
155
|
limit?: number;
|
|
227
|
-
/**
|
|
228
|
-
|
|
229
|
-
/** "
|
|
230
|
-
count?: OpenEnum<"true">;
|
|
231
|
-
/** "true" — only return materials with at least one catalog image. */
|
|
232
|
-
hasImages?: OpenEnum<"true">;
|
|
233
|
-
/** Require a recorded accepted sampleable=true fact. */
|
|
234
|
-
sampleableOnly?: OpenEnum<"true" | "false">;
|
|
235
|
-
/** Result projection — `"full"` (default) or the lean `"card"` grid form. */
|
|
156
|
+
/** The previous response's `cursor`, passed back verbatim. */
|
|
157
|
+
cursor?: Cursor;
|
|
158
|
+
/** Result projection: `"full"` (default) or the lean `"card"` grid form. */
|
|
236
159
|
view?: OpenEnum<"full" | "card">;
|
|
237
|
-
/**
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
* has no nested values. Same spelling as `filters=` on `/search/browse`.
|
|
241
|
-
*/
|
|
242
|
-
orderBy?: string;
|
|
243
|
-
/** Comma-separated attribute ids — the `returnAttributes` list. */
|
|
244
|
-
returnAttributes?: string;
|
|
245
|
-
}
|
|
160
|
+
/** `"1"` adds `timings` and `explain.plan`. */
|
|
161
|
+
explain?: OpenEnum<"0" | "1">;
|
|
162
|
+
};
|
|
@@ -1,264 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module sdk/search-response-receipt-types
|
|
3
|
-
* @description
|
|
4
|
-
*
|
|
3
|
+
* @description The ranking source and the explain-only plan receipt a Search
|
|
4
|
+
* response carries.
|
|
5
5
|
*/
|
|
6
|
+
import type { SearchPlanReceipt } from "./search-index-plan-types.js";
|
|
6
7
|
import type { OpenEnum } from "./types.js";
|
|
7
|
-
/** Inspectable metadata for an opaque, principal-bound search refinement receipt. */
|
|
8
|
-
export interface SearchRefinementReceipt {
|
|
9
|
-
token: string;
|
|
10
|
-
expiresAt: string;
|
|
11
|
-
poolSize: number;
|
|
12
|
-
schemaVersion: string;
|
|
13
|
-
projectionVersion: number;
|
|
14
|
-
}
|
|
15
|
-
/** The primary ranking source a query resolved to and reports as its mode. */
|
|
16
|
-
export type SearchMode = OpenEnum<"image" | "colour" | "text" | "lexical" | "entity-browse">;
|
|
17
8
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
9
|
+
* What ordered the page: `image` (a look-alike), `colour` (colour distance
|
|
10
|
+
* inside the named colour's family), `lexical` (the query's words, by text
|
|
11
|
+
* rank on the index), `attribute` (the category and filters alone define the
|
|
12
|
+
* page) or `agent` (the search agent chose the variants and their order).
|
|
21
13
|
*/
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
colourLabel?: string;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* A part of the search that can fail without stopping it.
|
|
29
|
-
*
|
|
30
|
-
* Coarse on purpose: a caller needs to know that something did not answer, not
|
|
31
|
-
* which provider it was. OPEN, and it will grow — read it with a default
|
|
32
|
-
* branch.
|
|
33
|
-
*/
|
|
34
|
-
export type SearchDegradedPart = OpenEnum<"filter-coverage" | "term-coverage">;
|
|
35
|
-
/**
|
|
36
|
-
* Which parts of the search did not answer, on EVERY response (MG-1913).
|
|
37
|
-
*
|
|
38
|
-
* `parts: []` says no part reported a failure. It does NOT promise every check
|
|
39
|
-
* ran: a check the request never needed is skipped rather than failed. ABSENT
|
|
40
|
-
* means the response came from a server that does not report this, never that
|
|
41
|
-
* nothing was degraded.
|
|
42
|
-
*/
|
|
43
|
-
export interface SearchDegraded {
|
|
44
|
-
parts: SearchDegradedPart[];
|
|
45
|
-
}
|
|
46
|
-
/** Stage counts retained when a search returns no results. */
|
|
47
|
-
export interface SearchEmptyOutcomeCounts {
|
|
48
|
-
retrieved: number;
|
|
49
|
-
afterPrune: number;
|
|
50
|
-
final: number;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Why a search returned no results, on EVERY empty response (MG-1911).
|
|
54
|
-
*
|
|
55
|
-
* `proven-corpus-empty` is exhaustive and is the only member that supports
|
|
56
|
-
* telling someone the catalogue holds nothing. `unproven-empty` is an honest
|
|
57
|
-
* end to a search that ran without establishing that. `search-degraded` means
|
|
58
|
-
* part of the search did not answer, so the empty page describes the runtime
|
|
59
|
-
* rather than the catalogue, and the right response is to retry.
|
|
60
|
-
*
|
|
61
|
-
* Read it by `kind` with a default branch: this union has grown once and the
|
|
62
|
-
* reason and basis enums are open.
|
|
63
|
-
*/
|
|
64
|
-
export type SearchEmptyOutcome = {
|
|
65
|
-
kind: "proven-corpus-empty";
|
|
66
|
-
basis: OpenEnum<"spec-allowlist" | "brand-scope" | "brand-product-type">;
|
|
67
|
-
exhaustive: true;
|
|
68
|
-
sourceEmpty?: boolean | null;
|
|
69
|
-
counts?: SearchEmptyOutcomeCounts;
|
|
70
|
-
} | {
|
|
71
|
-
kind: "unproven-empty";
|
|
72
|
-
reason: OpenEnum<"allowlist-truncated" | "retrieval-window-not-exhaustive" | "source-empty" | "post-retrieval-rejected" | "pagination-empty" | "no-authoritative-empty-proof">;
|
|
73
|
-
sourceEmpty?: boolean | null;
|
|
74
|
-
counts?: SearchEmptyOutcomeCounts;
|
|
75
|
-
} | {
|
|
76
|
-
kind: "search-degraded";
|
|
77
|
-
/** Which parts did not answer. Coarse: never a provider's name. */
|
|
78
|
-
parts: SearchDegradedPart[];
|
|
79
|
-
sourceEmpty?: boolean | null;
|
|
80
|
-
counts?: SearchEmptyOutcomeCounts;
|
|
81
|
-
};
|
|
82
|
-
/** Explain-only coverage of substantive query terms in the lexical projection. */
|
|
83
|
-
export interface SearchTermCoverageReceipt {
|
|
84
|
-
status: OpenEnum<"covered" | "uncovered" | "unavailable" | "skipped">;
|
|
85
|
-
terms: string[];
|
|
86
|
-
note?: string;
|
|
87
|
-
}
|
|
88
|
-
/** The Search workflow run a ledger receipt belongs to. */
|
|
89
|
-
export interface SearchRunRef {
|
|
90
|
-
contextId: string;
|
|
91
|
-
runId: string;
|
|
92
|
-
schemaVersion: 1;
|
|
93
|
-
}
|
|
94
|
-
/** One artifact a Search workflow step read or wrote. */
|
|
95
|
-
export interface SearchRunArtifactRef {
|
|
96
|
-
artifactId: string;
|
|
97
|
-
kind: string;
|
|
98
|
-
producedBy: string;
|
|
99
|
-
runRef: SearchRunRef;
|
|
100
|
-
schemaVersion: 1;
|
|
101
|
-
}
|
|
102
|
-
/** What one Search workflow step did: its reads, its write and its time. */
|
|
103
|
-
export interface SearchStageReceipt {
|
|
104
|
-
stageId: string;
|
|
105
|
-
status: "succeeded";
|
|
106
|
-
/** The step's own work, excluding reading and writing its artifacts. */
|
|
107
|
-
durationMs: number;
|
|
108
|
-
inputArtifacts: SearchRunArtifactRef[];
|
|
109
|
-
outputArtifact: SearchRunArtifactRef;
|
|
110
|
-
inputCount: number | null;
|
|
111
|
-
outputCount: number | null;
|
|
112
|
-
runRef: SearchRunRef;
|
|
113
|
-
/** The outcome the step chose, when it chooses one. */
|
|
114
|
-
outcome?: string;
|
|
115
|
-
/** The arm a fork took and why. */
|
|
116
|
-
branch?: {
|
|
117
|
-
decision: string;
|
|
118
|
-
reason: string;
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
/** One ledger line: a step's receipt and its span since the run opened. */
|
|
122
|
-
export interface SearchRunLedgerEntry {
|
|
123
|
-
receipt: SearchStageReceipt;
|
|
124
|
-
/** The nested workflows the step ran under, outermost first. */
|
|
125
|
-
workflowPath: string[];
|
|
126
|
-
startedAtMs: number;
|
|
127
|
-
endedAtMs: number;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Outcome receipts shared by full and card search responses. `degraded` and
|
|
131
|
-
* `emptyOutcome` are on every response; `termCoverage` and `explain` are
|
|
132
|
-
* explain-only.
|
|
133
|
-
*/
|
|
134
|
-
export interface SearchResponseExplainReceipts {
|
|
135
|
-
degraded?: SearchDegraded;
|
|
136
|
-
emptyOutcome?: SearchEmptyOutcome;
|
|
137
|
-
termCoverage?: SearchTermCoverageReceipt;
|
|
14
|
+
export type SearchMode = OpenEnum<"image" | "colour" | "lexical" | "agent" | "attribute">;
|
|
15
|
+
/** The explain-only receipt shared by full and card search responses. */
|
|
16
|
+
export type SearchResponseExplainReceipts = {
|
|
138
17
|
/**
|
|
139
|
-
* Present under `explain`
|
|
140
|
-
*
|
|
18
|
+
* Present under `explain` only: the receipt of the plan the one search ran
|
|
19
|
+
* on, with the plan itself (ADR 0031). Diagnostic, like `timings`.
|
|
141
20
|
*/
|
|
142
21
|
explain?: {
|
|
143
|
-
|
|
22
|
+
plan: SearchPlanReceipt;
|
|
144
23
|
};
|
|
145
|
-
}
|
|
146
|
-
/** One stage in the explain-only ledger of transformations that actually ran. */
|
|
147
|
-
export type SearchQueryTransformStage = {
|
|
148
|
-
stage: OpenEnum<"normalise" | "resolve-spec" | "resolve-paint" | "resolve-brand">;
|
|
149
|
-
applied: true;
|
|
150
|
-
} | {
|
|
151
|
-
stage: OpenEnum<"normalise" | "resolve-spec" | "resolve-paint" | "resolve-brand">;
|
|
152
|
-
applied: false;
|
|
153
|
-
reason: string;
|
|
154
24
|
};
|
|
155
|
-
/** Explain-only category gate selected by query understanding. */
|
|
156
|
-
export interface SearchCategoryAnchor {
|
|
157
|
-
/**
|
|
158
|
-
* A leaf type id; the group key when `source` is `"group"`; or the canonical
|
|
159
|
-
* category noun when `source` is `"head-noun"`. Gate on `productTypeIds`.
|
|
160
|
-
*/
|
|
161
|
-
productTypeId: string;
|
|
162
|
-
/**
|
|
163
|
-
* The leaf type ids a `"group"` or `"head-noun"` anchor expanded to; absent
|
|
164
|
-
* for leaf sources.
|
|
165
|
-
*/
|
|
166
|
-
productTypeIds?: readonly string[];
|
|
167
|
-
displayName: string;
|
|
168
|
-
similarity: number;
|
|
169
|
-
margin: number | null;
|
|
170
|
-
source: OpenEnum<"taxonomy" | "synonym" | "display-name" | "group" | "head-noun" | "vector">;
|
|
171
|
-
/** Hard category eligibility is applied inside lexical candidate selection. */
|
|
172
|
-
candidateSource?: OpenEnum<"lexical">;
|
|
173
|
-
applied: boolean;
|
|
174
|
-
}
|
|
175
|
-
/** Explain-only brand gate selected by query understanding. */
|
|
176
|
-
export interface SearchBrandAnchor {
|
|
177
|
-
brandSlug: string;
|
|
178
|
-
brandName: string;
|
|
179
|
-
confidence: number;
|
|
180
|
-
margin: number | null;
|
|
181
|
-
tier: OpenEnum<"exact_id" | "exact_alias" | "lexical" | "semantic">;
|
|
182
|
-
variantCount: number;
|
|
183
|
-
applied: boolean;
|
|
184
|
-
}
|
|
185
|
-
/** A real brand candidate the engine deliberately declined to gate on. */
|
|
186
|
-
export interface SearchBrandSkip {
|
|
187
|
-
reason: OpenEnum<"ambiguous" | "weak-tier" | "too-broad">;
|
|
188
|
-
candidates?: string[];
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* EXPLAIN-only receipt of the query shape that executed. This is distinct from
|
|
192
|
-
* the separate Search Plan compiler operation: it reports execution and never
|
|
193
|
-
* causes it.
|
|
194
|
-
*/
|
|
195
|
-
export interface SearchExecutionPlan {
|
|
196
|
-
grain: OpenEnum<"variant" | "product">;
|
|
197
|
-
/** Which 2048D Voyage projection served a text-mode request. */
|
|
198
|
-
textLane?: OpenEnum<"image-text" | "variant-text">;
|
|
199
|
-
weights: {
|
|
200
|
-
portrait: number;
|
|
201
|
-
image: number;
|
|
202
|
-
category: number;
|
|
203
|
-
colour: number;
|
|
204
|
-
lexical: number;
|
|
205
|
-
text: number;
|
|
206
|
-
};
|
|
207
|
-
queryTransform: SearchQueryTransformStage[];
|
|
208
|
-
/** Ordered, explain-only request-understanding execution trace. */
|
|
209
|
-
steps?: Array<{
|
|
210
|
-
key: string;
|
|
211
|
-
status: OpenEnum<"executed" | "skipped">;
|
|
212
|
-
reason: string;
|
|
213
|
-
durationMs: number;
|
|
214
|
-
}>;
|
|
215
|
-
categoryAnchor?: SearchCategoryAnchor;
|
|
216
|
-
brandAnchor?: SearchBrandAnchor;
|
|
217
|
-
brandSkipped?: SearchBrandSkip;
|
|
218
|
-
}
|
|
219
|
-
/** Why a compound colour constraint returned a full or short page. */
|
|
220
|
-
export interface CompoundColourAbundanceReceipt {
|
|
221
|
-
grain: OpenEnum<"variant" | "product">;
|
|
222
|
-
requested: number;
|
|
223
|
-
eligible: number;
|
|
224
|
-
candidateWindow: number;
|
|
225
|
-
sourceExhausted: boolean;
|
|
226
|
-
state: OpenEnum<"filled" | "corpus_scarcity" | "evidence_unavailable" | "retrieval_window_exhausted">;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Eligibility proof for an explicit or taxonomy-backed colour inside a compound
|
|
230
|
-
* text query. Counts describe the bounded candidate pool, not the whole corpus.
|
|
231
|
-
*/
|
|
232
|
-
export interface CompoundColourConstraintReceipt {
|
|
233
|
-
basis: OpenEnum<"explicit" | "detected-strong">;
|
|
234
|
-
family: string;
|
|
235
|
-
queryHexes: string[];
|
|
236
|
-
considered: number;
|
|
237
|
-
kept: number;
|
|
238
|
-
dropped: number;
|
|
239
|
-
unknown: number;
|
|
240
|
-
adjacent: number;
|
|
241
|
-
abundance?: CompoundColourAbundanceReceipt;
|
|
242
|
-
}
|
|
243
|
-
/** Why a hard form constraint returned a full or short page. */
|
|
244
|
-
export interface CompoundFormAbundanceReceipt {
|
|
245
|
-
grain: OpenEnum<"variant" | "product">;
|
|
246
|
-
requested: number;
|
|
247
|
-
eligible: number;
|
|
248
|
-
candidateWindow: number;
|
|
249
|
-
sourceExhausted: boolean;
|
|
250
|
-
state: OpenEnum<"filled" | "corpus_scarcity" | "evidence_unavailable" | "retrieval_window_exhausted">;
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Hard form eligibility for a compound text query. Product and variant names
|
|
254
|
-
* may retrieve a candidate but never prove that it satisfies the form.
|
|
255
|
-
*/
|
|
256
|
-
export interface CompoundFormConstraintReceipt {
|
|
257
|
-
instruction: OpenEnum<"subway" | "plank" | "square" | "hexagon" | "penny-round">;
|
|
258
|
-
considered: number;
|
|
259
|
-
kept: number;
|
|
260
|
-
dropped: number;
|
|
261
|
-
contradicted: number;
|
|
262
|
-
unknown: number;
|
|
263
|
-
abundance: CompoundFormAbundanceReceipt;
|
|
264
|
-
}
|