@ai-stack/payloadcms 3.2.14-beta → 3.2.16-beta
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 +18 -2
- package/dist/ai/utils/filterEditorSchemaByNodes.js +1 -2
- package/dist/ai/utils/filterEditorSchemaByNodes.js.map +1 -1
- package/dist/collections/Instructions.d.ts.map +1 -1
- package/dist/collections/Instructions.js +26 -5
- package/dist/collections/Instructions.js.map +1 -1
- package/dist/endpoints/fetchFields.d.ts +2 -2
- package/dist/endpoints/fetchFields.d.ts.map +1 -1
- package/dist/endpoints/fetchFields.js +2 -1
- package/dist/endpoints/fetchFields.js.map +1 -1
- package/dist/endpoints/index.d.ts.map +1 -1
- package/dist/endpoints/index.js +196 -140
- package/dist/endpoints/index.js.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +27 -2
- package/dist/plugin.js.map +1 -1
- package/dist/providers/InstructionsProvider/InstructionsProvider.d.ts +1 -0
- package/dist/providers/InstructionsProvider/InstructionsProvider.d.ts.map +1 -1
- package/dist/providers/InstructionsProvider/InstructionsProvider.js +3 -0
- package/dist/providers/InstructionsProvider/InstructionsProvider.js.map +1 -1
- package/dist/types.d.ts +25 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui/Compose/hooks/menu/TranslateMenu.d.ts +4 -0
- package/dist/ui/Compose/hooks/menu/TranslateMenu.d.ts.map +1 -1
- package/dist/ui/Compose/hooks/menu/TranslateMenu.js +9 -4
- package/dist/ui/Compose/hooks/menu/TranslateMenu.js.map +1 -1
- package/dist/ui/Compose/hooks/menu/itemsMap.js +2 -2
- package/dist/ui/Compose/hooks/menu/itemsMap.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,10 +47,10 @@ Want to dive deeper?
|
|
|
47
47
|
- 🎛️ **Field-level Prompt Customization**
|
|
48
48
|
- 🔐 **Access Control Support**
|
|
49
49
|
- 🧠 **Prompt Editor**
|
|
50
|
+
- 🌍 **Internationalization Support**
|
|
50
51
|
- 📊 **Document Analyzer** (Coming Soon)
|
|
51
52
|
- ✅ **Fact Checking** (Coming Soon)
|
|
52
53
|
- 🔄 **Automated Content Workflows** (Coming Soon)
|
|
53
|
-
- 🌍 **Internationalization Support** (Coming Soon)
|
|
54
54
|
- 🌍 **Editor AI suggestions** (Coming Soon)
|
|
55
55
|
- 💬 **AI Chat Support** (Coming Soon)
|
|
56
56
|
|
|
@@ -154,6 +154,11 @@ export default buildConfig({
|
|
|
154
154
|
[Posts.slug]: true,
|
|
155
155
|
},
|
|
156
156
|
|
|
157
|
+
// Optional
|
|
158
|
+
globals: {
|
|
159
|
+
[Home.slug]: true,
|
|
160
|
+
},
|
|
161
|
+
|
|
157
162
|
// Optional: Show debug logs to list AI-enabled fields
|
|
158
163
|
debugging: false,
|
|
159
164
|
|
|
@@ -166,11 +171,22 @@ export default buildConfig({
|
|
|
166
171
|
// Optional: Specify the media collection used by the gpt-image-1 model to reference images (defaults to media)
|
|
167
172
|
uploadCollectionSlug: "media",
|
|
168
173
|
|
|
169
|
-
// Optional:
|
|
174
|
+
// Optional: Access control for AI features
|
|
170
175
|
access: {
|
|
176
|
+
// Control who can generate AI content
|
|
177
|
+
generate: ({ req }) => req.user?.role === 'admin',
|
|
178
|
+
|
|
179
|
+
// Control who can modify AI settings and prompts
|
|
171
180
|
settings: ({ req }) => req.user?.role === 'admin',
|
|
172
181
|
},
|
|
173
182
|
|
|
183
|
+
options: {
|
|
184
|
+
// Visit locale-codes for tags,
|
|
185
|
+
// defaults to display all language options for Translate feature
|
|
186
|
+
// https://www.npmjs.com/package/locale-codes
|
|
187
|
+
enabledLanguages: ["en-US", "zh-SG", "zh-CN", "en"],
|
|
188
|
+
},
|
|
189
|
+
|
|
174
190
|
// Optional: Custom media upload handling, useful for multi-tenant setups
|
|
175
191
|
mediaUpload: async (result, { request, collection }) => {
|
|
176
192
|
return request.payload.create({
|
|
@@ -7,8 +7,7 @@ export function filterEditorSchemaByNodes(schema, allowedNodes) {
|
|
|
7
7
|
if (isObjectSchema(def)) {
|
|
8
8
|
const typeEnum = def.properties?.type?.enum;
|
|
9
9
|
if (typeEnum && typeEnum.some((t)=>allowedTypes.has(t))) {
|
|
10
|
-
filteredDefinitions[key] = JSON.parse(JSON.stringify(def)) // Deep copy to safely mutate
|
|
11
|
-
;
|
|
10
|
+
filteredDefinitions[key] = JSON.parse(JSON.stringify(def)); // Deep copy to safely mutate
|
|
12
11
|
}
|
|
13
12
|
}
|
|
14
13
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/ai/utils/filterEditorSchemaByNodes.ts"],"sourcesContent":["import type { LexicalNodeSchema } from '../schemas/lexicalJsonSchema.js'\n\nimport { isObjectSchema } from './isObjectSchema.js'\n\nexport function filterEditorSchemaByNodes(schema: LexicalNodeSchema, allowedNodes) {\n const allowedTypes = new Set(allowedNodes)\n\n const filteredDefinitions = {}\n\n // First pass: collect definitions whose \"type.enum\" includes an allowed type\n for (const [key, def] of Object.entries(schema.definitions)) {\n if(isObjectSchema(def)) {\n const typeEnum = def.properties?.type?.enum\n if (typeEnum && typeEnum.some((t) => allowedTypes.has(t))) {\n filteredDefinitions[key] = JSON.parse(JSON.stringify(def)) // Deep copy to safely mutate\n }\n }\n }\n\n // Helper to check if a $ref points to an allowed definition\n const isAllowedRef = (ref) => {\n if (typeof ref !== 'string') return false\n const defName = ref.replace('#/definitions/', '')\n return defName in filteredDefinitions\n }\n\n // Second pass: update \"children\" in each definition to only include allowed refs\n for (const def of Object.values(filteredDefinitions)) {\n if (isObjectSchema(def) && def.properties?.children?.items) {\n const items = def.properties.children.items\n\n if (Array.isArray(items.anyOf)) {\n // Filter anyOf to only allowed $refs\n items.anyOf = items.anyOf.filter((entry) => isAllowedRef(entry.$ref))\n if (items.anyOf.length === 0) {\n delete def.properties.children\n }\n } else if (items.$ref && !isAllowedRef(items.$ref)) {\n delete def.properties.children\n }\n }\n }\n\n // Return the new schema with pruned definitions\n return {\n ...schema,\n definitions: filteredDefinitions,\n }\n}\n"],"names":["isObjectSchema","filterEditorSchemaByNodes","schema","allowedNodes","allowedTypes","Set","filteredDefinitions","key","def","Object","entries","definitions","typeEnum","properties","type","enum","some","t","has","JSON","parse","stringify","isAllowedRef","ref","defName","replace","values","children","items","Array","isArray","anyOf","filter","entry","$ref","length"],"mappings":"AAEA,SAASA,cAAc,QAAQ,sBAAqB;AAEpD,OAAO,SAASC,0BAA0BC,MAAyB,EAAEC,YAAY;IAC/E,MAAMC,eAAe,IAAIC,IAAIF;IAE7B,MAAMG,sBAAsB,CAAC;IAE7B,6EAA6E;IAC7E,KAAK,MAAM,CAACC,KAAKC,IAAI,IAAIC,OAAOC,OAAO,CAACR,OAAOS,WAAW,EAAG;QAC3D,IAAGX,eAAeQ,MAAM;YACtB,MAAMI,WAAWJ,IAAIK,UAAU,EAAEC,MAAMC;YACvC,IAAIH,YAAYA,SAASI,IAAI,CAAC,CAACC,IAAMb,aAAac,GAAG,CAACD,KAAK;gBACzDX,mBAAmB,CAACC,IAAI,GAAGY,KAAKC,KAAK,CAACD,KAAKE,SAAS,CAACb,
|
|
1
|
+
{"version":3,"sources":["../../../src/ai/utils/filterEditorSchemaByNodes.ts"],"sourcesContent":["import type { LexicalNodeSchema } from '../schemas/lexicalJsonSchema.js'\n\nimport { isObjectSchema } from './isObjectSchema.js'\n\nexport function filterEditorSchemaByNodes(schema: LexicalNodeSchema, allowedNodes) {\n const allowedTypes = new Set(allowedNodes)\n\n const filteredDefinitions = {}\n\n // First pass: collect definitions whose \"type.enum\" includes an allowed type\n for (const [key, def] of Object.entries(schema.definitions)) {\n if(isObjectSchema(def)) {\n const typeEnum = def.properties?.type?.enum\n if (typeEnum && typeEnum.some((t) => allowedTypes.has(t))) {\n filteredDefinitions[key] = JSON.parse(JSON.stringify(def)) // Deep copy to safely mutate\n }\n }\n }\n\n // Helper to check if a $ref points to an allowed definition\n const isAllowedRef = (ref) => {\n if (typeof ref !== 'string') return false\n const defName = ref.replace('#/definitions/', '')\n return defName in filteredDefinitions\n }\n\n // Second pass: update \"children\" in each definition to only include allowed refs\n for (const def of Object.values(filteredDefinitions)) {\n if (isObjectSchema(def) && def.properties?.children?.items) {\n const items = def.properties.children.items\n\n if (Array.isArray(items.anyOf)) {\n // Filter anyOf to only allowed $refs\n items.anyOf = items.anyOf.filter((entry) => isAllowedRef(entry.$ref))\n if (items.anyOf.length === 0) {\n delete def.properties.children\n }\n } else if (items.$ref && !isAllowedRef(items.$ref)) {\n delete def.properties.children\n }\n }\n }\n\n // Return the new schema with pruned definitions\n return {\n ...schema,\n definitions: filteredDefinitions,\n }\n}\n"],"names":["isObjectSchema","filterEditorSchemaByNodes","schema","allowedNodes","allowedTypes","Set","filteredDefinitions","key","def","Object","entries","definitions","typeEnum","properties","type","enum","some","t","has","JSON","parse","stringify","isAllowedRef","ref","defName","replace","values","children","items","Array","isArray","anyOf","filter","entry","$ref","length"],"mappings":"AAEA,SAASA,cAAc,QAAQ,sBAAqB;AAEpD,OAAO,SAASC,0BAA0BC,MAAyB,EAAEC,YAAY;IAC/E,MAAMC,eAAe,IAAIC,IAAIF;IAE7B,MAAMG,sBAAsB,CAAC;IAE7B,6EAA6E;IAC7E,KAAK,MAAM,CAACC,KAAKC,IAAI,IAAIC,OAAOC,OAAO,CAACR,OAAOS,WAAW,EAAG;QAC3D,IAAGX,eAAeQ,MAAM;YACtB,MAAMI,WAAWJ,IAAIK,UAAU,EAAEC,MAAMC;YACvC,IAAIH,YAAYA,SAASI,IAAI,CAAC,CAACC,IAAMb,aAAac,GAAG,CAACD,KAAK;gBACzDX,mBAAmB,CAACC,IAAI,GAAGY,KAAKC,KAAK,CAACD,KAAKE,SAAS,CAACb,OAAM,6BAA6B;YAC1F;QACF;IACF;IAEA,4DAA4D;IAC5D,MAAMc,eAAe,CAACC;QACpB,IAAI,OAAOA,QAAQ,UAAU,OAAO;QACpC,MAAMC,UAAUD,IAAIE,OAAO,CAAC,kBAAkB;QAC9C,OAAOD,WAAWlB;IACpB;IAEA,iFAAiF;IACjF,KAAK,MAAME,OAAOC,OAAOiB,MAAM,CAACpB,qBAAsB;QACpD,IAAIN,eAAeQ,QAAQA,IAAIK,UAAU,EAAEc,UAAUC,OAAO;YAC1D,MAAMA,QAAQpB,IAAIK,UAAU,CAACc,QAAQ,CAACC,KAAK;YAE3C,IAAIC,MAAMC,OAAO,CAACF,MAAMG,KAAK,GAAG;gBAC9B,qCAAqC;gBACrCH,MAAMG,KAAK,GAAGH,MAAMG,KAAK,CAACC,MAAM,CAAC,CAACC,QAAUX,aAAaW,MAAMC,IAAI;gBACnE,IAAIN,MAAMG,KAAK,CAACI,MAAM,KAAK,GAAG;oBAC5B,OAAO3B,IAAIK,UAAU,CAACc,QAAQ;gBAChC;YACF,OAAO,IAAIC,MAAMM,IAAI,IAAI,CAACZ,aAAaM,MAAMM,IAAI,GAAG;gBAClD,OAAO1B,IAAIK,UAAU,CAACc,QAAQ;YAChC;QACF;IACF;IAEA,gDAAgD;IAChD,OAAO;QACL,GAAGzB,MAAM;QACTS,aAAaL;IACf;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Instructions.d.ts","sourceRoot":"","sources":["../../src/collections/Instructions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,SAAS,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"Instructions.d.ts","sourceRoot":"","sources":["../../src/collections/Instructions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,SAAS,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAsDhD,eAAO,MAAM,sBAAsB,GACjC,cAAc,YAAY,EAC1B,UAAU,OAAO,CAAC,gBAAgB,CAAC,KAElC,gBAgMA,CAAA"}
|
|
@@ -14,9 +14,30 @@ const modelOptions = (pluginConfig)=>getGenerationModels(pluginConfig).map((mode
|
|
|
14
14
|
};
|
|
15
15
|
});
|
|
16
16
|
const defaultAccessConfig = {
|
|
17
|
-
create: ()=>
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
create: ({ req })=>{
|
|
18
|
+
if (!req.user) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return true;
|
|
22
|
+
},
|
|
23
|
+
delete: ({ req })=>{
|
|
24
|
+
if (!req.user) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
},
|
|
29
|
+
read: ({ req })=>{
|
|
30
|
+
if (!req.user) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
return true;
|
|
34
|
+
},
|
|
35
|
+
update: ({ req })=>{
|
|
36
|
+
if (!req.user) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
20
41
|
};
|
|
21
42
|
const defaultAdminConfig = {
|
|
22
43
|
group: 'Plugins',
|
|
@@ -38,7 +59,7 @@ export const instructionsCollection = (pluginConfig, options)=>({
|
|
|
38
59
|
name: 'schema-path',
|
|
39
60
|
type: 'text',
|
|
40
61
|
admin: {
|
|
41
|
-
description: "Please don
|
|
62
|
+
description: "Please don't change this unless you're sure of what you're doing"
|
|
42
63
|
},
|
|
43
64
|
unique: true
|
|
44
65
|
},
|
|
@@ -46,7 +67,7 @@ export const instructionsCollection = (pluginConfig, options)=>({
|
|
|
46
67
|
name: 'field-type',
|
|
47
68
|
type: 'select',
|
|
48
69
|
admin: {
|
|
49
|
-
description: "Please don
|
|
70
|
+
description: "Please don't change this unless you're sure of what you're doing"
|
|
50
71
|
},
|
|
51
72
|
defaultValue: 'text',
|
|
52
73
|
label: 'Field type',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/collections/Instructions.ts"],"sourcesContent":["import type { CollectionConfig, GroupField } from 'payload'\nimport type { PluginConfig } from 'src/types.js'\n\nimport { PLUGIN_INSTRUCTIONS_TABLE } from '../defaults.js'\nimport { getGenerationModels } from '../utilities/getGenerationModels.js'\n\nconst groupSettings = (pluginConfig: PluginConfig) =>\n getGenerationModels(pluginConfig).reduce((fields, model) => {\n if (model.settings) {\n fields.push(model.settings)\n }\n return fields\n }, [] as GroupField[])\n\nconst modelOptions = (pluginConfig: PluginConfig) =>\n getGenerationModels(pluginConfig).map((model) => {\n return {\n fields: model.fields,\n label: model.name,\n value: model.id,\n }\n })\n\nconst defaultAccessConfig = {\n create: () => true,\n read: () => true,\n update: () => true,\n}\n\nconst defaultAdminConfig = {\n group: 'Plugins',\n hidden: true,\n}\n\nexport const instructionsCollection = (\n pluginConfig: PluginConfig,\n options?: Partial<CollectionConfig>,\n) =>\n <CollectionConfig>{\n slug: PLUGIN_INSTRUCTIONS_TABLE,\n access: {\n ...defaultAccessConfig,\n ...options?.access,\n },\n admin: {\n ...defaultAdminConfig,\n ...options?.admin,\n group: 'Plugins',\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 },\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 },\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 },\n {\n name: 'relation-to',\n type: 'text',\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'upload'\n },\n },\n label: 'Relation to',\n },\n {\n name: 'model-id',\n type: 'select',\n admin: {\n components: {\n Field: {\n clientProps: {\n filterByField: 'field-type',\n options: modelOptions(pluginConfig),\n },\n path: '@ai-stack/payloadcms/fields#SelectField',\n },\n },\n },\n label: 'Model',\n options: modelOptions(pluginConfig).map((option) => {\n return {\n label: option.label,\n value: option.value,\n }\n }),\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 {\n name: 'prompt',\n type: 'textarea',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/fields#PromptEditorField',\n },\n description: \"Click 'Compose' to run this custom prompt and generate content\",\n },\n label: '',\n },\n ],\n label: 'Prompt',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'upload' && current['model-id'] === 'gpt-image-1'\n },\n },\n description:\n 'These images will be used to generate new visuals in a similar style, layout, or content. You can combine multiple references for more controlled results.',\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 /** TODO:\n * - Layouts can be saved in as an array\n * - User can add their own layout to collections and use it later for generate specific rich text\n * - User can select previously added layout\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 ...groupSettings(pluginConfig),\n ],\n labels: {\n plural: 'Compose Settings',\n singular: 'Compose Setting',\n },\n }\n"],"names":["PLUGIN_INSTRUCTIONS_TABLE","getGenerationModels","groupSettings","pluginConfig","reduce","fields","model","settings","push","modelOptions","map","label","name","value","id","defaultAccessConfig","create","read","update","defaultAdminConfig","group","hidden","instructionsCollection","options","slug","access","admin","type","description","unique","defaultValue","condition","_","current","components","Field","clientProps","filterByField","path","option","tabs","relationTo","uploadCollectionSlug","labels","plural","singular"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/collections/Instructions.ts"],"sourcesContent":["import type { CollectionConfig, GroupField } from 'payload'\nimport type { PluginConfig } from 'src/types.js'\n\nimport { PLUGIN_INSTRUCTIONS_TABLE } from '../defaults.js'\nimport { getGenerationModels } from '../utilities/getGenerationModels.js'\n\nconst groupSettings = (pluginConfig: PluginConfig) =>\n getGenerationModels(pluginConfig).reduce((fields, model) => {\n if (model.settings) {\n fields.push(model.settings)\n }\n return fields\n }, [] as GroupField[])\n\nconst modelOptions = (pluginConfig: PluginConfig) =>\n getGenerationModels(pluginConfig).map((model) => {\n return {\n fields: model.fields,\n label: model.name,\n value: model.id,\n }\n })\n\nconst defaultAccessConfig = {\n create: ({ req }) => {\n if (!req.user) {\n return false\n }\n return true\n },\n delete: ({ req }) => {\n if (!req.user) {\n return false\n }\n return true\n },\n read: ({ req }) => {\n if (!req.user) {\n return false\n }\n return true\n },\n update: ({ req }) => {\n if (!req.user) {\n return false\n }\n return true\n },\n}\n\nconst defaultAdminConfig = {\n group: 'Plugins',\n hidden: true,\n}\n\nexport const instructionsCollection = (\n pluginConfig: PluginConfig,\n options?: Partial<CollectionConfig>,\n) =>\n <CollectionConfig>{\n slug: PLUGIN_INSTRUCTIONS_TABLE,\n access: {\n ...defaultAccessConfig,\n ...options?.access,\n },\n admin: {\n ...defaultAdminConfig,\n ...options?.admin,\n group: 'Plugins',\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 },\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 },\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 },\n {\n name: 'relation-to',\n type: 'text',\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'upload'\n },\n },\n label: 'Relation to',\n },\n {\n name: 'model-id',\n type: 'select',\n admin: {\n components: {\n Field: {\n clientProps: {\n filterByField: 'field-type',\n options: modelOptions(pluginConfig),\n },\n path: '@ai-stack/payloadcms/fields#SelectField',\n },\n },\n },\n label: 'Model',\n options: modelOptions(pluginConfig).map((option) => {\n return {\n label: option.label,\n value: option.value,\n }\n }),\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 {\n name: 'prompt',\n type: 'textarea',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/fields#PromptEditorField',\n },\n description: \"Click 'Compose' to run this custom prompt and generate content\",\n },\n label: '',\n },\n ],\n label: 'Prompt',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'upload' && current['model-id'] === 'gpt-image-1'\n },\n },\n description:\n 'These images will be used to generate new visuals in a similar style, layout, or content. You can combine multiple references for more controlled results.',\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 /** TODO:\n * - Layouts can be saved in as an array\n * - User can add their own layout to collections and use it later for generate specific rich text\n * - User can select previously added layout\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 ...groupSettings(pluginConfig),\n ],\n labels: {\n plural: 'Compose Settings',\n singular: 'Compose Setting',\n },\n }\n"],"names":["PLUGIN_INSTRUCTIONS_TABLE","getGenerationModels","groupSettings","pluginConfig","reduce","fields","model","settings","push","modelOptions","map","label","name","value","id","defaultAccessConfig","create","req","user","delete","read","update","defaultAdminConfig","group","hidden","instructionsCollection","options","slug","access","admin","type","description","unique","defaultValue","condition","_","current","components","Field","clientProps","filterByField","path","option","tabs","relationTo","uploadCollectionSlug","labels","plural","singular"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Endpoint } from 'payload';
|
|
2
|
-
import type { PluginConfigAccess } from '../types.js';
|
|
3
|
-
export declare const fetchFields: (access: PluginConfigAccess) => Endpoint;
|
|
2
|
+
import type { PluginConfigAccess, PluginOptions } from '../types.js';
|
|
3
|
+
export declare const fetchFields: (access: PluginConfigAccess, options?: PluginOptions) => Endpoint;
|
|
4
4
|
//# sourceMappingURL=fetchFields.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchFields.d.ts","sourceRoot":"","sources":["../../src/endpoints/fetchFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAkB,MAAM,SAAS,CAAA;AAEvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"fetchFields.d.ts","sourceRoot":"","sources":["../../src/endpoints/fetchFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAkB,MAAM,SAAS,CAAA;AAEvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAIpE,eAAO,MAAM,WAAW,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,aAAa,KAAK,QAsClF,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PLUGIN_FETCH_FIELDS_ENDPOINT, PLUGIN_INSTRUCTIONS_TABLE } from '../defaults.js';
|
|
2
|
-
export const fetchFields = (access)=>{
|
|
2
|
+
export const fetchFields = (access, options = {})=>{
|
|
3
3
|
return {
|
|
4
4
|
handler: async (req)=>{
|
|
5
5
|
const { docs = [] } = await req.payload.find({
|
|
@@ -25,6 +25,7 @@ export const fetchFields = (access)=>{
|
|
|
25
25
|
};
|
|
26
26
|
});
|
|
27
27
|
return Response.json({
|
|
28
|
+
...options,
|
|
28
29
|
fields: fieldMap,
|
|
29
30
|
isConfigAllowed
|
|
30
31
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/endpoints/fetchFields.ts"],"sourcesContent":["import type { Endpoint, PayloadRequest } from 'payload'\n\nimport type { PluginConfigAccess } from '../types.js'\n\nimport { PLUGIN_FETCH_FIELDS_ENDPOINT, PLUGIN_INSTRUCTIONS_TABLE } from '../defaults.js'\n\nexport const fetchFields: (access: PluginConfigAccess) => Endpoint = (access) => {\n return {\n handler: async (req: PayloadRequest) => {\n const { docs = [] } = await req.payload.find({\n collection: PLUGIN_INSTRUCTIONS_TABLE,\n pagination: false,\n })\n\n let isConfigAllowed = true // Users allowed to update prompts by default\n\n if (access?.settings) {\n try {\n isConfigAllowed = await access.settings({ req })\n } catch (e) {\n req.payload.logger.error('Please check your \"access.settings\" for request:', req)\n }\n }\n\n const fieldMap = {}\n docs.forEach((doc) => {\n fieldMap[doc['schema-path']] = {\n id: doc.id,\n fieldType: doc['field-type'],\n }\n })\n\n return Response.json({\n fields: fieldMap,\n isConfigAllowed,\n })\n },\n method: 'get',\n path: PLUGIN_FETCH_FIELDS_ENDPOINT,\n }\n}\n"],"names":["PLUGIN_FETCH_FIELDS_ENDPOINT","PLUGIN_INSTRUCTIONS_TABLE","fetchFields","access","handler","req","docs","payload","find","collection","pagination","isConfigAllowed","settings","e","logger","error","fieldMap","forEach","doc","id","fieldType","Response","json","fields","method","path"],"mappings":"AAIA,SAASA,4BAA4B,EAAEC,yBAAyB,QAAQ,iBAAgB;AAExF,OAAO,MAAMC,
|
|
1
|
+
{"version":3,"sources":["../../src/endpoints/fetchFields.ts"],"sourcesContent":["import type { Endpoint, PayloadRequest } from 'payload'\n\nimport type { PluginConfigAccess, PluginOptions } from '../types.js'\n\nimport { PLUGIN_FETCH_FIELDS_ENDPOINT, PLUGIN_INSTRUCTIONS_TABLE } from '../defaults.js'\n\nexport const fetchFields: (access: PluginConfigAccess, options?: PluginOptions) => Endpoint = (\n access,\n options = {},\n) => {\n return {\n handler: async (req: PayloadRequest) => {\n const { docs = [] } = await req.payload.find({\n collection: PLUGIN_INSTRUCTIONS_TABLE,\n pagination: false,\n })\n\n let isConfigAllowed = true // Users allowed to update prompts by default\n\n if (access?.settings) {\n try {\n isConfigAllowed = await access.settings({ req })\n } catch (e) {\n req.payload.logger.error('Please check your \"access.settings\" for request:', req)\n }\n }\n\n const fieldMap = {}\n docs.forEach((doc) => {\n fieldMap[doc['schema-path']] = {\n id: doc.id,\n fieldType: doc['field-type'],\n }\n })\n\n return Response.json({\n ...options,\n fields: fieldMap,\n isConfigAllowed,\n })\n },\n method: 'get',\n path: PLUGIN_FETCH_FIELDS_ENDPOINT,\n }\n}\n"],"names":["PLUGIN_FETCH_FIELDS_ENDPOINT","PLUGIN_INSTRUCTIONS_TABLE","fetchFields","access","options","handler","req","docs","payload","find","collection","pagination","isConfigAllowed","settings","e","logger","error","fieldMap","forEach","doc","id","fieldType","Response","json","fields","method","path"],"mappings":"AAIA,SAASA,4BAA4B,EAAEC,yBAAyB,QAAQ,iBAAgB;AAExF,OAAO,MAAMC,cAAiF,CAC5FC,QACAC,UAAU,CAAC,CAAC;IAEZ,OAAO;QACLC,SAAS,OAAOC;YACd,MAAM,EAAEC,OAAO,EAAE,EAAE,GAAG,MAAMD,IAAIE,OAAO,CAACC,IAAI,CAAC;gBAC3CC,YAAYT;gBACZU,YAAY;YACd;YAEA,IAAIC,kBAAkB,KAAK,6CAA6C;;YAExE,IAAIT,QAAQU,UAAU;gBACpB,IAAI;oBACFD,kBAAkB,MAAMT,OAAOU,QAAQ,CAAC;wBAAEP;oBAAI;gBAChD,EAAE,OAAOQ,GAAG;oBACVR,IAAIE,OAAO,CAACO,MAAM,CAACC,KAAK,CAAC,oDAAoDV;gBAC/E;YACF;YAEA,MAAMW,WAAW,CAAC;YAClBV,KAAKW,OAAO,CAAC,CAACC;gBACZF,QAAQ,CAACE,GAAG,CAAC,cAAc,CAAC,GAAG;oBAC7BC,IAAID,IAAIC,EAAE;oBACVC,WAAWF,GAAG,CAAC,aAAa;gBAC9B;YACF;YAEA,OAAOG,SAASC,IAAI,CAAC;gBACnB,GAAGnB,OAAO;gBACVoB,QAAQP;gBACRL;YACF;QACF;QACAa,QAAQ;QACRC,MAAM1B;IACR;AACF,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/endpoints/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAmB,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/endpoints/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAmB,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AA2G3E,eAAO,MAAM,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,SAwPhC,CAAA"}
|
package/dist/endpoints/index.js
CHANGED
|
@@ -7,7 +7,25 @@ import { handlebarsHelpersMap } from '../libraries/handlebars/helpersMap.js';
|
|
|
7
7
|
import { replacePlaceholders } from '../libraries/handlebars/replacePlaceholders.js';
|
|
8
8
|
import { extractImageData } from '../utilities/extractImageData.js';
|
|
9
9
|
import { getGenerationModels } from '../utilities/getGenerationModels.js';
|
|
10
|
-
const
|
|
10
|
+
const requireAuthentication = (req)=>{
|
|
11
|
+
if (!req.user) {
|
|
12
|
+
throw new Error('Authentication required. Please log in to use AI features.');
|
|
13
|
+
}
|
|
14
|
+
return true;
|
|
15
|
+
};
|
|
16
|
+
const checkAccess = async (req, pluginConfig)=>{
|
|
17
|
+
requireAuthentication(req);
|
|
18
|
+
if (pluginConfig.access?.generate) {
|
|
19
|
+
const hasAccess = await pluginConfig.access.generate({
|
|
20
|
+
req
|
|
21
|
+
});
|
|
22
|
+
if (!hasAccess) {
|
|
23
|
+
throw new Error('Insufficient permissions to use AI generation features.');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
};
|
|
28
|
+
const assignPrompt = async (action, { type, actionParams, context, field, layout, locale, systemPrompt = '', template })=>{
|
|
11
29
|
const prompt = await replacePlaceholders(template, context);
|
|
12
30
|
const toLexicalHTML = type === 'richText' ? handlebarsHelpersMap.toHTML.name : '';
|
|
13
31
|
const assignedPrompts = {
|
|
@@ -17,6 +35,16 @@ const assignPrompt = async (action, { type, actionParams, context, field, layout
|
|
|
17
35
|
system: type === 'richText' ? systemPrompt : undefined
|
|
18
36
|
};
|
|
19
37
|
if (action === 'Compose') {
|
|
38
|
+
if (locale && locale !== 'en') {
|
|
39
|
+
/**
|
|
40
|
+
* NOTE: Avoid using the "system prompt" for setting the output language,
|
|
41
|
+
* as it causes quotation marks to appear in the output (Currently only tested with openai models).
|
|
42
|
+
* Appending the language instruction directly to the prompt resolves this issue.
|
|
43
|
+
**/ assignedPrompts.prompt += `
|
|
44
|
+
---
|
|
45
|
+
OUTPUT LANGUAGE: ${locale}
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
20
48
|
return assignedPrompts;
|
|
21
49
|
}
|
|
22
50
|
const { layout: getLayout, system: getSystemPrompt } = defaultPrompts.find((p)=>p.name === action);
|
|
@@ -40,51 +68,56 @@ export const endpoints = (pluginConfig)=>({
|
|
|
40
68
|
textarea: {
|
|
41
69
|
//TODO: This is the main endpoint for generating content - its just needs to be renamed to 'generate' or something.
|
|
42
70
|
handler: async (req)=>{
|
|
43
|
-
const data = await req.json?.();
|
|
44
|
-
const { allowedEditorNodes = [], locale = 'en', options } = data;
|
|
45
|
-
const { action, actionParams, instructionId } = options;
|
|
46
|
-
const contextData = data.doc;
|
|
47
|
-
if (!instructionId) {
|
|
48
|
-
throw new Error(`Instruction ID is required for "${PLUGIN_NAME}" to work, please check your configuration`);
|
|
49
|
-
}
|
|
50
|
-
const instructions = await req.payload.findByID({
|
|
51
|
-
id: instructionId,
|
|
52
|
-
collection: PLUGIN_INSTRUCTIONS_TABLE
|
|
53
|
-
});
|
|
54
|
-
const { collections } = req.payload.config;
|
|
55
|
-
const collection = collections.find((collection)=>collection.slug === PLUGIN_INSTRUCTIONS_TABLE);
|
|
56
|
-
const { custom: { [PLUGIN_NAME]: { editorConfig = {} } = {} } = {} } = collection.admin;
|
|
57
|
-
const { schema: editorSchema = {} } = editorConfig;
|
|
58
|
-
const { prompt: promptTemplate = '' } = instructions;
|
|
59
|
-
let allowedEditorSchema = editorSchema;
|
|
60
|
-
if (allowedEditorNodes.length) {
|
|
61
|
-
allowedEditorSchema = filterEditorSchemaByNodes(editorSchema, allowedEditorNodes);
|
|
62
|
-
}
|
|
63
|
-
const schemaPath = instructions['schema-path'];
|
|
64
|
-
const fieldName = schemaPath?.split('.').pop();
|
|
65
|
-
registerEditorHelper(req.payload, schemaPath);
|
|
66
|
-
const { defaultLocale, locales = [] } = req.payload.config.localization || {};
|
|
67
|
-
const localeData = locales.find((l)=>{
|
|
68
|
-
return l.code === locale;
|
|
69
|
-
});
|
|
70
|
-
const localeInfo = localeData?.label[defaultLocale] || locale;
|
|
71
|
-
const model = getGenerationModels(pluginConfig).find((model)=>model.id === instructions['model-id']);
|
|
72
|
-
// @ts-expect-error
|
|
73
|
-
const settingsName = model.settings?.name;
|
|
74
|
-
if (!settingsName) {
|
|
75
|
-
req.payload.logger.error('— AI Plugin: Error fetching settings name!');
|
|
76
|
-
}
|
|
77
|
-
const modelOptions = instructions[settingsName] || {};
|
|
78
|
-
const prompts = await assignPrompt(action, {
|
|
79
|
-
type: instructions['field-type'],
|
|
80
|
-
actionParams,
|
|
81
|
-
context: contextData,
|
|
82
|
-
field: fieldName,
|
|
83
|
-
layout: instructions.layout,
|
|
84
|
-
systemPrompt: instructions.system,
|
|
85
|
-
template: promptTemplate
|
|
86
|
-
});
|
|
87
71
|
try {
|
|
72
|
+
// Check authentication and authorization first
|
|
73
|
+
await checkAccess(req, pluginConfig);
|
|
74
|
+
const data = await req.json?.();
|
|
75
|
+
const { allowedEditorNodes = [], locale = 'en', options } = data;
|
|
76
|
+
const { action, actionParams, instructionId } = options;
|
|
77
|
+
const contextData = data.doc;
|
|
78
|
+
if (!instructionId) {
|
|
79
|
+
throw new Error(`Instruction ID is required for "${PLUGIN_NAME}" to work, please check your configuration`);
|
|
80
|
+
}
|
|
81
|
+
// Verify user has access to the specific instruction
|
|
82
|
+
const instructions = await req.payload.findByID({
|
|
83
|
+
id: instructionId,
|
|
84
|
+
collection: PLUGIN_INSTRUCTIONS_TABLE,
|
|
85
|
+
req
|
|
86
|
+
});
|
|
87
|
+
const { collections } = req.payload.config;
|
|
88
|
+
const collection = collections.find((collection)=>collection.slug === PLUGIN_INSTRUCTIONS_TABLE);
|
|
89
|
+
const { custom: { [PLUGIN_NAME]: { editorConfig = {} } = {} } = {} } = collection.admin;
|
|
90
|
+
const { schema: editorSchema = {} } = editorConfig;
|
|
91
|
+
const { prompt: promptTemplate = '' } = instructions;
|
|
92
|
+
let allowedEditorSchema = editorSchema;
|
|
93
|
+
if (allowedEditorNodes.length) {
|
|
94
|
+
allowedEditorSchema = filterEditorSchemaByNodes(editorSchema, allowedEditorNodes);
|
|
95
|
+
}
|
|
96
|
+
const schemaPath = instructions['schema-path'];
|
|
97
|
+
const fieldName = schemaPath?.split('.').pop();
|
|
98
|
+
registerEditorHelper(req.payload, schemaPath);
|
|
99
|
+
const { defaultLocale, locales = [] } = req.payload.config.localization || {};
|
|
100
|
+
const localeData = locales.find((l)=>{
|
|
101
|
+
return l.code === locale;
|
|
102
|
+
});
|
|
103
|
+
const localeInfo = localeData?.label[defaultLocale] || locale;
|
|
104
|
+
const model = getGenerationModels(pluginConfig).find((model)=>model.id === instructions['model-id']);
|
|
105
|
+
// @ts-expect-error
|
|
106
|
+
const settingsName = model.settings?.name;
|
|
107
|
+
if (!settingsName) {
|
|
108
|
+
req.payload.logger.error('— AI Plugin: Error fetching settings name!');
|
|
109
|
+
}
|
|
110
|
+
const modelOptions = instructions[settingsName] || {};
|
|
111
|
+
const prompts = await assignPrompt(action, {
|
|
112
|
+
type: instructions['field-type'],
|
|
113
|
+
actionParams,
|
|
114
|
+
context: contextData,
|
|
115
|
+
field: fieldName,
|
|
116
|
+
layout: instructions.layout,
|
|
117
|
+
locale: localeInfo,
|
|
118
|
+
systemPrompt: instructions.system,
|
|
119
|
+
template: promptTemplate
|
|
120
|
+
});
|
|
88
121
|
return model.handler?.(prompts.prompt, {
|
|
89
122
|
...modelOptions,
|
|
90
123
|
editorSchema: allowedEditorSchema,
|
|
@@ -94,8 +127,13 @@ export const endpoints = (pluginConfig)=>({
|
|
|
94
127
|
});
|
|
95
128
|
} catch (error) {
|
|
96
129
|
req.payload.logger.error('Error generating content: ', error);
|
|
97
|
-
return new Response(JSON.stringify(
|
|
98
|
-
|
|
130
|
+
return new Response(JSON.stringify({
|
|
131
|
+
error: error.message
|
|
132
|
+
}), {
|
|
133
|
+
headers: {
|
|
134
|
+
'Content-Type': 'application/json'
|
|
135
|
+
},
|
|
136
|
+
status: error.message.includes('Authentication required') || error.message.includes('Insufficient permissions') ? 401 : 500
|
|
99
137
|
});
|
|
100
138
|
}
|
|
101
139
|
},
|
|
@@ -104,107 +142,125 @@ export const endpoints = (pluginConfig)=>({
|
|
|
104
142
|
},
|
|
105
143
|
upload: {
|
|
106
144
|
handler: async (req)=>{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
145
|
+
try {
|
|
146
|
+
// Check authentication and authorization first
|
|
147
|
+
await checkAccess(req, pluginConfig);
|
|
148
|
+
const data = await req.json?.();
|
|
149
|
+
const { collectionSlug, documentId, options } = data;
|
|
150
|
+
const { instructionId } = options;
|
|
151
|
+
let docData = {};
|
|
152
|
+
if (documentId) {
|
|
153
|
+
try {
|
|
154
|
+
docData = await req.payload.findByID({
|
|
155
|
+
id: documentId,
|
|
156
|
+
collection: collectionSlug,
|
|
157
|
+
draft: true,
|
|
158
|
+
req
|
|
159
|
+
});
|
|
160
|
+
} catch (e) {
|
|
161
|
+
req.payload.logger.error('— AI Plugin: Error fetching document, you should try again after enabling drafts for this collection');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const contextData = {
|
|
165
|
+
...data.doc,
|
|
166
|
+
...docData
|
|
167
|
+
};
|
|
168
|
+
let instructions = {
|
|
169
|
+
images: [],
|
|
170
|
+
'model-id': '',
|
|
171
|
+
prompt: ''
|
|
172
|
+
};
|
|
173
|
+
if (instructionId) {
|
|
174
|
+
// Verify user has access to the specific instruction
|
|
175
|
+
// @ts-expect-error
|
|
176
|
+
instructions = await req.payload.findByID({
|
|
177
|
+
id: instructionId,
|
|
178
|
+
collection: PLUGIN_INSTRUCTIONS_TABLE,
|
|
179
|
+
req
|
|
117
180
|
});
|
|
118
|
-
} catch (e) {
|
|
119
|
-
req.payload.logger.error('— AI Plugin: Error fetching document, you should try again after enabling drafts for this collection');
|
|
120
181
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
images
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
182
|
+
const { images: sampleImages = [], prompt: promptTemplate = '' } = instructions;
|
|
183
|
+
const schemaPath = instructions['schema-path'];
|
|
184
|
+
registerEditorHelper(req.payload, schemaPath);
|
|
185
|
+
const text = await replacePlaceholders(promptTemplate, contextData);
|
|
186
|
+
const modelId = instructions['model-id'];
|
|
187
|
+
const uploadCollectionSlug = instructions['relation-to'];
|
|
188
|
+
const images = [
|
|
189
|
+
...extractImageData(text),
|
|
190
|
+
...sampleImages
|
|
191
|
+
];
|
|
192
|
+
const editImages = [];
|
|
193
|
+
for (const img of images){
|
|
194
|
+
try {
|
|
195
|
+
const serverURL = req.payload.config?.serverURL || process.env.SERVER_URL || process.env.NEXT_PUBLIC_SERVER_URL;
|
|
196
|
+
const response = await fetch(`${serverURL}${img.image.url}`, {
|
|
197
|
+
headers: {
|
|
198
|
+
//TODO: Further testing needed or so find a proper way.
|
|
199
|
+
Authorization: `Bearer ${req.headers.get('Authorization')?.split('Bearer ')[1] || ''}`
|
|
200
|
+
},
|
|
201
|
+
method: 'GET'
|
|
202
|
+
});
|
|
203
|
+
const blob = await response.blob();
|
|
204
|
+
editImages.push({
|
|
205
|
+
name: img.image.name,
|
|
206
|
+
type: img.image.type,
|
|
207
|
+
data: blob,
|
|
208
|
+
size: blob.size,
|
|
209
|
+
url: `${serverURL}${img.image.url}`
|
|
210
|
+
});
|
|
211
|
+
} catch (e) {
|
|
212
|
+
req.payload.logger.error('Error fetching reference images!');
|
|
213
|
+
console.error(e);
|
|
214
|
+
throw Error("We couldn't fetch the images. Please ensure the images are accessible and hosted publicly.");
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
const model = getGenerationModels(pluginConfig).find((model)=>model.id === modelId);
|
|
132
218
|
// @ts-expect-error
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const editImages = [];
|
|
149
|
-
for (const img of images){
|
|
150
|
-
try {
|
|
151
|
-
const serverURL = req.payload.config?.serverURL || process.env.SERVER_URL || process.env.NEXT_PUBLIC_SERVER_URL;
|
|
152
|
-
const response = await fetch(`${serverURL}${img.image.url}`, {
|
|
153
|
-
headers: {
|
|
154
|
-
//TODO: Further testing needed or so find a proper way.
|
|
155
|
-
Authorization: `Bearer ${req.headers.get('Authorization')?.split('Bearer ')[1] || ''}`
|
|
156
|
-
},
|
|
157
|
-
method: 'GET'
|
|
219
|
+
const settingsName = model.settings?.name;
|
|
220
|
+
if (!settingsName) {
|
|
221
|
+
req.payload.logger.error('— AI Plugin: Error fetching settings name!');
|
|
222
|
+
}
|
|
223
|
+
let modelOptions = instructions[settingsName] || {};
|
|
224
|
+
modelOptions = {
|
|
225
|
+
...modelOptions,
|
|
226
|
+
images: editImages
|
|
227
|
+
};
|
|
228
|
+
const result = await model.handler?.(text, modelOptions);
|
|
229
|
+
let assetData;
|
|
230
|
+
if (typeof pluginConfig.mediaUpload === 'function') {
|
|
231
|
+
assetData = await pluginConfig.mediaUpload(result, {
|
|
232
|
+
collection: uploadCollectionSlug,
|
|
233
|
+
request: req
|
|
158
234
|
});
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
url: `${serverURL}${img.image.url}`
|
|
235
|
+
} else {
|
|
236
|
+
assetData = await req.payload.create({
|
|
237
|
+
collection: uploadCollectionSlug,
|
|
238
|
+
data: result.data,
|
|
239
|
+
file: result.file,
|
|
240
|
+
req
|
|
166
241
|
});
|
|
167
|
-
} catch (e) {
|
|
168
|
-
req.payload.logger.error('Error fetching reference images!');
|
|
169
|
-
console.error(e);
|
|
170
|
-
throw Error("We couldn't fetch the images. Please ensure the images are accessible and hosted publicly.");
|
|
171
242
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
} else {
|
|
192
|
-
assetData = await req.payload.create({
|
|
193
|
-
collection: uploadCollectionSlug,
|
|
194
|
-
data: result.data,
|
|
195
|
-
file: result.file
|
|
243
|
+
if (!assetData.id) {
|
|
244
|
+
req.payload.logger.error('Error uploading generated media, is your media upload function correct?');
|
|
245
|
+
throw new Error('Error uploading generated media!');
|
|
246
|
+
}
|
|
247
|
+
return new Response(JSON.stringify({
|
|
248
|
+
result: {
|
|
249
|
+
id: assetData.id,
|
|
250
|
+
alt: assetData.alt
|
|
251
|
+
}
|
|
252
|
+
}));
|
|
253
|
+
} catch (error) {
|
|
254
|
+
req.payload.logger.error('Error generating upload: ', error);
|
|
255
|
+
return new Response(JSON.stringify({
|
|
256
|
+
error: error.message
|
|
257
|
+
}), {
|
|
258
|
+
headers: {
|
|
259
|
+
'Content-Type': 'application/json'
|
|
260
|
+
},
|
|
261
|
+
status: error.message.includes('Authentication required') || error.message.includes('Insufficient permissions') ? 401 : 500
|
|
196
262
|
});
|
|
197
263
|
}
|
|
198
|
-
if (!assetData.id) {
|
|
199
|
-
req.payload.logger.error('Error uploading generated media, is your media upload function correct?');
|
|
200
|
-
throw new Error('Error uploading generated media!');
|
|
201
|
-
}
|
|
202
|
-
return new Response(JSON.stringify({
|
|
203
|
-
result: {
|
|
204
|
-
id: assetData.id,
|
|
205
|
-
alt: assetData.alt
|
|
206
|
-
}
|
|
207
|
-
}));
|
|
208
264
|
},
|
|
209
265
|
method: 'post',
|
|
210
266
|
path: PLUGIN_API_ENDPOINT_GENERATE_UPLOAD
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/endpoints/index.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport * as process from 'node:process'\n\nimport type { ActionMenuItems, Endpoints, PluginConfig } from '../types.js'\n\nimport { defaultPrompts } from '../ai/prompts.js'\nimport { filterEditorSchemaByNodes } from '../ai/utils/filterEditorSchemaByNodes.js'\nimport {\n PLUGIN_API_ENDPOINT_GENERATE,\n PLUGIN_API_ENDPOINT_GENERATE_UPLOAD,\n PLUGIN_INSTRUCTIONS_TABLE,\n PLUGIN_NAME,\n} from '../defaults.js'\nimport { registerEditorHelper } from '../libraries/handlebars/helpers.js'\nimport { handlebarsHelpersMap } from '../libraries/handlebars/helpersMap.js'\nimport { replacePlaceholders } from '../libraries/handlebars/replacePlaceholders.js'\nimport { extractImageData } from '../utilities/extractImageData.js'\nimport { getGenerationModels } from '../utilities/getGenerationModels.js'\n\nconst assignPrompt = async (\n action: ActionMenuItems,\n {\n type,\n actionParams,\n context,\n field,\n layout,\n systemPrompt = '',\n template,\n }: {\n actionParams: Record<any, any>\n context: object\n field: string\n layout: string\n systemPrompt: string\n template: string\n type: string\n },\n) => {\n const prompt = await replacePlaceholders(template, context)\n const toLexicalHTML = type === 'richText' ? handlebarsHelpersMap.toHTML.name : ''\n\n const assignedPrompts = {\n layout: type === 'richText' ? layout : undefined,\n prompt,\n //TODO: Define only once on a collection level\n system: type === 'richText' ? systemPrompt : undefined,\n }\n\n if (action === 'Compose') {\n return assignedPrompts\n }\n\n const { layout: getLayout, system: getSystemPrompt } = defaultPrompts.find(\n (p) => p.name === action,\n )\n\n let updatedLayout = layout\n if (getLayout) {\n updatedLayout = getLayout()\n }\n\n const system = getSystemPrompt({\n ...(actionParams || {}),\n prompt,\n systemPrompt,\n })\n\n return {\n layout: updatedLayout,\n // TODO: revisit this toLexicalHTML\n prompt: await replacePlaceholders(`{{${toLexicalHTML} ${field}}}`, context),\n system,\n }\n}\n\nexport const endpoints: (pluginConfig: PluginConfig) => Endpoints = (pluginConfig) =>\n ({\n textarea: {\n //TODO: This is the main endpoint for generating content - its just needs to be renamed to 'generate' or something.\n handler: async (req: PayloadRequest) => {\n const data = await req.json?.()\n\n const { allowedEditorNodes = [], locale = 'en', options } = data\n const { action, actionParams, instructionId } = options\n const contextData = data.doc\n\n if (!instructionId) {\n throw new Error(\n `Instruction ID is required for \"${PLUGIN_NAME}\" to work, please check your configuration`,\n )\n }\n\n const instructions = await req.payload.findByID({\n id: instructionId,\n collection: PLUGIN_INSTRUCTIONS_TABLE,\n })\n\n const { collections } = req.payload.config\n const collection = collections.find(\n (collection) => collection.slug === PLUGIN_INSTRUCTIONS_TABLE,\n )\n\n const { custom: { [PLUGIN_NAME]: { editorConfig = {} } = {} } = {} } = collection.admin\n const { schema: editorSchema = {} } = editorConfig\n const { prompt: promptTemplate = '' } = instructions\n\n let allowedEditorSchema = editorSchema\n if (allowedEditorNodes.length) {\n allowedEditorSchema = filterEditorSchemaByNodes(editorSchema, allowedEditorNodes)\n }\n\n const schemaPath = instructions['schema-path'] as string\n const fieldName = schemaPath?.split('.').pop()\n\n registerEditorHelper(req.payload, schemaPath)\n\n const { defaultLocale, locales = [] } = req.payload.config.localization || {}\n const localeData = locales.find((l) => {\n return l.code === locale\n })\n\n const localeInfo = localeData?.label[defaultLocale] || locale\n\n const model = getGenerationModels(pluginConfig).find(\n (model) => model.id === instructions['model-id'],\n )\n\n // @ts-expect-error\n const settingsName = model.settings?.name\n if (!settingsName) {\n req.payload.logger.error('— AI Plugin: Error fetching settings name!')\n }\n\n const modelOptions = instructions[settingsName] || {}\n\n const prompts = await assignPrompt(action, {\n type: instructions['field-type'] as string,\n actionParams,\n context: contextData,\n field: fieldName,\n layout: instructions.layout,\n systemPrompt: instructions.system,\n template: promptTemplate as string,\n })\n\n try {\n return model.handler?.(prompts.prompt, {\n ...modelOptions,\n editorSchema: allowedEditorSchema,\n layout: prompts.layout,\n locale: localeInfo,\n system: prompts.system,\n })\n } catch (error) {\n req.payload.logger.error('Error generating content: ', error)\n return new Response(JSON.stringify(error.message), { status: 500 })\n }\n },\n method: 'post',\n path: PLUGIN_API_ENDPOINT_GENERATE,\n },\n upload: {\n handler: async (req: PayloadRequest) => {\n const data = await req.json?.()\n\n const { collectionSlug, documentId, options } = data\n const { instructionId } = options\n let docData = {}\n\n if (documentId) {\n try {\n docData = await req.payload.findByID({\n id: documentId,\n collection: collectionSlug,\n draft: true,\n })\n } catch (e) {\n req.payload.logger.error(\n '— AI Plugin: Error fetching document, you should try again after enabling drafts for this collection',\n )\n }\n }\n\n const contextData = {\n ...data.doc,\n ...docData,\n }\n\n let instructions = { images: [], 'model-id': '', prompt: '' }\n\n if (instructionId) {\n // @ts-expect-error\n instructions = await req.payload.findByID({\n id: instructionId,\n collection: PLUGIN_INSTRUCTIONS_TABLE,\n })\n }\n\n const { images: sampleImages = [], prompt: promptTemplate = '' } = instructions\n const schemaPath = instructions['schema-path']\n\n registerEditorHelper(req.payload, schemaPath)\n\n const text = await replacePlaceholders(promptTemplate, contextData)\n const modelId = instructions['model-id']\n const uploadCollectionSlug = instructions['relation-to']\n\n const images = [...extractImageData(text), ...sampleImages]\n\n const editImages = []\n for (const img of images) {\n try {\n const serverURL =\n req.payload.config?.serverURL ||\n process.env.SERVER_URL ||\n process.env.NEXT_PUBLIC_SERVER_URL\n\n const response = await fetch(`${serverURL}${img.image.url}`, {\n headers: {\n //TODO: Further testing needed or so find a proper way.\n Authorization: `Bearer ${req.headers.get('Authorization')?.split('Bearer ')[1] || ''}`,\n },\n method: 'GET',\n })\n\n const blob = await response.blob()\n editImages.push({\n name: img.image.name,\n type: img.image.type,\n data: blob,\n size: blob.size,\n url: `${serverURL}${img.image.url}`,\n })\n } catch (e) {\n req.payload.logger.error('Error fetching reference images!')\n console.error(e)\n throw Error(\n \"We couldn't fetch the images. Please ensure the images are accessible and hosted publicly.\",\n )\n }\n }\n\n const model = getGenerationModels(pluginConfig).find((model) => model.id === modelId)\n\n // @ts-expect-error\n const settingsName = model.settings?.name\n if (!settingsName) {\n req.payload.logger.error('— AI Plugin: Error fetching settings name!')\n }\n\n let modelOptions = instructions[settingsName] || {}\n modelOptions = {\n ...modelOptions,\n images: editImages,\n }\n\n const result = await model.handler?.(text, modelOptions)\n let assetData: { alt?: string; id: number | string }\n\n if (typeof pluginConfig.mediaUpload === 'function') {\n assetData = await pluginConfig.mediaUpload(result, {\n collection: uploadCollectionSlug,\n request: req,\n })\n } else {\n assetData = await req.payload.create({\n collection: uploadCollectionSlug,\n data: result.data,\n file: result.file,\n })\n }\n\n if (!assetData.id) {\n req.payload.logger.error(\n 'Error uploading generated media, is your media upload function correct?',\n )\n throw new Error('Error uploading generated media!')\n }\n\n return new Response(\n JSON.stringify({\n result: {\n id: assetData.id,\n alt: assetData.alt,\n },\n }),\n )\n },\n method: 'post',\n path: PLUGIN_API_ENDPOINT_GENERATE_UPLOAD,\n },\n }) satisfies Endpoints\n"],"names":["process","defaultPrompts","filterEditorSchemaByNodes","PLUGIN_API_ENDPOINT_GENERATE","PLUGIN_API_ENDPOINT_GENERATE_UPLOAD","PLUGIN_INSTRUCTIONS_TABLE","PLUGIN_NAME","registerEditorHelper","handlebarsHelpersMap","replacePlaceholders","extractImageData","getGenerationModels","assignPrompt","action","type","actionParams","context","field","layout","systemPrompt","template","prompt","toLexicalHTML","toHTML","name","assignedPrompts","undefined","system","getLayout","getSystemPrompt","find","p","updatedLayout","endpoints","pluginConfig","textarea","handler","req","data","json","allowedEditorNodes","locale","options","instructionId","contextData","doc","Error","instructions","payload","findByID","id","collection","collections","config","slug","custom","editorConfig","admin","schema","editorSchema","promptTemplate","allowedEditorSchema","length","schemaPath","fieldName","split","pop","defaultLocale","locales","localization","localeData","l","code","localeInfo","label","model","settingsName","settings","logger","error","modelOptions","prompts","Response","JSON","stringify","message","status","method","path","upload","collectionSlug","documentId","docData","draft","e","images","sampleImages","text","modelId","uploadCollectionSlug","editImages","img","serverURL","env","SERVER_URL","NEXT_PUBLIC_SERVER_URL","response","fetch","image","url","headers","Authorization","get","blob","push","size","console","result","assetData","mediaUpload","request","create","file","alt"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/endpoints/index.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nimport * as process from 'node:process'\n\nimport type { ActionMenuItems, Endpoints, PluginConfig } from '../types.js'\n\nimport { defaultPrompts } from '../ai/prompts.js'\nimport { filterEditorSchemaByNodes } from '../ai/utils/filterEditorSchemaByNodes.js'\nimport {\n PLUGIN_API_ENDPOINT_GENERATE,\n PLUGIN_API_ENDPOINT_GENERATE_UPLOAD,\n PLUGIN_INSTRUCTIONS_TABLE,\n PLUGIN_NAME,\n} from '../defaults.js'\nimport { registerEditorHelper } from '../libraries/handlebars/helpers.js'\nimport { handlebarsHelpersMap } from '../libraries/handlebars/helpersMap.js'\nimport { replacePlaceholders } from '../libraries/handlebars/replacePlaceholders.js'\nimport { extractImageData } from '../utilities/extractImageData.js'\nimport { getGenerationModels } from '../utilities/getGenerationModels.js'\n\nconst requireAuthentication = (req: PayloadRequest) => {\n if (!req.user) {\n throw new Error('Authentication required. Please log in to use AI features.')\n }\n return true\n}\n\nconst checkAccess = async (req: PayloadRequest, pluginConfig: PluginConfig) => {\n requireAuthentication(req)\n\n if (pluginConfig.access?.generate) {\n const hasAccess = await pluginConfig.access.generate({ req })\n if (!hasAccess) {\n throw new Error('Insufficient permissions to use AI generation features.')\n }\n }\n\n return true\n}\n\nconst assignPrompt = async (\n action: ActionMenuItems,\n {\n type,\n actionParams,\n context,\n field,\n layout,\n locale,\n systemPrompt = '',\n template,\n }: {\n actionParams: Record<any, any>\n context: object\n field: string\n layout: string\n locale: string\n systemPrompt: string\n template: string\n type: string\n },\n) => {\n const prompt = await replacePlaceholders(template, context)\n const toLexicalHTML = type === 'richText' ? handlebarsHelpersMap.toHTML.name : ''\n\n const assignedPrompts = {\n layout: type === 'richText' ? layout : undefined,\n prompt,\n //TODO: Define only once on a collection level\n system: type === 'richText' ? systemPrompt : undefined,\n }\n\n if (action === 'Compose') {\n if (locale && locale !== 'en') {\n /**\n * NOTE: Avoid using the \"system prompt\" for setting the output language,\n * as it causes quotation marks to appear in the output (Currently only tested with openai models).\n * Appending the language instruction directly to the prompt resolves this issue.\n **/\n assignedPrompts.prompt += `\n --- \n OUTPUT LANGUAGE: ${locale}\n `\n }\n\n return assignedPrompts\n }\n\n const { layout: getLayout, system: getSystemPrompt } = defaultPrompts.find(\n (p) => p.name === action,\n )\n\n let updatedLayout = layout\n if (getLayout) {\n updatedLayout = getLayout()\n }\n\n const system = getSystemPrompt({\n ...(actionParams || {}),\n prompt,\n systemPrompt,\n })\n\n return {\n layout: updatedLayout,\n // TODO: revisit this toLexicalHTML\n prompt: await replacePlaceholders(`{{${toLexicalHTML} ${field}}}`, context),\n system,\n }\n}\n\nexport const endpoints: (pluginConfig: PluginConfig) => Endpoints = (pluginConfig) =>\n ({\n textarea: {\n //TODO: This is the main endpoint for generating content - its just needs to be renamed to 'generate' or something.\n handler: async (req: PayloadRequest) => {\n try {\n // Check authentication and authorization first\n await checkAccess(req, pluginConfig)\n\n const data = await req.json?.()\n\n const { allowedEditorNodes = [], locale = 'en', options } = data\n const { action, actionParams, instructionId } = options\n const contextData = data.doc\n\n if (!instructionId) {\n throw new Error(\n `Instruction ID is required for \"${PLUGIN_NAME}\" to work, please check your configuration`,\n )\n }\n\n // Verify user has access to the specific instruction\n const instructions = await req.payload.findByID({\n id: instructionId,\n collection: PLUGIN_INSTRUCTIONS_TABLE,\n req, // Pass req to ensure access control is applied\n })\n\n const { collections } = req.payload.config\n const collection = collections.find(\n (collection) => collection.slug === PLUGIN_INSTRUCTIONS_TABLE,\n )\n\n const { custom: { [PLUGIN_NAME]: { editorConfig = {} } = {} } = {} } = collection.admin\n const { schema: editorSchema = {} } = editorConfig\n const { prompt: promptTemplate = '' } = instructions\n\n let allowedEditorSchema = editorSchema\n if (allowedEditorNodes.length) {\n allowedEditorSchema = filterEditorSchemaByNodes(editorSchema, allowedEditorNodes)\n }\n\n const schemaPath = instructions['schema-path'] as string\n const fieldName = schemaPath?.split('.').pop()\n\n registerEditorHelper(req.payload, schemaPath)\n\n const { defaultLocale, locales = [] } = req.payload.config.localization || {}\n const localeData = locales.find((l) => {\n return l.code === locale\n })\n\n const localeInfo = localeData?.label[defaultLocale] || locale\n\n const model = getGenerationModels(pluginConfig).find(\n (model) => model.id === instructions['model-id'],\n )\n\n // @ts-expect-error\n const settingsName = model.settings?.name\n if (!settingsName) {\n req.payload.logger.error('— AI Plugin: Error fetching settings name!')\n }\n\n const modelOptions = instructions[settingsName] || {}\n\n const prompts = await assignPrompt(action, {\n type: instructions['field-type'] as string,\n actionParams,\n context: contextData,\n field: fieldName,\n layout: instructions.layout,\n locale: localeInfo,\n systemPrompt: instructions.system,\n template: promptTemplate as string,\n })\n\n return model.handler?.(prompts.prompt, {\n ...modelOptions,\n editorSchema: allowedEditorSchema,\n layout: prompts.layout,\n locale: localeInfo,\n system: prompts.system,\n })\n } catch (error) {\n req.payload.logger.error('Error generating content: ', error)\n return new Response(JSON.stringify({ error: error.message }), {\n headers: { 'Content-Type': 'application/json' },\n status:\n error.message.includes('Authentication required') ||\n error.message.includes('Insufficient permissions')\n ? 401\n : 500,\n })\n }\n },\n method: 'post',\n path: PLUGIN_API_ENDPOINT_GENERATE,\n },\n upload: {\n handler: async (req: PayloadRequest) => {\n try {\n // Check authentication and authorization first\n await checkAccess(req, pluginConfig)\n\n const data = await req.json?.()\n\n const { collectionSlug, documentId, options } = data\n const { instructionId } = options\n let docData = {}\n\n if (documentId) {\n try {\n docData = await req.payload.findByID({\n id: documentId,\n collection: collectionSlug,\n draft: true,\n req, // Pass req to ensure access control is applied\n })\n } catch (e) {\n req.payload.logger.error(\n '— AI Plugin: Error fetching document, you should try again after enabling drafts for this collection',\n )\n }\n }\n\n const contextData = {\n ...data.doc,\n ...docData,\n }\n\n let instructions = { images: [], 'model-id': '', prompt: '' }\n\n if (instructionId) {\n // Verify user has access to the specific instruction\n // @ts-expect-error\n instructions = await req.payload.findByID({\n id: instructionId,\n collection: PLUGIN_INSTRUCTIONS_TABLE,\n req, // Pass req to ensure access control is applied\n })\n }\n\n const { images: sampleImages = [], prompt: promptTemplate = '' } = instructions\n const schemaPath = instructions['schema-path']\n\n registerEditorHelper(req.payload, schemaPath)\n\n const text = await replacePlaceholders(promptTemplate, contextData)\n const modelId = instructions['model-id']\n const uploadCollectionSlug = instructions['relation-to']\n\n const images = [...extractImageData(text), ...sampleImages]\n\n const editImages = []\n for (const img of images) {\n try {\n const serverURL =\n req.payload.config?.serverURL ||\n process.env.SERVER_URL ||\n process.env.NEXT_PUBLIC_SERVER_URL\n\n const response = await fetch(`${serverURL}${img.image.url}`, {\n headers: {\n //TODO: Further testing needed or so find a proper way.\n Authorization: `Bearer ${req.headers.get('Authorization')?.split('Bearer ')[1] || ''}`,\n },\n method: 'GET',\n })\n\n const blob = await response.blob()\n editImages.push({\n name: img.image.name,\n type: img.image.type,\n data: blob,\n size: blob.size,\n url: `${serverURL}${img.image.url}`,\n })\n } catch (e) {\n req.payload.logger.error('Error fetching reference images!')\n console.error(e)\n throw Error(\n \"We couldn't fetch the images. Please ensure the images are accessible and hosted publicly.\",\n )\n }\n }\n\n const model = getGenerationModels(pluginConfig).find((model) => model.id === modelId)\n\n // @ts-expect-error\n const settingsName = model.settings?.name\n if (!settingsName) {\n req.payload.logger.error('— AI Plugin: Error fetching settings name!')\n }\n\n let modelOptions = instructions[settingsName] || {}\n modelOptions = {\n ...modelOptions,\n images: editImages,\n }\n\n const result = await model.handler?.(text, modelOptions)\n let assetData: { alt?: string; id: number | string }\n\n if (typeof pluginConfig.mediaUpload === 'function') {\n assetData = await pluginConfig.mediaUpload(result, {\n collection: uploadCollectionSlug,\n request: req,\n })\n } else {\n assetData = await req.payload.create({\n collection: uploadCollectionSlug,\n data: result.data,\n file: result.file,\n req, // Pass req to ensure access control is applied\n })\n }\n\n if (!assetData.id) {\n req.payload.logger.error(\n 'Error uploading generated media, is your media upload function correct?',\n )\n throw new Error('Error uploading generated media!')\n }\n\n return new Response(\n JSON.stringify({\n result: {\n id: assetData.id,\n alt: assetData.alt,\n },\n }),\n )\n } catch (error) {\n req.payload.logger.error('Error generating upload: ', error)\n return new Response(JSON.stringify({ error: error.message }), {\n headers: { 'Content-Type': 'application/json' },\n status:\n error.message.includes('Authentication required') ||\n error.message.includes('Insufficient permissions')\n ? 401\n : 500,\n })\n }\n },\n method: 'post',\n path: PLUGIN_API_ENDPOINT_GENERATE_UPLOAD,\n },\n }) satisfies Endpoints\n"],"names":["process","defaultPrompts","filterEditorSchemaByNodes","PLUGIN_API_ENDPOINT_GENERATE","PLUGIN_API_ENDPOINT_GENERATE_UPLOAD","PLUGIN_INSTRUCTIONS_TABLE","PLUGIN_NAME","registerEditorHelper","handlebarsHelpersMap","replacePlaceholders","extractImageData","getGenerationModels","requireAuthentication","req","user","Error","checkAccess","pluginConfig","access","generate","hasAccess","assignPrompt","action","type","actionParams","context","field","layout","locale","systemPrompt","template","prompt","toLexicalHTML","toHTML","name","assignedPrompts","undefined","system","getLayout","getSystemPrompt","find","p","updatedLayout","endpoints","textarea","handler","data","json","allowedEditorNodes","options","instructionId","contextData","doc","instructions","payload","findByID","id","collection","collections","config","slug","custom","editorConfig","admin","schema","editorSchema","promptTemplate","allowedEditorSchema","length","schemaPath","fieldName","split","pop","defaultLocale","locales","localization","localeData","l","code","localeInfo","label","model","settingsName","settings","logger","error","modelOptions","prompts","Response","JSON","stringify","message","headers","status","includes","method","path","upload","collectionSlug","documentId","docData","draft","e","images","sampleImages","text","modelId","uploadCollectionSlug","editImages","img","serverURL","env","SERVER_URL","NEXT_PUBLIC_SERVER_URL","response","fetch","image","url","Authorization","get","blob","push","size","console","result","assetData","mediaUpload","request","create","file","alt"],"mappings":"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"}
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,MAAM,EAAgB,MAAM,SAAS,CAAA;AAIrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,MAAM,EAAgB,MAAM,SAAS,CAAA;AAIrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AA4D9C,QAAA,MAAM,eAAe,GAClB,cAAc,YAAY,MACxB,gBAAgB,MAAM,KAAG,MA6HzB,CAAA;AAEL,OAAO,EAAE,eAAe,EAAE,CAAA"}
|
package/dist/plugin.js
CHANGED
|
@@ -11,6 +11,10 @@ import { getGenerationModels } from './utilities/getGenerationModels.js';
|
|
|
11
11
|
import { isPluginActivated } from './utilities/isPluginActivated.js';
|
|
12
12
|
import { updateFieldsConfig } from './utilities/updateFieldsConfig.js';
|
|
13
13
|
const defaultPluginConfig = {
|
|
14
|
+
access: {
|
|
15
|
+
generate: ({ req })=>!!req.user,
|
|
16
|
+
settings: ({ req })=>!!req.user
|
|
17
|
+
},
|
|
14
18
|
collections: {},
|
|
15
19
|
disableSponsorMessage: false,
|
|
16
20
|
generatePromptOnInit: true,
|
|
@@ -35,10 +39,28 @@ const sponsorMessage = `
|
|
|
35
39
|
║ Thank you again, and happy building! ║
|
|
36
40
|
╚═══════════════════════════════════════════════════════════════╝
|
|
37
41
|
`;
|
|
42
|
+
const securityMessage = `
|
|
43
|
+
╔═══════════════════════════════════════════════════════════════╗
|
|
44
|
+
║ SECURITY NOTICE ║
|
|
45
|
+
║ ║
|
|
46
|
+
║ The AI Plugin now requires authentication by default. ║
|
|
47
|
+
║ All AI features are restricted to authenticated users. ║
|
|
48
|
+
║ ║
|
|
49
|
+
║ To customize access control, configure the 'access' option ║
|
|
50
|
+
║ in your plugin settings. See documentation for details. ║
|
|
51
|
+
║ ║
|
|
52
|
+
║ If you need different access patterns, please configure ║
|
|
53
|
+
║ them explicitly in your plugin configuration. ║
|
|
54
|
+
╚═══════════════════════════════════════════════════════════════╝
|
|
55
|
+
`;
|
|
38
56
|
const payloadAiPlugin = (pluginConfig)=>(incomingConfig)=>{
|
|
39
57
|
pluginConfig = {
|
|
40
58
|
...defaultPluginConfig,
|
|
41
|
-
...pluginConfig
|
|
59
|
+
...pluginConfig,
|
|
60
|
+
access: {
|
|
61
|
+
...defaultPluginConfig.access,
|
|
62
|
+
...pluginConfig.access
|
|
63
|
+
}
|
|
42
64
|
};
|
|
43
65
|
pluginConfig.generationModels = getGenerationModels(pluginConfig);
|
|
44
66
|
const isActivated = isPluginActivated(pluginConfig);
|
|
@@ -102,7 +124,7 @@ const payloadAiPlugin = (pluginConfig)=>(incomingConfig)=>{
|
|
|
102
124
|
...incomingConfig.endpoints ?? [],
|
|
103
125
|
pluginEndpoints.textarea,
|
|
104
126
|
pluginEndpoints.upload,
|
|
105
|
-
fetchFields(pluginConfig.access)
|
|
127
|
+
fetchFields(pluginConfig.access, pluginConfig.options)
|
|
106
128
|
],
|
|
107
129
|
globals: globals.map((global)=>{
|
|
108
130
|
if (globalsSlugs[global.slug]) {
|
|
@@ -133,6 +155,9 @@ const payloadAiPlugin = (pluginConfig)=>(incomingConfig)=>{
|
|
|
133
155
|
console.error(error);
|
|
134
156
|
payload.logger.error(`— AI Plugin: Initialization Error: ${error}`);
|
|
135
157
|
}).finally(()=>{
|
|
158
|
+
setTimeout(()=>{
|
|
159
|
+
payload.logger.info(securityMessage);
|
|
160
|
+
}, 1000);
|
|
136
161
|
if (!pluginConfig.disableSponsorMessage) {
|
|
137
162
|
setTimeout(()=>{
|
|
138
163
|
payload.logger.info(sponsorMessage);
|
package/dist/plugin.js.map
CHANGED
|
@@ -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 { defaultGenerationModels } from './ai/models/index.js'\nimport { lexicalJsonSchema } from './ai/schemas/lexicalJsonSchema.js'\nimport { instructionsCollection } from './collections/Instructions.js'\nimport { PLUGIN_NAME } from './defaults.js'\nimport { fetchFields } from './endpoints/fetchFields.js'\nimport { endpoints } from './endpoints/index.js'\nimport { init } from './init.js'\nimport { translations } from './translations/index.js'\nimport { getGenerationModels } from './utilities/getGenerationModels.js'\nimport { isPluginActivated } from './utilities/isPluginActivated.js'\nimport { updateFieldsConfig } from './utilities/updateFieldsConfig.js'\n\nconst defaultPluginConfig: PluginConfig = {\n collections: {},\n disableSponsorMessage: false,\n generatePromptOnInit: true,\n generationModels: defaultGenerationModels,\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 payloadAiPlugin =\n (pluginConfig: PluginConfig) =>\n (incomingConfig: Config): Config => {\n\n pluginConfig = { ...defaultPluginConfig, ...pluginConfig }\n pluginConfig.generationModels = getGenerationModels(pluginConfig)\n\n const isActivated = isPluginActivated(pluginConfig)\n let updatedConfig: Config = { ...incomingConfig }\n let collectionsFieldPathMap = {}\n\n if (isActivated) {\n const Instructions = instructionsCollection(pluginConfig)\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 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]\n const globals = [...(incomingConfig.globals ?? [])]\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 fetchFields(pluginConfig.access),\n ],\n globals: globals.map((global) => {\n if (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) await incomingConfig.onInit(payload)\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 console.error(error)\n payload.logger.error(`— AI Plugin: Initialization Error: ${error}`)\n })\n .finally(() => {\n if (!pluginConfig.disableSponsorMessage) {\n setTimeout(() => {\n payload.logger.info(sponsorMessage)\n }, 3000)\n }\n })\n }\n\n return updatedConfig\n }\n\nexport { payloadAiPlugin }\n"],"names":["deepMerge","defaultGenerationModels","lexicalJsonSchema","instructionsCollection","PLUGIN_NAME","fetchFields","endpoints","init","translations","getGenerationModels","isPluginActivated","updateFieldsConfig","defaultPluginConfig","collections","disableSponsorMessage","generatePromptOnInit","generationModels","sponsorMessage","payloadAiPlugin","pluginConfig","incomingConfig","isActivated","updatedConfig","collectionsFieldPathMap","Instructions","lexicalSchema","editorConfig","nodes","debugging","admin","hidden","custom","schema","globals","collectionSlugs","globalsSlugs","components","providers","updatedProviders","path","pluginEndpoints","map","collection","slug","schemaPathMap","updatedCollectionConfig","textarea","upload","access","global","i18n","onInit","payload","logger","warn","catch","error","console","finally","setTimeout","info"],"mappings":"AAEA,SAASA,SAAS,QAAQ,iBAAgB;AAI1C,SAASC,uBAAuB,QAAQ,uBAAsB;AAC9D,SAASC,iBAAiB,QAAQ,oCAAmC;AACrE,SAASC,sBAAsB,QAAQ,gCAA+B;AACtE,SAASC,WAAW,QAAQ,gBAAe;AAC3C,SAASC,WAAW,QAAQ,6BAA4B;AACxD,SAASC,SAAS,QAAQ,uBAAsB;AAChD,SAASC,IAAI,QAAQ,YAAW;AAChC,SAASC,YAAY,QAAQ,0BAAyB;AACtD,SAASC,mBAAmB,QAAQ,qCAAoC;AACxE,SAASC,iBAAiB,QAAQ,mCAAkC;AACpE,SAASC,kBAAkB,QAAQ,oCAAmC;AAEtE,MAAMC,sBAAoC;IACxCC,aAAa,CAAC;IACdC,uBAAuB;IACvBC,sBAAsB;IACtBC,kBAAkBf;AACpB;AAEA,MAAMgB,iBAAiB,CAAC;;;;;;;;;;;;;;;;;;AAkBxB,CAAC;AAED,MAAMC,kBACJ,CAACC,eACC,CAACC;QAECD,eAAe;YAAE,GAAGP,mBAAmB;YAAE,GAAGO,YAAY;QAAC;QACzDA,aAAaH,gBAAgB,GAAGP,oBAAoBU;QAEpD,MAAME,cAAcX,kBAAkBS;QACtC,IAAIG,gBAAwB;YAAE,GAAGF,cAAc;QAAC;QAChD,IAAIG,0BAA0B,CAAC;QAE/B,IAAIF,aAAa;YACf,MAAMG,eAAerB,uBAAuBgB;YAC5C,8FAA8F;YAC9F,MAAMM,gBAAgBvB,kBAAkBiB,aAAaO,YAAY,EAAEC;YAEnE,IAAIR,aAAaS,SAAS,EAAE;gBAC1BJ,aAAaK,KAAK,CAACC,MAAM,GAAG;YAC9B;YAEAN,aAAaK,KAAK,CAACE,MAAM,GAAG;gBAC1B,GAAIP,aAAaK,KAAK,CAACE,MAAM,IAAI,CAAC,CAAC;gBACnC,CAAC3B,YAAY,EAAE;oBACbsB,cAAc;wBACZ,0CAA0C;wBAC1CM,QAAQP;oBACV;gBACF;YACF;YAEA,MAAMZ,cAAc;mBAAKO,eAAeP,WAAW,IAAI,EAAE;gBAAGW;aAAa;YACzE,MAAMS,UAAU;mBAAKb,eAAea,OAAO,IAAI,EAAE;aAAE;YACnD,MAAM,EAAEpB,aAAaqB,kBAAkB,EAAE,EAAED,SAASE,eAAe,EAAE,EAAE,GAAGhB;YAE1E,MAAM,EAAEiB,YAAY,EAAEC,YAAY,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,GAAGjB,eAAeS,KAAK,IAAI,CAAC;YACzE,MAAMS,mBAAmB;mBACnBD,aAAa,EAAE;gBACnB;oBACEE,MAAM;gBACR;aACD;YAEDnB,eAAeS,KAAK,GAAG;gBACrB,GAAIT,eAAeS,KAAK,IAAI,CAAC,CAAC;gBAC9BO,YAAY;oBACV,GAAIhB,eAAeS,KAAK,EAAEO,cAAc,CAAC,CAAC;oBAC1CC,WAAWC;gBACb;YACF;YAEA,MAAME,kBAAkBlC,UAAUa;YAClCG,gBAAgB;gBACd,GAAGF,cAAc;gBACjBP,aAAaA,YAAY4B,GAAG,CAAC,CAACC;oBAC5B,IAAIR,eAAe,CAACQ,WAAWC,IAAI,CAAC,EAAE;wBACpC,MAAM,EAAEC,aAAa,EAAEC,uBAAuB,EAAE,GAAGlC,mBAAmB+B;wBACtEnB,0BAA0B;4BACxB,GAAGA,uBAAuB;4BAC1B,GAAGqB,aAAa;wBAClB;wBACA,OAAOC;oBACT;oBAEA,OAAOH;gBACT;gBACApC,WAAW;uBACLc,eAAed,SAAS,IAAI,EAAE;oBAClCkC,gBAAgBM,QAAQ;oBACxBN,gBAAgBO,MAAM;oBACtB1C,YAAYc,aAAa6B,MAAM;iBAChC;gBACDf,SAASA,QAAQQ,GAAG,CAAC,CAACQ;oBACpB,IAAId,YAAY,CAACc,OAAON,IAAI,CAAC,EAAE;wBAC7B,MAAM,EAAEC,aAAa,EAAEC,uBAAuB,EAAE,GAAGlC,mBAAmBsC;wBACtE1B,0BAA0B;4BACxB,GAAGA,uBAAuB;4BAC1B,GAAGqB,aAAa;wBAClB;wBACA,OAAOC;oBACT;oBAEA,OAAOI;gBACT;gBACAC,MAAM;oBACJ,GAAI9B,eAAe8B,IAAI,IAAI,CAAC,CAAC;oBAC7B1C,cAAc;wBACZ,GAAGR,UAAUQ,cAAcY,eAAe8B,IAAI,EAAE1C,gBAAgB,CAAC,EAAE;oBACrE;gBACF;YACF;QACF;QAEAc,cAAc6B,MAAM,GAAG,OAAOC;YAC5B,IAAIhC,eAAe+B,MAAM,EAAE,MAAM/B,eAAe+B,MAAM,CAACC;YAEvD,IAAI,CAAC/B,aAAa;gBAChB+B,QAAQC,MAAM,CAACC,IAAI,CAAC,CAAC,gEAAgE,CAAC;gBACtF;YACF;YAEA,MAAM/C,KAAK6C,SAAS7B,yBAAyBJ,cAC1CoC,KAAK,CAAC,CAACC;gBACNC,QAAQD,KAAK,CAACA;gBACdJ,QAAQC,MAAM,CAACG,KAAK,CAAC,CAAC,mCAAmC,EAAEA,OAAO;YACpE,GACCE,OAAO,CAAC;gBACP,IAAI,CAACvC,aAAaL,qBAAqB,EAAE;oBACvC6C,WAAW;wBACTP,QAAQC,MAAM,CAACO,IAAI,CAAC3C;oBACtB,GAAG;gBACL;YACF;QACJ;QAEA,OAAOK;IACT;AAEJ,SAASJ,eAAe,GAAE"}
|
|
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 { defaultGenerationModels } from './ai/models/index.js'\nimport { lexicalJsonSchema } from './ai/schemas/lexicalJsonSchema.js'\nimport { instructionsCollection } from './collections/Instructions.js'\nimport { PLUGIN_NAME } from './defaults.js'\nimport { fetchFields } from './endpoints/fetchFields.js'\nimport { endpoints } from './endpoints/index.js'\nimport { init } from './init.js'\nimport { translations } from './translations/index.js'\nimport { getGenerationModels } from './utilities/getGenerationModels.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 generationModels: defaultGenerationModels,\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\n pluginConfig = { \n ...defaultPluginConfig, \n ...pluginConfig,\n access: {\n ...defaultPluginConfig.access,\n ...pluginConfig.access,\n }\n }\n \n pluginConfig.generationModels = getGenerationModels(pluginConfig)\n\n const isActivated = isPluginActivated(pluginConfig)\n let updatedConfig: Config = { ...incomingConfig }\n let collectionsFieldPathMap = {}\n\n if (isActivated) {\n const Instructions = instructionsCollection(pluginConfig)\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 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]\n const globals = [...(incomingConfig.globals ?? [])]\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 fetchFields(pluginConfig.access, pluginConfig.options),\n ],\n globals: globals.map((global) => {\n if (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) await incomingConfig.onInit(payload)\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 console.error(error)\n payload.logger.error(`— AI Plugin: Initialization Error: ${error}`)\n })\n .finally(() => {\n setTimeout(() => {\n payload.logger.info(securityMessage)\n }, 1000)\n \n if (!pluginConfig.disableSponsorMessage) {\n setTimeout(() => {\n payload.logger.info(sponsorMessage)\n }, 3000)\n }\n })\n }\n\n return updatedConfig\n }\n\nexport { payloadAiPlugin }"],"names":["deepMerge","defaultGenerationModels","lexicalJsonSchema","instructionsCollection","PLUGIN_NAME","fetchFields","endpoints","init","translations","getGenerationModels","isPluginActivated","updateFieldsConfig","defaultPluginConfig","access","generate","req","user","settings","collections","disableSponsorMessage","generatePromptOnInit","generationModels","sponsorMessage","securityMessage","payloadAiPlugin","pluginConfig","incomingConfig","isActivated","updatedConfig","collectionsFieldPathMap","Instructions","lexicalSchema","editorConfig","nodes","debugging","admin","hidden","custom","schema","globals","collectionSlugs","globalsSlugs","components","providers","updatedProviders","path","pluginEndpoints","map","collection","slug","schemaPathMap","updatedCollectionConfig","textarea","upload","options","global","i18n","onInit","payload","logger","warn","catch","error","console","finally","setTimeout","info"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InstructionsProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/InstructionsProvider/InstructionsProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAGpC,OAAO,KAA6C,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"InstructionsProvider.d.ts","sourceRoot":"","sources":["../../../src/providers/InstructionsProvider/InstructionsProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAGpC,OAAO,KAA6C,MAAM,OAAO,CAAA;AAqBjE,eAAO,MAAM,mBAAmB;uBAhBX,MAAM;uBACN,MAAM,EAAE;YACnB,KAAK;kBACC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;qBAChB,OAAO;WACjB,MAAM;iBACA,OAAO;0BACE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI;EASkB,CAAA;AAEhE,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EA0CxC,CAAA"}
|
|
@@ -15,6 +15,7 @@ export const InstructionsProvider = ({ children })=>{
|
|
|
15
15
|
const [instructions, setInstructionsState] = useState({});
|
|
16
16
|
const [activeCollection, setActiveCollection] = useState('');
|
|
17
17
|
const [isConfigAllowed, setIsConfigAllowed] = useState(false);
|
|
18
|
+
const [enabledLanguages, setEnabledLanguages] = useState();
|
|
18
19
|
const { user } = useAuth();
|
|
19
20
|
const { config } = useConfig();
|
|
20
21
|
const { routes: { api }, serverURL } = config;
|
|
@@ -24,6 +25,7 @@ export const InstructionsProvider = ({ children })=>{
|
|
|
24
25
|
fetch(`${serverURL}${api}${PLUGIN_FETCH_FIELDS_ENDPOINT}`).then(async (res)=>{
|
|
25
26
|
await res.json().then((data)=>{
|
|
26
27
|
setIsConfigAllowed(data?.isConfigAllowed);
|
|
28
|
+
setEnabledLanguages(data?.enabledLanguages);
|
|
27
29
|
setInstructionsState(data?.fields);
|
|
28
30
|
});
|
|
29
31
|
}).catch((err)=>{
|
|
@@ -35,6 +37,7 @@ export const InstructionsProvider = ({ children })=>{
|
|
|
35
37
|
return /*#__PURE__*/ _jsx(InstructionsContext.Provider, {
|
|
36
38
|
value: {
|
|
37
39
|
activeCollection,
|
|
40
|
+
enabledLanguages,
|
|
38
41
|
instructions,
|
|
39
42
|
isConfigAllowed,
|
|
40
43
|
setActiveCollection
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/providers/InstructionsProvider/InstructionsProvider.tsx"],"sourcesContent":["'use client'\n\nimport type { Field } from 'payload'\n\nimport { useAuth, useConfig } from '@payloadcms/ui'\nimport React, { createContext, useEffect, useState } from 'react'\n\nimport { PLUGIN_FETCH_FIELDS_ENDPOINT } from '../../defaults.js'\n\nconst initialContext: {\n activeCollection?: string\n field?: Field\n instructions: Record<string, any>\n isConfigAllowed: boolean\n path?: string\n schemaPath?: unknown\n setActiveCollection?: (val: unknown) => void\n} = {\n field: undefined,\n instructions: undefined,\n isConfigAllowed: true,\n path: '',\n schemaPath: '',\n}\n\nexport const InstructionsContext = createContext(initialContext)\n\nexport const InstructionsProvider: React.FC = ({ children }: { children: React.ReactNode }) => {\n const [instructions, setInstructionsState] = useState({})\n const [activeCollection, setActiveCollection] = useState('')\n const [isConfigAllowed, setIsConfigAllowed] = useState(false)\n const { user } = useAuth()\n\n const { config } = useConfig()\n const {\n routes: { api },\n serverURL,\n } = config\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 fetch(`${serverURL}${api}${PLUGIN_FETCH_FIELDS_ENDPOINT}`)\n .then(async (res) => {\n await res.json().then((data) => {\n setIsConfigAllowed(data?.isConfigAllowed)\n setInstructionsState(data?.fields)\n })\n })\n .catch((err) => {\n console.error('InstructionsProvider:', err)\n })\n }, [user])\n\n return (\n <InstructionsContext.Provider\n value={{
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/InstructionsProvider/InstructionsProvider.tsx"],"sourcesContent":["'use client'\n\nimport type { Field } from 'payload'\n\nimport { useAuth, useConfig } from '@payloadcms/ui'\nimport React, { createContext, useEffect, useState } from 'react'\n\nimport { PLUGIN_FETCH_FIELDS_ENDPOINT } from '../../defaults.js'\n\nconst initialContext: {\n activeCollection?: string\n enabledLanguages?: string[]\n field?: Field\n instructions: Record<string, any>\n isConfigAllowed: boolean\n path?: string\n schemaPath?: unknown\n setActiveCollection?: (val: unknown) => void\n} = {\n field: undefined,\n instructions: undefined,\n isConfigAllowed: true,\n path: '',\n schemaPath: '',\n}\n\nexport const InstructionsContext = createContext(initialContext)\n\nexport const InstructionsProvider: React.FC = ({ children }: { children: React.ReactNode }) => {\n const [instructions, setInstructionsState] = useState({})\n const [activeCollection, setActiveCollection] = useState('')\n const [isConfigAllowed, setIsConfigAllowed] = useState(false)\n const [enabledLanguages, setEnabledLanguages] = useState<string[]>()\n const { user } = useAuth()\n\n const { config } = useConfig()\n const {\n routes: { api },\n serverURL,\n } = config\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 fetch(`${serverURL}${api}${PLUGIN_FETCH_FIELDS_ENDPOINT}`)\n .then(async (res) => {\n await res.json().then((data) => {\n setIsConfigAllowed(data?.isConfigAllowed)\n setEnabledLanguages(data?.enabledLanguages)\n setInstructionsState(data?.fields)\n })\n })\n .catch((err) => {\n console.error('InstructionsProvider:', err)\n })\n }, [user])\n\n return (\n <InstructionsContext.Provider\n value={{\n activeCollection,\n enabledLanguages,\n instructions,\n isConfigAllowed,\n setActiveCollection,\n }}\n >\n {children}\n </InstructionsContext.Provider>\n )\n}\n"],"names":["useAuth","useConfig","React","createContext","useEffect","useState","PLUGIN_FETCH_FIELDS_ENDPOINT","initialContext","field","undefined","instructions","isConfigAllowed","path","schemaPath","InstructionsContext","InstructionsProvider","children","setInstructionsState","activeCollection","setActiveCollection","setIsConfigAllowed","enabledLanguages","setEnabledLanguages","user","config","routes","api","serverURL","fetch","then","res","json","data","fields","catch","err","console","error","Provider","value"],"mappings":"AAAA;;AAIA,SAASA,OAAO,EAAEC,SAAS,QAAQ,iBAAgB;AACnD,OAAOC,SAASC,aAAa,EAAEC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAEjE,SAASC,4BAA4B,QAAQ,oBAAmB;AAEhE,MAAMC,iBASF;IACFC,OAAOC;IACPC,cAAcD;IACdE,iBAAiB;IACjBC,MAAM;IACNC,YAAY;AACd;AAEA,OAAO,MAAMC,oCAAsBX,cAAcI,gBAAe;AAEhE,OAAO,MAAMQ,uBAAiC,CAAC,EAAEC,QAAQ,EAAiC;IACxF,MAAM,CAACN,cAAcO,qBAAqB,GAAGZ,SAAS,CAAC;IACvD,MAAM,CAACa,kBAAkBC,oBAAoB,GAAGd,SAAS;IACzD,MAAM,CAACM,iBAAiBS,mBAAmB,GAAGf,SAAS;IACvD,MAAM,CAACgB,kBAAkBC,oBAAoB,GAAGjB;IAChD,MAAM,EAAEkB,IAAI,EAAE,GAAGvB;IAEjB,MAAM,EAAEwB,MAAM,EAAE,GAAGvB;IACnB,MAAM,EACJwB,QAAQ,EAAEC,GAAG,EAAE,EACfC,SAAS,EACV,GAAGH;IAEJ,iEAAiE;IACjE,6CAA6C;IAC7CpB,UAAU;QACRwB,MAAM,GAAGD,YAAYD,MAAMpB,8BAA8B,EACtDuB,IAAI,CAAC,OAAOC;YACX,MAAMA,IAAIC,IAAI,GAAGF,IAAI,CAAC,CAACG;gBACrBZ,mBAAmBY,MAAMrB;gBACzBW,oBAAoBU,MAAMX;gBAC1BJ,qBAAqBe,MAAMC;YAC7B;QACF,GACCC,KAAK,CAAC,CAACC;YACNC,QAAQC,KAAK,CAAC,yBAAyBF;QACzC;IACJ,GAAG;QAACZ;KAAK;IAET,qBACE,KAACT,oBAAoBwB,QAAQ;QAC3BC,OAAO;YACLrB;YACAG;YACAX;YACAC;YACAQ;QACF;kBAECH;;AAGP,EAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -3,10 +3,30 @@ import type { ImageGenerateParams } from 'openai/resources/images';
|
|
|
3
3
|
import type { CollectionSlug, DataFromCollectionSlug, Endpoint, Field, File, GlobalConfig, GroupField, PayloadRequest } from 'payload';
|
|
4
4
|
import type { CSSProperties, MouseEventHandler } from 'react';
|
|
5
5
|
export interface PluginConfigAccess {
|
|
6
|
+
/**
|
|
7
|
+
* Control access to AI generation features (generate text, images, audio)
|
|
8
|
+
* @default () => !!req.user (requires authentication)
|
|
9
|
+
*/
|
|
10
|
+
generate?: ({ req }: {
|
|
11
|
+
req: PayloadRequest;
|
|
12
|
+
}) => Promise<boolean> | boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Control access to AI settings/configuration
|
|
15
|
+
* @default () => !!req.user (requires authentication)
|
|
16
|
+
*/
|
|
6
17
|
settings?: ({ req }: {
|
|
7
18
|
req: PayloadRequest;
|
|
8
19
|
}) => Promise<boolean> | boolean;
|
|
9
20
|
}
|
|
21
|
+
export interface PluginOptions {
|
|
22
|
+
/**
|
|
23
|
+
* Provide local tags to filter language options from the Translate Menu
|
|
24
|
+
* Check for the available local tags,
|
|
25
|
+
* visit: https://www.npmjs.com/package/locale-codes
|
|
26
|
+
* Example: ["en-US", "zh-SG", "zh-CN", "en"]
|
|
27
|
+
*/
|
|
28
|
+
enabledLanguages?: string[];
|
|
29
|
+
}
|
|
10
30
|
export type PluginConfigMediaUploadFunction = (result: {
|
|
11
31
|
data: Record<any, any>;
|
|
12
32
|
file: File;
|
|
@@ -15,6 +35,10 @@ export type PluginConfigMediaUploadFunction = (result: {
|
|
|
15
35
|
request: PayloadRequest;
|
|
16
36
|
}) => Promise<DataFromCollectionSlug<CollectionSlug>>;
|
|
17
37
|
export interface PluginConfig {
|
|
38
|
+
/**
|
|
39
|
+
* Access control configuration for AI features
|
|
40
|
+
* By default, all AI features require authentication
|
|
41
|
+
*/
|
|
18
42
|
access?: PluginConfigAccess;
|
|
19
43
|
collections: {
|
|
20
44
|
[key: CollectionSlug]: boolean;
|
|
@@ -32,6 +56,7 @@ export interface PluginConfig {
|
|
|
32
56
|
};
|
|
33
57
|
interfaceName?: string;
|
|
34
58
|
mediaUpload?: PluginConfigMediaUploadFunction;
|
|
59
|
+
options?: PluginOptions;
|
|
35
60
|
uploadCollectionSlug?: CollectionSlug;
|
|
36
61
|
}
|
|
37
62
|
export interface GenerationModel {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { JSONSchema } from 'openai/lib/jsonschema'\nimport type { ImageGenerateParams } from 'openai/resources/images'\nimport type {\n CollectionSlug,\n DataFromCollectionSlug,\n Endpoint,\n Field,\n File,\n GlobalConfig,\n GroupField,\n PayloadRequest,\n} from 'payload'\nimport type { CSSProperties, MouseEventHandler } from 'react'\n\nexport interface PluginConfigAccess {\n settings?: ({ req }: { req: PayloadRequest }) => Promise<boolean> | boolean\n}\n\nexport type PluginConfigMediaUploadFunction = (\n result: { data: Record<any, any>; file: File },\n {\n collection,\n request,\n }: {\n collection: CollectionSlug\n request: PayloadRequest\n },\n) => Promise<DataFromCollectionSlug<CollectionSlug>>\n\nexport interface PluginConfig {\n access?: PluginConfigAccess\n collections: {\n [key: CollectionSlug]: boolean\n }\n debugging?: boolean\n disableSponsorMessage?: boolean\n editorConfig?: { nodes: JSONSchema[] }\n fields?: Field[]\n generatePromptOnInit?: boolean\n generationModels?: ((defaultModels: GenerationModel[]) => GenerationModel[]) | GenerationModel[]\n globals?: {\n [key: GlobalConfig['slug']]: boolean\n }\n interfaceName?: string\n mediaUpload?: PluginConfigMediaUploadFunction\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) => 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 textarea: Omit<Endpoint, 'root'>\n upload: 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 ActionMenuEvents =\n | 'onCompose'\n | 'onExpand'\n | 'onProofread'\n | 'onRephrase'\n | 'onSettings'\n | 'onSimplify'\n | 'onSummarize'\n | 'onTone'\n | 'onTranslate'\n\nexport type UseMenuEvents = {\n [key in ActionMenuEvents]?: (data?: unknown) => void\n}\n\nexport type UseMenuOptions = {\n isConfigAllowed: boolean\n}\n\nexport type BaseItemProps<T = any> = {\n children?: React.ReactNode\n disabled?: boolean\n hideIcon?: boolean\n isActive?: boolean\n isMenu?: boolean\n onClick: (data?: unknown) => void\n onMouseEnter?: MouseEventHandler<T> | undefined\n onMouseLeave?: MouseEventHandler<T> | undefined\n style?: CSSProperties | undefined\n title?: string\n}\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"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { JSONSchema } from 'openai/lib/jsonschema'\nimport type { ImageGenerateParams } from 'openai/resources/images'\nimport type {\n CollectionSlug,\n DataFromCollectionSlug,\n Endpoint,\n Field,\n File,\n GlobalConfig,\n GroupField,\n PayloadRequest,\n} from 'payload'\nimport type { CSSProperties, MouseEventHandler } from 'react'\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 }) => Promise<boolean> | boolean\n /**\n * Control access to AI settings/configuration\n * @default () => !!req.user (requires authentication)\n */\n settings?: ({ req }: { req: PayloadRequest }) => Promise<boolean> | boolean\n}\n\nexport interface PluginOptions {\n\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: { data: Record<any, any>; file: File },\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 collections: {\n [key: CollectionSlug]: boolean\n }\n debugging?: boolean\n disableSponsorMessage?: boolean\n editorConfig?: { nodes: JSONSchema[] }\n fields?: Field[]\n generatePromptOnInit?: boolean\n generationModels?: ((defaultModels: GenerationModel[]) => GenerationModel[]) | GenerationModel[]\n globals?: {\n [key: GlobalConfig['slug']]: boolean\n }\n interfaceName?: string\n mediaUpload?: PluginConfigMediaUploadFunction\n options?: PluginOptions\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) => 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 textarea: Omit<Endpoint, 'root'>\n upload: 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 ActionMenuEvents =\n | 'onCompose'\n | 'onExpand'\n | 'onProofread'\n | 'onRephrase'\n | 'onSettings'\n | 'onSimplify'\n | 'onSummarize'\n | 'onTone'\n | 'onTranslate'\n\nexport type UseMenuEvents = {\n [key in ActionMenuEvents]?: (data?: unknown) => void\n}\n\nexport type UseMenuOptions = {\n isConfigAllowed: boolean\n}\n\nexport type BaseItemProps<T = any> = {\n children?: React.ReactNode\n disabled?: boolean\n hideIcon?: boolean\n isActive?: boolean\n isMenu?: boolean\n onClick: (data?: unknown) => void\n onMouseEnter?: MouseEventHandler<T> | undefined\n onMouseLeave?: MouseEventHandler<T> | undefined\n style?: CSSProperties | undefined\n title?: string\n}\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"],"names":[],"mappings":"AAyJA,WAKC"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
export declare const TranslateMenu: ({ onClick }: {
|
|
2
3
|
onClick: any;
|
|
3
4
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare const MemoizedTranslateMenu: React.MemoExoticComponent<({ onClick }: {
|
|
6
|
+
onClick: any;
|
|
7
|
+
}) => import("react/jsx-runtime").JSX.Element>;
|
|
4
8
|
//# sourceMappingURL=TranslateMenu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TranslateMenu.d.ts","sourceRoot":"","sources":["../../../../../src/ui/Compose/hooks/menu/TranslateMenu.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TranslateMenu.d.ts","sourceRoot":"","sources":["../../../../../src/ui/Compose/hooks/menu/TranslateMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAAyB,MAAM,OAAO,CAAA;AAO7C,eAAO,MAAM,aAAa,GAAI;;CAAW,4CAsFxC,CAAA;AAED,eAAO,MAAM,qBAAqB;;8CAAsB,CAAA"}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import locales from 'locale-codes';
|
|
3
|
-
import React, { useState } from 'react';
|
|
3
|
+
import React, { memo, useState } from 'react';
|
|
4
|
+
import { useInstructions } from '../../../../providers/InstructionsProvider/useInstructions.js';
|
|
4
5
|
import { Item } from './Item.js';
|
|
5
6
|
import { Translate } from './items.js';
|
|
6
7
|
import styles from './menu.module.scss';
|
|
7
8
|
export const TranslateMenu = ({ onClick })=>{
|
|
8
9
|
const [show, setShow] = useState(false);
|
|
9
|
-
const
|
|
10
|
+
const { enabledLanguages = [] } = useInstructions();
|
|
11
|
+
let filteredLocales = locales.all.filter((a)=>{
|
|
10
12
|
return a.tag && a.location;
|
|
11
13
|
});
|
|
14
|
+
if (enabledLanguages?.length) {
|
|
15
|
+
filteredLocales = filteredLocales.filter((a)=>enabledLanguages?.includes(a.tag));
|
|
16
|
+
}
|
|
12
17
|
const [languages, setLanguages] = useState(filteredLocales);
|
|
13
18
|
const [inputFocus, setInputFocus] = useState(false);
|
|
14
19
|
return /*#__PURE__*/ _jsxs("div", {
|
|
@@ -33,8 +38,7 @@ export const TranslateMenu = ({ onClick })=>{
|
|
|
33
38
|
children: /*#__PURE__*/ _jsxs("div", {
|
|
34
39
|
className: `${styles.menu} ${styles.subMenu}`,
|
|
35
40
|
style: {
|
|
36
|
-
background:
|
|
37
|
-
minHeight: "300px"
|
|
41
|
+
background: 'var(--popup-bg)'
|
|
38
42
|
},
|
|
39
43
|
children: [
|
|
40
44
|
/*#__PURE__*/ _jsx(Item, {
|
|
@@ -78,5 +82,6 @@ export const TranslateMenu = ({ onClick })=>{
|
|
|
78
82
|
]
|
|
79
83
|
});
|
|
80
84
|
};
|
|
85
|
+
export const MemoizedTranslateMenu = /*#__PURE__*/ memo(TranslateMenu);
|
|
81
86
|
|
|
82
87
|
//# sourceMappingURL=TranslateMenu.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/ui/Compose/hooks/menu/TranslateMenu.tsx"],"sourcesContent":["import locales from 'locale-codes'\nimport React, { useState } from 'react'\n\nimport { Item } from './Item.js'\nimport { Translate } from './items.js'\nimport styles from './menu.module.scss'\n\nexport const TranslateMenu = ({ onClick }) => {\n const [show, setShow] = useState(false)\n\n const filteredLocales = locales.all.filter((a) => {\n return a.tag && a.location\n })\n\n const [languages, setLanguages] = useState(filteredLocales)\n const [inputFocus, setInputFocus] = useState(false)\n\n return (\n <div\n className={styles.menu}\n onMouseLeave={() => {\n if (!inputFocus) {\n setShow(false)\n }\n }}\n >\n <Translate\n isActive={show}\n isMenu\n onClick={() => {\n setShow(!show)\n }}\n onMouseEnter={() => setShow(true)}\n
|
|
1
|
+
{"version":3,"sources":["../../../../../src/ui/Compose/hooks/menu/TranslateMenu.tsx"],"sourcesContent":["import locales from 'locale-codes'\nimport React, { memo, useState } from 'react'\n\nimport { useInstructions } from '../../../../providers/InstructionsProvider/useInstructions.js'\nimport { Item } from './Item.js'\nimport { Translate } from './items.js'\nimport styles from './menu.module.scss'\n\nexport const TranslateMenu = ({ onClick }) => {\n const [show, setShow] = useState(false)\n\n const { enabledLanguages = [] } = useInstructions()\n\n let filteredLocales = locales.all.filter((a) => {\n return a.tag && a.location\n })\n\n if (enabledLanguages?.length) {\n filteredLocales = filteredLocales.filter((a) => enabledLanguages?.includes(a.tag))\n }\n\n const [languages, setLanguages] = useState(filteredLocales)\n const [inputFocus, setInputFocus] = useState(false)\n\n return (\n <div\n className={styles.menu}\n onMouseLeave={() => {\n if (!inputFocus) {\n setShow(false)\n }\n }}\n >\n <Translate\n isActive={show}\n isMenu\n onClick={() => {\n setShow(!show)\n }}\n onMouseEnter={() => setShow(true)}\n />\n <div className={styles.hoverMenu} data-show={show}>\n <div\n className={`${styles.menu} ${styles.subMenu}`}\n style={{\n background: 'var(--popup-bg)',\n // minHeight: '300px',\n }}\n >\n <Item\n onClick={() => {}}\n style={{\n background: 'transparent',\n padding: '0 0 5px 0',\n position: 'sticky',\n top: 0,\n }}\n >\n <input\n className={styles.menuInput}\n onBlur={() => setInputFocus(false)}\n onChange={(event) => {\n const value = event.target.value\n setLanguages(\n filteredLocales.filter((l) => {\n const lowerCaseValue = value.toLowerCase()\n return (\n l.name.toLowerCase().startsWith(lowerCaseValue) ||\n l.location.toLowerCase().startsWith(lowerCaseValue) ||\n l.tag.toLowerCase().startsWith(lowerCaseValue)\n )\n }),\n )\n }}\n onFocus={() => setInputFocus(true)}\n placeholder=\"Search...\"\n />\n </Item>\n {languages.map((locale) => {\n return (\n <Item\n key={locale.tag}\n onClick={() => {\n onClick({ locale: locale.tag })\n }}\n >\n <span className={styles.ellipsis}>{`${locale.location} (${locale.tag})`}</span>\n </Item>\n )\n })}\n </div>\n </div>\n </div>\n )\n}\n\nexport const MemoizedTranslateMenu = memo(TranslateMenu)\n"],"names":["locales","React","memo","useState","useInstructions","Item","Translate","styles","TranslateMenu","onClick","show","setShow","enabledLanguages","filteredLocales","all","filter","a","tag","location","length","includes","languages","setLanguages","inputFocus","setInputFocus","div","className","menu","onMouseLeave","isActive","isMenu","onMouseEnter","hoverMenu","data-show","subMenu","style","background","padding","position","top","input","menuInput","onBlur","onChange","event","value","target","l","lowerCaseValue","toLowerCase","name","startsWith","onFocus","placeholder","map","locale","span","ellipsis","MemoizedTranslateMenu"],"mappings":";AAAA,OAAOA,aAAa,eAAc;AAClC,OAAOC,SAASC,IAAI,EAAEC,QAAQ,QAAQ,QAAO;AAE7C,SAASC,eAAe,QAAQ,gEAA+D;AAC/F,SAASC,IAAI,QAAQ,YAAW;AAChC,SAASC,SAAS,QAAQ,aAAY;AACtC,OAAOC,YAAY,qBAAoB;AAEvC,OAAO,MAAMC,gBAAgB,CAAC,EAAEC,OAAO,EAAE;IACvC,MAAM,CAACC,MAAMC,QAAQ,GAAGR,SAAS;IAEjC,MAAM,EAAES,mBAAmB,EAAE,EAAE,GAAGR;IAElC,IAAIS,kBAAkBb,QAAQc,GAAG,CAACC,MAAM,CAAC,CAACC;QACxC,OAAOA,EAAEC,GAAG,IAAID,EAAEE,QAAQ;IAC5B;IAEA,IAAIN,kBAAkBO,QAAQ;QAC5BN,kBAAkBA,gBAAgBE,MAAM,CAAC,CAACC,IAAMJ,kBAAkBQ,SAASJ,EAAEC,GAAG;IAClF;IAEA,MAAM,CAACI,WAAWC,aAAa,GAAGnB,SAASU;IAC3C,MAAM,CAACU,YAAYC,cAAc,GAAGrB,SAAS;IAE7C,qBACE,MAACsB;QACCC,WAAWnB,OAAOoB,IAAI;QACtBC,cAAc;YACZ,IAAI,CAACL,YAAY;gBACfZ,QAAQ;YACV;QACF;;0BAEA,KAACL;gBACCuB,UAAUnB;gBACVoB,MAAM;gBACNrB,SAAS;oBACPE,QAAQ,CAACD;gBACX;gBACAqB,cAAc,IAAMpB,QAAQ;;0BAE9B,KAACc;gBAAIC,WAAWnB,OAAOyB,SAAS;gBAAEC,aAAWvB;0BAC3C,cAAA,MAACe;oBACCC,WAAW,GAAGnB,OAAOoB,IAAI,CAAC,CAAC,EAAEpB,OAAO2B,OAAO,EAAE;oBAC7CC,OAAO;wBACLC,YAAY;oBAEd;;sCAEA,KAAC/B;4BACCI,SAAS,KAAO;4BAChB0B,OAAO;gCACLC,YAAY;gCACZC,SAAS;gCACTC,UAAU;gCACVC,KAAK;4BACP;sCAEA,cAAA,KAACC;gCACCd,WAAWnB,OAAOkC,SAAS;gCAC3BC,QAAQ,IAAMlB,cAAc;gCAC5BmB,UAAU,CAACC;oCACT,MAAMC,QAAQD,MAAME,MAAM,CAACD,KAAK;oCAChCvB,aACET,gBAAgBE,MAAM,CAAC,CAACgC;wCACtB,MAAMC,iBAAiBH,MAAMI,WAAW;wCACxC,OACEF,EAAEG,IAAI,CAACD,WAAW,GAAGE,UAAU,CAACH,mBAChCD,EAAE7B,QAAQ,CAAC+B,WAAW,GAAGE,UAAU,CAACH,mBACpCD,EAAE9B,GAAG,CAACgC,WAAW,GAAGE,UAAU,CAACH;oCAEnC;gCAEJ;gCACAI,SAAS,IAAM5B,cAAc;gCAC7B6B,aAAY;;;wBAGfhC,UAAUiC,GAAG,CAAC,CAACC;4BACd,qBACE,KAAClD;gCAECI,SAAS;oCACPA,QAAQ;wCAAE8C,QAAQA,OAAOtC,GAAG;oCAAC;gCAC/B;0CAEA,cAAA,KAACuC;oCAAK9B,WAAWnB,OAAOkD,QAAQ;8CAAG,GAAGF,OAAOrC,QAAQ,CAAC,EAAE,EAAEqC,OAAOtC,GAAG,CAAC,CAAC,CAAC;;+BALlEsC,OAAOtC,GAAG;wBAQrB;;;;;;AAKV,EAAC;AAED,OAAO,MAAMyC,sCAAwBxD,KAAKM,eAAc"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MemoizedTranslateMenu } from './TranslateMenu.js';
|
|
2
2
|
import { Compose, Expand, Proofread, Rephrase, Settings, Simplify, Summarize } from './items.js';
|
|
3
3
|
export const menuItemsMap = [
|
|
4
4
|
{
|
|
@@ -19,7 +19,7 @@ export const menuItemsMap = [
|
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
name: 'Translate',
|
|
22
|
-
component:
|
|
22
|
+
component: MemoizedTranslateMenu,
|
|
23
23
|
excludedFor: [
|
|
24
24
|
'upload'
|
|
25
25
|
],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/ui/Compose/hooks/menu/itemsMap.ts"],"sourcesContent":["import type React from 'react'\n\nimport type { ActionMenuItems, BaseItemProps } from '../../../../types.js'\n\nimport { TranslateMenu } from './TranslateMenu.js'\nimport { Compose, Expand, Proofread, Rephrase, Settings, Simplify, Summarize } from './items.js'\n\ntype MenuItemsMapType = {\n component: React.FC<BaseItemProps>\n excludedFor?: string[]\n loadingText?: string\n name: ActionMenuItems\n}\n\nexport const menuItemsMap: MenuItemsMapType[] = [\n { name: 'Proofread', component: Proofread, excludedFor: ['upload'], loadingText: 'Proofreading' },\n { name: 'Rephrase', component: Rephrase, excludedFor: ['upload'], loadingText: 'Rephrasing' },\n {\n name: 'Translate',\n component:
|
|
1
|
+
{"version":3,"sources":["../../../../../src/ui/Compose/hooks/menu/itemsMap.ts"],"sourcesContent":["import type React from 'react'\n\nimport type { ActionMenuItems, BaseItemProps } from '../../../../types.js'\n\nimport { MemoizedTranslateMenu, TranslateMenu } from './TranslateMenu.js'\nimport { Compose, Expand, Proofread, Rephrase, Settings, Simplify, Summarize } from './items.js'\n\ntype MenuItemsMapType = {\n component: React.FC<BaseItemProps>\n excludedFor?: string[]\n loadingText?: string\n name: ActionMenuItems\n}\n\nexport const menuItemsMap: MenuItemsMapType[] = [\n { name: 'Proofread', component: Proofread, excludedFor: ['upload'], loadingText: 'Proofreading' },\n { name: 'Rephrase', component: Rephrase, excludedFor: ['upload'], loadingText: 'Rephrasing' },\n {\n name: 'Translate',\n component: MemoizedTranslateMenu,\n excludedFor: ['upload'],\n loadingText: 'Translating',\n },\n { name: 'Expand', component: Expand, excludedFor: ['upload', 'text'], loadingText: 'Expanding' },\n {\n // Turned off - WIP\n name: 'Summarize',\n component: Summarize,\n excludedFor: ['upload', 'text', 'richText'],\n loadingText: 'Summarizing',\n },\n { name: 'Simplify', component: Simplify, excludedFor: ['upload'], loadingText: 'Simplifying' },\n { name: 'Compose', component: Compose, loadingText: 'Composing' },\n { name: 'Settings', component: Settings },\n]\n"],"names":["MemoizedTranslateMenu","Compose","Expand","Proofread","Rephrase","Settings","Simplify","Summarize","menuItemsMap","name","component","excludedFor","loadingText"],"mappings":"AAIA,SAASA,qBAAqB,QAAuB,qBAAoB;AACzE,SAASC,OAAO,EAAEC,MAAM,EAAEC,SAAS,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,SAAS,QAAQ,aAAY;AAShG,OAAO,MAAMC,eAAmC;IAC9C;QAAEC,MAAM;QAAaC,WAAWP;QAAWQ,aAAa;YAAC;SAAS;QAAEC,aAAa;IAAe;IAChG;QAAEH,MAAM;QAAYC,WAAWN;QAAUO,aAAa;YAAC;SAAS;QAAEC,aAAa;IAAa;IAC5F;QACEH,MAAM;QACNC,WAAWV;QACXW,aAAa;YAAC;SAAS;QACvBC,aAAa;IACf;IACA;QAAEH,MAAM;QAAUC,WAAWR;QAAQS,aAAa;YAAC;YAAU;SAAO;QAAEC,aAAa;IAAY;IAC/F;QACE,mBAAmB;QACnBH,MAAM;QACNC,WAAWH;QACXI,aAAa;YAAC;YAAU;YAAQ;SAAW;QAC3CC,aAAa;IACf;IACA;QAAEH,MAAM;QAAYC,WAAWJ;QAAUK,aAAa;YAAC;SAAS;QAAEC,aAAa;IAAc;IAC7F;QAAEH,MAAM;QAAWC,WAAWT;QAASW,aAAa;IAAY;IAChE;QAAEH,MAAM;QAAYC,WAAWL;IAAS;CACzC,CAAA"}
|