@instruments/materialgraph 0.32.0 → 0.35.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.
Files changed (88) hide show
  1. package/association-types.d.ts +11 -11
  2. package/associations-client.d.ts +7 -7
  3. package/associations-client.js +5 -5
  4. package/brand-types.d.ts +37 -41
  5. package/brand-types.js +3 -5
  6. package/brands-client.d.ts +22 -9
  7. package/brands-client.js +20 -6
  8. package/by-spec-types.d.ts +2 -3
  9. package/catalog-discovery-types.d.ts +3 -3
  10. package/catalogue-client.d.ts +2 -50
  11. package/catalogue-client.js +2 -10
  12. package/catalogue-types.d.ts +1 -1
  13. package/categories-client.d.ts +3 -5
  14. package/categories-client.js +1 -1
  15. package/category-types.d.ts +17 -30
  16. package/citation-types.d.ts +2 -2
  17. package/client-vocabulary.d.ts +2 -2
  18. package/client-vocabulary.js +4 -1
  19. package/client.d.ts +75 -102
  20. package/client.js +83 -100
  21. package/color-profiles-types.d.ts +70 -0
  22. package/colors-client.d.ts +76 -0
  23. package/colors-client.js +52 -0
  24. package/find-companions-types.d.ts +8 -8
  25. package/{find-variants-by-colour-types.d.ts → find-variants-by-color-types.d.ts} +70 -64
  26. package/find-variants-by-vector-types.d.ts +4 -1
  27. package/get-variant-types.d.ts +14 -2
  28. package/http-transport.d.ts +1 -1
  29. package/http-transport.js +1 -2
  30. package/identifiers.d.ts +2 -2
  31. package/identifiers.js +1 -1
  32. package/index.d.ts +5 -13
  33. package/index.js +1 -3
  34. package/list-variant-facets-types.d.ts +4 -4
  35. package/list-variants-types.d.ts +108 -19
  36. package/material-asset-types.d.ts +3 -3
  37. package/material-block-types.d.ts +9 -9
  38. package/material-types.d.ts +10 -8
  39. package/operations.d.ts +2 -2
  40. package/operations.js +14 -24
  41. package/package.json +2 -2
  42. package/{resolve-colour-types.d.ts → resolve-color-types.d.ts} +18 -18
  43. package/response-schemas.generated.d.ts +2 -2
  44. package/response-schemas.generated.js +40 -68
  45. package/response-schemas.js +1 -1
  46. package/samplize-catalogue-types.d.ts +4 -4
  47. package/samplize-colorvec.js +6 -6
  48. package/{corpus-scope-types.d.ts → search-catalogue-subset-types.d.ts} +3 -3
  49. package/search-variants-types.d.ts +91 -0
  50. package/types.d.ts +31 -283
  51. package/webmcp.generated.js +4 -9
  52. package/attribution-types.d.ts +0 -51
  53. package/attribution-types.js +0 -13
  54. package/by-colour-types.d.ts +0 -320
  55. package/colour-region-types.d.ts +0 -18
  56. package/colours-client.d.ts +0 -70
  57. package/colours-client.js +0 -38
  58. package/material-query-plan-types.d.ts +0 -70
  59. package/palette-search-types.d.ts +0 -171
  60. package/palette-search-types.js +0 -1
  61. package/query-understanding-types.d.ts +0 -254
  62. package/query-understanding-types.js +0 -1
  63. package/resolve-colour-types.js +0 -1
  64. package/search-card-types.d.ts +0 -86
  65. package/search-card-types.js +0 -1
  66. package/search-index-plan-types.d.ts +0 -74
  67. package/search-index-plan-types.js +0 -1
  68. package/search-refinement-types.d.ts +0 -103
  69. package/search-refinement-types.js +0 -2
  70. package/search-request-types.d.ts +0 -170
  71. package/search-request-types.js +0 -1
  72. package/search-response-receipt-types.d.ts +0 -24
  73. package/search-response-receipt-types.js +0 -1
  74. package/search-response-types.d.ts +0 -11
  75. package/search-response-types.js +0 -1
  76. package/search-result-validation.d.ts +0 -9
  77. package/search-result-validation.js +0 -83
  78. package/spec-types.d.ts +0 -109
  79. package/spec-types.js +0 -54
  80. package/specifications.d.ts +0 -34
  81. package/specifications.js +0 -56
  82. package/validation.d.ts +0 -43
  83. package/validation.js +0 -117
  84. /package/{by-colour-types.js → color-profiles-types.js} +0 -0
  85. /package/{colour-region-types.js → find-variants-by-color-types.js} +0 -0
  86. /package/{corpus-scope-types.js → resolve-color-types.js} +0 -0
  87. /package/{find-variants-by-colour-types.js → search-catalogue-subset-types.js} +0 -0
  88. /package/{material-query-plan-types.js → search-variants-types.js} +0 -0
