@strapi/content-type-builder 5.58.0 → 5.60.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.
Files changed (130) hide show
  1. package/dist/admin/components/AIChat/FeedbackModal.js +13 -7
  2. package/dist/admin/components/AIChat/FeedbackModal.js.map +1 -1
  3. package/dist/admin/components/AIChat/FeedbackModal.mjs +14 -8
  4. package/dist/admin/components/AIChat/FeedbackModal.mjs.map +1 -1
  5. package/dist/admin/components/AIChat/UploadCodeModal.js +12 -6
  6. package/dist/admin/components/AIChat/UploadCodeModal.js.map +1 -1
  7. package/dist/admin/components/AIChat/UploadCodeModal.mjs +13 -7
  8. package/dist/admin/components/AIChat/UploadCodeModal.mjs.map +1 -1
  9. package/dist/admin/components/AIChat/UploadFigmaModal.js +12 -6
  10. package/dist/admin/components/AIChat/UploadFigmaModal.js.map +1 -1
  11. package/dist/admin/components/AIChat/UploadFigmaModal.mjs +13 -7
  12. package/dist/admin/components/AIChat/UploadFigmaModal.mjs.map +1 -1
  13. package/dist/admin/components/AIChat/components/Attachments/components/Attachment.js +6 -3
  14. package/dist/admin/components/AIChat/components/Attachments/components/Attachment.js.map +1 -1
  15. package/dist/admin/components/AIChat/components/Attachments/components/Attachment.mjs +7 -4
  16. package/dist/admin/components/AIChat/components/Attachments/components/Attachment.mjs.map +1 -1
  17. package/dist/admin/components/AIChat/components/Collapsible.js +9 -4
  18. package/dist/admin/components/AIChat/components/Collapsible.js.map +1 -1
  19. package/dist/admin/components/AIChat/components/Collapsible.mjs +10 -5
  20. package/dist/admin/components/AIChat/components/Collapsible.mjs.map +1 -1
  21. package/dist/admin/components/AIChat/components/Dropzone.js +13 -6
  22. package/dist/admin/components/AIChat/components/Dropzone.js.map +1 -1
  23. package/dist/admin/components/AIChat/components/Dropzone.mjs +14 -7
  24. package/dist/admin/components/AIChat/components/Dropzone.mjs.map +1 -1
  25. package/dist/admin/components/AIChat/components/FloatingPanel.js +11 -4
  26. package/dist/admin/components/AIChat/components/FloatingPanel.js.map +1 -1
  27. package/dist/admin/components/AIChat/components/FloatingPanel.mjs +12 -5
  28. package/dist/admin/components/AIChat/components/FloatingPanel.mjs.map +1 -1
  29. package/dist/admin/components/AIChat/components/FullScreenImage.js +16 -8
  30. package/dist/admin/components/AIChat/components/FullScreenImage.js.map +1 -1
  31. package/dist/admin/components/AIChat/components/FullScreenImage.mjs +17 -9
  32. package/dist/admin/components/AIChat/components/FullScreenImage.mjs.map +1 -1
  33. package/dist/admin/components/AIChat/components/Input.js +6 -3
  34. package/dist/admin/components/AIChat/components/Input.js.map +1 -1
  35. package/dist/admin/components/AIChat/components/Input.mjs +7 -4
  36. package/dist/admin/components/AIChat/components/Input.mjs.map +1 -1
  37. package/dist/admin/components/AIChat/components/Messages/Message.js +88 -12
  38. package/dist/admin/components/AIChat/components/Messages/Message.js.map +1 -1
  39. package/dist/admin/components/AIChat/components/Messages/Message.mjs +87 -13
  40. package/dist/admin/components/AIChat/components/Messages/Message.mjs.map +1 -1
  41. package/dist/admin/components/AIChat/components/StepModal.js +44 -17
  42. package/dist/admin/components/AIChat/components/StepModal.js.map +1 -1
  43. package/dist/admin/components/AIChat/components/StepModal.mjs +45 -18
  44. package/dist/admin/components/AIChat/components/StepModal.mjs.map +1 -1
  45. package/dist/admin/components/AIChat/providers/ChatProvider.js +79 -27
  46. package/dist/admin/components/AIChat/providers/ChatProvider.js.map +1 -1
  47. package/dist/admin/components/AIChat/providers/ChatProvider.mjs +80 -28
  48. package/dist/admin/components/AIChat/providers/ChatProvider.mjs.map +1 -1
  49. package/dist/admin/components/AIChat/providers/SchemaProvider.js +6 -3
  50. package/dist/admin/components/AIChat/providers/SchemaProvider.js.map +1 -1
  51. package/dist/admin/components/AIChat/providers/SchemaProvider.mjs +7 -4
  52. package/dist/admin/components/AIChat/providers/SchemaProvider.mjs.map +1 -1
  53. package/dist/admin/components/AttributeOptions/AttributeOption.js +2 -2
  54. package/dist/admin/components/AttributeOptions/AttributeOption.js.map +1 -1
  55. package/dist/admin/components/AttributeOptions/AttributeOption.mjs +2 -2
  56. package/dist/admin/components/AttributeOptions/AttributeOption.mjs.map +1 -1
  57. package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.js.map +1 -1
  58. package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.mjs.map +1 -1
  59. package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.js.map +1 -1
  60. package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.mjs.map +1 -1
  61. package/dist/admin/components/CustomRadioGroup/CustomRadioGroup.js +2 -1
  62. package/dist/admin/components/CustomRadioGroup/CustomRadioGroup.js.map +1 -1
  63. package/dist/admin/components/CustomRadioGroup/CustomRadioGroup.mjs +2 -1
  64. package/dist/admin/components/CustomRadioGroup/CustomRadioGroup.mjs.map +1 -1
  65. package/dist/admin/components/DataManager/DataManagerProvider.js +317 -275
  66. package/dist/admin/components/DataManager/DataManagerProvider.js.map +1 -1
  67. package/dist/admin/components/DataManager/DataManagerProvider.mjs +319 -277
  68. package/dist/admin/components/DataManager/DataManagerProvider.mjs.map +1 -1
  69. package/dist/admin/components/DataManager/RenameMigrationModal.js.map +1 -1
  70. package/dist/admin/components/DataManager/RenameMigrationModal.mjs.map +1 -1
  71. package/dist/admin/components/DataManager/reducer.js +31 -4
  72. package/dist/admin/components/DataManager/reducer.js.map +1 -1
  73. package/dist/admin/components/DataManager/reducer.mjs +31 -4
  74. package/dist/admin/components/DataManager/reducer.mjs.map +1 -1
  75. package/dist/admin/components/DynamicZoneList.js +2 -1
  76. package/dist/admin/components/DynamicZoneList.js.map +1 -1
  77. package/dist/admin/components/DynamicZoneList.mjs +2 -1
  78. package/dist/admin/components/DynamicZoneList.mjs.map +1 -1
  79. package/dist/admin/components/FormModal/attributes/ConditionForm.js +2 -1
  80. package/dist/admin/components/FormModal/attributes/ConditionForm.js.map +1 -1
  81. package/dist/admin/components/FormModal/attributes/ConditionForm.mjs +2 -1
  82. package/dist/admin/components/FormModal/attributes/ConditionForm.mjs.map +1 -1
  83. package/dist/admin/components/FormModal/attributes/types.js +2 -2
  84. package/dist/admin/components/FormModal/attributes/types.js.map +1 -1
  85. package/dist/admin/components/FormModal/attributes/types.mjs +2 -2
  86. package/dist/admin/components/FormModal/attributes/types.mjs.map +1 -1
  87. package/dist/admin/components/FormModal/forms/forms.js +1 -1
  88. package/dist/admin/components/FormModal/forms/forms.js.map +1 -1
  89. package/dist/admin/components/FormModal/forms/forms.mjs +1 -1
  90. package/dist/admin/components/FormModal/forms/forms.mjs.map +1 -1
  91. package/dist/admin/components/GenericInputs.js +2 -1
  92. package/dist/admin/components/GenericInputs.js.map +1 -1
  93. package/dist/admin/components/GenericInputs.mjs +2 -1
  94. package/dist/admin/components/GenericInputs.mjs.map +1 -1
  95. package/dist/admin/components/TabForm.js.map +1 -1
  96. package/dist/admin/components/TabForm.mjs.map +1 -1
  97. package/dist/admin/src/components/AIChat/components/FullScreenImage.d.ts +8 -0
  98. package/dist/admin/src/components/AIChat/components/Messages/Message.d.ts +20 -0
  99. package/dist/admin/utils/folderTelemetry.js.map +1 -1
  100. package/dist/admin/utils/folderTelemetry.mjs.map +1 -1
  101. package/dist/admin/utils/formAPI.js.map +1 -1
  102. package/dist/admin/utils/formAPI.mjs.map +1 -1
  103. package/dist/server/controllers/validation/common.js +1 -1
  104. package/dist/server/controllers/validation/common.js.map +1 -1
  105. package/dist/server/controllers/validation/common.mjs +1 -1
  106. package/dist/server/controllers/validation/common.mjs.map +1 -1
  107. package/dist/server/controllers/validation/schema.js +3 -2
  108. package/dist/server/controllers/validation/schema.js.map +1 -1
  109. package/dist/server/controllers/validation/schema.mjs +4 -3
  110. package/dist/server/controllers/validation/schema.mjs.map +1 -1
  111. package/dist/server/register.js.map +1 -1
  112. package/dist/server/register.mjs.map +1 -1
  113. package/dist/server/services/migration-builder/index.js.map +1 -1
  114. package/dist/server/services/migration-builder/index.mjs.map +1 -1
  115. package/dist/server/services/schema.js +34 -1
  116. package/dist/server/services/schema.js.map +1 -1
  117. package/dist/server/services/schema.mjs +34 -1
  118. package/dist/server/services/schema.mjs.map +1 -1
  119. package/dist/server/src/controllers/validation/schema.d.ts.map +1 -1
  120. package/dist/server/src/register.d.ts.map +1 -1
  121. package/dist/server/src/services/migration-builder/index.d.ts.map +1 -1
  122. package/dist/server/src/services/schema-builder/types.d.ts.map +1 -1
  123. package/dist/server/src/services/schema.d.ts.map +1 -1
  124. package/dist/server/src/utils/uid-target.d.ts +18 -0
  125. package/dist/server/src/utils/uid-target.d.ts.map +1 -0
  126. package/dist/server/utils/uid-target.js +34 -0
  127. package/dist/server/utils/uid-target.js.map +1 -0
  128. package/dist/server/utils/uid-target.mjs +31 -0
  129. package/dist/server/utils/uid-target.mjs.map +1 -0
  130. package/package.json +6 -6
@@ -42,14 +42,14 @@ const BaseChatProvider = ({ children, defaultOpen = false })=>{
42
42
  contentTypes,
43
43
  components
44
44
  ]);
