@humaan/payload-plugin-ai-assistant 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +277 -2
- package/dist/admin/AiAssistantControl.d.ts +11 -0
- package/dist/admin/AiAssistantControl.js +31 -0
- package/dist/admin/AiAssistantControl.js.map +1 -0
- package/dist/admin/AiAssistantPanel.d.ts +10 -0
- package/dist/admin/AiAssistantPanel.js +208 -0
- package/dist/admin/AiAssistantPanel.js.map +1 -0
- package/dist/admin/AiAssistantPanel.module.scss +689 -0
- package/dist/admin/AiSourceSwitch.d.ts +13 -0
- package/dist/admin/AiSourceSwitch.js +14 -0
- package/dist/admin/AiSourceSwitch.js.map +1 -0
- package/dist/admin/BudgetField.d.ts +8 -0
- package/dist/admin/BudgetField.js +145 -0
- package/dist/admin/BudgetField.js.map +1 -0
- package/dist/admin/BudgetField.module.scss +47 -0
- package/dist/admin/Conversation.d.ts +12 -0
- package/dist/admin/Conversation.js +469 -0
- package/dist/admin/Conversation.js.map +1 -0
- package/dist/admin/Markdown.d.ts +9 -0
- package/dist/admin/Markdown.js +63 -0
- package/dist/admin/Markdown.js.map +1 -0
- package/dist/admin/PageContextBridge.d.ts +5 -0
- package/dist/admin/PageContextBridge.js +72 -0
- package/dist/admin/PageContextBridge.js.map +1 -0
- package/dist/admin/Pill.d.ts +11 -0
- package/dist/admin/Pill.js +27 -0
- package/dist/admin/Pill.js.map +1 -0
- package/dist/admin/PlanCard.d.ts +14 -0
- package/dist/admin/PlanCard.js +465 -0
- package/dist/admin/PlanCard.js.map +1 -0
- package/dist/admin/SettingsAlerts.d.ts +7 -0
- package/dist/admin/SettingsAlerts.js +37 -0
- package/dist/admin/SettingsAlerts.js.map +1 -0
- package/dist/admin/UsageSummary.d.ts +11 -0
- package/dist/admin/UsageSummary.js +129 -0
- package/dist/admin/UsageSummary.js.map +1 -0
- package/dist/admin/attachmentUpload.d.ts +25 -0
- package/dist/admin/attachmentUpload.js +76 -0
- package/dist/admin/attachmentUpload.js.map +1 -0
- package/dist/admin/openDocument.d.ts +13 -0
- package/dist/admin/openDocument.js +34 -0
- package/dist/admin/openDocument.js.map +1 -0
- package/dist/admin/percent.d.ts +10 -0
- package/dist/admin/percent.js +21 -0
- package/dist/admin/percent.js.map +1 -0
- package/dist/admin/threads.d.ts +21 -0
- package/dist/admin/threads.js +92 -0
- package/dist/admin/threads.js.map +1 -0
- package/dist/admin/toolSteps.d.ts +12 -0
- package/dist/admin/toolSteps.js +57 -0
- package/dist/admin/toolSteps.js.map +1 -0
- package/dist/admin/transport.d.ts +24 -0
- package/dist/admin/transport.js +75 -0
- package/dist/admin/transport.js.map +1 -0
- package/dist/admin/useAttachments.d.ts +32 -0
- package/dist/admin/useAttachments.js +91 -0
- package/dist/admin/useAttachments.js.map +1 -0
- package/dist/admin/useEntityLabel.d.ts +3 -0
- package/dist/admin/useEntityLabel.js +23 -0
- package/dist/admin/useEntityLabel.js.map +1 -0
- package/dist/attachments/collection.d.ts +15 -0
- package/dist/attachments/collection.js +90 -0
- package/dist/attachments/collection.js.map +1 -0
- package/dist/attachments/conversation.d.ts +25 -0
- package/dist/attachments/conversation.js +105 -0
- package/dist/attachments/conversation.js.map +1 -0
- package/dist/attachments/rules.d.ts +9 -0
- package/dist/attachments/rules.js +17 -0
- package/dist/attachments/rules.js.map +1 -0
- package/dist/attachments/store.d.ts +27 -0
- package/dist/attachments/store.js +187 -0
- package/dist/attachments/store.js.map +1 -0
- package/dist/billing.d.ts +60 -0
- package/dist/billing.js +116 -0
- package/dist/billing.js.map +1 -0
- package/dist/chat/history.d.ts +37 -0
- package/dist/chat/history.js +165 -0
- package/dist/chat/history.js.map +1 -0
- package/dist/chat/messages.d.ts +5 -0
- package/dist/chat/messages.js +3 -0
- package/dist/chat/messages.js.map +1 -0
- package/dist/chat/threads.d.ts +33 -0
- package/dist/chat/threads.js +77 -0
- package/dist/chat/threads.js.map +1 -0
- package/dist/chat/tools.d.ts +76 -0
- package/dist/chat/tools.js +596 -0
- package/dist/chat/tools.js.map +1 -0
- package/dist/chat/usage.d.ts +66 -0
- package/dist/chat/usage.js +219 -0
- package/dist/chat/usage.js.map +1 -0
- package/dist/collectionAccess.d.ts +6 -0
- package/dist/collectionAccess.js +32 -0
- package/dist/collectionAccess.js.map +1 -0
- package/dist/constants.d.ts +64 -0
- package/dist/constants.js +51 -0
- package/dist/constants.js.map +1 -0
- package/dist/endpoints/access.d.ts +4 -0
- package/dist/endpoints/access.js +28 -0
- package/dist/endpoints/access.js.map +1 -0
- package/dist/endpoints/allowance.d.ts +22 -0
- package/dist/endpoints/allowance.js +37 -0
- package/dist/endpoints/allowance.js.map +1 -0
- package/dist/endpoints/applyEndpoint.d.ts +12 -0
- package/dist/endpoints/applyEndpoint.js +170 -0
- package/dist/endpoints/applyEndpoint.js.map +1 -0
- package/dist/endpoints/budget.d.ts +30 -0
- package/dist/endpoints/budget.js +153 -0
- package/dist/endpoints/budget.js.map +1 -0
- package/dist/endpoints/chatEndpoint.d.ts +12 -0
- package/dist/endpoints/chatEndpoint.js +295 -0
- package/dist/endpoints/chatEndpoint.js.map +1 -0
- package/dist/endpoints/form.d.ts +23 -0
- package/dist/endpoints/form.js +95 -0
- package/dist/endpoints/form.js.map +1 -0
- package/dist/endpoints/usageEndpoint.d.ts +13 -0
- package/dist/endpoints/usageEndpoint.js +70 -0
- package/dist/endpoints/usageEndpoint.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/lexical/editorConfig.d.ts +4 -0
- package/dist/lexical/editorConfig.js +19 -0
- package/dist/lexical/editorConfig.js.map +1 -0
- package/dist/lexical/lexicalToMarkdown.d.ts +10 -0
- package/dist/lexical/lexicalToMarkdown.js +10 -0
- package/dist/lexical/lexicalToMarkdown.js.map +1 -0
- package/dist/lexical/markdownToLexical.d.ts +7 -0
- package/dist/lexical/markdownToLexical.js +10 -0
- package/dist/lexical/markdownToLexical.js.map +1 -0
- package/dist/plan/allowed.d.ts +7 -0
- package/dist/plan/allowed.js +19 -0
- package/dist/plan/allowed.js.map +1 -0
- package/dist/plan/applyPlan.d.ts +16 -0
- package/dist/plan/applyPlan.js +353 -0
- package/dist/plan/applyPlan.js.map +1 -0
- package/dist/plan/catalogue.d.ts +37 -0
- package/dist/plan/catalogue.js +157 -0
- package/dist/plan/catalogue.js.map +1 -0
- package/dist/plan/diff.d.ts +13 -0
- package/dist/plan/diff.js +87 -0
- package/dist/plan/diff.js.map +1 -0
- package/dist/plan/parsePlan.d.ts +27 -0
- package/dist/plan/parsePlan.js +322 -0
- package/dist/plan/parsePlan.js.map +1 -0
- package/dist/plan/prompt.d.ts +1 -0
- package/dist/plan/prompt.js +45 -0
- package/dist/plan/prompt.js.map +1 -0
- package/dist/plan/stored.d.ts +53 -0
- package/dist/plan/stored.js +3 -0
- package/dist/plan/stored.js.map +1 -0
- package/dist/plan/tokens.d.ts +8 -0
- package/dist/plan/tokens.js +79 -0
- package/dist/plan/tokens.js.map +1 -0
- package/dist/plan/view.d.ts +4 -0
- package/dist/plan/view.js +43 -0
- package/dist/plan/view.js.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.js +464 -0
- package/dist/plugin.js.map +1 -0
- package/dist/read/outline.d.ts +7 -0
- package/dist/read/outline.js +70 -0
- package/dist/read/outline.js.map +1 -0
- package/dist/read/readTarget.d.ts +4 -0
- package/dist/read/readTarget.js +13 -0
- package/dist/read/readTarget.js.map +1 -0
- package/dist/read/readable.d.ts +8 -0
- package/dist/read/readable.js +131 -0
- package/dist/read/readable.js.map +1 -0
- package/dist/runtime.d.ts +15 -0
- package/dist/runtime.js +14 -0
- package/dist/runtime.js.map +1 -0
- package/dist/schema/fields.d.ts +113 -0
- package/dist/schema/fields.js +1036 -0
- package/dist/schema/fields.js.map +1 -0
- package/dist/schema/listingFields.d.ts +9 -0
- package/dist/schema/listingFields.js +95 -0
- package/dist/schema/listingFields.js.map +1 -0
- package/dist/schema/slugify.d.ts +2 -0
- package/dist/schema/slugify.js +5 -0
- package/dist/schema/slugify.js.map +1 -0
- package/dist/settings.d.ts +10 -0
- package/dist/settings.js +54 -0
- package/dist/settings.js.map +1 -0
- package/dist/types.d.ts +198 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/uploads/routeAsset.d.ts +27 -0
- package/dist/uploads/routeAsset.js +127 -0
- package/dist/uploads/routeAsset.js.map +1 -0
- package/package.json +122 -3
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { convertLexicalToMarkdown } from '@payloadcms/richtext-lexical';
|
|
2
|
+
import { editorConfigFor } from './editorConfig.js';
|
|
3
|
+
/** Turns stored lexical JSON back into markdown, so the assistant reads the words rather than the node tree. */ export async function lexicalToMarkdown({ config, field, data }) {
|
|
4
|
+
return convertLexicalToMarkdown({
|
|
5
|
+
data,
|
|
6
|
+
editorConfig: await editorConfigFor(config, field)
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=lexicalToMarkdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lexical/lexicalToMarkdown.ts"],"sourcesContent":["import type { RichTextField, SanitizedConfig } from 'payload'\n\nimport { convertLexicalToMarkdown } from '@payloadcms/richtext-lexical'\n\nimport { editorConfigFor } from './editorConfig.js'\n\ntype LexicalState = Parameters<typeof convertLexicalToMarkdown>[0]['data']\n\n/** Turns stored lexical JSON back into markdown, so the assistant reads the words rather than the node tree. */\nexport async function lexicalToMarkdown({\n config,\n field,\n data,\n}: {\n config: SanitizedConfig\n data: LexicalState\n field: RichTextField\n}): Promise<string> {\n return convertLexicalToMarkdown({ data, editorConfig: await editorConfigFor(config, field) })\n}\n"],"names":["convertLexicalToMarkdown","editorConfigFor","lexicalToMarkdown","config","field","data","editorConfig"],"mappings":"AAEA,SAASA,wBAAwB,QAAQ,+BAA8B;AAEvE,SAASC,eAAe,QAAQ,oBAAmB;AAInD,8GAA8G,GAC9G,OAAO,eAAeC,kBAAkB,EACtCC,MAAM,EACNC,KAAK,EACLC,IAAI,EAKL;IACC,OAAOL,yBAAyB;QAAEK;QAAMC,cAAc,MAAML,gBAAgBE,QAAQC;IAAO;AAC7F"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RichTextField, SanitizedConfig } from 'payload';
|
|
2
|
+
/** Turns markdown into the lexical JSON the rich text field stores. */
|
|
3
|
+
export declare function markdownToLexical({ config, field, markdown, }: {
|
|
4
|
+
config: SanitizedConfig;
|
|
5
|
+
field: RichTextField;
|
|
6
|
+
markdown: string;
|
|
7
|
+
}): Promise<unknown>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { convertMarkdownToLexical } from '@payloadcms/richtext-lexical';
|
|
2
|
+
import { editorConfigFor } from './editorConfig.js';
|
|
3
|
+
/** Turns markdown into the lexical JSON the rich text field stores. */ export async function markdownToLexical({ config, field, markdown }) {
|
|
4
|
+
return convertMarkdownToLexical({
|
|
5
|
+
editorConfig: await editorConfigFor(config, field),
|
|
6
|
+
markdown
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=markdownToLexical.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lexical/markdownToLexical.ts"],"sourcesContent":["import type { RichTextField, SanitizedConfig } from 'payload'\n\nimport { convertMarkdownToLexical } from '@payloadcms/richtext-lexical'\n\nimport { editorConfigFor } from './editorConfig.js'\n\n/** Turns markdown into the lexical JSON the rich text field stores. */\nexport async function markdownToLexical({\n config,\n field,\n markdown,\n}: {\n config: SanitizedConfig\n field: RichTextField\n markdown: string\n}): Promise<unknown> {\n return convertMarkdownToLexical({ editorConfig: await editorConfigFor(config, field), markdown })\n}\n"],"names":["convertMarkdownToLexical","editorConfigFor","markdownToLexical","config","field","markdown","editorConfig"],"mappings":"AAEA,SAASA,wBAAwB,QAAQ,+BAA8B;AAEvE,SAASC,eAAe,QAAQ,oBAAmB;AAEnD,qEAAqE,GACrE,OAAO,eAAeC,kBAAkB,EACtCC,MAAM,EACNC,KAAK,EACLC,QAAQ,EAKT;IACC,OAAOL,yBAAyB;QAAEM,cAAc,MAAML,gBAAgBE,QAAQC;QAAQC;IAAS;AACjG"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SanitizedConfig } from 'payload';
|
|
2
|
+
import type { StoredPlan } from './stored.js';
|
|
3
|
+
/**
|
|
4
|
+
* What a plan would change that the plugin options deny, in words for the model or the editor.
|
|
5
|
+
* Checked when the plan is made and again on Proceed, in case the options changed in between.
|
|
6
|
+
*/
|
|
7
|
+
export declare function notAllowed(plan: StoredPlan, config: SanitizedConfig): string | undefined;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { canChangeTarget, uploadTargets } from './catalogue.js';
|
|
2
|
+
/**
|
|
3
|
+
* What a plan would change that the plugin options deny, in words for the model or the editor.
|
|
4
|
+
* Checked when the plan is made and again on Proceed, in case the options changed in between.
|
|
5
|
+
*/ export function notAllowed(plan, config) {
|
|
6
|
+
const uploads = new Set(uploadTargets(config).map((target)=>target.slug));
|
|
7
|
+
const blocked = [
|
|
8
|
+
...plan.operations.filter((operation)=>!canChangeTarget(config, operation.kind, operation.slug)).map((operation)=>operation.slug),
|
|
9
|
+
...plan.files.filter((file)=>!uploads.has(file.collection)).map((file)=>file.collection)
|
|
10
|
+
];
|
|
11
|
+
if (blocked.length === 0) {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
return `The assistant cannot change ${[
|
|
15
|
+
...new Set(blocked)
|
|
16
|
+
].join(', ')}. The editor can make this change themselves.`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=allowed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/plan/allowed.ts"],"sourcesContent":["import type { SanitizedConfig } from 'payload'\n\nimport type { StoredPlan } from './stored.js'\n\nimport { canChangeTarget, uploadTargets } from './catalogue.js'\n\n/**\n * What a plan would change that the plugin options deny, in words for the model or the editor.\n * Checked when the plan is made and again on Proceed, in case the options changed in between.\n */\nexport function notAllowed(plan: StoredPlan, config: SanitizedConfig): string | undefined {\n const uploads = new Set(uploadTargets(config).map((target) => target.slug))\n const blocked = [\n ...plan.operations\n .filter((operation) => !canChangeTarget(config, operation.kind, operation.slug))\n .map((operation) => operation.slug),\n ...plan.files.filter((file) => !uploads.has(file.collection)).map((file) => file.collection),\n ]\n if (blocked.length === 0) {\n return undefined\n }\n return `The assistant cannot change ${[...new Set(blocked)].join(', ')}. The editor can make this change themselves.`\n}\n"],"names":["canChangeTarget","uploadTargets","notAllowed","plan","config","uploads","Set","map","target","slug","blocked","operations","filter","operation","kind","files","file","has","collection","length","undefined","join"],"mappings":"AAIA,SAASA,eAAe,EAAEC,aAAa,QAAQ,iBAAgB;AAE/D;;;CAGC,GACD,OAAO,SAASC,WAAWC,IAAgB,EAAEC,MAAuB;IAClE,MAAMC,UAAU,IAAIC,IAAIL,cAAcG,QAAQG,GAAG,CAAC,CAACC,SAAWA,OAAOC,IAAI;IACzE,MAAMC,UAAU;WACXP,KAAKQ,UAAU,CACfC,MAAM,CAAC,CAACC,YAAc,CAACb,gBAAgBI,QAAQS,UAAUC,IAAI,EAAED,UAAUJ,IAAI,GAC7EF,GAAG,CAAC,CAACM,YAAcA,UAAUJ,IAAI;WACjCN,KAAKY,KAAK,CAACH,MAAM,CAAC,CAACI,OAAS,CAACX,QAAQY,GAAG,CAACD,KAAKE,UAAU,GAAGX,GAAG,CAAC,CAACS,OAASA,KAAKE,UAAU;KAC5F;IACD,IAAIR,QAAQS,MAAM,KAAK,GAAG;QACxB,OAAOC;IACT;IACA,OAAO,CAAC,4BAA4B,EAAE;WAAI,IAAId,IAAII;KAAS,CAACW,IAAI,CAAC,MAAM,6CAA6C,CAAC;AACvH"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PayloadRequest } from 'payload';
|
|
2
|
+
import type { AssistantChange } from '../types.js';
|
|
3
|
+
import type { StoredPlan } from './stored.js';
|
|
4
|
+
export declare class ApplyError extends Error {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Runs a stored plan. Uploads and document writes share one transaction.
|
|
9
|
+
* A failure rolls the whole plan back.
|
|
10
|
+
*/
|
|
11
|
+
export declare function applyStoredPlan({ req, plan, planId, adminRoute, }: {
|
|
12
|
+
adminRoute: string;
|
|
13
|
+
plan: StoredPlan;
|
|
14
|
+
planId: string;
|
|
15
|
+
req: PayloadRequest;
|
|
16
|
+
}): Promise<AssistantChange[]>;
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import { commitTransaction, initTransaction } from 'payload';
|
|
2
|
+
import { readAttachment } from '../attachments/store.js';
|
|
3
|
+
import { aiAssistantPlanSlug, attachmentRetentionDays } from '../constants.js';
|
|
4
|
+
import { markdownToLexical } from '../lexical/markdownToLexical.js';
|
|
5
|
+
import { applyFields, followedSlug, withDerivedValues } from '../schema/fields.js';
|
|
6
|
+
import { titleFromFilename } from '../uploads/routeAsset.js';
|
|
7
|
+
import { mergePatch, nest, replaceTokens, setAtPath, valueAtPath } from './tokens.js';
|
|
8
|
+
function isRecord(value) {
|
|
9
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
10
|
+
}
|
|
11
|
+
export class ApplyError extends Error {
|
|
12
|
+
constructor(message){
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'ApplyError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Runs a stored plan. Uploads and document writes share one transaction.
|
|
19
|
+
* A failure rolls the whole plan back.
|
|
20
|
+
*/ export async function applyStoredPlan({ req, plan, planId, adminRoute }) {
|
|
21
|
+
if (plan.blocked) {
|
|
22
|
+
throw new ApplyError('This plan is waiting for a decision. It has not been applied.');
|
|
23
|
+
}
|
|
24
|
+
// Read before the transaction starts, so downloads from storage do not hold it open.
|
|
25
|
+
const files = await readPlanFiles(req, plan.files);
|
|
26
|
+
const shouldCommit = await initTransaction(req);
|
|
27
|
+
try {
|
|
28
|
+
const fileIds = await createFiles(req, plan.files, files);
|
|
29
|
+
const operationIds = [];
|
|
30
|
+
const changes = [];
|
|
31
|
+
for (const file of plan.files){
|
|
32
|
+
const id = fileIds[file.index];
|
|
33
|
+
if (!id) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
changes.push({
|
|
37
|
+
action: 'uploaded',
|
|
38
|
+
collection: file.collection,
|
|
39
|
+
id,
|
|
40
|
+
label: file.title || file.name,
|
|
41
|
+
href: href(adminRoute, 'collection', file.collection, id),
|
|
42
|
+
detail: file.savesImmediately ? 'Saved immediately.' : 'Saved as a draft.'
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
for (const [index, operation] of plan.operations.entries()){
|
|
46
|
+
const set = replaceTokens(operation.set, fileIds, operationIds);
|
|
47
|
+
const append = operation.append.map((item)=>({
|
|
48
|
+
path: item.path,
|
|
49
|
+
blocks: replaceTokens(item.blocks, fileIds, operationIds)
|
|
50
|
+
}));
|
|
51
|
+
if (!isRecord(set) || append.some((item)=>!Array.isArray(item.blocks))) {
|
|
52
|
+
throw new ApplyError(`Operation ${index + 1} has a file or document reference that could not be resolved.`);
|
|
53
|
+
}
|
|
54
|
+
const id = await writeOperation(req, operation, set, append);
|
|
55
|
+
operationIds[index] = id;
|
|
56
|
+
changes.push({
|
|
57
|
+
action: operation.action === 'create' ? 'created' : 'updated',
|
|
58
|
+
collection: operation.slug,
|
|
59
|
+
id,
|
|
60
|
+
label: operation.label,
|
|
61
|
+
href: href(adminRoute, operation.kind, operation.slug, operation.kind === 'global' ? undefined : id),
|
|
62
|
+
detail: operation.savesImmediately ? 'Saved immediately.' : 'Saved as a draft.'
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
// Plans are written only by the assistant endpoints, which checked the owner already.
|
|
66
|
+
await req.payload.update({
|
|
67
|
+
collection: aiAssistantPlanSlug,
|
|
68
|
+
id: planId,
|
|
69
|
+
data: {
|
|
70
|
+
status: 'applied'
|
|
71
|
+
},
|
|
72
|
+
req
|
|
73
|
+
});
|
|
74
|
+
if (shouldCommit && req.transactionID) {
|
|
75
|
+
await commitTransaction(req);
|
|
76
|
+
}
|
|
77
|
+
return changes;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
await rollback(req, shouldCommit);
|
|
80
|
+
throw error instanceof ApplyError ? error : new ApplyError(payloadErrorMessage(error));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** Each listed attachment's bytes, by its index in the conversation. */ async function readPlanFiles(req, manifest) {
|
|
84
|
+
const files = [];
|
|
85
|
+
for (const file of manifest){
|
|
86
|
+
try {
|
|
87
|
+
files[file.index] = await readAttachment(req, file.attachmentId);
|
|
88
|
+
} catch {
|
|
89
|
+
throw new ApplyError(`${file.name} is no longer available. Attachments are kept for ${attachmentRetentionDays} days; attach it again in a new conversation.`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return files;
|
|
93
|
+
}
|
|
94
|
+
async function createFiles(req, manifest, files) {
|
|
95
|
+
const ids = [];
|
|
96
|
+
const captionIds = [];
|
|
97
|
+
const ordered = [
|
|
98
|
+
...manifest
|
|
99
|
+
].sort((a, b)=>{
|
|
100
|
+
if (a.kind === 'caption' && b.kind !== 'caption') {
|
|
101
|
+
return -1;
|
|
102
|
+
}
|
|
103
|
+
if (b.kind === 'caption' && a.kind !== 'caption') {
|
|
104
|
+
return 1;
|
|
105
|
+
}
|
|
106
|
+
return a.index - b.index;
|
|
107
|
+
});
|
|
108
|
+
for (const file of ordered){
|
|
109
|
+
const bytes = files[file.index];
|
|
110
|
+
if (!bytes) {
|
|
111
|
+
throw new ApplyError(`Missing the file for ${file.name}.`);
|
|
112
|
+
}
|
|
113
|
+
const data = seedFile(file, captionIds);
|
|
114
|
+
const created = await req.payload.create({
|
|
115
|
+
collection: file.collection,
|
|
116
|
+
data: data,
|
|
117
|
+
file: {
|
|
118
|
+
data: bytes.data,
|
|
119
|
+
mimetype: bytes.type || file.type || 'application/octet-stream',
|
|
120
|
+
name: file.name,
|
|
121
|
+
size: bytes.data.length
|
|
122
|
+
},
|
|
123
|
+
draft: !file.savesImmediately,
|
|
124
|
+
overrideAccess: false,
|
|
125
|
+
req,
|
|
126
|
+
user: req.user
|
|
127
|
+
});
|
|
128
|
+
const id = String(created.id);
|
|
129
|
+
ids[file.index] = id;
|
|
130
|
+
if (file.kind === 'caption') {
|
|
131
|
+
captionIds.push(id);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return ids;
|
|
135
|
+
}
|
|
136
|
+
function seedFile(file, captionIds) {
|
|
137
|
+
if (file.kind === 'image') {
|
|
138
|
+
return {
|
|
139
|
+
alt: file.alt,
|
|
140
|
+
isDecorative: false
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
if (file.kind === 'video' && captionIds[0]) {
|
|
144
|
+
return {
|
|
145
|
+
alt: file.alt || file.name,
|
|
146
|
+
isDecorative: false,
|
|
147
|
+
tracks: [
|
|
148
|
+
{
|
|
149
|
+
file: captionIds[0],
|
|
150
|
+
srcLang: 'en',
|
|
151
|
+
kind: 'captions'
|
|
152
|
+
}
|
|
153
|
+
]
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
if (file.kind === 'video') {
|
|
157
|
+
return {
|
|
158
|
+
isDecorative: true
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
if (file.kind === 'document') {
|
|
162
|
+
return {
|
|
163
|
+
title: file.title || titleFromFilename(file.name)
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
return {};
|
|
167
|
+
}
|
|
168
|
+
async function writeOperation(req, operation, set, append) {
|
|
169
|
+
const fields = fieldsOf(req, operation);
|
|
170
|
+
const toLexical = (field, markdown)=>markdownToLexical({
|
|
171
|
+
config: req.payload.config,
|
|
172
|
+
field,
|
|
173
|
+
markdown
|
|
174
|
+
});
|
|
175
|
+
const partial = operation.action === 'update';
|
|
176
|
+
const applied = await applyFields(fields, set, {
|
|
177
|
+
toLexical,
|
|
178
|
+
partial
|
|
179
|
+
});
|
|
180
|
+
if (!applied.ok) {
|
|
181
|
+
throw new ApplyError(applied.errors.map((error)=>`${error.path}: ${error.message}`).join(' '));
|
|
182
|
+
}
|
|
183
|
+
const appended = [];
|
|
184
|
+
for (const item of append){
|
|
185
|
+
const nested = await applyFields(fields, nest(item.path, item.blocks), {
|
|
186
|
+
toLexical,
|
|
187
|
+
partial: true
|
|
188
|
+
});
|
|
189
|
+
if (!nested.ok) {
|
|
190
|
+
throw new ApplyError(nested.errors.map((error)=>`${error.path}: ${error.message}`).join(' '));
|
|
191
|
+
}
|
|
192
|
+
const blocks = valueAtPath(nested.data, item.path);
|
|
193
|
+
if (!Array.isArray(blocks)) {
|
|
194
|
+
throw new ApplyError(`${item.path} is not a blocks field.`);
|
|
195
|
+
}
|
|
196
|
+
appended.push({
|
|
197
|
+
path: item.path,
|
|
198
|
+
blocks
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
if (operation.action === 'create') {
|
|
202
|
+
const data = withDerivedValues(fields, applied.data, {
|
|
203
|
+
prependPath: prependPathOf(req, operation)
|
|
204
|
+
});
|
|
205
|
+
for (const item of appended){
|
|
206
|
+
setAtPath(data, item.path, item.blocks);
|
|
207
|
+
}
|
|
208
|
+
const created = await req.payload.create({
|
|
209
|
+
collection: operation.slug,
|
|
210
|
+
data: data,
|
|
211
|
+
draft: !operation.savesImmediately,
|
|
212
|
+
overrideAccess: false,
|
|
213
|
+
req,
|
|
214
|
+
user: req.user
|
|
215
|
+
});
|
|
216
|
+
return String(created.id);
|
|
217
|
+
}
|
|
218
|
+
const existing = await readExisting(req, operation);
|
|
219
|
+
const merged = mergePatch(existing, applied.data);
|
|
220
|
+
if (!isRecord(merged)) {
|
|
221
|
+
throw new ApplyError(`Could not update ${operation.label}.`);
|
|
222
|
+
}
|
|
223
|
+
for (const item of appended){
|
|
224
|
+
const current = valueAtPath(merged, item.path);
|
|
225
|
+
const rows = Array.isArray(current) ? current : [];
|
|
226
|
+
setAtPath(merged, item.path, [
|
|
227
|
+
...rows,
|
|
228
|
+
...item.blocks
|
|
229
|
+
]);
|
|
230
|
+
}
|
|
231
|
+
const keys = new Set([
|
|
232
|
+
...appended.map((item)=>item.path.split('.')[0] ?? ''),
|
|
233
|
+
...Object.keys(applied.data)
|
|
234
|
+
]);
|
|
235
|
+
const data = {};
|
|
236
|
+
for (const key of keys){
|
|
237
|
+
if (!key || !(key in merged)) {
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
data[key] = merged[key];
|
|
241
|
+
}
|
|
242
|
+
const slug = followedSlug(fields, existing, data.title);
|
|
243
|
+
if (slug) {
|
|
244
|
+
data.slug = slug;
|
|
245
|
+
}
|
|
246
|
+
if (operation.kind === 'global') {
|
|
247
|
+
const updated = await req.payload.updateGlobal({
|
|
248
|
+
slug: operation.slug,
|
|
249
|
+
data: data,
|
|
250
|
+
draft: !operation.savesImmediately,
|
|
251
|
+
overrideAccess: false,
|
|
252
|
+
req,
|
|
253
|
+
user: req.user
|
|
254
|
+
});
|
|
255
|
+
return String(updated.id ?? operation.slug);
|
|
256
|
+
}
|
|
257
|
+
const updated = await req.payload.update({
|
|
258
|
+
collection: operation.slug,
|
|
259
|
+
id: operation.id,
|
|
260
|
+
data: data,
|
|
261
|
+
draft: !operation.savesImmediately,
|
|
262
|
+
overrideAccess: false,
|
|
263
|
+
req,
|
|
264
|
+
user: req.user
|
|
265
|
+
});
|
|
266
|
+
return String(updated.id);
|
|
267
|
+
}
|
|
268
|
+
function prependPathOf(req, operation) {
|
|
269
|
+
if (operation.kind !== 'collection') {
|
|
270
|
+
return undefined;
|
|
271
|
+
}
|
|
272
|
+
const custom = req.payload.config.collections?.find((collection)=>collection.slug === operation.slug)?.custom;
|
|
273
|
+
if (!custom || typeof custom !== 'object') {
|
|
274
|
+
return undefined;
|
|
275
|
+
}
|
|
276
|
+
const prepend = custom.prependPath;
|
|
277
|
+
return typeof prepend === 'string' ? prepend : undefined;
|
|
278
|
+
}
|
|
279
|
+
function fieldsOf(req, operation) {
|
|
280
|
+
if (operation.kind === 'global') {
|
|
281
|
+
const fields = req.payload.config.globals?.find((global)=>global.slug === operation.slug)?.fields;
|
|
282
|
+
if (!fields) {
|
|
283
|
+
throw new ApplyError(`Unknown global "${operation.slug}".`);
|
|
284
|
+
}
|
|
285
|
+
return fields;
|
|
286
|
+
}
|
|
287
|
+
const fields = req.payload.config.collections?.find((collection)=>collection.slug === operation.slug)?.fields;
|
|
288
|
+
if (!fields) {
|
|
289
|
+
throw new ApplyError(`Unknown collection "${operation.slug}".`);
|
|
290
|
+
}
|
|
291
|
+
return fields;
|
|
292
|
+
}
|
|
293
|
+
async function readExisting(req, operation) {
|
|
294
|
+
if (operation.kind === 'global') {
|
|
295
|
+
return req.payload.findGlobal({
|
|
296
|
+
slug: operation.slug,
|
|
297
|
+
depth: 0,
|
|
298
|
+
draft: true,
|
|
299
|
+
overrideAccess: false,
|
|
300
|
+
req,
|
|
301
|
+
user: req.user
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
return req.payload.findByID({
|
|
305
|
+
collection: operation.slug,
|
|
306
|
+
id: operation.id,
|
|
307
|
+
depth: 0,
|
|
308
|
+
draft: true,
|
|
309
|
+
overrideAccess: false,
|
|
310
|
+
req,
|
|
311
|
+
user: req.user
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
function href(adminRoute, kind, slug, id) {
|
|
315
|
+
const base = adminRoute.endsWith('/') ? adminRoute.slice(0, -1) : adminRoute;
|
|
316
|
+
if (kind === 'global') {
|
|
317
|
+
return `${base}/globals/${slug}`;
|
|
318
|
+
}
|
|
319
|
+
return id ? `${base}/collections/${slug}/${id}` : `${base}/collections/${slug}`;
|
|
320
|
+
}
|
|
321
|
+
async function rollback(req, shouldCommit) {
|
|
322
|
+
if (!shouldCommit) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
const transactionID = req.transactionID;
|
|
326
|
+
if (typeof transactionID === 'string' || typeof transactionID === 'number') {
|
|
327
|
+
await req.payload.db.rollbackTransaction?.(transactionID);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
function payloadErrorMessage(error) {
|
|
331
|
+
if (isRecord(error) && isRecord(error.data) && Array.isArray(error.data.errors)) {
|
|
332
|
+
const parts = error.data.errors.map((item)=>{
|
|
333
|
+
if (!isRecord(item)) {
|
|
334
|
+
return '';
|
|
335
|
+
}
|
|
336
|
+
const path = typeof item.path === 'string' ? item.path : '';
|
|
337
|
+
const message = typeof item.message === 'string' ? item.message : '';
|
|
338
|
+
return [
|
|
339
|
+
path,
|
|
340
|
+
message
|
|
341
|
+
].filter(Boolean).join(': ');
|
|
342
|
+
}).filter(Boolean);
|
|
343
|
+
if (parts.length > 0) {
|
|
344
|
+
return parts.join(' ');
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
if (error instanceof Error && error.message) {
|
|
348
|
+
return error.message;
|
|
349
|
+
}
|
|
350
|
+
return 'The changes could not be saved.';
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
//# sourceMappingURL=applyPlan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/plan/applyPlan.ts"],"sourcesContent":["import type { CollectionSlug, GlobalSlug, PayloadRequest, RichTextField } from 'payload'\n\nimport { commitTransaction, initTransaction } from 'payload'\n\nimport type { AttachmentFile } from '../attachments/store.js'\nimport type { AssistantChange } from '../types.js'\nimport type { StoredFile, StoredOperation, StoredPlan } from './stored.js'\n\nimport { readAttachment } from '../attachments/store.js'\nimport { aiAssistantPlanSlug, attachmentRetentionDays } from '../constants.js'\nimport { markdownToLexical } from '../lexical/markdownToLexical.js'\nimport { applyFields, followedSlug, withDerivedValues } from '../schema/fields.js'\nimport { titleFromFilename } from '../uploads/routeAsset.js'\nimport { mergePatch, nest, replaceTokens, setAtPath, valueAtPath } from './tokens.js'\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n\nexport class ApplyError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ApplyError'\n }\n}\n\n/**\n * Runs a stored plan. Uploads and document writes share one transaction.\n * A failure rolls the whole plan back.\n */\nexport async function applyStoredPlan({\n req,\n plan,\n planId,\n adminRoute,\n}: {\n adminRoute: string\n plan: StoredPlan\n planId: string\n req: PayloadRequest\n}): Promise<AssistantChange[]> {\n if (plan.blocked) {\n throw new ApplyError('This plan is waiting for a decision. It has not been applied.')\n }\n // Read before the transaction starts, so downloads from storage do not hold it open.\n const files = await readPlanFiles(req, plan.files)\n\n const shouldCommit = await initTransaction(req)\n try {\n const fileIds = await createFiles(req, plan.files, files)\n const operationIds: string[] = []\n const changes: AssistantChange[] = []\n\n for (const file of plan.files) {\n const id = fileIds[file.index]\n if (!id) {\n continue\n }\n changes.push({\n action: 'uploaded',\n collection: file.collection,\n id,\n label: file.title || file.name,\n href: href(adminRoute, 'collection', file.collection, id),\n detail: file.savesImmediately ? 'Saved immediately.' : 'Saved as a draft.',\n })\n }\n\n for (const [index, operation] of plan.operations.entries()) {\n const set = replaceTokens(operation.set, fileIds, operationIds)\n const append = operation.append.map((item) => ({\n path: item.path,\n blocks: replaceTokens(item.blocks, fileIds, operationIds),\n }))\n if (!isRecord(set) || append.some((item) => !Array.isArray(item.blocks))) {\n throw new ApplyError(\n `Operation ${index + 1} has a file or document reference that could not be resolved.`,\n )\n }\n const id = await writeOperation(\n req,\n operation,\n set,\n append as { blocks: Record<string, unknown>[]; path: string }[],\n )\n operationIds[index] = id\n changes.push({\n action: operation.action === 'create' ? 'created' : 'updated',\n collection: operation.slug,\n id,\n label: operation.label,\n href: href(\n adminRoute,\n operation.kind,\n operation.slug,\n operation.kind === 'global' ? undefined : id,\n ),\n detail: operation.savesImmediately ? 'Saved immediately.' : 'Saved as a draft.',\n })\n }\n\n // Plans are written only by the assistant endpoints, which checked the owner already.\n await req.payload.update({\n collection: aiAssistantPlanSlug as CollectionSlug,\n id: planId,\n data: { status: 'applied' } as never,\n req,\n })\n\n if (shouldCommit && req.transactionID) {\n await commitTransaction(req)\n }\n return changes\n } catch (error) {\n await rollback(req, shouldCommit)\n throw error instanceof ApplyError ? error : new ApplyError(payloadErrorMessage(error))\n }\n}\n\n/** Each listed attachment's bytes, by its index in the conversation. */\nasync function readPlanFiles(\n req: PayloadRequest,\n manifest: StoredFile[],\n): Promise<AttachmentFile[]> {\n const files: AttachmentFile[] = []\n for (const file of manifest) {\n try {\n files[file.index] = await readAttachment(req, file.attachmentId)\n } catch {\n throw new ApplyError(\n `${file.name} is no longer available. Attachments are kept for ${attachmentRetentionDays} days; attach it again in a new conversation.`,\n )\n }\n }\n return files\n}\n\nasync function createFiles(\n req: PayloadRequest,\n manifest: StoredFile[],\n files: AttachmentFile[],\n): Promise<string[]> {\n const ids: string[] = []\n const captionIds: string[] = []\n const ordered = [...manifest].sort((a, b) => {\n if (a.kind === 'caption' && b.kind !== 'caption') {\n return -1\n }\n if (b.kind === 'caption' && a.kind !== 'caption') {\n return 1\n }\n return a.index - b.index\n })\n\n for (const file of ordered) {\n const bytes = files[file.index]\n if (!bytes) {\n throw new ApplyError(`Missing the file for ${file.name}.`)\n }\n const data = seedFile(file, captionIds)\n const created = await req.payload.create({\n collection: file.collection as CollectionSlug,\n data: data as never,\n file: {\n data: bytes.data,\n mimetype: bytes.type || file.type || 'application/octet-stream',\n name: file.name,\n size: bytes.data.length,\n },\n draft: !file.savesImmediately,\n overrideAccess: false,\n req,\n user: req.user,\n })\n const id = String((created as { id: unknown }).id)\n ids[file.index] = id\n if (file.kind === 'caption') {\n captionIds.push(id)\n }\n }\n return ids\n}\n\nfunction seedFile(file: StoredFile, captionIds: string[]): Record<string, unknown> {\n if (file.kind === 'image') {\n return { alt: file.alt, isDecorative: false }\n }\n if (file.kind === 'video' && captionIds[0]) {\n return {\n alt: file.alt || file.name,\n isDecorative: false,\n tracks: [{ file: captionIds[0], srcLang: 'en', kind: 'captions' }],\n }\n }\n if (file.kind === 'video') {\n return { isDecorative: true }\n }\n if (file.kind === 'document') {\n return { title: file.title || titleFromFilename(file.name) }\n }\n return {}\n}\n\nasync function writeOperation(\n req: PayloadRequest,\n operation: StoredOperation,\n set: Record<string, unknown>,\n append: { blocks: Record<string, unknown>[]; path: string }[],\n): Promise<string> {\n const fields = fieldsOf(req, operation)\n const toLexical = (field: RichTextField, markdown: string) =>\n markdownToLexical({ config: req.payload.config, field, markdown })\n const partial = operation.action === 'update'\n const applied = await applyFields(fields, set, { toLexical, partial })\n if (!applied.ok) {\n throw new ApplyError(applied.errors.map((error) => `${error.path}: ${error.message}`).join(' '))\n }\n\n const appended: { blocks: unknown[]; path: string }[] = []\n for (const item of append) {\n const nested = await applyFields(fields, nest(item.path, item.blocks), {\n toLexical,\n partial: true,\n })\n if (!nested.ok) {\n throw new ApplyError(\n nested.errors.map((error) => `${error.path}: ${error.message}`).join(' '),\n )\n }\n const blocks = valueAtPath(nested.data, item.path)\n if (!Array.isArray(blocks)) {\n throw new ApplyError(`${item.path} is not a blocks field.`)\n }\n appended.push({ path: item.path, blocks })\n }\n\n if (operation.action === 'create') {\n const data = withDerivedValues(fields, applied.data, {\n prependPath: prependPathOf(req, operation),\n })\n for (const item of appended) {\n setAtPath(data, item.path, item.blocks)\n }\n const created = await req.payload.create({\n collection: operation.slug as CollectionSlug,\n data: data as never,\n draft: !operation.savesImmediately,\n overrideAccess: false,\n req,\n user: req.user,\n })\n return String((created as { id: unknown }).id)\n }\n\n const existing = await readExisting(req, operation)\n const merged = mergePatch(existing, applied.data)\n if (!isRecord(merged)) {\n throw new ApplyError(`Could not update ${operation.label}.`)\n }\n for (const item of appended) {\n const current = valueAtPath(merged, item.path)\n const rows = Array.isArray(current) ? current : []\n setAtPath(merged, item.path, [...rows, ...item.blocks])\n }\n\n const keys = new Set<string>([\n ...appended.map((item) => item.path.split('.')[0] ?? ''),\n ...Object.keys(applied.data),\n ])\n const data: Record<string, unknown> = {}\n for (const key of keys) {\n if (!key || !(key in merged)) {\n continue\n }\n data[key] = merged[key]\n }\n const slug = followedSlug(fields, existing, data.title)\n if (slug) {\n data.slug = slug\n }\n\n if (operation.kind === 'global') {\n const updated = await req.payload.updateGlobal({\n slug: operation.slug as GlobalSlug,\n data: data as never,\n draft: !operation.savesImmediately,\n overrideAccess: false,\n req,\n user: req.user,\n })\n return String((updated as { id?: number | string }).id ?? operation.slug)\n }\n\n const updated = await req.payload.update({\n collection: operation.slug as CollectionSlug,\n id: operation.id as string,\n data: data as never,\n draft: !operation.savesImmediately,\n overrideAccess: false,\n req,\n user: req.user,\n })\n return String((updated as { id: unknown }).id)\n}\n\nfunction prependPathOf(req: PayloadRequest, operation: StoredOperation): string | undefined {\n if (operation.kind !== 'collection') {\n return undefined\n }\n const custom = req.payload.config.collections?.find(\n (collection) => collection.slug === operation.slug,\n )?.custom\n if (!custom || typeof custom !== 'object') {\n return undefined\n }\n const prepend = (custom as { prependPath?: unknown }).prependPath\n return typeof prepend === 'string' ? prepend : undefined\n}\n\nfunction fieldsOf(req: PayloadRequest, operation: StoredOperation) {\n if (operation.kind === 'global') {\n const fields = req.payload.config.globals?.find(\n (global) => global.slug === operation.slug,\n )?.fields\n if (!fields) {\n throw new ApplyError(`Unknown global \"${operation.slug}\".`)\n }\n return fields\n }\n const fields = req.payload.config.collections?.find(\n (collection) => collection.slug === operation.slug,\n )?.fields\n if (!fields) {\n throw new ApplyError(`Unknown collection \"${operation.slug}\".`)\n }\n return fields\n}\n\nasync function readExisting(req: PayloadRequest, operation: StoredOperation): Promise<unknown> {\n if (operation.kind === 'global') {\n return req.payload.findGlobal({\n slug: operation.slug as GlobalSlug,\n depth: 0,\n draft: true,\n overrideAccess: false,\n req,\n user: req.user,\n })\n }\n return req.payload.findByID({\n collection: operation.slug as CollectionSlug,\n id: operation.id as string,\n depth: 0,\n draft: true,\n overrideAccess: false,\n req,\n user: req.user,\n })\n}\n\nfunction href(\n adminRoute: string,\n kind: 'collection' | 'global',\n slug: string,\n id?: string,\n): string {\n const base = adminRoute.endsWith('/') ? adminRoute.slice(0, -1) : adminRoute\n if (kind === 'global') {\n return `${base}/globals/${slug}`\n }\n return id ? `${base}/collections/${slug}/${id}` : `${base}/collections/${slug}`\n}\n\nasync function rollback(req: PayloadRequest, shouldCommit: boolean): Promise<void> {\n if (!shouldCommit) {\n return\n }\n const transactionID = req.transactionID\n if (typeof transactionID === 'string' || typeof transactionID === 'number') {\n await req.payload.db.rollbackTransaction?.(transactionID)\n }\n}\n\nfunction payloadErrorMessage(error: unknown): string {\n if (isRecord(error) && isRecord(error.data) && Array.isArray(error.data.errors)) {\n const parts = error.data.errors\n .map((item) => {\n if (!isRecord(item)) {\n return ''\n }\n const path = typeof item.path === 'string' ? item.path : ''\n const message = typeof item.message === 'string' ? item.message : ''\n return [path, message].filter(Boolean).join(': ')\n })\n .filter(Boolean)\n if (parts.length > 0) {\n return parts.join(' ')\n }\n }\n if (error instanceof Error && error.message) {\n return error.message\n }\n return 'The changes could not be saved.'\n}\n"],"names":["commitTransaction","initTransaction","readAttachment","aiAssistantPlanSlug","attachmentRetentionDays","markdownToLexical","applyFields","followedSlug","withDerivedValues","titleFromFilename","mergePatch","nest","replaceTokens","setAtPath","valueAtPath","isRecord","value","Boolean","Array","isArray","ApplyError","Error","message","name","applyStoredPlan","req","plan","planId","adminRoute","blocked","files","readPlanFiles","shouldCommit","fileIds","createFiles","operationIds","changes","file","id","index","push","action","collection","label","title","href","detail","savesImmediately","operation","operations","entries","set","append","map","item","path","blocks","some","writeOperation","slug","kind","undefined","payload","update","data","status","transactionID","error","rollback","payloadErrorMessage","manifest","attachmentId","ids","captionIds","ordered","sort","a","b","bytes","seedFile","created","create","mimetype","type","size","length","draft","overrideAccess","user","String","alt","isDecorative","tracks","srcLang","fields","fieldsOf","toLexical","field","markdown","config","partial","applied","ok","errors","join","appended","nested","prependPath","prependPathOf","existing","readExisting","merged","current","rows","keys","Set","split","Object","key","updated","updateGlobal","custom","collections","find","prepend","globals","global","findGlobal","depth","findByID","base","endsWith","slice","db","rollbackTransaction","parts","filter"],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Field, SanitizedConfig, Where } from 'payload';
|
|
2
|
+
import type { AiAssistantPluginOptions } from '../types.js';
|
|
3
|
+
import type { PlanTarget } from './stored.js';
|
|
4
|
+
/** Every collection and global the assistant can read, with the editor's own access. */
|
|
5
|
+
export declare function planTargets(config: SanitizedConfig): PlanTarget[];
|
|
6
|
+
/**
|
|
7
|
+
* Whether a plan may change a target. Never what the assistant cannot read, nor Payload's own `payload-*`
|
|
8
|
+
* collections, nor anything the plugin options deny.
|
|
9
|
+
*/
|
|
10
|
+
export declare function canChangeTarget(config: SanitizedConfig, kind: 'collection' | 'global', slug: string): boolean;
|
|
11
|
+
/** Upload collections a plan may save attachments into. */
|
|
12
|
+
export declare function uploadTargets(config: SanitizedConfig): {
|
|
13
|
+
mimeTypes: string[];
|
|
14
|
+
slug: string;
|
|
15
|
+
}[];
|
|
16
|
+
export declare function findTarget(config: SanitizedConfig, kind: 'collection' | 'global', slug: string): PlanTarget | undefined;
|
|
17
|
+
export declare function collectionFields(config: SanitizedConfig, slug: string): Field[] | undefined;
|
|
18
|
+
export declare function globalFields(config: SanitizedConfig, slug: string): Field[] | undefined;
|
|
19
|
+
export declare function titleFieldOf(config: SanitizedConfig, slug: string): string;
|
|
20
|
+
export declare function describeTarget(config: SanitizedConfig, kind: 'collection' | 'global', slug: string, rules: AiAssistantPluginOptions['collectionRules'], blocks?: readonly string[]): {
|
|
21
|
+
blocks?: string;
|
|
22
|
+
drafts: boolean;
|
|
23
|
+
guide: string;
|
|
24
|
+
note?: string;
|
|
25
|
+
rules?: string;
|
|
26
|
+
upload: boolean;
|
|
27
|
+
} | {
|
|
28
|
+
error: string;
|
|
29
|
+
};
|
|
30
|
+
export interface SearchFilter {
|
|
31
|
+
/** Dotted field path, such as `category` or `seo.noIndex`. Payload checks it against the schema and the editor's field access. */
|
|
32
|
+
field: string;
|
|
33
|
+
operator: 'equals' | 'exists' | 'in' | 'like' | 'not_equals';
|
|
34
|
+
value: (number | string)[] | boolean | number | string;
|
|
35
|
+
}
|
|
36
|
+
/** A title search and any field filters, all of which must match. */
|
|
37
|
+
export declare function searchWhere(config: SanitizedConfig, slug: string, query: string, filters?: readonly SearchFilter[]): undefined | Where;
|