@ai-stack/payloadcms 3.68.0 → 3.76.0-beta.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 (154) hide show
  1. package/dist/ai/core/media/image/generateImage.js +2 -6
  2. package/dist/ai/core/media/image/generateImage.js.map +1 -1
  3. package/dist/ai/core/media/image/handlers/multimodal.js +5 -0
  4. package/dist/ai/core/media/image/handlers/multimodal.js.map +1 -1
  5. package/dist/ai/core/streamObject.js +3 -3
  6. package/dist/ai/core/streamObject.js.map +1 -1
  7. package/dist/ai/core/types.d.ts +3 -0
  8. package/dist/ai/core/types.js.map +1 -1
  9. package/dist/ai/prompts.d.ts +1 -2
  10. package/dist/ai/prompts.js +0 -110
  11. package/dist/ai/prompts.js.map +1 -1
  12. package/dist/ai/providers/blocks/anthropic.js +2 -1
  13. package/dist/ai/providers/blocks/anthropic.js.map +1 -1
  14. package/dist/ai/providers/blocks/elevenlabs.js +3 -2
  15. package/dist/ai/providers/blocks/elevenlabs.js.map +1 -1
  16. package/dist/ai/providers/blocks/fal.js +2 -1
  17. package/dist/ai/providers/blocks/fal.js.map +1 -1
  18. package/dist/ai/providers/blocks/google.js +11 -6
  19. package/dist/ai/providers/blocks/google.js.map +1 -1
  20. package/dist/ai/providers/blocks/openai-compatible.js +2 -1
  21. package/dist/ai/providers/blocks/openai-compatible.js.map +1 -1
  22. package/dist/ai/providers/blocks/openai.js +3 -2
  23. package/dist/ai/providers/blocks/openai.js.map +1 -1
  24. package/dist/ai/providers/blocks/xai.js +2 -1
  25. package/dist/ai/providers/blocks/xai.js.map +1 -1
  26. package/dist/ai/providers/icons.d.ts +7 -0
  27. package/dist/ai/providers/icons.js +9 -0
  28. package/dist/ai/providers/icons.js.map +1 -0
  29. package/dist/ai/providers/registry.js +34 -24
  30. package/dist/ai/providers/registry.js.map +1 -1
  31. package/dist/ai/utils/filterEditorSchemaByNodes.d.ts +9 -0
  32. package/dist/ai/utils/filterEditorSchemaByNodes.js +30 -3
  33. package/dist/ai/utils/filterEditorSchemaByNodes.js.map +1 -1
  34. package/dist/ai/utils/nodeToSchemaMap.d.ts +22 -0
  35. package/dist/ai/utils/nodeToSchemaMap.js +72 -0
  36. package/dist/ai/utils/nodeToSchemaMap.js.map +1 -0
  37. package/dist/collections/AIJobs.js +1 -1
  38. package/dist/collections/AIJobs.js.map +1 -1
  39. package/dist/collections/AISettings.js +47 -20
  40. package/dist/collections/AISettings.js.map +1 -1
  41. package/dist/collections/Instructions.js +37 -0
  42. package/dist/collections/Instructions.js.map +1 -1
  43. package/dist/defaults.d.ts +1 -0
  44. package/dist/defaults.js +8 -0
  45. package/dist/defaults.js.map +1 -1
  46. package/dist/endpoints/chat.d.ts +4 -0
  47. package/dist/endpoints/fetchFields.js +10 -0
  48. package/dist/endpoints/fetchFields.js.map +1 -1
  49. package/dist/endpoints/fetchVoices.js +41 -24
  50. package/dist/endpoints/fetchVoices.js.map +1 -1
  51. package/dist/endpoints/index.js +194 -16
  52. package/dist/endpoints/index.js.map +1 -1
  53. package/dist/exports/fields.d.ts +1 -0
  54. package/dist/exports/fields.js +1 -0
  55. package/dist/exports/fields.js.map +1 -1
  56. package/dist/fields/ArrayComposeField/ArrayComposeField.d.ts +15 -0
  57. package/dist/fields/ArrayComposeField/ArrayComposeField.js +87 -0
  58. package/dist/fields/ArrayComposeField/ArrayComposeField.js.map +1 -0
  59. package/dist/fields/ArrayComposeField/ArrayComposeField.jsx +73 -0
  60. package/dist/fields/PromptEditorField/PromptEditorField.js +7 -2
  61. package/dist/fields/PromptEditorField/PromptEditorField.js.map +1 -1
  62. package/dist/fields/PromptEditorField/PromptEditorField.jsx +5 -2
  63. package/dist/index.d.ts +3 -1
  64. package/dist/index.js +2 -1
  65. package/dist/index.js.map +1 -1
  66. package/dist/payload-ai.d.ts +152 -0
  67. package/dist/plugin.js +16 -32
  68. package/dist/plugin.js.map +1 -1
  69. package/dist/providers/InstructionsProvider/InstructionsProvider.js +47 -15
  70. package/dist/providers/InstructionsProvider/InstructionsProvider.js.map +1 -1
  71. package/dist/providers/InstructionsProvider/InstructionsProvider.jsx +39 -16
  72. package/dist/providers/InstructionsProvider/context.d.ts +3 -0
  73. package/dist/providers/InstructionsProvider/context.js +2 -0
  74. package/dist/providers/InstructionsProvider/context.js.map +1 -1
  75. package/dist/providers/InstructionsProvider/useInstructions.js +21 -2
  76. package/dist/providers/InstructionsProvider/useInstructions.js.map +1 -1
  77. package/dist/styles.d.ts +11 -0
  78. package/dist/types/handlebars-async-helpers.d.ts +1 -0
  79. package/dist/types/handlebars-dist-handlebars.d.ts +1 -0
  80. package/dist/types/react-mentions.d.ts +1 -0
  81. package/dist/types.d.ts +34 -5
  82. package/dist/types.js +1 -0
  83. package/dist/types.js.map +1 -1
  84. package/dist/ui/AIConfigDashboard/index.js +198 -22
  85. package/dist/ui/AIConfigDashboard/index.js.map +1 -1
  86. package/dist/ui/AIConfigDashboard/index.jsx +159 -13
  87. package/dist/ui/Compose/Compose.d.ts +1 -0
  88. package/dist/ui/Compose/Compose.js +23 -4
  89. package/dist/ui/Compose/Compose.js.map +1 -1
  90. package/dist/ui/Compose/Compose.jsx +23 -4
  91. package/dist/ui/Compose/UndoRedoActions.d.ts +2 -2
  92. package/dist/ui/Compose/UndoRedoActions.js +8 -5
  93. package/dist/ui/Compose/UndoRedoActions.js.map +1 -1
  94. package/dist/ui/Compose/UndoRedoActions.jsx +6 -5
  95. package/dist/ui/Compose/compose.module.css +56 -16
  96. package/dist/ui/Compose/hooks/menu/itemsMap.js +12 -6
  97. package/dist/ui/Compose/hooks/menu/itemsMap.js.map +1 -1
  98. package/dist/ui/Compose/hooks/menu/useMenu.js +26 -15
  99. package/dist/ui/Compose/hooks/menu/useMenu.js.map +1 -1
  100. package/dist/ui/Compose/hooks/menu/useMenu.jsx +25 -12
  101. package/dist/ui/Compose/hooks/useGenerate.js +26 -174
  102. package/dist/ui/Compose/hooks/useGenerate.js.map +1 -1
  103. package/dist/ui/Compose/hooks/useGenerateUpload.d.ts +11 -0
  104. package/dist/ui/Compose/hooks/useGenerateUpload.js +150 -0
  105. package/dist/ui/Compose/hooks/useGenerateUpload.js.map +1 -0
  106. package/dist/ui/Compose/hooks/useHistory.d.ts +0 -1
  107. package/dist/ui/Compose/hooks/useHistory.js +65 -25
  108. package/dist/ui/Compose/hooks/useHistory.js.map +1 -1
  109. package/dist/ui/Compose/hooks/useStreamingUpdate.d.ts +8 -0
  110. package/dist/ui/Compose/hooks/useStreamingUpdate.js +48 -0
  111. package/dist/ui/Compose/hooks/useStreamingUpdate.js.map +1 -0
  112. package/dist/ui/DynamicVoiceSelect/index.js +63 -11
  113. package/dist/ui/DynamicVoiceSelect/index.js.map +1 -1
  114. package/dist/ui/DynamicVoiceSelect/index.jsx +47 -14
  115. package/dist/ui/EncryptedTextField/index.js +4 -4
  116. package/dist/ui/EncryptedTextField/index.js.map +1 -1
  117. package/dist/ui/EncryptedTextField/index.jsx +4 -4
  118. package/dist/ui/VoicesFetcher/index.js +34 -16
  119. package/dist/ui/VoicesFetcher/index.js.map +1 -1
  120. package/dist/ui/VoicesFetcher/index.jsx +32 -15
  121. package/dist/utilities/buildSmartPrompt.d.ts +22 -0
  122. package/dist/utilities/buildSmartPrompt.js +141 -0
  123. package/dist/utilities/buildSmartPrompt.js.map +1 -0
  124. package/dist/utilities/encryption.js +2 -1
  125. package/dist/utilities/encryption.js.map +1 -1
  126. package/dist/utilities/fieldToJsonSchema.js +32 -3
  127. package/dist/utilities/fieldToJsonSchema.js.map +1 -1
  128. package/dist/utilities/resolveImageReferences.d.ts +3 -1
  129. package/dist/utilities/resolveImageReferences.js +21 -2
  130. package/dist/utilities/resolveImageReferences.js.map +1 -1
  131. package/dist/utilities/seedProperties.d.ts +7 -0
  132. package/dist/utilities/seedProperties.js +100 -0
  133. package/dist/utilities/seedProperties.js.map +1 -0
  134. package/dist/utilities/setSafeLexicalState.js +79 -6
  135. package/dist/utilities/setSafeLexicalState.js.map +1 -1
  136. package/dist/utilities/updateFieldsConfig.d.ts +1 -1
  137. package/dist/utilities/updateFieldsConfig.js +8 -1
  138. package/dist/utilities/updateFieldsConfig.js.map +1 -1
  139. package/package.json +35 -33
  140. package/dist/endpoints/chat.d.js +0 -3
  141. package/dist/endpoints/chat.d.js.map +0 -1
  142. package/dist/init.d.ts +0 -7
  143. package/dist/init.js +0 -135
  144. package/dist/init.js.map +0 -1
  145. package/dist/payload-ai.d.js +0 -3
  146. package/dist/payload-ai.d.js.map +0 -1
  147. package/dist/styles.d.js +0 -2
  148. package/dist/styles.d.js.map +0 -1
  149. package/dist/types/handlebars-async-helpers.d.js +0 -2
  150. package/dist/types/handlebars-async-helpers.d.js.map +0 -1
  151. package/dist/types/handlebars-dist-handlebars.d.js +0 -2
  152. package/dist/types/handlebars-dist-handlebars.d.js.map +0 -1
  153. package/dist/types/react-mentions.d.js +0 -2
  154. package/dist/types/react-mentions.d.js.map +0 -1