@@ -1,70 +0,0 @@
1
- import type { QueryParams } from "./http-transport.js";
2
- import type { SdkOperationId } from "./operations.js";
3
- /**
4
- * The colour surface, namespaced as `mg.colours` — MULTI-COLOUR search
5
- * (`palette`).
6
- *
7
- * A namespace rather than a flat method on an already-large client facade:
8
- * "what goes with these colours" (`palette`). `mg.codes` set the precedent for
9
- * a namespace when a capability is a family rather than a single verb.
10
- *
11
- * The namespace holds no transport of its own: the client hands it a bound
12
- * `get`/`post`, so auth, rate-limit accounting and error shaping stay in one
13
- * place.
14
- *
15
- * `palette`'s response is live and uncached.
16
- *
17
- * ROUTING OUT OF THIS NAMESPACE. Colour is a lens, and this is not the only
18
- * door into it:
19
- * - ONE colour → `mg.byColour({ hex })`. This namespace's `palette` is for N
20
- * colours at stated proportions, which is a different ranking, not a
21
- * convenience wrapper.
22
- * - A colour NAME rather than a hex → `mg.resolveColour(name)` first.
23
- * - Colour WORDS (families, moods, undertones) → `mg.colourFacets()`.
24
- * - Walking the corpus by lightness/vividness → `mg.listVariants({ orderBy })`.
25
- * - Colour as one signal among words and a seed → `mg.search(...)`.
26
- *
27
- * And the honesty rule the whole lens rests on: every colour here is DERIVED
28
- * FROM PRODUCT IMAGERY, not declared by the manufacturer. Report visual
29
- * likeness, never a stated colour specification.
30
- */
31
- import type { SearchPaletteInput, SearchPaletteResponse } from "./palette-search-types.js";
32
- /** The client's own request primitives, handed down so this file owns no transport. */
33
- export type ColoursTransport = {
34
- get<T>(operationId: SdkOperationId, query?: QueryParams, signal?: AbortSignal): Promise<T>;
35
- post<T>(operationId: SdkOperationId, body: unknown, signal?: AbortSignal): Promise<T>;
36
- };
37
- export declare class ColoursClient {
38
- #private;
39
- constructor(transport: ColoursTransport);
40
- /**
41
- * THE QUESTION: "what goes with this WHOLE PALETTE?" — N colours at once, at
42
- * stated proportions, not one colour repeated (POST `/api/v1/search/palettes`).
43
- *
44
- * Use `mg.byColour()` for a single colour.
45
- *
46
- * Each colour scores `sim × prop`: `sim` is OKLab closeness on the same
47
- * mapping `byColour` ranks with, and `prop` rewards a candidate whose own
48
- * swatch SHARE sits near the `proportion` you asked for. So the same colours
49
- * at different proportions come back in a different order — a colour at 60%
50
- * of the surface is a different query from one at 5%. `logic: "all"` (the
51
- * default) applies a per-colour eligibility floor and returns the weighted
52
- * geometric mean, so a candidate missing one colour is rejected rather than
53
- * merely ranked low; `logic: "any"` is a noisy-OR that accepts partial
54
- * answers but saturates once several colours score well, so prefer `all`
55
- * when the ORDER is what matters.
56
- *
57
- * Every match carries the candidate's full `palette` plus a per-colour
58
- * receipt naming the swatch that answered each queried colour.
59
- *
60
- * @example
61
- * const { matches } = await mg.colours.palette({
62
- * colours: [
63
- * { hex: "F5EFE0", proportion: 0.6 },
64
- * { hex: "9CAF88", proportion: 0.2 },
65
- * { hex: "3E3B36", proportion: 0.2 },
66
- * ],
67
- * });
68
- */
69
- palette(input: SearchPaletteInput, signal?: AbortSignal): Promise<SearchPaletteResponse>;
70
- }
package/colours-client.js DELETED
@@ -1,38 +0,0 @@
1
- export class ColoursClient {
2
- #transport;
3
- constructor(transport) {
4
- this.#transport = transport;
5
- }
6
- /**
7
- * THE QUESTION: "what goes with this WHOLE PALETTE?" — N colours at once, at
8
- * stated proportions, not one colour repeated (POST `/api/v1/search/palettes`).
9
- *
10
- * Use `mg.byColour()` for a single colour.
11
- *
12
- * Each colour scores `sim × prop`: `sim` is OKLab closeness on the same
13
- * mapping `byColour` ranks with, and `prop` rewards a candidate whose own
14
- * swatch SHARE sits near the `proportion` you asked for. So the same colours
15
- * at different proportions come back in a different order — a colour at 60%
16
- * of the surface is a different query from one at 5%. `logic: "all"` (the
17
- * default) applies a per-colour eligibility floor and returns the weighted
18
- * geometric mean, so a candidate missing one colour is rejected rather than
19
- * merely ranked low; `logic: "any"` is a noisy-OR that accepts partial
20
- * answers but saturates once several colours score well, so prefer `all`
21
- * when the ORDER is what matters.
22
- *
23
- * Every match carries the candidate's full `palette` plus a per-colour
24
- * receipt naming the swatch that answered each queried colour.
25
- *
26
- * @example
27
- * const { matches } = await mg.colours.palette({
28
- * colours: [
29
- * { hex: "F5EFE0", proportion: 0.6 },
30
- * { hex: "9CAF88", proportion: 0.2 },
31
- * { hex: "3E3B36", proportion: 0.2 },
32
- * ],
33
- * });
34
- */
35
- async palette(input, signal) {
36
- return await this.#transport.post("search_by_palette", input, signal);
37
- }
38
- }
@@ -1,70 +0,0 @@
1
- /** Hand-mirrored wire types for `POST /api/v1/search/plan`. */
2
- import type { OpenEnum } from "./types.js";
3
- /** One wanted value: hard filters the page, soft only orders it. */
4
- export type MaterialQueryWant = {
5
- attributeId: string;
6
- terms: string[];
7
- phrase: string;
8
- strength: OpenEnum<"hard" | "soft">;
9
- fill: number;
10
- };
11
- export type MaterialQueryExclusion = {
12
- attributeId: string;
13
- term: string;
14
- phrase: string;
15
- };
16
- /** The dictionary reading of one query, as the index search runs it. */
17
- export type MaterialQueryReading = {
18
- normalised: string;
19
- category: {
20
- productTypeIds: string[];
21
- label: string;
22
- phrase: string;
23
- } | null;
24
- brands: {
25
- ids: string[];
26
- names: string[];
27
- phrase: string;
28
- } | null;
29
- wants: MaterialQueryWant[];
30
- excludes: MaterialQueryExclusion[];
31
- excludeBrands: string[];
32
- colour: {
33
- phrase: string;
34
- familyId: string;
35
- hex: string;
36
- oklab: [number, number, number];
37
- family12: string[];
38
- } | null;
39
- vendorColourNames: string[];
40
- leftover: string[];
41
- softAlone: boolean;
42
- };
43
- /** Present when a word no material carries was corrected: showing results for `to`. */
44
- export type MaterialQueryCorrection = {
45
- from: string;
46
- to: string;
47
- words: {
48
- word: string;
49
- correction: string;
50
- }[];
51
- };
52
- /** One search over the index. */
53
- export type MaterialSearchRequest = {
54
- text: string;
55
- view?: OpenEnum<"card" | "full">;
56
- limit?: number;
57
- cursor?: string;
58
- };
59
- export type MaterialQueryPlan = {
60
- version: OpenEnum<"2">;
61
- rawQuery: string;
62
- normalisedQuery: string;
63
- readingVersion: string;
64
- source: OpenEnum<"dictionary" | "jev">;
65
- cached: boolean;
66
- plan: MaterialQueryReading;
67
- correction: MaterialQueryCorrection | null;
68
- /** The one search to run, in the phrasing that was read. */
69
- requests: MaterialSearchRequest[];
70
- };
@@ -1,171 +0,0 @@
1
- import type { ColourCategoryGate } from "./by-colour-types.js";
2
- import type { CorpusScope, CorpusScopeReceipt } from "./corpus-scope-types.js";
3
- /**
4
- * Wire types for MULTI-COLOUR search — `POST /api/v1/search/palettes`.
5
- *
6
- * Kept out of `types.ts` for the repository's source-file size budget. Same
7
- * tolerant-parsing contract as the rest of the mirror — response enums are
8
- * widened so a new server value still type-checks.
9
- *
10
- * The MATCH SEMANTICS these types carry are the server's, stated on
11
- * {@link SearchPaletteInput.logic} rather than left to the endpoint docs.
12
- */
13
- import type { VariantId } from "./identifiers.js";
14
- import type { OklabTriple, OpenEnum } from "./types.js";
15
- /** How the per-colour scores are combined across a palette. */
16
- export type PaletteLogic = OpenEnum<"all" | "any">;
17
- /** One queried palette colour — exactly one of `hex` or `oklab`. */
18
- export type PaletteQueryColour = {
19
- hex?: string;
20
- oklab?: OklabTriple;
21
- /**
22
- * Share of the surface this colour should occupy, in (0,1]. A colour stated
23
- * below 5% is dropped; otherwise not applied, since a palette is ordered by
24
- * its first colour alone.
25
- */
26
- proportion?: number;
27
- /** Relative importance. Not applied: a palette is ordered by its first colour. */
28
- weight?: number;
29
- };
30
- export type SearchPaletteInput = {
31
- /**
32
- * HARD category filter: category-group or product-type names or keys.
33
- * Absent, the page holds surface materials only, so lights, taps and
34
- * furniture are left out.
35
- */
36
- category?: string[];
37
- corpusScope?: CorpusScope;
38
- /**
39
- * The palette to match, 1–8 colours. The page is ordered by the FIRST colour;
40
- * the rest come back in `query.droppedColours`.
41
- */
42
- colours: PaletteQueryColour[];
43
- /**
44
- * Kept so existing callers still parse: the one search orders the page by
45
- * the first colour with no eligibility floor, so `all` and `any` return the
46
- * same page.
47
- */
48
- logic?: PaletteLogic;
49
- /** Results to return; defaults to 24, capped at 48. */
50
- limit?: number;
51
- };
52
- /**
53
- * One swatch used for scoring. Samplize paint uses its selected published hex;
54
- * other materials use colorscope palettes extracted from imagery. `name` is null when no human
55
- * name was resolved — unnamed, not colourless.
56
- */
57
- export type CandidateSwatch = {
58
- hex: string;
59
- proportion: number;
60
- name: string | null;
61
- };
62
- /** Why a queried colour (or gradient sample) scored what it scored. */
63
- export type ColourMatchReceipt = {
64
- queryHex: string;
65
- /** `colourScore × proportionScore`, so `colourScore` on the one search. */
66
- score: number;
67
- /**
68
- * Closeness in [0,1] of the matched swatch to the queried colour, from plain
69
- * OKLab distance with lightness counted in full. Not a confidence.
70
- */
71
- colourScore: number;
72
- /** Proportion agreement; always 1, since no proportion is applied. */
73
- proportionScore: number;
74
- /** The swatch that produced the score, or null when nothing matched. */
75
- matched: CandidateSwatch | null;
76
- /**
77
- * Whether `matched` has a hue compatible with the queried colour, at the
78
- * response's `hueGate` thresholds. A flag, never a gate: an incompatible
79
- * swatch still scores and ranks. Absent when there is no `matched` swatch.
80
- */
81
- hueCompatible?: boolean;
82
- };
83
- /** Identity and evidence shared by both multi-colour match shapes. */
84
- export type MultiColourMatchBase = {
85
- /** Opaque — round-trip verbatim. */
86
- variantId: VariantId;
87
- brand: string;
88
- product: string;
89
- brandSlug: string | null;
90
- productId: string | null;
91
- color: string | null;
92
- variantName: string | null;
93
- imageUrl: string | null;
94
- /**
95
- * SHA-256 of the displayed image `imageUrl` points at, as a hex digest.
96
- * ABSENT means no hash is on record, never that there is no image.
97
- */
98
- imageSha256?: string;
99
- /** MB has retired or hidden this SKU. */
100
- retired: boolean;
101
- /**
102
- * The catalog GROUP — "Flooring", "Textile Materials", "Coatings" — or null
103
- * when the material has no accepted primary product type.
104
- *
105
- * A palette query is cross-category BY INTENT: a designer building a scheme,
106
- * not browsing one aisle. So this is the field that says whether a result
107
- * answers the question — one real palette returned 30 of 40 results in a
108
- * single category while every one of the fourteen groups held something
109
- * closer on the same colours (MG-1245). Group by it, and keep null as its own
110
- * bucket: null means UNKNOWN, not uncategorised, and it is not rare.
111
- */
112
- category: string | null;
113
- /** The candidate's full extracted palette — the evidence scored against. */
114
- palette: CandidateSwatch[];
115
- /**
116
- * Closeness in [0,1] of the material's own colour to the searched colour,
117
- * the page's order. Not a confidence or a percentage.
118
- */
119
- score: number;
120
- };
121
- export type PaletteMatch = {
122
- /** One receipt per queried colour, in query order. */
123
- colours: ColourMatchReceipt[];
124
- } & MultiColourMatchBase;
125
- /**
126
- * The thresholds behind every receipt's `hueCompatible`: the exact values
127
- * passed to colorscope's `isHueCompatible`, fixed server-side with no request
128
- * knob. A FLAG, never admission or ranking: every swatch still scores, and the
129
- * page and its order are the same with or without it.
130
- */
131
- export type HueGateReceipt = {
132
- /** Below this query chroma the colour is achromatic and any hue is admitted. */
133
- achromaticQueryChroma: number;
134
- /** A swatch must carry at least this share of the query colour's chroma. */
135
- minChromaRatio: number;
136
- /** Floor on the cosine agreement between the two hue vectors. */
137
- minHueCosine: number;
138
- };
139
- /**
140
- * A PAGE, NOT A CORPUS. `count` is `matches.length` under `limit` (24 default,
141
- * 48 max) — this surface states no corpus total and has no cursor, so "N
142
- * materials match this palette" is not a claim you can make from it.
143
- */
144
- export type SearchPaletteResponse = {
145
- corpusScope?: CorpusScopeReceipt;
146
- /** The query as interpreted — check it before trusting a surprising order. */
147
- query: {
148
- /** Colours that actually ran after minor stated shares were omitted. */
149
- colours: {
150
- hex: string;
151
- proportion?: number;
152
- weight?: number;
153
- }[];
154
- /** Colours not searched because their stated share was below 5%. */
155
- droppedColours: {
156
- hex: string;
157
- proportion?: number;
158
- weight?: number;
159
- }[];
160
- logic: PaletteLogic;
161
- /** `no_effective_colours` means no material query ran. */
162
- outcome: OpenEnum<"matches" | "no_effective_colours">;
163
- };
164
- /** The category gate the page ran under. */
165
- categoryGate?: ColourCategoryGate;
166
- /** The thresholds behind each receipt's `hueCompatible`. Absent only on responses stored before it existed. */
167
- hueGate?: HueGateReceipt;
168
- /** `matches.length`, capped by `limit`. Never a corpus total. */
169
- count: number;
170
- matches: PaletteMatch[];
171
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,254 +0,0 @@
1
- import type { MatchTarget } from "@instruments/colorscope/match";
2
- import type { ColorResolution } from "@instruments/colorscope/naming";
3
- import type { SearchFilter } from "./search-refinement-types.js";
4
- import type { OpenEnum } from "./types.js";
5
- export type QuerySenseKind = OpenEnum<"brand" | "product" | "paint_identity" | "category" | "material" | "colour" | "attribute" | "attribute_value" | "certification">;
6
- export type QuerySense = {
7
- id: string;
8
- kind: QuerySenseKind;
9
- label: string;
10
- outcome: OpenEnum<"applied" | "ambiguous" | "recognized" | "refused">;
11
- effect: OpenEnum<"restrict" | "prioritize" | "rerank" | "offer" | "none">;
12
- confidence: number;
13
- evidence: {
14
- source: string;
15
- matchedText: string;
16
- span?: {
17
- start: number;
18
- end: number;
19
- };
20
- };
21
- entity?: {
22
- brandSlug?: string;
23
- productId?: string;
24
- variantId?: string;
25
- materialBankId?: string;
26
- productTypeId?: string;
27
- paintCode?: string;
28
- hex?: string;
29
- };
30
- reason?: string;
31
- };
32
- export type CanonicalLexicalAuthorityReceipt = {
33
- authority: OpenEnum<"taxonomy" | "colorscope">;
34
- version: string;
35
- revision: string;
36
- digest?: string;
37
- };
38
- export type CanonicalLexicalReading = {
39
- matchTarget?: MatchTarget;
40
- colorResolution?: ColorResolution;
41
- authority: OpenEnum<"taxonomy" | "colorscope">;
42
- identity: string;
43
- outcome: OpenEnum<"equivalent" | "ambiguous" | "declined">;
44
- executionStatus: OpenEnum<"applied" | "suppressed" | "executable" | "recognized-but-unexecutable" | "declined">;
45
- role: OpenEnum<"primary" | "secondary"> | null;
46
- kind?: OpenEnum<"domain" | "core-colour" | "paint">;
47
- label?: string;
48
- libraryId?: string;
49
- code?: string;
50
- aliasCount?: number;
51
- matchForm?: OpenEnum<"name" | "code" | "authoritative-term">;
52
- collisionCount?: number;
53
- familyId?: string;
54
- hex?: string;
55
- level?: OpenEnum<"family" | "tone-band" | "branch" | "concept">;
56
- lifecycle?: {
57
- introducedAt: string;
58
- reviewedAt?: string;
59
- status: string;
60
- };
61
- provenance?: {
62
- basis: string;
63
- snapshot?: string;
64
- source: string;
65
- };
66
- };
67
- export type CanonicalLexicalMatch = {
68
- original: string;
69
- canonical: string;
70
- rule: OpenEnum<"exact" | "plural-to-singular" | "typo-to-canonical">;
71
- span: {
72
- start: number;
73
- end: number;
74
- };
75
- coverage: number;
76
- readings: CanonicalLexicalReading[];
77
- receipt: {
78
- original: string;
79
- canonical: string;
80
- rule: OpenEnum<"exact" | "plural-to-singular" | "typo-to-canonical">;
81
- authorities: CanonicalLexicalAuthorityReceipt[];
82
- };
83
- };
84
- export type CanonicalLexicalReceipt = {
85
- original: string;
86
- outcome: OpenEnum<"resolved" | "ambiguous" | "declined" | "partial" | "unresolved">;
87
- matches: CanonicalLexicalMatch[];
88
- unresolved: CanonicalLexicalMatch[];
89
- };
90
- export type QueryResidualReceipt = {
91
- kind: OpenEnum<"compound" | "descriptive" | "ambiguous" | "empty">;
92
- tokens: string[];
93
- resolvedTokens: string[];
94
- unresolvedTokens: string[];
95
- resolvedRatio: number;
96
- comparisonFrame: boolean;
97
- };
98
- /** Deterministic criteria compiled from the query before retrieval. */
99
- export type QueryCriteriaReceipt = {
100
- applied: {
101
- criterion: SearchFilter;
102
- lane: OpenEnum<"filter" | "preference">;
103
- lexicalSignal?: {
104
- attributeId: string;
105
- canonical: string;
106
- identity: string;
107
- original: string;
108
- relation: OpenEnum<"equivalent" | "broader-storage-term">;
109
- span: {
110
- start: number;
111
- end: number;
112
- };
113
- storedTerm: string;
114
- };
115
- source: OpenEnum<"compiled" | "taxonomy-adapter">;
116
- span: string;
117
- }[];
118
- conflicts: {
119
- attributeId: string;
120
- caller: SearchFilter;
121
- compiled: SearchFilter;
122
- reason: string;
123
- }[];
124
- exclusions: {
125
- criterion: SearchFilter;
126
- execution: OpenEnum<"blocked-positive-only-contract">;
127
- lane: OpenEnum<"hard" | "soft">;
128
- missingValuePolicy: OpenEnum<"retain-unknown">;
129
- span: string;
130
- }[];
131
- preferences: SearchFilter[];
132
- residualText: string | null;
133
- unresolved: {
134
- code: OpenEnum<"missing-searchable-attribute" | "missing-dimension-pair-contract" | "missing-explicit-comparator" | "negative-criterion-contract-blocked" | "registry-contract-drift" | "unsupported-numeric-format" | "unsupported-unit" | "unsupported-strict-comparator">;
135
- reason: string;
136
- span: string;
137
- }[];
138
- };
139
- /** How the query named or inferred a product type before retrieval. */
140
- export type QueryProductTypeReceipt = {
141
- kind: OpenEnum<"leaf" | "group" | "vector" | "ambiguous" | "none">;
142
- gate: OpenEnum<"hard" | "constrain" | "none">;
143
- pass: OpenEnum<"taxonomy" | "synonym" | "display-name" | "group" | "head-noun" | "vector" | "none">;
144
- reason: string;
145
- displayName: string | null;
146
- productTypeId: string | null;
147
- groupKey: string | null;
148
- productTypeIds: string[];
149
- similarity: number | null;
150
- margin: number | null;
151
- residualText: string;
152
- vectorPassRan: boolean;
153
- registryVersion: string;
154
- durationMs: number;
155
- candidates: {
156
- productTypeId: string;
157
- displayName: string;
158
- similarity: number;
159
- }[];
160
- };
161
- /** The selected retrieval arm; null when the path is browse or criteria-only. */
162
- export type QueryArmReceipt = {
163
- arm: OpenEnum<"dense" | "lexical" | "colour"> | null;
164
- reason: string;
165
- reasonDetail?: OpenEnum<"derived-colour-veto" | "typo-recovery" | "literal-compound-without-type">;
166
- outcome: OpenEnum<"dense" | "lexical" | "colour" | "browse" | "criteria-only" | "ambiguous">;
167
- decidedBy: OpenEnum<"deterministic" | "model">;
168
- productTypeGate: OpenEnum<"hard" | "constrain" | "none">;
169
- productTypeIds: string[];
170
- residual: QueryResidualReceipt;
171
- registryVersion: string;
172
- };
173
- export type QueryAmbiguityReceipt = {
174
- outcome: OpenEnum<"applied" | "abstained" | "refused" | "timeout">;
175
- modelId: string | null;
176
- providerRan: boolean;
177
- durationMs: number;
178
- timeoutMs: number;
179
- validation: OpenEnum<"valid" | "invalid" | "not-run">;
180
- refusalCode: string | null;
181
- confidence: number | null;
182
- routing: OpenEnum<"compound" | "descriptive"> | null;
183
- productTypeIds: string[];
184
- changedArm: boolean;
185
- };
186
- export type QueryCategoryScopeReceipt = {
187
- source: OpenEnum<"caller" | "anchor">;
188
- mechanism: OpenEnum<"sql-predicate" | "provider-filter" | "allowlist" | "prune">;
189
- variantCount: number | null;
190
- ceiling: number;
191
- specScanBounded?: boolean;
192
- [key: string]: unknown;
193
- };
194
- export type QuerySpecAllowlistReceipt = {
195
- limit: number;
196
- returned: number;
197
- retrieved?: number;
198
- truncated: boolean;
199
- emptyMeansScarcity: boolean;
200
- outcome?: OpenEnum<"corpus-scarcity" | "retrieval-miss" | "unknown">;
201
- };
202
- /**
203
- * Whether the phrase-reading step turned the query's descriptive words into
204
- * filters and preferences. Present only on the workflow lane.
205
- */
206
- export type QueryPhraseReadingReceipt = {
207
- outcome: OpenEnum<"skipped">;
208
- reason: string;
209
- } | {
210
- outcome: OpenEnum<"read">;
211
- /** Which model read the phrase: `jev`, or `second` behind it. */
212
- reader: OpenEnum<"jev" | "second">;
213
- elapsedMs: number;
214
- leftAsText: string[];
215
- rows: {
216
- kind: OpenEnum<"want" | "avoid">;
217
- attributeId: string;
218
- values: string[];
219
- confidence: number;
220
- applied: boolean;
221
- }[];
222
- };
223
- export type QueryUnsatisfiableNarrowing = {
224
- narrowing: OpenEnum<"product-type">;
225
- gate: OpenEnum<"hard">;
226
- productTypeId: string;
227
- displayName: string;
228
- productTypeIds: string[];
229
- pass: string;
230
- evidence: OpenEnum<"zero-accepted-variants">;
231
- relaxedDisplayName?: string;
232
- relaxedProductTypeId?: string;
233
- relaxedProductTypeIds?: string[];
234
- relaxedTo: OpenEnum<"head-noun" | "none">;
235
- };
236
- /** Inspectable interpretation of the raw query by ordinary MaterialGraph search. */
237
- export type QueryUnderstanding = {
238
- version: OpenEnum<"1">;
239
- rawQuery: string;
240
- normalisedQuery: string;
241
- residualText: string;
242
- status: OpenEnum<"resolved" | "ambiguous" | "partial" | "unresolved">;
243
- mode: OpenEnum<"image" | "colour" | "text" | "lexical" | "entity-browse" | "attribute">;
244
- senses: QuerySense[];
245
- canonicalLexical?: CanonicalLexicalReceipt;
246
- criteria?: QueryCriteriaReceipt;
247
- productType?: QueryProductTypeReceipt;
248
- arm?: QueryArmReceipt;
249
- ambiguity?: QueryAmbiguityReceipt;
250
- categoryScope?: QueryCategoryScopeReceipt;
251
- specAllowlist?: QuerySpecAllowlistReceipt;
252
- unsatisfiableNarrowing?: QueryUnsatisfiableNarrowing;
253
- phraseReading?: QueryPhraseReadingReceipt;
254
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};