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

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.
Files changed (78) hide show
  1. package/README.md +5 -5
  2. package/dist/ai/core/media/image/handlers/multimodal.js +2 -2
  3. package/dist/ai/core/media/image/handlers/multimodal.js.map +1 -1
  4. package/dist/ai/providers/blocks/anthropic.js +2 -2
  5. package/dist/ai/providers/blocks/anthropic.js.map +1 -1
  6. package/dist/ai/providers/blocks/elevenlabs.js +3 -3
  7. package/dist/ai/providers/blocks/elevenlabs.js.map +1 -1
  8. package/dist/ai/providers/blocks/fal.js +2 -2
  9. package/dist/ai/providers/blocks/fal.js.map +1 -1
  10. package/dist/ai/providers/blocks/google.js +4 -3
  11. package/dist/ai/providers/blocks/google.js.map +1 -1
  12. package/dist/ai/providers/blocks/openai-compatible.js +2 -2
  13. package/dist/ai/providers/blocks/openai-compatible.js.map +1 -1
  14. package/dist/ai/providers/blocks/openai.js +2 -2
  15. package/dist/ai/providers/blocks/openai.js.map +1 -1
  16. package/dist/ai/providers/blocks/xai.js +2 -2
  17. package/dist/ai/providers/blocks/xai.js.map +1 -1
  18. package/dist/ai/utilities/nodeToSchemaMap.js +6 -6
  19. package/dist/ai/utilities/nodeToSchemaMap.js.map +1 -1
  20. package/dist/collections/AIProviders.js +13 -13
  21. package/dist/collections/AIProviders.js.map +1 -1
  22. package/dist/collections/Instructions.js +6 -6
  23. package/dist/collections/Instructions.js.map +1 -1
  24. package/dist/endpoints/index.js +1 -1
  25. package/dist/endpoints/index.js.map +1 -1
  26. package/dist/exports/types.d.ts +1 -1
  27. package/dist/exports/types.js.map +1 -1
  28. package/dist/fields/LexicalEditor/feature.server.d.ts +1 -1
  29. package/dist/fields/LexicalEditor/feature.server.js +2 -2
  30. package/dist/fields/LexicalEditor/feature.server.js.map +1 -1
  31. package/dist/fields/PromptEditorField/feature.client.js.map +1 -1
  32. package/dist/fields/PromptEditorField/feature.server.js +1 -1
  33. package/dist/fields/PromptEditorField/feature.server.js.map +1 -1
  34. package/dist/index.d.ts +2 -2
  35. package/dist/index.js +2 -2
  36. package/dist/index.js.map +1 -1
  37. package/dist/plugin.d.ts +2 -2
  38. package/dist/plugin.js +3 -3
  39. package/dist/plugin.js.map +1 -1
  40. package/dist/providers/FieldProvider/FieldProvider.js +1 -1
  41. package/dist/providers/FieldProvider/FieldProvider.js.map +1 -1
  42. package/dist/providers/FieldProvider/FieldProvider.jsx +2 -2
  43. package/dist/providers/InstructionsProvider/InstructionsProvider.js +1 -1
  44. package/dist/providers/InstructionsProvider/InstructionsProvider.js.map +1 -1
  45. package/dist/providers/InstructionsProvider/InstructionsProvider.jsx +2 -2
  46. package/dist/types.d.ts +10 -0
  47. package/dist/types.js.map +1 -1
  48. package/dist/ui/Compose/Compose.js.map +1 -1
  49. package/dist/ui/Compose/hooks/menu/Item.js.map +1 -1
  50. package/dist/ui/Compose/hooks/menu/TranslateMenu.js +12 -4
  51. package/dist/ui/Compose/hooks/menu/TranslateMenu.js.map +1 -1
  52. package/dist/ui/Compose/hooks/menu/TranslateMenu.jsx +8 -4
  53. package/dist/ui/Compose/hooks/useHistory.js +1 -1
  54. package/dist/ui/Compose/hooks/useHistory.js.map +1 -1
  55. package/dist/ui/DynamicModelSelect/index.js +1 -1
  56. package/dist/ui/DynamicModelSelect/index.js.map +1 -1
  57. package/dist/ui/DynamicModelSelect/index.jsx +1 -1
  58. package/dist/ui/DynamicProviderSelect/index.js +1 -1
  59. package/dist/ui/DynamicProviderSelect/index.js.map +1 -1
  60. package/dist/ui/DynamicProviderSelect/index.jsx +1 -1
  61. package/dist/ui/DynamicVoiceSelect/index.js +1 -1
  62. package/dist/ui/DynamicVoiceSelect/index.js.map +1 -1
  63. package/dist/ui/DynamicVoiceSelect/index.jsx +1 -1
  64. package/dist/ui/InstructionProviderOptions/ProviderOptionsTree.js.map +1 -1
  65. package/dist/ui/hooks/useAISettings.js.map +1 -1
  66. package/dist/ui/providerOptions/updateProviderOptionsValue.d.ts +1 -1
  67. package/dist/ui/providerOptions/updateProviderOptionsValue.js.map +1 -1
  68. package/dist/utilities/ai/resolveEffectiveInstructionSettings.js.map +1 -1
  69. package/dist/utilities/fields/updateFieldsConfig.js +1 -1
  70. package/dist/utilities/fields/updateFieldsConfig.js.map +1 -1
  71. package/dist/utilities/lexical/lexicalToPromptTemplate.d.ts +1 -1
  72. package/dist/utilities/lexical/lexicalToPromptTemplate.js +1 -1
  73. package/dist/utilities/lexical/lexicalToPromptTemplate.js.map +1 -1
  74. package/dist/utilities/lexical/stringToLexicalJSON.js +1 -1
  75. package/dist/utilities/lexical/stringToLexicalJSON.js.map +1 -1
  76. package/dist/utilities/seedProperties.js +19 -2
  77. package/dist/utilities/seedProperties.js.map +1 -1
  78. package/package.json +37 -6
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/ai/providers/blocks/xai.ts"],"sourcesContent":["import type { Block } from 'payload'\n\nimport { XAIIcon } from '../icons.js'\n\nexport const xaiBlock: Block = {\n slug: 'xai',\n fields: [\n {\n type: 'tabs',\n tabs: [\n // 1. Setup tab\n {\n fields: [\n {\n name: 'enabled',\n type: 'checkbox',\n defaultValue: true,\n label: 'Enabled',\n },\n {\n name: 'apiKey',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#EncryptedTextField',\n },\n description: 'Your xAI API key. Will be encrypted in the database.',\n },\n label: 'API Key',\n required: true,\n },\n ],\n label: 'Setup',\n },\n\n // 3. Models tab\n {\n fields: [\n {\n name: 'models',\n type: 'array',\n admin: {\n components: {\n RowLabel: '@ai-stack/payloadcms/client#ModelRowLabel',\n },\n initCollapsed: true,\n },\n defaultValue: [\n { id: 'grok-4', name: 'Grok 4', enabled: true, responseModalities: ['TEXT'], useCase: 'text' },\n { id: 'grok-3', name: 'Grok 3', enabled: true, responseModalities: ['TEXT'], useCase: 'text' },\n { id: 'grok-3-fast', name: 'Grok 3 Fast', enabled: true, responseModalities: ['TEXT'], useCase: 'text' },\n { id: 'grok-2-1212', name: 'Grok 2', enabled: true, responseModalities: ['TEXT'], useCase: 'text' },\n { id: 'grok-2-vision-1212', name: 'Grok 2 Vision', enabled: true, responseModalities: ['TEXT'], useCase: 'image' },\n { id: 'grok-vision-beta', name: 'Grok Vision Beta', enabled: true, responseModalities: ['TEXT'], useCase: 'image' },\n ],\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'id',\n type: 'text',\n admin: { width: '33%' },\n label: 'Model ID',\n required: true,\n },\n {\n name: 'name',\n type: 'text',\n admin: { width: '33%' },\n label: 'Display Name',\n required: true,\n },\n {\n name: 'useCase',\n type: 'select',\n admin: { width: '33%' },\n dbName: 'xai-model-useCase',\n label: 'Use Case',\n options: [\n { label: 'Text Generation', value: 'text' },\n { label: 'Image Generation', value: 'image' },\n ],\n required: true,\n },\n ],\n },\n {\n name: 'responseModalities',\n type: 'select',\n admin: {\n description: 'Output capabilities of this model',\n width: '50%',\n },\n dbName: 'xai-model-modalities',\n hasMany: true,\n label: 'Response Modalities',\n options: [\n { label: 'Text', value: 'TEXT' },\n { label: 'Image', value: 'IMAGE' },\n { label: 'Audio', value: 'AUDIO' },\n ],\n },\n {\n name: 'enabled',\n type: 'checkbox',\n admin: {\n width: '50%',\n },\n defaultValue: true,\n label: 'Enabled',\n },\n ],\n label: 'Available Models',\n },\n ],\n label: 'Models',\n },\n ],\n },\n ],\n imageURL: XAIIcon,\n labels: {\n plural: 'xAI Providers',\n singular: 'xAI Grok',\n },\n}\n"],"names":["XAIIcon","xaiBlock","slug","fields","type","tabs","name","defaultValue","label","admin","components","Field","description","required","RowLabel","initCollapsed","id","enabled","responseModalities","useCase","width","dbName","options","value","hasMany","imageURL","labels","plural","singular"],"mappings":"AAEA,SAASA,OAAO,QAAQ,cAAa;AAErC,OAAO,MAAMC,WAAkB;IAC7BC,MAAM;IACNC,QAAQ;QACN;YACEC,MAAM;YACNC,MAAM;gBACJ,eAAe;gBACf;oBACEF,QAAQ;wBACN;4BACEG,MAAM;4BACNF,MAAM;4BACNG,cAAc;4BACdC,OAAO;wBACT;wBACA;4BACEF,MAAM;4BACNF,MAAM;4BACNK,OAAO;gCACLC,YAAY;oCACVC,OAAO;gCACT;gCACAC,aAAa;4BACf;4BACAJ,OAAO;4BACPK,UAAU;wBACZ;qBACD;oBACDL,OAAO;gBACT;gBAEA,gBAAgB;gBAChB;oBACEL,QAAQ;wBACN;4BACEG,MAAM;4BACNF,MAAM;4BACNK,OAAO;gCACLC,YAAY;oCACVI,UAAU;gCACZ;gCACAC,eAAe;4BACjB;4BACAR,cAAc;gCACZ;oCAAES,IAAI;oCAAUV,MAAM;oCAAUW,SAAS;oCAAMC,oBAAoB;wCAAC;qCAAO;oCAAEC,SAAS;gCAAO;gCAC7F;oCAAEH,IAAI;oCAAUV,MAAM;oCAAUW,SAAS;oCAAMC,oBAAoB;wCAAC;qCAAO;oCAAEC,SAAS;gCAAO;gCAC7F;oCAAEH,IAAI;oCAAeV,MAAM;oCAAeW,SAAS;oCAAMC,oBAAoB;wCAAC;qCAAO;oCAAEC,SAAS;gCAAO;gCACvG;oCAAEH,IAAI;oCAAeV,MAAM;oCAAUW,SAAS;oCAAMC,oBAAoB;wCAAC;qCAAO;oCAAEC,SAAS;gCAAO;gCAClG;oCAAEH,IAAI;oCAAsBV,MAAM;oCAAiBW,SAAS;oCAAMC,oBAAoB;wCAAC;qCAAO;oCAAEC,SAAS;gCAAQ;gCACjH;oCAAEH,IAAI;oCAAoBV,MAAM;oCAAoBW,SAAS;oCAAMC,oBAAoB;wCAAC;qCAAO;oCAAEC,SAAS;gCAAQ;6BACnH;4BACDhB,QAAQ;gCACN;oCACEC,MAAM;oCACND,QAAQ;wCACN;4CACEG,MAAM;4CACNF,MAAM;4CACNK,OAAO;gDAAEW,OAAO;4CAAM;4CACtBZ,OAAO;4CACPK,UAAU;wCACZ;wCACA;4CACEP,MAAM;4CACNF,MAAM;4CACNK,OAAO;gDAAEW,OAAO;4CAAM;4CACtBZ,OAAO;4CACPK,UAAU;wCACZ;wCACA;4CACEP,MAAM;4CACNF,MAAM;4CACNK,OAAO;gDAAEW,OAAO;4CAAM;4CACtBC,QAAQ;4CACRb,OAAO;4CACPc,SAAS;gDACP;oDAAEd,OAAO;oDAAmBe,OAAO;gDAAO;gDAC1C;oDAAEf,OAAO;oDAAoBe,OAAO;gDAAQ;6CAC7C;4CACDV,UAAU;wCACZ;qCACD;gCACH;gCACA;oCACEP,MAAM;oCACNF,MAAM;oCACNK,OAAO;wCACLG,aAAa;wCACbQ,OAAO;oCACT;oCACAC,QAAQ;oCACRG,SAAS;oCACThB,OAAO;oCACPc,SAAS;wCACP;4CAAEd,OAAO;4CAAQe,OAAO;wCAAO;wCAC/B;4CAAEf,OAAO;4CAASe,OAAO;wCAAQ;wCACjC;4CAAEf,OAAO;4CAASe,OAAO;wCAAQ;qCAClC;gCACH;gCACA;oCACEjB,MAAM;oCACNF,MAAM;oCACNK,OAAO;wCACLW,OAAO;oCACT;oCACAb,cAAc;oCACdC,OAAO;gCACT;6BACD;4BACDA,OAAO;wBACT;qBACD;oBACDA,OAAO;gBACT;aACD;QACH;KACD;IACDiB,UAAUzB;IACV0B,QAAQ;QACNC,QAAQ;QACRC,UAAU;IACZ;AACF,EAAC"}
1
+ {"version":3,"sources":["../../../../src/ai/providers/blocks/xai.ts"],"sourcesContent":["import type { Block } from 'payload'\n\nimport { XAIIcon } from '../icons.js'\n\nexport const xaiBlock: Block = {\n slug: 'xai',\n fields: [\n {\n type: 'tabs',\n tabs: [\n // 1. Setup tab\n {\n fields: [\n {\n name: 'enabled',\n type: 'checkbox',\n defaultValue: true,\n label: 'Enabled',\n },\n {\n name: 'apiKey',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/EncryptedTextField/index.js#EncryptedTextField',\n },\n description: 'Your xAI API key. Will be encrypted in the database.',\n },\n label: 'API Key',\n required: true,\n },\n ],\n label: 'Setup',\n },\n\n // 3. Models tab\n {\n fields: [\n {\n name: 'models',\n type: 'array',\n admin: {\n components: {\n RowLabel: '@ai-stack/payloadcms/ui/ModelRowLabel/index.js#ModelRowLabel',\n },\n initCollapsed: true,\n },\n defaultValue: [\n { id: 'grok-4', name: 'Grok 4', enabled: true, responseModalities: ['TEXT'], useCase: 'text' },\n { id: 'grok-3', name: 'Grok 3', enabled: true, responseModalities: ['TEXT'], useCase: 'text' },\n { id: 'grok-3-fast', name: 'Grok 3 Fast', enabled: true, responseModalities: ['TEXT'], useCase: 'text' },\n { id: 'grok-2-1212', name: 'Grok 2', enabled: true, responseModalities: ['TEXT'], useCase: 'text' },\n { id: 'grok-2-vision-1212', name: 'Grok 2 Vision', enabled: true, responseModalities: ['TEXT'], useCase: 'image' },\n { id: 'grok-vision-beta', name: 'Grok Vision Beta', enabled: true, responseModalities: ['TEXT'], useCase: 'image' },\n ],\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'id',\n type: 'text',\n admin: { width: '33%' },\n label: 'Model ID',\n required: true,\n },\n {\n name: 'name',\n type: 'text',\n admin: { width: '33%' },\n label: 'Display Name',\n required: true,\n },\n {\n name: 'useCase',\n type: 'select',\n admin: { width: '33%' },\n dbName: 'xai-model-useCase',\n label: 'Use Case',\n options: [\n { label: 'Text Generation', value: 'text' },\n { label: 'Image Generation', value: 'image' },\n ],\n required: true,\n },\n ],\n },\n {\n name: 'responseModalities',\n type: 'select',\n admin: {\n description: 'Output capabilities of this model',\n width: '50%',\n },\n dbName: 'xai-model-modalities',\n hasMany: true,\n label: 'Response Modalities',\n options: [\n { label: 'Text', value: 'TEXT' },\n { label: 'Image', value: 'IMAGE' },\n { label: 'Audio', value: 'AUDIO' },\n ],\n },\n {\n name: 'enabled',\n type: 'checkbox',\n admin: {\n width: '50%',\n },\n defaultValue: true,\n label: 'Enabled',\n },\n ],\n label: 'Available Models',\n },\n ],\n label: 'Models',\n },\n ],\n },\n ],\n imageURL: XAIIcon,\n labels: {\n plural: 'xAI Providers',\n singular: 'xAI Grok',\n },\n}\n"],"names":["XAIIcon","xaiBlock","slug","fields","type","tabs","name","defaultValue","label","admin","components","Field","description","required","RowLabel","initCollapsed","id","enabled","responseModalities","useCase","width","dbName","options","value","hasMany","imageURL","labels","plural","singular"],"mappings":"AAEA,SAASA,OAAO,QAAQ,cAAa;AAErC,OAAO,MAAMC,WAAkB;IAC7BC,MAAM;IACNC,QAAQ;QACN;YACEC,MAAM;YACNC,MAAM;gBACJ,eAAe;gBACf;oBACEF,QAAQ;wBACN;4BACEG,MAAM;4BACNF,MAAM;4BACNG,cAAc;4BACdC,OAAO;wBACT;wBACA;4BACEF,MAAM;4BACNF,MAAM;4BACNK,OAAO;gCACLC,YAAY;oCACVC,OAAO;gCACT;gCACAC,aAAa;4BACf;4BACAJ,OAAO;4BACPK,UAAU;wBACZ;qBACD;oBACDL,OAAO;gBACT;gBAEA,gBAAgB;gBAChB;oBACEL,QAAQ;wBACN;4BACEG,MAAM;4BACNF,MAAM;4BACNK,OAAO;gCACLC,YAAY;oCACVI,UAAU;gCACZ;gCACAC,eAAe;4BACjB;4BACAR,cAAc;gCACZ;oCAAES,IAAI;oCAAUV,MAAM;oCAAUW,SAAS;oCAAMC,oBAAoB;wCAAC;qCAAO;oCAAEC,SAAS;gCAAO;gCAC7F;oCAAEH,IAAI;oCAAUV,MAAM;oCAAUW,SAAS;oCAAMC,oBAAoB;wCAAC;qCAAO;oCAAEC,SAAS;gCAAO;gCAC7F;oCAAEH,IAAI;oCAAeV,MAAM;oCAAeW,SAAS;oCAAMC,oBAAoB;wCAAC;qCAAO;oCAAEC,SAAS;gCAAO;gCACvG;oCAAEH,IAAI;oCAAeV,MAAM;oCAAUW,SAAS;oCAAMC,oBAAoB;wCAAC;qCAAO;oCAAEC,SAAS;gCAAO;gCAClG;oCAAEH,IAAI;oCAAsBV,MAAM;oCAAiBW,SAAS;oCAAMC,oBAAoB;wCAAC;qCAAO;oCAAEC,SAAS;gCAAQ;gCACjH;oCAAEH,IAAI;oCAAoBV,MAAM;oCAAoBW,SAAS;oCAAMC,oBAAoB;wCAAC;qCAAO;oCAAEC,SAAS;gCAAQ;6BACnH;4BACDhB,QAAQ;gCACN;oCACEC,MAAM;oCACND,QAAQ;wCACN;4CACEG,MAAM;4CACNF,MAAM;4CACNK,OAAO;gDAAEW,OAAO;4CAAM;4CACtBZ,OAAO;4CACPK,UAAU;wCACZ;wCACA;4CACEP,MAAM;4CACNF,MAAM;4CACNK,OAAO;gDAAEW,OAAO;4CAAM;4CACtBZ,OAAO;4CACPK,UAAU;wCACZ;wCACA;4CACEP,MAAM;4CACNF,MAAM;4CACNK,OAAO;gDAAEW,OAAO;4CAAM;4CACtBC,QAAQ;4CACRb,OAAO;4CACPc,SAAS;gDACP;oDAAEd,OAAO;oDAAmBe,OAAO;gDAAO;gDAC1C;oDAAEf,OAAO;oDAAoBe,OAAO;gDAAQ;6CAC7C;4CACDV,UAAU;wCACZ;qCACD;gCACH;gCACA;oCACEP,MAAM;oCACNF,MAAM;oCACNK,OAAO;wCACLG,aAAa;wCACbQ,OAAO;oCACT;oCACAC,QAAQ;oCACRG,SAAS;oCACThB,OAAO;oCACPc,SAAS;wCACP;4CAAEd,OAAO;4CAAQe,OAAO;wCAAO;wCAC/B;4CAAEf,OAAO;4CAASe,OAAO;wCAAQ;wCACjC;4CAAEf,OAAO;4CAASe,OAAO;wCAAQ;qCAClC;gCACH;gCACA;oCACEjB,MAAM;oCACNF,MAAM;oCACNK,OAAO;wCACLW,OAAO;oCACT;oCACAb,cAAc;oCACdC,OAAO;gCACT;6BACD;4BACDA,OAAO;wBACT;qBACD;oBACDA,OAAO;gBACT;aACD;QACH;KACD;IACDiB,UAAUzB;IACV0B,QAAQ;QACNC,QAAQ;QACRC,UAAU;IACZ;AACF,EAAC"}
@@ -6,24 +6,24 @@
6
6
  * The values are the schema definition names as defined in lexicalJsonSchema.ts.
7
7
  */ export const nodeTypeToSchemaMap = {
8
8
  // Core nodes (typically always included)
9
- text: 'TextNode',
10
9
  linebreak: 'LineBreakNode',
11
- tab: 'TabNode',
12
10
  root: 'RootNode',
11
+ tab: 'TabNode',
12
+ text: 'TextNode',
13
13
  // Block nodes
14
- paragraph: 'ParagraphNode',
15
14
  heading: 'HeadingNode',
16
- quote: 'QuoteNode',
17
15
  list: 'ListNode',
18
16
  listitem: 'ListItemNode',
17
+ paragraph: 'ParagraphNode',
18
+ quote: 'QuoteNode',
19
19
  // Rich content nodes
20
- link: 'LinkNode',
21
20
  code: 'CodeNode',
22
21
  horizontalrule: 'HorizontalRuleNode',
22
+ link: 'LinkNode',
23
23
  // Table nodes
24
24
  table: 'TableNode',
25
- tablerow: 'TableRowNode',
26
25
  tablecell: 'TableCellNode',
26
+ tablerow: 'TableRowNode',
27
27
  // Media nodes
28
28
  image: 'ImageNode'
29
29
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/ai/utilities/nodeToSchemaMap.ts"],"sourcesContent":["/**\n * Maps Lexical node type values to JSON schema definition names.\n * This is used to filter the editor schema based on allowed editor nodes.\n *\n * The keys are the type values that appear in serialized Lexical JSON (e.g., 'heading', 'paragraph').\n * The values are the schema definition names as defined in lexicalJsonSchema.ts.\n */\nexport const nodeTypeToSchemaMap: Record<string, string> = {\n // Core nodes (typically always included)\n text: 'TextNode',\n linebreak: 'LineBreakNode',\n tab: 'TabNode',\n root: 'RootNode',\n\n // Block nodes\n paragraph: 'ParagraphNode',\n heading: 'HeadingNode',\n quote: 'QuoteNode',\n list: 'ListNode',\n listitem: 'ListItemNode',\n\n // Rich content nodes\n link: 'LinkNode',\n code: 'CodeNode',\n horizontalrule: 'HorizontalRuleNode',\n\n // Table nodes\n table: 'TableNode',\n tablerow: 'TableRowNode',\n tablecell: 'TableCellNode',\n\n // Media nodes\n image: 'ImageNode',\n}\n\n/**\n * Core nodes that should always be included in the filtered schema\n */\nexport const coreNodeTypes = ['text', 'linebreak', 'tab', 'root', 'paragraph']\n\n/**\n * Converts a Lexical node class name (e.g., 'HeadingNode') to its type value (e.g., 'heading').\n * This handles the common pattern where node classes are named with the pattern `{Type}Node`.\n */\nexport function nodeClassToType(nodeClassName: string): string {\n // Handle common formats:\n // 'HeadingNode' -> 'heading'\n // 'ParagraphNode' -> 'paragraph'\n // 'HorizontalRuleNode' -> 'horizontalrule'\n return nodeClassName.replace(/Node$/, '').toLowerCase()\n}\n\n/**\n * Converts a set of Lexical node class names to their corresponding schema definition names.\n * Includes core nodes automatically.\n */\nexport function nodeClassesToSchemaDefinitions(nodeClassNames: string[]): string[] {\n const definitions = new Set<string>()\n\n // Always include core nodes\n for (const coreType of coreNodeTypes) {\n const def = nodeTypeToSchemaMap[coreType]\n if (def) {\n definitions.add(def)\n }\n }\n\n // Convert each node class to its definition\n for (const className of nodeClassNames) {\n const type = nodeClassToType(className)\n const def = nodeTypeToSchemaMap[type]\n if (def) {\n definitions.add(def)\n }\n }\n\n return Array.from(definitions)\n}\n"],"names":["nodeTypeToSchemaMap","text","linebreak","tab","root","paragraph","heading","quote","list","listitem","link","code","horizontalrule","table","tablerow","tablecell","image","coreNodeTypes","nodeClassToType","nodeClassName","replace","toLowerCase","nodeClassesToSchemaDefinitions","nodeClassNames","definitions","Set","coreType","def","add","className","type","Array","from"],"mappings":"AAAA;;;;;;CAMC,GACD,OAAO,MAAMA,sBAA8C;IACzD,yCAAyC;IACzCC,MAAM;IACNC,WAAW;IACXC,KAAK;IACLC,MAAM;IAEN,cAAc;IACdC,WAAW;IACXC,SAAS;IACTC,OAAO;IACPC,MAAM;IACNC,UAAU;IAEV,qBAAqB;IACrBC,MAAM;IACNC,MAAM;IACNC,gBAAgB;IAEhB,cAAc;IACdC,OAAO;IACPC,UAAU;IACVC,WAAW;IAEX,cAAc;IACdC,OAAO;AACT,EAAC;AAED;;CAEC,GACD,OAAO,MAAMC,gBAAgB;IAAC;IAAQ;IAAa;IAAO;IAAQ;CAAY,CAAA;AAE9E;;;CAGC,GACD,OAAO,SAASC,gBAAgBC,aAAqB;IACnD,yBAAyB;IACzB,6BAA6B;IAC7B,iCAAiC;IACjC,2CAA2C;IAC3C,OAAOA,cAAcC,OAAO,CAAC,SAAS,IAAIC,WAAW;AACvD;AAEA;;;CAGC,GACD,OAAO,SAASC,+BAA+BC,cAAwB;IACrE,MAAMC,cAAc,IAAIC;IAExB,4BAA4B;IAC5B,KAAK,MAAMC,YAAYT,cAAe;QACpC,MAAMU,MAAM3B,mBAAmB,CAAC0B,SAAS;QACzC,IAAIC,KAAK;YACPH,YAAYI,GAAG,CAACD;QAClB;IACF;IAEA,4CAA4C;IAC5C,KAAK,MAAME,aAAaN,eAAgB;QACtC,MAAMO,OAAOZ,gBAAgBW;QAC7B,MAAMF,MAAM3B,mBAAmB,CAAC8B,KAAK;QACrC,IAAIH,KAAK;YACPH,YAAYI,GAAG,CAACD;QAClB;IACF;IAEA,OAAOI,MAAMC,IAAI,CAACR;AACpB"}
1
+ {"version":3,"sources":["../../../src/ai/utilities/nodeToSchemaMap.ts"],"sourcesContent":["/**\n * Maps Lexical node type values to JSON schema definition names.\n * This is used to filter the editor schema based on allowed editor nodes.\n *\n * The keys are the type values that appear in serialized Lexical JSON (e.g., 'heading', 'paragraph').\n * The values are the schema definition names as defined in lexicalJsonSchema.ts.\n */\nexport const nodeTypeToSchemaMap: Record<string, string> = {\n // Core nodes (typically always included)\n linebreak: 'LineBreakNode',\n root: 'RootNode',\n tab: 'TabNode',\n text: 'TextNode',\n\n // Block nodes\n heading: 'HeadingNode',\n list: 'ListNode',\n listitem: 'ListItemNode',\n paragraph: 'ParagraphNode',\n quote: 'QuoteNode',\n\n // Rich content nodes\n code: 'CodeNode',\n horizontalrule: 'HorizontalRuleNode',\n link: 'LinkNode',\n\n // Table nodes\n table: 'TableNode',\n tablecell: 'TableCellNode',\n tablerow: 'TableRowNode',\n\n // Media nodes\n image: 'ImageNode',\n}\n\n/**\n * Core nodes that should always be included in the filtered schema\n */\nexport const coreNodeTypes = ['text', 'linebreak', 'tab', 'root', 'paragraph']\n\n/**\n * Converts a Lexical node class name (e.g., 'HeadingNode') to its type value (e.g., 'heading').\n * This handles the common pattern where node classes are named with the pattern `{Type}Node`.\n */\nexport function nodeClassToType(nodeClassName: string): string {\n // Handle common formats:\n // 'HeadingNode' -> 'heading'\n // 'ParagraphNode' -> 'paragraph'\n // 'HorizontalRuleNode' -> 'horizontalrule'\n return nodeClassName.replace(/Node$/, '').toLowerCase()\n}\n\n/**\n * Converts a set of Lexical node class names to their corresponding schema definition names.\n * Includes core nodes automatically.\n */\nexport function nodeClassesToSchemaDefinitions(nodeClassNames: string[]): string[] {\n const definitions = new Set<string>()\n\n // Always include core nodes\n for (const coreType of coreNodeTypes) {\n const def = nodeTypeToSchemaMap[coreType]\n if (def) {\n definitions.add(def)\n }\n }\n\n // Convert each node class to its definition\n for (const className of nodeClassNames) {\n const type = nodeClassToType(className)\n const def = nodeTypeToSchemaMap[type]\n if (def) {\n definitions.add(def)\n }\n }\n\n return Array.from(definitions)\n}\n"],"names":["nodeTypeToSchemaMap","linebreak","root","tab","text","heading","list","listitem","paragraph","quote","code","horizontalrule","link","table","tablecell","tablerow","image","coreNodeTypes","nodeClassToType","nodeClassName","replace","toLowerCase","nodeClassesToSchemaDefinitions","nodeClassNames","definitions","Set","coreType","def","add","className","type","Array","from"],"mappings":"AAAA;;;;;;CAMC,GACD,OAAO,MAAMA,sBAA8C;IACzD,yCAAyC;IACzCC,WAAW;IACXC,MAAM;IACNC,KAAK;IACLC,MAAM;IAEN,cAAc;IACdC,SAAS;IACTC,MAAM;IACNC,UAAU;IACVC,WAAW;IACXC,OAAO;IAEP,qBAAqB;IACrBC,MAAM;IACNC,gBAAgB;IAChBC,MAAM;IAEN,cAAc;IACdC,OAAO;IACPC,WAAW;IACXC,UAAU;IAEV,cAAc;IACdC,OAAO;AACT,EAAC;AAED;;CAEC,GACD,OAAO,MAAMC,gBAAgB;IAAC;IAAQ;IAAa;IAAO;IAAQ;CAAY,CAAA;AAE9E;;;CAGC,GACD,OAAO,SAASC,gBAAgBC,aAAqB;IACnD,yBAAyB;IACzB,6BAA6B;IAC7B,iCAAiC;IACjC,2CAA2C;IAC3C,OAAOA,cAAcC,OAAO,CAAC,SAAS,IAAIC,WAAW;AACvD;AAEA;;;CAGC,GACD,OAAO,SAASC,+BAA+BC,cAAwB;IACrE,MAAMC,cAAc,IAAIC;IAExB,4BAA4B;IAC5B,KAAK,MAAMC,YAAYT,cAAe;QACpC,MAAMU,MAAM3B,mBAAmB,CAAC0B,SAAS;QACzC,IAAIC,KAAK;YACPH,YAAYI,GAAG,CAACD;QAClB;IACF;IAEA,4CAA4C;IAC5C,KAAK,MAAME,aAAaN,eAAgB;QACtC,MAAMO,OAAOZ,gBAAgBW;QAC7B,MAAMF,MAAM3B,mBAAmB,CAAC8B,KAAK;QACrC,IAAIH,KAAK;YACPH,YAAYI,GAAG,CAACD;QAClB;IACF;IAEA,OAAOI,MAAMC,IAAI,CAACR;AACpB"}
@@ -50,7 +50,7 @@ export const AIProvidersGlobal = {
50
50
  type: 'text',
51
51
  admin: {
52
52
  components: {
53
- Field: '@ai-stack/payloadcms/client#DynamicProviderSelect'
53
+ Field: '@ai-stack/payloadcms/ui/DynamicProviderSelect/index.js#DynamicProviderSelect'
54
54
  }
55
55
  },
56
56
  label: 'Default Provider'
@@ -60,7 +60,7 @@ export const AIProvidersGlobal = {
60
60
  type: 'text',
61
61
  admin: {
62
62
  components: {
63
- Field: '@ai-stack/payloadcms/client#DynamicModelSelect'
63
+ Field: '@ai-stack/payloadcms/ui/DynamicModelSelect/index.js#DynamicModelSelect'
64
64
  }
65
65
  },
66
66
  label: 'Default Model'
@@ -70,7 +70,7 @@ export const AIProvidersGlobal = {
70
70
  type: 'json',
71
71
  admin: {
72
72
  components: {
73
- Field: '@ai-stack/payloadcms/client#GlobalProviderOptions'
73
+ Field: '@ai-stack/payloadcms/ui/GlobalProviderOptions/index.js#GlobalProviderOptions'
74
74
  }
75
75
  },
76
76
  label: 'Provider Options'
@@ -99,7 +99,7 @@ export const AIProvidersGlobal = {
99
99
  type: 'text',
100
100
  admin: {
101
101
  components: {
102
- Field: '@ai-stack/payloadcms/client#DynamicProviderSelect'
102
+ Field: '@ai-stack/payloadcms/ui/DynamicProviderSelect/index.js#DynamicProviderSelect'
103
103
  }
104
104
  },
105
105
  label: 'Default Provider'
@@ -109,7 +109,7 @@ export const AIProvidersGlobal = {
109
109
  type: 'text',
110
110
  admin: {
111
111
  components: {
112
- Field: '@ai-stack/payloadcms/client#DynamicModelSelect'
112
+ Field: '@ai-stack/payloadcms/ui/DynamicModelSelect/index.js#DynamicModelSelect'
113
113
  }
114
114
  },
115
115
  label: 'Default Model'
@@ -119,7 +119,7 @@ export const AIProvidersGlobal = {
119
119
  type: 'json',
120
120
  admin: {
121
121
  components: {
122
- Field: '@ai-stack/payloadcms/client#GlobalProviderOptions'
122
+ Field: '@ai-stack/payloadcms/ui/GlobalProviderOptions/index.js#GlobalProviderOptions'
123
123
  }
124
124
  },
125
125
  label: 'Provider Options'
@@ -148,7 +148,7 @@ export const AIProvidersGlobal = {
148
148
  type: 'text',
149
149
  admin: {
150
150
  components: {
151
- Field: '@ai-stack/payloadcms/client#DynamicProviderSelect'
151
+ Field: '@ai-stack/payloadcms/ui/DynamicProviderSelect/index.js#DynamicProviderSelect'
152
152
  }
153
153
  },
154
154
  label: 'Default Provider'
@@ -158,7 +158,7 @@ export const AIProvidersGlobal = {
158
158
  type: 'text',
159
159
  admin: {
160
160
  components: {
161
- Field: '@ai-stack/payloadcms/client#DynamicModelSelect'
161
+ Field: '@ai-stack/payloadcms/ui/DynamicModelSelect/index.js#DynamicModelSelect'
162
162
  }
163
163
  },
164
164
  label: 'Default Model'
@@ -168,7 +168,7 @@ export const AIProvidersGlobal = {
168
168
  type: 'text',
169
169
  admin: {
170
170
  components: {
171
- Field: '@ai-stack/payloadcms/client#DynamicVoiceSelect'
171
+ Field: '@ai-stack/payloadcms/ui/DynamicVoiceSelect/index.js#DynamicVoiceSelect'
172
172
  }
173
173
  },
174
174
  label: 'Default Voice'
@@ -178,7 +178,7 @@ export const AIProvidersGlobal = {
178
178
  type: 'json',
179
179
  admin: {
180
180
  components: {
181
- Field: '@ai-stack/payloadcms/client#GlobalProviderOptions'
181
+ Field: '@ai-stack/payloadcms/ui/GlobalProviderOptions/index.js#GlobalProviderOptions'
182
182
  }
183
183
  },
184
184
  label: 'Provider Options'
@@ -210,7 +210,7 @@ export const AIProvidersGlobal = {
210
210
  type: 'text',
211
211
  admin: {
212
212
  components: {
213
- Field: '@ai-stack/payloadcms/client#DynamicProviderSelect'
213
+ Field: '@ai-stack/payloadcms/ui/DynamicProviderSelect/index.js#DynamicProviderSelect'
214
214
  }
215
215
  },
216
216
  label: 'Default Provider'
@@ -220,7 +220,7 @@ export const AIProvidersGlobal = {
220
220
  type: 'text',
221
221
  admin: {
222
222
  components: {
223
- Field: '@ai-stack/payloadcms/client#DynamicModelSelect'
223
+ Field: '@ai-stack/payloadcms/ui/DynamicModelSelect/index.js#DynamicModelSelect'
224
224
  }
225
225
  },
226
226
  label: 'Default Model'
@@ -230,7 +230,7 @@ export const AIProvidersGlobal = {
230
230
  type: 'json',
231
231
  admin: {
232
232
  components: {
233
- Field: '@ai-stack/payloadcms/client#GlobalProviderOptions'
233
+ Field: '@ai-stack/payloadcms/ui/GlobalProviderOptions/index.js#GlobalProviderOptions'
234
234
  }
235
235
  },
236
236
  label: 'Provider Options'
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/collections/AIProviders.ts"],"sourcesContent":["import type { GlobalConfig } from 'payload'\n\nimport { allProviderBlocks } from '../ai/providers/blocks/index.js'\nimport { invalidateProviderCache } from '../ai/providers/registry.js'\n\nexport const AIProvidersGlobal: GlobalConfig = {\n slug: 'ai-providers',\n access: {\n read: ({ req }) => !!req.user,\n update: ({ req }) => !!req.user,\n },\n admin: {\n description: 'Connect your providers and choose the default models used across your project.',\n group: false,\n },\n fields: [\n {\n name: 'providers',\n type: 'blocks',\n admin: {\n description:\n 'Add one or more providers and set their credentials and settings. You can keep multiple providers and switch defaults below.',\n initCollapsed: true,\n },\n blocks: allProviderBlocks,\n label: 'AI Providers',\n required: true,\n },\n {\n name: 'enabledCollections',\n type: 'json',\n admin: {\n hidden: true,\n },\n },\n {\n name: 'defaults',\n type: 'group',\n admin: {\n description:\n 'Pick the default provider and model for each feature. These defaults are used unless a collection or field overrides them.',\n },\n fields: [\n {\n type: 'tabs',\n tabs: [\n {\n fields: [\n {\n name: 'text',\n type: 'group',\n fields: [\n {\n name: 'provider',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#DynamicProviderSelect',\n },\n },\n label: 'Default Provider',\n },\n {\n name: 'model',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#DynamicModelSelect',\n },\n },\n label: 'Default Model',\n },\n {\n name: 'providerOptions',\n type: 'json',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#GlobalProviderOptions',\n },\n },\n label: 'Provider Options',\n },\n {\n name: 'schema',\n type: 'json',\n admin: {\n hidden: true,\n },\n },\n ],\n label: '',\n },\n ],\n label: 'Text Generation',\n },\n {\n fields: [\n {\n name: 'image',\n type: 'group',\n fields: [\n {\n name: 'provider',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#DynamicProviderSelect',\n },\n },\n label: 'Default Provider',\n },\n {\n name: 'model',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#DynamicModelSelect',\n },\n },\n label: 'Default Model',\n },\n {\n name: 'providerOptions',\n type: 'json',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#GlobalProviderOptions',\n },\n },\n label: 'Provider Options',\n },\n {\n name: 'schema',\n type: 'json',\n admin: {\n hidden: true,\n },\n },\n ],\n label: '',\n },\n ],\n label: 'Image Generation',\n },\n {\n fields: [\n {\n name: 'tts',\n type: 'group',\n fields: [\n {\n name: 'provider',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#DynamicProviderSelect',\n },\n },\n label: 'Default Provider',\n },\n {\n name: 'model',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#DynamicModelSelect',\n },\n },\n label: 'Default Model',\n },\n {\n name: 'voice',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#DynamicVoiceSelect',\n },\n },\n label: 'Default Voice',\n },\n {\n name: 'providerOptions',\n type: 'json',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#GlobalProviderOptions',\n },\n },\n label: 'Provider Options',\n },\n {\n name: 'schema',\n type: 'json',\n admin: {\n hidden: true,\n },\n },\n ],\n label: '',\n },\n ],\n label: 'Speech Generation',\n },\n {\n admin: {\n disabled: true,\n },\n fields: [\n {\n name: 'video',\n type: 'group',\n fields: [\n {\n name: 'provider',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#DynamicProviderSelect',\n },\n },\n label: 'Default Provider',\n },\n {\n name: 'model',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#DynamicModelSelect',\n },\n },\n label: 'Default Model',\n },\n {\n name: 'providerOptions',\n type: 'json',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#GlobalProviderOptions',\n },\n },\n label: 'Provider Options',\n },\n {\n name: 'schema',\n type: 'json',\n admin: {\n hidden: true,\n },\n },\n ],\n label: '',\n },\n ],\n label: 'Video Generation',\n },\n ],\n },\n ],\n label: 'Default Models',\n },\n ],\n hooks: {\n afterChange: [\n async ({ doc, req }) => {\n // Immediately invalidate cached provider registry so new settings take effect\n invalidateProviderCache()\n\n if (doc.enabledCollections && doc.enabledCollections.length > 0) {\n const { seedProperties } = await import('../utilities/seedProperties.js')\n await seedProperties({\n enabledCollections: doc.enabledCollections,\n req,\n })\n }\n return doc\n },\n ],\n afterRead: [\n async ({ context, doc, req }) => {\n if (!req.payload.secret) {\n return doc\n }\n\n const { decrypt } = await import('../utilities/encryption.js')\n\n if (doc.providers) {\n doc.providers = doc.providers.map((provider: any) => {\n if (provider.apiKey) {\n if (context.unsafe) {\n // Internal use: decrypt\n provider.apiKey = decrypt(provider.apiKey, req.payload.secret)\n } else {\n // Admin UI: mask\n // We can't easily check if it's valid without decrypting, but for UI we just show mask\n // If we want to show \"present\", we can return a mask\n provider.apiKey = 'sk-****' + provider.apiKey.slice(-4)\n }\n }\n return provider\n })\n }\n return doc\n },\n ],\n beforeChange: [\n async ({ data, originalDoc, req }) => {\n if (!req.payload.secret) {\n return data\n }\n\n const { encrypt } = await import('../utilities/encryption.js')\n\n // Iterate over providers and encrypt API keys\n if (data.providers) {\n data.providers = data.providers.map((provider: any) => {\n if (provider.apiKey) {\n const originalProvider = originalDoc?.providers?.find(\n (p: any) => p.id === provider.id,\n )\n\n // If the key strictly equals the existing one (e.g. partial update merge), do nothing.\n // This prevents re-encrypting an already encrypted key.\n if (originalProvider?.apiKey && provider.apiKey === originalProvider.apiKey) {\n return provider\n }\n\n // If it looks like a masked key, don't re-encrypt (it means it wasn't changed via UI)\n if (provider.apiKey.startsWith('sk-') && provider.apiKey.includes('****')) {\n // Restore the original encrypted key from originalDoc\n if (originalProvider?.apiKey) {\n provider.apiKey = originalProvider.apiKey\n }\n } else {\n // Encrypt new key\n provider.apiKey = encrypt(provider.apiKey, req.payload.secret)\n }\n }\n return provider\n })\n }\n return data\n },\n ],\n },\n label: 'AI Providers',\n}\n"],"names":["allProviderBlocks","invalidateProviderCache","AIProvidersGlobal","slug","access","read","req","user","update","admin","description","group","fields","name","type","initCollapsed","blocks","label","required","hidden","tabs","components","Field","disabled","hooks","afterChange","doc","enabledCollections","length","seedProperties","afterRead","context","payload","secret","decrypt","providers","map","provider","apiKey","unsafe","slice","beforeChange","data","originalDoc","encrypt","originalProvider","find","p","id","startsWith","includes"],"mappings":"AAEA,SAASA,iBAAiB,QAAQ,kCAAiC;AACnE,SAASC,uBAAuB,QAAQ,8BAA6B;AAErE,OAAO,MAAMC,oBAAkC;IAC7CC,MAAM;IACNC,QAAQ;QACNC,MAAM,CAAC,EAAEC,GAAG,EAAE,GAAK,CAAC,CAACA,IAAIC,IAAI;QAC7BC,QAAQ,CAAC,EAAEF,GAAG,EAAE,GAAK,CAAC,CAACA,IAAIC,IAAI;IACjC;IACAE,OAAO;QACLC,aAAa;QACbC,OAAO;IACT;IACAC,QAAQ;QACN;YACEC,MAAM;YACNC,MAAM;YACNL,OAAO;gBACLC,aACE;gBACFK,eAAe;YACjB;YACAC,QAAQhB;YACRiB,OAAO;YACPC,UAAU;QACZ;QACA;YACEL,MAAM;YACNC,MAAM;YACNL,OAAO;gBACLU,QAAQ;YACV;QACF;QACA;YACEN,MAAM;YACNC,MAAM;YACNL,OAAO;gBACLC,aACE;YACJ;YACAE,QAAQ;gBACN;oBACEE,MAAM;oBACNM,MAAM;wBACJ;4BACER,QAAQ;gCACN;oCACEC,MAAM;oCACNC,MAAM;oCACNF,QAAQ;wCACN;4CACEC,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLU,QAAQ;4CACV;wCACF;qCACD;oCACDF,OAAO;gCACT;6BACD;4BACDA,OAAO;wBACT;wBACA;4BACEL,QAAQ;gCACN;oCACEC,MAAM;oCACNC,MAAM;oCACNF,QAAQ;wCACN;4CACEC,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLU,QAAQ;4CACV;wCACF;qCACD;oCACDF,OAAO;gCACT;6BACD;4BACDA,OAAO;wBACT;wBACA;4BACEL,QAAQ;gCACN;oCACEC,MAAM;oCACNC,MAAM;oCACNF,QAAQ;wCACN;4CACEC,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLU,QAAQ;4CACV;wCACF;qCACD;oCACDF,OAAO;gCACT;6BACD;4BACDA,OAAO;wBACT;wBACA;4BACER,OAAO;gCACLc,UAAU;4BACZ;4BACAX,QAAQ;gCACN;oCACEC,MAAM;oCACNC,MAAM;oCACNF,QAAQ;wCACN;4CACEC,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLU,QAAQ;4CACV;wCACF;qCACD;oCACDF,OAAO;gCACT;6BACD;4BACDA,OAAO;wBACT;qBACD;gBACH;aACD;YACDA,OAAO;QACT;KACD;IACDO,OAAO;QACLC,aAAa;YACX,OAAO,EAAEC,GAAG,EAAEpB,GAAG,EAAE;gBACjB,8EAA8E;gBAC9EL;gBAEA,IAAIyB,IAAIC,kBAAkB,IAAID,IAAIC,kBAAkB,CAACC,MAAM,GAAG,GAAG;oBAC/D,MAAM,EAAEC,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC;oBACxC,MAAMA,eAAe;wBACnBF,oBAAoBD,IAAIC,kBAAkB;wBAC1CrB;oBACF;gBACF;gBACA,OAAOoB;YACT;SACD;QACDI,WAAW;YACT,OAAO,EAAEC,OAAO,EAAEL,GAAG,EAAEpB,GAAG,EAAE;gBAC1B,IAAI,CAACA,IAAI0B,OAAO,CAACC,MAAM,EAAE;oBACvB,OAAOP;gBACT;gBAEA,MAAM,EAAEQ,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC;gBAEjC,IAAIR,IAAIS,SAAS,EAAE;oBACjBT,IAAIS,SAAS,GAAGT,IAAIS,SAAS,CAACC,GAAG,CAAC,CAACC;wBACjC,IAAIA,SAASC,MAAM,EAAE;4BACnB,IAAIP,QAAQQ,MAAM,EAAE;gCAClB,wBAAwB;gCACxBF,SAASC,MAAM,GAAGJ,QAAQG,SAASC,MAAM,EAAEhC,IAAI0B,OAAO,CAACC,MAAM;4BAC/D,OAAO;gCACL,iBAAiB;gCACjB,uFAAuF;gCACvF,qDAAqD;gCACrDI,SAASC,MAAM,GAAG,YAAYD,SAASC,MAAM,CAACE,KAAK,CAAC,CAAC;4BACvD;wBACF;wBACA,OAAOH;oBACT;gBACF;gBACA,OAAOX;YACT;SACD;QACDe,cAAc;YACZ,OAAO,EAAEC,IAAI,EAAEC,WAAW,EAAErC,GAAG,EAAE;gBAC/B,IAAI,CAACA,IAAI0B,OAAO,CAACC,MAAM,EAAE;oBACvB,OAAOS;gBACT;gBAEA,MAAM,EAAEE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC;gBAEjC,8CAA8C;gBAC9C,IAAIF,KAAKP,SAAS,EAAE;oBAClBO,KAAKP,SAAS,GAAGO,KAAKP,SAAS,CAACC,GAAG,CAAC,CAACC;wBACnC,IAAIA,SAASC,MAAM,EAAE;4BACnB,MAAMO,mBAAmBF,aAAaR,WAAWW,KAC/C,CAACC,IAAWA,EAAEC,EAAE,KAAKX,SAASW,EAAE;4BAGlC,uFAAuF;4BACvF,wDAAwD;4BACxD,IAAIH,kBAAkBP,UAAUD,SAASC,MAAM,KAAKO,iBAAiBP,MAAM,EAAE;gCAC3E,OAAOD;4BACT;4BAEA,sFAAsF;4BACtF,IAAIA,SAASC,MAAM,CAACW,UAAU,CAAC,UAAUZ,SAASC,MAAM,CAACY,QAAQ,CAAC,SAAS;gCACzE,sDAAsD;gCACtD,IAAIL,kBAAkBP,QAAQ;oCAC5BD,SAASC,MAAM,GAAGO,iBAAiBP,MAAM;gCAC3C;4BACF,OAAO;gCACL,kBAAkB;gCAClBD,SAASC,MAAM,GAAGM,QAAQP,SAASC,MAAM,EAAEhC,IAAI0B,OAAO,CAACC,MAAM;4BAC/D;wBACF;wBACA,OAAOI;oBACT;gBACF;gBACA,OAAOK;YACT;SACD;IACH;IACAzB,OAAO;AACT,EAAC"}
1
+ {"version":3,"sources":["../../src/collections/AIProviders.ts"],"sourcesContent":["import type { GlobalConfig } from 'payload'\n\nimport { allProviderBlocks } from '../ai/providers/blocks/index.js'\nimport { invalidateProviderCache } from '../ai/providers/registry.js'\n\nexport const AIProvidersGlobal: GlobalConfig = {\n slug: 'ai-providers',\n access: {\n read: ({ req }) => !!req.user,\n update: ({ req }) => !!req.user,\n },\n admin: {\n description: 'Connect your providers and choose the default models used across your project.',\n group: false,\n },\n fields: [\n {\n name: 'providers',\n type: 'blocks',\n admin: {\n description:\n 'Add one or more providers and set their credentials and settings. You can keep multiple providers and switch defaults below.',\n initCollapsed: true,\n },\n blocks: allProviderBlocks,\n label: 'AI Providers',\n required: true,\n },\n {\n name: 'enabledCollections',\n type: 'json',\n admin: {\n hidden: true,\n },\n },\n {\n name: 'defaults',\n type: 'group',\n admin: {\n description:\n 'Pick the default provider and model for each feature. These defaults are used unless a collection or field overrides them.',\n },\n fields: [\n {\n type: 'tabs',\n tabs: [\n {\n fields: [\n {\n name: 'text',\n type: 'group',\n fields: [\n {\n name: 'provider',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicProviderSelect/index.js#DynamicProviderSelect',\n },\n },\n label: 'Default Provider',\n },\n {\n name: 'model',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicModelSelect/index.js#DynamicModelSelect',\n },\n },\n label: 'Default Model',\n },\n {\n name: 'providerOptions',\n type: 'json',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/GlobalProviderOptions/index.js#GlobalProviderOptions',\n },\n },\n label: 'Provider Options',\n },\n {\n name: 'schema',\n type: 'json',\n admin: {\n hidden: true,\n },\n },\n ],\n label: '',\n },\n ],\n label: 'Text Generation',\n },\n {\n fields: [\n {\n name: 'image',\n type: 'group',\n fields: [\n {\n name: 'provider',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicProviderSelect/index.js#DynamicProviderSelect',\n },\n },\n label: 'Default Provider',\n },\n {\n name: 'model',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicModelSelect/index.js#DynamicModelSelect',\n },\n },\n label: 'Default Model',\n },\n {\n name: 'providerOptions',\n type: 'json',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/GlobalProviderOptions/index.js#GlobalProviderOptions',\n },\n },\n label: 'Provider Options',\n },\n {\n name: 'schema',\n type: 'json',\n admin: {\n hidden: true,\n },\n },\n ],\n label: '',\n },\n ],\n label: 'Image Generation',\n },\n {\n fields: [\n {\n name: 'tts',\n type: 'group',\n fields: [\n {\n name: 'provider',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicProviderSelect/index.js#DynamicProviderSelect',\n },\n },\n label: 'Default Provider',\n },\n {\n name: 'model',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicModelSelect/index.js#DynamicModelSelect',\n },\n },\n label: 'Default Model',\n },\n {\n name: 'voice',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicVoiceSelect/index.js#DynamicVoiceSelect',\n },\n },\n label: 'Default Voice',\n },\n {\n name: 'providerOptions',\n type: 'json',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/GlobalProviderOptions/index.js#GlobalProviderOptions',\n },\n },\n label: 'Provider Options',\n },\n {\n name: 'schema',\n type: 'json',\n admin: {\n hidden: true,\n },\n },\n ],\n label: '',\n },\n ],\n label: 'Speech Generation',\n },\n {\n admin: {\n disabled: true,\n },\n fields: [\n {\n name: 'video',\n type: 'group',\n fields: [\n {\n name: 'provider',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicProviderSelect/index.js#DynamicProviderSelect',\n },\n },\n label: 'Default Provider',\n },\n {\n name: 'model',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicModelSelect/index.js#DynamicModelSelect',\n },\n },\n label: 'Default Model',\n },\n {\n name: 'providerOptions',\n type: 'json',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/GlobalProviderOptions/index.js#GlobalProviderOptions',\n },\n },\n label: 'Provider Options',\n },\n {\n name: 'schema',\n type: 'json',\n admin: {\n hidden: true,\n },\n },\n ],\n label: '',\n },\n ],\n label: 'Video Generation',\n },\n ],\n },\n ],\n label: 'Default Models',\n },\n ],\n hooks: {\n afterChange: [\n async ({ doc, req }) => {\n // Immediately invalidate cached provider registry so new settings take effect\n invalidateProviderCache()\n\n if (doc.enabledCollections && doc.enabledCollections.length > 0) {\n const { seedProperties } = await import('../utilities/seedProperties.js')\n await seedProperties({\n enabledCollections: doc.enabledCollections,\n req,\n })\n }\n return doc\n },\n ],\n afterRead: [\n async ({ context, doc, req }) => {\n if (!req.payload.secret) {\n return doc\n }\n\n const { decrypt } = await import('../utilities/encryption.js')\n\n if (doc.providers) {\n doc.providers = doc.providers.map((provider: any) => {\n if (provider.apiKey) {\n if (context.unsafe) {\n // Internal use: decrypt\n provider.apiKey = decrypt(provider.apiKey, req.payload.secret)\n } else {\n // Admin UI: mask\n // We can't easily check if it's valid without decrypting, but for UI we just show mask\n // If we want to show \"present\", we can return a mask\n provider.apiKey = 'sk-****' + provider.apiKey.slice(-4)\n }\n }\n return provider\n })\n }\n return doc\n },\n ],\n beforeChange: [\n async ({ data, originalDoc, req }) => {\n if (!req.payload.secret) {\n return data\n }\n\n const { encrypt } = await import('../utilities/encryption.js')\n\n // Iterate over providers and encrypt API keys\n if (data.providers) {\n data.providers = data.providers.map((provider: any) => {\n if (provider.apiKey) {\n const originalProvider = originalDoc?.providers?.find(\n (p: any) => p.id === provider.id,\n )\n\n // If the key strictly equals the existing one (e.g. partial update merge), do nothing.\n // This prevents re-encrypting an already encrypted key.\n if (originalProvider?.apiKey && provider.apiKey === originalProvider.apiKey) {\n return provider\n }\n\n // If it looks like a masked key, don't re-encrypt (it means it wasn't changed via UI)\n if (provider.apiKey.startsWith('sk-') && provider.apiKey.includes('****')) {\n // Restore the original encrypted key from originalDoc\n if (originalProvider?.apiKey) {\n provider.apiKey = originalProvider.apiKey\n }\n } else {\n // Encrypt new key\n provider.apiKey = encrypt(provider.apiKey, req.payload.secret)\n }\n }\n return provider\n })\n }\n return data\n },\n ],\n },\n label: 'AI Providers',\n}\n"],"names":["allProviderBlocks","invalidateProviderCache","AIProvidersGlobal","slug","access","read","req","user","update","admin","description","group","fields","name","type","initCollapsed","blocks","label","required","hidden","tabs","components","Field","disabled","hooks","afterChange","doc","enabledCollections","length","seedProperties","afterRead","context","payload","secret","decrypt","providers","map","provider","apiKey","unsafe","slice","beforeChange","data","originalDoc","encrypt","originalProvider","find","p","id","startsWith","includes"],"mappings":"AAEA,SAASA,iBAAiB,QAAQ,kCAAiC;AACnE,SAASC,uBAAuB,QAAQ,8BAA6B;AAErE,OAAO,MAAMC,oBAAkC;IAC7CC,MAAM;IACNC,QAAQ;QACNC,MAAM,CAAC,EAAEC,GAAG,EAAE,GAAK,CAAC,CAACA,IAAIC,IAAI;QAC7BC,QAAQ,CAAC,EAAEF,GAAG,EAAE,GAAK,CAAC,CAACA,IAAIC,IAAI;IACjC;IACAE,OAAO;QACLC,aAAa;QACbC,OAAO;IACT;IACAC,QAAQ;QACN;YACEC,MAAM;YACNC,MAAM;YACNL,OAAO;gBACLC,aACE;gBACFK,eAAe;YACjB;YACAC,QAAQhB;YACRiB,OAAO;YACPC,UAAU;QACZ;QACA;YACEL,MAAM;YACNC,MAAM;YACNL,OAAO;gBACLU,QAAQ;YACV;QACF;QACA;YACEN,MAAM;YACNC,MAAM;YACNL,OAAO;gBACLC,aACE;YACJ;YACAE,QAAQ;gBACN;oBACEE,MAAM;oBACNM,MAAM;wBACJ;4BACER,QAAQ;gCACN;oCACEC,MAAM;oCACNC,MAAM;oCACNF,QAAQ;wCACN;4CACEC,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLU,QAAQ;4CACV;wCACF;qCACD;oCACDF,OAAO;gCACT;6BACD;4BACDA,OAAO;wBACT;wBACA;4BACEL,QAAQ;gCACN;oCACEC,MAAM;oCACNC,MAAM;oCACNF,QAAQ;wCACN;4CACEC,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLU,QAAQ;4CACV;wCACF;qCACD;oCACDF,OAAO;gCACT;6BACD;4BACDA,OAAO;wBACT;wBACA;4BACEL,QAAQ;gCACN;oCACEC,MAAM;oCACNC,MAAM;oCACNF,QAAQ;wCACN;4CACEC,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLU,QAAQ;4CACV;wCACF;qCACD;oCACDF,OAAO;gCACT;6BACD;4BACDA,OAAO;wBACT;wBACA;4BACER,OAAO;gCACLc,UAAU;4BACZ;4BACAX,QAAQ;gCACN;oCACEC,MAAM;oCACNC,MAAM;oCACNF,QAAQ;wCACN;4CACEC,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLY,YAAY;oDACVC,OAAO;gDACT;4CACF;4CACAL,OAAO;wCACT;wCACA;4CACEJ,MAAM;4CACNC,MAAM;4CACNL,OAAO;gDACLU,QAAQ;4CACV;wCACF;qCACD;oCACDF,OAAO;gCACT;6BACD;4BACDA,OAAO;wBACT;qBACD;gBACH;aACD;YACDA,OAAO;QACT;KACD;IACDO,OAAO;QACLC,aAAa;YACX,OAAO,EAAEC,GAAG,EAAEpB,GAAG,EAAE;gBACjB,8EAA8E;gBAC9EL;gBAEA,IAAIyB,IAAIC,kBAAkB,IAAID,IAAIC,kBAAkB,CAACC,MAAM,GAAG,GAAG;oBAC/D,MAAM,EAAEC,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC;oBACxC,MAAMA,eAAe;wBACnBF,oBAAoBD,IAAIC,kBAAkB;wBAC1CrB;oBACF;gBACF;gBACA,OAAOoB;YACT;SACD;QACDI,WAAW;YACT,OAAO,EAAEC,OAAO,EAAEL,GAAG,EAAEpB,GAAG,EAAE;gBAC1B,IAAI,CAACA,IAAI0B,OAAO,CAACC,MAAM,EAAE;oBACvB,OAAOP;gBACT;gBAEA,MAAM,EAAEQ,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC;gBAEjC,IAAIR,IAAIS,SAAS,EAAE;oBACjBT,IAAIS,SAAS,GAAGT,IAAIS,SAAS,CAACC,GAAG,CAAC,CAACC;wBACjC,IAAIA,SAASC,MAAM,EAAE;4BACnB,IAAIP,QAAQQ,MAAM,EAAE;gCAClB,wBAAwB;gCACxBF,SAASC,MAAM,GAAGJ,QAAQG,SAASC,MAAM,EAAEhC,IAAI0B,OAAO,CAACC,MAAM;4BAC/D,OAAO;gCACL,iBAAiB;gCACjB,uFAAuF;gCACvF,qDAAqD;gCACrDI,SAASC,MAAM,GAAG,YAAYD,SAASC,MAAM,CAACE,KAAK,CAAC,CAAC;4BACvD;wBACF;wBACA,OAAOH;oBACT;gBACF;gBACA,OAAOX;YACT;SACD;QACDe,cAAc;YACZ,OAAO,EAAEC,IAAI,EAAEC,WAAW,EAAErC,GAAG,EAAE;gBAC/B,IAAI,CAACA,IAAI0B,OAAO,CAACC,MAAM,EAAE;oBACvB,OAAOS;gBACT;gBAEA,MAAM,EAAEE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC;gBAEjC,8CAA8C;gBAC9C,IAAIF,KAAKP,SAAS,EAAE;oBAClBO,KAAKP,SAAS,GAAGO,KAAKP,SAAS,CAACC,GAAG,CAAC,CAACC;wBACnC,IAAIA,SAASC,MAAM,EAAE;4BACnB,MAAMO,mBAAmBF,aAAaR,WAAWW,KAC/C,CAACC,IAAWA,EAAEC,EAAE,KAAKX,SAASW,EAAE;4BAGlC,uFAAuF;4BACvF,wDAAwD;4BACxD,IAAIH,kBAAkBP,UAAUD,SAASC,MAAM,KAAKO,iBAAiBP,MAAM,EAAE;gCAC3E,OAAOD;4BACT;4BAEA,sFAAsF;4BACtF,IAAIA,SAASC,MAAM,CAACW,UAAU,CAAC,UAAUZ,SAASC,MAAM,CAACY,QAAQ,CAAC,SAAS;gCACzE,sDAAsD;gCACtD,IAAIL,kBAAkBP,QAAQ;oCAC5BD,SAASC,MAAM,GAAGO,iBAAiBP,MAAM;gCAC3C;4BACF,OAAO;gCACL,kBAAkB;gCAClBD,SAASC,MAAM,GAAGM,QAAQP,SAASC,MAAM,EAAEhC,IAAI0B,OAAO,CAACC,MAAM;4BAC/D;wBACF;wBACA,OAAOI;oBACT;gBACF;gBACA,OAAOK;YACT;SACD;IACH;IACAzB,OAAO;AACT,EAAC"}
@@ -48,7 +48,7 @@ const providerSelect = {
48
48
  type: 'text',
49
49
  admin: {
50
50
  components: {
51
- Field: '@ai-stack/payloadcms/client#DynamicProviderSelect'
51
+ Field: '@ai-stack/payloadcms/ui/DynamicProviderSelect/index.js#DynamicProviderSelect'
52
52
  }
53
53
  },
54
54
  label: 'Provider'
@@ -58,7 +58,7 @@ const modelSelect = {
58
58
  type: 'text',
59
59
  admin: {
60
60
  components: {
61
- Field: '@ai-stack/payloadcms/client#DynamicModelSelect'
61
+ Field: '@ai-stack/payloadcms/ui/DynamicModelSelect/index.js#DynamicModelSelect'
62
62
  }
63
63
  },
64
64
  label: 'Model'
@@ -96,7 +96,7 @@ const providerOptionsUIField = {
96
96
  type: 'json',
97
97
  admin: {
98
98
  components: {
99
- Field: '@ai-stack/payloadcms/client#InstructionProviderOptions'
99
+ Field: '@ai-stack/payloadcms/ui/InstructionProviderOptions/index.js#InstructionProviderOptions'
100
100
  }
101
101
  },
102
102
  label: 'Provider Options'
@@ -118,7 +118,7 @@ export const instructionsCollection = (pluginConfig)=>({
118
118
  ...pluginConfig.overrideInstructions?.admin,
119
119
  components: {
120
120
  beforeList: [
121
- '@ai-stack/payloadcms/client#ConfigDashboard'
121
+ '@ai-stack/payloadcms/ui/ConfigDashboard/index.js#ConfigDashboard'
122
122
  ]
123
123
  }
124
124
  },
@@ -197,7 +197,7 @@ export const instructionsCollection = (pluginConfig)=>({
197
197
  value: c.id
198
198
  }))
199
199
  },
200
- path: '@ai-stack/payloadcms/fields#SelectField'
200
+ path: '@ai-stack/payloadcms/fields/SelectField/SelectField.js#SelectField'
201
201
  }
202
202
  }
203
203
  },
@@ -401,7 +401,7 @@ informative and accurate but also captivating and beautifully structured.`,
401
401
  type: 'text',
402
402
  admin: {
403
403
  components: {
404
- Field: '@ai-stack/payloadcms/client#DynamicVoiceSelect'
404
+ Field: '@ai-stack/payloadcms/ui/DynamicVoiceSelect/index.js#DynamicVoiceSelect'
405
405
  }
406
406
  },
407
407
  label: 'Voice'
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/collections/Instructions.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\nimport type { PluginConfig } from 'src/types.js'\n\nimport { lexicalEditor } from '@payloadcms/richtext-lexical'\n\nimport { PLUGIN_INSTRUCTIONS_TABLE } from '../defaults.js'\nimport { PromptMentionsFeature } from '../fields/PromptEditorField/feature.server.js'\nimport { applyInstructionDefaultsForDisplay } from '../utilities/ai/resolveEffectiveInstructionSettings.js'\nimport { pluginCollectionAccess, pluginCollectionAdmin } from './shared.js'\n\n// Defined capabilities replacing src/ai/models/\nconst CAPABILITIES = [\n {\n id: 'text',\n name: 'Text Generation',\n fields: ['text', 'textarea'],\n },\n {\n id: 'richtext',\n name: 'Rich Text Generation',\n fields: ['richText'],\n },\n {\n id: 'image',\n name: 'Image Generation',\n fields: ['upload'],\n },\n {\n id: 'tts',\n name: 'Text to Speech',\n fields: ['upload'],\n },\n {\n id: 'array',\n name: 'Array Generation',\n fields: ['array'],\n },\n]\n\n\nconst providerSelect = {\n name: 'provider',\n type: 'text' as const,\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#DynamicProviderSelect',\n },\n },\n label: 'Provider',\n}\n\nconst modelSelect = {\n name: 'model',\n type: 'text' as const,\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#DynamicModelSelect',\n },\n },\n label: 'Model',\n}\n\n\nconst commonTextParams = [\n {\n type: 'row' as const,\n fields: [\n {\n name: 'maxTokens',\n type: 'number' as const,\n admin: {\n placeholder: 'Model Default',\n },\n label: 'Max Tokens',\n },\n {\n name: 'temperature',\n type: 'number' as const,\n defaultValue: 0.7,\n label: 'Temperature',\n max: 1,\n min: 0,\n },\n ],\n },\n {\n name: 'extractAttachments',\n type: 'checkbox' as const,\n label: 'Extract Attachments',\n },\n]\n\nconst providerOptionsUIField = {\n name: 'providerOptions',\n type: 'json' as const,\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#InstructionProviderOptions',\n },\n },\n label: 'Provider Options',\n}\n\nexport const instructionsCollection = (pluginConfig: PluginConfig) =>\n <CollectionConfig>{\n labels: {\n plural: 'Compose Settings',\n singular: 'Compose Setting',\n },\n ...pluginConfig.overrideInstructions,\n slug: PLUGIN_INSTRUCTIONS_TABLE,\n access: {\n ...pluginCollectionAccess,\n ...pluginConfig.overrideInstructions?.access,\n },\n admin: {\n description:\n 'Customize how AI interacts with specific fields within your enabled collections.',\n ...pluginCollectionAdmin,\n ...pluginConfig.overrideInstructions?.admin,\n components: {\n beforeList: ['@ai-stack/payloadcms/client#ConfigDashboard'],\n },\n },\n fields: [\n {\n name: 'schema-path',\n type: 'text',\n admin: {\n description: \"Please don't change this unless you're sure of what you're doing\",\n hidden: !pluginConfig.debugging,\n },\n unique: true,\n },\n {\n name: 'field-type',\n type: 'select',\n admin: {\n description: \"Please don't change this unless you're sure of what you're doing\",\n hidden: !pluginConfig.debugging,\n },\n defaultValue: 'text',\n label: 'Field type',\n options: [\n {\n label: 'text',\n value: 'text',\n },\n {\n label: 'textarea',\n value: 'textarea',\n },\n {\n label: 'upload',\n value: 'upload',\n },\n {\n label: 'richText',\n value: 'richText',\n },\n {\n label: 'array',\n value: 'array',\n },\n ],\n },\n {\n name: 'relation-to',\n type: 'text',\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'upload'\n },\n hidden: !pluginConfig.debugging,\n },\n label: 'Relation to',\n },\n {\n name: 'hasMany',\n type: 'checkbox',\n admin: {\n hidden: true,\n },\n defaultValue: false,\n },\n {\n name: 'model-id',\n type: 'select',\n admin: {\n components: {\n Field: {\n clientProps: {\n filterByField: 'field-type',\n options: CAPABILITIES.map((c) => ({\n fields: c.fields,\n label: c.name,\n value: c.id,\n })),\n },\n path: '@ai-stack/payloadcms/fields#SelectField',\n },\n },\n },\n label: 'Capability',\n options: CAPABILITIES.map((c) => ({\n label: c.name,\n value: c.id,\n })),\n },\n {\n name: 'disabled',\n type: 'checkbox',\n admin: {\n description: 'Please reload your collection after applying the changes',\n },\n defaultValue: false,\n label: 'Hide Compose button for this field',\n },\n {\n name: 'alwaysShow',\n type: 'checkbox',\n admin: {\n condition: (_, current) => !current.disabled,\n description: 'Compose button will always be visible without requiring field focus',\n },\n defaultValue: false,\n label: 'Always show Compose button',\n },\n {\n name: 'appendGenerated',\n type: 'checkbox',\n admin: {\n condition: (_, current) => current?.hasMany === true && current?.disabled !== true,\n description: 'If enabled, generated values are appended to current values instead of replacing them.',\n },\n defaultValue: false,\n label: 'Append generated values',\n },\n {\n id: 'ai-prompts-tabs',\n type: 'tabs',\n tabs: [\n {\n description:\n 'Define dynamic templates using {{ fieldName }}. Type { to see available field suggestions.',\n fields: [\n { // TODO: update below to use PromptField\n name: 'prompt',\n type: 'richText',\n admin: {\n description: \"Click 'Compose' to run this custom prompt and generate content\",\n },\n editor: lexicalEditor({\n features: ({ rootFeatures: _rootFeatures }) => [PromptMentionsFeature()],\n }),\n label: '',\n },\n ],\n label: 'Prompt',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'upload' && current['model-id'] === 'image'\n },\n },\n description:\n 'These images will be used to generate new visuals in a similar style, layout, or content.',\n fields: [\n {\n name: 'images',\n type: 'array',\n fields: [\n {\n name: 'image',\n type: 'upload',\n admin: {\n description: 'Please make sure the image is publicly accessible.',\n },\n relationTo: pluginConfig.uploadCollectionSlug\n ? pluginConfig.uploadCollectionSlug\n : 'media',\n },\n ],\n },\n ],\n label: 'Sample Images',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'richText'\n },\n },\n description: '',\n fields: [\n {\n name: 'system',\n type: 'textarea',\n defaultValue: `INSTRUCTIONS:\nYou are a highly skilled and professional blog writer,\nrenowned for crafting engaging and well-organized articles.\nWhen given a title, you meticulously create blogs that are not only\ninformative and accurate but also captivating and beautifully structured.`,\n label: '',\n },\n ],\n label: 'System prompt',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'richText'\n },\n },\n description: '',\n fields: [\n {\n name: 'layout',\n type: 'textarea',\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'richText'\n },\n },\n defaultValue: `[paragraph] - Write a concise introduction (2-3 sentences) that outlines the main topic.\n[horizontalrule] - Insert a horizontal rule to separate the introduction from the main content.\n[list] - Create a list with 3-5 items. Each list item should contain:\n a. [heading] - A brief, descriptive heading (up to 5 words)\n b. [paragraph] - A short explanation or elaboration (1-2 sentences)\n[horizontalrule] - Insert another horizontal rule to separate the main content from the conclusion.\n[paragraph] - Compose a brief conclusion (2-3 sentences) summarizing the key points.\n[quote] - Include a relevant quote from a famous person, directly related to the topic. Format: \"Quote text.\" - Author Name`,\n label: '',\n },\n ],\n label: 'Layout',\n },\n ],\n },\n\n // Inline Settings Groups by Capability\n\n // Text Settings\n {\n name: 'text-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'text',\n },\n fields: [\n providerSelect,\n modelSelect,\n ...commonTextParams,\n providerOptionsUIField,\n ],\n label: 'Text Settings',\n },\n\n // Rich Text Settings\n {\n name: 'richtext-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'richtext',\n },\n fields: [\n providerSelect,\n modelSelect,\n ...commonTextParams,\n providerOptionsUIField,\n ],\n label: 'Rich Text Settings',\n },\n\n // Image Settings\n {\n name: 'image-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'image',\n },\n fields: [providerSelect, modelSelect, providerOptionsUIField],\n label: 'Image Settings',\n },\n\n // TTS Settings\n {\n name: 'tts-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'tts',\n },\n fields: [\n providerSelect,\n modelSelect,\n {\n name: 'voice',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/client#DynamicVoiceSelect',\n },\n },\n label: 'Voice',\n },\n providerOptionsUIField,\n ],\n label: 'TTS Settings',\n },\n\n // Array Settings\n {\n name: 'array-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'array',\n },\n fields: [\n providerSelect,\n modelSelect,\n {\n name: 'count',\n type: 'number',\n admin: {\n description: 'Number of items to generate',\n },\n defaultValue: 3,\n label: 'Items to Generate',\n max: 20,\n min: 1,\n },\n providerOptionsUIField,\n ],\n label: 'Array Settings',\n },\n ],\n hooks: {\n ...pluginConfig.overrideInstructions?.hooks,\n afterRead: [\n ...(pluginConfig.overrideInstructions?.hooks?.afterRead || []),\n async ({ context, doc, req }) => {\n if (!doc || typeof doc !== 'object') {\n return doc\n }\n\n const cacheKey = '__aiProvidersDefaults'\n const hookContext = (context || {}) as Record<string, unknown>\n let defaults = hookContext[cacheKey] as Record<string, unknown> | undefined\n\n if (!defaults) {\n try {\n const aiSettings = await req.payload.findGlobal({\n slug: 'ai-providers',\n })\n defaults = (aiSettings?.defaults || {}) as Record<string, unknown>\n hookContext[cacheKey] = defaults\n } catch (_error) {\n return doc\n }\n }\n\n return applyInstructionDefaultsForDisplay({\n defaults,\n instructions: doc as Record<string, unknown>,\n })\n },\n ],\n },\n }\n"],"names":["lexicalEditor","PLUGIN_INSTRUCTIONS_TABLE","PromptMentionsFeature","applyInstructionDefaultsForDisplay","pluginCollectionAccess","pluginCollectionAdmin","CAPABILITIES","id","name","fields","providerSelect","type","admin","components","Field","label","modelSelect","commonTextParams","placeholder","defaultValue","max","min","providerOptionsUIField","instructionsCollection","pluginConfig","labels","plural","singular","overrideInstructions","slug","access","description","beforeList","hidden","debugging","unique","options","value","condition","_","current","clientProps","filterByField","map","c","path","disabled","hasMany","tabs","editor","features","rootFeatures","_rootFeatures","relationTo","uploadCollectionSlug","data","hooks","afterRead","context","doc","req","cacheKey","hookContext","defaults","aiSettings","payload","findGlobal","_error","instructions"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/collections/Instructions.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\nimport type { PluginConfig } from 'src/types.js'\n\nimport { lexicalEditor } from '@payloadcms/richtext-lexical'\n\nimport { PLUGIN_INSTRUCTIONS_TABLE } from '../defaults.js'\nimport { PromptMentionsFeature } from '../fields/PromptEditorField/feature.server.js'\nimport { applyInstructionDefaultsForDisplay } from '../utilities/ai/resolveEffectiveInstructionSettings.js'\nimport { pluginCollectionAccess, pluginCollectionAdmin } from './shared.js'\n\n// Defined capabilities replacing src/ai/models/\nconst CAPABILITIES = [\n {\n id: 'text',\n name: 'Text Generation',\n fields: ['text', 'textarea'],\n },\n {\n id: 'richtext',\n name: 'Rich Text Generation',\n fields: ['richText'],\n },\n {\n id: 'image',\n name: 'Image Generation',\n fields: ['upload'],\n },\n {\n id: 'tts',\n name: 'Text to Speech',\n fields: ['upload'],\n },\n {\n id: 'array',\n name: 'Array Generation',\n fields: ['array'],\n },\n]\n\n\nconst providerSelect = {\n name: 'provider',\n type: 'text' as const,\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicProviderSelect/index.js#DynamicProviderSelect',\n },\n },\n label: 'Provider',\n}\n\nconst modelSelect = {\n name: 'model',\n type: 'text' as const,\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicModelSelect/index.js#DynamicModelSelect',\n },\n },\n label: 'Model',\n}\n\n\nconst commonTextParams = [\n {\n type: 'row' as const,\n fields: [\n {\n name: 'maxTokens',\n type: 'number' as const,\n admin: {\n placeholder: 'Model Default',\n },\n label: 'Max Tokens',\n },\n {\n name: 'temperature',\n type: 'number' as const,\n defaultValue: 0.7,\n label: 'Temperature',\n max: 1,\n min: 0,\n },\n ],\n },\n {\n name: 'extractAttachments',\n type: 'checkbox' as const,\n label: 'Extract Attachments',\n },\n]\n\nconst providerOptionsUIField = {\n name: 'providerOptions',\n type: 'json' as const,\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/InstructionProviderOptions/index.js#InstructionProviderOptions',\n },\n },\n label: 'Provider Options',\n}\n\nexport const instructionsCollection = (pluginConfig: PluginConfig) =>\n <CollectionConfig>{\n labels: {\n plural: 'Compose Settings',\n singular: 'Compose Setting',\n },\n ...pluginConfig.overrideInstructions,\n slug: PLUGIN_INSTRUCTIONS_TABLE,\n access: {\n ...pluginCollectionAccess,\n ...pluginConfig.overrideInstructions?.access,\n },\n admin: {\n description:\n 'Customize how AI interacts with specific fields within your enabled collections.',\n ...pluginCollectionAdmin,\n ...pluginConfig.overrideInstructions?.admin,\n components: {\n beforeList: ['@ai-stack/payloadcms/ui/ConfigDashboard/index.js#ConfigDashboard'],\n },\n },\n fields: [\n {\n name: 'schema-path',\n type: 'text',\n admin: {\n description: \"Please don't change this unless you're sure of what you're doing\",\n hidden: !pluginConfig.debugging,\n },\n unique: true,\n },\n {\n name: 'field-type',\n type: 'select',\n admin: {\n description: \"Please don't change this unless you're sure of what you're doing\",\n hidden: !pluginConfig.debugging,\n },\n defaultValue: 'text',\n label: 'Field type',\n options: [\n {\n label: 'text',\n value: 'text',\n },\n {\n label: 'textarea',\n value: 'textarea',\n },\n {\n label: 'upload',\n value: 'upload',\n },\n {\n label: 'richText',\n value: 'richText',\n },\n {\n label: 'array',\n value: 'array',\n },\n ],\n },\n {\n name: 'relation-to',\n type: 'text',\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'upload'\n },\n hidden: !pluginConfig.debugging,\n },\n label: 'Relation to',\n },\n {\n name: 'hasMany',\n type: 'checkbox',\n admin: {\n hidden: true,\n },\n defaultValue: false,\n },\n {\n name: 'model-id',\n type: 'select',\n admin: {\n components: {\n Field: {\n clientProps: {\n filterByField: 'field-type',\n options: CAPABILITIES.map((c) => ({\n fields: c.fields,\n label: c.name,\n value: c.id,\n })),\n },\n path: '@ai-stack/payloadcms/fields/SelectField/SelectField.js#SelectField',\n },\n },\n },\n label: 'Capability',\n options: CAPABILITIES.map((c) => ({\n label: c.name,\n value: c.id,\n })),\n },\n {\n name: 'disabled',\n type: 'checkbox',\n admin: {\n description: 'Please reload your collection after applying the changes',\n },\n defaultValue: false,\n label: 'Hide Compose button for this field',\n },\n {\n name: 'alwaysShow',\n type: 'checkbox',\n admin: {\n condition: (_, current) => !current.disabled,\n description: 'Compose button will always be visible without requiring field focus',\n },\n defaultValue: false,\n label: 'Always show Compose button',\n },\n {\n name: 'appendGenerated',\n type: 'checkbox',\n admin: {\n condition: (_, current) => current?.hasMany === true && current?.disabled !== true,\n description: 'If enabled, generated values are appended to current values instead of replacing them.',\n },\n defaultValue: false,\n label: 'Append generated values',\n },\n {\n id: 'ai-prompts-tabs',\n type: 'tabs',\n tabs: [\n {\n description:\n 'Define dynamic templates using {{ fieldName }}. Type { to see available field suggestions.',\n fields: [\n { // TODO: update below to use PromptField\n name: 'prompt',\n type: 'richText',\n admin: {\n description: \"Click 'Compose' to run this custom prompt and generate content\",\n },\n editor: lexicalEditor({\n features: ({ rootFeatures: _rootFeatures }) => [PromptMentionsFeature()],\n }),\n label: '',\n },\n ],\n label: 'Prompt',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'upload' && current['model-id'] === 'image'\n },\n },\n description:\n 'These images will be used to generate new visuals in a similar style, layout, or content.',\n fields: [\n {\n name: 'images',\n type: 'array',\n fields: [\n {\n name: 'image',\n type: 'upload',\n admin: {\n description: 'Please make sure the image is publicly accessible.',\n },\n relationTo: pluginConfig.uploadCollectionSlug\n ? pluginConfig.uploadCollectionSlug\n : 'media',\n },\n ],\n },\n ],\n label: 'Sample Images',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'richText'\n },\n },\n description: '',\n fields: [\n {\n name: 'system',\n type: 'textarea',\n defaultValue: `INSTRUCTIONS:\nYou are a highly skilled and professional blog writer,\nrenowned for crafting engaging and well-organized articles.\nWhen given a title, you meticulously create blogs that are not only\ninformative and accurate but also captivating and beautifully structured.`,\n label: '',\n },\n ],\n label: 'System prompt',\n },\n {\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'richText'\n },\n },\n description: '',\n fields: [\n {\n name: 'layout',\n type: 'textarea',\n admin: {\n condition: (_, current) => {\n return current['field-type'] === 'richText'\n },\n },\n defaultValue: `[paragraph] - Write a concise introduction (2-3 sentences) that outlines the main topic.\n[horizontalrule] - Insert a horizontal rule to separate the introduction from the main content.\n[list] - Create a list with 3-5 items. Each list item should contain:\n a. [heading] - A brief, descriptive heading (up to 5 words)\n b. [paragraph] - A short explanation or elaboration (1-2 sentences)\n[horizontalrule] - Insert another horizontal rule to separate the main content from the conclusion.\n[paragraph] - Compose a brief conclusion (2-3 sentences) summarizing the key points.\n[quote] - Include a relevant quote from a famous person, directly related to the topic. Format: \"Quote text.\" - Author Name`,\n label: '',\n },\n ],\n label: 'Layout',\n },\n ],\n },\n\n // Inline Settings Groups by Capability\n\n // Text Settings\n {\n name: 'text-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'text',\n },\n fields: [\n providerSelect,\n modelSelect,\n ...commonTextParams,\n providerOptionsUIField,\n ],\n label: 'Text Settings',\n },\n\n // Rich Text Settings\n {\n name: 'richtext-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'richtext',\n },\n fields: [\n providerSelect,\n modelSelect,\n ...commonTextParams,\n providerOptionsUIField,\n ],\n label: 'Rich Text Settings',\n },\n\n // Image Settings\n {\n name: 'image-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'image',\n },\n fields: [providerSelect, modelSelect, providerOptionsUIField],\n label: 'Image Settings',\n },\n\n // TTS Settings\n {\n name: 'tts-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'tts',\n },\n fields: [\n providerSelect,\n modelSelect,\n {\n name: 'voice',\n type: 'text',\n admin: {\n components: {\n Field: '@ai-stack/payloadcms/ui/DynamicVoiceSelect/index.js#DynamicVoiceSelect',\n },\n },\n label: 'Voice',\n },\n providerOptionsUIField,\n ],\n label: 'TTS Settings',\n },\n\n // Array Settings\n {\n name: 'array-settings',\n type: 'group',\n admin: {\n condition: (data) => data['model-id'] === 'array',\n },\n fields: [\n providerSelect,\n modelSelect,\n {\n name: 'count',\n type: 'number',\n admin: {\n description: 'Number of items to generate',\n },\n defaultValue: 3,\n label: 'Items to Generate',\n max: 20,\n min: 1,\n },\n providerOptionsUIField,\n ],\n label: 'Array Settings',\n },\n ],\n hooks: {\n ...pluginConfig.overrideInstructions?.hooks,\n afterRead: [\n ...(pluginConfig.overrideInstructions?.hooks?.afterRead || []),\n async ({ context, doc, req }) => {\n if (!doc || typeof doc !== 'object') {\n return doc\n }\n\n const cacheKey = '__aiProvidersDefaults'\n const hookContext = (context || {}) as Record<string, unknown>\n let defaults = hookContext[cacheKey] as Record<string, unknown> | undefined\n\n if (!defaults) {\n try {\n const aiSettings = await req.payload.findGlobal({\n slug: 'ai-providers',\n })\n defaults = (aiSettings?.defaults || {}) as Record<string, unknown>\n hookContext[cacheKey] = defaults\n } catch (_error) {\n return doc\n }\n }\n\n return applyInstructionDefaultsForDisplay({\n defaults,\n instructions: doc as Record<string, unknown>,\n })\n },\n ],\n },\n }\n"],"names":["lexicalEditor","PLUGIN_INSTRUCTIONS_TABLE","PromptMentionsFeature","applyInstructionDefaultsForDisplay","pluginCollectionAccess","pluginCollectionAdmin","CAPABILITIES","id","name","fields","providerSelect","type","admin","components","Field","label","modelSelect","commonTextParams","placeholder","defaultValue","max","min","providerOptionsUIField","instructionsCollection","pluginConfig","labels","plural","singular","overrideInstructions","slug","access","description","beforeList","hidden","debugging","unique","options","value","condition","_","current","clientProps","filterByField","map","c","path","disabled","hasMany","tabs","editor","features","rootFeatures","_rootFeatures","relationTo","uploadCollectionSlug","data","hooks","afterRead","context","doc","req","cacheKey","hookContext","defaults","aiSettings","payload","findGlobal","_error","instructions"],"mappings":"AAGA,SAASA,aAAa,QAAQ,+BAA8B;AAE5D,SAASC,yBAAyB,QAAQ,iBAAgB;AAC1D,SAASC,qBAAqB,QAAQ,gDAA+C;AACrF,SAASC,kCAAkC,QAAQ,yDAAwD;AAC3G,SAASC,sBAAsB,EAAEC,qBAAqB,QAAQ,cAAa;AAE3E,gDAAgD;AAAhD,gDAAgD;AAChD,MAAMC,eAAe;IACnB;QACEC,IAAI;QACJC,MAAM;QACNC,QAAQ;YAAC;YAAQ;SAAW;IAC9B;IACA;QACEF,IAAI;QACJC,MAAM;QACNC,QAAQ;YAAC;SAAW;IACtB;IACA;QACEF,IAAI;QACJC,MAAM;QACNC,QAAQ;YAAC;SAAS;IACpB;IACA;QACEF,IAAI;QACJC,MAAM;QACNC,QAAQ;YAAC;SAAS;IACpB;IACA;QACEF,IAAI;QACJC,MAAM;QACNC,QAAQ;YAAC;SAAQ;IACnB;CACD;AAGD,MAAMC,iBAAiB;IACrBF,MAAM;IACNG,MAAM;IACNC,OAAO;QACLC,YAAY;YACVC,OAAO;QACT;IACF;IACAC,OAAO;AACT;AAEA,MAAMC,cAAc;IAClBR,MAAM;IACNG,MAAM;IACNC,OAAO;QACLC,YAAY;YACVC,OAAO;QACT;IACF;IACAC,OAAO;AACT;AAGA,MAAME,mBAAmB;IACvB;QACEN,MAAM;QACNF,QAAQ;YACN;gBACED,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACLM,aAAa;gBACf;gBACAH,OAAO;YACT;YACA;gBACEP,MAAM;gBACNG,MAAM;gBACNQ,cAAc;gBACdJ,OAAO;gBACPK,KAAK;gBACLC,KAAK;YACP;SACD;IACH;IACA;QACEb,MAAM;QACNG,MAAM;QACNI,OAAO;IACT;CACD;AAED,MAAMO,yBAAyB;IAC7Bd,MAAM;IACNG,MAAM;IACNC,OAAO;QACLC,YAAY;YACVC,OAAO;QACT;IACF;IACAC,OAAO;AACT;AAEA,OAAO,MAAMQ,yBAAyB,CAACC,eACnB,CAAA;QAChBC,QAAQ;YACNC,QAAQ;YACRC,UAAU;QACZ;QACA,GAAGH,aAAaI,oBAAoB;QACpCC,MAAM5B;QACN6B,QAAQ;YACN,GAAG1B,sBAAsB;YACzB,GAAGoB,aAAaI,oBAAoB,EAAEE,MAAM;QAC9C;QACAlB,OAAO;YACLmB,aACE;YACF,GAAG1B,qBAAqB;YACxB,GAAGmB,aAAaI,oBAAoB,EAAEhB,KAAK;YAC3CC,YAAY;gBACVmB,YAAY;oBAAC;iBAAmE;YAClF;QACF;QACAvB,QAAQ;YACN;gBACED,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACLmB,aAAa;oBACbE,QAAQ,CAACT,aAAaU,SAAS;gBACjC;gBACAC,QAAQ;YACV;YACA;gBACE3B,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACLmB,aAAa;oBACbE,QAAQ,CAACT,aAAaU,SAAS;gBACjC;gBACAf,cAAc;gBACdJ,OAAO;gBACPqB,SAAS;oBACP;wBACErB,OAAO;wBACPsB,OAAO;oBACT;oBACA;wBACEtB,OAAO;wBACPsB,OAAO;oBACT;oBACA;wBACEtB,OAAO;wBACPsB,OAAO;oBACT;oBACA;wBACEtB,OAAO;wBACPsB,OAAO;oBACT;oBACA;wBACEtB,OAAO;wBACPsB,OAAO;oBACT;iBACD;YACH;YACA;gBACE7B,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACL0B,WAAW,CAACC,GAAGC;wBACb,OAAOA,OAAO,CAAC,aAAa,KAAK;oBACnC;oBACAP,QAAQ,CAACT,aAAaU,SAAS;gBACjC;gBACAnB,OAAO;YACT;YACA;gBACEP,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACLqB,QAAQ;gBACV;gBACAd,cAAc;YAChB;YACA;gBACEX,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACLC,YAAY;wBACVC,OAAO;4BACL2B,aAAa;gCACXC,eAAe;gCACfN,SAAS9B,aAAaqC,GAAG,CAAC,CAACC,IAAO,CAAA;wCAChCnC,QAAQmC,EAAEnC,MAAM;wCAChBM,OAAO6B,EAAEpC,IAAI;wCACb6B,OAAOO,EAAErC,EAAE;oCACb,CAAA;4BACF;4BACAsC,MAAM;wBACR;oBACF;gBACF;gBACA9B,OAAO;gBACPqB,SAAS9B,aAAaqC,GAAG,CAAC,CAACC,IAAO,CAAA;wBAChC7B,OAAO6B,EAAEpC,IAAI;wBACb6B,OAAOO,EAAErC,EAAE;oBACb,CAAA;YACF;YACA;gBACEC,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACLmB,aAAa;gBACf;gBACAZ,cAAc;gBACdJ,OAAO;YACT;YACA;gBACEP,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACL0B,WAAW,CAACC,GAAGC,UAAY,CAACA,QAAQM,QAAQ;oBAC5Cf,aAAa;gBACf;gBACAZ,cAAc;gBACdJ,OAAO;YACT;YACA;gBACEP,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACL0B,WAAW,CAACC,GAAGC,UAAYA,SAASO,YAAY,QAAQP,SAASM,aAAa;oBAC9Ef,aAAa;gBACf;gBACAZ,cAAc;gBACdJ,OAAO;YACT;YACA;gBACER,IAAI;gBACJI,MAAM;gBACNqC,MAAM;oBACJ;wBACEjB,aACE;wBACFtB,QAAQ;4BACN;gCACED,MAAM;gCACNG,MAAM;gCACNC,OAAO;oCACLmB,aAAa;gCACf;gCACAkB,QAAQjD,cAAc;oCACpBkD,UAAU,CAAC,EAAEC,cAAcC,aAAa,EAAE,GAAK;4CAAClD;yCAAwB;gCAC1E;gCACAa,OAAO;4BACT;yBACD;wBACDA,OAAO;oBACT;oBACA;wBACEH,OAAO;4BACL0B,WAAW,CAACC,GAAGC;gCACb,OAAOA,OAAO,CAAC,aAAa,KAAK,YAAYA,OAAO,CAAC,WAAW,KAAK;4BACvE;wBACF;wBACAT,aACE;wBACFtB,QAAQ;4BACN;gCACED,MAAM;gCACNG,MAAM;gCACNF,QAAQ;oCACN;wCACED,MAAM;wCACNG,MAAM;wCACNC,OAAO;4CACLmB,aAAa;wCACf;wCACAsB,YAAY7B,aAAa8B,oBAAoB,GACzC9B,aAAa8B,oBAAoB,GACjC;oCACN;iCACD;4BACH;yBACD;wBACDvC,OAAO;oBACT;oBACA;wBACEH,OAAO;4BACL0B,WAAW,CAACC,GAAGC;gCACb,OAAOA,OAAO,CAAC,aAAa,KAAK;4BACnC;wBACF;wBACAT,aAAa;wBACbtB,QAAQ;4BACN;gCACED,MAAM;gCACNG,MAAM;gCACNQ,cAAc,CAAC;;;;yEAI0C,CAAC;gCAC1DJ,OAAO;4BACT;yBACD;wBACDA,OAAO;oBACT;oBACA;wBACEH,OAAO;4BACL0B,WAAW,CAACC,GAAGC;gCACb,OAAOA,OAAO,CAAC,aAAa,KAAK;4BACnC;wBACF;wBACAT,aAAa;wBACbtB,QAAQ;4BACN;gCACED,MAAM;gCACNG,MAAM;gCACNC,OAAO;oCACL0B,WAAW,CAACC,GAAGC;wCACb,OAAOA,OAAO,CAAC,aAAa,KAAK;oCACnC;gCACF;gCACArB,cAAc,CAAC;;;;;;;2HAO4F,CAAC;gCAC5GJ,OAAO;4BACT;yBACD;wBACDA,OAAO;oBACT;iBACD;YACH;YAEA,uCAAuC;YAEvC,gBAAgB;YAFhB,uCAAuC;YAEvC,gBAAgB;YAChB;gBACEP,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACL0B,WAAW,CAACiB,OAASA,IAAI,CAAC,WAAW,KAAK;gBAC5C;gBACA9C,QAAQ;oBACNC;oBACAM;uBACGC;oBACHK;iBACD;gBACDP,OAAO;YACT;YAEA,qBAAqB;YAArB,qBAAqB;YACrB;gBACEP,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACL0B,WAAW,CAACiB,OAASA,IAAI,CAAC,WAAW,KAAK;gBAC5C;gBACA9C,QAAQ;oBACNC;oBACAM;uBACGC;oBACHK;iBACD;gBACDP,OAAO;YACT;YAEA,iBAAiB;YAAjB,iBAAiB;YACjB;gBACEP,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACL0B,WAAW,CAACiB,OAASA,IAAI,CAAC,WAAW,KAAK;gBAC5C;gBACA9C,QAAQ;oBAACC;oBAAgBM;oBAAaM;iBAAuB;gBAC7DP,OAAO;YACT;YAEA,eAAe;YAAf,eAAe;YACf;gBACEP,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACL0B,WAAW,CAACiB,OAASA,IAAI,CAAC,WAAW,KAAK;gBAC5C;gBACA9C,QAAQ;oBACNC;oBACAM;oBACA;wBACER,MAAM;wBACNG,MAAM;wBACNC,OAAO;4BACLC,YAAY;gCACVC,OAAO;4BACT;wBACF;wBACAC,OAAO;oBACT;oBACAO;iBACD;gBACDP,OAAO;YACT;YAEA,iBAAiB;YAAjB,iBAAiB;YACjB;gBACEP,MAAM;gBACNG,MAAM;gBACNC,OAAO;oBACL0B,WAAW,CAACiB,OAASA,IAAI,CAAC,WAAW,KAAK;gBAC5C;gBACA9C,QAAQ;oBACNC;oBACAM;oBACA;wBACER,MAAM;wBACNG,MAAM;wBACNC,OAAO;4BACLmB,aAAa;wBACf;wBACAZ,cAAc;wBACdJ,OAAO;wBACPK,KAAK;wBACLC,KAAK;oBACP;oBACAC;iBACD;gBACDP,OAAO;YACT;SACD;QACDyC,OAAO;YACL,GAAGhC,aAAaI,oBAAoB,EAAE4B,KAAK;YAC3CC,WAAW;mBACLjC,aAAaI,oBAAoB,EAAE4B,OAAOC,aAAa,EAAE;gBAC7D,OAAO,EAAEC,OAAO,EAAEC,GAAG,EAAEC,GAAG,EAAE;oBAC1B,IAAI,CAACD,OAAO,OAAOA,QAAQ,UAAU;wBACnC,OAAOA;oBACT;oBAEA,MAAME,WAAW;oBACjB,MAAMC,cAAeJ,WAAW,CAAC;oBACjC,IAAIK,WAAWD,WAAW,CAACD,SAAS;oBAEpC,IAAI,CAACE,UAAU;wBACb,IAAI;4BACF,MAAMC,aAAa,MAAMJ,IAAIK,OAAO,CAACC,UAAU,CAAC;gCAC9CrC,MAAM;4BACR;4BACAkC,WAAYC,YAAYD,YAAY,CAAC;4BACrCD,WAAW,CAACD,SAAS,GAAGE;wBAC1B,EAAE,OAAOI,QAAQ;4BACf,OAAOR;wBACT;oBACF;oBAEA,OAAOxD,mCAAmC;wBACxC4D;wBACAK,cAAcT;oBAChB;gBACF;aACD;QACH;IACF,CAAA,EAAC"}
@@ -1,6 +1,6 @@
1
1
  import { PLUGIN_API_ENDPOINT_GENERATE, PLUGIN_API_ENDPOINT_GENERATE_UPLOAD, PLUGIN_API_ENDPOINT_VIDEOGEN_WEBHOOK } from '../defaults.js';
2
- import { promptMentionsEndpoint } from './promptMentions.js';
3
2
  import { generateHandler } from './generate.js';
3
+ import { promptMentionsEndpoint } from './promptMentions.js';
4
4
  import { uploadHandler } from './upload.js';
5
5
  import { videogenWebhookHandler } from './videogenWebhook.js';
6
6
  export const endpoints = (pluginConfig)=>({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/endpoints/index.ts"],"sourcesContent":["import type { Endpoints, PluginConfig } from '../types.js'\n\nimport {\n PLUGIN_API_ENDPOINT_GENERATE,\n PLUGIN_API_ENDPOINT_GENERATE_UPLOAD,\n PLUGIN_API_ENDPOINT_VIDEOGEN_WEBHOOK,\n} from '../defaults.js'\nimport { promptMentionsEndpoint } from './promptMentions.js'\nimport { generateHandler } from './generate.js'\nimport { uploadHandler } from './upload.js'\nimport { videogenWebhookHandler } from './videogenWebhook.js'\n\nexport const endpoints: (pluginConfig: PluginConfig) => Endpoints = (pluginConfig) =>\n ({\n promptMentions: promptMentionsEndpoint,\n textarea: {\n handler: generateHandler(pluginConfig),\n method: 'post',\n path: PLUGIN_API_ENDPOINT_GENERATE,\n },\n upload: {\n handler: uploadHandler(pluginConfig),\n method: 'post',\n path: PLUGIN_API_ENDPOINT_GENERATE_UPLOAD,\n },\n videogenWebhook: {\n handler: videogenWebhookHandler,\n method: 'post',\n path: PLUGIN_API_ENDPOINT_VIDEOGEN_WEBHOOK,\n },\n }) satisfies Endpoints\n"],"names":["PLUGIN_API_ENDPOINT_GENERATE","PLUGIN_API_ENDPOINT_GENERATE_UPLOAD","PLUGIN_API_ENDPOINT_VIDEOGEN_WEBHOOK","promptMentionsEndpoint","generateHandler","uploadHandler","videogenWebhookHandler","endpoints","pluginConfig","promptMentions","textarea","handler","method","path","upload","videogenWebhook"],"mappings":"AAEA,SACEA,4BAA4B,EAC5BC,mCAAmC,EACnCC,oCAAoC,QAC/B,iBAAgB;AACvB,SAASC,sBAAsB,QAAQ,sBAAqB;AAC5D,SAASC,eAAe,QAAQ,gBAAe;AAC/C,SAASC,aAAa,QAAQ,cAAa;AAC3C,SAASC,sBAAsB,QAAQ,uBAAsB;AAE7D,OAAO,MAAMC,YAAuD,CAACC,eAClE,CAAA;QACCC,gBAAgBN;QAChBO,UAAU;YACRC,SAASP,gBAAgBI;YACzBI,QAAQ;YACRC,MAAMb;QACR;QACAc,QAAQ;YACNH,SAASN,cAAcG;YACvBI,QAAQ;YACRC,MAAMZ;QACR;QACAc,iBAAiB;YACfJ,SAASL;YACTM,QAAQ;YACRC,MAAMX;QACR;IACF,CAAA,EAAsB"}
1
+ {"version":3,"sources":["../../src/endpoints/index.ts"],"sourcesContent":["import type { Endpoints, PluginConfig } from '../types.js'\n\nimport {\n PLUGIN_API_ENDPOINT_GENERATE,\n PLUGIN_API_ENDPOINT_GENERATE_UPLOAD,\n PLUGIN_API_ENDPOINT_VIDEOGEN_WEBHOOK,\n} from '../defaults.js'\nimport { generateHandler } from './generate.js'\nimport { promptMentionsEndpoint } from './promptMentions.js'\nimport { uploadHandler } from './upload.js'\nimport { videogenWebhookHandler } from './videogenWebhook.js'\n\nexport const endpoints: (pluginConfig: PluginConfig) => Endpoints = (pluginConfig) =>\n ({\n promptMentions: promptMentionsEndpoint,\n textarea: {\n handler: generateHandler(pluginConfig),\n method: 'post',\n path: PLUGIN_API_ENDPOINT_GENERATE,\n },\n upload: {\n handler: uploadHandler(pluginConfig),\n method: 'post',\n path: PLUGIN_API_ENDPOINT_GENERATE_UPLOAD,\n },\n videogenWebhook: {\n handler: videogenWebhookHandler,\n method: 'post',\n path: PLUGIN_API_ENDPOINT_VIDEOGEN_WEBHOOK,\n },\n }) satisfies Endpoints\n"],"names":["PLUGIN_API_ENDPOINT_GENERATE","PLUGIN_API_ENDPOINT_GENERATE_UPLOAD","PLUGIN_API_ENDPOINT_VIDEOGEN_WEBHOOK","generateHandler","promptMentionsEndpoint","uploadHandler","videogenWebhookHandler","endpoints","pluginConfig","promptMentions","textarea","handler","method","path","upload","videogenWebhook"],"mappings":"AAEA,SACEA,4BAA4B,EAC5BC,mCAAmC,EACnCC,oCAAoC,QAC/B,iBAAgB;AACvB,SAASC,eAAe,QAAQ,gBAAe;AAC/C,SAASC,sBAAsB,QAAQ,sBAAqB;AAC5D,SAASC,aAAa,QAAQ,cAAa;AAC3C,SAASC,sBAAsB,QAAQ,uBAAsB;AAE7D,OAAO,MAAMC,YAAuD,CAACC,eAClE,CAAA;QACCC,gBAAgBL;QAChBM,UAAU;YACRC,SAASR,gBAAgBK;YACzBI,QAAQ;YACRC,MAAMb;QACR;QACAc,QAAQ;YACNH,SAASN,cAAcG;YACvBI,QAAQ;YACRC,MAAMZ;QACR;QACAc,iBAAiB;YACfJ,SAASL;YACTM,QAAQ;YACRC,MAAMX;QACR;IACF,CAAA,EAAsB"}
@@ -1,2 +1,2 @@
1
- export type { payloadAiPlugin } from '../index.ts';
1
+ export type { aiPlugin } from '../index.ts';
2
2
  export type { ActionMenuItems, ActionPrompt, ActionPromptOptions, GenerationConfig, GenerationModel, PluginConfig, PluginConfigAccess, PluginConfigMediaUploadFunction, PluginOptions, PromptField, PromptFieldGetterContext, SeedPromptData, SeedPromptFunction, SeedPromptOptions, SeedPromptResult, } from '../types.ts';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type { payloadAiPlugin } from '../index.ts'\nexport type { \n ActionMenuItems,\n ActionPrompt,\n ActionPromptOptions,\n GenerationConfig, \n GenerationModel,\n PluginConfig, \n PluginConfigAccess,\n PluginConfigMediaUploadFunction,\n PluginOptions,\n PromptField,\n PromptFieldGetterContext,\n SeedPromptData,\n SeedPromptFunction,\n SeedPromptOptions,\n SeedPromptResult,\n} from '../types.ts'"],"names":[],"mappings":"AACA,WAgBoB"}
1
+ {"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type { aiPlugin } from '../index.ts'\nexport type { \n ActionMenuItems,\n ActionPrompt,\n ActionPromptOptions,\n GenerationConfig, \n GenerationModel,\n PluginConfig, \n PluginConfigAccess,\n PluginConfigMediaUploadFunction,\n PluginOptions,\n PromptField,\n PromptFieldGetterContext,\n SeedPromptData,\n SeedPromptFunction,\n SeedPromptOptions,\n SeedPromptResult,\n} from '../types.ts'"],"names":[],"mappings":"AACA,WAgBoB"}
@@ -1 +1 @@
1
- export declare const PayloadAiPluginLexicalEditorFeature: import("@payloadcms/richtext-lexical").FeatureProviderProviderServer<undefined, undefined, undefined>;
1
+ export declare const aiPluginLexicalEditorFeature: import("@payloadcms/richtext-lexical").FeatureProviderProviderServer<undefined, undefined, undefined>;
@@ -1,9 +1,9 @@
1
1
  import { createServerFeature } from '@payloadcms/richtext-lexical';
2
2
  import { PLUGIN_LEXICAL_EDITOR_FEATURE } from '../../defaults.js';
3
3
  // TODO: Find a way to check if the plugin is activated
4
- export const PayloadAiPluginLexicalEditorFeature = createServerFeature({
4
+ export const aiPluginLexicalEditorFeature = createServerFeature({
5
5
  feature: {
6
- ClientFeature: '@ai-stack/payloadcms/client#LexicalEditorFeatureClient'
6
+ ClientFeature: '@ai-stack/payloadcms/fields/LexicalEditor/feature.client.js#LexicalEditorFeatureClient'
7
7
  },
8
8
  key: PLUGIN_LEXICAL_EDITOR_FEATURE
9
9
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/fields/LexicalEditor/feature.server.ts"],"sourcesContent":["import { createServerFeature } from '@payloadcms/richtext-lexical'\n\nimport { PLUGIN_LEXICAL_EDITOR_FEATURE } from '../../defaults.js'\n\n// TODO: Find a way to check if the plugin is activated\nexport const PayloadAiPluginLexicalEditorFeature = createServerFeature({\n feature: {\n ClientFeature: '@ai-stack/payloadcms/client#LexicalEditorFeatureClient',\n },\n key: PLUGIN_LEXICAL_EDITOR_FEATURE,\n})\n"],"names":["createServerFeature","PLUGIN_LEXICAL_EDITOR_FEATURE","PayloadAiPluginLexicalEditorFeature","feature","ClientFeature","key"],"mappings":"AAAA,SAASA,mBAAmB,QAAQ,+BAA8B;AAElE,SAASC,6BAA6B,QAAQ,oBAAmB;AAEjE,uDAAuD;AACvD,OAAO,MAAMC,sCAAsCF,oBAAoB;IACrEG,SAAS;QACPC,eAAe;IACjB;IACAC,KAAKJ;AACP,GAAE"}
1
+ {"version":3,"sources":["../../../src/fields/LexicalEditor/feature.server.ts"],"sourcesContent":["import { createServerFeature } from '@payloadcms/richtext-lexical'\n\nimport { PLUGIN_LEXICAL_EDITOR_FEATURE } from '../../defaults.js'\n\n// TODO: Find a way to check if the plugin is activated\nexport const aiPluginLexicalEditorFeature = createServerFeature({\n feature: {\n ClientFeature: '@ai-stack/payloadcms/fields/LexicalEditor/feature.client.js#LexicalEditorFeatureClient',\n },\n key: PLUGIN_LEXICAL_EDITOR_FEATURE,\n})\n"],"names":["createServerFeature","PLUGIN_LEXICAL_EDITOR_FEATURE","aiPluginLexicalEditorFeature","feature","ClientFeature","key"],"mappings":"AAAA,SAASA,mBAAmB,QAAQ,+BAA8B;AAElE,SAASC,6BAA6B,QAAQ,oBAAmB;AAEjE,uDAAuD;AACvD,OAAO,MAAMC,+BAA+BF,oBAAoB;IAC9DG,SAAS;QACPC,eAAe;IACjB;IACAC,KAAKJ;AACP,GAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/fields/PromptEditorField/feature.client.tsx"],"sourcesContent":["'use client'\n\nimport type {\n BeautifulMentionsItem} from 'lexical-beautiful-mentions';\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'\nimport { createClientFeature } from '@payloadcms/richtext-lexical/client'\nimport { useDocumentInfo, useFormFields, useTranslation } from '@payloadcms/ui'\nimport {\n BeautifulMentionNode,\n BeautifulMentionsPlugin,\n} from 'lexical-beautiful-mentions'\nimport React, { useCallback } from 'react'\n\ntype MentionSuggestion = BeautifulMentionsItem & {\n display?: string\n id?: string\n value?: string\n}\n\nconst MENTION_SUGGESTIONS_TTL_MS = 60_000\nconst mentionSuggestionsCache = new Map<string, { expiresAt: number; items: MentionSuggestion[] }>()\nconst mentionSuggestionsInFlight = new Map<string, Promise<MentionSuggestion[]>>()\n\nconst getMentionCacheKey = (collectionSlug: string, trigger: string): string =>\n `${collectionSlug}:${trigger}`\n\nconst fetchMentionSuggestions = async (\n collectionSlug: string,\n trigger: string,\n): Promise<MentionSuggestion[]> => {\n const cacheKey = getMentionCacheKey(collectionSlug, trigger)\n const now = Date.now()\n const cached = mentionSuggestionsCache.get(cacheKey)\n\n if (cached && cached.expiresAt > now) {\n return cached.items\n }\n\n const existingRequest = mentionSuggestionsInFlight.get(cacheKey)\n if (existingRequest) {\n return existingRequest\n }\n\n const request = (async () => {\n const params = new URLSearchParams({\n collection: collectionSlug,\n q: '',\n trigger,\n })\n\n try {\n const response = await fetch(`/api/prompt-mentions?${params.toString()}`)\n if (!response.ok) {\n return []\n }\n\n const data = await response.json()\n const items = (data.items || []).map((item: any) => ({\n ...item,\n value: item.id || item.value,\n })) as MentionSuggestion[]\n\n mentionSuggestionsCache.set(cacheKey, {\n expiresAt: now + MENTION_SUGGESTIONS_TTL_MS,\n items,\n })\n\n return items\n } catch (e) {\n console.error(`Failed to fetch suggestions for ${trigger}`, e)\n return []\n } finally {\n mentionSuggestionsInFlight.delete(cacheKey)\n }\n })()\n\n mentionSuggestionsInFlight.set(cacheKey, request)\n return request\n}\n\nconst PromptMentionsMenu = ({\n children,\n className,\n loading,\n ref,\n style,\n ...props\n}: {\n children?: React.ReactNode\n className?: string\n loading?: boolean\n role?: string\n style?: React.CSSProperties\n} & { ref?: React.RefObject<HTMLUListElement | null> }) => {\n const { t } = useTranslation()\n return (\n <ul\n className={className}\n ref={ref}\n style={{\n backgroundColor: 'var(--theme-elevation-0)',\n border: '1px solid var(--theme-elevation-200)',\n borderRadius: '4px',\n boxShadow: '0 4px 12px 0 rgba(0,0,0,0.1)',\n listStyle: 'none',\n margin: 0,\n maxHeight: '300px',\n minWidth: '250px',\n overflowY: 'auto',\n padding: '4px 0',\n position: 'absolute',\n width: 'max-content',\n zIndex: 100,\n ...style,\n }}\n {...props}\n >\n {loading ? (\n <li\n style={{\n color: 'var(--theme-elevation-500)',\n fontSize: '14px',\n padding: '8px 12px',\n }}\n >\n {t('ai-plugin:general:loading' as any)}\n </li>\n ) : (\n children\n )}\n </ul>\n )\n}\nPromptMentionsMenu.displayName = 'PromptMentionsMenu'\n\nconst PromptMentionsMenuItem = ({\n children,\n className,\n isFocused,\n itemValue: _itemValue,\n label,\n ref,\n selected,\n style,\n ...props\n}: {\n children?: React.ReactNode\n className?: string\n isFocused?: boolean\n itemValue?: string\n label?: string\n onClick?: () => void\n onMouseEnter?: () => void\n role?: string\n selected?: boolean\n style?: React.CSSProperties\n} & { ref?: React.RefObject<HTMLLIElement | null> }) => {\n return (\n <li\n className={className}\n ref={ref}\n style={{\n alignItems: 'center',\n backgroundColor: selected || isFocused ? 'var(--theme-elevation-100)' : 'transparent',\n color: 'var(--theme-elevation-800)',\n cursor: 'pointer',\n display: 'flex',\n fontSize: '14px',\n lineHeight: '1.5',\n padding: '8px 12px',\n whiteSpace: 'nowrap',\n ...style,\n }}\n {...props}\n >\n {label || children}\n </li>\n )\n}\nPromptMentionsMenuItem.displayName = 'PromptMentionsMenuItem'\n\nconst PromptMentionsPlugin: React.FC = () => {\n useLexicalComposerContext()\n const suggestionsRef = React.useRef<Record<string, MentionSuggestion[]>>({})\n\n // Get schema-path from the form to determine the target collection (Instructions context)\n const schemaPathField = useFormFields(([fields]: any) => fields['schema-path'])\n const schemaPath = schemaPathField?.value as string\n\n // Get current document info (Regular Collection context)\n const { collectionSlug: currentCollectionSlug } = useDocumentInfo()\n\n // Determine effective collection slug\n // 1. If schemaPath exists (Instructions), derive slug from it (e.g. \"products.name\" -> \"products\")\n // 2. Fallback to current collection slug (e.g. editing a Product directly)\n const collectionSlug = schemaPath ? schemaPath.split('.')[0] : currentCollectionSlug\n\n // Pre-fetch suggestions when collectionSlug changes\n React.useEffect(() => {\n const fetchSuggestions = async () => {\n if (!collectionSlug) {\n return\n }\n\n const triggers = ['@', '#']\n const newSuggestions: Record<string, any[]> = {}\n\n await Promise.all(\n triggers.map(async (trigger) => {\n newSuggestions[trigger] = await fetchMentionSuggestions(collectionSlug, trigger)\n }),\n )\n\n suggestionsRef.current = newSuggestions\n }\n\n fetchSuggestions().catch(console.error)\n }, [collectionSlug])\n\n const queryMentions = useCallback(async (trigger: string, queryString?: null | string) => {\n const items = suggestionsRef.current[trigger] || []\n\n if (!queryString) {\n return items as BeautifulMentionsItem[]\n }\n\n const lowerQuery = queryString.toLowerCase()\n return items.filter((item) => {\n const display = item.display || item.value || ''\n return display.toLowerCase().includes(lowerQuery)\n }) as BeautifulMentionsItem[]\n }, [])\n\n return (\n <BeautifulMentionsPlugin\n menuComponent={PromptMentionsMenu}\n menuItemComponent={PromptMentionsMenuItem}\n onSearch={queryMentions}\n triggers={['@', '#']}\n />\n )\n}\n\nexport const PromptMentionsClient = createClientFeature({\n nodes: [BeautifulMentionNode],\n plugins: [\n {\n Component: PromptMentionsPlugin,\n position: 'normal',\n },\n ],\n})\n"],"names":["useLexicalComposerContext","createClientFeature","useDocumentInfo","useFormFields","useTranslation","BeautifulMentionNode","BeautifulMentionsPlugin","React","useCallback","MENTION_SUGGESTIONS_TTL_MS","mentionSuggestionsCache","Map","mentionSuggestionsInFlight","getMentionCacheKey","collectionSlug","trigger","fetchMentionSuggestions","cacheKey","now","Date","cached","get","expiresAt","items","existingRequest","request","params","URLSearchParams","collection","q","response","fetch","toString","ok","data","json","map","item","value","id","set","e","console","error","delete","PromptMentionsMenu","children","className","loading","ref","style","props","t","ul","backgroundColor","border","borderRadius","boxShadow","listStyle","margin","maxHeight","minWidth","overflowY","padding","position","width","zIndex","li","color","fontSize","displayName","PromptMentionsMenuItem","isFocused","itemValue","_itemValue","label","selected","alignItems","cursor","display","lineHeight","whiteSpace","PromptMentionsPlugin","suggestionsRef","useRef","schemaPathField","fields","schemaPath","currentCollectionSlug","split","useEffect","fetchSuggestions","triggers","newSuggestions","Promise","all","current","catch","queryMentions","queryString","lowerQuery","toLowerCase","filter","includes","menuComponent","menuItemComponent","onSearch","PromptMentionsClient","nodes","plugins","Component"],"mappings":"AAAA;;AAKA,SAASA,yBAAyB,QAAQ,wCAAuC;AACjF,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,eAAe,EAAEC,aAAa,EAAEC,cAAc,QAAQ,iBAAgB;AAC/E,SACEC,oBAAoB,EACpBC,uBAAuB,QAClB,6BAA4B;AACnC,OAAOC,SAASC,WAAW,QAAQ,QAAO;AAQ1C,MAAMC,6BAA6B;AACnC,MAAMC,0BAA0B,IAAIC;AACpC,MAAMC,6BAA6B,IAAID;AAEvC,MAAME,qBAAqB,CAACC,gBAAwBC,UAClD,CAAC,EAAED,eAAe,CAAC,EAAEC,QAAQ,CAAC;AAEhC,MAAMC,0BAA0B,OAC9BF,gBACAC;IAEA,MAAME,WAAWJ,mBAAmBC,gBAAgBC;IACpD,MAAMG,MAAMC,KAAKD,GAAG;IACpB,MAAME,SAASV,wBAAwBW,GAAG,CAACJ;IAE3C,IAAIG,UAAUA,OAAOE,SAAS,GAAGJ,KAAK;QACpC,OAAOE,OAAOG,KAAK;IACrB;IAEA,MAAMC,kBAAkBZ,2BAA2BS,GAAG,CAACJ;IACvD,IAAIO,iBAAiB;QACnB,OAAOA;IACT;IAEA,MAAMC,UAAU,AAAC,CAAA;QACf,MAAMC,SAAS,IAAIC,gBAAgB;YACjCC,YAAYd;YACZe,GAAG;YACHd;QACF;QAEA,IAAI;YACF,MAAMe,WAAW,MAAMC,MAAM,CAAC,qBAAqB,EAAEL,OAAOM,QAAQ,GAAG,CAAC;YACxE,IAAI,CAACF,SAASG,EAAE,EAAE;gBAChB,OAAO,EAAE;YACX;YAEA,MAAMC,OAAO,MAAMJ,SAASK,IAAI;YAChC,MAAMZ,QAAQ,AAACW,CAAAA,KAAKX,KAAK,IAAI,EAAE,AAAD,EAAGa,GAAG,CAAC,CAACC,OAAe,CAAA;oBACnD,GAAGA,IAAI;oBACPC,OAAOD,KAAKE,EAAE,IAAIF,KAAKC,KAAK;gBAC9B,CAAA;YAEA5B,wBAAwB8B,GAAG,CAACvB,UAAU;gBACpCK,WAAWJ,MAAMT;gBACjBc;YACF;YAEA,OAAOA;QACT,EAAE,OAAOkB,GAAG;YACVC,QAAQC,KAAK,CAAC,CAAC,gCAAgC,EAAE5B,QAAQ,CAAC,EAAE0B;YAC5D,OAAO,EAAE;QACX,SAAU;YACR7B,2BAA2BgC,MAAM,CAAC3B;QACpC;IACF,CAAA;IAEAL,2BAA2B4B,GAAG,CAACvB,UAAUQ;IACzC,OAAOA;AACT;AAEA,MAAMoB,qBAAqB,CAAC,EAC1BC,QAAQ,EACRC,SAAS,EACTC,OAAO,EACPC,GAAG,EACHC,KAAK,EACL,GAAGC,OAOiD;IACpD,MAAM,EAAEC,CAAC,EAAE,GAAGhD;IACd,qBACE,KAACiD;QACCN,WAAWA;QACXE,KAAKA;QACLC,OAAO;YACLI,iBAAiB;YACjBC,QAAQ;YACRC,cAAc;YACdC,WAAW;YACXC,WAAW;YACXC,QAAQ;YACRC,WAAW;YACXC,UAAU;YACVC,WAAW;YACXC,SAAS;YACTC,UAAU;YACVC,OAAO;YACPC,QAAQ;YACR,GAAGhB,KAAK;QACV;QACC,GAAGC,KAAK;kBAERH,wBACC,KAACmB;YACCjB,OAAO;gBACLkB,OAAO;gBACPC,UAAU;gBACVN,SAAS;YACX;sBAECX,EAAE;aAGLN;;AAIR;AACAD,mBAAmByB,WAAW,GAAG;AAEjC,MAAMC,yBAAyB,CAAC,EAC9BzB,QAAQ,EACRC,SAAS,EACTyB,SAAS,EACTC,WAAWC,UAAU,EACrBC,KAAK,EACL1B,GAAG,EACH2B,QAAQ,EACR1B,KAAK,EACL,GAAGC,OAY8C;IACjD,qBACE,KAACgB;QACCpB,WAAWA;QACXE,KAAKA;QACLC,OAAO;YACL2B,YAAY;YACZvB,iBAAiBsB,YAAYJ,YAAY,+BAA+B;YACxEJ,OAAO;YACPU,QAAQ;YACRC,SAAS;YACTV,UAAU;YACVW,YAAY;YACZjB,SAAS;YACTkB,YAAY;YACZ,GAAG/B,KAAK;QACV;QACC,GAAGC,KAAK;kBAERwB,SAAS7B;;AAGhB;AACAyB,uBAAuBD,WAAW,GAAG;AAErC,MAAMY,uBAAiC;IACrClF;IACA,MAAMmF,iBAAiB5E,MAAM6E,MAAM,CAAsC,CAAC;IAE1E,0FAA0F;IAC1F,MAAMC,kBAAkBlF,cAAc,CAAC,CAACmF,OAAY,GAAKA,MAAM,CAAC,cAAc;IAC9E,MAAMC,aAAaF,iBAAiB/C;IAEpC,yDAAyD;IACzD,MAAM,EAAExB,gBAAgB0E,qBAAqB,EAAE,GAAGtF;IAElD,sCAAsC;IACtC,mGAAmG;IACnG,2EAA2E;IAC3E,MAAMY,iBAAiByE,aAAaA,WAAWE,KAAK,CAAC,IAAI,CAAC,EAAE,GAAGD;IAE/D,oDAAoD;IACpDjF,MAAMmF,SAAS,CAAC;QACd,MAAMC,mBAAmB;YACvB,IAAI,CAAC7E,gBAAgB;gBACnB;YACF;YAEA,MAAM8E,WAAW;gBAAC;gBAAK;aAAI;YAC3B,MAAMC,iBAAwC,CAAC;YAE/C,MAAMC,QAAQC,GAAG,CACfH,SAASxD,GAAG,CAAC,OAAOrB;gBAClB8E,cAAc,CAAC9E,QAAQ,GAAG,MAAMC,wBAAwBF,gBAAgBC;YAC1E;YAGFoE,eAAea,OAAO,GAAGH;QAC3B;QAEAF,mBAAmBM,KAAK,CAACvD,QAAQC,KAAK;IACxC,GAAG;QAAC7B;KAAe;IAEnB,MAAMoF,gBAAgB1F,YAAY,OAAOO,SAAiBoF;QACxD,MAAM5E,QAAQ4D,eAAea,OAAO,CAACjF,QAAQ,IAAI,EAAE;QAEnD,IAAI,CAACoF,aAAa;YAChB,OAAO5E;QACT;QAEA,MAAM6E,aAAaD,YAAYE,WAAW;QAC1C,OAAO9E,MAAM+E,MAAM,CAAC,CAACjE;YACnB,MAAM0C,UAAU1C,KAAK0C,OAAO,IAAI1C,KAAKC,KAAK,IAAI;YAC9C,OAAOyC,QAAQsB,WAAW,GAAGE,QAAQ,CAACH;QACxC;IACF,GAAG,EAAE;IAEL,qBACE,KAAC9F;QACCkG,eAAe3D;QACf4D,mBAAmBlC;QACnBmC,UAAUR;QACVN,UAAU;YAAC;YAAK;SAAI;;AAG1B;AAEA,OAAO,MAAMe,uBAAuB1G,oBAAoB;IACtD2G,OAAO;QAACvG;KAAqB;IAC7BwG,SAAS;QACP;YACEC,WAAW5B;YACXlB,UAAU;QACZ;KACD;AACH,GAAE"}
1
+ {"version":3,"sources":["../../../src/fields/PromptEditorField/feature.client.tsx"],"sourcesContent":["'use client'\n\nimport type {\n BeautifulMentionsItem} from 'lexical-beautiful-mentions';\n\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'\nimport { createClientFeature } from '@payloadcms/richtext-lexical/client'\nimport { useDocumentInfo, useFormFields, useTranslation } from '@payloadcms/ui'\nimport {\n BeautifulMentionNode,\n BeautifulMentionsPlugin,\n} from 'lexical-beautiful-mentions'\nimport React, { useCallback } from 'react'\n\ntype MentionSuggestion = {\n display?: string\n id?: string\n value?: string\n} & BeautifulMentionsItem\n\nconst MENTION_SUGGESTIONS_TTL_MS = 60_000\nconst mentionSuggestionsCache = new Map<string, { expiresAt: number; items: MentionSuggestion[] }>()\nconst mentionSuggestionsInFlight = new Map<string, Promise<MentionSuggestion[]>>()\n\nconst getMentionCacheKey = (collectionSlug: string, trigger: string): string =>\n `${collectionSlug}:${trigger}`\n\nconst fetchMentionSuggestions = async (\n collectionSlug: string,\n trigger: string,\n): Promise<MentionSuggestion[]> => {\n const cacheKey = getMentionCacheKey(collectionSlug, trigger)\n const now = Date.now()\n const cached = mentionSuggestionsCache.get(cacheKey)\n\n if (cached && cached.expiresAt > now) {\n return cached.items\n }\n\n const existingRequest = mentionSuggestionsInFlight.get(cacheKey)\n if (existingRequest) {\n return existingRequest\n }\n\n const request = (async () => {\n const params = new URLSearchParams({\n collection: collectionSlug,\n q: '',\n trigger,\n })\n\n try {\n const response = await fetch(`/api/prompt-mentions?${params.toString()}`)\n if (!response.ok) {\n return []\n }\n\n const data = await response.json()\n const items = (data.items || []).map((item: any) => ({\n ...item,\n value: item.id || item.value,\n })) as MentionSuggestion[]\n\n mentionSuggestionsCache.set(cacheKey, {\n expiresAt: now + MENTION_SUGGESTIONS_TTL_MS,\n items,\n })\n\n return items\n } catch (e) {\n console.error(`Failed to fetch suggestions for ${trigger}`, e)\n return []\n } finally {\n mentionSuggestionsInFlight.delete(cacheKey)\n }\n })()\n\n mentionSuggestionsInFlight.set(cacheKey, request)\n return request\n}\n\nconst PromptMentionsMenu = ({\n children,\n className,\n loading,\n ref,\n style,\n ...props\n}: {\n children?: React.ReactNode\n className?: string\n loading?: boolean\n role?: string\n style?: React.CSSProperties\n} & { ref?: React.RefObject<HTMLUListElement | null> }) => {\n const { t } = useTranslation()\n return (\n <ul\n className={className}\n ref={ref}\n style={{\n backgroundColor: 'var(--theme-elevation-0)',\n border: '1px solid var(--theme-elevation-200)',\n borderRadius: '4px',\n boxShadow: '0 4px 12px 0 rgba(0,0,0,0.1)',\n listStyle: 'none',\n margin: 0,\n maxHeight: '300px',\n minWidth: '250px',\n overflowY: 'auto',\n padding: '4px 0',\n position: 'absolute',\n width: 'max-content',\n zIndex: 100,\n ...style,\n }}\n {...props}\n >\n {loading ? (\n <li\n style={{\n color: 'var(--theme-elevation-500)',\n fontSize: '14px',\n padding: '8px 12px',\n }}\n >\n {t('ai-plugin:general:loading' as any)}\n </li>\n ) : (\n children\n )}\n </ul>\n )\n}\nPromptMentionsMenu.displayName = 'PromptMentionsMenu'\n\nconst PromptMentionsMenuItem = ({\n children,\n className,\n isFocused,\n itemValue: _itemValue,\n label,\n ref,\n selected,\n style,\n ...props\n}: {\n children?: React.ReactNode\n className?: string\n isFocused?: boolean\n itemValue?: string\n label?: string\n onClick?: () => void\n onMouseEnter?: () => void\n role?: string\n selected?: boolean\n style?: React.CSSProperties\n} & { ref?: React.RefObject<HTMLLIElement | null> }) => {\n return (\n <li\n className={className}\n ref={ref}\n style={{\n alignItems: 'center',\n backgroundColor: selected || isFocused ? 'var(--theme-elevation-100)' : 'transparent',\n color: 'var(--theme-elevation-800)',\n cursor: 'pointer',\n display: 'flex',\n fontSize: '14px',\n lineHeight: '1.5',\n padding: '8px 12px',\n whiteSpace: 'nowrap',\n ...style,\n }}\n {...props}\n >\n {label || children}\n </li>\n )\n}\nPromptMentionsMenuItem.displayName = 'PromptMentionsMenuItem'\n\nconst PromptMentionsPlugin: React.FC = () => {\n useLexicalComposerContext()\n const suggestionsRef = React.useRef<Record<string, MentionSuggestion[]>>({})\n\n // Get schema-path from the form to determine the target collection (Instructions context)\n const schemaPathField = useFormFields(([fields]: any) => fields['schema-path'])\n const schemaPath = schemaPathField?.value as string\n\n // Get current document info (Regular Collection context)\n const { collectionSlug: currentCollectionSlug } = useDocumentInfo()\n\n // Determine effective collection slug\n // 1. If schemaPath exists (Instructions), derive slug from it (e.g. \"products.name\" -> \"products\")\n // 2. Fallback to current collection slug (e.g. editing a Product directly)\n const collectionSlug = schemaPath ? schemaPath.split('.')[0] : currentCollectionSlug\n\n // Pre-fetch suggestions when collectionSlug changes\n React.useEffect(() => {\n const fetchSuggestions = async () => {\n if (!collectionSlug) {\n return\n }\n\n const triggers = ['@', '#']\n const newSuggestions: Record<string, any[]> = {}\n\n await Promise.all(\n triggers.map(async (trigger) => {\n newSuggestions[trigger] = await fetchMentionSuggestions(collectionSlug, trigger)\n }),\n )\n\n suggestionsRef.current = newSuggestions\n }\n\n fetchSuggestions().catch(console.error)\n }, [collectionSlug])\n\n const queryMentions = useCallback(async (trigger: string, queryString?: null | string) => {\n const items = suggestionsRef.current[trigger] || []\n\n if (!queryString) {\n return items as BeautifulMentionsItem[]\n }\n\n const lowerQuery = queryString.toLowerCase()\n return items.filter((item) => {\n const display = item.display || item.value || ''\n return display.toLowerCase().includes(lowerQuery)\n }) as BeautifulMentionsItem[]\n }, [])\n\n return (\n <BeautifulMentionsPlugin\n menuComponent={PromptMentionsMenu}\n menuItemComponent={PromptMentionsMenuItem}\n onSearch={queryMentions}\n triggers={['@', '#']}\n />\n )\n}\n\nexport const PromptMentionsClient = createClientFeature({\n nodes: [BeautifulMentionNode],\n plugins: [\n {\n Component: PromptMentionsPlugin,\n position: 'normal',\n },\n ],\n})\n"],"names":["useLexicalComposerContext","createClientFeature","useDocumentInfo","useFormFields","useTranslation","BeautifulMentionNode","BeautifulMentionsPlugin","React","useCallback","MENTION_SUGGESTIONS_TTL_MS","mentionSuggestionsCache","Map","mentionSuggestionsInFlight","getMentionCacheKey","collectionSlug","trigger","fetchMentionSuggestions","cacheKey","now","Date","cached","get","expiresAt","items","existingRequest","request","params","URLSearchParams","collection","q","response","fetch","toString","ok","data","json","map","item","value","id","set","e","console","error","delete","PromptMentionsMenu","children","className","loading","ref","style","props","t","ul","backgroundColor","border","borderRadius","boxShadow","listStyle","margin","maxHeight","minWidth","overflowY","padding","position","width","zIndex","li","color","fontSize","displayName","PromptMentionsMenuItem","isFocused","itemValue","_itemValue","label","selected","alignItems","cursor","display","lineHeight","whiteSpace","PromptMentionsPlugin","suggestionsRef","useRef","schemaPathField","fields","schemaPath","currentCollectionSlug","split","useEffect","fetchSuggestions","triggers","newSuggestions","Promise","all","current","catch","queryMentions","queryString","lowerQuery","toLowerCase","filter","includes","menuComponent","menuItemComponent","onSearch","PromptMentionsClient","nodes","plugins","Component"],"mappings":"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"}
@@ -16,7 +16,7 @@ const BeautifulMentionNode = {
16
16
  };
17
17
  export const PromptMentionsFeature = createServerFeature({
18
18
  feature: {
19
- ClientFeature: '@ai-stack/payloadcms/fields#PromptMentionsClient',
19
+ ClientFeature: '@ai-stack/payloadcms/fields/PromptEditorField/feature.client.js#PromptMentionsClient',
20
20
  nodes: [
21
21
  {
22
22
  converters: {},