@@ -0,0 +1,152 @@
1
+ // Global type definitions for @ai-stack/payloadcms
2
+ // This file augments the Payload types using inline type definitions
3
+
4
+ import type { GenerateObjectResult, ImagePart, JSONValue, ModelMessage } from 'ai'
5
+ import type { z } from 'zod'
6
+
7
+ /**
8
+ * Provider options compatible with AI SDK
9
+ */
10
+ type ProviderOptions = Record<string, Record<string, JSONValue>>
11
+
12
+ /**
13
+ * Base arguments for all generation methods
14
+ */
15
+ interface PayloadGenerationBaseArgs {
16
+ extractAttachments?: boolean
17
+ maxTokens?: number
18
+ messages?: ModelMessage[]
19
+ model?: string
20
+ prompt: string
21
+ provider?: string
22
+ providerOptions?: ProviderOptions
23
+ system?: string
24
+ temperature?: number
25
+ }
26
+
27
+ /**
28
+ * Arguments for generateObject - structured output generation
29
+ */
30
+ interface PayloadGenerateObjectArgs extends PayloadGenerationBaseArgs {
31
+ images?: ImagePart[]
32
+ mode?: 'auto' | 'json' | 'tool'
33
+ onFinish?: (event: { object?: unknown }) => Promise<void> | void
34
+ schema?: Record<string, unknown> | z.ZodTypeAny
35
+ }
36
+
37
+ /**
38
+ * Arguments for generateText - simple text generation
39
+ */
40
+ interface PayloadGenerateTextArgs extends PayloadGenerationBaseArgs {
41
+ // No additional fields needed for basic text generation
42
+ }
43
+
44
+ /**
45
+ * Arguments for generateMedia - image/video generation
46
+ */
47
+ interface PayloadGenerateMediaArgs {
48
+ aspectRatio?: string
49
+ audioFormat?: string
50
+ callbackUrl?: string
51
+ duration?: number
52
+ fps?: number
53
+ images?: ImagePart[]
54
+ instructionId?: number | string
55
+ mode?: 'i2v' | 't2v'
56
+ model?: string
57
+ n?: number
58
+ prompt: string
59
+ provider?: string
60
+ providerOptions?: ProviderOptions
61
+ seed?: number
62
+ size?: { height: number; width: number }
63
+ speed?: number
64
+ voice?: string
65
+ }
66
+
67
+ /**
68
+ * Result from generateMedia - can be immediate file or async job
69
+ */
70
+ interface MediaResult {
71
+ // Immediate result (image generation)
72
+ file?: {
73
+ data: Buffer
74
+ mimetype: string
75
+ name: string
76
+ size: number
77
+ }
78
+
79
+ // Async job result (video generation)
80
+ jobId?: string
81
+ progress?: number
82
+ status?: 'completed' | 'failed' | 'queued' | 'running'
83
+ taskId?: string
84
+ }
85
+
86
+ declare module 'payload' {
87
+ interface BasePayload {
88
+ ai: {
89
+ /**
90
+ * @deprecated Use generateObject or generateText instead
91
+ * Legacy generate method for backward compatibility
92
+ */
93
+ generate: (args: unknown) => Promise<unknown>
94
+
95
+ /**
96
+ * Generate media (images or videos)
97
+ * @param args - Generation arguments including provider, model, prompt, and media options
98
+ * @returns Promise resolving to either a file or async job info
99
+ */
100
+ generateMedia: (args: PayloadGenerateMediaArgs) => Promise<MediaResult>
101
+
102
+ /**
103
+ * Generate structured output with schema validation
104
+ * @param args - Generation arguments including provider, model, prompt, and schema
105
+ * @returns Promise resolving to the generated object
106
+ */
107
+ generateObject: <T = unknown>(args: PayloadGenerateObjectArgs) => Promise<GenerateObjectResult<T>>
108
+
109
+ /**
110
+ * Generate simple text output
111
+ * @param args - Generation arguments including provider, model, and prompt
112
+ * @returns Promise resolving to the generated text
113
+ */
114
+ generateText: (args: PayloadGenerateTextArgs) => Promise<string>
115
+
116
+ /**
117
+ * Get a specific model instance
118
+ * @param provider - Provider name (e.g., 'openai', 'anthropic')
119
+ * @param modelId - Model ID (e.g., 'gpt-4', 'claude-3')
120
+ * @param type - Model type ('text', 'image', or 'tts')
121
+ * @returns Promise resolving to the model instance
122
+ */
123
+ getModel: (
124
+ provider: string,
125
+ modelId: string,
126
+ type?: 'image' | 'text' | 'tts',
127
+ ) => Promise<unknown>
128
+
129
+ /**
130
+ * Get the provider registry
131
+ * @returns Promise resolving to the provider registry
132
+ */
133
+ getRegistry: () => Promise<Record<string, unknown>>
134
+
135
+ /**
136
+ * Stream structured output with schema validation
137
+ * @param args - Generation arguments including provider, model, prompt, and schema
138
+ * @returns Response stream
139
+ */
140
+ streamObject: <T = unknown>(args: PayloadGenerateObjectArgs) => Promise<Response>
141
+
142
+ /**
143
+ * Stream text output
144
+ * @param args - Generation arguments including provider, model, and prompt
145
+ * @returns Response stream
146
+ */
147
+ streamText: (args: PayloadGenerateTextArgs) => Promise<Response>
148
+ }
149
+ }
150
+ }
151
+
152
+ export {}
package/dist/plugin.js CHANGED
@@ -7,7 +7,6 @@ import { PLUGIN_NAME } from './defaults.js';
7
7
  import { fetchFields } from './endpoints/fetchFields.js';
8
8
  import { fetchVoices } from './endpoints/fetchVoices.js';
9
9
  import { endpoints } from './endpoints/index.js';
