@ai-stack/payloadcms 3.2.20-beta → 3.2.21-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/dist/ai/models/anthropic/index.js +9 -15
- package/dist/ai/models/anthropic/index.js.map +1 -1
- package/dist/ai/models/generateObject.d.ts +11 -0
- package/dist/ai/models/generateObject.js +22 -0
- package/dist/ai/models/generateObject.js.map +1 -0
- package/dist/ai/models/openai/index.js +19 -17
- package/dist/ai/models/openai/index.js.map +1 -1
- package/dist/collections/Instructions.js +2 -0
- package/dist/collections/Instructions.js.map +1 -1
- package/dist/endpoints/index.js +55 -6
- package/dist/endpoints/index.js.map +1 -1
- package/dist/fields/ComposeField/ComposeField.js +5 -3
- package/dist/fields/ComposeField/ComposeField.js.map +1 -1
- package/dist/fields/ComposeField/ComposeField.jsx +32 -0
- package/dist/fields/LexicalEditor/ComposeFeatureComponent.js +1 -1
- package/dist/fields/LexicalEditor/ComposeFeatureComponent.js.map +1 -1
- package/dist/fields/LexicalEditor/ComposeFeatureComponent.jsx +24 -0
- package/dist/fields/LexicalEditor/feature.client.jsx +21 -0
- package/dist/fields/PromptEditorField/PromptEditorField.jsx +42 -0
- package/dist/fields/SelectField/SelectField.jsx +38 -0
- package/dist/providers/FieldProvider/FieldProvider.d.ts +7 -4
- package/dist/providers/FieldProvider/FieldProvider.js +7 -6
- package/dist/providers/FieldProvider/FieldProvider.js.map +1 -1
- package/dist/providers/FieldProvider/FieldProvider.jsx +27 -0
- package/dist/providers/FieldProvider/useFieldProps.d.ts +1 -1
- package/dist/providers/FieldProvider/useFieldProps.js +2 -2
- package/dist/providers/FieldProvider/useFieldProps.js.map +1 -1
- package/dist/providers/InstructionsProvider/InstructionsProvider.jsx +45 -0
- package/dist/types.d.ts +4 -4
- package/dist/types.js.map +1 -1
- package/dist/ui/Compose/Compose.js +12 -81
- package/dist/ui/Compose/Compose.js.map +1 -1
- package/dist/ui/Compose/Compose.jsx +141 -0
- package/dist/ui/Compose/UndoRedoActions.jsx +34 -0
- package/dist/ui/Compose/compose.module.css +99 -12
- package/dist/ui/Compose/hooks/menu/Item.jsx +15 -0
- package/dist/ui/Compose/hooks/menu/TranslateMenu.jsx +58 -0
- package/dist/ui/Compose/hooks/menu/items.jsx +10 -0
- package/dist/ui/Compose/hooks/menu/useMenu.js +1 -1
- package/dist/ui/Compose/hooks/menu/useMenu.js.map +1 -1
- package/dist/ui/Compose/hooks/menu/useMenu.jsx +89 -0
- package/dist/ui/Compose/hooks/useActiveFieldTracking.d.ts +5 -0
- package/dist/ui/Compose/hooks/useActiveFieldTracking.js +148 -0
- package/dist/ui/Compose/hooks/useActiveFieldTracking.js.map +1 -0
- package/dist/ui/Compose/hooks/useGenerate.js +46 -79
- package/dist/ui/Compose/hooks/useGenerate.js.map +1 -1
- package/dist/ui/Icons/Icons.jsx +78 -0
- package/dist/ui/Icons/LottieAnimation.jsx +64 -0
- package/dist/utilities/extractPromptAttachments.d.ts +2 -2
- package/dist/utilities/extractPromptAttachments.js.map +1 -1
- package/dist/utilities/fieldToJsonSchema.d.ts +37 -0
- package/dist/utilities/fieldToJsonSchema.js +274 -0
- package/dist/utilities/fieldToJsonSchema.js.map +1 -0
- package/dist/utilities/getFieldBySchemaPath.d.ts +12 -1
- package/dist/utilities/getFieldBySchemaPath.js +63 -29
- package/dist/utilities/getFieldBySchemaPath.js.map +1 -1
- package/package.json +2 -1
- package/dist/ai/models/anthropic/generateRichText.d.ts +0 -1
- package/dist/ai/models/anthropic/generateRichText.js +0 -36
- package/dist/ai/models/anthropic/generateRichText.js.map +0 -1
- package/dist/ai/models/openai/generateRichText.d.ts +0 -1
- package/dist/ai/models/openai/generateRichText.js +0 -37
- package/dist/ai/models/openai/generateRichText.js.map +0 -1
|
@@ -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) || (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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"}
|
|
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 { fieldToJsonSchema } from '../utilities/fieldToJsonSchema.js'\nimport { getFieldBySchemaPath } from '../utilities/getFieldBySchemaPath.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)\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 buildRichTextSystem = (baseSystem: string, layout: string) => {\n return `${baseSystem}\n\nRULES:\n- Generate original and unique content based on the given topic.\n- Strictly adhere to the specified layout and formatting instructions.\n- Utilize the provided rich text editor tools for appropriate formatting.\n- Ensure the output follows the structure of the sample output object.\n- Produce valid JSON with no undefined or null values.\n---\nLAYOUT INSTRUCTIONS:\n${layout}\n\n---\nADDITIONAL GUIDELINES:\n- Ensure coherence and logical flow between all sections.\n- Maintain a consistent tone and style throughout the content.\n- Use clear and concise language appropriate for the target audience.\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' ? buildRichTextSystem(systemPrompt, layout) : 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: type === 'richText' ? buildRichTextSystem(system, updatedLayout) : 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 parts = schemaPath?.split('.') || []\n const collectionName = parts[0]\n const fieldName = parts.length > 1 ? parts[parts.length - 1] : ''\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 const settingsName = model.settings && \"name\" in 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 // Build per-field JSON schema for structured generation when applicable\n let jsonSchema= allowedEditorSchema\n try {\n const targetCollection = req.payload.config.collections.find(\n (c) => c.slug === collectionName,\n )\n if (targetCollection && fieldName) {\n const targetField = getFieldBySchemaPath(targetCollection, schemaPath)\n const supported = ['text', 'textarea', 'select', 'number', 'date', 'code', 'email', 'json']\n const t = String(targetField?.type || '')\n if (targetField && supported.includes(t)) {\n jsonSchema = fieldToJsonSchema(targetField as any, { nameOverride: fieldName })\n }\n }\n } catch (e) {\n req.payload.logger.error(e, '— AI Plugin: Error building field JSON schema')\n }\n\n return model.handler?.(prompts.prompt, {\n ...modelOptions,\n layout: prompts.layout,\n locale: localeInfo,\n schema: jsonSchema,\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","fieldToJsonSchema","getFieldBySchemaPath","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","buildRichTextSystem","baseSystem","layout","assignPrompt","action","type","actionParams","context","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","parts","split","collectionName","fieldName","defaultLocale","locales","localization","localeData","l","code","localeInfo","label","models","model","Array","isArray","settingsName","settings","logger","error","modelOptions","String","debugging","info","jsonSchema","targetCollection","c","targetField","supported","t","nameOverride","e","message","Response","JSON","stringify","headers","status","method","path","upload","collectionSlug","documentId","docData","draft","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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"}
|
|
@@ -11,9 +11,11 @@ export const ComposeField = (props)=>{
|
|
|
11
11
|
const { id: instructionId, disabled, hasInstructions, isConfigAllowed } = useInstructions({
|
|
12
12
|
schemaPath: finalSchemaPath
|
|
13
13
|
});
|
|
14
|
+
const adminDescription = props?.field?.admin || {};
|
|
15
|
+
const description = "description" in adminDescription ? adminDescription.description : "";
|
|
14
16
|
return /*#__PURE__*/ _jsxs(FieldProvider, {
|
|
15
17
|
context: {
|
|
16
|
-
|
|
18
|
+
field: props?.field,
|
|
17
19
|
path: props?.path ?? '',
|
|
18
20
|
schemaPath: finalSchemaPath
|
|
19
21
|
},
|
|
@@ -30,8 +32,8 @@ export const ComposeField = (props)=>{
|
|
|
30
32
|
}) : null,
|
|
31
33
|
/*#__PURE__*/ _jsx("div", {
|
|
32
34
|
children: /*#__PURE__*/ _jsx(FieldDescription, {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
description: description,
|
|
36
|
+
path: props?.path
|
|
35
37
|
})
|
|
36
38
|
})
|
|
37
39
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fields/ComposeField/ComposeField.tsx"],"sourcesContent":["'use client'\n\nimport type { ClientField } from 'payload'\n\nimport { FieldDescription, useDocumentInfo } from '@payloadcms/ui'\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 {\n id: instructionId,\n disabled,\n hasInstructions,\n isConfigAllowed,\n } = useInstructions({\n schemaPath: finalSchemaPath,\n })\n\n return (\n <FieldProvider\n context={{\n
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/ComposeField/ComposeField.tsx"],"sourcesContent":["'use client'\n\nimport type { ClientField } from 'payload'\n\nimport { FieldDescription, useDocumentInfo } from '@payloadcms/ui'\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 {\n id: instructionId,\n disabled,\n hasInstructions,\n isConfigAllowed,\n } = useInstructions({\n schemaPath: finalSchemaPath,\n })\n\n const adminDescription = props?.field?.admin || {}\n const description = \"description\" in adminDescription ? adminDescription.description : \"\"\n\n return (\n <FieldProvider\n context={{\n field: props?.field,\n path: props?.path ?? '',\n schemaPath: finalSchemaPath,\n }}\n >\n {hasInstructions && instructionId && !disabled ? (\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 <div>\n <FieldDescription description={description as any} path={props?.path as string} />\n </div>\n </FieldProvider>\n )\n}\n"],"names":["FieldDescription","useDocumentInfo","React","FieldProvider","useInstructions","Compose","ComposeField","props","collectionSlug","finalSchemaPath","schemaPath","path","id","instructionId","disabled","hasInstructions","isConfigAllowed","adminDescription","field","admin","description","context","descriptionProps","div"],"mappings":"AAAA;;AAIA,SAASA,gBAAgB,EAAEC,eAAe,QAAQ,iBAAgB;AAClE,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,EACJC,IAAIC,aAAa,EACjBC,QAAQ,EACRC,eAAe,EACfC,eAAe,EAChB,GAAGZ,gBAAgB;QAClBM,YAAYD;IACd;IAEA,MAAMQ,mBAAmBV,OAAOW,OAAOC,SAAS,CAAC;IACjD,MAAMC,cAAc,iBAAiBH,mBAAmBA,iBAAiBG,WAAW,GAAG;IAEvF,qBACE,MAACjB;QACCkB,SAAS;YACPH,OAAOX,OAAOW;YACdP,MAAMJ,OAAOI,QAAQ;YACrBD,YAAYD;QACd;;YAECM,mBAAmBF,iBAAiB,CAACC,yBACpC,KAACT;gBACCiB,kBAAkB;oBAChB,GAAGf,KAAK;oBACRW,OAAOX,OAAOW;oBACdP,MAAMJ,OAAOI,QAAQ;oBACrBD,YAAYD;gBACd;gBACAI,eAAeA;gBACfG,iBAAiBA;iBAEjB;0BAEJ,KAACO;0BACC,cAAA,KAACvB;oBAAiBoB,aAAaA;oBAAoBT,MAAMJ,OAAOI;;;;;AAIxE,EAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { FieldDescription, useDocumentInfo } from '@payloadcms/ui';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { FieldProvider } from '../../providers/FieldProvider/FieldProvider.js';
|
|
5
|
+
import { useInstructions } from '../../providers/InstructionsProvider/useInstructions.js';
|
|
6
|
+
import { Compose } from '../../ui/Compose/Compose.js';
|
|
7
|
+
export const ComposeField = (props) => {
|
|
8
|
+
const { collectionSlug } = useDocumentInfo();
|
|
9
|
+
const finalSchemaPath = props?.schemaPath ??
|
|
10
|
+
(collectionSlug ? `${collectionSlug}.${props?.path ?? ''}` : (props?.path ?? ''));
|
|
11
|
+
const { id: instructionId, disabled, hasInstructions, isConfigAllowed, } = useInstructions({
|
|
12
|
+
schemaPath: finalSchemaPath,
|
|
13
|
+
});
|
|
14
|
+
const adminDescription = props?.field?.admin || {};
|
|
15
|
+
const description = "description" in adminDescription ? adminDescription.description : "";
|
|
16
|
+
return (<FieldProvider context={{
|
|
17
|
+
field: props?.field,
|
|
18
|
+
path: props?.path ?? '',
|
|
19
|
+
schemaPath: finalSchemaPath,
|
|
20
|
+
}}>
|
|
21
|
+
{hasInstructions && instructionId && !disabled ? (<Compose descriptionProps={{
|
|
22
|
+
...props,
|
|
23
|
+
field: props?.field,
|
|
24
|
+
path: props?.path ?? '',
|
|
25
|
+
schemaPath: finalSchemaPath,
|
|
26
|
+
}} instructionId={instructionId} isConfigAllowed={isConfigAllowed}/>) : null}
|
|
27
|
+
|
|
28
|
+
<div>
|
|
29
|
+
<FieldDescription description={description} path={props?.path}/>
|
|
30
|
+
</div>
|
|
31
|
+
</FieldProvider>);
|
|
32
|
+
};
|
|
@@ -12,7 +12,7 @@ export const ComposeFeatureComponent = (props)=>{
|
|
|
12
12
|
}
|
|
13
13
|
return /*#__PURE__*/ _jsx(FieldProvider, {
|
|
14
14
|
context: {
|
|
15
|
-
|
|
15
|
+
field: props?.clientProps?.field,
|
|
16
16
|
path: props?.clientProps?.path,
|
|
17
17
|
schemaPath: props?.clientProps?.schemaPath
|
|
18
18
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fields/LexicalEditor/ComposeFeatureComponent.tsx"],"sourcesContent":["import 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\nexport const ComposeFeatureComponent = (props: any) => {\n const {\n id: instructionId,\n disabled,\n isConfigAllowed,\n } = useInstructions({\n schemaPath: props?.clientProps?.schemaPath,\n })\n\n if (!instructionId || disabled) {\n return null\n }\n\n return (\n <FieldProvider\n context={{\n
|
|
1
|
+
{"version":3,"sources":["../../../src/fields/LexicalEditor/ComposeFeatureComponent.tsx"],"sourcesContent":["import 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\nexport const ComposeFeatureComponent = (props: any) => {\n const {\n id: instructionId,\n disabled,\n isConfigAllowed,\n } = useInstructions({\n schemaPath: props?.clientProps?.schemaPath,\n })\n\n if (!instructionId || disabled) {\n return null\n }\n\n return (\n <FieldProvider\n context={{\n field: props?.clientProps?.field,\n path: props?.clientProps?.path,\n schemaPath: props?.clientProps?.schemaPath,\n }}\n >\n <Compose\n descriptionProps={{\n field: props?.clientProps?.field,\n path: props?.clientProps?.path,\n schemaPath: props?.clientProps?.schemaPath,\n ...props?.clientProps,\n }}\n instructionId={instructionId}\n isConfigAllowed={isConfigAllowed}\n />\n </FieldProvider>\n )\n}\n"],"names":["React","FieldProvider","useInstructions","Compose","ComposeFeatureComponent","props","id","instructionId","disabled","isConfigAllowed","schemaPath","clientProps","context","field","path","descriptionProps"],"mappings":";AAAA,OAAOA,WAAW,QAAO;AAEzB,SAASC,aAAa,QAAQ,iDAAgD;AAC9E,SAASC,eAAe,QAAQ,0DAAyD;AACzF,SAASC,OAAO,QAAQ,8BAA6B;AAErD,OAAO,MAAMC,0BAA0B,CAACC;IACtC,MAAM,EACJC,IAAIC,aAAa,EACjBC,QAAQ,EACRC,eAAe,EAChB,GAAGP,gBAAgB;QAClBQ,YAAYL,OAAOM,aAAaD;IAClC;IAEA,IAAI,CAACH,iBAAiBC,UAAU;QAC9B,OAAO;IACT;IAEA,qBACE,KAACP;QACCW,SAAS;YACPC,OAAOR,OAAOM,aAAaE;YAC3BC,MAAMT,OAAOM,aAAaG;YAC1BJ,YAAYL,OAAOM,aAAaD;QAClC;kBAEA,cAAA,KAACP;YACCY,kBAAkB;gBAChBF,OAAOR,OAAOM,aAAaE;gBAC3BC,MAAMT,OAAOM,aAAaG;gBAC1BJ,YAAYL,OAAOM,aAAaD;gBAChC,GAAGL,OAAOM,WAAW;YACvB;YACAJ,eAAeA;YACfE,iBAAiBA;;;AAIzB,EAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FieldProvider } from '../../providers/FieldProvider/FieldProvider.js';
|
|
3
|
+
import { useInstructions } from '../../providers/InstructionsProvider/useInstructions.js';
|
|
4
|
+
import { Compose } from '../../ui/Compose/Compose.js';
|
|
5
|
+
export const ComposeFeatureComponent = (props) => {
|
|
6
|
+
const { id: instructionId, disabled, isConfigAllowed, } = useInstructions({
|
|
7
|
+
schemaPath: props?.clientProps?.schemaPath,
|
|
8
|
+
});
|
|
9
|
+
if (!instructionId || disabled) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
return (<FieldProvider context={{
|
|
13
|
+
field: props?.clientProps?.field,
|
|
14
|
+
path: props?.clientProps?.path,
|
|
15
|
+
schemaPath: props?.clientProps?.schemaPath,
|
|
16
|
+
}}>
|
|
17
|
+
<Compose descriptionProps={{
|
|
18
|
+
field: props?.clientProps?.field,
|
|
19
|
+
path: props?.clientProps?.path,
|
|
20
|
+
schemaPath: props?.clientProps?.schemaPath,
|
|
21
|
+
...props?.clientProps,
|
|
22
|
+
}} instructionId={instructionId} isConfigAllowed={isConfigAllowed}/>
|
|
23
|
+
</FieldProvider>);
|
|
24
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { createClientFeature } from '@payloadcms/richtext-lexical/client';
|
|
3
|
+
import { TextNode } from 'lexical';
|
|
4
|
+
import { ComposeFeatureComponent } from './ComposeFeatureComponent.js';
|
|
5
|
+
export const LexicalEditorFeatureClient = createClientFeature((props) => {
|
|
6
|
+
return {
|
|
7
|
+
nodes: [TextNode],
|
|
8
|
+
plugins: [
|
|
9
|
+
{
|
|
10
|
+
Component: ComposeFeatureComponent,
|
|
11
|
+
position: 'belowContainer',
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
sanitizedClientFeatureProps: {
|
|
15
|
+
field: props.field,
|
|
16
|
+
path: props.field?.name,
|
|
17
|
+
schemaPath: props.schemaPath,
|
|
18
|
+
...props?.props,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { FieldDescription, FieldLabel, useField } from '@payloadcms/ui';
|
|
3
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { Mention, MentionsInput } from 'react-mentions/dist/react-mentions.cjs.js';
|
|
5
|
+
import { useInstructions } from '../../providers/InstructionsProvider/useInstructions.js';
|
|
6
|
+
import { defaultStyle } from './defaultStyle.js';
|
|
7
|
+
export const PromptEditorField = (props) => {
|
|
8
|
+
const { field, path: pathFromContext } = props;
|
|
9
|
+
const { setValue, value: payloadValue } = useField({
|
|
10
|
+
path: pathFromContext,
|
|
11
|
+
});
|
|
12
|
+
const [localValue, setLocalValue] = useState(payloadValue || '');
|
|
13
|
+
const hasInitialized = useRef(false);
|
|
14
|
+
const { promptEditorSuggestions } = useInstructions();
|
|
15
|
+
const suggestions = useMemo(() => promptEditorSuggestions.map((suggestion) => ({
|
|
16
|
+
id: suggestion,
|
|
17
|
+
display: suggestion,
|
|
18
|
+
})), [promptEditorSuggestions]);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (!hasInitialized.current || payloadValue === '') {
|
|
21
|
+
setLocalValue(payloadValue || '');
|
|
22
|
+
hasInitialized.current = true;
|
|
23
|
+
}
|
|
24
|
+
}, [payloadValue]);
|
|
25
|
+
const handleChange = useCallback((e) => {
|
|
26
|
+
setLocalValue(e.target.value);
|
|
27
|
+
}, []);
|
|
28
|
+
const handleBlur = useCallback(() => {
|
|
29
|
+
setValue(localValue);
|
|
30
|
+
}, [localValue, setValue]);
|
|
31
|
+
const displayTransform = useCallback((id) => `{{ ${id} }}`, []);
|
|
32
|
+
return (<div className="field-type textarea">
|
|
33
|
+
<FieldLabel label={field.label}/>
|
|
34
|
+
<MentionsInput onBlur={handleBlur} onChange={handleChange} placeholder="Type your prompt using {{ fieldName }} variables..." style={defaultStyle} value={localValue}>
|
|
35
|
+
<Mention data={suggestions} displayTransform={displayTransform} markup="{{__id__}}" style={{
|
|
36
|
+
backgroundColor: 'var(--theme-elevation-100)',
|
|
37
|
+
padding: '2px 0',
|
|
38
|
+
}} trigger="{"/>
|
|
39
|
+
</MentionsInput>
|
|
40
|
+
<FieldDescription description={field?.admin?.description} path=""/>
|
|
41
|
+
</div>);
|
|
42
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { SelectInput, useField } from '@payloadcms/ui';
|
|
3
|
+
import React, { useEffect, useState } from 'react';
|
|
4
|
+
// Use to filter model options in settings based on field types
|
|
5
|
+
export const SelectField = (props) => {
|
|
6
|
+
const { field, filterByField, options, path } = props;
|
|
7
|
+
const { value: relatedField } = useField({
|
|
8
|
+
path: filterByField,
|
|
9
|
+
});
|
|
10
|
+
const [filterOptions, setFilterOptions] = useState([]);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!Array.isArray(options)) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const opts = options.filter((option) => {
|
|
16
|
+
if (!relatedField || !option.fields) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (Array.isArray(option.fields)) {
|
|
20
|
+
return option.fields.includes(relatedField);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
setFilterOptions(opts);
|
|
24
|
+
}, [relatedField, options]);
|
|
25
|
+
const { setValue, value: selectValue } = useField({ path });
|
|
26
|
+
return (<SelectInput label={field.label} name={path} onChange={(value) => {
|
|
27
|
+
console.log("value --- ", value);
|
|
28
|
+
if (Array.isArray(value)) {
|
|
29
|
+
setValue(value[0]?.value ?? '');
|
|
30
|
+
}
|
|
31
|
+
else if (value && typeof value === 'object' && 'value' in value) {
|
|
32
|
+
setValue(value.value);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
setValue('');
|
|
36
|
+
}
|
|
37
|
+
}} options={filterOptions} path={path} value={selectValue}/>);
|
|
38
|
+
};
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
import type { ClientField } from 'payload';
|
|
1
2
|
import React from 'react';
|
|
2
|
-
|
|
3
|
+
type FieldContextType = {
|
|
4
|
+
field?: ClientField;
|
|
3
5
|
path?: string;
|
|
4
6
|
schemaPath?: string;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
};
|
|
8
|
+
export declare const FieldContext: React.Context<FieldContextType>;
|
|
7
9
|
export declare const FieldProvider: ({ children, context, }: {
|
|
8
10
|
children: React.ReactNode;
|
|
9
11
|
context: {
|
|
12
|
+
field?: ClientField;
|
|
10
13
|
path: string;
|
|
11
14
|
schemaPath: unknown;
|
|
12
|
-
type: unknown;
|
|
13
15
|
};
|
|
14
16
|
}) => React.JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React, { createContext, useEffect } from 'react';
|
|
3
3
|
const initialContext = {
|
|
4
|
-
|
|
4
|
+
field: undefined,
|
|
5
5
|
path: '',
|
|
6
6
|
schemaPath: ''
|
|
7
7
|
};
|
|
8
8
|
export const FieldContext = /*#__PURE__*/ createContext(initialContext);
|
|
9
9
|
export const FieldProvider = ({ children, context })=>{
|
|
10
|
-
const [
|
|
10
|
+
const [field, setField] = React.useState();
|
|
11
11
|
const [path, setPath] = React.useState();
|
|
12
12
|
const [schemaPath, setSchemaPath] = React.useState();
|
|
13
13
|
useEffect(()=>{
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const nextSchemaPath = String(context.schemaPath ?? '');
|
|
15
|
+
if (schemaPath !== nextSchemaPath) {
|
|
16
|
+
setField(context.field);
|
|
16
17
|
setPath(context.path);
|
|
17
|
-
setSchemaPath(
|
|
18
|
+
setSchemaPath(nextSchemaPath);
|
|
18
19
|
}
|
|
19
20
|
}, [
|
|
20
21
|
schemaPath,
|
|
@@ -22,7 +23,7 @@ export const FieldProvider = ({ children, context })=>{
|
|
|
22
23
|
]);
|
|
23
24
|
return /*#__PURE__*/ _jsx(FieldContext.Provider, {
|
|
24
25
|
value: {
|
|
25
|
-
|
|
26
|
+
field,
|
|
26
27
|
path,
|
|
27
28
|
schemaPath
|
|
28
29
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/providers/FieldProvider/FieldProvider.tsx"],"sourcesContent":["import React, { createContext, useEffect } from 'react'\n\
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/FieldProvider/FieldProvider.tsx"],"sourcesContent":["import type { ClientField } from 'payload'\n\nimport React, { createContext, useEffect } from 'react'\n\ntype FieldContextType = {\n field?: ClientField\n path?: string\n schemaPath?: string\n}\n\nconst initialContext: FieldContextType = {\n field: undefined,\n path: '',\n schemaPath: '',\n}\n\nexport const FieldContext = createContext<FieldContextType>(initialContext)\n\nexport const FieldProvider = ({\n children,\n context,\n}: {\n children: React.ReactNode\n context: {\n field?: ClientField\n path: string\n schemaPath: unknown\n }\n}) => {\n const [field, setField] = React.useState<ClientField | undefined>()\n const [path, setPath] = React.useState<string>()\n const [schemaPath, setSchemaPath] = React.useState<string>()\n\n useEffect(() => {\n const nextSchemaPath = String(context.schemaPath ?? '')\n if (schemaPath !== nextSchemaPath) {\n setField(context.field)\n setPath(context.path)\n setSchemaPath(nextSchemaPath)\n }\n }, [schemaPath, context])\n\n return (\n <FieldContext.Provider\n value={{\n field,\n path,\n schemaPath,\n }}\n >\n {children}\n </FieldContext.Provider>\n )\n}\n"],"names":["React","createContext","useEffect","initialContext","field","undefined","path","schemaPath","FieldContext","FieldProvider","children","context","setField","useState","setPath","setSchemaPath","nextSchemaPath","String","Provider","value"],"mappings":";AAEA,OAAOA,SAASC,aAAa,EAAEC,SAAS,QAAQ,QAAO;AAQvD,MAAMC,iBAAmC;IACvCC,OAAOC;IACPC,MAAM;IACNC,YAAY;AACd;AAEA,OAAO,MAAMC,6BAAeP,cAAgCE,gBAAe;AAE3E,OAAO,MAAMM,gBAAgB,CAAC,EAC5BC,QAAQ,EACRC,OAAO,EAQR;IACC,MAAM,CAACP,OAAOQ,SAAS,GAAGZ,MAAMa,QAAQ;IACxC,MAAM,CAACP,MAAMQ,QAAQ,GAAGd,MAAMa,QAAQ;IACtC,MAAM,CAACN,YAAYQ,cAAc,GAAGf,MAAMa,QAAQ;IAElDX,UAAU;QACR,MAAMc,iBAAiBC,OAAON,QAAQJ,UAAU,IAAI;QACpD,IAAIA,eAAeS,gBAAgB;YACjCJ,SAASD,QAAQP,KAAK;YACtBU,QAAQH,QAAQL,IAAI;YACpBS,cAAcC;QAChB;IACF,GAAG;QAACT;QAAYI;KAAQ;IAExB,qBACE,KAACH,aAAaU,QAAQ;QACpBC,OAAO;YACLf;YACAE;YACAC;QACF;kBAECG;;AAGP,EAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React, { createContext, useEffect } from 'react';
|
|
2
|
+
const initialContext = {
|
|
3
|
+
field: undefined,
|
|
4
|
+
path: '',
|
|
5
|
+
schemaPath: '',
|
|
6
|
+
};
|
|
7
|
+
export const FieldContext = createContext(initialContext);
|
|
8
|
+
export const FieldProvider = ({ children, context, }) => {
|
|
9
|
+
const [field, setField] = React.useState();
|
|
10
|
+
const [path, setPath] = React.useState();
|
|
11
|
+
const [schemaPath, setSchemaPath] = React.useState();
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const nextSchemaPath = String(context.schemaPath ?? '');
|
|
14
|
+
if (schemaPath !== nextSchemaPath) {
|
|
15
|
+
setField(context.field);
|
|
16
|
+
setPath(context.path);
|
|
17
|
+
setSchemaPath(nextSchemaPath);
|
|
18
|
+
}
|
|
19
|
+
}, [schemaPath, context]);
|
|
20
|
+
return (<FieldContext.Provider value={{
|
|
21
|
+
field,
|
|
22
|
+
path,
|
|
23
|
+
schemaPath,
|
|
24
|
+
}}>
|
|
25
|
+
{children}
|
|
26
|
+
</FieldContext.Provider>);
|
|
27
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useContext } from 'react';
|
|
2
2
|
import { FieldContext } from './FieldProvider.js';
|
|
3
3
|
export const useFieldProps = ()=>{
|
|
4
|
-
const {
|
|
4
|
+
const { field, path, schemaPath } = useContext(FieldContext);
|
|
5
5
|
return {
|
|
6
|
-
|
|
6
|
+
field,
|
|
7
7
|
path,
|
|
8
8
|
schemaPath
|
|
9
9
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/providers/FieldProvider/useFieldProps.ts"],"sourcesContent":["import { useContext } from 'react'\n\nimport { FieldContext } from './FieldProvider.js'\n\nexport const useFieldProps = () => {\n const {
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/FieldProvider/useFieldProps.ts"],"sourcesContent":["import { useContext } from 'react'\n\nimport { FieldContext } from './FieldProvider.js'\n\nexport const useFieldProps = () => {\n const { field, path, schemaPath } = useContext(FieldContext)\n\n return {\n field,\n path,\n schemaPath,\n }\n}\n"],"names":["useContext","FieldContext","useFieldProps","field","path","schemaPath"],"mappings":"AAAA,SAASA,UAAU,QAAQ,QAAO;AAElC,SAASC,YAAY,QAAQ,qBAAoB;AAEjD,OAAO,MAAMC,gBAAgB;IAC3B,MAAM,EAAEC,KAAK,EAAEC,IAAI,EAAEC,UAAU,EAAE,GAAGL,WAAWC;IAE/C,OAAO;QACLE;QACAC;QACAC;IACF;AACF,EAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useAuth, useConfig } from '@payloadcms/ui';
|
|
3
|
+
import React, { useEffect, useState } from 'react';
|
|
4
|
+
import { PLUGIN_FETCH_FIELDS_ENDPOINT } from '../../defaults.js';
|
|
5
|
+
import { InstructionsContext } from './context.js';
|
|
6
|
+
export const InstructionsProvider = ({ children }) => {
|
|
7
|
+
const [instructions, setInstructionsState] = useState({});
|
|
8
|
+
const [promptFields, setPromptFields] = useState([]);
|
|
9
|
+
const [activeCollection, setActiveCollection] = useState('');
|
|
10
|
+
const [isConfigAllowed, setIsConfigAllowed] = useState(false);
|
|
11
|
+
const [enabledLanguages, setEnabledLanguages] = useState();
|
|
12
|
+
const [debugging, setDebugging] = useState(false);
|
|
13
|
+
const { user } = useAuth();
|
|
14
|
+
const { config } = useConfig();
|
|
15
|
+
const { routes: { api }, serverURL, } = config;
|
|
16
|
+
// This is here because each field have separate instructions and
|
|
17
|
+
// their ID is needed to edit them for Drawer
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
fetch(`${serverURL}${api}${PLUGIN_FETCH_FIELDS_ENDPOINT}`)
|
|
20
|
+
.then(async (res) => {
|
|
21
|
+
await res.json().then((data) => {
|
|
22
|
+
setIsConfigAllowed(data?.isConfigAllowed || false);
|
|
23
|
+
setEnabledLanguages(data?.enabledLanguages || []);
|
|
24
|
+
setInstructionsState(data?.fields || {});
|
|
25
|
+
setPromptFields(data?.promptFields || []);
|
|
26
|
+
setDebugging(data?.debugging || false);
|
|
27
|
+
});
|
|
28
|
+
})
|
|
29
|
+
.catch((err) => {
|
|
30
|
+
console.error('InstructionsProvider:', err);
|
|
31
|
+
});
|
|
32
|
+
}, [api, serverURL, user]);
|
|
33
|
+
return (<InstructionsContext.Provider value={{
|
|
34
|
+
activeCollection,
|
|
35
|
+
debugging,
|
|
36
|
+
enabledLanguages,
|
|
37
|
+
hasInstructions: instructions && Object.keys(instructions).length > 0,
|
|
38
|
+
instructions,
|
|
39
|
+
isConfigAllowed,
|
|
40
|
+
promptFields,
|
|
41
|
+
setActiveCollection,
|
|
42
|
+
}}>
|
|
43
|
+
{children}
|
|
44
|
+
</InstructionsContext.Provider>);
|
|
45
|
+
};
|
package/dist/types.d.ts
CHANGED
|
@@ -10,14 +10,14 @@ export interface PluginConfigAccess {
|
|
|
10
10
|
*/
|
|
11
11
|
generate?: ({ req }: {
|
|
12
12
|
req: PayloadRequest;
|
|
13
|
-
}) =>
|
|
13
|
+
}) => boolean | Promise<boolean>;
|
|
14
14
|
/**
|
|
15
15
|
* Control access to AI settings/configuration
|
|
16
16
|
* @default () => !!req.user (requires authentication)
|
|
17
17
|
*/
|
|
18
18
|
settings?: ({ req }: {
|
|
19
19
|
req: PayloadRequest;
|
|
20
|
-
}) =>
|
|
20
|
+
}) => boolean | Promise<boolean>;
|
|
21
21
|
}
|
|
22
22
|
export interface PluginOptions {
|
|
23
23
|
/**
|
|
@@ -120,10 +120,10 @@ export type SeedPromptOptions = {
|
|
|
120
120
|
export type SeedPromptData = Omit<TypedCollection[typeof PLUGIN_INSTRUCTIONS_TABLE], 'createdAt' | 'id' | 'updatedAt'>;
|
|
121
121
|
export type SeedPromptResult = {
|
|
122
122
|
data?: SeedPromptData;
|
|
123
|
-
prompt: string;
|
|
124
|
-
system: string;
|
|
125
123
|
} | {
|
|
126
124
|
data?: SeedPromptData;
|
|
125
|
+
prompt: string;
|
|
126
|
+
system: string;
|
|
127
127
|
} | false | undefined | void;
|
|
128
128
|
export type SeedPromptFunction = (options: SeedPromptOptions) => Promise<SeedPromptResult> | SeedPromptResult;
|
|
129
129
|
export type ActionMenuEvents = 'onCompose' | 'onExpand' | 'onProofread' | 'onRephrase' | 'onSettings' | 'onSimplify' | 'onSummarize' | 'onTone' | 'onTranslate';
|
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 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 }) =>
|
|
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 }) => boolean | Promise<boolean>\n /**\n * Control access to AI settings/configuration\n * @default () => !!req.user (requires authentication)\n */\n settings?: ({ req }: { req: PayloadRequest }) => boolean | Promise<boolean>\n}\n\nexport interface PluginOptions {\n /**\n * Provide local tags to filter language options from the Translate Menu\n * Check for the available local tags,\n * visit: https://www.npmjs.com/package/locale-codes\n * Example: [\"en-US\", \"zh-SG\", \"zh-CN\", \"en\"]\n */\n enabledLanguages?: string[]\n}\n\nexport type PluginConfigMediaUploadFunction = (\n result: { 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} | {\n data?: SeedPromptData\n prompt: string\n system: string\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"}
|