@instruments/materialgraph 0.17.0 → 0.19.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 +90 -4
- package/associations-client.d.ts +3 -1
- package/associations-client.js +4 -0
- package/browse-types.d.ts +14 -3
- package/by-colour-types.d.ts +24 -6
- package/by-spec-types.d.ts +4 -0
- package/catalogue-client.d.ts +14 -2
- package/catalogue-client.js +23 -0
- package/catalogue-types.d.ts +278 -4
- package/citation-types.d.ts +34 -0
- package/citation-types.js +1 -0
- package/client-browse.d.ts +1 -0
- package/client-browse.js +1 -0
- package/client-vocabulary.d.ts +10 -0
- package/client-vocabulary.js +32 -0
- package/client.d.ts +28 -62
- package/client.js +51 -75
- package/composition-types.d.ts +6 -0
- package/corpus-scope-types.d.ts +6 -4
- package/errors.d.ts +1 -1
- package/errors.js +2 -0
- package/index.d.ts +6 -0
- package/json-value-types.d.ts +8 -0
- package/json-value-types.js +1 -0
- package/match-types.d.ts +3 -0
- package/material-asset-types.d.ts +71 -0
- package/material-resources-client.d.ts +18 -0
- package/material-resources-client.js +29 -0
- package/material-types.d.ts +59 -0
- package/operations.d.ts +1 -1
- package/operations.js +62 -0
- package/package.json +1 -1
- package/palette-search-types.d.ts +16 -2
- package/query-understanding-types.d.ts +5 -2
- package/render-assets-types.d.ts +65 -0
- package/render-assets-types.js +1 -0
- package/run-events.d.ts +13 -0
- package/samplize-catalogue-types.d.ts +92 -0
- package/samplize-catalogue-types.js +1 -0
- package/schedule-reference-types.d.ts +46 -0
- package/schedule-reference-types.js +1 -0
- package/schedule-references-client.d.ts +14 -0
- package/schedule-references-client.js +26 -0
- package/schedule-types.d.ts +34 -0
- package/search-collapse-types.d.ts +1 -1
- package/search-mood-types.d.ts +6 -0
- package/search-mood-types.js +1 -0
- package/search-refinement-types.d.ts +5 -0
- package/search-request-types.d.ts +29 -11
- package/search-response-receipt-types.d.ts +59 -3
- package/search-result-validation.js +14 -1
- package/search-window-types.d.ts +13 -5
- package/slot-pool-types.d.ts +2 -0
- package/spec-types.d.ts +6 -1
- package/specifications.d.ts +3 -1
- package/specifications.js +4 -0
- package/substitute-types.d.ts +75 -0
- package/substitute-types.js +1 -0
- package/suggest-types.d.ts +6 -0
- package/suggest-types.js +1 -1
- package/taxonomy-coverage-types.d.ts +34 -0
- package/taxonomy-coverage-types.js +1 -0
- package/types.d.ts +20 -21
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** samplizeCatalogue admits published US Samplize paint colours, regardless of stock. */
|
|
1
2
|
/**
|
|
2
3
|
* @module search-request-types
|
|
3
4
|
* The two request shapes for the `/search` surface — the POST JSON body and the
|
|
@@ -32,8 +33,8 @@ export interface SearchInput {
|
|
|
32
33
|
};
|
|
33
34
|
mood?: string;
|
|
34
35
|
/**
|
|
35
|
-
* Re-order the final scored results. `relevance` (default) keeps the
|
|
36
|
-
* score; `light` / `dark` / `vivid` / `muted` / `colourful` are the colour
|
|
36
|
+
* Re-order the final scored results. `relevance` (default) keeps the selected
|
|
37
|
+
* mode's primary score; `light` / `dark` / `vivid` / `muted` / `colourful` are the colour
|
|
37
38
|
* ramps; `name` (A→Z), `name_desc` (Z→A) and `recent` (newest first) are the
|
|
38
39
|
* catalogue orders — the same three `/search/browse` walks the corpus in, so
|
|
39
40
|
* one word means one order on both lanes.
|
|
@@ -100,12 +101,18 @@ export interface SearchInput {
|
|
|
100
101
|
boost?: string;
|
|
101
102
|
filter?: string[];
|
|
102
103
|
};
|
|
104
|
+
/**
|
|
105
|
+
* Optional multipliers for the selected mode's one ordering signal. At most
|
|
106
|
+
* one is applied: image for image/image-text, lexical for lexical/browse, and
|
|
107
|
+
* colour for colour mode. Non-mode keys are accepted for compatibility but
|
|
108
|
+
* cannot activate secondary scoring.
|
|
109
|
+
*/
|
|
103
110
|
weights?: {
|
|
104
111
|
image?: number;
|
|
105
112
|
category?: number;
|
|
106
113
|
colour?: number;
|
|
107
114
|
lexical?: number;
|
|
108
|
-
/**
|
|
115
|
+
/** Compatibility field; seeded text does not activate secondary scoring. */
|
|
109
116
|
text?: number;
|
|
110
117
|
};
|
|
111
118
|
filters?: SearchFilter[];
|
|
@@ -120,6 +127,7 @@ export interface SearchInput {
|
|
|
120
127
|
/** The previous response's `cursor`, passed back verbatim. Never synthesise one. */
|
|
121
128
|
cursor?: Cursor;
|
|
122
129
|
explain?: boolean;
|
|
130
|
+
/** Public POST defaults to distinct products; send `"none"` for individual variants. */
|
|
123
131
|
collapse?: OpenEnum<"none" | "product">;
|
|
124
132
|
/**
|
|
125
133
|
* Opt-in feed total: EXACT up to 1,000, `lowerBound` beyond / for ANN pools.
|
|
@@ -141,6 +149,8 @@ export interface SearchInput {
|
|
|
141
149
|
refinementToken?: string;
|
|
142
150
|
/** Only return materials with at least one catalog image. Default false (full catalog). */
|
|
143
151
|
hasImages?: boolean;
|
|
152
|
+
/** Require a recorded accepted sampleable=true fact; unknown and false are excluded. */
|
|
153
|
+
sampleableOnly?: boolean;
|
|
144
154
|
/**
|
|
145
155
|
* Opt-in seed-relative verdict cells (MG-629). Only meaningful with
|
|
146
156
|
* `similarTo: { variantId }`: each hit's `verdict` gains `preferred` cells
|
|
@@ -156,7 +166,7 @@ export interface SearchInput {
|
|
|
156
166
|
* `"search"` (default) is the full engine. `"typeahead"` is the as-you-type
|
|
157
167
|
* profile: lexical-only with prefix match on the final token, forced
|
|
158
168
|
* `view: "card"`, `limit` capped at 24, and no mood/colour detection tiers,
|
|
159
|
-
* semantic fallback,
|
|
169
|
+
* semantic fallback, secondary scoring, refinement suggestions,
|
|
160
170
|
* counts, or meanings. `textModes` is ignored under typeahead.
|
|
161
171
|
*/
|
|
162
172
|
intent?: OpenEnum<"search" | "typeahead">;
|
|
@@ -166,22 +176,26 @@ export interface SearchInput {
|
|
|
166
176
|
* **ABSENT means the WHOLE GRAPH** — every material MaterialGraph knows,
|
|
167
177
|
* orderable or not. Absence is never a narrower default, so a caller that
|
|
168
178
|
* says nothing gets materials it may not be able to buy.
|
|
169
|
-
* Three scopes gate on CHANNEL membership
|
|
170
|
-
*
|
|
179
|
+
* Three transaction-oriented scopes gate on governed CHANNEL membership:
|
|
180
|
+
* `"materialBankNaOrderable"` (Material Bank North America,
|
|
171
181
|
* ~277,000 materials), `"materialBankEuOrderable"` (Material Bank Europe,
|
|
172
182
|
* ~65,000) and `"designShopOrderable"` (DesignShop, ~34,000, with the
|
|
173
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.
|
|
174
188
|
*
|
|
175
189
|
* `"materialBankOrderable"` is NOT one of them, despite the name. It selects
|
|
176
190
|
* materials carrying a Material Bank identity — a PROVENANCE signal, not a
|
|
177
191
|
* storefront — and admits about 98% of the graph. Use it to exclude the
|
|
178
192
|
* crawl-sourced brands that were never in the Material Bank feed; if you mean
|
|
179
|
-
* orderable, use one of the
|
|
193
|
+
* orderable, use one of the channel-backed scopes above.
|
|
180
194
|
*
|
|
181
|
-
* A scope answers
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
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.
|
|
185
199
|
*
|
|
186
200
|
* The scope is applied INSIDE the query: `limit` fills with eligible rows,
|
|
187
201
|
* `counts` describe the SCOPED corpus, and the response echoes the scope.
|
|
@@ -203,6 +217,8 @@ export interface SearchGetParams {
|
|
|
203
217
|
colours?: string;
|
|
204
218
|
logic?: OpenEnum<"all" | "any">;
|
|
205
219
|
mood?: string;
|
|
220
|
+
/** Governed corpus applied inside retrieval; absent means the whole graph. */
|
|
221
|
+
corpusScope?: CorpusScope;
|
|
206
222
|
sort?: OpenEnum<"relevance" | "light" | "dark" | "vivid" | "muted" | "colourful" | "name" | "name_desc" | "recent">;
|
|
207
223
|
tol?: OpenEnum<"tight" | "normal" | "loose">;
|
|
208
224
|
/** Seed the search from this variant's image. Opaque — pass it through verbatim. */
|
|
@@ -214,6 +230,8 @@ export interface SearchGetParams {
|
|
|
214
230
|
count?: OpenEnum<"true">;
|
|
215
231
|
/** "true" — only return materials with at least one catalog image. */
|
|
216
232
|
hasImages?: OpenEnum<"true">;
|
|
233
|
+
/** Require a recorded accepted sampleable=true fact. */
|
|
234
|
+
sampleableOnly?: OpenEnum<"true" | "false">;
|
|
217
235
|
/** Result projection — `"full"` (default) or the lean `"card"` grid form. */
|
|
218
236
|
view?: OpenEnum<"full" | "card">;
|
|
219
237
|
/**
|
|
@@ -1,17 +1,63 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module sdk/search-response-receipt-types
|
|
3
|
-
* @description Inspectable routing,
|
|
4
|
-
* emitted by ordinary Search responses.
|
|
3
|
+
* @description Inspectable routing, compatibility, and compound-constraint
|
|
4
|
+
* receipts emitted by ordinary Search responses.
|
|
5
5
|
*/
|
|
6
6
|
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
|
+
}
|
|
7
15
|
/** The primary ranking source a query resolved to and reports as its mode. */
|
|
8
16
|
export type SearchMode = OpenEnum<"image" | "colour" | "text" | "lexical" | "entity-browse">;
|
|
9
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Compatibility receipt for non-mode colour handling. Current one-signal
|
|
19
|
+
* ordering reports it skipped at weight 0; colour may still be diagnostic or a
|
|
20
|
+
* hard displayed-image constraint, but does not blend into score.
|
|
21
|
+
*/
|
|
10
22
|
export interface SearchRerankReport {
|
|
11
23
|
colour?: OpenEnum<"ok" | "failed" | "skipped">;
|
|
12
24
|
colourWeight?: number;
|
|
13
25
|
colourLabel?: string;
|
|
14
26
|
}
|
|
27
|
+
/** Stage counts retained when an explain-enabled search returns no results. */
|
|
28
|
+
export interface SearchEmptyOutcomeCounts {
|
|
29
|
+
retrieved: number;
|
|
30
|
+
afterPrune: number;
|
|
31
|
+
final: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Explain-only evidence for why a completed search returned no results.
|
|
35
|
+
* `proven-corpus-empty` is exhaustive; every other empty remains explicitly
|
|
36
|
+
* unproven rather than being presented as catalogue absence.
|
|
37
|
+
*/
|
|
38
|
+
export type SearchEmptyOutcome = {
|
|
39
|
+
kind: "proven-corpus-empty";
|
|
40
|
+
basis: OpenEnum<"spec-allowlist" | "brand-scope">;
|
|
41
|
+
exhaustive: true;
|
|
42
|
+
sourceEmpty?: boolean | null;
|
|
43
|
+
counts?: SearchEmptyOutcomeCounts;
|
|
44
|
+
} | {
|
|
45
|
+
kind: "unproven-empty";
|
|
46
|
+
reason: OpenEnum<"allowlist-truncated" | "retrieval-window-not-exhaustive" | "source-empty" | "post-retrieval-rejected" | "pagination-empty" | "no-authoritative-empty-proof">;
|
|
47
|
+
sourceEmpty?: boolean | null;
|
|
48
|
+
counts?: SearchEmptyOutcomeCounts;
|
|
49
|
+
};
|
|
50
|
+
/** Explain-only coverage of substantive query terms in the lexical projection. */
|
|
51
|
+
export interface SearchTermCoverageReceipt {
|
|
52
|
+
status: OpenEnum<"covered" | "uncovered" | "unavailable" | "skipped">;
|
|
53
|
+
terms: string[];
|
|
54
|
+
note?: string;
|
|
55
|
+
}
|
|
56
|
+
/** Explain-only outcome receipts shared by full and card search responses. */
|
|
57
|
+
export interface SearchResponseExplainReceipts {
|
|
58
|
+
emptyOutcome?: SearchEmptyOutcome;
|
|
59
|
+
termCoverage?: SearchTermCoverageReceipt;
|
|
60
|
+
}
|
|
15
61
|
/** One stage in the explain-only ledger of transformations that actually ran. */
|
|
16
62
|
export type SearchQueryTransformStage = {
|
|
17
63
|
stage: OpenEnum<"normalise" | "resolve-spec" | "resolve-paint" | "resolve-brand">;
|
|
@@ -63,7 +109,10 @@ export interface SearchBrandSkip {
|
|
|
63
109
|
*/
|
|
64
110
|
export interface SearchExecutionPlan {
|
|
65
111
|
grain: OpenEnum<"variant" | "product">;
|
|
112
|
+
/** Which 2048D Voyage projection served a text-mode request. */
|
|
113
|
+
textLane?: OpenEnum<"image-text" | "variant-text">;
|
|
66
114
|
weights: {
|
|
115
|
+
portrait: number;
|
|
67
116
|
image: number;
|
|
68
117
|
category: number;
|
|
69
118
|
colour: number;
|
|
@@ -71,6 +120,13 @@ export interface SearchExecutionPlan {
|
|
|
71
120
|
text: number;
|
|
72
121
|
};
|
|
73
122
|
queryTransform: SearchQueryTransformStage[];
|
|
123
|
+
/** Ordered, explain-only request-understanding execution trace. */
|
|
124
|
+
steps?: Array<{
|
|
125
|
+
key: string;
|
|
126
|
+
status: OpenEnum<"executed" | "skipped">;
|
|
127
|
+
reason: string;
|
|
128
|
+
durationMs: number;
|
|
129
|
+
}>;
|
|
74
130
|
categoryAnchor?: SearchCategoryAnchor;
|
|
75
131
|
brandAnchor?: SearchBrandAnchor;
|
|
76
132
|
brandSkipped?: SearchBrandSkip;
|
|
@@ -73,9 +73,12 @@ function checkColourMeta(value, what, fail) {
|
|
|
73
73
|
requireOptionalString(record.dominantFamily, `${what}.dominantFamily`, fail);
|
|
74
74
|
requireOptionalString(record.dominantHex, `${what}.dominantHex`, fail);
|
|
75
75
|
}
|
|
76
|
-
/** `searchResultSignalsSchema` — five
|
|
76
|
+
/** `searchResultSignalsSchema` — five required scores plus additive portrait. */
|
|
77
77
|
function checkSignals(value, what, fail) {
|
|
78
78
|
const record = requireRecord(value, what, fail);
|
|
79
|
+
if (record.portrait !== undefined) {
|
|
80
|
+
requireNullableNumber(record.portrait, `${what}.portrait`, fail);
|
|
81
|
+
}
|
|
79
82
|
for (const signal of ["image", "category", "colour", "lexical", "text"]) {
|
|
80
83
|
requireNullableNumber(record[signal], `${what}.${signal}`, fail);
|
|
81
84
|
}
|
|
@@ -140,6 +143,15 @@ function checkAttributeVerdict(value, what, fail) {
|
|
|
140
143
|
requireNullableString(record.value, `${what}.value`, fail);
|
|
141
144
|
requireNullableBoundedNumber(record.confidence, `${what}.confidence`, fail, 0, 1);
|
|
142
145
|
requireNullableString(record.sourceBasis, `${what}.sourceBasis`, fail);
|
|
146
|
+
if (record.citation !== undefined) {
|
|
147
|
+
const citation = requireRecord(record.citation, `${what}.citation`, fail);
|
|
148
|
+
requireNonEmptyString(citation.citationId, `${what}.citation.citationId`, fail);
|
|
149
|
+
requireNonEmptyString(citation.sourceType, `${what}.citation.sourceType`, fail);
|
|
150
|
+
const count = requireNumber(citation.count, `${what}.citation.count`, fail);
|
|
151
|
+
if (!Number.isInteger(count) || count <= 0) {
|
|
152
|
+
throw fail(`${what}.citation.count must be a positive integer`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
143
155
|
const deviation = record.deviation;
|
|
144
156
|
if (deviation !== null)
|
|
145
157
|
checkVerdictDeviation(deviation, `${what}.deviation`, fail);
|
|
@@ -204,6 +216,7 @@ export function checkSearchResultItem(value, what, fail) {
|
|
|
204
216
|
if (record.signals !== undefined)
|
|
205
217
|
checkSignals(record.signals, `${what}.signals`, fail);
|
|
206
218
|
requireOptionalBoolean(record.retired, `${what}.retired`, fail);
|
|
219
|
+
requireOptionalBoolean(record.sampleable, `${what}.sampleable`, fail);
|
|
207
220
|
requireOptionalBoolean(record.belowFloor, `${what}.belowFloor`, fail);
|
|
208
221
|
requireOptionalBoolean(record.admittedOnColour, `${what}.admittedOnColour`, fail);
|
|
209
222
|
if (record.siblingCount !== undefined) {
|
package/search-window-types.d.ts
CHANGED
|
@@ -4,14 +4,22 @@ export interface SearchWindowReceipt {
|
|
|
4
4
|
profile: "interactive-r1" | (string & {});
|
|
5
5
|
/** Candidate depth used by the final retrieval. */
|
|
6
6
|
candidateTier: number;
|
|
7
|
-
/**
|
|
7
|
+
/** Candidate retrieval count; `searchMaterials` reports exactly one selected retrieval. */
|
|
8
8
|
retrievalRounds: number;
|
|
9
9
|
/** Candidate-retrieval wall time only, in milliseconds. */
|
|
10
10
|
retrievalMs: number;
|
|
11
11
|
/** True when the serving source proved there were no more candidates. */
|
|
12
12
|
exhaustive: boolean;
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Candidate attrition through the selected retrieval source. Absent when the
|
|
15
|
+
* response path did not perform ordinary retrieval (for example typeahead).
|
|
16
|
+
*/
|
|
17
|
+
candidateCounts?: {
|
|
18
|
+
/** Provider-returned matches before bounded selection; null for SQL/exact arms. */
|
|
19
|
+
rawProviderMatches: number | null;
|
|
20
|
+
/** Matches selected from that provider response; null for SQL/exact arms. */
|
|
21
|
+
selectedMatches: number | null;
|
|
22
|
+
/** Canonical candidates returned by the selected retrieval arm. */
|
|
23
|
+
hydratedCanonicalCandidates: number;
|
|
24
|
+
};
|
|
17
25
|
}
|
package/slot-pool-types.d.ts
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
* TOLERANT-PARSING CONTRACT: response enums are widened with {@link OpenEnum}
|
|
26
26
|
* so a new server value still type-checks; objects are read structurally.
|
|
27
27
|
*/
|
|
28
|
+
import type { VerdictCitation } from "./citation-types.js";
|
|
28
29
|
import type { VariantId } from "./identifiers.js";
|
|
29
30
|
import type { OpenEnum } from "./types.js";
|
|
30
31
|
/**
|
|
@@ -147,6 +148,7 @@ export interface SlotPoolVerdictCell {
|
|
|
147
148
|
*/
|
|
148
149
|
sourceBasis: string | null;
|
|
149
150
|
trustGap: OpenEnum<"below_confidence" | "basis_unmet" | "proposed"> | null;
|
|
151
|
+
citation?: VerdictCitation;
|
|
150
152
|
}
|
|
151
153
|
/** Why a candidate is labelled. An eligible candidate carries none of these. */
|
|
152
154
|
export type SlotPoolFlag = OpenEnum<"below-floor" | "required-not-applied" | "discontinued" | "superseded" | "unverified-value">;
|
package/spec-types.d.ts
CHANGED
|
@@ -64,6 +64,11 @@ export interface SpecTermFilter {
|
|
|
64
64
|
attributeId: string;
|
|
65
65
|
term: string;
|
|
66
66
|
}
|
|
67
|
+
/** A negative spec criterion; absence of a value remains unproven. */
|
|
68
|
+
export interface SpecExclusionFilter {
|
|
69
|
+
attributeId: string;
|
|
70
|
+
excludesTerm: string;
|
|
71
|
+
}
|
|
67
72
|
/**
|
|
68
73
|
* A presence spec criterion: the attribute must have ANY accepted value —
|
|
69
74
|
* "has an EPD on record", "has a measured slip figure at all". Not supported for
|
|
@@ -94,4 +99,4 @@ export interface CertificationProgrammeFilter {
|
|
|
94
99
|
* presence check. The union the search engine applies as a restriction BEFORE
|
|
95
100
|
* ranking. Identical in shape to the SDK's `SearchFilter`.
|
|
96
101
|
*/
|
|
97
|
-
export type SpecFilter = SpecTermFilter | SpecPresenceFilter;
|
|
102
|
+
export type SpecFilter = SpecTermFilter | SpecExclusionFilter | SpecPresenceFilter;
|
package/specifications.d.ts
CHANGED
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
* hand-format the `attribute:value` string the `bySpec` route splits on its
|
|
15
15
|
* first `:`.
|
|
16
16
|
*/
|
|
17
|
-
import { type CertificationProgrammeFilter, type SpecPresenceFilter, type SpecTermFilter } from "./spec-types.js";
|
|
17
|
+
import { type CertificationProgrammeFilter, type SpecExclusionFilter, type SpecPresenceFilter, type SpecTermFilter } from "./spec-types.js";
|
|
18
|
+
/** A hard criterion excluding one known canonical value while retaining only variants with known values. */
|
|
19
|
+
export declare function excludeSpec(attributeId: string, excludesTerm: string): SpecExclusionFilter;
|
|
18
20
|
/**
|
|
19
21
|
* A term-equality criterion for `search({ filters })` — the attribute must
|
|
20
22
|
* carry this canonical value.
|
package/specifications.js
CHANGED
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
* first `:`.
|
|
16
16
|
*/
|
|
17
17
|
import { CERTIFICATION_PROGRAMME_ATTRIBUTE_ID, } from "./spec-types.js";
|
|
18
|
+
/** A hard criterion excluding one known canonical value while retaining only variants with known values. */
|
|
19
|
+
export function excludeSpec(attributeId, excludesTerm) {
|
|
20
|
+
return { attributeId, excludesTerm };
|
|
21
|
+
}
|
|
18
22
|
/**
|
|
19
23
|
* A term-equality criterion for `search({ filters })` — the attribute must
|
|
20
24
|
* carry this canonical value.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { BySpecVerdict } from "./by-spec-types.js";
|
|
2
|
+
import type { VariantId } from "./identifiers.js";
|
|
3
|
+
import type { MaterialSuccessor } from "./material-types.js";
|
|
4
|
+
export type SubstituteSignatureFamily = "textile" | "tile" | "coating" | "lighting_electrical" | "acoustic" | "surface" | "furniture" | "sanitaryware" | "fittings" | "architectural_hardware";
|
|
5
|
+
export interface SubstituteSignatureCriterion {
|
|
6
|
+
role: "primary_material" | "performance";
|
|
7
|
+
attributeId: string;
|
|
8
|
+
term: string;
|
|
9
|
+
}
|
|
10
|
+
export interface AvailableSubstituteSignature {
|
|
11
|
+
family: SubstituteSignatureFamily;
|
|
12
|
+
form: string;
|
|
13
|
+
criteria: [SubstituteSignatureCriterion, SubstituteSignatureCriterion];
|
|
14
|
+
}
|
|
15
|
+
export interface UnsupportedSubstituteSignature {
|
|
16
|
+
family: SubstituteSignatureFamily;
|
|
17
|
+
form: string;
|
|
18
|
+
reason: string;
|
|
19
|
+
}
|
|
20
|
+
export interface InsufficientSubstituteSignature {
|
|
21
|
+
family: SubstituteSignatureFamily;
|
|
22
|
+
form: string;
|
|
23
|
+
missingRoles: ("primary_material" | "performance")[];
|
|
24
|
+
}
|
|
25
|
+
export interface FindSubstitutesOptions {
|
|
26
|
+
excludeBrands?: string[];
|
|
27
|
+
diversityBoost?: number;
|
|
28
|
+
limit?: number;
|
|
29
|
+
cursor?: string;
|
|
30
|
+
includeSamplingArtifacts?: boolean;
|
|
31
|
+
includeUnavailable?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface SubstituteMatchedCriterion {
|
|
34
|
+
attributeId: string;
|
|
35
|
+
confidence: number | null;
|
|
36
|
+
sourceBasis: string | null;
|
|
37
|
+
}
|
|
38
|
+
export interface SubstituteResultItem {
|
|
39
|
+
variantId: VariantId;
|
|
40
|
+
brandSlug: string;
|
|
41
|
+
brand: string;
|
|
42
|
+
product: string;
|
|
43
|
+
variant: string;
|
|
44
|
+
color: string | null;
|
|
45
|
+
imageUrl: string | null;
|
|
46
|
+
hex: string | null;
|
|
47
|
+
matched: SubstituteMatchedCriterion[];
|
|
48
|
+
minConfidence: number | null;
|
|
49
|
+
baseScore: number;
|
|
50
|
+
diversityAdjustment: number;
|
|
51
|
+
score: number;
|
|
52
|
+
verdict: BySpecVerdict;
|
|
53
|
+
}
|
|
54
|
+
export interface AvailableSubstitutesResponse {
|
|
55
|
+
status: "available";
|
|
56
|
+
signatureUsed: AvailableSubstituteSignature;
|
|
57
|
+
items: SubstituteResultItem[];
|
|
58
|
+
candidatePoolSize: number;
|
|
59
|
+
droppedUnavailable: number;
|
|
60
|
+
supersededBy: MaterialSuccessor | null;
|
|
61
|
+
nextCursor?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface UnsupportedSubstitutesResponse {
|
|
64
|
+
status: "unsupported";
|
|
65
|
+
signature: UnsupportedSubstituteSignature;
|
|
66
|
+
items: [];
|
|
67
|
+
supersededBy: MaterialSuccessor | null;
|
|
68
|
+
}
|
|
69
|
+
export interface InsufficientSubstitutesResponse {
|
|
70
|
+
status: "insufficient_signature";
|
|
71
|
+
signature: InsufficientSubstituteSignature;
|
|
72
|
+
items: [];
|
|
73
|
+
supersededBy: MaterialSuccessor | null;
|
|
74
|
+
}
|
|
75
|
+
export type FindSubstitutesResponse = AvailableSubstitutesResponse | UnsupportedSubstitutesResponse | InsufficientSubstitutesResponse;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/suggest-types.d.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* `mg.searchVocabulary()` covers attribute/value tokens. Suggestions are a page
|
|
13
13
|
* of the best matches, never a census of matching entities.
|
|
14
14
|
*/
|
|
15
|
+
import type { CorpusScope, CorpusScopeReceipt } from "./corpus-scope-types.js";
|
|
15
16
|
/** Which kind of entity a suggestion is — and therefore what `refId` means. */
|
|
16
17
|
export type SuggestKind = "product" | "brand" | "category";
|
|
17
18
|
/** How the query met the suggestion's label. Strongest first. */
|
|
@@ -44,6 +45,8 @@ export interface SuggestResponse {
|
|
|
44
45
|
query: string;
|
|
45
46
|
/** Ranked best-match-first. Empty when nothing came close — a miss, not an error. */
|
|
46
47
|
suggestions: Suggestion[];
|
|
48
|
+
/** Present only when a narrowing governed corpus was applied. */
|
|
49
|
+
corpusScope?: CorpusScopeReceipt;
|
|
47
50
|
}
|
|
48
51
|
/** Options for {@link MaterialGraphClient.suggest}. */
|
|
49
52
|
export interface SuggestOptions {
|
|
@@ -51,6 +54,8 @@ export interface SuggestOptions {
|
|
|
51
54
|
limit?: number;
|
|
52
55
|
/** Restrict to these kinds. Omit for all of them. */
|
|
53
56
|
kind?: SuggestKind | SuggestKind[];
|
|
57
|
+
/** Governed corpus membership; absent means the whole graph. */
|
|
58
|
+
corpusScope?: CorpusScope;
|
|
54
59
|
}
|
|
55
60
|
/**
|
|
56
61
|
* Shape the query string for a suggest call.
|
|
@@ -64,4 +69,5 @@ export declare function suggestQuery(q: string, options?: SuggestOptions): {
|
|
|
64
69
|
q: string;
|
|
65
70
|
limit?: number;
|
|
66
71
|
kind?: string;
|
|
72
|
+
corpusScope?: CorpusScope;
|
|
67
73
|
};
|
package/suggest-types.js
CHANGED
|
@@ -24,5 +24,5 @@ export function suggestQuery(q, options) {
|
|
|
24
24
|
const kind = Array.isArray(options?.kind)
|
|
25
25
|
? options.kind.join(",")
|
|
26
26
|
: options?.kind;
|
|
27
|
-
return { q, limit: options?.limit, kind };
|
|
27
|
+
return { q, limit: options?.limit, kind, corpusScope: options?.corpusScope };
|
|
28
28
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Exact, source-path-grained status coverage for primary product typing. */
|
|
2
|
+
export interface ProductTypeStatusCoverageCounts {
|
|
3
|
+
variants: number;
|
|
4
|
+
accepted: number;
|
|
5
|
+
proposed: number;
|
|
6
|
+
proposedBelowThreshold: number;
|
|
7
|
+
/** Proposed rows with no confidence remain explicit rather than thresholded. */
|
|
8
|
+
proposedUnknownConfidence: number;
|
|
9
|
+
otherStatus: number;
|
|
10
|
+
missingPrimary: number;
|
|
11
|
+
}
|
|
12
|
+
export interface ProductTypeStatusCoverageSourcePath extends ProductTypeStatusCoverageCounts {
|
|
13
|
+
/** Complete stored source path; null means the product retained no path. */
|
|
14
|
+
sourcePath: string | null;
|
|
15
|
+
}
|
|
16
|
+
/** Current primary-assignment coverage, never an inferred acceptance decision. */
|
|
17
|
+
export interface ProductTypeStatusCoverage {
|
|
18
|
+
computedAt: string;
|
|
19
|
+
basis: {
|
|
20
|
+
count: "exact";
|
|
21
|
+
universe: "non_superseded_variants";
|
|
22
|
+
assignment: "variant_primary_only";
|
|
23
|
+
sourcePath: "products.source_category_path";
|
|
24
|
+
/** Reporting cutoff only: higher-confidence proposals remain proposed. */
|
|
25
|
+
comparisonThreshold: number;
|
|
26
|
+
};
|
|
27
|
+
totals: ProductTypeStatusCoverageCounts;
|
|
28
|
+
sourcePaths: ProductTypeStatusCoverageSourcePath[];
|
|
29
|
+
}
|
|
30
|
+
export interface ProductTypeCoverageOptions {
|
|
31
|
+
[key: string]: number | undefined;
|
|
32
|
+
/** Reporting cutoff in [0,1], default 0.85; it never accepts a proposal. */
|
|
33
|
+
comparisonThreshold?: number;
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/types.d.ts
CHANGED
|
@@ -32,18 +32,12 @@ import type { MaterialDetail, MaterialTile } from "./material-types.js";
|
|
|
32
32
|
import type { QueryUnderstanding } from "./query-understanding-types.js";
|
|
33
33
|
import type { CollapsedVariant, SearchAnatomyMember } from "./search-collapse-types.js";
|
|
34
34
|
import type { SearchDisambiguation, SearchSuggestion } from "./search-refinement-types.js";
|
|
35
|
-
import type { CompoundColourConstraintReceipt, CompoundFormConstraintReceipt, SearchExecutionPlan, SearchMode, SearchRerankReport } from "./search-response-receipt-types.js";
|
|
35
|
+
import type { CompoundColourConstraintReceipt, CompoundFormConstraintReceipt, SearchExecutionPlan, SearchMode, SearchRefinementReceipt, SearchRerankReport, SearchResponseExplainReceipts } from "./search-response-receipt-types.js";
|
|
36
36
|
import type { SearchWindowReceipt } from "./search-window-types.js";
|
|
37
37
|
export type * from "./search-response-receipt-types.js";
|
|
38
|
+
export type { MoodInterpretation } from "./search-mood-types.js";
|
|
38
39
|
export type OpenEnum<T extends string> = T | (string & {});
|
|
39
|
-
|
|
40
|
-
* A JSON value, recursively — exactly what survives a `jsonb` round-trip
|
|
41
|
-
* unchanged. Used where a payload's SHAPE belongs to its producer but its values
|
|
42
|
-
* must still be JSON: `Date`, `bigint`, `undefined`, and functions are not.
|
|
43
|
-
*/
|
|
44
|
-
export type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
45
|
-
[key: string]: JsonValue;
|
|
46
|
-
};
|
|
40
|
+
export type { JsonValue } from "./json-value-types.js";
|
|
47
41
|
/**
|
|
48
42
|
* One palette swatch of a material's main image — colour DERIVED FROM PRODUCT
|
|
49
43
|
* IMAGERY, so read it as visual likeness, never as a declared colour spec.
|
|
@@ -90,11 +84,13 @@ export type ImageSource = OpenEnum<"r2" | "origin">;
|
|
|
90
84
|
export type { DimensionEntry, MaterialAvailability, MaterialDetail, MaterialFacet, MaterialSuccessor, MaterialTile, } from "./material-types.js";
|
|
91
85
|
/** Per-signal scores, present on a result when `explain` was requested. */
|
|
92
86
|
export interface SearchResultSignals {
|
|
87
|
+
/** Voyage similarity in the dedicated variant text-portrait space. */
|
|
88
|
+
portrait?: number | null;
|
|
93
89
|
image: number | null;
|
|
94
90
|
category: number | null;
|
|
95
91
|
colour: number | null;
|
|
96
92
|
lexical: number | null;
|
|
97
|
-
/**
|
|
93
|
+
/** Compatibility slot for retired seeded secondary scoring; currently null. */
|
|
98
94
|
text: number | null;
|
|
99
95
|
}
|
|
100
96
|
/** An accepted/measured visual meaning — descriptive evidence, never a ranking cause. */
|
|
@@ -118,6 +114,8 @@ export interface VisualMeaning {
|
|
|
118
114
|
* `visualMeanings` is not "this material has no visual meaning".
|
|
119
115
|
*/
|
|
120
116
|
export interface SearchResultItem {
|
|
117
|
+
/** Accepted sampleability fact. Absent means unknown, never false. */
|
|
118
|
+
sampleable?: boolean;
|
|
121
119
|
/** Opaque — round-trip verbatim into `material()`, `pairings()`, `similarTo`. */
|
|
122
120
|
variantId: VariantId;
|
|
123
121
|
brand: string;
|
|
@@ -132,7 +130,7 @@ export interface SearchResultItem {
|
|
|
132
130
|
* Populated on EVERY lane: `search()` (all four arms), `match()`, and
|
|
133
131
|
* `matchStream()` frames.
|
|
134
132
|
* ABSENT means no MB identity is known for the variant — never that the SKU
|
|
135
|
-
* cannot be ordered. Presence
|
|
133
|
+
* cannot be ordered. Presence identifies the source; it does not establish sampleability.
|
|
136
134
|
*/
|
|
137
135
|
materialBankId?: string;
|
|
138
136
|
manufacturerCode?: string;
|
|
@@ -190,7 +188,7 @@ export interface SearchResultItem {
|
|
|
190
188
|
siblings?: SearchAnatomyMember[];
|
|
191
189
|
siblingsTruncated?: boolean;
|
|
192
190
|
};
|
|
193
|
-
/**
|
|
191
|
+
/** Selected mode's weighted primary score; see `maxScore`. */
|
|
194
192
|
score: number;
|
|
195
193
|
/**
|
|
196
194
|
* Match only. How close this material is to the query, as an ABSOLUTE
|
|
@@ -274,6 +272,8 @@ export interface SearchResultItem {
|
|
|
274
272
|
* card does not carry.
|
|
275
273
|
*/
|
|
276
274
|
export interface SearchCardItem {
|
|
275
|
+
/** Accepted sampleability fact. Absent means unknown, never false. */
|
|
276
|
+
sampleable?: boolean;
|
|
277
277
|
/** Opaque — round-trip verbatim. */
|
|
278
278
|
variantId: VariantId;
|
|
279
279
|
productId: ProductId | null;
|
|
@@ -378,14 +378,6 @@ export interface SearchFacets {
|
|
|
378
378
|
absent: SearchAbsentFacet[];
|
|
379
379
|
counts: Record<string, SearchFacetCount>;
|
|
380
380
|
}
|
|
381
|
-
/** Inspectable metadata for an opaque, principal-bound search refinement receipt. */
|
|
382
|
-
export interface SearchRefinementReceipt {
|
|
383
|
-
token: string;
|
|
384
|
-
expiresAt: string;
|
|
385
|
-
poolSize: number;
|
|
386
|
-
schemaVersion: string;
|
|
387
|
-
projectionVersion: number;
|
|
388
|
-
}
|
|
389
381
|
/**
|
|
390
382
|
* The search response envelope. `view` discriminates the `results` union:
|
|
391
383
|
* `"full"` (default) carries {@link SearchResultItem}s, `"card"` the lean
|
|
@@ -398,7 +390,7 @@ export interface SearchRefinementReceipt {
|
|
|
398
390
|
* you asked for it. Follow `cursor` for the rest. "I found 24 materials" is
|
|
399
391
|
* wrong whenever `limit` was 24.
|
|
400
392
|
*/
|
|
401
|
-
export interface SearchResponse {
|
|
393
|
+
export interface SearchResponse extends SearchResponseExplainReceipts {
|
|
402
394
|
view: OpenEnum<"full" | "card">;
|
|
403
395
|
/** THIS PAGE. Its length is a page size, never a total. */
|
|
404
396
|
results: SearchResultItem[];
|
|
@@ -436,6 +428,11 @@ export interface SearchResponse {
|
|
|
436
428
|
timings?: Record<string, number>;
|
|
437
429
|
/** A detected mood term overridden by a stronger colour reading. */
|
|
438
430
|
supersededMoodId?: string;
|
|
431
|
+
/**
|
|
432
|
+
* Explicit standard-search mood reading; null ids mean no selected mood.
|
|
433
|
+
* Absent when mood was not evaluated or an older server produced the result.
|
|
434
|
+
*/
|
|
435
|
+
moodInterpretation?: import("./search-mood-types.js").MoodInterpretation;
|
|
439
436
|
/**
|
|
440
437
|
* Present when the query had multiple defensible readings. Says which one
|
|
441
438
|
* ran, or leaves every reading non-default when the engine chose none. Every
|
|
@@ -711,6 +708,8 @@ export interface PairingsOptions {
|
|
|
711
708
|
categories?: string;
|
|
712
709
|
/** Page size, 1–24 inclusive (default 12). The server rejects (400), not clamps, values outside this range. */
|
|
713
710
|
limit?: number;
|
|
711
|
+
/** Return sampled order evidence only, without board or colour fallback. */
|
|
712
|
+
sampledOnly?: boolean;
|
|
714
713
|
/** Graph-owned order applied within fixed cospec → considered → colour tiers. */
|
|
715
714
|
order?: PairingOrderMode;
|
|
716
715
|
/** Optional Material Bank/orderable gate; requires an explicit `order`. */
|