@ai-stack/payloadcms 3.2.18-beta → 3.2.19-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 +15 -0
- package/dist/collections/Instructions.d.ts +1 -1
- package/dist/collections/Instructions.js +9 -9
- package/dist/collections/Instructions.js.map +1 -1
- package/dist/endpoints/fetchFields.js +1 -0
- package/dist/endpoints/fetchFields.js.map +1 -1
- package/dist/endpoints/index.js +10 -6
- package/dist/endpoints/index.js.map +1 -1
- package/dist/exports/types.d.ts +1 -1
- package/dist/exports/types.js.map +1 -1
- package/dist/fields/ComposeField/ComposeField.js +22 -14
- package/dist/fields/ComposeField/ComposeField.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/init.js +61 -30
- package/dist/init.js.map +1 -1
- package/dist/plugin.js +3 -3
- package/dist/plugin.js.map +1 -1
- package/dist/providers/InstructionsProvider/InstructionsProvider.js +8 -4
- package/dist/providers/InstructionsProvider/InstructionsProvider.js.map +1 -1
- package/dist/providers/InstructionsProvider/context.d.ts +2 -0
- package/dist/providers/InstructionsProvider/context.js +2 -0
- package/dist/providers/InstructionsProvider/context.js.map +1 -1
- package/dist/providers/InstructionsProvider/useInstructions.js +15 -3
- package/dist/providers/InstructionsProvider/useInstructions.js.map +1 -1
- package/dist/types.d.ts +10 -3
- package/dist/types.js.map +1 -1
- package/dist/ui/Compose/Compose.js +21 -30
- package/dist/ui/Compose/Compose.js.map +1 -1
- package/dist/utilities/extractImageData.js +1 -1
- package/dist/utilities/extractImageData.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -201,6 +201,21 @@ export default buildConfig({
|
|
|
201
201
|
}
|
|
202
202
|
],
|
|
203
203
|
|
|
204
|
+
// Optional: Control how field prompts are seeded for the first time
|
|
205
|
+
seedPrompts: ({path}) => {
|
|
206
|
+
if (path.endsWith('.meta.description')) {
|
|
207
|
+
return {
|
|
208
|
+
data: {
|
|
209
|
+
prompt: 'Generate SEO-friendly title for this document: {{markdown}}',
|
|
210
|
+
// other instruction options
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// Don't allow generating slugs
|
|
215
|
+
if (path.endswith('.slug')) return false
|
|
216
|
+
// returning undefined fallbacks to default seed prompt
|
|
217
|
+
},
|
|
218
|
+
|
|
204
219
|
// Optional: Custom media upload handling, useful for multi-tenant setups
|
|
205
220
|
mediaUpload: async (result, { request, collection }) => {
|
|
206
221
|
return request.payload.create({
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { CollectionConfig } from 'payload';
|
|
2
2
|
import type { PluginConfig } from 'src/types.js';
|
|
3
|
-
export declare const instructionsCollection: (pluginConfig: PluginConfig
|
|
3
|
+
export declare const instructionsCollection: (pluginConfig: PluginConfig) => CollectionConfig;
|
|
@@ -43,16 +43,20 @@ const defaultAdminConfig = {
|
|
|
43
43
|
group: 'Plugins',
|
|
44
44
|
hidden: true
|
|
45
45
|
};
|
|
46
|
-
export const instructionsCollection = (pluginConfig
|
|
46
|
+
export const instructionsCollection = (pluginConfig)=>({
|
|
47
|
+
labels: {
|
|
48
|
+
plural: 'Compose Settings',
|
|
49
|
+
singular: 'Compose Setting'
|
|
50
|
+
},
|
|
51
|
+
...pluginConfig.overrideInstructions,
|
|
47
52
|
slug: PLUGIN_INSTRUCTIONS_TABLE,
|
|
48
53
|
access: {
|
|
49
54
|
...defaultAccessConfig,
|
|
50
|
-
...
|
|
55
|
+
...pluginConfig.overrideInstructions?.access
|
|
51
56
|
},
|
|
52
57
|
admin: {
|
|
53
58
|
...defaultAdminConfig,
|
|
54
|
-
...
|
|
55
|
-
group: 'Plugins'
|
|
59
|
+
...pluginConfig.overrideInstructions?.admin
|
|
56
60
|
},
|
|
57
61
|
fields: [
|
|
58
62
|
{
|
|
@@ -229,11 +233,7 @@ informative and accurate but also captivating and beautifully structured.`,
|
|
|
229
233
|
]
|
|
230
234
|
},
|
|
231
235
|
...groupSettings(pluginConfig)
|
|
232
|
-
]
|
|
233
|
-
labels: {
|
|
234
|
-
plural: 'Compose Settings',
|
|
235
|
-
singular: 'Compose Setting'
|
|
236
|
-
}
|
|
236
|
+
]
|
|
237
237
|
});
|
|
238
238
|
|
|
239
239
|
//# sourceMappingURL=Instructions.js.map
|
|
@@ -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: ({ req }: { req: { user?: any } }) => {\n if (!req.user) {\n return false\n }\n return true\n },\n delete: ({ req }: { req: { user?: any } }) => {\n if (!req.user) {\n return false\n }\n return true\n },\n read: ({ req }: { req: { user?: any } }) => {\n if (!req.user) {\n return false\n }\n return true\n },\n update: ({ req }: { req: { user?: any } }) => {\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":"AAGA,SAASA,yBAAyB,QAAQ,iBAAgB;AAC1D,SAASC,mBAAmB,QAAQ,sCAAqC;AAEzE,MAAMC,gBAAgB,CAACC,eACrB,AAACF,CAAAA,oBAAoBE,iBAAiB,EAAE,AAAD,EAAGC,MAAM,CAAC,CAACC,QAAQC;QACxD,IAAIA,MAAMC,QAAQ,EAAE;YAClBF,OAAOG,IAAI,CAACF,MAAMC,QAAQ;QAC5B;QACA,OAAOF;IACT,GAAG,EAAE;AAEP,MAAMI,eAAe,CAACN,eACpB,AAACF,CAAAA,oBAAoBE,iBAAiB,EAAE,AAAD,EAAGO,GAAG,CAAC,CAACJ;QAC7C,OAAO;YACLD,QAAQC,MAAMD,MAAM;YACpBM,OAAOL,MAAMM,IAAI;YACjBC,OAAOP,MAAMQ,EAAE;QACjB;IACF;AAEF,MAAMC,sBAAsB;IAC1BC,QAAQ,CAAC,EAAEC,GAAG,EAA2B;QACvC,IAAI,CAACA,IAAIC,IAAI,EAAE;YACb,OAAO;QACT;QACA,OAAO;IACT;IACAC,QAAQ,CAAC,EAAEF,GAAG,EAA2B;QACvC,IAAI,CAACA,IAAIC,IAAI,EAAE;YACb,OAAO;QACT;QACA,OAAO;IACT;IACAE,MAAM,CAAC,EAAEH,GAAG,EAA2B;QACrC,IAAI,CAACA,IAAIC,IAAI,EAAE;YACb,OAAO;QACT;QACA,OAAO;IACT;IACAG,QAAQ,CAAC,EAAEJ,GAAG,EAA2B;QACvC,IAAI,CAACA,IAAIC,IAAI,EAAE;YACb,OAAO;QACT;QACA,OAAO;IACT;AACF;AAEA,MAAMI,qBAAqB;IACzBC,OAAO;IACPC,QAAQ;AACV;AAEA,OAAO,MAAMC,yBAAyB,CACpCtB,cACAuB,UAEkB,CAAA;QAChBC,MAAM3B;QACN4B,QAAQ;YACN,GAAGb,mBAAmB;YACtB,GAAGW,SAASE,MAAM;QACpB;QACAC,OAAO;YACL,GAAGP,kBAAkB;YACrB,GAAGI,SAASG,KAAK;YACjBN,OAAO;QACT;QACAlB,QAAQ;YACN;gBACEO,MAAM;gBACNkB,MAAM;gBACND,OAAO;oBACLE,aAAa;gBACf;gBACAC,QAAQ;YACV;YACA;gBACEpB,MAAM;gBACNkB,MAAM;gBACND,OAAO;oBACLE,aAAa;gBACf;gBACAE,cAAc;gBACdtB,OAAO;gBACPe,SAAS;oBACP;wBACEf,OAAO;wBACPE,OAAO;oBACT;oBACA;wBACEF,OAAO;wBACPE,OAAO;oBACT;oBACA;wBACEF,OAAO;wBACPE,OAAO;oBACT;oBACA;wBACEF,OAAO;wBACPE,OAAO;oBACT;iBACD;YACH;YACA;gBACED,MAAM;gBACNkB,MAAM;gBACND,OAAO;oBACLK,WAAW,CAACC,GAAGC;wBACb,OAAOA,OAAO,CAAC,aAAa,KAAK;oBACnC;gBACF;gBACAzB,OAAO;YACT;YACA;gBACEC,MAAM;gBACNkB,MAAM;gBACND,OAAO;oBACLQ,YAAY;wBACVC,OAAO;4BACLC,aAAa;gCACXC,eAAe;gCACfd,SAASjB,aAAaN;4BACxB;4BACAsC,MAAM;wBACR;oBACF;gBACF;gBACA9B,OAAO;gBACPe,SAASjB,aAAaN,cAAcO,GAAG,CAAC,CAACgC;oBACvC,OAAO;wBACL/B,OAAO+B,OAAO/B,KAAK;wBACnBE,OAAO6B,OAAO7B,KAAK;oBACrB;gBACF;YACF;YACA;gBACEC,IAAI;gBACJgB,MAAM;gBACNa,MAAM;oBACJ;wBACEZ,aACE;wBACF1B,QAAQ;4BACN;gCACEO,MAAM;gCACNkB,MAAM;gCACND,OAAO;oCACLQ,YAAY;wCACVC,OAAO;oCACT;oCACAP,aAAa;gCACf;gCACApB,OAAO;4BACT;yBACD;wBACDA,OAAO;oBACT;oBACA;wBACEkB,OAAO;4BACLK,WAAW,CAACC,GAAGC;gCACb,OAAOA,OAAO,CAAC,aAAa,KAAK,YAAYA,OAAO,CAAC,WAAW,KAAK;4BACvE;wBACF;wBACAL,aACE;wBACF1B,QAAQ;4BACN;gCACEO,MAAM;gCACNkB,MAAM;gCACNzB,QAAQ;oCACN;wCACEO,MAAM;wCACNkB,MAAM;wCACND,OAAO;4CACLE,aAAa;wCACf;wCACAa,YAAYzC,aAAa0C,oBAAoB,GACzC1C,aAAa0C,oBAAoB,GACjC;oCACN;iCACD;4BACH;yBACD;wBACDlC,OAAO;oBACT;oBACA;wBACEkB,OAAO;4BACLK,WAAW,CAACC,GAAGC;gCACb,OAAOA,OAAO,CAAC,aAAa,KAAK;4BACnC;wBACF;wBACAL,aAAa;wBACb1B,QAAQ;4BACN;gCACEO,MAAM;gCACNkB,MAAM;gCACNG,cAAc,CAAC;;;;yEAI0C,CAAC;gCAC1DtB,OAAO;4BACT;yBACD;wBACDA,OAAO;oBACT;oBACA;wBACEkB,OAAO;4BACLK,WAAW,CAACC,GAAGC;gCACb,OAAOA,OAAO,CAAC,aAAa,KAAK;4BACnC;wBACF;wBACAL,aAAa;wBACb1B,QAAQ;4BACN;gCACE;;;;iBAIC,GAJD;;;;iBAIC,GACDO,MAAM;gCACNkB,MAAM;gCACND,OAAO;oCACLK,WAAW,CAACC,GAAGC;wCACb,OAAOA,OAAO,CAAC,aAAa,KAAK;oCACnC;gCACF;gCACAH,cAAc,CAAC;;;;;;;2HAO4F,CAAC;gCAC5GtB,OAAO;4BACT;yBACD;wBACDA,OAAO;oBACT;iBACD;YACH;eACGT,cAAcC;SAClB;QACD2C,QAAQ;YACNC,QAAQ;YACRC,UAAU;QACZ;IACF,CAAA,EAAC"}
|
|
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 }: { req: { user?: any } }) => {\n if (!req.user) {\n return false\n }\n return true\n },\n delete: ({ req }: { req: { user?: any } }) => {\n if (!req.user) {\n return false\n }\n return true\n },\n read: ({ req }: { req: { user?: any } }) => {\n if (!req.user) {\n return false\n }\n return true\n },\n update: ({ req }: { req: { user?: any } }) => {\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) =>\n <CollectionConfig>{\n labels: {\n plural: 'Compose Settings',\n singular: 'Compose Setting',\n },\n ...pluginConfig.overrideInstructions,\n slug: PLUGIN_INSTRUCTIONS_TABLE,\n access: {\n ...defaultAccessConfig,\n ...pluginConfig.overrideInstructions?.access,\n },\n admin: {\n ...defaultAdminConfig,\n ...pluginConfig.overrideInstructions?.admin,\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 }\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","labels","plural","singular","overrideInstructions","slug","access","admin","type","description","unique","defaultValue","options","condition","_","current","components","Field","clientProps","filterByField","path","option","tabs","relationTo","uploadCollectionSlug"],"mappings":"AAGA,SAASA,yBAAyB,QAAQ,iBAAgB;AAC1D,SAASC,mBAAmB,QAAQ,sCAAqC;AAEzE,MAAMC,gBAAgB,CAACC,eACrB,AAACF,CAAAA,oBAAoBE,iBAAiB,EAAE,AAAD,EAAGC,MAAM,CAAC,CAACC,QAAQC;QACxD,IAAIA,MAAMC,QAAQ,EAAE;YAClBF,OAAOG,IAAI,CAACF,MAAMC,QAAQ;QAC5B;QACA,OAAOF;IACT,GAAG,EAAE;AAEP,MAAMI,eAAe,CAACN,eACpB,AAACF,CAAAA,oBAAoBE,iBAAiB,EAAE,AAAD,EAAGO,GAAG,CAAC,CAACJ;QAC7C,OAAO;YACLD,QAAQC,MAAMD,MAAM;YACpBM,OAAOL,MAAMM,IAAI;YACjBC,OAAOP,MAAMQ,EAAE;QACjB;IACF;AAEF,MAAMC,sBAAsB;IAC1BC,QAAQ,CAAC,EAAEC,GAAG,EAA2B;QACvC,IAAI,CAACA,IAAIC,IAAI,EAAE;YACb,OAAO;QACT;QACA,OAAO;IACT;IACAC,QAAQ,CAAC,EAAEF,GAAG,EAA2B;QACvC,IAAI,CAACA,IAAIC,IAAI,EAAE;YACb,OAAO;QACT;QACA,OAAO;IACT;IACAE,MAAM,CAAC,EAAEH,GAAG,EAA2B;QACrC,IAAI,CAACA,IAAIC,IAAI,EAAE;YACb,OAAO;QACT;QACA,OAAO;IACT;IACAG,QAAQ,CAAC,EAAEJ,GAAG,EAA2B;QACvC,IAAI,CAACA,IAAIC,IAAI,EAAE;YACb,OAAO;QACT;QACA,OAAO;IACT;AACF;AAEA,MAAMI,qBAAqB;IACzBC,OAAO;IACPC,QAAQ;AACV;AAEA,OAAO,MAAMC,yBAAyB,CACpCtB,eAEkB,CAAA;QAChBuB,QAAQ;YACNC,QAAQ;YACRC,UAAU;QACZ;QACA,GAAGzB,aAAa0B,oBAAoB;QACpCC,MAAM9B;QACN+B,QAAQ;YACN,GAAGhB,mBAAmB;YACtB,GAAGZ,aAAa0B,oBAAoB,EAAEE,MAAM;QAC9C;QACAC,OAAO;YACL,GAAGV,kBAAkB;YACrB,GAAGnB,aAAa0B,oBAAoB,EAAEG,KAAK;QAC7C;QACA3B,QAAQ;YACN;gBACEO,MAAM;gBACNqB,MAAM;gBACND,OAAO;oBACLE,aAAa;gBACf;gBACAC,QAAQ;YACV;YACA;gBACEvB,MAAM;gBACNqB,MAAM;gBACND,OAAO;oBACLE,aAAa;gBACf;gBACAE,cAAc;gBACdzB,OAAO;gBACP0B,SAAS;oBACP;wBACE1B,OAAO;wBACPE,OAAO;oBACT;oBACA;wBACEF,OAAO;wBACPE,OAAO;oBACT;oBACA;wBACEF,OAAO;wBACPE,OAAO;oBACT;oBACA;wBACEF,OAAO;wBACPE,OAAO;oBACT;iBACD;YACH;YACA;gBACED,MAAM;gBACNqB,MAAM;gBACND,OAAO;oBACLM,WAAW,CAACC,GAAGC;wBACb,OAAOA,OAAO,CAAC,aAAa,KAAK;oBACnC;gBACF;gBACA7B,OAAO;YACT;YACA;gBACEC,MAAM;gBACNqB,MAAM;gBACND,OAAO;oBACLS,YAAY;wBACVC,OAAO;4BACLC,aAAa;gCACXC,eAAe;gCACfP,SAAS5B,aAAaN;4BACxB;4BACA0C,MAAM;wBACR;oBACF;gBACF;gBACAlC,OAAO;gBACP0B,SAAS5B,aAAaN,cAAcO,GAAG,CAAC,CAACoC;oBACvC,OAAO;wBACLnC,OAAOmC,OAAOnC,KAAK;wBACnBE,OAAOiC,OAAOjC,KAAK;oBACrB;gBACF;YACF;YACA;gBACEC,IAAI;gBACJmB,MAAM;gBACNc,MAAM;oBACJ;wBACEb,aACE;wBACF7B,QAAQ;4BACN;gCACEO,MAAM;gCACNqB,MAAM;gCACND,OAAO;oCACLS,YAAY;wCACVC,OAAO;oCACT;oCACAR,aAAa;gCACf;gCACAvB,OAAO;4BACT;yBACD;wBACDA,OAAO;oBACT;oBACA;wBACEqB,OAAO;4BACLM,WAAW,CAACC,GAAGC;gCACb,OAAOA,OAAO,CAAC,aAAa,KAAK,YAAYA,OAAO,CAAC,WAAW,KAAK;4BACvE;wBACF;wBACAN,aACE;wBACF7B,QAAQ;4BACN;gCACEO,MAAM;gCACNqB,MAAM;gCACN5B,QAAQ;oCACN;wCACEO,MAAM;wCACNqB,MAAM;wCACND,OAAO;4CACLE,aAAa;wCACf;wCACAc,YAAY7C,aAAa8C,oBAAoB,GACzC9C,aAAa8C,oBAAoB,GACjC;oCACN;iCACD;4BACH;yBACD;wBACDtC,OAAO;oBACT;oBACA;wBACEqB,OAAO;4BACLM,WAAW,CAACC,GAAGC;gCACb,OAAOA,OAAO,CAAC,aAAa,KAAK;4BACnC;wBACF;wBACAN,aAAa;wBACb7B,QAAQ;4BACN;gCACEO,MAAM;gCACNqB,MAAM;gCACNG,cAAc,CAAC;;;;yEAI0C,CAAC;gCAC1DzB,OAAO;4BACT;yBACD;wBACDA,OAAO;oBACT;oBACA;wBACEqB,OAAO;4BACLM,WAAW,CAACC,GAAGC;gCACb,OAAOA,OAAO,CAAC,aAAa,KAAK;4BACnC;wBACF;wBACAN,aAAa;wBACb7B,QAAQ;4BACN;gCACE;;;;iBAIC,GAJD;;;;iBAIC,GACDO,MAAM;gCACNqB,MAAM;gCACND,OAAO;oCACLM,WAAW,CAACC,GAAGC;wCACb,OAAOA,OAAO,CAAC,aAAa,KAAK;oCACnC;gCACF;gCACAJ,cAAc,CAAC;;;;;;;2HAO4F,CAAC;gCAC5GzB,OAAO;4BACT;yBACD;wBACDA,OAAO;oBACT;iBACD;YACH;eACGT,cAAcC;SAClB;IACH,CAAA,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/endpoints/fetchFields.ts"],"sourcesContent":["import type { Endpoint, PayloadRequest } from 'payload'\n\nimport type { PluginConfig, SerializedPromptField } from '../types.js'\n\nimport { PLUGIN_FETCH_FIELDS_ENDPOINT, PLUGIN_INSTRUCTIONS_TABLE } from '../defaults.js'\n\nexport const fetchFields: (config: PluginConfig) => Endpoint = (\n config\n) => {\n const {access, options = {}, promptFields = []} = config\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(req, 'Please check your \"access.settings\" for request')\n }\n }\n\n const fieldMap: Record<string, { fieldType: any; id: any }> = {}\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 promptFields: promptFields.map(({getter: _getter, ...field}): SerializedPromptField => {\n return field\n }),\n })\n },\n method: 'get',\n path: PLUGIN_FETCH_FIELDS_ENDPOINT,\n }\n}\n"],"names":["PLUGIN_FETCH_FIELDS_ENDPOINT","PLUGIN_INSTRUCTIONS_TABLE","fetchFields","config","access","options","promptFields","handler","req","docs","payload","find","collection","pagination","isConfigAllowed","settings","e","logger","error","fieldMap","forEach","doc","id","fieldType","Response","json","fields","map","getter","_getter","field","method","path"],"mappings":"AAIA,SAASA,4BAA4B,EAAEC,yBAAyB,QAAQ,iBAAgB;AAExF,OAAO,MAAMC,cAAkD,CAC7DC;IAEA,MAAM,EAACC,MAAM,EAAEC,UAAU,CAAC,CAAC,EAAEC,eAAe,EAAE,EAAC,GAAGH;IAClD,OAAO;QACLI,SAAS,OAAOC;YACd,MAAM,EAAEC,OAAO,EAAE,EAAE,GAAG,MAAMD,IAAIE,OAAO,CAACC,IAAI,CAAC;gBAC3CC,YAAYX;gBACZY,YAAY;YACd;YAEA,IAAIC,kBAAkB,KAAK,6CAA6C;;YAExE,IAAIV,QAAQW,UAAU;gBACpB,IAAI;oBACFD,kBAAkB,MAAMV,OAAOW,QAAQ,CAAC;wBAAEP;oBAAI;gBAChD,EAAE,OAAOQ,GAAG;oBACVR,IAAIE,OAAO,CAACO,MAAM,CAACC,KAAK,CAACV,KAAK;gBAChC;YACF;YAEA,MAAMW,WAAwD,CAAC;YAC/DV,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,GAAGpB,OAAO;gBACVqB,
|
|
1
|
+
{"version":3,"sources":["../../src/endpoints/fetchFields.ts"],"sourcesContent":["import type { Endpoint, PayloadRequest } from 'payload'\n\nimport type { PluginConfig, SerializedPromptField } from '../types.js'\n\nimport { PLUGIN_FETCH_FIELDS_ENDPOINT, PLUGIN_INSTRUCTIONS_TABLE } from '../defaults.js'\n\nexport const fetchFields: (config: PluginConfig) => Endpoint = (\n config\n) => {\n const {access, options = {}, promptFields = []} = config\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(req, 'Please check your \"access.settings\" for request')\n }\n }\n\n const fieldMap: Record<string, { fieldType: any; id: any }> = {}\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 debugging: config.debugging,\n fields: fieldMap,\n isConfigAllowed,\n promptFields: promptFields.map(({getter: _getter, ...field}): SerializedPromptField => {\n return field\n }),\n })\n },\n method: 'get',\n path: PLUGIN_FETCH_FIELDS_ENDPOINT,\n }\n}\n"],"names":["PLUGIN_FETCH_FIELDS_ENDPOINT","PLUGIN_INSTRUCTIONS_TABLE","fetchFields","config","access","options","promptFields","handler","req","docs","payload","find","collection","pagination","isConfigAllowed","settings","e","logger","error","fieldMap","forEach","doc","id","fieldType","Response","json","debugging","fields","map","getter","_getter","field","method","path"],"mappings":"AAIA,SAASA,4BAA4B,EAAEC,yBAAyB,QAAQ,iBAAgB;AAExF,OAAO,MAAMC,cAAkD,CAC7DC;IAEA,MAAM,EAACC,MAAM,EAAEC,UAAU,CAAC,CAAC,EAAEC,eAAe,EAAE,EAAC,GAAGH;IAClD,OAAO;QACLI,SAAS,OAAOC;YACd,MAAM,EAAEC,OAAO,EAAE,EAAE,GAAG,MAAMD,IAAIE,OAAO,CAACC,IAAI,CAAC;gBAC3CC,YAAYX;gBACZY,YAAY;YACd;YAEA,IAAIC,kBAAkB,KAAK,6CAA6C;;YAExE,IAAIV,QAAQW,UAAU;gBACpB,IAAI;oBACFD,kBAAkB,MAAMV,OAAOW,QAAQ,CAAC;wBAAEP;oBAAI;gBAChD,EAAE,OAAOQ,GAAG;oBACVR,IAAIE,OAAO,CAACO,MAAM,CAACC,KAAK,CAACV,KAAK;gBAChC;YACF;YAEA,MAAMW,WAAwD,CAAC;YAC/DV,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,GAAGpB,OAAO;gBACVqB,WAAWvB,OAAOuB,SAAS;gBAC3BC,QAAQR;gBACRL;gBACAR,cAAcA,aAAasB,GAAG,CAAC,CAAC,EAACC,QAAQC,OAAO,EAAE,GAAGC,OAAM;oBACzD,OAAOA;gBACT;YACF;QACF;QACAC,QAAQ;QACRC,MAAMjC;IACR;AACF,EAAC"}
|
package/dist/endpoints/index.js
CHANGED
|
@@ -55,12 +55,12 @@ const extendContextWithPromptFields = (data, ctx, pluginConfig)=>{
|
|
|
55
55
|
return Object.getOwnPropertyDescriptor(target, prop);
|
|
56
56
|
},
|
|
57
57
|
has: (target, prop)=>{
|
|
58
|
-
return fieldsMap.has(prop) || prop in target;
|
|
58
|
+
return fieldsMap.has(prop) || target && prop in target;
|
|
59
59
|
},
|
|
60
60
|
ownKeys: (target)=>{
|
|
61
61
|
return [
|
|
62
62
|
...fieldsMap.keys(),
|
|
63
|
-
...Object.keys(target)
|
|
63
|
+
...Object.keys(target || {})
|
|
64
64
|
];
|
|
65
65
|
}
|
|
66
66
|
});
|
|
@@ -262,9 +262,13 @@ export const endpoints = (pluginConfig)=>({
|
|
|
262
262
|
];
|
|
263
263
|
const editImages = [];
|
|
264
264
|
for (const img of images){
|
|
265
|
+
const serverURL = req.payload.config?.serverURL || process.env.SERVER_URL || process.env.NEXT_PUBLIC_SERVER_URL;
|
|
266
|
+
let url = img.image.thumbnailURL || img.image.url;
|
|
267
|
+
if (!url.startsWith('http')) {
|
|
268
|
+
url = `${serverURL}${url}`;
|
|
269
|
+
}
|
|
265
270
|
try {
|
|
266
|
-
const
|
|
267
|
-
const response = await fetch(`${serverURL}${img.image.url}`, {
|
|
271
|
+
const response = await fetch(url, {
|
|
268
272
|
headers: {
|
|
269
273
|
//TODO: Further testing needed or so find a proper way.
|
|
270
274
|
Authorization: `Bearer ${req.headers.get('Authorization')?.split('Bearer ')[1] || ''}`
|
|
@@ -277,10 +281,10 @@ export const endpoints = (pluginConfig)=>({
|
|
|
277
281
|
type: img.image.type,
|
|
278
282
|
data: blob,
|
|
279
283
|
size: blob.size,
|
|
280
|
-
url
|
|
284
|
+
url
|
|
281
285
|
});
|
|
282
286
|
} catch (e) {
|
|
283
|
-
req.payload.logger.error(e,
|
|
287
|
+
req.payload.logger.error(e, `Error fetching reference image ${url}`);
|
|
284
288
|
throw Error("We couldn't fetch the images. Please ensure the images are accessible and hosted publicly.");
|
|
285
289
|
}
|
|
286
290
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/endpoints/index.ts"],"sourcesContent":["import type { CollectionSlug, PayloadRequest } from 'payload'\n\nimport * as process from 'node:process'\n\nimport type {\n ActionMenuItems,\n Endpoints,\n PluginConfig,\n PromptFieldGetterContext,\n} 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 { asyncHandlebars } from '../libraries/handlebars/asyncHandlebars.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 extendContextWithPromptFields = (\n data: object,\n ctx: PromptFieldGetterContext,\n pluginConfig: PluginConfig,\n) => {\n const { promptFields = [] } = pluginConfig\n const fieldsMap = new Map(\n promptFields\n .filter((f) => !f.collections || f.collections.includes(ctx.collection))\n .map((f) => [f.name, f]),\n )\n return new Proxy(data, {\n get: (target, prop: string) => {\n const field = fieldsMap.get(prop as string)\n if (field?.getter) {\n const value = field.getter(data, ctx)\n return Promise.resolve(value).then((v) => new asyncHandlebars.SafeString(v))\n }\n // {{prop}} escapes content by default. Here we make sure it won't be escaped.\n const value = typeof target === \"object\" ? (target as any)[prop] : undefined\n return typeof value === 'string' ? new asyncHandlebars.SafeString(value) : value\n },\n // It's used by the handlebars library to determine if the property is enumerable\n getOwnPropertyDescriptor: (target, prop) => {\n const field = fieldsMap.get(prop as string)\n if (field) {\n return {\n configurable: true,\n enumerable: true,\n }\n }\n return Object.getOwnPropertyDescriptor(target, prop)\n },\n has: (target, prop) => {\n return fieldsMap.has(prop as string) || prop in target\n },\n ownKeys: (target) => {\n return [...fieldsMap.keys(), ...Object.keys(target)]\n },\n })\n}\n\nconst assignPrompt = async (\n action: ActionMenuItems,\n {\n type,\n actionParams,\n collection,\n context,\n field,\n layout,\n locale,\n pluginConfig,\n systemPrompt = '',\n template,\n }: {\n actionParams: Record<any, any>\n collection: CollectionSlug\n context: object\n field: string\n layout: string\n locale: string\n pluginConfig: PluginConfig\n systemPrompt: string\n template: string\n type: string\n },\n) => {\n const extendedContext = extendContextWithPromptFields(context, { type, collection }, pluginConfig)\n const prompt = await replacePlaceholders(template, extendedContext)\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 prompts = [...(pluginConfig.prompts || []), ...defaultPrompts]\n const foundPrompt = prompts.find((p) => p.name === action)\n const getLayout = foundPrompt?.layout\n const getSystemPrompt = foundPrompt?.system\n\n let updatedLayout = layout\n if (getLayout) {\n updatedLayout = getLayout()\n }\n\n const system = getSystemPrompt\n ? getSystemPrompt({\n ...(actionParams || {}),\n prompt,\n systemPrompt,\n })\n : ''\n\n return {\n layout: updatedLayout,\n // TODO: revisit this toLexicalHTML\n prompt: await replacePlaceholders(`{{${toLexicalHTML} ${field}}}`, extendedContext),\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, or try again`,\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 if (!collection) {\n throw new Error('Collection not found')\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 [collectionName, fieldName] = schemaPath?.split('.') || []\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 let localeInfo = locale\n if (\n localeData &&\n defaultLocale &&\n localeData.label &&\n typeof localeData.label === 'object' &&\n defaultLocale in localeData.label\n ) {\n localeInfo = localeData.label[defaultLocale]\n }\n\n const models = getGenerationModels(pluginConfig)\n const model =\n models && Array.isArray(models)\n ? models.find((model) => model.id === instructions['model-id'])\n : undefined\n\n if (!model) {\n throw new Error('Model not found')\n }\n\n // @ts-ignore\n const settingsName = model && model.settings ? model.settings.name : undefined\n if (!settingsName) {\n req.payload.logger.error('— AI Plugin: Error fetching settings name!')\n }\n\n const modelOptions = settingsName ? instructions[settingsName] || {} : {}\n\n const prompts = await assignPrompt(action, {\n type: String(instructions['field-type']),\n actionParams,\n collection: collectionName,\n context: contextData,\n field: fieldName || '',\n layout: instructions.layout,\n locale: localeInfo,\n pluginConfig,\n systemPrompt: instructions.system,\n template: String(promptTemplate),\n })\n\n if (pluginConfig.debugging) {\n req.payload.logger.info(\n { prompts },\n `— AI Plugin: Executing text prompt on ${schemaPath} using ${model.id}`,\n )\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, 'Error generating content: ')\n const message =\n error && typeof error === 'object' && 'message' in error\n ? (error as any).message\n : String(error)\n return new Response(JSON.stringify({ error: message }), {\n headers: { 'Content-Type': 'application/json' },\n status:\n message.includes('Authentication required') ||\n 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 e,\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: Record<string, any> = { images: [], 'model-id': '', prompt: '' }\n\n if (instructionId) {\n // Verify user has access to the specific instruction\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 extendedContext = extendContextWithPromptFields(\n contextData,\n { type: instructions['field-type'], collection: collectionSlug },\n pluginConfig,\n )\n const text = await replacePlaceholders(promptTemplate, extendedContext)\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(e, 'Error fetching reference images!')\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 modelsUpload = getGenerationModels(pluginConfig)\n const model =\n modelsUpload && Array.isArray(modelsUpload)\n ? modelsUpload.find((model) => model.id === modelId)\n : undefined\n\n if (!model) {\n throw new Error('Model not found')\n }\n\n // @ts-ignore\n const settingsName = model && model.settings ? model.settings.name : undefined\n if (!settingsName) {\n req.payload.logger.error('— AI Plugin: Error fetching settings name!')\n }\n\n let modelOptions = settingsName ? instructions[settingsName] || {} : {}\n modelOptions = {\n ...modelOptions,\n images: editImages,\n }\n\n if (pluginConfig.debugging) {\n req.payload.logger.info(\n { text },\n `— AI Plugin: Executing image prompt using ${model.id}`,\n )\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, 'Error generating upload: ')\n const message =\n error && typeof error === 'object' && 'message' in error\n ? (error as any).message\n : String(error)\n return new Response(JSON.stringify({ error: message }), {\n headers: { 'Content-Type': 'application/json' },\n status:\n message.includes('Authentication required') ||\n 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","asyncHandlebars","registerEditorHelper","handlebarsHelpersMap","replacePlaceholders","extractImageData","getGenerationModels","requireAuthentication","req","user","Error","checkAccess","pluginConfig","access","generate","hasAccess","extendContextWithPromptFields","data","ctx","promptFields","fieldsMap","Map","filter","f","collections","includes","collection","map","name","Proxy","get","target","prop","field","getter","value","Promise","resolve","then","v","SafeString","undefined","getOwnPropertyDescriptor","configurable","enumerable","Object","has","ownKeys","keys","assignPrompt","action","type","actionParams","context","layout","locale","systemPrompt","template","extendedContext","prompt","toLexicalHTML","toHTML","assignedPrompts","system","prompts","foundPrompt","find","p","getLayout","getSystemPrompt","updatedLayout","endpoints","textarea","handler","json","allowedEditorNodes","options","instructionId","contextData","doc","instructions","payload","findByID","id","config","slug","custom","editorConfig","admin","schema","editorSchema","promptTemplate","allowedEditorSchema","length","schemaPath","collectionName","fieldName","split","defaultLocale","locales","localization","localeData","l","code","localeInfo","label","models","model","Array","isArray","settingsName","settings","logger","error","modelOptions","String","debugging","info","message","Response","JSON","stringify","headers","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","Authorization","blob","push","size","modelsUpload","result","assetData","mediaUpload","request","create","file","alt"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/endpoints/index.ts"],"sourcesContent":["import type { CollectionSlug, PayloadRequest } from 'payload'\n\nimport * as process from 'node:process'\n\nimport type {\n ActionMenuItems,\n Endpoints,\n PluginConfig,\n PromptFieldGetterContext,\n} 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 { asyncHandlebars } from '../libraries/handlebars/asyncHandlebars.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 extendContextWithPromptFields = (\n data: object,\n ctx: PromptFieldGetterContext,\n pluginConfig: PluginConfig,\n) => {\n const { promptFields = [] } = pluginConfig\n const fieldsMap = new Map(\n promptFields\n .filter((f) => !f.collections || f.collections.includes(ctx.collection))\n .map((f) => [f.name, f]),\n )\n return new Proxy(data, {\n get: (target, prop: string) => {\n const field = fieldsMap.get(prop as string)\n if (field?.getter) {\n const value = field.getter(data, ctx)\n return Promise.resolve(value).then((v) => new asyncHandlebars.SafeString(v))\n }\n // {{prop}} escapes content by default. Here we make sure it won't be escaped.\n const value = typeof target === \"object\" ? (target as any)[prop] : undefined\n return typeof value === 'string' ? new asyncHandlebars.SafeString(value) : value\n },\n // It's used by the handlebars library to determine if the property is enumerable\n getOwnPropertyDescriptor: (target, prop) => {\n const field = fieldsMap.get(prop as string)\n if (field) {\n return {\n configurable: true,\n enumerable: true,\n }\n }\n return Object.getOwnPropertyDescriptor(target, prop)\n },\n has: (target, prop) => {\n return fieldsMap.has(prop as string) || (target && prop in target)\n },\n ownKeys: (target) => {\n return [...fieldsMap.keys(), ...Object.keys(target || {})]\n },\n })\n}\n\nconst assignPrompt = async (\n action: ActionMenuItems,\n {\n type,\n actionParams,\n collection,\n context,\n field,\n layout,\n locale,\n pluginConfig,\n systemPrompt = '',\n template,\n }: {\n actionParams: Record<any, any>\n collection: CollectionSlug\n context: object\n field: string\n layout: string\n locale: string\n pluginConfig: PluginConfig\n systemPrompt: string\n template: string\n type: string\n },\n) => {\n const extendedContext = extendContextWithPromptFields(context, { type, collection }, pluginConfig)\n const prompt = await replacePlaceholders(template, extendedContext)\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 prompts = [...(pluginConfig.prompts || []), ...defaultPrompts]\n const foundPrompt = prompts.find((p) => p.name === action)\n const getLayout = foundPrompt?.layout\n const getSystemPrompt = foundPrompt?.system\n\n let updatedLayout = layout\n if (getLayout) {\n updatedLayout = getLayout()\n }\n\n const system = getSystemPrompt\n ? getSystemPrompt({\n ...(actionParams || {}),\n prompt,\n systemPrompt,\n })\n : ''\n\n return {\n layout: updatedLayout,\n // TODO: revisit this toLexicalHTML\n prompt: await replacePlaceholders(`{{${toLexicalHTML} ${field}}}`, extendedContext),\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, or try again`,\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 if (!collection) {\n throw new Error('Collection not found')\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 [collectionName, fieldName] = schemaPath?.split('.') || []\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 let localeInfo = locale\n if (\n localeData &&\n defaultLocale &&\n localeData.label &&\n typeof localeData.label === 'object' &&\n defaultLocale in localeData.label\n ) {\n localeInfo = localeData.label[defaultLocale]\n }\n\n const models = getGenerationModels(pluginConfig)\n const model =\n models && Array.isArray(models)\n ? models.find((model) => model.id === instructions['model-id'])\n : undefined\n\n if (!model) {\n throw new Error('Model not found')\n }\n\n // @ts-ignore\n const settingsName = model && model.settings ? model.settings.name : undefined\n if (!settingsName) {\n req.payload.logger.error('— AI Plugin: Error fetching settings name!')\n }\n\n const modelOptions = settingsName ? instructions[settingsName] || {} : {}\n\n const prompts = await assignPrompt(action, {\n type: String(instructions['field-type']),\n actionParams,\n collection: collectionName,\n context: contextData,\n field: fieldName || '',\n layout: instructions.layout,\n locale: localeInfo,\n pluginConfig,\n systemPrompt: instructions.system,\n template: String(promptTemplate),\n })\n\n if (pluginConfig.debugging) {\n req.payload.logger.info(\n { prompts },\n `— AI Plugin: Executing text prompt on ${schemaPath} using ${model.id}`,\n )\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, 'Error generating content: ')\n const message =\n error && typeof error === 'object' && 'message' in error\n ? (error as any).message\n : String(error)\n return new Response(JSON.stringify({ error: message }), {\n headers: { 'Content-Type': 'application/json' },\n status:\n message.includes('Authentication required') ||\n 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 e,\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: Record<string, any> = { images: [], 'model-id': '', prompt: '' }\n\n if (instructionId) {\n // Verify user has access to the specific instruction\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 extendedContext = extendContextWithPromptFields(\n contextData,\n { type: instructions['field-type'], collection: collectionSlug },\n pluginConfig,\n )\n const text = await replacePlaceholders(promptTemplate, extendedContext)\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 const serverURL =\n req.payload.config?.serverURL ||\n process.env.SERVER_URL ||\n process.env.NEXT_PUBLIC_SERVER_URL\n\n let url = img.image.thumbnailURL || img.image.url\n if (!url.startsWith('http')) {\n url = `${serverURL}${url}`\n }\n\n try {\n\n const response = await fetch(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,\n })\n } catch (e) {\n req.payload.logger.error(e, `Error fetching reference image ${url}`)\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 modelsUpload = getGenerationModels(pluginConfig)\n const model =\n modelsUpload && Array.isArray(modelsUpload)\n ? modelsUpload.find((model) => model.id === modelId)\n : undefined\n\n if (!model) {\n throw new Error('Model not found')\n }\n\n // @ts-ignore\n const settingsName = model && model.settings ? model.settings.name : undefined\n if (!settingsName) {\n req.payload.logger.error('— AI Plugin: Error fetching settings name!')\n }\n\n let modelOptions = settingsName ? instructions[settingsName] || {} : {}\n modelOptions = {\n ...modelOptions,\n images: editImages,\n }\n\n if (pluginConfig.debugging) {\n req.payload.logger.info(\n { text },\n `— AI Plugin: Executing image prompt using ${model.id}`,\n )\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, 'Error generating upload: ')\n const message =\n error && typeof error === 'object' && 'message' in error\n ? (error as any).message\n : String(error)\n return new Response(JSON.stringify({ error: message }), {\n headers: { 'Content-Type': 'application/json' },\n status:\n message.includes('Authentication required') ||\n 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","asyncHandlebars","registerEditorHelper","handlebarsHelpersMap","replacePlaceholders","extractImageData","getGenerationModels","requireAuthentication","req","user","Error","checkAccess","pluginConfig","access","generate","hasAccess","extendContextWithPromptFields","data","ctx","promptFields","fieldsMap","Map","filter","f","collections","includes","collection","map","name","Proxy","get","target","prop","field","getter","value","Promise","resolve","then","v","SafeString","undefined","getOwnPropertyDescriptor","configurable","enumerable","Object","has","ownKeys","keys","assignPrompt","action","type","actionParams","context","layout","locale","systemPrompt","template","extendedContext","prompt","toLexicalHTML","toHTML","assignedPrompts","system","prompts","foundPrompt","find","p","getLayout","getSystemPrompt","updatedLayout","endpoints","textarea","handler","json","allowedEditorNodes","options","instructionId","contextData","doc","instructions","payload","findByID","id","config","slug","custom","editorConfig","admin","schema","editorSchema","promptTemplate","allowedEditorSchema","length","schemaPath","collectionName","fieldName","split","defaultLocale","locales","localization","localeData","l","code","localeInfo","label","models","model","Array","isArray","settingsName","settings","logger","error","modelOptions","String","debugging","info","message","Response","JSON","stringify","headers","status","method","path","upload","collectionSlug","documentId","docData","draft","e","images","sampleImages","text","modelId","uploadCollectionSlug","editImages","img","serverURL","env","SERVER_URL","NEXT_PUBLIC_SERVER_URL","url","image","thumbnailURL","startsWith","response","fetch","Authorization","blob","push","size","modelsUpload","result","assetData","mediaUpload","request","create","file","alt"],"mappings":"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"}
|
package/dist/exports/types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export type { payloadAiPlugin } from '../index.ts';
|
|
2
|
-
export type { GenerationConfig, GenerationModel, PluginConfig } from '../types.ts';
|
|
2
|
+
export type { ActionMenuItems, ActionPrompt, ActionPromptOptions, GenerationConfig, GenerationModel, PluginConfig, PluginConfigAccess, PluginConfigMediaUploadFunction, PluginOptions, PromptField, PromptFieldGetterContext, SeedPromptData, SeedPromptFunction, SeedPromptOptions, SeedPromptResult, } from '../types.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type { payloadAiPlugin } from '../index.ts'\nexport type { GenerationConfig, GenerationModel,
|
|
1
|
+
{"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type { payloadAiPlugin } from '../index.ts'\nexport type { \n ActionMenuItems,\n ActionPrompt,\n ActionPromptOptions,\n GenerationConfig, \n GenerationModel,\n PluginConfig, \n PluginConfigAccess,\n PluginConfigMediaUploadFunction,\n PluginOptions,\n PromptField,\n PromptFieldGetterContext,\n SeedPromptData,\n SeedPromptFunction,\n SeedPromptOptions,\n SeedPromptResult,\n} from '../types.ts'"],"names":[],"mappings":"AACA,WAgBoB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { useDocumentInfo } from
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { FieldDescription, useDocumentInfo } from "@payloadcms/ui";
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { FieldProvider } from '../../providers/FieldProvider/FieldProvider.js';
|
|
6
6
|
import { useInstructions } from '../../providers/InstructionsProvider/useInstructions.js';
|
|
@@ -8,25 +8,33 @@ import { Compose } from '../../ui/Compose/Compose.js';
|
|
|
8
8
|
export const ComposeField = (props)=>{
|
|
9
9
|
const { collectionSlug } = useDocumentInfo();
|
|
10
10
|
const finalSchemaPath = props?.schemaPath ?? (collectionSlug ? `${collectionSlug}.${props?.path ?? ''}` : props?.path ?? '');
|
|
11
|
-
const { id: instructionId, isConfigAllowed } = useInstructions({
|
|
11
|
+
const { id: instructionId, hasInstructions, isConfigAllowed } = useInstructions({
|
|
12
12
|
schemaPath: finalSchemaPath
|
|
13
13
|
});
|
|
14
|
-
return /*#__PURE__*/
|
|
14
|
+
return /*#__PURE__*/ _jsxs(FieldProvider, {
|
|
15
15
|
context: {
|
|
16
16
|
type: (props?.field).type,
|
|
17
17
|
path: props?.path ?? '',
|
|
18
18
|
schemaPath: finalSchemaPath
|
|
19
19
|
},
|
|
20
|
-
children:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
children: [
|
|
21
|
+
hasInstructions && instructionId ? /*#__PURE__*/ _jsx(Compose, {
|
|
22
|
+
descriptionProps: {
|
|
23
|
+
...props,
|
|
24
|
+
field: props?.field,
|
|
25
|
+
path: props?.path ?? '',
|
|
26
|
+
schemaPath: finalSchemaPath
|
|
27
|
+
},
|
|
28
|
+
instructionId: instructionId,
|
|
29
|
+
isConfigAllowed: isConfigAllowed
|
|
30
|
+
}) : null,
|
|
31
|
+
/*#__PURE__*/ _jsx("div", {
|
|
32
|
+
children: /*#__PURE__*/ _jsx(FieldDescription, {
|
|
33
|
+
path: props?.path ?? '',
|
|
34
|
+
...props
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
]
|
|
30
38
|
});
|
|
31
39
|
};
|
|
32
40
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fields/ComposeField/ComposeField.tsx"],"sourcesContent":["'use client'\n\nimport
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/ComposeField/ComposeField.tsx"],"sourcesContent":["'use client'\n\nimport {FieldDescription, useDocumentInfo} from \"@payloadcms/ui\";\nimport type { ClientField } from 'payload'\n\nimport React from 'react'\n\nimport { FieldProvider } from '../../providers/FieldProvider/FieldProvider.js'\nimport { useInstructions } from '../../providers/InstructionsProvider/useInstructions.js'\nimport { Compose } from '../../ui/Compose/Compose.js'\n\ntype ComposeFieldProps = {\n [key: string]: any\n field: ClientField\n path?: string\n schemaPath?: string\n}\n\nexport const ComposeField = (props: ComposeFieldProps) => {\n const { collectionSlug } = useDocumentInfo()\n\n const finalSchemaPath =\n props?.schemaPath ??\n (collectionSlug ? `${collectionSlug}.${props?.path ?? ''}` : (props?.path ?? ''))\n\n const { id: instructionId, hasInstructions, isConfigAllowed, } = useInstructions({\n schemaPath: finalSchemaPath,\n })\n\n return (\n <FieldProvider\n context={{\n type: (props?.field as any).type,\n path: props?.path ?? '',\n schemaPath: finalSchemaPath,\n }}\n >\n {hasInstructions && instructionId ? (\n <Compose\n descriptionProps={{\n ...props,\n field: props?.field,\n path: props?.path ?? '',\n schemaPath: finalSchemaPath,\n }}\n instructionId={instructionId}\n isConfigAllowed={isConfigAllowed}\n />\n ) : null\n }\n {/*Render the incoming description field*/}\n <div>\n <FieldDescription path={props?.path ?? ''} {...props} />\n </div>\n </FieldProvider>\n )\n}\n"],"names":["FieldDescription","useDocumentInfo","React","FieldProvider","useInstructions","Compose","ComposeField","props","collectionSlug","finalSchemaPath","schemaPath","path","id","instructionId","hasInstructions","isConfigAllowed","context","type","field","descriptionProps","div"],"mappings":"AAAA;;AAEA,SAAQA,gBAAgB,EAAEC,eAAe,QAAO,iBAAiB;AAGjE,OAAOC,WAAW,QAAO;AAEzB,SAASC,aAAa,QAAQ,iDAAgD;AAC9E,SAASC,eAAe,QAAQ,0DAAyD;AACzF,SAASC,OAAO,QAAQ,8BAA6B;AASrD,OAAO,MAAMC,eAAe,CAACC;IAC3B,MAAM,EAAEC,cAAc,EAAE,GAAGP;IAE3B,MAAMQ,kBACJF,OAAOG,cACNF,CAAAA,iBAAiB,GAAGA,eAAe,CAAC,EAAED,OAAOI,QAAQ,IAAI,GAAIJ,OAAOI,QAAQ,EAAE;IAEjF,MAAM,EAAEC,IAAIC,aAAa,EAAEC,eAAe,EAAEC,eAAe,EAAI,GAAGX,gBAAgB;QAChFM,YAAYD;IACd;IAEA,qBACE,MAACN;QACCa,SAAS;YACPC,MAAM,AAACV,CAAAA,OAAOW,KAAI,EAAUD,IAAI;YAChCN,MAAMJ,OAAOI,QAAQ;YACrBD,YAAYD;QACd;;YAECK,mBAAmBD,8BAClB,KAACR;gBACCc,kBAAkB;oBAChB,GAAGZ,KAAK;oBACRW,OAAOX,OAAOW;oBACdP,MAAMJ,OAAOI,QAAQ;oBACrBD,YAAYD;gBACd;gBACAI,eAAeA;gBACfE,iBAAiBA;iBAEf;0BAGN,KAACK;0BACC,cAAA,KAACpB;oBAAiBW,MAAMJ,OAAOI,QAAQ;oBAAK,GAAGJ,KAAK;;;;;AAI5D,EAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { defaultPrompts, defaultSeedPrompts
|
|
1
|
+
export { defaultPrompts, defaultSeedPrompts } from './ai/prompts.js';
|
|
2
2
|
export { PayloadAiPluginLexicalEditorFeature } from './fields/LexicalEditor/feature.server.js';
|
|
3
3
|
export { payloadAiPlugin } from './plugin.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { defaultPrompts, defaultSeedPrompts
|
|
1
|
+
export { defaultPrompts, defaultSeedPrompts } from './ai/prompts.js';
|
|
2
2
|
export { PayloadAiPluginLexicalEditorFeature } from './fields/LexicalEditor/feature.server.js';
|
|
3
3
|
export { payloadAiPlugin } from './plugin.js';
|
|
4
4
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { defaultPrompts, defaultSeedPrompts
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { defaultPrompts, defaultSeedPrompts } from './ai/prompts.js'\n\nexport { PayloadAiPluginLexicalEditorFeature } from './fields/LexicalEditor/feature.server.js'\nexport { payloadAiPlugin } from './plugin.js'\n"],"names":["defaultPrompts","defaultSeedPrompts","PayloadAiPluginLexicalEditorFeature","payloadAiPlugin"],"mappings":"AAAA,SAASA,cAAc,EAAEC,kBAAkB,QAAQ,kBAAiB;AAEpE,SAASC,mCAAmC,QAAQ,2CAA0C;AAC9F,SAASC,eAAe,QAAQ,cAAa"}
|
package/dist/init.js
CHANGED
|
@@ -3,57 +3,78 @@ import { systemGenerate } from './ai/utils/systemGenerate.js';
|
|
|
3
3
|
import { PLUGIN_INSTRUCTIONS_TABLE } from './defaults.js';
|
|
4
4
|
import { getGenerationModels } from './utilities/getGenerationModels.js';
|
|
5
5
|
export const init = async (payload, fieldSchemaPaths, pluginConfig)=>{
|
|
6
|
+
if (!pluginConfig.generatePromptOnInit) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
6
9
|
if (pluginConfig.debugging) {
|
|
7
10
|
payload.logger.info(`— AI Plugin: Initializing...`);
|
|
8
11
|
}
|
|
9
12
|
const paths = Object.keys(fieldSchemaPaths);
|
|
13
|
+
// Get all instructions for faster initialization
|
|
14
|
+
const { docs: allInstructions } = await payload.find({
|
|
15
|
+
collection: PLUGIN_INSTRUCTIONS_TABLE,
|
|
16
|
+
depth: 0,
|
|
17
|
+
pagination: false,
|
|
18
|
+
select: {
|
|
19
|
+
'field-type': true,
|
|
20
|
+
'schema-path': true
|
|
21
|
+
}
|
|
22
|
+
});
|
|
10
23
|
const fieldInstructionsMap = {};
|
|
11
24
|
for(let i = 0; i < paths.length; i++){
|
|
12
25
|
const path = paths[i];
|
|
13
26
|
const { type: fieldType, label: fieldLabel, relationTo } = fieldSchemaPaths[path];
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
'field-type': {
|
|
19
|
-
equals: fieldType
|
|
20
|
-
},
|
|
21
|
-
'schema-path': {
|
|
22
|
-
equals: path
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
if (!entry?.docs?.length) {
|
|
27
|
-
const seedPrompts = pluginConfig.seedPrompts || defaultSeedPrompts;
|
|
28
|
-
const { prompt, system } = seedPrompts({
|
|
27
|
+
let instructions = allInstructions.find((entry)=>entry['schema-path'] === path);
|
|
28
|
+
if (!instructions) {
|
|
29
|
+
let seed;
|
|
30
|
+
const seedOptions = {
|
|
29
31
|
fieldLabel,
|
|
30
32
|
fieldSchemaPaths,
|
|
31
33
|
fieldType,
|
|
32
34
|
path
|
|
33
|
-
}
|
|
35
|
+
};
|
|
36
|
+
if (pluginConfig.seedPrompts) {
|
|
37
|
+
seed = await pluginConfig.seedPrompts(seedOptions);
|
|
38
|
+
}
|
|
39
|
+
if (seed === undefined) {
|
|
40
|
+
seed = await defaultSeedPrompts(seedOptions);
|
|
41
|
+
}
|
|
42
|
+
// Field should be ignored
|
|
43
|
+
if (!seed) {
|
|
44
|
+
if (pluginConfig.debugging) {
|
|
45
|
+
payload.logger.info(`— AI Plugin: No seed prompt for ${path}, ignoring...`);
|
|
46
|
+
}
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
34
49
|
let generatedPrompt = '{{ title }}';
|
|
35
|
-
if (
|
|
50
|
+
if ('prompt' in seed) {
|
|
36
51
|
// find the model that has the generateText function
|
|
37
52
|
const models = getGenerationModels(pluginConfig);
|
|
38
53
|
const model = models && Array.isArray(models) ? models.find((model)=>model.generateText) : undefined;
|
|
39
54
|
generatedPrompt = await systemGenerate({
|
|
40
|
-
prompt,
|
|
41
|
-
system
|
|
55
|
+
prompt: seed.prompt,
|
|
56
|
+
system: seed.system
|
|
42
57
|
}, model?.generateText);
|
|
43
|
-
payload.logger.info(`\nPrompt generated for "${fieldLabel}" field:\nprompt: ${generatedPrompt}\n\n`);
|
|
44
58
|
}
|
|
45
59
|
const modelsForId = getGenerationModels(pluginConfig);
|
|
46
60
|
const modelForId = modelsForId && Array.isArray(modelsForId) ? modelsForId.find((a)=>a.fields.includes(fieldType)) : undefined;
|
|
47
|
-
const
|
|
61
|
+
const data = {
|
|
62
|
+
'model-id': modelForId?.id,
|
|
63
|
+
prompt: generatedPrompt,
|
|
64
|
+
...seed.data,
|
|
65
|
+
'field-type': fieldType,
|
|
66
|
+
'relation-to': relationTo,
|
|
67
|
+
'schema-path': path
|
|
68
|
+
};
|
|
69
|
+
payload.logger.info({
|
|
70
|
+
'model-id': data['model-id'],
|
|
71
|
+
prompt: generatedPrompt,
|
|
72
|
+
...seed.data
|
|
73
|
+
}, `Prompt seeded for "${path}" field`);
|
|
74
|
+
instructions = await payload.create({
|
|
48
75
|
collection: PLUGIN_INSTRUCTIONS_TABLE,
|
|
49
|
-
data
|
|
50
|
-
|
|
51
|
-
'model-id': modelForId?.id,
|
|
52
|
-
prompt: generatedPrompt,
|
|
53
|
-
'relation-to': relationTo,
|
|
54
|
-
'schema-path': path
|
|
55
|
-
}
|
|
56
|
-
}).then((a)=>a).catch((err)=>{
|
|
76
|
+
data
|
|
77
|
+
}).catch((err)=>{
|
|
57
78
|
payload.logger.error(err, '— AI Plugin: Error creating Compose settings-');
|
|
58
79
|
});
|
|
59
80
|
if (instructions?.id) {
|
|
@@ -63,7 +84,17 @@ export const init = async (payload, fieldSchemaPaths, pluginConfig)=>{
|
|
|
63
84
|
};
|
|
64
85
|
}
|
|
65
86
|
} else {
|
|
66
|
-
|
|
87
|
+
if (instructions['field-type'] !== fieldType) {
|
|
88
|
+
payload.logger.warn(`— AI Plugin: Field type mismatch for ${path}! Was "${fieldType}", it is "${instructions['field-type']}" now. Updating...`);
|
|
89
|
+
await payload.update({
|
|
90
|
+
id: instructions.id,
|
|
91
|
+
collection: PLUGIN_INSTRUCTIONS_TABLE,
|
|
92
|
+
data: {
|
|
93
|
+
'field-type': fieldType
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
instructions['field-type'] = fieldType;
|
|
97
|
+
}
|
|
67
98
|
fieldInstructionsMap[path] = {
|
|
68
99
|
id: instructions.id,
|
|
69
100
|
fieldType
|
package/dist/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/init.ts"],"sourcesContent":["import type { Payload } from 'payload'\n\nimport type { PluginConfig } from './types.js'\n\nimport { defaultSeedPrompts } from './ai/prompts.js'\nimport { systemGenerate } from './ai/utils/systemGenerate.js'\nimport { PLUGIN_INSTRUCTIONS_TABLE } from './defaults.js'\nimport { getGenerationModels } from './utilities/getGenerationModels.js'\n\nexport const init = async (\n payload: Payload,\n fieldSchemaPaths: Record<string, { label: string; relationTo?: string; type: string }>,\n pluginConfig: PluginConfig,\n) => {\n if (pluginConfig.debugging) {\n payload.logger.info(`— AI Plugin: Initializing...`)\n }\n\n const paths = Object.keys(fieldSchemaPaths)\n\n const fieldInstructionsMap: Record<string, { fieldType: any; id: any }> = {}\n for (let i = 0; i < paths.length; i++) {\n const path = paths[i]\n const { type: fieldType, label: fieldLabel, relationTo } = fieldSchemaPaths[path]\n
|
|
1
|
+
{"version":3,"sources":["../src/init.ts"],"sourcesContent":["import type { Payload } from 'payload'\n\nimport type { PluginConfig } from './types.js'\n\nimport { defaultSeedPrompts } from './ai/prompts.js'\nimport { systemGenerate } from './ai/utils/systemGenerate.js'\nimport { PLUGIN_INSTRUCTIONS_TABLE } from './defaults.js'\nimport { getGenerationModels } from './utilities/getGenerationModels.js'\n\nexport const init = async (\n payload: Payload,\n fieldSchemaPaths: Record<string, { label: string; relationTo?: string; type: string }>,\n pluginConfig: PluginConfig,\n) => {\n if (!pluginConfig.generatePromptOnInit) {\n return\n }\n\n if (pluginConfig.debugging) {\n payload.logger.info(`— AI Plugin: Initializing...`)\n }\n\n const paths = Object.keys(fieldSchemaPaths)\n\n // Get all instructions for faster initialization\n const { docs: allInstructions } = await payload.find({\n collection: PLUGIN_INSTRUCTIONS_TABLE,\n depth: 0,\n pagination: false,\n select: {\n 'field-type': true,\n 'schema-path': true,\n },\n })\n\n const fieldInstructionsMap: Record<string, { fieldType: any; id: any }> = {}\n\n for (let i = 0; i < paths.length; i++) {\n const path = paths[i]\n const { type: fieldType, label: fieldLabel, relationTo } = fieldSchemaPaths[path]\n let instructions = allInstructions.find((entry) => entry['schema-path'] === path)\n\n if (!instructions) {\n let seed\n const seedOptions = {\n fieldLabel,\n fieldSchemaPaths,\n fieldType,\n path,\n }\n\n if (pluginConfig.seedPrompts) {seed = await pluginConfig.seedPrompts(seedOptions)}\n if (seed === undefined) {seed = await defaultSeedPrompts(seedOptions)}\n // Field should be ignored\n if (!seed) {\n if (pluginConfig.debugging) {\n payload.logger.info(`— AI Plugin: No seed prompt for ${path}, ignoring...`)\n }\n continue\n }\n\n let generatedPrompt = '{{ title }}'\n if ('prompt' in seed) {\n // find the model that has the generateText function\n const models = getGenerationModels(pluginConfig)\n const model =\n models && Array.isArray(models) ? models.find((model) => model.generateText) : undefined\n generatedPrompt = await systemGenerate(\n {\n prompt: seed.prompt,\n system: seed.system,\n },\n model?.generateText,\n )\n }\n\n const modelsForId = getGenerationModels(pluginConfig)\n const modelForId =\n modelsForId && Array.isArray(modelsForId)\n ? modelsForId.find((a) => a.fields.includes(fieldType))\n : undefined\n\n const data = {\n 'model-id': modelForId?.id,\n prompt: generatedPrompt,\n ...seed.data, // allow to override data, but not the one below\n 'field-type': fieldType,\n 'relation-to': relationTo,\n 'schema-path': path,\n }\n\n payload.logger.info(\n {\n 'model-id': data['model-id'],\n prompt: generatedPrompt,\n ...seed.data,\n },\n `Prompt seeded for \"${path}\" field`,\n )\n\n instructions = (await payload\n .create({\n collection: PLUGIN_INSTRUCTIONS_TABLE,\n data,\n })\n .catch((err) => {\n payload.logger.error(err, '— AI Plugin: Error creating Compose settings-')\n })) as (typeof allInstructions)[0]\n\n if (instructions?.id) {\n fieldInstructionsMap[path] = {\n id: instructions.id,\n fieldType,\n }\n }\n } else {\n if (instructions['field-type'] !== fieldType) {\n payload.logger.warn(\n `— AI Plugin: Field type mismatch for ${path}! Was \"${fieldType}\", it is \"${instructions['field-type']}\" now. Updating...`,\n )\n await payload.update({\n id: instructions.id,\n collection: PLUGIN_INSTRUCTIONS_TABLE,\n data: {\n 'field-type': fieldType,\n },\n })\n instructions['field-type'] = fieldType\n }\n\n fieldInstructionsMap[path] = {\n id: instructions.id,\n fieldType,\n }\n }\n }\n\n if (pluginConfig.debugging) {\n payload.logger.info(\n `— AI Plugin: Enabled fields map: ${JSON.stringify(fieldInstructionsMap, null, 2)}`,\n )\n payload.logger.info(`— AI Plugin: Initialized!`)\n }\n\n if (pluginConfig.generatePromptOnInit) {\n payload.logger.info(\n '\\n\\n-AI Plugin: Example prompts are added to get you started, Now go break some code 🚀🚀🚀\\n\\n',\n )\n }\n}\n"],"names":["defaultSeedPrompts","systemGenerate","PLUGIN_INSTRUCTIONS_TABLE","getGenerationModels","init","payload","fieldSchemaPaths","pluginConfig","generatePromptOnInit","debugging","logger","info","paths","Object","keys","docs","allInstructions","find","collection","depth","pagination","select","fieldInstructionsMap","i","length","path","type","fieldType","label","fieldLabel","relationTo","instructions","entry","seed","seedOptions","seedPrompts","undefined","generatedPrompt","models","model","Array","isArray","generateText","prompt","system","modelsForId","modelForId","a","fields","includes","data","id","create","catch","err","error","warn","update","JSON","stringify"],"mappings":"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"}
|
package/dist/plugin.js
CHANGED
|
@@ -157,10 +157,10 @@ const payloadAiPlugin = (pluginConfig)=>(incomingConfig)=>{
|
|
|
157
157
|
await init(payload, collectionsFieldPathMap, pluginConfig).catch((error)=>{
|
|
158
158
|
payload.logger.error(error, `— AI Plugin: Initialization Error`);
|
|
159
159
|
}).finally(()=>{
|
|
160
|
-
setTimeout(()=>{
|
|
161
|
-
payload.logger.info(securityMessage);
|
|
162
|
-
}, 1000);
|
|
163
160
|
if (!pluginConfig.disableSponsorMessage) {
|
|
161
|
+
setTimeout(()=>{
|
|
162
|
+
payload.logger.info(securityMessage);
|
|
163
|
+
}, 1000);
|
|
164
164
|
setTimeout(()=>{
|
|
165
165
|
payload.logger.info(sponsorMessage);
|
|
166
166
|
}, 3000);
|
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 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 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 Instructions.admin = {\n ...Instructions.admin,\n }\n\n if (pluginConfig.debugging) {\n Instructions.admin.hidden = false\n }\n\n Instructions.admin.custom = {\n ...(Instructions.admin.custom || {}),\n [PLUGIN_NAME]: {\n editorConfig: {\n // Used in admin client for useObject hook\n schema: lexicalSchema,\n },\n },\n }\n\n const collections = [...(incomingConfig.collections ?? []), Instructions]\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),\n ],\n globals: globals.map((global) => {\n if (globalsSlugs && globalsSlugs[global.slug]) {\n const { schemaPathMap, updatedCollectionConfig } = updateFieldsConfig(global)\n collectionsFieldPathMap = {\n ...collectionsFieldPathMap,\n ...schemaPathMap,\n }\n return updatedCollectionConfig as GlobalConfig\n }\n\n return global\n }),\n i18n: {\n ...(incomingConfig.i18n || {}),\n translations: {\n ...deepMerge(translations, incomingConfig.i18n?.translations ?? {}),\n },\n },\n }\n }\n\n updatedConfig.onInit = async (payload) => {\n if (incomingConfig.onInit) 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 payload.logger.error(error, `— AI Plugin: Initialization 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 }\n"],"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","admin","debugging","hidden","custom","schema","globals","collectionSlugs","globalsSlugs","components","providers","updatedProviders","path","pluginEndpoints","map","collection","slug","schemaPathMap","updatedCollectionConfig","textarea","upload","global","i18n","onInit","payload","logger","warn","catch","error","finally","setTimeout","info"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts"],"sourcesContent":["import type { CollectionConfig, Config, GlobalConfig } from 'payload'\n\nimport { deepMerge } from 'payload/shared'\n\nimport type { PluginConfig } from './types.js'\n\nimport { 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 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 Instructions.admin = {\n ...Instructions.admin,\n }\n\n if (pluginConfig.debugging) {\n Instructions.admin.hidden = false\n }\n\n Instructions.admin.custom = {\n ...(Instructions.admin.custom || {}),\n [PLUGIN_NAME]: {\n editorConfig: {\n // Used in admin client for useObject hook\n schema: lexicalSchema,\n },\n },\n }\n\n const collections = [...(incomingConfig.collections ?? []), Instructions]\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),\n ],\n globals: globals.map((global) => {\n if (globalsSlugs && globalsSlugs[global.slug]) {\n const { schemaPathMap, updatedCollectionConfig } = updateFieldsConfig(global)\n collectionsFieldPathMap = {\n ...collectionsFieldPathMap,\n ...schemaPathMap,\n }\n return updatedCollectionConfig as GlobalConfig\n }\n\n return global\n }),\n i18n: {\n ...(incomingConfig.i18n || {}),\n translations: {\n ...deepMerge(translations, incomingConfig.i18n?.translations ?? {}),\n },\n },\n }\n }\n\n updatedConfig.onInit = async (payload) => {\n if (incomingConfig.onInit) 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 payload.logger.error(error, `— AI Plugin: Initialization Error`)\n })\n .finally(() => {\n if (!pluginConfig.disableSponsorMessage) {\n setTimeout(() => {\n payload.logger.info(securityMessage)\n }, 1000)\n setTimeout(() => {\n payload.logger.info(sponsorMessage)\n }, 3000)\n }\n })\n }\n\n return updatedConfig\n }\n\nexport { payloadAiPlugin }\n"],"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","admin","debugging","hidden","custom","schema","globals","collectionSlugs","globalsSlugs","components","providers","updatedProviders","path","pluginEndpoints","map","collection","slug","schemaPathMap","updatedCollectionConfig","textarea","upload","global","i18n","onInit","payload","logger","warn","catch","error","finally","setTimeout","info"],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ export const InstructionsProvider = ({ children })=>{
|
|
|
10
10
|
const [activeCollection, setActiveCollection] = useState('');
|
|
11
11
|
const [isConfigAllowed, setIsConfigAllowed] = useState(false);
|
|
12
12
|
const [enabledLanguages, setEnabledLanguages] = useState();
|
|
13
|
+
const [debugging, setDebugging] = useState(false);
|
|
13
14
|
const { user } = useAuth();
|
|
14
15
|
const { config } = useConfig();
|
|
15
16
|
const { routes: { api }, serverURL } = config;
|
|
@@ -18,10 +19,11 @@ export const InstructionsProvider = ({ children })=>{
|
|
|
18
19
|
useEffect(()=>{
|
|
19
20
|
fetch(`${serverURL}${api}${PLUGIN_FETCH_FIELDS_ENDPOINT}`).then(async (res)=>{
|
|
20
21
|
await res.json().then((data)=>{
|
|
21
|
-
setIsConfigAllowed(data?.isConfigAllowed);
|
|
22
|
-
setEnabledLanguages(data?.enabledLanguages);
|
|
23
|
-
setInstructionsState(data?.fields);
|
|
24
|
-
setPromptFields(data?.promptFields);
|
|
22
|
+
setIsConfigAllowed(data?.isConfigAllowed || false);
|
|
23
|
+
setEnabledLanguages(data?.enabledLanguages || []);
|
|
24
|
+
setInstructionsState(data?.fields || {});
|
|
25
|
+
setPromptFields(data?.promptFields || []);
|
|
26
|
+
setDebugging(data?.debugging || false);
|
|
25
27
|
});
|
|
26
28
|
}).catch((err)=>{
|
|
27
29
|
console.error('InstructionsProvider:', err);
|
|
@@ -34,7 +36,9 @@ export const InstructionsProvider = ({ children })=>{
|
|
|
34
36
|
return /*#__PURE__*/ _jsx(InstructionsContext.Provider, {
|
|
35
37
|
value: {
|
|
36
38
|
activeCollection,
|
|
39
|
+
debugging,
|
|
37
40
|
enabledLanguages,
|
|
41
|
+
hasInstructions: instructions && Object.keys(instructions).length > 0,
|
|
38
42
|
instructions,
|
|
39
43
|
isConfigAllowed,
|
|
40
44
|
promptFields,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/providers/InstructionsProvider/InstructionsProvider.tsx"],"sourcesContent":["'use client'\n\n\nimport { useAuth, useConfig } from '@payloadcms/ui'\nimport React, { useEffect, useState } from 'react'\n\nimport type { SerializedPromptField } from '../../types.js'\n\nimport { PLUGIN_FETCH_FIELDS_ENDPOINT } from '../../defaults.js'\nimport { InstructionsContext } from './context.js'\n\n\nexport const InstructionsProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const [instructions, setInstructionsState] = useState({})\n const [promptFields, setPromptFields] = useState<SerializedPromptField[]>([])\n const [activeCollection, setActiveCollection] = useState('')\n const [isConfigAllowed, setIsConfigAllowed] = useState(false)\n const [enabledLanguages, setEnabledLanguages] = useState<string[]>()\n const { 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 setPromptFields(data?.promptFields)\n })\n })\n .catch((err) => {\n console.error('InstructionsProvider:', err)\n })\n }, [api, serverURL, user])\n\n return (\n <InstructionsContext.Provider\n value={{\n activeCollection,\n enabledLanguages,\n instructions,\n isConfigAllowed,\n promptFields,\n setActiveCollection,\n }}\n >\n {children}\n </InstructionsContext.Provider>\n )\n}\n"],"names":["useAuth","useConfig","React","useEffect","useState","PLUGIN_FETCH_FIELDS_ENDPOINT","InstructionsContext","InstructionsProvider","children","instructions","setInstructionsState","promptFields","setPromptFields","activeCollection","setActiveCollection","isConfigAllowed","setIsConfigAllowed","enabledLanguages","setEnabledLanguages","user","config","routes","api","serverURL","fetch","then","res","json","data","fields","catch","err","console","error","Provider","value"],"mappings":"AAAA;;AAGA,SAASA,OAAO,EAAEC,SAAS,QAAQ,iBAAgB;AACnD,OAAOC,SAASC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAIlD,SAASC,4BAA4B,QAAQ,oBAAmB;AAChE,SAASC,mBAAmB,QAAQ,eAAc;AAGlD,OAAO,MAAMC,uBAAgE,CAAC,EAAEC,QAAQ,EAAE;IACxF,MAAM,CAACC,cAAcC,qBAAqB,GAAGN,SAAS,CAAC;IACvD,MAAM,CAACO,cAAcC,gBAAgB,GAAGR,SAAkC,EAAE;IAC5E,MAAM,CAACS,kBAAkBC,oBAAoB,GAAGV,SAAS;IACzD,MAAM,CAACW,iBAAiBC,mBAAmB,GAAGZ,SAAS;IACvD,MAAM,CAACa,kBAAkBC,oBAAoB,GAAGd;IAChD,MAAM,
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/InstructionsProvider/InstructionsProvider.tsx"],"sourcesContent":["'use client'\n\n\nimport { useAuth, useConfig } from '@payloadcms/ui'\nimport React, { useEffect, useState } from 'react'\n\nimport type { SerializedPromptField } from '../../types.js'\n\nimport { PLUGIN_FETCH_FIELDS_ENDPOINT } from '../../defaults.js'\nimport { InstructionsContext } from './context.js'\n\n\nexport const InstructionsProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const [instructions, setInstructionsState] = useState({})\n const [promptFields, setPromptFields] = useState<SerializedPromptField[]>([])\n const [activeCollection, setActiveCollection] = useState('')\n const [isConfigAllowed, setIsConfigAllowed] = useState(false)\n const [enabledLanguages, setEnabledLanguages] = useState<string[]>()\n const [debugging, setDebugging] = useState(false)\n const { user } = useAuth()\n\n const { config } = useConfig()\n const {\n routes: { api },\n serverURL,\n } = config\n\n // 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 || false)\n setEnabledLanguages(data?.enabledLanguages || [])\n setInstructionsState(data?.fields || {})\n setPromptFields(data?.promptFields || [])\n setDebugging(data?.debugging || false)\n })\n })\n .catch((err) => {\n console.error('InstructionsProvider:', err)\n })\n }, [api, serverURL, user])\n\n return (\n <InstructionsContext.Provider\n value={{\n activeCollection,\n debugging,\n enabledLanguages,\n hasInstructions: instructions && Object.keys(instructions).length > 0,\n instructions,\n isConfigAllowed,\n promptFields,\n setActiveCollection,\n }}\n >\n {children}\n </InstructionsContext.Provider>\n )\n}\n"],"names":["useAuth","useConfig","React","useEffect","useState","PLUGIN_FETCH_FIELDS_ENDPOINT","InstructionsContext","InstructionsProvider","children","instructions","setInstructionsState","promptFields","setPromptFields","activeCollection","setActiveCollection","isConfigAllowed","setIsConfigAllowed","enabledLanguages","setEnabledLanguages","debugging","setDebugging","user","config","routes","api","serverURL","fetch","then","res","json","data","fields","catch","err","console","error","Provider","value","hasInstructions","Object","keys","length"],"mappings":"AAAA;;AAGA,SAASA,OAAO,EAAEC,SAAS,QAAQ,iBAAgB;AACnD,OAAOC,SAASC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAIlD,SAASC,4BAA4B,QAAQ,oBAAmB;AAChE,SAASC,mBAAmB,QAAQ,eAAc;AAGlD,OAAO,MAAMC,uBAAgE,CAAC,EAAEC,QAAQ,EAAE;IACxF,MAAM,CAACC,cAAcC,qBAAqB,GAAGN,SAAS,CAAC;IACvD,MAAM,CAACO,cAAcC,gBAAgB,GAAGR,SAAkC,EAAE;IAC5E,MAAM,CAACS,kBAAkBC,oBAAoB,GAAGV,SAAS;IACzD,MAAM,CAACW,iBAAiBC,mBAAmB,GAAGZ,SAAS;IACvD,MAAM,CAACa,kBAAkBC,oBAAoB,GAAGd;IAChD,MAAM,CAACe,WAAWC,aAAa,GAAGhB,SAAS;IAC3C,MAAM,EAAEiB,IAAI,EAAE,GAAGrB;IAEjB,MAAM,EAAEsB,MAAM,EAAE,GAAGrB;IACnB,MAAM,EACJsB,QAAQ,EAAEC,GAAG,EAAE,EACfC,SAAS,EACV,GAAGH;IAEJ,iEAAiE;IACjE,6CAA6C;IAC7CnB,UAAU;QACRuB,MAAM,GAAGD,YAAYD,MAAMnB,8BAA8B,EACtDsB,IAAI,CAAC,OAAOC;YACX,MAAMA,IAAIC,IAAI,GAAGF,IAAI,CAAC,CAACG;gBACrBd,mBAAmBc,MAAMf,mBAAmB;gBAC5CG,oBAAoBY,MAAMb,oBAAoB,EAAE;gBAChDP,qBAAqBoB,MAAMC,UAAU,CAAC;gBACtCnB,gBAAgBkB,MAAMnB,gBAAgB,EAAE;gBACxCS,aAAaU,MAAMX,aAAa;YAClC;QACF,GACCa,KAAK,CAAC,CAACC;YACNC,QAAQC,KAAK,CAAC,yBAAyBF;QACzC;IACJ,GAAG;QAACT;QAAKC;QAAWJ;KAAK;IAEzB,qBACE,KAACf,oBAAoB8B,QAAQ;QAC3BC,OAAO;YACLxB;YACAM;YACAF;YACAqB,iBAAiB7B,gBAAgB8B,OAAOC,IAAI,CAAC/B,cAAcgC,MAAM,GAAG;YACpEhC;YACAM;YACAJ;YACAG;QACF;kBAECN;;AAGP,EAAC"}
|
|
@@ -3,8 +3,10 @@ import type React from 'react';
|
|
|
3
3
|
import type { SerializedPromptField } from '../../types.js';
|
|
4
4
|
export type InstructionsContextValue = {
|
|
5
5
|
activeCollection?: string;
|
|
6
|
+
debugging?: boolean;
|
|
6
7
|
enabledLanguages?: string[];
|
|
7
8
|
field?: Field;
|
|
9
|
+
hasInstructions: boolean;
|
|
8
10
|
instructions: Record<string, any>;
|
|
9
11
|
isConfigAllowed: boolean;
|
|
10
12
|
path?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/providers/InstructionsProvider/context.ts"],"sourcesContent":["'use client'\n\nimport type { Field } from 'payload'\nimport type React from 'react';\n\nimport { createContext } from 'react'\n\nimport type { SerializedPromptField } from '../../types.js'\n\nexport type InstructionsContextValue = {\n activeCollection?: string\n enabledLanguages?: string[]\n field?: Field\n instructions: Record<string, any>\n isConfigAllowed: boolean\n path?: string\n promptFields: SerializedPromptField[]\n schemaPath?: unknown\n setActiveCollection?: React.Dispatch<React.SetStateAction<string>>\n}\n\nexport const initialContext: InstructionsContextValue = {\n field: undefined,\n instructions: {},\n isConfigAllowed: true,\n path: '',\n promptFields: [],\n schemaPath: '',\n}\n\nexport const InstructionsContext = createContext<InstructionsContextValue>(initialContext)\n"],"names":["createContext","initialContext","field","undefined","instructions","isConfigAllowed","path","promptFields","schemaPath","InstructionsContext"],"mappings":"AAAA;AAKA,SAASA,aAAa,QAAQ,QAAO;
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/InstructionsProvider/context.ts"],"sourcesContent":["'use client'\n\nimport type { Field } from 'payload'\nimport type React from 'react';\n\nimport { createContext } from 'react'\n\nimport type { SerializedPromptField } from '../../types.js'\n\nexport type InstructionsContextValue = {\n activeCollection?: string\n debugging?: boolean\n enabledLanguages?: string[]\n field?: Field\n hasInstructions: boolean\n instructions: Record<string, any>\n isConfigAllowed: boolean\n path?: string\n promptFields: SerializedPromptField[]\n schemaPath?: unknown\n setActiveCollection?: React.Dispatch<React.SetStateAction<string>>\n}\n\nexport const initialContext: InstructionsContextValue = {\n debugging: false,\n field: undefined,\n hasInstructions: false,\n instructions: {},\n isConfigAllowed: true,\n path: '',\n promptFields: [],\n schemaPath: '',\n}\n\nexport const InstructionsContext = createContext<InstructionsContextValue>(initialContext)\n"],"names":["createContext","initialContext","debugging","field","undefined","hasInstructions","instructions","isConfigAllowed","path","promptFields","schemaPath","InstructionsContext"],"mappings":"AAAA;AAKA,SAASA,aAAa,QAAQ,QAAO;AAkBrC,OAAO,MAAMC,iBAA2C;IACtDC,WAAW;IACXC,OAAOC;IACPC,iBAAiB;IACjBC,cAAc,CAAC;IACfC,iBAAiB;IACjBC,MAAM;IACNC,cAAc,EAAE;IAChBC,YAAY;AACd,EAAC;AAED,OAAO,MAAMC,sBAAsBX,cAAwCC,gBAAe"}
|
|
@@ -3,10 +3,18 @@ import { useDocumentInfo } from '@payloadcms/ui';
|
|
|
3
3
|
import { useContext, useEffect, useMemo, useState } from 'react';
|
|
4
4
|
import { PLUGIN_INSTRUCTIONS_TABLE } from '../../defaults.js';
|
|
5
5
|
import { handlebarsHelpers, handlebarsHelpersMap } from '../../libraries/handlebars/helpersMap.js';
|
|
6
|
+
const warnedOnceOnNoInstructionId = new Set();
|
|
7
|
+
const warnOnceOnMissingInstructions = (path)=>{
|
|
8
|
+
if (!warnedOnceOnNoInstructionId.has(path)) {
|
|
9
|
+
warnedOnceOnNoInstructionId.add(path);
|
|
10
|
+
// eslint-disable-next-line no-console
|
|
11
|
+
console.info(`[AI Plugin] There are no AI instructions for this field: ${path}. Enable "generatePromptOnInit" option to enable them.`);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
6
14
|
export const useInstructions = (update = {})=>{
|
|
7
15
|
const context = useContext(InstructionsContext);
|
|
8
16
|
const { collectionSlug } = useDocumentInfo();
|
|
9
|
-
const { activeCollection, instructions, promptFields, setActiveCollection } = context;
|
|
17
|
+
const { activeCollection, hasInstructions, instructions, promptFields, setActiveCollection, debugging } = context;
|
|
10
18
|
const [schemaPath, setSchemaPath] = useState(update.schemaPath);
|
|
11
19
|
useEffect(()=>{
|
|
12
20
|
if (update.schemaPath !== schemaPath) {
|
|
@@ -26,7 +34,7 @@ export const useInstructions = (update = {})=>{
|
|
|
26
34
|
]);
|
|
27
35
|
const groupedFields = useMemo(()=>{
|
|
28
36
|
const result = {};
|
|
29
|
-
for (const fullKey of Object.keys(instructions)){
|
|
37
|
+
for (const fullKey of Object.keys(instructions || {})){
|
|
30
38
|
const [collection, ...pathParts] = fullKey.split('.');
|
|
31
39
|
const path = pathParts.join('.');
|
|
32
40
|
if (!result[collection]) {
|
|
@@ -76,9 +84,13 @@ export const useInstructions = (update = {})=>{
|
|
|
76
84
|
instructions,
|
|
77
85
|
promptFields
|
|
78
86
|
]);
|
|
87
|
+
const pathInstructions = instructions[schemaPath];
|
|
88
|
+
if (debugging && !pathInstructions && schemaPath && hasInstructions) {
|
|
89
|
+
warnOnceOnMissingInstructions(schemaPath);
|
|
90
|
+
}
|
|
79
91
|
return {
|
|
80
92
|
...context,
|
|
81
|
-
...
|
|
93
|
+
...pathInstructions || {},
|
|
82
94
|
promptEditorSuggestions
|
|
83
95
|
};
|
|
84
96
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/providers/InstructionsProvider/useInstructions.ts"],"sourcesContent":["import { InstructionsContext } from '@ai-stack/payloadcms/client'\nimport { useDocumentInfo } from '@payloadcms/ui'\nimport { useContext, useEffect, useMemo, useState } from 'react'\n\nimport { PLUGIN_INSTRUCTIONS_TABLE } from '../../defaults.js'\nimport { handlebarsHelpers, handlebarsHelpersMap } from '../../libraries/handlebars/helpersMap.js'\n\nexport const useInstructions = (\n update: {\n schemaPath?: unknown\n } = {},\n) => {\n const context = useContext(InstructionsContext)\n const { collectionSlug } = useDocumentInfo()\n const { activeCollection, instructions, promptFields, setActiveCollection } = context\n\n const [schemaPath, setSchemaPath] = useState(update.schemaPath as string)\n\n useEffect(() => {\n if (update.schemaPath !== schemaPath) {\n setSchemaPath((update.schemaPath as string) ?? '')\n }\n }, [update.schemaPath])\n\n useEffect(() => {\n if (\n activeCollection !== collectionSlug &&\n collectionSlug !== PLUGIN_INSTRUCTIONS_TABLE &&\n typeof setActiveCollection === 'function'\n ) {\n setActiveCollection(collectionSlug ?? '')\n }\n }, [activeCollection, collectionSlug, setActiveCollection])\n\n const groupedFields = useMemo(() => {\n const result: Record<string, string[]> = {}\n\n for (const fullKey of Object.keys(instructions)) {\n const [collection, ...pathParts] = fullKey.split('.')\n const path = pathParts.join('.')\n if (!result[collection]) {\n result[collection] = []\n }\n result[collection].push(path)\n }\n\n return result\n }, [instructions])\n\n // Suggestions for prompt editor\n const promptEditorSuggestions = useMemo(() => {\n const activeFields = groupedFields[activeCollection as string] || []\n\n const suggestions: string[] = []\n\n activeFields.forEach((f) => {\n const fieldKey = Object.keys(instructions).find((k) => k.endsWith(f))\n const fieldInfo = fieldKey ? instructions[fieldKey] : undefined\n\n if (!fieldInfo) {return}\n\n if (fieldInfo.fieldType === 'upload') {\n suggestions.push(`${f}.url`)\n return\n }\n\n const helpers = handlebarsHelpers.filter(\n (h) => (handlebarsHelpersMap as Record<string, any>)[h]?.field === fieldInfo.fieldType,\n )\n\n if (helpers.length) {\n for (const helper of helpers) {\n suggestions.push(`${helper} ${f}`)\n }\n } else {\n suggestions.push(f)\n }\n }, [])\n\n promptFields.forEach(({ name, collections }) => {\n if (!activeCollection) {return}\n\n if (!collections || collections.includes(activeCollection)) {\n suggestions.push(name)\n }\n })\n\n return suggestions\n }, [groupedFields, activeCollection, instructions, promptFields])\n\n return {\n ...context,\n ...(
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/InstructionsProvider/useInstructions.ts"],"sourcesContent":["import { InstructionsContext } from '@ai-stack/payloadcms/client'\nimport { useDocumentInfo } from '@payloadcms/ui'\nimport { useContext, useEffect, useMemo, useState } from 'react'\n\nimport { PLUGIN_INSTRUCTIONS_TABLE } from '../../defaults.js'\nimport { handlebarsHelpers, handlebarsHelpersMap } from '../../libraries/handlebars/helpersMap.js'\n\n\nconst warnedOnceOnNoInstructionId = new Set<string>()\nconst warnOnceOnMissingInstructions = (path: string) => {\n if (!warnedOnceOnNoInstructionId.has(path)) {\n warnedOnceOnNoInstructionId.add(path)\n // eslint-disable-next-line no-console\n console.info(`[AI Plugin] There are no AI instructions for this field: ${path}. Enable \"generatePromptOnInit\" option to enable them.`)\n }\n}\n\nexport const useInstructions = (\n update: {\n schemaPath?: unknown\n } = {},\n) => {\n const context = useContext(InstructionsContext)\n const { collectionSlug } = useDocumentInfo()\n const { activeCollection, hasInstructions, instructions, promptFields, setActiveCollection, debugging } = context\n\n const [schemaPath, setSchemaPath] = useState(update.schemaPath as string)\n\n useEffect(() => {\n if (update.schemaPath !== schemaPath) {\n setSchemaPath((update.schemaPath as string) ?? '')\n }\n }, [update.schemaPath])\n\n useEffect(() => {\n if (\n activeCollection !== collectionSlug &&\n collectionSlug !== PLUGIN_INSTRUCTIONS_TABLE &&\n typeof setActiveCollection === 'function'\n ) {\n setActiveCollection(collectionSlug ?? '')\n }\n }, [activeCollection, collectionSlug, setActiveCollection])\n\n const groupedFields = useMemo(() => {\n const result: Record<string, string[]> = {}\n\n for (const fullKey of Object.keys(instructions || {})) {\n const [collection, ...pathParts] = fullKey.split('.')\n const path = pathParts.join('.')\n if (!result[collection]) {\n result[collection] = []\n }\n result[collection].push(path)\n }\n\n return result\n }, [instructions])\n\n // Suggestions for prompt editor\n const promptEditorSuggestions = useMemo(() => {\n const activeFields = groupedFields[activeCollection as string] || []\n\n const suggestions: string[] = []\n\n activeFields.forEach((f) => {\n const fieldKey = Object.keys(instructions).find((k) => k.endsWith(f))\n const fieldInfo = fieldKey ? instructions[fieldKey] : undefined\n\n if (!fieldInfo) {return}\n\n if (fieldInfo.fieldType === 'upload') {\n suggestions.push(`${f}.url`)\n return\n }\n\n const helpers = handlebarsHelpers.filter(\n (h) => (handlebarsHelpersMap as Record<string, any>)[h]?.field === fieldInfo.fieldType,\n )\n\n if (helpers.length) {\n for (const helper of helpers) {\n suggestions.push(`${helper} ${f}`)\n }\n } else {\n suggestions.push(f)\n }\n }, [])\n\n promptFields.forEach(({ name, collections }) => {\n if (!activeCollection) {return}\n\n if (!collections || collections.includes(activeCollection)) {\n suggestions.push(name)\n }\n })\n\n return suggestions\n }, [groupedFields, activeCollection, instructions, promptFields])\n\n const pathInstructions = instructions[schemaPath]\n\n if (debugging && !pathInstructions && schemaPath && hasInstructions) {\n warnOnceOnMissingInstructions(schemaPath)\n }\n \n return {\n ...context,\n ...(pathInstructions || {}),\n promptEditorSuggestions,\n }\n}\n"],"names":["InstructionsContext","useDocumentInfo","useContext","useEffect","useMemo","useState","PLUGIN_INSTRUCTIONS_TABLE","handlebarsHelpers","handlebarsHelpersMap","warnedOnceOnNoInstructionId","Set","warnOnceOnMissingInstructions","path","has","add","console","info","useInstructions","update","context","collectionSlug","activeCollection","hasInstructions","instructions","promptFields","setActiveCollection","debugging","schemaPath","setSchemaPath","groupedFields","result","fullKey","Object","keys","collection","pathParts","split","join","push","promptEditorSuggestions","activeFields","suggestions","forEach","f","fieldKey","find","k","endsWith","fieldInfo","undefined","fieldType","helpers","filter","h","field","length","helper","name","collections","includes","pathInstructions"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { JSONSchema } from 'openai/lib/jsonschema';
|
|
2
2
|
import type { ImageGenerateParams } from 'openai/resources/images';
|
|
3
|
-
import type { CollectionSlug, DataFromCollectionSlug, Endpoint, Field, File, GlobalConfig, GroupField, PayloadRequest } from 'payload';
|
|
3
|
+
import type { CollectionConfig, CollectionSlug, DataFromCollectionSlug, Endpoint, Field, File, GlobalConfig, GroupField, PayloadRequest, TypedCollection } from 'payload';
|
|
4
4
|
import type { CSSProperties, MouseEventHandler } from 'react';
|
|
5
|
+
import type { PLUGIN_INSTRUCTIONS_TABLE } from "./defaults.js";
|
|
5
6
|
export interface PluginConfigAccess {
|
|
6
7
|
/**
|
|
7
8
|
* Control access to AI generation features (generate text, images, audio)
|
|
@@ -57,6 +58,7 @@ export interface PluginConfig {
|
|
|
57
58
|
interfaceName?: string;
|
|
58
59
|
mediaUpload?: PluginConfigMediaUploadFunction;
|
|
59
60
|
options?: PluginOptions;
|
|
61
|
+
overrideInstructions?: Partial<CollectionConfig>;
|
|
60
62
|
promptFields?: PromptField[];
|
|
61
63
|
/**
|
|
62
64
|
* Custom action prompts for AI text generation
|
|
@@ -115,10 +117,15 @@ export type SeedPromptOptions = {
|
|
|
115
117
|
fieldType: string;
|
|
116
118
|
path: string;
|
|
117
119
|
};
|
|
118
|
-
export type
|
|
120
|
+
export type SeedPromptData = Omit<TypedCollection[typeof PLUGIN_INSTRUCTIONS_TABLE], 'createdAt' | 'id' | 'updatedAt'>;
|
|
121
|
+
export type SeedPromptResult = {
|
|
122
|
+
data?: SeedPromptData;
|
|
119
123
|
prompt: string;
|
|
120
124
|
system: string;
|
|
121
|
-
}
|
|
125
|
+
} | {
|
|
126
|
+
data?: SeedPromptData;
|
|
127
|
+
} | false | undefined | void;
|
|
128
|
+
export type SeedPromptFunction = (options: SeedPromptOptions) => Promise<SeedPromptResult> | SeedPromptResult;
|
|
122
129
|
export type ActionMenuEvents = 'onCompose' | 'onExpand' | 'onProofread' | 'onRephrase' | 'onSettings' | 'onSimplify' | 'onSummarize' | 'onTone' | 'onTranslate';
|
|
123
130
|
export type UseMenuEvents = {
|
|
124
131
|
[key in ActionMenuEvents]?: (data?: unknown) => void;
|
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 /**\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 * 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 promptFields?: PromptField[]\n /**\n * Custom action prompts for AI text generation\n * If not provided, uses default prompts\n * You can access default prompts by importing { defaultPrompts } from '@ai-stack/payloadcms'\n */\n prompts?: ActionPrompt[]\n /**\n * Custom seed prompt function for generating field-specific prompts\n * If not provided, uses default seed prompt function\n * You can access default seed prompts by importing { defaultSeedPrompts } from '@ai-stack/payloadcms'\n */\n seedPrompts?: SeedPromptFunction\n uploadCollectionSlug?: CollectionSlug\n}\n\nexport interface GenerationModel {\n fields: string[]\n generateText?: (prompt: string, system: string) => Promise<string>\n handler?: (prompt: string, options: any) => 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 ActionPromptOptions = {\n layout?: string\n locale?: string\n prompt?: string\n systemPrompt?: string\n}\n\nexport type ActionPrompt = {\n layout?: (options?: ActionPromptOptions) => string\n name: ActionMenuItems\n system: (options: ActionPromptOptions) => string\n}\n\nexport type SeedPromptOptions = {\n fieldLabel: string\n fieldSchemaPaths: Record<string, any>\n fieldType: string\n path: string\n}\n\nexport type
|
|
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 CollectionConfig,\n CollectionSlug,\n DataFromCollectionSlug,\n Endpoint,\n Field,\n File,\n GlobalConfig,\n GroupField,\n PayloadRequest,\n TypedCollection,\n} from 'payload'\nimport type { CSSProperties, MouseEventHandler } from 'react'\n\nimport type {PLUGIN_INSTRUCTIONS_TABLE} from \"./defaults.js\";\n\nexport interface PluginConfigAccess {\n /**\n * Control access to AI generation features (generate text, images, audio)\n * @default () => !!req.user (requires authentication)\n */\n generate?: ({ req }: { req: PayloadRequest }) => 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 * 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 // Override the instructions collection config\n overrideInstructions?: Partial<CollectionConfig>\n promptFields?: PromptField[]\n /**\n * Custom action prompts for AI text generation\n * If not provided, uses default prompts\n * You can access default prompts by importing { defaultPrompts } from '@ai-stack/payloadcms'\n */\n prompts?: ActionPrompt[]\n /**\n * Custom seed prompt function for generating field-specific prompts\n * If not provided, uses default seed prompt function\n * You can access default seed prompts by importing { defaultSeedPrompts } from '@ai-stack/payloadcms'\n */\n seedPrompts?: SeedPromptFunction\n uploadCollectionSlug?: CollectionSlug\n}\n\nexport interface GenerationModel {\n fields: string[]\n generateText?: (prompt: string, system: string) => Promise<string>\n handler?: (prompt: string, options: any) => 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 ActionPromptOptions = {\n layout?: string\n locale?: string\n prompt?: string\n systemPrompt?: string\n}\n\nexport type ActionPrompt = {\n layout?: (options?: ActionPromptOptions) => string\n name: ActionMenuItems\n system: (options: ActionPromptOptions) => string\n}\n\nexport type SeedPromptOptions = {\n fieldLabel: string\n fieldSchemaPaths: Record<string, any>\n fieldType: string\n path: string\n}\n\nexport type SeedPromptData = Omit<TypedCollection[typeof PLUGIN_INSTRUCTIONS_TABLE], 'createdAt' | 'id' | 'updatedAt'>\n\nexport type SeedPromptResult = {\n data?: SeedPromptData\n prompt: string\n system: string\n} | {\n data?: SeedPromptData\n} | false | undefined | void\n\nexport type SeedPromptFunction = (options: SeedPromptOptions) => Promise<SeedPromptResult> | SeedPromptResult\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\nexport type SerializedPromptField = {\n collections?: (CollectionSlug)[]\n name: string\n}\n\nexport type PromptFieldGetterContext = {\n collection: CollectionSlug\n type: string\n}\n\nexport type PromptField = {\n // If not provided, the value will be returned from the data object as-is\n getter?: (data: object, ctx: PromptFieldGetterContext) => Promise<string> | string\n} & SerializedPromptField\n"],"names":[],"mappings":"AA4NA,WAGyB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEditorConfigContext } from '@payloadcms/richtext-lexical/client';
|
|
4
|
-
import {
|
|
4
|
+
import { Popup, useDocumentDrawer, useField } from '@payloadcms/ui';
|
|
5
5
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
6
6
|
import { PLUGIN_INSTRUCTIONS_TABLE } from '../../defaults.js';
|
|
7
7
|
import { setSafeLexicalState } from '../../utilities/setSafeLexicalState.js';
|
|
@@ -201,37 +201,28 @@ export const Compose = ({ descriptionProps, instructionId, isConfigAllowed })=>{
|
|
|
201
201
|
isProcessing,
|
|
202
202
|
isLoading
|
|
203
203
|
]);
|
|
204
|
-
return /*#__PURE__*/ _jsxs(
|
|
204
|
+
return /*#__PURE__*/ _jsxs("label", {
|
|
205
|
+
className: `payloadai-compose__actions ${styles.actions}`,
|
|
206
|
+
onClick: (e)=>e.preventDefault(),
|
|
207
|
+
ref: actionsRef,
|
|
208
|
+
role: "presentation",
|
|
205
209
|
children: [
|
|
206
|
-
/*#__PURE__*/
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
}),
|
|
217
|
-
memoizedPopup,
|
|
218
|
-
/*#__PURE__*/ _jsx(ActiveComponent, {
|
|
219
|
-
isLoading: isProcessing || isLoading,
|
|
220
|
-
stop: stop
|
|
221
|
-
}),
|
|
222
|
-
/*#__PURE__*/ _jsx(UndoRedoActions, {
|
|
223
|
-
onChange: (val)=>{
|
|
224
|
-
setValue(val);
|
|
225
|
-
setIfValueIsLexicalState(val);
|
|
226
|
-
}
|
|
227
|
-
})
|
|
228
|
-
]
|
|
210
|
+
/*#__PURE__*/ _jsx(DocumentDrawer, {
|
|
211
|
+
onSave: ()=>{
|
|
212
|
+
closeDrawer();
|
|
213
|
+
}
|
|
214
|
+
}),
|
|
215
|
+
memoizedPopup,
|
|
216
|
+
/*#__PURE__*/ _jsx(ActiveComponent, {
|
|
217
|
+
isLoading: isProcessing || isLoading,
|
|
218
|
+
stop: stop
|
|
229
219
|
}),
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
220
|
+
/*#__PURE__*/ _jsx(UndoRedoActions, {
|
|
221
|
+
onChange: (val)=>{
|
|
222
|
+
setValue(val);
|
|
223
|
+
setIfValueIsLexicalState(val);
|
|
224
|
+
}
|
|
225
|
+
})
|
|
235
226
|
]
|
|
236
227
|
});
|
|
237
228
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/ui/Compose/Compose.tsx"],"sourcesContent":["'use client'\n\nimport type { ClientField } from 'payload'\nimport type { FC } from 'react'\n\nimport { useEditorConfigContext } from '@payloadcms/richtext-lexical/client'\nimport { FieldDescription, Popup, useDocumentDrawer, useField } from '@payloadcms/ui'\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\n\nimport { PLUGIN_INSTRUCTIONS_TABLE } from '../../defaults.js'\nimport { setSafeLexicalState } from '../../utilities/setSafeLexicalState.js'\nimport { PluginIcon } from '../Icons/Icons.js'\nimport styles from './compose.module.css'\nimport { useMenu } from './hooks/menu/useMenu.js'\nimport { useGenerate } from './hooks/useGenerate.js'\nimport { UndoRedoActions } from './UndoRedoActions.js'\n\nfunction findParentWithClass(element: HTMLElement | null, className: string): HTMLElement | null {\n // Base case: if the element is null, or we've reached the top of the DOM\n if (!element || element === document.body) {\n return null\n }\n\n // Check if the current element has the class we're looking for\n if (element.classList.contains(className)) {\n return element\n }\n\n // Recursively call the function on the parent element\n return findParentWithClass(element.parentElement, className)\n}\n\ntype ComposeProps = {\n descriptionProps?: {\n field: ClientField\n path: string\n schemaPath: string\n }\n instructionId: string\n isConfigAllowed: boolean\n}\n\nexport const Compose: FC<ComposeProps> = ({ descriptionProps, instructionId, isConfigAllowed }) => {\n const [DocumentDrawer, _, { closeDrawer, openDrawer }] = useDocumentDrawer({\n id: instructionId,\n collectionSlug: PLUGIN_INSTRUCTIONS_TABLE,\n })\n\n const fieldType = descriptionProps?.field?.type\n const pathFromContext = descriptionProps?.path\n const schemaPath = descriptionProps?.schemaPath\n const { editor: lexicalEditor, editorContainerRef } = useEditorConfigContext()\n\n // The below snippet is used to show/hide the action menu on AI-enabled fields\n const [input, setInput] = useState<HTMLElement | null>(null)\n const actionsRef = useRef<HTMLLabelElement | null>(null)\n\n // Set input element for current field\n useEffect(() => {\n if (!actionsRef.current) {\n return\n }\n\n if (!pathFromContext) {\n return\n }\n\n const fieldId = `field-${pathFromContext.replace(/\\./g, '__')}`\n const inputElement = document.getElementById(fieldId)\n\n if (!inputElement && fieldType === 'richText') {\n setInput(editorContainerRef.current as HTMLElement | null)\n } else {\n actionsRef.current?.setAttribute('for', fieldId)\n setInput(inputElement)\n }\n }, [pathFromContext, schemaPath, actionsRef, editorContainerRef, fieldType])\n\n // Show or hide actions menu on field\n useEffect(() => {\n if (!input || !actionsRef.current) {\n return\n }\n\n actionsRef.current?.classList.add(styles.actions_hidden)\n\n // Create the handler function\n const clickHandler = (event: MouseEvent) => {\n document.querySelectorAll('.ai-plugin-active')?.forEach((element) => {\n const actionElement = (element as HTMLElement).querySelector(`.${styles.actions}`)\n if (actionElement) {\n actionElement.classList.add(styles.actions_hidden)\n element.classList.remove('ai-plugin-active')\n }\n })\n\n actionsRef.current?.classList.remove(styles.actions_hidden)\n const parentWithClass = findParentWithClass(event.target as HTMLElement, 'field-type')\n if (parentWithClass) {\n parentWithClass.classList.add('ai-plugin-active')\n }\n }\n\n // Add the event listener\n input?.addEventListener('click', clickHandler)\n\n // Clean up the event listener when the component unmounts or input changes\n return () => {\n input?.removeEventListener('click', clickHandler)\n }\n }, [input, actionsRef])\n\n const [isProcessing, setIsProcessing] = useState<boolean>(false)\n const { generate, isLoading, stop } = useGenerate({ instructionId })\n\n const { ActiveComponent, Menu } = useMenu(\n {\n onCompose: () => {\n console.log('Composing...')\n setIsProcessing(true)\n generate({\n action: 'Compose',\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n onExpand: () => {\n console.log('Expanding...')\n generate({\n action: 'Expand',\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n onProofread: () => {\n console.log('Proofreading...')\n generate({\n action: 'Proofread',\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n onRephrase: () => {\n console.log('Rephrasing...')\n generate({\n action: 'Rephrase',\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n onSettings: isConfigAllowed ? openDrawer : undefined,\n onSimplify: () => {\n console.log('Simplifying...')\n generate({\n action: 'Simplify',\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n onSummarize: () => {\n console.log('Summarizing...')\n generate({\n action: 'Summarize',\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n onTranslate: (data) => {\n console.log('Translating...')\n generate({\n action: 'Translate',\n params: data,\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n },\n {\n isConfigAllowed,\n },\n )\n\n const { setValue } = useField<string>({\n path: pathFromContext,\n })\n\n const setIfValueIsLexicalState = useCallback((val: any) => {\n if (val && typeof val === 'object' && 'root' in val && lexicalEditor) {\n setSafeLexicalState(JSON.stringify(val), lexicalEditor)\n }\n\n // DO NOT PROVIDE lexicalEditor as a dependency, it freaks out and does not update the editor after first undo/redo\n }, [])\n\n const popupRender = useCallback(\n ({ close }: { close: () => void }) => {\n return <Menu isLoading={isProcessing || isLoading} onClose={close} />\n },\n [isProcessing, isLoading, Menu],\n )\n\n const memoizedPopup = useMemo(() => {\n return (\n <Popup\n button={<PluginIcon isLoading={isProcessing || isLoading} />}\n render={popupRender}\n verticalAlign=\"bottom\"\n />\n )\n }, [popupRender, isProcessing, isLoading])\n\n return (\n <React.Fragment>\n <label\n className={`${styles.actions}`}\n onClick={(e) => e.preventDefault()}\n ref={actionsRef}\n role=\"presentation\"\n >\n <DocumentDrawer\n onSave={() => {\n closeDrawer()\n }}\n />\n {memoizedPopup}\n <ActiveComponent isLoading={isProcessing || isLoading} stop={stop} />\n <UndoRedoActions\n onChange={(val) => {\n setValue(val)\n setIfValueIsLexicalState(val)\n }}\n />\n </label>\n {/*Render the incoming description field*/}\n {descriptionProps ? (\n <div>\n <FieldDescription {...descriptionProps} />\n </div>\n ) : null}\n </React.Fragment>\n )\n}\n"],"names":["useEditorConfigContext","FieldDescription","Popup","useDocumentDrawer","useField","React","useCallback","useEffect","useMemo","useRef","useState","PLUGIN_INSTRUCTIONS_TABLE","setSafeLexicalState","PluginIcon","styles","useMenu","useGenerate","UndoRedoActions","findParentWithClass","element","className","document","body","classList","contains","parentElement","Compose","descriptionProps","instructionId","isConfigAllowed","DocumentDrawer","_","closeDrawer","openDrawer","id","collectionSlug","fieldType","field","type","pathFromContext","path","schemaPath","editor","lexicalEditor","editorContainerRef","input","setInput","actionsRef","current","fieldId","replace","inputElement","getElementById","setAttribute","add","actions_hidden","clickHandler","event","querySelectorAll","forEach","actionElement","querySelector","actions","remove","parentWithClass","target","addEventListener","removeEventListener","isProcessing","setIsProcessing","generate","isLoading","stop","ActiveComponent","Menu","onCompose","console","log","action","catch","reason","error","finally","onExpand","onProofread","onRephrase","onSettings","undefined","onSimplify","onSummarize","onTranslate","data","params","setValue","setIfValueIsLexicalState","val","JSON","stringify","popupRender","close","onClose","memoizedPopup","button","render","verticalAlign","Fragment","label","onClick","e","preventDefault","ref","role","onSave","onChange","div"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/Compose/Compose.tsx"],"sourcesContent":["'use client'\n\nimport type { ClientField } from 'payload'\nimport type { FC } from 'react'\n\nimport { useEditorConfigContext } from '@payloadcms/richtext-lexical/client'\nimport { FieldDescription, Popup, useDocumentDrawer, useField } from '@payloadcms/ui'\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\n\nimport { PLUGIN_INSTRUCTIONS_TABLE } from '../../defaults.js'\nimport { setSafeLexicalState } from '../../utilities/setSafeLexicalState.js'\nimport { PluginIcon } from '../Icons/Icons.js'\nimport styles from './compose.module.css'\nimport { useMenu } from './hooks/menu/useMenu.js'\nimport { useGenerate } from './hooks/useGenerate.js'\nimport { UndoRedoActions } from './UndoRedoActions.js'\n\nfunction findParentWithClass(element: HTMLElement | null, className: string): HTMLElement | null {\n // Base case: if the element is null, or we've reached the top of the DOM\n if (!element || element === document.body) {\n return null\n }\n\n // Check if the current element has the class we're looking for\n if (element.classList.contains(className)) {\n return element\n }\n\n // Recursively call the function on the parent element\n return findParentWithClass(element.parentElement, className)\n}\n\ntype ComposeProps = {\n descriptionProps?: {\n field: ClientField\n path: string\n schemaPath: string\n }\n instructionId: string\n isConfigAllowed: boolean\n}\n\nexport const Compose: FC<ComposeProps> = ({ descriptionProps, instructionId, isConfigAllowed }) => {\n const [DocumentDrawer, _, { closeDrawer, openDrawer }] = useDocumentDrawer({\n id: instructionId,\n collectionSlug: PLUGIN_INSTRUCTIONS_TABLE,\n })\n\n const fieldType = descriptionProps?.field?.type\n const pathFromContext = descriptionProps?.path\n const schemaPath = descriptionProps?.schemaPath\n const { editor: lexicalEditor, editorContainerRef } = useEditorConfigContext()\n\n // The below snippet is used to show/hide the action menu on AI-enabled fields\n const [input, setInput] = useState<HTMLElement | null>(null)\n const actionsRef = useRef<HTMLLabelElement | null>(null)\n\n // Set input element for current field\n useEffect(() => {\n if (!actionsRef.current) {\n return\n }\n\n if (!pathFromContext) {\n return\n }\n\n const fieldId = `field-${pathFromContext.replace(/\\./g, '__')}`\n const inputElement = document.getElementById(fieldId)\n\n if (!inputElement && fieldType === 'richText') {\n setInput(editorContainerRef.current as HTMLElement | null)\n } else {\n actionsRef.current?.setAttribute('for', fieldId)\n setInput(inputElement)\n }\n }, [pathFromContext, schemaPath, actionsRef, editorContainerRef, fieldType])\n\n // Show or hide actions menu on field\n useEffect(() => {\n if (!input || !actionsRef.current) {\n return\n }\n\n actionsRef.current?.classList.add(styles.actions_hidden)\n\n // Create the handler function\n const clickHandler = (event: MouseEvent) => {\n document.querySelectorAll('.ai-plugin-active')?.forEach((element) => {\n const actionElement = (element as HTMLElement).querySelector(`.${styles.actions}`)\n if (actionElement) {\n actionElement.classList.add(styles.actions_hidden)\n element.classList.remove('ai-plugin-active')\n }\n })\n\n actionsRef.current?.classList.remove(styles.actions_hidden)\n const parentWithClass = findParentWithClass(event.target as HTMLElement, 'field-type')\n if (parentWithClass) {\n parentWithClass.classList.add('ai-plugin-active')\n }\n }\n\n // Add the event listener\n input?.addEventListener('click', clickHandler)\n\n // Clean up the event listener when the component unmounts or input changes\n return () => {\n input?.removeEventListener('click', clickHandler)\n }\n }, [input, actionsRef])\n\n const [isProcessing, setIsProcessing] = useState<boolean>(false)\n const { generate, isLoading, stop } = useGenerate({ instructionId })\n\n const { ActiveComponent, Menu } = useMenu(\n {\n onCompose: () => {\n console.log('Composing...')\n setIsProcessing(true)\n generate({\n action: 'Compose',\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n onExpand: () => {\n console.log('Expanding...')\n generate({\n action: 'Expand',\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n onProofread: () => {\n console.log('Proofreading...')\n generate({\n action: 'Proofread',\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n onRephrase: () => {\n console.log('Rephrasing...')\n generate({\n action: 'Rephrase',\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n onSettings: isConfigAllowed ? openDrawer : undefined,\n onSimplify: () => {\n console.log('Simplifying...')\n generate({\n action: 'Simplify',\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n onSummarize: () => {\n console.log('Summarizing...')\n generate({\n action: 'Summarize',\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n onTranslate: (data) => {\n console.log('Translating...')\n generate({\n action: 'Translate',\n params: data,\n }).catch((reason)=>{\n console.error(\"Compose : \",reason)\n }).finally(() => {\n setIsProcessing(false)\n })\n },\n },\n {\n isConfigAllowed,\n },\n )\n\n const { setValue } = useField<string>({\n path: pathFromContext,\n })\n\n const setIfValueIsLexicalState = useCallback((val: any) => {\n if (val && typeof val === 'object' && 'root' in val && lexicalEditor) {\n setSafeLexicalState(JSON.stringify(val), lexicalEditor)\n }\n\n // DO NOT PROVIDE lexicalEditor as a dependency, it freaks out and does not update the editor after first undo/redo\n }, [])\n\n const popupRender = useCallback(\n ({ close }: { close: () => void }) => {\n return <Menu isLoading={isProcessing || isLoading} onClose={close} />\n },\n [isProcessing, isLoading, Menu],\n )\n\n const memoizedPopup = useMemo(() => {\n return (\n <Popup\n button={<PluginIcon isLoading={isProcessing || isLoading} />}\n render={popupRender}\n verticalAlign=\"bottom\"\n />\n )\n }, [popupRender, isProcessing, isLoading])\n\n return (\n <label\n className={`payloadai-compose__actions ${styles.actions}`}\n onClick={(e) => e.preventDefault()}\n ref={actionsRef}\n role=\"presentation\"\n >\n <DocumentDrawer\n onSave={() => {\n closeDrawer()\n }}\n />\n {memoizedPopup}\n <ActiveComponent isLoading={isProcessing || isLoading} stop={stop} />\n <UndoRedoActions\n onChange={(val) => {\n setValue(val)\n setIfValueIsLexicalState(val)\n }}\n />\n </label>\n )\n}\n"],"names":["useEditorConfigContext","Popup","useDocumentDrawer","useField","React","useCallback","useEffect","useMemo","useRef","useState","PLUGIN_INSTRUCTIONS_TABLE","setSafeLexicalState","PluginIcon","styles","useMenu","useGenerate","UndoRedoActions","findParentWithClass","element","className","document","body","classList","contains","parentElement","Compose","descriptionProps","instructionId","isConfigAllowed","DocumentDrawer","_","closeDrawer","openDrawer","id","collectionSlug","fieldType","field","type","pathFromContext","path","schemaPath","editor","lexicalEditor","editorContainerRef","input","setInput","actionsRef","current","fieldId","replace","inputElement","getElementById","setAttribute","add","actions_hidden","clickHandler","event","querySelectorAll","forEach","actionElement","querySelector","actions","remove","parentWithClass","target","addEventListener","removeEventListener","isProcessing","setIsProcessing","generate","isLoading","stop","ActiveComponent","Menu","onCompose","console","log","action","catch","reason","error","finally","onExpand","onProofread","onRephrase","onSettings","undefined","onSimplify","onSummarize","onTranslate","data","params","setValue","setIfValueIsLexicalState","val","JSON","stringify","popupRender","close","onClose","memoizedPopup","button","render","verticalAlign","label","onClick","e","preventDefault","ref","role","onSave","onChange"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/extractImageData.ts"],"sourcesContent":["type ImageData = {\n image: { name: string; type: string; url: string }\n}[]\n\nexport function extractImageData(input: string): ImageData {\n const regex =
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/extractImageData.ts"],"sourcesContent":["type ImageData = {\n image: { name: string; type: string; url: string }\n}[]\n\nexport function extractImageData(input: string): ImageData {\n const regex = /(?:https?:)?\\/[\\w%\\-.,/]+\\.(png|jpe?g|webp)/gi\n const matches = input.match(regex)\n\n if (!matches) return []\n\n return matches.map((url) => {\n const decodedUrl = decodeURIComponent(url)\n const parts = decodedUrl.split('/')\n const filename = parts[parts.length - 1]\n const name = filename.replace(/\\.(png|jpe?g|webp)$/i, '')\n const typeMatch = filename.match(/\\.(png|jpe?g|webp)$/i)\n const type = typeMatch ? typeMatch[1].toLowerCase() : 'unknown'\n\n return {\n image: {\n name,\n type,\n url,\n },\n }\n })\n}\n"],"names":["extractImageData","input","regex","matches","match","map","url","decodedUrl","decodeURIComponent","parts","split","filename","length","name","replace","typeMatch","type","toLowerCase","image"],"mappings":"AAIA,OAAO,SAASA,iBAAiBC,KAAa;IAC5C,MAAMC,QAAQ;IACd,MAAMC,UAAUF,MAAMG,KAAK,CAACF;IAE5B,IAAI,CAACC,SAAS,OAAO,EAAE;IAEvB,OAAOA,QAAQE,GAAG,CAAC,CAACC;QAClB,MAAMC,aAAaC,mBAAmBF;QACtC,MAAMG,QAAQF,WAAWG,KAAK,CAAC;QAC/B,MAAMC,WAAWF,KAAK,CAACA,MAAMG,MAAM,GAAG,EAAE;QACxC,MAAMC,OAAOF,SAASG,OAAO,CAAC,wBAAwB;QACtD,MAAMC,YAAYJ,SAASP,KAAK,CAAC;QACjC,MAAMY,OAAOD,YAAYA,SAAS,CAAC,EAAE,CAACE,WAAW,KAAK;QAEtD,OAAO;YACLC,OAAO;gBACLL;gBACAG;gBACAV;YACF;QACF;IACF;AACF"}
|