@ai-stack/payloadcms 3.2.24 → 3.68.0-beta.1
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/{LICENSE.md → LICENSE} +1 -1
- package/README.md +218 -229
- package/dist/access/checkAccess.d.ts +4 -0
- package/dist/access/checkAccess.js +20 -0
- package/dist/access/checkAccess.js.map +1 -0
- package/dist/ai/core/generateObject.d.ts +7 -0
- package/dist/ai/core/generateObject.js +35 -0
- package/dist/ai/core/generateObject.js.map +1 -0
- package/dist/ai/core/generateText.d.ts +7 -0
- package/dist/ai/core/generateText.js +31 -0
- package/dist/ai/core/generateText.js.map +1 -0
- package/dist/ai/core/index.d.ts +11 -0
- package/dist/ai/core/index.js +10 -0
- package/dist/ai/core/index.js.map +1 -0
- package/dist/ai/core/media/generateMedia.d.ts +7 -0
- package/dist/ai/core/media/generateMedia.js +50 -0
- package/dist/ai/core/media/generateMedia.js.map +1 -0
- package/dist/ai/core/media/image/generateImage.d.ts +6 -0
- package/dist/ai/core/media/image/generateImage.js +41 -0
- package/dist/ai/core/media/image/generateImage.js.map +1 -0
- package/dist/ai/core/media/image/handlers/multimodal.d.ts +7 -0
- package/dist/ai/core/media/image/handlers/multimodal.js +95 -0
- package/dist/ai/core/media/image/handlers/multimodal.js.map +1 -0
- package/dist/ai/core/media/image/handlers/standard.d.ts +7 -0
- package/dist/ai/core/media/image/handlers/standard.js +28 -0
- package/dist/ai/core/media/image/handlers/standard.js.map +1 -0
- package/dist/ai/core/media/image/index.d.ts +2 -0
- package/dist/ai/core/media/image/index.js +3 -0
- package/dist/ai/core/media/image/index.js.map +1 -0
- package/dist/ai/core/media/index.d.ts +2 -0
- package/dist/ai/core/media/index.js +3 -0
- package/dist/ai/core/media/index.js.map +1 -0
- package/dist/ai/core/media/speech/generateSpeech.d.ts +5 -0
- package/dist/ai/core/media/speech/generateSpeech.js +55 -0
- package/dist/ai/core/media/speech/generateSpeech.js.map +1 -0
- package/dist/ai/core/media/speech/index.d.ts +2 -0
- package/dist/ai/core/media/speech/index.js +3 -0
- package/dist/ai/core/media/speech/index.js.map +1 -0
- package/dist/ai/core/media/types.d.ts +74 -0
- package/dist/ai/core/media/types.js +5 -0
- package/dist/ai/core/media/types.js.map +1 -0
- package/dist/ai/core/media/utils.d.ts +11 -0
- package/dist/ai/core/media/utils.js +34 -0
- package/dist/ai/core/media/utils.js.map +1 -0
- package/dist/ai/core/media/video/generateVideo.d.ts +6 -0
- package/dist/ai/core/media/video/generateVideo.js +32 -0
- package/dist/ai/core/media/video/generateVideo.js.map +1 -0
- package/dist/ai/core/media/video/index.d.ts +2 -0
- package/dist/ai/core/media/video/index.js +3 -0
- package/dist/ai/core/media/video/index.js.map +1 -0
- package/dist/ai/core/streamObject.d.ts +7 -0
- package/dist/ai/core/streamObject.js +57 -0
- package/dist/ai/core/streamObject.js.map +1 -0
- package/dist/ai/core/streamText.d.ts +7 -0
- package/dist/ai/core/streamText.js +30 -0
- package/dist/ai/core/streamText.js.map +1 -0
- package/dist/ai/core/types.d.ts +85 -0
- package/dist/ai/core/types.js +5 -0
- package/dist/ai/core/types.js.map +1 -0
- package/dist/ai/index.d.ts +11 -0
- package/dist/ai/index.js +25 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/providers/blocks/anthropic.d.ts +2 -0
- package/dist/ai/providers/blocks/anthropic.js +222 -0
- package/dist/ai/providers/blocks/anthropic.js.map +1 -0
- package/dist/ai/providers/blocks/elevenlabs.d.ts +2 -0
- package/dist/ai/providers/blocks/elevenlabs.js +448 -0
- package/dist/ai/providers/blocks/elevenlabs.js.map +1 -0
- package/dist/ai/providers/blocks/fal.d.ts +2 -0
- package/dist/ai/providers/blocks/fal.js +311 -0
- package/dist/ai/providers/blocks/fal.js.map +1 -0
- package/dist/ai/providers/blocks/google.d.ts +2 -0
- package/dist/ai/providers/blocks/google.js +622 -0
- package/dist/ai/providers/blocks/google.js.map +1 -0
- package/dist/ai/providers/blocks/index.d.ts +2 -0
- package/dist/ai/providers/blocks/index.js +18 -0
- package/dist/ai/providers/blocks/index.js.map +1 -0
- package/dist/ai/providers/blocks/openai-compatible.d.ts +2 -0
- package/dist/ai/providers/blocks/openai-compatible.js +307 -0
- package/dist/ai/providers/blocks/openai-compatible.js.map +1 -0
- package/dist/ai/providers/blocks/openai.d.ts +2 -0
- package/dist/ai/providers/blocks/openai.js +599 -0
- package/dist/ai/providers/blocks/openai.js.map +1 -0
- package/dist/ai/providers/blocks/xai.d.ts +2 -0
- package/dist/ai/providers/blocks/xai.js +246 -0
- package/dist/ai/providers/blocks/xai.js.map +1 -0
- package/dist/ai/providers/index.d.ts +2 -0
- package/dist/ai/providers/index.js +6 -0
- package/dist/ai/providers/index.js.map +1 -0
- package/dist/ai/providers/registry.d.ts +40 -0
- package/dist/ai/providers/registry.js +256 -0
- package/dist/ai/providers/registry.js.map +1 -0
- package/dist/ai/providers/types.d.ts +115 -0
- package/dist/ai/providers/types.js +4 -0
- package/dist/ai/providers/types.js.map +1 -0
- package/dist/ai/utils/systemGenerate.d.ts +1 -1
- package/dist/ai/utils/systemGenerate.js +19 -19
- package/dist/ai/utils/systemGenerate.js.map +1 -1
- package/dist/collections/AIJobs.d.ts +2 -0
- package/dist/collections/AIJobs.js +81 -0
- package/dist/collections/AIJobs.js.map +1 -0
- package/dist/collections/AISettings.d.ts +2 -0
- package/dist/collections/AISettings.js +279 -0
- package/dist/collections/AISettings.js.map +1 -0
- package/dist/collections/Instructions.js +185 -37
- package/dist/collections/Instructions.js.map +1 -1
- package/dist/defaults.d.ts +3 -0
- package/dist/defaults.js +3 -0
- package/dist/defaults.js.map +1 -1
- package/dist/endpoints/buildPromptUtils.d.ts +19 -0
- package/dist/endpoints/buildPromptUtils.js +114 -0
- package/dist/endpoints/buildPromptUtils.js.map +1 -0
- package/dist/endpoints/chat.d.js +3 -0
- package/dist/endpoints/chat.d.js.map +1 -0
- package/dist/endpoints/fetchVoices.d.ts +2 -0
- package/dist/endpoints/fetchVoices.js +79 -0
- package/dist/endpoints/fetchVoices.js.map +1 -0
- package/dist/endpoints/index.js +253 -214
- package/dist/endpoints/index.js.map +1 -1
- package/dist/exports/client.d.ts +9 -0
- package/dist/exports/client.js +9 -0
- package/dist/exports/client.js.map +1 -1
- package/dist/fields/ComposeField/ComposeField.js +2 -2
- package/dist/fields/ComposeField/ComposeField.js.map +1 -1
- package/dist/fields/ComposeField/ComposeField.jsx +2 -2
- package/dist/fields/PromptEditorField/PromptEditorField.js +155 -14
- package/dist/fields/PromptEditorField/PromptEditorField.js.map +1 -1
- package/dist/fields/PromptEditorField/PromptEditorField.jsx +118 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js.map +1 -1
- package/dist/init.js +35 -13
- package/dist/init.js.map +1 -1
- package/dist/payload-ai.d.js +3 -0
- package/dist/payload-ai.d.js.map +1 -0
- package/dist/plugin.js +80 -9
- package/dist/plugin.js.map +1 -1
- package/dist/providers/InstructionsProvider/InstructionsProvider.js +35 -7
- package/dist/providers/InstructionsProvider/InstructionsProvider.js.map +1 -1
- package/dist/providers/InstructionsProvider/InstructionsProvider.jsx +27 -4
- package/dist/providers/InstructionsProvider/context.d.ts +1 -0
- package/dist/providers/InstructionsProvider/context.js +1 -0
- package/dist/providers/InstructionsProvider/context.js.map +1 -1
- package/dist/providers/InstructionsProvider/useInstructions.js +13 -6
- package/dist/providers/InstructionsProvider/useInstructions.js.map +1 -1
- package/dist/types.d.ts +7 -7
- package/dist/types.js.map +1 -1
- package/dist/ui/AIConfigDashboard/index.d.ts +2 -0
- package/dist/ui/AIConfigDashboard/index.js +46 -0
- package/dist/ui/AIConfigDashboard/index.js.map +1 -0
- package/dist/ui/AIConfigDashboard/index.jsx +24 -0
- package/dist/ui/ApiKeyStatusIndicator/index.d.ts +6 -0
- package/dist/ui/ApiKeyStatusIndicator/index.js +39 -0
- package/dist/ui/ApiKeyStatusIndicator/index.js.map +1 -0
- package/dist/ui/ApiKeyStatusIndicator/index.jsx +29 -0
- package/dist/ui/Compose/Compose.d.ts +1 -2
- package/dist/ui/Compose/Compose.js +116 -90
- package/dist/ui/Compose/Compose.js.map +1 -1
- package/dist/ui/Compose/Compose.jsx +111 -101
- package/dist/ui/Compose/ComposePlaceholder.d.ts +7 -0
- package/dist/ui/Compose/ComposePlaceholder.js +78 -0
- package/dist/ui/Compose/ComposePlaceholder.js.map +1 -0
- package/dist/ui/Compose/ComposePlaceholder.jsx +66 -0
- package/dist/ui/Compose/UndoRedoActions.js +3 -1
- package/dist/ui/Compose/UndoRedoActions.js.map +1 -1
- package/dist/ui/Compose/UndoRedoActions.jsx +2 -1
- package/dist/ui/Compose/compose.module.css +1 -1
- package/dist/ui/Compose/hooks/menu/itemsMap.js +1 -1
- package/dist/ui/Compose/hooks/menu/itemsMap.js.map +1 -1
- package/dist/ui/Compose/hooks/menu/useMenu.d.ts +2 -1
- package/dist/ui/Compose/hooks/menu/useMenu.js +2 -2
- package/dist/ui/Compose/hooks/menu/useMenu.js.map +1 -1
- package/dist/ui/Compose/hooks/menu/useMenu.jsx +2 -2
- package/dist/ui/Compose/hooks/useActiveFieldTracking.js +69 -10
- package/dist/ui/Compose/hooks/useActiveFieldTracking.js.map +1 -1
- package/dist/ui/Compose/hooks/useGenerate.d.ts +3 -0
- package/dist/ui/Compose/hooks/useGenerate.js +71 -11
- package/dist/ui/Compose/hooks/useGenerate.js.map +1 -1
- package/dist/ui/Compose/hooks/useHistory.js +52 -5
- package/dist/ui/Compose/hooks/useHistory.js.map +1 -1
- package/dist/ui/DynamicModelSelect/index.d.ts +7 -0
- package/dist/ui/DynamicModelSelect/index.js +231 -0
- package/dist/ui/DynamicModelSelect/index.js.map +1 -0
- package/dist/ui/DynamicModelSelect/index.jsx +207 -0
- package/dist/ui/DynamicProviderSelect/index.d.ts +7 -0
- package/dist/ui/DynamicProviderSelect/index.js +101 -0
- package/dist/ui/DynamicProviderSelect/index.js.map +1 -0
- package/dist/ui/DynamicProviderSelect/index.jsx +90 -0
- package/dist/ui/DynamicVoiceSelect/index.d.ts +7 -0
- package/dist/ui/DynamicVoiceSelect/index.js +104 -0
- package/dist/ui/DynamicVoiceSelect/index.js.map +1 -0
- package/dist/ui/DynamicVoiceSelect/index.jsx +69 -0
- package/dist/ui/EncryptedTextField/index.d.ts +8 -0
- package/dist/ui/EncryptedTextField/index.js +74 -0
- package/dist/ui/EncryptedTextField/index.js.map +1 -0
- package/dist/ui/EncryptedTextField/index.jsx +35 -0
- package/dist/ui/Icons/LottieAnimation.js +3 -1
- package/dist/ui/Icons/LottieAnimation.js.map +1 -1
- package/dist/ui/Icons/LottieAnimation.jsx +2 -1
- package/dist/ui/ModelRowLabel/index.d.ts +6 -0
- package/dist/ui/ModelRowLabel/index.js +41 -0
- package/dist/ui/ModelRowLabel/index.js.map +1 -0
- package/dist/ui/ModelRowLabel/index.jsx +26 -0
- package/dist/ui/ProviderOptionsEditor/index.d.ts +7 -0
- package/dist/ui/ProviderOptionsEditor/index.js +291 -0
- package/dist/ui/ProviderOptionsEditor/index.js.map +1 -0
- package/dist/ui/ProviderOptionsEditor/index.jsx +210 -0
- package/dist/ui/VoicesFetcher/index.d.ts +7 -0
- package/dist/ui/VoicesFetcher/index.js +72 -0
- package/dist/ui/VoicesFetcher/index.js.map +1 -0
- package/dist/ui/VoicesFetcher/index.jsx +56 -0
- package/dist/utilities/encryption.d.ts +2 -0
- package/dist/utilities/encryption.js +47 -0
- package/dist/utilities/encryption.js.map +1 -0
- package/dist/utilities/extractImageData.d.ts +9 -0
- package/dist/utilities/extractImageData.js +12 -2
- package/dist/utilities/extractImageData.js.map +1 -1
- package/dist/utilities/fetchImages.d.ts +14 -0
- package/dist/utilities/fetchImages.js +38 -0
- package/dist/utilities/fetchImages.js.map +1 -0
- package/dist/utilities/fieldToJsonSchema.d.ts +2 -1
- package/dist/utilities/fieldToJsonSchema.js +66 -3
- package/dist/utilities/fieldToJsonSchema.js.map +1 -1
- package/dist/utilities/getFieldBySchemaPath.js +15 -0
- package/dist/utilities/getFieldBySchemaPath.js.map +1 -1
- package/dist/utilities/getProviderOptionsFields.d.ts +16 -0
- package/dist/utilities/getProviderOptionsFields.js +80 -0
- package/dist/utilities/getProviderOptionsFields.js.map +1 -0
- package/dist/utilities/isPluginActivated.js +1 -2
- package/dist/utilities/isPluginActivated.js.map +1 -1
- package/dist/utilities/lexicalToHTML.js.map +1 -1
- package/dist/utilities/resolveImageReferences.d.ts +28 -0
- package/dist/utilities/resolveImageReferences.js +148 -0
- package/dist/utilities/resolveImageReferences.js.map +1 -0
- package/dist/utilities/schemaConverter.d.ts +3 -0
- package/dist/utilities/schemaConverter.js +93 -0
- package/dist/utilities/schemaConverter.js.map +1 -0
- package/dist/utilities/setSafeLexicalState.d.ts +1 -3
- package/dist/utilities/setSafeLexicalState.js +1 -1
- package/dist/utilities/setSafeLexicalState.js.map +1 -1
- package/package.json +38 -39
- package/dist/ai/models/anthropic/index.d.ts +0 -2
- package/dist/ai/models/anthropic/index.js +0 -129
- package/dist/ai/models/anthropic/index.js.map +0 -1
- package/dist/ai/models/elevenLabs/generateVoice.d.ts +0 -8
- package/dist/ai/models/elevenLabs/generateVoice.js +0 -20
- package/dist/ai/models/elevenLabs/generateVoice.js.map +0 -1
- package/dist/ai/models/elevenLabs/index.d.ts +0 -2
- package/dist/ai/models/elevenLabs/index.js +0 -133
- package/dist/ai/models/elevenLabs/index.js.map +0 -1
- package/dist/ai/models/elevenLabs/voices.d.ts +0 -8
- package/dist/ai/models/elevenLabs/voices.js +0 -24
- package/dist/ai/models/elevenLabs/voices.js.map +0 -1
- package/dist/ai/models/generateObject.d.ts +0 -11
- package/dist/ai/models/generateObject.js +0 -22
- package/dist/ai/models/generateObject.js.map +0 -1
- package/dist/ai/models/google/generateImage.d.ts +0 -9
- package/dist/ai/models/google/generateImage.js +0 -27
- package/dist/ai/models/google/generateImage.js.map +0 -1
- package/dist/ai/models/google/index.d.ts +0 -2
- package/dist/ai/models/google/index.js +0 -201
- package/dist/ai/models/google/index.js.map +0 -1
- package/dist/ai/models/index.d.ts +0 -2
- package/dist/ai/models/index.js +0 -13
- package/dist/ai/models/index.js.map +0 -1
- package/dist/ai/models/openai/generateImage.d.ts +0 -5
- package/dist/ai/models/openai/generateImage.js +0 -31
- package/dist/ai/models/openai/generateImage.js.map +0 -1
- package/dist/ai/models/openai/generateVoice.d.ts +0 -6
- package/dist/ai/models/openai/generateVoice.js +0 -19
- package/dist/ai/models/openai/generateVoice.js.map +0 -1
- package/dist/ai/models/openai/index.d.ts +0 -2
- package/dist/ai/models/openai/index.js +0 -428
- package/dist/ai/models/openai/index.js.map +0 -1
- package/dist/ai/models/openai/openai.d.ts +0 -1
- package/dist/ai/models/openai/openai.js +0 -8
- package/dist/ai/models/openai/openai.js.map +0 -1
- package/dist/ai/utils/editImagesWithOpenAI.d.ts +0 -10
- package/dist/ai/utils/editImagesWithOpenAI.js +0 -37
- package/dist/ai/utils/editImagesWithOpenAI.js.map +0 -1
- package/dist/types.d.js +0 -3
- package/dist/types.d.js.map +0 -1
- package/dist/utilities/getGenerationModels.d.ts +0 -2
- package/dist/utilities/getGenerationModels.js +0 -10
- package/dist/utilities/getGenerationModels.js.map +0 -1
package/dist/endpoints/index.js
CHANGED
|
@@ -1,144 +1,18 @@
|
|
|
1
1
|
import * as process from 'node:process';
|
|
2
|
-
import {
|
|
2
|
+
import { checkAccess } from '../access/checkAccess.js';
|
|
3
3
|
import { filterEditorSchemaByNodes } from '../ai/utils/filterEditorSchemaByNodes.js';
|
|
4
|
-
import { PLUGIN_API_ENDPOINT_GENERATE, PLUGIN_API_ENDPOINT_GENERATE_UPLOAD, PLUGIN_INSTRUCTIONS_TABLE, PLUGIN_NAME } from '../defaults.js';
|
|
5
|
-
import { asyncHandlebars } from '../libraries/handlebars/asyncHandlebars.js';
|
|
4
|
+
import { PLUGIN_AI_JOBS_TABLE, PLUGIN_API_ENDPOINT_GENERATE, PLUGIN_API_ENDPOINT_GENERATE_UPLOAD, PLUGIN_API_ENDPOINT_VIDEOGEN_WEBHOOK, PLUGIN_INSTRUCTIONS_TABLE, PLUGIN_NAME } from '../defaults.js';
|
|
6
5
|
import { registerEditorHelper } from '../libraries/handlebars/helpers.js';
|
|
7
|
-
import { handlebarsHelpersMap } from '../libraries/handlebars/helpersMap.js';
|
|
8
6
|
import { replacePlaceholders } from '../libraries/handlebars/replacePlaceholders.js';
|
|
9
7
|
import { extractImageData } from '../utilities/extractImageData.js';
|
|
8
|
+
import { fetchImages } from '../utilities/fetchImages.js';
|
|
10
9
|
import { fieldToJsonSchema } from '../utilities/fieldToJsonSchema.js';
|
|
11
10
|
import { getFieldBySchemaPath } from '../utilities/getFieldBySchemaPath.js';
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
if (!req.user) {
|
|
15
|
-
throw new Error('Authentication required. Please log in to use AI features.');
|
|
16
|
-
}
|
|
17
|
-
return true;
|
|
18
|
-
};
|
|
19
|
-
const checkAccess = async (req, pluginConfig)=>{
|
|
20
|
-
requireAuthentication(req);
|
|
21
|
-
if (pluginConfig.access?.generate) {
|
|
22
|
-
const hasAccess = await pluginConfig.access.generate({
|
|
23
|
-
req
|
|
24
|
-
});
|
|
25
|
-
if (!hasAccess) {
|
|
26
|
-
throw new Error('Insufficient permissions to use AI generation features.');
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return true;
|
|
30
|
-
};
|
|
31
|
-
const extendContextWithPromptFields = (data, ctx, pluginConfig)=>{
|
|
32
|
-
const { promptFields = [] } = pluginConfig;
|
|
33
|
-
const fieldsMap = new Map(promptFields.filter((f)=>!f.collections || f.collections.includes(ctx.collection)).map((f)=>[
|
|
34
|
-
f.name,
|
|
35
|
-
f
|
|
36
|
-
]));
|
|
37
|
-
return new Proxy(data, {
|
|
38
|
-
get: (target, prop)=>{
|
|
39
|
-
const field = fieldsMap.get(prop);
|
|
40
|
-
if (field?.getter) {
|
|
41
|
-
const value = field.getter(data, ctx);
|
|
42
|
-
return Promise.resolve(value).then((v)=>new asyncHandlebars.SafeString(v));
|
|
43
|
-
}
|
|
44
|
-
// {{prop}} escapes content by default. Here we make sure it won't be escaped.
|
|
45
|
-
const value = typeof target === "object" ? target[prop] : undefined;
|
|
46
|
-
return typeof value === 'string' ? new asyncHandlebars.SafeString(value) : value;
|
|
47
|
-
},
|
|
48
|
-
// It's used by the handlebars library to determine if the property is enumerable
|
|
49
|
-
getOwnPropertyDescriptor: (target, prop)=>{
|
|
50
|
-
const field = fieldsMap.get(prop);
|
|
51
|
-
if (field) {
|
|
52
|
-
return {
|
|
53
|
-
configurable: true,
|
|
54
|
-
enumerable: true
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
return Object.getOwnPropertyDescriptor(target, prop);
|
|
58
|
-
},
|
|
59
|
-
has: (target, prop)=>{
|
|
60
|
-
return fieldsMap.has(prop) || target && prop in target;
|
|
61
|
-
},
|
|
62
|
-
ownKeys: (target)=>{
|
|
63
|
-
return [
|
|
64
|
-
...fieldsMap.keys(),
|
|
65
|
-
...Object.keys(target || {})
|
|
66
|
-
];
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
};
|
|
70
|
-
const buildRichTextSystem = (baseSystem, layout)=>{
|
|
71
|
-
return `${baseSystem}
|
|
72
|
-
|
|
73
|
-
RULES:
|
|
74
|
-
- Generate original and unique content based on the given topic.
|
|
75
|
-
- Strictly adhere to the specified layout and formatting instructions.
|
|
76
|
-
- Utilize the provided rich text editor tools for appropriate formatting.
|
|
77
|
-
- Ensure the output follows the structure of the sample output object.
|
|
78
|
-
- Produce valid JSON with no undefined or null values.
|
|
79
|
-
---
|
|
80
|
-
LAYOUT INSTRUCTIONS:
|
|
81
|
-
${layout}
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
ADDITIONAL GUIDELINES:
|
|
85
|
-
- Ensure coherence and logical flow between all sections.
|
|
86
|
-
- Maintain a consistent tone and style throughout the content.
|
|
87
|
-
- Use clear and concise language appropriate for the target audience.
|
|
88
|
-
`;
|
|
89
|
-
};
|
|
90
|
-
const assignPrompt = async (action, { type, actionParams, collection, context, field, layout, locale, pluginConfig, systemPrompt = '', template })=>{
|
|
91
|
-
const extendedContext = extendContextWithPromptFields(context, {
|
|
92
|
-
type,
|
|
93
|
-
collection
|
|
94
|
-
}, pluginConfig);
|
|
95
|
-
const prompt = await replacePlaceholders(template, extendedContext);
|
|
96
|
-
const toLexicalHTML = type === 'richText' ? handlebarsHelpersMap.toHTML.name : '';
|
|
97
|
-
const assignedPrompts = {
|
|
98
|
-
layout: type === 'richText' ? layout : undefined,
|
|
99
|
-
prompt,
|
|
100
|
-
//TODO: Define only once on a collection level
|
|
101
|
-
system: type === 'richText' ? buildRichTextSystem(systemPrompt, layout) : undefined
|
|
102
|
-
};
|
|
103
|
-
if (action === 'Compose') {
|
|
104
|
-
if (locale && locale !== 'en') {
|
|
105
|
-
/**
|
|
106
|
-
* NOTE: Avoid using the "system prompt" for setting the output language,
|
|
107
|
-
* as it causes quotation marks to appear in the output (Currently only tested with openai models).
|
|
108
|
-
* Appending the language instruction directly to the prompt resolves this issue.
|
|
109
|
-
**/ assignedPrompts.prompt += `
|
|
110
|
-
---
|
|
111
|
-
OUTPUT LANGUAGE: ${locale}
|
|
112
|
-
`;
|
|
113
|
-
}
|
|
114
|
-
return assignedPrompts;
|
|
115
|
-
}
|
|
116
|
-
const prompts = [
|
|
117
|
-
...pluginConfig.prompts || [],
|
|
118
|
-
...defaultPrompts
|
|
119
|
-
];
|
|
120
|
-
const foundPrompt = prompts.find((p)=>p.name === action);
|
|
121
|
-
const getLayout = foundPrompt?.layout;
|
|
122
|
-
const getSystemPrompt = foundPrompt?.system;
|
|
123
|
-
let updatedLayout = layout;
|
|
124
|
-
if (getLayout) {
|
|
125
|
-
updatedLayout = getLayout();
|
|
126
|
-
}
|
|
127
|
-
const system = getSystemPrompt ? getSystemPrompt({
|
|
128
|
-
...actionParams || {},
|
|
129
|
-
prompt,
|
|
130
|
-
systemPrompt
|
|
131
|
-
}) : '';
|
|
132
|
-
return {
|
|
133
|
-
layout: updatedLayout,
|
|
134
|
-
// TODO: revisit this toLexicalHTML
|
|
135
|
-
prompt: await replacePlaceholders(`{{${toLexicalHTML} ${field}}}`, extendedContext),
|
|
136
|
-
system: type === 'richText' ? buildRichTextSystem(system, updatedLayout) : system
|
|
137
|
-
};
|
|
138
|
-
};
|
|
11
|
+
import { resolveImageReferences } from '../utilities/resolveImageReferences.js';
|
|
12
|
+
import { assignPrompt, extendContextWithPromptFields } from './buildPromptUtils.js';
|
|
139
13
|
export const endpoints = (pluginConfig)=>({
|
|
140
14
|
textarea: {
|
|
141
|
-
//
|
|
15
|
+
// Text/rich-text generation endpoint using payload.ai.streamObject
|
|
142
16
|
handler: async (req)=>{
|
|
143
17
|
try {
|
|
144
18
|
// Check authentication and authorization first
|
|
@@ -168,8 +42,8 @@ export const endpoints = (pluginConfig)=>({
|
|
|
168
42
|
if (allowedEditorNodes.length) {
|
|
169
43
|
allowedEditorSchema = filterEditorSchemaByNodes(editorSchema, allowedEditorNodes);
|
|
170
44
|
}
|
|
171
|
-
const schemaPath = instructions['schema-path'];
|
|
172
|
-
const parts = schemaPath
|
|
45
|
+
const schemaPath = String(instructions['schema-path']);
|
|
46
|
+
const parts = (schemaPath || '').split('.') || [];
|
|
173
47
|
const collectionName = parts[0];
|
|
174
48
|
const fieldName = parts.length > 1 ? parts[parts.length - 1] : '';
|
|
175
49
|
registerEditorHelper(req.payload, schemaPath);
|
|
@@ -181,16 +55,6 @@ export const endpoints = (pluginConfig)=>({
|
|
|
181
55
|
if (localeData && defaultLocale && localeData.label && typeof localeData.label === 'object' && defaultLocale in localeData.label) {
|
|
182
56
|
localeInfo = localeData.label[defaultLocale];
|
|
183
57
|
}
|
|
184
|
-
const models = getGenerationModels(pluginConfig);
|
|
185
|
-
const model = models && Array.isArray(models) ? models.find((model)=>model.id === instructions['model-id']) : undefined;
|
|
186
|
-
if (!model) {
|
|
187
|
-
throw new Error('Model not found');
|
|
188
|
-
}
|
|
189
|
-
const settingsName = model.settings && "name" in model.settings ? model.settings.name : undefined;
|
|
190
|
-
if (!settingsName) {
|
|
191
|
-
req.payload.logger.error('— AI Plugin: Error fetching settings name!');
|
|
192
|
-
}
|
|
193
|
-
const modelOptions = settingsName ? instructions[settingsName] || {} : {};
|
|
194
58
|
const prompts = await assignPrompt(action, {
|
|
195
59
|
type: String(instructions['field-type']),
|
|
196
60
|
actionParams,
|
|
@@ -206,7 +70,7 @@ export const endpoints = (pluginConfig)=>({
|
|
|
206
70
|
if (pluginConfig.debugging) {
|
|
207
71
|
req.payload.logger.info({
|
|
208
72
|
prompts
|
|
209
|
-
}, `— AI Plugin: Executing text prompt on ${schemaPath}
|
|
73
|
+
}, `— AI Plugin: Executing text prompt on ${schemaPath}`);
|
|
210
74
|
}
|
|
211
75
|
// Build per-field JSON schema for structured generation when applicable
|
|
212
76
|
let jsonSchema = allowedEditorSchema;
|
|
@@ -234,13 +98,42 @@ export const endpoints = (pluginConfig)=>({
|
|
|
234
98
|
} catch (e) {
|
|
235
99
|
req.payload.logger.error(e, '— AI Plugin: Error building field JSON schema');
|
|
236
100
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
101
|
+
// Get model settings from instruction
|
|
102
|
+
const settingsName = instructions['model-id'] === 'richtext' ? 'richtext-settings' : instructions['model-id'] === 'text' ? 'text-settings' : undefined;
|
|
103
|
+
if (!settingsName) {
|
|
104
|
+
throw new Error(`Unsupported model-id: ${instructions['model-id']}`);
|
|
105
|
+
}
|
|
106
|
+
const modelSettings = instructions[settingsName] || {};
|
|
107
|
+
// Resolve @field:filename references from the prompt
|
|
108
|
+
const { images: resolvedImages, processedPrompt } = await resolveImageReferences(prompts.prompt, contextData, req);
|
|
109
|
+
console.log('resolvedImagesL ', resolvedImages);
|
|
110
|
+
// Extract hardcoded URLs from the processed prompt
|
|
111
|
+
const hardcodedImages = extractImageData(processedPrompt);
|
|
112
|
+
// Combine images
|
|
113
|
+
const allImages = [
|
|
114
|
+
...hardcodedImages,
|
|
115
|
+
...resolvedImages
|
|
116
|
+
];
|
|
117
|
+
let images;
|
|
118
|
+
if (allImages.length > 0) {
|
|
119
|
+
const imageParts = await fetchImages(req, allImages);
|
|
120
|
+
if (imageParts.length > 0) {
|
|
121
|
+
images = imageParts;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Use payload.ai.streamObject directly! 🎉
|
|
125
|
+
const streamResult = await req.payload.ai.streamObject({
|
|
126
|
+
// extractAttachments: modelSettings.extractAttachments as boolean | undefined,
|
|
127
|
+
images,
|
|
128
|
+
maxTokens: modelSettings.maxTokens,
|
|
129
|
+
model: modelSettings.model,
|
|
130
|
+
prompt: processedPrompt,
|
|
131
|
+
provider: modelSettings.provider,
|
|
241
132
|
schema: jsonSchema,
|
|
242
|
-
system: prompts.system
|
|
133
|
+
system: prompts.system,
|
|
134
|
+
temperature: modelSettings.temperature
|
|
243
135
|
});
|
|
136
|
+
return streamResult;
|
|
244
137
|
} catch (error) {
|
|
245
138
|
req.payload.logger.error(error, 'Error generating content: ');
|
|
246
139
|
const message = error && typeof error === 'object' && 'message' in error ? error.message : String(error);
|
|
@@ -258,6 +151,7 @@ export const endpoints = (pluginConfig)=>({
|
|
|
258
151
|
path: PLUGIN_API_ENDPOINT_GENERATE
|
|
259
152
|
},
|
|
260
153
|
upload: {
|
|
154
|
+
// Image/video generation endpoint using payload.ai.generateMedia
|
|
261
155
|
handler: async (req)=>{
|
|
262
156
|
try {
|
|
263
157
|
// Check authentication and authorization first
|
|
@@ -296,94 +190,239 @@ export const endpoints = (pluginConfig)=>({
|
|
|
296
190
|
});
|
|
297
191
|
}
|
|
298
192
|
const { images: sampleImages = [], prompt: promptTemplate = '' } = instructions;
|
|
299
|
-
const schemaPath = instructions['schema-path'];
|
|
193
|
+
const schemaPath = String(instructions['schema-path']);
|
|
300
194
|
registerEditorHelper(req.payload, schemaPath);
|
|
301
195
|
const extendedContext = extendContextWithPromptFields(contextData, {
|
|
302
|
-
type: instructions['field-type'],
|
|
196
|
+
type: String(instructions['field-type']),
|
|
303
197
|
collection: collectionSlug
|
|
304
198
|
}, pluginConfig);
|
|
305
199
|
const text = await replacePlaceholders(promptTemplate, extendedContext);
|
|
306
200
|
const modelId = instructions['model-id'];
|
|
307
201
|
const uploadCollectionSlug = instructions['relation-to'];
|
|
202
|
+
// Resolve @field:filename references from the prompt
|
|
203
|
+
const { images: resolvedImages, processedPrompt } = await resolveImageReferences(text, contextData, req);
|
|
204
|
+
// Extract hardcoded URLs from the processed prompt and merge with resolved images and sample images
|
|
308
205
|
const images = [
|
|
309
|
-
...extractImageData(
|
|
206
|
+
...extractImageData(processedPrompt),
|
|
207
|
+
...resolvedImages,
|
|
310
208
|
...sampleImages
|
|
311
209
|
];
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
210
|
+
// Process images - convert to ImagePart format using helper
|
|
211
|
+
const editImages = await fetchImages(req, images);
|
|
212
|
+
if (pluginConfig.debugging) {
|
|
213
|
+
req.payload.logger.info({
|
|
214
|
+
text
|
|
215
|
+
}, `— AI Plugin: Executing media generation`);
|
|
216
|
+
}
|
|
217
|
+
// Prepare callback URL for async jobs
|
|
218
|
+
const serverURL = req.payload.config?.serverURL || process.env.SERVER_URL || process.env.NEXT_PUBLIC_SERVER_URL;
|
|
219
|
+
const callbackUrl = serverURL ? `${serverURL.replace(/\/$/, '')}/api${PLUGIN_API_ENDPOINT_VIDEOGEN_WEBHOOK}?instructionId=${instructionId}` : undefined;
|
|
220
|
+
// Get model settings
|
|
221
|
+
const settingsName = modelId === 'image' ? 'image-settings' : modelId === 'video' ? 'video-settings' : modelId === 'tts' ? 'tts-settings' : undefined;
|
|
222
|
+
if (!settingsName) {
|
|
223
|
+
throw new Error(`Unsupported model-id: ${modelId}`);
|
|
224
|
+
}
|
|
225
|
+
const modelSettings = instructions[settingsName] || {};
|
|
226
|
+
// Use payload.ai.generateMedia directly! 🎉
|
|
227
|
+
const result = await req.payload.ai.generateMedia({
|
|
228
|
+
callbackUrl,
|
|
229
|
+
images: editImages,
|
|
230
|
+
instructionId,
|
|
231
|
+
model: modelSettings.model,
|
|
232
|
+
prompt: text,
|
|
233
|
+
provider: modelSettings.provider,
|
|
234
|
+
...modelSettings
|
|
235
|
+
});
|
|
236
|
+
// If model returned a file immediately, proceed with upload
|
|
237
|
+
if (result && 'file' in result) {
|
|
238
|
+
let assetData;
|
|
239
|
+
if (typeof pluginConfig.mediaUpload === 'function') {
|
|
240
|
+
assetData = await pluginConfig.mediaUpload(result, {
|
|
241
|
+
collection: uploadCollectionSlug,
|
|
242
|
+
request: req
|
|
326
243
|
});
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
244
|
+
} else {
|
|
245
|
+
assetData = await req.payload.create({
|
|
246
|
+
collection: uploadCollectionSlug,
|
|
247
|
+
data: {
|
|
248
|
+
alt: text
|
|
249
|
+
},
|
|
250
|
+
file: result.file,
|
|
251
|
+
req
|
|
334
252
|
});
|
|
335
|
-
} catch (e) {
|
|
336
|
-
req.payload.logger.error(e, `Error fetching reference image ${url}`);
|
|
337
|
-
throw Error("We couldn't fetch the images. Please ensure the images are accessible and hosted publicly.");
|
|
338
253
|
}
|
|
254
|
+
if (!assetData.id) {
|
|
255
|
+
req.payload.logger.error('Error uploading generated media, is your media upload function correct?');
|
|
256
|
+
throw new Error('Error uploading generated media!');
|
|
257
|
+
}
|
|
258
|
+
return new Response(JSON.stringify({
|
|
259
|
+
result: {
|
|
260
|
+
id: assetData.id,
|
|
261
|
+
alt: assetData.alt
|
|
262
|
+
}
|
|
263
|
+
}));
|
|
339
264
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
265
|
+
// Otherwise, assume async job launch
|
|
266
|
+
if (result && ('jobId' in result || 'taskId' in result)) {
|
|
267
|
+
const externalTaskId = result.jobId || result.taskId;
|
|
268
|
+
const status = result.status || 'queued';
|
|
269
|
+
const progress = result.progress ?? 0;
|
|
270
|
+
// Create AI Job doc and return only its id
|
|
271
|
+
const createdJob = await req.payload.create({
|
|
272
|
+
collection: PLUGIN_AI_JOBS_TABLE,
|
|
273
|
+
data: {
|
|
274
|
+
instructionId,
|
|
275
|
+
progress,
|
|
276
|
+
status,
|
|
277
|
+
task_id: externalTaskId
|
|
278
|
+
},
|
|
279
|
+
overrideAccess: true,
|
|
280
|
+
req
|
|
281
|
+
});
|
|
282
|
+
return new Response(JSON.stringify({
|
|
283
|
+
job: {
|
|
284
|
+
id: createdJob.id
|
|
285
|
+
}
|
|
286
|
+
}), {
|
|
287
|
+
headers: {
|
|
288
|
+
'Content-Type': 'application/json'
|
|
289
|
+
}
|
|
290
|
+
});
|
|
344
291
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
292
|
+
throw new Error('Unexpected model response.');
|
|
293
|
+
} catch (error) {
|
|
294
|
+
req.payload.logger.error(// @ts-expect-error
|
|
295
|
+
error?.type || error.message, 'Error generating upload: ');
|
|
296
|
+
const message = error && typeof error === 'object' && 'message' in error ? error.message : String(error);
|
|
297
|
+
return new Response(JSON.stringify({
|
|
298
|
+
error: message
|
|
299
|
+
}), {
|
|
300
|
+
headers: {
|
|
301
|
+
'Content-Type': 'application/json'
|
|
302
|
+
},
|
|
303
|
+
status: message.includes('Authentication required') || message.includes('Insufficient permissions') ? 401 : 500
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
method: 'post',
|
|
308
|
+
path: PLUGIN_API_ENDPOINT_GENERATE_UPLOAD
|
|
309
|
+
},
|
|
310
|
+
videogenWebhook: {
|
|
311
|
+
handler: async (req)=>{
|
|
312
|
+
console.log('videogenWebhook --> ', req);
|
|
313
|
+
try {
|
|
314
|
+
const urlAll = new URL(req.url || '');
|
|
315
|
+
const qpSecret = urlAll.searchParams.get('secret') || '';
|
|
316
|
+
const headerSecret = req.headers.get('x-webhook-secret') || '';
|
|
317
|
+
const falSecret = process.env.FAL_WEBHOOK_SECRET;
|
|
318
|
+
const legacySecret = process.env.VIDEOGEN_WEBHOOK_SECRET;
|
|
319
|
+
const provided = qpSecret || headerSecret;
|
|
320
|
+
// TODO: fal is failing because of auth but webhook seem to work
|
|
321
|
+
if (!provided || (falSecret ? provided !== falSecret : provided !== legacySecret)) {
|
|
322
|
+
return new Response('Unauthorized', {
|
|
323
|
+
status: 401
|
|
324
|
+
});
|
|
349
325
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
images: editImages
|
|
354
|
-
};
|
|
355
|
-
if (pluginConfig.debugging) {
|
|
356
|
-
req.payload.logger.info({
|
|
357
|
-
text
|
|
358
|
-
}, `— AI Plugin: Executing image prompt using ${model.id}`);
|
|
326
|
+
const instructionId = urlAll.searchParams.get('instructionId');
|
|
327
|
+
if (!instructionId) {
|
|
328
|
+
throw new Error('instructionId missing');
|
|
359
329
|
}
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
330
|
+
const body = await req.json?.();
|
|
331
|
+
// Normalize fal webhook payload
|
|
332
|
+
const status = body && (body.status || body.data?.status || body.response?.status) || undefined;
|
|
333
|
+
const progress = (body && (body.progress ?? body.data?.progress ?? body.response?.progress)) ?? undefined;
|
|
334
|
+
const requestId = body && (body.taskId || body.request_id || body.gateway_request_id || body.request?.request_id) || undefined;
|
|
335
|
+
const error = body?.error || body?.data?.error || body?.response?.error;
|
|
336
|
+
// Update AI Job row by task_id (and instructionId)
|
|
337
|
+
const jobSearch = await req.payload.find({
|
|
338
|
+
collection: PLUGIN_AI_JOBS_TABLE,
|
|
339
|
+
depth: 0,
|
|
340
|
+
limit: 1,
|
|
341
|
+
where: {
|
|
342
|
+
and: [
|
|
343
|
+
{
|
|
344
|
+
task_id: {
|
|
345
|
+
equals: requestId
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
instructionId: {
|
|
350
|
+
equals: instructionId
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
]
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
const jobDoc = jobSearch.docs?.[0];
|
|
357
|
+
if (jobDoc) {
|
|
358
|
+
await req.payload.update({
|
|
359
|
+
id: jobDoc.id,
|
|
360
|
+
collection: PLUGIN_AI_JOBS_TABLE,
|
|
361
|
+
data: {
|
|
362
|
+
progress,
|
|
363
|
+
status,
|
|
364
|
+
task_id: requestId
|
|
365
|
+
},
|
|
366
|
+
overrideAccess: true,
|
|
367
|
+
req
|
|
366
368
|
});
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
+
}
|
|
370
|
+
console.log('fal webhook body: ', body);
|
|
371
|
+
const videoUrl = body?.outputs?.[0]?.url || body?.data?.outputs?.[0]?.url || body?.video?.url || body?.data?.video?.url || body?.response?.video?.url || body?.videos?.[0]?.url || body?.data?.videos?.[0]?.url;
|
|
372
|
+
if (status === 'completed' && videoUrl) {
|
|
373
|
+
// Fetch the related instruction to get upload collection
|
|
374
|
+
const instructions = await req.payload.findByID({
|
|
375
|
+
id: instructionId,
|
|
376
|
+
collection: PLUGIN_INSTRUCTIONS_TABLE,
|
|
377
|
+
req
|
|
378
|
+
});
|
|
379
|
+
const uploadCollectionSlug = instructions['relation-to'];
|
|
380
|
+
const videoResp = await fetch(videoUrl);
|
|
381
|
+
if (!videoResp.ok) {
|
|
382
|
+
throw new Error(`Failed to fetch output: ${videoResp.status}`);
|
|
383
|
+
}
|
|
384
|
+
const buffer = Buffer.from(await videoResp.arrayBuffer());
|
|
385
|
+
const created = await req.payload.create({
|
|
369
386
|
collection: uploadCollectionSlug,
|
|
370
|
-
data:
|
|
371
|
-
|
|
387
|
+
data: {
|
|
388
|
+
alt: 'video generation'
|
|
389
|
+
},
|
|
390
|
+
file: {
|
|
391
|
+
name: 'video_generation.mp4',
|
|
392
|
+
data: buffer,
|
|
393
|
+
mimetype: 'video/mp4',
|
|
394
|
+
size: buffer.byteLength
|
|
395
|
+
},
|
|
396
|
+
overrideAccess: true,
|
|
372
397
|
req
|
|
373
398
|
});
|
|
399
|
+
// Persist the result on the AI Job record
|
|
400
|
+
if (jobDoc) {
|
|
401
|
+
await req.payload.update({
|
|
402
|
+
id: jobDoc.id,
|
|
403
|
+
collection: PLUGIN_AI_JOBS_TABLE,
|
|
404
|
+
data: {
|
|
405
|
+
progress: 100,
|
|
406
|
+
result_id: created?.id,
|
|
407
|
+
status: 'completed'
|
|
408
|
+
},
|
|
409
|
+
overrideAccess: true,
|
|
410
|
+
req
|
|
411
|
+
});
|
|
412
|
+
}
|
|
374
413
|
}
|
|
375
|
-
if (
|
|
376
|
-
req.payload.logger.error(
|
|
377
|
-
throw new Error('Error uploading generated media!');
|
|
414
|
+
if (status === 'failed' && error) {
|
|
415
|
+
req.payload.logger.error(error, 'Video generation failed: ');
|
|
378
416
|
}
|
|
379
417
|
return new Response(JSON.stringify({
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
418
|
+
ok: true
|
|
419
|
+
}), {
|
|
420
|
+
headers: {
|
|
421
|
+
'Content-Type': 'application/json'
|
|
383
422
|
}
|
|
384
|
-
})
|
|
423
|
+
});
|
|
385
424
|
} catch (error) {
|
|
386
|
-
req.payload.logger.error(error, 'Error
|
|
425
|
+
req.payload.logger.error(error, 'Error in videogen webhook: ');
|
|
387
426
|
const message = error && typeof error === 'object' && 'message' in error ? error.message : String(error);
|
|
388
427
|
return new Response(JSON.stringify({
|
|
389
428
|
error: message
|
|
@@ -391,12 +430,12 @@ export const endpoints = (pluginConfig)=>({
|
|
|
391
430
|
headers: {
|
|
392
431
|
'Content-Type': 'application/json'
|
|
393
432
|
},
|
|
394
|
-
status:
|
|
433
|
+
status: 500
|
|
395
434
|
});
|
|
396
435
|
}
|
|
397
436
|
},
|
|
398
437
|
method: 'post',
|
|
399
|
-
path:
|
|
438
|
+
path: PLUGIN_API_ENDPOINT_VIDEOGEN_WEBHOOK
|
|
400
439
|
}
|
|
401
440
|
});
|
|
402
441
|
|