@ai-stack/payloadcms 3.2.26 → 3.68.0-beta.2

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 (313) hide show
  1. package/{LICENSE.md → LICENSE} +1 -1
  2. package/README.md +218 -229
  3. package/dist/access/checkAccess.d.ts +4 -0
  4. package/dist/access/checkAccess.js +20 -0
  5. package/dist/access/checkAccess.js.map +1 -0
  6. package/dist/ai/core/generateObject.d.ts +7 -0
  7. package/dist/ai/core/generateObject.js +35 -0
  8. package/dist/ai/core/generateObject.js.map +1 -0
  9. package/dist/ai/core/generateText.d.ts +7 -0
  10. package/dist/ai/core/generateText.js +31 -0
  11. package/dist/ai/core/generateText.js.map +1 -0
  12. package/dist/ai/core/index.d.ts +11 -0
  13. package/dist/ai/core/index.js +10 -0
  14. package/dist/ai/core/index.js.map +1 -0
  15. package/dist/ai/core/media/generateMedia.d.ts +7 -0
  16. package/dist/ai/core/media/generateMedia.js +50 -0
  17. package/dist/ai/core/media/generateMedia.js.map +1 -0
  18. package/dist/ai/core/media/image/generateImage.d.ts +6 -0
  19. package/dist/ai/core/media/image/generateImage.js +41 -0
  20. package/dist/ai/core/media/image/generateImage.js.map +1 -0
  21. package/dist/ai/core/media/image/handlers/multimodal.d.ts +7 -0
  22. package/dist/ai/core/media/image/handlers/multimodal.js +100 -0
  23. package/dist/ai/core/media/image/handlers/multimodal.js.map +1 -0
  24. package/dist/ai/core/media/image/handlers/standard.d.ts +7 -0
  25. package/dist/ai/core/media/image/handlers/standard.js +28 -0
  26. package/dist/ai/core/media/image/handlers/standard.js.map +1 -0
  27. package/dist/ai/core/media/image/index.d.ts +2 -0
  28. package/dist/ai/core/media/image/index.js +3 -0
  29. package/dist/ai/core/media/image/index.js.map +1 -0
  30. package/dist/ai/core/media/index.d.ts +2 -0
  31. package/dist/ai/core/media/index.js +3 -0
  32. package/dist/ai/core/media/index.js.map +1 -0
  33. package/dist/ai/core/media/speech/generateSpeech.d.ts +5 -0
  34. package/dist/ai/core/media/speech/generateSpeech.js +55 -0
  35. package/dist/ai/core/media/speech/generateSpeech.js.map +1 -0
  36. package/dist/ai/core/media/speech/index.d.ts +2 -0
  37. package/dist/ai/core/media/speech/index.js +3 -0
  38. package/dist/ai/core/media/speech/index.js.map +1 -0
  39. package/dist/ai/core/media/types.d.ts +74 -0
  40. package/dist/ai/core/media/types.js +5 -0
  41. package/dist/ai/core/media/types.js.map +1 -0
  42. package/dist/ai/core/media/utils.d.ts +11 -0
  43. package/dist/ai/core/media/utils.js +34 -0
  44. package/dist/ai/core/media/utils.js.map +1 -0
  45. package/dist/ai/core/media/video/generateVideo.d.ts +6 -0
  46. package/dist/ai/core/media/video/generateVideo.js +32 -0
  47. package/dist/ai/core/media/video/generateVideo.js.map +1 -0
  48. package/dist/ai/core/media/video/index.d.ts +2 -0
  49. package/dist/ai/core/media/video/index.js +3 -0
  50. package/dist/ai/core/media/video/index.js.map +1 -0
  51. package/dist/ai/core/streamObject.d.ts +7 -0
  52. package/dist/ai/core/streamObject.js +54 -0
  53. package/dist/ai/core/streamObject.js.map +1 -0
  54. package/dist/ai/core/streamText.d.ts +7 -0
  55. package/dist/ai/core/streamText.js +30 -0
  56. package/dist/ai/core/streamText.js.map +1 -0
  57. package/dist/ai/core/types.d.ts +85 -0
  58. package/dist/ai/core/types.js +5 -0
  59. package/dist/ai/core/types.js.map +1 -0
  60. package/dist/ai/index.d.ts +11 -0
  61. package/dist/ai/index.js +25 -0
  62. package/dist/ai/index.js.map +1 -0
  63. package/dist/ai/providers/blocks/anthropic.d.ts +2 -0
  64. package/dist/ai/providers/blocks/anthropic.js +223 -0
  65. package/dist/ai/providers/blocks/anthropic.js.map +1 -0
  66. package/dist/ai/providers/blocks/elevenlabs.d.ts +2 -0
  67. package/dist/ai/providers/blocks/elevenlabs.js +449 -0
  68. package/dist/ai/providers/blocks/elevenlabs.js.map +1 -0
  69. package/dist/ai/providers/blocks/fal.d.ts +2 -0
  70. package/dist/ai/providers/blocks/fal.js +312 -0
  71. package/dist/ai/providers/blocks/fal.js.map +1 -0
  72. package/dist/ai/providers/blocks/google.d.ts +2 -0
  73. package/dist/ai/providers/blocks/google.js +623 -0
  74. package/dist/ai/providers/blocks/google.js.map +1 -0
  75. package/dist/ai/providers/blocks/index.d.ts +2 -0
  76. package/dist/ai/providers/blocks/index.js +18 -0
  77. package/dist/ai/providers/blocks/index.js.map +1 -0
  78. package/dist/ai/providers/blocks/openai-compatible.d.ts +2 -0
  79. package/dist/ai/providers/blocks/openai-compatible.js +308 -0
  80. package/dist/ai/providers/blocks/openai-compatible.js.map +1 -0
  81. package/dist/ai/providers/blocks/openai.d.ts +2 -0
  82. package/dist/ai/providers/blocks/openai.js +600 -0
  83. package/dist/ai/providers/blocks/openai.js.map +1 -0
  84. package/dist/ai/providers/blocks/xai.d.ts +2 -0
  85. package/dist/ai/providers/blocks/xai.js +247 -0
  86. package/dist/ai/providers/blocks/xai.js.map +1 -0
  87. package/dist/ai/providers/icons.d.ts +7 -0
  88. package/dist/ai/providers/icons.js +9 -0
  89. package/dist/ai/providers/icons.js.map +1 -0
  90. package/dist/ai/providers/index.d.ts +2 -0
  91. package/dist/ai/providers/index.js +6 -0
  92. package/dist/ai/providers/index.js.map +1 -0
  93. package/dist/ai/providers/registry.d.ts +40 -0
  94. package/dist/ai/providers/registry.js +267 -0
  95. package/dist/ai/providers/registry.js.map +1 -0
  96. package/dist/ai/providers/types.d.ts +115 -0
  97. package/dist/ai/providers/types.js +4 -0
  98. package/dist/ai/providers/types.js.map +1 -0
  99. package/dist/ai/utils/systemGenerate.d.ts +1 -1
  100. package/dist/ai/utils/systemGenerate.js +19 -19
  101. package/dist/ai/utils/systemGenerate.js.map +1 -1
  102. package/dist/collections/AIJobs.d.ts +2 -0
  103. package/dist/collections/AIJobs.js +81 -0
  104. package/dist/collections/AIJobs.js.map +1 -0
  105. package/dist/collections/AISettings.d.ts +2 -0
  106. package/dist/collections/AISettings.js +279 -0
  107. package/dist/collections/AISettings.js.map +1 -0
  108. package/dist/collections/Instructions.js +224 -50
  109. package/dist/collections/Instructions.js.map +1 -1
  110. package/dist/defaults.d.ts +3 -0
  111. package/dist/defaults.js +3 -0
  112. package/dist/defaults.js.map +1 -1
  113. package/dist/endpoints/buildPromptUtils.d.ts +19 -0
  114. package/dist/endpoints/buildPromptUtils.js +114 -0
  115. package/dist/endpoints/buildPromptUtils.js.map +1 -0
  116. package/dist/endpoints/chat.d.ts +4 -0
  117. package/dist/endpoints/fetchFields.js +0 -7
  118. package/dist/endpoints/fetchFields.js.map +1 -1
  119. package/dist/endpoints/fetchVoices.d.ts +2 -0
  120. package/dist/endpoints/fetchVoices.js +79 -0
  121. package/dist/endpoints/fetchVoices.js.map +1 -0
  122. package/dist/endpoints/index.js +339 -232
  123. package/dist/endpoints/index.js.map +1 -1
  124. package/dist/exports/client.d.ts +9 -0
  125. package/dist/exports/client.js +9 -0
  126. package/dist/exports/client.js.map +1 -1
  127. package/dist/exports/fields.d.ts +1 -0
  128. package/dist/exports/fields.js +1 -0
  129. package/dist/exports/fields.js.map +1 -1
  130. package/dist/fields/ArrayComposeField/ArrayComposeField.d.ts +15 -0
  131. package/dist/fields/ArrayComposeField/ArrayComposeField.js +87 -0
  132. package/dist/fields/ArrayComposeField/ArrayComposeField.js.map +1 -0
  133. package/dist/fields/ArrayComposeField/ArrayComposeField.jsx +73 -0
  134. package/dist/fields/ComposeField/ComposeField.js +2 -2
  135. package/dist/fields/ComposeField/ComposeField.js.map +1 -1
  136. package/dist/fields/ComposeField/ComposeField.jsx +2 -2
  137. package/dist/fields/PromptEditorField/PromptEditorField.js +162 -16
  138. package/dist/fields/PromptEditorField/PromptEditorField.js.map +1 -1
  139. package/dist/fields/PromptEditorField/PromptEditorField.jsx +123 -5
  140. package/dist/index.d.ts +3 -0
  141. package/dist/index.js +1 -0
  142. package/dist/index.js.map +1 -1
  143. package/dist/init.js +63 -65
  144. package/dist/init.js.map +1 -1
  145. package/dist/payload-ai.d.ts +149 -0
  146. package/dist/plugin.js +94 -46
  147. package/dist/plugin.js.map +1 -1
  148. package/dist/providers/InstructionsProvider/InstructionsProvider.js +38 -7
  149. package/dist/providers/InstructionsProvider/InstructionsProvider.js.map +1 -1
  150. package/dist/providers/InstructionsProvider/InstructionsProvider.jsx +30 -4
  151. package/dist/providers/InstructionsProvider/context.d.ts +1 -0
  152. package/dist/providers/InstructionsProvider/context.js +1 -0
  153. package/dist/providers/InstructionsProvider/context.js.map +1 -1
  154. package/dist/providers/InstructionsProvider/useInstructions.js +30 -10
  155. package/dist/providers/InstructionsProvider/useInstructions.js.map +1 -1
  156. package/dist/styles.d.ts +11 -0
  157. package/dist/types/handlebars-async-helpers.d.ts +1 -0
  158. package/dist/types/handlebars-dist-handlebars.d.ts +1 -0
  159. package/dist/types/react-mentions.d.ts +1 -0
  160. package/dist/types.d.ts +6 -16
  161. package/dist/types.js.map +1 -1
  162. package/dist/ui/AIConfigDashboard/index.d.ts +2 -0
  163. package/dist/ui/AIConfigDashboard/index.js +46 -0
  164. package/dist/ui/AIConfigDashboard/index.js.map +1 -0
  165. package/dist/ui/AIConfigDashboard/index.jsx +24 -0
  166. package/dist/ui/ApiKeyStatusIndicator/index.d.ts +6 -0
  167. package/dist/ui/ApiKeyStatusIndicator/index.js +39 -0
  168. package/dist/ui/ApiKeyStatusIndicator/index.js.map +1 -0
  169. package/dist/ui/ApiKeyStatusIndicator/index.jsx +29 -0
  170. package/dist/ui/Compose/Compose.d.ts +2 -2
  171. package/dist/ui/Compose/Compose.js +118 -92
  172. package/dist/ui/Compose/Compose.js.map +1 -1
  173. package/dist/ui/Compose/Compose.jsx +113 -103
  174. package/dist/ui/Compose/ComposePlaceholder.d.ts +7 -0
  175. package/dist/ui/Compose/ComposePlaceholder.js +78 -0
  176. package/dist/ui/Compose/ComposePlaceholder.js.map +1 -0
  177. package/dist/ui/Compose/ComposePlaceholder.jsx +66 -0
  178. package/dist/ui/Compose/UndoRedoActions.d.ts +2 -2
  179. package/dist/ui/Compose/UndoRedoActions.js +11 -6
  180. package/dist/ui/Compose/UndoRedoActions.js.map +1 -1
  181. package/dist/ui/Compose/UndoRedoActions.jsx +8 -6
  182. package/dist/ui/Compose/compose.module.css +57 -17
  183. package/dist/ui/Compose/hooks/menu/itemsMap.js +13 -7
  184. package/dist/ui/Compose/hooks/menu/itemsMap.js.map +1 -1
  185. package/dist/ui/Compose/hooks/menu/useMenu.d.ts +2 -1
  186. package/dist/ui/Compose/hooks/menu/useMenu.js +28 -17
  187. package/dist/ui/Compose/hooks/menu/useMenu.js.map +1 -1
  188. package/dist/ui/Compose/hooks/menu/useMenu.jsx +27 -14
  189. package/dist/ui/Compose/hooks/useActiveFieldTracking.js +69 -10
  190. package/dist/ui/Compose/hooks/useActiveFieldTracking.js.map +1 -1
  191. package/dist/ui/Compose/hooks/useGenerate.d.ts +3 -0
  192. package/dist/ui/Compose/hooks/useGenerate.js +71 -11
  193. package/dist/ui/Compose/hooks/useGenerate.js.map +1 -1
  194. package/dist/ui/Compose/hooks/useHistory.d.ts +0 -1
  195. package/dist/ui/Compose/hooks/useHistory.js +113 -26
  196. package/dist/ui/Compose/hooks/useHistory.js.map +1 -1
  197. package/dist/ui/DynamicModelSelect/index.d.ts +7 -0
  198. package/dist/ui/DynamicModelSelect/index.js +231 -0
  199. package/dist/ui/DynamicModelSelect/index.js.map +1 -0
  200. package/dist/ui/DynamicModelSelect/index.jsx +207 -0
  201. package/dist/ui/DynamicProviderSelect/index.d.ts +7 -0
  202. package/dist/ui/DynamicProviderSelect/index.js +101 -0
  203. package/dist/ui/DynamicProviderSelect/index.js.map +1 -0
  204. package/dist/ui/DynamicProviderSelect/index.jsx +90 -0
  205. package/dist/ui/DynamicVoiceSelect/index.d.ts +7 -0
  206. package/dist/ui/DynamicVoiceSelect/index.js +156 -0
  207. package/dist/ui/DynamicVoiceSelect/index.js.map +1 -0
  208. package/dist/ui/DynamicVoiceSelect/index.jsx +102 -0
  209. package/dist/ui/EncryptedTextField/index.d.ts +8 -0
  210. package/dist/ui/EncryptedTextField/index.js +74 -0
  211. package/dist/ui/EncryptedTextField/index.js.map +1 -0
  212. package/dist/ui/EncryptedTextField/index.jsx +35 -0
  213. package/dist/ui/Icons/LottieAnimation.js +3 -1
  214. package/dist/ui/Icons/LottieAnimation.js.map +1 -1
  215. package/dist/ui/Icons/LottieAnimation.jsx +2 -1
  216. package/dist/ui/ModelRowLabel/index.d.ts +6 -0
  217. package/dist/ui/ModelRowLabel/index.js +41 -0
  218. package/dist/ui/ModelRowLabel/index.js.map +1 -0
  219. package/dist/ui/ModelRowLabel/index.jsx +26 -0
  220. package/dist/ui/ProviderOptionsEditor/index.d.ts +7 -0
  221. package/dist/ui/ProviderOptionsEditor/index.js +291 -0
  222. package/dist/ui/ProviderOptionsEditor/index.js.map +1 -0
  223. package/dist/ui/ProviderOptionsEditor/index.jsx +210 -0
  224. package/dist/ui/VoicesFetcher/index.d.ts +7 -0
  225. package/dist/ui/VoicesFetcher/index.js +118 -0
  226. package/dist/ui/VoicesFetcher/index.js.map +1 -0
  227. package/dist/ui/VoicesFetcher/index.jsx +79 -0
  228. package/dist/utilities/buildSmartPrompt.d.ts +22 -0
  229. package/dist/utilities/buildSmartPrompt.js +143 -0
  230. package/dist/utilities/buildSmartPrompt.js.map +1 -0
  231. package/dist/utilities/encryption.d.ts +2 -0
  232. package/dist/utilities/encryption.js +47 -0
  233. package/dist/utilities/encryption.js.map +1 -0
  234. package/dist/utilities/extractImageData.d.ts +9 -0
  235. package/dist/utilities/extractImageData.js +12 -2
  236. package/dist/utilities/extractImageData.js.map +1 -1
  237. package/dist/utilities/fetchImages.d.ts +14 -0
  238. package/dist/utilities/fetchImages.js +38 -0
  239. package/dist/utilities/fetchImages.js.map +1 -0
  240. package/dist/utilities/fieldToJsonSchema.d.ts +2 -1
  241. package/dist/utilities/fieldToJsonSchema.js +66 -3
  242. package/dist/utilities/fieldToJsonSchema.js.map +1 -1
  243. package/dist/utilities/getFieldBySchemaPath.d.ts +2 -2
  244. package/dist/utilities/getFieldBySchemaPath.js +15 -0
  245. package/dist/utilities/getFieldBySchemaPath.js.map +1 -1
  246. package/dist/utilities/getProviderOptionsFields.d.ts +16 -0
  247. package/dist/utilities/getProviderOptionsFields.js +80 -0
  248. package/dist/utilities/getProviderOptionsFields.js.map +1 -0
  249. package/dist/utilities/isPluginActivated.js +1 -2
  250. package/dist/utilities/isPluginActivated.js.map +1 -1
  251. package/dist/utilities/lexicalToHTML.js.map +1 -1
  252. package/dist/utilities/resolveImageReferences.d.ts +30 -0
  253. package/dist/utilities/resolveImageReferences.js +167 -0
  254. package/dist/utilities/resolveImageReferences.js.map +1 -0
  255. package/dist/utilities/schemaConverter.d.ts +3 -0
  256. package/dist/utilities/schemaConverter.js +93 -0
  257. package/dist/utilities/schemaConverter.js.map +1 -0
  258. package/dist/utilities/setSafeLexicalState.d.ts +1 -3
  259. package/dist/utilities/setSafeLexicalState.js +1 -1
  260. package/dist/utilities/setSafeLexicalState.js.map +1 -1
  261. package/dist/utilities/updateFieldsConfig.js +27 -43
  262. package/dist/utilities/updateFieldsConfig.js.map +1 -1
  263. package/package.json +23 -24
  264. package/dist/ai/models/anthropic/index.d.ts +0 -2
  265. package/dist/ai/models/anthropic/index.js +0 -129
  266. package/dist/ai/models/anthropic/index.js.map +0 -1
  267. package/dist/ai/models/elevenLabs/generateVoice.d.ts +0 -8
  268. package/dist/ai/models/elevenLabs/generateVoice.js +0 -20
  269. package/dist/ai/models/elevenLabs/generateVoice.js.map +0 -1
  270. package/dist/ai/models/elevenLabs/index.d.ts +0 -2
  271. package/dist/ai/models/elevenLabs/index.js +0 -133
  272. package/dist/ai/models/elevenLabs/index.js.map +0 -1
  273. package/dist/ai/models/elevenLabs/voices.d.ts +0 -8
  274. package/dist/ai/models/elevenLabs/voices.js +0 -24
  275. package/dist/ai/models/elevenLabs/voices.js.map +0 -1
  276. package/dist/ai/models/generateObject.d.ts +0 -11
  277. package/dist/ai/models/generateObject.js +0 -22
  278. package/dist/ai/models/generateObject.js.map +0 -1
  279. package/dist/ai/models/google/generateImage.d.ts +0 -9
  280. package/dist/ai/models/google/generateImage.js +0 -27
  281. package/dist/ai/models/google/generateImage.js.map +0 -1
  282. package/dist/ai/models/google/index.d.ts +0 -2
  283. package/dist/ai/models/google/index.js +0 -201
  284. package/dist/ai/models/google/index.js.map +0 -1
  285. package/dist/ai/models/index.d.ts +0 -2
  286. package/dist/ai/models/index.js +0 -13
  287. package/dist/ai/models/index.js.map +0 -1
  288. package/dist/ai/models/openai/generateImage.d.ts +0 -5
  289. package/dist/ai/models/openai/generateImage.js +0 -31
  290. package/dist/ai/models/openai/generateImage.js.map +0 -1
  291. package/dist/ai/models/openai/generateVoice.d.ts +0 -6
  292. package/dist/ai/models/openai/generateVoice.js +0 -19
  293. package/dist/ai/models/openai/generateVoice.js.map +0 -1
  294. package/dist/ai/models/openai/index.d.ts +0 -2
  295. package/dist/ai/models/openai/index.js +0 -428
  296. package/dist/ai/models/openai/index.js.map +0 -1
  297. package/dist/ai/models/openai/openai.d.ts +0 -1
  298. package/dist/ai/models/openai/openai.js +0 -8
  299. package/dist/ai/models/openai/openai.js.map +0 -1
  300. package/dist/ai/utils/editImagesWithOpenAI.d.ts +0 -10
  301. package/dist/ai/utils/editImagesWithOpenAI.js +0 -37
  302. package/dist/ai/utils/editImagesWithOpenAI.js.map +0 -1
  303. package/dist/styles.d.js +0 -2
  304. package/dist/styles.d.js.map +0 -1
  305. package/dist/types/handlebars-async-helpers.d.js +0 -2
  306. package/dist/types/handlebars-async-helpers.d.js.map +0 -1
  307. package/dist/types/handlebars-dist-handlebars.d.js +0 -2
  308. package/dist/types/handlebars-dist-handlebars.d.js.map +0 -1
  309. package/dist/types/react-mentions.d.js +0 -2
  310. package/dist/types/react-mentions.d.js.map +0 -1
  311. package/dist/utilities/getGenerationModels.d.ts +0 -2
  312. package/dist/utilities/getGenerationModels.js +0 -10
  313. package/dist/utilities/getGenerationModels.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { FieldDescription, FieldLabel, useField } from '@payloadcms/ui';
