@adobe/spacecat-shared-utils 1.114.0 → 1.115.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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [@adobe/spacecat-shared-utils-v1.115.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-utils-v1.114.0...@adobe/spacecat-shared-utils-v1.115.0) (2026-05-04)
2
+
3
+ ### Features
4
+
5
+ * **strategy:** add type discriminator and experimentId for Atomic strategies | LLMO-4643 ([#1571](https://github.com/adobe/spacecat-shared/issues/1571)) ([0151ff5](https://github.com/adobe/spacecat-shared/commit/0151ff510f7643021e6c1ccf21298f6d3c07034b))
6
+
1
7
  ## [@adobe/spacecat-shared-utils-v1.114.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-utils-v1.113.0...@adobe/spacecat-shared-utils-v1.114.0) (2026-05-04)
2
8
 
3
9
  ### Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-utils",
3
- "version": "1.114.0",
3
+ "version": "1.115.0",
4
4
  "description": "Shared modules of the Spacecat Services - utils",
5
5
  "type": "module",
6
6
  "exports": {
@@ -38,6 +38,10 @@ const strategyGoalType = z.union([
38
38
  z.string(), // Catchall for future goal types
39
39
  ]);
40
40
 
41
+ // Discriminator between Atomic (experiment-driven) and Evolving (iterative) strategies.
42
+ // Existing pre-GA strategies have no `type` field and default to 'evolving' for backward compat.
43
+ const strategyType = z.enum(['atomic', 'evolving']);
44
+
41
45
  /**
42
46
  * Library opportunity - user-created reusable opportunity template
43
47
  */
@@ -76,6 +80,7 @@ const strategyPromptSelection = z.object({
76
80
  */
77
81
  const strategy = z.object({
78
82
  id: nonEmptyString,
83
+ type: strategyType.default('evolving'),
79
84
  name: nonEmptyString,
80
85
  status: workflowStatus,
81
86
  url: z.union([z.string(), z.array(z.string())]),
@@ -90,6 +95,7 @@ const strategy = z.object({
90
95
  createdBy: z.string().optional(), // Email of strategy creator/owner
91
96
  completedAt: z.string().optional(), // ISO 8601 date string
92
97
  goalType: strategyGoalType.optional(),
98
+ experimentId: z.uuid().nullable().optional(),
93
99
  });
94
100
 
95
101
  /**
@@ -138,4 +144,37 @@ export const strategyWorkspaceData = z.object({
138
144
  }
139
145
  });
140
146
  });
147
+
148
+ // Validate type-based invariants (Atomic vs Evolving)
149
+ strategies.forEach((strat, strategyIndex) => {
150
+ // Atomic must have a non-null experimentId
151
+ if (strat.type === 'atomic' && (strat.experimentId === undefined || strat.experimentId === null)) {
152
+ ctx.addIssue({
153
+ code: 'custom',
154
+ path: ['strategies', strategyIndex, 'experimentId'],
155
+ message: 'Atomic strategies require a non-null experimentId',
156
+ });
157
+ }
158
+
159
+ // Atomic must not carry selectedPrompts (those come from GeoExperiment)
160
+ if (strat.type === 'atomic' && Array.isArray(strat.selectedPrompts) && strat.selectedPrompts.length > 0) {
161
+ ctx.addIssue({
162
+ code: 'custom',
163
+ path: ['strategies', strategyIndex, 'selectedPrompts'],
164
+ message: 'Atomic strategies must not carry selectedPrompts (use GeoExperiment.promptsLocation)',
165
+ });
166
+ }
167
+
168
+ // Evolving: schema is intentionally permissive on `selectedPrompts`. Today's
169
+ // CreateStrategyDialog initializes selectedPrompts as `[]` for newly-created
170
+ // Evolving strategies (no prompt-selection UI yet). Enforcing "must be
171
+ // non-empty" at the schema would reject those in-flight reads + writes.
172
+ //
173
+ // The "newly-created Evolving strategies must include selectedPrompts" rule
174
+ // is deferred to the milestone where Evolving promotes out of co-innovation
175
+ // mode — at that point the schema tightens, the API layer (saveStrategy)
176
+ // adds the creation-time check, and the prompt-selection screen ships.
177
+ // All three land together. Until then, selectedPrompts on Evolving is
178
+ // structurally validated only.
179
+ });
141
180
  });