@modainteract/moda-interact-shared 3.0.0 → 4.0.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/README.md CHANGED
@@ -2382,3 +2382,70 @@ Type-only exports:
2382
2382
  - `RunnerTool`
2383
2383
 
2384
2384
  </details>
2385
+
2386
+
2387
+ ## Product discovery and code-owned discount contracts
2388
+
2389
+ The existing `/commerce` entrypoint exports `CommerceCategoryCandidateSchema`,
2390
+ `CommerceCategoryResolutionSchema`, `CommerceOptionalLookupUnavailableSchema`,
2391
+ `CommerceConversationToolContextSchema`, and
2392
+ `CommerceProductRecommendationSelectionSchema`, with matching inferred types.
2393
+ The product input/output dictionaries include category resolution and flat,
2394
+ category-aware search. Recommendation selection contains identifiers and quantity,
2395
+ not model-authored prices or savings; applicability and cross-field relationships
2396
+ remain service policy.
2397
+
2398
+ `CommerceBuiltInToolDescriptorSchema`, `CommerceBuiltInToolGrantSchema`,
2399
+ `commerceDiscountBuiltInDescriptors`, and `commerceBuiltInToolContractPayload`
2400
+ define the two code-owned discount reads. Their checked-in SHA256 hashes cover
2401
+ the name, version, description, bounded input schema and actual generated output
2402
+ schema using canonical JSON. The helper returns canonical text; hashing is
2403
+ injected by the trusted Node adapter. Reading these exports needs no Node crypto
2404
+ or provider/database configuration.
2405
+
2406
+ Grants and runner descriptors now explicitly distinguish published identities
2407
+ from `kind: "BUILT_IN"`. Built-ins have no fabricated tool/revision IDs or
2408
+ capability provenance. Manifest `builtInTools` defaults to an empty array, but
2409
+ retained grants must equal the exact canonical descriptor set as well as the
2410
+ published capability union. `deduplicateTools` accepts the optional built-in
2411
+ descriptor set; `currentlyGrantedTools` requires an explicit currently permitted
2412
+ canonical built-in set and otherwise denies built-ins. Hosts still check current
2413
+ tenant/turn/release/permission before and after asynchronous tool work.
2414
+
2415
+ The runtime runner version is **1.1.0**. Optional lookup unavailability is data
2416
+ inside `status: "OK"`; hard errors, stale turns and required referrals retain
2417
+ their existing semantics. Details permit bounded nullable scalars and depth five;
2418
+ input depth stays three and details payloads stay at 16KiB.
2419
+
2420
+ These inferred output/grant changes require the coordinated **4.0.0** publication
2421
+ and consumer migrations in the separate release task. This source change does
2422
+ not bump package metadata or publish to a registry.
2423
+
2424
+ Run `npm run test:product-discovery-contracts` for the focused contracts/runner
2425
+ fixtures. To execute the actual Commerce-owned projector/publication integration,
2426
+ set `COMMERCE_CONTRACT_SOURCE_ROOT` to its explicit accepted source checkout.
2427
+ The test passes candidate schemas as function arguments to that existing
2428
+ projector; it neither changes nor links the consumer's installed package.
2429
+ The installed consumer still has the released operation registry: candidate operation
2430
+ metadata is checked against candidate Shared, and the installed publication pipeline
2431
+ is exercised with a registered operation and the actual generated input schema.
2432
+ This does not certify consumer adoption of the new operations before release.
2433
+ Without this test-only source prerequisite, that integration case is explicitly
2434
+ skipped rather than reported as executed.
2435
+
2436
+ The discovery input dictionary also supports explicit `browse` (default `false`)
2437
+ and the published `commerce_get_shipping_information` operation
2438
+ (`shipping.getInformation`, version `1.0.0`). The named
2439
+ `CommerceShippingInformationInputSchema` / `CommerceShippingInformationSchema`
2440
+ and inferred types expose bounded native facts and independent product/policy outcomes.
2441
+ Policy HTML remains untrusted data; adapters enforce ownership, status relationships,
2442
+ verified hosts and the UTF-8 body budget.
2443
+
2444
+ `CommerceResponseDispositionSchema` / `CommerceResponseDisposition` and
2445
+ `CommerceAnswerPresentationSelectionSchema` / `CommerceAnswerPresentationSelection`
2446
+ add optional identifier-only presentation fields. Merge their shape with recommendation
2447
+ and existing release details; Commerce owns explicit published instructions, and Background
2448
+ owns controlled composition. Product-bearing shipping observations latch that host path even
2449
+ without a selection; policy-only observations alone may retain ordinary grounded answers.
2450
+ Expected limitations never clear a terminal tool error. The default empty response contract,
2451
+ hard-referral envelope and two-tool discount built-in allowlist remain unchanged.
@@ -0,0 +1,26 @@
1
+ import { z } from 'zod';
2
+
3
+ /** Version shared by hosted Woo API and Shopify response-delay settings. */
4
+ declare const AI_RESPONSE_DELAY_SCHEMA_VERSION: 1;
5
+ /** Merchant-selected additional wait before an AI reply; human replies are not delayed. */
6
+ declare const AiResponseDelayMinutesSchema: z.ZodNumber;
7
+ /** Wire revision shape. Consumers must also validate that timestamp values parse as real dates. */
8
+ declare const AiResponseDelayRevisionSchema: z.ZodUnion<readonly [z.ZodLiteral<"UNCONFIGURED">, z.ZodString]>;
9
+ /** Canonical GET and successful PUT response shared by hosted Woo API and Shopify. */
10
+ declare const MerchantAiResponseDelayReadV1Schema: z.ZodObject<{
11
+ schemaVersion: z.ZodLiteral<1>;
12
+ revision: z.ZodUnion<readonly [z.ZodLiteral<"UNCONFIGURED">, z.ZodString]>;
13
+ aiResponseDelayMinutes: z.ZodNumber;
14
+ }, z.core.$strict>;
15
+ /** Canonical optimistic-concurrency PUT request shared by hosted Woo API and Shopify. */
16
+ declare const MerchantAiResponseDelayWriteV1Schema: z.ZodObject<{
17
+ schemaVersion: z.ZodLiteral<1>;
18
+ expectedRevision: z.ZodUnion<readonly [z.ZodLiteral<"UNCONFIGURED">, z.ZodString]>;
19
+ aiResponseDelayMinutes: z.ZodNumber;
20
+ }, z.core.$strict>;
21
+ type AiResponseDelayMinutes = z.infer<typeof AiResponseDelayMinutesSchema>;
22
+ type AiResponseDelayRevision = z.infer<typeof AiResponseDelayRevisionSchema>;
23
+ type MerchantAiResponseDelayReadV1 = z.infer<typeof MerchantAiResponseDelayReadV1Schema>;
24
+ type MerchantAiResponseDelayWriteV1 = z.infer<typeof MerchantAiResponseDelayWriteV1Schema>;
25
+
26
+ export { AI_RESPONSE_DELAY_SCHEMA_VERSION, type AiResponseDelayMinutes, AiResponseDelayMinutesSchema, type AiResponseDelayRevision, AiResponseDelayRevisionSchema, type MerchantAiResponseDelayReadV1, MerchantAiResponseDelayReadV1Schema, type MerchantAiResponseDelayWriteV1, MerchantAiResponseDelayWriteV1Schema };
@@ -0,0 +1,26 @@
1
+ // src/ai-response-delay.ts
2
+ import { z } from "zod";
3
+ var AI_RESPONSE_DELAY_SCHEMA_VERSION = 1;
4
+ var AiResponseDelayMinutesSchema = z.number().int().min(0).max(30);
5
+ var AiResponseDelayRevisionSchema = z.union([
6
+ z.literal("UNCONFIGURED"),
7
+ z.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/)
8
+ ]);
9
+ var MerchantAiResponseDelayReadV1Schema = z.strictObject({
10
+ schemaVersion: z.literal(AI_RESPONSE_DELAY_SCHEMA_VERSION),
11
+ revision: AiResponseDelayRevisionSchema,
12
+ aiResponseDelayMinutes: AiResponseDelayMinutesSchema
13
+ });
14
+ var MerchantAiResponseDelayWriteV1Schema = z.strictObject({
15
+ schemaVersion: z.literal(AI_RESPONSE_DELAY_SCHEMA_VERSION),
16
+ expectedRevision: AiResponseDelayRevisionSchema,
17
+ aiResponseDelayMinutes: AiResponseDelayMinutesSchema
18
+ });
19
+ export {
20
+ AI_RESPONSE_DELAY_SCHEMA_VERSION,
21
+ AiResponseDelayMinutesSchema,
22
+ AiResponseDelayRevisionSchema,
23
+ MerchantAiResponseDelayReadV1Schema,
24
+ MerchantAiResponseDelayWriteV1Schema
25
+ };
26
+ //# sourceMappingURL=ai-response-delay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ai-response-delay.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/** Version shared by hosted Woo API and Shopify response-delay settings. */\nexport const AI_RESPONSE_DELAY_SCHEMA_VERSION = 1 as const;\n\n/** Merchant-selected additional wait before an AI reply; human replies are not delayed. */\nexport const AiResponseDelayMinutesSchema = z.number().int().min(0).max(30);\n\n/** Wire revision shape. Consumers must also validate that timestamp values parse as real dates. */\nexport const AiResponseDelayRevisionSchema = z.union([\n z.literal(\"UNCONFIGURED\"),\n z.string().regex(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/),\n]);\n\n/** Canonical GET and successful PUT response shared by hosted Woo API and Shopify. */\nexport const MerchantAiResponseDelayReadV1Schema = z.strictObject({\n schemaVersion: z.literal(AI_RESPONSE_DELAY_SCHEMA_VERSION),\n revision: AiResponseDelayRevisionSchema,\n aiResponseDelayMinutes: AiResponseDelayMinutesSchema,\n});\n\n/** Canonical optimistic-concurrency PUT request shared by hosted Woo API and Shopify. */\nexport const MerchantAiResponseDelayWriteV1Schema = z.strictObject({\n schemaVersion: z.literal(AI_RESPONSE_DELAY_SCHEMA_VERSION),\n expectedRevision: AiResponseDelayRevisionSchema,\n aiResponseDelayMinutes: AiResponseDelayMinutesSchema,\n});\n\nexport type AiResponseDelayMinutes =\n z.infer<typeof AiResponseDelayMinutesSchema>;\nexport type AiResponseDelayRevision =\n z.infer<typeof AiResponseDelayRevisionSchema>;\nexport type MerchantAiResponseDelayReadV1 =\n z.infer<typeof MerchantAiResponseDelayReadV1Schema>;\nexport type MerchantAiResponseDelayWriteV1 =\n z.infer<typeof MerchantAiResponseDelayWriteV1Schema>;\n"],"mappings":";AAAA,SAAS,SAAS;AAGX,IAAM,mCAAmC;AAGzC,IAAM,+BAA+B,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAGnE,IAAM,gCAAgC,EAAE,MAAM;AAAA,EACnD,EAAE,QAAQ,cAAc;AAAA,EACxB,EAAE,OAAO,EAAE,MAAM,+CAA+C;AAClE,CAAC;AAGM,IAAM,sCAAsC,EAAE,aAAa;AAAA,EAChE,eAAe,EAAE,QAAQ,gCAAgC;AAAA,EACzD,UAAU;AAAA,EACV,wBAAwB;AAC1B,CAAC;AAGM,IAAM,uCAAuC,EAAE,aAAa;AAAA,EACjE,eAAe,EAAE,QAAQ,gCAAgC;AAAA,EACzD,kBAAkB;AAAA,EAClB,wBAAwB;AAC1B,CAAC;","names":[]}
@@ -40,7 +40,7 @@ var keywords = [
40
40
  ];