3
+ import { FieldDescription, FieldLabel, useConfig, useField } from '@payloadcms/ui';
4
4
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
5
5
  import { Mention, MentionsInput } from 'react-mentions/dist/react-mentions.cjs.js';
6
6
  import { useInstructions } from '../../providers/InstructionsProvider/useInstructions.js';
@@ -12,13 +12,141 @@ export const PromptEditorField = (props)=>{
12
12
  });
13
13
  const [localValue, setLocalValue] = useState(payloadValue || '');
14
14
  const hasInitialized = useRef(false);
15
- const { promptEditorSuggestions } = useInstructions();
15
+ const { activeCollection, promptEditorSuggestions } = useInstructions();
16
+ const { config } = useConfig();
16
17
  const suggestions = useMemo(()=>promptEditorSuggestions.map((suggestion)=>({
17
18
  id: suggestion,
18
19
  display: suggestion
19
20
  })), [
20
21
  promptEditorSuggestions
21
22
  ]);
23
+ // Extract document ID from URL if available (to get specific filenames)
24
+ const [documentData, setDocumentData] = useState(null);
25
+ useEffect(()=>{
26
+ // Only run in browser
27
+ if (typeof window === 'undefined') {
28
+ return;
29
+ }
30
+ // Allow time for verify window.location is stable (unlikely to change but good practice)
31
+ const segments = window.location.pathname.split('/');
32
+ const collectionsIndex = segments.indexOf('collections');
33
+ if (collectionsIndex > -1 && segments.length > collectionsIndex + 2) {
34
+ const urlCollectionSlug = segments[collectionsIndex + 1];
35
+ const urlId = segments[collectionsIndex + 2];
36
+ // Only fetch if we are editing instructions for the same collection we are viewing
37
+ // and we haven't fetched yet (or ID changed)
38
+ if (urlCollectionSlug === activeCollection && urlId && urlId !== 'create') {
39
+ const fetchDocument = async ()=>{
40
+ try {
41
+ const response = await fetch(`${String(config.serverURL)}${String(config.routes.api)}/${String(urlCollectionSlug)}/${String(urlId)}`);
42
+ if (response.ok) {
43
+ const data = await response.json();
44
+ setDocumentData(data);
45
+ }
46
+ } catch (_err) {
47
+ // Ignore error
48
+ }
49
+ };
50
+ void fetchDocument();
51
+ }
52
+ }
53
+ }, [
54
+ activeCollection,
55
+ config
56
+ ]);
57
+ // Extract all upload fields from the current collection schema
58
+ const imageFieldSuggestions = useMemo(()=>{
59
+ const suggestions = [];
60
+ // Use activeCollection from context which holds the target collection slug
61
+ const targetSlug = activeCollection;
62
+ if (!targetSlug || !config?.collections) {
63
+ return [];
64
+ }
65
+ const collection = config.collections.find((c)=>c.slug === targetSlug);
66
+ if (!collection?.fields) {
67
+ return [];
68
+ }
69
+ const uploadFields = [];
70
+ // Recursive function to find upload fields
71
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
+ const findUploadFields = (fields, prefix = '')=>{
73
+ for (const field of fields){
74
+ if (field.type === 'upload' && field.name) {
75
+ const fieldPath = prefix ? `${prefix}.${String(field.name)}` : String(field.name);
76
+ uploadFields.push({
77
+ name: fieldPath,
78
+ hasMany: field.hasMany === true
79
+ });
80
+ }
81
+ // Check nested fields in groups, arrays, etc.
82
+ if (field.fields && Array.isArray(field.fields)) {
83
+ const newPrefix = field.name ? prefix ? `${prefix}.${String(field.name)}` : String(field.name) : prefix;
84
+ findUploadFields(field.fields, newPrefix);
85
+ }
86
+ }
87
+ };
88
+ findUploadFields(collection.fields);
89
+ // Add generic field names (base suggestions) - ONLY for single uploads (not hasMany arrays)
90
+ uploadFields.forEach(({ name, hasMany })=>{
91
+ // User requested to hide the array itself for hasMany fields
92
+ if (!hasMany) {
93
+ suggestions.push({
94
+ id: name,
95
+ display: name
96
+ });
97
+ }
98
+ });
99
+ // If we have document data, add specific filename suggestions
100
+ if (documentData) {
101
+ uploadFields.forEach(({ name, hasMany })=>{
102
+ const value = documentData[name] // Note: nested access logic simplified for now
103
+ ;
104
+ // Helper to extract filename from media doc (which might be ID or object)
105
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
106
+ const getFilename = (item)=>{
107
+ if (typeof item === 'object' && item && (item.filename || item.name)) {
108
+ return item.filename || item.name;
109
+ }
110
+ // If it's just an ID, we can't show filename without populating.
111
+ // Assuming compose view usually fetches with depth > 0 or we rely on what we have.
112
+ return null;
113
+ };
114
+ if (value) {
115
+ if (hasMany && Array.isArray(value)) {
116
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
117
+ value.forEach((item)=>{
118
+ const fname = getFilename(item);
119
+ if (fname) {
120
+ const suggestion = `${name}:${fname}`;
121
+ suggestions.push({
122
+ id: suggestion,
123
+ display: suggestion
124
+ });
125
+ }
126
+ });
127
+ } else if (!hasMany) {
128
+ // Single image - we already added the base name above.
129
+ // We can optionally add the specific filename too if desired,
130
+ // but user request focused on arrays.
131
+ // Adding the specific filename option for Single images too as it's explicit.
132
+ const fname = getFilename(value);
133
+ if (fname) {
134
+ const suggestion = `${name}:${fname}`;
135
+ suggestions.push({
136
+ id: suggestion,
137
+ display: suggestion
138
+ });
139
+ }
140
+ }
141
+ }
142
+ });
143
+ }
144
+ return suggestions;
145
+ }, [
146
+ activeCollection,
147
+ config,
148
+ documentData
149
+ ]);
22
150
  useEffect(()=>{
23
151
  if (!hasInitialized.current || payloadValue === '') {
24
152
  setLocalValue(payloadValue || '');
@@ -28,8 +156,13 @@ export const PromptEditorField = (props)=>{
28
156
  payloadValue
29
157
  ]);
30
158
  const handleChange = useCallback((e)=>{
31
- setLocalValue(e.target.value);
32
- }, []);
159
+ const newValue = e.target.value;
160
+ setLocalValue(newValue);
161
+ // Also update Payload value immediately to prevent loss when Save is clicked
162
+ setValue(newValue);
163
+ }, [
164
+ setValue
165
+ ]);
33
166
  const handleBlur = useCallback(()=>{
34
167
  setValue(localValue);
35
168
  }, [
@@ -37,28 +170,41 @@ export const PromptEditorField = (props)=>{
37
170
  setValue
38
171
  ]);
39
172
  const displayTransform = useCallback((id)=>`{{ ${id} }}`, []);
173
+ const imageDisplayTransform = useCallback((id)=>`@${id}`, []);
40
174
  return /*#__PURE__*/ _jsxs("div", {
41
175
  className: "field-type textarea",
42
176
  children: [
43
177
  /*#__PURE__*/ _jsx(FieldLabel, {
44
178
  label: field.label
45
179
  }),
46
- /*#__PURE__*/ _jsx(MentionsInput, {
180
+ /*#__PURE__*/ _jsxs(MentionsInput, {
47
181
  onBlur: handleBlur,
48
182
  onChange: handleChange,
49
- placeholder: "Type your prompt using {{ fieldName }} variables...",
183
+ placeholder: "Type {{ for fields }} or @imageField for images. For specific images use @imageField:filename.jpg",
50
184
  style: defaultStyle,
51
185
  value: localValue,
52
- children: /*#__PURE__*/ _jsx(Mention, {
53
- data: suggestions,
54
- displayTransform: displayTransform,
55
- markup: "{{__id__}}",
56
- style: {
57
- backgroundColor: 'var(--theme-elevation-100)',
58
- padding: '2px 0'
59
- },
60
- trigger: "{"
61
- })
186
+ children: [
187
+ /*#__PURE__*/ _jsx(Mention, {
188
+ data: suggestions,
189
+ displayTransform: displayTransform,
190
+ markup: "{{__id__}}",
191
+ style: {
192
+ backgroundColor: 'var(--theme-elevation-100)',
193
+ padding: '2px 0'
194
+ },
195
+ trigger: "{"
196
+ }),
197
+ /*#__PURE__*/ _jsx(Mention, {
198
+ data: imageFieldSuggestions,
199
+ displayTransform: imageDisplayTransform,
200
+ markup: "@__id__",
201
+ style: {
202
+ backgroundColor: 'var(--theme-elevation-150)',
203
+ padding: '2px 0'
204
+ },
205
+ trigger: "@"
206
+ })
207
+ ]
62
208
  }),
63
209
  /*#__PURE__*/ _jsx(FieldDescription, {
64
210
  description: field?.admin?.description,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/fields/PromptEditorField/PromptEditorField.tsx"],"sourcesContent":["'use client'\n\nimport type { TextareaFieldClientProps } from 'payload'\n\nimport { FieldDescription, FieldLabel, useField } from '@payloadcms/ui'\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { Mention, MentionsInput } from 'react-mentions/dist/react-mentions.cjs.js'\n\nimport { useInstructions } from '../../providers/InstructionsProvider/useInstructions.js'\nimport { defaultStyle } from './defaultStyle.js'\n\nexport const PromptEditorField: React.FC<TextareaFieldClientProps> = (props) => {\n const { field, path: pathFromContext } = props\n const { setValue, value: payloadValue } = useField<string>({\n path: pathFromContext,\n })\n\n const [localValue, setLocalValue] = useState(payloadValue || '')\n const hasInitialized = useRef(false)\n\n const { promptEditorSuggestions } = useInstructions()\n\n const suggestions = useMemo(\n () =>\n promptEditorSuggestions.map((suggestion: string) => ({\n id: suggestion,\n display: suggestion,\n })),\n [promptEditorSuggestions],\n )\n\n useEffect(() => {\n if (!hasInitialized.current || payloadValue === '') {\n setLocalValue(payloadValue || '')\n hasInitialized.current = true\n }\n }, [payloadValue])\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setLocalValue(e.target.value)\n }, [])\n\n const handleBlur = useCallback(() => {\n setValue(localValue)\n }, [localValue, setValue])\n\n const displayTransform = useCallback((id: string) => `{{ ${id} }}`, [])\n\n return (\n <div className=\"field-type textarea\">\n <FieldLabel label={field.label} />\n <MentionsInput\n onBlur={handleBlur}\n onChange={handleChange}\n placeholder=\"Type your prompt using {{ fieldName }} variables...\"\n style={defaultStyle}\n value={localValue}\n >\n <Mention\n data={suggestions}\n displayTransform={displayTransform}\n markup=\"{{__id__}}\"\n style={{\n backgroundColor: 'var(--theme-elevation-100)',\n padding: '2px 0',\n }}\n trigger=\"{\"\n />\n </MentionsInput>\n <FieldDescription description={field?.admin?.description} path=\"\" />\n </div>\n )\n}\n"],"names":["FieldDescription","FieldLabel","useField","React","useCallback","useEffect","useMemo","useRef","useState","Mention","MentionsInput","useInstructions","defaultStyle","PromptEditorField","props","field","path","pathFromContext","setValue","value","payloadValue","localValue","setLocalValue","hasInitialized","promptEditorSuggestions","suggestions","map","suggestion","id","display","current","handleChange","e","target","handleBlur","displayTransform","div","className","label","onBlur","onChange","placeholder","style","data","markup","backgroundColor","padding","trigger","description","admin"],"mappings":"AAAA;;AAIA,SAASA,gBAAgB,EAAEC,UAAU,EAAEC,QAAQ,QAAQ,iBAAgB;AACvE,OAAOC,SAASC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAO;AAChF,SAASC,OAAO,EAAEC,aAAa,QAAQ,4CAA2C;AAElF,SAASC,eAAe,QAAQ,0DAAyD;AACzF,SAASC,YAAY,QAAQ,oBAAmB;AAEhD,OAAO,MAAMC,oBAAwD,CAACC;IACpE,MAAM,EAAEC,KAAK,EAAEC,MAAMC,eAAe,EAAE,GAAGH;IACzC,MAAM,EAAEI,QAAQ,EAAEC,OAAOC,YAAY,EAAE,GAAGlB,SAAiB;QACzDc,MAAMC;IACR;IAEA,MAAM,CAACI,YAAYC,cAAc,GAAGd,SAASY,gBAAgB;IAC7D,MAAMG,iBAAiBhB,OAAO;IAE9B,MAAM,EAAEiB,uBAAuB,EAAE,GAAGb;IAEpC,MAAMc,cAAcnB,QAClB,IACEkB,wBAAwBE,GAAG,CAAC,CAACC,aAAwB,CAAA;gBACnDC,IAAID;gBACJE,SAASF;YACX,CAAA,IACF;QAACH;KAAwB;IAG3BnB,UAAU;QACR,IAAI,CAACkB,eAAeO,OAAO,IAAIV,iBAAiB,IAAI;YAClDE,cAAcF,gBAAgB;YAC9BG,eAAeO,OAAO,GAAG;QAC3B;IACF,GAAG;QAACV;KAAa;IAEjB,MAAMW,eAAe3B,YAAY,CAAC4B;QAChCV,cAAcU,EAAEC,MAAM,CAACd,KAAK;IAC9B,GAAG,EAAE;IAEL,MAAMe,aAAa9B,YAAY;QAC7Bc,SAASG;IACX,GAAG;QAACA;QAAYH;KAAS;IAEzB,MAAMiB,mBAAmB/B,YAAY,CAACwB,KAAe,CAAC,GAAG,EAAEA,GAAG,GAAG,CAAC,EAAE,EAAE;IAEtE,qBACE,MAACQ;QAAIC,WAAU;;0BACb,KAACpC;gBAAWqC,OAAOvB,MAAMuB,KAAK;;0BAC9B,KAAC5B;gBACC6B,QAAQL;gBACRM,UAAUT;gBACVU,aAAY;gBACZC,OAAO9B;gBACPO,OAAOE;0BAEP,cAAA,KAACZ;oBACCkC,MAAMlB;oBACNU,kBAAkBA;oBAClBS,QAAO;oBACPF,OAAO;wBACLG,iBAAiB;wBACjBC,SAAS;oBACX;oBACAC,SAAQ;;;0BAGZ,KAAC/C;gBAAiBgD,aAAajC,OAAOkC,OAAOD;gBAAahC,MAAK;;;;AAGrE,EAAC"}
1
+ {"version":3,"sources":["../../../src/fields/PromptEditorField/PromptEditorField.tsx"],"sourcesContent":["'use client'\n\nimport type { TextareaFieldClientProps } from 'payload'\n\nimport { FieldDescription, FieldLabel, useConfig, useField } from '@payloadcms/ui'\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { Mention, MentionsInput } from 'react-mentions/dist/react-mentions.cjs.js'\n\nimport { useInstructions } from '../../providers/InstructionsProvider/useInstructions.js'\nimport { defaultStyle } from './defaultStyle.js'\n\nexport const PromptEditorField: React.FC<TextareaFieldClientProps> = (props) => {\n const { field, path: pathFromContext } = props\n const { setValue, value: payloadValue } = useField<string>({\n path: pathFromContext,\n })\n\n const [localValue, setLocalValue] = useState(payloadValue || '')\n const hasInitialized = useRef(false)\n\n const { activeCollection, promptEditorSuggestions } = useInstructions()\n const { config } = useConfig()\n\n const suggestions = useMemo(\n () =>\n promptEditorSuggestions.map((suggestion: string) => ({\n id: suggestion,\n display: suggestion,\n })),\n [promptEditorSuggestions],\n )\n\n // Extract document ID from URL if available (to get specific filenames)\n const [documentData, setDocumentData] = useState<null | Record<string, unknown>>(null)\n \n useEffect(() => {\n // Only run in browser\n if (typeof window === 'undefined') {\n return\n }\n\n // Allow time for verify window.location is stable (unlikely to change but good practice)\n const segments = window.location.pathname.split('/')\n const collectionsIndex = segments.indexOf('collections')\n \n if (collectionsIndex > -1 && segments.length > collectionsIndex + 2) {\n const urlCollectionSlug = segments[collectionsIndex + 1]\n const urlId = segments[collectionsIndex + 2]\n\n // Only fetch if we are editing instructions for the same collection we are viewing\n // and we haven't fetched yet (or ID changed)\n if (urlCollectionSlug === activeCollection && urlId && urlId !== 'create') {\n const fetchDocument = async () => {\n try {\n \n const response = await fetch(`${String(config.serverURL)}${String(config.routes.api)}/${String(urlCollectionSlug)}/${String(urlId)}`)\n if (response.ok) {\n const data = await response.json()\n setDocumentData(data)\n }\n } catch (_err) {\n // Ignore error\n }\n }\n void fetchDocument()\n }\n }\n }, [activeCollection, config])\n\n // Extract all upload fields from the current collection schema\n const imageFieldSuggestions = useMemo(() => {\n const suggestions: { display: string; id: string }[] = []\n \n // Use activeCollection from context which holds the target collection slug\n const targetSlug = activeCollection\n \n if (!targetSlug || !config?.collections) {\n return []\n }\n\n const collection = config.collections.find((c) => c.slug === targetSlug)\n if (!collection?.fields) {\n return []\n }\n\n const uploadFields: { hasMany: boolean; name: string }[] = []\n\n // Recursive function to find upload fields\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const findUploadFields = (fields: any[], prefix = ''): void => {\n for (const field of fields) {\n if (field.type === 'upload' && field.name) {\n const fieldPath = prefix ? `${prefix}.${String(field.name)}` : String(field.name)\n uploadFields.push({ name: fieldPath, hasMany: field.hasMany === true })\n }\n // Check nested fields in groups, arrays, etc.\n if (field.fields && Array.isArray(field.fields)) {\n const newPrefix = field.name ? (prefix ? `${prefix}.${String(field.name)}` : String(field.name)) : prefix\n findUploadFields(field.fields, newPrefix)\n }\n }\n }\n\n findUploadFields(collection.fields)\n \n // Add generic field names (base suggestions) - ONLY for single uploads (not hasMany arrays)\n uploadFields.forEach(({ name, hasMany }) => {\n // User requested to hide the array itself for hasMany fields\n if (!hasMany) {\n suggestions.push({ id: name, display: name })\n }\n })\n\n // If we have document data, add specific filename suggestions\n if (documentData) {\n uploadFields.forEach(({ name, hasMany }) => {\n const value = documentData[name] // Note: nested access logic simplified for now\n \n // Helper to extract filename from media doc (which might be ID or object)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const getFilename = (item: any): null | string => {\n if (typeof item === 'object' && item && (item.filename || item.name)) {\n return item.filename || item.name\n }\n // If it's just an ID, we can't show filename without populating. \n // Assuming compose view usually fetches with depth > 0 or we rely on what we have.\n return null\n }\n\n if (value) {\n if (hasMany && Array.isArray(value)) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n value.forEach((item: any) => {\n const fname = getFilename(item)\n if (fname) {\n const suggestion = `${name}:${fname}`\n suggestions.push({ id: suggestion, display: suggestion })\n }\n })\n } else if (!hasMany) {\n // Single image - we already added the base name above.\n // We can optionally add the specific filename too if desired, \n // but user request focused on arrays.\n // Adding the specific filename option for Single images too as it's explicit.\n const fname = getFilename(value)\n if (fname) {\n const suggestion = `${name}:${fname}`\n suggestions.push({ id: suggestion, display: suggestion })\n }\n }\n }\n })\n }\n \n return suggestions\n }, [activeCollection, config, documentData])\n\n useEffect(() => {\n if (!hasInitialized.current || payloadValue === '') {\n setLocalValue(payloadValue || '')\n hasInitialized.current = true\n }\n }, [payloadValue])\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const newValue = e.target.value\n setLocalValue(newValue)\n // Also update Payload value immediately to prevent loss when Save is clicked\n setValue(newValue)\n }, [setValue])\n\n const handleBlur = useCallback(() => {\n setValue(localValue)\n }, [localValue, setValue])\n\n const displayTransform = useCallback((id: string) => `{{ ${id} }}`, [])\n const imageDisplayTransform = useCallback((id: string) => `@${id}`, [])\n\n return (\n <div className=\"field-type textarea\">\n <FieldLabel label={field.label} />\n <MentionsInput\n onBlur={handleBlur}\n onChange={handleChange}\n placeholder=\"Type {{ for fields }} or @imageField for images. For specific images use @imageField:filename.jpg\"\n style={defaultStyle}\n value={localValue}\n >\n <Mention\n data={suggestions}\n displayTransform={displayTransform}\n markup=\"{{__id__}}\"\n style={{\n backgroundColor: 'var(--theme-elevation-100)',\n padding: '2px 0',\n }}\n trigger=\"{\"\n />\n <Mention\n data={imageFieldSuggestions}\n displayTransform={imageDisplayTransform}\n markup=\"@__id__\"\n style={{\n backgroundColor: 'var(--theme-elevation-150)',\n padding: '2px 0',\n }}\n trigger=\"@\"\n />\n </MentionsInput>\n <FieldDescription description={field?.admin?.description} path=\"\" />\n </div>\n )\n}\n"],"names":["FieldDescription","FieldLabel","useConfig","useField","React","useCallback","useEffect","useMemo","useRef","useState","Mention","MentionsInput","useInstructions","defaultStyle","PromptEditorField","props","field","path","pathFromContext","setValue","value","payloadValue","localValue","setLocalValue","hasInitialized","activeCollection","promptEditorSuggestions","config","suggestions","map","suggestion","id","display","documentData","setDocumentData","window","segments","location","pathname","split","collectionsIndex","indexOf","length","urlCollectionSlug","urlId","fetchDocument","response","fetch","String","serverURL","routes","api","ok","data","json","_err","imageFieldSuggestions","targetSlug","collections","collection","find","c","slug","fields","uploadFields","findUploadFields","prefix","type","name","fieldPath","push","hasMany","Array","isArray","newPrefix","forEach","getFilename","item","filename","fname","current","handleChange","e","newValue","target","handleBlur","displayTransform","imageDisplayTransform","div","className","label","onBlur","onChange","placeholder","style","markup","backgroundColor","padding","trigger","description","admin"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { FieldDescription, FieldLabel, useField } from '@payloadcms/ui';
2
+ import { FieldDescription, FieldLabel, useConfig, useField } from '@payloadcms/ui';
3
3
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { Mention, MentionsInput } from 'react-mentions/dist/react-mentions.cjs.js';
5
5
  import { useInstructions } from '../../providers/InstructionsProvider/useInstructions.js';
@@ -11,11 +11,121 @@ export const PromptEditorField = (props) => {
11
11
  });
12
12
  const [localValue, setLocalValue] = useState(payloadValue || '');
13
13
  const hasInitialized = useRef(false);
14
- const { promptEditorSuggestions } = useInstructions();
14
+ const { activeCollection, promptEditorSuggestions } = useInstructions();
15
+ const { config } = useConfig();
15
16
  const suggestions = useMemo(() => promptEditorSuggestions.map((suggestion) => ({
16
17
  id: suggestion,
17
18
  display: suggestion,
18
19
  })), [promptEditorSuggestions]);
20
+ // Extract document ID from URL if available (to get specific filenames)
21
+ const [documentData, setDocumentData] = useState(null);
22
+ useEffect(() => {
23
+ // Only run in browser
24
+ if (typeof window === 'undefined') {
25
+ return;
26
+ }
27
+ // Allow time for verify window.location is stable (unlikely to change but good practice)
28
+ const segments = window.location.pathname.split('/');
29
+ const collectionsIndex = segments.indexOf('collections');
30
+ if (collectionsIndex > -1 && segments.length > collectionsIndex + 2) {
31
+ const urlCollectionSlug = segments[collectionsIndex + 1];
32
+ const urlId = segments[collectionsIndex + 2];
33
+ // Only fetch if we are editing instructions for the same collection we are viewing
34
+ // and we haven't fetched yet (or ID changed)
35
+ if (urlCollectionSlug === activeCollection && urlId && urlId !== 'create') {
36
+ const fetchDocument = async () => {
37
+ try {
38
+ const response = await fetch(`${String(config.serverURL)}${String(config.routes.api)}/${String(urlCollectionSlug)}/${String(urlId)}`);
39
+ if (response.ok) {
40
+ const data = await response.json();
41
+ setDocumentData(data);
42
+ }
43
+ }
44
+ catch (_err) {
45
+ // Ignore error
46
+ }
47
+ };
48
+ void fetchDocument();
49
+ }
50
+ }
51
+ }, [activeCollection, config]);
52
+ // Extract all upload fields from the current collection schema
53
+ const imageFieldSuggestions = useMemo(() => {
54
+ const suggestions = [];
55
+ // Use activeCollection from context which holds the target collection slug
56
+ const targetSlug = activeCollection;
57
+ if (!targetSlug || !config?.collections) {
58
+ return [];
59
+ }
60
+ const collection = config.collections.find((c) => c.slug === targetSlug);
61
+ if (!collection?.fields) {
62
+ return [];
63
+ }
64
+ const uploadFields = [];
65
+ // Recursive function to find upload fields
66
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
+ const findUploadFields = (fields, prefix = '') => {
68
+ for (const field of fields) {
69
+ if (field.type === 'upload' && field.name) {
70
+ const fieldPath = prefix ? `${prefix}.${String(field.name)}` : String(field.name);
71
+ uploadFields.push({ name: fieldPath, hasMany: field.hasMany === true });
72
+ }
73
+ // Check nested fields in groups, arrays, etc.
74
+ if (field.fields && Array.isArray(field.fields)) {
75
+ const newPrefix = field.name ? (prefix ? `${prefix}.${String(field.name)}` : String(field.name)) : prefix;
76
+ findUploadFields(field.fields, newPrefix);
77
+ }
78
+ }
79
+ };
80
+ findUploadFields(collection.fields);
81
+ // Add generic field names (base suggestions) - ONLY for single uploads (not hasMany arrays)
82
+ uploadFields.forEach(({ name, hasMany }) => {
83
+ // User requested to hide the array itself for hasMany fields
84
+ if (!hasMany) {
85
+ suggestions.push({ id: name, display: name });
86
+ }
87
+ });
88
+ // If we have document data, add specific filename suggestions
89
+ if (documentData) {
90
+ uploadFields.forEach(({ name, hasMany }) => {
91
+ const value = documentData[name]; // Note: nested access logic simplified for now
92
+ // Helper to extract filename from media doc (which might be ID or object)
93
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
+ const getFilename = (item) => {
95
+ if (typeof item === 'object' && item && (item.filename || item.name)) {
96
+ return item.filename || item.name;
97
+ }
98
+ // If it's just an ID, we can't show filename without populating.
99
+ // Assuming compose view usually fetches with depth > 0 or we rely on what we have.
100
+ return null;
101
+ };
102
+ if (value) {
103
+ if (hasMany && Array.isArray(value)) {
104
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
+ value.forEach((item) => {
106
+ const fname = getFilename(item);
107
+ if (fname) {
108
+ const suggestion = `${name}:${fname}`;
109
+ suggestions.push({ id: suggestion, display: suggestion });
110
+ }
111
+ });
112
+ }
113
+ else if (!hasMany) {
114
+ // Single image - we already added the base name above.
115
+ // We can optionally add the specific filename too if desired,
116
+ // but user request focused on arrays.
117
+ // Adding the specific filename option for Single images too as it's explicit.
118
+ const fname = getFilename(value);
119
+ if (fname) {
120
+ const suggestion = `${name}:${fname}`;
121
+ suggestions.push({ id: suggestion, display: suggestion });
122
+ }
123
+ }
124
+ }
125
+ });
126
+ }
127
+ return suggestions;
128
+ }, [activeCollection, config, documentData]);
19
129
  useEffect(() => {
20
130
  if (!hasInitialized.current || payloadValue === '') {
21
131
  setLocalValue(payloadValue || '');
@@ -23,19 +133,27 @@ export const PromptEditorField = (props) => {
23
133
  }
24
134
  }, [payloadValue]);
25
135
  const handleChange = useCallback((e) => {
26
- setLocalValue(e.target.value);
27
- }, []);
136
+ const newValue = e.target.value;
137
+ setLocalValue(newValue);
138
+ // Also update Payload value immediately to prevent loss when Save is clicked
139
+ setValue(newValue);
140
+ }, [setValue]);
28
141
  const handleBlur = useCallback(() => {
29
142
  setValue(localValue);
30
143
  }, [localValue, setValue]);
31
144
  const displayTransform = useCallback((id) => `{{ ${id} }}`, []);
145
+ const imageDisplayTransform = useCallback((id) => `@${id}`, []);
32
146
  return (<div className="field-type textarea">
33
147
  <FieldLabel label={field.label}/>
34
- <MentionsInput onBlur={handleBlur} onChange={handleChange} placeholder="Type your prompt using {{ fieldName }} variables..." style={defaultStyle} value={localValue}>
148
+ <MentionsInput onBlur={handleBlur} onChange={handleChange} placeholder="Type {{ for fields }} or @imageField for images. For specific images use @imageField:filename.jpg" style={defaultStyle} value={localValue}>
35
149
  <Mention data={suggestions} displayTransform={displayTransform} markup="{{__id__}}" style={{
36
150
  backgroundColor: 'var(--theme-elevation-100)',
37
151
  padding: '2px 0',
38
152
  }} trigger="{"/>
153
+ <Mention data={imageFieldSuggestions} displayTransform={imageDisplayTransform} markup="@__id__" style={{
154
+ backgroundColor: 'var(--theme-elevation-150)',
155
+ padding: '2px 0',
156
+ }} trigger="@"/>
39
157
  </MentionsInput>
40
158
  <FieldDescription description={field?.admin?.description} path=""/>
41
159
  </div>);
package/dist/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ export type { GenerateArgs } from './ai/index.js';
1
2
  export { defaultPrompts, defaultSeedPrompts } from './ai/prompts.js';
2
3
  export { PayloadAiPluginLexicalEditorFeature } from './fields/LexicalEditor/feature.server.js';
4
+ export type {} from './payload-ai.d.ts';
3
5
  export { payloadAiPlugin } from './plugin.js';
6
+ export { fieldToJsonSchema } from './utilities/fieldToJsonSchema.js';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { defaultPrompts, defaultSeedPrompts } from './ai/prompts.js';
2
2
  export { PayloadAiPluginLexicalEditorFeature } from './fields/LexicalEditor/feature.server.js';
3
3
  export { payloadAiPlugin } from './plugin.js';
4
+ export { fieldToJsonSchema } from './utilities/fieldToJsonSchema.js';
4
5
 
5
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { defaultPrompts, defaultSeedPrompts } from './ai/prompts.js'\n\nexport { PayloadAiPluginLexicalEditorFeature } from './fields/LexicalEditor/feature.server.js'\nexport { payloadAiPlugin } from './plugin.js'\n"],"names":["defaultPrompts","defaultSeedPrompts","PayloadAiPluginLexicalEditorFeature","payloadAiPlugin"],"mappings":"AAAA,SAASA,cAAc,EAAEC,kBAAkB,QAAQ,kBAAiB;AAEpE,SAASC,mCAAmC,QAAQ,2CAA0C;AAC9F,SAASC,eAAe,QAAQ,cAAa"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type { GenerateArgs } from './ai/index.js'\n\nexport { defaultPrompts, defaultSeedPrompts } from './ai/prompts.js'\n\nexport { PayloadAiPluginLexicalEditorFeature } from './fields/LexicalEditor/feature.server.js'\n// Re-export to ensure payload.ai module augmentation is included\nexport type {} from './payload-ai.d.ts'\n\nexport { payloadAiPlugin } from './plugin.js'\nexport { fieldToJsonSchema } from './utilities/fieldToJsonSchema.js'\n"],"names":["defaultPrompts","defaultSeedPrompts","PayloadAiPluginLexicalEditorFeature","payloadAiPlugin","fieldToJsonSchema"],"mappings":"AAEA,SAASA,cAAc,EAAEC,kBAAkB,QAAQ,kBAAiB;AAEpE,SAASC,mCAAmC,QAAQ,2CAA0C;AAI9F,SAASC,eAAe,QAAQ,cAAa;AAC7C,SAASC,iBAAiB,QAAQ,mCAAkC"}
package/dist/init.js CHANGED
@@ -1,7 +1,33 @@
1
1
  import { defaultSeedPrompts } from './ai/prompts.js';
2
- import { systemGenerate } from './ai/utils/systemGenerate.js';
3
2
  import { PLUGIN_INSTRUCTIONS_TABLE } from './defaults.js';
4
- import { getGenerationModels } from './utilities/getGenerationModels.js';
3
+ // Defined capabilities mapping for init
4
+ const CAPABILITY_MAP = [
5
+ {
6
+ id: 'text',
7
+ fields: [
8
+ 'text',
9
+ 'textarea'
10
+ ]
11
+ },
12
+ {
13
+ id: 'richtext',
14
+ fields: [
15
+ 'richText'
16
+ ]
17
+ },
18
+ {
19
+ id: 'image',
20
+ fields: [
21
+ 'upload'
22
+ ]
23
+ },
24
+ {
25
+ id: 'array',
26
+ fields: [
27
+ 'array'
28
+ ]
29
+ }
30
+ ];
5
31
  export const init = async (payload, fieldSchemaPaths, pluginConfig)=>{
6
32
  if (!pluginConfig.generatePromptOnInit) {
7
33
  return;
@@ -10,20 +36,14 @@ export const init = async (payload, fieldSchemaPaths, pluginConfig)=>{
10
36
  payload.logger.info(`— AI Plugin: Initializing...`);
11
37
  }
12
38
  const paths = Object.keys(fieldSchemaPaths);
13
- // Note: schema-path is globally unique, so we create one entry per path regardless of localization
14
- // Localization info is kept for potential future use or debugging
15
- const _isLocalized = pluginConfig._localization?.enabled && pluginConfig._localization.locales.length > 0;
16
- const _locales = pluginConfig._localization?.locales || [];
17
39
  // Get all instructions for faster initialization
18
- // Query with locale: 'all' to get entries from all locales when localization is enabled
19
40
  const { docs: allInstructions } = await payload.find({
20
41
  collection: PLUGIN_INSTRUCTIONS_TABLE,
21
42
  depth: 0,
22
- locale: 'all',
23
43
  pagination: false,
24
44
  select: {
25
- id: true,
26
45
  'field-type': true,
46
+ 'model-id': true,
27
47
  'schema-path': true
28
48
  }
29
49
  });
@@ -31,7 +51,6 @@ export const init = async (payload, fieldSchemaPaths, pluginConfig)=>{
31
51
  for(let i = 0; i < paths.length; i++){
32
52
  const path = paths[i];
33
53
  const { type: fieldType, label: fieldLabel, relationTo } = fieldSchemaPaths[path];
34
- // Find existing entry for this path (schema-path is globally unique, not per locale)
35
54
  let instructions = allInstructions.find((entry)=>entry['schema-path'] === path);
36
55
  if (!instructions) {
37
56
  let seed;
@@ -54,18 +73,21 @@ export const init = async (payload, fieldSchemaPaths, pluginConfig)=>{
54
73
  }
55
74
  continue;
56
75
  }
57
- let generatedPrompt = '{{ title }}';
76
+ // Empty prompt - smart fallback will generate a contextual prompt at runtime
77
+ const generatedPrompt = '';
58
78
  if ('prompt' in seed) {
59
- // find the model that has the generateText function
60
- const models = getGenerationModels(pluginConfig);
61
- const model = models && Array.isArray(models) ? models.find((model)=>model.generateText) : undefined;
62
- generatedPrompt = await systemGenerate({
63
- prompt: seed.prompt,
64
- system: seed.system
65
- }, model?.generateText);
66
- }
67
- const modelsForId = getGenerationModels(pluginConfig);
68
- const modelForId = modelsForId && Array.isArray(modelsForId) ? modelsForId.find((a)=>a.fields.includes(fieldType)) : undefined;
79
+ // Prompt generation currently disabled during migration to AI SDK Providers
80
+ // TODO: Re-enable using a default provider from AI Settings if available
81
+ /*
82
+ generatedPrompt = await systemGenerate(
83
+ {
84
+ prompt: seed.prompt,
85
+ system: seed.system,
86
+ },
87
+ undefined // No generateTextFn currently
88
+ )
89
+ */ }
90
+ const modelForId = CAPABILITY_MAP.find((a)=>a.fields.includes(fieldType));
69
91
  const data = {
70
92
  'model-id': modelForId?.id,
71
93
  prompt: generatedPrompt,
@@ -79,44 +101,12 @@ export const init = async (payload, fieldSchemaPaths, pluginConfig)=>{
79
101
  prompt: generatedPrompt,
80
102
  ...seed.data
81
103
  }, `Prompt seeded for "${path}" field`);
82
- try {
83
- instructions = await payload.create({
84
- collection: PLUGIN_INSTRUCTIONS_TABLE,
85
- data
86
- });
87
- } catch (err) {
88
- // Handle unique constraint violation - entry might already exist for another locale
89
- const error = err;
90
- if (error?.name === 'ValidationError' && error?.data?.errors?.some((e)=>e.path === 'schema-path')) {
91
- // Try to find the existing entry across all locales
92
- const { docs } = await payload.find({
93
- collection: PLUGIN_INSTRUCTIONS_TABLE,
94
- limit: 1,
95
- locale: 'all',
96
- select: {
97
- id: true,
98
- 'field-type': true,
99
- 'schema-path': true
100
- },
101
- where: {
102
- 'schema-path': {
103
- equals: path
104
- }
105
- }
106
- });
107
- const existingEntry = docs[0];
108
- if (existingEntry) {
109
- instructions = existingEntry;
110
- if (pluginConfig.debugging) {
111
- payload.logger.info(`— AI Plugin: Entry already exists for ${path}, using existing entry`);
112
- }
113
- } else {
114
- payload.logger.error(err, `— AI Plugin: Error creating Compose settings for ${path}`);
115
- }
116
- } else {
117
- payload.logger.error(err, `— AI Plugin: Error creating Compose settings for ${path}`);
118
- }
119
- }
104
+ instructions = await payload.create({
105
+ collection: PLUGIN_INSTRUCTIONS_TABLE,
106
+ data
107
+ }).catch((err)=>{
108
+ payload.logger.error(err, '— AI Plugin: Error creating Compose settings-');
109
+ });
120
110
  if (instructions?.id) {
121
111
  fieldInstructionsMap[path] = {
122
112
  id: instructions.id,
@@ -124,17 +114,25 @@ export const init = async (payload, fieldSchemaPaths, pluginConfig)=>{
124
114
  };
125
115
  }
126
116
  } else {
127
- if (instructions['field-type'] !== fieldType) {
128
- const currentFieldType = instructions['field-type'];
129
- payload.logger.warn(`— AI Plugin: Field type mismatch for ${path}! Was "${fieldType}", it is "${currentFieldType}" now. Updating...`);
117
+ const modelForId = CAPABILITY_MAP.find((a)=>a.fields.includes(fieldType));
118
+ if (instructions['field-type'] !== fieldType || !instructions['model-id']) {
119
+ payload.logger.warn(`— AI Plugin: Field config mismatch for ${path}! Updating...`);
120
+ const updateData = {
121
+ 'field-type': fieldType
122
+ };
123
+ // Only set model-id if it's missing or we have a better default
124
+ if (!instructions['model-id'] && modelForId?.id) {
125
+ updateData['model-id'] = modelForId.id;
126
+ }
130
127
  await payload.update({
131
128
  id: instructions.id,
132
129
  collection: PLUGIN_INSTRUCTIONS_TABLE,
133
- data: {
134
- 'field-type': fieldType
135
- }
130
+ data: updateData
136
131
  });
137
132
  instructions['field-type'] = fieldType;
133
+ if (updateData['model-id']) {
134
+ instructions['model-id'] = updateData['model-id'];
135
+ }
138
136
  }
139
137
  fieldInstructionsMap[path] = {
140
138
  id: instructions.id,