@humaan/payload-plugin-ai-assistant 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/README.md +277 -2
  2. package/dist/admin/AiAssistantControl.d.ts +11 -0
  3. package/dist/admin/AiAssistantControl.js +31 -0
  4. package/dist/admin/AiAssistantControl.js.map +1 -0
  5. package/dist/admin/AiAssistantPanel.d.ts +10 -0
  6. package/dist/admin/AiAssistantPanel.js +208 -0
  7. package/dist/admin/AiAssistantPanel.js.map +1 -0
  8. package/dist/admin/AiAssistantPanel.module.scss +689 -0
  9. package/dist/admin/AiSourceSwitch.d.ts +13 -0
  10. package/dist/admin/AiSourceSwitch.js +14 -0
  11. package/dist/admin/AiSourceSwitch.js.map +1 -0
  12. package/dist/admin/BudgetField.d.ts +8 -0
  13. package/dist/admin/BudgetField.js +145 -0
  14. package/dist/admin/BudgetField.js.map +1 -0
  15. package/dist/admin/BudgetField.module.scss +47 -0
  16. package/dist/admin/Conversation.d.ts +12 -0
  17. package/dist/admin/Conversation.js +469 -0
  18. package/dist/admin/Conversation.js.map +1 -0
  19. package/dist/admin/Markdown.d.ts +9 -0
  20. package/dist/admin/Markdown.js +63 -0
  21. package/dist/admin/Markdown.js.map +1 -0
  22. package/dist/admin/PageContextBridge.d.ts +5 -0
  23. package/dist/admin/PageContextBridge.js +72 -0
  24. package/dist/admin/PageContextBridge.js.map +1 -0
  25. package/dist/admin/Pill.d.ts +11 -0
  26. package/dist/admin/Pill.js +27 -0
  27. package/dist/admin/Pill.js.map +1 -0
  28. package/dist/admin/PlanCard.d.ts +14 -0
  29. package/dist/admin/PlanCard.js +465 -0
  30. package/dist/admin/PlanCard.js.map +1 -0
  31. package/dist/admin/SettingsAlerts.d.ts +7 -0
  32. package/dist/admin/SettingsAlerts.js +37 -0
  33. package/dist/admin/SettingsAlerts.js.map +1 -0
  34. package/dist/admin/UsageSummary.d.ts +11 -0
  35. package/dist/admin/UsageSummary.js +129 -0
  36. package/dist/admin/UsageSummary.js.map +1 -0
  37. package/dist/admin/attachmentUpload.d.ts +25 -0
  38. package/dist/admin/attachmentUpload.js +76 -0
  39. package/dist/admin/attachmentUpload.js.map +1 -0
  40. package/dist/admin/openDocument.d.ts +13 -0
  41. package/dist/admin/openDocument.js +34 -0
  42. package/dist/admin/openDocument.js.map +1 -0
  43. package/dist/admin/percent.d.ts +10 -0
  44. package/dist/admin/percent.js +21 -0
  45. package/dist/admin/percent.js.map +1 -0
  46. package/dist/admin/threads.d.ts +21 -0
  47. package/dist/admin/threads.js +92 -0
  48. package/dist/admin/threads.js.map +1 -0
  49. package/dist/admin/toolSteps.d.ts +12 -0
  50. package/dist/admin/toolSteps.js +57 -0
  51. package/dist/admin/toolSteps.js.map +1 -0
  52. package/dist/admin/transport.d.ts +24 -0
  53. package/dist/admin/transport.js +75 -0
  54. package/dist/admin/transport.js.map +1 -0
  55. package/dist/admin/useAttachments.d.ts +32 -0
  56. package/dist/admin/useAttachments.js +91 -0
  57. package/dist/admin/useAttachments.js.map +1 -0
  58. package/dist/admin/useEntityLabel.d.ts +3 -0
  59. package/dist/admin/useEntityLabel.js +23 -0
  60. package/dist/admin/useEntityLabel.js.map +1 -0
  61. package/dist/attachments/collection.d.ts +15 -0
  62. package/dist/attachments/collection.js +90 -0
  63. package/dist/attachments/collection.js.map +1 -0
  64. package/dist/attachments/conversation.d.ts +25 -0
  65. package/dist/attachments/conversation.js +105 -0
  66. package/dist/attachments/conversation.js.map +1 -0
  67. package/dist/attachments/rules.d.ts +9 -0
  68. package/dist/attachments/rules.js +17 -0
  69. package/dist/attachments/rules.js.map +1 -0
  70. package/dist/attachments/store.d.ts +27 -0
  71. package/dist/attachments/store.js +187 -0
  72. package/dist/attachments/store.js.map +1 -0
  73. package/dist/billing.d.ts +60 -0
  74. package/dist/billing.js +116 -0
  75. package/dist/billing.js.map +1 -0
  76. package/dist/chat/history.d.ts +37 -0
  77. package/dist/chat/history.js +165 -0
  78. package/dist/chat/history.js.map +1 -0
  79. package/dist/chat/messages.d.ts +5 -0
  80. package/dist/chat/messages.js +3 -0
  81. package/dist/chat/messages.js.map +1 -0
  82. package/dist/chat/threads.d.ts +33 -0
  83. package/dist/chat/threads.js +77 -0
  84. package/dist/chat/threads.js.map +1 -0
  85. package/dist/chat/tools.d.ts +76 -0
  86. package/dist/chat/tools.js +596 -0
  87. package/dist/chat/tools.js.map +1 -0
  88. package/dist/chat/usage.d.ts +66 -0
  89. package/dist/chat/usage.js +219 -0
  90. package/dist/chat/usage.js.map +1 -0
  91. package/dist/collectionAccess.d.ts +6 -0
  92. package/dist/collectionAccess.js +32 -0
  93. package/dist/collectionAccess.js.map +1 -0
  94. package/dist/constants.d.ts +64 -0
  95. package/dist/constants.js +51 -0
  96. package/dist/constants.js.map +1 -0
  97. package/dist/endpoints/access.d.ts +4 -0
  98. package/dist/endpoints/access.js +28 -0
  99. package/dist/endpoints/access.js.map +1 -0
  100. package/dist/endpoints/allowance.d.ts +22 -0
  101. package/dist/endpoints/allowance.js +37 -0
  102. package/dist/endpoints/allowance.js.map +1 -0
  103. package/dist/endpoints/applyEndpoint.d.ts +12 -0
  104. package/dist/endpoints/applyEndpoint.js +170 -0
  105. package/dist/endpoints/applyEndpoint.js.map +1 -0
  106. package/dist/endpoints/budget.d.ts +30 -0
  107. package/dist/endpoints/budget.js +153 -0
  108. package/dist/endpoints/budget.js.map +1 -0
  109. package/dist/endpoints/chatEndpoint.d.ts +12 -0
  110. package/dist/endpoints/chatEndpoint.js +295 -0
  111. package/dist/endpoints/chatEndpoint.js.map +1 -0
  112. package/dist/endpoints/form.d.ts +23 -0
  113. package/dist/endpoints/form.js +95 -0
  114. package/dist/endpoints/form.js.map +1 -0
  115. package/dist/endpoints/usageEndpoint.d.ts +13 -0
  116. package/dist/endpoints/usageEndpoint.js +70 -0
  117. package/dist/endpoints/usageEndpoint.js.map +1 -0
  118. package/dist/index.d.ts +4 -0
  119. package/dist/index.js +5 -0
  120. package/dist/index.js.map +1 -0
  121. package/dist/lexical/editorConfig.d.ts +4 -0
  122. package/dist/lexical/editorConfig.js +19 -0
  123. package/dist/lexical/editorConfig.js.map +1 -0
  124. package/dist/lexical/lexicalToMarkdown.d.ts +10 -0
  125. package/dist/lexical/lexicalToMarkdown.js +10 -0
  126. package/dist/lexical/lexicalToMarkdown.js.map +1 -0
  127. package/dist/lexical/markdownToLexical.d.ts +7 -0
  128. package/dist/lexical/markdownToLexical.js +10 -0
  129. package/dist/lexical/markdownToLexical.js.map +1 -0
  130. package/dist/plan/allowed.d.ts +7 -0
  131. package/dist/plan/allowed.js +19 -0
  132. package/dist/plan/allowed.js.map +1 -0
  133. package/dist/plan/applyPlan.d.ts +16 -0
  134. package/dist/plan/applyPlan.js +353 -0
  135. package/dist/plan/applyPlan.js.map +1 -0
  136. package/dist/plan/catalogue.d.ts +37 -0
  137. package/dist/plan/catalogue.js +157 -0
  138. package/dist/plan/catalogue.js.map +1 -0
  139. package/dist/plan/diff.d.ts +13 -0
  140. package/dist/plan/diff.js +87 -0
  141. package/dist/plan/diff.js.map +1 -0
  142. package/dist/plan/parsePlan.d.ts +27 -0
  143. package/dist/plan/parsePlan.js +322 -0
  144. package/dist/plan/parsePlan.js.map +1 -0
  145. package/dist/plan/prompt.d.ts +1 -0
  146. package/dist/plan/prompt.js +45 -0
  147. package/dist/plan/prompt.js.map +1 -0
  148. package/dist/plan/stored.d.ts +53 -0
  149. package/dist/plan/stored.js +3 -0
  150. package/dist/plan/stored.js.map +1 -0
  151. package/dist/plan/tokens.d.ts +8 -0
  152. package/dist/plan/tokens.js +79 -0
  153. package/dist/plan/tokens.js.map +1 -0
  154. package/dist/plan/view.d.ts +4 -0
  155. package/dist/plan/view.js +43 -0
  156. package/dist/plan/view.js.map +1 -0
  157. package/dist/plugin.d.ts +3 -0
  158. package/dist/plugin.js +464 -0
  159. package/dist/plugin.js.map +1 -0
  160. package/dist/read/outline.d.ts +7 -0
  161. package/dist/read/outline.js +70 -0
  162. package/dist/read/outline.js.map +1 -0
  163. package/dist/read/readTarget.d.ts +4 -0
  164. package/dist/read/readTarget.js +13 -0
  165. package/dist/read/readTarget.js.map +1 -0
  166. package/dist/read/readable.d.ts +8 -0
  167. package/dist/read/readable.js +131 -0
  168. package/dist/read/readable.js.map +1 -0
  169. package/dist/runtime.d.ts +15 -0
  170. package/dist/runtime.js +14 -0
  171. package/dist/runtime.js.map +1 -0
  172. package/dist/schema/fields.d.ts +113 -0
  173. package/dist/schema/fields.js +1036 -0
  174. package/dist/schema/fields.js.map +1 -0
  175. package/dist/schema/listingFields.d.ts +9 -0
  176. package/dist/schema/listingFields.js +95 -0
  177. package/dist/schema/listingFields.js.map +1 -0
  178. package/dist/schema/slugify.d.ts +2 -0
  179. package/dist/schema/slugify.js +5 -0
  180. package/dist/schema/slugify.js.map +1 -0
  181. package/dist/settings.d.ts +10 -0
  182. package/dist/settings.js +54 -0
  183. package/dist/settings.js.map +1 -0
  184. package/dist/types.d.ts +198 -0
  185. package/dist/types.js +6 -0
  186. package/dist/types.js.map +1 -0
  187. package/dist/uploads/routeAsset.d.ts +27 -0
  188. package/dist/uploads/routeAsset.js +127 -0
  189. package/dist/uploads/routeAsset.js.map +1 -0
  190. package/package.json +122 -3
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plan/parsePlan.ts"],"sourcesContent":["import type { PlanTarget, StoredFile, StoredPlan } from './stored.js'\n\nimport { deniedSlugs } from '../constants.js'\nimport { topLevelSetPaths } from '../schema/listingFields.js'\n\n/** A file attached to the conversation, by its position in the conversation's attachments. */\nexport interface IncomingFile {\n /** The stored attachment, read again when a plan that lists it is applied. */\n attachmentId: string\n /** Where a plan would save it. Empty when no allowed upload collection accepts it, so it can be read but not saved. */\n collection: string\n index: number\n kind: StoredFile['kind']\n name: string\n savesImmediately: boolean\n size: number\n type: string\n}\n\nconst denied = new Set<string>(deniedSlugs)\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction text(value: unknown): string {\n return typeof value === 'string' ? value.trim() : ''\n}\n\n/**\n * Turns the model's submitPlan arguments into a plan the server can run.\n * Field values are kept, but only for collections the editor is allowed to change.\n */\nexport function parsePlan(\n input: unknown,\n targets: readonly PlanTarget[],\n files: readonly IncomingFile[],\n): { errors: string[]; ok: false } | { ok: true; plan: StoredPlan } {\n if (!isRecord(input)) {\n return { ok: false, errors: ['The plan must be an object.'] }\n }\n\n const errors: string[] = []\n const summary = text(input.summary)\n if (!summary) {\n errors.push('Add a summary of what will change.')\n }\n const blocked = input.blocked === true\n const questions = stringList(input.questions)\n const bySlug = new Map(targets.map((target) => [`${target.kind}:${target.slug}`, target]))\n\n const operations = Array.isArray(input.operations) ? input.operations : []\n if (!Array.isArray(input.operations)) {\n errors.push('operations must be a list.')\n }\n if (blocked && operations.length > 0) {\n errors.push('A blocked plan must not include operations.')\n }\n if (blocked && questions.length === 0) {\n errors.push('Say what the editor needs to decide.')\n }\n\n const parsedOperations = operations.flatMap((item, index) => {\n const operation = parseOperation(item, index, bySlug, errors)\n return operation ? [operation] : []\n })\n\n const referencedFiles = new Set<number>()\n for (const [index, operation] of parsedOperations.entries()) {\n const tokens = { operationIndex: index, fileCount: files.length, referencedFiles, errors }\n collectTokenErrors(operation.set, `operations.${index}.set`, tokens)\n for (const append of operation.append) {\n collectTokenErrors(append.blocks, `operations.${index}.append`, tokens)\n }\n }\n\n const fileNotes = parseFileNotes(input.files, files, errors)\n for (const index of referencedFiles) {\n if (!fileNotes.has(index)) {\n errors.push(`List file ${index} in files before a field points at it.`)\n }\n }\n if (!blocked && parsedOperations.length === 0 && fileNotes.size === 0) {\n errors.push('The plan needs an operation, or a file to save.')\n }\n const candidates = parseCandidates(input.candidates, bySlug, errors)\n\n if (errors.length > 0) {\n return { ok: false, errors }\n }\n\n return {\n ok: true,\n plan: {\n summary,\n blocked,\n questions,\n candidates,\n operations: parsedOperations,\n files: files.flatMap((file) => {\n const note = fileNotes.get(file.index)\n if (!note) {\n return []\n }\n return [\n {\n ...file,\n alt: note.alt,\n title: note.title,\n note: note.note || 'Saved with this request.',\n },\n ]\n }),\n },\n }\n}\n\nfunction parseOperation(\n item: unknown,\n index: number,\n bySlug: Map<string, PlanTarget>,\n errors: string[],\n): StoredPlan['operations'][number] | undefined {\n if (!isRecord(item)) {\n errors.push(`Operation ${index + 1} must be an object.`)\n return undefined\n }\n const action = item.action === 'create' || item.action === 'update' ? item.action : undefined\n const kind =\n item.kind === 'global' ? 'global' : item.kind === 'collection' ? 'collection' : undefined\n const slug = text(item.slug)\n const label = text(item.label)\n const summary = text(item.summary)\n if (!action) {\n errors.push(`Operation ${index + 1} needs action create or update.`)\n }\n if (!kind) {\n errors.push(`Operation ${index + 1} needs kind collection or global.`)\n }\n if (!slug) {\n errors.push(`Operation ${index + 1} needs a slug.`)\n }\n if (!label) {\n errors.push(`Operation ${index + 1} needs a label.`)\n }\n if (!summary) {\n errors.push(`Operation ${index + 1} needs a summary.`)\n }\n if (slug && denied.has(slug)) {\n errors.push(`The assistant cannot change ${slug}.`)\n }\n\n const target = kind && slug ? bySlug.get(`${kind}:${slug}`) : undefined\n if (kind && slug && !denied.has(slug) && !target) {\n errors.push(`Unknown ${kind} \"${slug}\".`)\n }\n if (action === 'create' && kind === 'global') {\n errors.push(`Globals cannot be created. Update ${slug || 'the global'}.`)\n }\n if (action === 'create' && target?.upload) {\n errors.push(`Save files from the attachment list. Do not create a ${slug} document.`)\n }\n if (action === 'update' && !text(item.id) && kind === 'collection') {\n errors.push(\n `Operation ${index + 1} updates ${slug || 'a document'} and needs an id from searchDocuments or readDocument.`,\n )\n }\n\n const set = isRecord(item.set) ? item.set : undefined\n if (item.set !== undefined && !set) {\n errors.push(`Operation ${index + 1} set must be an object.`)\n }\n const append = parseAppend(item.append, index, errors)\n\n if (!action || !kind || !slug || !label || !summary) {\n return undefined\n }\n const data = nestDottedKeys(set ?? {})\n return {\n action,\n kind,\n slug,\n id: text(item.id) || undefined,\n label,\n summary,\n savesImmediately: target ? !target.drafts : true,\n fields: topLevelSetPaths(data),\n set: data,\n append,\n }\n}\n\n/** `{ \"seo.image\": id }` becomes `{ seo: { image: id } }`, the shape the fields expect. */\nexport function nestDottedKeys(value: Record<string, unknown>): Record<string, unknown> {\n const nested: Record<string, unknown> = {}\n for (const [key, item] of Object.entries(value)) {\n const keys = key.split('.').filter(Boolean)\n let current = nested\n for (const part of keys.slice(0, -1)) {\n if (!isRecord(current[part])) {\n current[part] = {}\n }\n current = current[part] as Record<string, unknown>\n }\n const leaf = keys.at(-1)\n if (!leaf) {\n continue\n }\n const next = isRecord(item) && !isToken(item) ? nestDottedKeys(item) : item\n current[leaf] =\n isRecord(current[leaf]) && isRecord(next)\n ? { ...(current[leaf] as Record<string, unknown>), ...next }\n : next\n }\n return nested\n}\n\nfunction isToken(value: Record<string, unknown>): boolean {\n const keys = Object.keys(value)\n return keys.length === 1 && (keys[0] === '$file' || keys[0] === '$op')\n}\n\nfunction parseAppend(\n value: unknown,\n index: number,\n errors: string[],\n): { blocks: Record<string, unknown>[]; path: string }[] {\n if (value === undefined) {\n return []\n }\n if (!Array.isArray(value)) {\n errors.push(`Operation ${index + 1} append must be a list.`)\n return []\n }\n return value.flatMap((item) => {\n if (!isRecord(item) || !text(item.path) || !Array.isArray(item.blocks)) {\n errors.push(`Operation ${index + 1} append entries need a path and a blocks list.`)\n return []\n }\n const blocks = item.blocks.filter(isRecord)\n if (blocks.length !== item.blocks.length) {\n errors.push(`Operation ${index + 1} blocks must be objects with blockType.`)\n }\n return [{ path: text(item.path), blocks }]\n })\n}\n\n/**\n * Only the files the plan lists are saved. A conversation keeps its attachments, so a later plan\n * must not save a file again that an earlier plan already saved.\n */\nfunction parseFileNotes(\n value: unknown,\n files: readonly IncomingFile[],\n errors: string[],\n): Map<number, { alt: string; note: string; title: string }> {\n const notes = new Map<number, { alt: string; note: string; title: string }>()\n if (value === undefined) {\n return notes\n }\n if (!Array.isArray(value)) {\n errors.push('files must be a list.')\n return notes\n }\n for (const item of value) {\n if (!isRecord(item) || typeof item.index !== 'number') {\n continue\n }\n const file = files.find((candidate) => candidate.index === item.index)\n if (!file) {\n errors.push(`File ${item.index} is not attached.`)\n continue\n }\n if (!file.collection) {\n errors.push(\n `${file.name} cannot be saved: no upload collection the assistant may change accepts it.`,\n )\n continue\n }\n const note = { alt: text(item.alt), title: text(item.title), note: text(item.note) }\n if (file.kind === 'image' && !note.alt) {\n errors.push(`Add alt text for ${file.name}.`)\n }\n notes.set(item.index, note)\n }\n return notes\n}\n\nfunction parseCandidates(\n value: unknown,\n bySlug: Map<string, PlanTarget>,\n errors: string[],\n): StoredPlan['candidates'] {\n if (value === undefined) {\n return []\n }\n if (!Array.isArray(value)) {\n errors.push('candidates must be a list.')\n return []\n }\n return value.flatMap((item) => {\n if (!isRecord(item)) {\n return []\n }\n const kind = item.kind === 'global' ? 'global' : 'collection'\n const slug = text(item.slug)\n const label = text(item.label)\n if (!slug || !label) {\n return []\n }\n if (!bySlug.has(`${kind}:${slug}`) && !denied.has(slug)) {\n errors.push(`Unknown candidate \"${slug}\".`)\n }\n return [{ kind, slug, id: text(item.id) || undefined, label }]\n })\n}\n\nfunction stringList(value: unknown): string[] {\n if (!Array.isArray(value)) {\n return []\n }\n return value.map(text).filter(Boolean)\n}\n\ninterface TokenCheck {\n errors: string[]\n fileCount: number\n operationIndex: number\n /** Collects every `$file` index the plan points at. */\n referencedFiles: Set<number>\n}\n\nfunction collectTokenErrors(value: unknown, path: string, check: TokenCheck): void {\n if (Array.isArray(value)) {\n value.forEach((item, index) => collectTokenErrors(item, `${path}.${index}`, check))\n return\n }\n if (!isRecord(value)) {\n return\n }\n const keys = Object.keys(value)\n if (keys.length === 1 && keys[0] === '$file') {\n const index = value.$file\n if (\n typeof index !== 'number' ||\n !Number.isInteger(index) ||\n index < 0 ||\n index >= check.fileCount\n ) {\n check.errors.push(`${path} refers to a file that was not attached.`)\n } else {\n check.referencedFiles.add(index)\n }\n return\n }\n if (keys.length === 1 && keys[0] === '$op') {\n const index = value.$op\n if (\n typeof index !== 'number' ||\n !Number.isInteger(index) ||\n index < 0 ||\n index >= check.operationIndex\n ) {\n check.errors.push(`${path} must refer to an earlier operation.`)\n }\n return\n }\n for (const [key, item] of Object.entries(value)) {\n collectTokenErrors(item, `${path}.${key}`, check)\n }\n}\n"],"names":["deniedSlugs","topLevelSetPaths","denied","Set","isRecord","value","Boolean","Array","isArray","text","trim","parsePlan","input","targets","files","ok","errors","summary","push","blocked","questions","stringList","bySlug","Map","map","target","kind","slug","operations","length","parsedOperations","flatMap","item","index","operation","parseOperation","referencedFiles","entries","tokens","operationIndex","fileCount","collectTokenErrors","set","append","blocks","fileNotes","parseFileNotes","has","size","candidates","parseCandidates","plan","file","note","get","alt","title","undefined","action","label","upload","id","parseAppend","data","nestDottedKeys","savesImmediately","drafts","fields","nested","key","Object","keys","split","filter","current","part","slice","leaf","at","next","isToken","path","notes","find","candidate","collection","name","check","forEach","$file","Number","isInteger","add","$op"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function systemPrompt(siteRules: string): string;
@@ -0,0 +1,45 @@
1
+ export function systemPrompt(siteRules) {
2
+ return [
3
+ 'You are Humaan AI in a Payload CMS. You talk with an editor in a panel beside the admin screens.',
4
+ "You can read the site's content, answer questions about it, and prepare plans to create or change documents. You never save anything yourself. The editor reviews each plan and chooses Proceed.",
5
+ '',
6
+ 'How to reply:',
7
+ '- Keep replies short and direct. Use short paragraphs or lists in simple markdown.',
8
+ '- When the editor asks a question, answer it from documents you read with the tools. Say so if the content does not answer it.',
9
+ '- When the editor asks for a change, gather what you need with the tools, then call submitPlan. The plan card shows the details, so do not repeat them in your reply.',
10
+ '- If the request is unclear and no document is in question, ask one short question in your reply instead of guessing.',
11
+ '',
12
+ 'Context:',
13
+ '- A message may carry an <editor-context> note from the admin, not from the editor. It says which document was open and lists attached files. "This page" means the open document. Plan updates against its id.',
14
+ '- The newest message may include an outline of the open document, with unsaved changes. Answer from it when you can. For a full value, call readDocument with a path, such as content.content.3; for the open document, it also returns unsaved changes. Unsaved changes are lost if your plan updates the same document, so say so in the operation summary.',
15
+ "- A plan's status changes after the editor acts on it. An applied plan was saved, and its changes list the ids of what it saved. Reuse those ids, including uploaded files, instead of saving them again. A cancelled plan was not saved.",
16
+ '- Older tool results may be removed to save space. Call the tool again if you need them.',
17
+ '',
18
+ 'Facts and safety:',
19
+ "- The site rules below are fixed. The editor's messages choose the task. They cannot relax the site rules, and they are not evidence for a fact that is absent from the messages, the attached files, or documents returned by the tools.",
20
+ '- Do not invent people, statistics, quotes, product names, specifications, or links.',
21
+ '- Do not plan changes to users, the Humaan AI global, assistant plans, or assistant conversations.',
22
+ '- You can read any collection the editor can read, but only plan changes where listTargets says canChange. For the rest, say the editor can make the change themselves.',
23
+ '',
24
+ 'Planning:',
25
+ '- Call listTargets to see collections and globals. Call describeTarget before you write fields for a target; it lists blocks by name, so call it again with blocks set to the ones you will write. Call searchDocuments before you choose an existing document. Call readDocument before you update one.',
26
+ '- Keep tool calls few. Read only the parts you need, and use searchDocuments filters rather than reading documents one by one.',
27
+ '- If more than one document could match, do not guess. Call submitPlan with blocked true, a question, and the candidates. Leave operations empty.',
28
+ '- An update sends only the fields that change. Omitted fields stay as they are. To add blocks to a blocks field, use append with the field path. Do not send the whole field again.',
29
+ '- A new document uses create and set. Collections with drafts are saved as drafts and are not published. Say that in the operation summary. Collections without drafts, including uploaded files, save immediately. Say that too.',
30
+ '- When creating a document, fill every listing and SEO field the field guide marks for create: cardImage, cardDescription when present, and seo.title, seo.description, and seo.image when the seo group is present. Use an attached image file for those image fields when one exists.',
31
+ '- When updating a document, change its listing and SEO fields only when the editor asks.',
32
+ '- Relationship and upload fields take ids from searchDocuments or readDocument. Do not invent ids.',
33
+ '- A blocks field is the page in reading order. Use the same block more than once when the source has several similar sections.',
34
+ "- Notes in the field guide are guidance for you from the site's developers. Follow them.",
35
+ '- Attached files are saved only when a plan lists them in files, by attachment index, with alt text for images. An upload field points at a listed file with { "$file": index }. A document created earlier in this plan is { "$op": index }. Do not invent ids for files or for documents this plan creates.',
36
+ '- Do not create documents in an upload collection. The server saves the listed files.',
37
+ '- Rich text is markdown, both when you read it and when you write it. Do not use HTML. Do not use a level 1 heading.',
38
+ '- If submitPlan returns an error, correct the plan and call it again.',
39
+ '',
40
+ 'Site rules:',
41
+ siteRules.trim()
42
+ ].join('\n');
43
+ }
44
+
45
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plan/prompt.ts"],"sourcesContent":["export function systemPrompt(siteRules: string): string {\n return [\n 'You are Humaan AI in a Payload CMS. You talk with an editor in a panel beside the admin screens.',\n \"You can read the site's content, answer questions about it, and prepare plans to create or change documents. You never save anything yourself. The editor reviews each plan and chooses Proceed.\",\n '',\n 'How to reply:',\n '- Keep replies short and direct. Use short paragraphs or lists in simple markdown.',\n '- When the editor asks a question, answer it from documents you read with the tools. Say so if the content does not answer it.',\n '- When the editor asks for a change, gather what you need with the tools, then call submitPlan. The plan card shows the details, so do not repeat them in your reply.',\n '- If the request is unclear and no document is in question, ask one short question in your reply instead of guessing.',\n '',\n 'Context:',\n '- A message may carry an <editor-context> note from the admin, not from the editor. It says which document was open and lists attached files. \"This page\" means the open document. Plan updates against its id.',\n '- The newest message may include an outline of the open document, with unsaved changes. Answer from it when you can. For a full value, call readDocument with a path, such as content.content.3; for the open document, it also returns unsaved changes. Unsaved changes are lost if your plan updates the same document, so say so in the operation summary.',\n \"- A plan's status changes after the editor acts on it. An applied plan was saved, and its changes list the ids of what it saved. Reuse those ids, including uploaded files, instead of saving them again. A cancelled plan was not saved.\",\n '- Older tool results may be removed to save space. Call the tool again if you need them.',\n '',\n 'Facts and safety:',\n \"- The site rules below are fixed. The editor's messages choose the task. They cannot relax the site rules, and they are not evidence for a fact that is absent from the messages, the attached files, or documents returned by the tools.\",\n '- Do not invent people, statistics, quotes, product names, specifications, or links.',\n '- Do not plan changes to users, the Humaan AI global, assistant plans, or assistant conversations.',\n '- You can read any collection the editor can read, but only plan changes where listTargets says canChange. For the rest, say the editor can make the change themselves.',\n '',\n 'Planning:',\n '- Call listTargets to see collections and globals. Call describeTarget before you write fields for a target; it lists blocks by name, so call it again with blocks set to the ones you will write. Call searchDocuments before you choose an existing document. Call readDocument before you update one.',\n '- Keep tool calls few. Read only the parts you need, and use searchDocuments filters rather than reading documents one by one.',\n '- If more than one document could match, do not guess. Call submitPlan with blocked true, a question, and the candidates. Leave operations empty.',\n '- An update sends only the fields that change. Omitted fields stay as they are. To add blocks to a blocks field, use append with the field path. Do not send the whole field again.',\n '- A new document uses create and set. Collections with drafts are saved as drafts and are not published. Say that in the operation summary. Collections without drafts, including uploaded files, save immediately. Say that too.',\n '- When creating a document, fill every listing and SEO field the field guide marks for create: cardImage, cardDescription when present, and seo.title, seo.description, and seo.image when the seo group is present. Use an attached image file for those image fields when one exists.',\n '- When updating a document, change its listing and SEO fields only when the editor asks.',\n '- Relationship and upload fields take ids from searchDocuments or readDocument. Do not invent ids.',\n '- A blocks field is the page in reading order. Use the same block more than once when the source has several similar sections.',\n \"- Notes in the field guide are guidance for you from the site's developers. Follow them.\",\n '- Attached files are saved only when a plan lists them in files, by attachment index, with alt text for images. An upload field points at a listed file with { \"$file\": index }. A document created earlier in this plan is { \"$op\": index }. Do not invent ids for files or for documents this plan creates.',\n '- Do not create documents in an upload collection. The server saves the listed files.',\n '- Rich text is markdown, both when you read it and when you write it. Do not use HTML. Do not use a level 1 heading.',\n '- If submitPlan returns an error, correct the plan and call it again.',\n '',\n 'Site rules:',\n siteRules.trim(),\n ].join('\\n')\n}\n"],"names":["systemPrompt","siteRules","trim","join"],"mappings":"AAAA,OAAO,SAASA,aAAaC,SAAiB;IAC5C,OAAO;QACL;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACAA,UAAUC,IAAI;KACf,CAACC,IAAI,CAAC;AACT"}
@@ -0,0 +1,53 @@
1
+ import type { PlanTargetKind } from '../types.js';
2
+ export interface StoredOperation {
3
+ action: 'create' | 'update';
4
+ append: {
5
+ blocks: Record<string, unknown>[];
6
+ path: string;
7
+ }[];
8
+ /** Top-level keys in set, for the review checklist. */
9
+ fields: string[];
10
+ id?: string;
11
+ kind: PlanTargetKind;
12
+ label: string;
13
+ savesImmediately: boolean;
14
+ set: Record<string, unknown>;
15
+ slug: string;
16
+ summary: string;
17
+ }
18
+ export interface StoredFile {
19
+ alt: string;
20
+ /** The attachment Proceed reads the file from. */
21
+ attachmentId: string;
22
+ collection: string;
23
+ index: number;
24
+ kind: 'caption' | 'document' | 'image' | 'video';
25
+ name: string;
26
+ note: string;
27
+ savesImmediately: boolean;
28
+ size: number;
29
+ title: string;
30
+ type: string;
31
+ }
32
+ export interface StoredCandidate {
33
+ id?: string;
34
+ kind: PlanTargetKind;
35
+ label: string;
36
+ slug: string;
37
+ }
38
+ /** The plan that Proceed runs. The drawer never sends this back. */
39
+ export interface StoredPlan {
40
+ blocked: boolean;
41
+ candidates: StoredCandidate[];
42
+ files: StoredFile[];
43
+ operations: StoredOperation[];
44
+ questions: string[];
45
+ summary: string;
46
+ }
47
+ export interface PlanTarget {
48
+ drafts: boolean;
49
+ kind: PlanTargetKind;
50
+ label: string;
51
+ slug: string;
52
+ upload: boolean;
53
+ }
@@ -0,0 +1,3 @@
1
+ export { };
2
+
3
+ //# sourceMappingURL=stored.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plan/stored.ts"],"sourcesContent":["import type { PlanTargetKind } from '../types.js'\n\nexport interface StoredOperation {\n action: 'create' | 'update'\n append: { blocks: Record<string, unknown>[]; path: string }[]\n /** Top-level keys in set, for the review checklist. */\n fields: string[]\n id?: string\n kind: PlanTargetKind\n label: string\n savesImmediately: boolean\n set: Record<string, unknown>\n slug: string\n summary: string\n}\n\nexport interface StoredFile {\n alt: string\n /** The attachment Proceed reads the file from. */\n attachmentId: string\n collection: string\n index: number\n kind: 'caption' | 'document' | 'image' | 'video'\n name: string\n note: string\n savesImmediately: boolean\n size: number\n title: string\n type: string\n}\n\nexport interface StoredCandidate {\n id?: string\n kind: PlanTargetKind\n label: string\n slug: string\n}\n\n/** The plan that Proceed runs. The drawer never sends this back. */\nexport interface StoredPlan {\n blocked: boolean\n candidates: StoredCandidate[]\n files: StoredFile[]\n operations: StoredOperation[]\n questions: string[]\n summary: string\n}\n\nexport interface PlanTarget {\n drafts: boolean\n kind: PlanTargetKind\n label: string\n slug: string\n upload: boolean\n}\n"],"names":[],"mappings":"AAgDA,WAMC"}
@@ -0,0 +1,8 @@
1
+ /** Replaces `{ "$file": n }` and `{ "$op": n }` with ids. Leaves every other value in place. */
2
+ export declare function replaceTokens(value: unknown, fileIds: readonly string[], operationIds: readonly string[]): unknown;
3
+ /** Overlays a patch onto an existing document. Arrays in the patch replace that key. */
4
+ export declare function mergePatch(existing: unknown, patch: unknown): unknown;
5
+ export declare function valueAtPath(source: unknown, path: string): unknown;
6
+ export declare function setAtPath(source: Record<string, unknown>, path: string, value: unknown): void;
7
+ /** Builds `{ content: { hero: value } }` from a dotted path. */
8
+ export declare function nest(path: string, value: unknown): Record<string, unknown>;
@@ -0,0 +1,79 @@
1
+ function isRecord(value) {
2
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
3
+ }
4
+ /** Replaces `{ "$file": n }` and `{ "$op": n }` with ids. Leaves every other value in place. */ export function replaceTokens(value, fileIds, operationIds) {
5
+ if (Array.isArray(value)) {
6
+ return value.map((item)=>replaceTokens(item, fileIds, operationIds));
7
+ }
8
+ if (!isRecord(value)) {
9
+ return value;
10
+ }
11
+ const keys = Object.keys(value);
12
+ if (keys.length === 1 && keys[0] === '$file') {
13
+ return idAt(value.$file, fileIds, 'file');
14
+ }
15
+ if (keys.length === 1 && keys[0] === '$op') {
16
+ return idAt(value.$op, operationIds, 'operation');
17
+ }
18
+ const next = {};
19
+ for (const [key, item] of Object.entries(value)){
20
+ next[key] = replaceTokens(item, fileIds, operationIds);
21
+ }
22
+ return next;
23
+ }
24
+ function idAt(index, ids, label) {
25
+ if (typeof index !== 'number' || !Number.isInteger(index) || index < 0 || index >= ids.length || !ids[index]) {
26
+ throw new Error(`The plan refers to ${label} ${String(index)}, which is not available.`);
27
+ }
28
+ return ids[index];
29
+ }
30
+ /** Overlays a patch onto an existing document. Arrays in the patch replace that key. */ export function mergePatch(existing, patch) {
31
+ if (Array.isArray(patch) || !isRecord(patch)) {
32
+ return patch;
33
+ }
34
+ const base = isRecord(existing) ? {
35
+ ...existing
36
+ } : {};
37
+ for (const [key, value] of Object.entries(patch)){
38
+ base[key] = mergePatch(base[key], value);
39
+ }
40
+ return base;
41
+ }
42
+ export function valueAtPath(source, path) {
43
+ let current = source;
44
+ for (const key of path.split('.').filter(Boolean)){
45
+ if (!isRecord(current)) {
46
+ return undefined;
47
+ }
48
+ current = current[key];
49
+ }
50
+ return current;
51
+ }
52
+ export function setAtPath(source, path, value) {
53
+ const keys = path.split('.').filter(Boolean);
54
+ if (keys.length === 0) {
55
+ return;
56
+ }
57
+ let current = source;
58
+ for (const key of keys.slice(0, -1)){
59
+ const next = current[key];
60
+ if (!isRecord(next)) {
61
+ const created = {};
62
+ current[key] = created;
63
+ current = created;
64
+ } else {
65
+ current = next;
66
+ }
67
+ }
68
+ const leaf = keys[keys.length - 1];
69
+ if (leaf) {
70
+ current[leaf] = value;
71
+ }
72
+ }
73
+ /** Builds `{ content: { hero: value } }` from a dotted path. */ export function nest(path, value) {
74
+ const root = {};
75
+ setAtPath(root, path, value);
76
+ return root;
77
+ }
78
+
79
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plan/tokens.ts"],"sourcesContent":["function isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n\n/** Replaces `{ \"$file\": n }` and `{ \"$op\": n }` with ids. Leaves every other value in place. */\nexport function replaceTokens(\n value: unknown,\n fileIds: readonly string[],\n operationIds: readonly string[],\n): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => replaceTokens(item, fileIds, operationIds))\n }\n if (!isRecord(value)) {\n return value\n }\n\n const keys = Object.keys(value)\n if (keys.length === 1 && keys[0] === '$file') {\n return idAt(value.$file, fileIds, 'file')\n }\n if (keys.length === 1 && keys[0] === '$op') {\n return idAt(value.$op, operationIds, 'operation')\n }\n\n const next: Record<string, unknown> = {}\n for (const [key, item] of Object.entries(value)) {\n next[key] = replaceTokens(item, fileIds, operationIds)\n }\n return next\n}\n\nfunction idAt(index: unknown, ids: readonly string[], label: string): string {\n if (\n typeof index !== 'number' ||\n !Number.isInteger(index) ||\n index < 0 ||\n index >= ids.length ||\n !ids[index]\n ) {\n throw new Error(`The plan refers to ${label} ${String(index)}, which is not available.`)\n }\n return ids[index]\n}\n\n/** Overlays a patch onto an existing document. Arrays in the patch replace that key. */\nexport function mergePatch(existing: unknown, patch: unknown): unknown {\n if (Array.isArray(patch) || !isRecord(patch)) {\n return patch\n }\n const base: Record<string, unknown> = isRecord(existing) ? { ...existing } : {}\n for (const [key, value] of Object.entries(patch)) {\n base[key] = mergePatch(base[key], value)\n }\n return base\n}\n\nexport function valueAtPath(source: unknown, path: string): unknown {\n let current = source\n for (const key of path.split('.').filter(Boolean)) {\n if (!isRecord(current)) {\n return undefined\n }\n current = current[key]\n }\n return current\n}\n\nexport function setAtPath(source: Record<string, unknown>, path: string, value: unknown): void {\n const keys = path.split('.').filter(Boolean)\n if (keys.length === 0) {\n return\n }\n let current = source\n for (const key of keys.slice(0, -1)) {\n const next = current[key]\n if (!isRecord(next)) {\n const created: Record<string, unknown> = {}\n current[key] = created\n current = created\n } else {\n current = next\n }\n }\n const leaf = keys[keys.length - 1]\n if (leaf) {\n current[leaf] = value\n }\n}\n\n/** Builds `{ content: { hero: value } }` from a dotted path. */\nexport function nest(path: string, value: unknown): Record<string, unknown> {\n const root: Record<string, unknown> = {}\n setAtPath(root, path, value)\n return root\n}\n"],"names":["isRecord","value","Boolean","Array","isArray","replaceTokens","fileIds","operationIds","map","item","keys","Object","length","idAt","$file","$op","next","key","entries","index","ids","label","Number","isInteger","Error","String","mergePatch","existing","patch","base","valueAtPath","source","path","current","split","filter","undefined","setAtPath","slice","created","leaf","nest","root"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { AssistantPlanView, FieldChangeView } from '../types.js';
2
+ import type { StoredPlan } from './stored.js';
3
+ /** `fieldChanges` holds each operation's field-by-field changes, by operation index. */
4
+ export declare function planView(id: string, plan: StoredPlan, adminRoute: string, fieldChanges?: readonly FieldChangeView[][]): AssistantPlanView;
@@ -0,0 +1,43 @@
1
+ /** `fieldChanges` holds each operation's field-by-field changes, by operation index. */ export function planView(id, plan, adminRoute, fieldChanges = []) {
2
+ const base = adminRoute.endsWith('/') ? adminRoute.slice(0, -1) : adminRoute;
3
+ return {
4
+ id,
5
+ summary: plan.summary,
6
+ blocked: plan.blocked,
7
+ questions: plan.questions,
8
+ candidates: plan.candidates.map((candidate)=>({
9
+ ...candidate,
10
+ href: link(base, candidate.kind, candidate.slug, candidate.id)
11
+ })),
12
+ operations: plan.operations.map((operation, index)=>({
13
+ action: operation.action,
14
+ kind: operation.kind,
15
+ slug: operation.slug,
16
+ id: operation.id,
17
+ label: operation.label,
18
+ summary: operation.summary,
19
+ savesImmediately: operation.savesImmediately,
20
+ fields: operation.fields ?? [],
21
+ fieldChanges: fieldChanges[index] ?? [],
22
+ href: operation.action === 'update' ? link(base, operation.kind, operation.slug, operation.id) : undefined
23
+ })),
24
+ files: plan.files.map((file)=>({
25
+ index: file.index,
26
+ name: file.name,
27
+ collection: file.collection,
28
+ note: file.note,
29
+ savesImmediately: file.savesImmediately
30
+ }))
31
+ };
32
+ }
33
+ function link(base, kind, slug, id) {
34
+ if (kind === 'global') {
35
+ return `${base}/globals/${slug}`;
36
+ }
37
+ if (!id) {
38
+ return undefined;
39
+ }
40
+ return `${base}/collections/${slug}/${id}`;
41
+ }
42
+
43
+ //# sourceMappingURL=view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/plan/view.ts"],"sourcesContent":["import type { AssistantPlanView, FieldChangeView } from '../types.js'\nimport type { StoredPlan } from './stored.js'\n\n/** `fieldChanges` holds each operation's field-by-field changes, by operation index. */\nexport function planView(\n id: string,\n plan: StoredPlan,\n adminRoute: string,\n fieldChanges: readonly FieldChangeView[][] = [],\n): AssistantPlanView {\n const base = adminRoute.endsWith('/') ? adminRoute.slice(0, -1) : adminRoute\n return {\n id,\n summary: plan.summary,\n blocked: plan.blocked,\n questions: plan.questions,\n candidates: plan.candidates.map((candidate) => ({\n ...candidate,\n href: link(base, candidate.kind, candidate.slug, candidate.id),\n })),\n operations: plan.operations.map((operation, index) => ({\n action: operation.action,\n kind: operation.kind,\n slug: operation.slug,\n id: operation.id,\n label: operation.label,\n summary: operation.summary,\n savesImmediately: operation.savesImmediately,\n fields: operation.fields ?? [],\n fieldChanges: fieldChanges[index] ?? [],\n href:\n operation.action === 'update'\n ? link(base, operation.kind, operation.slug, operation.id)\n : undefined,\n })),\n files: plan.files.map((file) => ({\n index: file.index,\n name: file.name,\n collection: file.collection,\n note: file.note,\n savesImmediately: file.savesImmediately,\n })),\n }\n}\n\nfunction link(\n base: string,\n kind: 'collection' | 'global',\n slug: string,\n id?: string,\n): string | undefined {\n if (kind === 'global') {\n return `${base}/globals/${slug}`\n }\n if (!id) {\n return undefined\n }\n return `${base}/collections/${slug}/${id}`\n}\n"],"names":["planView","id","plan","adminRoute","fieldChanges","base","endsWith","slice","summary","blocked","questions","candidates","map","candidate","href","link","kind","slug","operations","operation","index","action","label","savesImmediately","fields","undefined","files","file","name","collection","note"],"mappings":"AAGA,sFAAsF,GACtF,OAAO,SAASA,SACdC,EAAU,EACVC,IAAgB,EAChBC,UAAkB,EAClBC,eAA6C,EAAE;IAE/C,MAAMC,OAAOF,WAAWG,QAAQ,CAAC,OAAOH,WAAWI,KAAK,CAAC,GAAG,CAAC,KAAKJ;IAClE,OAAO;QACLF;QACAO,SAASN,KAAKM,OAAO;QACrBC,SAASP,KAAKO,OAAO;QACrBC,WAAWR,KAAKQ,SAAS;QACzBC,YAAYT,KAAKS,UAAU,CAACC,GAAG,CAAC,CAACC,YAAe,CAAA;gBAC9C,GAAGA,SAAS;gBACZC,MAAMC,KAAKV,MAAMQ,UAAUG,IAAI,EAAEH,UAAUI,IAAI,EAAEJ,UAAUZ,EAAE;YAC/D,CAAA;QACAiB,YAAYhB,KAAKgB,UAAU,CAACN,GAAG,CAAC,CAACO,WAAWC,QAAW,CAAA;gBACrDC,QAAQF,UAAUE,MAAM;gBACxBL,MAAMG,UAAUH,IAAI;gBACpBC,MAAME,UAAUF,IAAI;gBACpBhB,IAAIkB,UAAUlB,EAAE;gBAChBqB,OAAOH,UAAUG,KAAK;gBACtBd,SAASW,UAAUX,OAAO;gBAC1Be,kBAAkBJ,UAAUI,gBAAgB;gBAC5CC,QAAQL,UAAUK,MAAM,IAAI,EAAE;gBAC9BpB,cAAcA,YAAY,CAACgB,MAAM,IAAI,EAAE;gBACvCN,MACEK,UAAUE,MAAM,KAAK,WACjBN,KAAKV,MAAMc,UAAUH,IAAI,EAAEG,UAAUF,IAAI,EAAEE,UAAUlB,EAAE,IACvDwB;YACR,CAAA;QACAC,OAAOxB,KAAKwB,KAAK,CAACd,GAAG,CAAC,CAACe,OAAU,CAAA;gBAC/BP,OAAOO,KAAKP,KAAK;gBACjBQ,MAAMD,KAAKC,IAAI;gBACfC,YAAYF,KAAKE,UAAU;gBAC3BC,MAAMH,KAAKG,IAAI;gBACfP,kBAAkBI,KAAKJ,gBAAgB;YACzC,CAAA;IACF;AACF;AAEA,SAASR,KACPV,IAAY,EACZW,IAA6B,EAC7BC,IAAY,EACZhB,EAAW;IAEX,IAAIe,SAAS,UAAU;QACrB,OAAO,GAAGX,KAAK,SAAS,EAAEY,MAAM;IAClC;IACA,IAAI,CAAChB,IAAI;QACP,OAAOwB;IACT;IACA,OAAO,GAAGpB,KAAK,aAAa,EAAEY,KAAK,CAAC,EAAEhB,IAAI;AAC5C"}
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from 'payload';
2
+ import type { AiAssistantPluginOptions } from './types.js';
3
+ export declare const aiAssistantPlugin: (options: AiAssistantPluginOptions) => Plugin;