@alpaca-editor/core 1.0.4033 → 1.0.4037

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.
Files changed (187) hide show
  1. package/dist/components/index.d.ts +1 -0
  2. package/dist/components/index.js +1 -0
  3. package/dist/components/index.js.map +1 -1
  4. package/dist/{editor/menubar → components/ui}/LanguageSelector.d.ts +1 -1
  5. package/dist/{editor/menubar → components/ui}/LanguageSelector.js +8 -8
  6. package/dist/components/ui/LanguageSelector.js.map +1 -0
  7. package/dist/components/ui/button.d.ts +1 -1
  8. package/dist/components/ui/dropdown-menu.d.ts +1 -1
  9. package/dist/components/ui/dropdown-menu.js +2 -2
  10. package/dist/components/ui/dropdown-menu.js.map +1 -1
  11. package/dist/components/ui/sonner.js +3 -1
  12. package/dist/components/ui/sonner.js.map +1 -1
  13. package/dist/config/config.js +5 -5
  14. package/dist/config/config.js.map +1 -1
  15. package/dist/editor/ContentTree.d.ts +2 -1
  16. package/dist/editor/ContentTree.js +33 -9
  17. package/dist/editor/ContentTree.js.map +1 -1
  18. package/dist/editor/PictureEditor.js +2 -2
  19. package/dist/editor/PictureEditor.js.map +1 -1
  20. package/dist/editor/ScrollingContentTree.d.ts +2 -1
  21. package/dist/editor/ScrollingContentTree.js +2 -2
  22. package/dist/editor/ScrollingContentTree.js.map +1 -1
  23. package/dist/editor/Terminal.d.ts +2 -0
  24. package/dist/editor/Terminal.js +2 -2
  25. package/dist/editor/Terminal.js.map +1 -1
  26. package/dist/editor/ai/AgentHistory.d.ts +11 -0
  27. package/dist/editor/ai/AgentHistory.js +12 -0
  28. package/dist/editor/ai/AgentHistory.js.map +1 -0
  29. package/dist/editor/ai/Agents.js +187 -24
  30. package/dist/editor/ai/Agents.js.map +1 -1
  31. package/dist/editor/ai/AiResponseMessage.d.ts +2 -1
  32. package/dist/editor/ai/AiResponseMessage.js +6 -6
  33. package/dist/editor/ai/AiResponseMessage.js.map +1 -1
  34. package/dist/editor/ai/AiTerminal.d.ts +1 -0
  35. package/dist/editor/ai/AiTerminal.js +330 -43
  36. package/dist/editor/ai/AiTerminal.js.map +1 -1
  37. package/dist/editor/client/itemsRepository.js +19 -7
  38. package/dist/editor/client/itemsRepository.js.map +1 -1
  39. package/dist/editor/field-types/InternalLinkFieldEditor.js +48 -1
  40. package/dist/editor/field-types/InternalLinkFieldEditor.js.map +1 -1
  41. package/dist/editor/field-types/richtext/contextMenuFactory.js +1 -1
  42. package/dist/editor/field-types/richtext/contextMenuFactory.js.map +1 -1
  43. package/dist/editor/menubar/ItemLanguageVersion.js +1 -1
  44. package/dist/editor/menubar/ItemLanguageVersion.js.map +1 -1
  45. package/dist/editor/menubar/PageSelector.js +1 -1
  46. package/dist/editor/menubar/PageSelector.js.map +1 -1
  47. package/dist/editor/page-editor-chrome/FieldActionIndicator.js +1 -1
  48. package/dist/editor/page-editor-chrome/FieldActionIndicator.js.map +1 -1
  49. package/dist/editor/page-editor-chrome/FieldEditedIndicator.js +2 -2
  50. package/dist/editor/page-editor-chrome/FieldEditedIndicator.js.map +1 -1
  51. package/dist/editor/page-editor-chrome/FrameMenu.js +2 -2
  52. package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
  53. package/dist/editor/page-editor-chrome/InlineEditor.js +9 -9
  54. package/dist/editor/page-editor-chrome/InlineEditor.js.map +1 -1
  55. package/dist/editor/page-editor-chrome/LockedFieldIndicator.js +2 -2
  56. package/dist/editor/page-editor-chrome/LockedFieldIndicator.js.map +1 -1
  57. package/dist/editor/page-editor-chrome/PageEditorChrome.js +1 -1
  58. package/dist/editor/page-editor-chrome/PageEditorChrome.js.map +1 -1
  59. package/dist/editor/page-editor-chrome/PictureEditorOverlay.js +1 -1
  60. package/dist/editor/page-editor-chrome/PictureEditorOverlay.js.map +1 -1
  61. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +1 -1
  62. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +2 -2
  63. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
  64. package/dist/editor/page-editor-chrome/useInlineAICompletion.js +12 -12
  65. package/dist/editor/page-editor-chrome/useInlineAICompletion.js.map +1 -1
  66. package/dist/editor/page-viewer/EditorForm.js +1 -1
  67. package/dist/editor/page-viewer/EditorForm.js.map +1 -1
  68. package/dist/editor/page-viewer/MiniMap.js +10 -11
  69. package/dist/editor/page-viewer/MiniMap.js.map +1 -1
  70. package/dist/editor/page-viewer/PageViewer.js +2 -2
  71. package/dist/editor/page-viewer/PageViewer.js.map +1 -1
  72. package/dist/editor/page-viewer/PageViewerFrame.js +4 -4
  73. package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
  74. package/dist/editor/page-viewer/pageViewContext.d.ts +2 -2
  75. package/dist/editor/page-viewer/pageViewContext.js +11 -14
  76. package/dist/editor/page-viewer/pageViewContext.js.map +1 -1
  77. package/dist/editor/services/agentService.d.ts +21 -1
  78. package/dist/editor/services/agentService.js +101 -0
  79. package/dist/editor/services/agentService.js.map +1 -1
  80. package/dist/editor/services/aiService.d.ts +1 -1
  81. package/dist/editor/services/aiService.js +1 -2
  82. package/dist/editor/services/aiService.js.map +1 -1
  83. package/dist/editor/sidebar/GraphQL.js +5 -6
  84. package/dist/editor/sidebar/GraphQL.js.map +1 -1
  85. package/dist/editor/sidebar/MainContentTree.d.ts +2 -1
  86. package/dist/editor/sidebar/MainContentTree.js +9 -5
  87. package/dist/editor/sidebar/MainContentTree.js.map +1 -1
  88. package/dist/editor/ui/Icons.d.ts +5 -0
  89. package/dist/editor/ui/Icons.js +3 -0
  90. package/dist/editor/ui/Icons.js.map +1 -1
  91. package/dist/editor/ui/ItemNameDialogNew.js +26 -14
  92. package/dist/editor/ui/ItemNameDialogNew.js.map +1 -1
  93. package/dist/editor/ui/PerfectTree.js +54 -2
  94. package/dist/editor/ui/PerfectTree.js.map +1 -1
  95. package/dist/editor/views/CompareView.js +3 -3
  96. package/dist/editor/views/CompareView.js.map +1 -1
  97. package/dist/editor/views/EditView.js +1 -1
  98. package/dist/editor/views/EditView.js.map +1 -1
  99. package/dist/editor/views/ItemEditor.js +1 -1
  100. package/dist/editor/views/ItemEditor.js.map +1 -1
  101. package/dist/index.d.ts +3 -4
  102. package/dist/index.js +3 -4
  103. package/dist/index.js.map +1 -1
  104. package/dist/page-wizard/steps/ContentStep.js +5 -5
  105. package/dist/page-wizard/steps/ContentStep.js.map +1 -1
  106. package/dist/page-wizard/steps/FindItemsStep.js +1 -1
  107. package/dist/page-wizard/steps/ImagesStep.js +1 -1
  108. package/dist/page-wizard/steps/ImagesStep.js.map +1 -1
  109. package/dist/page-wizard/steps/LayoutStep.js +1 -1
  110. package/dist/page-wizard/steps/LayoutStep.js.map +1 -1
  111. package/dist/page-wizard/steps/MetaDataStep.js +1 -1
  112. package/dist/page-wizard/steps/MetaDataStep.js.map +1 -1
  113. package/dist/page-wizard/steps/SelectStep.js +1 -1
  114. package/dist/page-wizard/steps/StructureStep.js +28 -11
  115. package/dist/page-wizard/steps/StructureStep.js.map +1 -1
  116. package/dist/page-wizard/steps/TranslateStep.d.ts +1 -0
  117. package/dist/page-wizard/steps/TranslateStep.js +67 -73
  118. package/dist/page-wizard/steps/TranslateStep.js.map +1 -1
  119. package/dist/revision.d.ts +2 -2
  120. package/dist/revision.js +2 -2
  121. package/dist/splash-screen/NewPage.js +1 -1
  122. package/dist/splash-screen/NewPage.js.map +1 -1
  123. package/dist/splash-screen/OpenPage.js +1 -1
  124. package/dist/splash-screen/OpenPage.js.map +1 -1
  125. package/dist/styles.css +71 -8
  126. package/package.json +1 -1
  127. package/src/components/index.ts +1 -0
  128. package/src/{editor/menubar → components/ui}/LanguageSelector.tsx +12 -12
  129. package/src/components/ui/dropdown-menu.tsx +3 -1
  130. package/src/components/ui/sonner.tsx +5 -1
  131. package/src/config/config.tsx +4 -3
  132. package/src/editor/ContentTree.tsx +41 -12
  133. package/src/editor/PictureEditor.tsx +2 -2
  134. package/src/editor/ScrollingContentTree.tsx +3 -0
  135. package/src/editor/Terminal.tsx +16 -7
  136. package/src/editor/ai/AgentHistory.tsx +85 -0
  137. package/src/editor/ai/Agents.tsx +256 -88
  138. package/src/editor/ai/AiResponseMessage.tsx +25 -11
  139. package/src/editor/ai/AiTerminal.tsx +571 -73
  140. package/src/editor/client/itemsRepository.ts +29 -12
  141. package/src/editor/field-types/InternalLinkFieldEditor.tsx +52 -1
  142. package/src/editor/field-types/richtext/components/SimpleRichTextEditor.css +64 -0
  143. package/src/editor/field-types/richtext/contextMenuFactory.tsx +7 -8
  144. package/src/editor/menubar/ItemLanguageVersion.tsx +1 -1
  145. package/src/editor/menubar/PageSelector.tsx +1 -0
  146. package/src/editor/page-editor-chrome/FieldActionIndicator.tsx +1 -1
  147. package/src/editor/page-editor-chrome/FieldEditedIndicator.tsx +3 -3
  148. package/src/editor/page-editor-chrome/FrameMenu.tsx +2 -2
  149. package/src/editor/page-editor-chrome/InlineEditor.tsx +9 -12
  150. package/src/editor/page-editor-chrome/LockedFieldIndicator.tsx +3 -3
  151. package/src/editor/page-editor-chrome/PageEditorChrome.tsx +3 -3
  152. package/src/editor/page-editor-chrome/PictureEditorOverlay.tsx +1 -1
  153. package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +1 -1
  154. package/src/editor/page-editor-chrome/PlaceholderDropZones.tsx +2 -2
  155. package/src/editor/page-editor-chrome/useInlineAICompletion.tsx +12 -18
  156. package/src/editor/page-viewer/EditorForm.tsx +1 -1
  157. package/src/editor/page-viewer/MiniMap.tsx +10 -11
  158. package/src/editor/page-viewer/PageViewer.tsx +8 -3
  159. package/src/editor/page-viewer/PageViewerFrame.tsx +4 -4
  160. package/src/editor/page-viewer/pageViewContext.ts +71 -66
  161. package/src/editor/services/agentService.ts +129 -1
  162. package/src/editor/services/aiService.ts +2 -4
  163. package/src/editor/sidebar/GraphQL.tsx +16 -15
  164. package/src/editor/sidebar/MainContentTree.tsx +12 -4
  165. package/src/editor/ui/Icons.tsx +35 -0
  166. package/src/editor/ui/ItemNameDialogNew.tsx +29 -13
  167. package/src/editor/ui/PerfectTree.tsx +70 -4
  168. package/src/editor/views/CompareView.tsx +3 -3
  169. package/src/editor/views/EditView.tsx +1 -1
  170. package/src/editor/views/ItemEditor.tsx +1 -1
  171. package/src/index.ts +10 -4
  172. package/src/page-wizard/steps/ContentStep.tsx +5 -5
  173. package/src/page-wizard/steps/FindItemsStep.tsx +1 -1
  174. package/src/page-wizard/steps/ImagesStep.tsx +1 -1
  175. package/src/page-wizard/steps/LayoutStep.tsx +1 -1
  176. package/src/page-wizard/steps/MetaDataStep.tsx +1 -1
  177. package/src/page-wizard/steps/SelectStep.tsx +1 -1
  178. package/src/page-wizard/steps/StructureStep.tsx +41 -17
  179. package/src/page-wizard/steps/TranslateStep.tsx +326 -222
  180. package/src/revision.ts +2 -2
  181. package/src/splash-screen/NewPage.tsx +1 -0
  182. package/src/splash-screen/OpenPage.tsx +1 -0
  183. package/dist/components/SimpleLanguageSelector.d.ts +0 -10
  184. package/dist/components/SimpleLanguageSelector.js +0 -59
  185. package/dist/components/SimpleLanguageSelector.js.map +0 -1
  186. package/dist/editor/menubar/LanguageSelector.js.map +0 -1
  187. package/src/components/SimpleLanguageSelector.tsx +0 -113
