@elementor/editor-canvas 4.2.0-936 → 4.2.0-937
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/index.js +90 -45
- package/dist/index.mjs +90 -45
- package/package.json +19 -19
- package/src/mcp/mcp-description.ts +1 -1
- package/src/mcp/resources/__tests__/widgets-schema-resource.test.ts +95 -0
- package/src/mcp/resources/build-llm-guidance.ts +110 -0
- package/src/mcp/resources/widgets-schema-resource.ts +11 -45
- package/src/mcp/tools/build-composition/prompt.ts +2 -1
- package/src/mcp/tools/configure-element/prompt.ts +2 -0
package/dist/index.js
CHANGED
|
@@ -74,18 +74,6 @@ var import_editor_elements2 = require("@elementor/editor-elements");
|
|
|
74
74
|
var import_editor_mcp = require("@elementor/editor-mcp");
|
|
75
75
|
var import_editor_props = require("@elementor/editor-props");
|
|
76
76
|
|
|
77
|
-
// src/composition-builder/utils/required-default-child-tags.ts
|
|
78
|
-
function getRequiredDefaultChildTemplates(elementConfig) {
|
|
79
|
-
const defaultChildren = elementConfig?.default_children;
|
|
80
|
-
if (!Array.isArray(defaultChildren)) {
|
|
81
|
-
return [];
|
|
82
|
-
}
|
|
83
|
-
return defaultChildren.filter((child) => child?.meta?.required ?? false);
|
|
84
|
-
}
|
|
85
|
-
function getRequiredDefaultChildTypes(elementConfig) {
|
|
86
|
-
return getRequiredDefaultChildTemplates(elementConfig).map((child) => child.widgetType ?? child.elType ?? "").filter((type) => Boolean(type));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
77
|
// src/mcp/utils/element-data-util.ts
|
|
90
78
|
var import_editor_elements = require("@elementor/editor-elements");
|
|
91
79
|
function hasV3Controls(controls) {
|
|
@@ -122,6 +110,84 @@ function getAvailableWidgets() {
|
|
|
122
110
|
});
|
|
123
111
|
}
|
|
124
112
|
|
|
113
|
+
// src/composition-builder/utils/required-default-child-tags.ts
|
|
114
|
+
function getRequiredDefaultChildTemplates(elementConfig) {
|
|
115
|
+
const defaultChildren = elementConfig?.default_children;
|
|
116
|
+
if (!Array.isArray(defaultChildren)) {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
return defaultChildren.filter((child) => child?.meta?.required ?? false);
|
|
120
|
+
}
|
|
121
|
+
function getRequiredDefaultChildTypes(elementConfig) {
|
|
122
|
+
return getRequiredDefaultChildTemplates(elementConfig).map((child) => child.widgetType ?? child.elType ?? "").filter((type) => Boolean(type));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// src/mcp/resources/build-llm-guidance.ts
|
|
126
|
+
var DEFAULT_STYLES_INSTRUCTION = "These are the default styles applied to the widget. Override only when necessary.";
|
|
127
|
+
var DEFAULT_SETTINGS_INSTRUCTION = "These are the default settings applied to the widget. Omit them from elementConfig unless the user explicitly asks to change them.";
|
|
128
|
+
var BASE_SETTING_PROP_HINT = "Has a widget default \u2014 omit unless user explicitly requests a change. See llm_guidance.default_settings.";
|
|
129
|
+
function mergeInstructions(existing, additional) {
|
|
130
|
+
if (typeof existing === "string" && existing.length > 0) {
|
|
131
|
+
return `${existing} ${additional}`;
|
|
132
|
+
}
|
|
133
|
+
return additional;
|
|
134
|
+
}
|
|
135
|
+
function enrichPropertiesWithBaseSettingsHints(properties, baseSettingsKeys) {
|
|
136
|
+
if (!baseSettingsKeys.length) {
|
|
137
|
+
return properties;
|
|
138
|
+
}
|
|
139
|
+
const enriched = { ...properties };
|
|
140
|
+
for (const key of baseSettingsKeys) {
|
|
141
|
+
const propSchema = enriched[key];
|
|
142
|
+
if (!propSchema) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
enriched[key] = {
|
|
146
|
+
...propSchema,
|
|
147
|
+
description: propSchema.description ? `${propSchema.description} ${BASE_SETTING_PROP_HINT}` : BASE_SETTING_PROP_HINT
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return enriched;
|
|
151
|
+
}
|
|
152
|
+
function buildLlmGuidance(widgetData, widgetType, allWidgets) {
|
|
153
|
+
const defaultStyles = {};
|
|
154
|
+
const baseStyleSchema = widgetData?.base_styles;
|
|
155
|
+
if (baseStyleSchema) {
|
|
156
|
+
Object.values(baseStyleSchema).forEach((stylePropType) => {
|
|
157
|
+
stylePropType.variants.forEach((variant) => {
|
|
158
|
+
Object.assign(defaultStyles, variant.props);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
const baseSettings = widgetData?.base_settings ?? {};
|
|
163
|
+
const hasDefaultStyles = Object.keys(defaultStyles).length > 0;
|
|
164
|
+
const hasDefaultSettings = Object.keys(baseSettings).length > 0;
|
|
165
|
+
const llmGuidance = {
|
|
166
|
+
can_have_children: !!widgetData?.meta?.is_container
|
|
167
|
+
};
|
|
168
|
+
if (hasDefaultStyles) {
|
|
169
|
+
llmGuidance.instructions = DEFAULT_STYLES_INSTRUCTION;
|
|
170
|
+
llmGuidance.default_styles = defaultStyles;
|
|
171
|
+
}
|
|
172
|
+
if (hasDefaultSettings) {
|
|
173
|
+
llmGuidance.instructions = mergeInstructions(llmGuidance.instructions, DEFAULT_SETTINGS_INSTRUCTION);
|
|
174
|
+
llmGuidance.default_settings = baseSettings;
|
|
175
|
+
}
|
|
176
|
+
const allowedChildTypes = widgetData.allowed_child_types;
|
|
177
|
+
const allowedParents = Object.entries(allWidgets).filter(([, parentConfig]) => parentConfig.allowed_child_types?.includes(widgetType)).map(([parentType]) => parentType);
|
|
178
|
+
if (allowedChildTypes?.length || allowedParents.length) {
|
|
179
|
+
llmGuidance.nesting = {
|
|
180
|
+
...allowedChildTypes?.length ? { allowed_child_types: allowedChildTypes } : {},
|
|
181
|
+
...allowedParents.length ? { allowed_parents: allowedParents } : {}
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
const requiredDirectChildTags = getRequiredDefaultChildTypes(widgetData);
|
|
185
|
+
if (requiredDirectChildTags.length) {
|
|
186
|
+
llmGuidance.required_direct_children = requiredDirectChildTags;
|
|
187
|
+
}
|
|
188
|
+
return llmGuidance;
|
|
189
|
+
}
|
|
190
|
+
|
|
125
191
|
// src/mcp/resources/widgets-schema-resource.ts
|
|
126
192
|
var V3_LAYOUT_CONTROL_TYPES = /* @__PURE__ */ new Set(["section", "tab", "tabs"]);
|
|
127
193
|
function extractV3ControlsMetadata(controls) {
|
|
@@ -238,40 +304,16 @@ Variables from the user context ARE NOT SUPPORTED AND WILL RESOLVE IN ERROR.
|
|
|
238
304
|
]
|
|
239
305
|
};
|
|
240
306
|
}
|
|
241
|
-
const
|
|
242
|
-
|
|
307
|
+
const baseSettingsKeys = Object.keys(widgetData?.base_settings ?? {});
|
|
308
|
+
const asJson = enrichPropertiesWithBaseSettingsHints(
|
|
309
|
+
Object.fromEntries(
|
|
310
|
+
Object.entries(propSchema).filter(([key, propType]) => import_editor_props.Schema.isPropKeyConfigurable(key, propType)).map(([key, propType]) => [key, import_editor_props.Schema.propTypeToJsonSchema(propType)])
|
|
311
|
+
),
|
|
312
|
+
baseSettingsKeys
|
|
243
313
|
);
|
|
244
314
|
const description = typeof widgetData?.meta?.description === "string" ? widgetData.meta.description : void 0;
|
|
245
|
-
const defaultStyles = {};
|
|
246
|
-
const baseStyleSchema = widgetData?.base_styles;
|
|
247
|
-
if (baseStyleSchema) {
|
|
248
|
-
Object.values(baseStyleSchema).forEach((stylePropType) => {
|
|
249
|
-
stylePropType.variants.forEach((variant) => {
|
|
250
|
-
Object.assign(defaultStyles, variant.props);
|
|
251
|
-
});
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
const hasDefaultStyles = Object.keys(defaultStyles).length > 0;
|
|
255
|
-
const llmGuidance = {
|
|
256
|
-
can_have_children: !!widgetData?.meta?.is_container
|
|
257
|
-
};
|
|
258
|
-
if (hasDefaultStyles) {
|
|
259
|
-
llmGuidance.instructions = "These are the default styles applied to the widget. Override only when necessary.";
|
|
260
|
-
llmGuidance.default_styles = defaultStyles;
|
|
261
|
-
}
|
|
262
|
-
const allowedChildTypes = widgetData.allowed_child_types;
|
|
263
315
|
const allWidgets = (0, import_editor_elements2.getWidgetsCache)() || {};
|
|
264
|
-
const
|
|
265
|
-
if (allowedChildTypes?.length || allowedParents.length) {
|
|
266
|
-
llmGuidance.nesting = {
|
|
267
|
-
...allowedChildTypes?.length ? { allowed_child_types: allowedChildTypes } : {},
|
|
268
|
-
...allowedParents.length ? { allowed_parents: allowedParents } : {}
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
const requiredDirectChildTags = getRequiredDefaultChildTypes(widgetData);
|
|
272
|
-
if (requiredDirectChildTags.length) {
|
|
273
|
-
llmGuidance.required_direct_children = requiredDirectChildTags;
|
|
274
|
-
}
|
|
316
|
+
const llmGuidance = buildLlmGuidance(widgetData, widgetType, allWidgets);
|
|
275
317
|
return {
|
|
276
318
|
contents: [
|
|
277
319
|
{
|
|
@@ -5085,6 +5127,7 @@ Some elements have internal tree structures (nesting). When using these elements
|
|
|
5085
5127
|
- style is raw CSS (property \u2192 value strings); the server converts it to native styles and stores any unconvertible declarations as the element custom CSS
|
|
5086
5128
|
- NO LINKS in configuration
|
|
5087
5129
|
- Retry on errors up to 10x
|
|
5130
|
+
- Check \`llm_guidance.default_settings\` in widget schemas \u2014 omit only keys listed there from elementConfig unless the user explicitly asks to change them
|
|
5088
5131
|
|
|
5089
5132
|
# DYNAMIC TAGS
|
|
5090
5133
|
- A value can be made dynamic wherever its schema exposes a \`"$$type": "dynamic"\` variant. This may be the property root OR a NESTED field (e.g. an image's \`src\`, not the whole \`image\`).
|
|
@@ -5163,7 +5206,7 @@ BAD: \`<e-flexbox style="height:100vh"><e-div-block style="height:100vh">overflo
|
|
|
5163
5206
|
# HARD CONSTRAINTS
|
|
5164
5207
|
- Variables ONLY from [elementor://global-variables] (others throw errors)
|
|
5165
5208
|
- Avoid SVG widgets unless assets are pre-uploaded
|
|
5166
|
-
- Check \`llm_guidance\` in widget schemas
|
|
5209
|
+
- Check \`llm_guidance\` in widget schemas (\`default_styles\`, nesting, required children)
|
|
5167
5210
|
|
|
5168
5211
|
# PARAMETERS
|
|
5169
5212
|
- **xmlStructure**: Valid XML with configuration-id attributes
|
|
@@ -5565,6 +5608,8 @@ For all non-primitive entries in \`propertiesToChange\`, provide the schema \`ke
|
|
|
5565
5608
|
|
|
5566
5609
|
Use the EXACT PropType schema given, and ALWAYS include the \`key\` from the schema for every property you are changing in \`propertiesToChange\`.
|
|
5567
5610
|
|
|
5611
|
+
Check \`llm_guidance.default_settings\` in the widget schema \u2014 include a key in \`propertiesToChange\` only when the user explicitly asks to change it.
|
|
5612
|
+
|
|
5568
5613
|
# Dynamic tags
|
|
5569
5614
|
A value can be made dynamic wherever its schema exposes a variant with "$$type": "dynamic". This may be the property root OR a NESTED field: for example an image is made dynamic on its "src" (the root stays "image"), NOT on the whole "image" value.
|
|
5570
5615
|
Put the dynamic object EXACTLY at the node whose schema offers the "dynamic" variant, in place of the static variant. The variant's "name" enumerates the tags allowed at that node.
|
|
@@ -5922,7 +5967,7 @@ Always check existing resources before building:
|
|
|
5922
5967
|
For each widget you'll use:
|
|
5923
5968
|
- List \`${WIDGET_SCHEMA_URI}\` to see available widgets
|
|
5924
5969
|
- Retrieve configuration schema from \`${ELEMENT_SCHEMA_URI}\` for each widget
|
|
5925
|
-
- Check the \`llm_guidance\` property
|
|
5970
|
+
- Check the \`llm_guidance\` property for container nesting, \`default_styles\`, and \`default_settings\` (omit default_settings from elementConfig unless the user asks to change them)
|
|
5926
5971
|
|
|
5927
5972
|
### 4. Build XML Structure
|
|
5928
5973
|
Create valid XML with configuration-ids:
|
package/dist/index.mjs
CHANGED
|
@@ -8,18 +8,6 @@ import {
|
|
|
8
8
|
Schema
|
|
9
9
|
} from "@elementor/editor-props";
|
|
10
10
|
|
|
11
|
-
// src/composition-builder/utils/required-default-child-tags.ts
|
|
12
|
-
function getRequiredDefaultChildTemplates(elementConfig) {
|
|
13
|
-
const defaultChildren = elementConfig?.default_children;
|
|
14
|
-
if (!Array.isArray(defaultChildren)) {
|
|
15
|
-
return [];
|
|
16
|
-
}
|
|
17
|
-
return defaultChildren.filter((child) => child?.meta?.required ?? false);
|
|
18
|
-
}
|
|
19
|
-
function getRequiredDefaultChildTypes(elementConfig) {
|
|
20
|
-
return getRequiredDefaultChildTemplates(elementConfig).map((child) => child.widgetType ?? child.elType ?? "").filter((type) => Boolean(type));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
11
|
// src/mcp/utils/element-data-util.ts
|
|
24
12
|
import { getWidgetsCache } from "@elementor/editor-elements";
|
|
25
13
|
function hasV3Controls(controls) {
|
|
@@ -56,6 +44,84 @@ function getAvailableWidgets() {
|
|
|
56
44
|
});
|
|
57
45
|
}
|
|
58
46
|
|
|
47
|
+
// src/composition-builder/utils/required-default-child-tags.ts
|
|
48
|
+
function getRequiredDefaultChildTemplates(elementConfig) {
|
|
49
|
+
const defaultChildren = elementConfig?.default_children;
|
|
50
|
+
if (!Array.isArray(defaultChildren)) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
return defaultChildren.filter((child) => child?.meta?.required ?? false);
|
|
54
|
+
}
|
|
55
|
+
function getRequiredDefaultChildTypes(elementConfig) {
|
|
56
|
+
return getRequiredDefaultChildTemplates(elementConfig).map((child) => child.widgetType ?? child.elType ?? "").filter((type) => Boolean(type));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/mcp/resources/build-llm-guidance.ts
|
|
60
|
+
var DEFAULT_STYLES_INSTRUCTION = "These are the default styles applied to the widget. Override only when necessary.";
|
|
61
|
+
var DEFAULT_SETTINGS_INSTRUCTION = "These are the default settings applied to the widget. Omit them from elementConfig unless the user explicitly asks to change them.";
|
|
62
|
+
var BASE_SETTING_PROP_HINT = "Has a widget default \u2014 omit unless user explicitly requests a change. See llm_guidance.default_settings.";
|
|
63
|
+
function mergeInstructions(existing, additional) {
|
|
64
|
+
if (typeof existing === "string" && existing.length > 0) {
|
|
65
|
+
return `${existing} ${additional}`;
|
|
66
|
+
}
|
|
67
|
+
return additional;
|
|
68
|
+
}
|
|
69
|
+
function enrichPropertiesWithBaseSettingsHints(properties, baseSettingsKeys) {
|
|
70
|
+
if (!baseSettingsKeys.length) {
|
|
71
|
+
return properties;
|
|
72
|
+
}
|
|
73
|
+
const enriched = { ...properties };
|
|
74
|
+
for (const key of baseSettingsKeys) {
|
|
75
|
+
const propSchema = enriched[key];
|
|
76
|
+
if (!propSchema) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
enriched[key] = {
|
|
80
|
+
...propSchema,
|
|
81
|
+
description: propSchema.description ? `${propSchema.description} ${BASE_SETTING_PROP_HINT}` : BASE_SETTING_PROP_HINT
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return enriched;
|
|
85
|
+
}
|
|
86
|
+
function buildLlmGuidance(widgetData, widgetType, allWidgets) {
|
|
87
|
+
const defaultStyles = {};
|
|
88
|
+
const baseStyleSchema = widgetData?.base_styles;
|
|
89
|
+
if (baseStyleSchema) {
|
|
90
|
+
Object.values(baseStyleSchema).forEach((stylePropType) => {
|
|
91
|
+
stylePropType.variants.forEach((variant) => {
|
|
92
|
+
Object.assign(defaultStyles, variant.props);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
const baseSettings = widgetData?.base_settings ?? {};
|
|
97
|
+
const hasDefaultStyles = Object.keys(defaultStyles).length > 0;
|
|
98
|
+
const hasDefaultSettings = Object.keys(baseSettings).length > 0;
|
|
99
|
+
const llmGuidance = {
|
|
100
|
+
can_have_children: !!widgetData?.meta?.is_container
|
|
101
|
+
};
|
|
102
|
+
if (hasDefaultStyles) {
|
|
103
|
+
llmGuidance.instructions = DEFAULT_STYLES_INSTRUCTION;
|
|
104
|
+
llmGuidance.default_styles = defaultStyles;
|
|
105
|
+
}
|
|
106
|
+
if (hasDefaultSettings) {
|
|
107
|
+
llmGuidance.instructions = mergeInstructions(llmGuidance.instructions, DEFAULT_SETTINGS_INSTRUCTION);
|
|
108
|
+
llmGuidance.default_settings = baseSettings;
|
|
109
|
+
}
|
|
110
|
+
const allowedChildTypes = widgetData.allowed_child_types;
|
|
111
|
+
const allowedParents = Object.entries(allWidgets).filter(([, parentConfig]) => parentConfig.allowed_child_types?.includes(widgetType)).map(([parentType]) => parentType);
|
|
112
|
+
if (allowedChildTypes?.length || allowedParents.length) {
|
|
113
|
+
llmGuidance.nesting = {
|
|
114
|
+
...allowedChildTypes?.length ? { allowed_child_types: allowedChildTypes } : {},
|
|
115
|
+
...allowedParents.length ? { allowed_parents: allowedParents } : {}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const requiredDirectChildTags = getRequiredDefaultChildTypes(widgetData);
|
|
119
|
+
if (requiredDirectChildTags.length) {
|
|
120
|
+
llmGuidance.required_direct_children = requiredDirectChildTags;
|
|
121
|
+
}
|
|
122
|
+
return llmGuidance;
|
|
123
|
+
}
|
|
124
|
+
|
|
59
125
|
// src/mcp/resources/widgets-schema-resource.ts
|
|
60
126
|
var V3_LAYOUT_CONTROL_TYPES = /* @__PURE__ */ new Set(["section", "tab", "tabs"]);
|
|
61
127
|
function extractV3ControlsMetadata(controls) {
|
|
@@ -172,40 +238,16 @@ Variables from the user context ARE NOT SUPPORTED AND WILL RESOLVE IN ERROR.
|
|
|
172
238
|
]
|
|
173
239
|
};
|
|
174
240
|
}
|
|
175
|
-
const
|
|
176
|
-
|
|
241
|
+
const baseSettingsKeys = Object.keys(widgetData?.base_settings ?? {});
|
|
242
|
+
const asJson = enrichPropertiesWithBaseSettingsHints(
|
|
243
|
+
Object.fromEntries(
|
|
244
|
+
Object.entries(propSchema).filter(([key, propType]) => Schema.isPropKeyConfigurable(key, propType)).map(([key, propType]) => [key, Schema.propTypeToJsonSchema(propType)])
|
|
245
|
+
),
|
|
246
|
+
baseSettingsKeys
|
|
177
247
|
);
|
|
178
248
|
const description = typeof widgetData?.meta?.description === "string" ? widgetData.meta.description : void 0;
|
|
179
|
-
const defaultStyles = {};
|
|
180
|
-
const baseStyleSchema = widgetData?.base_styles;
|
|
181
|
-
if (baseStyleSchema) {
|
|
182
|
-
Object.values(baseStyleSchema).forEach((stylePropType) => {
|
|
183
|
-
stylePropType.variants.forEach((variant) => {
|
|
184
|
-
Object.assign(defaultStyles, variant.props);
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
const hasDefaultStyles = Object.keys(defaultStyles).length > 0;
|
|
189
|
-
const llmGuidance = {
|
|
190
|
-
can_have_children: !!widgetData?.meta?.is_container
|
|
191
|
-
};
|
|
192
|
-
if (hasDefaultStyles) {
|
|
193
|
-
llmGuidance.instructions = "These are the default styles applied to the widget. Override only when necessary.";
|
|
194
|
-
llmGuidance.default_styles = defaultStyles;
|
|
195
|
-
}
|
|
196
|
-
const allowedChildTypes = widgetData.allowed_child_types;
|
|
197
249
|
const allWidgets = getWidgetsCache2() || {};
|
|
198
|
-
const
|
|
199
|
-
if (allowedChildTypes?.length || allowedParents.length) {
|
|
200
|
-
llmGuidance.nesting = {
|
|
201
|
-
...allowedChildTypes?.length ? { allowed_child_types: allowedChildTypes } : {},
|
|
202
|
-
...allowedParents.length ? { allowed_parents: allowedParents } : {}
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
const requiredDirectChildTags = getRequiredDefaultChildTypes(widgetData);
|
|
206
|
-
if (requiredDirectChildTags.length) {
|
|
207
|
-
llmGuidance.required_direct_children = requiredDirectChildTags;
|
|
208
|
-
}
|
|
250
|
+
const llmGuidance = buildLlmGuidance(widgetData, widgetType, allWidgets);
|
|
209
251
|
return {
|
|
210
252
|
contents: [
|
|
211
253
|
{
|
|
@@ -5071,6 +5113,7 @@ Some elements have internal tree structures (nesting). When using these elements
|
|
|
5071
5113
|
- style is raw CSS (property \u2192 value strings); the server converts it to native styles and stores any unconvertible declarations as the element custom CSS
|
|
5072
5114
|
- NO LINKS in configuration
|
|
5073
5115
|
- Retry on errors up to 10x
|
|
5116
|
+
- Check \`llm_guidance.default_settings\` in widget schemas \u2014 omit only keys listed there from elementConfig unless the user explicitly asks to change them
|
|
5074
5117
|
|
|
5075
5118
|
# DYNAMIC TAGS
|
|
5076
5119
|
- A value can be made dynamic wherever its schema exposes a \`"$$type": "dynamic"\` variant. This may be the property root OR a NESTED field (e.g. an image's \`src\`, not the whole \`image\`).
|
|
@@ -5149,7 +5192,7 @@ BAD: \`<e-flexbox style="height:100vh"><e-div-block style="height:100vh">overflo
|
|
|
5149
5192
|
# HARD CONSTRAINTS
|
|
5150
5193
|
- Variables ONLY from [elementor://global-variables] (others throw errors)
|
|
5151
5194
|
- Avoid SVG widgets unless assets are pre-uploaded
|
|
5152
|
-
- Check \`llm_guidance\` in widget schemas
|
|
5195
|
+
- Check \`llm_guidance\` in widget schemas (\`default_styles\`, nesting, required children)
|
|
5153
5196
|
|
|
5154
5197
|
# PARAMETERS
|
|
5155
5198
|
- **xmlStructure**: Valid XML with configuration-id attributes
|
|
@@ -5551,6 +5594,8 @@ For all non-primitive entries in \`propertiesToChange\`, provide the schema \`ke
|
|
|
5551
5594
|
|
|
5552
5595
|
Use the EXACT PropType schema given, and ALWAYS include the \`key\` from the schema for every property you are changing in \`propertiesToChange\`.
|
|
5553
5596
|
|
|
5597
|
+
Check \`llm_guidance.default_settings\` in the widget schema \u2014 include a key in \`propertiesToChange\` only when the user explicitly asks to change it.
|
|
5598
|
+
|
|
5554
5599
|
# Dynamic tags
|
|
5555
5600
|
A value can be made dynamic wherever its schema exposes a variant with "$$type": "dynamic". This may be the property root OR a NESTED field: for example an image is made dynamic on its "src" (the root stays "image"), NOT on the whole "image" value.
|
|
5556
5601
|
Put the dynamic object EXACTLY at the node whose schema offers the "dynamic" variant, in place of the static variant. The variant's "name" enumerates the tags allowed at that node.
|
|
@@ -5908,7 +5953,7 @@ Always check existing resources before building:
|
|
|
5908
5953
|
For each widget you'll use:
|
|
5909
5954
|
- List \`${WIDGET_SCHEMA_URI}\` to see available widgets
|
|
5910
5955
|
- Retrieve configuration schema from \`${ELEMENT_SCHEMA_URI}\` for each widget
|
|
5911
|
-
- Check the \`llm_guidance\` property
|
|
5956
|
+
- Check the \`llm_guidance\` property for container nesting, \`default_styles\`, and \`default_settings\` (omit default_settings from elementConfig unless the user asks to change them)
|
|
5912
5957
|
|
|
5913
5958
|
### 4. Build XML Structure
|
|
5914
5959
|
Create valid XML with configuration-ids:
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-canvas",
|
|
3
3
|
"description": "Elementor Editor Canvas",
|
|
4
|
-
"version": "4.2.0-
|
|
4
|
+
"version": "4.2.0-937",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -37,26 +37,26 @@
|
|
|
37
37
|
"react-dom": "^18.3.1"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@elementor/editor": "4.2.0-
|
|
40
|
+
"@elementor/editor": "4.2.0-937",
|
|
41
41
|
"dompurify": "^3.2.6",
|
|
42
|
-
"@elementor/editor-controls": "4.2.0-
|
|
43
|
-
"@elementor/editor-documents": "4.2.0-
|
|
44
|
-
"@elementor/editor-elements": "4.2.0-
|
|
45
|
-
"@elementor/editor-interactions": "4.2.0-
|
|
46
|
-
"@elementor/editor-mcp": "4.2.0-
|
|
47
|
-
"@elementor/editor-notifications": "4.2.0-
|
|
48
|
-
"@elementor/editor-props": "4.2.0-
|
|
49
|
-
"@elementor/editor-responsive": "4.2.0-
|
|
50
|
-
"@elementor/editor-styles": "4.2.0-
|
|
51
|
-
"@elementor/editor-styles-repository": "4.2.0-
|
|
52
|
-
"@elementor/editor-ui": "4.2.0-
|
|
53
|
-
"@elementor/editor-v1-adapters": "4.2.0-
|
|
54
|
-
"@elementor/http-client": "4.2.0-
|
|
55
|
-
"@elementor/schema": "4.2.0-
|
|
56
|
-
"@elementor/twing": "4.2.0-
|
|
42
|
+
"@elementor/editor-controls": "4.2.0-937",
|
|
43
|
+
"@elementor/editor-documents": "4.2.0-937",
|
|
44
|
+
"@elementor/editor-elements": "4.2.0-937",
|
|
45
|
+
"@elementor/editor-interactions": "4.2.0-937",
|
|
46
|
+
"@elementor/editor-mcp": "4.2.0-937",
|
|
47
|
+
"@elementor/editor-notifications": "4.2.0-937",
|
|
48
|
+
"@elementor/editor-props": "4.2.0-937",
|
|
49
|
+
"@elementor/editor-responsive": "4.2.0-937",
|
|
50
|
+
"@elementor/editor-styles": "4.2.0-937",
|
|
51
|
+
"@elementor/editor-styles-repository": "4.2.0-937",
|
|
52
|
+
"@elementor/editor-ui": "4.2.0-937",
|
|
53
|
+
"@elementor/editor-v1-adapters": "4.2.0-937",
|
|
54
|
+
"@elementor/http-client": "4.2.0-937",
|
|
55
|
+
"@elementor/schema": "4.2.0-937",
|
|
56
|
+
"@elementor/twing": "4.2.0-937",
|
|
57
57
|
"@elementor/ui": "1.37.5",
|
|
58
|
-
"@elementor/utils": "4.2.0-
|
|
59
|
-
"@elementor/wp-media": "4.2.0-
|
|
58
|
+
"@elementor/utils": "4.2.0-937",
|
|
59
|
+
"@elementor/wp-media": "4.2.0-937",
|
|
60
60
|
"@floating-ui/react": "^0.27.5",
|
|
61
61
|
"@wordpress/i18n": "^5.13.0"
|
|
62
62
|
},
|
|
@@ -41,7 +41,7 @@ Always check existing resources before building:
|
|
|
41
41
|
For each widget you'll use:
|
|
42
42
|
- List \`${ WIDGET_SCHEMA_URI }\` to see available widgets
|
|
43
43
|
- Retrieve configuration schema from \`${ ELEMENT_SCHEMA_URI }\` for each widget
|
|
44
|
-
- Check the \`llm_guidance\` property
|
|
44
|
+
- Check the \`llm_guidance\` property for container nesting, \`default_styles\`, and \`default_settings\` (omit default_settings from elementConfig unless the user asks to change them)
|
|
45
45
|
|
|
46
46
|
### 4. Build XML Structure
|
|
47
47
|
Create valid XML with configuration-ids:
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { type V1ElementConfig } from '@elementor/editor-elements';
|
|
2
|
+
|
|
3
|
+
import { buildLlmGuidance, enrichPropertiesWithBaseSettingsHints, mergeInstructions } from '../build-llm-guidance';
|
|
4
|
+
|
|
5
|
+
const mockEmailBaseSettings = {
|
|
6
|
+
email: {
|
|
7
|
+
$$type: 'emails',
|
|
8
|
+
value: {
|
|
9
|
+
to: {
|
|
10
|
+
$$type: 'string-array',
|
|
11
|
+
value: [ { $$type: 'string', value: 'admin@example.com' } ],
|
|
12
|
+
},
|
|
13
|
+
from: { $$type: 'string', value: 'email@example.com' },
|
|
14
|
+
message: { $$type: 'string', value: '[all-fields]' },
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const mockFormWidgetData = {
|
|
20
|
+
title: 'Form',
|
|
21
|
+
controls: {},
|
|
22
|
+
elType: 'widget',
|
|
23
|
+
meta: { is_container: true },
|
|
24
|
+
base_settings: mockEmailBaseSettings,
|
|
25
|
+
atomic_props_schema: {
|
|
26
|
+
email: { kind: 'object', key: 'emails' },
|
|
27
|
+
'form-name': { kind: 'string', key: 'string' },
|
|
28
|
+
},
|
|
29
|
+
} as unknown as V1ElementConfig;
|
|
30
|
+
|
|
31
|
+
describe( 'build-llm-guidance', () => {
|
|
32
|
+
it( 'mergeInstructions combines existing and additional instructions', () => {
|
|
33
|
+
expect( mergeInstructions( 'First.', 'Second.' ) ).toBe( 'First. Second.' );
|
|
34
|
+
expect( mergeInstructions( undefined, 'Only.' ) ).toBe( 'Only.' );
|
|
35
|
+
} );
|
|
36
|
+
|
|
37
|
+
it( 'buildLlmGuidance exposes default_settings for widgets with base_settings', () => {
|
|
38
|
+
const guidance = buildLlmGuidance( mockFormWidgetData, 'e-form', {} );
|
|
39
|
+
|
|
40
|
+
expect( guidance.default_settings ).toEqual( mockEmailBaseSettings );
|
|
41
|
+
expect( guidance.instructions ).toContain( 'Omit them from elementConfig unless the user explicitly asks' );
|
|
42
|
+
expect( guidance.can_have_children ).toBe( true );
|
|
43
|
+
} );
|
|
44
|
+
|
|
45
|
+
it( 'buildLlmGuidance merges style and settings instructions when both exist', () => {
|
|
46
|
+
const widgetData = {
|
|
47
|
+
...mockFormWidgetData,
|
|
48
|
+
base_styles: {
|
|
49
|
+
'e-form-base': {
|
|
50
|
+
variants: [
|
|
51
|
+
{
|
|
52
|
+
props: {
|
|
53
|
+
display: { $$type: 'string', value: 'flex' },
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
} as unknown as V1ElementConfig;
|
|
60
|
+
|
|
61
|
+
const guidance = buildLlmGuidance( widgetData, 'e-form', {} );
|
|
62
|
+
|
|
63
|
+
expect( guidance.default_styles ).toEqual( { display: { $$type: 'string', value: 'flex' } } );
|
|
64
|
+
expect( guidance.default_settings ).toEqual( mockEmailBaseSettings );
|
|
65
|
+
expect( guidance.instructions ).toContain( 'default styles' );
|
|
66
|
+
expect( guidance.instructions ).toContain( 'default settings' );
|
|
67
|
+
} );
|
|
68
|
+
|
|
69
|
+
it( 'enrichPropertiesWithBaseSettingsHints adds omit guidance to base setting props', () => {
|
|
70
|
+
const enriched = enrichPropertiesWithBaseSettingsHints(
|
|
71
|
+
{
|
|
72
|
+
email: { type: 'object' },
|
|
73
|
+
'form-name': { type: 'object' },
|
|
74
|
+
},
|
|
75
|
+
[ 'email' ]
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
expect( enriched.email.description ).toContain( 'llm_guidance.default_settings' );
|
|
79
|
+
expect( enriched[ 'form-name' ].description ).toBeUndefined();
|
|
80
|
+
} );
|
|
81
|
+
} );
|
|
82
|
+
|
|
83
|
+
describe( 'widgets-schema-resource base_settings integration', () => {
|
|
84
|
+
it( 'keeps base setting props in schema while enriching descriptions', () => {
|
|
85
|
+
const properties = enrichPropertiesWithBaseSettingsHints(
|
|
86
|
+
{
|
|
87
|
+
email: { type: 'object', properties: {} },
|
|
88
|
+
},
|
|
89
|
+
Object.keys( mockEmailBaseSettings )
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
expect( properties ).toHaveProperty( 'email' );
|
|
93
|
+
expect( properties.email.description ).toContain( 'omit unless user explicitly requests' );
|
|
94
|
+
} );
|
|
95
|
+
} );
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { type V1ElementConfig } from '@elementor/editor-elements';
|
|
2
|
+
import { type Props, type PropValue } from '@elementor/editor-props';
|
|
3
|
+
|
|
4
|
+
import { getRequiredDefaultChildTypes } from '../../composition-builder/utils/required-default-child-tags';
|
|
5
|
+
|
|
6
|
+
const DEFAULT_STYLES_INSTRUCTION = 'These are the default styles applied to the widget. Override only when necessary.';
|
|
7
|
+
|
|
8
|
+
const DEFAULT_SETTINGS_INSTRUCTION =
|
|
9
|
+
'These are the default settings applied to the widget. Omit them from elementConfig unless the user explicitly asks to change them.';
|
|
10
|
+
|
|
11
|
+
const BASE_SETTING_PROP_HINT =
|
|
12
|
+
'Has a widget default — omit unless user explicitly requests a change. See llm_guidance.default_settings.';
|
|
13
|
+
|
|
14
|
+
export type LlmGuidance = Record< string, unknown >;
|
|
15
|
+
|
|
16
|
+
export type JsonSchemaProperty = {
|
|
17
|
+
description?: string;
|
|
18
|
+
[ key: string ]: unknown;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export function mergeInstructions( existing: unknown, additional: string ): string {
|
|
22
|
+
if ( typeof existing === 'string' && existing.length > 0 ) {
|
|
23
|
+
return `${ existing } ${ additional }`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return additional;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function enrichPropertiesWithBaseSettingsHints(
|
|
30
|
+
properties: Record< string, JsonSchemaProperty >,
|
|
31
|
+
baseSettingsKeys: string[]
|
|
32
|
+
): Record< string, JsonSchemaProperty > {
|
|
33
|
+
if ( ! baseSettingsKeys.length ) {
|
|
34
|
+
return properties;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const enriched: Record< string, JsonSchemaProperty > = { ...properties };
|
|
38
|
+
|
|
39
|
+
for ( const key of baseSettingsKeys ) {
|
|
40
|
+
const propSchema = enriched[ key ];
|
|
41
|
+
|
|
42
|
+
if ( ! propSchema ) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
enriched[ key ] = {
|
|
47
|
+
...propSchema,
|
|
48
|
+
description: propSchema.description
|
|
49
|
+
? `${ propSchema.description } ${ BASE_SETTING_PROP_HINT }`
|
|
50
|
+
: BASE_SETTING_PROP_HINT,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return enriched;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function buildLlmGuidance(
|
|
58
|
+
widgetData: V1ElementConfig,
|
|
59
|
+
widgetType: string,
|
|
60
|
+
allWidgets: Record< string, V1ElementConfig >
|
|
61
|
+
): LlmGuidance {
|
|
62
|
+
const defaultStyles: Record< string, Props > = {};
|
|
63
|
+
const baseStyleSchema = widgetData?.base_styles;
|
|
64
|
+
|
|
65
|
+
if ( baseStyleSchema ) {
|
|
66
|
+
Object.values( baseStyleSchema ).forEach( ( stylePropType ) => {
|
|
67
|
+
stylePropType.variants.forEach( ( variant ) => {
|
|
68
|
+
Object.assign( defaultStyles, variant.props );
|
|
69
|
+
} );
|
|
70
|
+
} );
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const baseSettings = ( widgetData?.base_settings ?? {} ) as Record< string, PropValue >;
|
|
74
|
+
const hasDefaultStyles = Object.keys( defaultStyles ).length > 0;
|
|
75
|
+
const hasDefaultSettings = Object.keys( baseSettings ).length > 0;
|
|
76
|
+
|
|
77
|
+
const llmGuidance: LlmGuidance = {
|
|
78
|
+
can_have_children: !! widgetData?.meta?.is_container,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
if ( hasDefaultStyles ) {
|
|
82
|
+
llmGuidance.instructions = DEFAULT_STYLES_INSTRUCTION;
|
|
83
|
+
llmGuidance.default_styles = defaultStyles;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if ( hasDefaultSettings ) {
|
|
87
|
+
llmGuidance.instructions = mergeInstructions( llmGuidance.instructions, DEFAULT_SETTINGS_INSTRUCTION );
|
|
88
|
+
llmGuidance.default_settings = baseSettings;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const allowedChildTypes = widgetData.allowed_child_types;
|
|
92
|
+
const allowedParents = Object.entries( allWidgets )
|
|
93
|
+
.filter( ( [ , parentConfig ] ) => parentConfig.allowed_child_types?.includes( widgetType ) )
|
|
94
|
+
.map( ( [ parentType ] ) => parentType );
|
|
95
|
+
|
|
96
|
+
if ( allowedChildTypes?.length || allowedParents.length ) {
|
|
97
|
+
llmGuidance.nesting = {
|
|
98
|
+
...( allowedChildTypes?.length ? { allowed_child_types: allowedChildTypes } : {} ),
|
|
99
|
+
...( allowedParents.length ? { allowed_parents: allowedParents } : {} ),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const requiredDirectChildTags = getRequiredDefaultChildTypes( widgetData );
|
|
104
|
+
|
|
105
|
+
if ( requiredDirectChildTags.length ) {
|
|
106
|
+
llmGuidance.required_direct_children = requiredDirectChildTags;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return llmGuidance;
|
|
110
|
+
}
|
|
@@ -3,15 +3,14 @@ import { type MCPRegistryEntry, ResourceTemplate } from '@elementor/editor-mcp';
|
|
|
3
3
|
import {
|
|
4
4
|
type ArrayPropType,
|
|
5
5
|
type ObjectPropType,
|
|
6
|
-
type Props,
|
|
7
6
|
type PropType,
|
|
8
7
|
Schema,
|
|
9
8
|
type TransformablePropType,
|
|
10
9
|
type UnionPropType,
|
|
11
10
|
} from '@elementor/editor-props';
|
|
12
11
|
|
|
13
|
-
import { getRequiredDefaultChildTypes } from '../../composition-builder/utils/required-default-child-tags';
|
|
14
12
|
import { hasV3Controls, isWidgetAvailableForLLM } from '../utils/element-data-util';
|
|
13
|
+
import { buildLlmGuidance, enrichPropertiesWithBaseSettingsHints } from './build-llm-guidance';
|
|
15
14
|
|
|
16
15
|
const V3_LAYOUT_CONTROL_TYPES = new Set( [ 'section', 'tab', 'tabs' ] );
|
|
17
16
|
|
|
@@ -143,55 +142,22 @@ Variables from the user context ARE NOT SUPPORTED AND WILL RESOLVE IN ERROR.
|
|
|
143
142
|
],
|
|
144
143
|
};
|
|
145
144
|
}
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
145
|
+
const baseSettingsKeys = Object.keys( widgetData?.base_settings ?? {} );
|
|
146
|
+
|
|
147
|
+
const asJson = enrichPropertiesWithBaseSettingsHints(
|
|
148
|
+
Object.fromEntries(
|
|
149
|
+
Object.entries( propSchema )
|
|
150
|
+
.filter( ( [ key, propType ] ) => Schema.isPropKeyConfigurable( key, propType as PropType ) )
|
|
151
|
+
.map( ( [ key, propType ] ) => [ key, Schema.propTypeToJsonSchema( propType ) ] )
|
|
152
|
+
),
|
|
153
|
+
baseSettingsKeys
|
|
150
154
|
);
|
|
151
155
|
|
|
152
156
|
const description =
|
|
153
157
|
typeof widgetData?.meta?.description === 'string' ? widgetData.meta.description : undefined;
|
|
154
158
|
|
|
155
|
-
const defaultStyles: Record< string, Props > = {};
|
|
156
|
-
const baseStyleSchema = widgetData?.base_styles;
|
|
157
|
-
if ( baseStyleSchema ) {
|
|
158
|
-
Object.values( baseStyleSchema ).forEach( ( stylePropType ) => {
|
|
159
|
-
stylePropType.variants.forEach( ( variant ) => {
|
|
160
|
-
Object.assign( defaultStyles, variant.props );
|
|
161
|
-
} );
|
|
162
|
-
} );
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// build llm instructions
|
|
166
|
-
const hasDefaultStyles = Object.keys( defaultStyles ).length > 0;
|
|
167
|
-
const llmGuidance: Record< string, unknown > = {
|
|
168
|
-
can_have_children: !! widgetData?.meta?.is_container,
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
if ( hasDefaultStyles ) {
|
|
172
|
-
llmGuidance.instructions =
|
|
173
|
-
'These are the default styles applied to the widget. Override only when necessary.';
|
|
174
|
-
llmGuidance.default_styles = defaultStyles;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const allowedChildTypes = widgetData.allowed_child_types;
|
|
178
|
-
|
|
179
159
|
const allWidgets = getWidgetsCache() || {};
|
|
180
|
-
const
|
|
181
|
-
.filter( ( [ , parentConfig ] ) => parentConfig.allowed_child_types?.includes( widgetType ) )
|
|
182
|
-
.map( ( [ parentType ] ) => parentType );
|
|
183
|
-
|
|
184
|
-
if ( allowedChildTypes?.length || allowedParents.length ) {
|
|
185
|
-
llmGuidance.nesting = {
|
|
186
|
-
...( allowedChildTypes?.length ? { allowed_child_types: allowedChildTypes } : {} ),
|
|
187
|
-
...( allowedParents.length ? { allowed_parents: allowedParents } : {} ),
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const requiredDirectChildTags = getRequiredDefaultChildTypes( widgetData );
|
|
192
|
-
if ( requiredDirectChildTags.length ) {
|
|
193
|
-
llmGuidance.required_direct_children = requiredDirectChildTags;
|
|
194
|
-
}
|
|
160
|
+
const llmGuidance = buildLlmGuidance( widgetData, widgetType, allWidgets );
|
|
195
161
|
|
|
196
162
|
return {
|
|
197
163
|
contents: [
|
|
@@ -41,6 +41,7 @@ Some elements have internal tree structures (nesting). When using these elements
|
|
|
41
41
|
- style is raw CSS (property → value strings); the server converts it to native styles and stores any unconvertible declarations as the element custom CSS
|
|
42
42
|
- NO LINKS in configuration
|
|
43
43
|
- Retry on errors up to 10x
|
|
44
|
+
- Check \`llm_guidance.default_settings\` in widget schemas — omit only keys listed there from elementConfig unless the user explicitly asks to change them
|
|
44
45
|
|
|
45
46
|
# DYNAMIC TAGS
|
|
46
47
|
- A value can be made dynamic wherever its schema exposes a \`"$$type": "dynamic"\` variant. This may be the property root OR a NESTED field (e.g. an image's \`src\`, not the whole \`image\`).
|
|
@@ -119,7 +120,7 @@ BAD: \`<e-flexbox style="height:100vh"><e-div-block style="height:100vh">overflo
|
|
|
119
120
|
# HARD CONSTRAINTS
|
|
120
121
|
- Variables ONLY from [elementor://global-variables] (others throw errors)
|
|
121
122
|
- Avoid SVG widgets unless assets are pre-uploaded
|
|
122
|
-
- Check \`llm_guidance\` in widget schemas
|
|
123
|
+
- Check \`llm_guidance\` in widget schemas (\`default_styles\`, nesting, required children)
|
|
123
124
|
|
|
124
125
|
# PARAMETERS
|
|
125
126
|
- **xmlStructure**: Valid XML with configuration-id attributes
|
|
@@ -50,6 +50,8 @@ For all non-primitive entries in \`propertiesToChange\`, provide the schema \`ke
|
|
|
50
50
|
|
|
51
51
|
Use the EXACT PropType schema given, and ALWAYS include the \`key\` from the schema for every property you are changing in \`propertiesToChange\`.
|
|
52
52
|
|
|
53
|
+
Check \`llm_guidance.default_settings\` in the widget schema — include a key in \`propertiesToChange\` only when the user explicitly asks to change it.
|
|
54
|
+
|
|
53
55
|
# Dynamic tags
|
|
54
56
|
A value can be made dynamic wherever its schema exposes a variant with "$$type": "dynamic". This may be the property root OR a NESTED field: for example an image is made dynamic on its "src" (the root stays "image"), NOT on the whole "image" value.
|
|
55
57
|
Put the dynamic object EXACTLY at the node whose schema offers the "dynamic" variant, in place of the static variant. The variant's "name" enumerates the tags allowed at that node.
|