41
41
  function validateSubset(value, mode) {
42
42
  let propertyCount = 0;
43
- const maxDepth = mode === "input" ? 3 : 4;
43
+ const maxDepth = mode === "input" ? 3 : 5;
44
44
  function walk(raw, depth) {
45
45
  if (depth > maxDepth || !raw || typeof raw !== "object" || Array.isArray(raw))
46
46
  return false;
@@ -50,7 +50,7 @@ function validateSubset(value, mode) {
50
50
  ))
51
51
  return false;
52
52
  const nullable = Array.isArray(s.type);
53
- if (nullable && (mode !== "input" || s.type.length !== 2 || s.type[1] !== "null"))
53
+ if (nullable && (s.type.length !== 2 || s.type[1] !== "null" || mode === "details" && ["object", "array"].includes(s.type[0])))
54
54
  return false;
55
55
  const type = typeof s.type === "string" ? s.type : s.type[0];
56
56
  if (![
@@ -255,17 +255,14 @@ var DEFINITION_SIZE_MESSAGE = "Definition exceeds the 65536-byte jsonb text limi
255
255
 
256
256
  // src/commerce/definitions.ts
257
257
  var ToolNameSchema = z3.string().regex(/^[a-z][a-z0-9_]{0,127}$/).refine((n) => n !== "finalResponse");
258
- var GrantedToolSchema = z3.strictObject({
258
+ var PublishedGrantedToolSchema = z3.strictObject({
259
259
  toolId: IdSchema,
260
260
  toolRevisionId: IdSchema,
261
261
  toolName: ToolNameSchema,
262
262
  definitionVersion: SemverSchema,
263
263
  capabilityKeys: z3.array(IdSchema).min(1).max(32).refine((v) => distinct(v) && v.join("\0") === [...v].sort().join("\0"))
264
264
  });
265
- var GrantedToolsSchema = z3.array(GrantedToolSchema).max(32).refine(
266
- (v) => distinct(v.map((x) => x.toolId)) && distinct(v.map((x) => x.toolName))
267
- );
268
- var ToolDescriptorSchema = z3.strictObject({
265
+ var PublishedToolDescriptorSchema = z3.strictObject({
269
266
  toolId: IdSchema,
270
267
  toolRevisionId: IdSchema,
271
268
  name: ToolNameSchema,
@@ -273,6 +270,31 @@ var ToolDescriptorSchema = z3.strictObject({
273
270
  description: z3.string().min(1).max(4096),
274
271
  inputSchema: InputSchemaSchema
275
272
  });
273
+ var CommerceBuiltInToolNameSchema = z3.enum([
274
+ "commerce_get_discount_options",
275
+ "commerce_get_discount_details"
276
+ ]).meta({ maxLength: 29 });
277
+ var CommerceBuiltInToolGrantSchema = z3.strictObject({
278
+ kind: z3.enum(["BUILT_IN"]).meta({ maxLength: 8 }),
279
+ toolName: CommerceBuiltInToolNameSchema,
280
+ definitionVersion: z3.enum(["1.0.0"]).meta({ maxLength: 5 }),
281
+ contractHash: HashSchema
282
+ });
283
+ var CommerceBuiltInToolDescriptorSchema = z3.strictObject({
284
+ kind: z3.enum(["BUILT_IN"]).meta({ maxLength: 8 }),
285
+ name: CommerceBuiltInToolNameSchema,
286
+ definitionVersion: z3.enum(["1.0.0"]).meta({ maxLength: 5 }),
287
+ contractHash: HashSchema,
288
+ description: z3.string().min(1).max(4096),
289
+ inputSchema: InputSchemaSchema
290
+ });
291
+ var GrantedToolSchema = z3.union([PublishedGrantedToolSchema, CommerceBuiltInToolGrantSchema]);
292
+ var ToolDescriptorSchema = z3.union([PublishedToolDescriptorSchema, CommerceBuiltInToolDescriptorSchema]);
293
+ var GrantedToolsSchema = z3.array(GrantedToolSchema).max(32).refine((values) => {
294
+ const published = values.filter((value) => !("kind" in value));
295
+ return distinct(values.map((value) => value.toolName)) && distinct(published.map((value) => value.toolId));
296
+ });
297
+ var isBuiltInTool = (value) => "kind" in value && value.kind === "BUILT_IN";
276
298
  var MappingSchema = z3.union([
277
299
  z3.strictObject({
278
300
  input: z3.string().refine(safeName),
@@ -282,6 +304,10 @@ var MappingSchema = z3.union([
282
304
  ]);
283
305
  var MappingsSchema = z3.record(z3.string().refine(safeName), MappingSchema).refine((v) => Object.keys(v).length <= 32);
284
306
  var POLICY_OPERATIONS = [
307
+ "taxonomy.resolveCategories",
308
+ "products.search",
309
+ "products.get",
310
+ "shipping.getInformation",
285
311
  "recovery.getBasket",
286
312
  "shopify.searchProducts",
287
313
  "discounts.getOptions",
@@ -499,6 +525,13 @@ var POLICY_OPERATION_DESCRIPTORS = POLICY_OPERATIONS.map(
499
525
  (operation) => ({ operation, operationVersion: "1.0.0" })
500
526
  );
501
527
 
528
+ // src/commerce/built-in-tools.ts
529
+ import { z as z6 } from "zod";
530
+
531
+ // src/commerce/schemas.ts
532
+ import { z as z5 } from "zod";
533
+ import { validRange } from "semver";
534
+
502
535
  // src/commerce/response.ts
503
536
  import { z as z4 } from "zod";
504
537
  var CommerceResponseContractSchema = z4.strictObject({
@@ -676,8 +709,6 @@ function finalResponseToolSchema(definition) {
676
709
  }
677
710
 
678
711
  // src/commerce/schemas.ts
679
- import { z as z5 } from "zod";
680
- import { validRange } from "semver";
681
712
  var CommerceTurnIdentitySchema = z5.strictObject({
682
713
  contractVersion: ContractVersionSchema,
683
714
  shopId: IdSchema,
@@ -700,7 +731,7 @@ var CommerceConversationGrantSchema = z5.strictObject({
700
731
  if (v.expiresAt && Date.parse(v.expiresAt) <= Date.parse(v.createdAt))
701
732
  c.addIssue({ code: "custom", message: "Invalid grant retention date" });
702
733
  if (jsonBytes(v.grantedTools) > 65536 || jsonBytes(v.selectedCapabilityKeys) > 8192 || v.grantedTools.some(
703
- (t) => t.capabilityKeys.some((k) => !v.selectedCapabilityKeys.includes(k))
734
+ (t) => isBuiltInTool(t) ? !isTrustedCommerceBuiltInGrant(t) : t.capabilityKeys.some((k) => !v.selectedCapabilityKeys.includes(k))
704
735
  ))
705
736
  c.addIssue({ code: "custom", message: "Unselected grant provenance" });
706
737
  });
@@ -714,7 +745,7 @@ var CommerceManifestSchema = z5.strictObject({
714
745
  key: IdSchema,
715
746
  featureId: IdSchema,
716
747
  position: z5.number().int().nonnegative(),
717
- toolDescriptor: ToolDescriptorSchema
748
+ toolDescriptor: PublishedToolDescriptorSchema
718
749
  })
719
750
  ).max(32),
720
751
  featureBehaviours: z5.array(
@@ -724,6 +755,7 @@ var CommerceManifestSchema = z5.strictObject({
724
755
  })
725
756
  ).max(32),
726
757
  selectedCapabilityKeys: z5.array(IdSchema).max(32).refine(distinct),
758
+ builtInTools: z5.array(CommerceBuiltInToolDescriptorSchema).max(2).default([]),
727
759
  grantedTools: GrantedToolsSchema,
728
760
  responseContract: CommerceResponseContractSchema,
729
761
  responseContractHash: HashSchema
@@ -765,7 +797,8 @@ var CommerceManifestSchema = z5.strictObject({
765
797
  }
766
798
  });
767
799
  }
768
- if (union.size !== v.grantedTools.length || v.grantedTools.some((t) => {
800
+ if (union.size + v.builtInTools.length !== v.grantedTools.length || !distinct(v.builtInTools.map((tool) => tool.name)) || v.builtInTools.some((tool) => !isTrustedCommerceBuiltInDescriptor(tool)) || v.grantedTools.some((t) => {
801
+ if (isBuiltInTool(t)) return !v.builtInTools.some((descriptor) => descriptor.name === t.toolName && descriptor.definitionVersion === t.definitionVersion && descriptor.contractHash === t.contractHash && isTrustedCommerceBuiltInGrant(t));
769
802
  const expected = union.get(t.toolId)?.tool;
770
803
  return !expected || expected.toolRevisionId !== t.toolRevisionId || expected.toolName !== t.toolName || expected.definitionVersion !== t.definitionVersion || JSON.stringify([...new Set(expected.capabilityKeys)].sort()) !== JSON.stringify(t.capabilityKeys);
771
804
  }))
@@ -1003,11 +1036,117 @@ function commerceToolResultSchema(data) {
1003
1036
  var CommerceToolResultSchema = commerceToolResultSchema(
1004
1037
  boundedJson(262144)
1005
1038
  );
1039
+ var wireId = z5.string().min(1).max(128);
1040
+ var taxonomySource = z5.enum(["SHOPIFY_STANDARD_PRODUCT_TAXONOMY"]).meta({ maxLength: 33 });
1041
+ var CommerceCategoryCandidateSchema = z5.strictObject({
1042
+ categoryId: wireId,
1043
+ name: z5.string().min(1).max(512),
1044
+ fullName: z5.string().min(1).max(4096),
1045
+ parentId: wireId.nullable(),
1046
+ level: z5.number().int().min(0).max(32),
1047
+ ancestorIds: z5.array(wireId).max(32),
1048
+ distance: z5.number().min(0).max(2)
1049
+ });
1050
+ var CommerceCategoryResolutionSchema = z5.union([
1051
+ z5.strictObject({
1052
+ outcome: z5.enum(["CANDIDATES", "NO_CANDIDATES"]).meta({ maxLength: 13 }),
1053
+ generationId: wireId,
1054
+ source: taxonomySource,
1055
+ taxonomyVersion: z5.string().min(1).max(64),
1056
+ languageTag: z5.string().min(1).max(35),
1057
+ candidates: z5.array(CommerceCategoryCandidateSchema).max(10)
1058
+ }),
1059
+ z5.strictObject({
1060
+ outcome: z5.enum(["UNAVAILABLE"]).meta({ maxLength: 11 }),
1061
+ reasonCode: z5.enum(["NOT_READY", "TEMPORARY_UNAVAILABLE"]).meta({ maxLength: 21 })
1062
+ })
1063
+ ]);
1064
+ var CommerceOptionalLookupUnavailableSchema = z5.strictObject({
1065
+ outcome: z5.enum(["UNAVAILABLE"]).meta({ maxLength: 11 }),
1066
+ reasonCode: z5.enum(["TEMPORARY_UNAVAILABLE"]).meta({ maxLength: 21 })
1067
+ });
1068
+ var CommerceConversationToolContextSchema = z5.strictObject({
1069
+ purpose: z5.enum(["CONVERSATION"]).meta({ maxLength: 12 }),
1070
+ conversationId: IdSchema,
1071
+ inboundVersion: z5.number().int().positive(),
1072
+ grantId: IdSchema.nullable()
1073
+ });
1074
+ var CommerceProductRecommendationSelectionSchema = z5.strictObject({
1075
+ productRecommendationVersion: z5.enum(["1"]).meta({ maxLength: 1 }).optional(),
1076
+ productRecommendations: z5.array(z5.strictObject({
1077
+ scope: z5.enum(["PRODUCT_ONLY", "ADD_TO_BASKET", "REPLACE_BASKET_LINE"]).meta({ maxLength: 19 }),
1078
+ basketLineId: wireId.nullable(),
1079
+ productId: wireId,
1080
+ variantId: wireId.nullable(),
1081
+ quantity: z5.number().int().min(1).max(99),
1082
+ promotionKind: z5.enum(["NONE", "NATIVE_SALE", "DISCOUNT"]).meta({ maxLength: 11 }),
1083
+ offerIds: z5.array(wireId).max(3)
1084
+ })).min(1).max(3).optional()
1085
+ });
1086
+ var CommerceResponseDispositionSchema = z5.enum([
1087
+ "STANDARD",
1088
+ "OUT_OF_SCOPE_REDIRECT",
1089
+ "SHIPPING_INFORMATION_UNVERIFIED"
1090
+ ]).meta({ maxLength: 31 });
1091
+ var CommerceAnswerPresentationSelectionSchema = z5.strictObject({
1092
+ responseDisposition: CommerceResponseDispositionSchema.optional(),
1093
+ shippingInformationSelection: z5.strictObject({
1094
+ productId: wireId.nullable(),
1095
+ variantId: wireId.nullable()
1096
+ }).optional()
1097
+ });
1098
+ var CommerceShippingInformationInputSchema = z5.strictObject({
1099
+ productId: wireId.nullable().default(null),
1100
+ variantId: wireId.nullable().default(null)
1101
+ });
1102
+ var CommerceShippingInformationSchema = z5.strictObject({
1103
+ provider: z5.enum(["SHOPIFY", "WOOCOMMERCE"]).meta({ maxLength: 11 }),
1104
+ observedAt: DateSchema,
1105
+ product: z5.strictObject({
1106
+ status: z5.enum(["NOT_REQUESTED", "VARIANT_REQUIRED", "AVAILABLE"]).meta({ maxLength: 16 }),
1107
+ productId: wireId.nullable(),
1108
+ variantId: wireId.nullable(),
1109
+ requiresShipping: z5.boolean().nullable(),
1110
+ virtual: z5.boolean().nullable(),
1111
+ weight: z5.strictObject({
1112
+ value: z5.number().min(0),
1113
+ unit: z5.enum(["GRAMS", "KILOGRAMS", "OUNCES", "POUNDS"]).meta({ maxLength: 9 }).nullable()
1114
+ }).nullable(),
1115
+ dimensions: z5.strictObject({
1116
+ length: z5.number().min(0).nullable(),
1117
+ width: z5.number().min(0).nullable(),
1118
+ height: z5.number().min(0).nullable(),
1119
+ unit: z5.string().min(1).max(16).nullable()
1120
+ }).nullable(),
1121
+ shippingClassId: wireId.nullable(),
1122
+ shippingClassSlug: z5.string().min(1).max(512).nullable()
1123
+ }),
1124
+ policy: z5.strictObject({
1125
+ status: z5.enum(["AVAILABLE", "NOT_CONFIGURED", "SCOPE_NOT_GRANTED", "UNSUPPORTED"]).meta({ maxLength: 17 }),
1126
+ trust: z5.enum(["UNTRUSTED_REFERENCE"]).meta({ maxLength: 19 }),
1127
+ title: z5.string().min(1).max(512).nullable(),
1128
+ bodyStatus: z5.enum(["AVAILABLE", "EMPTY", "TOO_LARGE", "NOT_AVAILABLE"]).meta({ maxLength: 13 }),
1129
+ bodyHtml: z5.string().min(1).max(8e3).nullable(),
1130
+ url: z5.url({ protocol: /^https$/ }).min(1).max(2048).nullable(),
1131
+ updatedAt: DateSchema.nullable()
1132
+ })
1133
+ });
1006
1134
  var limit = z5.number().int().min(1).max(3).default(3);
1007
1135
  var CommerceToolInputs = {
1136
+ commerce_resolve_product_categories: z5.strictObject({
1137
+ query: z5.string().min(1).max(200),
1138
+ limit: z5.number().int().min(1).max(10).default(5)
1139
+ }),
1140
+ commerce_get_shipping_information: CommerceShippingInformationInputSchema,
1008
1141
  commerce_get_basket: z5.strictObject({}),
1009
1142
  commerce_search_products: z5.strictObject({
1010
- query: z5.string().min(1).max(200),
1143
+ query: z5.string().min(1).max(200).nullable().default(null),
1144
+ category: z5.strictObject({
1145
+ system: z5.enum(["SHOPIFY_STANDARD_PRODUCT_TAXONOMY", "WOOCOMMERCE_PRODUCT_CATEGORY"]).meta({ maxLength: 33 }),
1146
+ id: wireId,
1147
+ taxonomyVersion: z5.string().min(1).max(64).nullable()
1148
+ }).optional(),
1149
+ browse: z5.boolean().default(false),
1011
1150
  maximumPrice: MoneySchema.optional(),
1012
1151
  availableOnly: z5.boolean().default(true),
1013
1152
  limit: z5.number().int().min(1).max(20).default(10),
@@ -1042,6 +1181,8 @@ var alternatives = z5.strictObject({
1042
1181
  truncated: z5.boolean()
1043
1182
  });
1044
1183
  var CommerceToolOutputs = {
1184
+ commerce_resolve_product_categories: CommerceCategoryResolutionSchema,
1185
+ commerce_get_shipping_information: CommerceShippingInformationSchema,
1045
1186
  commerce_get_basket: CommerceBasketSchema,
1046
1187
  commerce_search_products: z5.strictObject({
1047
1188
  products: z5.array(CommerceProductSchema).max(20),
@@ -1051,15 +1192,15 @@ var CommerceToolOutputs = {
1051
1192
  commerce_get_product: z5.strictObject({
1052
1193
  product: CommerceProductSchema.nullable()
1053
1194
  }),
1054
- commerce_get_discount_options: z5.strictObject({
1195
+ commerce_get_discount_options: z5.union([CommerceOptionalLookupUnavailableSchema, z5.strictObject({
1055
1196
  mode: z5.enum(["NONE", "FIXED", "AI_BEST_APPLICABLE"]),
1056
1197
  offers: z5.array(CommerceOfferSchema).max(50),
1057
1198
  truncated: z5.boolean(),
1058
1199
  cursor: z5.string().max(2048).nullable().optional()
1059
- }),
1060
- commerce_get_discount_details: z5.strictObject({
1200
+ })]),
1201
+ commerce_get_discount_details: z5.union([CommerceOptionalLookupUnavailableSchema, z5.strictObject({
1061
1202
  details: CommerceDiscountDetailsSchema.nullable()
1062
- }),
1203
+ })]),
1063
1204
  commerce_evaluate_discount: CommerceEvidenceSchema,
1064
1205
  commerce_find_qualifying_products: alternatives,
1065
1206
  commerce_find_similar_products: alternatives
@@ -1072,6 +1213,58 @@ function productBelongsToDomain(product, verifiedDomain) {
1072
1213
  }
1073
1214
  }
1074
1215
 
1216
+ // src/commerce/built-in-tools.ts
1217
+ function immutable(value) {
1218
+ for (const child of Object.values(value))
1219
+ if (child && typeof child === "object") immutable(child);
1220
+ return Object.freeze(value);
1221
+ }
1222
+ var commerceDiscountBuiltInDescriptors = immutable([
1223
+ {
1224
+ kind: "BUILT_IN",
1225
+ name: "commerce_get_discount_options",
1226
+ definitionVersion: "1.0.0",
1227
+ contractHash: "a0a4a88c7920a25a31657a03761b6556419189aeab251261a58e2dfb83a3bdcb",
1228
+ description: "Read the current shop's permitted discount options.",
1229
+ inputSchema: {
1230
+ type: "object",
1231
+ properties: {
1232
+ limit: { type: "integer", minimum: 1, maximum: 50 },
1233
+ cursor: { type: ["string", "null"], maxLength: 2048 }
1234
+ },
1235
+ additionalProperties: false
1236
+ }
1237
+ },
1238
+ {
1239
+ kind: "BUILT_IN",
1240
+ name: "commerce_get_discount_details",
1241
+ definitionVersion: "1.0.0",
1242
+ contractHash: "776f6bc6ac1800c75744c2ffa7357f07a32be2b61309b1d71abf0493a2de316f",
1243
+ description: "Read details for a permitted discount in the current shop.",
1244
+ inputSchema: {
1245
+ type: "object",
1246
+ properties: { offerId: { type: "string", minLength: 1, maxLength: 128 } },
1247
+ required: ["offerId"],
1248
+ additionalProperties: false
1249
+ }
1250
+ }
1251
+ ]);
1252
+ function commerceBuiltInToolContractPayload(descriptor) {
1253
+ return canonicalJson({
1254
+ name: descriptor.name,
1255
+ definitionVersion: descriptor.definitionVersion,
1256
+ description: descriptor.description,
1257
+ inputSchema: descriptor.inputSchema,
1258
+ outputSchema: z6.toJSONSchema(CommerceToolOutputs[descriptor.name], { io: "output", unrepresentable: "any" })
1259
+ });
1260
+ }
1261
+ function isTrustedCommerceBuiltInDescriptor(value) {
1262
+ return commerceDiscountBuiltInDescriptors.some((expected) => canonicalJson(expected) === canonicalJson(value));
1263
+ }
1264
+ function isTrustedCommerceBuiltInGrant(value) {
1265
+ return commerceDiscountBuiltInDescriptors.some((expected) => value.toolName === expected.name && value.definitionVersion === expected.definitionVersion && value.contractHash === expected.contractHash);
1266
+ }
1267
+
1075
1268
  export {
1076
1269
  MONEY_PATTERN,
1077
1270
  safeName,
@@ -1101,9 +1294,15 @@ export {
1101
1294
  ConnectionIssueSchema,
1102
1295
  ConnectionResultSchema,
1103
1296
  ToolNameSchema,
1297
+ PublishedGrantedToolSchema,
1298
+ PublishedToolDescriptorSchema,
1299
+ CommerceBuiltInToolNameSchema,
1300
+ CommerceBuiltInToolGrantSchema,
1301
+ CommerceBuiltInToolDescriptorSchema,
1104
1302
  GrantedToolSchema,
1105
- GrantedToolsSchema,
1106
1303
  ToolDescriptorSchema,
1304
+ GrantedToolsSchema,
1305
+ isBuiltInTool,
1107
1306
  POLICY_OPERATIONS,
1108
1307
  ExternalHttpExecutionSchema,
1109
1308
  CommerceExecutionSchema,
@@ -1118,6 +1317,10 @@ export {
1118
1317
  CommerceToolIdentitySchema,
1119
1318
  CommerceToolRevisionIdentitySchema,
1120
1319
  POLICY_OPERATION_DESCRIPTORS,
1320
+ commerceDiscountBuiltInDescriptors,
1321
+ commerceBuiltInToolContractPayload,
1322
+ isTrustedCommerceBuiltInDescriptor,
1323
+ isTrustedCommerceBuiltInGrant,
1121
1324
  CommerceResponseContractSchema,
1122
1325
  EMPTY_RESPONSE_CONTRACT,
1123
1326
  ReferralReasonSchema,
@@ -1145,8 +1348,17 @@ export {
1145
1348
  CommerceErrorCodeSchema,
1146
1349
  commerceToolResultSchema,
1147
1350
  CommerceToolResultSchema,
1351
+ CommerceCategoryCandidateSchema,
1352
+ CommerceCategoryResolutionSchema,
1353
+ CommerceOptionalLookupUnavailableSchema,
1354
+ CommerceConversationToolContextSchema,
1355
+ CommerceProductRecommendationSelectionSchema,
1356
+ CommerceResponseDispositionSchema,
1357
+ CommerceAnswerPresentationSelectionSchema,
1358
+ CommerceShippingInformationInputSchema,
1359
+ CommerceShippingInformationSchema,
1148
1360
  CommerceToolInputs,
1149
1361
  CommerceToolOutputs,
1150
1362
  productBelongsToDomain
1151
1363
  };
1152
- //# sourceMappingURL=chunk-H7AUKACO.js.map
1364
+ //# sourceMappingURL=chunk-HR7T3UEW.js.map