@instruments/materialgraph 0.25.0 → 0.26.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 +20 -20
- package/associations-client.d.ts +4 -4
- package/associations-client.js +3 -10
- package/attribution-types.d.ts +3 -3
- package/brand-most-sampled-types.d.ts +4 -4
- package/brand-types.d.ts +6 -6
- package/brands-client.d.ts +4 -4
- package/brands-client.js +9 -13
- package/browse-types.d.ts +8 -8
- package/by-colour-types.d.ts +18 -18
- package/by-spec-types.d.ts +14 -14
- package/catalog-discovery-types.d.ts +14 -14
- package/catalogue-client.d.ts +4 -4
- package/catalogue-client.js +38 -37
- package/catalogue-types.d.ts +4 -4
- package/citation-types.d.ts +4 -4
- package/client-browse.d.ts +4 -4
- package/client-browse.js +24 -25
- package/client-config.d.ts +2 -2
- package/client-exploration.d.ts +3 -3
- package/client-exploration.js +4 -6
- package/client-source-material-comments.d.ts +4 -4
- package/client-source-material-comments.js +4 -38
- package/client-vocabulary.d.ts +8 -8
- package/client-vocabulary.js +20 -30
- package/client.d.ts +11 -45
- package/client.js +143 -188
- package/codes-client.d.ts +2 -2
- package/codes-client.js +8 -8
- package/codes-types.d.ts +34 -34
- package/colour-aggregate-types.d.ts +24 -24
- package/colours-client.d.ts +2 -2
- package/colours-client.js +15 -15
- package/compare-types.d.ts +10 -10
- package/composition-client.d.ts +3 -3
- package/composition-client.js +8 -7
- package/composition-types.d.ts +12 -12
- 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/correction-types.d.ts +10 -10
- package/demand-batch-types.d.ts +18 -18
- package/demand-types.d.ts +24 -24
- package/errors.d.ts +12 -12
- package/errors.js +53 -52
- package/exploration-types.d.ts +22 -22
- package/fan-deck-types.d.ts +6 -6
- package/http-transport.d.ts +13 -21
- package/http-transport.js +31 -28
- package/identify-types.d.ts +10 -10
- package/index.d.ts +0 -6
- package/index.js +0 -2
- package/match-rejection-types.d.ts +6 -6
- package/match-stream-types.d.ts +32 -32
- package/match-stream.d.ts +2 -2
- package/match-stream.js +55 -41
- package/match-types.d.ts +8 -8
- package/material-asset-types.d.ts +26 -26
- package/material-block-types.d.ts +6 -6
- package/material-query-plan-types.d.ts +26 -26
- package/material-resources-client.d.ts +5 -5
- package/material-resources-client.js +10 -20
- package/material-types.d.ts +12 -12
- package/ndjson.js +16 -8
- package/operations.d.ts +6 -6
- package/operations.js +9 -39
- package/package.json +1 -1
- package/palette-completion-types.d.ts +22 -22
- package/palette-search-types.d.ts +28 -28
- package/query-understanding-types.d.ts +38 -35
- package/render-assets-types.d.ts +8 -8
- package/resolve-client.d.ts +2 -2
- package/resolve-client.js +4 -6
- package/resolve-colour-types.d.ts +8 -8
- package/resolve-types.d.ts +10 -10
- package/run-types.d.ts +70 -70
- package/runs.d.ts +13 -26
- package/runs.js +77 -89
- 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 +38 -38
- package/schema-resource-types.js +5 -5
- package/search-card-types.d.ts +4 -4
- package/search-collapse-types.d.ts +4 -4
- package/search-mood-types.d.ts +2 -2
- package/search-refinement-types.d.ts +8 -8
- package/search-request-types.d.ts +5 -5
- package/search-response-receipt-types.d.ts +58 -42
- package/search-response-types.d.ts +2 -2
- package/search-result-validation.d.ts +3 -3
- package/search-result-validation.js +53 -36
- package/search-window-types.d.ts +2 -2
- package/slot-pool-types.d.ts +20 -20
- package/source-material-validation.d.ts +3 -3
- package/source-material-validation.js +35 -39
- package/spec-facet-types.d.ts +10 -10
- package/spec-types.d.ts +6 -6
- package/specifications.d.ts +9 -25
- package/specifications.js +15 -21
- package/sse.d.ts +2 -2
- package/sse.js +32 -16
- package/substitute-types.d.ts +22 -22
- package/suggest-types.d.ts +7 -7
- package/suggest-types.js +3 -3
- package/taxonomy-coverage-types.d.ts +8 -8
- package/types.d.ts +119 -119
- package/validation.d.ts +26 -26
- package/validation.js +97 -92
- package/webmcp.d.ts +2 -2
- package/webmcp.generated.js +94 -93
- 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/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
|
@@ -5,25 +5,25 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { OpenEnum } from "./types.js";
|
|
7
7
|
/** Inspectable metadata for an opaque, principal-bound search refinement receipt. */
|
|
8
|
-
export
|
|
8
|
+
export type SearchRefinementReceipt = {
|
|
9
9
|
token: string;
|
|
10
10
|
expiresAt: string;
|
|
11
11
|
poolSize: number;
|
|
12
12
|
schemaVersion: string;
|
|
13
13
|
projectionVersion: number;
|
|
14
|
-
}
|
|
14
|
+
};
|
|
15
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">;
|
|
16
|
+
export type SearchMode = OpenEnum<"image" | "colour" | "text" | "lexical" | "entity-browse" | "agent">;
|
|
17
17
|
/**
|
|
18
18
|
* Compatibility receipt for non-mode colour handling. Current one-signal
|
|
19
19
|
* ordering reports it skipped at weight 0; colour may still be diagnostic or a
|
|
20
20
|
* hard displayed-image constraint, but does not blend into score.
|
|
21
21
|
*/
|
|
22
|
-
export
|
|
22
|
+
export type SearchRerankReport = {
|
|
23
23
|
colour?: OpenEnum<"ok" | "failed" | "skipped">;
|
|
24
24
|
colourWeight?: number;
|
|
25
25
|
colourLabel?: string;
|
|
26
|
-
}
|
|
26
|
+
};
|
|
27
27
|
/**
|
|
28
28
|
* A part of the search that can fail without stopping it.
|
|
29
29
|
*
|
|
@@ -40,15 +40,15 @@ export type SearchDegradedPart = OpenEnum<"filter-coverage" | "term-coverage">;
|
|
|
40
40
|
* means the response came from a server that does not report this, never that
|
|
41
41
|
* nothing was degraded.
|
|
42
42
|
*/
|
|
43
|
-
export
|
|
43
|
+
export type SearchDegraded = {
|
|
44
44
|
parts: SearchDegradedPart[];
|
|
45
|
-
}
|
|
45
|
+
};
|
|
46
46
|
/** Stage counts retained when a search returns no results. */
|
|
47
|
-
export
|
|
47
|
+
export type SearchEmptyOutcomeCounts = {
|
|
48
48
|
retrieved: number;
|
|
49
49
|
afterPrune: number;
|
|
50
50
|
final: number;
|
|
51
|
-
}
|
|
51
|
+
};
|
|
52
52
|
/**
|
|
53
53
|
* Why a search returned no results, on EVERY empty response (MG-1911).
|
|
54
54
|
*
|
|
@@ -80,27 +80,37 @@ export type SearchEmptyOutcome = {
|
|
|
80
80
|
counts?: SearchEmptyOutcomeCounts;
|
|
81
81
|
};
|
|
82
82
|
/** Explain-only coverage of substantive query terms in the lexical projection. */
|
|
83
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Which of the query's substantive words the catalogue holds at all
|
|
85
|
+
* (MG-1858), on every text-family response. `terms` names the words found in
|
|
86
|
+
* no document; `checkedTerms` is how many were asked about; `noneMatched` is
|
|
87
|
+
* true when no checked word is attested anywhere. `unavailable` means the read
|
|
88
|
+
* failed and never means everything matched; `skipped` means this mode never
|
|
89
|
+
* claimed to match words.
|
|
90
|
+
*/
|
|
91
|
+
export type SearchTermCoverageReceipt = {
|
|
84
92
|
status: OpenEnum<"covered" | "uncovered" | "unavailable" | "skipped">;
|
|
85
93
|
terms: string[];
|
|
94
|
+
checkedTerms: number;
|
|
95
|
+
noneMatched: boolean;
|
|
86
96
|
note?: string;
|
|
87
|
-
}
|
|
97
|
+
};
|
|
88
98
|
/** The Search workflow run a ledger receipt belongs to. */
|
|
89
|
-
export
|
|
99
|
+
export type SearchRunRef = {
|
|
90
100
|
contextId: string;
|
|
91
101
|
runId: string;
|
|
92
102
|
schemaVersion: 1;
|
|
93
|
-
}
|
|
103
|
+
};
|
|
94
104
|
/** One artifact a Search workflow step read or wrote. */
|
|
95
|
-
export
|
|
105
|
+
export type SearchRunArtifactRef = {
|
|
96
106
|
artifactId: string;
|
|
97
107
|
kind: string;
|
|
98
108
|
producedBy: string;
|
|
99
109
|
runRef: SearchRunRef;
|
|
100
110
|
schemaVersion: 1;
|
|
101
|
-
}
|
|
111
|
+
};
|
|
102
112
|
/** What one Search workflow step did: its reads, its write and its time. */
|
|
103
|
-
export
|
|
113
|
+
export type SearchStageReceipt = {
|
|
104
114
|
stageId: string;
|
|
105
115
|
status: "succeeded";
|
|
106
116
|
/** The step's own work, excluding reading and writing its artifacts. */
|
|
@@ -117,24 +127,30 @@ export interface SearchStageReceipt {
|
|
|
117
127
|
decision: string;
|
|
118
128
|
reason: string;
|
|
119
129
|
};
|
|
120
|
-
}
|
|
130
|
+
};
|
|
121
131
|
/** One ledger line: a step's receipt and its span since the run opened. */
|
|
122
|
-
export
|
|
132
|
+
export type SearchRunLedgerEntry = {
|
|
123
133
|
receipt: SearchStageReceipt;
|
|
124
134
|
/** The nested workflows the step ran under, outermost first. */
|
|
125
135
|
workflowPath: string[];
|
|
126
136
|
startedAtMs: number;
|
|
127
137
|
endedAtMs: number;
|
|
128
|
-
}
|
|
138
|
+
};
|
|
129
139
|
/**
|
|
130
|
-
* Outcome receipts shared by full and card search responses. `degraded
|
|
131
|
-
* `emptyOutcome` are on every response; `
|
|
132
|
-
* explain-only.
|
|
140
|
+
* Outcome receipts shared by full and card search responses. `degraded`,
|
|
141
|
+
* `emptyOutcome` and `termCoverage` are on every response; `diagnostics` and
|
|
142
|
+
* `explain` are explain-only.
|
|
133
143
|
*/
|
|
134
|
-
export
|
|
144
|
+
export type SearchResponseExplainReceipts = {
|
|
135
145
|
degraded?: SearchDegraded;
|
|
136
146
|
emptyOutcome?: SearchEmptyOutcome;
|
|
137
147
|
termCoverage?: SearchTermCoverageReceipt;
|
|
148
|
+
/**
|
|
149
|
+
* The engine's notes written for an engineer (tier timings, cache states,
|
|
150
|
+
* index names), under `explain` only. `note` carries the reader's sentences
|
|
151
|
+
* alone (MG-1919).
|
|
152
|
+
*/
|
|
153
|
+
diagnostics?: string[];
|
|
138
154
|
/**
|
|
139
155
|
* Present under `explain` when the Search workflow answered the request:
|
|
140
156
|
* every step receipt, in completion order. Absent when the engine answered.
|
|
@@ -142,7 +158,7 @@ export interface SearchResponseExplainReceipts {
|
|
|
142
158
|
explain?: {
|
|
143
159
|
ledger: readonly SearchRunLedgerEntry[];
|
|
144
160
|
};
|
|
145
|
-
}
|
|
161
|
+
};
|
|
146
162
|
/** One stage in the explain-only ledger of transformations that actually ran. */
|
|
147
163
|
export type SearchQueryTransformStage = {
|
|
148
164
|
stage: OpenEnum<"normalise" | "resolve-spec" | "resolve-paint" | "resolve-brand">;
|
|
@@ -153,7 +169,7 @@ export type SearchQueryTransformStage = {
|
|
|
153
169
|
reason: string;
|
|
154
170
|
};
|
|
155
171
|
/** Explain-only category gate selected by query understanding. */
|
|
156
|
-
export
|
|
172
|
+
export type SearchCategoryAnchor = {
|
|
157
173
|
/**
|
|
158
174
|
* A leaf type id; the group key when `source` is `"group"`; or the canonical
|
|
159
175
|
* category noun when `source` is `"head-noun"`. Gate on `productTypeIds`.
|
|
@@ -171,9 +187,9 @@ export interface SearchCategoryAnchor {
|
|
|
171
187
|
/** Hard category eligibility is applied inside lexical candidate selection. */
|
|
172
188
|
candidateSource?: OpenEnum<"lexical">;
|
|
173
189
|
applied: boolean;
|
|
174
|
-
}
|
|
190
|
+
};
|
|
175
191
|
/** Explain-only brand gate selected by query understanding. */
|
|
176
|
-
export
|
|
192
|
+
export type SearchBrandAnchor = {
|
|
177
193
|
brandSlug: string;
|
|
178
194
|
brandName: string;
|
|
179
195
|
confidence: number;
|
|
@@ -181,18 +197,18 @@ export interface SearchBrandAnchor {
|
|
|
181
197
|
tier: OpenEnum<"exact_id" | "exact_alias" | "lexical" | "semantic">;
|
|
182
198
|
variantCount: number;
|
|
183
199
|
applied: boolean;
|
|
184
|
-
}
|
|
200
|
+
};
|
|
185
201
|
/** A real brand candidate the engine deliberately declined to gate on. */
|
|
186
|
-
export
|
|
202
|
+
export type SearchBrandSkip = {
|
|
187
203
|
reason: OpenEnum<"ambiguous" | "weak-tier" | "too-broad">;
|
|
188
204
|
candidates?: string[];
|
|
189
|
-
}
|
|
205
|
+
};
|
|
190
206
|
/**
|
|
191
207
|
* EXPLAIN-only receipt of the query shape that executed. This is distinct from
|
|
192
208
|
* the separate Search Plan compiler operation: it reports execution and never
|
|
193
209
|
* causes it.
|
|
194
210
|
*/
|
|
195
|
-
export
|
|
211
|
+
export type SearchExecutionPlan = {
|
|
196
212
|
grain: OpenEnum<"variant" | "product">;
|
|
197
213
|
/** Which 2048D Voyage projection served a text-mode request. */
|
|
198
214
|
textLane?: OpenEnum<"image-text" | "variant-text">;
|
|
@@ -206,30 +222,30 @@ export interface SearchExecutionPlan {
|
|
|
206
222
|
};
|
|
207
223
|
queryTransform: SearchQueryTransformStage[];
|
|
208
224
|
/** Ordered, explain-only request-understanding execution trace. */
|
|
209
|
-
steps?:
|
|
225
|
+
steps?: {
|
|
210
226
|
key: string;
|
|
211
227
|
status: OpenEnum<"executed" | "skipped">;
|
|
212
228
|
reason: string;
|
|
213
229
|
durationMs: number;
|
|
214
|
-
}
|
|
230
|
+
}[];
|
|
215
231
|
categoryAnchor?: SearchCategoryAnchor;
|
|
216
232
|
brandAnchor?: SearchBrandAnchor;
|
|
217
233
|
brandSkipped?: SearchBrandSkip;
|
|
218
|
-
}
|
|
234
|
+
};
|
|
219
235
|
/** Why a compound colour constraint returned a full or short page. */
|
|
220
|
-
export
|
|
236
|
+
export type CompoundColourAbundanceReceipt = {
|
|
221
237
|
grain: OpenEnum<"variant" | "product">;
|
|
222
238
|
requested: number;
|
|
223
239
|
eligible: number;
|
|
224
240
|
candidateWindow: number;
|
|
225
241
|
sourceExhausted: boolean;
|
|
226
242
|
state: OpenEnum<"filled" | "corpus_scarcity" | "evidence_unavailable" | "retrieval_window_exhausted">;
|
|
227
|
-
}
|
|
243
|
+
};
|
|
228
244
|
/**
|
|
229
245
|
* Eligibility proof for an explicit or taxonomy-backed colour inside a compound
|
|
230
246
|
* text query. Counts describe the bounded candidate pool, not the whole corpus.
|
|
231
247
|
*/
|
|
232
|
-
export
|
|
248
|
+
export type CompoundColourConstraintReceipt = {
|
|
233
249
|
basis: OpenEnum<"explicit" | "detected-strong">;
|
|
234
250
|
family: string;
|
|
235
251
|
queryHexes: string[];
|
|
@@ -239,21 +255,21 @@ export interface CompoundColourConstraintReceipt {
|
|
|
239
255
|
unknown: number;
|
|
240
256
|
adjacent: number;
|
|
241
257
|
abundance?: CompoundColourAbundanceReceipt;
|
|
242
|
-
}
|
|
258
|
+
};
|
|
243
259
|
/** Why a hard form constraint returned a full or short page. */
|
|
244
|
-
export
|
|
260
|
+
export type CompoundFormAbundanceReceipt = {
|
|
245
261
|
grain: OpenEnum<"variant" | "product">;
|
|
246
262
|
requested: number;
|
|
247
263
|
eligible: number;
|
|
248
264
|
candidateWindow: number;
|
|
249
265
|
sourceExhausted: boolean;
|
|
250
266
|
state: OpenEnum<"filled" | "corpus_scarcity" | "evidence_unavailable" | "retrieval_window_exhausted">;
|
|
251
|
-
}
|
|
267
|
+
};
|
|
252
268
|
/**
|
|
253
269
|
* Hard form eligibility for a compound text query. Product and variant names
|
|
254
270
|
* may retrieve a candidate but never prove that it satisfies the form.
|
|
255
271
|
*/
|
|
256
|
-
export
|
|
272
|
+
export type CompoundFormConstraintReceipt = {
|
|
257
273
|
instruction: OpenEnum<"subway" | "plank" | "square" | "hexagon" | "penny-round">;
|
|
258
274
|
considered: number;
|
|
259
275
|
kept: number;
|
|
@@ -261,4 +277,4 @@ export interface CompoundFormConstraintReceipt {
|
|
|
261
277
|
contradicted: number;
|
|
262
278
|
unknown: number;
|
|
263
279
|
abundance: CompoundFormAbundanceReceipt;
|
|
264
|
-
}
|
|
280
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SearchData } from "./types.js";
|
|
2
2
|
/** Canonical Search wire response. Raw SDK methods preserve this envelope. */
|
|
3
|
-
export
|
|
3
|
+
export type SearchResponse = {
|
|
4
4
|
data: SearchData;
|
|
5
5
|
meta: {
|
|
6
6
|
operationId: "search_materials_post" | "search_materials_get";
|
|
@@ -8,4 +8,4 @@ export interface SearchResponse {
|
|
|
8
8
|
};
|
|
9
9
|
links: Record<string, never>;
|
|
10
10
|
warnings: never[];
|
|
11
|
-
}
|
|
11
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ValidationFailure } from "./validation.js";
|
|
2
2
|
/** `verdictStateSchema` — the six live cell states. */
|
|
3
3
|
export declare const VERDICT_STATES: readonly ["matched", "deviated", "failed", "unverified", "missing", "not_evaluated"];
|
|
4
4
|
/** `attributeVerdictSchema.strength`. */
|
|
@@ -22,6 +22,6 @@ export declare const VISUAL_MEANING_BASES: readonly ["canonical_attribute", "ima
|
|
|
22
22
|
* contract (nothing on the emit path parses, so stripping would invent a
|
|
23
23
|
* normalisation the wire never had).
|
|
24
24
|
*/
|
|
25
|
-
export declare
|
|
25
|
+
export declare const checkSearchResultItem: (value: unknown, what: string, fail: ValidationFailure) => void;
|
|
26
26
|
/** Prove every entry of a `results[]` array is a {@link SearchResultItem}. */
|
|
27
|
-
export declare
|
|
27
|
+
export declare const checkSearchResultItems: (items: readonly unknown[], what: string, fail: ValidationFailure) => void;
|
|
@@ -41,20 +41,21 @@ export const VISUAL_MEANING_BASES = [
|
|
|
41
41
|
];
|
|
42
42
|
// ── Leaf checks ──────────────────────────────────────────────────────────────
|
|
43
43
|
/** `palette[]` — `{ hex, proportion, name: string.nullable().optional() }`. */
|
|
44
|
-
|
|
44
|
+
const checkPaletteSwatch = (value, what, fail) => {
|
|
45
45
|
const record = requireRecord(value, what, fail);
|
|
46
46
|
requireString(record.hex, `${what}.hex`, fail);
|
|
47
47
|
requireNumber(record.proportion, `${what}.proportion`, fail);
|
|
48
48
|
// `.nullable().optional()` — absent OR null OR a string.
|
|
49
|
-
if (record.name !== undefined)
|
|
49
|
+
if (record.name !== undefined) {
|
|
50
50
|
requireNullableString(record.name, `${what}.name`, fail);
|
|
51
|
-
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
52
53
|
/**
|
|
53
54
|
* `variants[]` — one entry of a product-collapsed result's ranked variant list
|
|
54
55
|
* (`collapsedVariantSchema`). A SLIM projection, not a nested result item: the
|
|
55
56
|
* checks here are the whole shape.
|
|
56
57
|
*/
|
|
57
|
-
|
|
58
|
+
const checkCollapsedVariant = (value, what, fail) => {
|
|
58
59
|
const record = requireRecord(value, what, fail);
|
|
59
60
|
requireString(record.variantId, `${what}.variantId`, fail);
|
|
60
61
|
requireNullableString(record.variantName, `${what}.variantName`, fail);
|
|
@@ -65,16 +66,16 @@ function checkCollapsedVariant(value, what, fail) {
|
|
|
65
66
|
requireNullableString(record.imageUrl, `${what}.imageUrl`, fail);
|
|
66
67
|
requireOptionalString(record.materialBankId, `${what}.materialBankId`, fail);
|
|
67
68
|
requireNumber(record.score, `${what}.score`, fail);
|
|
68
|
-
}
|
|
69
|
+
};
|
|
69
70
|
/** `colourMeta` — three independently optional strings. */
|
|
70
|
-
|
|
71
|
+
const checkColourMeta = (value, what, fail) => {
|
|
71
72
|
const record = requireRecord(value, what, fail);
|
|
72
73
|
requireOptionalString(record.mood, `${what}.mood`, fail);
|
|
73
74
|
requireOptionalString(record.dominantFamily, `${what}.dominantFamily`, fail);
|
|
74
75
|
requireOptionalString(record.dominantHex, `${what}.dominantHex`, fail);
|
|
75
|
-
}
|
|
76
|
+
};
|
|
76
77
|
/** `searchResultSignalsSchema` — five required scores plus additive portrait. */
|
|
77
|
-
|
|
78
|
+
const checkSignals = (value, what, fail) => {
|
|
78
79
|
const record = requireRecord(value, what, fail);
|
|
79
80
|
if (record.portrait !== undefined) {
|
|
80
81
|
requireNullableNumber(record.portrait, `${what}.portrait`, fail);
|
|
@@ -82,9 +83,9 @@ function checkSignals(value, what, fail) {
|
|
|
82
83
|
for (const signal of ["image", "category", "colour", "lexical", "text"]) {
|
|
83
84
|
requireNullableNumber(record[signal], `${what}.${signal}`, fail);
|
|
84
85
|
}
|
|
85
|
-
}
|
|
86
|
+
};
|
|
86
87
|
/** `visualMeaningSchema` — note the NON-EMPTY `values` array and the closed `basis`. */
|
|
87
|
-
|
|
88
|
+
const checkVisualMeaning = (value, what, fail) => {
|
|
88
89
|
const record = requireRecord(value, what, fail);
|
|
89
90
|
requireString(record.id, `${what}.id`, fail);
|
|
90
91
|
requireString(record.label, `${what}.label`, fail);
|
|
@@ -94,39 +95,43 @@ function checkVisualMeaning(value, what, fail) {
|
|
|
94
95
|
requireOptionalString(record.sourceBasis, `${what}.sourceBasis`, fail);
|
|
95
96
|
requireOptionalString(record.version, `${what}.version`, fail);
|
|
96
97
|
requireOptionalString(record.appliedAt, `${what}.appliedAt`, fail);
|
|
97
|
-
}
|
|
98
|
+
};
|
|
98
99
|
// ── Verdict subtree ──────────────────────────────────────────────────────────
|
|
99
100
|
/**
|
|
100
101
|
* `verdictBaselineSchema` — a discriminated union on `kind`. An unknown
|
|
101
102
|
* discriminant is rejected, exactly as `z.discriminatedUnion` rejects it, and
|
|
102
103
|
* each arm carries only the fields it needs.
|
|
103
104
|
*/
|
|
104
|
-
|
|
105
|
+
const checkVerdictBaseline = (value, what, fail) => {
|
|
105
106
|
const record = requireRecord(value, what, fail);
|
|
106
107
|
const kind = requireEnum(record.kind, VERDICT_BASELINE_KINDS, `${what}.kind`, fail);
|
|
107
108
|
switch (kind) {
|
|
108
|
-
case "term":
|
|
109
|
+
case "term": {
|
|
109
110
|
requireNonEmptyString(record.term, `${what}.term`, fail);
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
case "presence": {
|
|
110
114
|
return;
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
case "seed":
|
|
115
|
+
}
|
|
116
|
+
case "seed": {
|
|
114
117
|
requireNonEmptyString(record.variantId, `${what}.variantId`, fail);
|
|
115
118
|
return;
|
|
116
|
-
|
|
119
|
+
}
|
|
120
|
+
default: {
|
|
117
121
|
// `image` — the like-this-picture arm.
|
|
118
122
|
requireEnum(record.source, VERDICT_IMAGE_SOURCES, `${what}.source`, fail);
|
|
119
123
|
requireNullableNonEmptyString(record.variantId, `${what}.variantId`, fail);
|
|
124
|
+
}
|
|
120
125
|
}
|
|
121
|
-
}
|
|
126
|
+
};
|
|
122
127
|
/** `verdictDeviationSchema` — a named near-miss. */
|
|
123
|
-
|
|
128
|
+
const checkVerdictDeviation = (value, what, fail) => {
|
|
124
129
|
const record = requireRecord(value, what, fail);
|
|
125
130
|
requireEnum(record.direction, VERDICT_DEVIATION_DIRECTIONS, `${what}.direction`, fail);
|
|
126
131
|
requireNullableNumber(record.delta, `${what}.delta`, fail);
|
|
127
132
|
requireNullableString(record.unit, `${what}.unit`, fail);
|
|
128
133
|
requireNonEmptyString(record.label, `${what}.label`, fail);
|
|
129
|
-
}
|
|
134
|
+
};
|
|
130
135
|
/**
|
|
131
136
|
* `attributeVerdictSchema` — nine fields plus the TWO cross-field invariants its
|
|
132
137
|
* `.superRefine()` enforces. Those are relational rather than field-wise, which
|
|
@@ -134,7 +139,7 @@ function checkVerdictDeviation(value, what, fail) {
|
|
|
134
139
|
* schema's own doc calls them out as the reason a malformed cell can never reach
|
|
135
140
|
* a consumer.
|
|
136
141
|
*/
|
|
137
|
-
|
|
142
|
+
const checkAttributeVerdict = (value, what, fail) => {
|
|
138
143
|
const record = requireRecord(value, what, fail);
|
|
139
144
|
requireNonEmptyString(record.attributeId, `${what}.attributeId`, fail);
|
|
140
145
|
const state = requireEnum(record.state, VERDICT_STATES, `${what}.state`, fail);
|
|
@@ -152,9 +157,10 @@ function checkAttributeVerdict(value, what, fail) {
|
|
|
152
157
|
throw fail(`${what}.citation.count must be a positive integer`);
|
|
153
158
|
}
|
|
154
159
|
}
|
|
155
|
-
const deviation = record
|
|
156
|
-
if (deviation !== null)
|
|
160
|
+
const { deviation } = record;
|
|
161
|
+
if (deviation !== null) {
|
|
157
162
|
checkVerdictDeviation(deviation, `${what}.deviation`, fail);
|
|
163
|
+
}
|
|
158
164
|
const trustGap = requireNullableEnum(record.trustGap, VERDICT_TRUST_GAPS, `${what}.trustGap`, fail);
|
|
159
165
|
// superRefine invariant 1 — a deviation only describes a `deviated` cell.
|
|
160
166
|
if (deviation !== null && state !== "deviated") {
|
|
@@ -164,15 +170,17 @@ function checkAttributeVerdict(value, what, fail) {
|
|
|
164
170
|
if (trustGap !== null && state !== "unverified") {
|
|
165
171
|
throw fail(`${what}.trustGap is set on a cell whose state is "${state}", not "unverified"`);
|
|
166
172
|
}
|
|
167
|
-
}
|
|
173
|
+
};
|
|
168
174
|
/** `candidateVerdictSchema` — the whole report card. */
|
|
169
|
-
|
|
175
|
+
const checkCandidateVerdict = (value, what, fail) => {
|
|
170
176
|
const record = requireRecord(value, what, fail);
|
|
171
177
|
const cells = requireArray(record.cells, `${what}.cells`, fail);
|
|
172
|
-
cells.forEach((cell, index) =>
|
|
178
|
+
cells.forEach((cell, index) => {
|
|
179
|
+
checkAttributeVerdict(cell, `${what}.cells[${index}]`, fail);
|
|
180
|
+
});
|
|
173
181
|
requireEnum(record.grade, VERDICT_GRADES, `${what}.grade`, fail);
|
|
174
182
|
requireNullableBoundedNumber(record.minConfidence, `${what}.minConfidence`, fail, 0, 1);
|
|
175
|
-
}
|
|
183
|
+
};
|
|
176
184
|
// ── The item ─────────────────────────────────────────────────────────────────
|
|
177
185
|
/**
|
|
178
186
|
* Prove one wire value is a {@link SearchResultItem}, raising through `fail` at
|
|
@@ -181,7 +189,7 @@ function checkCandidateVerdict(value, what, fail) {
|
|
|
181
189
|
* contract (nothing on the emit path parses, so stripping would invent a
|
|
182
190
|
* normalisation the wire never had).
|
|
183
191
|
*/
|
|
184
|
-
export
|
|
192
|
+
export const checkSearchResultItem = (value, what, fail) => {
|
|
185
193
|
const record = requireRecord(value, what, fail);
|
|
186
194
|
requireString(record.variantId, `${what}.variantId`, fail);
|
|
187
195
|
requireString(record.brand, `${what}.brand`, fail);
|
|
@@ -209,12 +217,15 @@ export function checkSearchResultItem(value, what, fail) {
|
|
|
209
217
|
requireBoolean(record.hasImage, `${what}.hasImage`, fail);
|
|
210
218
|
requireNumber(record.score, `${what}.score`, fail);
|
|
211
219
|
const palette = requireArray(record.palette, `${what}.palette`, fail);
|
|
212
|
-
palette.forEach((swatch, index) =>
|
|
220
|
+
palette.forEach((swatch, index) => {
|
|
221
|
+
checkPaletteSwatch(swatch, `${what}.palette[${index}]`, fail);
|
|
222
|
+
});
|
|
213
223
|
if (record.colourMeta !== undefined) {
|
|
214
224
|
checkColourMeta(record.colourMeta, `${what}.colourMeta`, fail);
|
|
215
225
|
}
|
|
216
|
-
if (record.signals !== undefined)
|
|
226
|
+
if (record.signals !== undefined) {
|
|
217
227
|
checkSignals(record.signals, `${what}.signals`, fail);
|
|
228
|
+
}
|
|
218
229
|
requireOptionalBoolean(record.retired, `${what}.retired`, fail);
|
|
219
230
|
requireOptionalBoolean(record.sampleable, `${what}.sampleable`, fail);
|
|
220
231
|
requireOptionalBoolean(record.belowFloor, `${what}.belowFloor`, fail);
|
|
@@ -224,17 +235,23 @@ export function checkSearchResultItem(value, what, fail) {
|
|
|
224
235
|
}
|
|
225
236
|
if (record.variants !== undefined) {
|
|
226
237
|
const variants = requireArray(record.variants, `${what}.variants`, fail);
|
|
227
|
-
variants.forEach((variant, index) =>
|
|
238
|
+
variants.forEach((variant, index) => {
|
|
239
|
+
checkCollapsedVariant(variant, `${what}.variants[${index}]`, fail);
|
|
240
|
+
});
|
|
228
241
|
}
|
|
229
242
|
if (record.visualMeanings !== undefined) {
|
|
230
243
|
const meanings = requireArray(record.visualMeanings, `${what}.visualMeanings`, fail);
|
|
231
|
-
meanings.forEach((meaning, index) =>
|
|
244
|
+
meanings.forEach((meaning, index) => {
|
|
245
|
+
checkVisualMeaning(meaning, `${what}.visualMeanings[${index}]`, fail);
|
|
246
|
+
});
|
|
232
247
|
}
|
|
233
248
|
if (record.verdict !== undefined) {
|
|
234
249
|
checkCandidateVerdict(record.verdict, `${what}.verdict`, fail);
|
|
235
250
|
}
|
|
236
|
-
}
|
|
251
|
+
};
|
|
237
252
|
/** Prove every entry of a `results[]` array is a {@link SearchResultItem}. */
|
|
238
|
-
export
|
|
239
|
-
items.forEach((item, index) =>
|
|
240
|
-
}
|
|
253
|
+
export const checkSearchResultItems = (items, what, fail) => {
|
|
254
|
+
items.forEach((item, index) => {
|
|
255
|
+
checkSearchResultItem(item, `${what}[${index}]`, fail);
|
|
256
|
+
});
|
|
257
|
+
};
|
package/search-window-types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** The bounded candidate window that produced a search page. */
|
|
2
|
-
export
|
|
2
|
+
export type SearchWindowReceipt = {
|
|
3
3
|
/** Versioned budget profile; interpret the remaining fields under this version. */
|
|
4
4
|
profile: "interactive-r1" | (string & {});
|
|
5
5
|
/** Candidate depth used by the final retrieval. */
|
|
@@ -22,4 +22,4 @@ export interface SearchWindowReceipt {
|
|
|
22
22
|
/** Canonical candidates returned by the selected retrieval arm. */
|
|
23
23
|
hydratedCanonicalCandidates: number;
|
|
24
24
|
};
|
|
25
|
-
}
|
|
25
|
+
};
|
package/slot-pool-types.d.ts
CHANGED
|
@@ -61,11 +61,11 @@ export type SlotPoolCriterion = {
|
|
|
61
61
|
coverageNote?: string;
|
|
62
62
|
};
|
|
63
63
|
/** A colour cue for a slot. Colours rerank within the retrieved set; they never admit. */
|
|
64
|
-
export
|
|
64
|
+
export type SlotPoolColourCue = {
|
|
65
65
|
/** `#rrggbb`. */
|
|
66
66
|
hex: string;
|
|
67
67
|
name?: string;
|
|
68
|
-
}
|
|
68
|
+
};
|
|
69
69
|
/**
|
|
70
70
|
* What to do with a candidate the catalogue no longer lists. Neither value ever
|
|
71
71
|
* marks such a candidate eligible — the policy decides only whether it is
|
|
@@ -73,7 +73,7 @@ export interface SlotPoolColourCue {
|
|
|
73
73
|
*/
|
|
74
74
|
export type SlotPoolAvailabilityPolicy = "flag-unavailable" | "exclude-unavailable";
|
|
75
75
|
/** One slot of work. Self-contained: nothing in it identifies a project. */
|
|
76
|
-
export
|
|
76
|
+
export type SlotPoolTask = {
|
|
77
77
|
/**
|
|
78
78
|
* YOUR key for this task, opaque to MaterialGraph and returned verbatim on the
|
|
79
79
|
* matching pool. This is how you correlate 24 results; it is never parsed,
|
|
@@ -102,9 +102,9 @@ export interface SlotPoolTask {
|
|
|
102
102
|
availability?: SlotPoolAvailabilityPolicy;
|
|
103
103
|
/** Candidates returned for this task. Max 48, default 12. */
|
|
104
104
|
limit?: number;
|
|
105
|
-
}
|
|
105
|
+
};
|
|
106
106
|
/** Body for `POST /api/v1/schemes/pools` ({@link MaterialGraphClient.slotPools}). */
|
|
107
|
-
export
|
|
107
|
+
export type SlotPoolsRequest = {
|
|
108
108
|
/** Up to 24 tasks. Each is independent: one failing costs that one. */
|
|
109
109
|
tasks: SlotPoolTask[];
|
|
110
110
|
/**
|
|
@@ -112,11 +112,11 @@ export interface SlotPoolsRequest {
|
|
|
112
112
|
* (default true). One bounded read — never one request per candidate.
|
|
113
113
|
*/
|
|
114
114
|
coSpecification?: boolean;
|
|
115
|
-
}
|
|
115
|
+
};
|
|
116
116
|
/** The six live verdict states, plus the two legacy tokens older rows carry. */
|
|
117
117
|
export type SlotPoolVerdictState = OpenEnum<"matched" | "deviated" | "failed" | "unverified" | "missing" | "not_evaluated">;
|
|
118
118
|
/** One cell of a candidate's report card against one criterion. */
|
|
119
|
-
export
|
|
119
|
+
export type SlotPoolVerdictCell = {
|
|
120
120
|
attributeId: string;
|
|
121
121
|
state: SlotPoolVerdictState;
|
|
122
122
|
strength: OpenEnum<"required" | "preferred">;
|
|
@@ -149,12 +149,12 @@ export interface SlotPoolVerdictCell {
|
|
|
149
149
|
sourceBasis: string | null;
|
|
150
150
|
trustGap: OpenEnum<"below_confidence" | "basis_unmet" | "proposed"> | null;
|
|
151
151
|
citation?: VerdictCitation;
|
|
152
|
-
}
|
|
152
|
+
};
|
|
153
153
|
/** Why a candidate is labelled. An eligible candidate carries none of these. */
|
|
154
154
|
export type SlotPoolFlag = OpenEnum<"below-floor" | "required-not-applied" | "discontinued" | "superseded" | "unverified-value">;
|
|
155
155
|
export type SlotPoolAvailability = OpenEnum<"available" | "discontinued" | "superseded" | "unknown">;
|
|
156
156
|
/** The declared successor of a withdrawn material, one hop only. */
|
|
157
|
-
export
|
|
157
|
+
export type SlotPoolSuccessor = {
|
|
158
158
|
variantId: VariantId;
|
|
159
159
|
brandSlug: string;
|
|
160
160
|
productId: string;
|
|
@@ -163,13 +163,13 @@ export interface SlotPoolSuccessor {
|
|
|
163
163
|
variant: string;
|
|
164
164
|
color: string | null;
|
|
165
165
|
availability: SlotPoolAvailability;
|
|
166
|
-
}
|
|
166
|
+
};
|
|
167
167
|
/**
|
|
168
168
|
* The features a composer scores on. Colours are EXTRACTED FROM PRODUCT IMAGERY
|
|
169
169
|
* — visual likeness, never a declared colour specification. An empty `palette`
|
|
170
170
|
* or `attributes` means nothing is on record, never that the material has none.
|
|
171
171
|
*/
|
|
172
|
-
export
|
|
172
|
+
export type SlotPoolCandidateFeatures = {
|
|
173
173
|
colour: {
|
|
174
174
|
dominantHex: string | null;
|
|
175
175
|
hsl: {
|
|
@@ -201,8 +201,8 @@ export interface SlotPoolCandidateFeatures {
|
|
|
201
201
|
term: string;
|
|
202
202
|
}[];
|
|
203
203
|
dimensions: Record<string, unknown>[] | null;
|
|
204
|
-
}
|
|
205
|
-
export
|
|
204
|
+
};
|
|
205
|
+
export type SlotPoolCandidate = {
|
|
206
206
|
variantId: VariantId;
|
|
207
207
|
productId: string;
|
|
208
208
|
brandSlug: string;
|
|
@@ -241,7 +241,7 @@ export interface SlotPoolCandidate {
|
|
|
241
241
|
minConfidence: number | null;
|
|
242
242
|
};
|
|
243
243
|
features: SlotPoolCandidateFeatures;
|
|
244
|
-
}
|
|
244
|
+
};
|
|
245
245
|
/**
|
|
246
246
|
* Why a pool is short. Four different facts, and none of them is "nothing in
|
|
247
247
|
* the catalogue matches your brief".
|
|
@@ -268,7 +268,7 @@ export type SlotPoolShortfall = {
|
|
|
268
268
|
tier: string;
|
|
269
269
|
consideredCount: number;
|
|
270
270
|
};
|
|
271
|
-
export
|
|
271
|
+
export type SlotPool = {
|
|
272
272
|
/** Your own key, verbatim. */
|
|
273
273
|
taskKey: string;
|
|
274
274
|
category: string | null;
|
|
@@ -305,14 +305,14 @@ export interface SlotPool {
|
|
|
305
305
|
variantId: VariantId;
|
|
306
306
|
} | null;
|
|
307
307
|
warnings: string[];
|
|
308
|
-
}
|
|
308
|
+
};
|
|
309
309
|
/**
|
|
310
310
|
* The sparse pairing graph among the returned candidates. Each unordered pair
|
|
311
311
|
* appears ONCE and the relation is symmetric. An empty `edges` under a null
|
|
312
312
|
* `datasetSessionId` means the dataset is absent, NOT that these materials are
|
|
313
313
|
* never specified together.
|
|
314
314
|
*/
|
|
315
|
-
export
|
|
315
|
+
export type SlotPoolCoSpecification = {
|
|
316
316
|
edges: {
|
|
317
317
|
from: VariantId;
|
|
318
318
|
to: VariantId;
|
|
@@ -326,9 +326,9 @@ export interface SlotPoolCoSpecification {
|
|
|
326
326
|
window: string;
|
|
327
327
|
signal: string;
|
|
328
328
|
};
|
|
329
|
-
}
|
|
329
|
+
};
|
|
330
330
|
/** The `200` body from `POST /api/v1/schemes/pools`. */
|
|
331
|
-
export
|
|
331
|
+
export type SlotPoolsResponse = {
|
|
332
332
|
versions: {
|
|
333
333
|
contract: string;
|
|
334
334
|
retrieval: string;
|
|
@@ -369,4 +369,4 @@ export interface SlotPoolsResponse {
|
|
|
369
369
|
coSpecificationQueries: number;
|
|
370
370
|
};
|
|
371
371
|
warnings: string[];
|
|
372
|
-
}
|
|
372
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PostSourceMaterialCommentResult, SourceMaterialBatchDetail, SourceMaterialCommentThread } from "./run-types.js";
|
|
2
2
|
/** Validate a batch-detail body, returning it typed, or throw explaining why. */
|
|
3
|
-
export declare
|
|
3
|
+
export declare const checkSourceMaterialBatchDetail: (value: unknown, batchId: string) => SourceMaterialBatchDetail;
|
|
4
4
|
/** Validate a comment-thread body, returning it typed, or throw explaining why. */
|
|
5
|
-
export declare
|
|
5
|
+
export declare const checkSourceMaterialCommentThread: (value: unknown, sourceId: string) => SourceMaterialCommentThread;
|
|
6
6
|
/** Validate a posted-comment body, returning it typed, or throw explaining why. */
|
|
7
|
-
export declare
|
|
7
|
+
export declare const checkPostSourceMaterialCommentResult: (value: unknown, sourceId: string) => PostSourceMaterialCommentResult;
|