@@ -373,7 +373,7 @@ const NodeContent = memo(
373
373
  event: React.DragEvent<any>;
374
374
  isMultiSelect: boolean;
375
375
  }) => void;
376
- onDragEnd?: (event: React.DragEvent<any>) => void;
376
+ onDragEnd?: (event: React.DragEvent<any> | null) => void;
377
377
  onDragOverZone?: (
378
378
  parent: TreeNode<any> | null,
379
379
  index: number,
@@ -427,7 +427,7 @@ const NodeContent = memo(
427
427
  onStartDrag({ node, event, isMultiSelect: isMultiSelect ?? false });
428
428
  }
429
429
  },
430
- [node, onStartDrag],
430
+ [node, onStartDrag, isSelected, selectedKeys],
431
431
  );
432
432
 
433
433
  const handleDragLeave = useCallback((event: React.DragEvent<any>) => {
@@ -642,23 +642,63 @@ export const PerfectTree = <T,>({
642
642
 
643
643
  // Global drag end handler.
644
644
  const isDraggingRef = React.useRef(false);
645
+ const dragTimeoutRef = React.useRef<NodeJS.Timeout | undefined>(undefined);
646
+
645
647
  useEffect(() => {
646
648
  const handleGlobalDragEnd = (event: DragEvent) => {
647
649
  if (isDraggingRef.current && onDragEnd) {
648
650
  onDragEnd(event as unknown as React.DragEvent);
649
651
  isDraggingRef.current = false;
650
652
  }
653
+ // Clear timeout when drag ends properly
654
+ if (dragTimeoutRef.current !== undefined) {
655
+ clearTimeout(dragTimeoutRef.current!);
656
+ dragTimeoutRef.current = undefined;
657
+ }
658
+ };
659
+
660
+ const handleEscapeKey = (event: KeyboardEvent) => {
661
+ if (event.key === "Escape" && isDraggingRef.current && onDragEnd) {
662
+ onDragEnd(null);
663
+ isDraggingRef.current = false;
664
+ if (dragTimeoutRef.current !== undefined) {
665
+ clearTimeout(dragTimeoutRef.current!);
666
+ dragTimeoutRef.current = undefined;
667
+ }
668
+ }
669
+ };
670
+
671
+ const handleMouseLeave = (event: Event) => {
672
+ // Reset drag state if mouse leaves the window during a drag
673
+ if (isDraggingRef.current && onDragEnd) {
674
+ onDragEnd(null);
675
+ isDraggingRef.current = false;
676
+ if (dragTimeoutRef.current !== undefined) {
677
+ clearTimeout(dragTimeoutRef.current!);
678
+ dragTimeoutRef.current = undefined;
679
+ }
680
+ }
651
681
  };
652
682
 
653
683
  document.addEventListener("dragend", handleGlobalDragEnd);
684
+ document.addEventListener("keydown", handleEscapeKey);
685
+ window.addEventListener("mouseleave", handleMouseLeave);
686
+
654
687
  return () => {
655
688
  document.removeEventListener("dragend", handleGlobalDragEnd);
689
+ document.removeEventListener("keydown", handleEscapeKey);
690
+ window.removeEventListener("mouseleave", handleMouseLeave);
656
691
  };
657
692
  }, [onDragEnd]);
658
693
 
659
694
  const handleDragEnd = useCallback(
660
- (event: React.DragEvent<HTMLDivElement>) => {
695
+ (event: React.DragEvent<HTMLDivElement> | null) => {
661
696
  isDraggingRef.current = false;
697
+ // Clear timeout when drag ends normally
698
+ if (dragTimeoutRef.current !== undefined) {
699
+ clearTimeout(dragTimeoutRef.current!);
700
+ dragTimeoutRef.current = undefined;
701
+ }
662
702
  if (onDragEnd) {
663
703
  onDragEnd(event);
664
704
  }
@@ -666,6 +706,32 @@ export const PerfectTree = <T,>({
666
706
  [onDragEnd],
667
707
  );
668
708
 
709
+ // Wrapper for onStartDrag that has access to the refs
710
+ const handleStartDragWithTimeout = useCallback(
711
+ (data: {
712
+ node: TreeNode<T>;
713
+ event: React.DragEvent<any>;
714
+ isMultiSelect: boolean;
715
+ }) => {
716
+ // Set the dragging ref to true when drag starts
717
+ isDraggingRef.current = true;
718
+
719
+ // Set up a timeout to auto-reset drag state if it gets stuck
720
+ dragTimeoutRef.current = setTimeout(() => {
721
+ if (isDraggingRef.current && onDragEnd) {
722
+ onDragEnd(null);
723
+ isDraggingRef.current = false;
724
+ }
725
+ }, 30000); // 30 second timeout
726
+
727
+ // Call the original onStartDrag
728
+ if (onStartDrag) {
729
+ onStartDrag(data);
730
+ }
731
+ },
732
+ [onStartDrag, onDragEnd],
733
+ );
734
+
669
735
  // Scroll to selected node when scrollToSelected is enabled and selectedKeys change
670
736
  const treeRef = useRef<HTMLDivElement>(null);
671
737
 
@@ -840,7 +906,7 @@ export const PerfectTree = <T,>({
840
906
  isSelected={isSelected}
841
907
  onSelect={handleSelect}
842
908
  onToggleNode={handleToggle}
843
- onStartDrag={onStartDrag}
909
+ onStartDrag={handleStartDragWithTimeout}
844
910
  onDragEnd={handleDragEnd}
845
911
  onDragOverZone={onDragOverZone}
846
912
  onDrop={onDrop}
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useState } from "react";
2
2
  import { useEditContext } from "../client/editContext";
3
- import { LanguageSelector } from "../menubar/LanguageSelector";
3
+ import { LanguageSelector } from "../../components/ui/LanguageSelector";
4
4
  import { VersionSelector } from "../menubar/VersionSelector";
5
5
  import { FullItem, ItemDescriptor, Version } from "../pageModel";
6
6
  import { usePageViewContext } from "../page-viewer/pageViewContext";
@@ -115,7 +115,7 @@ export function CompareView() {
115
115
  }
116
116
 
117
117
  const originalSelector = (
118
- <div className=" gap-1 flex flex-1 flex-shrink-0 items-center justify-center border-b bg-white p-1 text-sm text-gray-600">
118
+ <div className="flex flex-1 flex-shrink-0 items-center justify-center gap-1 border-b bg-white p-1 text-sm text-gray-600">
119
119
  <LanguageSelector
120
120
  selectedLanguage={editContext.contentEditorItem?.descriptor?.language}
121
121
  showAllLanguagesSwitch={false}
@@ -149,7 +149,7 @@ export function CompareView() {
149
149
  );
150
150
 
151
151
  const compareToSelector = (
152
- <div className="gap-1 flex flex-1 flex-shrink-0 items-center justify-center border-b bg-white p-1 text-sm text-gray-600">
152
+ <div className="flex flex-1 flex-shrink-0 items-center justify-center gap-1 border-b bg-white p-1 text-sm text-gray-600">
153
153
  <LanguageSelector
154
154
  selectedLanguage={compareTo?.language}
155
155
  showAllLanguagesSwitch={false}
@@ -9,7 +9,7 @@ export function EditView() {
9
9
  if (!editContext.contentEditorItem?.descriptor)
10
10
  return (
11
11
  <div className="grid h-full w-full items-center justify-center">
12
- <div className="text-sm text-gray-500">Not item selected</div>
12
+ <div className="text-xs text-gray-500">No item selected</div>
13
13
  </div>
14
14
  );
15
15
 
@@ -5,7 +5,7 @@ import { ItemInfo } from "../ItemInfo";
5
5
  import { useEditContext } from "../client/editContext";
6
6
  import { PageViewContext } from "../page-viewer/pageViewContext";
7
7
  import { FullItem } from "../pageModel";
8
- import { LanguageSelector } from "../menubar/LanguageSelector";
8
+ import { LanguageSelector } from "../../components/ui/LanguageSelector";
9
9
 
10
10
  export function ItemEditor({
11
11
  item,
package/src/index.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  export * from "./config/types";
2
2
 
3
3
  export * from "./types";
4
- export { useEditorSettings, useItemNameValidation } from "./editor/hooks/useEditorSettings";
4
+ export {
5
+ useEditorSettings,
6
+ useItemNameValidation,
7
+ } from "./editor/hooks/useEditorSettings";
5
8
 
6
9
  export { Editor } from "./editor/Editor";
7
10
 
@@ -25,10 +28,13 @@ export * from "./fonts";
25
28
  export { Card } from "./components/ui/card";
26
29
  export { Button } from "./components/ui/button";
27
30
 
28
- export { getFilteredInputData, setDataProperty } from "./page-wizard/utils/dataAccessor";
31
+ export {
32
+ getFilteredInputData,
33
+ setDataProperty,
34
+ } from "./page-wizard/utils/dataAccessor";
35
+
36
+ export { LanguageSelector } from "./components/ui/LanguageSelector";
29
37
 
30
- export { LanguageSelector } from "./editor/menubar/LanguageSelector";
31
- export { SimpleLanguageSelector } from "./components/SimpleLanguageSelector";
32
38
  export type { Language } from "./editor/pageModel";
33
39
 
34
40
  export { MainContentTree } from "./editor/sidebar/MainContentTree";
@@ -26,7 +26,7 @@ import { usePageCreator } from "./usePageCreator";
26
26
  import { useThrottledCallback } from "use-debounce";
27
27
  import { InputTextarea } from "primereact/inputtextarea";
28
28
  import { Input } from "../../components/ui/input";
29
- import { LanguageSelector } from "../../editor/menubar/LanguageSelector";
29
+ import { LanguageSelector } from "../../components/ui/LanguageSelector";
30
30
  import { EditControls } from "../../editor/menubar/toolbar-sections/EditControls";
31
31
  import {
32
32
  getFilteredInputData,
@@ -150,7 +150,7 @@ export function ContentStep({
150
150
  { editContext, createAiContext: createWizardAiContext },
151
151
  {
152
152
  allowedFunctions: ["get-children", "create-item"],
153
- model: step.fields.aiModel || "gpt-4.1",
153
+ model: step.fields.aiModel || undefined,
154
154
  },
155
155
  { signal: abortController.signal },
156
156
  (response) => {
@@ -520,7 +520,7 @@ export function ContentStep({
520
520
  },
521
521
  ],
522
522
  { editContext, createAiContext: createWizardAiContext },
523
- { model: step.fields.aiModel || "gpt-4.1" },
523
+ { model: step.fields.aiModel || undefined },
524
524
  { signal: abortController.signal },
525
525
  (response) => {
526
526
  try {
@@ -826,7 +826,7 @@ export function ContentStep({
826
826
  },
827
827
  {
828
828
  allowedFunctions: [],
829
- model: step.fields.aiModel || "gpt-4.1",
829
+ model: step.fields.aiModel || undefined,
830
830
  endpoint: "/alpaca/editor/page-wizard/prompt",
831
831
  },
832
832
  { signal: localAbortController.signal },
@@ -1060,7 +1060,7 @@ export function ContentStep({
1060
1060
  <div className="relative mb-4">
1061
1061
  <label
1062
1062
  htmlFor="language"
1063
- className="mb-1 block text-sm font-medium"
1063
+ className="mb-1 block text-xs font-medium"
1064
1064
  >
1065
1065
  Language
1066
1066
  </label>
@@ -246,7 +246,7 @@ Return a JSON object with suggested item IDs in this format:
246
246
  createAiContext: createWizardAiContext,
247
247
  },
248
248
  {
249
- model: step.fields.aiModel || "gpt-4.1",
249
+ model: step.fields.aiModel || undefined,
250
250
  allowedFunctions: ["get-children"],
251
251
  endpoint: "/alpaca/editor/page-wizard/prompt",
252
252
  },
@@ -120,7 +120,7 @@ export const ImagesStep = (props: StepComponentProps) => {
120
120
  },
121
121
  ],
122
122
  { editContext: editContext!, createAiContext: createWizardAiContext },
123
- { model: "gpt-4.1" },
123
+ { model: props.step.fields.aiModel || undefined },
124
124
  { signal: localAbortController.signal },
125
125
  );
126
126
 
@@ -89,7 +89,7 @@ export function LayoutStep({
89
89
  },
90
90
  ],
91
91
  { editContext, createAiContext: createWizardAiContext },
92
- { model: "gpt-4.1" },
92
+ { model: step.fields.aiModel || undefined },
93
93
  { signal: abortController.signal },
94
94
  (response: any) => {
95
95
  try {
@@ -69,7 +69,7 @@ export function MetaDataStep({
69
69
  },
70
70
  ],
71
71
  { editContext, createAiContext: createWizardAiContext },
72
- { model: "gpt-4.1" },
72
+ { model: step.fields.aiModel || undefined },
73
73
  { signal: abortController.signal },
74
74
  (response: any) => {
75
75
  try {
@@ -114,7 +114,7 @@ Create ${step.fields.numberOfOptions || 5} relevant options.`,
114
114
  },
115
115
  ],
116
116
  { editContext, createAiContext: createWizardAiContext },
117
- { model: step.fields.aiModel || "gpt-4.1" },
117
+ { model: step.fields.aiModel || undefined },
118
118
  { signal: abortController.signal },
119
119
  );
120
120
 
@@ -42,7 +42,7 @@ export function StructureStep({
42
42
  // Get the property name from the step or use "structure" as default
43
43
  const inputProperties =
44
44
  step.fields?.inputProperties || step.fields?.propertyName || "structure";
45
- const propertyName = step.fields.propertyName || "structure";
45
+ const propertyName = step.fields?.propertyName || "structure";
46
46
 
47
47
  useEffect(() => {
48
48
  const { value: existingStructure, error } = evaluateDataExpression(
@@ -79,8 +79,19 @@ export function StructureStep({
79
79
  inputProperties,
80
80
  data,
81
81
  );
82
- if (existingStructure) {
82
+ if (Array.isArray(existingStructure)) {
83
83
  setStructure(existingStructure);
84
+ } else if (
85
+ existingStructure &&
86
+ typeof existingStructure === "object" &&
87
+ Array.isArray((existingStructure as any).sections)
88
+ ) {
89
+ setStructure((existingStructure as any).sections);
90
+ } else if (existingStructure !== undefined) {
91
+ console.warn(
92
+ "StructureStep: existing structure is not an array; ignoring value",
93
+ existingStructure,
94
+ );
84
95
  }
85
96
  }, [data, inputProperties]);
86
97
 
@@ -177,7 +188,7 @@ ${customInstructionsResult.value ? `Additional requirements: ${customInstruction
177
188
  { editContext, createAiContext: createWizardAiContext },
178
189
  {
179
190
  allowedFunctions: [],
180
- model: step.fields.aiModel || "gpt-4.1",
191
+ model: step.fields.aiModel || undefined,
181
192
  endpoint: "/alpaca/editor/page-wizard/prompt",
182
193
  },
183
194
  undefined,
@@ -196,18 +207,31 @@ ${customInstructionsResult.value ? `Additional requirements: ${customInstruction
196
207
  sections: StructureElement[];
197
208
  };
198
209
 
199
- setStructure(generatedStructure.sections);
200
- setData((prevData) =>
201
- setDataProperty(
202
- propertyName,
203
- generatedStructure.sections,
204
- prevData,
205
- ),
206
- );
207
- setInternalState((state: any) => ({
208
- ...state,
209
- [step.id + "structure"]: generatedStructure.sections,
210
- }));
210
+
211
+ const sections: StructureElement[] | undefined = Array.isArray(
212
+ generatedStructure?.sections,
213
+ )
214
+ ? generatedStructure.sections
215
+ : undefined;
216
+
217
+ if (!sections) {
218
+ console.error(
219
+ "StructureStep: AI response missing valid 'sections' array",
220
+ generatedStructure,
221
+ );
222
+ setError(
223
+ "Failed to parse structure. The response did not include a valid 'sections' array.",
224
+ );
225
+ } else {
226
+ setStructure(sections);
227
+ setData((prevData) =>
228
+ setDataProperty(propertyName, sections, prevData),
229
+ );
230
+ setInternalState((state: any) => ({
231
+ ...state,
232
+ [step.id + "structure"]: sections,
233
+ }));
234
+ }
211
235
  }
212
236
  } catch (parseError) {
213
237
  console.error("Error parsing structure:", parseError);
@@ -316,7 +340,7 @@ ${customInstructionsResult.value ? `Additional requirements: ${customInstruction
316
340
  )}
317
341
 
318
342
  {/* Generated Structure */}
319
- {structure.length > 0 && (
343
+ {(structure?.length ?? 0) > 0 && (
320
344
  <div className="space-y-4">
321
345
  <h3 className="text-sm font-medium text-gray-900">
322
346
  Generated Structure
@@ -401,7 +425,7 @@ ${customInstructionsResult.value ? `Additional requirements: ${customInstruction
401
425
  <ActionButton onClick={generateStructure} disabled={loading}>
402
426
  <div className="flex items-center gap-2">
403
427
  <Settings className="h-4 w-4" />
404
- {structure.length > 0
428
+ {(structure?.length ?? 0) > 0
405
429
  ? "Regenerate Structure"
406
430
  : "Generate Structure"}
407
431
  </div>