@instruments/materialgraph 0.7.0 → 0.7.1
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/by-spec-types.d.ts +45 -0
- package/catalog-discovery-types.d.ts +30 -14
- package/client.d.ts +4 -1
- package/client.js +4 -1
- package/package.json +1 -1
- package/types.d.ts +1 -0
package/by-spec-types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ValueResolution } from "./catalog-discovery-types.js";
|
|
1
2
|
import type { VariantId } from "./identifiers.js";
|
|
2
3
|
/**
|
|
3
4
|
* One criterion a match satisfied, with the trust behind it.
|
|
@@ -107,6 +108,32 @@ export interface BySpecMatch {
|
|
|
107
108
|
minConfidence: number | null;
|
|
108
109
|
verdict: BySpecVerdict;
|
|
109
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* One criterion the server could not resolve to canonical vocabulary, with the
|
|
113
|
+
* resolver's ranked suggestions for it.
|
|
114
|
+
*
|
|
115
|
+
* `attributeId` and `value` echo the parsed criterion, both of them, so a failed
|
|
116
|
+
* query can be restated without losing either half. (The HTTP route trims the
|
|
117
|
+
* attribute and value around the first `:` before validation.) Which HALF failed
|
|
118
|
+
* is read off `resolution.query`, the token actually resolved:
|
|
119
|
+
*
|
|
120
|
+
* - `resolution.query === attributeId` — the attribute id is unknown, and
|
|
121
|
+
* `resolution.candidates` are ATTRIBUTE ids.
|
|
122
|
+
* - `resolution.query === value` — the attribute is known but its value is no
|
|
123
|
+
* canonical term, and `resolution.candidates` are TERM ids, each carrying the
|
|
124
|
+
* `dictionaryId` it came from.
|
|
125
|
+
*
|
|
126
|
+
* EVERY miss is reported, not just the first, so one round trip is enough to fix
|
|
127
|
+
* a whole spec.
|
|
128
|
+
*/
|
|
129
|
+
export interface BySpecUnresolvedCriterion {
|
|
130
|
+
/** The parsed attribute id, after the route's surrounding-whitespace trim. */
|
|
131
|
+
attributeId: string;
|
|
132
|
+
/** The parsed value — never overwritten by the attribute id when that id is unknown. */
|
|
133
|
+
value: string;
|
|
134
|
+
/** Ranked candidates for whichever half failed. See {@link ValueResolution}. */
|
|
135
|
+
resolution: ValueResolution;
|
|
136
|
+
}
|
|
110
137
|
/**
|
|
111
138
|
* The find-by-spec envelope — A PAGE, AND NOTHING BUT A PAGE.
|
|
112
139
|
*
|
|
@@ -116,6 +143,9 @@ export interface BySpecMatch {
|
|
|
116
143
|
* states NO corpus total, so "N materials meet this specification" is not a
|
|
117
144
|
* claim you can make from one response. Raise `limit`, or say "at least N".
|
|
118
145
|
* `brandsSpanned` is likewise the brand count OF THIS SAMPLE.
|
|
146
|
+
*
|
|
147
|
+
* And check `unresolvedCriteria` BEFORE reading any of that: when it is present
|
|
148
|
+
* the numbers beside it describe a query that never ran.
|
|
119
149
|
*/
|
|
120
150
|
export interface BySpecResponse {
|
|
121
151
|
/** The criteria as parsed — check them before trusting a surprising result. */
|
|
@@ -129,4 +159,19 @@ export interface BySpecResponse {
|
|
|
129
159
|
brandsSpanned: number;
|
|
130
160
|
/** The sample, photo-first, capped by `limit`. */
|
|
131
161
|
matches: BySpecMatch[];
|
|
162
|
+
/**
|
|
163
|
+
* Present ONLY when a criterion failed exact canonical-vocabulary membership —
|
|
164
|
+
* and its presence means THE QUERY WAS NEVER RUN. A pre-flight gate short-circuits
|
|
165
|
+
* before the search, so the rest of the envelope is a placeholder rather than
|
|
166
|
+
* a finding: `matches` is `[]` and `totalMatches` is `0` because nothing was
|
|
167
|
+
* searched, not because nothing qualifies. Reporting that zero as "no material
|
|
168
|
+
* meets this specification" states a fact about the corpus on the strength of
|
|
169
|
+
* a question nobody asked it.
|
|
170
|
+
*
|
|
171
|
+
* Treat these criteria as UNAPPLIED and surface them: retry with a
|
|
172
|
+
* `resolution.candidates` id (subject to `recommendedAction` — `ambiguous`
|
|
173
|
+
* means ask, not pick), or say the value could not be resolved. Absent means
|
|
174
|
+
* every criterion resolved and the query did run.
|
|
175
|
+
*/
|
|
176
|
+
unresolvedCriteria?: BySpecUnresolvedCriterion[];
|
|
132
177
|
}
|
|
@@ -24,6 +24,34 @@ export interface ResolveValueCandidate {
|
|
|
24
24
|
/** Present only for a colour_family candidate resolved via the colorscope fallback. */
|
|
25
25
|
via?: OpenEnum<"colorscope">;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* The resolver's verdict on ONE free-text token — the single shape every
|
|
29
|
+
* resolving surface speaks, so a caller learns to read it once. Returned whole
|
|
30
|
+
* by {@link MaterialGraphClient.resolveAttributeValue}, and carried per bad
|
|
31
|
+
* criterion by `bySpec`'s `unresolvedCriteria`.
|
|
32
|
+
*
|
|
33
|
+
* READ `recommendedAction`, NOT JUST `best`. `ambiguous` with a populated
|
|
34
|
+
* `candidates` list means the phrase genuinely matched several terms — taking
|
|
35
|
+
* `best` silently there is how a query ends up answering a question nobody
|
|
36
|
+
* asked. `unresolved` means no candidate cleared the resolver's confidence
|
|
37
|
+
* threshold (and may still carry weak candidates); it says nothing about how
|
|
38
|
+
* many materials would match a corrected criterion.
|
|
39
|
+
*
|
|
40
|
+
* The resolver ranks, classifies and reports; it never substitutes the nearest
|
|
41
|
+
* token for the one you asked for. `best` is populated whenever ANY candidate
|
|
42
|
+
* exists — including under an `ambiguous` or `unresolved` status — so it is a
|
|
43
|
+
* leader, not a licence.
|
|
44
|
+
*
|
|
45
|
+
* `query` is the trimmed token that was actually resolved, which is how you tell
|
|
46
|
+
* WHICH half of a failed `attribute:value` pair was the problem.
|
|
47
|
+
*/
|
|
48
|
+
export interface ValueResolution {
|
|
49
|
+
status: OpenEnum<"resolved" | "ambiguous" | "unresolved">;
|
|
50
|
+
query: string;
|
|
51
|
+
best: ResolveValueCandidate | null;
|
|
52
|
+
candidates: ResolveValueCandidate[];
|
|
53
|
+
recommendedAction: OpenEnum<"use_best" | "choose_from_candidates" | "ask_user" | "none_found">;
|
|
54
|
+
}
|
|
27
55
|
/** Response from resolving a free-text value against one attribute's dictionary. */
|
|
28
56
|
export interface ResolveAttributeValueResponse {
|
|
29
57
|
attribute: {
|
|
@@ -31,20 +59,8 @@ export interface ResolveAttributeValueResponse {
|
|
|
31
59
|
name: string;
|
|
32
60
|
dictionaryId: string;
|
|
33
61
|
};
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
* `candidates` list means the phrase genuinely matched several terms — taking
|
|
37
|
-
* `best` silently there is how a query ends up answering a question nobody
|
|
38
|
-
* asked. `unresolved` means the vocabulary holds nothing like it, which is not
|
|
39
|
-
* the same as the corpus holding no such materials.
|
|
40
|
-
*/
|
|
41
|
-
resolution: {
|
|
42
|
-
status: OpenEnum<"resolved" | "ambiguous" | "unresolved">;
|
|
43
|
-
query: string;
|
|
44
|
-
best: ResolveValueCandidate | null;
|
|
45
|
-
candidates: ResolveValueCandidate[];
|
|
46
|
-
recommendedAction: OpenEnum<"use_best" | "choose_from_candidates" | "ask_user" | "none_found">;
|
|
47
|
-
};
|
|
62
|
+
/** The verdict on `q`. Read `recommendedAction` — see {@link ValueResolution}. */
|
|
63
|
+
resolution: ValueResolution;
|
|
48
64
|
}
|
|
49
65
|
/** Options for searching registry attributes and value-dictionary terms together. */
|
|
50
66
|
export interface VocabularySearchOptions {
|
package/client.d.ts
CHANGED
|
@@ -333,7 +333,10 @@ export declare class MaterialGraphClient {
|
|
|
333
333
|
* Instead use `search({ filters })` when the spec merely GATES a ranked
|
|
334
334
|
* question, `codes.advisory()` when the real question is what a space demands,
|
|
335
335
|
* and {@link MaterialGraphClient.specificationFacets} first if you do not know
|
|
336
|
-
* the canonical tokens
|
|
336
|
+
* the canonical tokens. Guessing one no longer returns a silently empty
|
|
337
|
+
* answer: an unresolvable criterion means the query NEVER RAN, and the
|
|
338
|
+
* response says so — read {@link BySpecResponse.unresolvedCriteria} before
|
|
339
|
+
* treating an empty `matches` as "nothing qualifies".
|
|
337
340
|
*
|
|
338
341
|
* A PAGE, NOT A CORPUS, unusually so: `totalMatches` is the size of the
|
|
339
342
|
* returned sample under `limit`, not a corpus count. See {@link BySpecResponse}.
|
package/client.js
CHANGED
|
@@ -398,7 +398,10 @@ export class MaterialGraphClient {
|
|
|
398
398
|
* Instead use `search({ filters })` when the spec merely GATES a ranked
|
|
399
399
|
* question, `codes.advisory()` when the real question is what a space demands,
|
|
400
400
|
* and {@link MaterialGraphClient.specificationFacets} first if you do not know
|
|
401
|
-
* the canonical tokens
|
|
401
|
+
* the canonical tokens. Guessing one no longer returns a silently empty
|
|
402
|
+
* answer: an unresolvable criterion means the query NEVER RAN, and the
|
|
403
|
+
* response says so — read {@link BySpecResponse.unresolvedCriteria} before
|
|
404
|
+
* treating an empty `matches` as "nothing qualifies".
|
|
402
405
|
*
|
|
403
406
|
* A PAGE, NOT A CORPUS, unusually so: `totalMatches` is the size of the
|
|
404
407
|
* returned sample under `limit`, not a corpus count. See {@link BySpecResponse}.
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -695,6 +695,7 @@ export interface MaterialsBatchOptions {
|
|
|
695
695
|
export interface PairingsOptions {
|
|
696
696
|
/** Comma-separated coarse category display names; filters both arms. */
|
|
697
697
|
categories?: string;
|
|
698
|
+
/** Page size, 1–24 inclusive (default 12). The server rejects (400), not clamps, values outside this range. */
|
|
698
699
|
limit?: number;
|
|
699
700
|
/** Graph-owned order applied within fixed cospec → considered → colour tiers. */
|
|
700
701
|
order?: PairingOrderMode;
|