10
- import { init } from './init.js';
11
10
  import { translations } from './translations/index.js';
12
11
  import { isPluginActivated } from './utilities/isPluginActivated.js';
13
12
  import { updateFieldsConfig } from './utilities/updateFieldsConfig.js';
@@ -16,9 +15,7 @@ const defaultPluginConfig = {
16
15
  generate: ({ req })=>!!req.user,
17
16
  settings: ({ req })=>!!req.user
18
17
  },
19
- collections: {},
20
- disableSponsorMessage: false,
21
- generatePromptOnInit: true
18
+ disableSponsorMessage: false
22
19
  };
23
20
  const sponsorMessage = `
24
21
  ╔═══════════════════════════════════════════════════════════════╗
@@ -66,7 +63,6 @@ const payloadAiPlugin = (pluginConfig)=>(incomingConfig)=>{
66
63
  let updatedConfig = {
67
64
  ...incomingConfig
68
65
  };
69
- let collectionsFieldPathMap = {};
70
66
  if (isActivated) {
71
67
  const Instructions = instructionsCollection(pluginConfig);
72
68
  const AIJobs = aiJobsCollection();
@@ -96,7 +92,7 @@ const payloadAiPlugin = (pluginConfig)=>(incomingConfig)=>{
96
92
  ...incomingConfig.globals ?? [],
97
93
  aiSettingsGlobal
98
94
  ];
99
- const { collections: collectionSlugs, globals: globalsSlugs } = pluginConfig;
95
+ const { globals: globalsSlugs } = pluginConfig;
100
96
  const { components: { providers = [] } = {} } = incomingConfig.admin || {};
101
97
  const updatedProviders = [
102
98
  ...providers ?? [],
@@ -115,15 +111,9 @@ const payloadAiPlugin = (pluginConfig)=>(incomingConfig)=>{
115
111
  updatedConfig = {
116
112
  ...incomingConfig,
117
113
  collections: collections.map((collection)=>{
118
- if (collectionSlugs[collection.slug]) {
119
- const { schemaPathMap, updatedCollectionConfig } = updateFieldsConfig(collection);
120
- collectionsFieldPathMap = {
121
- ...collectionsFieldPathMap,
122
- ...schemaPathMap
123
- };
124
- return updatedCollectionConfig;
125
- }
126
- return collection;
114
+ // Always inject fields, but they will be dynamically enabled/disabled by the InstructionsProvider
115
+ const { updatedCollectionConfig } = updateFieldsConfig(collection);
116
+ return updatedCollectionConfig;
127
117
  }),
128
118
  endpoints: [
129
119
  ...incomingConfig.endpoints ?? [],
@@ -137,11 +127,7 @@ const payloadAiPlugin = (pluginConfig)=>(incomingConfig)=>{
137
127
  ],
138
128
  globals: globals.map((global)=>{
139
129
  if (globalsSlugs && globalsSlugs[global.slug]) {
140
- const { schemaPathMap, updatedCollectionConfig } = updateFieldsConfig(global);
141
- collectionsFieldPathMap = {
142
- ...collectionsFieldPathMap,
143
- ...schemaPathMap
144
- };
130
+ const { updatedCollectionConfig } = updateFieldsConfig(global);
145
131
  return updatedCollectionConfig;
146
132
  }
147
133
  return global;
@@ -162,18 +148,16 @@ const payloadAiPlugin = (pluginConfig)=>(incomingConfig)=>{
162
148
  payload.logger.warn(`— AI Plugin: Not activated. Please verify your environment keys.`);
163
149
  return;
164
150
  }
165
- await init(payload, collectionsFieldPathMap, pluginConfig).catch((error)=>{
166
- payload.logger.error(error, `— AI Plugin: Initialization Error`);
167
- }).finally(()=>{
168
- if (!pluginConfig.disableSponsorMessage) {
169
- setTimeout(()=>{
170
- payload.logger.info(securityMessage);
171
- }, 1000);
172
- setTimeout(()=>{
173
- payload.logger.info(sponsorMessage);
174
- }, 3000);
175
- }
176
- });
151
+ if (!pluginConfig.disableSponsorMessage) {
152
+ setTimeout(()=>{
153
+ payload.logger.info(securityMessage);
154
+ }, 1000);
155
+ setTimeout(()=>{
156
+ payload.logger.info(sponsorMessage);
157
+ }, 3000);
158
+ }
159
+ // Inject AI capabilities with the abstraction layer
160
+ ;
177
161
  payload.ai = {
178
162
  // Core generation methods
179
163
  generateObject: async (args)=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/plugin.ts"],"sourcesContent":["import type { CollectionConfig, Config, GlobalConfig } from 'payload'\n\nimport { deepMerge } from 'payload/shared'\n\nimport type { PluginConfig } from './types.js'\n\nimport { lexicalJsonSchema } from './ai/schemas/lexicalJsonSchema.js'\nimport { aiJobsCollection } from './collections/AIJobs.js'\nimport { aiSettingsGlobal } from './collections/AISettings.js'\nimport { instructionsCollection } from './collections/Instructions.js'\nimport { PLUGIN_NAME } from './defaults.js'\nimport { fetchFields } from './endpoints/fetchFields.js'\nimport { fetchVoices } from './endpoints/fetchVoices.js'\nimport { endpoints } from './endpoints/index.js'\nimport { init } from './init.js'\nimport { translations } from './translations/index.js'\nimport { isPluginActivated } from './utilities/isPluginActivated.js'\nimport { updateFieldsConfig } from './utilities/updateFieldsConfig.js'\n\nconst defaultPluginConfig: PluginConfig = {\n access: {\n generate: ({ req }) => !!req.user,\n settings: ({ req }) => !!req.user,\n },\n collections: {},\n disableSponsorMessage: false,\n generatePromptOnInit: true,\n}\n\nconst sponsorMessage = `\n╔═══════════════════════════════════════════════════════════════╗\n║ THANK YOU FOR USING THE PAYLOAD AI PLUGIN! ║\n║ ║\n║ If this plugin makes your life easier, please ║\n║ consider supporting its development and maintenance: ║\n║ ║\n║ • Buy me a coffee: https://buymeacoffee.com/ashbuilds ║\n║ • Sponsor on GitHub: https://github.com/sponsors/ashbuilds ║\n║ ║\n║ Your support fuels continued improvements, ║\n║ new features, and more caffeinated coding sessions! ☕ ║\n║ ║\n║ Got feedback or need help? Submit an issue here: ║\n║ • https://github.com/ashbuilds/payload-ai/issues/new ║\n║ ║\n║ Thank you again, and happy building! ║\n╚═══════════════════════════════════════════════════════════════╝\n`\n\nconst securityMessage = `\n╔═══════════════════════════════════════════════════════════════╗\n║ SECURITY NOTICE ║\n║ ║\n║ The AI Plugin now requires authentication by default. ║\n║ All AI features are restricted to authenticated users. ║\n║ ║\n║ To customize access control, configure the 'access' option ║\n║ in your plugin settings. See documentation for details. ║\n║ ║\n║ If you need different access patterns, please configure ║\n║ them explicitly in your plugin configuration. ║\n╚═══════════════════════════════════════════════════════════════╝\n`\n\nconst payloadAiPlugin =\n (pluginConfig: PluginConfig) =>\n (incomingConfig: Config): Config => {\n pluginConfig = {\n ...defaultPluginConfig,\n ...pluginConfig,\n access: {\n ...defaultPluginConfig.access,\n ...pluginConfig.access,\n },\n }\n\n const isActivated = isPluginActivated(pluginConfig)\n let updatedConfig: Config = { ...incomingConfig }\n let collectionsFieldPathMap = {}\n\n if (isActivated) {\n const Instructions = instructionsCollection(pluginConfig)\n const AIJobs = aiJobsCollection()\n // Inject editor schema to config, so that it can be accessed when /textarea endpoint will hit\n const lexicalSchema = lexicalJsonSchema(pluginConfig.editorConfig?.nodes)\n\n Instructions.admin = {\n ...Instructions.admin,\n }\n\n if (pluginConfig.debugging) {\n Instructions.admin.hidden = false\n }\n\n Instructions.admin.custom = {\n ...(Instructions.admin.custom || {}),\n [PLUGIN_NAME]: {\n editorConfig: {\n // Used in admin client for useObject hook\n schema: lexicalSchema,\n },\n },\n }\n\n const collections = [...(incomingConfig.collections ?? []), Instructions, AIJobs]\n const globals = [...(incomingConfig.globals ?? []), aiSettingsGlobal]\n const { collections: collectionSlugs, globals: globalsSlugs } = pluginConfig\n\n const { components: { providers = [] } = {} } = incomingConfig.admin || {}\n const updatedProviders = [\n ...(providers ?? []),\n {\n path: '@ai-stack/payloadcms/client#InstructionsProvider',\n },\n ]\n\n incomingConfig.admin = {\n ...(incomingConfig.admin || {}),\n components: {\n ...(incomingConfig.admin?.components ?? {}),\n providers: updatedProviders,\n },\n }\n\n const pluginEndpoints = endpoints(pluginConfig)\n updatedConfig = {\n ...incomingConfig,\n collections: collections.map((collection) => {\n if (collectionSlugs[collection.slug]) {\n const { schemaPathMap, updatedCollectionConfig } = updateFieldsConfig(collection)\n collectionsFieldPathMap = {\n ...collectionsFieldPathMap,\n ...schemaPathMap,\n }\n return updatedCollectionConfig as CollectionConfig\n }\n\n return collection\n }),\n endpoints: [\n ...(incomingConfig.endpoints ?? []),\n pluginEndpoints.textarea,\n pluginEndpoints.upload,\n ...(pluginEndpoints.videogenWebhook ? [pluginEndpoints.videogenWebhook] : []),\n fetchFields(pluginConfig),\n fetchVoices,\n ],\n globals: globals.map((global) => {\n if (globalsSlugs && globalsSlugs[global.slug]) {\n const { schemaPathMap, updatedCollectionConfig } = updateFieldsConfig(global)\n collectionsFieldPathMap = {\n ...collectionsFieldPathMap,\n ...schemaPathMap,\n }\n return updatedCollectionConfig as GlobalConfig\n }\n\n return global\n }),\n i18n: {\n ...(incomingConfig.i18n || {}),\n translations: {\n ...deepMerge(translations, incomingConfig.i18n?.translations ?? {}),\n },\n },\n }\n }\n\n updatedConfig.onInit = async (payload) => {\n if (incomingConfig.onInit) {\n await incomingConfig.onInit(payload)\n }\n\n if (!isActivated) {\n payload.logger.warn(`— AI Plugin: Not activated. Please verify your environment keys.`)\n return\n }\n\n await init(payload, collectionsFieldPathMap, pluginConfig)\n .catch((error) => {\n payload.logger.error(error, `— AI Plugin: Initialization Error`)\n })\n .finally(() => {\n if (!pluginConfig.disableSponsorMessage) {\n setTimeout(() => {\n payload.logger.info(securityMessage)\n }, 1000)\n setTimeout(() => {\n payload.logger.info(sponsorMessage)\n }, 3000)\n }\n })\n\n // Inject AI capabilities with enhanced abstraction layer\n ;(payload as any).ai = {\n // Core generation methods\n generateObject: async (args: any) => {\n const { generateObject } = await import('./ai/core/index.js')\n return generateObject({ ...args, payload })\n },\n\n generateText: async (args: any) => {\n const { generateText } = await import('./ai/core/index.js')\n return generateText({ ...args, payload })\n },\n\n generateMedia: async (args: any) => {\n const { generateMedia } = await import('./ai/core/index.js')\n return generateMedia({ ...args, payload })\n },\n\n // Streaming variants\n streamObject: async (args: any) => {\n const { streamObject } = await import('./ai/core/index.js')\n const result = await streamObject({ ...args, payload })\n return result.toTextStreamResponse()\n },\n\n streamText: async (args: any) => {\n const { streamText } = await import('./ai/core/index.js')\n return streamText({ ...args, payload })\n },\n\n // Helper utilities\n getModel: async (provider: string, modelId: string, type?: 'image' | 'text' | 'tts') => {\n const { getImageModel, getLanguageModel, getTTSModel } = await import(\n './ai/providers/registry.js'\n )\n if (type === 'image') {\n return getImageModel(payload, provider, modelId)\n }\n if (type === 'tts') {\n return getTTSModel(payload, provider, modelId)\n }\n return getLanguageModel(payload, provider, modelId)\n },\n\n getRegistry: async () => {\n const { getProviderRegistry } = await import('./ai/providers/registry.js')\n return getProviderRegistry(payload)\n },\n\n // Legacy method for backward compatibility\n /** @deprecated Use generateObject or generateText instead */\n generate: async (args: any) => {\n const { generate } = await import('./ai/index.js')\n return generate({ ...args, payload })\n },\n }\n }\n\n return updatedConfig\n }\n\nexport { payloadAiPlugin }\n"],"names":["deepMerge","lexicalJsonSchema","aiJobsCollection","aiSettingsGlobal","instructionsCollection","PLUGIN_NAME","fetchFields","fetchVoices","endpoints","init","translations","isPluginActivated","updateFieldsConfig","defaultPluginConfig","access","generate","req","user","settings","collections","disableSponsorMessage","generatePromptOnInit","sponsorMessage","securityMessage","payloadAiPlugin","pluginConfig","incomingConfig","isActivated","updatedConfig","collectionsFieldPathMap","Instructions","AIJobs","lexicalSchema","editorConfig","nodes","admin","debugging","hidden","custom","schema","globals","collectionSlugs","globalsSlugs","components","providers","updatedProviders","path","pluginEndpoints","map","collection","slug","schemaPathMap","updatedCollectionConfig","textarea","upload","videogenWebhook","global","i18n","onInit","payload","logger","warn","catch","error","finally","setTimeout","info","ai","generateObject","args","generateText","generateMedia","streamObject","result","toTextStreamResponse","streamText","getModel","provider","modelId","type","getImageModel","getLanguageModel","getTTSModel","getRegistry","getProviderRegistry"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/plugin.ts"],"sourcesContent":["import type { CollectionConfig, Config, GlobalConfig } from 'payload'\n\nimport { deepMerge } from 'payload/shared'\n\nimport type { PluginConfig } from './types.js'\n\nimport { lexicalJsonSchema } from './ai/schemas/lexicalJsonSchema.js'\nimport { aiJobsCollection } from './collections/AIJobs.js'\nimport { aiSettingsGlobal } from './collections/AISettings.js'\nimport { instructionsCollection } from './collections/Instructions.js'\nimport { PLUGIN_NAME } from './defaults.js'\nimport { fetchFields } from './endpoints/fetchFields.js'\nimport { fetchVoices } from './endpoints/fetchVoices.js'\nimport { endpoints } from './endpoints/index.js'\nimport { translations } from './translations/index.js'\nimport { isPluginActivated } from './utilities/isPluginActivated.js'\nimport { updateFieldsConfig } from './utilities/updateFieldsConfig.js'\n\nconst defaultPluginConfig: PluginConfig = {\n access: {\n generate: ({ req }) => !!req.user,\n settings: ({ req }) => !!req.user,\n },\n disableSponsorMessage: false,\n}\n\nconst sponsorMessage = `\n╔═══════════════════════════════════════════════════════════════╗\n║ THANK YOU FOR USING THE PAYLOAD AI PLUGIN! ║\n║ ║\n║ If this plugin makes your life easier, please ║\n║ consider supporting its development and maintenance: ║\n║ ║\n║ • Buy me a coffee: https://buymeacoffee.com/ashbuilds ║\n║ • Sponsor on GitHub: https://github.com/sponsors/ashbuilds ║\n║ ║\n║ Your support fuels continued improvements, ║\n║ new features, and more caffeinated coding sessions! ☕ ║\n║ ║\n║ Got feedback or need help? Submit an issue here: ║\n║ • https://github.com/ashbuilds/payload-ai/issues/new ║\n║ ║\n║ Thank you again, and happy building! ║\n╚═══════════════════════════════════════════════════════════════╝\n`\n\nconst securityMessage = `\n╔═══════════════════════════════════════════════════════════════╗\n║ SECURITY NOTICE ║\n║ ║\n║ The AI Plugin now requires authentication by default. ║\n║ All AI features are restricted to authenticated users. ║\n║ ║\n║ To customize access control, configure the 'access' option ║\n║ in your plugin settings. See documentation for details. ║\n║ ║\n║ If you need different access patterns, please configure ║\n║ them explicitly in your plugin configuration. ║\n╚═══════════════════════════════════════════════════════════════╝\n`\n\nconst payloadAiPlugin =\n (pluginConfig: PluginConfig) =>\n (incomingConfig: Config): Config => {\n pluginConfig = {\n ...defaultPluginConfig,\n ...pluginConfig,\n access: {\n ...defaultPluginConfig.access,\n ...pluginConfig.access,\n },\n }\n\n const isActivated = isPluginActivated(pluginConfig)\n let updatedConfig: Config = { ...incomingConfig }\n\n if (isActivated) {\n const Instructions = instructionsCollection(pluginConfig)\n const AIJobs = aiJobsCollection()\n // Inject editor schema to config, so that it can be accessed when /textarea endpoint will hit\n const lexicalSchema = lexicalJsonSchema(pluginConfig.editorConfig?.nodes)\n\n Instructions.admin = {\n ...Instructions.admin,\n }\n\n if (pluginConfig.debugging) {\n Instructions.admin.hidden = false\n }\n\n Instructions.admin.custom = {\n ...(Instructions.admin.custom || {}),\n [PLUGIN_NAME]: {\n editorConfig: {\n // Used in admin client for useObject hook\n schema: lexicalSchema,\n },\n },\n }\n\n const collections = [...(incomingConfig.collections ?? []), Instructions, AIJobs]\n const globals = [...(incomingConfig.globals ?? []), aiSettingsGlobal]\n const { globals: globalsSlugs } = pluginConfig\n\n const { components: { providers = [] } = {} } = incomingConfig.admin || {}\n const updatedProviders = [\n ...(providers ?? []),\n {\n path: '@ai-stack/payloadcms/client#InstructionsProvider',\n },\n ]\n\n incomingConfig.admin = {\n ...(incomingConfig.admin || {}),\n components: {\n ...(incomingConfig.admin?.components ?? {}),\n providers: updatedProviders,\n },\n }\n\n const pluginEndpoints = endpoints(pluginConfig)\n updatedConfig = {\n ...incomingConfig,\n collections: collections.map((collection) => {\n // Always inject fields, but they will be dynamically enabled/disabled by the InstructionsProvider\n const { updatedCollectionConfig } = updateFieldsConfig(collection)\n return updatedCollectionConfig as CollectionConfig\n }),\n endpoints: [\n ...(incomingConfig.endpoints ?? []),\n pluginEndpoints.textarea,\n pluginEndpoints.upload,\n ...(pluginEndpoints.videogenWebhook ? [pluginEndpoints.videogenWebhook] : []),\n fetchFields(pluginConfig),\n fetchVoices,\n ],\n globals: globals.map((global) => {\n if (globalsSlugs && globalsSlugs[global.slug]) {\n const { updatedCollectionConfig } = updateFieldsConfig(global)\n return updatedCollectionConfig as GlobalConfig\n }\n\n return global\n }),\n i18n: {\n ...(incomingConfig.i18n || {}),\n translations: {\n ...deepMerge(translations, incomingConfig.i18n?.translations ?? {}),\n },\n },\n }\n }\n\n updatedConfig.onInit = async (payload) => {\n if (incomingConfig.onInit) {\n await incomingConfig.onInit(payload)\n }\n\n if (!isActivated) {\n payload.logger.warn(`— AI Plugin: Not activated. Please verify your environment keys.`)\n return\n }\n\n if (!pluginConfig.disableSponsorMessage) {\n setTimeout(() => {\n payload.logger.info(securityMessage)\n }, 1000)\n setTimeout(() => {\n payload.logger.info(sponsorMessage)\n }, 3000)\n }\n\n // Inject AI capabilities with the abstraction layer\n ;(payload as any).ai = {\n // Core generation methods\n generateObject: async (args: any) => {\n const { generateObject } = await import('./ai/core/index.js')\n return generateObject({ ...args, payload })\n },\n\n generateText: async (args: any) => {\n const { generateText } = await import('./ai/core/index.js')\n return generateText({ ...args, payload })\n },\n\n generateMedia: async (args: any) => {\n const { generateMedia } = await import('./ai/core/index.js')\n return generateMedia({ ...args, payload })\n },\n\n // Streaming variants\n streamObject: async (args: any) => {\n const { streamObject } = await import('./ai/core/index.js')\n const result = await streamObject({ ...args, payload })\n return result.toTextStreamResponse()\n },\n\n streamText: async (args: any) => {\n const { streamText } = await import('./ai/core/index.js')\n return streamText({ ...args, payload })\n },\n\n // Helper utilities\n getModel: async (provider: string, modelId: string, type?: 'image' | 'text' | 'tts') => {\n const { getImageModel, getLanguageModel, getTTSModel } = await import(\n './ai/providers/registry.js'\n )\n if (type === 'image') {\n return getImageModel(payload, provider, modelId)\n }\n if (type === 'tts') {\n return getTTSModel(payload, provider, modelId)\n }\n return getLanguageModel(payload, provider, modelId)\n },\n\n getRegistry: async () => {\n const { getProviderRegistry } = await import('./ai/providers/registry.js')\n return getProviderRegistry(payload)\n },\n\n // Legacy method for backward compatibility\n /** @deprecated Use generateObject or generateText instead */\n generate: async (args: any) => {\n const { generate } = await import('./ai/index.js')\n return generate({ ...args, payload })\n },\n }\n }\n\n return updatedConfig\n }\n\nexport { payloadAiPlugin }\n"],"names":["deepMerge","lexicalJsonSchema","aiJobsCollection","aiSettingsGlobal","instructionsCollection","PLUGIN_NAME","fetchFields","fetchVoices","endpoints","translations","isPluginActivated","updateFieldsConfig","defaultPluginConfig","access","generate","req","user","settings","disableSponsorMessage","sponsorMessage","securityMessage","payloadAiPlugin","pluginConfig","incomingConfig","isActivated","updatedConfig","Instructions","AIJobs","lexicalSchema","editorConfig","nodes","admin","debugging","hidden","custom","schema","collections","globals","globalsSlugs","components","providers","updatedProviders","path","pluginEndpoints","map","collection","updatedCollectionConfig","textarea","upload","videogenWebhook","global","slug","i18n","onInit","payload","logger","warn","setTimeout","info","ai","generateObject","args","generateText","generateMedia","streamObject","result","toTextStreamResponse","streamText","getModel","provider","modelId","type","getImageModel","getLanguageModel","getTTSModel","getRegistry","getProviderRegistry"],"mappings":"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"}
