@ai-stack/payloadcms 3.76.0-beta.4 → 3.76.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -127,13 +127,39 @@ fields: [
127
127
  # .env
128
128
  OPENAI_API_KEY=your-openai-api-key
129
129
  ANTHROPIC_API_KEY=your-anthropic-api-key # Optional
130
- GOOGLE_AI_API_KEY=your-google-api-key # Optional
130
+ GOOGLE_GENERATIVE_AI_API_KEY=your-google-api-key # Optional
131
+ GEMINI_API_KEY=your-google-api-key # Optional alias
131
132
  XAI_API_KEY=your-xai-api-key # Optional
132
133
  ELEVENLABS_API_KEY=your-elevenlabs-api-key # Optional
133
134
  ```
134
135
 
135
136
  > **✨ Pro tip:** You can also configure API keys directly in the AI Settings panel within Payload Admin—encrypted and secure.
136
137
 
138
+ ### 4. Cloudflare / Edge Runtime (Optional)
139
+
140
+ If your runtime does not expose provider keys via `process.env`, pass them to the plugin explicitly.
141
+
142
+ ```typescript
143
+ import { aiPlugin } from '@ai-stack/payloadcms'
144
+
145
+ export default buildConfig({
146
+ plugins: [
147
+ aiPlugin({
148
+ // Resolution order: getEnv -> env -> process.env
149
+ env: {
150
+ OPENAI_API_KEY: cloudflare.env.OPENAI_API_KEY,
151
+ GOOGLE_GENERATIVE_AI_API_KEY: cloudflare.env.GOOGLE_GENERATIVE_AI_API_KEY,
152
+ },
153
+ // or provide a resolver:
154
+ getEnv: (key) => {
155
+ const value = (cloudflare.env as Record<string, unknown>)[key]
156
+ return typeof value === 'string' ? value : undefined
157
+ },
158
+ }),
159
+ ],
160
+ })
161
+ ```
162
+
137
163
  ---
138
164
 
139
165
  ## 🚀 Programmatic API (`payload.ai`)
@@ -103,8 +103,8 @@ const providerOptionsUIField = {
103
103
  };
104
104
  export const instructionsCollection = (pluginConfig)=>({
105
105
  labels: {
106
- plural: 'Compose Settings',
107
- singular: 'Compose Setting'
106
+ plural: 'Instructions',
107
+ singular: 'Instruction'
108
108
  },
109
109
  ...pluginConfig.overrideInstructions,
110
110
  slug: PLUGIN_INSTRUCTIONS_TABLE,
@@ -115,6 +115,7 @@ export const instructionsCollection = (pluginConfig)=>({
115
115
  admin: {
116
116
  description: 'Customize how AI interacts with specific fields within your enabled collections.',
117
117
  ...pluginCollectionAdmin,
118
+ group: 'AI Plugin',
118
119
  ...pluginConfig.overrideInstructions?.admin,
119
120
  components: {
120
121
  beforeList: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/collections/Instructions.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\nimport type { PluginConfig } from 'src/types.js'\n\nimport { lexicalEditor } from '@payloadcms/richtext-lexical'\n\nimport { PLUGIN_INSTRUCTIONS_TABLE } from '../defaults.js'\nimport { PromptMentionsFeature } from '../fields/PromptEditorField/feature.server.js'\nimport { applyInstructionDefaultsForDisplay } from '../utilities/ai/resolveEffectiveInstructionSettings.js'\nimport { pluginCollectionAccess, pluginCollectionAdmin } from './shared.js'\n\n// Defined capabilities replacing src/ai/models/\nconst CAPABILITIES = [\n {\n id: 'text',\n name: 'Text Generation',\n fields: ['text', 'textarea'],\n },\n {\n id: 'richtext',\n name: 'Rich Text Generation',\n fields: ['richText'],\n },\n {\n id: 'image',\n name: 'Image Generation',\n fields: ['upload'],\n },\n {\n id: 'tts',\n name: 'Text to Speech',\n fields: ['upload'],\n },\n {\n id: 'array',\n name: 'Array Generation',\n fields: ['array'],\n },\n]\n\n\nconst providerSelect = {\n name: 'provider',\n type: 'text' as const,\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicProviderSelect/index.js#DynamicProviderSelect',\n },\n },\n label: 'Provider',\n}\n\nconst modelSelect = {\n name: 'model',\n type: 'text' as const,\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicModelSelect/index.js#DynamicModelSelect',\n },\n },\n label: 'Model',\n}\n\n\nconst commonTextParams = [\n {\n type: 'row' as const,\n fields: [\n {\n name: 'maxTokens',\n type: 'number' as const,\n admin: {\n placeholder: 'Model Default',\n },\n label: 'Max Tokens',\n },\n {\n name: 'temperature',\n type: 'number' as const,\n defaultValue: 0.7,\n label: 'Temperature',\n max: 1,\n min: 0,\n },\n ],\n },\n {\n name: 'extractAttachments',\n type: 'checkbox' as const,\n label: 'Extract Attachments',\n },\n]\n\nconst providerOptionsUIField = {\n name: 'providerOptions',\n type: 'json' as const,\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/InstructionProviderOptions/index.js#InstructionProviderOptions',\n },\n },\n label: 'Provider Options',\n}\n\nexport const instructionsCollection = (pluginConfig: PluginConfig) =>\n <CollectionConfig>{\n labels: {\n plural: 'Compose Settings',\n singular: 'Compose Setting',\n },\n ...pluginConfig.overrideInstructions,\n slug: PLUGIN_INSTRUCTIONS_TABLE,\n access: {\n ...pluginCollectionAccess,\n ...pluginConfig.overrideInstructions?.access,\n },\n admin: {\n description:\n 'Customize how AI interacts with specific fields within your enabled collections.',\n ...pluginCollectionAdmin,\n ...pluginConfig.overrideInstructions?.admin,\n components: {\n beforeList: ['@ai-stack/payloadcms/ui/ConfigDashboard/index.js#ConfigDashboard'],\n },\n },\n fields: [\n {\n name: 'schema-path',\n type: 'text',\n admin: {\n description: \"Please don't change this unless you're sure of what you're doing\",\n hidden: !pluginConfig.debugging,\n },\n unique: true,\n },\n {\n name: 'field-type',\n type: 'select',\n admin: {\n description: \"Please don't change this unless you're sure of what you're doing\",\n hidden: !pluginConfig.debugging,\n },\n defaultValue: 'text',\n label: 'Field type',\n options: [\n {\n label: 'text',\n value: 'text',\n },\n {\n label: 'textarea',\n value: 'textarea',\n },\n {\n label: 'upload',\n value: 'upload',\n },\n {\n label: 'richText',\n value: 'richText',\n },\n {\n label: 'array',\n value: 'array',\n },\n ],\n },\n {\n name: 'relation-to',\n type: 'text',\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'upload'\n },\n hidden: !pluginConfig.debugging,\n },\n label: 'Relation to',\n },\n {\n name: 'hasMany',\n type: 'checkbox',\n admin: {\n hidden: true,\n },\n defaultValue: false,\n },\n {\n name: 'model-id',\n type: 'select',\n admin: {\n components: {\n Field: {\n clientProps: {\n filterByField: 'field-type',\n options: CAPABILITIES.map((c) => ({\n fields: c.fields,\n label: c.name,\n value: c.id,\n })),\n },\n path: '@ai-stack/payloadcms/fields/SelectField/SelectField.js#SelectField',\n },\n },\n },\n label: 'Capability',\n options: CAPABILITIES.map((c) => ({\n label: c.name,\n value: c.id,\n })),\n },\n {\n name: 'disabled',\n type: 'checkbox',\n admin: {\n description: 'Please reload your collection after applying the changes',\n },\n defaultValue: false,\n label: 'Hide Compose button for this field',\n },\n {\n name: 'alwaysShow',\n type: 'checkbox',\n admin: {\n condition: (_, current) => !current.disabled,\n description: 'Compose button will always be visible without requiring field focus',\n },\n defaultValue: false,\n label: 'Always show Compose button',\n },\n {\n name: 'appendGenerated',\n type: 'checkbox',\n admin: {\n condition: (_, current) => current?.hasMany === true && current?.disabled !== true,\n description: 'If enabled, generated values are appended to current values instead of replacing them.',\n },\n defaultValue: false,\n label: 'Append generated values',\n },\n {\n id: 'ai-prompts-tabs',\n type: 'tabs',\n tabs: [\n {\n description:\n 'Define dynamic templates using {{ fieldName }}. Type { to see available field suggestions.',\n fields: [\n { // TODO: update below to use PromptField\n name: 'prompt',\n type: 'richText',\n admin: {\n description: \"Click 'Compose' to run this custom prompt and generate content\",\n },\n editor: lexicalEditor({\n features: ({ rootFeatures: _rootFeatures }) => [PromptMentionsFeature()],\n }),\n label: '',\n },\n ],\n label: 'Prompt',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'upload' && current['model-id'] === 'image'\n },\n },\n description:\n 'These images will be used to generate new visuals in a similar style, layout, or content.',\n fields: [\n {\n name: 'images',\n type: 'array',\n fields: [\n {\n name: 'image',\n type: 'upload',\n admin: {\n description: 'Please make sure the image is publicly accessible.',\n },\n relationTo: pluginConfig.uploadCollectionSlug\n ? pluginConfig.uploadCollectionSlug\n : 'media',\n },\n ],\n },\n ],\n label: 'Sample Images',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'richText'\n },\n },\n description: '',\n fields: [\n {\n name: 'system',\n type: 'textarea',\n defaultValue: `INSTRUCTIONS:\nYou are a highly skilled and professional blog writer,\nrenowned for crafting engaging and well-organized articles.\nWhen given a title, you meticulously create blogs that are not only\ninformative and accurate but also captivating and beautifully structured.`,\n label: '',\n },\n ],\n label: 'System prompt',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'richText'\n },\n },\n description: '',\n fields: [\n {\n name: 'layout',\n type: 'textarea',\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'richText'\n },\n },\n defaultValue: `[paragraph] - Write a concise introduction (2-3 sentences) that outlines the main topic.\n[horizontalrule] - Insert a horizontal rule to separate the introduction from the main content.\n[list] - Create a list with 3-5 items. Each list item should contain:\n a. [heading] - A brief, descriptive heading (up to 5 words)\n b. [paragraph] - A short explanation or elaboration (1-2 sentences)\n[horizontalrule] - Insert another horizontal rule to separate the main content from the conclusion.\n[paragraph] - Compose a brief conclusion (2-3 sentences) summarizing the key points.\n[quote] - Include a relevant quote from a famous person, directly related to the topic. Format: \"Quote text.\" - Author Name`,\n label: '',\n },\n ],\n label: 'Layout',\n },\n ],\n },\n\n // Inline Settings Groups by Capability\n\n // Text Settings\n {\n name: 'text-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'text',\n },\n fields: [\n providerSelect,\n modelSelect,\n ...commonTextParams,\n providerOptionsUIField,\n ],\n label: 'Text Settings',\n },\n\n // Rich Text Settings\n {\n name: 'richtext-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'richtext',\n },\n fields: [\n providerSelect,\n modelSelect,\n ...commonTextParams,\n providerOptionsUIField,\n ],\n label: 'Rich Text Settings',\n },\n\n // Image Settings\n {\n name: 'image-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'image',\n },\n fields: [providerSelect, modelSelect, providerOptionsUIField],\n label: 'Image Settings',\n },\n\n // TTS Settings\n {\n name: 'tts-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'tts',\n },\n fields: [\n providerSelect,\n modelSelect,\n {\n name: 'voice',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicVoiceSelect/index.js#DynamicVoiceSelect',\n },\n },\n label: 'Voice',\n },\n providerOptionsUIField,\n ],\n label: 'TTS Settings',\n },\n\n // Array Settings\n {\n name: 'array-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'array',\n },\n fields: [\n providerSelect,\n modelSelect,\n {\n name: 'count',\n type: 'number',\n admin: {\n description: 'Number of items to generate',\n },\n defaultValue: 3,\n label: 'Items to Generate',\n max: 20,\n min: 1,\n },\n providerOptionsUIField,\n ],\n label: 'Array Settings',\n },\n ],\n hooks: {\n ...pluginConfig.overrideInstructions?.hooks,\n afterRead: [\n ...(pluginConfig.overrideInstructions?.hooks?.afterRead || []),\n async ({ context, doc, req }) => {\n if (!doc || typeof doc !== 'object') {\n return doc\n }\n\n const cacheKey = '__aiProvidersDefaults'\n const hookContext = (context || {}) as Record<string, unknown>\n let defaults = hookContext[cacheKey] as Record<string, unknown> | undefined\n\n if (!defaults) {\n try {\n const aiSettings = await req.payload.findGlobal({\n slug: 'ai-providers',\n })\n defaults = (aiSettings?.defaults || {}) as Record<string, unknown>\n hookContext[cacheKey] = defaults\n } catch (_error) {\n return doc\n }\n }\n\n return applyInstructionDefaultsForDisplay({\n defaults,\n instructions: doc as Record<string, unknown>,\n })\n },\n ],\n },\n }\n"],"names":["lexicalEditor","PLUGIN_INSTRUCTIONS_TABLE","PromptMentionsFeature","applyInstructionDefaultsForDisplay","pluginCollectionAccess","pluginCollectionAdmin","CAPABILITIES","id","name","fields","providerSelect","type","admin","components","Field","label","modelSelect","commonTextParams","placeholder","defaultValue","max","min","providerOptionsUIField","instructionsCollection","pluginConfig","labels","plural","singular","overrideInstructions","slug","access","description","beforeList","hidden","debugging","unique","options","value","condition","_","current","clientProps","filterByField","map","c","path","disabled","hasMany","tabs","editor","features","rootFeatures","_rootFeatures","relationTo","uploadCollectionSlug","data","hooks","afterRead","context","doc","req","cacheKey","hookContext","defaults","aiSettings","payload","findGlobal","_error","instructions"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/collections/Instructions.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\nimport type { PluginConfig } from 'src/types.js'\n\nimport { lexicalEditor } from '@payloadcms/richtext-lexical'\n\nimport { PLUGIN_INSTRUCTIONS_TABLE } from '../defaults.js'\nimport { PromptMentionsFeature } from '../fields/PromptEditorField/feature.server.js'\nimport { applyInstructionDefaultsForDisplay } from '../utilities/ai/resolveEffectiveInstructionSettings.js'\nimport { pluginCollectionAccess, pluginCollectionAdmin } from './shared.js'\n\n// Defined capabilities replacing src/ai/models/\nconst CAPABILITIES = [\n {\n id: 'text',\n name: 'Text Generation',\n fields: ['text', 'textarea'],\n },\n {\n id: 'richtext',\n name: 'Rich Text Generation',\n fields: ['richText'],\n },\n {\n id: 'image',\n name: 'Image Generation',\n fields: ['upload'],\n },\n {\n id: 'tts',\n name: 'Text to Speech',\n fields: ['upload'],\n },\n {\n id: 'array',\n name: 'Array Generation',\n fields: ['array'],\n },\n]\n\n\nconst providerSelect = {\n name: 'provider',\n type: 'text' as const,\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicProviderSelect/index.js#DynamicProviderSelect',\n },\n },\n label: 'Provider',\n}\n\nconst modelSelect = {\n name: 'model',\n type: 'text' as const,\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicModelSelect/index.js#DynamicModelSelect',\n },\n },\n label: 'Model',\n}\n\n\nconst commonTextParams = [\n {\n type: 'row' as const,\n fields: [\n {\n name: 'maxTokens',\n type: 'number' as const,\n admin: {\n placeholder: 'Model Default',\n },\n label: 'Max Tokens',\n },\n {\n name: 'temperature',\n type: 'number' as const,\n defaultValue: 0.7,\n label: 'Temperature',\n max: 1,\n min: 0,\n },\n ],\n },\n {\n name: 'extractAttachments',\n type: 'checkbox' as const,\n label: 'Extract Attachments',\n },\n]\n\nconst providerOptionsUIField = {\n name: 'providerOptions',\n type: 'json' as const,\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/InstructionProviderOptions/index.js#InstructionProviderOptions',\n },\n },\n label: 'Provider Options',\n}\n\nexport const instructionsCollection = (pluginConfig: PluginConfig) =>\n <CollectionConfig>{\n labels: {\n plural: 'Instructions',\n singular: 'Instruction',\n },\n ...pluginConfig.overrideInstructions,\n slug: PLUGIN_INSTRUCTIONS_TABLE,\n access: {\n ...pluginCollectionAccess,\n ...pluginConfig.overrideInstructions?.access,\n },\n admin: {\n description:\n 'Customize how AI interacts with specific fields within your enabled collections.',\n ...pluginCollectionAdmin,\n group: 'AI Plugin',\n ...pluginConfig.overrideInstructions?.admin,\n components: {\n beforeList: ['@ai-stack/payloadcms/ui/ConfigDashboard/index.js#ConfigDashboard'],\n },\n },\n fields: [\n {\n name: 'schema-path',\n type: 'text',\n admin: {\n description: \"Please don't change this unless you're sure of what you're doing\",\n hidden: !pluginConfig.debugging,\n },\n unique: true,\n },\n {\n name: 'field-type',\n type: 'select',\n admin: {\n description: \"Please don't change this unless you're sure of what you're doing\",\n hidden: !pluginConfig.debugging,\n },\n defaultValue: 'text',\n label: 'Field type',\n options: [\n {\n label: 'text',\n value: 'text',\n },\n {\n label: 'textarea',\n value: 'textarea',\n },\n {\n label: 'upload',\n value: 'upload',\n },\n {\n label: 'richText',\n value: 'richText',\n },\n {\n label: 'array',\n value: 'array',\n },\n ],\n },\n {\n name: 'relation-to',\n type: 'text',\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'upload'\n },\n hidden: !pluginConfig.debugging,\n },\n label: 'Relation to',\n },\n {\n name: 'hasMany',\n type: 'checkbox',\n admin: {\n hidden: true,\n },\n defaultValue: false,\n },\n {\n name: 'model-id',\n type: 'select',\n admin: {\n components: {\n Field: {\n clientProps: {\n filterByField: 'field-type',\n options: CAPABILITIES.map((c) => ({\n fields: c.fields,\n label: c.name,\n value: c.id,\n })),\n },\n path: '@ai-stack/payloadcms/fields/SelectField/SelectField.js#SelectField',\n },\n },\n },\n label: 'Capability',\n options: CAPABILITIES.map((c) => ({\n label: c.name,\n value: c.id,\n })),\n },\n {\n name: 'disabled',\n type: 'checkbox',\n admin: {\n description: 'Please reload your collection after applying the changes',\n },\n defaultValue: false,\n label: 'Hide Compose button for this field',\n },\n {\n name: 'alwaysShow',\n type: 'checkbox',\n admin: {\n condition: (_, current) => !current.disabled,\n description: 'Compose button will always be visible without requiring field focus',\n },\n defaultValue: false,\n label: 'Always show Compose button',\n },\n {\n name: 'appendGenerated',\n type: 'checkbox',\n admin: {\n condition: (_, current) => current?.hasMany === true && current?.disabled !== true,\n description: 'If enabled, generated values are appended to current values instead of replacing them.',\n },\n defaultValue: false,\n label: 'Append generated values',\n },\n {\n id: 'ai-prompts-tabs',\n type: 'tabs',\n tabs: [\n {\n description:\n 'Define dynamic templates using {{ fieldName }}. Type { to see available field suggestions.',\n fields: [\n { // TODO: update below to use PromptField\n name: 'prompt',\n type: 'richText',\n admin: {\n description: \"Click 'Compose' to run this custom prompt and generate content\",\n },\n editor: lexicalEditor({\n features: ({ rootFeatures: _rootFeatures }) => [PromptMentionsFeature()],\n }),\n label: '',\n },\n ],\n label: 'Prompt',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'upload' && current['model-id'] === 'image'\n },\n },\n description:\n 'These images will be used to generate new visuals in a similar style, layout, or content.',\n fields: [\n {\n name: 'images',\n type: 'array',\n fields: [\n {\n name: 'image',\n type: 'upload',\n admin: {\n description: 'Please make sure the image is publicly accessible.',\n },\n relationTo: pluginConfig.uploadCollectionSlug\n ? pluginConfig.uploadCollectionSlug\n : 'media',\n },\n ],\n },\n ],\n label: 'Sample Images',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'richText'\n },\n },\n description: '',\n fields: [\n {\n name: 'system',\n type: 'textarea',\n defaultValue: `INSTRUCTIONS:\nYou are a highly skilled and professional blog writer,\nrenowned for crafting engaging and well-organized articles.\nWhen given a title, you meticulously create blogs that are not only\ninformative and accurate but also captivating and beautifully structured.`,\n label: '',\n },\n ],\n label: 'System prompt',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'richText'\n },\n },\n description: '',\n fields: [\n {\n name: 'layout',\n type: 'textarea',\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'richText'\n },\n },\n defaultValue: `[paragraph] - Write a concise introduction (2-3 sentences) that outlines the main topic.\n[horizontalrule] - Insert a horizontal rule to separate the introduction from the main content.\n[list] - Create a list with 3-5 items. Each list item should contain:\n a. [heading] - A brief, descriptive heading (up to 5 words)\n b. [paragraph] - A short explanation or elaboration (1-2 sentences)\n[horizontalrule] - Insert another horizontal rule to separate the main content from the conclusion.\n[paragraph] - Compose a brief conclusion (2-3 sentences) summarizing the key points.\n[quote] - Include a relevant quote from a famous person, directly related to the topic. Format: \"Quote text.\" - Author Name`,\n label: '',\n },\n ],\n label: 'Layout',\n },\n ],\n },\n\n // Inline Settings Groups by Capability\n\n // Text Settings\n {\n name: 'text-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'text',\n },\n fields: [\n providerSelect,\n modelSelect,\n ...commonTextParams,\n providerOptionsUIField,\n ],\n label: 'Text Settings',\n },\n\n // Rich Text Settings\n {\n name: 'richtext-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'richtext',\n },\n fields: [\n providerSelect,\n modelSelect,\n ...commonTextParams,\n providerOptionsUIField,\n ],\n label: 'Rich Text Settings',\n },\n\n // Image Settings\n {\n name: 'image-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'image',\n },\n fields: [providerSelect, modelSelect, providerOptionsUIField],\n label: 'Image Settings',\n },\n\n // TTS Settings\n {\n name: 'tts-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'tts',\n },\n fields: [\n providerSelect,\n modelSelect,\n {\n name: 'voice',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicVoiceSelect/index.js#DynamicVoiceSelect',\n },\n },\n label: 'Voice',\n },\n providerOptionsUIField,\n ],\n label: 'TTS Settings',\n },\n\n // Array Settings\n {\n name: 'array-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'array',\n },\n fields: [\n providerSelect,\n modelSelect,\n {\n name: 'count',\n type: 'number',\n admin: {\n description: 'Number of items to generate',\n },\n defaultValue: 3,\n label: 'Items to Generate',\n max: 20,\n min: 1,\n },\n providerOptionsUIField,\n ],\n label: 'Array Settings',\n },\n ],\n hooks: {\n ...pluginConfig.overrideInstructions?.hooks,\n afterRead: [\n ...(pluginConfig.overrideInstructions?.hooks?.afterRead || []),\n async ({ context, doc, req }) => {\n if (!doc || typeof doc !== 'object') {\n return doc\n }\n\n const cacheKey = '__aiProvidersDefaults'\n const hookContext = (context || {}) as Record<string, unknown>\n let defaults = hookContext[cacheKey] as Record<string, unknown> | undefined\n\n if (!defaults) {\n try {\n const aiSettings = await req.payload.findGlobal({\n slug: 'ai-providers',\n })\n defaults = (aiSettings?.defaults || {}) as Record<string, unknown>\n hookContext[cacheKey] = defaults\n } catch (_error) {\n return doc\n }\n }\n\n return applyInstructionDefaultsForDisplay({\n defaults,\n instructions: doc as Record<string, unknown>,\n })\n },\n ],\n },\n }\n"],"names":["lexicalEditor","PLUGIN_INSTRUCTIONS_TABLE","PromptMentionsFeature","applyInstructionDefaultsForDisplay","pluginCollectionAccess","pluginCollectionAdmin","CAPABILITIES","id","name","fields","providerSelect","type","admin","components","Field","label","modelSelect","commonTextParams","placeholder","defaultValue","max","min","providerOptionsUIField","instructionsCollection","pluginConfig","labels","plural","singular","overrideInstructions","slug","access","description","group","beforeList","hidden","debugging","unique","options","value","condition","_","current","clientProps","filterByField","map","c","path","disabled","hasMany","tabs","editor","features","rootFeatures","_rootFeatures","relationTo","uploadCollectionSlug","data","hooks","afterRead","context","doc","req","cacheKey","hookContext","defaults","aiSettings","payload","findGlobal","_error","instructions"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -44,6 +44,11 @@ export interface PluginConfig {
44
44
  editorConfig?: {
45
45
  nodes: JSONSchema[];
46
46
  };
47
+ /**
48
+ * Optional runtime environment map for non-Node runtimes (Cloudflare Workers, Edge runtimes).
49
+ * Values in this map are checked before `process.env` during provider auto-setup.
50
+ */
51
+ env?: Partial<Record<string, string>>;
47
52
  fields?: Field[];
48
53
  /**
49
54
  * Defines default provider and models to be selected
@@ -69,6 +74,11 @@ export interface PluginConfig {
69
74
  };
70
75
  };
71
76
  generationModels?: ((defaultModels: GenerationModel[]) => GenerationModel[]) | GenerationModel[];
77
+ /**
78
+ * Optional runtime resolver for environment values.
79
+ * Resolution order is: `getEnv` -> `env` -> `process.env`.
80
+ */
81
+ getEnv?: (key: string) => string | undefined;
72
82
  globals?: {
73
83
  [key: GlobalConfig['slug']]: boolean;
74
84
  };
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { GenerateObjectResult, ModelMessage } from 'ai'\nimport type { JSONSchema } from 'openai/lib/jsonschema'\nimport type { ImageGenerateParams } from 'openai/resources/images'\nimport type {\n CollectionConfig,\n CollectionSlug,\n DataFromCollectionSlug,\n Endpoint,\n Field,\n File,\n GlobalConfig,\n GroupField,\n PayloadRequest,\n TypedCollection,\n} from 'payload'\n\nimport type { MediaResult } from './ai/core/index.js'\nimport type { PLUGIN_INSTRUCTIONS_TABLE } from './defaults.js'\n\nexport interface PluginConfigAccess {\n /**\n * Control access to AI generation features (generate text, images, audio)\n * @default () => !!req.user (requires authentication)\n */\n generate?: ({ req }: { req: PayloadRequest }) => boolean | Promise<boolean>\n /**\n * Control access to AI settings/configuration\n * @default () => !!req.user (requires authentication)\n */\n settings?: ({ req }: { req: PayloadRequest }) => boolean | Promise<boolean>\n}\n\nexport interface PluginOptions {\n /**\n * Provide local tags to filter language options from the Translate Menu\n * Check for the available local tags,\n * visit: https://www.npmjs.com/package/locale-codes\n * Example: [\"en-US\", \"zh-SG\", \"zh-CN\", \"en\"]\n */\n enabledLanguages?: string[]\n}\n\nexport type PluginConfigMediaUploadFunction = (\n result: MediaResult,\n {\n collection,\n request,\n }: {\n collection: CollectionSlug\n request: PayloadRequest\n },\n) => Promise<DataFromCollectionSlug<CollectionSlug>>\n\nexport interface PluginConfig {\n /**\n * Access control configuration for AI features\n * By default, all AI features require authentication\n */\n access?: PluginConfigAccess\n debugging?: boolean\n disableSponsorMessage?: boolean\n editorConfig?: { nodes: JSONSchema[] }\n fields?: Field[]\n /**\n * Defines default provider and models to be selected\n * when creating initial database records for Generation Defaults.\n */\n generationDefaults?: {\n image?: { model: string; provider: string }\n text?: { model: string; provider: string }\n tts?: { model: string; provider: string; voice?: string }\n video?: { model: string; provider: string }\n }\n generationModels?: ((defaultModels: GenerationModel[]) => GenerationModel[]) | GenerationModel[]\n globals?: {\n [key: GlobalConfig['slug']]: boolean\n }\n interfaceName?: string\n mediaUpload?: PluginConfigMediaUploadFunction\n options?: PluginOptions\n overrideInstructions?: any\n promptFields?: any[]\n prompts?: ActionPrompt[]\n /**\n * Pre-configured options that get passed directly to AI SDK providers.\n * This allows devs to define AI options safely via payload.config.ts.\n */\n providerOptions?: {\n [key: string]: Record<string, any> | undefined // generic fallback\n anthropic?: Record<string, any>\n elevenlabs?: Record<string, any>\n fal?: Record<string, any>\n google?: Record<string, any>\n openai?: Record<string, any>\n }\n /**\n * Custom seed prompt function for generating field-specific prompts\n * If not provided, fields will have empty prompts by default\n */\n seedPrompts?: SeedPromptFunction\n uploadCollectionSlug?: CollectionSlug\n}\n\nexport interface GenerationModel {\n fields: string[]\n generateText?: (prompt: string, system: string) => Promise<string>\n handler?: (prompt: string, options: any) => File | Promise<any> | Response\n id: string\n name: string\n output: 'audio' | 'file' | 'image' | 'json' | 'text' | 'video'\n settings?: GroupField\n supportsPromptOptimization?: boolean\n}\n\nexport interface GenerationConfig {\n models: GenerationModel[]\n provider: string\n}\n\nexport type GenerateTextarea<T = any> = (args: {\n collectionSlug: CollectionSlug\n doc: T\n documentId?: number | string\n locale?: string\n options?: any\n}) => Promise<string> | string\n\nexport interface Endpoints {\n fetchVoices?: Omit<Endpoint, 'root'>\n promptMentions: Endpoint\n textarea: Omit<Endpoint, 'root'>\n upload: Omit<Endpoint, 'root'>\n videogenWebhook?: Omit<Endpoint, 'root'>\n}\n\nexport type ActionMenuItems =\n | 'Compose'\n | 'Expand'\n | 'Proofread'\n | 'Rephrase'\n | 'Settings'\n | 'Simplify'\n | 'Summarize'\n | 'Tone'\n | 'Translate'\n\nexport type ActionPromptOptions = {\n layout?: string\n locale?: string\n prompt?: string\n systemPrompt?: string\n}\n\nexport type ActionPrompt = {\n layout?: (options?: ActionPromptOptions) => string\n name: ActionMenuItems\n system: (options: ActionPromptOptions) => string\n}\n\nexport type SeedPromptOptions = {\n fieldLabel: string\n fieldSchemaPaths: Record<string, any>\n fieldType: string\n path: string\n}\n\nexport type SeedPromptData = Omit<\n TypedCollection[typeof PLUGIN_INSTRUCTIONS_TABLE],\n 'createdAt' | 'id' | 'updatedAt'\n>\n\nexport type SeedPromptResult =\n | {\n data?: SeedPromptData\n }\n | {\n data?: SeedPromptData\n prompt: string\n system: string\n }\n | false\n | undefined\n | void\n\nexport type SeedPromptFunction = (\n options: SeedPromptOptions,\n) => Promise<SeedPromptResult> | SeedPromptResult\n\nexport type ImageReference = {\n data: Blob\n name: string\n size: number\n type: string\n url: string\n}\n\nexport type GenerateImageParams = {\n images?: ImageReference[]\n size?: ImageGenerateParams['size']\n style?: ImageGenerateParams['style']\n version?: ImageGenerateParams['model']\n}\n\nexport type SerializedPromptField = {\n collections?: CollectionSlug[]\n name: string\n}\n\nexport type PromptFieldGetterContext = {\n collection: CollectionSlug\n type: string\n}\n\nexport type PromptField = {\n // If not provided, the value will be returned from the data object as-is\n getter?: (data: object, ctx: PromptFieldGetterContext) => Promise<string> | string\n} & SerializedPromptField\n\nexport interface BeforeGenerateArgs<T = any> {\n doc: T\n field: Field\n headers: Record<string, string>\n instructions: Record<string, unknown> // The instruction document\n messages?: ModelMessage[]\n payload: PayloadRequest['payload']\n prompt: string\n req: PayloadRequest\n system: string\n}\n\nexport type BeforeGenerateResult = {\n messages?: ModelMessage[]\n prompt?: string\n system?: string\n} | void\n\nexport type BeforeGenerateHook<T = any> = (\n args: BeforeGenerateArgs<T>,\n) => BeforeGenerateResult | Promise<BeforeGenerateResult>\n\nexport interface AfterGenerateArgs<T = any> {\n doc: T\n field: Field\n headers: Record<string, string>\n instructions: Record<string, unknown>\n payload: PayloadRequest['payload']\n req: PayloadRequest\n result: GenerateObjectResult<any> | MediaResult | string // depends on context\n}\n\nexport type AfterGenerateHook<T = any> = (args: AfterGenerateArgs<T>) => Promise<void> | void\n\n// Add to PluginConfig or a new interface if accessed via custom.ai\nexport interface AIFieldConfig {\n [key: string]: unknown\n afterGenerate?: AfterGenerateHook[]\n /**\n * When true, the Compose button is always visible on this field,\n * bypassing the focus-based show/hide system.\n * Admin `disabled` in Instructions still takes priority.\n */\n alwaysShow?: boolean\n /**\n * When true and the field hasMany, generated values are appended\n * instead of replacing current field value(s).\n */\n appendGenerated?: boolean\n beforeGenerate?: BeforeGenerateHook[]\n /**\n * Default hidden state for Compose in instructions.\n * When true, Compose is hidden for this field.\n */\n disabled?: boolean\n /**\n * Set to false to opt-out of compose button injection for this field.\n * When false, no compose button is injected at build time.\n * @default true (compose is auto-injected on supported field types)\n */\n enabled?: boolean\n /** Custom prompt template for this field */\n prompt?: string\n /** Custom system prompt for this field */\n system?: string\n}\n"],"names":[],"mappings":"AA4PA,mEAAmE;AACnE,WA8BC"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { GenerateObjectResult, ModelMessage } from 'ai'\nimport type { JSONSchema } from 'openai/lib/jsonschema'\nimport type { ImageGenerateParams } from 'openai/resources/images'\nimport type {\n CollectionConfig,\n CollectionSlug,\n DataFromCollectionSlug,\n Endpoint,\n Field,\n File,\n GlobalConfig,\n GroupField,\n PayloadRequest,\n TypedCollection,\n} from 'payload'\n\nimport type { MediaResult } from './ai/core/index.js'\nimport type { PLUGIN_INSTRUCTIONS_TABLE } from './defaults.js'\n\nexport interface PluginConfigAccess {\n /**\n * Control access to AI generation features (generate text, images, audio)\n * @default () => !!req.user (requires authentication)\n */\n generate?: ({ req }: { req: PayloadRequest }) => boolean | Promise<boolean>\n /**\n * Control access to AI settings/configuration\n * @default () => !!req.user (requires authentication)\n */\n settings?: ({ req }: { req: PayloadRequest }) => boolean | Promise<boolean>\n}\n\nexport interface PluginOptions {\n /**\n * Provide local tags to filter language options from the Translate Menu\n * Check for the available local tags,\n * visit: https://www.npmjs.com/package/locale-codes\n * Example: [\"en-US\", \"zh-SG\", \"zh-CN\", \"en\"]\n */\n enabledLanguages?: string[]\n}\n\nexport type PluginConfigMediaUploadFunction = (\n result: MediaResult,\n {\n collection,\n request,\n }: {\n collection: CollectionSlug\n request: PayloadRequest\n },\n) => Promise<DataFromCollectionSlug<CollectionSlug>>\n\nexport interface PluginConfig {\n /**\n * Access control configuration for AI features\n * By default, all AI features require authentication\n */\n access?: PluginConfigAccess\n debugging?: boolean\n disableSponsorMessage?: boolean\n editorConfig?: { nodes: JSONSchema[] }\n /**\n * Optional runtime environment map for non-Node runtimes (Cloudflare Workers, Edge runtimes).\n * Values in this map are checked before `process.env` during provider auto-setup.\n */\n env?: Partial<Record<string, string>>\n fields?: Field[]\n /**\n * Defines default provider and models to be selected\n * when creating initial database records for Generation Defaults.\n */\n generationDefaults?: {\n image?: { model: string; provider: string }\n text?: { model: string; provider: string }\n tts?: { model: string; provider: string; voice?: string }\n video?: { model: string; provider: string }\n }\n generationModels?: ((defaultModels: GenerationModel[]) => GenerationModel[]) | GenerationModel[]\n /**\n * Optional runtime resolver for environment values.\n * Resolution order is: `getEnv` -> `env` -> `process.env`.\n */\n getEnv?: (key: string) => string | undefined\n globals?: {\n [key: GlobalConfig['slug']]: boolean\n }\n interfaceName?: string\n mediaUpload?: PluginConfigMediaUploadFunction\n options?: PluginOptions\n overrideInstructions?: any\n promptFields?: any[]\n prompts?: ActionPrompt[]\n /**\n * Pre-configured options that get passed directly to AI SDK providers.\n * This allows devs to define AI options safely via payload.config.ts.\n */\n providerOptions?: {\n [key: string]: Record<string, any> | undefined // generic fallback\n anthropic?: Record<string, any>\n elevenlabs?: Record<string, any>\n fal?: Record<string, any>\n google?: Record<string, any>\n openai?: Record<string, any>\n }\n /**\n * Custom seed prompt function for generating field-specific prompts\n * If not provided, fields will have empty prompts by default\n */\n seedPrompts?: SeedPromptFunction\n uploadCollectionSlug?: CollectionSlug\n}\n\nexport interface GenerationModel {\n fields: string[]\n generateText?: (prompt: string, system: string) => Promise<string>\n handler?: (prompt: string, options: any) => File | Promise<any> | Response\n id: string\n name: string\n output: 'audio' | 'file' | 'image' | 'json' | 'text' | 'video'\n settings?: GroupField\n supportsPromptOptimization?: boolean\n}\n\nexport interface GenerationConfig {\n models: GenerationModel[]\n provider: string\n}\n\nexport type GenerateTextarea<T = any> = (args: {\n collectionSlug: CollectionSlug\n doc: T\n documentId?: number | string\n locale?: string\n options?: any\n}) => Promise<string> | string\n\nexport interface Endpoints {\n fetchVoices?: Omit<Endpoint, 'root'>\n promptMentions: Endpoint\n textarea: Omit<Endpoint, 'root'>\n upload: Omit<Endpoint, 'root'>\n videogenWebhook?: Omit<Endpoint, 'root'>\n}\n\nexport type ActionMenuItems =\n | 'Compose'\n | 'Expand'\n | 'Proofread'\n | 'Rephrase'\n | 'Settings'\n | 'Simplify'\n | 'Summarize'\n | 'Tone'\n | 'Translate'\n\nexport type ActionPromptOptions = {\n layout?: string\n locale?: string\n prompt?: string\n systemPrompt?: string\n}\n\nexport type ActionPrompt = {\n layout?: (options?: ActionPromptOptions) => string\n name: ActionMenuItems\n system: (options: ActionPromptOptions) => string\n}\n\nexport type SeedPromptOptions = {\n fieldLabel: string\n fieldSchemaPaths: Record<string, any>\n fieldType: string\n path: string\n}\n\nexport type SeedPromptData = Omit<\n TypedCollection[typeof PLUGIN_INSTRUCTIONS_TABLE],\n 'createdAt' | 'id' | 'updatedAt'\n>\n\nexport type SeedPromptResult =\n | {\n data?: SeedPromptData\n }\n | {\n data?: SeedPromptData\n prompt: string\n system: string\n }\n | false\n | undefined\n | void\n\nexport type SeedPromptFunction = (\n options: SeedPromptOptions,\n) => Promise<SeedPromptResult> | SeedPromptResult\n\nexport type ImageReference = {\n data: Blob\n name: string\n size: number\n type: string\n url: string\n}\n\nexport type GenerateImageParams = {\n images?: ImageReference[]\n size?: ImageGenerateParams['size']\n style?: ImageGenerateParams['style']\n version?: ImageGenerateParams['model']\n}\n\nexport type SerializedPromptField = {\n collections?: CollectionSlug[]\n name: string\n}\n\nexport type PromptFieldGetterContext = {\n collection: CollectionSlug\n type: string\n}\n\nexport type PromptField = {\n // If not provided, the value will be returned from the data object as-is\n getter?: (data: object, ctx: PromptFieldGetterContext) => Promise<string> | string\n} & SerializedPromptField\n\nexport interface BeforeGenerateArgs<T = any> {\n doc: T\n field: Field\n headers: Record<string, string>\n instructions: Record<string, unknown> // The instruction document\n messages?: ModelMessage[]\n payload: PayloadRequest['payload']\n prompt: string\n req: PayloadRequest\n system: string\n}\n\nexport type BeforeGenerateResult = {\n messages?: ModelMessage[]\n prompt?: string\n system?: string\n} | void\n\nexport type BeforeGenerateHook<T = any> = (\n args: BeforeGenerateArgs<T>,\n) => BeforeGenerateResult | Promise<BeforeGenerateResult>\n\nexport interface AfterGenerateArgs<T = any> {\n doc: T\n field: Field\n headers: Record<string, string>\n instructions: Record<string, unknown>\n payload: PayloadRequest['payload']\n req: PayloadRequest\n result: GenerateObjectResult<any> | MediaResult | string // depends on context\n}\n\nexport type AfterGenerateHook<T = any> = (args: AfterGenerateArgs<T>) => Promise<void> | void\n\n// Add to PluginConfig or a new interface if accessed via custom.ai\nexport interface AIFieldConfig {\n [key: string]: unknown\n afterGenerate?: AfterGenerateHook[]\n /**\n * When true, the Compose button is always visible on this field,\n * bypassing the focus-based show/hide system.\n * Admin `disabled` in Instructions still takes priority.\n */\n alwaysShow?: boolean\n /**\n * When true and the field hasMany, generated values are appended\n * instead of replacing current field value(s).\n */\n appendGenerated?: boolean\n beforeGenerate?: BeforeGenerateHook[]\n /**\n * Default hidden state for Compose in instructions.\n * When true, Compose is hidden for this field.\n */\n disabled?: boolean\n /**\n * Set to false to opt-out of compose button injection for this field.\n * When false, no compose button is injected at build time.\n * @default true (compose is auto-injected on supported field types)\n */\n enabled?: boolean\n /** Custom prompt template for this field */\n prompt?: string\n /** Custom system prompt for this field */\n system?: string\n}\n"],"names":[],"mappings":"AAsQA,mEAAmE;AACnE,WA8BC"}
@@ -45,6 +45,21 @@ const providerKeys = {
45
45
  };
46
46
  export const autoSetupProviders = async (payload, config)=>{
47
47
  try {
48
+ const getEnvValue = (key)=>{
49
+ const fromResolver = config.getEnv?.(key);
50
+ if (typeof fromResolver === 'string' && fromResolver.length > 0) {
51
+ return fromResolver;
52
+ }
53
+ const fromMap = config.env?.[key];
54
+ if (typeof fromMap === 'string' && fromMap.length > 0) {
55
+ return fromMap;
56
+ }
57
+ const fromProcessEnv = process.env[key];
58
+ if (typeof fromProcessEnv === 'string' && fromProcessEnv.length > 0) {
59
+ return fromProcessEnv;
60
+ }
61
+ return undefined;
62
+ };
48
63
  const existing = await payload.findGlobal({
49
64
  slug: 'ai-providers'
50
65
  });
@@ -71,11 +86,12 @@ export const autoSetupProviders = async (payload, config)=>{
71
86
  };
72
87
  const { providerOptions } = config;
73
88
  // OpenAI Setup
74
- if (process.env[providerKeys.openai]) {
89
+ const openaiKey = getEnvValue(providerKeys.openai);
90
+ if (openaiKey) {
75
91
  const isAlreadyConfigured = existing.providers?.find((p)=>p.blockType === 'openai');
76
92
  if (!isAlreadyConfigured) {
77
93
  providersArray.push({
78
- apiKey: process.env[providerKeys.openai],
94
+ apiKey: openaiKey,
79
95
  blockType: 'openai',
80
96
  enabled: true,
81
97
  models: findModelsDefault(openaiBlock)
@@ -84,7 +100,7 @@ export const autoSetupProviders = async (payload, config)=>{
84
100
  }
85
101
  }
86
102
  // Google Setup
87
- const googleKey = process.env[providerKeys.google[0]] || process.env[providerKeys.google[1]];
103
+ const googleKey = getEnvValue(providerKeys.google[0]) || getEnvValue(providerKeys.google[1]);
88
104
  if (googleKey) {
89
105
  const isAlreadyConfigured = existing.providers?.find((p)=>p.blockType === 'google');
90
106
  if (!isAlreadyConfigured) {
@@ -98,11 +114,12 @@ export const autoSetupProviders = async (payload, config)=>{
98
114
  }
99
115
  }
100
116
  // Anthropic Setup
101
- if (process.env[providerKeys.anthropic]) {
117
+ const anthropicKey = getEnvValue(providerKeys.anthropic);
118
+ if (anthropicKey) {
102
119
  const isAlreadyConfigured = existing.providers?.find((p)=>p.blockType === 'anthropic');
103
120
  if (!isAlreadyConfigured) {
104
121
  providersArray.push({
105
- apiKey: process.env[providerKeys.anthropic],
122
+ apiKey: anthropicKey,
106
123
  blockType: 'anthropic',
107
124
  enabled: true,
108
125
  models: findModelsDefault(anthropicBlock)
@@ -111,11 +128,12 @@ export const autoSetupProviders = async (payload, config)=>{
111
128
  }
112
129
  }
113
130
  // ElevenLabs Setup
114
- if (process.env[providerKeys.elevenlabs]) {
131
+ const elevenlabsKey = getEnvValue(providerKeys.elevenlabs);
132
+ if (elevenlabsKey) {
115
133
  const isAlreadyConfigured = existing.providers?.find((p)=>p.blockType === 'elevenlabs');
116
134
  if (!isAlreadyConfigured) {
117
135
  providersArray.push({
118
- apiKey: process.env[providerKeys.elevenlabs],
136
+ apiKey: elevenlabsKey,
119
137
  blockType: 'elevenlabs',
120
138
  enabled: true,
121
139
  models: findModelsDefault(elevenlabsBlock)
@@ -124,11 +142,12 @@ export const autoSetupProviders = async (payload, config)=>{
124
142
  }
125
143
  }
126
144
  // XAI Setup
127
- if (process.env[providerKeys.xai]) {
145
+ const xaiKey = getEnvValue(providerKeys.xai);
146
+ if (xaiKey) {
128
147
  const isAlreadyConfigured = existing.providers?.find((p)=>p.blockType === 'xai');
129
148
  if (!isAlreadyConfigured) {
130
149
  providersArray.push({
131
- apiKey: process.env[providerKeys.xai],
150
+ apiKey: xaiKey,
132
151
  blockType: 'xai',
133
152
  enabled: true,
134
153
  models: findModelsDefault(xaiBlock)
@@ -137,11 +156,12 @@ export const autoSetupProviders = async (payload, config)=>{
137
156
  }
138
157
  }
139
158
  // Fal Setup
140
- if (process.env[providerKeys.fal]) {
159
+ const falKey = getEnvValue(providerKeys.fal);
160
+ if (falKey) {
141
161
  const isAlreadyConfigured = existing.providers?.find((p)=>p.blockType === 'fal');
142
162
  if (!isAlreadyConfigured) {
143
163
  providersArray.push({
144
- apiKey: process.env[providerKeys.fal],
164
+ apiKey: falKey,
145
165
  blockType: 'fal',
146
166
  enabled: true,
147
167
  models: findModelsDefault(falBlock)
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utilities/init/autoSetupProviders.ts"],"sourcesContent":["import type { Payload } from 'payload'\n\nimport type { PluginConfig } from '../../types.js'\n\nimport { anthropicBlock } from '../../ai/providers/blocks/anthropic.js'\nimport { elevenlabsBlock } from '../../ai/providers/blocks/elevenlabs.js'\nimport { falBlock } from '../../ai/providers/blocks/fal.js'\nimport { googleBlock } from '../../ai/providers/blocks/google.js'\nimport { openaiBlock } from '../../ai/providers/blocks/openai.js'\nimport { xaiBlock } from '../../ai/providers/blocks/xai.js'\n\n\nconst findModelsDefault = (block: any): any[] => {\n let defaultModels: any[] = []\n const search = (fields: any[]): boolean => {\n for (const f of fields) {\n if (f.name === 'models' && Array.isArray(f.defaultValue)) {\n defaultModels = f.defaultValue\n return true\n }\n if (f.tabs) {\n for (const t of f.tabs) {\n if (search(t.fields)) {\n return true\n }\n }\n }\n if (f.fields) {\n if (search(f.fields)) {\n return true\n }\n }\n }\n return false\n }\n if (block?.fields) {\n search(block.fields)\n }\n return defaultModels\n}\n\nconst providerKeys = {\n anthropic: 'ANTHROPIC_API_KEY',\n elevenlabs: 'ELEVENLABS_API_KEY',\n fal: 'FAL_KEY',\n google: ['GOOGLE_GENERATIVE_AI_API_KEY', 'GEMINI_API_KEY'],\n openai: 'OPENAI_API_KEY',\n xai: 'XAI_API_KEY',\n}\n\nexport const autoSetupProviders = async (payload: Payload, config: PluginConfig) => {\n try {\n const existing = await payload.findGlobal({ slug: 'ai-providers' })\n\n // Build the default array structure\n let initializedAny = false\n const providersArray: any[] = []\n const defaults = {\n image: existing.defaults?.image || { model: '', provider: '' },\n text: existing.defaults?.text || { model: '', provider: '' },\n tts: existing.defaults?.tts || { model: '', provider: '' },\n video: existing.defaults?.video || { model: '', provider: '' },\n }\n\n const { providerOptions } = config\n\n // OpenAI Setup\n if (process.env[providerKeys.openai]) {\n const isAlreadyConfigured = existing.providers?.find((p: any) => p.blockType === 'openai')\n if (!isAlreadyConfigured) {\n providersArray.push({\n apiKey: process.env[providerKeys.openai],\n blockType: 'openai',\n enabled: true,\n models: findModelsDefault(openaiBlock),\n })\n initializedAny = true\n }\n }\n\n // Google Setup\n const googleKey = process.env[providerKeys.google[0]] || process.env[providerKeys.google[1]]\n if (googleKey) {\n const isAlreadyConfigured = existing.providers?.find((p: any) => p.blockType === 'google')\n if (!isAlreadyConfigured) {\n providersArray.push({\n apiKey: googleKey,\n blockType: 'google',\n enabled: true,\n models: findModelsDefault(googleBlock),\n })\n initializedAny = true\n }\n }\n\n // Anthropic Setup\n if (process.env[providerKeys.anthropic]) {\n const isAlreadyConfigured = existing.providers?.find((p: any) => p.blockType === 'anthropic')\n if (!isAlreadyConfigured) {\n providersArray.push({\n apiKey: process.env[providerKeys.anthropic],\n blockType: 'anthropic',\n enabled: true,\n models: findModelsDefault(anthropicBlock),\n })\n initializedAny = true\n }\n }\n\n // ElevenLabs Setup\n if (process.env[providerKeys.elevenlabs]) {\n const isAlreadyConfigured = existing.providers?.find((p: any) => p.blockType === 'elevenlabs')\n if (!isAlreadyConfigured) {\n providersArray.push({\n apiKey: process.env[providerKeys.elevenlabs],\n blockType: 'elevenlabs',\n enabled: true,\n models: findModelsDefault(elevenlabsBlock),\n })\n initializedAny = true\n }\n }\n\n // XAI Setup\n if (process.env[providerKeys.xai]) {\n const isAlreadyConfigured = existing.providers?.find((p: any) => p.blockType === 'xai')\n if (!isAlreadyConfigured) {\n providersArray.push({\n apiKey: process.env[providerKeys.xai],\n blockType: 'xai',\n enabled: true,\n models: findModelsDefault(xaiBlock),\n })\n initializedAny = true\n }\n }\n\n // Fal Setup\n if (process.env[providerKeys.fal]) {\n const isAlreadyConfigured = existing.providers?.find((p: any) => p.blockType === 'fal')\n if (!isAlreadyConfigured) {\n providersArray.push({\n apiKey: process.env[providerKeys.fal],\n blockType: 'fal',\n enabled: true,\n models: findModelsDefault(falBlock),\n })\n initializedAny = true\n }\n }\n\n // Setup defaults globally regardless of whether providers were newly added or not\n const configuredProviders = [...(existing.providers || []), ...providersArray]\n if (configuredProviders.length > 0) {\n if (!defaults.text.provider && config.generationDefaults?.text) {\n defaults.text.provider = config.generationDefaults.text.provider\n defaults.text.model = config.generationDefaults.text.model\n initializedAny = true\n }\n \n const providerSchemaByProvider: Record<string, unknown> = {}\n for (const [providerName, options] of Object.entries(providerOptions || {})) {\n if (options && typeof options === 'object' && !Array.isArray(options)) {\n providerSchemaByProvider[providerName] = options\n }\n }\n\n if (!defaults.image.provider && config.generationDefaults?.image) {\n defaults.image.provider = config.generationDefaults.image.provider\n defaults.image.model = config.generationDefaults.image.model\n initializedAny = true\n }\n\n if (!defaults.tts.provider && config.generationDefaults?.tts) {\n defaults.tts.provider = config.generationDefaults.tts.provider\n defaults.tts.model = config.generationDefaults.tts.model\n defaults.tts.voice = config.generationDefaults.tts.voice\n initializedAny = true\n }\n\n if (!defaults.video.provider && config.generationDefaults?.video) {\n defaults.video.provider = config.generationDefaults.video.provider\n defaults.video.model = config.generationDefaults.video.model\n initializedAny = true\n }\n\n if (Object.keys(providerSchemaByProvider).length > 0) {\n const schemaForUseCases = JSON.stringify(providerSchemaByProvider)\n const useCases: Array<'image' | 'text' | 'tts' | 'video'> = ['text', 'image', 'tts', 'video']\n\n for (const useCase of useCases) {\n if (JSON.stringify(defaults[useCase].schema) !== schemaForUseCases) {\n defaults[useCase].schema = JSON.parse(schemaForUseCases)\n initializedAny = true\n }\n }\n }\n }\n\n if (initializedAny) {\n await payload.updateGlobal({\n slug: 'ai-providers',\n data: {\n defaults,\n providers: configuredProviders,\n },\n })\n payload.logger.info(\n `— AI Plugin: Auto-setup complete. Handled defaults for seeded providers.`,\n )\n }\n } catch (error) {\n payload.logger.warn(\n `— AI Plugin: Failed to auto-setup providers: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n}\n"],"names":["anthropicBlock","elevenlabsBlock","falBlock","googleBlock","openaiBlock","xaiBlock","findModelsDefault","block","defaultModels","search","fields","f","name","Array","isArray","defaultValue","tabs","t","providerKeys","anthropic","elevenlabs","fal","google","openai","xai","autoSetupProviders","payload","config","existing","findGlobal","slug","initializedAny","providersArray","defaults","image","model","provider","text","tts","video","providerOptions","process","env","isAlreadyConfigured","providers","find","p","blockType","push","apiKey","enabled","models","googleKey","configuredProviders","length","generationDefaults","providerSchemaByProvider","providerName","options","Object","entries","voice","keys","schemaForUseCases","JSON","stringify","useCases","useCase","schema","parse","updateGlobal","data","logger","info","error","warn","Error","message","String"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utilities/init/autoSetupProviders.ts"],"sourcesContent":["import type { Payload } from 'payload'\n\nimport type { PluginConfig } from '../../types.js'\n\nimport { anthropicBlock } from '../../ai/providers/blocks/anthropic.js'\nimport { elevenlabsBlock } from '../../ai/providers/blocks/elevenlabs.js'\nimport { falBlock } from '../../ai/providers/blocks/fal.js'\nimport { googleBlock } from '../../ai/providers/blocks/google.js'\nimport { openaiBlock } from '../../ai/providers/blocks/openai.js'\nimport { xaiBlock } from '../../ai/providers/blocks/xai.js'\n\n\nconst findModelsDefault = (block: any): any[] => {\n let defaultModels: any[] = []\n const search = (fields: any[]): boolean => {\n for (const f of fields) {\n if (f.name === 'models' && Array.isArray(f.defaultValue)) {\n defaultModels = f.defaultValue\n return true\n }\n if (f.tabs) {\n for (const t of f.tabs) {\n if (search(t.fields)) {\n return true\n }\n }\n }\n if (f.fields) {\n if (search(f.fields)) {\n return true\n }\n }\n }\n return false\n }\n if (block?.fields) {\n search(block.fields)\n }\n return defaultModels\n}\n\nconst providerKeys = {\n anthropic: 'ANTHROPIC_API_KEY',\n elevenlabs: 'ELEVENLABS_API_KEY',\n fal: 'FAL_KEY',\n google: ['GOOGLE_GENERATIVE_AI_API_KEY', 'GEMINI_API_KEY'],\n openai: 'OPENAI_API_KEY',\n xai: 'XAI_API_KEY',\n}\n\nexport const autoSetupProviders = async (payload: Payload, config: PluginConfig) => {\n try {\n const getEnvValue = (key: string): string | undefined => {\n const fromResolver = config.getEnv?.(key)\n if (typeof fromResolver === 'string' && fromResolver.length > 0) {\n return fromResolver\n }\n\n const fromMap = config.env?.[key]\n if (typeof fromMap === 'string' && fromMap.length > 0) {\n return fromMap\n }\n\n const fromProcessEnv = process.env[key]\n if (typeof fromProcessEnv === 'string' && fromProcessEnv.length > 0) {\n return fromProcessEnv\n }\n\n return undefined\n }\n\n const existing = await payload.findGlobal({ slug: 'ai-providers' })\n\n // Build the default array structure\n let initializedAny = false\n const providersArray: any[] = []\n const defaults = {\n image: existing.defaults?.image || { model: '', provider: '' },\n text: existing.defaults?.text || { model: '', provider: '' },\n tts: existing.defaults?.tts || { model: '', provider: '' },\n video: existing.defaults?.video || { model: '', provider: '' },\n }\n\n const { providerOptions } = config\n\n // OpenAI Setup\n const openaiKey = getEnvValue(providerKeys.openai)\n if (openaiKey) {\n const isAlreadyConfigured = existing.providers?.find((p: any) => p.blockType === 'openai')\n if (!isAlreadyConfigured) {\n providersArray.push({\n apiKey: openaiKey,\n blockType: 'openai',\n enabled: true,\n models: findModelsDefault(openaiBlock),\n })\n initializedAny = true\n }\n }\n\n // Google Setup\n const googleKey = getEnvValue(providerKeys.google[0]) || getEnvValue(providerKeys.google[1])\n if (googleKey) {\n const isAlreadyConfigured = existing.providers?.find((p: any) => p.blockType === 'google')\n if (!isAlreadyConfigured) {\n providersArray.push({\n apiKey: googleKey,\n blockType: 'google',\n enabled: true,\n models: findModelsDefault(googleBlock),\n })\n initializedAny = true\n }\n }\n\n // Anthropic Setup\n const anthropicKey = getEnvValue(providerKeys.anthropic)\n if (anthropicKey) {\n const isAlreadyConfigured = existing.providers?.find((p: any) => p.blockType === 'anthropic')\n if (!isAlreadyConfigured) {\n providersArray.push({\n apiKey: anthropicKey,\n blockType: 'anthropic',\n enabled: true,\n models: findModelsDefault(anthropicBlock),\n })\n initializedAny = true\n }\n }\n\n // ElevenLabs Setup\n const elevenlabsKey = getEnvValue(providerKeys.elevenlabs)\n if (elevenlabsKey) {\n const isAlreadyConfigured = existing.providers?.find((p: any) => p.blockType === 'elevenlabs')\n if (!isAlreadyConfigured) {\n providersArray.push({\n apiKey: elevenlabsKey,\n blockType: 'elevenlabs',\n enabled: true,\n models: findModelsDefault(elevenlabsBlock),\n })\n initializedAny = true\n }\n }\n\n // XAI Setup\n const xaiKey = getEnvValue(providerKeys.xai)\n if (xaiKey) {\n const isAlreadyConfigured = existing.providers?.find((p: any) => p.blockType === 'xai')\n if (!isAlreadyConfigured) {\n providersArray.push({\n apiKey: xaiKey,\n blockType: 'xai',\n enabled: true,\n models: findModelsDefault(xaiBlock),\n })\n initializedAny = true\n }\n }\n\n // Fal Setup\n const falKey = getEnvValue(providerKeys.fal)\n if (falKey) {\n const isAlreadyConfigured = existing.providers?.find((p: any) => p.blockType === 'fal')\n if (!isAlreadyConfigured) {\n providersArray.push({\n apiKey: falKey,\n blockType: 'fal',\n enabled: true,\n models: findModelsDefault(falBlock),\n })\n initializedAny = true\n }\n }\n\n // Setup defaults globally regardless of whether providers were newly added or not\n const configuredProviders = [...(existing.providers || []), ...providersArray]\n if (configuredProviders.length > 0) {\n if (!defaults.text.provider && config.generationDefaults?.text) {\n defaults.text.provider = config.generationDefaults.text.provider\n defaults.text.model = config.generationDefaults.text.model\n initializedAny = true\n }\n \n const providerSchemaByProvider: Record<string, unknown> = {}\n for (const [providerName, options] of Object.entries(providerOptions || {})) {\n if (options && typeof options === 'object' && !Array.isArray(options)) {\n providerSchemaByProvider[providerName] = options\n }\n }\n\n if (!defaults.image.provider && config.generationDefaults?.image) {\n defaults.image.provider = config.generationDefaults.image.provider\n defaults.image.model = config.generationDefaults.image.model\n initializedAny = true\n }\n\n if (!defaults.tts.provider && config.generationDefaults?.tts) {\n defaults.tts.provider = config.generationDefaults.tts.provider\n defaults.tts.model = config.generationDefaults.tts.model\n defaults.tts.voice = config.generationDefaults.tts.voice\n initializedAny = true\n }\n\n if (!defaults.video.provider && config.generationDefaults?.video) {\n defaults.video.provider = config.generationDefaults.video.provider\n defaults.video.model = config.generationDefaults.video.model\n initializedAny = true\n }\n\n if (Object.keys(providerSchemaByProvider).length > 0) {\n const schemaForUseCases = JSON.stringify(providerSchemaByProvider)\n const useCases: Array<'image' | 'text' | 'tts' | 'video'> = ['text', 'image', 'tts', 'video']\n\n for (const useCase of useCases) {\n if (JSON.stringify(defaults[useCase].schema) !== schemaForUseCases) {\n defaults[useCase].schema = JSON.parse(schemaForUseCases)\n initializedAny = true\n }\n }\n }\n }\n\n if (initializedAny) {\n await payload.updateGlobal({\n slug: 'ai-providers',\n data: {\n defaults,\n providers: configuredProviders,\n },\n })\n payload.logger.info(\n `— AI Plugin: Auto-setup complete. Handled defaults for seeded providers.`,\n )\n }\n } catch (error) {\n payload.logger.warn(\n `— AI Plugin: Failed to auto-setup providers: ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n}\n"],"names":["anthropicBlock","elevenlabsBlock","falBlock","googleBlock","openaiBlock","xaiBlock","findModelsDefault","block","defaultModels","search","fields","f","name","Array","isArray","defaultValue","tabs","t","providerKeys","anthropic","elevenlabs","fal","google","openai","xai","autoSetupProviders","payload","config","getEnvValue","key","fromResolver","getEnv","length","fromMap","env","fromProcessEnv","process","undefined","existing","findGlobal","slug","initializedAny","providersArray","defaults","image","model","provider","text","tts","video","providerOptions","openaiKey","isAlreadyConfigured","providers","find","p","blockType","push","apiKey","enabled","models","googleKey","anthropicKey","elevenlabsKey","xaiKey","falKey","configuredProviders","generationDefaults","providerSchemaByProvider","providerName","options","Object","entries","voice","keys","schemaForUseCases","JSON","stringify","useCases","useCase","schema","parse","updateGlobal","data","logger","info","error","warn","Error","message","String"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-stack/payloadcms",
3
- "version": "3.76.0-beta.4",
3
+ "version": "3.76.0-beta.5",
4
4
  "private": false,
5
5
  "bugs": "https://github.com/ashbuilds/payload-ai/issues",
6
6
  "repository": "https://github.com/ashbuilds/payload-ai",