@automattic/jetpack-ai-client 0.25.6 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/build/components/ai-icon/index.d.ts +10 -0
  3. package/build/components/ai-icon/index.js +16 -0
  4. package/build/components/ai-image/components/ai-image-modal.d.ts +57 -0
  5. package/build/components/ai-image/components/ai-image-modal.js +92 -0
  6. package/build/components/ai-image/components/carrousel.d.ts +28 -0
  7. package/build/components/ai-image/components/carrousel.js +69 -0
  8. package/build/components/ai-image/components/usage-counter.d.ts +16 -0
  9. package/build/components/ai-image/components/usage-counter.js +29 -0
  10. package/build/components/ai-image/featured-image.d.ts +17 -0
  11. package/build/components/ai-image/featured-image.js +278 -0
  12. package/build/components/ai-image/general-purpose-image.d.ts +23 -0
  13. package/build/components/ai-image/general-purpose-image.js +184 -0
  14. package/build/components/ai-image/hooks/use-ai-image.d.ts +48 -0
  15. package/build/components/ai-image/hooks/use-ai-image.js +219 -0
  16. package/build/components/ai-image/hooks/use-site-type.d.ts +6 -0
  17. package/build/components/ai-image/hooks/use-site-type.js +23 -0
  18. package/build/components/ai-image/index.d.ts +4 -0
  19. package/build/components/ai-image/index.js +4 -0
  20. package/build/components/ai-image/types.d.ts +16 -0
  21. package/build/components/ai-image/types.js +6 -0
  22. package/build/{ai-client/src/components → components}/index.d.ts +4 -0
  23. package/build/{ai-client/src/components → components}/index.js +4 -0
  24. package/build/components/modal/index.d.ts +18 -0
  25. package/build/components/modal/index.js +23 -0
  26. package/build/components/quota-exceeded-message/index.d.ts +13 -0
  27. package/build/components/quota-exceeded-message/index.js +152 -0
  28. package/build/components/quota-exceeded-message/light-nudge.d.ts +11 -0
  29. package/build/components/quota-exceeded-message/light-nudge.js +8 -0
  30. package/build/{ai-client/src/constants.d.ts → constants.d.ts} +3 -0
  31. package/build/{ai-client/src/constants.js → constants.js} +4 -0
  32. package/build/hooks/use-ai-checkout/index.d.ts +13 -0
  33. package/build/hooks/use-ai-checkout/index.js +41 -0
  34. package/build/hooks/use-ai-feature/index.d.ts +33 -0
  35. package/build/hooks/use-ai-feature/index.js +37 -0
  36. package/build/hooks/use-post-content.d.ts +5 -0
  37. package/build/hooks/use-post-content.js +20 -0
  38. package/build/hooks/use-save-to-media-library.d.ts +12 -0
  39. package/build/hooks/use-save-to-media-library.js +74 -0
  40. package/build/{ai-client/src/index.d.ts → index.d.ts} +3 -0
  41. package/build/{ai-client/src/index.js → index.js} +3 -0
  42. package/build/{ai-client/src/logo-generator → logo-generator}/components/upgrade-screen.js +1 -1
  43. package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-fair-usage-notice-message.js +1 -1
  44. package/package.json +20 -14
  45. package/src/components/ai-icon/index.tsx +39 -0
  46. package/src/components/ai-image/components/ai-image-modal.scss +88 -0
  47. package/src/components/ai-image/components/ai-image-modal.tsx +240 -0
  48. package/src/components/ai-image/components/carrousel.scss +163 -0
  49. package/src/components/ai-image/components/carrousel.tsx +217 -0
  50. package/src/components/ai-image/components/usage-counter.scss +19 -0
  51. package/src/components/ai-image/components/usage-counter.tsx +54 -0
  52. package/src/components/ai-image/featured-image.tsx +439 -0
  53. package/src/components/ai-image/general-purpose-image.tsx +303 -0
  54. package/src/components/ai-image/hooks/use-ai-image.ts +339 -0
  55. package/src/components/ai-image/hooks/use-site-type.ts +26 -0
  56. package/src/components/ai-image/index.ts +10 -0
  57. package/src/components/ai-image/style.scss +95 -0
  58. package/src/components/ai-image/types.ts +19 -0
  59. package/src/components/index.ts +12 -0
  60. package/src/components/modal/index.tsx +70 -0
  61. package/src/components/modal/style.scss +45 -0
  62. package/src/components/quota-exceeded-message/index.tsx +319 -0
  63. package/src/components/quota-exceeded-message/light-nudge.tsx +38 -0
  64. package/src/components/quota-exceeded-message/style.scss +35 -0
  65. package/src/constants.ts +5 -0
  66. package/src/hooks/use-ai-checkout/index.ts +65 -0
  67. package/src/hooks/use-ai-feature/Readme.md +20 -0
  68. package/src/hooks/use-ai-feature/index.ts +62 -0
  69. package/src/hooks/use-post-content.ts +27 -0
  70. package/src/hooks/use-save-to-media-library.ts +100 -0
  71. package/src/index.ts +3 -0
  72. package/src/logo-generator/components/upgrade-screen.tsx +1 -1
  73. package/src/logo-generator/hooks/use-fair-usage-notice-message.tsx +1 -1
  74. package/build/components/tools/jp-redirect/index.d.ts +0 -20
  75. package/build/components/tools/jp-redirect/index.js +0 -50
  76. package/build/components/tools/jp-redirect/types.d.ts +0 -39
  77. package/build/components/tools/jp-redirect/types.js +0 -1
  78. /package/build/{ai-client/src/api-fetch → api-fetch}/index.d.ts +0 -0
  79. /package/build/{ai-client/src/api-fetch → api-fetch}/index.js +0 -0
  80. /package/build/{ai-client/src/ask-question → ask-question}/index.d.ts +0 -0
  81. /package/build/{ai-client/src/ask-question → ask-question}/index.js +0 -0
  82. /package/build/{ai-client/src/ask-question → ask-question}/sync.d.ts +0 -0
  83. /package/build/{ai-client/src/ask-question → ask-question}/sync.js +0 -0
  84. /package/build/{ai-client/src/audio-transcription → audio-transcription}/index.d.ts +0 -0
  85. /package/build/{ai-client/src/audio-transcription → audio-transcription}/index.js +0 -0
  86. /package/build/{ai-client/src/components → components}/ai-control/ai-control.d.ts +0 -0
  87. /package/build/{ai-client/src/components → components}/ai-control/ai-control.js +0 -0
  88. /package/build/{ai-client/src/components → components}/ai-control/block-ai-control.d.ts +0 -0
  89. /package/build/{ai-client/src/components → components}/ai-control/block-ai-control.js +0 -0
  90. /package/build/{ai-client/src/components → components}/ai-control/extension-ai-control.d.ts +0 -0
  91. /package/build/{ai-client/src/components → components}/ai-control/extension-ai-control.js +0 -0
  92. /package/build/{ai-client/src/components → components}/ai-control/index.d.ts +0 -0
  93. /package/build/{ai-client/src/components → components}/ai-control/index.js +0 -0
  94. /package/build/{ai-client/src/components → components}/ai-feedback/index.d.ts +0 -0
  95. /package/build/{ai-client/src/components → components}/ai-feedback/index.js +0 -0
  96. /package/build/{ai-client/src/components → components}/ai-modal-footer/index.d.ts +0 -0
  97. /package/build/{ai-client/src/components → components}/ai-modal-footer/index.js +0 -0
  98. /package/build/{ai-client/src/components → components}/ai-status-indicator/index.d.ts +0 -0
  99. /package/build/{ai-client/src/components → components}/ai-status-indicator/index.js +0 -0
  100. /package/build/{ai-client/src/components → components}/audio-duration-display/index.d.ts +0 -0
  101. /package/build/{ai-client/src/components → components}/audio-duration-display/index.js +0 -0
  102. /package/build/{ai-client/src/components → components}/audio-duration-display/lib/media.d.ts +0 -0
  103. /package/build/{ai-client/src/components → components}/audio-duration-display/lib/media.js +0 -0
  104. /package/build/{ai-client/src/components → components}/message/index.d.ts +0 -0
  105. /package/build/{ai-client/src/components → components}/message/index.js +0 -0
  106. /package/build/{ai-client/src/data-flow → data-flow}/context.d.ts +0 -0
  107. /package/build/{ai-client/src/data-flow → data-flow}/context.js +0 -0
  108. /package/build/{ai-client/src/data-flow → data-flow}/index.d.ts +0 -0
  109. /package/build/{ai-client/src/data-flow → data-flow}/index.js +0 -0
  110. /package/build/{ai-client/src/data-flow → data-flow}/use-ai-context.d.ts +0 -0
  111. /package/build/{ai-client/src/data-flow → data-flow}/use-ai-context.js +0 -0
  112. /package/build/{ai-client/src/data-flow → data-flow}/with-ai-assistant-data.d.ts +0 -0
  113. /package/build/{ai-client/src/data-flow → data-flow}/with-ai-assistant-data.js +0 -0
  114. /package/build/{ai-client/src/hooks → hooks}/use-ai-suggestions/index.d.ts +0 -0
  115. /package/build/{ai-client/src/hooks → hooks}/use-ai-suggestions/index.js +0 -0
  116. /package/build/{ai-client/src/hooks → hooks}/use-audio-transcription/index.d.ts +0 -0
  117. /package/build/{ai-client/src/hooks → hooks}/use-audio-transcription/index.js +0 -0
  118. /package/build/{ai-client/src/hooks → hooks}/use-audio-validation/index.d.ts +0 -0
  119. /package/build/{ai-client/src/hooks → hooks}/use-audio-validation/index.js +0 -0
  120. /package/build/{ai-client/src/hooks → hooks}/use-image-generator/constants.d.ts +0 -0
  121. /package/build/{ai-client/src/hooks → hooks}/use-image-generator/constants.js +0 -0
  122. /package/build/{ai-client/src/hooks → hooks}/use-image-generator/index.d.ts +0 -0
  123. /package/build/{ai-client/src/hooks → hooks}/use-image-generator/index.js +0 -0
  124. /package/build/{ai-client/src/hooks → hooks}/use-media-recording/index.d.ts +0 -0
  125. /package/build/{ai-client/src/hooks → hooks}/use-media-recording/index.js +0 -0
  126. /package/build/{ai-client/src/hooks → hooks}/use-save-to-media-library/index.d.ts +0 -0
  127. /package/build/{ai-client/src/hooks → hooks}/use-save-to-media-library/index.js +0 -0
  128. /package/build/{ai-client/src/hooks → hooks}/use-transcription-post-processing/index.d.ts +0 -0
  129. /package/build/{ai-client/src/hooks → hooks}/use-transcription-post-processing/index.js +0 -0
  130. /package/build/{ai-client/src/icons → icons}/ai-assistant.d.ts +0 -0
  131. /package/build/{ai-client/src/icons → icons}/ai-assistant.js +0 -0
  132. /package/build/{ai-client/src/icons → icons}/error-exclamation.d.ts +0 -0
  133. /package/build/{ai-client/src/icons → icons}/error-exclamation.js +0 -0
  134. /package/build/{ai-client/src/icons → icons}/index.d.ts +0 -0
  135. /package/build/{ai-client/src/icons → icons}/index.js +0 -0
  136. /package/build/{ai-client/src/icons → icons}/mic.d.ts +0 -0
  137. /package/build/{ai-client/src/icons → icons}/mic.js +0 -0
  138. /package/build/{ai-client/src/icons → icons}/origami-plane.d.ts +0 -0
  139. /package/build/{ai-client/src/icons → icons}/origami-plane.js +0 -0
  140. /package/build/{ai-client/src/icons → icons}/player-pause.d.ts +0 -0
  141. /package/build/{ai-client/src/icons → icons}/player-pause.js +0 -0
  142. /package/build/{ai-client/src/icons → icons}/player-play.d.ts +0 -0
  143. /package/build/{ai-client/src/icons → icons}/player-play.js +0 -0
  144. /package/build/{ai-client/src/icons → icons}/player-stop.d.ts +0 -0
  145. /package/build/{ai-client/src/icons → icons}/player-stop.js +0 -0
  146. /package/build/{ai-client/src/icons → icons}/speak-tone.d.ts +0 -0
  147. /package/build/{ai-client/src/icons → icons}/speak-tone.js +0 -0
  148. /package/build/{ai-client/src/jwt → jwt}/index.d.ts +0 -0
  149. /package/build/{ai-client/src/jwt → jwt}/index.js +0 -0
  150. /package/build/{ai-client/src/libs → libs}/index.d.ts +0 -0
  151. /package/build/{ai-client/src/libs → libs}/index.js +0 -0
  152. /package/build/{ai-client/src/libs → libs}/map-action-to-human-text.d.ts +0 -0
  153. /package/build/{ai-client/src/libs → libs}/map-action-to-human-text.js +0 -0
  154. /package/build/{ai-client/src/libs → libs}/markdown/html-to-markdown.d.ts +0 -0
  155. /package/build/{ai-client/src/libs → libs}/markdown/html-to-markdown.js +0 -0
  156. /package/build/{ai-client/src/libs → libs}/markdown/index.d.ts +0 -0
  157. /package/build/{ai-client/src/libs → libs}/markdown/index.js +0 -0
  158. /package/build/{ai-client/src/libs → libs}/markdown/markdown-to-html.d.ts +0 -0
  159. /package/build/{ai-client/src/libs → libs}/markdown/markdown-to-html.js +0 -0
  160. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/ai.d.ts +0 -0
  161. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/ai.js +0 -0
  162. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/check.d.ts +0 -0
  163. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/check.js +0 -0
  164. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/logo.d.ts +0 -0
  165. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/logo.js +0 -0
  166. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/media.d.ts +0 -0
  167. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/media.js +0 -0
  168. /package/build/{ai-client/src/logo-generator → logo-generator}/components/fair-usage-notice.d.ts +0 -0
  169. /package/build/{ai-client/src/logo-generator → logo-generator}/components/fair-usage-notice.js +0 -0
  170. /package/build/{ai-client/src/logo-generator → logo-generator}/components/feature-fetch-failure-screen.d.ts +0 -0
  171. /package/build/{ai-client/src/logo-generator → logo-generator}/components/feature-fetch-failure-screen.js +0 -0
  172. /package/build/{ai-client/src/logo-generator → logo-generator}/components/first-load-screen.d.ts +0 -0
  173. /package/build/{ai-client/src/logo-generator → logo-generator}/components/first-load-screen.js +0 -0
  174. /package/build/{ai-client/src/logo-generator → logo-generator}/components/generator-modal.d.ts +0 -0
  175. /package/build/{ai-client/src/logo-generator → logo-generator}/components/generator-modal.js +0 -0
  176. /package/build/{ai-client/src/logo-generator → logo-generator}/components/history-carousel.d.ts +0 -0
  177. /package/build/{ai-client/src/logo-generator → logo-generator}/components/history-carousel.js +0 -0
  178. /package/build/{ai-client/src/logo-generator → logo-generator}/components/image-loader.d.ts +0 -0
  179. /package/build/{ai-client/src/logo-generator → logo-generator}/components/image-loader.js +0 -0
  180. /package/build/{ai-client/src/logo-generator → logo-generator}/components/logo-presenter.d.ts +0 -0
  181. /package/build/{ai-client/src/logo-generator → logo-generator}/components/logo-presenter.js +0 -0
  182. /package/build/{ai-client/src/logo-generator → logo-generator}/components/prompt.d.ts +0 -0
  183. /package/build/{ai-client/src/logo-generator → logo-generator}/components/prompt.js +0 -0
  184. /package/build/{ai-client/src/logo-generator → logo-generator}/components/upgrade-nudge.d.ts +0 -0
  185. /package/build/{ai-client/src/logo-generator → logo-generator}/components/upgrade-nudge.js +0 -0
  186. /package/build/{ai-client/src/logo-generator → logo-generator}/components/upgrade-screen.d.ts +0 -0
  187. /package/build/{ai-client/src/logo-generator → logo-generator}/components/visit-site-banner.d.ts +0 -0
  188. /package/build/{ai-client/src/logo-generator → logo-generator}/components/visit-site-banner.js +0 -0
  189. /package/build/{ai-client/src/logo-generator → logo-generator}/constants.d.ts +0 -0
  190. /package/build/{ai-client/src/logo-generator → logo-generator}/constants.js +0 -0
  191. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-checkout.d.ts +0 -0
  192. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-checkout.js +0 -0
  193. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-fair-usage-notice-message.d.ts +0 -0
  194. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-logo-generator.d.ts +0 -0
  195. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-logo-generator.js +0 -0
  196. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-request-errors.d.ts +0 -0
  197. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-request-errors.js +0 -0
  198. /package/build/{ai-client/src/logo-generator → logo-generator}/index.d.ts +0 -0
  199. /package/build/{ai-client/src/logo-generator → logo-generator}/index.js +0 -0
  200. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/logo-storage.d.ts +0 -0
  201. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/logo-storage.js +0 -0
  202. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/media-exists.d.ts +0 -0
  203. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/media-exists.js +0 -0
  204. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/set-site-logo.d.ts +0 -0
  205. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/set-site-logo.js +0 -0
  206. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/wpcom-limited-request.d.ts +0 -0
  207. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/wpcom-limited-request.js +0 -0
  208. /package/build/{ai-client/src/logo-generator → logo-generator}/store/actions.d.ts +0 -0
  209. /package/build/{ai-client/src/logo-generator → logo-generator}/store/actions.js +0 -0
  210. /package/build/{ai-client/src/logo-generator → logo-generator}/store/constants.d.ts +0 -0
  211. /package/build/{ai-client/src/logo-generator → logo-generator}/store/constants.js +0 -0
  212. /package/build/{ai-client/src/logo-generator → logo-generator}/store/index.d.ts +0 -0
  213. /package/build/{ai-client/src/logo-generator → logo-generator}/store/index.js +0 -0
  214. /package/build/{ai-client/src/logo-generator → logo-generator}/store/initial-state.d.ts +0 -0
  215. /package/build/{ai-client/src/logo-generator → logo-generator}/store/initial-state.js +0 -0
  216. /package/build/{ai-client/src/logo-generator → logo-generator}/store/reducer.d.ts +0 -0
  217. /package/build/{ai-client/src/logo-generator → logo-generator}/store/reducer.js +0 -0
  218. /package/build/{ai-client/src/logo-generator → logo-generator}/store/selectors.d.ts +0 -0
  219. /package/build/{ai-client/src/logo-generator → logo-generator}/store/selectors.js +0 -0
  220. /package/build/{ai-client/src/logo-generator → logo-generator}/store/types.d.ts +0 -0
  221. /package/build/{ai-client/src/logo-generator → logo-generator}/store/types.js +0 -0
  222. /package/build/{ai-client/src/logo-generator → logo-generator}/types.d.ts +0 -0
  223. /package/build/{ai-client/src/logo-generator → logo-generator}/types.js +0 -0
  224. /package/build/{ai-client/src/suggestions-event-source → suggestions-event-source}/index.d.ts +0 -0
  225. /package/build/{ai-client/src/suggestions-event-source → suggestions-event-source}/index.js +0 -0
  226. /package/build/{ai-client/src/types.d.ts → types.d.ts} +0 -0
  227. /package/build/{ai-client/src/types.js → types.js} +0 -0