@@ -3,13 +3,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useAuth, useConfig, useDocumentDrawer } from '@payloadcms/ui';
4
4
  import React, { useCallback, useEffect, useState } from 'react';
5
5
  import { PLUGIN_FETCH_FIELDS_ENDPOINT, PLUGIN_INSTRUCTIONS_TABLE } from '../../defaults.js';
6
+ import { useActiveFieldTracking } from '../../ui/Compose/hooks/useActiveFieldTracking.js';
6
7
  import { InstructionsContext } from './context.js';
7
8
  export const InstructionsProvider = ({ children })=>{
9
+ // Initialize field tracking globally so ai-plugin-active class is added on field focus
10
+ useActiveFieldTracking();
8
11
  const [instructions, setInstructionsState] = useState({});
9
12
  const [promptFields, setPromptFields] = useState([]);
10
13
  const [activeCollection, setActiveCollection] = useState('');
11
14
  const [isConfigAllowed, setIsConfigAllowed] = useState(false);
12
15
  const [enabledLanguages, setEnabledLanguages] = useState();
16
+ const [enabledCollections, setEnabledCollections] = useState();
13
17
  const [debugging, setDebugging] = useState(false);
14
18
  const { user } = useAuth();
15
19
  const { config } = useConfig();
@@ -34,44 +38,72 @@ export const InstructionsProvider = ({ children })=>{
34
38
  drawerOpenCount,
35
39
  openPayloadDrawer
36
40
  ]);
