@modainteract/moda-interact-shared 1.2.0 → 1.3.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/dist/commerce/index.d.ts +43 -1
- package/dist/commerce/index.js +388 -0
- package/dist/commerce/index.js.map +1 -1
- package/package.json +1 -1
package/dist/commerce/index.d.ts
CHANGED
|
@@ -380,6 +380,48 @@ type CodeResponseProcessorResult = {
|
|
|
380
380
|
};
|
|
381
381
|
};
|
|
382
382
|
|
|
383
|
+
declare const STORE_CATEGORY_PROMPT_RUNTIME_VERSION: "store-category-prompt.v1";
|
|
384
|
+
declare const MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS = 100000;
|
|
385
|
+
declare const MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS = 100000;
|
|
386
|
+
declare const MAX_STORE_CATEGORY_PROMPT_CONDITIONS = 256;
|
|
387
|
+
declare const StoreCategoryPromptConditionKeySchema: z.ZodString;
|
|
388
|
+
type StoreCategoryPromptConditionKey = z.infer<typeof StoreCategoryPromptConditionKeySchema>;
|
|
389
|
+
declare const StoreCategoryPromptContextSchema: z.ZodObject<{
|
|
390
|
+
mappings: z.ZodRecord<z.ZodString, z.ZodBoolean>;
|
|
391
|
+
}, z.core.$strict>;
|
|
392
|
+
type StoreCategoryPromptContext = z.infer<typeof StoreCategoryPromptContextSchema>;
|
|
393
|
+
type StoreCategoryPromptTemplateIssue = {
|
|
394
|
+
path: "/promptText";
|
|
395
|
+
code: "invalid_prompt_source" | "unsupported_template_construct" | "invalid_template_structure" | "invalid_template_expression" | "invalid_mapping_condition" | "unknown_mapping_condition" | "template_too_complex" | "rendered_prompt_too_large";
|
|
396
|
+
message: string;
|
|
397
|
+
};
|
|
398
|
+
type StoreCategoryPromptTemplateValidation = {
|
|
399
|
+
valid: boolean;
|
|
400
|
+
issues: StoreCategoryPromptTemplateIssue[];
|
|
401
|
+
referencedConditionKeys: string[];
|
|
402
|
+
};
|
|
403
|
+
type StoreCategoryPromptRenderResult = {
|
|
404
|
+
ok: true;
|
|
405
|
+
promptText: string;
|
|
406
|
+
referencedConditionKeys: string[];
|
|
407
|
+
} | {
|
|
408
|
+
ok: false;
|
|
409
|
+
issues: StoreCategoryPromptTemplateIssue[];
|
|
410
|
+
};
|
|
411
|
+
declare function validateStoreCategoryPromptTemplate(input: {
|
|
412
|
+
source: string;
|
|
413
|
+
availableConditionKeys: readonly string[];
|
|
414
|
+
}): StoreCategoryPromptTemplateValidation;
|
|
415
|
+
declare function createStoreCategoryPromptConditionBlock(conditionKey: string): string;
|
|
416
|
+
declare function createStoreCategoryPromptContext(input: {
|
|
417
|
+
availableConditionKeys: readonly string[];
|
|
418
|
+
selectedConditionKeys: readonly string[];
|
|
419
|
+
}): StoreCategoryPromptContext;
|
|
420
|
+
declare function renderStoreCategoryPromptTemplate(input: {
|
|
421
|
+
source: string;
|
|
422
|
+
context: StoreCategoryPromptContext;
|
|
423
|
+
}): StoreCategoryPromptRenderResult;
|
|
424
|
+
|
|
383
425
|
/** Synthetic examples; no provider identity, schema artifact or publication claim. */
|
|
384
426
|
|
|
385
427
|
declare const exampleTool: ToolDescriptor;
|
|
@@ -389,4 +431,4 @@ declare function exampleManifest(digest: Digest, withTool?: boolean): CommerceMa
|
|
|
389
431
|
declare function exampleGrant(manifest: CommerceManifest): CommerceConversationGrant;
|
|
390
432
|
declare const exampleFinal: CommerceFinalResponse;
|
|
391
433
|
|
|
392
|
-
export { type CodeResponseProcessorInput, type CodeResponseProcessorResult, CommerceConversationGrant, CommerceFinalResponse, CommerceManifest, CommerceToolDefinition, CommerceTurnIdentity, type ConnectionCommand, ConnectionCommandSchema, ConnectionIssueSchema, type ConnectionResult, ConnectionResultSchema, type ConnectionRevisionView, ConnectionRevisionViewSchema, type ConnectionView, ConnectionViewSchema, ContractVersionSchema, type CredentialStatus, CredentialStatusSchema, CurrencySchema, DateSchema, Digest, type ExternalHttpResultData, ExternalHttpResultDataSchema, ExternalPathSchema, ExternalQueryMappingSchema, ExternalQueryMappingsSchema, ExternalQueryValueSchema, type ExternalResponseFormat, ExternalResponseFormatSchema, type FeatureFacts, type FieldProjection, FieldProjectionSchema, GrantedTool, HashSchema, IdSchema, LanguageSchema, MoneySchema, type ResponseFilter, ResponseFilterSchema, type ResponseProcessing, ResponseProcessingSchema, type RevisionInput, RevisionInputSchema, SemverSchema, SubsetSchema, ToolDescriptor, type TransformResponse, TransformResponseSchema, type TransformSample, TransformSampleSchema, type VisualResponseProcessing, VisualResponseProcessingSchema, type VisualResponseProcessorInput, type VisualResponseProcessorResult, boundedJson, currentlyGrantedTools, deduplicateTools, distinct, exampleDefinition, exampleFinal, exampleGrant, exampleManifest, exampleTool, exampleTurn, manifestMatchesGrant, parseCommerceManifest, selectCapabilities };
|
|
434
|
+
export { type CodeResponseProcessorInput, type CodeResponseProcessorResult, CommerceConversationGrant, CommerceFinalResponse, CommerceManifest, CommerceToolDefinition, CommerceTurnIdentity, type ConnectionCommand, ConnectionCommandSchema, ConnectionIssueSchema, type ConnectionResult, ConnectionResultSchema, type ConnectionRevisionView, ConnectionRevisionViewSchema, type ConnectionView, ConnectionViewSchema, ContractVersionSchema, type CredentialStatus, CredentialStatusSchema, CurrencySchema, DateSchema, Digest, type ExternalHttpResultData, ExternalHttpResultDataSchema, ExternalPathSchema, ExternalQueryMappingSchema, ExternalQueryMappingsSchema, ExternalQueryValueSchema, type ExternalResponseFormat, ExternalResponseFormatSchema, type FeatureFacts, type FieldProjection, FieldProjectionSchema, GrantedTool, HashSchema, IdSchema, LanguageSchema, MAX_STORE_CATEGORY_PROMPT_CONDITIONS, MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS, MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS, MoneySchema, type ResponseFilter, ResponseFilterSchema, type ResponseProcessing, ResponseProcessingSchema, type RevisionInput, RevisionInputSchema, STORE_CATEGORY_PROMPT_RUNTIME_VERSION, SemverSchema, type StoreCategoryPromptConditionKey, StoreCategoryPromptConditionKeySchema, type StoreCategoryPromptContext, StoreCategoryPromptContextSchema, type StoreCategoryPromptRenderResult, type StoreCategoryPromptTemplateIssue, type StoreCategoryPromptTemplateValidation, SubsetSchema, ToolDescriptor, type TransformResponse, TransformResponseSchema, type TransformSample, TransformSampleSchema, type VisualResponseProcessing, VisualResponseProcessingSchema, type VisualResponseProcessorInput, type VisualResponseProcessorResult, boundedJson, createStoreCategoryPromptConditionBlock, createStoreCategoryPromptContext, currentlyGrantedTools, deduplicateTools, distinct, exampleDefinition, exampleFinal, exampleGrant, exampleManifest, exampleTool, exampleTurn, manifestMatchesGrant, parseCommerceManifest, renderStoreCategoryPromptTemplate, selectCapabilities, validateStoreCategoryPromptTemplate };
|
package/dist/commerce/index.js
CHANGED
|
@@ -95,6 +95,384 @@ import {
|
|
|
95
95
|
} from "../chunk-AUS3WQIW.js";
|
|
96
96
|
import "../chunk-4KSODB2R.js";
|
|
97
97
|
|
|
98
|
+
// src/commerce/store-category-prompt.ts
|
|
99
|
+
import { z } from "zod";
|
|
100
|
+
var STORE_CATEGORY_PROMPT_RUNTIME_VERSION = "store-category-prompt.v1";
|
|
101
|
+
var MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS = 1e5;
|
|
102
|
+
var MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS = 1e5;
|
|
103
|
+
var MAX_STORE_CATEGORY_PROMPT_CONDITIONS = 256;
|
|
104
|
+
var MAX_CONTROL_TAGS = 512;
|
|
105
|
+
var MAX_CONTROL_DEPTH = 8;
|
|
106
|
+
var MAX_EXPRESSION_CHARS = 1024;
|
|
107
|
+
var forbiddenConditionKeys = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
|
|
108
|
+
var conditionKeyPattern = /^[a-z][a-z0-9_]{0,127}$/;
|
|
109
|
+
var StoreCategoryPromptConditionKeySchema = z.string().regex(conditionKeyPattern).refine((value) => !forbiddenConditionKeys.has(value));
|
|
110
|
+
var StoreCategoryPromptContextSchema = z.strictObject({
|
|
111
|
+
mappings: z.record(StoreCategoryPromptConditionKeySchema, z.boolean()).refine((value) => Object.keys(value).length <= MAX_STORE_CATEGORY_PROMPT_CONDITIONS)
|
|
112
|
+
});
|
|
113
|
+
function issue(code, message) {
|
|
114
|
+
return { path: "/promptText", code, message };
|
|
115
|
+
}
|
|
116
|
+
function boundedIssues(issues) {
|
|
117
|
+
return issues.slice(0, 32).map((entry) => ({
|
|
118
|
+
path: entry.path,
|
|
119
|
+
code: entry.code,
|
|
120
|
+
message: entry.message.slice(0, 512)
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
function sourceLength(value) {
|
|
124
|
+
return Array.from(value).length;
|
|
125
|
+
}
|
|
126
|
+
function findNextMarker(source, start) {
|
|
127
|
+
let best = null;
|
|
128
|
+
for (const marker of ["{%", "{{", "{#"]) {
|
|
129
|
+
const index = source.indexOf(marker, start);
|
|
130
|
+
if (index >= 0 && (!best || index < best.index)) best = { index, marker };
|
|
131
|
+
}
|
|
132
|
+
return best;
|
|
133
|
+
}
|
|
134
|
+
function tokenizeTemplate(source, issues) {
|
|
135
|
+
const tokens = [];
|
|
136
|
+
let cursor = 0;
|
|
137
|
+
while (cursor < source.length) {
|
|
138
|
+
const next = findNextMarker(source, cursor);
|
|
139
|
+
if (!next) {
|
|
140
|
+
tokens.push({ kind: "text", text: source.slice(cursor) });
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
if (next.index > cursor) tokens.push({ kind: "text", text: source.slice(cursor, next.index) });
|
|
144
|
+
const closeMarker = next.marker === "{%" ? "%}" : next.marker === "{{" ? "}}" : "#}";
|
|
145
|
+
const close = source.indexOf(closeMarker, next.index + 2);
|
|
146
|
+
if (close < 0) {
|
|
147
|
+
issues.push(issue("invalid_template_structure", `Unclosed ${next.marker} template construct.`));
|
|
148
|
+
tokens.push({ kind: "text", text: source.slice(next.index) });
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
const raw = source.slice(next.index + 2, close).trim();
|
|
152
|
+
if (next.marker === "{%") tokens.push({ kind: "control", source: raw });
|
|
153
|
+
else tokens.push({ kind: "unsupported", source: raw, marker: next.marker === "{{" ? "interpolation" : "comment" });
|
|
154
|
+
cursor = close + 2;
|
|
155
|
+
}
|
|
156
|
+
if (source.length === 0) tokens.push({ kind: "text", text: "" });
|
|
157
|
+
return tokens;
|
|
158
|
+
}
|
|
159
|
+
function lexExpression(source, issues) {
|
|
160
|
+
if (sourceLength(source) > MAX_EXPRESSION_CHARS) {
|
|
161
|
+
issues.push(issue("template_too_complex", `Conditional expressions must not exceed ${MAX_EXPRESSION_CHARS} characters.`));
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
const tokens = [];
|
|
165
|
+
let cursor = 0;
|
|
166
|
+
while (cursor < source.length) {
|
|
167
|
+
const char = source[cursor];
|
|
168
|
+
if (/\s/.test(char)) {
|
|
169
|
+
cursor += 1;
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (char === ".") {
|
|
173
|
+
tokens.push({ kind: "dot" });
|
|
174
|
+
cursor += 1;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (char === "(") {
|
|
178
|
+
tokens.push({ kind: "lparen" });
|
|
179
|
+
cursor += 1;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (char === ")") {
|
|
183
|
+
tokens.push({ kind: "rparen" });
|
|
184
|
+
cursor += 1;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const match = /^[A-Za-z_][A-Za-z0-9_]*/.exec(source.slice(cursor));
|
|
188
|
+
if (!match) {
|
|
189
|
+
issues.push(issue("invalid_template_expression", "Conditional expressions may only use mappings.<conditionKey>, not, and, or, and parentheses."));
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
tokens.push({ kind: "word", value: match[0] });
|
|
193
|
+
cursor += match[0].length;
|
|
194
|
+
}
|
|
195
|
+
return tokens;
|
|
196
|
+
}
|
|
197
|
+
function parseExpression(source, issues, referenced) {
|
|
198
|
+
const tokens = lexExpression(source, issues);
|
|
199
|
+
if (!tokens || tokens.length === 0) {
|
|
200
|
+
if (tokens?.length === 0) issues.push(issue("invalid_template_expression", "A conditional expression is required."));
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
let index = 0;
|
|
204
|
+
const peekWord = (word) => {
|
|
205
|
+
const token = tokens[index];
|
|
206
|
+
return token?.kind === "word" && token.value === word;
|
|
207
|
+
};
|
|
208
|
+
const parsePrimary = () => {
|
|
209
|
+
const token = tokens[index];
|
|
210
|
+
if (token?.kind === "lparen") {
|
|
211
|
+
index += 1;
|
|
212
|
+
const inner = parseOr();
|
|
213
|
+
if (tokens[index]?.kind !== "rparen") {
|
|
214
|
+
issues.push(issue("invalid_template_expression", "Conditional expression parentheses are unbalanced."));
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
index += 1;
|
|
218
|
+
return inner;
|
|
219
|
+
}
|
|
220
|
+
if (!peekWord("mappings")) {
|
|
221
|
+
issues.push(issue("invalid_template_expression", "Conditional expressions must reference mappings.<conditionKey>."));
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
index += 1;
|
|
225
|
+
if (tokens[index]?.kind !== "dot") {
|
|
226
|
+
issues.push(issue("invalid_template_expression", "Mapping conditions must use mappings.<conditionKey>."));
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
index += 1;
|
|
230
|
+
const keyToken = tokens[index];
|
|
231
|
+
if (keyToken?.kind !== "word") {
|
|
232
|
+
issues.push(issue("invalid_mapping_condition", "A valid mapping condition key is required after mappings."));
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
index += 1;
|
|
236
|
+
if (!StoreCategoryPromptConditionKeySchema.safeParse(keyToken.value).success) {
|
|
237
|
+
issues.push(issue("invalid_mapping_condition", `Invalid mapping condition key: ${keyToken.value}.`));
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
if (!referenced.includes(keyToken.value)) referenced.push(keyToken.value);
|
|
241
|
+
return { kind: "condition", key: keyToken.value };
|
|
242
|
+
};
|
|
243
|
+
const parseNot = () => {
|
|
244
|
+
if (peekWord("not")) {
|
|
245
|
+
index += 1;
|
|
246
|
+
const operand = parseNot();
|
|
247
|
+
return operand ? { kind: "not", operand } : null;
|
|
248
|
+
}
|
|
249
|
+
return parsePrimary();
|
|
250
|
+
};
|
|
251
|
+
const parseAnd = () => {
|
|
252
|
+
let left = parseNot();
|
|
253
|
+
while (left && peekWord("and")) {
|
|
254
|
+
index += 1;
|
|
255
|
+
const right = parseNot();
|
|
256
|
+
if (!right) return null;
|
|
257
|
+
left = { kind: "and", left, right };
|
|
258
|
+
}
|
|
259
|
+
return left;
|
|
260
|
+
};
|
|
261
|
+
const parseOr = () => {
|
|
262
|
+
let left = parseAnd();
|
|
263
|
+
while (left && peekWord("or")) {
|
|
264
|
+
index += 1;
|
|
265
|
+
const right = parseAnd();
|
|
266
|
+
if (!right) return null;
|
|
267
|
+
left = { kind: "or", left, right };
|
|
268
|
+
}
|
|
269
|
+
return left;
|
|
270
|
+
};
|
|
271
|
+
const expression = parseOr();
|
|
272
|
+
if (expression && index !== tokens.length) {
|
|
273
|
+
issues.push(issue("invalid_template_expression", "Conditional expression contains unsupported syntax."));
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
return expression;
|
|
277
|
+
}
|
|
278
|
+
function compileStoreCategoryPromptTemplate(source) {
|
|
279
|
+
const issues = [];
|
|
280
|
+
const referencedConditionKeys = [];
|
|
281
|
+
const nodes = [];
|
|
282
|
+
if (source.trim().length === 0) issues.push(issue("invalid_prompt_source", "Prompt template must not be blank."));
|
|
283
|
+
if (sourceLength(source) > MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS) {
|
|
284
|
+
issues.push(issue("invalid_prompt_source", `Prompt template must not exceed ${MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS.toLocaleString()} characters.`));
|
|
285
|
+
}
|
|
286
|
+
const tokens = tokenizeTemplate(source, issues);
|
|
287
|
+
const stack = [];
|
|
288
|
+
let currentBody = nodes;
|
|
289
|
+
let controlCount = 0;
|
|
290
|
+
for (const token of tokens) {
|
|
291
|
+
if (token.kind === "text") {
|
|
292
|
+
if (token.text) currentBody.push({ kind: "text", text: token.text });
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
if (token.kind === "unsupported") {
|
|
296
|
+
issues.push(issue(
|
|
297
|
+
"unsupported_template_construct",
|
|
298
|
+
token.marker === "interpolation" ? "Variable interpolation is not supported in Store Category prompt templates." : "Template comments are not supported in Store Category prompt templates."
|
|
299
|
+
));
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
controlCount += 1;
|
|
303
|
+
if (controlCount > MAX_CONTROL_TAGS) {
|
|
304
|
+
issues.push(issue("template_too_complex", `Prompt template must not contain more than ${MAX_CONTROL_TAGS} control tags.`));
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
const ifMatch = /^if\s+([\s\S]+)$/.exec(token.source);
|
|
308
|
+
if (ifMatch) {
|
|
309
|
+
if (stack.length >= MAX_CONTROL_DEPTH) {
|
|
310
|
+
issues.push(issue("template_too_complex", `Conditional nesting must not exceed ${MAX_CONTROL_DEPTH} levels.`));
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
const expression = parseExpression(ifMatch[1].trim(), issues, referencedConditionKeys);
|
|
314
|
+
if (!expression) continue;
|
|
315
|
+
const branchBody = [];
|
|
316
|
+
const node = {
|
|
317
|
+
kind: "if",
|
|
318
|
+
branches: [{ expression, body: branchBody }],
|
|
319
|
+
elseBody: null
|
|
320
|
+
};
|
|
321
|
+
currentBody.push(node);
|
|
322
|
+
const frame = { node, parentBody: currentBody, currentBody: branchBody, sawElse: false };
|
|
323
|
+
stack.push(frame);
|
|
324
|
+
currentBody = branchBody;
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
const elifMatch = /^elif\s+([\s\S]+)$/.exec(token.source);
|
|
328
|
+
if (elifMatch) {
|
|
329
|
+
const frame = stack.at(-1);
|
|
330
|
+
if (!frame || frame.sawElse) {
|
|
331
|
+
issues.push(issue("invalid_template_structure", "elif must appear inside an if block and before else."));
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
const expression = parseExpression(elifMatch[1].trim(), issues, referencedConditionKeys);
|
|
335
|
+
if (!expression) continue;
|
|
336
|
+
const branchBody = [];
|
|
337
|
+
frame.node.branches.push({ expression, body: branchBody });
|
|
338
|
+
frame.currentBody = branchBody;
|
|
339
|
+
currentBody = branchBody;
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
if (token.source === "else") {
|
|
343
|
+
const frame = stack.at(-1);
|
|
344
|
+
if (!frame || frame.sawElse) {
|
|
345
|
+
issues.push(issue("invalid_template_structure", "else must appear once inside an if block."));
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
const elseBody = [];
|
|
349
|
+
frame.node.elseBody = elseBody;
|
|
350
|
+
frame.currentBody = elseBody;
|
|
351
|
+
frame.sawElse = true;
|
|
352
|
+
currentBody = elseBody;
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (token.source === "endif") {
|
|
356
|
+
const frame = stack.pop();
|
|
357
|
+
if (!frame) {
|
|
358
|
+
issues.push(issue("invalid_template_structure", "endif does not have a matching if block."));
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
currentBody = frame.parentBody;
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
issues.push(issue(
|
|
365
|
+
"unsupported_template_construct",
|
|
366
|
+
"Only if, elif, else, and endif control tags are supported in Store Category prompt templates."
|
|
367
|
+
));
|
|
368
|
+
}
|
|
369
|
+
if (stack.length) issues.push(issue("invalid_template_structure", "Every if block must end with endif."));
|
|
370
|
+
return { issues: boundedIssues(issues), nodes, referencedConditionKeys };
|
|
371
|
+
}
|
|
372
|
+
function validateAvailableConditionKeys(values, issues) {
|
|
373
|
+
if (values.length > MAX_STORE_CATEGORY_PROMPT_CONDITIONS) {
|
|
374
|
+
issues.push(issue("template_too_complex", `At most ${MAX_STORE_CATEGORY_PROMPT_CONDITIONS} mapping conditions are supported.`));
|
|
375
|
+
}
|
|
376
|
+
const keys = /* @__PURE__ */ new Set();
|
|
377
|
+
for (const value of values.slice(0, MAX_STORE_CATEGORY_PROMPT_CONDITIONS + 1)) {
|
|
378
|
+
if (!StoreCategoryPromptConditionKeySchema.safeParse(value).success) {
|
|
379
|
+
issues.push(issue("invalid_mapping_condition", `Invalid mapping condition key: ${value}.`));
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
if (keys.has(value)) {
|
|
383
|
+
issues.push(issue("invalid_mapping_condition", `Duplicate mapping condition key: ${value}.`));
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
keys.add(value);
|
|
387
|
+
}
|
|
388
|
+
return keys;
|
|
389
|
+
}
|
|
390
|
+
function validateStoreCategoryPromptTemplate(input) {
|
|
391
|
+
const compiled = compileStoreCategoryPromptTemplate(input.source);
|
|
392
|
+
const issues = [...compiled.issues];
|
|
393
|
+
const available = validateAvailableConditionKeys(input.availableConditionKeys, issues);
|
|
394
|
+
for (const key of compiled.referencedConditionKeys) {
|
|
395
|
+
if (!available.has(key)) issues.push(issue("unknown_mapping_condition", `Prompt template references unavailable mapping condition: mappings.${key}.`));
|
|
396
|
+
}
|
|
397
|
+
const bounded = boundedIssues(issues);
|
|
398
|
+
return { valid: bounded.length === 0, issues: bounded, referencedConditionKeys: compiled.referencedConditionKeys };
|
|
399
|
+
}
|
|
400
|
+
function createStoreCategoryPromptConditionBlock(conditionKey) {
|
|
401
|
+
const parsed = StoreCategoryPromptConditionKeySchema.safeParse(conditionKey);
|
|
402
|
+
if (!parsed.success) throw new TypeError(`Invalid mapping condition key: ${conditionKey}.`);
|
|
403
|
+
return `{% if mappings.${conditionKey} %}
|
|
404
|
+
|
|
405
|
+
{% endif %}`;
|
|
406
|
+
}
|
|
407
|
+
function createStoreCategoryPromptContext(input) {
|
|
408
|
+
const issues = [];
|
|
409
|
+
const available = validateAvailableConditionKeys(input.availableConditionKeys, issues);
|
|
410
|
+
const selected = validateAvailableConditionKeys(input.selectedConditionKeys, issues);
|
|
411
|
+
for (const key of selected) {
|
|
412
|
+
if (!available.has(key)) issues.push(issue("unknown_mapping_condition", `Selected mapping condition is unavailable: ${key}.`));
|
|
413
|
+
}
|
|
414
|
+
if (issues.length) throw new TypeError(issues[0].message);
|
|
415
|
+
const mappings = /* @__PURE__ */ Object.create(null);
|
|
416
|
+
for (const key of available) mappings[key] = selected.has(key);
|
|
417
|
+
return { mappings };
|
|
418
|
+
}
|
|
419
|
+
function evaluateExpression(expression, mappings) {
|
|
420
|
+
switch (expression.kind) {
|
|
421
|
+
case "condition":
|
|
422
|
+
return mappings[expression.key] === true;
|
|
423
|
+
case "not":
|
|
424
|
+
return !evaluateExpression(expression.operand, mappings);
|
|
425
|
+
case "and":
|
|
426
|
+
return evaluateExpression(expression.left, mappings) && evaluateExpression(expression.right, mappings);
|
|
427
|
+
case "or":
|
|
428
|
+
return evaluateExpression(expression.left, mappings) || evaluateExpression(expression.right, mappings);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
function renderNodes(nodes, mappings, append) {
|
|
432
|
+
for (const node of nodes) {
|
|
433
|
+
if (node.kind === "text") {
|
|
434
|
+
if (!append(node.text)) return false;
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
let renderedBranch = false;
|
|
438
|
+
for (const branch of node.branches) {
|
|
439
|
+
if (evaluateExpression(branch.expression, mappings)) {
|
|
440
|
+
if (!renderNodes(branch.body, mappings, append)) return false;
|
|
441
|
+
renderedBranch = true;
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
if (!renderedBranch && node.elseBody && !renderNodes(node.elseBody, mappings, append)) return false;
|
|
446
|
+
}
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
function renderStoreCategoryPromptTemplate(input) {
|
|
450
|
+
const contextResult = StoreCategoryPromptContextSchema.safeParse(input.context);
|
|
451
|
+
if (!contextResult.success) {
|
|
452
|
+
return { ok: false, issues: [issue("invalid_mapping_condition", "Store Category prompt context contains invalid mapping conditions.")] };
|
|
453
|
+
}
|
|
454
|
+
const availableConditionKeys = Object.keys(contextResult.data.mappings);
|
|
455
|
+
const validation = validateStoreCategoryPromptTemplate({ source: input.source, availableConditionKeys });
|
|
456
|
+
if (!validation.valid) return { ok: false, issues: validation.issues };
|
|
457
|
+
const compiled = compileStoreCategoryPromptTemplate(input.source);
|
|
458
|
+
let output = "";
|
|
459
|
+
let outputChars = 0;
|
|
460
|
+
const append = (text) => {
|
|
461
|
+
outputChars += sourceLength(text);
|
|
462
|
+
if (outputChars > MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS) return false;
|
|
463
|
+
output += text;
|
|
464
|
+
return true;
|
|
465
|
+
};
|
|
466
|
+
const rendered = renderNodes(compiled.nodes, contextResult.data.mappings, append);
|
|
467
|
+
if (!rendered) {
|
|
468
|
+
return {
|
|
469
|
+
ok: false,
|
|
470
|
+
issues: [issue("rendered_prompt_too_large", `Rendered prompt must not exceed ${MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS.toLocaleString()} characters.`)]
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
return { ok: true, promptText: output, referencedConditionKeys: validation.referencedConditionKeys };
|
|
474
|
+
}
|
|
475
|
+
|
|
98
476
|
// src/commerce/fixtures.ts
|
|
99
477
|
var exampleTool = {
|
|
100
478
|
toolId: "tool-fixture",
|
|
@@ -240,6 +618,9 @@ export {
|
|
|
240
618
|
IdSchema,
|
|
241
619
|
InputSchemaSchema,
|
|
242
620
|
LanguageSchema,
|
|
621
|
+
MAX_STORE_CATEGORY_PROMPT_CONDITIONS,
|
|
622
|
+
MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS,
|
|
623
|
+
MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS,
|
|
243
624
|
MONEY_PATTERN,
|
|
244
625
|
MoneySchema,
|
|
245
626
|
POLICY_OPERATIONS,
|
|
@@ -249,7 +630,10 @@ export {
|
|
|
249
630
|
ResponseProcessingSchema,
|
|
250
631
|
ResponseTemplateSchema,
|
|
251
632
|
RevisionInputSchema,
|
|
633
|
+
STORE_CATEGORY_PROMPT_RUNTIME_VERSION,
|
|
252
634
|
SemverSchema,
|
|
635
|
+
StoreCategoryPromptConditionKeySchema,
|
|
636
|
+
StoreCategoryPromptContextSchema,
|
|
253
637
|
ToolDescriptorSchema,
|
|
254
638
|
ToolNameSchema,
|
|
255
639
|
TransformResponseSchema,
|
|
@@ -259,6 +643,8 @@ export {
|
|
|
259
643
|
canonicalJson,
|
|
260
644
|
commerceToolResultSchema,
|
|
261
645
|
compileSubset,
|
|
646
|
+
createStoreCategoryPromptConditionBlock,
|
|
647
|
+
createStoreCategoryPromptContext,
|
|
262
648
|
currentlyGrantedTools,
|
|
263
649
|
deduplicateTools,
|
|
264
650
|
definitionToMcpDescriptor,
|
|
@@ -277,6 +663,7 @@ export {
|
|
|
277
663
|
matchesSubset,
|
|
278
664
|
parseCommerceManifest,
|
|
279
665
|
productBelongsToDomain,
|
|
666
|
+
renderStoreCategoryPromptTemplate,
|
|
280
667
|
responseContractCanonicalJson,
|
|
281
668
|
safeName,
|
|
282
669
|
safePath,
|
|
@@ -284,6 +671,7 @@ export {
|
|
|
284
671
|
toolHashInput,
|
|
285
672
|
validateDefinitionForPublication,
|
|
286
673
|
validateDefinitionVersion,
|
|
674
|
+
validateStoreCategoryPromptTemplate,
|
|
287
675
|
validateSubset,
|
|
288
676
|
verifyResponseContract
|
|
289
677
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commerce/fixtures.ts"],"sourcesContent":["/** Synthetic examples; no provider identity, schema artifact or publication claim. */\nimport type {\n CommerceManifest,\n CommerceConversationGrant,\n CommerceTurnIdentity,\n} from \"./schemas\";\nimport {\n EMPTY_RESPONSE_CONTRACT,\n type CommerceFinalResponse,\n} from \"./response\";\nimport type { Digest } from \"./canonical-json\";\nimport { responseContractCanonicalJson } from \"./canonical-json\";\nimport type { ToolDescriptor, CommerceToolDefinition } from \"./definitions\";\nexport const exampleTool: ToolDescriptor = {\n toolId: \"tool-fixture\",\n toolRevisionId: \"revision-fixture\",\n name: \"never_seeded_catalogue_facts\",\n definitionVersion: \"1.0.0\",\n description: \"Read synthetic catalogue facts.\",\n inputSchema: {\n type: \"object\",\n properties: { handle: { type: \"string\", minLength: 1, maxLength: 255 } },\n required: [\"handle\"],\n additionalProperties: false,\n },\n};\nexport const exampleDefinition: CommerceToolDefinition = {\n name: exampleTool.name,\n definitionVersion: \"1.0.0\",\n description: exampleTool.description,\n inputSchema: exampleTool.inputSchema,\n execution: {\n kind: \"SHOPIFY_STOREFRONT_QUERY\",\n executorVersion: \"1.0.0\",\n apiVersion: \"2026-07\",\n schemaHash: \"a\".repeat(64),\n document:\n \"query ProductDetails($handle: String!) { product(handle: $handle) { title description } }\",\n operationName: \"ProductDetails\",\n variables: { handle: { input: \"handle\" } },\n resultPath: \"product\",\n },\n responseTemplate: {\n kind: \"text\",\n text: \"{{result.values.title}}: {{result.values.description}}\",\n unavailable: \"Product details could not be verified.\",\n },\n};\nexport const exampleTurn: CommerceTurnIdentity = {\n contractVersion: \"commerce.v1\",\n shopId: \"shop-fixture\",\n checkoutRecoveryId: \"recovery-fixture\",\n conversationId: \"conversation-fixture\",\n inboundVersion: 1,\n};\nexport function exampleManifest(\n digest: Digest,\n withTool = false,\n): CommerceManifest {\n const capabilities = withTool\n ? [{\n capabilityId: \"capability-fixture\",\n key: \"feature_product_read\",\n featureId: \"feature-fixture\",\n position: 0,\n toolDescriptor: structuredClone(exampleTool),\n }]\n : [];\n return {\n contractVersion: \"commerce.v1\",\n releaseId: \"release-fixture\",\n runnerCompatibility: \"^1.0.0\",\n capabilities,\n featureBehaviours: withTool\n ? [{ featureId: \"feature-fixture\", behaviourPrompt: \"Synthetic Feature behavior.\" }]\n : [],\n selectedCapabilityKeys: capabilities.map((capability) => capability.key),\n grantedTools: withTool\n ? [\n {\n toolId: exampleTool.toolId,\n toolRevisionId: exampleTool.toolRevisionId,\n toolName: exampleTool.name,\n definitionVersion: \"1.0.0\",\n capabilityKeys: [\"feature_product_read\"],\n },\n ]\n : [],\n responseContract: structuredClone(EMPTY_RESPONSE_CONTRACT),\n responseContractHash: digest(\n responseContractCanonicalJson(EMPTY_RESPONSE_CONTRACT),\n ),\n };\n}\nexport function exampleGrant(\n manifest: CommerceManifest,\n): CommerceConversationGrant {\n return {\n id: \"grant-fixture\",\n shopId: exampleTurn.shopId,\n conversationId: exampleTurn.conversationId,\n initialInboundVersion: 1,\n releaseId: manifest.releaseId,\n selectedCapabilityKeys: [...manifest.selectedCapabilityKeys],\n grantedTools: structuredClone(manifest.grantedTools),\n runnerVersion: \"1.0.0\",\n createdAt: \"2026-09-20T00:00:00.000Z\",\n expiresAt: null,\n };\n}\nexport const exampleFinal: CommerceFinalResponse = {\n answerKind: \"REFER_TO_STORE\",\n replyText:\n \"I cannot verify that information. Please contact the store directly.\",\n referralReason: \"INSUFFICIENT_TOOLS\",\n detectedLanguageTag: null,\n detectedLanguageConfidence: null,\n evidenceIds: [],\n details: {},\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaO,IAAM,cAA8B;AAAA,EACzC,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN,mBAAmB;AAAA,EACnB,aAAa;AAAA,EACb,aAAa;AAAA,IACX,MAAM;AAAA,IACN,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,WAAW,GAAG,WAAW,IAAI,EAAE;AAAA,IACvE,UAAU,CAAC,QAAQ;AAAA,IACnB,sBAAsB;AAAA,EACxB;AACF;AACO,IAAM,oBAA4C;AAAA,EACvD,MAAM,YAAY;AAAA,EAClB,mBAAmB;AAAA,EACnB,aAAa,YAAY;AAAA,EACzB,aAAa,YAAY;AAAA,EACzB,WAAW;AAAA,IACT,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,YAAY;AAAA,IACZ,YAAY,IAAI,OAAO,EAAE;AAAA,IACzB,UACE;AAAA,IACF,eAAe;AAAA,IACf,WAAW,EAAE,QAAQ,EAAE,OAAO,SAAS,EAAE;AAAA,IACzC,YAAY;AAAA,EACd;AAAA,EACA,kBAAkB;AAAA,IAChB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AACF;AACO,IAAM,cAAoC;AAAA,EAC/C,iBAAiB;AAAA,EACjB,QAAQ;AAAA,EACR,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,gBAAgB;AAClB;AACO,SAAS,gBACd,QACA,WAAW,OACO;AAClB,QAAM,eAAe,WACjB,CAAC;AAAA,IACC,cAAc;AAAA,IACd,KAAK;AAAA,IACL,WAAW;AAAA,IACX,UAAU;AAAA,IACV,gBAAgB,gBAAgB,WAAW;AAAA,EAC7C,CAAC,IACD,CAAC;AACL,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,qBAAqB;AAAA,IACrB;AAAA,IACA,mBAAmB,WACf,CAAC,EAAE,WAAW,mBAAmB,iBAAiB,8BAA8B,CAAC,IACjF,CAAC;AAAA,IACL,wBAAwB,aAAa,IAAI,CAAC,eAAe,WAAW,GAAG;AAAA,IACvE,cAAc,WACV;AAAA,MACE;AAAA,QACE,QAAQ,YAAY;AAAA,QACpB,gBAAgB,YAAY;AAAA,QAC5B,UAAU,YAAY;AAAA,QACtB,mBAAmB;AAAA,QACnB,gBAAgB,CAAC,sBAAsB;AAAA,MACzC;AAAA,IACF,IACA,CAAC;AAAA,IACL,kBAAkB,gBAAgB,uBAAuB;AAAA,IACzD,sBAAsB;AAAA,MACpB,8BAA8B,uBAAuB;AAAA,IACvD;AAAA,EACF;AACF;AACO,SAAS,aACd,UAC2B;AAC3B,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,QAAQ,YAAY;AAAA,IACpB,gBAAgB,YAAY;AAAA,IAC5B,uBAAuB;AAAA,IACvB,WAAW,SAAS;AAAA,IACpB,wBAAwB,CAAC,GAAG,SAAS,sBAAsB;AAAA,IAC3D,cAAc,gBAAgB,SAAS,YAAY;AAAA,IACnD,eAAe;AAAA,IACf,WAAW;AAAA,IACX,WAAW;AAAA,EACb;AACF;AACO,IAAM,eAAsC;AAAA,EACjD,YAAY;AAAA,EACZ,WACE;AAAA,EACF,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,4BAA4B;AAAA,EAC5B,aAAa,CAAC;AAAA,EACd,SAAS,CAAC;AACZ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/commerce/store-category-prompt.ts","../../src/commerce/fixtures.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const STORE_CATEGORY_PROMPT_RUNTIME_VERSION = \"store-category-prompt.v1\" as const;\nexport const MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS = 100_000;\nexport const MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS = 100_000;\nexport const MAX_STORE_CATEGORY_PROMPT_CONDITIONS = 256;\nconst MAX_CONTROL_TAGS = 512;\nconst MAX_CONTROL_DEPTH = 8;\nconst MAX_EXPRESSION_CHARS = 1_024;\n\nconst forbiddenConditionKeys = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\nconst conditionKeyPattern = /^[a-z][a-z0-9_]{0,127}$/;\n\nexport const StoreCategoryPromptConditionKeySchema = z\n .string()\n .regex(conditionKeyPattern)\n .refine((value) => !forbiddenConditionKeys.has(value));\n\nexport type StoreCategoryPromptConditionKey = z.infer<typeof StoreCategoryPromptConditionKeySchema>;\n\nexport const StoreCategoryPromptContextSchema = z.strictObject({\n mappings: z\n .record(StoreCategoryPromptConditionKeySchema, z.boolean())\n .refine((value) => Object.keys(value).length <= MAX_STORE_CATEGORY_PROMPT_CONDITIONS),\n});\n\nexport type StoreCategoryPromptContext = z.infer<typeof StoreCategoryPromptContextSchema>;\n\nexport type StoreCategoryPromptTemplateIssue = {\n path: \"/promptText\";\n code:\n | \"invalid_prompt_source\"\n | \"unsupported_template_construct\"\n | \"invalid_template_structure\"\n | \"invalid_template_expression\"\n | \"invalid_mapping_condition\"\n | \"unknown_mapping_condition\"\n | \"template_too_complex\"\n | \"rendered_prompt_too_large\";\n message: string;\n};\n\nexport type StoreCategoryPromptTemplateValidation = {\n valid: boolean;\n issues: StoreCategoryPromptTemplateIssue[];\n referencedConditionKeys: string[];\n};\n\nexport type StoreCategoryPromptRenderResult =\n | { ok: true; promptText: string; referencedConditionKeys: string[] }\n | { ok: false; issues: StoreCategoryPromptTemplateIssue[] };\n\ntype ExpressionNode =\n | { kind: \"condition\"; key: string }\n | { kind: \"not\"; operand: ExpressionNode }\n | { kind: \"and\"; left: ExpressionNode; right: ExpressionNode }\n | { kind: \"or\"; left: ExpressionNode; right: ExpressionNode };\n\ntype TemplateNode =\n | { kind: \"text\"; text: string }\n | {\n kind: \"if\";\n branches: Array<{ expression: ExpressionNode; body: TemplateNode[] }>;\n elseBody: TemplateNode[] | null;\n };\n\ntype TemplateToken =\n | { kind: \"text\"; text: string }\n | { kind: \"control\"; source: string }\n | { kind: \"unsupported\"; source: string; marker: \"interpolation\" | \"comment\" };\n\ntype CompileResult = {\n issues: StoreCategoryPromptTemplateIssue[];\n nodes: TemplateNode[];\n referencedConditionKeys: string[];\n};\n\nfunction issue(code: StoreCategoryPromptTemplateIssue[\"code\"], message: string): StoreCategoryPromptTemplateIssue {\n return { path: \"/promptText\", code, message };\n}\n\nfunction boundedIssues(issues: StoreCategoryPromptTemplateIssue[]): StoreCategoryPromptTemplateIssue[] {\n return issues.slice(0, 32).map((entry) => ({\n path: entry.path,\n code: entry.code,\n message: entry.message.slice(0, 512),\n }));\n}\n\nfunction sourceLength(value: string): number {\n return Array.from(value).length;\n}\n\nfunction findNextMarker(source: string, start: number): { index: number; marker: \"{%\" | \"{{\" | \"{#\" } | null {\n let best: { index: number; marker: \"{%\" | \"{{\" | \"{#\" } | null = null;\n for (const marker of [\"{%\", \"{{\", \"{#\"] as const) {\n const index = source.indexOf(marker, start);\n if (index >= 0 && (!best || index < best.index)) best = { index, marker };\n }\n return best;\n}\n\nfunction tokenizeTemplate(source: string, issues: StoreCategoryPromptTemplateIssue[]): TemplateToken[] {\n const tokens: TemplateToken[] = [];\n let cursor = 0;\n while (cursor < source.length) {\n const next = findNextMarker(source, cursor);\n if (!next) {\n tokens.push({ kind: \"text\", text: source.slice(cursor) });\n break;\n }\n if (next.index > cursor) tokens.push({ kind: \"text\", text: source.slice(cursor, next.index) });\n const closeMarker = next.marker === \"{%\" ? \"%}\" : next.marker === \"{{\" ? \"}}\" : \"#}\";\n const close = source.indexOf(closeMarker, next.index + 2);\n if (close < 0) {\n issues.push(issue(\"invalid_template_structure\", `Unclosed ${next.marker} template construct.`));\n tokens.push({ kind: \"text\", text: source.slice(next.index) });\n break;\n }\n const raw = source.slice(next.index + 2, close).trim();\n if (next.marker === \"{%\") tokens.push({ kind: \"control\", source: raw });\n else tokens.push({ kind: \"unsupported\", source: raw, marker: next.marker === \"{{\" ? \"interpolation\" : \"comment\" });\n cursor = close + 2;\n }\n if (source.length === 0) tokens.push({ kind: \"text\", text: \"\" });\n return tokens;\n}\n\ntype ExprToken = { kind: \"word\"; value: string } | { kind: \"dot\" } | { kind: \"lparen\" } | { kind: \"rparen\" };\n\nfunction lexExpression(source: string, issues: StoreCategoryPromptTemplateIssue[]): ExprToken[] | null {\n if (sourceLength(source) > MAX_EXPRESSION_CHARS) {\n issues.push(issue(\"template_too_complex\", `Conditional expressions must not exceed ${MAX_EXPRESSION_CHARS} characters.`));\n return null;\n }\n const tokens: ExprToken[] = [];\n let cursor = 0;\n while (cursor < source.length) {\n const char = source[cursor];\n if (/\\s/.test(char)) {\n cursor += 1;\n continue;\n }\n if (char === \".\") {\n tokens.push({ kind: \"dot\" });\n cursor += 1;\n continue;\n }\n if (char === \"(\") {\n tokens.push({ kind: \"lparen\" });\n cursor += 1;\n continue;\n }\n if (char === \")\") {\n tokens.push({ kind: \"rparen\" });\n cursor += 1;\n continue;\n }\n const match = /^[A-Za-z_][A-Za-z0-9_]*/.exec(source.slice(cursor));\n if (!match) {\n issues.push(issue(\"invalid_template_expression\", \"Conditional expressions may only use mappings.<conditionKey>, not, and, or, and parentheses.\"));\n return null;\n }\n tokens.push({ kind: \"word\", value: match[0] });\n cursor += match[0].length;\n }\n return tokens;\n}\n\nfunction parseExpression(source: string, issues: StoreCategoryPromptTemplateIssue[], referenced: string[]): ExpressionNode | null {\n const tokens = lexExpression(source, issues);\n if (!tokens || tokens.length === 0) {\n if (tokens?.length === 0) issues.push(issue(\"invalid_template_expression\", \"A conditional expression is required.\"));\n return null;\n }\n let index = 0;\n const peekWord = (word: string) => {\n const token = tokens[index];\n return token?.kind === \"word\" && token.value === word;\n };\n\n const parsePrimary = (): ExpressionNode | null => {\n const token = tokens[index];\n if (token?.kind === \"lparen\") {\n index += 1;\n const inner = parseOr();\n if (tokens[index]?.kind !== \"rparen\") {\n issues.push(issue(\"invalid_template_expression\", \"Conditional expression parentheses are unbalanced.\"));\n return null;\n }\n index += 1;\n return inner;\n }\n if (!peekWord(\"mappings\")) {\n issues.push(issue(\"invalid_template_expression\", \"Conditional expressions must reference mappings.<conditionKey>.\"));\n return null;\n }\n index += 1;\n if (tokens[index]?.kind !== \"dot\") {\n issues.push(issue(\"invalid_template_expression\", \"Mapping conditions must use mappings.<conditionKey>.\"));\n return null;\n }\n index += 1;\n const keyToken = tokens[index];\n if (keyToken?.kind !== \"word\") {\n issues.push(issue(\"invalid_mapping_condition\", \"A valid mapping condition key is required after mappings.\"));\n return null;\n }\n index += 1;\n if (!StoreCategoryPromptConditionKeySchema.safeParse(keyToken.value).success) {\n issues.push(issue(\"invalid_mapping_condition\", `Invalid mapping condition key: ${keyToken.value}.`));\n return null;\n }\n if (!referenced.includes(keyToken.value)) referenced.push(keyToken.value);\n return { kind: \"condition\", key: keyToken.value };\n };\n\n const parseNot = (): ExpressionNode | null => {\n if (peekWord(\"not\")) {\n index += 1;\n const operand = parseNot();\n return operand ? { kind: \"not\", operand } : null;\n }\n return parsePrimary();\n };\n\n const parseAnd = (): ExpressionNode | null => {\n let left = parseNot();\n while (left && peekWord(\"and\")) {\n index += 1;\n const right = parseNot();\n if (!right) return null;\n left = { kind: \"and\", left, right };\n }\n return left;\n };\n\n const parseOr = (): ExpressionNode | null => {\n let left = parseAnd();\n while (left && peekWord(\"or\")) {\n index += 1;\n const right = parseAnd();\n if (!right) return null;\n left = { kind: \"or\", left, right };\n }\n return left;\n };\n\n const expression = parseOr();\n if (expression && index !== tokens.length) {\n issues.push(issue(\"invalid_template_expression\", \"Conditional expression contains unsupported syntax.\"));\n return null;\n }\n return expression;\n}\n\nfunction compileStoreCategoryPromptTemplate(source: string): CompileResult {\n const issues: StoreCategoryPromptTemplateIssue[] = [];\n const referencedConditionKeys: string[] = [];\n const nodes: TemplateNode[] = [];\n\n if (source.trim().length === 0) issues.push(issue(\"invalid_prompt_source\", \"Prompt template must not be blank.\"));\n if (sourceLength(source) > MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS) {\n issues.push(issue(\"invalid_prompt_source\", `Prompt template must not exceed ${MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS.toLocaleString()} characters.`));\n }\n\n const tokens = tokenizeTemplate(source, issues);\n type Frame = {\n node: Extract<TemplateNode, { kind: \"if\" }>;\n parentBody: TemplateNode[];\n currentBody: TemplateNode[];\n sawElse: boolean;\n };\n const stack: Frame[] = [];\n let currentBody = nodes;\n let controlCount = 0;\n\n for (const token of tokens) {\n if (token.kind === \"text\") {\n if (token.text) currentBody.push({ kind: \"text\", text: token.text });\n continue;\n }\n if (token.kind === \"unsupported\") {\n issues.push(issue(\n \"unsupported_template_construct\",\n token.marker === \"interpolation\"\n ? \"Variable interpolation is not supported in Store Category prompt templates.\"\n : \"Template comments are not supported in Store Category prompt templates.\",\n ));\n continue;\n }\n\n controlCount += 1;\n if (controlCount > MAX_CONTROL_TAGS) {\n issues.push(issue(\"template_too_complex\", `Prompt template must not contain more than ${MAX_CONTROL_TAGS} control tags.`));\n break;\n }\n\n const ifMatch = /^if\\s+([\\s\\S]+)$/.exec(token.source);\n if (ifMatch) {\n if (stack.length >= MAX_CONTROL_DEPTH) {\n issues.push(issue(\"template_too_complex\", `Conditional nesting must not exceed ${MAX_CONTROL_DEPTH} levels.`));\n continue;\n }\n const expression = parseExpression(ifMatch[1].trim(), issues, referencedConditionKeys);\n if (!expression) continue;\n const branchBody: TemplateNode[] = [];\n const node: Extract<TemplateNode, { kind: \"if\" }> = {\n kind: \"if\",\n branches: [{ expression, body: branchBody }],\n elseBody: null,\n };\n currentBody.push(node);\n const frame: Frame = { node, parentBody: currentBody, currentBody: branchBody, sawElse: false };\n stack.push(frame);\n currentBody = branchBody;\n continue;\n }\n\n const elifMatch = /^elif\\s+([\\s\\S]+)$/.exec(token.source);\n if (elifMatch) {\n const frame = stack.at(-1);\n if (!frame || frame.sawElse) {\n issues.push(issue(\"invalid_template_structure\", \"elif must appear inside an if block and before else.\"));\n continue;\n }\n const expression = parseExpression(elifMatch[1].trim(), issues, referencedConditionKeys);\n if (!expression) continue;\n const branchBody: TemplateNode[] = [];\n frame.node.branches.push({ expression, body: branchBody });\n frame.currentBody = branchBody;\n currentBody = branchBody;\n continue;\n }\n\n if (token.source === \"else\") {\n const frame = stack.at(-1);\n if (!frame || frame.sawElse) {\n issues.push(issue(\"invalid_template_structure\", \"else must appear once inside an if block.\"));\n continue;\n }\n const elseBody: TemplateNode[] = [];\n frame.node.elseBody = elseBody;\n frame.currentBody = elseBody;\n frame.sawElse = true;\n currentBody = elseBody;\n continue;\n }\n\n if (token.source === \"endif\") {\n const frame = stack.pop();\n if (!frame) {\n issues.push(issue(\"invalid_template_structure\", \"endif does not have a matching if block.\"));\n continue;\n }\n currentBody = frame.parentBody;\n continue;\n }\n\n issues.push(issue(\n \"unsupported_template_construct\",\n \"Only if, elif, else, and endif control tags are supported in Store Category prompt templates.\",\n ));\n }\n\n if (stack.length) issues.push(issue(\"invalid_template_structure\", \"Every if block must end with endif.\"));\n return { issues: boundedIssues(issues), nodes, referencedConditionKeys };\n}\n\nfunction validateAvailableConditionKeys(values: readonly string[], issues: StoreCategoryPromptTemplateIssue[]): Set<string> {\n if (values.length > MAX_STORE_CATEGORY_PROMPT_CONDITIONS) {\n issues.push(issue(\"template_too_complex\", `At most ${MAX_STORE_CATEGORY_PROMPT_CONDITIONS} mapping conditions are supported.`));\n }\n const keys = new Set<string>();\n for (const value of values.slice(0, MAX_STORE_CATEGORY_PROMPT_CONDITIONS + 1)) {\n if (!StoreCategoryPromptConditionKeySchema.safeParse(value).success) {\n issues.push(issue(\"invalid_mapping_condition\", `Invalid mapping condition key: ${value}.`));\n continue;\n }\n if (keys.has(value)) {\n issues.push(issue(\"invalid_mapping_condition\", `Duplicate mapping condition key: ${value}.`));\n continue;\n }\n keys.add(value);\n }\n return keys;\n}\n\nexport function validateStoreCategoryPromptTemplate(input: {\n source: string;\n availableConditionKeys: readonly string[];\n}): StoreCategoryPromptTemplateValidation {\n const compiled = compileStoreCategoryPromptTemplate(input.source);\n const issues = [...compiled.issues];\n const available = validateAvailableConditionKeys(input.availableConditionKeys, issues);\n for (const key of compiled.referencedConditionKeys) {\n if (!available.has(key)) issues.push(issue(\"unknown_mapping_condition\", `Prompt template references unavailable mapping condition: mappings.${key}.`));\n }\n const bounded = boundedIssues(issues);\n return { valid: bounded.length === 0, issues: bounded, referencedConditionKeys: compiled.referencedConditionKeys };\n}\n\n\nexport function createStoreCategoryPromptConditionBlock(conditionKey: string): string {\n const parsed = StoreCategoryPromptConditionKeySchema.safeParse(conditionKey);\n if (!parsed.success) throw new TypeError(`Invalid mapping condition key: ${conditionKey}.`);\n return `{% if mappings.${conditionKey} %}\\n\\n{% endif %}`;\n}\n\nexport function createStoreCategoryPromptContext(input: {\n availableConditionKeys: readonly string[];\n selectedConditionKeys: readonly string[];\n}): StoreCategoryPromptContext {\n const issues: StoreCategoryPromptTemplateIssue[] = [];\n const available = validateAvailableConditionKeys(input.availableConditionKeys, issues);\n const selected = validateAvailableConditionKeys(input.selectedConditionKeys, issues);\n for (const key of selected) {\n if (!available.has(key)) issues.push(issue(\"unknown_mapping_condition\", `Selected mapping condition is unavailable: ${key}.`));\n }\n if (issues.length) throw new TypeError(issues[0].message);\n const mappings = Object.create(null) as Record<string, boolean>;\n for (const key of available) mappings[key] = selected.has(key);\n return { mappings };\n}\n\nfunction evaluateExpression(expression: ExpressionNode, mappings: Record<string, boolean>): boolean {\n switch (expression.kind) {\n case \"condition\":\n return mappings[expression.key] === true;\n case \"not\":\n return !evaluateExpression(expression.operand, mappings);\n case \"and\":\n return evaluateExpression(expression.left, mappings) && evaluateExpression(expression.right, mappings);\n case \"or\":\n return evaluateExpression(expression.left, mappings) || evaluateExpression(expression.right, mappings);\n }\n}\n\nfunction renderNodes(nodes: TemplateNode[], mappings: Record<string, boolean>, append: (text: string) => boolean): boolean {\n for (const node of nodes) {\n if (node.kind === \"text\") {\n if (!append(node.text)) return false;\n continue;\n }\n let renderedBranch = false;\n for (const branch of node.branches) {\n if (evaluateExpression(branch.expression, mappings)) {\n if (!renderNodes(branch.body, mappings, append)) return false;\n renderedBranch = true;\n break;\n }\n }\n if (!renderedBranch && node.elseBody && !renderNodes(node.elseBody, mappings, append)) return false;\n }\n return true;\n}\n\nexport function renderStoreCategoryPromptTemplate(input: {\n source: string;\n context: StoreCategoryPromptContext;\n}): StoreCategoryPromptRenderResult {\n const contextResult = StoreCategoryPromptContextSchema.safeParse(input.context);\n if (!contextResult.success) {\n return { ok: false, issues: [issue(\"invalid_mapping_condition\", \"Store Category prompt context contains invalid mapping conditions.\")] };\n }\n const availableConditionKeys = Object.keys(contextResult.data.mappings);\n const validation = validateStoreCategoryPromptTemplate({ source: input.source, availableConditionKeys });\n if (!validation.valid) return { ok: false, issues: validation.issues };\n\n const compiled = compileStoreCategoryPromptTemplate(input.source);\n let output = \"\";\n let outputChars = 0;\n const append = (text: string) => {\n outputChars += sourceLength(text);\n if (outputChars > MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS) return false;\n output += text;\n return true;\n };\n const rendered = renderNodes(compiled.nodes, contextResult.data.mappings, append);\n if (!rendered) {\n return {\n ok: false,\n issues: [issue(\"rendered_prompt_too_large\", `Rendered prompt must not exceed ${MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS.toLocaleString()} characters.`)],\n };\n }\n return { ok: true, promptText: output, referencedConditionKeys: validation.referencedConditionKeys };\n}\n","/** Synthetic examples; no provider identity, schema artifact or publication claim. */\nimport type {\n CommerceManifest,\n CommerceConversationGrant,\n CommerceTurnIdentity,\n} from \"./schemas\";\nimport {\n EMPTY_RESPONSE_CONTRACT,\n type CommerceFinalResponse,\n} from \"./response\";\nimport type { Digest } from \"./canonical-json\";\nimport { responseContractCanonicalJson } from \"./canonical-json\";\nimport type { ToolDescriptor, CommerceToolDefinition } from \"./definitions\";\nexport const exampleTool: ToolDescriptor = {\n toolId: \"tool-fixture\",\n toolRevisionId: \"revision-fixture\",\n name: \"never_seeded_catalogue_facts\",\n definitionVersion: \"1.0.0\",\n description: \"Read synthetic catalogue facts.\",\n inputSchema: {\n type: \"object\",\n properties: { handle: { type: \"string\", minLength: 1, maxLength: 255 } },\n required: [\"handle\"],\n additionalProperties: false,\n },\n};\nexport const exampleDefinition: CommerceToolDefinition = {\n name: exampleTool.name,\n definitionVersion: \"1.0.0\",\n description: exampleTool.description,\n inputSchema: exampleTool.inputSchema,\n execution: {\n kind: \"SHOPIFY_STOREFRONT_QUERY\",\n executorVersion: \"1.0.0\",\n apiVersion: \"2026-07\",\n schemaHash: \"a\".repeat(64),\n document:\n \"query ProductDetails($handle: String!) { product(handle: $handle) { title description } }\",\n operationName: \"ProductDetails\",\n variables: { handle: { input: \"handle\" } },\n resultPath: \"product\",\n },\n responseTemplate: {\n kind: \"text\",\n text: \"{{result.values.title}}: {{result.values.description}}\",\n unavailable: \"Product details could not be verified.\",\n },\n};\nexport const exampleTurn: CommerceTurnIdentity = {\n contractVersion: \"commerce.v1\",\n shopId: \"shop-fixture\",\n checkoutRecoveryId: \"recovery-fixture\",\n conversationId: \"conversation-fixture\",\n inboundVersion: 1,\n};\nexport function exampleManifest(\n digest: Digest,\n withTool = false,\n): CommerceManifest {\n const capabilities = withTool\n ? [{\n capabilityId: \"capability-fixture\",\n key: \"feature_product_read\",\n featureId: \"feature-fixture\",\n position: 0,\n toolDescriptor: structuredClone(exampleTool),\n }]\n : [];\n return {\n contractVersion: \"commerce.v1\",\n releaseId: \"release-fixture\",\n runnerCompatibility: \"^1.0.0\",\n capabilities,\n featureBehaviours: withTool\n ? [{ featureId: \"feature-fixture\", behaviourPrompt: \"Synthetic Feature behavior.\" }]\n : [],\n selectedCapabilityKeys: capabilities.map((capability) => capability.key),\n grantedTools: withTool\n ? [\n {\n toolId: exampleTool.toolId,\n toolRevisionId: exampleTool.toolRevisionId,\n toolName: exampleTool.name,\n definitionVersion: \"1.0.0\",\n capabilityKeys: [\"feature_product_read\"],\n },\n ]\n : [],\n responseContract: structuredClone(EMPTY_RESPONSE_CONTRACT),\n responseContractHash: digest(\n responseContractCanonicalJson(EMPTY_RESPONSE_CONTRACT),\n ),\n };\n}\nexport function exampleGrant(\n manifest: CommerceManifest,\n): CommerceConversationGrant {\n return {\n id: \"grant-fixture\",\n shopId: exampleTurn.shopId,\n conversationId: exampleTurn.conversationId,\n initialInboundVersion: 1,\n releaseId: manifest.releaseId,\n selectedCapabilityKeys: [...manifest.selectedCapabilityKeys],\n grantedTools: structuredClone(manifest.grantedTools),\n runnerVersion: \"1.0.0\",\n createdAt: \"2026-09-20T00:00:00.000Z\",\n expiresAt: null,\n };\n}\nexport const exampleFinal: CommerceFinalResponse = {\n answerKind: \"REFER_TO_STORE\",\n replyText:\n \"I cannot verify that information. Please contact the store directly.\",\n referralReason: \"INSUFFICIENT_TOOLS\",\n detectedLanguageTag: null,\n detectedLanguageConfidence: null,\n evidenceIds: [],\n details: {},\n};\n"],"mappings":"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","names":[]}
|