@@ -0,0 +1,152 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /*
3
+ * External dependencies
4
+ */
5
+ import getRedirectUrl from '@automattic/jetpack-components/tools/jp-redirect';
6
+ import { useAnalytics, canUserPurchasePlan } from '@automattic/jetpack-shared-extension-utils';
7
+ import { Nudge as StandardNudge } from '@automattic/jetpack-shared-extension-utils/components';
8
+ import { Notice } from '@wordpress/components';
9
+ import { createInterpolateElement, useCallback } from '@wordpress/element';
10
+ import { __, sprintf } from '@wordpress/i18n';
11
+ import debugFactory from 'debug';
12
+ /*
13
+ * Internal dependencies
14
+ */
15
+ import useAICheckout from '../../hooks/use-ai-checkout/index.js';
16
+ import useAiFeature from '../../hooks/use-ai-feature/index.js';
17
+ import { LightNudge } from './light-nudge.js';
18
+ import './style.scss';
19
+ const debug = debugFactory('jetpack-ai-client:upgrade-prompt');
20
+ /**
21
+ * The fair usage notice message for the AI Assistant block.
22
+ * @return {ReactElement} the fair usage notice message, with the proper link and date.
23
+ */
24
+ const useFairUsageNoticeMessage = () => {
25
+ const { usagePeriod } = useAiFeature();
26
+ const getFormattedUsagePeriodStartDate = planUsagePeriod => {
27
+ if (!planUsagePeriod?.nextStart) {
28
+ return null;
29
+ }
30
+ const nextUsagePeriodStartDate = new Date(planUsagePeriod.nextStart);
31
+ return (nextUsagePeriodStartDate.toLocaleString('default', { month: 'long' }) +
32
+ ' ' +
33
+ nextUsagePeriodStartDate.getDate());
34
+ };
35
+ const getFairUsageNoticeMessage = resetDateString => {
36
+ const fairUsageMessage = __("You've reached this month's request limit, per our <link>fair usage policy</link>.", 'jetpack-ai-client');
37
+ if (!resetDateString) {
38
+ return fairUsageMessage;
39
+ }
40
+ // Translators: %s is the date when the requests will reset.
41
+ const dateMessage = __('Requests will reset on %s.', 'jetpack-ai-client');
42
+ const formattedDateMessage = sprintf(dateMessage, resetDateString);
43
+ return `${fairUsageMessage} ${formattedDateMessage}`;
44
+ };
45
+ const nextUsagePeriodStartDateString = getFormattedUsagePeriodStartDate(usagePeriod);
46
+ // Get the proper template based on the presence of the next usage period start date.
47
+ const fairUsageNoticeMessage = getFairUsageNoticeMessage(nextUsagePeriodStartDateString);
48
+ const fairUsageNoticeMessageElement = createInterpolateElement(fairUsageNoticeMessage, {
49
+ link: (_jsx("a", { href: "https://jetpack.com/redirect/?source=ai-assistant-fair-usage-policy", target: "_blank", rel: "noreferrer" })),
50
+ });
51
+ return fairUsageNoticeMessageElement;
52
+ };
53
+ /**
54
+ * The default upgrade prompt for the AI Assistant block, containing the Upgrade button and linking
55
+ * to the checkout page or the Jetpack AI interstitial page.
56
+ *
57
+ * @param {QuotaExceededMessageProps} props - Component props.
58
+ * @return {ReactElement} the Nudge component with the prompt.
59
+ */
60
+ const DefaultUpgradePrompt = ({ placement = null, description = null, useLightNudge = false, }) => {
61
+ const Nudge = useLightNudge ? LightNudge : StandardNudge;
62
+ const { checkoutUrl } = useAICheckout();
63
+ const canUpgrade = canUserPurchasePlan();
64
+ const { nextTier, tierPlansEnabled, currentTier, requestsCount } = useAiFeature();
65
+ const { tracks } = useAnalytics();
66
+ const handleUpgradeClick = useCallback(() => {
67
+ debug('upgrade', placement);
68
+ tracks.recordEvent('jetpack_ai_upgrade_button', {
69
+ current_tier_slug: currentTier?.slug,
70
+ requests_count: requestsCount,
71
+ placement: placement,
72
+ });
73
+ }, [currentTier, requestsCount, tracks, placement]);
74
+ const handleContactUsClick = useCallback(() => {
75
+ debug('contact us', placement);
76
+ tracks.recordEvent('jetpack_ai_upgrade_contact_us', {
77
+ placement: placement,
78
+ });
79
+ }, [tracks, placement]);
80
+ if (!canUpgrade) {
81
+ const cantUpgradeDescription = createInterpolateElement(__('Congratulations on exploring Jetpack AI and reaching the free requests limit! <strong>Reach out to the site administrator to upgrade and keep using Jetpack AI.</strong>', 'jetpack-ai-client'), {
82
+ strong: _jsx("strong", {}),
83
+ });
84
+ return (_jsx(Nudge, { showButton: false, className: 'jetpack-ai-upgrade-banner', description: description || cantUpgradeDescription, visible: true, align: null, title: null, context: null }));
85
+ }
86
+ if (tierPlansEnabled) {
87
+ if (!nextTier) {
88
+ const contactHref = getRedirectUrl('jetpack-ai-tiers-more-requests-contact');
89
+ const contactUsDescription = __('You have reached the request limit for your current plan.', 'jetpack-ai-client');
90
+ return (_jsx(Nudge, { buttonText: __('Contact Us', 'jetpack-ai-client'), description: description || contactUsDescription, className: 'jetpack-ai-upgrade-banner', checkoutUrl: contactHref, visible: true, align: null, title: null, context: null, goToCheckoutPage: handleContactUsClick, target: "_blank" }));
91
+ }
92
+ const upgradeDescription = createInterpolateElement(sprintf(
93
+ /* Translators: number of requests */
94
+ __('You have reached the requests limit for your current plan. <strong>Upgrade now to increase your requests limit to %d.</strong>', 'jetpack-ai-client'), nextTier.limit), {
95
+ strong: _jsx("strong", {}),
96
+ });
97
+ return (_jsx(Nudge, { buttonText: sprintf(
98
+ /* Translators: number of requests */
99
+ __('Upgrade to %d requests', 'jetpack-ai-client'), nextTier.limit), checkoutUrl: checkoutUrl, className: 'jetpack-ai-upgrade-banner', description: description || upgradeDescription, goToCheckoutPage: handleUpgradeClick, visible: true, align: 'center', title: null, context: null, target: "_blank" }));
100
+ }
101
+ return (_jsx(Nudge, { buttonText: __('Upgrade', 'jetpack-ai-client'), checkoutUrl: checkoutUrl, className: 'jetpack-ai-upgrade-banner', description: createInterpolateElement(__('Congratulations on exploring Jetpack AI and reaching the free requests limit! <strong>Upgrade now to keep using it.</strong>', 'jetpack-ai-client'), {
102
+ strong: _jsx("strong", {}),
103
+ }), goToCheckoutPage: handleUpgradeClick, visible: true, align: null, title: null, context: null, target: "_blank" }));
104
+ };
105
+ /**
106
+ * The VIP upgrade prompt, with a single text message recommending that the user reach
107
+ * out to their VIP account team.
108
+ *
109
+ * @param {object} props - Component props.
110
+ * @param {string} props.description - The description to display in the prompt.
111
+ * @param {boolean} props.useLightNudge - Wheter to use the light variant of the nudge, or the standard one.
112
+ * @return {ReactElement} the Nudge component with the prompt.
113
+ */
114
+ const VIPUpgradePrompt = ({ description = null, useLightNudge = false, }) => {
115
+ const Nudge = useLightNudge ? LightNudge : StandardNudge;
116
+ const vipDescription = createInterpolateElement(__("You've reached the Jetpack AI rate limit. <strong>Please reach out to your VIP account team.</strong>", 'jetpack-ai-client'), {
117
+ strong: _jsx("strong", {}),
118
+ });
119
+ return (_jsx(Nudge, { buttonText: null, checkoutUrl: null, className: 'jetpack-ai-upgrade-banner', description: description || vipDescription, goToCheckoutPage: null, isRedirecting: null, visible: true, align: null, title: null, context: null }));
120
+ };
121
+ /**
122
+ * The fair usage notice component.
123
+ * @param {FairUsageNoticeProps} props - Fair usage notice component props.
124
+ * @param {FairUsageNoticeProps.variant} props.variant - The variant of the notice to render.
125
+ * @return {ReactElement} the Notice component with the fair usage message.
126
+ */
127
+ export const FairUsageNotice = ({ variant = 'error' }) => {
128
+ const useFairUsageNoticeMessageElement = useFairUsageNoticeMessage();
129
+ if (variant === 'muted') {
130
+ return (_jsx("span", { className: "jetpack-ai-fair-usage-notice-muted-variant", children: useFairUsageNoticeMessageElement }));
131
+ }
132
+ if (variant === 'error') {
133
+ return (_jsx(Notice, { status: "error", isDismissible: false, className: "jetpack-ai-fair-usage-notice", children: useFairUsageNoticeMessageElement }));
134
+ }
135
+ return null;
136
+ };
137
+ const QuotaExceededMessage = props => {
138
+ const { upgradeType, currentTier } = useAiFeature();
139
+ // Return notice component for the fair usage limit message, on unlimited plans.
140
+ if (currentTier?.value === 1) {
141
+ return _jsx(FairUsageNotice, {});
142
+ }
143
+ // If the user is on a VIP site, show the VIP upgrade prompt.
144
+ if (upgradeType === 'vip') {
145
+ return VIPUpgradePrompt({
146
+ description: props.description,
147
+ useLightNudge: props?.useLightNudge,
148
+ });
149
+ }
150
+ return DefaultUpgradePrompt(props);
151
+ };
152
+ export default QuotaExceededMessage;
@@ -0,0 +1,11 @@
1
+ import './style.scss';
2
+ export declare const LightNudge: ({ title, description, buttonText, checkoutUrl, goToCheckoutPage, isRedirecting, showButton, target, }: {
3
+ title: any;
4
+ description: any;
5
+ buttonText?: any;
6
+ checkoutUrl?: any;
7
+ goToCheckoutPage?: any;
8
+ isRedirecting?: boolean;
9
+ showButton?: boolean;
10
+ target?: string;
11
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Notice } from '@wordpress/components';
3
+ import { __ } from '@wordpress/i18n';
4
+ import './style.scss';
5
+ export const LightNudge = ({ title, description, buttonText = null, checkoutUrl = null, goToCheckoutPage = null, isRedirecting = false, showButton = true, target = '_top', }) => {
6
+ const redirectingText = __('Redirecting…', 'jetpack-ai-client');
7
+ return (_jsx("div", { className: "jetpack-upgrade-plan-banner-light", children: _jsx(Notice, { status: "error", isDismissible: false, children: _jsxs("p", { children: [title && _jsx("strong", { children: title }), description, ' ', showButton && (_jsx(Button, { href: isRedirecting ? null : checkoutUrl, onClick: goToCheckoutPage, variant: "link", target: target, children: isRedirecting ? redirectingText : buttonText }))] }) }) }));
8
+ };
@@ -104,3 +104,6 @@ export declare const WRITE_POST_FROM_LIST_LABEL: string;
104
104
  export declare const GENERATE_TITLE_LABEL: string;
105
105
  export declare const SUMMARY_BASED_ON_TITLE_LABEL: string;
106
106
  export declare const CONTINUE_LABEL: string;
107
+ export declare const PLACEMENT_JETPACK_SIDEBAR: "jetpack-sidebar";
108
+ export declare const PLACEMENT_DOCUMENT_SETTINGS: "document-settings";
109
+ export declare const PLACEMENT_PRE_PUBLISH: "pre-publish";
@@ -111,3 +111,7 @@ export const WRITE_POST_FROM_LIST_LABEL = __('Write a post from this list', 'jet
111
111
  export const GENERATE_TITLE_LABEL = __('Generate a post title', 'jetpack-ai-client');
112
112
  export const SUMMARY_BASED_ON_TITLE_LABEL = __('Summary based on title', 'jetpack-ai-client');
113
113
  export const CONTINUE_LABEL = __('Continue writing', 'jetpack-ai-client');
114
+ // Jetpack Sidebar
115
+ export const PLACEMENT_JETPACK_SIDEBAR = 'jetpack-sidebar';
116
+ export const PLACEMENT_DOCUMENT_SETTINGS = 'document-settings';
117
+ export const PLACEMENT_PRE_PUBLISH = 'pre-publish';
@@ -0,0 +1,13 @@
1
+ import type { MouseEvent } from 'react';
2
+ type UseAICheckoutReturn = {
3
+ checkoutUrl: string;
4
+ autosaveAndRedirect: (event: MouseEvent<HTMLButtonElement>) => void;
5
+ isRedirecting: boolean;
6
+ };
7
+ /**
8
+ * The hook to get properties for AICheckout
9
+ *
10
+ * @return {UseAICheckoutReturn} - Object containing properties for AICheckout.
11
+ */
12
+ export default function useAICheckout(): UseAICheckoutReturn;
13
+ export {};
@@ -0,0 +1,41 @@
1
+ /*
2
+ * External dependencies
3
+ */
4
+ import getRedirectUrl from '@automattic/jetpack-components/tools/jp-redirect';
5
+ import { isAtomicSite, isSimpleSite, getSiteFragment, useAutosaveAndRedirect, } from '@automattic/jetpack-shared-extension-utils';
6
+ import useAiFeature from '../use-ai-feature/index.js';
7
+ const getWPComRedirectToURL = () => {
8
+ const searchParams = new URLSearchParams(window.location.search);
9
+ const site = getSiteFragment();
10
+ if (isSimpleSite() && searchParams.has('post')) {
11
+ // When there is an explicit post, use it as the destination
12
+ return `https://wordpress.com/post/${site}/${searchParams.get('post')}`;
13
+ }
14
+ // When there is no explicit post, or the site is not Simple, use the home page as the destination
15
+ return `https://wordpress.com/home/${site}`;
16
+ };
17
+ /**
18
+ * The hook to get properties for AICheckout
19
+ *
20
+ * @return {UseAICheckoutReturn} - Object containing properties for AICheckout.
21
+ */
22
+ export default function useAICheckout() {
23
+ const { nextTier, tierPlansEnabled } = useAiFeature();
24
+ const wpcomRedirectToURL = getWPComRedirectToURL();
25
+ const wpcomCheckoutUrl = getRedirectUrl('jetpack-ai-yearly-tier-upgrade-nudge', {
26
+ site: getSiteFragment(),
27
+ path: tierPlansEnabled ? `jetpack_ai_yearly:-q-${nextTier?.limit}` : 'jetpack_ai_yearly',
28
+ query: `redirect_to=${encodeURIComponent(wpcomRedirectToURL)}`,
29
+ });
30
+ const jetpackCheckoutUrl = getRedirectUrl('jetpack-ai-upgrade-url-for-jetpack-sites', {
31
+ site: getSiteFragment(),
32
+ path: 'jetpack_ai_yearly',
33
+ });
34
+ const checkoutUrl = isAtomicSite() || isSimpleSite() ? wpcomCheckoutUrl : jetpackCheckoutUrl;
35
+ const { autosaveAndRedirect, isRedirecting } = useAutosaveAndRedirect(checkoutUrl);
36
+ return {
37
+ checkoutUrl,
38
+ autosaveAndRedirect,
39
+ isRedirecting,
40
+ };
41
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Hook to get properties for AiFeature
3
+ * @return {object} - Object containing properties for AiFeature.
4
+ */
5
+ export default function useAiFeature(): {
6
+ requestsCount: number;
7
+ requestsLimit: number;
8
+ loading: boolean;
9
+ error: any;
10
+ refresh: any;
11
+ increaseRequestsCount: any;
12
+ dequeueAsyncRequest: any;
13
+ hasFeature: boolean;
14
+ isOverLimit: boolean;
15
+ requireUpgrade: boolean;
16
+ errorMessage?: string;
17
+ errorCode?: string;
18
+ upgradeType: import("@automattic/jetpack-shared-extension-utils/store/wordpress-com/types").UpgradeTypeProp;
19
+ currentTier?: import("@automattic/jetpack-shared-extension-utils/store/wordpress-com/types").TierProp;
20
+ usagePeriod?: {
21
+ currentStart: string;
22
+ nextStart: string;
23
+ requestsCount: number;
24
+ };
25
+ nextTier?: import("@automattic/jetpack-shared-extension-utils/store/wordpress-com/types").TierProp;
26
+ tierPlansEnabled?: boolean;
27
+ costs?: {
28
+ [key: string]: {
29
+ [key: string]: number;
30
+ };
31
+ };
32
+ featuresControl?: import("@automattic/jetpack-shared-extension-utils/store/wordpress-com/types").FeaturesControl;
33
+ };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { PLAN_TYPE_FREE, usePlanType as getPlanType, } from '@automattic/jetpack-shared-extension-utils';
5
+ import { useDispatch, useSelect } from '@wordpress/data';
6
+ /**
7
+ * Hook to get properties for AiFeature
8
+ * @return {object} - Object containing properties for AiFeature.
9
+ */
10
+ export default function useAiFeature() {
11
+ const { data, loading, requestsLimit, requestsCount } = useSelect(select => {
12
+ const { getAiAssistantFeature, getIsRequestingAiAssistantFeature } = select('wordpress-com/plans');
13
+ const featureData = getAiAssistantFeature();
14
+ const { currentTier, usagePeriod, requestsCount: allTimeRequestsCount, requestsLimit: freeRequestsLimit, } = featureData;
15
+ const planType = getPlanType(currentTier);
16
+ const currentTierLimit = currentTier?.limit || freeRequestsLimit;
17
+ const actualRequestsCount = planType === PLAN_TYPE_FREE ? allTimeRequestsCount : usagePeriod?.requestsCount;
18
+ const actualRequestsLimit = planType === PLAN_TYPE_FREE ? freeRequestsLimit : currentTierLimit;
19
+ return {
20
+ data: featureData,
21
+ loading: getIsRequestingAiAssistantFeature(),
22
+ requestsCount: actualRequestsCount,
23
+ requestsLimit: actualRequestsLimit,
24
+ };
25
+ }, []);
26
+ const { fetchAiAssistantFeature: loadFeatures, increaseAiAssistantRequestsCount: increaseRequestsCount, dequeueAiAssistantFeatureAsyncRequest: dequeueAsyncRequest, } = useDispatch('wordpress-com/plans');
27
+ return {
28
+ ...data,
29
+ requestsCount,
30
+ requestsLimit,
31
+ loading,
32
+ error: null,
33
+ refresh: loadFeatures,
34
+ increaseRequestsCount,
35
+ dequeueAsyncRequest,
36
+ };
37
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ declare const usePostContent: () => string;
5
+ export default usePostContent;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { serialize } from '@wordpress/blocks';
5
+ import { useSelect } from '@wordpress/data';
6
+ /**
7
+ * Types
8
+ */
9
+ import { renderMarkdownFromHTML } from '../libs/markdown/index.js';
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ /*
14
+ * Simple helper to get the post content as markdown
15
+ */
16
+ const usePostContent = () => {
17
+ const blocks = useSelect(select => select('core/block-editor').getBlocks(), []);
18
+ return blocks?.length ? renderMarkdownFromHTML({ content: serialize(blocks) }) : '';
19
+ };
20
+ export default usePostContent;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Hook to save data to media library
3
+ *
4
+ * @return {UseSaveToMediaLibraryReturn} - Object containing properties to save data to media library.
5
+ */
6
+ export default function useSaveToMediaLibrary(): {
7
+ isLoading: boolean;
8
+ saveToMediaLibrary: (url: string, name?: string) => Promise<{
9
+ id: string;
10
+ url: string;
11
+ }>;
12
+ };
@@ -0,0 +1,74 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { isBlobURL } from '@wordpress/blob';
5
+ import { useSelect } from '@wordpress/data';
6
+ import { useState } from '@wordpress/element';
7
+ import debugFactory from 'debug';
8
+ const debug = debugFactory('jetpack-ai-client:save-to-media-library');
9
+ /**
10
+ * Hook to save data to media library
11
+ *
12
+ * @return {UseSaveToMediaLibraryReturn} - Object containing properties to save data to media library.
13
+ */
14
+ export default function useSaveToMediaLibrary() {
15
+ const [isLoading, setIsLoading] = useState(false);
16
+ const { getSettings } = useSelect(select => select('core/block-editor'), []);
17
+ const saveToMediaLibrary = (url, name = null) => {
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ const settings = getSettings();
20
+ return new Promise((resolve, reject) => {
21
+ setIsLoading(true);
22
+ debug('Fetching image from URL');
23
+ fetch(url)
24
+ .then(response => {
25
+ debug('Transforming response to blob');
26
+ response
27
+ .blob()
28
+ .then((blob) => {
29
+ debug('Uploading blob to media library');
30
+ const filesList = [];
31
+ if (name) {
32
+ filesList.push(new File([blob], name));
33
+ }
34
+ else {
35
+ filesList.push(blob);
36
+ }
37
+ settings.mediaUpload({
38
+ allowedTypes: ['image'],
39
+ filesList,
40
+ onFileChange([image]) {
41
+ if (isBlobURL(image?.url)) {
42
+ return;
43
+ }
44
+ if (image) {
45
+ debug('Image uploaded to media library', image);
46
+ resolve(image);
47
+ }
48
+ setIsLoading(false);
49
+ },
50
+ onError(message) {
51
+ debug('Error uploading image to media library:', message);
52
+ reject(message);
53
+ setIsLoading(false);
54
+ },
55
+ });
56
+ })
57
+ .catch(e => {
58
+ debug('Error transforming response to blob:', e?.message);
59
+ reject(e?.message);
60
+ setIsLoading(false);
61
+ });
62
+ })
63
+ .catch(e => {
64
+ debug('Error fetching image from URL:', e?.message);
65
+ reject(e?.message);
66
+ setIsLoading(false);
67
+ });
68
+ });
69
+ };
70
+ return {
71
+ isLoading,
72
+ saveToMediaLibrary,
73
+ };
74
+ }
@@ -3,12 +3,15 @@ export { default as SuggestionsEventSource } from './suggestions-event-source/in
3
3
  export { default as askQuestion } from './ask-question/index.js';
4
4
  export { default as askQuestionSync } from './ask-question/sync.js';
5
5
  export { default as transcribeAudio } from './audio-transcription/index.js';
6
+ export { default as useAICheckout } from './hooks/use-ai-checkout/index.js';
7
+ export { default as useAiFeature } from './hooks/use-ai-feature/index.js';
6
8
  export { default as useAiSuggestions, getErrorData } from './hooks/use-ai-suggestions/index.js';
7
9
  export { default as useMediaRecording } from './hooks/use-media-recording/index.js';
8
10
  export { default as useAudioTranscription } from './hooks/use-audio-transcription/index.js';
9
11
  export { default as useTranscriptionPostProcessing } from './hooks/use-transcription-post-processing/index.js';
10
12
  export { default as useAudioValidation } from './hooks/use-audio-validation/index.js';
11
13
  export { default as useImageGenerator } from './hooks/use-image-generator/index.js';
14
+ export { default as usePostContent } from './hooks/use-post-content.js';
12
15
  export * from './hooks/use-image-generator/constants.js';
13
16
  export * from './icons/index.js';
14
17
  export * from './components/index.js';
@@ -9,12 +9,15 @@ export { default as transcribeAudio } from './audio-transcription/index.js';
9
9
  /*
10
10
  * Hooks
11
11
  */
12
+ export { default as useAICheckout } from './hooks/use-ai-checkout/index.js';
13
+ export { default as useAiFeature } from './hooks/use-ai-feature/index.js';
12
14
  export { default as useAiSuggestions, getErrorData } from './hooks/use-ai-suggestions/index.js';
13
15
  export { default as useMediaRecording } from './hooks/use-media-recording/index.js';
14
16
  export { default as useAudioTranscription } from './hooks/use-audio-transcription/index.js';
15
17
  export { default as useTranscriptionPostProcessing } from './hooks/use-transcription-post-processing/index.js';
16
18
  export { default as useAudioValidation } from './hooks/use-audio-validation/index.js';
17
19
  export { default as useImageGenerator } from './hooks/use-image-generator/index.js';
20
+ export { default as usePostContent } from './hooks/use-post-content.js';
18
21
  export * from './hooks/use-image-generator/constants.js';
19
22
  /*
20
23
  * Components: Icons
@@ -2,13 +2,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
3
  * External dependencies
4
4
  */
5
+ import getRedirectUrl from '@automattic/jetpack-components/tools/jp-redirect';
5
6
  import { useAnalytics } from '@automattic/jetpack-shared-extension-utils';
6
7
  import { Button } from '@wordpress/components';
7
8
  import { __ } from '@wordpress/i18n';
8
9
  /**
9
10
  * Internal dependencies
10
11
  */
11
- import getRedirectUrl from '../../../../components/tools/jp-redirect/index.js';
12
12
  import { EVENT_PLACEMENT_FREE_USER_SCREEN, EVENT_UPGRADE } from '../constants.js';
13
13
  import useLogoGenerator from '../hooks/use-logo-generator.js';
14
14
  export const UpgradeScreen = ({ onCancel, upgradeURL, reason }) => {
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import getRedirectUrl from '@automattic/jetpack-components/tools/jp-redirect';
2
3
  import { useSelect } from '@wordpress/data';
3
4
  import { createInterpolateElement } from '@wordpress/element';
4
5
  import { __, sprintf } from '@wordpress/i18n';
5
- import getRedirectUrl from '../../../../components/tools/jp-redirect/index.js';
6
6
  /**
7
7
  * Internal dependencies
8
8
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@automattic/jetpack-ai-client",
4
- "version": "0.25.6",
4
+ "version": "0.26.0",
5
5
  "description": "A JS client for consuming Jetpack AI services",
6
6
  "homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/ai-client/#readme",
7
7
  "bugs": {
@@ -44,22 +44,28 @@
44
44
  "main": "./build/index.js",
45
45
  "types": "./build/index.d.ts",
46
46
  "dependencies": {
47
- "@automattic/jetpack-base-styles": "^0.6.40",
48
- "@automattic/jetpack-connection": "^0.36.4",
49
- "@automattic/jetpack-shared-extension-utils": "^0.16.4",
47
+ "@automattic/jetpack-base-styles": "^0.6.42",
48
+ "@automattic/jetpack-components": "^0.66.0",
49
+ "@automattic/jetpack-connection": "^0.36.5",
50
+ "@automattic/jetpack-shared-extension-utils": "^0.17.0",
50
51
  "@microsoft/fetch-event-source": "2.0.1",
52
+ "@types/jest": "29.5.14",
51
53
  "@types/react": "18.3.18",
52
54
  "@types/wordpress__block-editor": "11.5.16",
53
- "@wordpress/api-fetch": "7.16.0",
54
- "@wordpress/base-styles": "5.16.0",
55
- "@wordpress/blob": "4.16.0",
56
- "@wordpress/block-editor": "14.11.0",
57
- "@wordpress/components": "29.2.0",
58
- "@wordpress/compose": "7.16.0",
59
- "@wordpress/data": "10.16.0",
60
- "@wordpress/element": "6.16.0",
61
- "@wordpress/i18n": "5.16.0",
62
- "@wordpress/icons": "10.16.0",
55
+ "@wordpress/api-fetch": "7.17.0",
56
+ "@wordpress/base-styles": "5.17.0",
57
+ "@wordpress/blob": "4.17.0",
58
+ "@wordpress/blocks": "14.6.0",
59
+ "@wordpress/block-editor": "14.12.0",
60
+ "@wordpress/components": "29.3.0",
61
+ "@wordpress/compose": "7.17.0",
62
+ "@wordpress/data": "10.17.0",
63
+ "@wordpress/editor": "14.17.0",
64
+ "@wordpress/element": "6.17.0",
65
+ "@wordpress/i18n": "5.17.0",
66
+ "@wordpress/icons": "10.17.0",
67
+ "@wordpress/primitives": "4.17.0",
68
+ "@wordpress/url": "4.17.0",
63
69
  "clsx": "2.1.1",
64
70
  "debug": "4.4.0",
65
71
  "markdown-it": "14.1.0",
@@ -0,0 +1,39 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { G, Path, SVG, Rect } from '@wordpress/components';
5
+ import { Icon } from '@wordpress/icons';
6
+ import { Defs } from '@wordpress/primitives';
7
+
8
+ export const AiSVG = (
9
+ <SVG width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg">
10
+ <G clipPath="url(#clip0_4479_1006)">
11
+ <Path
12
+ d="M7.87488 0L10.1022 5.64753L15.7498 7.87488L10.1022 10.1022L7.87488 15.7498L5.64753 10.1022L0 7.87488L5.64753 5.64753L7.87488 0Z"
13
+ fill="#A7AAAD"
14
+ />
15
+ <Path
16
+ d="M31.4998 0L34.4696 7.53004L41.9997 10.4998L34.4696 13.4696L31.4998 20.9997L28.53 13.4696L21 10.4998L28.53 7.53004L31.4998 0Z"
17
+ fill="#A7AAAD"
18
+ />
19
+ <Path
20
+ d="M18.3748 15.7496L22.0871 25.1621L31.4996 28.8744L22.0871 32.5866L18.3748 41.9992L14.6625 32.5866L5.25 28.8744L14.6625 25.1621L18.3748 15.7496Z"
21
+ fill="#A7AAAD"
22
+ />
23
+ </G>
24
+ <Defs>
25
+ <clipPath id="clip0_4479_1006">
26
+ <Rect width="41.9997" height="41.9992" fill="white" />
27
+ </clipPath>
28
+ </Defs>
29
+ </SVG>
30
+ );
31
+
32
+ /**
33
+ * AiIcon component
34
+ * @param {string} className - The wrapper class name.
35
+ * @return {React.ReactElement} The `AiIcon` component.
36
+ */
37
+ export default function AiIcon( { className, size = 42 }: { className?: string; size?: number } ) {
38
+ return <Icon icon={ AiSVG } width={ size } height={ size } className={ className } />;
39
+ }