37
- // This is here because each field have separate instructions and
38
- // their ID is needed to edit them for Drawer
39
- useEffect(()=>{
41
+ const handleSave = useCallback(({ doc })=>{
42
+ setInstructionsState((prev)=>{
43
+ return {
44
+ ...prev,
45
+ [doc['schema-path']]: {
46
+ id: doc.id,
47
+ disabled: !!doc.disabled,
48
+ fieldType: doc['field-type']
49
+ }
50
+ };
51
+ });
52
+ }, [
53
+ setInstructionsState
54
+ ]);
55
+ const fetchFieldsData = useCallback(async ()=>{
40
56
  // Only fetch if we have a user ID - prevents fetching on every user object reference change
41
57
  if (!user?.id) {
42
58
  return;
43
59
  }
44
- fetch(`${serverURL}${api}${PLUGIN_FETCH_FIELDS_ENDPOINT}`).then(async (res)=>{
45
- await res.json().then((data)=>{
46
- setIsConfigAllowed(data?.isConfigAllowed || false);
47
- setEnabledLanguages(data?.enabledLanguages || []);
48
- setInstructionsState(data?.fields || {});
49
- setPromptFields(data?.promptFields || []);
50
- setDebugging(data?.debugging || false);
51
- });
52
- }).catch((err)=>{
60
+ try {
61
+ const res = await fetch(`${serverURL}${api}${PLUGIN_FETCH_FIELDS_ENDPOINT}`);
62
+ const data = await res.json();
63
+ setIsConfigAllowed(data?.isConfigAllowed || false);
64
+ setEnabledLanguages(data?.enabledLanguages || []);
65
+ setEnabledCollections(data?.enabledCollections || []);
66
+ setInstructionsState(data?.fields || {});
67
+ setPromptFields(data?.promptFields || []);
68
+ setDebugging(data?.debugging || false);
69
+ } catch (err) {
53
70
  console.error('InstructionsProvider:', err);
54
- });
71
+ }
55
72
  }, [
56
73
  api,
57
74
  serverURL,
58
75
  user?.id
59
76
  ]);
77
+ useEffect(()=>{
78
+ void fetchFieldsData();
79
+ }, [
80
+ fetchFieldsData
81
+ ]);
82
+ const refresh = useCallback(async ()=>{
83
+ await fetchFieldsData();
84
+ }, [
85
+ fetchFieldsData
86
+ ]);
60
87
  return /*#__PURE__*/ _jsxs(InstructionsContext.Provider, {
61
88
  value: {
62
89
  activeCollection,
63
90
  debugging,
91
+ enabledCollections,
64
92
  enabledLanguages,
65
93
  hasInstructions: instructions && Object.keys(instructions).length > 0,
66
94
  instructions,
67
95
  isConfigAllowed,
68
96
  openDrawer,
69
97
  promptFields,
70
- setActiveCollection
98
+ refresh,
99
+ setActiveCollection,
100
+ setEnabledCollections
71
101
  },
72
102
  children: [
73
103
  children,
74
- /*#__PURE__*/ _jsx(DocumentDrawer, {})
104
+ /*#__PURE__*/ _jsx(DocumentDrawer, {
105
+ onSave: handleSave
106
+ })
75
107
  ]
76
108
  });
77
109
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/providers/InstructionsProvider/InstructionsProvider.tsx"],"sourcesContent":["'use client'\n\nimport { useAuth, useConfig, useDocumentDrawer } from '@payloadcms/ui'\nimport React, { useCallback, useEffect, useState } from 'react'\n\nimport type { SerializedPromptField } from '../../types.js'\n\nimport { PLUGIN_FETCH_FIELDS_ENDPOINT, PLUGIN_INSTRUCTIONS_TABLE } from '../../defaults.js'\nimport { InstructionsContext } from './context.js'\n\nexport const InstructionsProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const [instructions, setInstructionsState] = useState({})\n const [promptFields, setPromptFields] = useState<SerializedPromptField[]>([])\n const [activeCollection, setActiveCollection] = useState('')\n const [isConfigAllowed, setIsConfigAllowed] = useState(false)\n const [enabledLanguages, setEnabledLanguages] = useState<string[]>()\n const [debugging, setDebugging] = useState(false)\n const { user } = useAuth()\n\n const { config } = useConfig()\n const {\n routes: { api },\n serverURL,\n } = config\n\n // Global Document Drawer state\n const [drawerInstructionId, setDrawerInstructionId] = useState<string>('')\n const [drawerOpenCount, setDrawerOpenCount] = useState(0)\n\n const [DocumentDrawer, _, { openDrawer: openPayloadDrawer }] = useDocumentDrawer({\n id: drawerInstructionId,\n collectionSlug: PLUGIN_INSTRUCTIONS_TABLE,\n })\n\n const openDrawer = useCallback((id: string) => {\n setDrawerInstructionId(id)\n setDrawerOpenCount((prev) => prev + 1)\n }, [])\n\n // Open drawer when count changes\n useEffect(() => {\n if (drawerOpenCount > 0) {\n openPayloadDrawer()\n }\n }, [drawerOpenCount, openPayloadDrawer])\n\n // This is here because each field have separate instructions and\n // their ID is needed to edit them for Drawer\n useEffect(() => {\n // Only fetch if we have a user ID - prevents fetching on every user object reference change\n if (!user?.id) {\n return\n }\n\n fetch(`${serverURL}${api}${PLUGIN_FETCH_FIELDS_ENDPOINT}`)\n .then(async (res) => {\n await res.json().then((data) => {\n setIsConfigAllowed(data?.isConfigAllowed || false)\n setEnabledLanguages(data?.enabledLanguages || [])\n setInstructionsState(data?.fields || {})\n setPromptFields(data?.promptFields || [])\n setDebugging(data?.debugging || false)\n })\n })\n .catch((err) => {\n console.error('InstructionsProvider:', err)\n })\n }, [api, serverURL, user?.id])\n\n return (\n <InstructionsContext.Provider\n value={{\n activeCollection,\n debugging,\n enabledLanguages,\n hasInstructions: instructions && Object.keys(instructions).length > 0,\n instructions,\n isConfigAllowed,\n openDrawer,\n promptFields,\n setActiveCollection,\n }}\n >\n {children}\n <DocumentDrawer />\n </InstructionsContext.Provider>\n )\n}\n"],"names":["useAuth","useConfig","useDocumentDrawer","React","useCallback","useEffect","useState","PLUGIN_FETCH_FIELDS_ENDPOINT","PLUGIN_INSTRUCTIONS_TABLE","InstructionsContext","InstructionsProvider","children","instructions","setInstructionsState","promptFields","setPromptFields","activeCollection","setActiveCollection","isConfigAllowed","setIsConfigAllowed","enabledLanguages","setEnabledLanguages","debugging","setDebugging","user","config","routes","api","serverURL","drawerInstructionId","setDrawerInstructionId","drawerOpenCount","setDrawerOpenCount","DocumentDrawer","_","openDrawer","openPayloadDrawer","id","collectionSlug","prev","fetch","then","res","json","data","fields","catch","err","console","error","Provider","value","hasInstructions","Object","keys","length"],"mappings":"AAAA;;AAEA,SAASA,OAAO,EAAEC,SAAS,EAAEC,iBAAiB,QAAQ,iBAAgB;AACtE,OAAOC,SAASC,WAAW,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAI/D,SAASC,4BAA4B,EAAEC,yBAAyB,QAAQ,oBAAmB;AAC3F,SAASC,mBAAmB,QAAQ,eAAc;AAElD,OAAO,MAAMC,uBAAgE,CAAC,EAAEC,QAAQ,EAAE;IACxF,MAAM,CAACC,cAAcC,qBAAqB,GAAGP,SAAS,CAAC;IACvD,MAAM,CAACQ,cAAcC,gBAAgB,GAAGT,SAAkC,EAAE;IAC5E,MAAM,CAACU,kBAAkBC,oBAAoB,GAAGX,SAAS;IACzD,MAAM,CAACY,iBAAiBC,mBAAmB,GAAGb,SAAS;IACvD,MAAM,CAACc,kBAAkBC,oBAAoB,GAAGf;IAChD,MAAM,CAACgB,WAAWC,aAAa,GAAGjB,SAAS;IAC3C,MAAM,EAAEkB,IAAI,EAAE,GAAGxB;IAEjB,MAAM,EAAEyB,MAAM,EAAE,GAAGxB;IACnB,MAAM,EACJyB,QAAQ,EAAEC,GAAG,EAAE,EACfC,SAAS,EACV,GAAGH;IAEJ,+BAA+B;IAC/B,MAAM,CAACI,qBAAqBC,uBAAuB,GAAGxB,SAAiB;IACvE,MAAM,CAACyB,iBAAiBC,mBAAmB,GAAG1B,SAAS;IAEvD,MAAM,CAAC2B,gBAAgBC,GAAG,EAAEC,YAAYC,iBAAiB,EAAE,CAAC,GAAGlC,kBAAkB;QAC/EmC,IAAIR;QACJS,gBAAgB9B;IAClB;IAEA,MAAM2B,aAAa/B,YAAY,CAACiC;QAC9BP,uBAAuBO;QACvBL,mBAAmB,CAACO,OAASA,OAAO;IACtC,GAAG,EAAE;IAEL,iCAAiC;IACjClC,UAAU;QACR,IAAI0B,kBAAkB,GAAG;YACvBK;QACF;IACF,GAAG;QAACL;QAAiBK;KAAkB;IAEvC,iEAAiE;IACjE,6CAA6C;IAC7C/B,UAAU;QACR,4FAA4F;QAC5F,IAAI,CAACmB,MAAMa,IAAI;YACb;QACF;QAEAG,MAAM,CAAC,EAAEZ,UAAU,EAAED,IAAI,EAAEpB,6BAA6B,CAAC,EACtDkC,IAAI,CAAC,OAAOC;YACX,MAAMA,IAAIC,IAAI,GAAGF,IAAI,CAAC,CAACG;gBACrBzB,mBAAmByB,MAAM1B,mBAAmB;gBAC5CG,oBAAoBuB,MAAMxB,oBAAoB,EAAE;gBAChDP,qBAAqB+B,MAAMC,UAAU,CAAC;gBACtC9B,gBAAgB6B,MAAM9B,gBAAgB,EAAE;gBACxCS,aAAaqB,MAAMtB,aAAa;YAClC;QACF,GACCwB,KAAK,CAAC,CAACC;YACNC,QAAQC,KAAK,CAAC,yBAAyBF;QACzC;IACJ,GAAG;QAACpB;QAAKC;QAAWJ,MAAMa;KAAG;IAE7B,qBACE,MAAC5B,oBAAoByC,QAAQ;QAC3BC,OAAO;YACLnC;YACAM;YACAF;YACAgC,iBAAiBxC,gBAAgByC,OAAOC,IAAI,CAAC1C,cAAc2C,MAAM,GAAG;YACpE3C;YACAM;YACAiB;YACArB;YACAG;QACF;;YAECN;0BACD,KAACsB;;;AAGP,EAAC"}
1
+ {"version":3,"sources":["../../../src/providers/InstructionsProvider/InstructionsProvider.tsx"],"sourcesContent":["'use client'\n\nimport { useAuth, useConfig, useDocumentDrawer } from '@payloadcms/ui'\nimport React, { useCallback, useEffect, useState } from 'react'\n\nimport type { SerializedPromptField } from '../../types.js'\n\nimport { PLUGIN_FETCH_FIELDS_ENDPOINT, PLUGIN_INSTRUCTIONS_TABLE } from '../../defaults.js'\nimport { useActiveFieldTracking } from '../../ui/Compose/hooks/useActiveFieldTracking.js'\nimport { InstructionsContext } from './context.js'\n\nexport const InstructionsProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n // Initialize field tracking globally so ai-plugin-active class is added on field focus\n useActiveFieldTracking()\n\n const [instructions, setInstructionsState] = useState({})\n const [promptFields, setPromptFields] = useState<SerializedPromptField[]>([])\n const [activeCollection, setActiveCollection] = useState('')\n const [isConfigAllowed, setIsConfigAllowed] = useState(false)\n const [enabledLanguages, setEnabledLanguages] = useState<string[]>()\n const [enabledCollections, setEnabledCollections] = useState<string[]>()\n const [debugging, setDebugging] = useState(false)\n const { user } = useAuth()\n\n const { config } = useConfig()\n const {\n routes: { api },\n serverURL,\n } = config\n\n // Global Document Drawer state\n const [drawerInstructionId, setDrawerInstructionId] = useState<string>('')\n const [drawerOpenCount, setDrawerOpenCount] = useState(0)\n\n const [DocumentDrawer, _, { openDrawer: openPayloadDrawer }] = useDocumentDrawer({\n id: drawerInstructionId,\n collectionSlug: PLUGIN_INSTRUCTIONS_TABLE,\n })\n\n const openDrawer = useCallback((id: string) => {\n setDrawerInstructionId(id)\n setDrawerOpenCount((prev) => prev + 1)\n }, [])\n\n // Open drawer when count changes\n useEffect(() => {\n if (drawerOpenCount > 0) {\n openPayloadDrawer()\n }\n }, [drawerOpenCount, openPayloadDrawer])\n\n const handleSave = useCallback(\n ({ doc }: { doc: any }) => {\n setInstructionsState((prev) => {\n return {\n ...prev,\n [doc['schema-path']]: {\n id: doc.id,\n disabled: !!doc.disabled,\n fieldType: doc['field-type'],\n },\n }\n })\n },\n [setInstructionsState],\n )\n\n const fetchFieldsData = useCallback(async () => {\n // Only fetch if we have a user ID - prevents fetching on every user object reference change\n if (!user?.id) {\n return\n }\n\n try {\n const res = await fetch(`${serverURL}${api}${PLUGIN_FETCH_FIELDS_ENDPOINT}`)\n const data = await res.json()\n setIsConfigAllowed(data?.isConfigAllowed || false)\n setEnabledLanguages(data?.enabledLanguages || [])\n setEnabledCollections(data?.enabledCollections || [])\n setInstructionsState(data?.fields || {})\n setPromptFields(data?.promptFields || [])\n setDebugging(data?.debugging || false)\n } catch (err) {\n console.error('InstructionsProvider:', err)\n }\n }, [api, serverURL, user?.id])\n\n useEffect(() => {\n void fetchFieldsData()\n }, [fetchFieldsData])\n\n const refresh = useCallback(async () => {\n await fetchFieldsData()\n }, [fetchFieldsData])\n\n return (\n <InstructionsContext.Provider\n value={{\n activeCollection,\n debugging,\n enabledCollections,\n enabledLanguages,\n hasInstructions: instructions && Object.keys(instructions).length > 0,\n instructions,\n isConfigAllowed,\n openDrawer,\n promptFields,\n refresh,\n setActiveCollection,\n setEnabledCollections,\n }}\n >\n {children}\n <DocumentDrawer onSave={handleSave} />\n </InstructionsContext.Provider>\n )\n}\n"],"names":["useAuth","useConfig","useDocumentDrawer","React","useCallback","useEffect","useState","PLUGIN_FETCH_FIELDS_ENDPOINT","PLUGIN_INSTRUCTIONS_TABLE","useActiveFieldTracking","InstructionsContext","InstructionsProvider","children","instructions","setInstructionsState","promptFields","setPromptFields","activeCollection","setActiveCollection","isConfigAllowed","setIsConfigAllowed","enabledLanguages","setEnabledLanguages","enabledCollections","setEnabledCollections","debugging","setDebugging","user","config","routes","api","serverURL","drawerInstructionId","setDrawerInstructionId","drawerOpenCount","setDrawerOpenCount","DocumentDrawer","_","openDrawer","openPayloadDrawer","id","collectionSlug","prev","handleSave","doc","disabled","fieldType","fetchFieldsData","res","fetch","data","json","fields","err","console","error","refresh","Provider","value","hasInstructions","Object","keys","length","onSave"],"mappings":"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"}
@@ -2,13 +2,17 @@
2
2
  import { useAuth, useConfig, useDocumentDrawer } from '@payloadcms/ui';
3
3
  import React, { useCallback, useEffect, useState } from 'react';
4
4
  import { PLUGIN_FETCH_FIELDS_ENDPOINT, PLUGIN_INSTRUCTIONS_TABLE } from '../../defaults.js';
5
+ import { useActiveFieldTracking } from '../../ui/Compose/hooks/useActiveFieldTracking.js';
5
6
  import { InstructionsContext } from './context.js';
6
7
  export const InstructionsProvider = ({ children }) => {
8
+ // Initialize field tracking globally so ai-plugin-active class is added on field focus
9
+ useActiveFieldTracking();
7
10
  const [instructions, setInstructionsState] = useState({});
8
11
  const [promptFields, setPromptFields] = useState([]);
9
12
  const [activeCollection, setActiveCollection] = useState('');
10
13
  const [isConfigAllowed, setIsConfigAllowed] = useState(false);
11
14
  const [enabledLanguages, setEnabledLanguages] = useState();
15
+ const [enabledCollections, setEnabledCollections] = useState();
12
16
  const [debugging, setDebugging] = useState(false);
13
17
  const { user } = useAuth();
14
18
  const { config } = useConfig();
@@ -30,39 +34,58 @@ export const InstructionsProvider = ({ children }) => {
30
34
  openPayloadDrawer();
31
35
  }
32
36
  }, [drawerOpenCount, openPayloadDrawer]);
33
- // This is here because each field have separate instructions and
34
- // their ID is needed to edit them for Drawer
35
- useEffect(() => {
37
+ const handleSave = useCallback(({ doc }) => {
38
+ setInstructionsState((prev) => {
39
+ return {
40
+ ...prev,
41
+ [doc['schema-path']]: {
42
+ id: doc.id,
43
+ disabled: !!doc.disabled,
44
+ fieldType: doc['field-type'],
45
+ },
46
+ };
47
+ });
48
+ }, [setInstructionsState]);
49
+ const fetchFieldsData = useCallback(async () => {
36
50
  // Only fetch if we have a user ID - prevents fetching on every user object reference change
37
51
  if (!user?.id) {
38
52
  return;
39
53
  }
40
- fetch(`${serverURL}${api}${PLUGIN_FETCH_FIELDS_ENDPOINT}`)
41
- .then(async (res) => {
42
- await res.json().then((data) => {
43
- setIsConfigAllowed(data?.isConfigAllowed || false);
44
- setEnabledLanguages(data?.enabledLanguages || []);
45
- setInstructionsState(data?.fields || {});
46
- setPromptFields(data?.promptFields || []);
47
- setDebugging(data?.debugging || false);
48
- });
49
- })
50
- .catch((err) => {
54
+ try {
55
+ const res = await fetch(`${serverURL}${api}${PLUGIN_FETCH_FIELDS_ENDPOINT}`);
56
+ const data = await res.json();
57
+ setIsConfigAllowed(data?.isConfigAllowed || false);
58
+ setEnabledLanguages(data?.enabledLanguages || []);
59
+ setEnabledCollections(data?.enabledCollections || []);
60
+ setInstructionsState(data?.fields || {});
61
+ setPromptFields(data?.promptFields || []);
62
+ setDebugging(data?.debugging || false);
63
+ }
64
+ catch (err) {
51
65
  console.error('InstructionsProvider:', err);
52
- });
66
+ }
53
67
  }, [api, serverURL, user?.id]);
68
+ useEffect(() => {
69
+ void fetchFieldsData();
70
+ }, [fetchFieldsData]);
71
+ const refresh = useCallback(async () => {
72
+ await fetchFieldsData();
73
+ }, [fetchFieldsData]);
54
74
  return (<InstructionsContext.Provider value={{
55
75
  activeCollection,
56
76
  debugging,
77
+ enabledCollections,
57
78
  enabledLanguages,
58
79
  hasInstructions: instructions && Object.keys(instructions).length > 0,
59
80
  instructions,
60
81
  isConfigAllowed,
61
82
  openDrawer,
62
83
  promptFields,
84
+ refresh,
63
85
  setActiveCollection,
86
+ setEnabledCollections,
64
87
  }}>
65
88
  {children}
66
- <DocumentDrawer />
89
+ <DocumentDrawer onSave={handleSave}/>
67
90
  </InstructionsContext.Provider>);
68
91
  };
@@ -4,6 +4,7 @@ import type { SerializedPromptField } from '../../types.js';
4
4
  export type InstructionsContextValue = {
5
5
  activeCollection?: string;
6
6
  debugging?: boolean;
7
+ enabledCollections?: string[];
7
8
  enabledLanguages?: string[];
8
9
  field?: Field;
9
10
  hasInstructions: boolean;
@@ -12,8 +13,10 @@ export type InstructionsContextValue = {
12
13
  openDrawer: (instructionId: string) => void;
13
14
  path?: string;
14
15
  promptFields: SerializedPromptField[];
16
+ refresh: () => Promise<void>;
15
17
  schemaPath?: unknown;
16
18
  setActiveCollection?: React.Dispatch<React.SetStateAction<string>>;
19
+ setEnabledCollections?: React.Dispatch<React.SetStateAction<string[] | undefined>>;
17
20
  };
18
21
  export declare const initialContext: InstructionsContextValue;
19
22
  export declare const InstructionsContext: React.Context<InstructionsContextValue>;
@@ -2,6 +2,7 @@
2
2
  import { createContext } from 'react';
3
3
  export const initialContext = {
4
4
  debugging: false,
5
+ enabledCollections: [],
5
6
  field: undefined,
6
7
  hasInstructions: false,
7
8
  instructions: {},
@@ -9,6 +10,7 @@ export const initialContext = {
9
10
  openDrawer: ()=>null,
10
11
  path: '',
11
12
  promptFields: [],
13
+ refresh: ()=>Promise.resolve(),
12
14
  schemaPath: ''
13
15
  };
14
16
  export const InstructionsContext = createContext(initialContext);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/providers/InstructionsProvider/context.ts"],"sourcesContent":["'use client'\n\nimport type { Field } from 'payload'\nimport type React from 'react';\n\nimport { createContext } from 'react'\n\nimport type { SerializedPromptField } from '../../types.js'\n\nexport type InstructionsContextValue = {\n activeCollection?: string\n debugging?: boolean\n enabledLanguages?: string[]\n field?: Field\n hasInstructions: boolean\n instructions: Record<string, any>\n isConfigAllowed: boolean\n openDrawer: (instructionId: string) => void\n path?: string\n promptFields: SerializedPromptField[]\n schemaPath?: unknown\n setActiveCollection?: React.Dispatch<React.SetStateAction<string>>\n}\n\nexport const initialContext: InstructionsContextValue = {\n debugging: false,\n field: undefined,\n hasInstructions: false,\n instructions: {},\n isConfigAllowed: true,\n openDrawer: () => null,\n path: '',\n promptFields: [],\n schemaPath: '',\n}\n\nexport const InstructionsContext = createContext<InstructionsContextValue>(initialContext)\n"],"names":["createContext","initialContext","debugging","field","undefined","hasInstructions","instructions","isConfigAllowed","openDrawer","path","promptFields","schemaPath","InstructionsContext"],"mappings":"AAAA;AAKA,SAASA,aAAa,QAAQ,QAAO;AAmBrC,OAAO,MAAMC,iBAA2C;IACtDC,WAAW;IACXC,OAAOC;IACPC,iBAAiB;IACjBC,cAAc,CAAC;IACfC,iBAAiB;IACjBC,YAAY,IAAM;IAClBC,MAAM;IACNC,cAAc,EAAE;IAChBC,YAAY;AACd,EAAC;AAED,OAAO,MAAMC,sBAAsBZ,cAAwCC,gBAAe"}
1
+ {"version":3,"sources":["../../../src/providers/InstructionsProvider/context.ts"],"sourcesContent":["'use client'\n\nimport type { Field } from 'payload'\nimport type React from 'react';\n\nimport { createContext } from 'react'\n\nimport type { SerializedPromptField } from '../../types.js'\n\nexport type InstructionsContextValue = {\n activeCollection?: string\n debugging?: boolean\n enabledCollections?: string[]\n enabledLanguages?: string[]\n field?: Field\n hasInstructions: boolean\n instructions: Record<string, any>\n isConfigAllowed: boolean\n openDrawer: (instructionId: string) => void\n path?: string\n promptFields: SerializedPromptField[]\n refresh: () => Promise<void>\n schemaPath?: unknown\n setActiveCollection?: React.Dispatch<React.SetStateAction<string>>\n setEnabledCollections?: React.Dispatch<React.SetStateAction<string[] | undefined>>\n}\n\nexport const initialContext: InstructionsContextValue = {\n debugging: false,\n enabledCollections: [],\n field: undefined,\n hasInstructions: false,\n instructions: {},\n isConfigAllowed: true,\n openDrawer: () => null,\n path: '',\n promptFields: [],\n refresh: () => Promise.resolve(),\n schemaPath: '',\n}\n\nexport const InstructionsContext = createContext<InstructionsContextValue>(initialContext)\n"],"names":["createContext","initialContext","debugging","enabledCollections","field","undefined","hasInstructions","instructions","isConfigAllowed","openDrawer","path","promptFields","refresh","Promise","resolve","schemaPath","InstructionsContext"],"mappings":"AAAA;AAKA,SAASA,aAAa,QAAQ,QAAO;AAsBrC,OAAO,MAAMC,iBAA2C;IACtDC,WAAW;IACXC,oBAAoB,EAAE;IACtBC,OAAOC;IACPC,iBAAiB;IACjBC,cAAc,CAAC;IACfC,iBAAiB;IACjBC,YAAY,IAAM;IAClBC,MAAM;IACNC,cAAc,EAAE;IAChBC,SAAS,IAAMC,QAAQC,OAAO;IAC9BC,YAAY;AACd,EAAC;AAED,OAAO,MAAMC,sBAAsBhB,cAAwCC,gBAAe"}