{"_id":"@apostrophecms/ai-helper","_rev":"28-a0326807b4983edc91d5cac21501ff04","name":"@apostrophecms/ai-helper","dist-tags":{"beta":"1.0.0-beta.3","latest":"1.0.0-beta.13"},"versions":{"1.0.0-beta":{"name":"@apostrophecms/ai-helper","version":"1.0.0-beta","keywords":["ApostropheCMS","apostrophe"],"author":{"name":"Apostrophe Technologies, Inc."},"license":"MIT","_id":"@apostrophecms/ai-helper@1.0.0-beta","maintainers":[{"name":"falkodev","email":"anthony@apostrophecms.com"},{"name":"triskuit","email":"tristan.krug@protonmail.com"},{"name":"bodonkey","email":"robert@robertmeans.net"},{"name":"etlaurent","email":"etldev@tuta.io"},{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"stuartromanek","email":"stuart@punkave.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"alexbea","email":"abea@mailbox.org"},{"name":"gregvanbrug","email":"greg.vanbrug@gmail.com"},{"name":"valjed","email":"vjeudy@protonmail.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"}],"homepage":"https://github.com/apostrophecms/ai-helper#readme","bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"dist":{"shasum":"14cd11124f80701c97ade8e54f9ca4aea4c5932f","tarball":"https://registry.npmjs.org/@apostrophecms/ai-helper/-/ai-helper-1.0.0-beta.tgz","fileCount":13,"integrity":"sha512-SGf8NJn4MJ41HOusgF7L3zTAQufftjOQ7CZZQ2IGMw9MgcWMT7HxUYieZc+NPEibBNBbPgDtg/RseIWKchlO0g==","signatures":[{"sig":"MEYCIQDMutx/VuzRSE32d49ogBl9wkXR76ysVIUtbJAaTijHsAIhAIAlm8JLa6H7ckwtkWLH0ezQw0HajcIv9z2JKso7oBVK","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":95070,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkSrsQACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqkbBAAk4UauMGq23VeaqpBxSTjjnyYURT594SGtoaFC7imA4hTkTwu\r\neOQBjugAdqdcEF94y4/ISv1l0Lm7bUM3NtCzIk80JwKhz3Ff5qbYncXOA7YK\r\nNoeRZowo4Pi90r6xC67loVR8LzhH8NAtabknWQwokxg/AVXj3xZM6d7NDWeq\r\nSMJ+6XInz427sNWKceXFVFKeipqTRO1nodJFPbhxBG5fP+lepjQlHoLoK2xU\r\n+qlBs+9mdMRk+m8lG9vz4n0seQWsdL+L8TQOmAaiVFUJUF3ltITdNt3c2oUg\r\nI2IpB6IEm+yUMx6lxgifaNlZrhKKx2+bsFkY9e5cR7RVWJKHgvdOJgetNkmS\r\n5icBeoflqTBewzbp63VDtN/fnojh+o2XlN1gkosDmRxHFjZn5vtRgwuds9/Q\r\nOs1ehSKOkD4ArQlY1SV8M3QMZDKlhQ/gn9ZpcpC9tHVhYQimeeIwI7A3XaVm\r\nt/AqKnjNjIWFmNxHcZR2u+teK0ognMNiZLxscWegAjGEy6iAZv7bx802FuI9\r\n6b/ArdCmyPhY/kcR7xCtC8pcZhWWmplwwc2pf6NaC5ilyeCoxUL70VXwrlwS\r\n03a0i3Uv9/cy8u6larpK9PKmTpbhuLr84UysDtfL06dllfS6yQJt0ULW44+1\r\nkPf88PtTdARvMZrLpCSWpm+PkpmnQeU+FQY=\r\n=fJfh\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"faa045b85fe09645173494423c232731ab149cbe","scripts":{"test":"npx eslint ."},"_npmUser":{"name":"boutell","email":"tom@apostrophecms.com"},"repository":{"url":"git+https://github.com/apostrophecms/ai-helper.git","type":"git"},"_npmVersion":"8.19.2","description":"AI helpers for content creation","directories":{},"_nodeVersion":"16.15.0","dependencies":{"cuid":"^3.0.0","marked":"^4.3.0","form-data":"^4.0.0","node-fetch":"^2.6.9"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^7.18.0","eslint-plugin-vue":"^7.4.1","eslint-config-apostrophe":"^3.4.1"},"_npmOperationalInternal":{"tmp":"tmp/ai-helper_1.0.0-beta_1682619152247_0.15180327960117257","host":"s3://npm-registry-packages"}},"1.0.0-beta.2":{"name":"@apostrophecms/ai-helper","version":"1.0.0-beta.2","keywords":["ApostropheCMS","apostrophe"],"author":{"name":"Apostrophe Technologies, Inc."},"license":"MIT","_id":"@apostrophecms/ai-helper@1.0.0-beta.2","maintainers":[{"name":"falkodev","email":"anthony@apostrophecms.com"},{"name":"triskuit","email":"tristan.krug@protonmail.com"},{"name":"bodonkey","email":"robert@robertmeans.net"},{"name":"etlaurent","email":"etldev@tuta.io"},{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"stuartromanek","email":"stuart@punkave.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"alexbea","email":"abea@mailbox.org"},{"name":"gregvanbrug","email":"greg.vanbrug@gmail.com"},{"name":"valjed","email":"vjeudy@protonmail.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"}],"homepage":"https://github.com/apostrophecms/ai-helper#readme","bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"dist":{"shasum":"26cb9a98f8c0180c4832edd5d8d28068f9179b0a","tarball":"https://registry.npmjs.org/@apostrophecms/ai-helper/-/ai-helper-1.0.0-beta.2.tgz","fileCount":13,"integrity":"sha512-g99NBQA7ETugCvGw5xRt3f5qH9jZrbRMo8lLLEFapR2NrqWukRxJz70CbAQ0TOS8aEPQlAhBbGRLMycuCisocw==","signatures":[{"sig":"MEUCIQCSBg4Bjxpfw6CQPOJHJ1EpCKX6Lbhnm+bIygiRz0sRAAIgQWOnZ8ln3mY83Zsk/o2tPr12JygAterzBFZb/8dsEhg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":95228},"main":"index.js","gitHead":"d50e2078082d588ee498860f21120db7d520bf29","scripts":{"test":"npx eslint ."},"_npmUser":{"name":"boutell","email":"tom@apostrophecms.com"},"repository":{"url":"git+https://github.com/apostrophecms/ai-helper.git","type":"git"},"_npmVersion":"8.19.2","description":"AI helpers for content creation","directories":{},"_nodeVersion":"16.15.0","dependencies":{"cuid":"^3.0.0","sharp":"^0.30.7","marked":"^4.3.0","form-data":"^4.0.0","node-fetch":"^2.6.9"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^7.18.0","eslint-plugin-vue":"^7.4.1","eslint-config-apostrophe":"^3.4.1"},"_npmOperationalInternal":{"tmp":"tmp/ai-helper_1.0.0-beta.2_1685116201881_0.22766344923865978","host":"s3://npm-registry-packages"}},"1.0.0-beta.3":{"name":"@apostrophecms/ai-helper","version":"1.0.0-beta.3","keywords":["ApostropheCMS","apostrophe"],"author":{"name":"Apostrophe Technologies, Inc."},"license":"MIT","_id":"@apostrophecms/ai-helper@1.0.0-beta.3","maintainers":[{"name":"falkodev","email":"anthony@apostrophecms.com"},{"name":"triskuit","email":"tristan.krug@protonmail.com"},{"name":"bodonkey","email":"robert@robertmeans.net"},{"name":"etlaurent","email":"etldev@tuta.io"},{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"stuartromanek","email":"stuart@punkave.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"alexbea","email":"abea@mailbox.org"},{"name":"gregvanbrug","email":"greg.vanbrug@gmail.com"},{"name":"valjed","email":"vjeudy@protonmail.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"}],"homepage":"https://github.com/apostrophecms/ai-helper#readme","bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"dist":{"shasum":"424a8c1d052ace9e326bf65f88b032210743b6fc","tarball":"https://registry.npmjs.org/@apostrophecms/ai-helper/-/ai-helper-1.0.0-beta.3.tgz","fileCount":13,"integrity":"sha512-DOqIqLI5uacMEi1vysFn4cdBZjjJTubAN2j2t8FFxWY9cxZQUC4h7lSfmsObftvk7sp4XIbmP5ssintIYrQzYg==","signatures":[{"sig":"MEUCIQDQPrBOcvUFIg1aGFJox5cVFrGu+azYEYinZXcJ+9x5JAIgU6+oJtM02mJPwPHFTKz7sElGRhAjJNcCe0HdTCr7D10=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":95715},"main":"index.js","gitHead":"9362a2e8f4a930dd6e7ed1a9c7769f527b1df117","scripts":{"test":"npx eslint ."},"_npmUser":{"name":"boutell","email":"tom@apostrophecms.com"},"repository":{"url":"git+https://github.com/apostrophecms/ai-helper.git","type":"git"},"_npmVersion":"9.5.0","description":"AI helpers for content creation","directories":{},"_nodeVersion":"18.15.0","dependencies":{"cuid":"^3.0.0","sharp":"^0.30.7","marked":"^4.3.0","form-data":"^4.0.0","node-fetch":"^2.6.9"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"eslint":"^7.18.0","eslint-plugin-vue":"^7.4.1","eslint-config-apostrophe":"^3.4.1"},"_npmOperationalInternal":{"tmp":"tmp/ai-helper_1.0.0-beta.3_1691063691643_0.29561041351920836","host":"s3://npm-registry-packages"}},"1.0.0-beta.4":{"name":"@apostrophecms/ai-helper","version":"1.0.0-beta.4","keywords":["ApostropheCMS","apostrophe"],"author":{"name":"Apostrophe Technologies, Inc."},"license":"MIT","_id":"@apostrophecms/ai-helper@1.0.0-beta.4","maintainers":[{"name":"triskuit","email":"tristan.krug@protonmail.com"},{"name":"bodonkey","email":"robert@robertmeans.net"},{"name":"etlaurent","email":"etldev@tuta.io"},{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"stuartromanek","email":"stuart@punkave.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"alexbea","email":"abea@mailbox.org"},{"name":"gregvanbrug","email":"greg.vanbrug@gmail.com"},{"name":"valjed","email":"vjeudy@protonmail.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"}],"homepage":"https://github.com/apostrophecms/ai-helper#readme","bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"dist":{"shasum":"465521080393ee2e92904f021d753e28bd238033","tarball":"https://registry.npmjs.org/@apostrophecms/ai-helper/-/ai-helper-1.0.0-beta.4.tgz","fileCount":13,"integrity":"sha512-KJDq2upj3p+BYnE3iSG3r6P5FEzt6thohiRPAGRyoN+e9fe2RIqojh0ux82FiHtLDAjH8xkFj4p20YGtm7+ZUg==","signatures":[{"sig":"MEYCIQC5+OVDtKH4Nc9pKs9CNTu1wKkH9j5Ho7XWAnXcM1br5AIhAOL+ZFQ08KRDz8o6H93scAoMTGh3Ipa8R8sCFG/Wizn2","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":95789},"main":"index.js","gitHead":"d261db08da355c3d672c50244b8dc1c9cf0a2c96","scripts":{"test":"npx eslint ."},"_npmUser":{"name":"boutell","email":"tom@apostrophecms.com"},"repository":{"url":"git+https://github.com/apostrophecms/ai-helper.git","type":"git"},"_npmVersion":"9.5.0","description":"AI helpers for content creation","directories":{},"_nodeVersion":"18.15.0","dependencies":{"cuid":"^3.0.0","sharp":"^0.30.7","marked":"^4.3.0","form-data":"^4.0.0","node-fetch":"^2.6.9"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^7.18.0","eslint-plugin-vue":"^7.4.1","eslint-config-apostrophe":"^3.4.1"},"_npmOperationalInternal":{"tmp":"tmp/ai-helper_1.0.0-beta.4_1694706522546_0.6773411980122803","host":"s3://npm-registry-packages"}},"1.0.0-beta.5":{"name":"@apostrophecms/ai-helper","version":"1.0.0-beta.5","keywords":["ApostropheCMS","apostrophe"],"author":{"name":"Apostrophe Technologies, Inc."},"license":"MIT","_id":"@apostrophecms/ai-helper@1.0.0-beta.5","maintainers":[{"name":"triskuit","email":"tristan.krug@protonmail.com"},{"name":"bodonkey","email":"robert@robertmeans.net"},{"name":"etlaurent","email":"etldev@tuta.io"},{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"stuartromanek","email":"stuart@punkave.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"alexbea","email":"abea@mailbox.org"},{"name":"gregvanbrug","email":"greg.vanbrug@gmail.com"},{"name":"valjed","email":"vjeudy@protonmail.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"}],"homepage":"https://github.com/apostrophecms/ai-helper#readme","bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"dist":{"shasum":"788b6ac94d2de25e2ab0f58b9044cbbe90aad707","tarball":"https://registry.npmjs.org/@apostrophecms/ai-helper/-/ai-helper-1.0.0-beta.5.tgz","fileCount":13,"integrity":"sha512-4q5koM9OQOV4DcaazQu+LSv/uyL6W+3rySACuHdzl3oV8WJI9ZM1yz5F0wEsjDLLwiCWD2bhUHZ6m/Io7m/ISg==","signatures":[{"sig":"MEYCIQDokTueFNFGXoiRs2LxG3xHWN0RBMsULnDP19Z+C4tydwIhAJqjV/zeoZwneJu+hDkdmqnf1GsNJ53hccfTwOFe+yCZ","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":96311},"main":"index.js","gitHead":"67a8562f591b28ed5e81ecc064e739c2467e7d55","scripts":{"test":"npx eslint ."},"_npmUser":{"name":"boutell","email":"tom@apostrophecms.com"},"repository":{"url":"git+https://github.com/apostrophecms/ai-helper.git","type":"git"},"_npmVersion":"9.5.0","description":"AI helpers for content creation","directories":{},"_nodeVersion":"18.15.0","dependencies":{"cuid":"^3.0.0","sharp":"^0.30.7","marked":"^4.3.0","form-data":"^4.0.0","node-fetch":"^2.6.9"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^7.18.0","eslint-plugin-vue":"^7.4.1","eslint-config-apostrophe":"^3.4.1"},"_npmOperationalInternal":{"tmp":"tmp/ai-helper_1.0.0-beta.5_1695222296505_0.6706595925302643","host":"s3://npm-registry-packages"}},"1.0.0-beta.6":{"name":"@apostrophecms/ai-helper","version":"1.0.0-beta.6","keywords":["ApostropheCMS","apostrophe"],"author":{"name":"Apostrophe Technologies, Inc."},"license":"MIT","_id":"@apostrophecms/ai-helper@1.0.0-beta.6","maintainers":[{"name":"itsrogil","email":"romain.gilles1@gmail.com"},{"name":"triskuit","email":"tristan.krug@protonmail.com"},{"name":"bodonkey","email":"robert@robertmeans.net"},{"name":"etlaurent","email":"etldev@tuta.io"},{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"stuartromanek","email":"stuart@punkave.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"alexbea","email":"abea@mailbox.org"},{"name":"gregvanbrug","email":"greg.vanbrug@gmail.com"},{"name":"valjed","email":"vjeudy@protonmail.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"}],"homepage":"https://github.com/apostrophecms/ai-helper#readme","bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"dist":{"shasum":"f1f34a5cd2fc3dcdd3c6b568dbebaa98856c1d52","tarball":"https://registry.npmjs.org/@apostrophecms/ai-helper/-/ai-helper-1.0.0-beta.6.tgz","fileCount":13,"integrity":"sha512-N638VFF99ceFgAjDiG6Lbyx1t7ffu7teKVPmwKCnQCQOMHKs6SMTv8pBjPBTk4nRN1VQqfXBihg5dKSOKIqQIA==","signatures":[{"sig":"MEUCIQCsNNOlSCN5Glg/9NxLMhhXWihnDR05BYQGG3J0ZtQJtgIgEvB8RnFXLfSOysBHr8C4Bcl8hOc3zH/VleriI3hFmoQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":96470},"main":"index.js","gitHead":"c2c813b26f048517b0bfd8f5d8a99d1c4a1d666f","scripts":{"test":"npx eslint ."},"_npmUser":{"name":"bodonkey","email":"robert@robertmeans.net"},"repository":{"url":"git+https://github.com/apostrophecms/ai-helper.git","type":"git"},"_npmVersion":"9.8.1","description":"AI helpers for content creation","directories":{},"_nodeVersion":"18.18.0","dependencies":{"cuid":"^3.0.0","sharp":"^0.30.7","marked":"^4.3.0","form-data":"^4.0.0","node-fetch":"^2.6.9"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^7.18.0","eslint-plugin-vue":"^7.4.1","eslint-config-apostrophe":"^3.4.1"},"_npmOperationalInternal":{"tmp":"tmp/ai-helper_1.0.0-beta.6_1708528379963_0.07524349799627927","host":"s3://npm-registry-packages"}},"1.0.0-beta.7":{"name":"@apostrophecms/ai-helper","version":"1.0.0-beta.7","keywords":["ApostropheCMS","apostrophe"],"author":{"name":"Apostrophe Technologies, Inc."},"license":"MIT","_id":"@apostrophecms/ai-helper@1.0.0-beta.7","maintainers":[{"name":"haroun","email":"haroun.npm@icloud.com"},{"name":"bodonkey","email":"robert@robertmeans.net"},{"name":"etlaurent","email":"etldev@tuta.io"},{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"stuartromanek","email":"stuart@punkave.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"valjed","email":"vjeudy@protonmail.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"}],"homepage":"https://github.com/apostrophecms/ai-helper#readme","bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"dist":{"shasum":"685e40dca4a3db37570973c19d6504514113c2b7","tarball":"https://registry.npmjs.org/@apostrophecms/ai-helper/-/ai-helper-1.0.0-beta.7.tgz","fileCount":13,"integrity":"sha512-BX9bl6dnyWkzDMFdenWfPbwD1OuqtKVp5OR9ZlPvcMKQU5roPJjwX7esugPaIpBeJ05t+GJzsU4s1YanP475QA==","signatures":[{"sig":"MEUCIQDop0pbLI4ZeyFpUlT1RvB1tkAdrWOPDxOoiHY58TmoAAIga33KQh3RjOcSqYyZwu0cZAhwvTc6JervUcPJobeEJFY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":96660},"main":"index.js","gitHead":"1baa53d086ab878859db72ab5e10d24568550c47","scripts":{"test":"npx eslint ."},"_npmUser":{"name":"boutell","email":"tom@apostrophecms.com"},"repository":{"url":"git+https://github.com/apostrophecms/ai-helper.git","type":"git"},"_npmVersion":"10.5.0","description":"AI helpers for content creation","directories":{},"_nodeVersion":"18.20.0","dependencies":{"cuid":"^3.0.0","sharp":"^0.30.7","marked":"^4.3.0","form-data":"^4.0.0","node-fetch":"^2.6.9"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^7.18.0","eslint-plugin-vue":"^7.4.1","eslint-config-apostrophe":"^3.4.1"},"_npmOperationalInternal":{"tmp":"tmp/ai-helper_1.0.0-beta.7_1720637440891_0.16828178801164184","host":"s3://npm-registry-packages"}},"1.0.0-beta.8":{"name":"@apostrophecms/ai-helper","version":"1.0.0-beta.8","keywords":["ApostropheCMS","apostrophe"],"author":{"name":"Apostrophe Technologies, Inc."},"license":"MIT","_id":"@apostrophecms/ai-helper@1.0.0-beta.8","maintainers":[{"name":"haroun","email":"haroun.npm@icloud.com"},{"name":"bodonkey","email":"robert@robertmeans.net"},{"name":"etlaurent","email":"etldev@tuta.io"},{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"stuartromanek","email":"stuart@punkave.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"valjed","email":"vjeudy@protonmail.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"}],"homepage":"https://github.com/apostrophecms/ai-helper#readme","bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"dist":{"shasum":"b701f3f2de638c7e713a405392082484fd9c3df3","tarball":"https://registry.npmjs.org/@apostrophecms/ai-helper/-/ai-helper-1.0.0-beta.8.tgz","fileCount":13,"integrity":"sha512-KOfZmtOvtatDDR4l1hfuo2zIlGqb4Dlg8ApT5mqCSyyFSjcSFtdveeiaZL8yo50Xp7clA+l3e2zYfVUD1stzeQ==","signatures":[{"sig":"MEUCIQDLcXAg2Tz26cxtfnyeJqjwjdCmicWHeOFpTqN0/r6BBAIgRb7lZ+LYLZyxeTfO6avxfjBEUCUPqcfBJHuFe95ng6I=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":98211},"main":"index.js","gitHead":"bab29bc55abff3f560d6df1d03a261b69f158184","scripts":{"test":"npx eslint ."},"_npmUser":{"name":"boutell","email":"tom@apostrophecms.com"},"repository":{"url":"git+https://github.com/apostrophecms/ai-helper.git","type":"git"},"_npmVersion":"10.5.2","description":"AI helpers for content creation","directories":{},"_nodeVersion":"18.18.0","dependencies":{"cuid":"^3.0.0","sharp":"^0.30.7","marked":"^4.3.0","form-data":"^4.0.0","node-fetch":"^2.6.9"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^7.18.0","eslint-plugin-vue":"^7.4.1","eslint-config-apostrophe":"^3.4.1"},"_npmOperationalInternal":{"tmp":"tmp/ai-helper_1.0.0-beta.8_1723233046434_0.25652617546140144","host":"s3://npm-registry-packages"}},"1.0.0-beta.9":{"name":"@apostrophecms/ai-helper","version":"1.0.0-beta.9","keywords":["ApostropheCMS","apostrophe"],"author":{"name":"Apostrophe Technologies, Inc."},"license":"MIT","_id":"@apostrophecms/ai-helper@1.0.0-beta.9","maintainers":[{"name":"haroun","email":"haroun.npm@icloud.com"},{"name":"bodonkey","email":"robert@robertmeans.net"},{"name":"etlaurent","email":"etldev@tuta.io"},{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"stuartromanek","email":"stuart@punkave.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"valjed","email":"vjeudy@protonmail.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"}],"homepage":"https://github.com/apostrophecms/ai-helper#readme","bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"dist":{"shasum":"ce5e68aa27a3a3a7296b1818b2f4e17c77d8220e","tarball":"https://registry.npmjs.org/@apostrophecms/ai-helper/-/ai-helper-1.0.0-beta.9.tgz","fileCount":19,"integrity":"sha512-i9m0PyRxLjXugOIUlZT1jCqDfzMa4gh2dG+G7srwM1VhSxj+wVpX2FH+ABsv7ZLZBt4EmxAwq8DGU+UngfYVPg==","signatures":[{"sig":"MEYCIQDnjIGNIoreJhxhtGrYNvvelQV1vHb7sCDMfUEA1wB4tgIhALScYOQQuJbKgV+j/HfGy/7wk126dVl9ojKoVVlFwHAW","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":102744},"main":"index.js","gitHead":"5bcaa32baa7f0c3a135e37918795acd03256c1e6","scripts":{"test":"npx eslint ."},"_npmUser":{"name":"boutell","email":"tom@apostrophecms.com"},"repository":{"url":"git+https://github.com/apostrophecms/ai-helper.git","type":"git"},"_npmVersion":"10.8.2","description":"AI helpers for content creation","directories":{},"_nodeVersion":"22.7.0","dependencies":{"cuid":"^3.0.0","sharp":"^0.30.7","marked":"^4.3.0","form-data":"^4.0.0","node-fetch":"^2.6.9"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^7.18.0","eslint-plugin-vue":"^7.4.1","eslint-config-apostrophe":"^3.4.1"},"_npmOperationalInternal":{"tmp":"tmp/ai-helper_1.0.0-beta.9_1725570202063_0.10454590924218365","host":"s3://npm-registry-packages"}},"1.0.0-beta.10":{"name":"@apostrophecms/ai-helper","version":"1.0.0-beta.10","keywords":["ApostropheCMS","apostrophe"],"author":{"name":"Apostrophe Technologies, Inc."},"license":"MIT","_id":"@apostrophecms/ai-helper@1.0.0-beta.10","maintainers":[{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"etlaurent","email":"npm_etlaurent.cartoon369@passmail.net"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"},{"name":"bodonkey","email":"robert.means1969+apostrophecms@gmail.com"},{"name":"haroun","email":"haroun.npm@icloud.com"},{"name":"valjed","email":"vjeudy@protonmail.com"}],"homepage":"https://github.com/apostrophecms/ai-helper#readme","bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"dist":{"shasum":"4fb2f42ec598b742719cb95e1a7b9efc1a19aa0b","tarball":"https://registry.npmjs.org/@apostrophecms/ai-helper/-/ai-helper-1.0.0-beta.10.tgz","fileCount":19,"integrity":"sha512-vF8E6Heq3RObDL4ShDqBYyytCOwGjdf2Pys308snNoAJnpJoNFxavldLP486qO0ddmcNkP0xLsZ5EwpRGm2Odw==","signatures":[{"sig":"MEUCIQDJgPb+Wjmd2JRZbPLhwW8VNFX44jTGTvGK0Y8u6mUo9AIgc8SocQPKFlN6Bxi50JVne/yFxu9OMpRVOeLHP/03SBI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105229},"main":"index.js","gitHead":"37ff4d5756a8cd3dccb0ee36377bebdf5435ac01","scripts":{"lint":"eslint --ext .js,.vue .","test":"npm run lint"},"_npmUser":{"name":"boutell","email":"tom@apostrophecms.com"},"repository":{"url":"git+https://github.com/apostrophecms/ai-helper.git","type":"git"},"_npmVersion":"10.9.2","description":"AI helpers for content creation","directories":{},"_nodeVersion":"20.19.3","dependencies":{"sharp":"^0.30.7","marked":"^4.3.0","form-data":"^4.0.0","node-fetch":"^2.6.9","@paralleldrive/cuid2":"^3.0.4"},"_hasShrinkwrap":false,"devDependencies":{"eslint-config-apostrophe":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ai-helper_1.0.0-beta.10_1763588562349_0.6377347377447782","host":"s3://npm-registry-packages-npm-production"}},"1.0.0-beta.11":{"name":"@apostrophecms/ai-helper","version":"1.0.0-beta.11","keywords":["ApostropheCMS","apostrophe"],"author":{"name":"Apostrophe Technologies, Inc."},"license":"MIT","_id":"@apostrophecms/ai-helper@1.0.0-beta.11","maintainers":[{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"},{"name":"bodonkey","email":"robert.means1969+apostrophecms@gmail.com"}],"homepage":"https://github.com/apostrophecms/apostrophe/tree/main/packages/ai-helper#readme","bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"dist":{"shasum":"ac71cbf055476ba00e619f2e1e19da5591b06d1b","tarball":"https://registry.npmjs.org/@apostrophecms/ai-helper/-/ai-helper-1.0.0-beta.11.tgz","fileCount":24,"integrity":"sha512-Z/RD9A5TljjNDVCanCddyAx5MvDFB+OVU8xkLLYLeLmOmC0OV/tBSM07x/MJlXtt+fFytb27vLEZnLB5hghflg==","signatures":[{"sig":"MEQCIARDUVjUB0rfKL8P7UPSR2bmOnMvOSUjtha404A1FuqzAiBBxdZxzMjwpP+t8/k9n6yoHt55gI+cLtUmUGLzwuL9RA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":174949},"main":"index.js","_from":"file:apostrophecms-ai-helper-1.0.0-beta.11.tgz","scripts":{"lint":"eslint --ext .js,.vue .","test":"npm run lint"},"_npmUser":{"name":"bodonkey","email":"robert.means1969+apostrophecms@gmail.com"},"_resolved":"/private/var/folders/1r/s8d0zxkj0077spyr8jzvx2200000gn/T/b3c3ecae58ebf2a9096143e356512f70/apostrophecms-ai-helper-1.0.0-beta.11.tgz","_integrity":"sha512-Z/RD9A5TljjNDVCanCddyAx5MvDFB+OVU8xkLLYLeLmOmC0OV/tBSM07x/MJlXtt+fFytb27vLEZnLB5hghflg==","repository":{"url":"git+https://github.com/apostrophecms/apostrophe.git","type":"git","directory":"packages/ai-helper"},"_npmVersion":"11.5.1","description":"AI helpers for content creation","directories":{},"_nodeVersion":"22.14.0","dependencies":{"sharp":"^0.32.6","marked":"^4.3.0","node-fetch":"^2.6.9","@paralleldrive/cuid2":"^3.0.4"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.39.1","eslint-config-apostrophe":"^6.0.2"},"_npmOperationalInternal":{"tmp":"tmp/ai-helper_1.0.0-beta.11_1771446980104_0.6932708075946605","host":"s3://npm-registry-packages-npm-production"}},"1.0.0-beta.12":{"name":"@apostrophecms/ai-helper","version":"1.0.0-beta.12","keywords":["ApostropheCMS","apostrophe"],"author":{"name":"Apostrophe Technologies, Inc."},"license":"MIT","_id":"@apostrophecms/ai-helper@1.0.0-beta.12","maintainers":[{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"},{"name":"bodonkey","email":"robert.means1969+apostrophecms@gmail.com"}],"homepage":"https://github.com/apostrophecms/apostrophe/tree/main/packages/ai-helper#readme","bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"dist":{"shasum":"662a61621b767230059d1e305ef20d7155659295","tarball":"https://registry.npmjs.org/@apostrophecms/ai-helper/-/ai-helper-1.0.0-beta.12.tgz","fileCount":23,"integrity":"sha512-0A+81Mb5pqE7rrUEuMH/RB6tWcIRdvE2FDv69gh4p+RqMKHJkAGzmt2ktarijAa36h6VVNdhUGJ+DqUxvBJcpg==","signatures":[{"sig":"MEMCIBDkdPMnkIvkahtuJk9cAEkkRDf23zhFaO1+8qzzrilUAh9X6r1TGdjrQhL5EV7LU8dTly+f/pthPqoP40elGJ4A","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":175042},"main":"index.js","_from":"file:apostrophecms-ai-helper-1.0.0-beta.12.tgz","scripts":{"lint":"eslint --ext .js,.vue .","test":"npm run lint"},"_npmUser":{"name":"boutell","email":"tom@apostrophecms.com"},"_resolved":"/private/var/folders/lg/7k83x5ys71d90nvc40mj1tbr0000gn/T/e8433a0f7983cdbfcb290d8f0031e7b9/apostrophecms-ai-helper-1.0.0-beta.12.tgz","_integrity":"sha512-0A+81Mb5pqE7rrUEuMH/RB6tWcIRdvE2FDv69gh4p+RqMKHJkAGzmt2ktarijAa36h6VVNdhUGJ+DqUxvBJcpg==","repository":{"url":"git+https://github.com/apostrophecms/apostrophe.git","type":"git","directory":"packages/ai-helper"},"_npmVersion":"11.16.0","description":"AI helpers for content creation","directories":{},"_nodeVersion":"24.18.0","dependencies":{"sharp":"^0.35.2","marked":"^4.3.0","node-fetch":"^2.6.9","@paralleldrive/cuid2":"^3.0.4"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.39.1","eslint-config-apostrophe":"^6.0.2"},"_npmOperationalInternal":{"tmp":"tmp/ai-helper_1.0.0-beta.12_1786635867912_0.31779697793383166","host":"s3://npm-registry-packages-npm-production"}},"1.0.0-beta.13":{"_id":"@apostrophecms/ai-helper@1.0.0-beta.13","bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"dist":{"shasum":"ca128e6e351742935d1e419cc1f899039a3bc022","tarball":"https://registry.npmjs.org/@apostrophecms/ai-helper/-/ai-helper-1.0.0-beta.13.tgz","fileCount":25,"integrity":"sha512-JJop01YQF2OW1bx/o094+X3CkKXpAeWcUjG0lae1qbPnlDY3z8I/cHySHB4AF/6l7VA7eO2LNph1zCtjjKytlQ==","signatures":[{"sig":"MEUCIAj9/jN64OSJ7HaQYSJoZitmega5ssSLJFX3wvi6qKXWAiEA+gB/s1LZ+ls1+ZXZ54ngTXxXfTJh3cbp7oQmspoCOTI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBBu8hJXyZmfIoeauUGFc7BW4sbV6Jg2Nbi6p85Qir7PAiEA8yQgtdUGwdrZi0T0uZ2omfuR3LIC6Efzp2OCowJaAVs="}],"unpackedSize":185708},"main":"index.js","name":"@apostrophecms/ai-helper","author":{"name":"Apostrophe Technologies, Inc."},"gitHead":"9500b8b0e1d630d5e07fbb5fd2c25ed0943845ce","license":"MIT","scripts":{"lint":"eslint --ext .js,.vue .","test":"npm run lint && mocha"},"version":"1.0.0-beta.13","_npmUser":{"name":"boutell","email":"tom@apostrophecms.com"},"homepage":"https://github.com/apostrophecms/apostrophe/tree/main/packages/ai-helper#readme","keywords":["ApostropheCMS","apostrophe"],"repository":{"url":"git+https://github.com/apostrophecms/apostrophe.git","type":"git","directory":"packages/ai-helper"},"_npmVersion":"11.19.0","description":"AI helpers for content creation","directories":{},"maintainers":[{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"},{"name":"bodonkey","email":"robert.means1969+apostrophecms@gmail.com"}],"_nodeVersion":"24.20.0","dependencies":{"sharp":"^0.35.4","marked":"^4.3.0","node-fetch":"^2.7.0","@paralleldrive/cuid2":"^3.3.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^11.8.0","eslint":"^9.39.5","apostrophe":"^4.33.0","eslint-config-apostrophe":"^6.1.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ai-helper_1.0.0-beta.13_1790796408739_0.3924590117613984"}}},"time":{"created":"2023-04-27T18:12:32.186Z","modified":"2026-09-30T19:26:49.037Z","1.0.0-beta":"2023-04-27T18:12:32.403Z","1.0.0-beta.2":"2023-05-26T15:50:02.118Z","1.0.0-beta.3":"2023-08-03T11:54:51.835Z","1.0.0-beta.4":"2023-09-14T15:48:42.864Z","1.0.0-beta.5":"2023-09-20T15:04:56.672Z","1.0.0-beta.6":"2024-02-21T15:13:00.152Z","1.0.0-beta.7":"2024-07-10T18:50:41.058Z","1.0.0-beta.8":"2024-08-09T19:50:46.589Z","1.0.0-beta.9":"2024-09-05T21:03:22.297Z","1.0.0-beta.10":"2025-11-19T21:42:42.534Z","1.0.0-beta.11":"2026-02-18T20:36:20.265Z","1.0.0-beta.12":"2026-08-13T15:44:28.066Z","1.0.0-beta.13":"2026-09-30T19:26:48.858Z"},"bugs":{"url":"https://github.com/apostrophecms/ai-helper/issues"},"author":{"name":"Apostrophe Technologies, Inc."},"license":"MIT","homepage":"https://github.com/apostrophecms/apostrophe/tree/main/packages/ai-helper#readme","keywords":["ApostropheCMS","apostrophe"],"repository":{"url":"git+https://github.com/apostrophecms/apostrophe.git","type":"git","directory":"packages/ai-helper"},"description":"AI helpers for content creation","maintainers":[{"name":"alexgilbert","email":"alex@apostrophecms.com"},{"name":"boutell","email":"tom@apostrophecms.com"},{"name":"romanek","email":"stuart+npm@apostrophecms.com"},{"name":"bodonkey","email":"robert.means1969+apostrophecms@gmail.com"}],"readme":"<div align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/apostrophecms/apostrophe/main/logo.svg\" alt=\"ApostropheCMS logo\" width=\"80\" height=\"80\" />\n\n  <h1>AI Helper</h1>\n\n  <p>\n    <a aria-label=\"Apostrophe logo\" href=\"https://v3.docs.apostrophecms.org\">\n      <img src=\"https://img.shields.io/badge/MADE%20FOR%20ApostropheCMS-000000.svg?style=for-the-badge&logo=Apostrophe&labelColor=6516dd\">\n    </a>\n    <a aria-label=\"Join the community on Discord\" href=\"http://chat.apostrophecms.org\">\n      <img alt=\"\" src=\"https://img.shields.io/discord/517772094482677790?color=5865f2&label=Join%20the%20Discord&logo=discord&logoColor=fff&labelColor=000&style=for-the-badge&logoWidth=20\" />\n    </a>\n    <a aria-label=\"License\" href=\"https://github.com/apostrophecms/ai-helper/blob/main/LICENSE.md\">\n      <img alt=\"\" src=\"https://img.shields.io/static/v1?style=for-the-badge&labelColor=000000&label=License&message=MIT&color=3DA639\" />\n    </a>\n  </p>\n</div>\n\n**Bring AI-powered content generation directly into your ApostropheCMS editing workflow.** Generate compelling text and stunning images from simple prompts, all without leaving the CMS. Choose your preferred AI provider (OpenAI, Anthropic Claude, or Google Gemini) or connect to enterprise AI services.\n\n## ⚠️ Beta / Experimental Module <!-- omit in toc -->\n\n**This module is experimental and will remain in beta status.** It provides early access to AI-powered content generation features in ApostropheCMS, but you should expect:\n\n- **Functional but evolving**: Core features work well and are production-ready, but the UI/UX may not have the polish of finished ApostropheCMS modules\n- **Active development**: Features and APIs may change as we refine the AI integration experience\n- **Future migration**: Much of this functionality will eventually move into ApostropheCMS core as part of a comprehensive AI coordination system\n\n**Who should use this module:**\n- Developers comfortable with experimental features who want early access to AI capabilities\n- Teams willing to provide feedback to help shape ApostropheCMS AI features\n- Projects that can adapt to potential UI/API changes in future updates\n\n**Stability note:** While the module is marked as beta, it is used in production environments. The \"experimental\" designation reflects ongoing UI refinement rather than fundamental instability.\n\n## Why AI Helper? <!-- omit in toc -->\n\n- **⚡ Accelerate Content Creation**: Generate high-quality text and images in seconds, not hours\n- **🎯 Stay in Your Workflow**: AI generation built directly into the rich text editor and media manager\n- **🔌 Your Choice of AI Provider**: Use OpenAI, Anthropic Claude, or Google Gemini - switch anytime\n\n### **Table of Contents**\n- [Installation](#installation)\n- [Configuration](#configuration)\n  - [Enable AI Text Generation](#enable-ai-text-generation)\n  - [(Optional) Customize System Prompt](#optional-customize-system-prompt)\n  - [(Optional) Configure Security Headers](#optional-configure-security-headers)\n  - [Mock Mode for Testing](#mock-mode-for-testing)\n- [Usage](#usage)\n  - [Generating Images](#generating-images)\n  - [Generating Text](#generating-text)\n- [Provider Configuration Options](#provider-configuration-options)\n  - [OpenAI Provider](#openai-provider)\n  - [Anthropic Provider](#anthropic-provider)\n  - [Gemini Provider](#gemini-provider)\n- [Mix and Match Providers](#mix-and-match-providers)\n- [Bundled Providers](#bundled-providers)\n- [Provider Metadata](#provider-metadata)\n- [Custom AI Providers](#custom-ai-providers)\n  - [Provider Architecture](#provider-architecture)\n  - [Provider Registration](#provider-registration)\n  - [Custom Provider Contract](#custom-provider-contract)\n  - [Error Handling](#error-handling)\n  - [Metadata](#metadata)\n  - [Implementation Guidance](#implementation-guidance)\n- [API Endpoints](#api-endpoints)\n  - [List Registered Providers](#list-registered-providers)\n- [💎 Ready for Enterprise AI Features?](#-ready-for-enterprise-ai-features)\n  - [🚀 Pro AI Features](#-pro-ai-features)\n- [Need Help?](#need-help)\n- [License](#license)\n\n\n## Installation\nTo install the module, use the command line to run this command in an Apostrophe project's root directory:\n\n```bash\nnpm install @apostrophecms/ai-helper\n```\n\nAll providers (OpenAI, Anthropic, Gemini) are bundled with the main package - no separate installation needed.\n\n## Configuration\n\nConfigure the AI helper module in your `app.js` file:\n\n```javascript\nimport apostrophe from 'apostrophe';\n\napostrophe({\n  root: import.meta,\n  shortName: 'my-project',\n  modules: {\n    '@apostrophecms/ai-helper': {\n      options: {\n        // Choose which providers to use\n        textProvider: 'openai',  // 'openai', 'anthropic', or 'gemini'\n        imageProvider: 'openai',  // 'openai' or 'gemini'\n\n        // Configure your text provider\n        textProviderOptions: {\n          apiKey: process.env.APOS_OPENAI_KEY,  // or export APOS_OPENAI_KEY\n          textModel: 'gpt-5.1',\n          textMaxTokens: 1000\n        },\n\n        // Configure your image provider\n        imageProviderOptions: {\n          apiKey: process.env.APOS_OPENAI_KEY,  // or export APOS_OPENAI_KEY\n          imageModel: 'gpt-image-1-mini',\n          imageSize: '1024x1024',\n          imageQuality: 'medium',\n          imageCount: 1\n        }\n      }\n    }\n  }\n});\n```\n> **Note:** Providers are selected at application startup via `app.js` configuration.\n> Switching providers at runtime via an admin UI is not currently supported.\n\n\n**API Keys:**\nEach provider requires its own API key. You can set them via:\n- Environment variables: `APOS_OPENAI_KEY`, `APOS_ANTHROPIC_KEY`, `APOS_GEMINI_KEY`\n- Configuration options: `textProviderOptions.apiKey` or `imageProviderOptions.apiKey`\n\n> Note:\n> You only need to provide keys for the services you will be using.\n\n### Enable AI Text Generation\n\nAdd the AI option to your rich text widget toolbar in any area configuration:\n\n```javascript\n// modules/article/index.js\nexport default {\n  extend: '@apostrophecms/piece-type',\n  fields: {\n    add: {\n      main: {\n        type: 'area',\n        options: {\n          widgets: {\n            '@apostrophecms/rich-text': {\n              toolbar: [ 'styles', 'bold', 'italic', 'bulletList', 'orderedList' ],\n              insert: [ 'ai' ],  // Enable AI text generation\n              styles: [\n                { name: 'Heading', tag: 'h2' },\n                { name: 'Subheading', tag: 'h3' },\n                { name: 'Paragraph', tag: 'p' }\n              ]\n            }\n          }\n        }\n      }\n    }\n  }\n};\n```\n\n### (Optional) Customize System Prompt\n\n>**Default System Prompt (with guardrails):**\n>```\n>You are a helpful text-generation assistant for CMS content. You generate text in Markdown format based on the given prompt. Do not include any meta-commentary, explanations, or offers to create additional versions. Output the content directly without preamble or postamble.\n>```\n\nCustomize how the AI generates text by modifying the system prompt. This can be configured **globally** (affects all rich text widgets) or **per-area** (specific areas only). Note that any prompt passed to a widget in an area will override the prompt set globally.\n\n**Precedence order:**\n1. Per-area prompt\n2. Global prompt\n3. Default guardrails\n\n**Global Configuration (in app.js):**\n```javascript\nimport apostrophe from 'apostrophe';\n\napostrophe({\n  root: import.meta,\n  modules: {\n    '@apostrophecms/rich-text-widget': {\n      options: {\n        customSystemPrompt: 'Write in a professional, technical tone suitable for enterprise documentation.',\n        appendSystemPrompt: true  // Append to default guardrails instead of replacing\n      }\n    }\n  }\n});\n```\n\n**Per-Area Configuration:**\n```javascript\n// modules/article/index.js\nexport default {\n  extend: '@apostrophecms/piece-type',\n  fields: {\n    add: {\n      main: {\n        type: 'area',\n        options: {\n          widgets: {\n            '@apostrophecms/rich-text': {\n              toolbar: [ 'styles', 'bold', 'italic', 'bulletList', 'orderedList' ],\n              insert: [ 'ai' ],\n              // Customize AI behavior for this specific area\n              customSystemPrompt: 'Write in a casual, conversational tone for blog content.',\n              appendSystemPrompt: true\n            }\n          }\n        }\n      }\n    }\n  }\n};\n```\n\n**Options:**\n- `customSystemPrompt` - Your custom instructions for the AI\n- `appendSystemPrompt` - When `true`, appends your prompt to the default guardrails. When `false`, replaces them entirely.\n\n> **Tip:** Set `appendSystemPrompt: true` to keep the default guardrails (Markdown formatting, no meta-commentary) while adding your brand voice or style requirements. Per-area configuration overrides global settings.\n\n### (Optional) Configure Security Headers\n\nIf using the `@apostrophecms/security-headers` module, add AI image sources:\n\n```javascript\n// modules/@apostrophecms/security-headers/index.js\nexport default {\n  options: {\n    policies: {\n      ai: {\n        'img-src': '*.blob.core.windows.net'  // OpenAI image URLs\n      }\n    }\n  }\n};\n```\n**Note:** This is an example only. The exact `img-src` value depends on the AI provider and region you are using.\n\n### Mock Mode for Testing\n\nFor offline development and testing without API calls or costs:\n\n```bash\nexport APOS_AI_HELPER_MOCK=true\n```\n\nWhen enabled:\n- Text generation returns pre-defined sample content\n- Image generation returns placeholder images\n- No API keys required\n- No external network calls made\n- Instant responses for rapid iteration\n\n> **Note:** Mock mode metadata may not match actual provider responses exactly.\n\n## Usage\n\n### Generating Images\n\n1. Add an image widget to your page\n2. Click \"Browse\" to open the media manager\n3. Click the 🤖 robot button in the upper right\n4. Enter a description and click \"Generate\"\n5. Review the generated image(s) (1 is the default)\n6. Click \"Select\" to import to media library, \"Variants\" for variations, or \"Delete\"\n\n**Note:** Generated images expire after 1 hour if not imported to your media library.\n\n### Generating Text\n\n> **Note:** Generated content may include headings, bullet lists, bold, italic, and other formatting. Make sure your rich text widget toolbar includes the formatting options you want to preserve (e.g., `toolbar: [ 'styles', 'bold', 'italic', 'bulletList', 'orderedList' ]`). Unsupported formatting will be stripped when inserted.\n\n1. In a rich text widget, press `/` at the start of a line\n2. Choose \"Generate Text\"\n3. Enter your prompt (be specific!)\n4. Click \"Generate\"\n\n**Prompt Tips:**\n- Specify a word count: \"Write 200 words about sustainable packaging\"\n- Request specific formats: \"Write a bulleted list of 5 benefits of...\"\n- Ask for structure: \"Write an article with 3 sections about cloud migration\"\n- Include tone: \"Write a friendly, conversational guide to...\"\n\n## Provider Configuration Options\n\nEach provider supports specific configuration parameters through `textProviderOptions` and `imageProviderOptions`:\n\n### OpenAI Provider\n```javascript\n'@apostrophecms/ai-helper': {\n  options: {\n    textProvider: 'openai',\n    imageProvider: 'openai',\n\n    textProviderOptions: {\n      apiKey: process.env.APOS_OPENAI_KEY,\n      textModel: 'gpt-5.1', //  Text model to use\n      textMaxTokens: 1000, //  Max tokens for text generation\n      textRetries: 3 //  Times to reattempt generation on timeout\n    },\n\n    imageProviderOptions: {\n      apiKey: process.env.APOS_OPENAI_KEY,\n      imageModel: 'gpt-image-1-mini',  // Image model to use\n      imageSize: '1024x1024',  // Image dimensions\n      imageQuality: 'medium',  // 'low', 'medium', or 'high'\n      imageCount: 1  //  Number of images to generate\n    }\n  }\n}\n```\n\n### Anthropic Provider\n```javascript\n'@apostrophecms/ai-helper': {\n  options: {\n    textProvider: 'anthropic',\n\n    textProviderOptions: {\n      apiKey: process.env.APOS_ANTHROPIC_KEY,\n      textModel: 'claude-sonnet-4-20250514',  // Claude model to use\n      textMaxTokens: 1000,  // Max tokens for text generation\n      textRetries: 3  // Times to reattempt generation on timeout\n    }\n  }\n}\n```\n\n**Note:** Anthropic does not support image generation. Use OpenAI or Gemini for images.\n\n### Gemini Provider\n```javascript\n'@apostrophecms/ai-helper': {\n  options: {\n    textProvider: 'gemini',\n    imageProvider: 'gemini',\n\n    textProviderOptions: {\n      apiKey: process.env.APOS_GEMINI_KEY,\n      textModel: 'gemini-2.5-flash-lite',  // Text model to use\n      textMaxTokens: 1000,  // Max tokens for text generation\n      textRetries: 3  // Times to reattempt generation on timeout\n    },\n\n    imageProviderOptions: {\n      apiKey: process.env.APOS_GEMINI_KEY,\n      imageModel: 'gemini-2.5-flash-image',   // Image model to use\n      imageAspectRatio: '1:1',                // '1:1', '16:9', or '9:16'\n      imageCount: 1                           // Number of images to generate\n    }\n  }\n}\n```\n\n**Note:** Gemini uses `imageAspectRatio` instead of `imageSize`.\n\n> The values shown are default values used for all generations. Future versions may support per-request options through the UI.\n\n## Mix and Match Providers\n\nUse different providers for text and images to optimize for cost, quality, or capability:\n\n```javascript\nimport apostrophe from 'apostrophe';\n\napostrophe({\n  root: import.meta,\n  modules: {\n    '@apostrophecms/ai-helper': {\n      options: {\n        textProvider: 'anthropic',  // Use Claude for text generation\n        imageProvider: 'gemini',  // Use Gemini for image generation\n\n        textProviderOptions: {\n          apiKey: process.env.APOS_ANTHROPIC_KEY,\n          textModel: 'claude-sonnet-4-20250514'\n        },\n\n        imageProviderOptions: {\n          apiKey: process.env.APOS_GEMINI_KEY,\n          imageModel: 'gemini-2.5-flash-image',\n          imageAspectRatio: '16:9'\n        }\n      }\n    }\n  }\n});\n```\n\n**Note:** Provider switching is currently configured in `app.js`. A future admin UI may allow switching providers without code changes.\n\n## Bundled Providers\n\nAll providers are included with `@apostrophecms/ai-helper` - no separate installation needed. They are implemented as lightweight factory functions and configured through `textProviderOptions` and `imageProviderOptions`.\n\n**OpenAI** (`textProvider: 'openai'` / `imageProvider: 'openai'`)\n- Text generation (GPT models)\n- Image generation (GPT Image models)\n- Image variations\n- Uses `imageSize` parameter (e.g., '1024x1024')\n\n**Anthropic** (`textProvider: 'anthropic'`)\n- Text generation (Claude models)\n- No image generation support\n\n**Gemini** (`textProvider: 'gemini'` / `imageProvider: 'gemini'`)\n- Text generation (Gemini models)\n- Image generation (Gemini Image models)\n- Image variations\n- Uses `imageAspectRatio` parameter (e.g., '1:1', '16:9', '9:16')\n\n## Provider Metadata\n\nAll providers return metadata with each generation, including:\n- Model used\n- Token counts and usage statistics\n- Provider-specific details (stop reasons, timestamps, etc.)\n\n**For text generation**, metadata is returned alongside the generated content in the API response. This allows you to capture usage information if needed for custom auditing or analytics at the project level.\n\n**For image generation**, metadata is stored temporarily in the `aposAiHelperImages` collection as `providerMetadata` on each generated image. This data persists for 1 hour (until cleanup) or until the image is imported to your media library.\n\nThe module does not automatically log or persist this metadata beyond what's needed for operation. If you need detailed auditing, cost tracking, or analytics, you can extend the relevant modules to capture and process this data according to your requirements.\n\n## Custom AI Providers\n\nIn addition to the bundled OpenAI, Anthropic, and Gemini providers, `@apostrophecms/ai-helper` supports **custom AI providers** for organizations that need to integrate enterprise platforms or internal AI services\n(e.g. AWS Bedrock, Azure OpenAI, self-hosted models).\n\n### Provider Architecture\n\nThe AI Helper uses a two-phase provider system:\n\n1. **Registration** - Providers register their factory function and metadata (capabilities, label)\n2. **Activation** - The core module instantiates only the providers actually configured for use\n\nThis means you can register multiple providers without the overhead of instantiating unused services.\n\n### Provider Registration\n\nCustom providers register a **factory function** along with metadata. The factory function\nwill be called by the core module during activation if the provider is configured for use.\n\nProviders can be implemented either:\n\n- As a **dedicated ApostropheCMS module**, or\n- As a **factory function** registered during another module's initialization\n\nBoth patterns must register a factory function - the AI Helper core handles instantiation.\n\n---\n\n### Custom Provider Contract\n\nCustom providers must implement a well-defined contract so the AI Helper can normalize behavior across different AI services.\n\n> **Streaming responses are not currently supported.**\n> Providers must return complete results for text and image generation.\n> Partial or incremental responses will be ignored.\n\n---\n\n#### Provider Registration API\n\nProviders register using `registerProvider(name, factoryInfo)`:\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `name` | `string` | Unique provider identifier (e.g. `\"bedrock\"`) |\n| `factoryInfo.factory` | `function` | Factory function `(apos, textOpts, imageOpts) => provider` |\n| `factoryInfo.label` | `string` | Human-readable name for admin UI |\n| `factoryInfo.capabilities` | `object` | Declares supported features |\n\nExample:\n```javascript\naiHelper.registerProvider('bedrock', {\n  factory: bedrockFactory,\n  label: 'AWS Bedrock',\n  capabilities: {\n    text: true,\n    image: false,\n    imageVariation: false\n  }\n});\n```\n\nThe factory function will be called with:\n- `apos` - ApostropheCMS instance\n- `textOpts` - Options from `textProviderOptions`\n- `imageOpts` - Options from `imageProviderOptions`\n\nIf a custom provider registers using the same name as a bundled provider, it will override the bundled implementation.\n\n---\n\n#### Required Provider Properties\n\nThe provider object **returned by the factory** must include:\n\n| Property | Type | Description |\n|--------|------|-------------|\n| `name` | `string` | Provider identifier (should match registration name) |\n| `label` | `string` | Human-readable name |\n| `capabilities` | `object` | Supported features |\n| `validate` | `function` | Configuration validation method |\n\nPlus methods for each declared capability (see below).\n\n---\n\n#### Required Methods\n\nProviders must implement methods that correspond to their declared capabilities.\n\n---\n\n##### `validate()`\n\n* Called during provider activation (after factory instantiation)\n* Must throw an error if required configuration is missing\n* Should be a no-op when `APOS_AI_HELPER_MOCK` is enabled\n\nUsed to:\n\n* Verify API keys or credentials\n* Validate required options\n* Fail fast on misconfiguration\n\n---\n\n##### `generateText(req, prompt, options)`\n\n**Required if `capabilities.text === true`**\n\n* Generates text content from a prompt\n* Must return the full generated result\n\nExpected return shape:\n```ts\n{\n  content: string,       // Markdown or HTML\n  metadata?: object      // Usage, model, provider-specific data\n}\n```\n\n---\n\n##### `generateImage(req, prompt, options)`\n\n**Required if `capabilities.image === true`**\n\n* Generates one or more images from a prompt\n* Must return complete image data\n\nExpected return shape:\n```ts\n[\n  {\n    type: 'url' | 'base64',\n    data: string,\n    metadata?: object\n  }\n]\n```\n\n---\n\n##### `generateImageVariation(req, image, prompt, options)`\n\n**Required if `capabilities.imageVariation === true`**\n\n* Generates a variant of an existing image based on an additional prompt or default\n\nExpected return shape is the same as `generateImage`.\n\n---\n\n### Error Handling\n\n* Providers should throw standard JavaScript `Error` objects\n* The AI Helper will normalize errors into user-facing messages\n* Provider-specific error details may be included in metadata when available\n\n---\n\n### Metadata\n\nProviders may return provider-specific metadata, such as:\n\n* Model name\n* Token usage\n* Stop reasons\n* Timestamps or request IDs\n\nMetadata is:\n\n* Returned with text generation responses\n* Temporarily stored for image generation (until import or cleanup)\n\n---\n\n### Implementation Guidance\n\nDetailed implementation examples, testing guidance, and edge-case handling\nare intentionally excluded from this README.\n\nFor full implementation details, see:\n\n* **`provider-creator.md`** in this repository\n\nThis file can also be added to AI-assisted development tools\n(e.g. Claude Projects, Cursor workspaces) to help generate\nprovider implementations safely and consistently.\n\n## API Endpoints\n\n### List Registered Providers\n\nQuery which AI providers are available for registration (whether currently active or not):\n```javascript\nconst aiHelper = apos.modules['@apostrophecms/ai-helper'];\nconst providers = aiHelper.listRegisteredProviders();\n\nconsole.log(providers);\n// [\n//   {\n//     name: 'openai',\n//     label: 'OpenAI',\n//     capabilities: { text: true, image: true, imageVariation: true }\n//   },\n//   {\n//     name: 'anthropic',\n//     label: 'Anthropic (Claude)',\n//     capabilities: { text: true, image: false, imageVariation: false }\n//   },\n//   {\n//     name: 'gemini',\n//     label: 'Google Gemini',\n//     capabilities: { text: true, image: true, imageVariation: true }\n//   }\n// ]\n```\n\nThis is useful for debugging provider registration, building admin UIs, or when creating custom providers that need to check what's already available.\n\n## 💎 Ready for Enterprise AI Features?\n\n**Love AI Helper but need advanced capabilities?** Upgrade to **ApostropheCMS Pro** to unlock AI-powered features that transform your content workflow:\n\n### 🚀 Pro AI Features\n- **🌍 AI-Powered Translation** - Automatically translate content into 100+ languages using DeepL, Google Translate, or Azure\n- **🔍 AI SEO Assistant** - Generate optimized meta descriptions, titles, and content recommendations\n\n**[Contact our team](https://apostrophecms.com/contact-us)** to learn about Pro licensing and enterprise AI capabilities.\n\n---\n\n## Need Help?\n\n- **Documentation**: [ApostropheCMS Documentation](https://apostrophecms.com/docs/)\n- **Community Support**: [Join our Discord](https://discord.com/invite/HwntQpADJr)\n- **Professional Support**: [Contact us](https://apostrophecms.com/contact-us) for dedicated support packages\n- **Issues & Feedback**: [GitHub Issues](https://github.com/apostrophecms/apostrophe/issues) - Your feedback helps shape future AI features!\n\n## License\n\nMIT\n\n---\n\n<div>\n  <p>Made with ❤️ by the <a href=\"https://apostrophecms.com\">ApostropheCMS</a> team. <strong>Found this useful? <a href=\"https://github.com/apostrophecms/ai-helper\">Give us a star on GitHub!</a> ⭐</strong>\n  </p>\n</div>","readmeFilename":"README.md"}