45
- const { id, messages, sendMessage: _sendMessage, status, stop, ...chat } = useAIFetch.useAIChat({
45
+ const { id, messages, sendMessage: _sendMessage, status, stop, setMessages, regenerate, clearError, error, resumeStream, addToolResult, addToolOutput, addToolApprovalResponse } = useAIFetch.useAIChat({
46
46
  id: chatId?.toString(),
47
47
  experimental_throttle: 100
48
48
  });
49
49
  /* -------------------------------------------------------------------------------------------------
50
50
  * AI SDK chat overrides
51
51
  * -----------------------------------------------------------------------------------------------*/ // NOTE: body is using state variables, so they can not be passed as a prop in useChat
52
- const sendMessage = async (message, options)=>{
52
+ const sendMessage = React.useCallback(async (message, options)=>{
53
53
  if (status === 'streaming' || status === 'submitted') {
54
54
  return;
55
55
  }
@@ -63,8 +63,13 @@ const BaseChatProvider = ({ children, defaultOpen = false })=>{
63
63
  }
64
64
  }
65
65
  });
66
- };
67
- const handleSubmit = (e)=>{
66
+ }, [
67
+ _sendMessage,
68
+ lastSeenSchemas,
69
+ schemas,
70
+ status
71
+ ]);
72
+ const handleSubmit = React.useCallback((e)=>{
68
73
  e.preventDefault();
69
74
  if (status === 'streaming' || status === 'submitted') {
70
75
  return;
@@ -85,7 +90,12 @@ const BaseChatProvider = ({ children, defaultOpen = false })=>{
85
90
  });
86
91
  setInput('');
87
92
  setAttachments([]);
88
- };
93
+ }, [
94
+ attachments,
95
+ input,
96
+ sendMessage,
97
+ status
98
+ ]);
89
99
  /* -------------------------------------------------------------------------------------------------
90
100
  * Chat title
91
101
  * -----------------------------------------------------------------------------------------------*/ const { title, generateTitle, resetTitle } = useChatTitle.useChatTitle({
@@ -118,42 +128,84 @@ const BaseChatProvider = ({ children, defaultOpen = false })=>{
118
128
  trackUsage
119
129
  ]);
120
130
  const isChatAvailable = ee.useAIAvailability();
121
- return /*#__PURE__*/ jsxRuntime.jsx(ChatContext.Provider, {
122
- value: {
131
+ const handleInputChange = React.useCallback((e)=>setInput(e.target.value), []);
132
+ const reset = React.useCallback(()=>{
133
+ stop();
134
+ setChatId(generateRandomId());
135
+ trackUsage('didStartNewChat');
136
+ resetTitle();
137
+ }, [
138
+ resetTitle,
139
+ stop,
140
+ trackUsage
141
+ ]);
142
+ const openChat = React.useCallback(()=>{
143
+ setIsChatOpen(true);
144
+ // if this is the first open, it's a new chat
145
+ if (openCount === 0) {
146
+ trackUsage('didStartNewChat');
147
+ }
148
+ setOpenCount((prev)=>prev + 1);
149
+ }, [
150
+ openCount,
151
+ trackUsage
152
+ ]);
153
+ const closeChat = React.useCallback(()=>setIsChatOpen(false), []);
154
+ const contextValue = React.useMemo(()=>({
123
155
  isChatEnabled: isChatAvailable,
124
156
  id,
125
157
  status,
126
158
  stop,
127
159
  sendMessage,
128
- ...chat,
160
+ setMessages,
161
+ regenerate,
162
+ clearError,
163
+ error,
164
+ resumeStream,
165
+ addToolResult,
166
+ addToolOutput,
167
+ addToolApprovalResponse,
129
168
  messages,
130
169
  handleSubmit,
131
170
  input,
132
171
  setInput,
133
- handleInputChange: (e)=>setInput(e.target.value),
134
- reset: ()=>{
135
- stop();
136
- setChatId(generateRandomId());
137
- trackUsage('didStartNewChat');
138
- resetTitle();
139
- },
172
+ handleInputChange,
173
+ reset,
140
174
  schemas,
141
- // Chat
142
175
  title,
143
176
  isChatOpen,
144
- openChat: ()=>{
145
- setIsChatOpen(true);
146
- // if this is the first open, it's a new chat
147
- if (openCount === 0) {
148
- trackUsage('didStartNewChat');
149
- }
150
- setOpenCount((prev)=>prev + 1);
151
- },
152
- closeChat: ()=>setIsChatOpen(false),
153
- // Attachments
177
+ openChat,
178
+ closeChat,
154
179
  attachments,
155
180
  setAttachments
156
- },
181
+ }), [
182
+ isChatAvailable,
183
+ id,
184
+ status,
185
+ stop,
186
+ sendMessage,
187
+ setMessages,
188
+ regenerate,
189
+ clearError,
190
+ error,
191
+ resumeStream,
192
+ addToolResult,
193
+ addToolOutput,
194
+ addToolApprovalResponse,
195
+ messages,
196
+ handleSubmit,
197
+ input,
198
+ handleInputChange,
199
+ reset,
200
+ schemas,
201
+ title,
202
+ isChatOpen,
203
+ openChat,
204
+ closeChat,
205
+ attachments
206
+ ]);
207
+ return /*#__PURE__*/ jsxRuntime.jsx(ChatContext.Provider, {
208
+ value: contextValue,
157
209
  children: children
158
210
  });
159
211
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ChatProvider.js","sources":["../../../../../admin/src/components/AIChat/providers/ChatProvider.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n createContext,\n useContext,\n useMemo,\n useState,\n useEffect,\n type ReactNode,\n type ChangeEvent,\n} from 'react';\n\nimport { UIMessage, useChat } from '@ai-sdk/react';\nimport { useAIAvailability } from '@strapi/admin/strapi-admin/ee';\n\nimport { useCTBTracking } from '../../CTBSession/ctbSession';\nimport { useDataManager } from '../../DataManager/useDataManager';\nimport { FeedbackProvider } from '../FeedbackModal';\nimport { useAIChat } from '../hooks/useAIFetch';\nimport { useChatTitle } from '../hooks/useChatTitle';\nimport { useLastSeenSchemas } from '../hooks/useLastSeenSchemas';\nimport { transformCTBToChat } from '../lib/transforms/schemas/fromCTB';\nimport { Attachment } from '../lib/types/attachments';\nimport { Schema } from '../lib/types/schema';\nimport { UploadProjectToChatProvider } from '../UploadCodeModal';\nimport { UploadFigmaToChatProvider } from '../UploadFigmaModal';\n\nimport { SchemaChatProvider } from './SchemaProvider';\n\ninterface ChatContextType extends Omit<ReturnType<typeof useChat>, 'messages'> {\n isChatEnabled: boolean;\n title?: string;\n messages: UIMessage[];\n handleSubmit: (event: any) => void;\n input: string;\n setInput: React.Dispatch<React.SetStateAction<string>>;\n handleInputChange: (e: ChangeEvent<HTMLInputElement> | ChangeEvent<HTMLTextAreaElement>) => void;\n reset: () => void;\n schemas: Schema[];\n // Chat window\n isChatOpen: boolean;\n openChat: () => void;\n closeChat: () => void;\n // Attachments\n attachments: Attachment[];\n setAttachments: React.Dispatch<React.SetStateAction<Attachment[]>>;\n}\n\nconst ChatContext = createContext<ChatContextType | undefined>(undefined);\n\nconst generateRandomId = () => {\n return Math.random().toString(36).substring(2, 15);\n};\n\nexport const BaseChatProvider = ({\n children,\n defaultOpen = false,\n}: {\n children: ReactNode;\n defaultOpen?: boolean;\n}) => {\n const [chatId, setChatId] = useState<string | undefined>(generateRandomId());\n const [isChatOpen, setIsChatOpen] = useState(defaultOpen);\n const [openCount, setOpenCount] = useState(0);\n const [input, setInput] = useState('');\n\n // Files\n const [attachments, setAttachments] = useState<Attachment[]>([]);\n\n const { trackUsage } = useCTBTracking();\n\n // DataManager\n const { components, contentTypes } = useDataManager();\n\n // Last user seen schemas\n const { lastSeenSchemas } = useLastSeenSchemas();\n\n // Schemas to be sent to the chat\n const schemas = useMemo(() => {\n return [\n ...Object.values(contentTypes)\n .filter((schema) => schema.status !== 'REMOVED')\n // Probably we should still keep this one, not sure\n .filter((schema) => schema.uid !== 'plugin::users-permissions.user')\n .filter((schema) => schema.visible)\n .map(transformCTBToChat as any),\n ...Object.values(components)\n .filter((schema) => schema.status !== 'REMOVED')\n .map(transformCTBToChat as any),\n ] as Schema[];\n }, [contentTypes, components]);\n\n const {\n id,\n messages,\n sendMessage: _sendMessage,\n status,\n stop,\n ...chat\n } = useAIChat({\n id: chatId?.toString(),\n experimental_throttle: 100,\n });\n\n /* -------------------------------------------------------------------------------------------------\n * AI SDK chat overrides\n * -----------------------------------------------------------------------------------------------*/\n\n // NOTE: body is using state variables, so they can not be passed as a prop in useChat\n const sendMessage: typeof _sendMessage = async (message, options) => {\n if (status === 'streaming' || status === 'submitted') {\n return;\n }\n\n return _sendMessage(message, {\n ...options,\n body: {\n ...options?.body,\n schemas,\n metadata: {\n lastSeenSchemas: lastSeenSchemas.map((schema) => schema.uid),\n },\n },\n });\n };\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n if (status === 'streaming' || status === 'submitted') {\n return;\n }\n\n const readyAttachments = attachments.filter((a) => a.status !== 'loading');\n if (input.trim().length === 0 && attachments.length === 0) {\n return;\n }\n\n const files = readyAttachments.map(\n (attachment) =>\n ({\n type: 'file',\n filename: attachment.filename,\n mediaType: attachment.mediaType,\n url: attachment.url,\n }) as const\n );\n sendMessage({ text: input, files });\n setInput('');\n setAttachments([]);\n };\n\n /* -------------------------------------------------------------------------------------------------\n * Chat title\n * -----------------------------------------------------------------------------------------------*/\n const { title, generateTitle, resetTitle } = useChatTitle({ chatId: id, messages });\n\n // Automatically generate title when we have at least 1 message (user query)\n useEffect(() => {\n if (messages.length >= 1 && !title) {\n generateTitle();\n }\n }, [messages.length, title, generateTitle]);\n\n useEffect(() => {\n if (status === 'error') {\n trackUsage('didAnswerMessage', {\n successful: false,\n });\n } else if (\n status === 'ready' &&\n messages.length > 0 &&\n messages[messages.length - 1]?.role === 'assistant'\n ) {\n trackUsage('didAnswerMessage', {\n successful: true,\n });\n }\n }, [status, messages, trackUsage]);\n\n const isChatAvailable = useAIAvailability();\n\n return (\n <ChatContext.Provider\n value={{\n isChatEnabled: isChatAvailable,\n id,\n status,\n stop,\n sendMessage,\n ...chat,\n messages,\n handleSubmit,\n input,\n setInput,\n handleInputChange: (e) => setInput(e.target.value),\n reset: () => {\n stop();\n setChatId(generateRandomId());\n trackUsage('didStartNewChat');\n resetTitle();\n },\n schemas,\n // Chat\n title,\n isChatOpen,\n openChat: () => {\n setIsChatOpen(true);\n // if this is the first open, it's a new chat\n if (openCount === 0) {\n trackUsage('didStartNewChat');\n }\n setOpenCount((prev) => prev + 1);\n },\n closeChat: () => setIsChatOpen(false),\n // Attachments\n attachments,\n setAttachments,\n }}\n >\n {children}\n </ChatContext.Provider>\n );\n};\n\nexport const ChatProvider = ({\n children,\n defaultOpen = false,\n}: {\n children: React.ReactNode;\n defaultOpen?: boolean;\n}) => {\n return (\n <BaseChatProvider defaultOpen={defaultOpen}>\n <SchemaChatProvider>\n <UploadProjectToChatProvider>\n <UploadFigmaToChatProvider>\n <FeedbackProvider>{children}</FeedbackProvider>\n </UploadFigmaToChatProvider>\n </UploadProjectToChatProvider>\n </SchemaChatProvider>\n </BaseChatProvider>\n );\n};\n\nexport function useStrapiChat() {\n const context = useContext(ChatContext);\n\n if (process.env.NODE_ENV === 'development') {\n // In development, provide a fallback to prevent crashes during hot reloading\n // This allows the app to continue working during HMR updates\n if (context === undefined) {\n console.warn(\n 'useStrapiChat was called outside of ChatProvider. This is only allowed in development mode.'\n );\n return {} as ChatContextType;\n }\n } else if (context === undefined) {\n throw new Error('useStrapiChat must be used within a ChatProvider');\n }\n return context;\n}\n"],"names":["ChatContext","createContext","undefined","generateRandomId","Math","random","toString","substring","BaseChatProvider","children","defaultOpen","chatId","setChatId","useState","isChatOpen","setIsChatOpen","openCount","setOpenCount","input","setInput","attachments","setAttachments","trackUsage","useCTBTracking","components","contentTypes","useDataManager","lastSeenSchemas","useLastSeenSchemas","schemas","useMemo","Object","values","filter","schema","status","uid","visible","map","transformCTBToChat","id","messages","sendMessage","_sendMessage","stop","chat","useAIChat","experimental_throttle","message","options","body","metadata","handleSubmit","e","preventDefault","readyAttachments","a","trim","length","files","attachment","type","filename","mediaType","url","text","title","generateTitle","resetTitle","useChatTitle","useEffect","successful","role","isChatAvailable","useAIAvailability","_jsx","Provider","value","isChatEnabled","handleInputChange","target","reset","openChat","prev","closeChat","ChatProvider","SchemaChatProvider","UploadProjectToChatProvider","UploadFigmaToChatProvider","FeedbackProvider","useStrapiChat","context","useContext","process","env","NODE_ENV","console","warn","Error"],"mappings":"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"}
1
+ {"version":3,"file":"ChatProvider.js","sources":["../../../../../admin/src/components/AIChat/providers/ChatProvider.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n useEffect,\n type ReactNode,\n type ChangeEvent,\n} from 'react';\n\nimport { UIMessage, useChat } from '@ai-sdk/react';\nimport { useAIAvailability } from '@strapi/admin/strapi-admin/ee';\n\nimport { useCTBTracking } from '../../CTBSession/ctbSession';\nimport { useDataManager } from '../../DataManager/useDataManager';\nimport { FeedbackProvider } from '../FeedbackModal';\nimport { useAIChat } from '../hooks/useAIFetch';\nimport { useChatTitle } from '../hooks/useChatTitle';\nimport { useLastSeenSchemas } from '../hooks/useLastSeenSchemas';\nimport { transformCTBToChat } from '../lib/transforms/schemas/fromCTB';\nimport { Attachment } from '../lib/types/attachments';\nimport { Schema } from '../lib/types/schema';\nimport { UploadProjectToChatProvider } from '../UploadCodeModal';\nimport { UploadFigmaToChatProvider } from '../UploadFigmaModal';\n\nimport { SchemaChatProvider } from './SchemaProvider';\n\ninterface ChatContextType extends Omit<ReturnType<typeof useChat>, 'messages'> {\n isChatEnabled: boolean;\n title?: string;\n messages: UIMessage[];\n handleSubmit: (event: any) => void;\n input: string;\n setInput: React.Dispatch<React.SetStateAction<string>>;\n handleInputChange: (e: ChangeEvent<HTMLInputElement> | ChangeEvent<HTMLTextAreaElement>) => void;\n reset: () => void;\n schemas: Schema[];\n // Chat window\n isChatOpen: boolean;\n openChat: () => void;\n closeChat: () => void;\n // Attachments\n attachments: Attachment[];\n setAttachments: React.Dispatch<React.SetStateAction<Attachment[]>>;\n}\n\nconst ChatContext = createContext<ChatContextType | undefined>(undefined);\n\nconst generateRandomId = () => {\n return Math.random().toString(36).substring(2, 15);\n};\n\nexport const BaseChatProvider = ({\n children,\n defaultOpen = false,\n}: {\n children: ReactNode;\n defaultOpen?: boolean;\n}) => {\n const [chatId, setChatId] = useState<string | undefined>(generateRandomId());\n const [isChatOpen, setIsChatOpen] = useState(defaultOpen);\n const [openCount, setOpenCount] = useState(0);\n const [input, setInput] = useState('');\n\n // Files\n const [attachments, setAttachments] = useState<Attachment[]>([]);\n\n const { trackUsage } = useCTBTracking();\n\n // DataManager\n const { components, contentTypes } = useDataManager();\n\n // Last user seen schemas\n const { lastSeenSchemas } = useLastSeenSchemas();\n\n // Schemas to be sent to the chat\n const schemas = useMemo(() => {\n return [\n ...Object.values(contentTypes)\n .filter((schema) => schema.status !== 'REMOVED')\n // Probably we should still keep this one, not sure\n .filter((schema) => schema.uid !== 'plugin::users-permissions.user')\n .filter((schema) => schema.visible)\n .map(transformCTBToChat as any),\n ...Object.values(components)\n .filter((schema) => schema.status !== 'REMOVED')\n .map(transformCTBToChat as any),\n ] as Schema[];\n }, [contentTypes, components]);\n\n const {\n id,\n messages,\n sendMessage: _sendMessage,\n status,\n stop,\n setMessages,\n regenerate,\n clearError,\n error,\n resumeStream,\n addToolResult,\n addToolOutput,\n addToolApprovalResponse,\n } = useAIChat({\n id: chatId?.toString(),\n experimental_throttle: 100,\n });\n\n /* -------------------------------------------------------------------------------------------------\n * AI SDK chat overrides\n * -----------------------------------------------------------------------------------------------*/\n\n // NOTE: body is using state variables, so they can not be passed as a prop in useChat\n const sendMessage: typeof _sendMessage = useCallback(\n async (message, options) => {\n if (status === 'streaming' || status === 'submitted') {\n return;\n }\n\n return _sendMessage(message, {\n ...options,\n body: {\n ...options?.body,\n schemas,\n metadata: {\n lastSeenSchemas: lastSeenSchemas.map((schema) => schema.uid),\n },\n },\n });\n },\n [_sendMessage, lastSeenSchemas, schemas, status]\n );\n\n const handleSubmit = useCallback(\n (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n if (status === 'streaming' || status === 'submitted') {\n return;\n }\n\n const readyAttachments = attachments.filter((a) => a.status !== 'loading');\n if (input.trim().length === 0 && attachments.length === 0) {\n return;\n }\n\n const files = readyAttachments.map(\n (attachment) =>\n ({\n type: 'file',\n filename: attachment.filename,\n mediaType: attachment.mediaType,\n url: attachment.url,\n }) as const\n );\n sendMessage({ text: input, files });\n setInput('');\n setAttachments([]);\n },\n [attachments, input, sendMessage, status]\n );\n\n /* -------------------------------------------------------------------------------------------------\n * Chat title\n * -----------------------------------------------------------------------------------------------*/\n const { title, generateTitle, resetTitle } = useChatTitle({ chatId: id, messages });\n\n // Automatically generate title when we have at least 1 message (user query)\n useEffect(() => {\n if (messages.length >= 1 && !title) {\n generateTitle();\n }\n }, [messages.length, title, generateTitle]);\n\n useEffect(() => {\n if (status === 'error') {\n trackUsage('didAnswerMessage', {\n successful: false,\n });\n } else if (\n status === 'ready' &&\n messages.length > 0 &&\n messages[messages.length - 1]?.role === 'assistant'\n ) {\n trackUsage('didAnswerMessage', {\n successful: true,\n });\n }\n }, [status, messages, trackUsage]);\n\n const isChatAvailable = useAIAvailability();\n const handleInputChange = useCallback<ChatContextType['handleInputChange']>(\n (e) => setInput(e.target.value),\n []\n );\n const reset = useCallback(() => {\n stop();\n setChatId(generateRandomId());\n trackUsage('didStartNewChat');\n resetTitle();\n }, [resetTitle, stop, trackUsage]);\n const openChat = useCallback(() => {\n setIsChatOpen(true);\n // if this is the first open, it's a new chat\n if (openCount === 0) {\n trackUsage('didStartNewChat');\n }\n setOpenCount((prev) => prev + 1);\n }, [openCount, trackUsage]);\n const closeChat = useCallback(() => setIsChatOpen(false), []);\n const contextValue = useMemo<ChatContextType>(\n () => ({\n isChatEnabled: isChatAvailable,\n id,\n status,\n stop,\n sendMessage,\n setMessages,\n regenerate,\n clearError,\n error,\n resumeStream,\n addToolResult,\n addToolOutput,\n addToolApprovalResponse,\n messages,\n handleSubmit,\n input,\n setInput,\n handleInputChange,\n reset,\n schemas,\n title,\n isChatOpen,\n openChat,\n closeChat,\n attachments,\n setAttachments,\n }),\n [\n isChatAvailable,\n id,\n status,\n stop,\n sendMessage,\n setMessages,\n regenerate,\n clearError,\n error,\n resumeStream,\n addToolResult,\n addToolOutput,\n addToolApprovalResponse,\n messages,\n handleSubmit,\n input,\n handleInputChange,\n reset,\n schemas,\n title,\n isChatOpen,\n openChat,\n closeChat,\n attachments,\n ]\n );\n\n return <ChatContext.Provider value={contextValue}>{children}</ChatContext.Provider>;\n};\n\nexport const ChatProvider = ({\n children,\n defaultOpen = false,\n}: {\n children: React.ReactNode;\n defaultOpen?: boolean;\n}) => {\n return (\n <BaseChatProvider defaultOpen={defaultOpen}>\n <SchemaChatProvider>\n <UploadProjectToChatProvider>\n <UploadFigmaToChatProvider>\n <FeedbackProvider>{children}</FeedbackProvider>\n </UploadFigmaToChatProvider>\n </UploadProjectToChatProvider>\n </SchemaChatProvider>\n </BaseChatProvider>\n );\n};\n\nexport function useStrapiChat() {\n const context = useContext(ChatContext);\n\n if (process.env.NODE_ENV === 'development') {\n // In development, provide a fallback to prevent crashes during hot reloading\n // This allows the app to continue working during HMR updates\n if (context === undefined) {\n console.warn(\n 'useStrapiChat was called outside of ChatProvider. This is only allowed in development mode.'\n );\n return {} as ChatContextType;\n }\n } else if (context === undefined) {\n throw new Error('useStrapiChat must be used within a ChatProvider');\n }\n return context;\n}\n"],"names":["ChatContext","createContext","undefined","generateRandomId","Math","random","toString","substring","BaseChatProvider","children","defaultOpen","chatId","setChatId","useState","isChatOpen","setIsChatOpen","openCount","setOpenCount","input","setInput","attachments","setAttachments","trackUsage","useCTBTracking","components","contentTypes","useDataManager","lastSeenSchemas","useLastSeenSchemas","schemas","useMemo","Object","values","filter","schema","status","uid","visible","map","transformCTBToChat","id","messages","sendMessage","_sendMessage","stop","setMessages","regenerate","clearError","error","resumeStream","addToolResult","addToolOutput","addToolApprovalResponse","useAIChat","experimental_throttle","useCallback","message","options","body","metadata","handleSubmit","e","preventDefault","readyAttachments","a","trim","length","files","attachment","type","filename","mediaType","url","text","title","generateTitle","resetTitle","useChatTitle","useEffect","successful","role","isChatAvailable","useAIAvailability","handleInputChange","target","value","reset","openChat","prev","closeChat","contextValue","isChatEnabled","_jsx","Provider","ChatProvider","SchemaChatProvider","UploadProjectToChatProvider","UploadFigmaToChatProvider","FeedbackProvider","useStrapiChat","context","useContext","process","env","NODE_ENV","console","warn","Error"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { useState, useMemo, useEffect, useContext, createContext } from 'react';
2
+ import { useState, useMemo, useCallback, useEffect, useContext, createContext } from 'react';
3
3
  import { useAIAvailability } from '@strapi/admin/strapi-admin/ee';
4
4
  import '../../CTBSession/sessionContext.mjs';
5
5
  import { useCTBTracking } from '../../CTBSession/useCTBTracking.mjs';
@@ -40,14 +40,14 @@ const BaseChatProvider = ({ children, defaultOpen = false })=>{
40
40
  contentTypes,
41
41
  components
42
42
  ]);
43
- const { id, messages, sendMessage: _sendMessage, status, stop, ...chat } = useAIChat({
43
+ const { id, messages, sendMessage: _sendMessage, status, stop, setMessages, regenerate, clearError, error, resumeStream, addToolResult, addToolOutput, addToolApprovalResponse } = useAIChat({
44
44
  id: chatId?.toString(),
45
45
  experimental_throttle: 100
46
46
  });
47
47
  /* -------------------------------------------------------------------------------------------------
48
48
  * AI SDK chat overrides
49
49
  * -----------------------------------------------------------------------------------------------*/ // NOTE: body is using state variables, so they can not be passed as a prop in useChat
50
- const sendMessage = async (message, options)=>{
50
+ const sendMessage = useCallback(async (message, options)=>{
51
51
  if (status === 'streaming' || status === 'submitted') {
52
52
  return;
53
53
  }
@@ -61,8 +61,13 @@ const BaseChatProvider = ({ children, defaultOpen = false })=>{
61
61
  }
62
62
  }
63
63
  });
64
- };
65
- const handleSubmit = (e)=>{
64
+ }, [
65
+ _sendMessage,
66
+ lastSeenSchemas,
67
+ schemas,
68
+ status
69
+ ]);
70
+ const handleSubmit = useCallback((e)=>{
66
71
  e.preventDefault();
67
72
  if (status === 'streaming' || status === 'submitted') {
68
73
  return;
@@ -83,7 +88,12 @@ const BaseChatProvider = ({ children, defaultOpen = false })=>{
83
88
  });
84
89
  setInput('');
85
90
  setAttachments([]);
86
- };
91
+ }, [
92
+ attachments,
93
+ input,
94
+ sendMessage,
95
+ status
96
+ ]);
87
97
  /* -------------------------------------------------------------------------------------------------
88
98
  * Chat title
89
99
  * -----------------------------------------------------------------------------------------------*/ const { title, generateTitle, resetTitle } = useChatTitle({
@@ -116,42 +126,84 @@ const BaseChatProvider = ({ children, defaultOpen = false })=>{
116
126
  trackUsage
117
127
  ]);
118
128
  const isChatAvailable = useAIAvailability();
119
- return /*#__PURE__*/ jsx(ChatContext.Provider, {
120
- value: {
129
+ const handleInputChange = useCallback((e)=>setInput(e.target.value), []);
130
+ const reset = useCallback(()=>{
131
+ stop();
132
+ setChatId(generateRandomId());
133
+ trackUsage('didStartNewChat');
134
+ resetTitle();
135
+ }, [
136
+ resetTitle,
137
+ stop,
138
+ trackUsage
139
+ ]);
140
+ const openChat = useCallback(()=>{
141
+ setIsChatOpen(true);
142
+ // if this is the first open, it's a new chat
143
+ if (openCount === 0) {
144
+ trackUsage('didStartNewChat');
145
+ }
146
+ setOpenCount((prev)=>prev + 1);
147
+ }, [
148
+ openCount,
149
+ trackUsage
150
+ ]);
151
+ const closeChat = useCallback(()=>setIsChatOpen(false), []);
152
+ const contextValue = useMemo(()=>({
121
153
  isChatEnabled: isChatAvailable,
122
154
  id,
123
155
  status,
124
156
  stop,
125
157
  sendMessage,
126
- ...chat,
158
+ setMessages,
159
+ regenerate,
160
+ clearError,
161
+ error,
162
+ resumeStream,
163
+ addToolResult,
164
+ addToolOutput,
165
+ addToolApprovalResponse,
127
166
  messages,
128
167
  handleSubmit,
129
168
  input,
130
169
  setInput,
131
- handleInputChange: (e)=>setInput(e.target.value),
132
- reset: ()=>{
133
- stop();
134
- setChatId(generateRandomId());
135
- trackUsage('didStartNewChat');
136
- resetTitle();
137
- },
170
+ handleInputChange,
171
+ reset,
138
172
  schemas,
139
- // Chat
140
173
  title,
141
174
  isChatOpen,
142
- openChat: ()=>{
143
- setIsChatOpen(true);
144
- // if this is the first open, it's a new chat
145
- if (openCount === 0) {
146
- trackUsage('didStartNewChat');
147
- }
148
- setOpenCount((prev)=>prev + 1);
149
- },
150
- closeChat: ()=>setIsChatOpen(false),
151
- // Attachments
175
+ openChat,
176
+ closeChat,
152
177
  attachments,
153
178
  setAttachments
154
- },
179
+ }), [
180
+ isChatAvailable,
181
+ id,
182
+ status,
183
+ stop,
184
+ sendMessage,
185
+ setMessages,
186
+ regenerate,
187
+ clearError,
188
+ error,
189
+ resumeStream,
190
+ addToolResult,
191
+ addToolOutput,
192
+ addToolApprovalResponse,
193
+ messages,
194
+ handleSubmit,
195
+ input,
196
+ handleInputChange,
197
+ reset,
198
+ schemas,
199
+ title,
200
+ isChatOpen,
201
+ openChat,
202
+ closeChat,
203
+ attachments
204
+ ]);
205
+ return /*#__PURE__*/ jsx(ChatContext.Provider, {
206
+ value: contextValue,
155
207
  children: children
156
208
  });
157
209
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ChatProvider.mjs","sources":["../../../../../admin/src/components/AIChat/providers/ChatProvider.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n createContext,\n useContext,\n useMemo,\n useState,\n useEffect,\n type ReactNode,\n type ChangeEvent,\n} from 'react';\n\nimport { UIMessage, useChat } from '@ai-sdk/react';\nimport { useAIAvailability } from '@strapi/admin/strapi-admin/ee';\n\nimport { useCTBTracking } from '../../CTBSession/ctbSession';\nimport { useDataManager } from '../../DataManager/useDataManager';\nimport { FeedbackProvider } from '../FeedbackModal';\nimport { useAIChat } from '../hooks/useAIFetch';\nimport { useChatTitle } from '../hooks/useChatTitle';\nimport { useLastSeenSchemas } from '../hooks/useLastSeenSchemas';\nimport { transformCTBToChat } from '../lib/transforms/schemas/fromCTB';\nimport { Attachment } from '../lib/types/attachments';\nimport { Schema } from '../lib/types/schema';\nimport { UploadProjectToChatProvider } from '../UploadCodeModal';\nimport { UploadFigmaToChatProvider } from '../UploadFigmaModal';\n\nimport { SchemaChatProvider } from './SchemaProvider';\n\ninterface ChatContextType extends Omit<ReturnType<typeof useChat>, 'messages'> {\n isChatEnabled: boolean;\n title?: string;\n messages: UIMessage[];\n handleSubmit: (event: any) => void;\n input: string;\n setInput: React.Dispatch<React.SetStateAction<string>>;\n handleInputChange: (e: ChangeEvent<HTMLInputElement> | ChangeEvent<HTMLTextAreaElement>) => void;\n reset: () => void;\n schemas: Schema[];\n // Chat window\n isChatOpen: boolean;\n openChat: () => void;\n closeChat: () => void;\n // Attachments\n attachments: Attachment[];\n setAttachments: React.Dispatch<React.SetStateAction<Attachment[]>>;\n}\n\nconst ChatContext = createContext<ChatContextType | undefined>(undefined);\n\nconst generateRandomId = () => {\n return Math.random().toString(36).substring(2, 15);\n};\n\nexport const BaseChatProvider = ({\n children,\n defaultOpen = false,\n}: {\n children: ReactNode;\n defaultOpen?: boolean;\n}) => {\n const [chatId, setChatId] = useState<string | undefined>(generateRandomId());\n const [isChatOpen, setIsChatOpen] = useState(defaultOpen);\n const [openCount, setOpenCount] = useState(0);\n const [input, setInput] = useState('');\n\n // Files\n const [attachments, setAttachments] = useState<Attachment[]>([]);\n\n const { trackUsage } = useCTBTracking();\n\n // DataManager\n const { components, contentTypes } = useDataManager();\n\n // Last user seen schemas\n const { lastSeenSchemas } = useLastSeenSchemas();\n\n // Schemas to be sent to the chat\n const schemas = useMemo(() => {\n return [\n ...Object.values(contentTypes)\n .filter((schema) => schema.status !== 'REMOVED')\n // Probably we should still keep this one, not sure\n .filter((schema) => schema.uid !== 'plugin::users-permissions.user')\n .filter((schema) => schema.visible)\n .map(transformCTBToChat as any),\n ...Object.values(components)\n .filter((schema) => schema.status !== 'REMOVED')\n .map(transformCTBToChat as any),\n ] as Schema[];\n }, [contentTypes, components]);\n\n const {\n id,\n messages,\n sendMessage: _sendMessage,\n status,\n stop,\n ...chat\n } = useAIChat({\n id: chatId?.toString(),\n experimental_throttle: 100,\n });\n\n /* -------------------------------------------------------------------------------------------------\n * AI SDK chat overrides\n * -----------------------------------------------------------------------------------------------*/\n\n // NOTE: body is using state variables, so they can not be passed as a prop in useChat\n const sendMessage: typeof _sendMessage = async (message, options) => {\n if (status === 'streaming' || status === 'submitted') {\n return;\n }\n\n return _sendMessage(message, {\n ...options,\n body: {\n ...options?.body,\n schemas,\n metadata: {\n lastSeenSchemas: lastSeenSchemas.map((schema) => schema.uid),\n },\n },\n });\n };\n\n const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n if (status === 'streaming' || status === 'submitted') {\n return;\n }\n\n const readyAttachments = attachments.filter((a) => a.status !== 'loading');\n if (input.trim().length === 0 && attachments.length === 0) {\n return;\n }\n\n const files = readyAttachments.map(\n (attachment) =>\n ({\n type: 'file',\n filename: attachment.filename,\n mediaType: attachment.mediaType,\n url: attachment.url,\n }) as const\n );\n sendMessage({ text: input, files });\n setInput('');\n setAttachments([]);\n };\n\n /* -------------------------------------------------------------------------------------------------\n * Chat title\n * -----------------------------------------------------------------------------------------------*/\n const { title, generateTitle, resetTitle } = useChatTitle({ chatId: id, messages });\n\n // Automatically generate title when we have at least 1 message (user query)\n useEffect(() => {\n if (messages.length >= 1 && !title) {\n generateTitle();\n }\n }, [messages.length, title, generateTitle]);\n\n useEffect(() => {\n if (status === 'error') {\n trackUsage('didAnswerMessage', {\n successful: false,\n });\n } else if (\n status === 'ready' &&\n messages.length > 0 &&\n messages[messages.length - 1]?.role === 'assistant'\n ) {\n trackUsage('didAnswerMessage', {\n successful: true,\n });\n }\n }, [status, messages, trackUsage]);\n\n const isChatAvailable = useAIAvailability();\n\n return (\n <ChatContext.Provider\n value={{\n isChatEnabled: isChatAvailable,\n id,\n status,\n stop,\n sendMessage,\n ...chat,\n messages,\n handleSubmit,\n input,\n setInput,\n handleInputChange: (e) => setInput(e.target.value),\n reset: () => {\n stop();\n setChatId(generateRandomId());\n trackUsage('didStartNewChat');\n resetTitle();\n },\n schemas,\n // Chat\n title,\n isChatOpen,\n openChat: () => {\n setIsChatOpen(true);\n // if this is the first open, it's a new chat\n if (openCount === 0) {\n trackUsage('didStartNewChat');\n }\n setOpenCount((prev) => prev + 1);\n },\n closeChat: () => setIsChatOpen(false),\n // Attachments\n attachments,\n setAttachments,\n }}\n >\n {children}\n </ChatContext.Provider>\n );\n};\n\nexport const ChatProvider = ({\n children,\n defaultOpen = false,\n}: {\n children: React.ReactNode;\n defaultOpen?: boolean;\n}) => {\n return (\n <BaseChatProvider defaultOpen={defaultOpen}>\n <SchemaChatProvider>\n <UploadProjectToChatProvider>\n <UploadFigmaToChatProvider>\n <FeedbackProvider>{children}</FeedbackProvider>\n </UploadFigmaToChatProvider>\n </UploadProjectToChatProvider>\n </SchemaChatProvider>\n </BaseChatProvider>\n );\n};\n\nexport function useStrapiChat() {\n const context = useContext(ChatContext);\n\n if (process.env.NODE_ENV === 'development') {\n // In development, provide a fallback to prevent crashes during hot reloading\n // This allows the app to continue working during HMR updates\n if (context === undefined) {\n console.warn(\n 'useStrapiChat was called outside of ChatProvider. This is only allowed in development mode.'\n );\n return {} as ChatContextType;\n }\n } else if (context === undefined) {\n throw new Error('useStrapiChat must be used within a ChatProvider');\n }\n return context;\n}\n"],"names":["ChatContext","createContext","undefined","generateRandomId","Math","random","toString","substring","BaseChatProvider","children","defaultOpen","chatId","setChatId","useState","isChatOpen","setIsChatOpen","openCount","setOpenCount","input","setInput","attachments","setAttachments","trackUsage","useCTBTracking","components","contentTypes","useDataManager","lastSeenSchemas","useLastSeenSchemas","schemas","useMemo","Object","values","filter","schema","status","uid","visible","map","transformCTBToChat","id","messages","sendMessage","_sendMessage","stop","chat","useAIChat","experimental_throttle","message","options","body","metadata","handleSubmit","e","preventDefault","readyAttachments","a","trim","length","files","attachment","type","filename","mediaType","url","text","title","generateTitle","resetTitle","useChatTitle","useEffect","successful","role","isChatAvailable","useAIAvailability","_jsx","Provider","value","isChatEnabled","handleInputChange","target","reset","openChat","prev","closeChat","ChatProvider","SchemaChatProvider","UploadProjectToChatProvider","UploadFigmaToChatProvider","FeedbackProvider","useStrapiChat","context","useContext","process","env","NODE_ENV","console","warn","Error"],"mappings":"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"}
1
+ {"version":3,"file":"ChatProvider.mjs","sources":["../../../../../admin/src/components/AIChat/providers/ChatProvider.tsx"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n useEffect,\n type ReactNode,\n type ChangeEvent,\n} from 'react';\n\nimport { UIMessage, useChat } from '@ai-sdk/react';\nimport { useAIAvailability } from '@strapi/admin/strapi-admin/ee';\n\nimport { useCTBTracking } from '../../CTBSession/ctbSession';\nimport { useDataManager } from '../../DataManager/useDataManager';\nimport { FeedbackProvider } from '../FeedbackModal';\nimport { useAIChat } from '../hooks/useAIFetch';\nimport { useChatTitle } from '../hooks/useChatTitle';\nimport { useLastSeenSchemas } from '../hooks/useLastSeenSchemas';\nimport { transformCTBToChat } from '../lib/transforms/schemas/fromCTB';\nimport { Attachment } from '../lib/types/attachments';\nimport { Schema } from '../lib/types/schema';\nimport { UploadProjectToChatProvider } from '../UploadCodeModal';\nimport { UploadFigmaToChatProvider } from '../UploadFigmaModal';\n\nimport { SchemaChatProvider } from './SchemaProvider';\n\ninterface ChatContextType extends Omit<ReturnType<typeof useChat>, 'messages'> {\n isChatEnabled: boolean;\n title?: string;\n messages: UIMessage[];\n handleSubmit: (event: any) => void;\n input: string;\n setInput: React.Dispatch<React.SetStateAction<string>>;\n handleInputChange: (e: ChangeEvent<HTMLInputElement> | ChangeEvent<HTMLTextAreaElement>) => void;\n reset: () => void;\n schemas: Schema[];\n // Chat window\n isChatOpen: boolean;\n openChat: () => void;\n closeChat: () => void;\n // Attachments\n attachments: Attachment[];\n setAttachments: React.Dispatch<React.SetStateAction<Attachment[]>>;\n}\n\nconst ChatContext = createContext<ChatContextType | undefined>(undefined);\n\nconst generateRandomId = () => {\n return Math.random().toString(36).substring(2, 15);\n};\n\nexport const BaseChatProvider = ({\n children,\n defaultOpen = false,\n}: {\n children: ReactNode;\n defaultOpen?: boolean;\n}) => {\n const [chatId, setChatId] = useState<string | undefined>(generateRandomId());\n const [isChatOpen, setIsChatOpen] = useState(defaultOpen);\n const [openCount, setOpenCount] = useState(0);\n const [input, setInput] = useState('');\n\n // Files\n const [attachments, setAttachments] = useState<Attachment[]>([]);\n\n const { trackUsage } = useCTBTracking();\n\n // DataManager\n const { components, contentTypes } = useDataManager();\n\n // Last user seen schemas\n const { lastSeenSchemas } = useLastSeenSchemas();\n\n // Schemas to be sent to the chat\n const schemas = useMemo(() => {\n return [\n ...Object.values(contentTypes)\n .filter((schema) => schema.status !== 'REMOVED')\n // Probably we should still keep this one, not sure\n .filter((schema) => schema.uid !== 'plugin::users-permissions.user')\n .filter((schema) => schema.visible)\n .map(transformCTBToChat as any),\n ...Object.values(components)\n .filter((schema) => schema.status !== 'REMOVED')\n .map(transformCTBToChat as any),\n ] as Schema[];\n }, [contentTypes, components]);\n\n const {\n id,\n messages,\n sendMessage: _sendMessage,\n status,\n stop,\n setMessages,\n regenerate,\n clearError,\n error,\n resumeStream,\n addToolResult,\n addToolOutput,\n addToolApprovalResponse,\n } = useAIChat({\n id: chatId?.toString(),\n experimental_throttle: 100,\n });\n\n /* -------------------------------------------------------------------------------------------------\n * AI SDK chat overrides\n * -----------------------------------------------------------------------------------------------*/\n\n // NOTE: body is using state variables, so they can not be passed as a prop in useChat\n const sendMessage: typeof _sendMessage = useCallback(\n async (message, options) => {\n if (status === 'streaming' || status === 'submitted') {\n return;\n }\n\n return _sendMessage(message, {\n ...options,\n body: {\n ...options?.body,\n schemas,\n metadata: {\n lastSeenSchemas: lastSeenSchemas.map((schema) => schema.uid),\n },\n },\n });\n },\n [_sendMessage, lastSeenSchemas, schemas, status]\n );\n\n const handleSubmit = useCallback(\n (e: React.FormEvent<HTMLFormElement>) => {\n e.preventDefault();\n\n if (status === 'streaming' || status === 'submitted') {\n return;\n }\n\n const readyAttachments = attachments.filter((a) => a.status !== 'loading');\n if (input.trim().length === 0 && attachments.length === 0) {\n return;\n }\n\n const files = readyAttachments.map(\n (attachment) =>\n ({\n type: 'file',\n filename: attachment.filename,\n mediaType: attachment.mediaType,\n url: attachment.url,\n }) as const\n );\n sendMessage({ text: input, files });\n setInput('');\n setAttachments([]);\n },\n [attachments, input, sendMessage, status]\n );\n\n /* -------------------------------------------------------------------------------------------------\n * Chat title\n * -----------------------------------------------------------------------------------------------*/\n const { title, generateTitle, resetTitle } = useChatTitle({ chatId: id, messages });\n\n // Automatically generate title when we have at least 1 message (user query)\n useEffect(() => {\n if (messages.length >= 1 && !title) {\n generateTitle();\n }\n }, [messages.length, title, generateTitle]);\n\n useEffect(() => {\n if (status === 'error') {\n trackUsage('didAnswerMessage', {\n successful: false,\n });\n } else if (\n status === 'ready' &&\n messages.length > 0 &&\n messages[messages.length - 1]?.role === 'assistant'\n ) {\n trackUsage('didAnswerMessage', {\n successful: true,\n });\n }\n }, [status, messages, trackUsage]);\n\n const isChatAvailable = useAIAvailability();\n const handleInputChange = useCallback<ChatContextType['handleInputChange']>(\n (e) => setInput(e.target.value),\n []\n );\n const reset = useCallback(() => {\n stop();\n setChatId(generateRandomId());\n trackUsage('didStartNewChat');\n resetTitle();\n }, [resetTitle, stop, trackUsage]);\n const openChat = useCallback(() => {\n setIsChatOpen(true);\n // if this is the first open, it's a new chat\n if (openCount === 0) {\n trackUsage('didStartNewChat');\n }\n setOpenCount((prev) => prev + 1);\n }, [openCount, trackUsage]);\n const closeChat = useCallback(() => setIsChatOpen(false), []);\n const contextValue = useMemo<ChatContextType>(\n () => ({\n isChatEnabled: isChatAvailable,\n id,\n status,\n stop,\n sendMessage,\n setMessages,\n regenerate,\n clearError,\n error,\n resumeStream,\n addToolResult,\n addToolOutput,\n addToolApprovalResponse,\n messages,\n handleSubmit,\n input,\n setInput,\n handleInputChange,\n reset,\n schemas,\n title,\n isChatOpen,\n openChat,\n closeChat,\n attachments,\n setAttachments,\n }),\n [\n isChatAvailable,\n id,\n status,\n stop,\n sendMessage,\n setMessages,\n regenerate,\n clearError,\n error,\n resumeStream,\n addToolResult,\n addToolOutput,\n addToolApprovalResponse,\n messages,\n handleSubmit,\n input,\n handleInputChange,\n reset,\n schemas,\n title,\n isChatOpen,\n openChat,\n closeChat,\n attachments,\n ]\n );\n\n return <ChatContext.Provider value={contextValue}>{children}</ChatContext.Provider>;\n};\n\nexport const ChatProvider = ({\n children,\n defaultOpen = false,\n}: {\n children: React.ReactNode;\n defaultOpen?: boolean;\n}) => {\n return (\n <BaseChatProvider defaultOpen={defaultOpen}>\n <SchemaChatProvider>\n <UploadProjectToChatProvider>\n <UploadFigmaToChatProvider>\n <FeedbackProvider>{children}</FeedbackProvider>\n </UploadFigmaToChatProvider>\n </UploadProjectToChatProvider>\n </SchemaChatProvider>\n </BaseChatProvider>\n );\n};\n\nexport function useStrapiChat() {\n const context = useContext(ChatContext);\n\n if (process.env.NODE_ENV === 'development') {\n // In development, provide a fallback to prevent crashes during hot reloading\n // This allows the app to continue working during HMR updates\n if (context === undefined) {\n console.warn(\n 'useStrapiChat was called outside of ChatProvider. This is only allowed in development mode.'\n );\n return {} as ChatContextType;\n }\n } else if (context === undefined) {\n throw new Error('useStrapiChat must be used within a ChatProvider');\n }\n return context;\n}\n"],"names":["ChatContext","createContext","undefined","generateRandomId","Math","random","toString","substring","BaseChatProvider","children","defaultOpen","chatId","setChatId","useState","isChatOpen","setIsChatOpen","openCount","setOpenCount","input","setInput","attachments","setAttachments","trackUsage","useCTBTracking","components","contentTypes","useDataManager","lastSeenSchemas","useLastSeenSchemas","schemas","useMemo","Object","values","filter","schema","status","uid","visible","map","transformCTBToChat","id","messages","sendMessage","_sendMessage","stop","setMessages","regenerate","clearError","error","resumeStream","addToolResult","addToolOutput","addToolApprovalResponse","useAIChat","experimental_throttle","useCallback","message","options","body","metadata","handleSubmit","e","preventDefault","readyAttachments","a","trim","length","files","attachment","type","filename","mediaType","url","text","title","generateTitle","resetTitle","useChatTitle","useEffect","successful","role","isChatAvailable","useAIAvailability","handleInputChange","target","value","reset","openChat","prev","closeChat","contextValue","isChatEnabled","_jsx","Provider","ChatProvider","SchemaChatProvider","UploadProjectToChatProvider","UploadFigmaToChatProvider","FeedbackProvider","useStrapiChat","context","useContext","process","env","NODE_ENV","console","warn","Error"],"mappings":";;;;;;;;;;;;;;;AAgDA,MAAMA,4BAAcC,aAAAA,CAA2CC,SAAAA,CAAAA;AAE/D,MAAMC,gBAAAA,GAAmB,IAAA;IACvB,OAAOC,IAAAA,CAAKC,MAAM,EAAA,CAAGC,QAAQ,CAAC,EAAA,CAAA,CAAIC,SAAS,CAAC,CAAA,EAAG,EAAA,CAAA;AACjD,CAAA;AAEO,MAAMC,mBAAmB,CAAC,EAC/BC,QAAQ,EACRC,WAAAA,GAAc,KAAK,EAIpB,GAAA;AACC,IAAA,MAAM,CAACC,MAAAA,EAAQC,SAAAA,CAAU,GAAGC,QAAAA,CAA6BV,gBAAAA,EAAAA,CAAAA;AACzD,IAAA,MAAM,CAACW,UAAAA,EAAYC,aAAAA,CAAc,GAAGF,QAAAA,CAASH,WAAAA,CAAAA;AAC7C,IAAA,MAAM,CAACM,SAAAA,EAAWC,YAAAA,CAAa,GAAGJ,QAAAA,CAAS,CAAA,CAAA;AAC3C,IAAA,MAAM,CAACK,KAAAA,EAAOC,QAAAA,CAAS,GAAGN,QAAAA,CAAS,EAAA,CAAA;;AAGnC,IAAA,MAAM,CAACO,WAAAA,EAAaC,cAAAA,CAAe,GAAGR,SAAuB,EAAE,CAAA;IAE/D,MAAM,EAAES,UAAU,EAAE,GAAGC,cAAAA,EAAAA;;AAGvB,IAAA,MAAM,EAAEC,UAAU,EAAEC,YAAY,EAAE,GAAGC,cAAAA,EAAAA;;IAGrC,MAAM,EAAEC,eAAe,EAAE,GAAGC,kBAAAA,EAAAA;;AAG5B,IAAA,MAAMC,UAAUC,OAAAA,CAAQ,IAAA;QACtB,OAAO;eACFC,MAAAA,CAAOC,MAAM,CAACP,YAAAA,CAAAA,CACdQ,MAAM,CAAC,CAACC,MAAAA,GAAWA,MAAAA,CAAOC,MAAM,KAAK,SAAA,CACtC;AACCF,aAAAA,MAAM,CAAC,CAACC,MAAAA,GAAWA,MAAAA,CAAOE,GAAG,KAAK,gCAAA,CAAA,CAClCH,MAAM,CAAC,CAACC,MAAAA,GAAWA,MAAAA,CAAOG,OAAO,CAAA,CACjCC,GAAG,CAACC,kBAAAA,CAAAA;AACJR,YAAAA,GAAAA,MAAAA,CAAOC,MAAM,CAACR,UAAAA,CAAAA,CACdS,MAAM,CAAC,CAACC,MAAAA,GAAWA,MAAAA,CAAOC,MAAM,KAAK,SAAA,CAAA,CACrCG,GAAG,CAACC,kBAAAA;AACR,SAAA;IACH,CAAA,EAAG;AAACd,QAAAA,YAAAA;AAAcD,QAAAA;AAAW,KAAA,CAAA;AAE7B,IAAA,MAAM,EACJgB,EAAE,EACFC,QAAQ,EACRC,WAAAA,EAAaC,YAAY,EACzBR,MAAM,EACNS,IAAI,EACJC,WAAW,EACXC,UAAU,EACVC,UAAU,EACVC,KAAK,EACLC,YAAY,EACZC,aAAa,EACbC,aAAa,EACbC,uBAAuB,EACxB,GAAGC,SAAAA,CAAU;AACZb,QAAAA,EAAAA,EAAI7B,MAAAA,EAAQL,QAAAA,EAAAA;QACZgD,qBAAAA,EAAuB;AACzB,KAAA,CAAA;AAEA;;AAEkG;IAGlG,MAAMZ,WAAAA,GAAmCa,WAAAA,CACvC,OAAOC,OAAAA,EAASC,OAAAA,GAAAA;QACd,IAAItB,MAAAA,KAAW,WAAA,IAAeA,MAAAA,KAAW,WAAA,EAAa;AACpD,YAAA;AACF,QAAA;AAEA,QAAA,OAAOQ,aAAaa,OAAAA,EAAS;AAC3B,YAAA,GAAGC,OAAO;YACVC,IAAAA,EAAM;AACJ,gBAAA,GAAGD,SAASC,IAAI;AAChB7B,gBAAAA,OAAAA;gBACA8B,QAAAA,EAAU;AACRhC,oBAAAA,eAAAA,EAAiBA,gBAAgBW,GAAG,CAAC,CAACJ,MAAAA,GAAWA,OAAOE,GAAG;AAC7D;AACF;AACF,SAAA,CAAA;IACF,CAAA,EACA;AAACO,QAAAA,YAAAA;AAAchB,QAAAA,eAAAA;AAAiBE,QAAAA,OAAAA;AAASM,QAAAA;AAAO,KAAA,CAAA;IAGlD,MAAMyB,YAAAA,GAAeL,YACnB,CAACM,CAAAA,GAAAA;AACCA,QAAAA,CAAAA,CAAEC,cAAc,EAAA;QAEhB,IAAI3B,MAAAA,KAAW,WAAA,IAAeA,MAAAA,KAAW,WAAA,EAAa;AACpD,YAAA;AACF,QAAA;QAEA,MAAM4B,gBAAAA,GAAmB3C,YAAYa,MAAM,CAAC,CAAC+B,CAAAA,GAAMA,CAAAA,CAAE7B,MAAM,KAAK,SAAA,CAAA;QAChE,IAAIjB,KAAAA,CAAM+C,IAAI,EAAA,CAAGC,MAAM,KAAK,CAAA,IAAK9C,WAAAA,CAAY8C,MAAM,KAAK,CAAA,EAAG;AACzD,YAAA;AACF,QAAA;AAEA,QAAA,MAAMC,QAAQJ,gBAAAA,CAAiBzB,GAAG,CAChC,CAAC8B,cACE;gBACCC,IAAAA,EAAM,MAAA;AACNC,gBAAAA,QAAAA,EAAUF,WAAWE,QAAQ;AAC7BC,gBAAAA,SAAAA,EAAWH,WAAWG,SAAS;AAC/BC,gBAAAA,GAAAA,EAAKJ,WAAWI;aAClB,CAAA,CAAA;QAEJ9B,WAAAA,CAAY;YAAE+B,IAAAA,EAAMvD,KAAAA;AAAOiD,YAAAA;AAAM,SAAA,CAAA;QACjChD,QAAAA,CAAS,EAAA,CAAA;AACTE,QAAAA,cAAAA,CAAe,EAAE,CAAA;IACnB,CAAA,EACA;AAACD,QAAAA,WAAAA;AAAaF,QAAAA,KAAAA;AAAOwB,QAAAA,WAAAA;AAAaP,QAAAA;AAAO,KAAA,CAAA;AAG3C;;uGAGA,MAAM,EAAEuC,KAAK,EAAEC,aAAa,EAAEC,UAAU,EAAE,GAAGC,YAAAA,CAAa;QAAElE,MAAAA,EAAQ6B,EAAAA;AAAIC,QAAAA;AAAS,KAAA,CAAA;;IAGjFqC,SAAAA,CAAU,IAAA;AACR,QAAA,IAAIrC,QAAAA,CAASyB,MAAM,IAAI,CAAA,IAAK,CAACQ,KAAAA,EAAO;AAClCC,YAAAA,aAAAA,EAAAA;AACF,QAAA;IACF,CAAA,EAAG;AAAClC,QAAAA,QAAAA,CAASyB,MAAM;AAAEQ,QAAAA,KAAAA;AAAOC,QAAAA;AAAc,KAAA,CAAA;IAE1CG,SAAAA,CAAU,IAAA;AACR,QAAA,IAAI3C,WAAW,OAAA,EAAS;AACtBb,YAAAA,UAAAA,CAAW,kBAAA,EAAoB;gBAC7ByD,UAAAA,EAAY;AACd,aAAA,CAAA;AACF,QAAA,CAAA,MAAO,IACL5C,MAAAA,KAAW,OAAA,IACXM,QAAAA,CAASyB,MAAM,GAAG,CAAA,IAClBzB,QAAQ,CAACA,SAASyB,MAAM,GAAG,CAAA,CAAE,EAAEc,SAAS,WAAA,EACxC;AACA1D,YAAAA,UAAAA,CAAW,kBAAA,EAAoB;gBAC7ByD,UAAAA,EAAY;AACd,aAAA,CAAA;AACF,QAAA;IACF,CAAA,EAAG;AAAC5C,QAAAA,MAAAA;AAAQM,QAAAA,QAAAA;AAAUnB,QAAAA;AAAW,KAAA,CAAA;AAEjC,IAAA,MAAM2D,eAAAA,GAAkBC,iBAAAA,EAAAA;IACxB,MAAMC,iBAAAA,GAAoB5B,WAAAA,CACxB,CAACM,CAAAA,GAAM1C,QAAAA,CAAS0C,EAAEuB,MAAM,CAACC,KAAK,CAAA,EAC9B,EAAE,CAAA;AAEJ,IAAA,MAAMC,QAAQ/B,WAAAA,CAAY,IAAA;AACxBX,QAAAA,IAAAA,EAAAA;QACAhC,SAAAA,CAAUT,gBAAAA,EAAAA,CAAAA;QACVmB,UAAAA,CAAW,iBAAA,CAAA;AACXsD,QAAAA,UAAAA,EAAAA;IACF,CAAA,EAAG;AAACA,QAAAA,UAAAA;AAAYhC,QAAAA,IAAAA;AAAMtB,QAAAA;AAAW,KAAA,CAAA;AACjC,IAAA,MAAMiE,WAAWhC,WAAAA,CAAY,IAAA;QAC3BxC,aAAAA,CAAc,IAAA,CAAA;;AAEd,QAAA,IAAIC,cAAc,CAAA,EAAG;YACnBM,UAAAA,CAAW,iBAAA,CAAA;AACb,QAAA;QACAL,YAAAA,CAAa,CAACuE,OAASA,IAAAA,GAAO,CAAA,CAAA;IAChC,CAAA,EAAG;AAACxE,QAAAA,SAAAA;AAAWM,QAAAA;AAAW,KAAA,CAAA;AAC1B,IAAA,MAAMmE,SAAAA,GAAYlC,WAAAA,CAAY,IAAMxC,aAAAA,CAAc,QAAQ,EAAE,CAAA;IAC5D,MAAM2E,YAAAA,GAAe5D,OAAAA,CACnB,KAAO;YACL6D,aAAAA,EAAeV,eAAAA;AACfzC,YAAAA,EAAAA;AACAL,YAAAA,MAAAA;AACAS,YAAAA,IAAAA;AACAF,YAAAA,WAAAA;AACAG,YAAAA,WAAAA;AACAC,YAAAA,UAAAA;AACAC,YAAAA,UAAAA;AACAC,YAAAA,KAAAA;AACAC,YAAAA,YAAAA;AACAC,YAAAA,aAAAA;AACAC,YAAAA,aAAAA;AACAC,YAAAA,uBAAAA;AACAX,YAAAA,QAAAA;AACAmB,YAAAA,YAAAA;AACA1C,YAAAA,KAAAA;AACAC,YAAAA,QAAAA;AACAgE,YAAAA,iBAAAA;AACAG,YAAAA,KAAAA;AACAzD,YAAAA,OAAAA;AACA6C,YAAAA,KAAAA;AACA5D,YAAAA,UAAAA;AACAyE,YAAAA,QAAAA;AACAE,YAAAA,SAAAA;AACArE,YAAAA,WAAAA;AACAC,YAAAA;AACF,SAAA,CAAA,EACA;AACE4D,QAAAA,eAAAA;AACAzC,QAAAA,EAAAA;AACAL,QAAAA,MAAAA;AACAS,QAAAA,IAAAA;AACAF,QAAAA,WAAAA;AACAG,QAAAA,WAAAA;AACAC,QAAAA,UAAAA;AACAC,QAAAA,UAAAA;AACAC,QAAAA,KAAAA;AACAC,QAAAA,YAAAA;AACAC,QAAAA,aAAAA;AACAC,QAAAA,aAAAA;AACAC,QAAAA,uBAAAA;AACAX,QAAAA,QAAAA;AACAmB,QAAAA,YAAAA;AACA1C,QAAAA,KAAAA;AACAiE,QAAAA,iBAAAA;AACAG,QAAAA,KAAAA;AACAzD,QAAAA,OAAAA;AACA6C,QAAAA,KAAAA;AACA5D,QAAAA,UAAAA;AACAyE,QAAAA,QAAAA;AACAE,QAAAA,SAAAA;AACArE,QAAAA;AACD,KAAA,CAAA;IAGH,qBAAOwE,GAAA,CAAC5F,YAAY6F,QAAQ,EAAA;QAACR,KAAAA,EAAOK,YAAAA;AAAejF,QAAAA,QAAAA,EAAAA;;AACrD;AAEO,MAAMqF,eAAe,CAAC,EAC3BrF,QAAQ,EACRC,WAAAA,GAAc,KAAK,EAIpB,GAAA;AACC,IAAA,qBACEkF,GAAA,CAACpF,gBAAAA,EAAAA;QAAiBE,WAAAA,EAAaA,WAAAA;AAC7B,QAAA,QAAA,gBAAAkF,GAAA,CAACG,kBAAAA,EAAAA;AACC,YAAA,QAAA,gBAAAH,GAAA,CAACI,2BAAAA,EAAAA;AACC,gBAAA,QAAA,gBAAAJ,GAAA,CAACK,yBAAAA,EAAAA;AACC,oBAAA,QAAA,gBAAAL,GAAA,CAACM,gBAAAA,EAAAA;AAAkBzF,wBAAAA,QAAAA,EAAAA;;;;;;AAM/B;AAEO,SAAS0F,aAAAA,GAAAA;AACd,IAAA,MAAMC,UAAUC,UAAAA,CAAWrG,WAAAA,CAAAA;AAE3B,IAAA,IAAIsG,OAAAA,CAAQC,GAAG,CAACC,QAAQ,KAAK,aAAA,EAAe;;;AAG1C,QAAA,IAAIJ,YAAYlG,SAAAA,EAAW;AACzBuG,YAAAA,OAAAA,CAAQC,IAAI,CACV,6FAAA,CAAA;AAEF,YAAA,OAAO,EAAC;AACV,QAAA;IACF,CAAA,MAAO,IAAIN,YAAYlG,SAAAA,EAAW;AAChC,QAAA,MAAM,IAAIyG,KAAAA,CAAM,kDAAA,CAAA;AAClB,IAAA;IACA,OAAOP,OAAAA;AACT;;;;"}
@@ -89,11 +89,14 @@ const SchemaChatProvider = ({ children })=>{
89
89
  }, [
90
90
  messages
91
91
  ]);
92
- return /*#__PURE__*/ jsxRuntime.jsx(SchemaContext.Provider, {
93
- value: {
92
+ const contextValue = React.useMemo(()=>({
94
93
  lastRevisedId,
95
94
  setLastRevisedId
96
- },
95
+ }), [
96
+ lastRevisedId
97
+ ]);
98
+ return /*#__PURE__*/ jsxRuntime.jsx(SchemaContext.Provider, {
99
+ value: contextValue,
97
100
  children: children
98
101
  });
99
102
  };
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaProvider.js","sources":["../../../../../admin/src/components/AIChat/providers/SchemaProvider.tsx"],"sourcesContent":["import { createContext, useContext, ReactNode, useEffect, useState } from 'react';\n\nimport { GUIDED_TOUR_REQUIRED_ACTIONS, useGuidedTour } from '@strapi/admin/strapi-admin';\n\nimport { useDataManager } from '../../DataManager/useDataManager';\nimport { transformChatToCTB } from '../lib/transforms/schemas/toCTB';\nimport { SchemaChange } from '../lib/types/annotations';\nimport { AIMessage } from '../lib/types/messages';\n\nimport { useStrapiChat } from './ChatProvider';\n\nimport type { Schema } from '../lib/types/schema';\nimport type { Internal } from '@strapi/types';\n\ninterface SchemaContextType {\n lastRevisedId: string | null;\n setLastRevisedId: (id: string | null) => void;\n}\n\nconst SchemaContext = createContext<SchemaContextType | undefined>(undefined);\n\nconst TYPE_TO_ACTION: Record<string, 'add' | 'update' | 'delete'> = {\n create: 'add',\n update: 'update',\n remove: 'delete',\n};\n\ntype SchemaGenerationOutput = {\n schemas?: Schema[];\n error?: unknown;\n};\n\nfunction extractSchemaChangesFromMessage(message: AIMessage): SchemaChange[] {\n if (message.role !== 'assistant') return [];\n\n const changes: SchemaChange[] = [];\n\n message.parts?.forEach((part, partIndex) => {\n // We only care about the schema generation tool\n if (part && typeof part === 'object' && part.type === 'tool-schemaGenerationTool') {\n // Prefer validated schemas from output; ignore if there's an error or no output yet\n const output = part.output as SchemaGenerationOutput | undefined;\n if (!output || output.error || !Array.isArray(output.schemas)) return;\n\n const baseId = part.toolCallId ?? `${message.id}-${partIndex}`;\n\n output.schemas.forEach((schema, schemaIndex) => {\n const revisionId = `${baseId}-${schema.uid ?? schema.name ?? schemaIndex}`;\n const type = (schema.action as SchemaChange['type']) || 'update';\n changes.push({ type, schema, revisionId });\n });\n }\n });\n\n return changes;\n}\n\nexport const SchemaChatProvider = ({ children }: { children: ReactNode }) => {\n const [lastRevisedId, setLastRevisedId] = useState<string | null>(null);\n const { messages, status } = useStrapiChat();\n const { contentTypes, components, applyChange } = useDataManager();\n const dispatch = useGuidedTour('SchemaChatProvider', (s) => s.dispatch);\n const state = useGuidedTour('SchemaChatProvider', (s) => s.state);\n\n useEffect(() => {\n const latestMessage = messages[messages.length - 1];\n if (!latestMessage) return;\n if (latestMessage.role !== 'assistant') return;\n // Wait until message streaming has finished\n if (status !== 'ready') return;\n\n // const schemaChanges = latestMessage.schemaChanges;\n const schemaChanges = extractSchemaChangesFromMessage(latestMessage);\n\n // Check if addField action is already completed\n const isAddFieldCompleted = state.completedActions.includes(\n GUIDED_TOUR_REQUIRED_ACTIONS.contentTypeBuilder.addField\n );\n\n // Changes are applied one at a time: a change that renames existing fields\n // may prompt the user for consent, and prompts must not overlap.\n const applyChanges = async () => {\n for (const change of schemaChanges) {\n const oldSchema =\n change.schema.modelType === 'contentType'\n ? contentTypes[change.schema.uid as Internal.UID.ContentType]\n : components[change.schema.uid as Internal.UID.Component];\n const newSchema = transformChatToCTB(change.schema, oldSchema);\n\n // Check if any attributes/fields are being added to any schema (existing or new)\n if (!isAddFieldCompleted && change.schema.attributes) {\n // If a field is being added or updated, dispatch guided tour action to show Save tooltip\n if (change.type !== 'remove' && Object.keys(change.schema.attributes).length > 0) {\n dispatch({\n type: 'set_completed_actions',\n payload: [GUIDED_TOUR_REQUIRED_ACTIONS.contentTypeBuilder.addField],\n });\n }\n }\n\n // eslint-disable-next-line no-await-in-loop\n const applied = await applyChange({\n action: TYPE_TO_ACTION[change.type]!,\n schema: newSchema,\n });\n\n // The user cancelled a rename prompt: stop here. Earlier changes in this\n // batch stay applied (they are in the undo history); the message is not\n // marked as revised.\n if (!applied) {\n return;\n }\n }\n\n setLastRevisedId(latestMessage.id);\n };\n\n applyChanges();\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [messages]);\n\n return (\n <SchemaContext.Provider value={{ lastRevisedId, setLastRevisedId }}>\n {children}\n </SchemaContext.Provider>\n );\n};\n\nexport const useChatSchema = () => {\n const context = useContext(SchemaContext);\n if (context === undefined) {\n throw new Error('useSchema must be used within a SchemaProvider');\n }\n return context;\n};\n"],"names":["SchemaContext","createContext","undefined","TYPE_TO_ACTION","create","update","remove","extractSchemaChangesFromMessage","message","role","changes","parts","forEach","part","partIndex","type","output","error","Array","isArray","schemas","baseId","toolCallId","id","schema","schemaIndex","revisionId","uid","name","action","push","SchemaChatProvider","children","lastRevisedId","setLastRevisedId","useState","messages","status","useStrapiChat","contentTypes","components","applyChange","useDataManager","dispatch","useGuidedTour","s","state","useEffect","latestMessage","length","schemaChanges","isAddFieldCompleted","completedActions","includes","GUIDED_TOUR_REQUIRED_ACTIONS","contentTypeBuilder","addField","applyChanges","change","oldSchema","modelType","newSchema","transformChatToCTB","attributes","Object","keys","payload","applied","_jsx","Provider","value"],"mappings":"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"}
1
+ {"version":3,"file":"SchemaProvider.js","sources":["../../../../../admin/src/components/AIChat/providers/SchemaProvider.tsx"],"sourcesContent":["import { createContext, useContext, ReactNode, useEffect, useMemo, useState } from 'react';\n\nimport { GUIDED_TOUR_REQUIRED_ACTIONS, useGuidedTour } from '@strapi/admin/strapi-admin';\n\nimport { useDataManager } from '../../DataManager/useDataManager';\nimport { transformChatToCTB } from '../lib/transforms/schemas/toCTB';\nimport { SchemaChange } from '../lib/types/annotations';\nimport { AIMessage } from '../lib/types/messages';\n\nimport { useStrapiChat } from './ChatProvider';\n\nimport type { Schema } from '../lib/types/schema';\nimport type { Internal } from '@strapi/types';\n\ninterface SchemaContextType {\n lastRevisedId: string | null;\n setLastRevisedId: (id: string | null) => void;\n}\n\nconst SchemaContext = createContext<SchemaContextType | undefined>(undefined);\n\nconst TYPE_TO_ACTION: Record<string, 'add' | 'update' | 'delete'> = {\n create: 'add',\n update: 'update',\n remove: 'delete',\n};\n\ntype SchemaGenerationOutput = {\n schemas?: Schema[];\n error?: unknown;\n};\n\nfunction extractSchemaChangesFromMessage(message: AIMessage): SchemaChange[] {\n if (message.role !== 'assistant') return [];\n\n const changes: SchemaChange[] = [];\n\n message.parts?.forEach((part, partIndex) => {\n // We only care about the schema generation tool\n if (part && typeof part === 'object' && part.type === 'tool-schemaGenerationTool') {\n // Prefer validated schemas from output; ignore if there's an error or no output yet\n const output = part.output as SchemaGenerationOutput | undefined;\n if (!output || output.error || !Array.isArray(output.schemas)) return;\n\n const baseId = part.toolCallId ?? `${message.id}-${partIndex}`;\n\n output.schemas.forEach((schema, schemaIndex) => {\n const revisionId = `${baseId}-${schema.uid ?? schema.name ?? schemaIndex}`;\n const type = (schema.action as SchemaChange['type']) || 'update';\n changes.push({ type, schema, revisionId });\n });\n }\n });\n\n return changes;\n}\n\nexport const SchemaChatProvider = ({ children }: { children: ReactNode }) => {\n const [lastRevisedId, setLastRevisedId] = useState<string | null>(null);\n const { messages, status } = useStrapiChat();\n const { contentTypes, components, applyChange } = useDataManager();\n const dispatch = useGuidedTour('SchemaChatProvider', (s) => s.dispatch);\n const state = useGuidedTour('SchemaChatProvider', (s) => s.state);\n\n useEffect(() => {\n const latestMessage = messages[messages.length - 1];\n if (!latestMessage) return;\n if (latestMessage.role !== 'assistant') return;\n // Wait until message streaming has finished\n if (status !== 'ready') return;\n\n // const schemaChanges = latestMessage.schemaChanges;\n const schemaChanges = extractSchemaChangesFromMessage(latestMessage);\n\n // Check if addField action is already completed\n const isAddFieldCompleted = state.completedActions.includes(\n GUIDED_TOUR_REQUIRED_ACTIONS.contentTypeBuilder.addField\n );\n\n // Changes are applied one at a time: a change that renames existing fields\n // may prompt the user for consent, and prompts must not overlap.\n const applyChanges = async () => {\n for (const change of schemaChanges) {\n const oldSchema =\n change.schema.modelType === 'contentType'\n ? contentTypes[change.schema.uid as Internal.UID.ContentType]\n : components[change.schema.uid as Internal.UID.Component];\n const newSchema = transformChatToCTB(change.schema, oldSchema);\n\n // Check if any attributes/fields are being added to any schema (existing or new)\n if (!isAddFieldCompleted && change.schema.attributes) {\n // If a field is being added or updated, dispatch guided tour action to show Save tooltip\n if (change.type !== 'remove' && Object.keys(change.schema.attributes).length > 0) {\n dispatch({\n type: 'set_completed_actions',\n payload: [GUIDED_TOUR_REQUIRED_ACTIONS.contentTypeBuilder.addField],\n });\n }\n }\n\n // eslint-disable-next-line no-await-in-loop\n const applied = await applyChange({\n action: TYPE_TO_ACTION[change.type]!,\n schema: newSchema,\n });\n\n // The user cancelled a rename prompt: stop here. Earlier changes in this\n // batch stay applied (they are in the undo history); the message is not\n // marked as revised.\n if (!applied) {\n return;\n }\n }\n\n setLastRevisedId(latestMessage.id);\n };\n\n applyChanges();\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [messages]);\n\n const contextValue = useMemo(() => ({ lastRevisedId, setLastRevisedId }), [lastRevisedId]);\n\n return <SchemaContext.Provider value={contextValue}>{children}</SchemaContext.Provider>;\n};\n\nexport const useChatSchema = () => {\n const context = useContext(SchemaContext);\n if (context === undefined) {\n throw new Error('useSchema must be used within a SchemaProvider');\n }\n return context;\n};\n"],"names":["SchemaContext","createContext","undefined","TYPE_TO_ACTION","create","update","remove","extractSchemaChangesFromMessage","message","role","changes","parts","forEach","part","partIndex","type","output","error","Array","isArray","schemas","baseId","toolCallId","id","schema","schemaIndex","revisionId","uid","name","action","push","SchemaChatProvider","children","lastRevisedId","setLastRevisedId","useState","messages","status","useStrapiChat","contentTypes","components","applyChange","useDataManager","dispatch","useGuidedTour","s","state","useEffect","latestMessage","length","schemaChanges","isAddFieldCompleted","completedActions","includes","GUIDED_TOUR_REQUIRED_ACTIONS","contentTypeBuilder","addField","applyChanges","change","oldSchema","modelType","newSchema","transformChatToCTB","attributes","Object","keys","payload","applied","contextValue","useMemo","_jsx","Provider","value"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { useState, useEffect, createContext } from 'react';
2
+ import { useState, useEffect, useMemo, createContext } from 'react';
3
3
  import { useGuidedTour, GUIDED_TOUR_REQUIRED_ACTIONS } from '@strapi/admin/strapi-admin';
4
4
  import { useDataManager } from '../../DataManager/useDataManager.mjs';
5
5
  import { transformChatToCTB } from '../lib/transforms/schemas/toCTB.mjs';
@@ -87,11 +87,14 @@ const SchemaChatProvider = ({ children })=>{
87
87
  }, [
88
88
  messages
89
89
  ]);
90
- return /*#__PURE__*/ jsx(SchemaContext.Provider, {
91
- value: {
90
+ const contextValue = useMemo(()=>({
92
91
  lastRevisedId,
93
92
  setLastRevisedId
94
- },
93
+ }), [
94
+ lastRevisedId
95
+ ]);
96
+ return /*#__PURE__*/ jsx(SchemaContext.Provider, {
97
+ value: contextValue,
95
98
  children: children
96
99
  });
97
100
  };
@@ -1 +1 @@
1
- {"version":3,"file":"SchemaProvider.mjs","sources":["../../../../../admin/src/components/AIChat/providers/SchemaProvider.tsx"],"sourcesContent":["import { createContext, useContext, ReactNode, useEffect, useState } from 'react';\n\nimport { GUIDED_TOUR_REQUIRED_ACTIONS, useGuidedTour } from '@strapi/admin/strapi-admin';\n\nimport { useDataManager } from '../../DataManager/useDataManager';\nimport { transformChatToCTB } from '../lib/transforms/schemas/toCTB';\nimport { SchemaChange } from '../lib/types/annotations';\nimport { AIMessage } from '../lib/types/messages';\n\nimport { useStrapiChat } from './ChatProvider';\n\nimport type { Schema } from '../lib/types/schema';\nimport type { Internal } from '@strapi/types';\n\ninterface SchemaContextType {\n lastRevisedId: string | null;\n setLastRevisedId: (id: string | null) => void;\n}\n\nconst SchemaContext = createContext<SchemaContextType | undefined>(undefined);\n\nconst TYPE_TO_ACTION: Record<string, 'add' | 'update' | 'delete'> = {\n create: 'add',\n update: 'update',\n remove: 'delete',\n};\n\ntype SchemaGenerationOutput = {\n schemas?: Schema[];\n error?: unknown;\n};\n\nfunction extractSchemaChangesFromMessage(message: AIMessage): SchemaChange[] {\n if (message.role !== 'assistant') return [];\n\n const changes: SchemaChange[] = [];\n\n message.parts?.forEach((part, partIndex) => {\n // We only care about the schema generation tool\n if (part && typeof part === 'object' && part.type === 'tool-schemaGenerationTool') {\n // Prefer validated schemas from output; ignore if there's an error or no output yet\n const output = part.output as SchemaGenerationOutput | undefined;\n if (!output || output.error || !Array.isArray(output.schemas)) return;\n\n const baseId = part.toolCallId ?? `${message.id}-${partIndex}`;\n\n output.schemas.forEach((schema, schemaIndex) => {\n const revisionId = `${baseId}-${schema.uid ?? schema.name ?? schemaIndex}`;\n const type = (schema.action as SchemaChange['type']) || 'update';\n changes.push({ type, schema, revisionId });\n });\n }\n });\n\n return changes;\n}\n\nexport const SchemaChatProvider = ({ children }: { children: ReactNode }) => {\n const [lastRevisedId, setLastRevisedId] = useState<string | null>(null);\n const { messages, status } = useStrapiChat();\n const { contentTypes, components, applyChange } = useDataManager();\n const dispatch = useGuidedTour('SchemaChatProvider', (s) => s.dispatch);\n const state = useGuidedTour('SchemaChatProvider', (s) => s.state);\n\n useEffect(() => {\n const latestMessage = messages[messages.length - 1];\n if (!latestMessage) return;\n if (latestMessage.role !== 'assistant') return;\n // Wait until message streaming has finished\n if (status !== 'ready') return;\n\n // const schemaChanges = latestMessage.schemaChanges;\n const schemaChanges = extractSchemaChangesFromMessage(latestMessage);\n\n // Check if addField action is already completed\n const isAddFieldCompleted = state.completedActions.includes(\n GUIDED_TOUR_REQUIRED_ACTIONS.contentTypeBuilder.addField\n );\n\n // Changes are applied one at a time: a change that renames existing fields\n // may prompt the user for consent, and prompts must not overlap.\n const applyChanges = async () => {\n for (const change of schemaChanges) {\n const oldSchema =\n change.schema.modelType === 'contentType'\n ? contentTypes[change.schema.uid as Internal.UID.ContentType]\n : components[change.schema.uid as Internal.UID.Component];\n const newSchema = transformChatToCTB(change.schema, oldSchema);\n\n // Check if any attributes/fields are being added to any schema (existing or new)\n if (!isAddFieldCompleted && change.schema.attributes) {\n // If a field is being added or updated, dispatch guided tour action to show Save tooltip\n if (change.type !== 'remove' && Object.keys(change.schema.attributes).length > 0) {\n dispatch({\n type: 'set_completed_actions',\n payload: [GUIDED_TOUR_REQUIRED_ACTIONS.contentTypeBuilder.addField],\n });\n }\n }\n\n // eslint-disable-next-line no-await-in-loop\n const applied = await applyChange({\n action: TYPE_TO_ACTION[change.type]!,\n schema: newSchema,\n });\n\n // The user cancelled a rename prompt: stop here. Earlier changes in this\n // batch stay applied (they are in the undo history); the message is not\n // marked as revised.\n if (!applied) {\n return;\n }\n }\n\n setLastRevisedId(latestMessage.id);\n };\n\n applyChanges();\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [messages]);\n\n return (\n <SchemaContext.Provider value={{ lastRevisedId, setLastRevisedId }}>\n {children}\n </SchemaContext.Provider>\n );\n};\n\nexport const useChatSchema = () => {\n const context = useContext(SchemaContext);\n if (context === undefined) {\n throw new Error('useSchema must be used within a SchemaProvider');\n }\n return context;\n};\n"],"names":["SchemaContext","createContext","undefined","TYPE_TO_ACTION","create","update","remove","extractSchemaChangesFromMessage","message","role","changes","parts","forEach","part","partIndex","type","output","error","Array","isArray","schemas","baseId","toolCallId","id","schema","schemaIndex","revisionId","uid","name","action","push","SchemaChatProvider","children","lastRevisedId","setLastRevisedId","useState","messages","status","useStrapiChat","contentTypes","components","applyChange","useDataManager","dispatch","useGuidedTour","s","state","useEffect","latestMessage","length","schemaChanges","isAddFieldCompleted","completedActions","includes","GUIDED_TOUR_REQUIRED_ACTIONS","contentTypeBuilder","addField","applyChanges","change","oldSchema","modelType","newSchema","transformChatToCTB","attributes","Object","keys","payload","applied","_jsx","Provider","value"],"mappings":"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"}
1
+ {"version":3,"file":"SchemaProvider.mjs","sources":["../../../../../admin/src/components/AIChat/providers/SchemaProvider.tsx"],"sourcesContent":["import { createContext, useContext, ReactNode, useEffect, useMemo, useState } from 'react';\n\nimport { GUIDED_TOUR_REQUIRED_ACTIONS, useGuidedTour } from '@strapi/admin/strapi-admin';\n\nimport { useDataManager } from '../../DataManager/useDataManager';\nimport { transformChatToCTB } from '../lib/transforms/schemas/toCTB';\nimport { SchemaChange } from '../lib/types/annotations';\nimport { AIMessage } from '../lib/types/messages';\n\nimport { useStrapiChat } from './ChatProvider';\n\nimport type { Schema } from '../lib/types/schema';\nimport type { Internal } from '@strapi/types';\n\ninterface SchemaContextType {\n lastRevisedId: string | null;\n setLastRevisedId: (id: string | null) => void;\n}\n\nconst SchemaContext = createContext<SchemaContextType | undefined>(undefined);\n\nconst TYPE_TO_ACTION: Record<string, 'add' | 'update' | 'delete'> = {\n create: 'add',\n update: 'update',\n remove: 'delete',\n};\n\ntype SchemaGenerationOutput = {\n schemas?: Schema[];\n error?: unknown;\n};\n\nfunction extractSchemaChangesFromMessage(message: AIMessage): SchemaChange[] {\n if (message.role !== 'assistant') return [];\n\n const changes: SchemaChange[] = [];\n\n message.parts?.forEach((part, partIndex) => {\n // We only care about the schema generation tool\n if (part && typeof part === 'object' && part.type === 'tool-schemaGenerationTool') {\n // Prefer validated schemas from output; ignore if there's an error or no output yet\n const output = part.output as SchemaGenerationOutput | undefined;\n if (!output || output.error || !Array.isArray(output.schemas)) return;\n\n const baseId = part.toolCallId ?? `${message.id}-${partIndex}`;\n\n output.schemas.forEach((schema, schemaIndex) => {\n const revisionId = `${baseId}-${schema.uid ?? schema.name ?? schemaIndex}`;\n const type = (schema.action as SchemaChange['type']) || 'update';\n changes.push({ type, schema, revisionId });\n });\n }\n });\n\n return changes;\n}\n\nexport const SchemaChatProvider = ({ children }: { children: ReactNode }) => {\n const [lastRevisedId, setLastRevisedId] = useState<string | null>(null);\n const { messages, status } = useStrapiChat();\n const { contentTypes, components, applyChange } = useDataManager();\n const dispatch = useGuidedTour('SchemaChatProvider', (s) => s.dispatch);\n const state = useGuidedTour('SchemaChatProvider', (s) => s.state);\n\n useEffect(() => {\n const latestMessage = messages[messages.length - 1];\n if (!latestMessage) return;\n if (latestMessage.role !== 'assistant') return;\n // Wait until message streaming has finished\n if (status !== 'ready') return;\n\n // const schemaChanges = latestMessage.schemaChanges;\n const schemaChanges = extractSchemaChangesFromMessage(latestMessage);\n\n // Check if addField action is already completed\n const isAddFieldCompleted = state.completedActions.includes(\n GUIDED_TOUR_REQUIRED_ACTIONS.contentTypeBuilder.addField\n );\n\n // Changes are applied one at a time: a change that renames existing fields\n // may prompt the user for consent, and prompts must not overlap.\n const applyChanges = async () => {\n for (const change of schemaChanges) {\n const oldSchema =\n change.schema.modelType === 'contentType'\n ? contentTypes[change.schema.uid as Internal.UID.ContentType]\n : components[change.schema.uid as Internal.UID.Component];\n const newSchema = transformChatToCTB(change.schema, oldSchema);\n\n // Check if any attributes/fields are being added to any schema (existing or new)\n if (!isAddFieldCompleted && change.schema.attributes) {\n // If a field is being added or updated, dispatch guided tour action to show Save tooltip\n if (change.type !== 'remove' && Object.keys(change.schema.attributes).length > 0) {\n dispatch({\n type: 'set_completed_actions',\n payload: [GUIDED_TOUR_REQUIRED_ACTIONS.contentTypeBuilder.addField],\n });\n }\n }\n\n // eslint-disable-next-line no-await-in-loop\n const applied = await applyChange({\n action: TYPE_TO_ACTION[change.type]!,\n schema: newSchema,\n });\n\n // The user cancelled a rename prompt: stop here. Earlier changes in this\n // batch stay applied (they are in the undo history); the message is not\n // marked as revised.\n if (!applied) {\n return;\n }\n }\n\n setLastRevisedId(latestMessage.id);\n };\n\n applyChanges();\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [messages]);\n\n const contextValue = useMemo(() => ({ lastRevisedId, setLastRevisedId }), [lastRevisedId]);\n\n return <SchemaContext.Provider value={contextValue}>{children}</SchemaContext.Provider>;\n};\n\nexport const useChatSchema = () => {\n const context = useContext(SchemaContext);\n if (context === undefined) {\n throw new Error('useSchema must be used within a SchemaProvider');\n }\n return context;\n};\n"],"names":["SchemaContext","createContext","undefined","TYPE_TO_ACTION","create","update","remove","extractSchemaChangesFromMessage","message","role","changes","parts","forEach","part","partIndex","type","output","error","Array","isArray","schemas","baseId","toolCallId","id","schema","schemaIndex","revisionId","uid","name","action","push","SchemaChatProvider","children","lastRevisedId","setLastRevisedId","useState","messages","status","useStrapiChat","contentTypes","components","applyChange","useDataManager","dispatch","useGuidedTour","s","state","useEffect","latestMessage","length","schemaChanges","isAddFieldCompleted","completedActions","includes","GUIDED_TOUR_REQUIRED_ACTIONS","contentTypeBuilder","addField","applyChanges","change","oldSchema","modelType","newSchema","transformChatToCTB","attributes","Object","keys","payload","applied","contextValue","useMemo","_jsx","Provider","value"],"mappings":"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"}